/* Board: Dust Walkers UI (Michroma, circuit traces, hazard plate). Side panels follow the case-study page:
   square edges, sentence-case labels, IBM Plex Sans, one gold. (Design pass 2026-11-13.) */
:root {
  color-scheme: dark;
  --bg: #15130f;
  --panel: #1f1c17;
  --panel-2: #29251e;
  --line: #3a342a;
  --text: #ece4d6;
  --muted: #a39887;
  --dim: #6b6255;
  --accent: #f0c46e;       /* yours: the page's gold */
  --accent-ink: #1b1408;
  --loot: #6fa8c9;         /* pre-built by the drop */
  --epic: #b884e0;
  --special: #f0675a;
  --bad: #d9705a;
  --radius: 0;
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--bg); color: var(--text);
  font: 15px/1.5 "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
}
button, select { font: inherit; color: inherit; }

.top {
  display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: end; justify-content: space-between;
  padding: 20px 24px 12px; border-bottom: 1px solid var(--line);
}
.title h1 { margin: 0; font-size: 22px; letter-spacing: .01em; }
.title .sub { margin: 2px 0 0; color: var(--muted); font-size: 13px; }
.weapon-pick { display: grid; gap: 6px; font-size: 14px; color: var(--muted); }
.weapon-pick select {
  min-width: 240px; padding: 8px 10px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
}

.layout {
  display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px;
  padding: 20px 24px 64px; max-width: 1320px; margin: 0 auto;
}
@media (max-width: 960px) { .layout { grid-template-columns: minmax(0, 1fr); padding: 16px; } .top { padding: 16px; } }

/* Tree board: Gabriel's ring layout, drawn like Last Epoch's skill trees. Icon nodes whose shape shows the
   node type, a 0/1 counter under each, names and text on hover, and a status badge per ring instead of wires. */
