/* ============================================================
   MEMORY / HEX DUMP — Cody Richard / @ssstrickys
   Palette pulled from a forensic hex editor in a cold theme:
   a graphite/steel base with ONE amber-phosphor decode signal.
   Not matrix green. The decode is the single bold moment;
   everything else stays still and precise.

   Served from 'self' to satisfy a strict CSP (no inline styles).
   ============================================================ */

@property --decode {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

:root{
  --ink:        #0c0f12;  /* Carbon         — deep page ground   */
  --slab:       #14181d;  /* Slate Slab     — raised panels      */
  --rule:       #232a31;  /* Rule Steel     — borders, gridlines */
  --offset:     #828f9b;  /* Cold Offset    — addresses, muted   */
  --bone:       #c5cdd4;  /* Bone           — primary read text  */
  --signal:     #ffb000;  /* Amber Phosphor — THE decode signal  */
  --signal-dim: #7a5a14;  /* dim amber — undecoded raw bytes     */

  --mono: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace;
  --line: 1px solid var(--rule);
  --gut: clamp(1rem, 4vw, 2.4rem);
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }

body{
  margin:0;
  background:
    radial-gradient(125% 80% at 50% -12%,
      color-mix(in oklab, var(--slab) 70%, var(--ink)) 0%, var(--ink) 60%);
  color:var(--bone);
  font-family:var(--mono);
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  letter-spacing:.01em;
}

/* one ambient texture — a faint vertical column lattice (forensic
   editor gridlines). every other decoration was cut on purpose. */
body::before{
  content:"";
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:linear-gradient(to right,
    color-mix(in oklab, var(--rule) 42%, transparent) 1px, transparent 1px);
  background-size:clamp(64px, 9vw, 120px) 100%;
  opacity:.32;
}

a{ color:var(--signal); text-decoration:none; }
a:hover{ text-decoration:underline; text-underline-offset:3px; }

:focus-visible{ outline:2px solid var(--signal); outline-offset:3px; border-radius:2px; }

.wrap{ width:min(960px, 92vw); margin-inline:auto; position:relative; z-index:1; }

/* skip link */
.skip{
  position:absolute; left:-999px; top:0; z-index:60;
  background:var(--signal); color:var(--ink);
  padding:.5rem .9rem; font-weight:700; text-decoration:none;
}
.skip:focus{ left:1rem; top:1rem; }

/* ---- sticky top bar ---- */
header.bar{
  position:sticky; top:0; z-index:30;
  /* opaque fallbacks first — nav stays readable with no color-mix AND no blur */
  background:var(--ink);
  background:color-mix(in oklab, var(--ink) 96%, transparent);
  border-bottom:var(--line);
}
/* upgrade to translucent + blur only where the engine actually supports it
   (older Firefox without the flag would otherwise render a see-through bar) */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){
  header.bar{
    background:color-mix(in oklab, var(--ink) 82%, transparent);
    -webkit-backdrop-filter:blur(6px);
    backdrop-filter:blur(6px);
  }
}
.bar .wrap{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; padding:.7rem 0; flex-wrap:wrap;
}
.brand{ display:flex; align-items:baseline; gap:.6rem; font-weight:700; letter-spacing:.04em; }
.brand b{ color:var(--bone); }
.brand span{ color:var(--offset); font-weight:400; }
nav.top{ display:flex; gap:1.1rem; font-size:.82rem; }
nav.top a{ color:var(--offset); }
nav.top a:hover{ color:var(--bone); text-decoration:none; }

/* ============================================================
   SIGNATURE — the live hex dump that DECODES into bio prose
   ============================================================ */
.hero{ padding: clamp(2.4rem,7vw,4.6rem) 0 clamp(2rem,5vw,3.2rem); }

.meta-row{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap; margin-bottom:1rem;
  color:var(--offset); font-size:.76rem; letter-spacing:.08em; text-transform:uppercase;
}
.meta-row .seg b{ color:var(--bone); }
.meta-row .badge{ border:var(--line); padding:.25rem .55rem; border-radius:3px; color:var(--bone); }

.dump{
  border:var(--line); border-radius:6px; overflow:hidden;
  background:var(--slab); /* fallback if color-mix/gradient token is unsupported */
  background:linear-gradient(180deg,
    color-mix(in oklab, var(--slab) 88%, var(--ink)), var(--ink));
  box-shadow:var(--elev-1);
}
.dump-head{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap;
  padding:.55rem .9rem; border-bottom:var(--line);
  background:color-mix(in oklab, var(--slab) 60%, var(--ink));
  color:var(--offset); font-size:.72rem; letter-spacing:.06em; text-transform:uppercase;
}
.dump-head .dot{
  width:8px; height:8px; border-radius:50%; display:inline-block;
  margin-right:.5rem; vertical-align:middle;
  background:var(--signal-dim); transition:background .3s ease;
}
.decoded .dump-head .dot{ background:var(--signal); }

