/* DEEPMINE UI v4 — talents page styles (panel data-mode="talents").
   Markup: mobile.mjs renderTalentPanel / renderTalentNode / renderTalentDrawer; glyphs: ui/talent-icons.mjs.
   Contract: the first <span> of every .skill-node is the medallion (.tn-med); drawTalentLinks anchors on it.
   Shared components: branch tabs = .seg.seg--tabs, family filters = .seg.seg--pills (scrolling row),
   section titles = .section-head, drawer close = .btn.btn--ghost.btn--sm.btn--icon.
   The tree is rebuilt from strings on polls, so nothing here animates in. The level ring is one element
   painted with conic gradients (no SVG, no filter). The only loop is the "ready" pulse: three runs that
   mobile.mjs keeps in phase across re-renders with --tn-phase and drops (.is-pulsing) once it has ended. */
@layer pages {
  #sheet[data-mode="talents"] {
    --tn-med: 64px;
    --tn-gold: var(--gold-300);
    --tn-jade: var(--jade-300);
    --tn-plate: rgb(7 22 16 / .86);
    /* Medallion face: painted art sits on this disc (tree, drawer rows, family pills). */
    --tn-face-bg: radial-gradient(circle at 50% 30%, #2f6b51, #133528 72%);
    /* Ring segment gaps are painted in the colour of what lies behind the medallion. */
    --tn-gap-c: rgb(6 19 14);
  }
  #sheet[data-mode="talents"] #sheet-body { padding-top: 10px; }

  /* ───────────── Branch tabs (.seg.seg--tabs) ───────────── */
  /* The component stacks glyph over label and draws the selected underline; the page adds the
     learned count beside the name and the "ready" badge on the glyph. */
  .talent-branches > button { position: relative; gap: 3px; }
  .talent-branches .tb-copy {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-height: 1.2;
    overflow-wrap: break-word;
  }
  .talent-branches .tb-name { font-weight: 800; }
  .talent-branches .tb-copy small {
    margin-left: 4px;
    font: 700 var(--fs-11)/1 var(--font-display);
    color: var(--text-3);
    white-space: nowrap;
  }
  .talent-branches > button.active .tb-copy small { color: var(--jade-200); }
  .talent-branches .badge { position: absolute; top: 3px; left: calc(50% + 5px); z-index: 1; }
  /* Latin/Cyrillic names: the count is an atomic box, so it wraps under the name as a whole instead of gluing to the
     last word and clipping; a third line is allowed before the clamp hides the count. */
  :root:not(:lang(zh)) .talent-branches .tb-copy { -webkit-line-clamp: 3; hyphens: auto; -webkit-hyphens: auto; }
  :root:not(:lang(zh)) .talent-branches .tb-copy small { display: inline-block; }

  /* ───────────── Family filters (.seg.seg--pills.seg--scroll) ───────────── */
  /* Portrait pills in one row. They grow to share the width but never shrink below their label, so a
     longer (e.g. English) label makes the row scroll sideways, edge to edge, instead of clipping. */
  .talent-families {
    flex-wrap: nowrap;
    gap: 4px;
    margin: var(--s-3) calc(var(--gutter) * -1) 0;
    padding: 2px var(--gutter) 4px;
    scroll-padding-inline: var(--gutter);
  }
  .talent-families > button {
    position: relative;
    flex: 1 1 0;
    flex-direction: column;
    gap: 3px;
    min-width: 44px;
    min-height: 66px;
    padding: 6px 5px;
    overflow: visible;
    font-size: var(--fs-12);
    font-weight: 800;
    transition: color var(--dur-2), background var(--dur-2), border-color var(--dur-2), transform var(--dur-1);
  }
  /* Latin/Cyrillic labels ("Kleiner Spaten", "Vue globale") are wider than an equal share: min-width:auto keeps each
     pill at least as wide as its (unwrapped) label, so the row scrolls instead of the labels overlapping. */
  :root:not(:lang(zh)) .talent-families > button { min-width: auto; }
  .talent-families > button:active { transform: translateY(1px); }
  .talent-families .tf-ava {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    flex: none;
    border-radius: 50%;
    overflow: hidden;
    background: var(--tn-face-bg);
    border: 1px solid var(--line-2);
    box-shadow: inset 0 -4px 8px rgb(0 0 0 / .35);
  }
  .talent-families .tf-ava img { width: 84%; height: 84%; object-fit: contain; }
  .talent-families .tf-ava .tn-art:is(.tn-art--miner, .tn-art--mole, .tn-art--golem) { width: 132%; height: 132%; max-width: none; margin-top: 38%; object-position: 50% 0; }
  .talent-families .tf-ava .gi { width: 24px; height: 24px; }
  .talent-families .tf-name { line-height: 1.2; white-space: nowrap; }
  .talent-families > button.active .tf-ava { border-color: rgb(79 50 13 / .55); box-shadow: 0 0 0 2px rgb(255 247 223 / .35), inset 0 -4px 8px rgb(0 0 0 / .35); }
  .talent-families .tf-dot {
    position: absolute;
    top: 5px;
    left: calc(50% + 10px);
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #ffb3a1, var(--danger-strong) 60%);
    box-shadow: 0 0 0 2px var(--surface-1);
  }

  /* ───────────── Growth summary (.section-head) ───────────── */
  .talent-progress { flex-wrap: wrap; row-gap: 4px; }
  .talent-progress > .meter { flex: 1 1 48px; min-width: 48px; height: 6px; align-self: center; }
  .talent-progress > small { flex: 0 1 auto; }
  .talent-progress > small b { font-size: var(--fs-14); font-weight: 800; color: var(--jade-200); white-space: nowrap; }

  /* ───────────── The tree board ───────────── */
  .talent-node-grid {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 26px 6px;
    padding: 18px 4px 20px;
    border-radius: var(--r-lg);
    background:
      radial-gradient(80% 40% at 50% 0%, rgb(245 200 105 / .08), transparent 70%),
      radial-gradient(circle, rgb(206 228 196 / .07) 1px, transparent 1.4px) 0 0 / 18px 18px,
      linear-gradient(180deg, rgb(3 13 9 / .55), rgb(3 13 9 / .22));
    box-shadow: inset 0 0 0 1px var(--line-1), inset 0 14px 30px -18px rgb(0 0 0 / .8);
  }
  #talent-links { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
  #talent-links path { fill: none; stroke: rgb(206 228 196 / .24); stroke-width: 2; stroke-dasharray: 3 6; stroke-linecap: round; }
  #talent-links path.met { stroke: var(--gold-300); stroke-width: 2.6; stroke-dasharray: none; }
  #talent-links path.halo { stroke: rgb(245 200 105 / .2); stroke-width: 9; stroke-dasharray: none; }
  #talent-links path.focus:not(.met, .halo) { stroke: rgb(255 203 107 / .8); stroke-width: 2.4; }
  #talent-links path.met.focus { stroke: var(--gold-100); stroke-width: 3; }
  #talent-links path.halo.focus { stroke: rgb(255 224 150 / .32); stroke-width: 12; }

  /* ───────────── Node ───────────── */
  .skill-node {
    position: relative;
    z-index: 1;
    isolation: isolate;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-content: flex-start;
    align-items: center;
    gap: 3px 4px;
    align-self: start;
    min-width: 0;
    padding: 0 2px 7px;
    color: var(--text-1);
    text-align: center;
  }
  /* Name plate: sits under the label and hides the links that pass behind it. */
  .skill-node::before {
    content: '';
    position: absolute;
    z-index: -1;
    left: 6px;
    right: 6px;
    top: calc(var(--tn-med) - 2px);
    bottom: 0;
    border-radius: var(--r-sm);
    background: var(--tn-plate);
    border: 1px solid var(--line-1);
    box-shadow: 0 4px 10px -6px rgb(0 0 0 / .8);
    transition: border-color var(--dur-2), box-shadow var(--dur-2);
  }
  /* The side margins make the medallion fill its own flex line, centred. */
  .skill-node > .tn-med { margin: 0 calc((100% - var(--tn-med)) / 2) 5px; }
  .skill-node > strong {
    flex: 0 0 100%;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    padding: 0 4px;
    font-size: var(--fs-13);
    font-weight: 800;
    line-height: 1.25;
    overflow-wrap: break-word;
  }
  /* Latin/Cyrillic node names run two to three times longer than the Chinese: three lines before the clamp. */
  :root:not(:lang(zh)) .skill-node > strong { -webkit-line-clamp: 3; padding-inline: 2px; hyphens: auto; -webkit-hyphens: auto; }
  .skill-node > small { flex: 0 0 auto; font: 700 var(--fs-11)/1 var(--font-display); color: var(--text-3); white-space: nowrap; }
  .skill-node > em.tn-cost {
    display: inline-flex;
    align-items: center;
    flex: 0 1 auto;
    gap: 2px;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 19px;
    padding: 0 6px 0 3px;
    border-radius: var(--r-pill);
    font: 700 var(--fs-11)/1 var(--font-display);
    font-style: normal;
    color: var(--text-2);
    background: rgb(255 255 255 / .06);
    border: 1px solid var(--line-1);
    white-space: nowrap;
  }
  .skill-node > em.tn-cost .currency-icon { width: 13px; height: 13px; }
  .skill-node:is(.is-max, .is-retired) > em.tn-cost { padding: 0 7px; font-family: var(--font-ui); }
  .skill-node.is-retired > small { flex-basis: 100%; }

  /* Medallion: segmented level ring + painted face + corner badges. Nothing in it is filtered. */
  .tn-med { position: relative; display: block; flex: none; width: var(--tn-med); height: var(--tn-med); border-radius: 50%; transition: transform var(--dur-2) var(--ease-spring); }
  .tn-ring {
    --tn-on: var(--tn-jade);
    --tn-next: var(--tn-gold);
    --tn-off: rgb(206 228 196 / .14);
    --tn-seg: calc(1turn / var(--tn-max, 1));
    --tn-gap: calc(min(1, var(--tn-max, 1) - 1) * 9deg);
    --tn-soft: calc(min(1, var(--tn-max, 1) - 1) * .8deg);
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background:
      repeating-conic-gradient(from calc(var(--tn-gap) / -2), var(--tn-gap-c) 0 var(--tn-gap), transparent calc(var(--tn-gap) + var(--tn-soft)) calc(var(--tn-seg) - var(--tn-soft)), var(--tn-gap-c) var(--tn-seg)),
      conic-gradient(var(--tn-on) 0 calc(var(--tn-seg) * var(--tn-lv, 0)), var(--tn-next) 0 calc(var(--tn-seg) * (var(--tn-lv, 0) + var(--tn-nx, 0))), var(--tn-off) 0);
  }
  .tn-face {
    position: absolute;
    inset: calc(var(--tn-med) * .094);
    display: grid;
    place-items: center;
    overflow: hidden;
    border-radius: 50%;
    background: var(--tn-face-bg);
    box-shadow: inset 0 2px 0 rgb(255 255 255 / .14), inset 0 -7px 12px rgb(0 0 0 / .45), 0 0 0 1.5px rgb(0 0 0 / .55);
  }
  /* State veil over the art (locked / retired) and the level-up flash: overlays, not filters. */
  .tn-face::after { content: none; position: absolute; inset: 0; border-radius: 50%; pointer-events: none; }
  .tn-art { width: 80%; height: 80%; object-fit: contain; }
  .tn-art:is(.tn-art--miner, .tn-art--mole, .tn-art--golem) { width: 128%; height: 128%; max-width: none; margin-top: 34%; object-position: 50% 0; }
  .tn-art--painted { width: 86%; height: 86%; }
  .tn-face > .gi { width: 62%; height: 62%; }
  .tn-fx, .tn-flag {
    position: absolute;
    z-index: 1;
    display: grid;
    place-items: center;
    --tn-badge: max(17px, calc(var(--tn-med) * .34));
    width: var(--tn-badge);
    height: var(--tn-badge);
    border-radius: 50%;
    border: 1.5px solid var(--bg-0);
    box-shadow: 0 2px 4px rgb(0 0 0 / .55), inset 0 1px 0 rgb(255 255 255 / .3);
  }
  .tn-fx { right: -3px; bottom: -1px; --fx: #e8853a; background: radial-gradient(circle at 40% 30%, color-mix(in srgb, var(--fx) 70%, white), var(--fx) 65%); }
  .tn-fx .gi { width: 68%; height: 68%; }
  .tn-fx img { width: 82%; height: 82%; object-fit: contain; }
  .tn-fx--cycle { --fx: #3f98dc; }
  .tn-fx--critical { --fx: #d84c6a; }
  .tn-fx--capacity { --fx: #2c9c6a; }
  .tn-flag { top: -3px; right: -3px; background: var(--surface-inset); }
  .tn-flag .gi { width: 68%; height: 68%; }

  /* Medallion states live on .tn-med.is-* so the tree node and the drawer header match. */
  /* Ready (can buy now): gold face ring and a gold next segment (static). */
  .tn-med.is-avail .tn-face { box-shadow: inset 0 2px 0 rgb(255 255 255 / .16), inset 0 -7px 12px rgb(0 0 0 / .4), 0 0 0 2px var(--tn-gold), 0 0 14px -2px rgb(245 200 105 / .7); }
  .tn-med.is-avail .tn-flag { background: radial-gradient(circle at 40% 30%, #8ef0bf, var(--jade-500) 70%); }
  .tn-med.is-avail .tn-flag .gi { --gi-glow: #f4fff9; }
  /* Call to action: a gold ring breathes outward three times when a node becomes ready (finite;
     transform + opacity only; mobile.mjs adds .is-pulsing only while the runs last). */
  .skill-node.is-pulsing .tn-med::after {
    content: '';
    position: absolute;
    inset: 1px;
    border-radius: 50%;
    border: 2px solid var(--gold-200);
    box-shadow: 0 0 12px rgb(245 200 105 / .55);
    opacity: 0;
    pointer-events: none;
    will-change: transform, opacity;
    animation: tn-pulse 2.4s var(--ease-out) var(--tn-phase, 0s) 3;
  }
  /* Locked: dark veil over the art, dim ring, grey effect badge, lock flag. */
  .tn-med.is-locked .tn-ring { --tn-off: rgb(206 228 196 / .08); }
  .tn-med.is-locked .tn-face::after { content: ''; background: radial-gradient(circle at 50% 40%, rgb(38 46 43 / .64), rgb(6 16 12 / .82) 75%); }
  .tn-med.is-locked .tn-fx { --fx: #66756e; }
  .tn-med.is-locked .tn-flag .gi { --gi-base: #b8c4bd; --gi-metal-shade: #6f7d77; }
  /* Maxed: full gold ring with a warm glow, star flag. */
  .tn-med.is-max .tn-ring { --tn-on: var(--tn-gold); box-shadow: 0 0 9px -1px rgb(245 200 105 / .7); }
  .tn-med.is-max .tn-face { background: radial-gradient(circle at 50% 30%, #4f7a4a, #1d3f2c 72%); }
  .tn-med.is-max .tn-flag { --tn-badge: max(18px, calc(var(--tn-med) * .37)); top: -5px; right: -5px; background: radial-gradient(circle at 40% 30%, #fff3c4, var(--gold-400) 70%); }
  .tn-med.is-max .tn-flag .gi { width: 72%; height: 72%; --gi-base: var(--gold-50); --gi-light: #fff; }
  /* Retired: muted and out of play; the label says why. */
  .tn-med.is-retired .tn-ring { --tn-on: rgb(206 228 196 / .1); --tn-off: rgb(206 228 196 / .1); }
  .tn-med.is-retired .tn-face::after { content: ''; background: rgb(6 16 12 / .66); }
  .tn-med.is-retired .tn-fx { display: none; }

  /* Node labels per state. */
  .skill-node.is-avail::before { border-color: rgb(245 200 105 / .4); }
  .skill-node.is-avail > em.tn-cost {
    color: var(--text-on-gold);
    background: var(--grad-gold);
    border-color: var(--gold-rim) #e7ad48 #b7751e;
    box-shadow: 0 1px 0 var(--gold-edge), 0 0 10px -2px rgb(245 200 105 / .6);
  }
  .skill-node.is-short > em.tn-cost { color: var(--warn); background: transparent; border-color: rgb(255 196 92 / .45); border-style: dashed; }
  .skill-node.is-locked > :is(strong, small) { color: var(--text-3); }
  .skill-node.is-locked > em.tn-cost { color: var(--text-3); background: transparent; }
  .skill-node.has-level > small { color: var(--jade-200); }
  .skill-node.is-max > small { color: var(--gold-200); }
  .skill-node.is-max > em.tn-cost { color: var(--gold-100); background: linear-gradient(180deg, rgb(245 200 105 / .22), rgb(245 200 105 / .1)); border-color: rgb(245 200 105 / .4); }
  .skill-node.is-max::before { border-color: rgb(245 200 105 / .28); }
  .skill-node.is-retired > :is(strong, small) { color: var(--text-3); }
  .skill-node.is-retired > em.tn-cost { color: var(--text-3); background: transparent; }
  .skill-node.is-retired::before { border-style: dashed; background: rgb(7 22 16 / .7); }

  /* Selected — lifted, haloed, jade plate. */
  .skill-node.selected .tn-med { transform: scale(1.08); }
  .skill-node.selected .tn-med::before {
    content: '';
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 2px solid var(--gold-100);
    box-shadow: 0 0 0 4px rgb(245 200 105 / .18), 0 0 26px 2px rgb(245 200 105 / .55);
    pointer-events: none;
  }
  .skill-node.selected::before { border-color: var(--line-gold-strong); background: var(--grad-jade-plate); box-shadow: 0 0 0 1px rgb(245 200 105 / .25), 0 8px 18px -8px rgb(0 0 0 / .9); }
  .skill-node.selected > strong { color: var(--gold-50); }
  /* The jade plate is lighter than the dark name plate: captions step up from --text-3 to --text-2. */
  .skill-node.selected:not(.has-level, .is-max) > small,
  .skill-node.selected:is(.is-locked, .is-retired) > em.tn-cost { color: var(--text-2); }
  .skill-node:active .tn-med { transform: scale(.95); }
  /* Keyboard focus: an ivory ring outside the selection halo, on the unfiltered medallion. */
  .skill-node:focus-visible { outline: none; }
  .skill-node:focus-visible .tn-med { outline: 3px solid var(--gold-50); outline-offset: 7px; border-radius: 50%; }

  .talent-idle-hint { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 14px 8px 0; font-size: var(--fs-12); line-height: 1.45; color: var(--text-3); text-align: center; }
  .talent-idle-hint .icon { width: 15px; height: 15px; color: var(--gold-300); }

  @keyframes tn-pulse {
    0% { transform: scale(.94); opacity: .95; }
    70% { transform: scale(1.3); opacity: 0; }
    100% { transform: scale(1.3); opacity: 0; }
  }

  /* Level-up: a one-off pop and flash on the node that just rose (state change, not an entrance). */
  .skill-node.is-bumped .tn-med { animation: tn-bump 800ms var(--ease-spring) backwards; animation-delay: var(--tn-bump, 0s); }
  .skill-node.is-bumped .tn-face::before {
    content: '';
    position: absolute;
    z-index: 1;
    inset: 0;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 40%, rgb(255 247 223 / .9), rgb(255 234 179 / .35) 70%);
    opacity: 0;
    pointer-events: none;
    animation: tn-flash 800ms var(--ease-out);
    animation-delay: var(--tn-bump, 0s);
  }
  @keyframes tn-bump { 0% { scale: .82; } 45% { scale: 1.16; } 100% { scale: 1; } }
  @keyframes tn-flash { 0% { opacity: 1; } 100% { opacity: 0; } }

  /* Motion off (in-game toggle / OS preference) and low quality: no pulse, no pop, no slide. */
  html:is(.reduce-motion, .low-quality) .skill-node .tn-med::after { content: none; animation: none; }
  html:is(.reduce-motion, .low-quality) .skill-node.is-bumped .tn-med,
  html:is(.reduce-motion, .low-quality) .skill-node.is-bumped .tn-face::before { animation: none; }
  html:is(.reduce-motion, .low-quality) #sheet[data-mode="talents"] > #sheet-footer { animation: none; }

  /* ───────────── Detail drawer (#sheet-footer) ───────────── */
  #sheet[data-mode="talents"] > #sheet-footer {
    --td-bg: var(--surface-1);
    --tn-gap-c: var(--surface-2);
    display: flex;
    flex-direction: column;
    max-height: min(60%, 460px);
    margin-top: -12px;
    padding: 0;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-top: 1px solid var(--line-gold-strong);
    background: var(--td-bg);
    box-shadow: 0 -16px 30px -12px rgb(0 0 0 / .85), inset 0 1px 0 rgb(255 255 255 / .08);
    animation: tn-drawer var(--dur-3) var(--ease-out);
  }
  @keyframes tn-drawer { from { transform: translateY(26px); opacity: .4; } to { transform: none; opacity: 1; } }
  #sheet[data-mode="talents"] > #sheet-footer::before {
    content: '';
    position: absolute;
    z-index: 3;
    top: 6px;
    left: 50%;
    width: 38px;
    height: 4px;
    margin-left: -19px;
    border-radius: 4px;
    background: rgb(206 228 196 / .22);
  }
  #sheet-footer .talent-description {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 var(--gutter);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: var(--td-bg);
  }
  /* Scroll cue: while more content lies below (.has-more, set from the scroll position by mobile.mjs),
     a fade and a small chevron are pinned to the bottom edge. The 26px strip is always there as the
     list's bottom spacing, so toggling the cue never changes the scroll height or covers the last row. */
  #sheet-footer .talent-description::after {
    content: '';
    position: sticky;
    z-index: 1;
    bottom: 0;
    display: block;
    height: 26px;
    margin: 0 calc(var(--gutter) * -1);
    pointer-events: none;
  }
  #sheet-footer .talent-description.has-more::after {
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1.5 1.5 7 7l5.5-5.5' fill='none' stroke='%23f5c869' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 50% 78% / 14px 9px no-repeat,
      linear-gradient(180deg, transparent, var(--td-bg) 72%);
  }
  #sheet-footer .talent-detail-heading {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 calc(var(--gutter) * -1);
    padding: 16px var(--gutter) 10px;
    background: var(--surface-2);
    box-shadow: 0 8px 10px -8px rgb(0 0 0 / .55);
  }
  #sheet-footer .talent-detail-heading .tn-med { --tn-med: 58px; }
  #sheet-footer .td-title { flex: 1; min-width: 0; display: grid; gap: 5px; }
  #sheet-footer .td-title strong { font-size: var(--fs-hero-title); font-weight: 800; line-height: 1.2; color: var(--text-1); overflow-wrap: break-word; }
  #sheet-footer .td-title strong small { margin-left: 2px; font: 700 var(--fs-13)/1 var(--font-display); color: var(--jade-200); white-space: nowrap; }
  #sheet-footer .is-max .td-title strong small { color: var(--gold-200); }
  #sheet-footer .td-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
  #sheet-footer .td-tagline { min-width: 0; font-size: var(--fs-11); color: var(--text-3); }
  #sheet-footer .talent-detail-close { align-self: flex-start; }
  #sheet-footer .td-desc { margin: 2px 2px 10px; font-size: var(--fs-13); line-height: 1.55; color: var(--text-2); }

  #sheet-footer .talent-comparison { padding: 2px 12px; border-radius: var(--r-md); background: var(--surface-inset); border: 1px solid var(--line-1); box-shadow: inset 0 2px 6px rgb(0 0 0 / .35); }
  #sheet-footer .talent-comparison .kv { align-items: center; padding: 9px 0; }
  #sheet-footer .talent-comparison .kv > :first-child { flex: none; font-size: var(--fs-12); font-weight: 600; }
  #sheet-footer .talent-comparison .kv > :last-child { min-width: 0; font-size: var(--fs-13); overflow-wrap: break-word; }
  #sheet-footer .talent-comparison .kv.is-next > :first-child { color: var(--jade-300); }
  #sheet-footer .talent-comparison .kv.is-next > :last-child { color: var(--jade-200); }
  #sheet-footer .talent-comparison .kv.is-next > :last-child::before { content: '▲ '; font-size: var(--fs-10); color: var(--jade-300); }
  #sheet-footer .talent-comparison .kv.is-max > :last-child { color: var(--gold-100); }
  #sheet-footer .is-retired .talent-comparison .kv > :last-child { color: var(--text-3); }

  #sheet-footer .td-sec { margin-top: 14px; }
  #sheet-footer .td-sec > .section-head { margin-bottom: 8px; }
  /* Locked nodes list the requirements first (td-desc → requirements → comparison). */
  #sheet-footer .td-desc + .td-sec { margin-top: 0; }
  #sheet-footer .talent-requirements + .talent-comparison { margin-top: 12px; }
  #sheet-footer .td-rows { display: grid; gap: 6px; }
  #sheet-footer .td-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 50px;
    padding: 6px 10px 6px 7px;
    border-radius: var(--r-md);
    background: var(--grad-panel), var(--surface-2);
    border: 1px solid var(--line-1);
    color: var(--text-1);
    text-align: left;
    box-shadow: var(--hl-top);
  }
  #sheet-footer button.td-row { transition: background var(--dur-1), transform var(--dur-1); }
  #sheet-footer button.td-row:active { transform: translateY(1px); background: var(--surface-3); }
  #sheet-footer .td-row.met { border-color: rgb(80 200 140 / .3); }
  #sheet-footer .td-row.unmet { border-color: rgb(255 196 92 / .34); background: linear-gradient(90deg, rgb(255 196 92 / .08), transparent 70%), var(--surface-2); }
  #sheet-footer .tn-mini {
    flex: none;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    overflow: hidden;
    border-radius: 50%;
    background: var(--tn-face-bg);
    border: 1px solid var(--line-2);
    box-shadow: inset 0 -4px 8px rgb(0 0 0 / .4);
  }
  #sheet-footer .tn-mini img { width: 80%; height: 80%; object-fit: contain; }
  #sheet-footer .tn-mini .tn-art:is(.tn-art--miner, .tn-art--mole, .tn-art--golem) { width: 128%; height: 128%; max-width: none; margin-top: 34%; object-position: 50% 0; }
  #sheet-footer .tn-mini .gi { width: 25px; height: 25px; }
  #sheet-footer .td-row.unmet .tn-mini > * { opacity: .55; }
  #sheet-footer .td-row-copy { flex: 1; min-width: 0; display: grid; gap: 1px; }
  #sheet-footer .td-row-name { font-size: var(--fs-13); font-weight: 700; line-height: 1.3; overflow-wrap: break-word; }
  #sheet-footer .td-row em { font-size: var(--fs-11); font-style: normal; line-height: 1.35; color: var(--text-3); }
  #sheet-footer .td-row.met em { color: var(--jade-300); }
  #sheet-footer .td-row.unmet em { color: var(--warn); }
  #sheet-footer .td-row-trail { flex: none; display: flex; align-items: center; gap: 4px; font: 700 var(--fs-11)/1 var(--font-display); color: var(--text-3); white-space: nowrap; }
  #sheet-footer .td-row-trail .icon { width: 16px; height: 16px; color: var(--gold-300); }
  #sheet-footer .td-row-trail .gi { width: 20px; height: 20px; }
  #sheet-footer .td-row.unmet .td-row-trail .gi-lock { --gi-base: var(--warn); }

  /* Materials: the shared chips; the legend moves up beside the section title. */
  #sheet-footer .td-materials { position: relative; }
  #sheet-footer .td-materials .materials-block { display: block; }
  #sheet-footer .td-materials .material-legend { position: absolute; top: 6px; right: 2px; }
  #sheet-footer .td-materials .material-chip { height: 34px; padding-left: 4px; }
  #sheet-footer .td-materials .material-chip img { width: 27px; height: 27px; filter: none; }

  /* Following levels preview. */
  #sheet-footer details.talent-next-preview { margin-top: 12px; border-top: 1px dashed var(--line-2); }
  #sheet-footer details.talent-next-preview > summary { padding: 0 2px; font-size: var(--fs-13); color: var(--text-2); }
  #sheet-footer details.talent-next-preview[open] > summary { color: var(--text-1); }
  #sheet-footer details.talent-next-preview > .td-rows { padding-bottom: 2px; }

  /* Pinned call to action. */
  #sheet-footer .talent-cta { flex: none; padding: 10px var(--gutter) 12px; border-top: 1px solid var(--line-1); background: linear-gradient(180deg, var(--surface-1), var(--bg-2)); }
  #sheet-footer .talent-cta [data-learn] {
    --btn-h: 54px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 100%;
    padding: 6px 16px;
    white-space: normal;
    font-size: var(--fs-16);
    font-weight: 800;
  }
  #sheet-footer .talent-cta [data-learn].is-max { flex-direction: row; gap: 6px; color: var(--gold-200); }
  #sheet-footer .talent-cta [data-learn].is-max .gi { filter: none; }
  #sheet-footer .talent-cta .cta-main { display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
  #sheet-footer .talent-cta .cta-main .currency-icon { width: 20px; height: 20px; }
  #sheet-footer .talent-cta .cta-main .num { font-size: 19px; line-height: 1; white-space: nowrap; }
  #sheet-footer .talent-cta .cta-main .gi { width: 20px; height: 20px; margin: 0; }
  #sheet-footer .talent-cta .cta-reason { max-width: 100%; font-size: var(--fs-12); font-weight: 700; line-height: 1.3; color: var(--warn); text-align: center; }
  #sheet-footer .talent-cta [data-learn].is-locked .cta-reason { color: var(--text-3); }

  /* ───────────── Small screens ───────────── */
  @media (max-width: 359px) {
    #sheet[data-mode="talents"] { --tn-med: 56px; }
    .talent-node-grid { gap: 22px 4px; padding-inline: 2px; }
    .skill-node > strong { font-size: var(--fs-12); }
    .skill-node > em.tn-cost { padding-right: 5px; }
    #sheet-footer .td-title strong { font-size: var(--fs-card-title); }
  }
  /* Short screens: the drawer takes at most ~55% of the sheet so the selected node stays in view,
     the current/next comparison sits on one row, and the header and call to action are tighter. */
  @media (max-height: 640px) {
    #sheet[data-mode="talents"] > #sheet-footer { max-height: 55%; }
    #sheet-footer .talent-detail-heading { gap: 10px; padding-top: 14px; padding-bottom: 8px; }
    #sheet-footer .talent-detail-heading .tn-med { --tn-med: 44px; }
    #sheet-footer .td-title { gap: 3px; }
    #sheet-footer .td-tagline { display: none; }
    #sheet-footer .td-desc { margin-bottom: 8px; line-height: 1.45; }
    #sheet-footer .talent-comparison { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding: 0; }
    #sheet-footer .talent-comparison .kv { display: grid; align-content: start; gap: 2px; padding: 7px 10px; }
    #sheet-footer .talent-comparison .kv + .kv { border-top: 0; border-left: 1px dashed var(--line-2); }
    #sheet-footer .talent-comparison .kv > :last-child { text-align: left; }
    #sheet-footer .td-sec { margin-top: 10px; }
    #sheet-footer .talent-cta { padding-top: 8px; padding-bottom: 8px; }
    #sheet-footer .talent-cta [data-learn] { --btn-h: 48px; }
    .talent-families > button { min-height: 58px; padding-block: 4px; }
    .talent-families .tf-ava { width: 30px; height: 30px; }
  }
}
