/* gh-polish.css - TPA "POLISH" (2026-09-27), items A-D. Layered AFTER gh-design.css, gh-site.css and each page's own <style>.
   Rollback = remove the two includes (this file + gh-polish.js). Nothing here changes a token in gh-design.css.
   Brand (binding): blue #002B7F, midnight #0B1640, yellow #FCD116, red #CE1126, ink #16191F, paper #FFFFFF.
   The hero gradient (blue -> midnight, top -> bottom) is for the nav bar and the hero ONLY. Tricolour only as a thin edge.
   Yellow = emphasis/focus, red = generated/warnings. Every motion plays once and stops; none runs under reduced motion.
   Scopes: body.gh = the gh-design pages (home, posits, full proof, hull, site index, /verify/, /v/);
           .stage > .room = the Evidence Room (its own design; left in its own fonts). */

:root {
  --ghp-blue: #002B7F; --ghp-mid: #0B1640; --ghp-yel: #FCD116; --ghp-red: #CE1126; --ghp-ink: #16191F; --ghp-paper: #FFFFFF;
  --ghp-hero: linear-gradient(180deg, #002B7F 0%, #0B1640 100%);
  --ghp-tri: linear-gradient(90deg, #002B7F 0 33.333%, #FCD116 33.333% 66.666%, #CE1126 66.666% 100%);
  /* glass on a dark ground (default) */
  --ghp-glass: linear-gradient(180deg, rgba(255,255,255,.13) 0%, rgba(255,255,255,.05) 100%);
  --ghp-glass-bd: rgba(255,255,255,.24);
  --ghp-glass-hi: rgba(255,255,255,.22);
  --ghp-glass-sh: rgba(0,0,0,.45);
}
@property --ghp-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

/* ======================================================================================================================
   D. The hero blue: nav bar + hero only
   ==================================================================================================================== */
/* the full-proof page painted the gradient on the whole body (2026-09-27 brand pass); the gradient now belongs to nav + hero */
:root:not([data-theme="light"]) body.gh { background: var(--bg); }

body.gh .gh-nav {
  position: relative; align-items: center; gap: .45rem .45rem;
  background: var(--ghp-hero); color: #FFFFFF;
  padding: .6rem .75rem .75rem; border: 1px solid rgba(255,255,255,.14); border-radius: 14px;
  box-shadow: 0 12px 30px -20px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.12);
  overflow: hidden;
}
/* C: the tricolour as a thin edge under the nav bar */
body.gh .gh-nav::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--ghp-tri); }
/* nav titles framed in glass */
body.gh .gh-nav a {
  color: #FFFFFF; text-decoration: none; font-family: var(--font-ui); font-size: max(15px, .92rem); line-height: 1.3;
  padding: .38rem .8rem; border-radius: 999px;
  background: var(--ghp-glass); border: 1px solid var(--ghp-glass-bd);
  box-shadow: inset 0 1px 0 var(--ghp-glass-hi);
  -webkit-backdrop-filter: blur(8px) saturate(140%); backdrop-filter: blur(8px) saturate(140%);
  transition: background-color .2s, border-color .2s;
}
body.gh .gh-nav a:hover { background-color: rgba(255,255,255,.12); border-color: rgba(255,255,255,.5); }
body.gh .gh-nav a[aria-current="page"] { border-color: var(--ghp-yel); }
body.gh .gh-nav a:focus-visible { outline: 3px solid var(--ghp-yel); outline-offset: 2px; }
body.gh .gh-nav .brand { font-family: var(--font-display); font-size: 1.25rem; font-weight: 700; padding: .2rem .85rem .2rem .25rem; }
body.gh .gh-nav .brand .gh-mark { width: 32px; height: 32px; border-radius: 999px; }

body.gh .gh-hero {
  background: var(--ghp-hero); border-style: solid; border-width: 0 0 3px 0;
  border-image: var(--ghp-tri) 1;   /* C: tricolour thin edge along the bottom (replaces the yellow rule) */
}

/* ======================================================================================================================
   D. Glass frames on every h1/h2/h3 (the site footer's small column labels excepted)
   ==================================================================================================================== */
