/* Companion site for the MCAIT 2026 NDMO/PDPL classifier paper.
   Palette follows Figure 1 of the paper: navy pipeline steps, amber interim branch, green PDPL
   axis, purple human gate, teal optional detector. Light and dark via prefers-color-scheme. */

/* Self-hosted, latin subset, variable weight. The Google Fonts stylesheet was removed so the
   pages make no external request; naming Inter and Source Serif 4 in the stacks while serving
   neither meant every visitor fell back to system-ui and a local serif, which is not the design.
   These are the same files Google serves for the latin subset, fetched once and committed:
   SIL Open Font Licence 1.1 for both, texts in assets/fonts/. font-display:swap so text paints
   immediately in the fallback and never blocks. unicode-range keeps them off non-latin runs, so
   the Arabic wordmark still uses the reader's own Arabic face. */
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/source-serif-4-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #fbfaf7;
  --bg-2: #f2efe8;
  --panel: #ffffff;
  --ink: #1a1a1a;
  --ink-2: #4a4a4a;
  /* #7a7a7a measured 4.29:1 on white and 3.74:1 on --bg-2, below WCAG AA for the
     muted text, definition-list labels and impact-dimension captions that use it. */
  --ink-3: #6b6b6b;
  --line: #ddd8cc;
  --navy: #1f4e79;
  --navy-bg: #e8eef7;
  --amber: #8a5a00;
  --amber-bg: #fbf3e2;
  --green: #2e6e3f;
  --green-bg: #e9f4ec;
  --purple: #5b2d82;
  --purple-bg: #f1ebf7;
  --teal: #0f6e73;
  --teal-bg: #e4f1f1;
  --red: #a3261e;
  --red-bg: #fbe9e7;
  --lvl-public: #3b6e3f;
  --lvl-restricted: #8a5a00;
  --lvl-secret: #a3261e;
  --lvl-ts: #2b2140;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --serif: "Source Serif 4", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --btn-fg: #ffffff;
  --btn-bg: #1f4e79;
  --btn-bg-hover: #2a62a3;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 16px rgba(20,30,50,.06);
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14161a; --bg-2: #1b1e24; --panel: #1f232a;
    /* --ink-3 was #8f8d86: 4.25-4.38:1 on the tinted callout backgrounds, under AA's 4.5.
       #9b9992 is 4.96:1 at worst (teal-bg) and still reads as muted. */
    --ink: #ecebe6; --ink-2: #c4c2ba; --ink-3: #9b9992; --line: #33373f;
    --navy: #8fb4de; --navy-bg: #1d2a3a; --amber: #e0a94a; --amber-bg: #34290f;
    --green: #7cc48c; --green-bg: #17301d; --purple: #c3a2e6; --purple-bg: #2b1f3a;
    --teal: #7dcbcf; --teal-bg: #10302f; --red: #f08a80; --red-bg: #3a1a17;
    --lvl-public: #7cc48c; --lvl-restricted: #e0a94a; --lvl-secret: #f08a80; --lvl-ts: #d9d2ee;
    --btn-fg: #14161a; --btn-bg: #9dc0e8; --btn-bg-hover: #b6d1f0;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 4px 16px rgba(0,0,0,.35);
  }
}

* { box-sizing: border-box; }
/* Chrome on Android inflates text in blocks it decides are the main content, leaving headers
   and navigation alone -- which is why a phone could render this page with body copy far larger
   than its own nav while a 390px desktop emulation looked correct. width=device-width usually
   suppresses it, but not in every layout, and making main.wrap a flex column on small screens
   is exactly the kind of change that alters how the heuristic clusters text. This is the
   documented opt-out. It disables the automatic boost only: a reader's own font-size preference
   still applies. */