.toggle{
  font:inherit; font-size:.72rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--signal); background:transparent;
  border:1px solid color-mix(in oklab, var(--signal) 45%, var(--rule));
  padding:.35rem .7rem; border-radius:3px; cursor:pointer;
}
.toggle:hover{ background:color-mix(in oklab, var(--signal) 14%, transparent); }
.toggle[aria-pressed="true"]{ background:var(--signal); color:var(--ink); border-color:var(--signal); }

.dump-body{ padding:clamp(.9rem,2.5vw,1.4rem); }

/* Stack the byte grid and prose in ONE grid cell so the container
   always sizes to the taller child (the prose). Cross-fade by
   opacity only — nothing can ever clip the bio. */
.panes{ display:grid; }
.panes > pre.bytes,
.panes > .prose{ grid-area:1 / 1; }

/* raw byte view: offset | hex grid | ASCII gutter */
pre.bytes{
  margin:0; white-space:pre; overflow-x:auto;
  font-size:clamp(.6rem,1.7vw,.82rem); line-height:1.7;
  color:var(--signal-dim);
  transition:opacity .5s ease, filter .5s ease;
  -webkit-overflow-scrolling:touch;
}
pre.bytes .off{ color:var(--offset); }
pre.bytes .asc{ color:color-mix(in oklab, var(--signal) 55%, var(--offset)); }

/* decoded prose, stacked over the bytes and cross-faded */
.prose{
  display:flex; flex-direction:column; justify-content:center; gap:clamp(.6rem,2vw,1rem);
  opacity:0; pointer-events:none;
  transition:opacity .55s ease .05s;
}
/* hide the prose only when JS is present to drive the decode;
   no-JS renders the real bio immediately (graceful degradation) */
html:not(.js) .prose{ opacity:1; pointer-events:auto; }
html:not(.js) pre.bytes{ display:none; }
.prose h1{
  margin:0; font-weight:700; color:var(--bone);
  font-size:clamp(1.4rem,4.6vw,2.35rem); line-height:1.16; letter-spacing:-.01em;
}
.prose h1 mark{
  background:transparent; color:var(--signal);
  border-bottom:2px solid color-mix(in oklab, var(--signal) 60%, transparent);
}
.prose p{ margin:0; max-width:60ch; color:color-mix(in oklab, var(--bone) 86%, var(--offset)); }
.prose .lede{ color:var(--bone); font-size:clamp(.95rem,2.4vw,1.05rem); }

.decoded pre.bytes{ opacity:.10; filter:blur(1px); }
.decoded .prose{ opacity:1; pointer-events:auto; }

/* the memorable operator line — always legible, under the dump */
.opline{ margin-top:1.3rem; font-size:clamp(.95rem,2.6vw,1.12rem); color:var(--bone); }
.opline .k{ color:var(--offset); }
.opline b{ color:var(--signal); font-weight:700; }

.cta{ display:flex; gap:.7rem; flex-wrap:wrap; margin-top:1.4rem; }
.btn{
  font:inherit; font-size:.85rem; letter-spacing:.03em;
  padding:.6rem 1rem; border-radius:4px; border:var(--line);
  color:var(--bone); background:var(--slab);
}
.btn:hover{ text-decoration:none; border-color:color-mix(in oklab, var(--signal) 60%, var(--rule)); }
.btn.primary{ border-color:var(--signal); background:var(--signal); color:var(--ink); font-weight:700; }
.btn.primary:hover{ background:color-mix(in oklab, var(--signal) 88%, var(--bone)); }

/* ---- section scaffold ---- */
section{ padding:clamp(2.4rem,6vw,3.6rem) 0; }
.sec-label{
  display:flex; align-items:center; gap:.8rem; margin-bottom:1.4rem;
  color:var(--offset); font-size:.74rem; letter-spacing:.14em; text-transform:uppercase;
}
.sec-label::before{ content:""; width:1.4rem; height:1px; background:var(--signal); }
.sec-label .addr{ color:color-mix(in oklab, var(--signal) 70%, var(--offset)); }
h2{ font-size:clamp(1.15rem,3vw,1.5rem); margin:.2rem 0 1rem; color:var(--bone); }

/* ---- focus / about grid ---- */
.focus-grid{
  display:grid; gap:1px; grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
}
.cell{ background:var(--slab); padding:1.1rem 1.2rem; }
.cell h3{ margin:0 0 .4rem; font-size:.9rem; color:var(--signal); letter-spacing:.02em; }
.cell p{ margin:0; font-size:.86rem; color:color-mix(in oklab, var(--bone) 80%, var(--offset)); }
.cell .hx{ color:var(--offset); font-size:.72rem; }

