/* wgf-talents.css - talent / trait-tree pages (/talents/ hub + /talent-tree/<slug>-<id>/).
   Vanilla CSS, design-token driven (Rule: no framework). The hub reuses the shared
   .wgf-cat-grid / .wgf-cat-tile from the class pages; this sheet only styles the
   detail page's talent grid. First-party datamined icons only (no Wowhead). */

/* ── section header count badge: a squared plate chip (the kit .wgf-chip material;
   rounded pills are BANNED, 13-ingame-reference sec 0) ── */
.wgf-talent-secount {
  margin-left: var(--space-1); padding: 1px var(--space-2); border-radius: 0; font-size: 12px;
  vertical-align: middle;
  background: linear-gradient(180deg, var(--wgf-plate-hi), var(--wgf-plate));
  border: 1px solid var(--wgf-metal-soft);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  color: var(--wgf-gold-muted); font-weight: 500;
}

/* ── the tree grid: a responsive wall of talent nodes ── */
.wgf-talent-grid {
  display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* Each SSR card is a squared kit well row (the markup carries .wgf-well for the
   inset surface; this rule only adds the card layout). No web-card radius. */
.wgf-talent-node {
  border-radius: 0; padding: var(--space-2); display: flex;
  flex-direction: column; gap: var(--space-2);
}
/* a choice node holds two selectable talents - flag it and split its entries */
.wgf-talent-node--choice {
  border-color: var(--wgf-gold-muted);
}
.wgf-talent-choice-tag {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--wgf-gold-accent); font-weight: 650;
}