html { color-scheme: light dark; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--navy); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }
h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -.01em; line-height: 1.2; }
h1 { font-size: clamp(1.9rem, 4vw, 2.9rem); margin: 0 0 .5rem; }
h2 { font-size: 1.55rem; margin: 2.5rem 0 .75rem; }
h3 { font-size: 1.15rem; margin: 1.5rem 0 .5rem; }
p { margin: .6rem 0; }
code, .mono { font-family: var(--mono); font-size: .92em; }
code { background: var(--bg-2); padding: .1em .35em; border-radius: 4px; }
small, .muted { color: var(--ink-3); }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
/* One column for every block, with running text capped instead. Page-level sections used to
   split between 760px and 1080px, so the right edge stepped in and out as you scrolled while the
   left edge stayed put. Boxes now align; only the text is short. */
.narrow { max-width: 74ch; }
/* Prose that is not inside .narrow inherits the 1080px column and reaches ~130 characters a
   line, about twice a comfortable measure. Cards, tables and lists are unaffected: this caps
   the running text only. */
.callout p, section > p, .hero > p:not(.lede) { max-width: 74ch; }

/* --- header / nav --------------------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--line); background: var(--panel);
  position: sticky; top: 0; z-index: 20;
}
.site-header .wrap { display: flex; align-items: center; gap: 1.5rem; min-height: 58px; }
.brand { font-family: var(--serif); font-weight: 600; font-size: 1.05rem; color: var(--ink); text-decoration: none; white-space: nowrap; }
.brand span { color: var(--navy); }
nav.main { display: flex; gap: .25rem; margin-left: auto; flex-wrap: wrap; }
nav.main a {
  color: var(--ink-2); text-decoration: none; padding: .45rem .7rem; border-radius: 6px; font-size: .93rem;
}
nav.main a:hover { background: var(--bg-2); color: var(--ink); }
nav.main a[aria-current="page"] { background: var(--navy-bg); color: var(--navy); font-weight: 600; }
/* On a phone the hero pushed the tool off the first screen: on triage.html the submit button
   sat at 1061px of an 844px viewport, so nobody could type without scrolling first. Below 640px
   the explanatory lede moves beneath the tool it explains; the heading still names the page, and
   desktop order is untouched. */
@media (max-width: 640px) {
  /* .two collapses to one column here, and the classifier's lede lives inside one of its cells,
     so that cell has to order its children too. Untouched children keep order 50 and therefore
     document order, so this reorders nothing that is not explicitly marked. */
  main.wrap, main.wrap .two > div { display: flex; flex-direction: column; }
  /* :where() so the default contributes no specificity: written plainly, the descendant
     selector for the nested cell outranked the .m* classes and nothing reordered. */
  :where(main.wrap) > *, :where(main.wrap .two > div) > * { order: 50; }
  main.wrap .m1 { order: 1; } main.wrap .m2 { order: 2; } main.wrap .m3 { order: 3; }
  main.wrap .m4 { order: 4; } main.wrap .m5 { order: 5; }
}
@media (max-width: 640px) {
  .site-header .wrap { flex-wrap: wrap; padding: 8px 20px; }
  nav.main { margin-left: 0; }
  /* wrapped, the sticky header grew to ~193px and permanently covered a quarter of a
     375px viewport; let it scroll away instead */
  .site-header { position: static; }
}

/* --- hero ---------------------------------------------------------------------------- */
.hero { padding: 3.5rem 0 2.5rem; }
.eyebrow { text-transform: uppercase; letter-spacing: .12em; font-size: .74rem; color: var(--navy); font-weight: 600; margin-bottom: 1rem; }
.hero .lede { font-size: 1.15rem; color: var(--ink-2); max-width: 760px; }
.byline { color: var(--ink-2); margin: .75rem 0 1.5rem; }
.byline strong { color: var(--ink); }
.cta-row { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1.5rem; }
.btn {
  display: inline-block; padding: .65rem 1.1rem; border-radius: 8px; text-decoration: none; font-weight: 600;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; font-size: .95rem;
  font-family: inherit;
}
.btn:hover { border-color: var(--navy); }
.btn.primary { background: var(--btn-bg); border-color: var(--btn-bg); color: var(--btn-fg); }
.btn.primary:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); }
.btn.small { padding: .4rem .75rem; font-size: .85rem; font-weight: 500; }
button.btn:disabled { opacity: .5; cursor: default; }