/* ---- write-ups as labeled MEMORY REGIONS ---- */
.regions{
  display:flex; flex-direction:column; gap:1px;
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
  container-type:inline-size;
}
.region{ background:var(--slab); display:grid; grid-template-columns:13rem 1fr; }
@container (max-width:600px){
  .region{ grid-template-columns:1fr; }
  .region .map{ border-right:none; border-bottom:var(--line); }
}
.region .map{
  border-right:var(--line); padding:1.1rem;
  background:color-mix(in oklab, var(--slab) 80%, var(--ink));
}
.region .map .range{ color:var(--signal); font-size:.82rem; letter-spacing:.02em; }
.region .map .perm{
  display:inline-block; margin-top:.4rem;
  color:var(--bone); font-size:.72rem; letter-spacing:.12em;
  border:var(--line); padding:.1rem .4rem; border-radius:3px;
}
.region .map .date{ display:block; margin-top:.6rem; color:var(--offset); font-size:.72rem; }
.region .body{ padding:1.1rem 1.2rem; }
.region .body h3{ margin:0 0 .3rem; font-size:1rem; color:var(--bone); }
.region .body h3 a{ color:var(--bone); }
.region .body h3 a:hover{ color:var(--signal); text-decoration:none; }
.region .body p{ margin:0 0 .7rem; font-size:.86rem; max-width:62ch; color:color-mix(in oklab, var(--bone) 80%, var(--offset)); }
.tags{ display:flex; gap:.4rem; flex-wrap:wrap; }
.tag{
  font-size:.68rem; letter-spacing:.06em; text-transform:uppercase; color:var(--offset);
  border:var(--line); padding:.12rem .45rem; border-radius:3px;
}
.tag::before{ content:"0x"; color:color-mix(in oklab, var(--signal) 55%, var(--offset)); }

/* scroll reveal — typed scroll-driven anim, degrades to visible */
.reveal{ opacity:1; }
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    .reveal{
      opacity:.001; transform:translateY(14px);
      animation:surface linear both;
      animation-timeline:view();
      animation-range:entry 0% entry 42%;
    }
    @keyframes surface{ to{ opacity:1; transform:none; } }
  }
}

/* ---- social / contact ---- */
.links{
  display:grid; gap:1px; grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
}
.links a, .links .item{
  background:var(--slab); padding:1.1rem 1.2rem;
  display:flex; flex-direction:column; gap:.25rem; color:var(--bone);
}
.links a:hover{ background:color-mix(in oklab, var(--signal) 10%, var(--slab)); text-decoration:none; }
.links .label{ font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--offset); }
.links .val{ color:var(--bone); }
.links a:hover .val{ color:var(--signal); }
.links .pgp{ font-size:.7rem; color:var(--offset); word-break:break-all; }

/* ---- footer ---- */
footer{ border-top:var(--line); padding:1.6rem 0 2.4rem; color:var(--offset); font-size:.78rem; }
footer .wrap{ display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap; }
footer .sig{ color:color-mix(in oklab, var(--signal) 60%, var(--offset)); }

/* ============================================================
   Grafts pulled from the runner-up concepts (judge's notes)
   ============================================================ */

/* was an inline style="" on the whoami copy — moved here for CSP */
.copy-wide{ max-width:64ch; color:color-mix(in oklab, var(--bone) 84%, var(--offset)); }

/* COBALT SIGNAL's sharpest line, reframed */
.whoami-kicker{ margin-top:1.1rem; color:var(--bone); font-size:clamp(.95rem,2.4vw,1.05rem); }
.whoami-kicker b{ color:var(--signal); font-weight:700; }

/* DISASSEMBLY-style discipline + PORT-SCAN kill-chain framing:
   a phase label so the region order carries real information */
.region .map .phase{
  display:block; margin-top:.55rem;
  color:color-mix(in oklab, var(--signal) 70%, var(--offset));
  font-size:.66rem; letter-spacing:.14em; text-transform:uppercase;
}

/* focus-within parity — the whole card reacts when an inner link is
   keyboard-focused, not just the link itself */
.region:focus-within{ outline:1px solid color-mix(in oklab, var(--signal) 55%, var(--rule)); outline-offset:-1px; }
.cell:focus-within{ background:color-mix(in oklab, var(--signal) 8%, var(--slab)); }

@media (max-width:560px){
  /* keep the Primary nav visible & in the a11y tree; let it wrap below the brand
     (was display:none, which removed navigation entirely on phones) */
  .bar .wrap{ gap:.5rem 1rem; }
  nav.top{ display:flex; flex-wrap:wrap; gap:.4rem .9rem; width:100%; font-size:.78rem; }
  nav.top a{ padding:.25rem 0; }
  /* on small screens the readable bio is always shown; the byte
     grid fades behind it so the signature still reads as a dump */
  .prose{ opacity:1 !important; pointer-events:auto; }
  pre.bytes{ opacity:.12; filter:blur(1px); }
  /* the decode control can't function at this width — don't show a toggle that lies about state */
  .dump-head .toggle{ display:none; }
}

/* reduced motion — calm ALL motion */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation:none !important; transition:none !important; }
  pre.bytes{ filter:none !important; }
}

/* ============================================================
   COMPETITION / SCOREBOARD SECTION
   ============================================================ */
