/* ===========================================================================
   Manan Patel - disclosure record
   Spacing is an 8px scale. Do not hand-pick margins; use the scale.
   =========================================================================== */

:root{
  --s1:4px;  --s2:8px;  --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:64px; --s9:96px; --s10:144px;

  /* TYPE RULE - two tiers, no exceptions.
     --display (serif): headings, and display-tier lead text only (hero lede,
       page lede, article deck, project names, footer name). Never body copy.
     --ui (mono): everything else - all body paragraphs, labels, meta, data,
       code. It is the body default, so body copy needs no declaration. */
  --display:"Newsreader","Noto Serif Devanagari",Georgia,serif;
  --ui:"JetBrains Mono","Noto Serif Devanagari",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* Light tone sampled from hacktron.ai: --background oklch(97.35% .0261 90.1)
     and --foreground oklch(17.07% .0143 2.14). Tiers are that foreground blended
     over that background; --fg-3 sits at 57% because 52% measured 3.76:1. */
  --bg:#fdf6e3;
  --bg-2:#f1ead8;
  --bg-3:#e6dfce;
  --fg:#150d0f;
  --fg-2:#564e4a;
  --fg-3:#766f68;
  --line:#dfd8c7;
  --line-2:#cfc7b9;
  --accent:#a8301f;
  --accent-2:#8a2718;

  --sev-critical:#8c1d12;
  --sev-high:#9a5411;
  --sev-medium:#6f6222;
  --ok:#3f7a49;

  --shell:1240px;
  --read:70ch;
  --t-item:clamp(20px,2.2vw,24px);   /* every card/tile/row/box heading */
  --radius:3px;

  /* one timing vocabulary: three durations, two easings */
  --fast:150ms;
  --mid:200ms;
  --slow:300ms;
  --ease:cubic-bezier(.4,0,.2,1);    /* colour, opacity */
  --out:cubic-bezier(0,0,.2,1);      /* position, transform */
}

:root[data-theme="dark"]{
  --bg:#0e0e0f;
  --bg-2:#161618;
  --bg-3:#1e1e21;
  --fg:#f3f0e7;
  --fg-2:#bdb8a8;
  --fg-3:#928c7c;
  --line:#2b2b2f;
  --line-2:#4a4a51;
  --accent:#e0705c;
  --accent-2:#f29a88;

  --sev-critical:#ff5470;   /* must not collide with --accent */
  --sev-high:#d9a05b;
  --sev-medium:#bdb488;
  --ok:#78c489;
}

*,*::before,*::after{box-sizing:border-box}
/* Author `display` beats the UA stylesheet's [hidden] rule, and the touch block
   sets display:inline-flex on .nav a - which leaked the hidden Writing link on
   phones. Keep this above everything that sets display. */
[hidden]{display:none!important}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--bg);
  color:var(--fg);
  font-family:var(--ui);
  font-size:14px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  transition:background var(--mid) var(--ease),color var(--mid) var(--ease);
}

h1,h2,h3,h4{font-family:var(--display);font-weight:400;margin:0;line-height:1.1;letter-spacing:-.012em}
p{margin:0}
a{color:var(--accent);text-decoration:none}
::selection{background:var(--accent);color:var(--bg)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:var(--radius)}
#main:focus{outline:none}

.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}
.skip{position:absolute;left:-9999px;top:0;background:var(--fg);color:var(--bg);
  padding:var(--s3) var(--s4);z-index:99}
.skip:focus{left:0}

/* arrows nudge on hover, everywhere */
i{font-style:normal;display:inline-block;transition:transform var(--mid) var(--out)}
a:hover > i,a:focus-visible > i{transform:translateX(4px)}

/* ─────────────────── ambient field (bg.js) ─────────────────── */
.bgfield{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.62;
  transition:opacity var(--mid) var(--ease);
  /* stop it reaching the copy: gone before the lower content band */
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 44%,transparent 76%);
          mask-image:linear-gradient(to bottom,#000 0%,#000 44%,transparent 76%)}
.cursorlayer{position:fixed;inset:0;z-index:60;pointer-events:none;
  transition:opacity var(--mid) var(--ease)}
.topbar,main,.foot{position:relative;z-index:1}
.topbar{z-index:50}

/* ─────────────────────────── top bar ─────────────────────────── */
.topbar{
  position:sticky;top:0;
  background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:blur(16px) saturate(1.4);
}
/* Inner rail matches .shell so the bar's contents line up with page content. */
.topbar-in{
  display:flex;align-items:center;gap:var(--s5);
  max-width:var(--shell);margin:0 auto;
  padding:var(--s4) var(--s6);
  transition:padding var(--mid) var(--ease);
}
.topbar::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 8%,var(--line) 92%,transparent);
  opacity:0;transition:opacity var(--mid) var(--ease);
}
.topbar.condensed .topbar-in{padding:var(--s2) var(--s6)}
.topbar.condensed::after{opacity:1}