body.gh main h1, body.gh main h2, body.gh main h3, body.gh .ghv h2,
.stage > .room h1, .stage > .room h2, .stage > .room h3 {
  width: fit-content; max-width: 100%;
  padding: .32em .72em .38em !important; border-radius: 12px;
  background: var(--ghp-glass);
  border: 1px solid var(--ghp-glass-bd) !important;
  box-shadow: inset 0 1px 0 var(--ghp-glass-hi), 0 10px 26px -16px var(--ghp-glass-sh);
  -webkit-backdrop-filter: blur(10px) saturate(140%); backdrop-filter: blur(10px) saturate(140%);
  overflow-wrap: anywhere;
}
/* the system's rules survive inside the frame: blue rule above an H2, red rule under an H3 */
body.gh main h2, body.gh .ghv h2 { border-top: 2px solid var(--rule-blue) !important; }
body.gh main h3 { border-bottom: 2px solid var(--rule-red) !important; }
body.gh main h1 { border-top: 2px solid var(--ghp-yel) !important; }
body.gh summary h3 { display: inline-block; }
body.gh .card h3, body.gh .hm-card h3 { font-size: 1rem; }

/* ======================================================================================================================
   D. Sections: each gets its own ground from the palette (JS groups a heading with what follows it; no JS = no bands,
   everything still readable). Tokens are re-set per band so every system component stays AA on it.
   ==================================================================================================================== */