.scoreboard{
  display:flex; flex-direction:column; gap:1px;
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
}
.score-entry{
  background:var(--slab);
  display:grid; grid-template-columns:1fr auto;
  gap:0 1rem;
  padding:1.1rem 1.2rem;
  transition:background .2s ease;
}
.score-entry:focus-within{ background:color-mix(in oklab, var(--signal) 7%, var(--slab)); }
.score-entry .evt{ min-width:0; }
.score-entry .evt .op{
  color:var(--offset); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase;
  margin-bottom:.3rem;
}
.score-entry .evt .op b{ color:color-mix(in oklab, var(--signal) 70%, var(--offset)); }
.score-entry .evt h3{ margin:0 0 .3rem; font-size:1rem; color:var(--bone); font-weight:700; }
.score-entry .evt p{ margin:0 0 .6rem; font-size:.85rem; max-width:62ch; color:color-mix(in oklab, var(--bone) 80%, var(--offset)); }
.score-entry .rank-col{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:.4rem .6rem .4rem 1rem; min-width:5.5rem; text-align:center;
  border-left:var(--line);
}
.score-entry .rank-col .n{
  font-size:clamp(1.5rem,4vw,2.1rem); font-weight:700; line-height:1; color:var(--signal);
  letter-spacing:-.02em;
}
.score-entry .rank-col .n.selected{ font-size:1.1rem; color:var(--signal); }
/* upcoming/invited status reads distinctly from achieved numeric ranks (#1/#36) */
.score-entry .rank-col .n.upcoming{ font-size:1.1rem; color:var(--offset); }
.score-entry .rank-col .lbl{
  font-size:.62rem; letter-spacing:.1em; text-transform:uppercase; color:var(--offset);
  margin-top:.25rem;
}
@media (max-width:480px){
  .score-entry{ grid-template-columns:1fr; }
  .score-entry .rank-col{ flex-direction:row; gap:.6rem; border-left:none; border-top:var(--line); padding:.6rem 0 0; min-width:0; text-align:left; }
}

/* ============================================================
   SECURITY RESEARCH / DISCLOSURES
   ============================================================ */
.disc-block{
  border:var(--line); border-radius:6px; overflow:hidden;
  background:var(--slab); /* fallback if color-mix/gradient token is unsupported */
  background:linear-gradient(180deg, color-mix(in oklab, var(--slab) 88%, var(--ink)), var(--ink));
}
.disc-block-head{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:1rem; flex-wrap:wrap;
  padding:1.1rem 1.2rem; border-bottom:var(--line);
  background:color-mix(in oklab, var(--slab) 60%, var(--ink));
}
.disc-block-head .proj{ min-width:0; }
.disc-block-head .proj .credited{
  color:var(--signal); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; margin-bottom:.3rem;
}
.disc-block-head .proj h3{ margin:0 0 .2rem; font-size:1.05rem; color:var(--bone); }
.disc-block-head .proj .stack-tag{
  color:var(--offset); font-size:.72rem; letter-spacing:.04em;
}
.disc-stats{ display:flex; gap:.8rem; align-items:flex-end; flex-shrink:0; }
.disc-stat{ text-align:center; }
.disc-stat .n{ display:block; font-size:clamp(1.3rem,3vw,1.8rem); font-weight:700; color:var(--signal); line-height:1; letter-spacing:-.02em; }
.disc-stat .lbl{ display:block; font-size:.62rem; letter-spacing:.1em; text-transform:uppercase; color:var(--offset); margin-top:.2rem; }
.disc-findings{ padding:.6rem 0; }
.disc-finding{
  display:grid; grid-template-columns:2.4rem 1fr;
  gap:0 .9rem; padding:.9rem 1.2rem; border-bottom:var(--line);
}
.disc-finding:last-child{ border-bottom:none; }
.disc-finding .fn{
  font-size:.76rem; font-weight:700; color:color-mix(in oklab, var(--signal) 65%, var(--offset));
  padding-top:.1rem;
}
.disc-finding .fd h4{ margin:0 0 .25rem; font-size:.92rem; color:var(--bone); font-weight:700; }
.disc-finding .fd p{ margin:0; font-size:.84rem; color:color-mix(in oklab, var(--bone) 78%, var(--offset)); }

/* ============================================================
   CERTIFICATIONS
   ============================================================ */
.cert-track-label{
  color:var(--offset); font-size:.72rem; letter-spacing:.14em; text-transform:uppercase;
  margin:1.8rem 0 .7rem; display:flex; align-items:center; gap:.7rem;
}
.cert-track-label::before{ content:""; width:1.4rem; height:1px; background:var(--signal); }
.cert-track-label:first-of-type{ margin-top:.2rem; }
.cert-grid{
  display:grid; gap:1px; grid-template-columns:repeat(auto-fill, minmax(200px,1fr));
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
}
.cert{
  background:var(--slab); padding:.9rem 1.1rem;
  display:flex; flex-direction:column; gap:.25rem;
}
.cert .cname{ color:var(--bone); font-size:.88rem; font-weight:700; }
.cert .ccode{ color:color-mix(in oklab, var(--signal) 70%, var(--offset)); font-size:.72rem; letter-spacing:.06em; }
.cert .cstatus{ color:var(--offset); font-size:.7rem; letter-spacing:.06em; text-transform:uppercase; margin-top:.15rem; }
.cert.inprog{ border-left:2px solid color-mix(in oklab, var(--signal) 40%, var(--rule)); }
.cert.inprog .cstatus{ color:color-mix(in oklab, var(--signal) 60%, var(--offset)); }