.brand{display:flex;align-items:baseline;gap:0;color:inherit;
  font-family:var(--ui);font-size:13.5px;letter-spacing:-.01em;white-space:nowrap;
  transition:font-size var(--mid) var(--ease)}
.topbar.condensed .brand{font-size:12.5px}
.p-user{color:var(--fg)}
.p-host{color:var(--accent)}
.p-dim{color:var(--fg-3)}
/* Steady block cursor (no blink). On hover the wordmark peeks a memory byte,
   tying into the hex field behind it - a small nod, not a gimmick. */
.caret{display:inline-block;height:1.05em;margin-left:6px;color:var(--accent);
  transform:translateY(1px);font-size:.86em;letter-spacing:.04em;white-space:nowrap;
  transition:opacity var(--fast) var(--ease)}
.caret::before{content:"\2588"}
.brand:hover .caret::before{content:attr(data-peek)}
.brand:hover .p-host{color:var(--accent-2)}

.nav{display:flex;gap:var(--s1);margin-left:auto}
.nav a{position:relative;color:var(--fg-3);font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;padding:var(--s2) var(--s3);
  transition:color var(--fast) var(--ease)}
.nav a:hover{color:var(--fg)}
.nav a::after{content:"";position:absolute;left:var(--s3);right:var(--s3);bottom:3px;height:1.5px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--mid) var(--out)}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1)}
.nav a[aria-current="page"]{color:var(--fg)}

.theme{width:30px;height:30px;border:1px solid var(--line-2);background:transparent;
  border-radius:50%;cursor:pointer;display:grid;place-items:center;
  transition:border-color var(--fast) var(--ease),transform var(--slow) var(--out)}
.theme:hover{border-color:var(--accent)}
.theme:active{transform:rotate(180deg)}
.theme-dot{width:12px;height:12px;border-radius:50%;background:var(--fg);
  box-shadow:inset -4px -1px 0 0 var(--bg);transition:box-shadow var(--mid) var(--ease)}

/* ─────────────────────────── layout ─────────────────────────── */
.shell{max-width:var(--shell);margin:0 auto;padding:0 var(--s6)}
.pb{padding-bottom:var(--s9)}
.pb:has(.section.last){padding-bottom:0}

.section{position:relative;padding:var(--s9) 0}
.section::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}
.section.last{padding-bottom:var(--s6)}

/* Name mark: a quiet identity line at the very top of the hero. One optical
   size across all three parts so it reads as a single line, not three. */
.namemark{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--s3);
  margin-bottom:var(--s4);font-family:var(--ui);font-size:clamp(13px,1.4vw,15px)}
.namemark .dev{font-family:var(--display);font-size:1.08em;
  color:var(--accent);line-height:1}
.namemark-rom{font-size:.82em;letter-spacing:.22em;text-transform:uppercase;color:var(--fg-2)}
.namemark-sep{color:var(--line-2);font-size:.82em}
.namemark-gloss{font-family:var(--display);color:var(--fg-3)}

.sec-label{display:flex;align-items:center;gap:var(--s4);
  font-family:var(--ui);font-weight:400;
  font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--fg-3);
  margin-bottom:var(--s6)}
.sec-label::after{content:"";flex:1;height:1px;
  background:linear-gradient(90deg,var(--line),transparent)}

.page-h1{font-size:clamp(34px,5vw,58px);margin:0 0 var(--s5);letter-spacing:-.025em}
.page-lede{font-family:var(--display);font-size:clamp(16px,1.8vw,21px);line-height:1.5;
  color:var(--fg-2);max-width:56ch;margin-bottom:var(--s7)}
.more{margin-top:var(--s6)}

/* staggered reveal - hidden state is opt-in, set by JS, so a script failure
   leaves the content visible rather than blank */
html.anim .reveal{opacity:0;transform:translateY(16px)}
html.anim .reveal.in{
  opacity:1;transform:none;
  transition:opacity 500ms var(--out),transform 500ms var(--out);
  transition-delay:calc(var(--i,0) * 40ms);
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  html.anim .reveal{opacity:1;transform:none}
  *{animation:none!important}
}

