:root { --bg0: #0b1018; --panel: rgba(14, 22, 34, 0.96); --line: rgba(140, 170, 210, 0.18); --text: #e8eef7; --muted: #8fa3bc; --good: #3dce7a; --bad: #e07a2f; --syn: #7ec8ff; --sel: #5ec8ff; --font: "Segoe UI", "Microsoft YaHei UI", "PingFang SC", sans-serif; } * { box-sizing: border-box; } html, body { margin: 0; min-height: 100%; color: var(--text); font-family: var(--font); background: radial-gradient(1200px 600px at 20% -10%, rgba(50, 80, 120, 0.35), transparent 60%), radial-gradient(900px 500px at 90% 10%, rgba(30, 60, 90, 0.28), transparent 55%), linear-gradient(180deg, #152033 0%, var(--bg0) 45%, #070a10 100%); } body { display: flex; flex-direction: column; height: 100dvh; max-height: 100dvh; overflow: hidden; } .topbar { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding: 12px 20px 14px; border-bottom: 1px solid var(--line); background: rgba(8, 12, 20, 0.45); flex: 0 0 auto; } /* Brand mark: official Dota 2 logo + 上分帝 title, pinned to the top-left corner of the topbar. Absolutely positioned so the centered tab row and toolbar layout are left untouched. */ .brand { position: absolute; left: 20px; top: 12px; height: 40px; display: flex; align-items: center; gap: 12px; pointer-events: none; z-index: 2; } .brand-logo { height: 34px; width: auto; display: block; } .brand-title { font-size: 18px; font-weight: 700; letter-spacing: 0.16em; color: var(--text); white-space: nowrap; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } @media (max-width: 880px) { .brand-title { display: none; } } @media (max-width: 620px) { .brand { display: none; } } .main-tabs { display: flex; justify-content: center; gap: 0; } .main-tab { min-width: 120px; padding: 10px 28px; border: 1px solid var(--line); background: rgba(255, 255, 255, 0.03); color: var(--muted); font: inherit; font-size: 15px; letter-spacing: 0.08em; cursor: pointer; } .main-tab:first-child { border-radius: 6px 0 0 6px; } .main-tab:last-child { border-radius: 0 6px 6px 0; } .main-tab + .main-tab { border-left: none; } .main-tab.active { color: var(--text); background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 -2px 0 var(--sel); } .toolbar { position: relative; display: flex; align-items: center; justify-content: center; min-height: 40px; gap: 12px; } .toolbar.hidden, .board.hidden, .hidden { display: none !important; } .tagbar { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; max-width: calc(100% - 220px); } .tagbar button { border: 1px solid var(--line); background: rgba(255,255,255,0.04); color: var(--muted); border-radius: 999px; padding: 8px 18px; cursor: pointer; font: inherit; font-size: 14px; } .tagbar button.active { color: var(--text); border-color: rgba(94, 200, 255, 0.55); background: rgba(94, 200, 255, 0.14); } .search { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 200px; padding: 9px 12px 9px 34px; border: 1px solid rgba(140, 170, 210, 0.38); border-radius: 8px; background-color: rgba(0, 0, 0, 0.45); background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: 10px center; background-size: 15px 15px; color: var(--text); font: inherit; font-size: 14px; outline: none; } .search::placeholder { color: var(--muted); } .search:focus { border-color: rgba(94, 200, 255, 0.65); background-color: rgba(0, 0, 0, 0.55); box-shadow: 0 0 0 2px rgba(94, 200, 255, 0.18); } .search::-webkit-search-cancel-button { cursor: pointer; } .board { padding: 8px 14px 12px; width: 100%; flex: 1 1 auto; min-height: 0; overflow: auto; } /* Hero picker fills all space above the bottom-pinned detail; scrolls inside when the grid is taller than the region (small windows). */ #heroes-view { flex: 1 1 auto; min-height: 0; margin-bottom: 16px; overflow: auto; } /* Heroes-only (#detail hidden on items page): pin to bottom with a gap above the hero grid. Selected state uses one taller fixed height for all tabs so 技能 ↔ 核心装备 ↔ 被克装备 does not jump; long edge cases still scroll. */ .detail { --detail-fixed-h: min(620px, calc(100dvh - clamp(260px, 40vh, 400px) - 8.5rem)); display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; margin: auto 14px 12px; padding: 12px 16px; border: 1px solid var(--line); border-radius: 10px; background: rgba(8, 12, 20, 0.55); min-height: 0; overflow: hidden; box-sizing: border-box; } .detail:not(.empty) { height: var(--detail-fixed-h); min-height: var(--detail-fixed-h); max-height: var(--detail-fixed-h); } .detail:not(.empty) > * { width: 100%; max-width: none; } .detail.empty { height: auto; min-height: 64px; max-height: none; justify-content: center; color: var(--muted); font-size: 14px; letter-spacing: 0.04em; } .detail-head { display: flex; flex-direction: column; flex-wrap: nowrap; align-items: center; justify-content: center; flex: 0 0 auto; gap: 8px; margin-bottom: 12px; text-align: center; } .detail-name { font-size: 18px; font-weight: 650; letter-spacing: 0.04em; } .detail-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; } /* Skills / items tab bodies fill remaining #detail height under head+tabs. */ .detail-skills-layout, .detail-items-layout { flex: 1 1 auto; min-height: 0; width: 100%; overflow: hidden; } /* Skills tab: 血/蓝+三维 | 技能 | 攻击/防御/机动 */ .detail-skills-layout { display: flex; flex-direction: row; align-items: stretch; gap: 14px 16px; } .detail-items-layout { display: flex; flex-direction: column; } .detail-skills-stats { flex: 0 0 260px; width: 260px; min-width: 240px; max-width: 280px; min-height: 0; overflow: auto; scrollbar-width: thin; } .detail-skills-stats .hero-stats, .detail-skills-combat .hero-stats { margin: 0; height: 100%; box-sizing: border-box; } .detail-skills-main { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; } .detail-skills-main .hero-inspect { flex: 1 1 auto; height: auto; min-height: 0; max-height: none; /* Flex column so the skill panel fills the available height (set by .detail's fixed height) instead of growing past it and scrolling. */ display: flex; flex-direction: column; } .detail-skills-combat { flex: 0 0 340px; width: 340px; min-width: 280px; max-width: 380px; min-height: 0; overflow: auto; scrollbar-width: thin; } .detail-items-layout .detail-tab-body { flex: 0 0 auto; } .detail-items-layout .hero-inspect { flex: 1 1 auto; height: auto; min-height: 0; max-height: none; } /* Patches tab: scrollable per-version list of hero changes (past year). */ .detail-patches-layout { flex: 1 1 auto; min-height: 0; width: 100%; overflow: hidden; display: flex; flex-direction: column; } .detail-patches-layout .detail-tab-body { flex: 1 1 auto; min-height: 0; overflow: auto; scrollbar-width: thin; padding-right: 6px; } .patch-changes { display: flex; flex-direction: column; gap: 14px; padding: 2px 0 8px; width: 100%; max-width: 880px; margin: 0 auto; } .patch-change-version { border-left: 3px solid var(--line); padding: 0 0 4px 12px; } .patch-change-ver { font-size: 15px; font-weight: 700; color: var(--sel); margin-bottom: 4px; } .patch-change-date { font-size: 12px; font-weight: 400; color: var(--muted); margin-left: 8px; } @media (max-width: 900px) { .detail-skills-layout { flex-wrap: wrap; } .detail-skills-stats { flex: 1 1 240px; width: auto; max-width: none; } .detail-skills-main { flex: 1 1 100%; order: 3; } .detail-skills-combat { flex: 1 1 300px; width: auto; max-width: none; } } @media (max-width: 640px) { .detail-skills-layout { flex-direction: column; } .detail-skills-stats, .detail-skills-combat { flex: 0 0 auto; width: 100%; max-width: none; } .detail-skills-main { order: 0; } } .hero-stats { display: flex; flex-direction: column; align-items: stretch; gap: 14px; margin: 0 0 12px; padding: 14px; border: 1px solid var(--line); border-radius: 8px; background: rgba(6, 10, 16, 0.55); } .hero-stats-vitals { display: flex; flex-direction: column; gap: 8px; width: 100%; } .hero-stat-bar { position: relative; min-height: 28px; border-radius: 5px; font-size: 13px; font-variant-numeric: tabular-nums; line-height: 1.25; overflow: hidden; background: rgba(12, 18, 28, 0.72); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); } .hero-stat-bar-track { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; } .hero-stat-bar-fill { height: 100%; border-radius: inherit; transition: width 0.15s ease-out; } .hero-stat-bar.hp .hero-stat-bar-fill { background: linear-gradient(90deg, rgba(46, 140, 70, 0.92), rgba(28, 90, 48, 0.62)); box-shadow: inset 0 0 0 1px rgba(90, 200, 120, 0.28); } .hero-stat-bar.mana .hero-stat-bar-fill { background: linear-gradient(90deg, rgba(50, 100, 180, 0.95), rgba(30, 60, 120, 0.62)); box-shadow: inset 0 0 0 1px rgba(120, 170, 240, 0.3); } .hero-stat-bar-text { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 28px; padding: 5px 10px; } .hero-stat-bar-label { color: rgba(255, 255, 255, 0.78); letter-spacing: 0.06em; } .hero-stat-bar-val { font-weight: 650; color: #fff; } .hero-stat-bar-val small { margin-left: 8px; font-weight: 500; font-size: 12px; opacity: 0.88; } /* Vertical STR / AGI / INT stack (official bottom-bar spacing). */ .hero-stats-attrs { display: flex; flex-direction: column; align-items: stretch; gap: 10px; width: 100%; padding: 4px 2px 2px; } .hero-stat-attr { display: flex; align-items: center; gap: 12px; min-height: 36px; padding: 6px 10px; border-radius: 6px; border: 1px solid transparent; opacity: 0.78; font-variant-numeric: tabular-nums; } .hero-stat-attr.primary { opacity: 1; border-color: rgba(94, 200, 255, 0.45); background: rgba(94, 200, 255, 0.1); box-shadow: 0 0 10px rgba(94, 200, 255, 0.18); } .hero-stat-attr .attr-icon { width: 26px; height: 26px; flex: 0 0 auto; } .hero-stat-attr-base { font-size: 20px; font-weight: 700; line-height: 1; color: var(--text); min-width: 1.4em; } .hero-stat-attr-gain { margin-left: 6px; font-size: 13px; color: var(--muted); letter-spacing: 0.02em; } /* Right-rail combat panel: Attack | Defense | Mobility side by side. */ .hero-stats-combat-panel { display: flex; flex-direction: column; justify-content: flex-start; gap: 0; padding: 12px 10px 10px; overflow: auto; scrollbar-width: thin; } .hero-stats-combat { display: grid; grid-template-columns: repeat(var(--combat-cols, 3), minmax(0, 1fr)); gap: 0 10px; width: 100%; flex: 1 1 auto; min-height: 0; margin: 0; padding: 0; border: none; } .hero-stats-combat-section { display: flex; flex-direction: column; min-width: 0; min-height: 0; padding: 0 6px; } .hero-stats-combat-section + .hero-stats-combat-section { border-left: 1px solid rgba(140, 170, 210, 0.14); } .hero-stats-combat-title { margin: 0 0 8px; padding: 0 0 5px; border-bottom: 1px solid rgba(140, 170, 210, 0.16); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; color: var(--muted); text-align: center; } .hero-stats-combat-list { display: grid; grid-template-rows: repeat(var(--combat-rows, 3), minmax(0, 1fr)); flex: 1 1 auto; gap: 8px; margin: 0; } .hero-stat-row { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 0; padding: 0; font-variant-numeric: tabular-nums; line-height: 1.2; text-align: center; } .hero-stat-row dt { margin: 0; font-size: 11px; color: var(--muted); letter-spacing: 0.04em; } .hero-stat-row dd { margin: 0; font-size: 13px; font-weight: 650; color: var(--text); text-align: center; word-break: break-word; white-space: pre-line; } .hero-stat-row-sub { font-weight: 400; } .tag-chip { border: 1px solid rgba(94, 200, 255, 0.35); background: rgba(94, 200, 255, 0.1); color: var(--text); border-radius: 999px; padding: 3px 10px; font-size: 12px; } .detail-muted { color: var(--muted); font-size: 13px; } .detail-tabs { display: flex; justify-content: center; flex: 0 0 auto; gap: 0; margin: 0 0 12px; border-bottom: 1px solid var(--line); } .detail-tab { min-width: 96px; padding: 8px 16px; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; background: transparent; color: var(--muted); font: inherit; font-size: 14px; letter-spacing: 0.04em; cursor: pointer; } .detail-tab:hover { color: var(--text); } .detail-tab.active { color: var(--text); border-bottom-color: var(--sel); } .detail-tab-body { min-height: 48px; } .detail-tab-panel { padding-top: 2px; } .detail-abilities { display: flex; flex-direction: column; gap: 10px; } /* Inspect region under icon rows: fills leftover space inside the fixed #detail height. Tall recipe / skill text scrolls inside; empty state same box. */ .hero-inspect { margin-top: 12px; padding: 12px 4px 4px; border-top: 1px solid var(--line); box-sizing: border-box; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; } .hero-inspect.empty { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 14px; letter-spacing: 0.04em; } /* Keep long Chinese inspect prose readable while icon rows use full width. */ .hero-inspect .item-detail-top { max-width: 720px; margin-left: auto; margin-right: auto; } /* Skill detail: official-page split — demo clip left, name/desc right. */ .hero-inspect .skill-info-body { max-width: 1320px; margin-left: auto; margin-right: auto; } .hero-inspect .item-detail-large-icon { width: 96px; height: 72px; } .hero-inspect .skill-info-head { margin-bottom: 8px; text-align: left; } .hero-inspect .skill-info-desc { text-align: left; } .hero-inspect .item-detail-name-row { justify-content: center; } .hero-inspect .item-detail-head { justify-content: center; } .hero-inspect .item-detail-recipe .craft-label, .hero-inspect .item-detail-upgrades .craft-label { text-align: center; } .hero-inspect .craft-row { justify-content: center; } .skill-icons { display: flex; flex-wrap: nowrap; gap: 10px; align-items: center; justify-content: center; width: 100%; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; /* Headroom so the scaled-up selected icon is not clipped. */ padding: 7px; } .skill-icon { position: relative; width: 68px; height: 68px; padding: 0; border: 1px solid rgba(140, 170, 210, 0.28); border-radius: 6px; background: rgba(0, 0, 0, 0.35); cursor: pointer; overflow: hidden; flex: 0 0 auto; transition: transform 0.15s ease; } .skill-icon img { width: 100%; height: 100%; object-fit: cover; display: block; } .skill-icon img.missing { visibility: hidden; } /* Circular triggers: talent tree + innate (official dota2.com order). */ .skill-icon.talent-trigger, .skill-icon.innate { border-radius: 50%; border-color: rgba(180, 160, 100, 0.35); background: rgba(0, 0, 0, 0.5); overflow: hidden; } .skill-icon.talent-trigger img, .skill-icon.innate img { object-fit: contain; padding: 4px; } .skill-icon.talent-trigger[aria-expanded="true"], .skill-icon.innate.active { border-color: rgba(231, 210, 146, 0.85); box-shadow: 0 0 0 1px rgba(231, 210, 146, 0.45); } /* Selected = enlarged icon (dota2.com style), no outline. */ .skill-icon.active, .skill-icon.selected { transform: scale(1.14); z-index: 1; } .skill-icon.kind-shard { border-color: rgba(80, 160, 255, 0.55); } .skill-icon.kind-scepter { border-color: rgba(120, 200, 255, 0.55); } .skill-aghs-mark { position: absolute; right: 2px; bottom: 2px; font-size: 13px; line-height: 1; padding: 3px 4px; border-radius: 3px; background: rgba(60, 140, 230, 0.95); color: #fff; pointer-events: none; } .skill-icon.kind-scepter .skill-aghs-mark { background: rgba(90, 180, 230, 0.95); color: #0b1520; font-weight: 700; min-width: 1.1em; text-align: center; } .skill-info { min-width: 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; background: rgba(0, 0, 0, 0.28); } .skill-info-head { margin-bottom: 8px; } .skill-info-titles { min-width: 0; } .skill-info-name { font-size: 17px; font-weight: 700; letter-spacing: 0.04em; } .skill-info-label { margin-top: 3px; font-size: 13px; color: var(--syn); } .skill-info-label.shard { color: #6eb6ff; } .skill-info-label.scepter { color: #9fd4ff; } .skill-info-dispel { margin-top: 3px; font-size: 12px; color: var(--bad); } .skill-info-desc { font-size: 13px; line-height: 1.4; color: rgba(232, 238, 247, 0.88); white-space: pre-wrap; } .skill-info-body { display: flex; flex-wrap: wrap; gap: 18px 30px; align-items: flex-start; justify-content: center; /* Fill the hero-inspect column so the video's 16:9 intrinsic height can no longer push the row past the viewport and trigger a scrollbar. */ flex: 1 1 auto; min-height: 0; } .skill-info-main { flex: 1 1 340px; min-width: 0; /* Cap the detail column so it does not stretch edge-to-edge (leaving a big empty band) when no demo video is cached beside it. */ max-width: 760px; /* height:100% pins this column to the body's definite height (same trick as the video) — align-self:stretch alone fails to shrink a column whose content is taller than the row. overflow-y:auto then keeps any overflow inside the detail column so the video beside it never scrolls. */ height: 100%; min-height: 0; display: flex; flex-direction: column; overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; } /* height:100% resolves against the definite body height (set by the flex chain from .detail's fixed height), so the 16:9 intrinsic ratio can no longer push the player past the viewport — align-self:stretch alone can't shrink a replaced element below its intrinsic size. cover crops to fill. */ .skill-info-video { flex: 1 1 500px; max-width: 820px; min-width: 0; min-height: 0; height: 100%; max-height: 100%; object-fit: cover; border-radius: 6px; border: 1px solid rgba(255, 255, 255, 0.08); background: #000; } /* Params panel, dota2.com.cn style: a two-column "generic" grid of meta attributes + a flowing grid of special values. Filling the column with several short columns avoids the wide empty band a single stretched label/value list leaves on the right. */ .skill-params { margin-top: 10px; } .skill-generic { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 20px; row-gap: 4px; } .skill-specific { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: 4px 20px; margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(140, 170, 210, 0.14); } .skill-param { display: flex; align-items: baseline; min-width: 0; font-size: 13px; line-height: 1.45; } .skill-param-label { flex: 0 0 auto; letter-spacing: 0.04em; color: var(--muted); } .skill-param-value { margin-left: 4px; min-width: 0; color: #fff; font-weight: 600; } /* Cooldown / mana footer. Mana glyph is the official CSS gradient square; cooldown uses the downloaded dota2.com.cn cooldown.png. */ .skill-bottom { display: flex; align-items: center; gap: 26px; /* Sinks the cooldown/mana footer to the column bottom (aligning with the stretched video); padding-top keeps the minimum gap when there is no spare height to absorb. */ margin-top: auto; padding-top: 10px; } .skill-stat { display: inline-flex; align-items: center; gap: 8px; } .skill-stat-icon { width: 18px; height: 18px; border-radius: 3px; object-fit: cover; display: inline-block; } .skill-stat-icon.mana { background: linear-gradient(#00a4db, #007196); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18); } .skill-stat-text { color: #fff; font-size: 14px; font-weight: 600; letter-spacing: 0.02em; } .skill-stat.cooldown .skill-stat-text { color: rgba(232, 238, 247, 0.92); } .skill-info-lore { margin-top: 8px; padding-top: 6px; border-top: 1px solid rgba(140, 170, 210, 0.12); font-size: 12px; font-style: italic; color: rgba(232, 238, 247, 0.45); } /* Floating talent popover (fixed to viewport; anchored above tree icon). */ .talent-popover { position: fixed; z-index: 80; width: min(520px, calc(100vw - 24px)); padding: 14px 14px 18px; pointer-events: auto; border-radius: 8px; border: 1px solid rgba(140, 170, 210, 0.14); background: linear-gradient(150deg, rgba(88, 98, 110, 0.97), rgba(14, 18, 24, 0.99)); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5); } .talent-popover .talent-tree { display: flex; flex-direction: column; gap: 8px; } .talent-tree-label { margin: 0; color: #fff; font-size: 15px; font-weight: 600; letter-spacing: 0.2em; text-align: center; } .talent-rows { display: flex; flex-direction: column; gap: 7px; } .talent-row { display: flex; align-items: center; justify-content: center; gap: 10px; min-height: 40px; padding: 0 12px; background: linear-gradient(150deg, rgb(52, 58, 64), rgb(10, 12, 14)); } .talent-cell { flex: 1 1 0; min-width: 0; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 6px 4px; border: none; border-radius: 0; background: transparent; color: rgba(255, 255, 255, 0.78); font-size: 12px; line-height: 1.3; text-align: center; } .talent-level { flex: 0 0 auto; width: 40px; height: 40px; padding: 3px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: linear-gradient(325deg, rgb(60, 66, 71), rgb(10, 12, 14)); } .talent-level-num { width: 100%; height: 100%; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: #222; color: #e7d292; font-size: 14px; font-weight: 700; text-shadow: 0 0 8px rgb(255, 83, 28); } /* Downward caret: outer triangle = panel border; ::after fill = panel charcoal (not #000). */ .talent-popover .talent-tree-beak { --talent-beak-fill: rgb(36, 42, 50); --talent-beak-line: rgba(140, 170, 210, 0.22); position: absolute; left: 50%; bottom: -9px; width: 0; height: 0; transform: translateX(-50%); border: 0; border-left: 9px solid transparent; border-right: 9px solid transparent; border-top: 9px solid var(--talent-beak-line); background: transparent; border-radius: 0; pointer-events: none; } .talent-popover .talent-tree-beak::after { content: ""; position: absolute; left: -8px; top: -9px; width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 8px solid var(--talent-beak-fill); } .talent-popover.below .talent-tree-beak { --talent-beak-fill: rgb(56, 64, 74); top: -9px; bottom: auto; border-top: 0; border-bottom: 9px solid var(--talent-beak-line); } .talent-popover.below .talent-tree-beak::after { top: auto; bottom: -9px; border-top: 0; border-bottom: 8px solid var(--talent-beak-fill); } .detail-items { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; min-width: 0; } .item-list { display: flex; flex-wrap: nowrap; gap: 8px; align-items: center; justify-content: center; width: 100%; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; /* Headroom so the scaled-up selected item is not clipped. */ padding: 6px; } .item { position: relative; display: inline-flex; width: 72px; height: 54px; padding: 0; border-radius: 4px; overflow: hidden; background: rgba(0, 0, 0, 0.35); border: 1px solid rgba(140, 170, 210, 0.22); flex: 0 0 auto; cursor: pointer; transition: transform 0.15s ease; } .item:hover:not(:disabled) { border-color: rgba(232, 200, 120, 0.95); } /* Selected = enlarged icon (dota2.com style), no outline. */ .item.selected { transform: scale(1.12); z-index: 1; } .item:disabled { cursor: default; } .item img { width: 100%; height: 100%; object-fit: contain; display: block; } /* In-client draft: str/agi/int 6 cols, universal 4 cols. */ .columns { display: grid; grid-template-columns: 6fr 6fr 6fr 4fr; gap: 22px; align-items: start; width: 100%; } .col { min-width: 0; } .col-head { display: flex; align-items: center; gap: 8px; margin: 0 0 8px 2px; font-size: 15px; font-weight: 600; letter-spacing: 0.08em; } .attr-icon { width: 22px; height: 22px; object-fit: contain; display: block; flex: 0 0 auto; } .grid { display: grid; gap: 2px; align-content: start; } .hero { position: relative; width: 100%; aspect-ratio: 16 / 9; border: none; border-radius: 0; overflow: hidden; cursor: pointer; background: #0a0e14; padding: 0; } .hero img { width: 100%; height: 100%; object-fit: contain; object-position: center center; display: block; filter: saturate(1.02) contrast(1.04); transition: transform 0.15s ease, filter 0.15s ease, opacity 0.15s ease; } .hero:hover img { transform: scale(1.06); } .hero.selected { outline: 2px solid var(--sel); outline-offset: 1px; z-index: 3; } .hero.dim img { filter: grayscale(0.55) brightness(0.38); opacity: 0.72; } .hero.related { z-index: 2; } .hero.related.is-counter { box-shadow: inset 0 0 0 2px rgba(61, 206, 122, 0.85); } .hero.related.is-countered { box-shadow: inset 0 0 0 2px rgba(224, 122, 47, 0.9); } .hero.related.is-synergy { box-shadow: inset 0 0 0 2px rgba(126, 200, 255, 0.9); } .hero.related.is-counter.is-countered, .hero.related.is-counter.is-synergy, .hero.related.is-countered.is-synergy { box-shadow: inset 0 0 0 2px rgba(61, 206, 122, 0.75), 0 0 0 2px rgba(224, 122, 47, 0.55); } .marks { position: absolute; left: 3px; top: 3px; display: flex; gap: 3px; pointer-events: none; z-index: 2; } .marks span { display: inline-flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; line-height: 1; text-shadow: 0 0 2px rgba(0, 0, 0, 0.9), 0 1px 1px rgba(0, 0, 0, 0.7); } /* 克制 */ .marks .m-counter { color: var(--good); } /* 被克制 */ .marks .m-countered { color: var(--bad); } /* 搭档 */ .marks .m-synergy { color: var(--syn); } /* 选中:青色勾选徽标 */ .marks .m-sel { width: 18px; height: 18px; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55); background-color: rgba(94, 200, 255, 0.95); background-repeat: no-repeat; background-position: center; background-size: 12px 12px; background-image: url("data:image/svg+xml;utf8,"); } @media (max-width: 1200px) { .columns { gap: 14px; } } @media (max-width: 900px) { .columns { grid-template-columns: 1fr 1fr; gap: 14px; } } /* —— Items shop page —— */ .item-tools { display: flex; align-items: center; justify-content: flex-end; width: 100%; gap: 10px; } .search-inline { position: static; transform: none; width: 220px; } /* Items page: pin body to the viewport so #items-view (not ) scrolls. Otherwise sticky detail sticks to the window and paints over shop columns. */ body:has(#items-view:not(.hidden)) { height: 100dvh; max-height: 100dvh; overflow: hidden; } /* Shop + detail as a centered cluster; detail sticks while shop scrolls. */ .items-board { display: block; position: relative; flex: 1 1 auto; min-height: 0; padding: 12px 16px 24px; overflow: auto; } .items-cluster { display: grid; grid-template-columns: max-content 320px; align-items: start; column-gap: 16px; width: max-content; margin: 0 auto; } .items-main { width: max-content; display: flex; flex-direction: column; gap: 10px; min-width: 0; grid-column: 1; } .item-detail-box { grid-column: 2; position: sticky; top: 12px; align-self: start; z-index: 1; width: 320px; height: fit-content; /* Cap to the items-board scrollport while sticky. */ max-height: calc(100dvh - 9rem); overflow: auto; padding: 14px 14px 16px; border: 1px solid var(--line); border-radius: 10px; background: rgba(8, 12, 20, 0.92); } .item-detail-box.empty { display: flex; align-items: center; justify-content: center; min-height: 0; padding: 16px 14px; color: var(--muted); font-size: 14px; letter-spacing: 0.04em; text-align: center; } .item-detail-top { display: flex; flex-direction: column; gap: 12px; } .item-detail-name-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; } .item-detail-name { font-size: 18px; font-weight: 650; letter-spacing: 0.04em; } .item-detail-head { display: flex; gap: 12px; align-items: flex-start; } .item-detail-large-icon { width: 88px; height: 66px; object-fit: contain; border: 1px solid rgba(200, 160, 70, 0.55); border-radius: 4px; background: rgba(0, 0, 0, 0.35); flex: 0 0 auto; } .item-detail-info { min-width: 0; flex: 1 1 auto; } .item-detail-recipe, .item-detail-upgrades { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line); } .item-detail-recipe .craft-label, .item-detail-upgrades .craft-label { display: block; margin: 0 0 8px; } .shop-col-headers { width: 100%; display: grid; grid-template-columns: 5fr 6fr; gap: 12px; padding: 0 4px; color: #d9d9d9; font-size: 15px; letter-spacing: 0.08em; } .shop-col-header.upgraded { padding-left: 8px; } .item-shop { width: 100%; } .item-shop.empty { color: var(--muted); text-align: center; padding: 40px 12px; } .item-shop.layout-cn { display: flex; justify-content: center; align-items: flex-start; gap: 18px; overflow-x: auto; /* Headroom so scaled-up selected items are not clipped. */ padding: 6px 6px 8px; } .shop-group { display: flex; align-items: flex-start; gap: 4px; } .shop-column { width: 70px; flex: 0 0 70px; display: flex; flex-direction: column; align-items: center; gap: 0; } .shop-column-cat { width: 49px; height: 49px; object-fit: contain; margin-bottom: 6px; } .shop-column-label { margin: 0 0 8px; min-height: 28px; color: #c0c0c0; font-size: 13px; font-weight: 500; text-align: center; line-height: 1.2; } .shop-item { position: relative; width: 70px; height: 53px; margin: 0 0 5px; padding: 0; border: 1px solid rgba(200, 160, 70, 0.45); border-radius: 2px; background: #000; cursor: pointer; overflow: hidden; transition: transform 0.15s ease; } .shop-item img { width: 100%; height: 100%; object-fit: contain; display: block; } .shop-item:hover { border-color: rgba(232, 200, 120, 0.95); } /* Selected = enlarged icon (dota2.com style), no outline. */ .shop-item.selected { transform: scale(1.1); z-index: 1; } .shop-charges { position: absolute; right: 2px; bottom: 1px; font-size: 11px; font-weight: 700; color: #fff; text-shadow: 0 0 2px #000, 0 1px 2px #000; pointer-events: none; } .detail-item-cost { color: #e8c878; font-size: 15px; font-weight: 650; letter-spacing: 0.04em; } .craft-label { color: var(--muted); font-size: 12px; letter-spacing: 0.1em; } .craft-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } .craft-chip { position: relative; width: 52px; height: 39px; padding: 0; border: 1px solid rgba(200, 160, 70, 0.55); border-radius: 3px; background: rgba(0, 0, 0, 0.4); cursor: pointer; overflow: hidden; } .craft-chip:hover:not(:disabled) { border-color: rgba(232, 200, 120, 0.95); } .craft-chip:disabled { cursor: default; opacity: 1; } .craft-chip.is-recipe { border-color: rgba(160, 170, 190, 0.55); } .craft-chip img { width: 100%; height: 100%; object-fit: contain; display: block; } .craft-recipe-cost { position: absolute; left: 0; right: 0; bottom: 0; font-size: 10px; font-weight: 700; color: #e8c878; text-align: center; background: rgba(0, 0, 0, 0.65); text-shadow: 0 0 2px #000; pointer-events: none; } .craft-upgrades .craft-chip { width: 48px; height: 36px; } @media (max-width: 1100px) { .items-cluster { grid-template-columns: 1fr; width: min(920px, 100%); row-gap: 12px; } .items-main { width: min(920px, 100%); grid-column: 1; grid-row: 2; } .item-detail-box { grid-column: 1; grid-row: 1; top: 8px; width: min(920px, 100%); max-height: min(42vh, 360px); margin: 0 auto; z-index: 1; } } @media (max-width: 720px) { .item-tools { justify-content: center; } .shop-col-headers { grid-template-columns: 1fr; } } .patches-board { display: flex; flex-direction: column; align-items: center; overflow-y: auto; } .patches-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: min(820px, 92%); padding: 26px 0 10px; } .patches-title { margin: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; } .patches-kicker { font-size: 15px; font-weight: 600; color: var(--muted); letter-spacing: 0.14em; } .patches-ver { font-size: 40px; font-weight: 800; color: var(--text); letter-spacing: 0.02em; line-height: 1; } #patch-select { flex: 0 1 auto; max-width: 360px; padding: 9px 14px; border-radius: 6px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 14px; font-family: var(--font); cursor: pointer; } #patch-select:focus-visible { outline: 2px solid var(--sel); outline-offset: 1px; } .patches-detail { width: min(820px, 92%); padding: 6px 0 64px; } .patches-empty { padding: 48px 0; text-align: center; color: var(--muted); font-size: 14px; } .patch-section { margin-top: 26px; } .patch-section-title { margin: 0 0 14px; padding-bottom: 7px; font-size: 18px; font-weight: 700; color: var(--sel); border-bottom: 1px solid var(--line); letter-spacing: 0.03em; } .patch-sub-title { margin: 16px 0 8px; font-size: 15px; font-weight: 600; color: var(--syn); } .patch-general { margin-bottom: 8px; } .patch-entry-row, .patch-ability { display: flex; align-items: flex-start; gap: 14px; padding: 10px 4px; } .patch-entry-body { flex: 1 1 auto; min-width: 0; } .patch-item-icon, .patch-ability-icon { flex: 0 0 auto; border-radius: 6px; object-fit: contain; border: 1px solid var(--line); } .patch-item-icon { /* Match Steam CDN item icon aspect (88x64) so contain fills with no bands. */ width: 66px; height: 48px; } .patch-ability-icon { width: 48px; height: 48px; margin-top: 2px; } .patch-name { display: block; margin-bottom: 4px; font-size: 15px; font-weight: 600; color: var(--text); } .patch-ability .patch-name { font-weight: 500; } .patch-hero { padding: 14px 16px; margin-bottom: 12px; border-radius: 8px; background: rgba(94, 200, 255, 0.04); border: 1px solid var(--line); } .patch-hero-head { display: flex; align-items: center; gap: 14px; margin-bottom: 8px; } .patch-hero-icon { width: 112px; aspect-ratio: 16 / 9; flex: 0 0 auto; border-radius: 6px; object-fit: contain; object-position: center center; background: #0a0e14; border: 1px solid var(--line); filter: saturate(1.02) contrast(1.04); } .patch-hero-head .patch-name { margin-bottom: 0; font-size: 17px; } .patch-notes { list-style: none; margin: 4px 0; padding: 0; } .patch-notes li { position: relative; padding-left: 18px; font-size: 14px; line-height: 1.6; color: var(--text); } .patch-notes li::before { content: "•"; position: absolute; left: 2px; color: var(--muted); } .patch-notes li.hide-dot, .patch-notes li.patch-spacer { padding-left: 0; } .patch-notes li.hide-dot::before, .patch-notes li.patch-spacer::before { content: ""; } .patch-notes li.patch-spacer { height: 6px; } .patch-hero-notes { margin: 2px 0 8px; } .stat-chip { display: inline-block; margin-right: 6px; padding: 1px 7px; border-radius: 3px; font-size: 11.5px; background: rgba(126, 200, 255, 0.14); color: var(--syn); vertical-align: 1px; } .stat-icon { width: 18px; height: 18px; margin-right: 6px; vertical-align: -4px; object-fit: contain; }