/* NI6-only additions. report.css (linked first) provides the tokens, cards,
   buttons, chat and settings chrome — the desk keeps the workshop's taste. */
#ni6-root { max-width: 1080px; margin: 0 auto; padding: 18px 14px 60px; }

/* report.css hides .b-sub below 640px (dashboard topbar economy); on NI6 it
   carries the green letterhead line (Cognitor Incognitus) the desk wants shown
   at every width. #id specificity wins over report.css without !important;
   inline (not block) so it doesn't double-space against the existing <br>. */
#rp-topbar .b-sub { display: inline; }

/* The desk's letterhead line — an engraving, not a banner. */
.ni6-motto {
  font-family: var(--font-carve); font-weight: 600; font-size: 11.5px;
  letter-spacing: 0.3em; text-transform: uppercase; color: var(--gold-deep);
  margin: 0;
}
.ni6-motto-row {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 2px 2px 12px;
}
.ni6-motto-spy { width: 44px; height: auto; flex: 0 0 auto; }

.ni6-tabs { display: flex; gap: 8px; margin: 6px 0 16px; }
.ni6-tab {
  font-family: var(--font-gob); font-weight: 600; font-size: 13px;
  letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--card); color: var(--dim);
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 16px;
  cursor: pointer;
}
.ni6-tab.active {
  color: #241804; border-color: var(--gold-deep);
  background: linear-gradient(180deg, var(--gold-bright), var(--gold) 60%, var(--gold-deep));
}

.ni6-form { display: flex; flex-wrap: wrap; gap: 8px; }
.ni6-form input {
  flex: 1 1 160px; min-width: 0;
  background: var(--card-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px;
  font: 14px var(--font-read);
}
.ni6-form input:focus { outline: none; border-color: var(--gold-deep); }
.ni6-blurb { color: var(--dim); font-size: 12.5px; font-style: italic; margin: 8px 2px 16px; }

#vet-root .rp-card, #scan-root .rp-card { margin-bottom: 14px; }

.ni6-idrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ni6-idname { font-family: var(--font-carve); font-weight: 700; font-size: 20px; }
.ni6-badge {
  font-family: var(--font-gob); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 9px; color: var(--body);
}
/* Spec badge on a prep night. Tinted so a swap reads at a glance beside the
   plain "played N/N" pill; several in a row = the raider changed spec mid-raid. */
.ni6-badge-spec { border-color: var(--gold); color: var(--gold); margin-left: 4px; }
.ni6-note { color: var(--dim); font-size: 12px; font-style: italic; margin-top: 8px; }
/* Re-vet diff line under the verdict strip: prior-look deltas. The ni6-delta
   pills carry the direction; the label+numbers stay ink like everything else. */
.ni6-vetdiff { flex-basis: 100%; }
.ni6-vetdiff .ni6-vd { white-space: nowrap; }
.ni6-trash-cons { font-size: 11.5px; color: var(--body); white-space: nowrap; }

.ni6-stints { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.ni6-stint {
  border: 1px solid var(--line); border-radius: 8px; padding: 4px 9px;
  font-size: 12.5px; color: var(--body); background: var(--card-2);
}
.ni6-flag { color: #e08a6a; }
.ni6-strip-wrap { overflow-x: auto; padding: 6px 0; }
.ni6-legend { display: flex; flex-wrap: wrap; gap: 10px; font-size: 11.5px; color: var(--dim); }
.ni6-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 4px; }

.ni6-delta {
  font-family: var(--font-mono); font-size: 12px; border-radius: 6px;
  padding: 1px 7px; white-space: nowrap;
}
.ni6-delta.up { color: #9fd08a; background: rgba(127, 176, 105, 0.12); }
.ni6-delta.down { color: #e08a6a; background: rgba(224, 138, 106, 0.12); }
.ni6-spark { display: block; }
.ni6-spark .sp-win { fill: rgba(216, 167, 62, 0.10); }
.ni6-spark .sp-career { stroke: var(--gold-deep); stroke-dasharray: 3 3; }
.ni6-spark .sp-line { stroke: var(--gold); fill: none; stroke-width: 1.4; }
.ni6-spark .sp-dot { fill: var(--dim); }
.ni6-spark .sp-last { fill: var(--gold-bright); }
.ni6-nohist { color: var(--dim); font-style: italic; font-size: 12.5px; }

.ni6-bar { position: relative; background: var(--card-2); border: 1px solid var(--hair);
  border-radius: 4px; height: 14px; min-width: 90px; overflow: hidden; }
.ni6-bar i { position: absolute; inset: 0 auto 0 0;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold)); opacity: 0.7; }

/* Healer read: effective-vs-overheal stack + mana-by-source bars. */
.ni6-stack { display: flex; height: 16px; margin-top: 6px; border-radius: 4px;
  overflow: hidden; border: 1px solid var(--hair); background: var(--card-2); }
/* 2px surface gap between the segments so they read as two quantities. */
.ni6-stack i + i { border-left: 2px solid var(--card); }
.ni6-stack .hs-eff { background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
/* Overheal is the de-emphasised REMAINDER of a fill-vs-track meter, not a
   status: high overheal is normal TBC healing (pre-hots, Prayer of Healing),
   so it must not wear --ember/--blood. Neutral dim, low opacity.
   (validated 2026-07-19: gold↔dim ΔE 40 deutan, contrast ≥3:1 on --card) */
.ni6-stack .hs-over { background: var(--dim); opacity: 0.38; }
.ni6-stack-key { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 5px;
  font-size: 12px; color: var(--dim); }
/* The swatch is a SECOND cue — each key entry is also worded. */
.ni6-stack-key span::before { content: ""; display: inline-block; width: 8px;
  height: 8px; border-radius: 2px; margin-right: 6px; vertical-align: 1px; }
.ni6-stack-key .hk-eff::before { background: var(--gold); }
.ni6-stack-key .hk-over::before { background: var(--dim); opacity: 0.45; }

/* Stat-tile + kicker-header pattern (dataviz pass 2026-07-19, healer read):
   generalized to ni6-* on its 2nd use (gear velocity) so both cards share one
   ruleset. hr-* stays as an alias — the healer card's markup is unchanged. */
.hr-tiles, .ni6-tiles { display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
.hr-tile, .ni6-tile { background: var(--card-2); border: 1px solid var(--hair);
  border-radius: 8px; padding: 9px 12px 8px; }
.hr-tile-lbl, .ni6-tile-lbl { font-family: var(--font-gob); font-weight: 500;
  font-size: 10px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--dim); }
.hr-tile-val, .ni6-tile-val { color: var(--ink); font-size: 21px; font-weight: 600;
  line-height: 1.25; margin-top: 2px; }
.hr-tile-off, .ni6-tile-off { color: var(--dim); font-weight: 400; }
.hr-tile-cap, .ni6-tile-cap { color: var(--dim); font-size: 11px; font-style: italic;
  margin-top: 1px; }
.hr-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 28px; align-items: start; }
.hr-h, .ni6-h { font-family: var(--font-gob); font-weight: 500; font-size: 10.5px;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--dim);
  border-bottom: 1px solid var(--line); padding-bottom: 4px; margin-top: 16px; }
/* Class-identity swatch: an 8px dot beside NEUTRAL name text — the mark
   carries identity, the text never wears the data colour. */
.hr-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 6px; vertical-align: 0; }
.hr-waste { font-style: normal; color: var(--ember); }
/* Per-spell net|overheal bar: the group's WIDTH carries gross (share of the
   biggest spell), its two segments carry the net/overheal split — same gold
   and neutral-grey as the whole-night stack above it. Overrides .ni6-bar i,
   which is absolutely positioned and gold by default. */