/* ─────────────────────────── hero ─────────────────────────── */
.hero{padding:var(--s10) 0 var(--s7)}
.hero-kicker{font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--accent);margin-bottom:var(--s5)}
.hero h1{font-size:clamp(46px,7.4vw,96px);line-height:.98;letter-spacing:-.028em;
  margin-bottom:var(--s5);max-width:15ch}
.hero h1 em{font-style:italic;color:var(--fg-3)}
.hero-lede{font-family:var(--display);font-size:clamp(17px,2vw,23px);line-height:1.5;
  color:var(--fg-2);max-width:54ch;margin-bottom:var(--s4);text-wrap:pretty}
.hero-pay{font-family:var(--display);font-size:clamp(15px,1.7vw,19px);color:var(--fg-3);
  max-width:60ch;margin-bottom:var(--s6);text-wrap:pretty}
.hero-meta{display:flex;flex-wrap:wrap;gap:var(--s3)}
/* Devanagari glyphs render via the Noto fallback in --display/--ui; this only
   nudges size, since Noto's x-height runs a touch small next to Newsreader. */
.dev{font-size:1.04em}

.pill{display:inline-flex;align-items:center;gap:var(--s2);
  font-size:11px;letter-spacing:.1em;
  padding:var(--s2) var(--s4);border:1px solid var(--line-2);border-radius:99px;
  color:var(--fg-2);
  transition:border-color var(--fast) var(--ease),color var(--fast) var(--ease),
             background var(--fast) var(--ease),transform var(--mid) var(--out)}
a.pill:hover{border-color:var(--accent);color:var(--accent);background:var(--bg-2);
  transform:translateY(-2px)}

/* every project, one size, one colour */
.namerows{position:relative;margin-top:var(--s8)}
.namerow{position:relative;display:grid;grid-template-columns:150px minmax(0,1fr);
  gap:var(--s5);padding:var(--s5) 0;align-items:baseline}
.namerow::before,.namerows::after{content:"";position:absolute;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}
.namerow::before{top:0}
.namerows::after{bottom:0}
.nr-label{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--fg-3);line-height:1.7}
.nr-list{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);font-family:var(--display);
  font-size:clamp(18px,1.9vw,23px);line-height:1.45}
.nr-list span{color:var(--fg);white-space:nowrap}
.nr-list .plogo{width:20px;height:20px;object-fit:contain;border-radius:4px;
  vertical-align:-4px;margin-right:9px;background:#fff;padding:1px}
/* the separator trails its own name, so a wrapped line never starts with one */
.nr-list span:not(:last-child)::after{content:" ·";color:var(--line-2)}

/* ─────────────────────────── report cards ─────────────────────────── */
.cards{display:grid;gap:var(--s4)}
.card{
  position:relative;display:block;overflow:hidden;
  padding:var(--s5) var(--s6) var(--s5) var(--s5);
  border:1px solid var(--line);border-left:3px solid var(--sev,var(--line-2));
  background:var(--bg);color:inherit;
  transition:transform var(--mid) var(--out),border-color var(--mid) var(--ease),
             background var(--mid) var(--ease);
}
.card::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 40%,color-mix(in srgb,var(--sev) 7%,transparent));
  opacity:0;transition:opacity var(--mid) var(--ease)}
.card:hover,.card:focus-visible{transform:translateX(6px);background:var(--bg-2);
  border-color:var(--line-2)}
.card:hover::before{opacity:1}
.card-top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s3);
  margin-bottom:var(--s3)}
.card h3{font-size:var(--t-item);line-height:1.15;margin-bottom:var(--s3);max-width:34ch;
  transition:color var(--fast) var(--ease)}
.card:hover h3{color:var(--accent)}
.card p{font-size:13px;color:var(--fg-2);max-width:var(--read)}
.card .held{font-style:italic;color:var(--fg-3)}
.card-foot{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s4);
  margin-top:var(--s4);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-3)}
.card-go{margin-left:auto;color:var(--accent);opacity:0;transform:translateX(-4px);
  transition:opacity var(--mid) var(--ease),transform var(--mid) var(--out)}
.card:hover .card-go,.card:focus-visible .card-go{opacity:1;transform:none}
@media (hover:none){.card-go{opacity:.7;transform:none}}