/* ── one selectable talent ── */
.wgf-talent-entry { display: flex; gap: var(--space-2); align-items: flex-start; }
.wgf-talent-node--choice .wgf-talent-entry + .wgf-talent-entry {
  border-top: 1px dashed var(--wgf-border-neutral-soft); padding-top: var(--space-2);
}
.wgf-talent-icon {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 0;
  border: 1px solid var(--wgf-border-neutral); background: var(--wgf-panel-3);
}
.wgf-talent-icon--empty { display: inline-block; }
.wgf-talent-body { min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.wgf-talent-head {
  display: flex; gap: var(--space-2); align-items: baseline; flex-wrap: wrap;
}
.wgf-talent-name { font-weight: 600; color: var(--wgf-text); text-decoration: none; }
.wgf-talent-name:hover { color: var(--wgf-gold-primary); text-decoration: underline; }
/* Rank badge wears the .wgf-tc-rank plate recipe (dark plate, gold rim, white
   numerals - the client's counter), not a web pill. */
.wgf-talent-ranks {
  font-size: 11px; color: #fff; padding: 1px var(--space-1); border-radius: 3px;
  background: rgba(8, 8, 8, 0.92); border: 1px solid var(--wgf-gold);
  font-family: var(--font-game); font-variant-numeric: tabular-nums;
  text-shadow: var(--text-ink-outline);
  white-space: nowrap; flex: 0 0 auto;
}
.wgf-talent-tip {
  margin: 0; font-size: 13px; line-height: 1.45; color: var(--wgf-muted);
}

.wgf-talent-pending { color: var(--wgf-muted); }

/* ── /talents/ hub: the spec-card grid sits inside a kit window body, which already
   pads - drop the grid's own outer margin so the header/body gaps don't double up. ── */
.wgf-cls-sec .wgf-window__body .wgf-ag-grid { margin: 0; }

@media (max-width: 640px) {
  .wgf-talent-grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   The Class | Hero | Spec lattice band - ONE home (Rule 11). TWO consumers draw
   this band: the interactive calculator (wgf-talent-calc.js, /talent-tree/) and
   the read-only character-page lattice (talent_app.render_build_lattice). Both
   emit <div class="talent__latticewrap"><div class="wgf-tc-panels">...</div></div>
   and wgf-pvp.js fitLattices() scales the WHOLE band to the available width
   (transform on the band; the wrap clips the transform's phantom layout width).
   The character band additionally carries .talent__lattice for its read-only
   pointer rules below. Spec panels are switched by wgf-pvp.js (all visible
   without JS).
   ═══════════════════════════════════════════════════════════════════════════ */
.talent__spec-panel[hidden] { display: none; }
.talent__spec-panel + .talent__spec-panel { margin-top: var(--space-1); }
.talent__latticewrap {
  margin-top: var(--space-3);
  overflow: hidden;          /* clip the phantom layout width left behind by the scale transform */
  text-align: center;        /* center the inline-flex band and its scaled visual */
  /* Phone-width blowout guard (walkthrough defect 2026-08-05): the band is fixed-px
     (~1300px) and overflow:hidden does NOT stop that min-content width from propagating
     up - it inflated .wgf-window / .wgf-seo-main and the mobile .wgf-seo-layout "1fr"
     track (whose min is auto) to band width, so the whole page was wider than a 390px
     viewport, fitLattices() measured avail == natural width, and never scaled. width:0 +
     min-width:100% makes the wrap contribute ZERO intrinsic width while still laying out
     at the full container width, so the wrap is genuinely viewport-constrained and the
     fit/scroll mechanism actually engages. */
  width: 0;
  min-width: 100%;
}
/* Set by fitLattices() when the band still overflows at the legibility floor: scroll the tree
   sideways rather than shrinking it further into unreadability. Origin flips to the left edge so
   the start of the tree is always reachable (a center origin pushed it out of scroll range). */
.talent__latticewrap--scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  text-align: left;
}
.talent__latticewrap--scroll .wgf-tc-panels { transform-origin: top left; }
/* the lattice nodes are display-only (not buttons) - kill the pointer + hover-as-button feel */
.talent__lattice .wgf-tc-node { cursor: default; }
/* …except a talent that links to its spell page: it's a real anchor, so restore the pointer */
.talent__lattice a.wgf-tc-node--link { cursor: pointer; text-decoration: none; }
.talent__lattice .wgf-tc-node--locked:hover { border-color: var(--wgf-border-neutral); }
.talent__lattice .wgf-tc-node--part:hover { border-color: var(--wgf-gold-muted); }
.talent__lattice .wgf-tc-node--max:hover { border-color: var(--wgf-gold-primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE IN-GAME TALENT FRAME (owner directive 13 - 1:1 in-game talent panel).
   One kit window is the whole talent surface: class crest + gold Friz H1 in
   the title bar, facts row, calculator, and the crawlable static tree inside
   the same frame. Chrome kit + real client textures only (wgf-chrome.css).
   ═══════════════════════════════════════════════════════════════════════════ */
.wgf-talent-frame__title { gap: var(--space-2); }
.wgf-talent-frame > .wgf-window__title { font-size: var(--text-lg); min-height: 44px; }
.wgf-talent-frame__crest { width: 28px; height: 28px; flex: 0 0 auto; }
/* Headings living INSIDE a window title bar inherit its carved gold Friz voice:
   the page H1 (.wgf-talent-frame__h1) and the h2 of a follow-up window
   (.wgf-talent-wh) share the one rule. */
.wgf-talent-frame__h1,
.wgf-talent-wh { margin: 0; font: inherit; color: inherit; letter-spacing: inherit; }
.wgf-talent-frame__sub { margin: 0 0 var(--space-2); font-size: 14px; color: var(--wgf-muted); }
.wgf-talent-frame__facts { margin-bottom: var(--space-3); }
/* The facts ledger sits on the kit .wgf-well (in the markup); rows come from
   wgf-world.css - label left, value right, the in-game records surface. */
.wgf-talent-frame .wgf-talent-static { margin-top: var(--space-3); }
/* Follow-up kit windows (About / Related / the trees list) keep the vertical
   rhythm the old flat .wgf-section boxes carried. */
.wgf-talent-win { margin-top: var(--space-4); }
/* SSR tree sections inside the frame window: rhythm only (the frame is the ONE
   container - no nested .wgf-section box, that double-framed the tree). */
.wgf-talent-sec + .wgf-talent-sec { margin-top: var(--space-4); }

/* ═══════════════════════════════════════════════════════════════════════════
   Interactive calculator (wgf-talent-calc.js hydrates #wgf-talent-calc)
   ═══════════════════════════════════════════════════════════════════════════ */
#wgf-talent-calc { margin: 0 0 var(--space-3); }

/* Action strip: plain right-aligned red buttons sitting on the window stone - the
   client puts Import/Share on the frame itself, never in a web toolbar plate.
   (Point counters moved into each tree pane's header, like the in-game trees.) */
.wgf-tc-bar {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  justify-content: flex-end; margin-bottom: var(--space-2);
}

/* Action + dialog buttons are the kit red button proper (.wgf-btn-red
   .wgf-btn-red--sm in the markup, BOTH classes) - no local button recipe. */
.wgf-tc-actions { display: flex; gap: var(--space-2); }

/* Carved instruction strip - ONE home for the calculator help line and the SSR
   section captions (LAW sec 1: helper copy sits on a surface, never floats bare).
   The markup carries .wgf-well for the inset surface; this adds voice + rhythm. */
.wgf-talent-note {
  margin: 0 0 var(--space-2);
  color: var(--wgf-gold);
  font-family: var(--font-game);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  text-shadow: var(--text-ink-outline);
}

/* The band itself (shared with the character pages - see the lattice-band header
   above): ONE centered Class | Hero | Spec row that never wraps; fitLattices()
   scales it down and flips the wrap to sideways scroll below the legibility floor. */
.wgf-tc-panels {
  display: inline-flex;
  flex-wrap: nowrap;
  gap: 28px;
  align-items: stretch;      /* panels share the tallest height so the short hero tree can center */
  text-align: left;
  transform-origin: top center;
}
/* Each tree pane is the client's near-black inset well (the surface the in-game
   trees sit on) - the kit .wgf-well recipe, scoped so the character-page lattice
   band wears the exact same material (one look everywhere). The title stays
   pinned to the top; the grid centers in the leftover space (margin: auto), so
   the short hero tree sits centered between the taller class and spec trees,
   matching the in-game / Drustvar layout. */
.wgf-tc-panels .wgf-tc-panel {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  border: 1px solid var(--wgf-well-edge);
  background: var(--wgf-well);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.75), inset 0 0 0 1px rgba(0, 0, 0, 0.6);
}
.wgf-tc-panels .wgf-tc-panel .wgf-tc-grid { margin: auto; }
/* In-game tree header: gold Friz small-caps with the points spent / budget counter
   riding the right edge (the client shows spent points at the top of each tree). */
.wgf-tc-panel-title {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
  margin: 0 0 var(--space-2);
  font-family: var(--font-game); font-size: var(--text-sm); font-weight: 700;
  font-variant: small-caps; letter-spacing: 0.03em;
  color: var(--wgf-gold); text-shadow: var(--text-ink-outline);
}
.wgf-tc-panel-spent {
  font-size: 12px; font-weight: 700; color: var(--wgf-gold-bright);
  font-family: var(--font-game); font-variant-numeric: tabular-nums; white-space: nowrap;
  text-shadow: var(--text-ink-outline);
}
/* Hero-tree switcher: the kit tab row (.wgf-tabrow + .wgf-tab in the markup;
   active tab = .is-active pressed state, all from wgf-chrome.css). This rule
   only spaces the strip above the hero grid - no local tab recipe, no pills. */
.wgf-tc-herotabs { margin-bottom: var(--space-2); }

.wgf-tc-grid { position: relative; }
.wgf-tc-edges { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.wgf-tc-edge { stroke: var(--wgf-border-neutral); stroke-width: 2; }
.wgf-tc-edge--on { stroke: var(--wgf-gold); stroke-width: 2.5; }
/* prerequisite-direction arrowhead (one shared marker; neutral so it reads on both on/off edges) */
.wgf-tc-arrowhead { fill: var(--wgf-border-neutral); }

/* Node box size comes from --tc-node, set inline from talent_app._LATTICE_NODE (the same constant
   that positioned the node), so the box can never disagree with the SVG edges drawn under it. */
.wgf-tc-node {
  position: absolute; z-index: 1;
  width: var(--tc-node, 52px); height: var(--tc-node, 52px); padding: 0;
  cursor: pointer; border-radius: 0; overflow: visible;
  border: 2px solid var(--wgf-border-neutral); background: var(--wgf-panel-3);
  transition: border-color .1s, box-shadow .1s, filter .1s, transform .06s;
}
.wgf-tc-node .wgf-tc-icon { display: block; width: 100%; height: 100%; border-radius: 0; }
.wgf-tc-icon--empty { background: var(--wgf-panel-2); }

/* .wgf-tc-oct wraps every node's icon. On an ordinary node it is an invisible passthrough; on a
   choice node it carries the octagon. The clip MUST live on this inner element, never on the button:
   clip-path crops a box AND its children, so a clipped button silently ate its own rank pip and
   choice marker (which sit outside the node box by design). */
.wgf-tc-oct { display: block; width: 100%; height: 100%; }

/* Choice node = octagon (the in-game shape). A border can't follow a clip-path, so the padded
   background stands in as the rim that the octagon clip reveals.
   Owner 2026-08-01 ("not clear which are the choice nodes"): the rim is a LIT gold at rest - not
   the neutral brown of an ordinary node's border - so the octagon silhouette reads as "this is a
   choice" before you hover it, and the padding is thick enough to actually see. */
.wgf-tc-node--choice { border: 0; padding: 0; border-radius: 0; background: transparent; }
.wgf-tc-node--choice .wgf-tc-oct {
  box-sizing: border-box; padding: 3px;
  background: var(--wgf-gold-muted);
  clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);
}
.wgf-tc-node--choice .wgf-tc-icon { border-radius: 0; }
.wgf-tc-node--choice.wgf-tc-node--part .wgf-tc-oct { background: var(--wgf-gold-muted); }
.wgf-tc-node--choice.wgf-tc-node--max .wgf-tc-oct { background: var(--wgf-gold-primary); }
.wgf-tc-node--choice.wgf-tc-node--max { box-shadow: none; }
.wgf-tc-node--choice:hover .wgf-tc-oct { background: var(--wgf-gold-primary); }

/* Untaken node. Was opacity:.5 + grayscale(1), which on a dark plate made a character's mostly
   untaken tree unreadable (owner 2026-08-01 "hard to read") - especially once the character-page
   band was scaled down. Now: fully opaque, mostly desaturated, and darkened. Still unmistakably
   "not taken", but the icon art stays legible. */
.wgf-tc-node--locked { opacity: 1; filter: grayscale(.85) brightness(.55) contrast(1.05); }
.wgf-tc-node--locked:hover { filter: grayscale(.35) brightness(.85) contrast(1.05); }
.wgf-tc-node--part { border-color: var(--wgf-gold-muted); }
.wgf-tc-node--max {
  border-color: var(--wgf-gold-primary);
  box-shadow: 0 0 0 2px rgba(var(--wgf-gold-rgb), .35);
}
.wgf-tc-node:hover { border-color: var(--wgf-gold-primary); }
/* Press feedback: a spent point should feel like a click, not a silent repaint. */
.wgf-tc-node:active { transform: scale(.94); }

/* Rejected click (no points, gate unmet, prerequisite missing). Without this a dead click was
   indistinguishable from a broken page. */
@keyframes wgf-tc-deny {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-3px); }
  75%      { transform: translateX(3px); }
}
.wgf-tc-node--deny { animation: wgf-tc-deny .22s ease-in-out; border-color: var(--wgf-down); }

/* In-game rank pip: dark plate, gold rim, white numerals (the client's counter),
   not a web-gold pill. Sized up with the node so it survives the character-page downscale. */
.wgf-tc-rank {
  position: absolute; right: -6px; bottom: -6px; min-width: 21px; height: 21px;
  padding: 0 var(--space-1); border-radius: 3px; font-size: 12.5px; line-height: 19px;
  font-variant-numeric: tabular-nums; text-align: center; color: #fff;
  font-family: var(--font-game); text-shadow: var(--text-ink-outline);
  background: rgba(8, 8, 8, 0.92); border: 1px solid var(--wgf-gold); font-weight: 700;
}
.wgf-tc-rank--dot { min-width: 19px; height: 19px; line-height: 17px; }

/* Choice node = a SPLIT octagon showing BOTH options, the way the client draws it: the node is
   divided down a slightly-raked seam, each half carrying one option's icon, the taken half lit and
   the other dimmed. This replaces the corner swap badge (owner 2026-08-01: a little web button
   bolted to the node, not the game). The shape itself now carries the meaning - a split node is
   self-evidently a choice, before any hover. */
.wgf-tc-node--choice .wgf-tc-oct { position: relative; }
.wgf-tc-half {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  border-radius: 0; object-fit: cover;
}
/* Raked seam (not a straight vertical) so the split reads as the in-game diagonal facet. The two
   polygons meet exactly along it, so there is no gap and no overlap. */
.wgf-tc-half--a { clip-path: polygon(0 0, 56% 0, 44% 100%, 0 100%); }
.wgf-tc-half--b { clip-path: polygon(56% 0, 100% 0, 100% 100%, 44% 100%); }
/* The option NOT taken: pushed back, still identifiable. */
.wgf-tc-half--off { filter: grayscale(1) brightness(.42) contrast(1.05); }
/* The seam itself, drawn over the join so the two halves read as one divided plate. */
.wgf-tc-node--choice .wgf-tc-oct::after {
  content: ""; position: absolute; top: -2%; bottom: -2%; left: 50%;
  width: 2px; margin-left: -1px; transform: skewX(6.8deg);
  background: rgba(0, 0, 0, .78); box-shadow: 0 0 0 1px rgba(var(--wgf-gold-rgb), .22);
  pointer-events: none;
}

/* import/export dialog */
.wgf-tc-modal {
  position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center;
  justify-content: center; background: rgba(0, 0, 0, .55); padding: var(--space-3);
}
/* The dialog wears the kit window material: metal rim + classhall stone plate
   (the .wgf-window recipe), gold Friz title, near-black well textarea. */
.wgf-tc-modal__box {
  width: min(560px, 100%); padding: var(--space-3);
  border: 2px solid var(--wgf-metal); border-radius: 0;
  background:
    linear-gradient(rgba(0, 0, 0, 0.44), rgba(0, 0, 0, 0.44)),
    url(/assets/ui/classhall-stone-tile.png) left top / 256px 256px repeat,
    var(--wgf-plate);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.65), 0 10px 40px rgba(0, 0, 0, .5);
}
.wgf-tc-modal__title {
  margin: 0 0 var(--space-2); font-size: var(--text-md);
  font-family: var(--font-game); font-weight: 700; font-variant: small-caps;
  letter-spacing: 0.03em; color: var(--wgf-gold); text-shadow: var(--text-ink-outline);
}
.wgf-tc-modal__ta {
  width: 100%; min-height: 90px; resize: vertical; font: 13px/1.4 monospace;
  color: var(--wgf-text); background: var(--wgf-well);
  border: 1px solid var(--wgf-well-edge); border-radius: 0; padding: var(--space-2); box-sizing: border-box;
}
.wgf-tc-modal__msg { min-height: 18px; margin: var(--space-1) 0; font-size: 12.5px; color: var(--wgf-gold-accent); }
.wgf-tc-modal__row { display: flex; gap: var(--space-2); justify-content: flex-end; }