.ni6-bar .hr-sgroup { position: absolute; inset: 0 auto 0 0; display: flex; }
.ni6-bar .hr-sgroup i { position: static; opacity: 1; }
.ni6-bar .hr-sgroup .sb-net {
  background: linear-gradient(90deg, var(--gold-deep), var(--gold)); opacity: 0.85; }
.ni6-bar .hr-sgroup .sb-over { background: var(--dim); opacity: 0.38; }
.ni6-bar .hr-sgroup i + i { border-left: 2px solid var(--card); }
@media (max-width: 860px) {
  .hr-tiles, .ni6-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hr-grid { grid-template-columns: 1fr; }
}

/* Gear velocity has 2 real KPIs, not 4 — an explicit 2-col override so its
   tiles fill the row edge-to-edge instead of sitting in half of a 4-col
   grid built for the healer card. Scoped to this one card; .hr-tiles/plain
   .ni6-tiles keep their shared repeat(4, ...) above untouched. */
.ni6-tiles.gv-tiles-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Gear-velocity per-slot timeline: up to 3 dots (one per sampled snapshot),
   the connecting segment lit gold where an upgrade happened between them —
   a status pair (--good/upgraded implied by gold, --dim/no-change), never a
   fresh hue, so it reads with the same vocabulary as the rest of the card. */
.gv-tl { display: inline-flex; align-items: center; height: 14px; }
.gv-tl .gv-seg { width: 22px; height: 2px; background: var(--hair); }
.gv-tl .gv-seg.gv-up { background: var(--gold); }
.gv-tl .gv-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--dim); }
.gv-tl .gv-dot:first-child, .gv-tl .gv-dot:last-child { background: var(--body); }

.ni6-manalist { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; }
.ni6-manarow { display: grid; grid-template-columns: minmax(90px, 150px) 1fr auto;
  align-items: center; gap: 10px; font-size: 12.5px; }
/* Each row being its own grid let the value column self-size PER ROW, so the
   1fr bar track absorbed the difference and two equal quantities drew
   different pixel lengths (measured 2026-07-19: 12 distinct track widths in
   one card — fatal for a block whose whole job is comparing bar lengths).
   One shared track set fixes it. Progressive: browsers without subgrid keep
   the previous behaviour rather than losing the layout, and rows stay real
   boxes (NOT display:contents) so their hover tooltips still work. */
@supports (grid-template-columns: subgrid) {
  .ni6-manalist { display: grid; grid-template-columns: minmax(90px, 150px) 1fr auto;
    gap: 4px 10px; }
  .ni6-manarow { grid-column: 1 / -1; grid-template-columns: subgrid; }
}
.ni6-manarow .mn-src { color: var(--body); }
.ni6-manarow .mn-amt { color: var(--dim); font-family: var(--font-mono, monospace);
  font-size: 11.5px; }