/* ============================================================
   WRITE-UP PAGES — long-form article layout
   ============================================================ */
.crumb{
  padding:1.4rem 0 .2rem;
  color:var(--offset); font-size:.78rem; letter-spacing:.04em;
}
.crumb a{ color:var(--offset); }
.crumb a:hover{ color:var(--signal); text-decoration:none; }
.crumb .sep{ color:var(--rule); margin:0 .5rem; }
.crumb .here{ color:var(--bone); }

.wu{ padding:1.4rem 0 1rem; }
.wu-head{ border-bottom:var(--line); padding-bottom:1.4rem; margin-bottom:1.8rem; }
.wu-head .range{ color:var(--signal); font-size:.78rem; letter-spacing:.04em; }
.wu-head h1{
  margin:.5rem 0 .3rem; color:var(--bone); letter-spacing:-.01em;
  font-size:clamp(1.5rem,4.6vw,2.3rem); line-height:1.18;
}
.wu-head .dek{
  margin:.6rem 0 0; max-width:64ch;
  color:color-mix(in oklab, var(--bone) 84%, var(--offset));
  font-size:clamp(.95rem,2.3vw,1.05rem);
}
.wu-meta{
  display:flex; flex-wrap:wrap; gap:.5rem 1.2rem; margin-top:1rem;
  color:var(--offset); font-size:.74rem; letter-spacing:.06em; text-transform:uppercase;
}
.wu-meta b{ color:var(--bone); font-weight:600; }
.wu-meta .perm{
  border:var(--line); padding:.08rem .4rem; border-radius:3px;
  color:var(--bone); letter-spacing:.12em;
}

.glance{
  display:grid; gap:1px; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  background:var(--rule); border:var(--line); border-radius:6px; overflow:hidden;
  margin:0 0 2rem;
}
.glance > div{ background:var(--slab); padding:.85rem 1rem; }
.glance dt{ color:var(--offset); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; }
.glance dd{ margin:.3rem 0 0; color:var(--bone); font-size:.9rem; }
.glance dd.hi{ color:var(--signal); font-weight:700; }

.prose-body{ max-width:72ch; }
.prose-body > *{ margin-block:0 1.1rem; }
.prose-body h2{
  margin-top:2.4rem; color:var(--bone);
  font-size:clamp(1.05rem,2.8vw,1.35rem); scroll-margin-top:4.5rem;
}
.prose-body h2 .n{ color:color-mix(in oklab, var(--signal) 70%, var(--offset)); font-size:.8em; margin-right:.5rem; }
.prose-body h3{ margin-top:1.8rem; color:var(--bone); font-size:.98rem; }
.prose-body p{ color:color-mix(in oklab, var(--bone) 88%, var(--offset)); line-height:1.7; }
.prose-body a{ text-decoration:underline; text-underline-offset:3px; }
.prose-body ul, .prose-body ol{ padding-left:1.3rem; color:color-mix(in oklab, var(--bone) 86%, var(--offset)); }
.prose-body li{ margin-bottom:.45rem; }
.prose-body li::marker{ color:color-mix(in oklab, var(--signal) 60%, var(--offset)); }
.prose-body strong{ color:var(--bone); }

code{
  font-family:var(--mono); font-size:.86em;
  background:color-mix(in oklab, var(--signal) 8%, var(--slab));
  border:1px solid color-mix(in oklab, var(--rule) 80%, transparent);
  padding:.08em .38em; border-radius:3px; color:var(--bone);
}
pre.code{
  margin:0 0 1.3rem; overflow-x:auto; -webkit-overflow-scrolling:touch;
  background:var(--slab); /* fallback if color-mix/gradient token is unsupported */
  background:linear-gradient(180deg, color-mix(in oklab, var(--slab) 90%, var(--ink)), var(--ink));
  border:var(--line); border-radius:6px;
}
pre.code .lang{
  display:block; padding:.4rem .9rem; border-bottom:var(--line);
  background:color-mix(in oklab, var(--slab) 60%, var(--ink));
  color:var(--offset); font-size:.68rem; letter-spacing:.1em; text-transform:uppercase;
}
pre.code samp{
  display:block; padding:1rem 1.1rem; white-space:pre;
  font-family:var(--mono); font-size:clamp(.72rem,1.8vw,.83rem); line-height:1.7;
  color:var(--bone);
}
pre.code code{ background:none; border:0; padding:0; font-size:inherit; color:inherit; }
pre.code .c{ color:var(--offset); }
pre.code .p{ color:var(--signal); }
pre.code .o{ color:color-mix(in oklab, var(--signal) 60%, var(--bone)); }