.tag{font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:2px var(--s2);
  border:1px solid var(--line-2);color:var(--fg-3)}
.tag.sev{border-color:currentColor;font-weight:700}
/* severity escalates in weight, not only hue */
.tag.sev.critical{background:var(--sev-critical);border-color:var(--sev-critical);color:var(--bg)}
.tag.sev.high{color:var(--sev-high)}
.tag.sev.medium{color:var(--sev-medium)}
.tag.cve{color:var(--accent);border-color:var(--accent)}
/* an identifier credited to the first reporter must not read as an award */
.tag.cve.uncredited{color:var(--fg-3);border-color:var(--line-2);border-style:dashed;cursor:help}
.tag.state-Fixed{color:var(--ok);border-color:var(--ok)}

/* ─────────────────────────── filters ─────────────────────────── */
/* This was sticky and rode down the page on top of the cards. The archive is
   short enough that scrolling back up to filter costs nothing. */
.filters{position:relative;padding:var(--s4) 0 var(--s5);margin-bottom:var(--s7)}
.filters::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}

.filter-row{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:center}
.search{flex:1 1 260px;display:flex;align-items:center;gap:var(--s3);
  border:1px solid var(--line-2);padding:var(--s2) var(--s3);background:var(--bg);
  color:var(--fg-3);
  transition:border-color var(--fast) var(--ease),box-shadow var(--fast) var(--ease)}
.search:focus-within{border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 12%,transparent)}
.search input{flex:1;border:0;background:transparent;color:var(--fg);font-family:var(--ui);
  font-size:13px;outline:0;min-width:0}
.search kbd{border:1px solid var(--line-2);padding:0 5px;font-size:10px;color:var(--fg-3);
  border-radius:2px}

.field{display:flex;align-items:center;gap:var(--s2);font-size:10.5px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}
.field select{font-family:var(--ui);font-size:11px;background:var(--bg);color:var(--fg);
  border:1px solid var(--line-2);padding:var(--s1) var(--s2);cursor:pointer}
.field select:focus-visible{outline:none;border-color:var(--accent)}
.sort{margin-left:auto}

.chiprow{display:grid;grid-template-columns:76px minmax(0,1fr);gap:var(--s3);
  align-items:start;margin-top:var(--s3)}
.chiprow.standalone{margin-bottom:var(--s7)}
.chip-label{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--fg-3);
  padding-top:var(--s2)}
/* column count is computed in JS so the last row can never hold exactly one */
.chips{display:grid;grid-template-columns:repeat(var(--cols,3),minmax(0,1fr));gap:var(--s2)}
.chips .chip{width:100%;text-align:center;justify-content:center}
.chips .chip.span{grid-column:1/-1}
.chip{font-family:var(--ui);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  padding:var(--s2) var(--s3);border:1px solid var(--line-2);background:transparent;
  color:var(--fg-2);cursor:pointer;border-radius:99px;
  transition:border-color var(--fast) var(--ease),color var(--fast) var(--ease),
             background var(--fast) var(--ease),transform var(--fast) var(--out)}
.chip:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
.chip[aria-pressed="true"]{background:var(--fg);color:var(--bg);border-color:var(--fg)}

.count-row{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s5)}
.result-count{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--fg-3)}
.clear,.linkish{background:none;border:0;cursor:pointer;color:var(--accent);
  font-family:var(--ui);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;padding:0}
.clear:hover,.linkish:hover{color:var(--accent-2);text-decoration:underline}
.empty{padding:var(--s7) 0;text-align:center;color:var(--fg-3);font-family:var(--display);
  font-size:20px;line-height:1.5}

/* ─────────────────────────── article ─────────────────────────── */
.crumbs{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;
  font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3);
  padding:var(--s6) 0 var(--s5)}
.crumbs a{color:var(--fg-3)}
.crumbs a:hover{color:var(--accent)}

.art-head{position:relative;padding-bottom:var(--s7);margin-bottom:var(--s7)}
.art-head::after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}
.art-eyebrow{display:flex;flex-wrap:wrap;gap:var(--s3);font-size:10.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--fg-3);margin-bottom:var(--s5)}
.art-eyebrow b{color:var(--accent);font-weight:400}
.art-head h1{font-size:clamp(32px,4.8vw,60px);line-height:1.04;letter-spacing:-.025em;
  max-width:22ch;margin-bottom:var(--s5)}
.art-deck{font-family:var(--display);font-style:italic;font-size:clamp(17px,2vw,22px);
  line-height:1.45;color:var(--fg-2);max-width:52ch;margin-bottom:var(--s6)}