.ni6-derived { color: var(--body); font-size: 13px; margin-top: 8px; }
table.rp td .hyg { display: inline-block; width: 15px; height: 15px; vertical-align: -2px; }
table.rp td .hyg svg { width: 100%; height: 100%; }
.hygx { font-style: normal; font-size: 11px; color: var(--dim); margin: 0 4px 0 1px; }
/* "n/a" = the role/class cannot fill this metric. Deliberately quieter than a
   real zero, which is a measurement. */
.hyg-na { opacity: 0.5; font-style: italic; }

@media (max-width: 640px) {
  .ni6-idname { font-size: 17px; }
  .ni6-form button { flex: 1 1 100%; }
}

/* v3: attendance dots */
.ni6-attrow { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.ni6-attrow i { width: 12px; height: 12px; border-radius: 50%; }
.ni6-attrow .att-present { background: var(--gold); }
.ni6-attrow .att-absent { border: 1.5px solid var(--ember); }
.ni6-attrow .att-prejoin { border: 1px solid var(--hair); }

/* v4 E1: the other team's nights — teal + dimmed; absence is only ever
   judged on the candidate's own team's nights. Teal matches Task 11's
   --ni6-home (fallback literal keeps this task standalone). */
.att-other_team { background: var(--ni6-home, #5fa8a0); opacity: .45; }
.ni6-reset { font-size: 15px; }

/* v3: verdict strip */
.ni6-vfl-mount { margin: 0 0 14px; }
.ni6-vchips { display: flex; flex-wrap: wrap; gap: 8px; }
.vchip {
  display: inline-flex; align-items: baseline; gap: 6px; cursor: pointer;
  font-family: var(--font-gob); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; border-radius: 999px; padding: 5px 11px;
  border: 1px solid var(--line); background: var(--card); color: var(--dim);
}
.vchip b { font-weight: 600; }
.vchip span { font-family: var(--font-mono); font-size: 10.5px; text-transform: none; letter-spacing: 0; }
.vchip.good { border-color: #4f7a2b; color: #9fd08a; }
.vchip.warn { border-color: #8a6a1f; color: var(--gold-bright); }
.vchip.bad { border-color: #8a3b26; color: #e08a6a; }
.vchip.off, .vchip.na { opacity: 0.62; }
.ni6-vflags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.vflag {
  font-size: 11.5px; color: #e08a6a; border: 1px solid #8a3b26;
  border-radius: 6px; padding: 2px 8px; background: rgba(224, 138, 106, 0.08);
}
.vflag.ok { color: #9fd08a; border-color: #4f7a2b; background: rgba(127, 176, 105, 0.08); }
/* v3: form + prep depth */
.ni6-volwrap { display: inline-block; vertical-align: middle; }
tr.prep-farm td { opacity: 0.55; }
.dth { display: inline-block; width: 10px; height: 10px; border-radius: 50%;
       margin-right: 3px; border: 1.5px solid var(--hair); }
.dth.solo { background: var(--ember); border-color: var(--ember); }
.dth.wipe { background: var(--hair); }

/* v4: home-guild control (E12) — a normal in-flow card below the tabs (chrome
   from .rp-card); the nav button toggles it. It pushes page content down
   instead of floating over the dossier, so it reads like every other box. */
.ni6-home-wrap { margin-left: auto; display: flex; align-items: center; }
.ni6-home-btn { white-space: nowrap; }
.ni6-home-panel { margin: 0 0 14px; }
.ni6-home-head {
  font-family: var(--font-gob); font-weight: 600; font-size: 12px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--gold-bright);
}
.ni6-home-hint { color: var(--dim); font-size: 12px; font-style: italic; margin: 4px 0 10px; }
.ni6-home-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ni6-home-panel input {
  flex: 1 1 220px; min-width: 0;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
  font: 13px var(--font-read);
}
.ni6-home-panel input:focus { outline: none; border-color: var(--gold-deep); }
.ni6-home-status { display: block; margin-top: 8px; font-size: 12px; color: var(--dim); }
.ni6-home-status.ok { color: #9fd08a; }
.ni6-home-status.err { color: #e08a6a; }

/* v4: vet<->scan pivot buttons (E7) */
.ni6-pivot { margin: 4px 0 12px; }

@media (max-width: 640px) {
  .ni6-home-wrap { margin-left: 0; flex: 1 1 100%; }
}

/* v4: small secondary Δ chip (E9 "vs career ±N") */
.ni6-delta-sm { font-size: 10.5px; padding: 0 5px; margin-left: 2px; }

/* v4: home-guild hue + blended "both" state (E11/E13). --ni6-home is a muted
   teal chosen to sit clearly apart from --gold/--green/--ember in this warm
   wood-black palette; --ni6-both is a third, visually distinct blend color
   (not a pattern — simplest CSP-safe choice per the design note) for
   schedule cells where the candidate AND the home guild both raid — a
   violet, since the original gold-family value sat too close to
   --gold/candidate-gold to read as its own state at a glance. */
.ni6-lane-wrap, .ni6-strip-wrap { --ni6-home: #5fa8a0; --ni6-both: #9b7fd4; }
:root { --ni6-home: #5fa8a0; --ni6-both: #9b7fd4; }
.ni6-lane { display: block; }
.ni6-lane-legend i[style*="border-radius: 0"] { border-radius: 0 !important; height: 2px; margin-top: 3px; }

/* v4 (post-ship): raid-clock side reading — fills the space right of the heat
   grid with the candidate's recurring nights and how they fit against yours. */
.ni6-clock { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.ni6-clock .ni6-strip-wrap { flex: 0 0 auto; padding: 0; }
.ni6-clock-side { flex: 1 1 200px; min-width: 180px; }
.ni6-clock-fit {
  font-family: var(--font-carve); font-weight: 700; font-size: 15px;
  color: var(--gold-bright); margin-bottom: 4px;
}
.ni6-clock-sub {
  font-family: var(--font-gob); font-size: 10.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--dim); margin: 12px 0 5px;
}
.ni6-clock-list { display: flex; flex-wrap: wrap; gap: 6px; }
.ni6-clock-night {
  font-family: var(--font-mono); font-size: 12px; color: var(--body);
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 8px;
  background: var(--card-2); white-space: nowrap;
}
.ni6-clock-night.hit { color: #9fd08a; border-color: #4f7a2b; }
.ni6-clock-night.miss { color: #e08a6a; border-color: #8a3b26; }

/* v4 (post-ship): counterparts — candidate vs same-spec home-guild members */
.ni6-cp-head { font-size: 14px; color: var(--body); margin-bottom: 8px; }
.ni6-cp-head b { font-family: var(--font-carve); font-weight: 700; color: var(--gold-bright); }
.ni6-cp-gap { color: #9fd08a; font-weight: 600; }
.ni6-cp-rows { display: flex; flex-direction: column; gap: 4px; }
.ni6-cp-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ni6-cp-label {
  font-family: var(--font-gob); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--dim); min-width: 62px;
}
.ni6-cp-val {
  font-family: var(--font-mono); font-size: 14px; min-width: 44px;
}
/* Parse values carry a .p-* band class (report.css) — identical coloring to
   the Form window parses. Gold is only for non-parse values (All-stars pts);
   .p-* wins over this since it is set directly on the same span. */
.ni6-cp-plain { color: var(--gold-bright); }
.ni6-cp-guild { font-size: 12px; color: var(--dim); }
.ni6-cp-util { color: var(--body); font-size: 12.5px; margin-top: 8px; }
.ni6-cp-util:empty { margin: 0; }
.ni6-cp-utlabel {
  font-family: var(--font-gob); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--dim);
}

/* v5a: verdict honesty + banner + copy */
.vchip.thin { border-style: dashed; opacity: 0.85; }
.ni6-home-banner { border: 1px dashed var(--line); border-radius: 8px;
  padding: 8px 12px; margin: 0 0 12px; }
.ni6-copy-sum { margin-top: 8px; }

/* v5a: zone checklist */
.ni6-zonechk .zc-out { opacity: 0.55; }

/* wave3 3.6 (F1 fix): gem color-coding. renderGear emits ni6-gem-<color>
   (color.toLowerCase()) for each socketed gem's closed color enum (Red/
   Blue/Yellow/Green/Orange/Purple/Meta) — this task's brief omitted
   ni6.css from its file list, so these classes had no rule and rendered in
   default text color. Hues picked to read distinctly against this page's
   warm wood-black surfaces (--bg/--card-2) without colliding with the
   existing status hues (--good/--bad/--ni6-home/--ni6-both above). */
.ni6-gem-red { color: #e0645c; }
.ni6-gem-orange { color: #e8934a; }
.ni6-gem-yellow { color: #d9c94a; }
.ni6-gem-green { color: #7fc482; }
.ni6-gem-blue { color: #5aa8e0; }
.ni6-gem-purple { color: #b481d6; }
.ni6-gem-meta { color: #d9d3f2; }

/* Wave 4 — attendance era + guild-health strip */
.ni6-ghealth-warn { color: #d2846a; }

/* Wave 4 — compare mode */
.cmp-wrap { overflow-x: auto; }
.cmp-head { display: flex; gap: 24px; align-items: baseline; margin: 10px 0; }
.cmp-name { display: flex; gap: 10px; align-items: baseline; }
table.cmp-table td.cmp-better { font-weight: 700; color: #d8a73e; }
tr.cmp-cap td { padding-top: 12px; font-family: Oswald, sans-serif;
  letter-spacing: .05em; text-transform: uppercase; font-size: .78em; opacity: .7; }
td.cmp-chips { vertical-align: top; }
.cmp-chips-inner { display: flex; flex-wrap: wrap; gap: 4px; }

/* compare visual blocks (candidate pair CVD-validated dark-mode vs --card
   #1d1610: lightness band, chroma floor, CVD ΔE, contrast — see task-3 report) */
:root { --cmp-a: #0b906e; --cmp-b: #b26144; }
.cmp-block { margin: 14px 0; }
.cmp-block-title { font-family: Oswald, sans-serif; font-size: 13px;
  letter-spacing: .04em; text-transform: uppercase; opacity: .8; margin-bottom: 6px; }
.cmp-legend { font-size: 12px; opacity: .75; margin-bottom: 4px; }
.cmp-legend .sw { display: inline-block; width: 10px; height: 10px;
  border-radius: 2px; margin: 0 4px 0 10px; vertical-align: -1px; }
.cmp-legend .sw.a { background: var(--cmp-a); }
.cmp-legend .sw.b { background: var(--cmp-b); }
.cmp-vgrid { display: grid; grid-template-columns: 150px 1fr 110px;
  gap: 4px 10px; align-items: center; font-size: 12px; }
.cmp-vlabel { opacity: .8; }
.cmp-track { background: rgba(255,255,255,.06); border-radius: 2px; height: 7px; }
.cmp-track + .cmp-track { margin-top: 2px; }
.cmp-bar { height: 7px; border-radius: 2px; }
.cmp-bar-a { background: var(--cmp-a); }
.cmp-bar-b { background: var(--cmp-b); }
.cmp-vnums { font-family: "Space Mono", monospace; font-size: 11px; }
.cmp-jw-sub { font-family: Oswald, sans-serif; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; opacity: .6; margin: 10px 0 4px; }
.cmp-vwin-a, .cmp-vwin-b { font-weight: 700; }
.cmp-delta { font-family: "Space Mono", monospace; font-size: 11px;
  opacity: .75; margin-left: 6px; }
.cmp-db-grid { stroke: rgba(255,255,255,.08); }
.cmp-db-conn { stroke: rgba(255,255,255,.35); stroke-width: 2; }
.cmp-db-boss, .cmp-db-axis { fill: currentColor; font-size: 11px; opacity: .8; }
.cmp-dot-a { fill: var(--cmp-a); }
.cmp-dot-b { fill: var(--cmp-b); }
.cmp-dot-hollow { fill: none; stroke-width: 2; }
.cmp-dot-hollow.cmp-dot-a { stroke: var(--cmp-a); }
.cmp-dot-hollow.cmp-dot-b { stroke: var(--cmp-b); }
.cmp-strip-tick-a { fill: var(--cmp-a); }
.cmp-strip-tick-b { fill: var(--cmp-b); }
.cmp-strip-tick-abs { fill: rgba(255,255,255,.22); }
.cmp-strip-era-a { fill: var(--cmp-a); opacity: .12; }
.cmp-strip-era-b { fill: var(--cmp-b); opacity: .12; }
.cmp-strip-label, .cmp-strip-chip { fill: currentColor; font-size: 11px; opacity: .8; }
.cmp-grid { display: grid; gap: 3px; font-size: 10px; }
.cmp-grid-cell { height: 18px; border-radius: 3px; background: rgba(255,255,255,.05); }
.cmp-grid-cell.a { background: var(--cmp-a); opacity: .8; }
.cmp-grid-cell.b { background: var(--cmp-b); opacity: .8; }
.cmp-grid-cell.both { background: #b08d4f; }
.cmp-grid-cell.home { outline: 2px solid #efb54a; outline-offset: -2px; }
.cmp-grid-head, .cmp-grid-hour { opacity: .7; align-self: center; }
.cmp-jw-note { font-size: 12px; opacity: .8; margin-top: 6px; }
.cmp-jw-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; font-size: 12px; }

/* ── compare "first look" card (2026-07-24 spec): one bounded summary card
   above the compare header/blocks. Verbatim payload numbers only. */
.cmp-flook { border: 1px solid rgba(255,255,255,.14); border-radius: 8px;
  padding: 14px 16px; margin: 10px 0 18px; background: rgba(255,255,255,.03); }
.cmp-fl-head { display: flex; gap: 24px; align-items: baseline;
  justify-content: space-between; flex-wrap: wrap; }
.cmp-fl-name { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.cmp-fl-name .specicon { width: 18px; height: 18px; border-radius: 3px;
  align-self: center; }
/* Side swatch: the name keeps its class colour, so this is what ties a name
   to its bars (same a/b swatch the block legend uses). */
.cmp-fl-name .sw { width: 10px; height: 10px; border-radius: 2px;
  align-self: center; flex: none; }
.cmp-fl-name .sw.a { background: var(--cmp-a); }
.cmp-fl-name .sw.b { background: var(--cmp-b); }
/* Paired tally rows (endboss kills). Compound selector so the b-side colour
   wins wherever .vfl-pip sits in this file. */
.cmp-fl-pips { min-height: 7px; }
.cmp-fl-pips + .cmp-fl-pips { margin-top: 2px; }
.vfl-pip.cmp-pip-b { background: var(--cmp-b); }
.cmp-fl-sub { font-size: 12px; opacity: .75; }
.cmp-fl-chips { display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin-top: 8px; }
.cmp-fl-chipcol { display: flex; flex-wrap: wrap; gap: 4px; align-content: flex-start; }
.cmp-fl-grid { margin-top: 10px; }
.cmp-fl-line { display: grid; grid-template-columns: 110px 1fr; gap: 8px;
  font-size: 12px; margin-top: 6px; align-items: baseline; }
.cmp-fl-linelabel { font-family: Oswald, sans-serif; font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em; opacity: .65; }
.cmp-fl-lineval { font-family: "Space Mono", monospace; font-size: 11.5px; }
.cmp-fl-a { color: var(--cmp-a); }
.cmp-fl-b { color: var(--cmp-b); }
.cmp-fl-sep { opacity: .55; }
.cmp-fl-jw-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  font-size: 12px; }
.cmp-fl-gearflag { border: 1px solid #8a6a1f; border-radius: 4px;
  padding: 1px 6px; margin-right: 6px; color: var(--gold-bright); }

/* ── vet "first look" solo card (2026-07-24 spec): same cmp-fl family, one
   candidate, absorbs the verdict strip. Bars/dots/ticks structural; every
   printed number verbatim. Task-2/3 visual-zone rules append HERE (this
   group), never after the clearance gate below. */
.vet-fl .cmp-fl-chips { grid-template-columns: 1fr; }
.ni6-vfl-mount .cmp-flook { margin: 10px 0 0; }  /* mount owns the 14px bottom gap */
.vfl-verdict { margin-top: 8px; }

/* solo bar rail: one bar (0-100 or own-max) + optional gold hollow marker
   (career best on the window-median rail). Marker/pips/dots/ticks are
   structural; the printed number is the payload field. */
.vfl-grid { grid-template-columns: 150px 1fr 130px; }
.vfl-rail { position: relative; }
/* A TICK, never a ring. As a hollow circle this sat flush against the number
   column whenever the marked value was near 100 (a 99.56 career best lands at
   99.6% of the rail) and read as a leading zero -- reported live 2026-07-31 as
   "what is that 0 just leftside of the median number". A 2px vertical bar
   cannot be mistaken for a digit at any position. */
.vfl-mark { position: absolute; top: -3px; width: 2px; height: 13px;
  background: var(--gold-bright); transform: translateX(-50%); }
.vfl-pips { display: flex; gap: 3px; align-items: center; }
.vfl-pip { width: 7px; height: 7px; border-radius: 50%; background: var(--cmp-a); }
/* Utility zone: credit-only rows read quieter than the ones the spec is
   actually accountable for (declared after .cmp-vlabel so this opacity wins). */
.vfl-util { margin-top: 10px; }
.vfl-credit { opacity: .5; }
/* "assigned" rows stay full opacity (a real job) but carry this small tag so
   a zero there never reads as a miss — same dim/uppercase language as the
   note lines below, not a new colour. */
.vfl-tag { font-family: Oswald, sans-serif; font-size: 9px; font-style: normal;
  text-transform: uppercase; letter-spacing: .04em; color: var(--dim); margin-left: 5px; }
.vfl-noop { font-size: 11px; color: var(--dim); }
/* Task 5: a flagged duty row (an `expected` job, zero count) -- the ONE
   red tone on this card. Applied to both the label (.vfl-flagged) and the
   note text (.vfl-flag) so the finding reads even if a reader only sees
   one half of the row. */
.vfl-flagged { color: var(--bad); }
.vfl-flag { font-size: 11px; color: var(--bad); font-weight: 600; }
/* I5 (2026-07-26 review): the "+N more in Utility" link that appears when
   the first-look card's credit-tier rows are capped -- same size/colour as
   the note lines above, underlined + pointer to read as clickable. */
.vfl-more { display: block; font-size: 11px; color: var(--dim); margin-top: 6px;
  text-decoration: underline; cursor: pointer; background: none; border: none;
  padding: 0; text-align: left; font-family: inherit; }
.vfl-more:hover { color: var(--gold-bright); }
.vfl-dots { display: inline-flex; gap: 3px; margin-right: 8px; vertical-align: middle; }
.vfl-dot { width: 8px; height: 8px; border-radius: 50%;
  background: rgba(255,255,255,.25); display: inline-block; }
.vfl-dot-cand { background: var(--cmp-a); outline: 2px solid var(--gold-bright);
  outline-offset: 1px; }
.vfl-strip { display: inline-block; margin-right: 8px; vertical-align: middle; }
.vfl-strip-bg { fill: rgba(255,255,255,.05); }
.vfl-tick { fill: var(--cmp-a); }

/* Task 6 (2026-07-27 wave): peer-relative bars for the utility zone's
   class/profession/racial rows, replacing the old raid-total-share bars
   (a single-cast job used to draw a false 100%). Grey track = the peer
   pool's own 0-100 (cand_rate/max_rate); tick = pool median at the same
   scale; bar colour is set inline per-row to the candidate's class colour. */
.vfl-track { background: rgba(255,255,255,.06); border-radius: 2px; height: 7px; }
.vfl-track-bar { height: 7px; border-radius: 2px; }
/* D-4 (2026-08-07 role-pools/avoidable-readability wave): a trash-measured
   row draws its bar as two segments instead of one -- solid boss, hatched
   trash -- sized off the SAME t.count/t.trash_count the text beside the bar
   already prints (vflUtilRow), never a new field. inline-block so the two
   sit flush left-to-right with no gap (they're appended with no whitespace
   text node between them, so the classic inline-block gap doesn't apply).
   Corners round on the outer edge only, so a full-width single segment
   (the other at 0) reads slightly squared on its inner edge -- a cosmetic
   trade, not worth a JS conditional-radius branch. */
.seg-boss, .seg-trash { display: inline-block; vertical-align: top; height: 7px; }
.seg-boss { border-radius: 2px 0 0 2px; }
.seg-trash { border-radius: 0 2px 2px 0;
  background-image: repeating-linear-gradient(45deg, currentColor 0 2px, transparent 2px 4px); }
.vfl-tickmark { position: absolute; top: -3px; width: 2px; height: 13px;
  background: var(--gold-bright); transform: translateX(-50%); border-radius: 1px; }
.vfl-rank { color: var(--gold-bright); }
/* IMPORTANT-1 fix (2026-08-07 wave review): nowrap scoped OFF .vfl-rank --
   vflUtilRow's zero_rate branch reuses this SAME class for two full
   sentences ("nobody in the pool did this" / "did none — some in the pool
   did", up to 31 chars), and nowrap on those overflowed .vfl-grid's fixed
   130px numbers track, giving the whole card a horizontal scrollbar (a
   regression on the Totem of Wrath expected-zero case that created this
   class in the first place). Only a true "12th of / 12" ordinal -- which
   must never wrap between its own words -- gets this second, additive
   class; the prose branch keeps plain .vfl-rank and keeps wrapping. */
.vfl-rank-ord { white-space: nowrap; }
/* Criticals 1-2 (2026-07-27 review): the pool description moved off the
   group header (a group can mix pools, so no header claim could stay true)
   onto each row's own numbers cell, right after its rank. */
.vfl-ranktag { font-size: 9.5px; color: var(--dim); font-style: italic; }
.vfl-sec { display: block; font-size: 9.5px; color: var(--dim); margin-top: 2px; }
/* D-3: the basis pill names the comparison POOL a rank is measured against
   -- t.basis (the evidence TIER: expected/assigned/credit, dimming/tagging
   above) is a different field entirely, untouched here. Steel-hue ramp,
   three lightness steps, deliberately NOT green/amber/ember (the verdict
   vocabulary elsewhere on this card): a pool basis is not a verdict. */
:root { --basis-spec: #8fb8d4; --basis-class: #5f8098; --basis-users: #4a5560; }
/* `display: table`: block-level for line-breaking (the pill always starts
   its own line, spec requirement) while still shrink-wrapping to its text
   -- a bare `display: block` would stretch the pill's rounded outline to
   the numbers column's full width.
   IMPORTANT-2 fix (2026-08-07 wave review): this used to be an OUTLINE
   pill -- transparent background, the ramp colour read as 8.5px `color`
   text against --card. Measured then: --basis-spec 8.5:1 pass,
   --basis-class 4.3:1 marginal fail, --basis-users 2.35:1 fail by ~2x --
   backwards, since `users` is the pool kind on the MAJORITY of rows
   (Interrupts/Purges/Dispels/Drums/every potion/engineering/racial row).
   Spec decision: the three custom properties above stay the ramp's
   identity colour (unchanged hex, steel hue, three-step lightness order),
   now rendered as a SOLID FILL with a per-step ink chosen from near-black/
   near-white so every step clears AA 4.5:1 against ITS OWN fill (the
   binding constraint) -- measured #8fb8d4 + #000000 ink = 9.97:1,
   #5f8098 + #000000 ink = 5.03:1, #4a5560 + #ffffff ink = 7.61:1, all
   comfortably over the 4.5 floor, so no ramp hex itself needed to move.
   No border: the fill now IS the pill's boundary, and a currentColor ring
   would draw in the INK colour instead of the ramp hue, undoing the point
   of a colour-coded ramp. */
.pill { display: table; font-family: Oswald, sans-serif; font-size: 8.5px;
  letter-spacing: .05em; text-transform: uppercase; border-radius: 999px;
  padding: 1px 7px; margin-top: 3px; }
.pill-spec { background: var(--basis-spec); color: #000000; }
.pill-class { background: var(--basis-class); color: #000000; }
.pill-users { background: var(--basis-users); color: #ffffff; }
/* Task 5b (2026-08-07 role-pools wave, final-review fold-in): avoidable
   damage's role pool (vflAvoidablePill) used to share .pill-class with
   utility's "widened past same-spec" state -- a role pool is the opposite,
   D-1's single designed basis for this metric, not a loosened comparison.
   Same ramp colour/ink as .pill-class (still the middle lightness step,
   AA-verified above), distinct selector so the two meanings stop sharing
   one class. */
.pill-role { background: var(--basis-class); color: #000000; }
/* Category group headers -- Class job / Profession / Racial -- only the
   non-empty ones render. Title only (no pool claim -- see .vfl-ranktag). */
.vfl-grouphead { grid-column: 1 / -1; display: flex;
  align-items: baseline; gap: 8px; font-family: Oswald, sans-serif; font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gold);
  margin: 10px 0 3px; border-bottom: 1px solid rgba(255,255,255,.08); padding-bottom: 3px; }
/* D5 (2026-07-28 wave, Task 7): totem rotation collapses to one line, no
   bar/pool -- spans the whole row grid like .vfl-grouphead, since this
   block has no label column of its own. */
.vfl-rotation-line { grid-column: 1 / -1; font-family: "Space Mono", monospace;
  font-size: 11px; color: var(--dim); margin-bottom: 4px; }
/* Sunder effective/wasted nest as indented sub-rows under Sunder Armor. */
.vfl-sublab { padding-left: 14px; opacity: .6; }
/* One legend, keyed to the swatches, replacing the old stacked per-condition
   notes (.vfl-utnote removed with them -- no other caller used it). */
.vfl-legend { font-size: 10.5px; color: var(--dim); margin-top: 10px; line-height: 1.6;
  border-top: 1px solid rgba(255,255,255,.08); padding-top: 8px; }
.vfl-sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  vertical-align: -1px; margin: 0 3px; }
.vfl-sw-tick { width: 2px; height: 11px; background: var(--gold-bright);
  vertical-align: -2px; }
/* IMPORTANT-1 fix (2026-08-08 final-fixes wave): the legend had a swatch for
   the bar colour and the tick but none for D-4's hatch (seg-trash's own
   pattern, above) -- same currentColor repeating-linear-gradient so this
   swatch matches what the bar actually draws, in the candidate's own colour
   (set inline via .style.color, same as segTrash). */
.vfl-sw-hatch { background-image:
  repeating-linear-gradient(45deg, currentColor 0 2px, transparent 2px 4px); }

/* 7-day slot grid: Mon..Sun; filled = the candidate's recurring raid nights
   (≥2 session starts on that weekday — the same recurrence threshold
   scheduleMatch applies to the home guild's slots); gold ring = a home-guild
   recurring night, ✓/✗ = whether the candidate's raid hours touch it. */
.vfl-week { display: inline-flex; gap: 3px; margin-right: 8px; vertical-align: middle; }
.vfl-slot { width: 16px; height: 16px; border-radius: 3px; box-sizing: border-box;
  background: rgba(255,255,255,.05); font-style: normal; font-size: 10px;
  line-height: 16px; text-align: center; color: var(--gold-bright); }
.vfl-slot.on { background: var(--cmp-a); opacity: .85; color: #141009; }
.vfl-slot.home { outline: 2px solid var(--gold-bright); outline-offset: -2px; }

/* Task 6 (2026-08-05 avoidable-damage wave): per-mechanic sub line and the
   two special-state number treatments. Grepped first -- no .vfl-sub/
   .vfl-caveat equivalent existed, so these are new (ad- prefixed, this
   section's own). */
.ad-sub { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 10.5px;
  color: var(--dim); padding-left: 14px; margin-top: -2px; }
/* MINOR-4 fix (Task 5b review): mirrors .vfl-rank-ord (IMPORTANT-1, Task 5
   review) for the avoidable-damage rank phrase -- "4th-lowest of 12" broke
   mid-phrase in prod the same way utility's "12th of / 12" did. Scoped to
   this second, additive class rather than onto .ad-sub itself: .ad-sub
   carries full sentences, and blanket nowrap there is exactly the
   IMPORTANT-1 defect (a horizontal scrollbar on the card). */
.ad-rank-ord { white-space: nowrap; }
.ad-belowfloor { font-style: italic; color: var(--dim); }
.ad-caveat { grid-column: 1 / -1; font-size: 11px; color: var(--dim); font-style: italic;
  margin-top: 8px; border-top: 1px solid var(--hair); padding-top: 7px; }

/* ── Clearance gate — comedy, not security (spec 2026-07-24) ─────────────── */
/* Ships HIDDEN and ni6.js opts it in (.ni6-gate-on) — the reverse would flash
   TOP SECRET at every already-cleared visitor, since the overlay paints as soon
   as it parses but nothing can remove it until ni6.js runs at the end of body
   (strict CSP: no inline head script to check localStorage before first paint). */
/* The document unrolls to its FULL height and the overlay is what scrolls —
   one continuous parchment, not a viewport-height window with the terms
   trapped in an inner scroller (which stranded Accept/Deny below the fold on
   a phone). `align-items: flex-start` + `margin: auto 0` on the wrap is the
   safe centring pattern for a scrollable flex container: the auto margins
   centre a short card (the DENIED state) and collapse to 0 when the content
   is taller, where `align-items: center` would clip the top out of reach. */
#ni6-gate {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(10, 8, 5, 0.96);
  display: none; align-items: flex-start; justify-content: center;
  padding: 42px 18px 24px; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  transition: opacity 0.3s ease;
}
#ni6-gate.ni6-gate-on { display: flex; }
#ni6-gate.ni6-gate-fade { opacity: 0; pointer-events: none; }
/* Top padding above leaves room for Fizzwick, who hangs 30px over the edge. */
.ni6-gate-wrap { position: relative; max-width: 560px; width: 100%; margin: auto 0; }
.ni6-gate-card {
  background: var(--card); border: 1px solid var(--gold-deep);
  border-radius: 10px; padding: 26px 28px 22px;
  font-family: "Space Mono", monospace; font-size: 13.5px; line-height: 1.55;
  color: var(--ink);
}
.ni6-gate-stamp {
  display: inline-block; transform: rotate(-6deg); transform-origin: left bottom;
  font-family: var(--font-carve); font-weight: 800; font-size: 15px;
  letter-spacing: 0.35em; text-transform: uppercase;
  color: var(--gold-bright); border: 2px solid var(--gold-bright);
  border-radius: 4px; padding: 4px 10px; margin: 0 0 14px 2px; opacity: 0.85;
}
.ni6-gate-stamp-red { color: #e5484d; border-color: #e5484d; font-size: 19px; }
.ni6-gate-head {
  font-family: var(--font-carve); font-size: 17px; letter-spacing: 0.08em;
  text-transform: uppercase; margin: 0 0 4px; color: var(--gold-bright);
}
.ni6-gate-class {
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--dim); margin: 0 0 14px;
}
.ni6-gate-articles { margin: 12px 0; padding-left: 0; list-style: none; }
.ni6-gate-articles li { margin: 6px 0; }
.ni6-gate-fine { color: var(--dim); font-size: 12px; }
.ni6-gate-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.ni6-gate-actions .rp-btn { text-decoration: none; }
/* Fizzwick peeks over the card's top edge (cloned by ni6.js from the letterhead) */
.ni6-gate-spy { position: absolute; top: -30px; right: 22px; width: 64px; height: auto; }
body.ni6-gate-lock { overflow: hidden; }