body.gh .ghp-band {
  display: flow-root; color: var(--fg); background: var(--ghp-band-bg);
  margin: var(--space-4) 0; padding: clamp(1rem, 2.6vw, 1.75rem); border-radius: 16px;
  border: 1px solid var(--ghp-band-bd); border-top: 4px solid var(--ghp-band-edge);
  box-shadow: 0 14px 34px -26px rgba(0,0,0,.8);
}
body.gh .ghp-band > h2:first-child { margin-top: 0; }
body.gh .ghp-band > hr:last-child { display: none; }
body.gh .ghp-band :not(.gh-table-wrap) > table, body.gh .ghp-band > table { display: block; max-width: 100%; overflow-x: auto; }
/* long unbroken strings (URLs, addresses, hashes) wrap instead of pushing the page sideways at phone width */
body.gh main { overflow-wrap: break-word; }
/* the /v/ QR box is white: its caption link in ink-blue, not the page's light link colour (was 1.44:1) */
body.gh .gh-verify-qr a, body.gh .gh-verify-qr code { color: #002B7F; }
body.gh .ghp-band, body.gh .ghp-band * { min-width: 0; }

/* dark grounds */
body.gh .ghp-band.ghp-navy  { --ghp-band-bg: #0B1640; --ghp-band-bd: #22306A; --ghp-band-edge: #8FA4E0;
  --surface: #0A2566; --surface-2: #123489; --witness-row: #123489; --border-soft: #2E4A99; }
body.gh .ghp-band.ghp-royal { --ghp-band-bg: #123489; --ghp-band-bd: #2E4A99; --ghp-band-edge: #DCE4F7;
  --surface: #0A2566; --surface-2: #1B3F9E; --witness-row: #0A2566; --border-soft: #3A57A8; --emphasis: #FFB3BC; --alert: #FFB3BC; }
body.gh .ghp-band.ghp-wine  { --ghp-band-bg: #5E0B1B; --ghp-band-bd: #7A1A2C; --ghp-band-edge: #CE1126;
  --surface: #4A0916; --surface-2: #6E1424; --witness-row: #4A0916; --generated-row: #3A0711; --border-soft: #8A2A3C;
  --emphasis: #FFB3BC; --alert: #FFB3BC; --rule-red: #FF8A96; --rule-blue: #C9D6FF; }
/* light grounds (the gh-design light set, re-scoped to the band) */
body.gh .ghp-band.ghp-gold, body.gh .ghp-band.ghp-paleblue {
  --fg: #1E2126; --fg-muted: #4A4F57; --structure: #002B7F; --deep: #002868;
  --emphasis: #CE1126; --alert: #BF0A30; --seal-text: #7A6300; --seal-word: #9A7D00; --seal-ground: #FFF8D6;
  --surface: #FFFFFF; --surface-2: #EEF1F8; --witness-row: #EEF1F8; --generated-row: #FBEAEC;
  --rule-blue: #002B7F; --rule-red: #CE1126; --link: #002B7F; --focus: #002B7F; --border-soft: #D5D8DF;
  --button-fg: #FFFFFF; --ring-dark: #4A4F57; color-scheme: light;
  --ghp-glass: linear-gradient(180deg, rgba(255,255,255,.85) 0%, rgba(255,255,255,.55) 100%);
  --ghp-glass-bd: rgba(0,43,127,.22); --ghp-glass-hi: rgba(255,255,255,.9); --ghp-glass-sh: rgba(0,20,60,.25);
}
body.gh .ghp-band.ghp-gold     { --ghp-band-bg: #FFF8D6; --ghp-band-bd: #EADFA4; --ghp-band-edge: #FCD116; }
body.gh .ghp-band.ghp-paleblue { --ghp-band-bg: #EEF1F8; --ghp-band-bd: #D5DCEC; --ghp-band-edge: #002B7F; }
body.gh .ghp-band.ghp-gold .gh-chip.pending, body.gh .ghp-band.ghp-paleblue .gh-chip.pending { color: #4A4F57; border-color: #4A4F57; }
body.gh .ghp-band .gh-verify-qr .small { color: #1E2126; }

/* ======================================================================================================================
   A. Controls come alive: a tricolour tracer runs round the Play / Hear it / Run the proof / Listen controls, three turns,
   then fades. It stops for good on the first click, touch, key or focus (gh-polish.js adds .ghp-still). Never under
   reduced motion. CSS only apart from that one class.
   ==================================================================================================================== */
.stage .listen, .stage #play, .stage #sound, .stage #runproof, .ghp-halo { position: relative; }
.stage .listen::after, .stage #play::after, .stage #sound::after, .stage #runproof::after, .ghp-halo::after {
  content: ""; position: absolute; inset: -5px; border-radius: inherit; padding: 3px; pointer-events: none; opacity: 0;
  background: conic-gradient(from var(--ghp-a), #CE1126 0deg, #FCD116 120deg, #002B7F 240deg, #CE1126 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.stage .ctrl#play::after, .stage .ctrl#sound::after { border-radius: 8px; }
@media (prefers-reduced-motion: no-preference) {
  .stage .listen:not(.ghp-still)::after, .stage #play:not(.ghp-still)::after, .stage #sound:not(.ghp-still)::after,
  .stage #runproof:not(.ghp-still)::after, .ghp-halo:not(.ghp-still)::after {
    animation: ghp-trace 2.4s linear .3s 3 both, ghp-life 7.8s ease .3s 1 both;
  }
}
@keyframes ghp-trace { from { --ghp-a: 0deg; } to { --ghp-a: 360deg; } }
@keyframes ghp-life { 0% { opacity: 0; } 6% { opacity: 1; } 88% { opacity: 1; } 100% { opacity: 0; } }
.ghp-still::after { animation: none !important; opacity: 0 !important; }

/* ======================================================================================================================
   B. Data moves: armed only by gh-polish.js (never under reduced motion), so without JS every figure is at rest, complete.
   ==================================================================================================================== */
/* wipes use a sliding mask, not clip-path: IntersectionObserver treats a fully clipped element as never visible */
.ghp-wipe-up, .ghp-wipe-right { -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.ghp-wipe-up.ghp-pre, .ghp-wipe-up.ghp-in {
  -webkit-mask-image: linear-gradient(0deg, #000 50%, transparent 50%); mask-image: linear-gradient(0deg, #000 50%, transparent 50%);
  -webkit-mask-size: 100% 200%; mask-size: 100% 200%; -webkit-mask-position: 0 0; mask-position: 0 0; }
.ghp-wipe-right.ghp-pre, .ghp-wipe-right.ghp-in {
  -webkit-mask-image: linear-gradient(90deg, #000 50%, transparent 50%); mask-image: linear-gradient(90deg, #000 50%, transparent 50%);
  -webkit-mask-size: 200% 100%; mask-size: 200% 100%; -webkit-mask-position: 100% 0; mask-position: 100% 0; }
.ghp-wipe-up.ghp-in    { animation: ghp-rise 1s cubic-bezier(.2,.7,.2,1) both; }
.ghp-wipe-right.ghp-in { animation: ghp-draw 1.3s cubic-bezier(.3,.6,.2,1) both; }
@keyframes ghp-rise { from { -webkit-mask-position: 0 0; mask-position: 0 0; } to { -webkit-mask-position: 0 100%; mask-position: 0 100%; } }
@keyframes ghp-draw { from { -webkit-mask-position: 100% 0; mask-position: 100% 0; } to { -webkit-mask-position: 0 0; mask-position: 0 0; } }
.gh-doll.ghp-pre circle.ring { stroke-dasharray: 100; stroke-dashoffset: 100; }
.gh-doll.ghp-in circle.ring { stroke-dasharray: 100; animation: ghp-ring 1.1s ease-out both; }
.gh-doll.ghp-in circle.ring:nth-child(2) { animation-delay: .12s; } .gh-doll.ghp-in circle.ring:nth-child(3) { animation-delay: .24s; }
.gh-doll.ghp-in circle.ring:nth-child(4) { animation-delay: .36s; }
@keyframes ghp-ring { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
.ghp-count { font-variant-numeric: tabular-nums; }

/* ======================================================================================================================
   C + D. The Evidence Room: lobby in the hero gradient, each room on its own ground from the palette, a thin tricolour edge
   on every room, red accents on the "generated, not measured" notes. Light and dark (the room follows the OS scheme).
   ==================================================================================================================== */
.stage .lobby { background: var(--ghp-hero); }
.stage > .room:not(.full) { border-top: 0; padding-top: 25px; overflow: hidden; }
.stage > .room:not(.full)::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 4px; background: var(--ghp-tri); border-radius: 4px 4px 0 0; }
.stage > #claims1, .stage > #pp005b, .stage > #method { --paper: #EEF1F8; --tint: #FFFFFF; --rule: #D0D8EA; }
.stage > #claims2, .stage > #pp006, .stage > #index   { --paper: #FFF8D6; --tint: #FFFFFF; --rule: #E6DCA6; }
.stage > #pp005, .stage > #pp003                      { --paper: #FBEAEC; --tint: #FFFFFF; --rule: #EDCDD2; }
.stage > .room:not(.full) { --muted: #4E5563; background: var(--paper); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .stage > #claims1, :root:not([data-theme="light"]) .stage > #pp005b, :root:not([data-theme="light"]) .stage > #method { --paper: #0F1D44; --tint: #18285A; --rule: #2A3C73; }
  :root:not([data-theme="light"]) .stage > #claims2, :root:not([data-theme="light"]) .stage > #pp006, :root:not([data-theme="light"]) .stage > #index { --paper: #262108; --tint: #353012; --rule: #4A4320; }
  :root:not([data-theme="light"]) .stage > #pp005, :root:not([data-theme="light"]) .stage > #pp003 { --paper: #33101A; --tint: #451A26; --rule: #5E2A37; }
  :root:not([data-theme="light"]) .stage > .room:not(.full) { --muted: #B4BBCB; }
}
:root[data-theme="dark"] .stage > #claims1, :root[data-theme="dark"] .stage > #pp005b, :root[data-theme="dark"] .stage > #method { --paper: #0F1D44; --tint: #18285A; --rule: #2A3C73; }
:root[data-theme="dark"] .stage > #claims2, :root[data-theme="dark"] .stage > #pp006, :root[data-theme="dark"] .stage > #index { --paper: #262108; --tint: #353012; --rule: #4A4320; }
:root[data-theme="dark"] .stage > #pp005, :root[data-theme="dark"] .stage > #pp003 { --paper: #33101A; --tint: #451A26; --rule: #5E2A37; }
:root[data-theme="dark"] .stage > .room:not(.full) { --muted: #B4BBCB; }

/* glass frames in the rooms: pale glass on the light rooms, dark glass on the lobby, the vault and the dark scheme */
.stage > .room:not(.full) { --ghp-glass: linear-gradient(180deg, rgba(255,255,255,.9) 0%, rgba(255,255,255,.6) 100%);
  --ghp-glass-bd: rgba(0,43,127,.2); --ghp-glass-hi: rgba(255,255,255,.95); --ghp-glass-sh: rgba(0,20,60,.28); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .stage > .room:not(.full) {
  --ghp-glass: linear-gradient(180deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.04) 100%);
  --ghp-glass-bd: rgba(255,255,255,.2); --ghp-glass-hi: rgba(255,255,255,.16); --ghp-glass-sh: rgba(0,0,0,.5); } }
:root[data-theme="dark"] .stage > .room:not(.full) {
  --ghp-glass: linear-gradient(180deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.04) 100%);
  --ghp-glass-bd: rgba(255,255,255,.2); --ghp-glass-hi: rgba(255,255,255,.16); --ghp-glass-sh: rgba(0,0,0,.5); }
.stage > .room h1, .stage > .room h2 { border-top: 2px solid var(--ghp-glass-edge, var(--blue)) !important; }
.stage > .room h3 { border-bottom: 2px solid var(--red) !important; }
.stage .lobby h1 { --ghp-glass-edge: var(--ghp-yel); }
.stage .vault h2 { padding-top: .32em !important; margin-top: 30px; --ghp-glass-edge: var(--ghp-yel);
  background: linear-gradient(180deg, rgba(12,18,34,.55), rgba(12,18,34,.35)); }
/* red = generated: the notes that say a sound, an animation or a voice is generated, not measured */
.stage p.ghp-generated {
  border-left: 3px solid var(--red); padding-left: 10px;
}
.stage .question { border-left-color: var(--red); }

/* dark scheme: the room's blue (#002B7F) text controls were 1.2-1.4:1 on the dark rooms (pre-existing); they take the room's own
   dark-mode link blue, as its .kick and .links already do */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .stage .listen:not(.onblue), :root:not([data-theme="light"]) .stage .btn.quiet,
  :root:not([data-theme="light"]) .stage .lens, :root:not([data-theme="light"]) .stage .papers a, :root:not([data-theme="light"]) .stage .sealed { color: #9DB8FF; }
  :root:not([data-theme="light"]) .stage .listen:not(.onblue) { border-color: #9DB8FF; }
  :root:not([data-theme="light"]) .stage .listen:not(.onblue)[aria-pressed="true"] { background: #9DB8FF; color: #0C1222; }
}
:root[data-theme="dark"] .stage .listen:not(.onblue), :root[data-theme="dark"] .stage .btn.quiet, :root[data-theme="dark"] .stage .lens,
:root[data-theme="dark"] .stage .papers a, :root[data-theme="dark"] .stage .sealed { color: #9DB8FF; }
:root[data-theme="dark"] .stage .listen:not(.onblue) { border-color: #9DB8FF; }
:root[data-theme="dark"] .stage .listen:not(.onblue)[aria-pressed="true"] { background: #9DB8FF; color: #0C1222; }

/* F. the verifier's two re-derivation controls: proper gh-design buttons, 44 px targets, an unmistakable "not yet" state */
body.gh .ghp-help { border-left: 3px solid var(--rule-blue); padding: .2rem 0 .2rem .9rem; }
body.gh .ghp-help p { margin: 0 0 .5rem; }
body.gh .ghp-actions button { min-height: 44px; border-radius: 8px; padding: .6rem 1.2rem; }
body.gh .ghp-actions button.secondary { border-width: 2px; }
body.gh .ghp-actions button:disabled { opacity: 1; cursor: not-allowed; background: transparent; color: var(--fg-muted); border: 2px dashed var(--fg-muted); }
body.gh .ghp-actions button:not(:disabled):hover { filter: brightness(1.08); }

/* the two oldest seal pages (/v/JFD-20260917-CERT-0000x) predate gh-design: tables sit straight in <body> and pushed the page
   203 px sideways at 390 px. They scroll inside themselves instead. */
body:not(.gh) > table { display: block; max-width: 100%; overflow-x: auto; }
body:not(.gh) { overflow-wrap: break-word; }

/* print: no grounds, no glass */
@media print {
  body.gh .ghp-band, body.gh main h1, body.gh main h2, body.gh main h3, body.gh .gh-nav a {
    background: none !important; box-shadow: none !important; -webkit-backdrop-filter: none; backdrop-filter: none; color: inherit; }
  body.gh .ghp-band { border: 1px solid #002B7F; }
  .ghp-pre { -webkit-mask: none !important; mask: none !important; }
}