.art-byline{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);align-items:center;
  font-size:11px;letter-spacing:.1em;color:var(--fg-3)}
.art-byline .who{color:var(--fg);letter-spacing:.02em}

.art-wrap{display:grid;grid-template-columns:200px minmax(0,1fr);gap:var(--s8);
  padding-bottom:var(--s9)}
/* Blog posts: header and body share one column so their left AND right edges
   line up; the TOC sits in the right rail. The content column is capped to a
   comfortable measure so lines don't stretch, leftover becomes a right margin. */
/* content column width is set live to the right edge of the "INDEX" nav word
   (see alignPostwrap in app.js); this is the fallback before/without JS. */
.art-wrap.postwrap{grid-template-columns:minmax(0,1fr) 200px;gap:var(--s8)}
.postmain{min-width:0}
.postwrap .toc{justify-self:end;width:200px}
.postwrap .prose{max-width:none}
/* justify body copy so the right edge is flush; hyphenate to avoid big gaps.
   Covers article prose (disclosures + posts) and the home's readable paragraphs. */
.prose p,.prose li,.hero-lede,.step p,.row p,.row li{text-align:justify;
  -webkit-hyphens:auto;hyphens:auto}
@media (max-width:920px){
  /* collapse to one column: the hidden TOC track was still reserving 200px,
     squeezing the content column to a sliver on phones */
  .art-wrap.postwrap{grid-template-columns:1fr}
  .art-wrap.postwrap .toc{display:none}
}
.toc{position:sticky;top:calc(var(--topbar-h,56px) + var(--s5));align-self:start;
  max-height:calc(100dvh - var(--topbar-h,56px) - var(--s7));overflow:auto}
.toc h4{font-family:var(--ui);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:var(--s3);font-weight:400}
.toc ol{list-style:none;margin:0;padding:0;border-left:1px solid var(--line)}
.toc a{display:block;padding:var(--s2) var(--s3);font-size:11.5px;color:var(--fg-3);
  border-left:1.5px solid transparent;margin-left:-1px;
  transition:color var(--fast) var(--ease),border-color var(--mid) var(--ease),
             padding-left var(--mid) var(--out)}
.toc a:hover{color:var(--fg)}
.toc a.active{color:var(--fg);border-left-color:var(--accent);padding-left:var(--s4)}

.prose{max-width:var(--read)}
.prose h2,.prose h3,.prose h4{font-family:var(--display)}
.prose h3{font-size:clamp(19px,2.2vw,24px);margin:var(--s7) 0 var(--s3)}
.prose h4{font-size:17px;margin:var(--s6) 0 var(--s3)}
.prose ul,.prose ol{margin:0 0 var(--s4);padding-left:var(--s5);display:grid;gap:var(--s2)}
.prose li{font-size:15px;line-height:1.75;color:var(--fg-2)}
.prose blockquote{margin:var(--s5) 0;padding-left:var(--s4);border-left:2px solid var(--line-2)}
.prose blockquote p{margin:0;font-family:var(--display);font-size:16px;color:var(--fg-2)}
.prose pre{background:var(--bg-2);border:1px solid var(--line);padding:var(--s4);
  overflow-x:auto;margin:0 0 var(--s4)}
.prose pre code{background:none;padding:0;font-size:12.5px;line-height:1.7}
.prose hr{border:0;height:1px;background:var(--line);margin:var(--s7) 0}
.prose img{max-width:100%;height:auto;display:block;margin:var(--s5) 0;
  border:1px solid var(--line)}
.post-card{border-left-color:var(--line-2)}
.prose h2{font-size:clamp(24px,3vw,32px);margin:var(--s8) 0 var(--s4);
  scroll-margin-top:calc(var(--topbar-h,56px) + var(--s5))}
.prose h2:first-child{margin-top:0}
/* anchored jumps must clear the sticky topbar for every heading level */
.prose h3,.prose h4{scroll-margin-top:calc(var(--topbar-h,56px) + var(--s5))}
.prose h3:first-child,.prose h4:first-child{margin-top:0}
.prose p{font-size:15px;line-height:1.75;color:var(--fg-2);margin-bottom:var(--s4)}
.prose code{font-size:12.5px;background:var(--bg-3);padding:1px 5px;border-radius:2px;
  color:var(--fg)}
.prose a{border-bottom:1px solid color-mix(in srgb,var(--accent) 40%,transparent);
  transition:border-color var(--fast) var(--ease)}