/* --- stat strip ------------------------------------------------------------------------ */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin: 2rem 0; }
.stat { background: var(--panel); padding: 1rem 1.1rem; }
.stat .n { font-family: var(--serif); font-size: 1.9rem; font-weight: 600; line-height: 1.1; color: var(--navy); }
.stat .l { font-size: .85rem; color: var(--ink-2); margin-top: .3rem; }
.stat.warn .n { color: var(--amber); }
.stat.bad .n { color: var(--red); }

/* --- cards ----------------------------------------------------------------------------- */
.grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.2rem;
  box-shadow: var(--shadow);
}
.card h3 { margin-top: 0; }
.card.step { border-top: 4px solid var(--navy); }
.card.interim { border-top: 4px solid var(--amber); }
.card.flags { border-top: 4px solid var(--green); }
.card.gate { border-top: 4px solid var(--purple); }
.card.detector { border-top: 4px solid var(--teal); }
.card .num { font-family: var(--serif); color: var(--navy); font-weight: 700; margin-right: .4rem; }
a.card { text-decoration: none; color: inherit; display: block; }
a.card:hover { border-color: var(--navy); }
a.card .go { color: var(--navy); font-weight: 600; margin-top: .6rem; display: block; }

/* --- callouts -------------------------------------------------------------------------- */
.callout { border-left: 4px solid var(--navy); background: var(--navy-bg); padding: .9rem 1.1rem; border-radius: 0 var(--radius) var(--radius) 0; margin: 1.25rem 0; }
.callout.warn { border-color: var(--amber); background: var(--amber-bg); }
.callout.bad { border-color: var(--red); background: var(--red-bg); }
.callout.ok { border-color: var(--green); background: var(--green-bg); }
.callout p:first-child { margin-top: 0; } .callout p:last-child { margin-bottom: 0; }

/* --- badges ---------------------------------------------------------------------------- */
.badge {
  display: inline-block; padding: .15em .6em; border-radius: 999px; font-size: .8rem; font-weight: 600;
  border: 1px solid currentColor; line-height: 1.5; white-space: nowrap;
}
/* the long headline badges ("Unclassified — interim Restricted handling (§1.4)") must wrap
   rather than push the page wider than the viewport */
.result .headline .badge { white-space: normal; }
.two > div { min-width: 0; }
.lvl-Public { color: var(--lvl-public); }
.lvl-Restricted { color: var(--lvl-restricted); }
.lvl-Secret { color: var(--lvl-secret); }
.lvl-Top.Secret, .lvl-TopSecret { color: var(--lvl-ts); }
.badge.gate { color: var(--purple); background: var(--purple-bg); }
.badge.auto { color: var(--green); background: var(--green-bg); }
.badge.interim { color: var(--amber); background: var(--amber-bg); }
.badge.flag { color: var(--green); background: var(--green-bg); border-color: transparent; font-weight: 500; white-space: normal; }
.badge.pass { color: var(--green); background: var(--green-bg); }
.badge.fail { color: var(--red); background: var(--red-bg); }
.badge.legacy { color: var(--ink-3); }

/* --- forms ----------------------------------------------------------------------------- */
label { display: block; font-size: .85rem; font-weight: 600; color: var(--ink-2); margin: .8rem 0 .3rem; }
input[type=text], textarea, select {
  width: 100%; font: inherit; padding: .6rem .7rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--ink);
}
input[type=text].mono, textarea.mono { font-family: var(--mono); font-size: .92rem; }
/* the native checkbox renders 13x13; accent-color keeps the platform control while sizing it */
input[type=checkbox] { width: 18px; height: 18px; accent-color: var(--navy); cursor: pointer; }
label:has(> input[type=checkbox]) { min-height: 24px; align-items: center; }
textarea { min-height: 120px; resize: vertical; }
input:focus, textarea:focus { outline: 2px solid var(--navy); outline-offset: 1px; border-color: transparent; }
.chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0 1rem; }
.chip { font-family: var(--mono); font-size: .8rem; padding: .25rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: var(--panel); cursor: pointer; color: var(--ink-2); }
.chip:hover { border-color: var(--navy); color: var(--navy); }
.two { display: grid; gap: 1.25rem; grid-template-columns: 1fr 1fr; }
@media (max-width: 800px) { .two { grid-template-columns: 1fr; } }