.callout{
  border:var(--line); border-left:3px solid var(--offset); border-radius:0 6px 6px 0;
  background:color-mix(in oklab, var(--slab) 80%, var(--ink));
  padding:.9rem 1.1rem; margin:0 0 1.3rem;
}
.callout .lbl{
  display:block; margin-bottom:.35rem;
  font-size:.7rem; letter-spacing:.12em; text-transform:uppercase; color:var(--offset);
}
.callout p:last-child{ margin-bottom:0; }
.callout.impact{ border-left-color:var(--signal); }
.callout.impact .lbl{ color:var(--signal); }
.callout.fix{ border-left-color:#3ad07a; }
.callout.fix .lbl{ color:#3ad07a; }

.chain{ list-style:none; padding:0; counter-reset:step; margin:0 0 1.3rem; }
.chain > li{
  position:relative; padding:.2rem 0 1.1rem 2.6rem; margin:0;
  border-left:var(--line); margin-left:.7rem;
}
.chain > li:last-child{ border-left-color:transparent; padding-bottom:0; }
.chain > li::before{
  counter-increment:step; content:counter(step);
  position:absolute; left:-0.88rem; top:0;
  width:1.7rem; height:1.7rem; border-radius:50%;
  display:grid; place-items:center;
  background:var(--ink); border:1px solid var(--signal); color:var(--signal);
  font-size:.74rem; font-weight:700;
}
.chain > li b{ color:var(--bone); }

.wu-foot{
  border-top:var(--line); margin-top:2.4rem; padding:1.6rem 0 0;
  display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  color:var(--offset); font-size:.8rem;
}
.wu-foot a{ color:var(--signal); }

/* ============================================================
   CARVE — the hex dump decodes as a watchable, inspectable process.
   JS owns timing (rAF, class toggles); CSS owns the look. All from
   'self' — no inline anything. Layout is unchanged (bytes + prose
   stay stacked in one grid cell); the read head wipes top-to-bottom,
   consuming bytes (.spent) into resolved prose words (.done).
   ============================================================ */

/* reserve the byte-grid height so filling it post-paint can't shift the hero
   (CLS). 25 rows == the current bio length; app.js also sets this exactly. */
pre.bytes{ min-block-size: calc(25 * 1.7em); }

/* ASCII gutter spells the real bio — keep it legible in the raw state */
pre.bytes .ac{ color:color-mix(in oklab, var(--signal) 55%, var(--offset)); }

pre.bytes .by, pre.bytes .ac{
  transition:color .2s ease, opacity .4s ease, background-color .15s ease;
}
pre.bytes .by.lit, pre.bytes .ac.lit{ color:var(--signal); }   /* active read-head glow */
pre.bytes .by.spent, pre.bytes .ac.spent{ opacity:.2; }        /* consumed bytes recede */

/* prose container shown during the carve; words resolve individually on .done.
   (.decoded reveal is handled by the existing `.decoded .prose` rule above.) */
.panes.carving .prose{ opacity:1; pointer-events:auto; }
.prose .pw{ opacity:0; filter:blur(.55px); transition:opacity .32s ease, filter .32s ease; }
.panes.carving .prose .pw.done,
.panes.decoded .prose .pw{ opacity:1; filter:none; }

/* linkage — a hex pair and the ASCII glyph it maps to light together */
pre.bytes .by.link, pre.bytes .ac.link{
  color:var(--ink); background-color:var(--signal); opacity:1; border-radius:2px;
}

/* the read head — a thin amber scan line. Only the small left grip is
   interactive, so the line itself never blocks hovering the bytes beneath. */
.dump-body{ position:relative; }
.head{
  position:absolute; left:0; right:0; top:0; height:14px; margin-top:-7px;
  transform:translateY(var(--y,0)); pointer-events:none; z-index:3; display:none;
  background:linear-gradient(to bottom, transparent 6px,
    color-mix(in oklab, var(--signal) 80%, transparent) 6px,
    color-mix(in oklab, var(--signal) 80%, transparent) 8px, transparent 8px);
}
.head.on{ display:block; }
.head .grip{
  position:absolute; left:0; top:1px; width:16px; height:12px; border-radius:2px;
  background:var(--signal); pointer-events:auto; cursor:grab;
  box-shadow:0 0 8px color-mix(in oklab, var(--signal) 55%, transparent);
}
.head .grip:active{ cursor:grabbing; }
.head .grip:focus-visible{ outline:2px solid var(--bone); outline-offset:2px; }

/* reduced motion: no carve runs (JS jumps to decoded); freeze + hide the head */
@media (prefers-reduced-motion: reduce){
  .head{ display:none !important; }
  .prose .pw{ opacity:1 !important; filter:none !important; }
}

/* small screens: decoded end-state only (no carve) — hide the scrub head,
   keep every word visible */
@media (max-width:560px){
  .head{ display:none !important; }
  .prose .pw{ opacity:1; filter:none; }
}

/* disclosure: clickable project title + explicit public-disclosure link */
.disc-block-head .proj h3 a{ color:var(--bone); }
.disc-block-head .proj h3 a:hover{ color:var(--signal); text-decoration:none; }
.disc-src{ margin:.45rem 0 0; font-size:.75rem; }
.disc-src a{ color:color-mix(in oklab, var(--signal) 82%, var(--bone)); }
.disc-src a:hover{ color:var(--signal); }

/* ============================================================
   ELEVATION PACKAGE — "a cold, precise instrument, quietly alive".
   All CSS served from 'self', no inline, no network. Motion is calmed
   by the existing prefers-reduced-motion block. Behavioural pieces
   (idle re-scan, INSPECT lens, address decode, rip) live in app.js.
   ============================================================ */

/* phosphor depth — elevation tokens + amber bloom (box-shadow only;
   never touches any panel background, so overflow:hidden + the 1px gap
   rules stay intact) */
:root{
  --elev-1: 0 1px 0 color-mix(in oklab,var(--bone) 7%,transparent) inset, 0 1px 2px rgba(0,0,0,.5), 0 8px 24px -10px rgba(0,0,0,.5), 0 22px 56px -30px rgba(0,0,0,.55);
  --elev-2: 0 1px 0 color-mix(in oklab,var(--signal) 14%,transparent) inset, 0 2px 4px rgba(0,0,0,.55), 0 12px 30px -10px rgba(0,0,0,.55), 0 30px 70px -34px rgba(0,0,0,.6);
  --glow: 0 0 .55em color-mix(in oklab,var(--signal) 20%,transparent);
}
.disc-block, pre.code, .focus-grid, .regions, .links, .scoreboard, .cert-grid, .glance{ box-shadow:var(--elev-1); }
.prose h1 mark, .sec-label .addr, .score-entry .rank-col .n, .opline b, .region .map .range, .disc-stat .n{ text-shadow:var(--glow); }
.btn.primary{ box-shadow:var(--glow); }
.dump, .disc-block, pre.code, .focus-grid, .regions, .links, .scoreboard, .cert-grid, .glance{ transition:box-shadow .2s ease; }
.dump:hover, .disc-block:hover, .focus-grid:focus-within, .regions:focus-within, .links:focus-within, .scoreboard:focus-within, .cert-grid:focus-within{ box-shadow:var(--elev-2); }

/* edge-light vignette + sub-perceptual mono grain (self-contained data-URI,
   zero requests; sits below .wrap so text never dims) */
html::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='2' stitchTiles='stitch' result='t'/%3E%3CfeColorMatrix in='t' type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 120% at 50% 40%, transparent 55%, rgba(0,0,0,.30) 100%);
  background-size:160px 160px, cover; background-repeat:repeat, no-repeat; opacity:1;
}
@media (prefers-contrast: more), (forced-colors: active){ html::before{ display:none; } }