.prose a:hover{border-bottom-color:var(--accent)}
.prose .callout{border-left:3px solid var(--accent);background:var(--bg-2);
  padding:var(--s4) var(--s5);margin:var(--s6) 0}
.prose .callout p{margin:0;font-size:13.5px}

.art-facts{border:1px solid var(--line);margin:var(--s7) 0}
.art-facts div{display:flex;justify-content:space-between;gap:var(--s4);
  padding:var(--s3) var(--s4);border-bottom:1px solid var(--line);font-size:12px}
.art-facts div:last-child{border-bottom:0}
.art-facts dt{color:var(--fg-3);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase}
.art-facts dd{margin:0;text-align:right;color:var(--fg)}
/* an advisory credited to someone else must not look like an award */
.art-facts dd a.not-mine{color:var(--fg-3);border-bottom:1px dashed var(--line-2)}
.art-facts dd a.not-mine:hover{color:var(--fg-2)}

.prevnext{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:var(--s4);
  padding-top:var(--s7);margin-top:var(--s8)}
.prevnext::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}
.prevnext a{border:1px solid var(--line);padding:var(--s4);color:inherit;
  transition:border-color var(--mid) var(--ease),background var(--mid) var(--ease),
             transform var(--mid) var(--out)}
.prevnext a:hover{border-color:var(--accent);background:var(--bg-2);transform:translateY(-2px)}
.prevnext span{display:block;font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:var(--s2)}
.prevnext b{font-family:var(--display);font-weight:400;font-size:16px}
.prevnext .nx{text-align:right}

/* ─────────────────────────── method + certs ─────────────────────────── */
.method{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--s6)}
.step{position:relative;padding-top:var(--s5);border-top:1px solid var(--line)}
.step-n{position:absolute;top:var(--s5);right:0;font-size:11px;letter-spacing:.2em;
  color:var(--line-2)}
.step h3{font-size:var(--t-item);margin-bottom:var(--s3)}
.step p{font-size:13.5px;line-height:1.75;color:var(--fg-2)}

/* Fixed 4 wide so 8 certs fill two full rows - auto-fit left empty tracks that
   showed the --line background as a gray block. Assumes a count divisible by 4
   (and by 2 on narrow); revisit these if the cert count stops being a multiple. */
.certs{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line)}
.cert{position:relative;background:var(--bg);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s2);
  transition:background var(--mid) var(--ease)}
.cert:hover{background:var(--bg-2)}
.certlogo{position:absolute;top:var(--s5);right:var(--s5);width:26px;height:26px;
  object-fit:contain;border-radius:5px;background:#fff;padding:2px}
.cert b{font-family:var(--display);font-weight:400;font-size:clamp(26px,3vw,34px);
  line-height:1;letter-spacing:-.02em}
.cert-full{font-size:12px;color:var(--fg-2);line-height:1.5}
.cert-by{font-size:11px;color:var(--fg-3);line-height:1.5}
.cert-group{margin-top:auto;padding-top:var(--s3);font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--fg-3)}
.certs-note{margin-top:var(--s4);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--fg-3)}

/* ─────────────────────────── audits ─────────────────────────── */
.audit-note{border-left:2px solid var(--line-2);padding:var(--s2) 0 var(--s2) var(--s4);
  margin-bottom:var(--s7);font-size:13px;line-height:1.7;color:var(--fg-2);max-width:60ch}

/* project cards: official logo + name + category */
.acards{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line)}
.acard{background:var(--bg);padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);
  min-height:150px;font-family:var(--ui);color:var(--fg);transition:background var(--mid) var(--ease)}
.acard:hover{background:var(--bg-2)}
.acard-logo{width:36px;height:36px;object-fit:contain;border-radius:7px;background:#fff;padding:3px}
.acard-name{font-family:var(--display);font-size:var(--t-item);line-height:1.05}
.acard-foot{display:flex;flex-direction:column;gap:var(--s2)}
.acard-area{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--fg-3)}
.acard-langs{display:flex;flex-wrap:wrap;gap:var(--s1)}
.acard-langs b{font-weight:400;font-size:10px;letter-spacing:.1em;padding:2px var(--s2);
  border:1px solid var(--line-2);color:var(--fg-3)}
.acard-langs b:first-child{color:var(--fg-2);border-color:var(--fg-3)}
/* borders live on the tiles, so a short last row leaves no filled dead cell */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));
  border-top:1px solid var(--line);border-left:1px solid var(--line)}