.tree { overflow-x: auto; padding-bottom: 4px; }
.board {
  position: relative; width: 100%; min-width: 760px; aspect-ratio: 1090 / 990;
  background: radial-gradient(ellipse at 50% 43%, #1c1915 0%, #12100d 70%);
  border-radius: 0;
}
.rings { position: absolute; inset: 0; width: 100%; height: 100%; }
.ring { fill: none; stroke: #2c2720; stroke-width: 1.5; stroke-dasharray: 5 7; }
.ring.gated { stroke: #5e4a28; stroke-dasharray: 10 6; fill: rgba(224, 162, 74, .025); }
.ring.open { stroke: #6e5a36; stroke-dasharray: none; fill: rgba(224, 162, 74, .035); }
.divider { stroke: #a39887; stroke-opacity: .35; stroke-width: 1.5; stroke-dasharray: 1 7; stroke-linecap: round; }

/* Prerequisite links between a node and the node it requires. */
.req-link { --e: #b9ad9a; fill: none; stroke: var(--e); stroke-width: 2; stroke-linejoin: round; stroke-opacity: .18; stroke-dasharray: 4 4; }
.req-link.sec-scope { --e: #7fe0cc; } .req-link.sec-barrel { --e: #c4e38a; } .req-link.sec-magazine { --e: #c9a4f0; } .req-link.sec-ammunition { --e: #f0d58a; }
.req-link.waiting { stroke-opacity: .35; }
.req-link.ready { stroke-opacity: .7; stroke-dasharray: none; }
.req-link.lit { stroke-opacity: 1; stroke-width: 2.6; stroke-dasharray: none; }

/* Section borders as circuit traces. */
.border-trace { fill: none; stroke: #a39887; stroke-opacity: .5; stroke-width: 1.6; stroke-linejoin: round; }
.border-pad { fill: #a39887; fill-opacity: .7; }
.border-bend { fill: #a39887; fill-opacity: .55; }
.border-via { fill: #12100d; stroke: #a39887; stroke-opacity: .75; stroke-width: 1.6; }

/* Section tints: a 3% wash of each slot's colour (trial, 2026-11-11). */
.section { fill-opacity: .03; }
.section.sec-scope { fill: #7fe0cc; } .section.sec-barrel { fill: #c4e38a; } .section.sec-magazine { fill: #c9a4f0; }
.section.sec-ammunition { fill: #f0d58a; } .section.sec-special { fill: #f08a6e; }

/* Ring outlines take the colour of the section they pass through. The base .ring only carries the fill. */
.ring { stroke: none !important; }
.ring-edge { fill: none; stroke-width: 2; --e: #b9ad9a; stroke: var(--e); }
.ring-edge.sec-scope { --e: #7fe0cc; } .ring-edge.sec-barrel { --e: #c4e38a; } .ring-edge.sec-magazine { --e: #c9a4f0; }
.ring-edge.sec-ammunition { --e: #f0d58a; } .ring-edge.sec-special { --e: #f08a6e; }
.ring-edge.open { stroke-opacity: .7; }
.ring-edge.gated { stroke-opacity: .55; stroke-dasharray: 10 6; }
.ring-edge.locked { stroke-opacity: .18; stroke-dasharray: 5 7; }

/* The weapon in the middle */
/* Rings as circuit traces: the inner "bus" line shows once a ring is open. */
.ring-edge.bus { stroke-width: 1; stroke-opacity: .28; stroke-dasharray: none; }

/* Decoration (after Dust Walkers' UI): circuit traces, ring corner markers, hub reticle, brackets, hazard bars. */
.trace { --e: #b9ad9a; }
.trace.sec-scope { --e: #7fe0cc; } .trace.sec-barrel { --e: #c4e38a; } .trace.sec-magazine { --e: #c9a4f0; } .trace.sec-ammunition { --e: #f0d58a; }
.trace polyline { fill: none; stroke: var(--e); stroke-width: 1.5; stroke-linejoin: round; stroke-opacity: .13; }
.trace .pad, .trace .via { fill: none; stroke: var(--e); stroke-width: 1.5; stroke-opacity: .2; }
.trace .pad { fill: var(--e); fill-opacity: .25; stroke: none; }
.trace .dot { fill: var(--e); fill-opacity: .3; }
.trace .part { fill: var(--e); fill-opacity: .3; }
.trace.open .dot, .trace.open .part { fill-opacity: .6; }
.trace.gated polyline { stroke-opacity: .2; }
.trace.open polyline { stroke-opacity: .32; }
.trace.open .via { stroke-opacity: .55; }
.trace.open .pad { fill-opacity: .6; }
/* A small light travels along the traces of open rings. */
.trace .pulse { stroke-opacity: .85; stroke-width: 2; stroke-dasharray: 6 400; stroke-dashoffset: 406; animation: trace-pulse 4s linear infinite; }
@keyframes trace-pulse { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .trace .pulse { display: none; } }
.corner { --e: #b9ad9a; fill: var(--e); fill-opacity: .25; }
.corner.sec-scope { --e: #7fe0cc; } .corner.sec-barrel { --e: #c4e38a; } .corner.sec-magazine { --e: #c9a4f0; } .corner.sec-ammunition { --e: #f0d58a; }
.corner.gated { fill-opacity: .5; } .corner.open { fill-opacity: .85; }
.reticle { fill: none; stroke: #c99a4b; stroke-width: 1.5; stroke-opacity: .55; }
.reticle.fine { stroke-opacity: .4; }
.bracket { fill: none; stroke: #e9e2d2; stroke-width: 2; stroke-opacity: .35; }
.hazard { fill: url(#hazard-stripes); opacity: .5; }
.hazard-ink { fill: #f0d070; }
.chevron { fill: none; stroke: #f0c46e; stroke-width: 2.2; stroke-opacity: .6; stroke-linecap: square; }

/* Header plate above the board, in Dust Walkers' type (Michroma) with a hazard stripe. */
.plate { display: flex; align-items: center; gap: 14px; margin: 0 0 10px; }
/* Gold like the weapon icon, board-black text set in Syncopate Bold (Michroma has no bold weight; Syncopate is the closest wide face that does),
   and 45 degree sides that lean the same way as the hazard stripe. --slant equals the plate's height. */
.plate-title {
  --slant: 30px;
  display: inline-flex; align-items: center; flex: none; white-space: nowrap; height: 30px; padding: 0 calc(var(--slant) + 6px);
  font: 700 13px/1 Syncopate, Michroma, system-ui, sans-serif; letter-spacing: .26em; text-transform: uppercase;
  color: #12100d; background: #f0c46e; /* the weapon icon's gold; the hazard stripe matches it */
  clip-path: polygon(var(--slant) 0, 100% 0, calc(100% - var(--slant)) 100%, 0 100%);
}
.plate-sub { font: 400 10px/1 Michroma, system-ui, sans-serif; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); }
.plate-hazard { flex: 1; height: 8px; max-width: 220px; margin-left: auto; opacity: .55;
  background: repeating-linear-gradient(-45deg, #f0c46e 0 6px, transparent 6px 12px); }

/* The hexagon itself is centred on the board centre (app.js uses its corners for the Legendary column),
   so the name hangs below it instead of shifting it up. Width must match HUB_W in app.js. */
.hub { position: absolute; transform: translate(-50%, -50%); width: 10.5%; pointer-events: none; }
.hub .shape { display: block; width: 100%; height: auto; filter: drop-shadow(0 0 10px rgba(224, 162, 74, .25)); }
.hub-text { position: absolute; top: 100%; left: 0; right: 0; display: grid; justify-items: center; gap: 2px; margin-top: 2px; }
.hub .frame { fill: #2b2216; stroke: #c99a4b; stroke-width: 4; }
.hub .inner { fill: #1a1510; stroke: #6e5a36; stroke-width: 1.5; }
.hub .glyph { stroke: #f0c46e; }
.hub-name { font: 400 11px/1.25 Michroma, system-ui, sans-serif; letter-spacing: .06em; text-transform: uppercase; text-align: center; }
.hub-rarity { font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }

/* Nodes */
.node {
  --c: #b9ad9a;
  position: absolute; transform: translate(-50%, -50%); width: 5.6%; padding: 0; background: none; border: 0;
  display: grid; justify-items: center; cursor: pointer; color: var(--text);
}
.node.shape-stat { width: 4.6%; }
.node.shape-epic { width: 7.4%; }
.node.shape-special { width: 4.4%; cursor: default; }
.slot-scope { --c: #7fe0cc; } .slot-barrel { --c: #c4e38a; } .slot-magazine { --c: #c9a4f0; }
.slot-ammunition { --c: #f0d58a; } .slot-epic, .slot-special { --c: #f08a6e; }
.node .shape { width: 100%; height: auto; overflow: visible; transition: filter .12s; }
.node .frame { fill: #221e18; stroke: #5b5244; stroke-width: 4; }
.node .inner { fill: #181512; stroke: #3a342a; stroke-width: 1.5; }
.node .glyph { stroke: var(--c); }
/* The counter hangs under the shape so a long label can't stretch the node; each node is centred on its shape. */
.node .count {
  position: absolute; top: 100%; left: 50%; transform: translate(-50%, -3px); white-space: nowrap; padding: 0 6px; border-radius: 4px; font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: #d8cfc0; background: #0f0d0a; border: 1px solid #2c2720; line-height: 16px;
}
.node:hover .shape { filter: brightness(1.25); }
.node:focus-visible { outline: none; }
.node:focus-visible .frame { stroke: var(--text); }

/* Can take a point: bright frame and a soft glow in the slot colour. */
.node.can .frame { stroke: var(--c); }
.node.can .shape { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--c) 55%, transparent)); }
/* Spent: filled with the slot colour, dark icon, gold counter. */
.node.spent .frame { fill: var(--c); stroke: #f3e7cf; }
.node.spent .inner { fill: color-mix(in srgb, var(--c) 75%, #15120d); stroke: #15120d; }
.node.spent .glyph { stroke: #15120d; }
.node.spent .count { color: #15120d; background: var(--accent); border-color: var(--accent); }
.node.spent.prebuilt .frame { stroke: var(--loot); stroke-dasharray: 9 5; }
/* Open by Rarity but waiting on a point in the ring inside it. */
.node.gated .frame { stroke: #5e4a28; stroke-dasharray: 6 4; }
.node.gated .glyph { stroke: color-mix(in srgb, var(--c) 45%, #3a342a); }
.node.blocked .glyph { opacity: .55; }
/* Locked by Rarity: greyed out. The name and text still show on hover. */
.node.locked .frame { fill: #191612; stroke: #36302a; }
.node.locked .glyph { stroke: #5b5244; }
.node.locked .count { color: #5b5244; }
.node.slot-special.spent .count { color: #15120d; background: var(--c); border-color: var(--c); }
.node.slot-special.none { opacity: .3; }
.node.selected .frame { stroke: #ffffff; stroke-width: 5; }

.tip {
  position: absolute; z-index: 5; width: 260px; padding: 10px 12px; pointer-events: none;
  background: #0d0b09; border: 1px solid #6e5a36; box-shadow: 0 10px 30px rgba(0,0,0,.6);
  opacity: 0; transform: translateX(-50%); transition: opacity .1s;
}
/* Hidden tips take no space, so a tip near the board edge can never add a scrollbar and resize the board. */
.tip:not(.show) { display: none; }
.tip.show { opacity: 1; }
.tip.above { transform: translate(-50%, -100%); }
.tip b { display: block; font-size: 14px; color: #f3e2c0; }
.tip small { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }
.tip p { margin: 6px 0 0; font-size: 14px; }
.tip .status { color: var(--accent); margin-top: 6px; }

.hint { color: var(--muted); font-size: 14px; margin: 12px 2px 0; }

/* Side panels */
.side { display: grid; gap: 14px; align-content: start; }
.panel { padding: 16px; background: var(--panel); border: 1px solid var(--line); }
.panel h2 { margin: 0 0 12px; font: 600 15px/1.35 "IBM Plex Sans", system-ui, sans-serif; color: var(--text); }
.panel p { margin: 6px 0; }
.muted { color: var(--muted); font-size: 14px; }

.ladder { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin-bottom: 12px; }
.ladder button { padding: 7px 0; text-align: center; font-size: 13px; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); cursor: pointer; transition: border-color .12s, color .12s; }
.ladder button:hover { border-color: var(--muted); color: var(--text); }
.ladder button.done { color: var(--text); }
.ladder button.now { background: var(--text); border-color: var(--text); color: var(--bg); font-weight: 600; }
.ladder button:active, .btn:active:not(:disabled) { transform: translateY(1px); }

.xp { display: flex; gap: 3px; margin: 8px 0 4px; }
.xp i { flex: 1; height: 8px; background: var(--panel-2); }
.xp i.on { background: var(--accent); }
.xp i.gap { margin-left: 6px; }
.stat-line { display: flex; justify-content: space-between; font-size: 14px; }
.stat-line b { font-variant-numeric: tabular-nums; }

.buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.btn {
  padding: 8px 14px; border: 1px solid var(--line); background: var(--panel-2); cursor: pointer; transition: border-color .12s, filter .12s;
}
.btn:hover:not(:disabled) { border-color: var(--muted); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px); }
.btn.primary:hover:not(:disabled) { filter: brightness(1.08); }
.btn:disabled { opacity: .45; cursor: default; }
.btn.small { padding: 5px 10px; font-size: 13px; }

.track { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.track li { padding: 10px 12px; background: var(--panel-2); border: 1px solid transparent; }
.track li.on { border-color: #4a4030; }
.track li.on b { color: #f08a6e; }
.track li.off { opacity: .5; }
.track b { font-size: 14px; }
.track small { display: block; color: var(--muted); font-size: 13px; }

.list { margin: 0; padding-left: 18px; font-size: 14px; }
.list li { margin: 3px 0; }
.list .sec-title { color: var(--c, inherit); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
.chip { padding: 3px 8px; border: 1px solid var(--line); font-size: 13px; }

.row-controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.row-controls select { padding: 7px 8px; background: var(--panel-2); border: 1px solid var(--line); }
.card { margin-top: 12px; padding: 12px; background: var(--panel-2); border: 1px solid var(--loot); }
.card h3 { margin: 0 0 4px; font-size: 15px; }
.legend { display: flex; gap: 8px 14px; flex-wrap: wrap; margin-top: 12px; font-size: 13px; color: var(--muted); }
.legend i { display: inline-block; width: 10px; height: 10px; margin-right: 6px; vertical-align: -1px; }

.toast {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%) translateY(20px); max-width: min(560px, calc(100% - 32px));
  padding: 10px 16px; background: var(--text); color: var(--bg); font-size: 14px;
  opacity: 0; pointer-events: none; transition: opacity .15s, transform .15s;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.bad { background: var(--bad); color: #1d0d09; }

/* Embedded in the case-study page (?embed): no page title, the picker sits on the left. */
.embed body { background: transparent; }
.embed .top { justify-content: flex-start; border-bottom: 0; padding-top: 4px; }
.embed .title { display: none; }
.embed .layout { padding-bottom: 8px; }