/* ::selection as amber phosphor — the whole page speaks the hero's
   hex-inversion language; byte grid isn't selectable except mid-carve */
::selection{ background:var(--signal); color:var(--ink); text-shadow:none; }
::-moz-selection{ background:var(--signal); color:var(--ink); text-shadow:none; }
pre.bytes{ -webkit-user-select:none; user-select:none; }
.panes.carving pre.bytes{ -webkit-user-select:text; user-select:text; }

/* card lift + border-glow on hover (clip-safe inset; mirrors focus-within) */
@media (hover:hover) and (pointer:fine){
  .cell, .score-entry{ transition-property:background,box-shadow; transition-duration:.18s; transition-timing-function:ease; }
  .cell:hover, .score-entry:hover{ background:color-mix(in oklab, var(--signal) 8%, var(--slab)); box-shadow:inset 0 0 0 1px color-mix(in oklab, var(--signal) 22%, transparent); }
  .region{ transition:box-shadow .18s ease; }
  .region:hover{ box-shadow:inset 0 0 0 1px color-mix(in oklab, var(--signal) 30%, var(--rule)); }
  .cert, .disc-finding{ transition:background .18s ease; }
  .cert:hover, .disc-finding:hover{ background:color-mix(in oklab, var(--signal) 6%, var(--slab)); }
  .links a{ transition:background .18s ease, box-shadow .18s ease, color .18s ease; }
  .links a:hover{ box-shadow:inset 0 0 0 1px color-mix(in oklab, var(--signal) 22%, transparent); }
}

/* nav underline — a left-to-right scan-wipe echoing the read-head */
nav.top{ position:relative; }
nav.top a{ position:relative; }
nav.top a::after{ content:""; position:absolute; left:0; right:0; bottom:-3px; height:1px; background:var(--signal); transform:scaleX(0); transform-origin:left; transition:transform .18s ease; }
nav.top a:hover::after, nav.top a:focus-visible::after{ transform:scaleX(1); }