/* hover / focus tooltip card - rich datamined tooltip on a calculator node.
   Positioned in JS (fixed, viewport coords); prose comes precomputed in the tree JSON.
   In-game skin (2026-07-02, matches the item hover card / wgf-item-tooltip.css): navy plate,
   silver-blue border, white name, gold rank + spell-description gold. */
.wgf-tc-tip {
  position: fixed; z-index: 1200; max-width: 340px; pointer-events: none;
  background: linear-gradient(180deg, rgba(12, 12, 30, 0.97), rgba(5, 5, 16, 0.97));
  border: 1px solid #7a7a96;
  border-radius: 5px; padding: var(--space-2) 12px; box-shadow: 0 12px 38px rgba(0, 0, 0, .65);
  font-size: 13px; line-height: 1.45; color: #ffffff;
}
.wgf-tc-tip[hidden] { display: none; }
.wgf-tc-tip__name {
  display: block; font-weight: 700; font-size: 14px; color: #ffffff;
}
.wgf-tc-tip__ranks {
  display: block; margin: 1px 0 var(--space-1); font-size: 11.5px; letter-spacing: .02em;
  text-transform: uppercase; color: #ffd100; font-variant-numeric: tabular-nums;
}
.wgf-tc-tip__body { margin: 0; color: #ffd100; }   /* in-game spell-description gold */
.wgf-tc-tip__muted { margin: var(--space-1) 0 0; font-size: 12px; color: #b8b8c8; }

/* Choice options block: names BOTH sides of a choice node, selected one lit. */
.wgf-tc-tip__choice {
  margin: var(--space-2) 0 2px; font-size: 11.5px; letter-spacing: .04em;
  text-transform: uppercase; color: #b8b8c8;
}
.wgf-tc-tip__opts { display: flex; flex-direction: column; gap: 1px; }
.wgf-tc-tip__opt { font-size: 12.5px; color: #b8b8c8; }
.wgf-tc-tip__opt--on { color: #ffffff; font-weight: 700; }