.tile{border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:var(--s5);display:flex;flex-direction:column;gap:var(--s2);min-height:156px;
  transition:background var(--mid) var(--ease)}
.tile:hover{background:var(--bg-2)}
.tile h3{font-size:var(--t-item)}
.tile .area{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--fg-3)}
.tile p{font-size:12px;color:var(--fg-2);margin-top:auto}
.tile .langs{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s3)}
.tile .langs b{font-weight:400;font-size:10px;letter-spacing:.1em;padding:2px var(--s2);
  border:1px solid var(--line-2);color:var(--fg-3)}
.tile .langs b:first-child{color:var(--fg-2);border-color:var(--fg-3)}

/* ─────────────────────────── rows / boxes ─────────────────────────── */
.rows{position:relative}
.row{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:var(--s2) var(--s5);padding:var(--s5) 0;align-items:baseline}
.row::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 4%,var(--line) 96%,transparent)}
.row h3{font-size:var(--t-item)}
.row .meta{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3);
  text-align:right;white-space:nowrap}
.row p{grid-column:1/-1;font-size:13px;color:var(--fg-2);max-width:var(--read)}
.row ul{grid-column:1/-1;margin:var(--s2) 0 0;padding:0;list-style:none;display:grid;gap:var(--s2)}
.row li{position:relative;padding-left:var(--s4);font-size:13px;color:var(--fg-2);
  max-width:var(--read)}
.row li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:1px;
  background:var(--accent)}
.row .lead-li{color:var(--fg);font-weight:500}

.two{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s4)}
.box{border:1px solid var(--line);padding:var(--s5);display:flex;flex-direction:column;
  gap:var(--s3);color:inherit;
  transition:border-color var(--mid) var(--ease),background var(--mid) var(--ease),
             transform var(--mid) var(--out)}
.box .tag{align-self:flex-start}
a.box:hover{border-color:var(--accent);background:var(--bg-2);transform:translateY(-3px)}
.box h3{font-size:var(--t-item)}
.box p{font-size:13px;color:var(--fg-2);flex:1}
.box .go{font-size:11px;color:var(--accent)}

/* ─────────────────────────── footer ─────────────────────────── */
.foot{position:relative;margin-top:var(--s8);padding:var(--s8) 0 var(--s7)}
.foot::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--line) 6%,var(--line) 94%,transparent)}
.foot-in{max-width:var(--shell);margin:0 auto;padding:0 var(--s6);
  display:grid;grid-template-columns:2fr 1fr 1fr 1.6fr;gap:var(--s7)}
.foot-name{font-family:var(--display);font-size:30px;letter-spacing:-.02em;margin-bottom:var(--s2)}
.foot-say{font-family:var(--display);font-style:italic;font-size:16px;color:var(--fg-3);
  margin-bottom:var(--s5)}
.foot-status{display:flex;align-items:center;gap:var(--s2);font-size:11px;color:var(--fg-2);
  max-width:34ch;line-height:1.5}
.live{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:0 0 auto;
  animation:ping2 2.6s var(--ease) infinite}
@keyframes ping2{
  0%,70%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 55%,transparent)}
  100%{box-shadow:0 0 0 8px transparent}
}
.foot-col h4{font-family:var(--ui);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--fg-3);font-weight:400;margin-bottom:var(--s4)}
.foot-col a{display:flex;justify-content:space-between;gap:var(--s3);font-size:12px;
  color:var(--fg);padding:var(--s2) 0;border-bottom:1px solid transparent;
  transition:color var(--fast) var(--ease),border-color var(--fast) var(--ease)}
.foot-col a span{color:var(--fg-3);font-size:11px}
.foot-col a:hover{color:var(--accent);border-bottom-color:var(--line)}
.foot-note{font-size:11.5px;color:var(--fg-3);line-height:1.6;margin-bottom:var(--s3)}

/* ─────────────────────────── responsive ─────────────────────────── */
@media (max-width:1000px){
  .foot-in{grid-template-columns:1fr 1fr;gap:var(--s6)}
}
@media (max-width:920px){
  .certs{grid-template-columns:repeat(2,1fr)}
  .art-wrap{grid-template-columns:1fr;gap:var(--s6)}
  .toc{position:static;max-height:none;padding-bottom:var(--s5);border-bottom:1px solid var(--line)}
  .toc ol{display:flex;flex-wrap:wrap;gap:var(--s2);border-left:0}
  .toc a{border-left:0;border-bottom:1.5px solid transparent;padding:var(--s1) var(--s2)}
  .toc a.active{border-left:0;border-bottom-color:var(--accent);padding-left:var(--s2)}
}