/* resting phosphor breath — only the decoded status dot (the one live element) */
@keyframes phosphor-breath{ 0%,100%{ filter:brightness(.86); } 50%{ filter:brightness(1); } }
.decoded .dump-head .dot{ animation:phosphor-breath 7s ease-in-out infinite; }

/* section perms — real mode bits (r-- facts, r-x tradecraft, rw- ops log) */
.sec-label .perm{
  margin-left:auto; text-transform:none;
  border:var(--line); padding:.08rem .4rem; border-radius:3px;
  color:var(--bone); font-size:.7rem; letter-spacing:.12em;
}
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* section addresses decode into place on entry (debugger resolving offsets) */
.addr-x{ font-variant-numeric:tabular-nums; }
.sec-label.resolving .addr{ color:var(--signal); }
.sec-label.resolved .addr{ transition:color 380ms ease; }

/* rip — live instruction-pointer readout in the header (muted below the hero seg) */
.rip{ display:flex; align-items:baseline; gap:.4rem; margin-left:.4rem; margin-right:auto; font-size:.74rem; letter-spacing:.04em; color:var(--offset); }
.rip #rip-addr{ font-variant-numeric:tabular-nums; min-width:9ch; color:color-mix(in oklab, var(--bone) 55%, var(--offset)); }
.rip #rip-seg{ color:color-mix(in oklab, var(--signal) 55%, var(--offset)); }
@media (max-width:560px){ .rip{ display:none; } }

/* INSPECT — a snap-to-byte inspection cell tracking the pointer (raw state, fine pointer) */
@property --lx{ syntax:'<length>'; inherits:true; initial-value:0px; }
@property --ly{ syntax:'<length>'; inherits:true; initial-value:0px; }
@property --lw{ syntax:'<length>'; inherits:true; initial-value:0px; }
@property --lh{ syntax:'<length>'; inherits:true; initial-value:0px; }
.lens{
  position:absolute; left:0; top:0; width:var(--lw); height:var(--lh);
  transform:translate3d(var(--lx), var(--ly), 0);
  pointer-events:none; z-index:2; border-radius:2px;
  border:1px solid color-mix(in oklab, var(--signal) 55%, transparent);
  box-shadow:inset 0 0 8px color-mix(in oklab, var(--signal) 22%, transparent);
  opacity:0; transition:opacity .12s ease, transform .08s ease;
}
.lens.on{ opacity:1; }
@media (prefers-reduced-motion: reduce){ .lens{ display:none !important; } }
@media (max-width:560px){ .lens{ display:none !important; } }

/* idle re-scan — faint ambient read-head sweep on the settled hero */
.head.ambient{ opacity:.28; }
@media (prefers-reduced-motion: reduce){ .head.ambient{ display:none !important; } }

/* cinematic section entrances (scroll-linked; degrades to today's flat reveal) */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    .sec-label{ opacity:.001; transform:translateY(8px); animation:surface linear both; animation-timeline:view(); animation-range:entry 0% entry 22%; }
    .sec-label::before{ transform-origin:left center; animation:rule-draw linear both; animation-timeline:view(); animation-range:entry 2% entry 24%; }
    @keyframes rule-draw{ from{ transform:scaleX(0); } to{ transform:scaleX(1); } }
    h2.reveal{ animation-range:entry 6% entry 34%; }
    .focus-grid.reveal, .scoreboard.reveal, .regions.reveal{ transform:none; animation-range:entry 8% entry 30%; }
    .focus-grid .cell, .scoreboard .score-entry, .regions .region, .cert-grid .cert{ opacity:.001; transform:translateY(6px); animation:surface-sm linear both; animation-timeline:view(); animation-range:entry 10% entry 40%; }
    @keyframes surface-sm{ to{ opacity:1; transform:none; } }
    .focus-grid .cell:nth-child(n+4), .cert-grid .cert:nth-child(n+4){ animation-range:entry 16% entry 46%; }
    .focus-grid .cell:nth-child(n+7), .cert-grid .cert:nth-child(n+7){ animation-range:entry 22% entry 52%; }
  }
}

/* ============================================================
   MULTI-PAGE — each section is its own page (one <section> per <main>).
   Neutralise the per-element scroll-entrances (they assumed one long
   scrolling page); mark the current page's nav item; gentle page entrance.
   ============================================================ */
html.js .reveal, html.js .sec-label, html.js .sec-label::before,
html.js .focus-grid .cell, html.js .scoreboard .score-entry,
html.js .regions .region, html.js .cert-grid .cert{
  opacity:1 !important; transform:none !important; animation:none !important;
}
nav.top a[aria-current="page"]{ color:var(--bone); }
nav.top a[aria-current="page"]::after{ transform:scaleX(1); }
html.js main{ min-block-size:62vh; }
@media (prefers-reduced-motion: no-preference){
  html.js main > section{ animation:page-in .34s ease both; }
  @keyframes page-in{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
}