/* --- result panel ---------------------------------------------------------------------- */
.result { margin-top: 1rem; }
.result .headline { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: .75rem; }
.result .headline .level { font-family: var(--serif); font-size: 1.7rem; font-weight: 700; }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; font-size: .93rem; }
.kv dt { color: var(--ink-3); font-weight: 500; }
.kv dd { margin: 0; }
/* the max-content label column leaves too little for long pattern chips on a phone */
@media (max-width: 560px) {
  .kv { grid-template-columns: 1fr; gap: .15rem; }
  .kv dt { margin-top: .5rem; }
}
.impact { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin: .5rem 0; }
/* four impact dimensions do not fit 375px: the row forced the whole page to scroll sideways */
@media (max-width: 520px) { .impact { grid-template-columns: repeat(2, 1fr); } }
.impact .dim { background: var(--bg-2); border-radius: 6px; padding: .45rem .5rem; text-align: center; }
.impact .dim .d { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.impact .dim .v { font-weight: 600; }
.impact .dim.hit { background: var(--navy-bg); color: var(--navy); }
/* the muted caption colour measures 4.38:1 on the highlighted dimension's tinted
   background in dark mode; inside a hit tile it takes the tile's own colour (6.8:1) */
.impact .dim.hit .d { color: inherit; }
.trace { list-style: none; padding: 0; margin: .4rem 0; }
.trace li { padding: .35rem .5rem; border-left: 3px solid var(--line); margin: .25rem 0; font-size: .9rem; }
.trace li.winner { border-color: var(--navy); background: var(--navy-bg); }
.cite { font-size: .9rem; color: var(--ink-2); border-left: 3px solid var(--green); padding-left: .7rem; margin: .5rem 0; }

/* --- tables ---------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; margin: .75rem 0 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
table { border-collapse: collapse; width: 100%; font-size: .9rem; }
th, td { text-align: left; padding: .5rem .7rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); font-weight: 600; background: var(--bg-2); position: sticky; top: 0; }
tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr.hl td { background: var(--navy-bg); font-weight: 600; }
td.mono { font-family: var(--mono); font-size: .85rem; }
caption { caption-side: top; text-align: left; font-family: var(--serif); font-weight: 600; font-size: 1rem; padding: .7rem .7rem .3rem; color: var(--ink); }
.bar { display: inline-block; height: .6em; background: var(--navy); border-radius: 2px; vertical-align: middle; margin-right: .4rem; opacity: .8; }

/* --- pattern inventory ----------------------------------------------------------------- */
details.rule { border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); margin: .6rem 0; }
details.rule summary { padding: .8rem 1rem; cursor: pointer; display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; }
details.rule summary code { font-weight: 600; }
details.rule .body { padding: 0 1rem 1rem; border-top: 1px solid var(--line); }
.patterns { display: flex; flex-wrap: wrap; gap: .35rem; margin: .5rem 0; }
.pat { font-family: var(--mono); font-size: .82rem; padding: .15rem .5rem; background: var(--bg-2); border-radius: 4px; }
.pat.prone { background: var(--amber-bg); color: var(--amber); font-weight: 700; }
.pat.desc { background: var(--green-bg); color: var(--green); }
[dir=auto] { unicode-bidi: plaintext; }

/* --- footer ---------------------------------------------------------------------------- */
/* Sticky section jump bar (rules pages). Horizontally scrollable on a phone rather than
   wrapping to three rows and eating the screen it exists to save. */
.jump { position: sticky; top: 0; z-index: 5; display: flex; gap: .3rem; overflow-x: auto;
  margin: 0 0 1.25rem; padding: .5rem 0; background: var(--bg); border-bottom: 1px solid var(--line);
  scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.jump::-webkit-scrollbar { display: none; }
.jump a { flex: 0 0 auto; font-size: .82rem; padding: .35rem .7rem; min-height: 24px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink-2); text-decoration: none; white-space: nowrap; }
.jump a:hover, .jump a:focus-visible { border-color: var(--navy); color: var(--navy); }
main h2[id] { scroll-margin-top: 3.5rem; }