/* Touch: every control gets a 44px target, and the micro-labels stop being 10px.
   Measured before the fix: chip 32, nav 34, theme 30, footer link 36, select 26. */
@media (max-width:900px),(pointer:coarse){
  .chip{min-height:44px;display:inline-flex;align-items:center;font-size:11px}
  .nav a{min-height:44px;display:inline-flex;align-items:center}
  .theme{width:40px;height:40px}
  .foot-col a{min-height:44px;align-items:center}
  .field select{min-height:40px;padding:var(--s2)}
  .search{min-height:44px}
  .clear,.linkish{min-height:44px;display:inline-flex;align-items:center;font-size:11px}
  .toc a{min-height:40px;display:inline-flex;align-items:center}

  .tag,.tag.sev,.tag.cve,.tag.state-Fixed,.tag.sev.critical,.tag.sev.high,.tag.sev.medium,
  .tag.cve.uncredited{font-size:11px}
  .foot-col h4,.toc h4,.chip-label,.art-facts dt{font-size:11px}
  .card-foot,.card-go,.nr-label,.sec-label,.tile .area,.result-count,.crumbs,
  .art-byline,.tile .lang,.meta,.row .meta,.step-n,.cert-group,.certs-note{font-size:11px}
  .foot-note{font-size:12px}
}

@media (max-width:760px){
  .shell,.foot-in{padding:0 var(--s4)}
  /* topbar stacks: brand + theme on row 1, nav on its own row below */
  .topbar-in{padding:var(--s3) var(--s4);gap:var(--s2) var(--s3);flex-wrap:wrap;align-items:center}
  .topbar.condensed .topbar-in{padding:var(--s2) var(--s4)}
  .brand{order:1}
  .theme{order:2;margin-left:auto}
  .nav{order:3;flex-basis:100%;margin-left:0;flex-wrap:wrap;gap:0 var(--s2)}
  .nav a{padding:var(--s2) 0;margin-right:var(--s3);letter-spacing:.1em}
  /* the ambient hex field competes with body text on a narrow screen */
  .bgfield{opacity:.14}
  .section{padding:var(--s8) 0}
  .hero{padding:var(--s8) 0 var(--s6)}
  .filter-row{flex-direction:column;align-items:stretch}
  .search{flex:0 0 auto;width:100%}   /* stop flex-grow stretching it vertically */
  .field{justify-content:space-between}
  .field select{flex:1;margin-left:var(--s3)}
  .sort{margin-left:0}
  .namerow{grid-template-columns:1fr;gap:var(--s2)}
  .prevnext{grid-template-columns:1fr}
  .prevnext .nx{text-align:left}
  .row{grid-template-columns:1fr}
  .row .meta{text-align:left}
  .foot-in{grid-template-columns:1fr;gap:var(--s6)}
}

@media print{
  .topbar,.filters,.toc,.prevnext,.theme,.skip,.foot,.bgfield{display:none!important}
  body{background:#fff;color:#000}
  .art-wrap{grid-template-columns:1fr}
  html.anim .reveal{opacity:1;transform:none}
}

/* ─────────────────────────── easter eggs ─────────────────────────── */
.egg-toast{position:fixed;left:50%;bottom:var(--s6);transform:translate(-50%,12px);
  font-family:var(--ui);font-size:11px;letter-spacing:.05em;color:var(--bg);
  background:var(--accent);padding:var(--s2) var(--s4);border-radius:99px;
  z-index:200;opacity:0;pointer-events:none;max-width:calc(100vw - var(--s6));
  text-align:center;transition:opacity var(--mid) var(--ease),transform var(--mid) var(--out)}
.egg-toast.show{opacity:1;transform:translate(-50%,0)}
.egg-rain{position:fixed;inset:0;z-index:120;pointer-events:none;mix-blend-mode:screen}
/* root mode runs hot: accent turns alarm-red everywhere, including the hex field.
   :root.rooted needed to outrank :root[data-theme="dark"] on specificity. */
:root.rooted{--accent:#ff3b30;--accent-2:#ff5a4f}
:root.rooted .topbar::after{opacity:1;background:#ff3b30}
/* discoverable trigger hint, styled as a faint shell comment next to the wordmark */