.site-footer { border-top: 1px solid var(--line); margin-top: 4rem; padding: 2rem 0 3rem; color: var(--ink-2); font-size: .9rem; }
.site-footer .wrap { display: grid; gap: 1.5rem; grid-template-columns: 2fr 1fr 1fr; }
@media (max-width: 720px) { .site-footer .wrap { grid-template-columns: 1fr; } }
.site-footer h4 { margin: 0 0 .5rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
/* 16px-tall link rows are below the 24px minimum target size (WCAG 2.5.8); these are list
   navigation, not links inline in a sentence, so the exception does not apply. */
.site-footer li { margin: .25rem 0; }
.site-footer li a { display: inline-block; padding: .25rem 0; min-height: 24px; }
/* the provenance line carries a long generated path and a hash: let them break rather
   than push the whole page wider than a phone viewport */
.site-footer code, .site-footer p { overflow-wrap: anywhere; }
pre.bib { background: var(--bg-2); padding: 1rem; border-radius: var(--radius); white-space: pre-wrap; overflow-wrap: anywhere; font-size: .82rem; line-height: 1.45; }
td.nowrap { white-space: nowrap; }
.sr { position: absolute; left: -9999px; }

/* --- tasnif umbrella additions ---------------------------------------------------------- */
.brand .ar { font-size: 1.15em; margin-right: .15em; }
.brand .sep { color: var(--ink-3); font-weight: 400; margin: 0 .2em; }
.brand .section { color: var(--ink-2); font-weight: 500; font-size: .95em; }
nav.main a.switch { margin-left: .5rem; color: var(--navy); border: 1px solid var(--line); }
.ar-display { display: block; font-size: 1.15em; color: var(--navy); line-height: 1.1; margin-bottom: .1em; }
.grid.two-up { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
a.card.paper h2 { margin: .4rem 0 .6rem; font-size: 1.3rem; }
a.card.paper .eyebrow { margin-bottom: .2rem; }
ul.facts { padding-left: 1.1rem; margin: .6rem 0; color: var(--ink-2); font-size: .93rem; }
ul.facts li { margin: .25rem 0; }
figure.figure { margin: 1.5rem 0 0; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem; }
figure.figure img { display: block; max-width: 100%; height: auto; margin: 0 auto; border-radius: 4px; }
/* The figures are the artifact's own PNGs on white paper and are not regenerated here, so in
   dark mode they arrive as a bright rectangle. A slight dim takes the glare off without
   touching the plotted colours; the data is unchanged. */
@media (prefers-color-scheme: dark) { figure.figure img { filter: brightness(.9); } }
figure.figure figcaption { font-size: .85rem; color: var(--ink-2); margin-top: .6rem; }
/* EU AI Act tiers */
.tier-prohibited { color: var(--red); }
.tier-high { color: var(--amber); }
.tier-indeterminate { color: var(--purple); }
.tier-limited { color: var(--teal); }
.tier-minimal { color: var(--green); }
.result .level.tier-prohibited, .result .level.tier-high, .result .level.tier-indeterminate, .result .level.tier-limited, .result .level.tier-minimal { font-family: var(--serif); font-size: 1.5rem; font-weight: 700; }

/* Mobile hero scale. Deliberately at the END of the stylesheet: the earlier max-width:640px
   block sits above the base .hero/.eyebrow/h1 rules, so overrides written there lose the
   cascade at equal specificity and silently do nothing. The hero used to take the whole first
   screen -- 3.5rem of padding, a letter-spaced eyebrow wrapping to three lines, a 1.15rem lede
   -- so a phone showed the introduction and none of the content. Nothing above 640px changes. */
@media (max-width: 640px) {
  .hero { padding: 1.75rem 0 1.25rem; }
  .eyebrow { letter-spacing: .08em; font-size: .7rem; margin-bottom: .6rem; }
  .hero .lede { font-size: 1.02rem; }
  h1 { font-size: clamp(1.65rem, 7vw, 2.1rem); }
}
