/* ==========================================================================
   YST · brand tokens
   Single source of truth. Every template references these; nothing hard-codes
   a colour, face or measurement. Re-skinning for another brand means editing
   this file only.

   Values are OKLCH. Never mix a new one · take a step from a ramp.
   Reference: BRAND.md, YST Brand Pack (BR-002), decision log (BR-001).
   ========================================================================== */

:root {
  /* --- neutrals · hue 265 · ~90% of surface ----------------------------- */
  --n-50:  oklch(0.985 0.002 265);
  --n-100: oklch(0.955 0.003 265);
  --n-200: oklch(0.905 0.004 265);
  --n-300: oklch(0.845 0.005 265);
  --n-400: oklch(0.740 0.006 265);
  --n-500: oklch(0.620 0.007 265);
  --n-600: oklch(0.520 0.008 265);
  --n-700: oklch(0.420 0.008 265);
  --n-800: oklch(0.330 0.008 265);
  --n-900: oklch(0.255 0.008 265);
  --n-950: oklch(0.185 0.008 265);

  /* --- teal · hue 212 · primary ---------------------------------------- */
  --teal-50:  oklch(0.968 0.010 212);
  --teal-100: oklch(0.930 0.024 212);
  --teal-200: oklch(0.872 0.044 212);
  --teal-300: oklch(0.790 0.066 212);
  --teal-400: oklch(0.690 0.090 212);
  --teal-500: oklch(0.580 0.108 212);
  --teal-600: oklch(0.490 0.116 212);
  --teal-700: oklch(0.400 0.120 212);
  --teal-800: oklch(0.330 0.104 212);
  --teal-900: oklch(0.268 0.082 212);
  --teal-950: oklch(0.212 0.058 212);

  /* --- indigo · hue 258 ------------------------------------------------ */
  --indigo-100: oklch(0.900 0.030 258);
  --indigo-300: oklch(0.760 0.070 258);
  --indigo-500: oklch(0.600 0.104 258);
  --indigo-700: oklch(0.470 0.120 258);
  --indigo-900: oklch(0.300 0.090 258);

  /* --- plum · hue 320 -------------------------------------------------- */
  --plum-100: oklch(0.905 0.030 320);
  --plum-300: oklch(0.770 0.066 320);
  --plum-500: oklch(0.610 0.098 320);
  --plum-700: oklch(0.470 0.110 320);
  --plum-900: oklch(0.300 0.084 320);

  /* --- jade · RETIRED ---------------------------------------------------
     Jade 168 sat 20° from success green 148 and was ambiguous in any chart
     showing both. It existed for the terminal-cursor concept, which was cut.
     Method now takes teal-500. Three brand hues, matching the mark's three
     barbs. Do not reintroduce a fourth. */

  /* --- semantic · severity only · never brand, marker or emphasis ------ */
  --sev-critical:      oklch(0.550 0.160 27);
  --sev-critical-text: oklch(0.440 0.145 27);
  --sev-critical-fill: oklch(0.948 0.026 27);
  --sev-warning:       oklch(0.700 0.135 70);
  --sev-warning-text:  oklch(0.500 0.110 70);
  --sev-warning-fill:  oklch(0.955 0.034 70);
  --sev-success:       oklch(0.560 0.110 148);
  --sev-success-text:  oklch(0.440 0.095 148);
  --sev-success-fill:  oklch(0.950 0.026 148);

  /* --- risk bands · the severity vocabulary, as fills -------------------
     A risk matrix is severity, so it uses severity's own hues and severity's
     own four words · the same Cleared / Minor / Material / Critical that the
     findings table and Figure 1 use. A cell can then be cited directly: "the
     three Critical cells", not "band 5". Lightness is solved so adjacent bands
     differ by at least 1.31:1 in luminance, so the ranking survives a mono
     laser printer as well as colour vision. Every band is chromatic: an earlier
     cut put Cleared at chroma 0.03 and Minor on neutral, which made "negligible"
     read as white and the ramp read as green, grey, amber, red. Cleared now sits
     1.34:1 against paper, so an occupied low cell cannot be mistaken for an
     empty one. Text is n-900 throughout, 4.57:1 at worst. */
  --risk-cleared:  oklch(0.877 0.095 150);
  --risk-minor:    oklch(0.799 0.1 115);
  --risk-material: oklch(0.731 0.118 72);
  --risk-critical: oklch(0.651 0.15 27);

  /* --- block washes · one per monospace kind ---------------------------
     Each matches its own rule colour so the block declares itself before the
     label is read. Terminal takes a neutral wash: a console is not a chapter. */
  --wash-code:     oklch(0.966 0.014 212);
  --wash-config:   oklch(0.963 0.016 258);
  --wash-terminal: oklch(0.928 0.005 265);
  --wash-evidence: oklch(0.964 0.016 320);

  /* --- diff · a distinct red and green ---------------------------------
     Diffs get colour because the convention is universal and a diff without it
     cannot be read. This pair is deliberately NOT the severity pair: deeper,
     duller, and at hues 16 and 132 against severity's 27 and 148. Severity
     never appears inside a diff block, and these never appear outside one. */
  --diff-add:      oklch(0.912 0.055 132);
  --diff-add-rule: oklch(0.470 0.090 132);
  --diff-del:      oklch(0.906 0.058 16);
  --diff-del-rule: oklch(0.420 0.115 16);

  /* --- surfaces -------------------------------------------------------- */
  --paper:        var(--n-50);
  --paper-white:  #ffffff;
  --slate:        oklch(0.245 0.016 265);   /* on the neutral hue, not its own */
  --ink:          var(--n-950);
  --ink-reversed: oklch(0.965 0.004 265);

  /* --- semantic text roles · measured ratios in comments --------------- */
  --text-primary:   var(--n-900);  /* 15.1:1 on paper */
  --text-secondary: var(--n-800);  /* 11.7:1 on paper */
  --text-muted:     var(--n-700);  /*  8.1:1 on paper · floor for small text */
  --text-display:   var(--n-950);  /* 17.9:1 on paper */
  --sheet-shadow:   oklch(0.185 0.008 265 / 0.16);
  --rule-hairline:  var(--n-200);
  --rule-strong:    var(--n-950);

  /* --- chapter hues · page furniture ----------------------------------- */
  --chapter-scope:    var(--teal-700);    /* 7.9:1 on paper */
  --chapter-method:   var(--teal-500);    /* 7.88:1 on paper · teal-500 measured 3.90:1, below the floor */
  --chapter-findings: var(--indigo-700);  /* 6.6:1 on paper */
  --chapter-evidence: var(--plum-700);    /* 6.9:1 on paper */

  /* --- type ------------------------------------------------------------ */
  --font-mono:    "IBM Plex Mono", "Berkeley Mono", ui-monospace, monospace;
  --font-display: "Atkinson Hyperlegible", Verdana, Helvetica, Arial, sans-serif;
  --font-body:    "Atkinson Hyperlegible", Verdana, Helvetica, Arial, sans-serif;

  /* Atkinson Hyperlegible ships two weights only, 400 and 700. Hierarchy comes
     from size, space and colour rather than weight, which suits a practice that
     does not raise its voice. 700 is for genuine emphasis inside running text,
     never for a heading.
     There is no 450 to ask for, so headings take 400 plus a hairline stroke in
     the text colour · optical weight without the jump. Set --display-stroke to
     0 to turn it off. */
  --w-body: 400;
  --w-med:  400;
  /* Mono has its own medium. Atkinson ships 400 and 700 only, so --w-med is 400 ·
     borrowing that for IBM Plex Mono, which has a real 500, downgraded the
     wordmark and every mono label by a step. The display face's limit must not
     silently govern the record face. */
  --w-mono-med: 500;
  --w-semi: 700;
  --display-stroke: 0.3px;

  /* Type scale · print-first, pt for paper artefacts. ONE declaration of each
     name, here and nowhere else: type.css holds element rules only, so a token
     can never resolve to two values depending on which sheets a page loads. */
  --fs-doc-title:   30pt;   /* alias of h1, kept for cover markup */
  --fs-h1:          30pt;   /* document title */
  --fs-h2:          17pt;   /* section · the numbered level */
  --fs-h3:          13pt;   /* subsection */
  --fs-h4:          10.5pt; /* numbered run-in, weight-differentiated */
  --fs-h5:          9pt;    /* label, not a heading */
  --fs-lead:        12pt;
  --fs-body:        10.5pt;
  --fs-small:       8pt;
  --fs-micro:       6.5pt;
  --fs-eyebrow:     7pt;

  --lh-tight:  1.14;
  --lh-body:   1.6;
  --lh-record: 1.7;
  --lh-h1:     1.14;
  --lh-h2:     1.2;
  --lh-h3:     1.28;

  /* Baseline rhythm: body 10.5pt x 1.6. Every vertical measure is a multiple or
     clean fraction of this, so facing pages align line for line. */
  --baseline:  16.8pt;
  --half-line: 8.4pt;

  --ls-eyebrow: 0.13em;
  --ls-mono:    0.05em;
  --ls-title:   -0.006em;   /* Atkinson is wider than Archivo; tight tracking closes its counters */

  /* --- lockup geometry · all multiples of wordmark ink height ---------- */
  --lockup-ink:        40px;   /* wordmark ink height · the one input */
  --lockup-mark-ratio: 1.10;   /* mark height = 1.10 x ink height */
  --lockup-gap-ratio:  0.37;   /* gap = 0.37 x ink height */
  --lockup-mark-aspect: 1.622; /* mark ink width / height */

  /* NOTE: mark height, width, gap and clear space are NOT pre-computed here.
     A var() inside a custom-property value is substituted where that property is
     declared · so deriving them in :root would freeze them at :root's --lockup-ink
     and no per-element override could ever change them. They are resolved at use
     time on .yst-lockup and its children instead. */
  --lockup-min-ink: 15px;                   /* below this, symbol alone */
  --mark-small-crossover: 24px;             /* three barbs -> two */

  /* wordmark ink measures 0.90 of font-size in Plex Mono 500 (cap + descender) */
  --lockup-ink-factor: 0.90;

  /* --- spacing --------------------------------------------------------- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;

  /* --- page ------------------------------------------------------------ */
  --page-margin:        16mm;   /* A4 · reclaimed from 20mm */
  /* Duplex. The gutter is wider than the outer margin because binding eats into
     it · 24mm inside against 16mm outside is the usual allowance for a stapled or
     perfect-bound A4 report. Single-sided printing ignores both and uses
     --page-margin on each side. */
  --page-margin-gutter: 24mm;
  --page-margin-outer:  16mm;
  --page-margin-top:    12mm;   /* one value for every sheet · never an inline override */
  --page-margin-bottom: 11mm;   /* footer sits low; these print edge to edge */
  --footer-gap:         var(--sp-5);  /* separator to disclosure */
  --page-margin-wide: 20mm;
  --measure:          66ch;

  /* --- furniture ------------------------------------------------------- */
  /* marker = one barb, drawn as SVG. Height is stroke length; width follows aspect. */
  --marker-h-section: 15px;
  --marker-h-bullet:  12px;
  --bullet-h:         10.5px;
  --bullet-aspect:    0.985;
  --marker-aspect:    0.3716;
  /* --- classification · YST's own scheme, so it may be styled ------------
     Two orthogonal axes: Classification (always) and Information Ownership
     (mandatory at Confidential and Restricted, defaulting to YST below).
     Depth escalation in NEUTRALS, deliberately not semantic hues: Restricted
     in red would collide with critical severity and put a third colour
     language on the page. The text label carries the meaning; depth carries
     the urgency. Externally mandated schemes (TLP, government markings) stay
     quarantined and unstyled · that rule is unchanged. */
  --classification-h: 7px;
  --class-own-w:      34px;   /* ownership segment at the right end of the bar */
  /* Texture floor, measured at two scales. On screen and in the running head 5px is
     the floor: the third-party inset leaves a 2px clear core, which still reads as
     hollow. On a cover, printed, 7px is the floor because the hatch fills in below
     that on a laser printer. Below 5px the ownership segment is dropped entirely and
     the ownership word in the label carries it alone. */
  --class-texture-floor: 5px;
  --class-texture-floor-print: 7px;
  /* The head bar spans the measure, so it can be thinner than the cover's: 5px with
     round caps carries the depth and the texture without becoming the heaviest mass
     on a light sheet. Still on the texture floor's terms · below 5px the third-party
     inset collapses, so this is the floor for a full-measure bar. */
  --class-bar-h: 5px;

  /* Document reference · YST-CCCCYYNN-TYPE-SSSS, 22 characters, every segment fixed
     width, so the hyphens can be dimmed to let the segments read as fields. */
  --ref-seg: var(--text-primary);
  /* n-400 measured 2.20:1 on paper · the faintest text in the system, inside the one
     string that gets transcribed, cited and read aloud. n-600 is 5.26:1 and still
     visibly recessive against the n-900 segments, so the field reading survives. */
  --ref-sep: var(--n-600);
  /* ROSE · hue 350 · A MARKING HUE, NOT A BRAND HUE.
     Declared outside the brand set, alongside the severity three. The brand is
     teal, indigo and plum; rose exists only to mark classification and appears
     nowhere else in any document. Treat "four brand hues" as three plus this.

     Reserved for classification and used nowhere else, so the*/
     colour alone tells a reader what kind of marking they are looking at before
     they read it. Chroma runs higher than the brand hues (0.15 against 0.11–0.12)
     precisely so it does not read as brand.
     Rejected: orange, ruled out by the brief; cyan, 20° from teal with its light
     step out of gamut; orchid, 20° from plum so it reads as the evidence hue;
     neutrals, which read as no decision having been made; and one hue per level,
     where indigo and plum sat 1.05:1 apart so no reader could order them.
     Every level clears 3:1 against paper as a graphic; steps sit ~1.8–2.1:1 apart. */
  --rose-100: oklch(0.930 0.040 350);
  --rose-300: oklch(0.790 0.095 350);
  --rose-500: oklch(0.630 0.150 350);
  --rose-700: oklch(0.490 0.160 350);
  --rose-800: oklch(0.340 0.145 350);
  --rose-900: oklch(0.300 0.115 350);
  --rose-950: oklch(0.235 0.085 350);

  --class-public:       var(--rose-500);  /*  3.63:1 on paper */
  --class-internal:     var(--rose-700);  /*  6.57:1 · step 1.81:1 */
  --class-confidential: var(--rose-800);  /* 12.03:1 · step 1.83:1 */
  --class-restricted:   var(--rose-950);  /* field; rule inverts to 14.9:1 */
  /* longest label: "Confidential · Customer-Personal" · 32 characters at
     10pt mono with 0.18em tracking measures ~88mm, against 170mm of A4
     content width, so the band never wraps. */
  --class-track: 0.18em;
  /* Ordered-list marker widths. In em, not ch: the marker is set in mono (advance
     0.6em) while the list element inherits the body face, so ch resolves differently on
     the two and the nested indent drifts · 5.9px at level 2, 9.5px at level 3. The
     indent is derived from the same token as the width, so they cannot disagree.
     3 / 4.8 / 6.6 mono characters: "A10", "A2.10", "A2.10.1". */
  --ord-marker-1: 1.8em;
  --ord-marker-2: 2.88em;
  --ord-marker-3: 3.96em;
  --separator-min-w:  88px;   /* below this the bands merge */
  --separator-h:      21px;   /* authored height · do not squash */
}

/* --------------------------------------------------------------------------
   Primitives shared by every template.
   -------------------------------------------------------------------------- */

.yst-lockup {
  display: flex;
  /* baseline, not center: the SVG mark has no baseline of its own, so with
     align-items:center the container synthesised its first baseline from the mark's
     bottom edge · which made every head that baseline-aligned sit 3px out. The word
     is the baseline source; the mark centres itself without participating. */
  align-items: baseline;
  gap: calc(var(--lockup-ink) * var(--lockup-gap-ratio));
}
.yst-lockup__mark {
  display: block;
  align-self: center;
  flex: none;
  height: calc(var(--lockup-ink) * var(--lockup-mark-ratio));
  width: calc(var(--lockup-ink) * var(--lockup-mark-ratio) * var(--lockup-mark-aspect));
}
.yst-lockup__word {
  font-family: var(--font-mono);
  font-weight: var(--w-mono-med);
  font-size: calc(var(--lockup-ink) / var(--lockup-ink-factor));
  letter-spacing: var(--ls-mono);
  line-height: 1;
  color: var(--text-display);
}
.yst-lockup--reversed .yst-lockup__word { color: var(--ink-reversed); }
/* permitted alternate: mark right. Not the default. */
.yst-lockup--mark-right { flex-direction: row-reverse; }

.yst-wordmark {
  font-family: var(--font-mono);
  font-weight: var(--w-mono-med);
  letter-spacing: var(--ls-mono);
  line-height: 1;
  color: var(--text-display);
}

/* Separator. Authored at the proportions it renders into (aspect 64.205), so
   height follows width and the scale is always uniform. Never set an explicit
   height and never use preserveAspectRatio="none" · both destroy the taper. */
.yst-separator {
  display: block;
  width: 100%;
  min-width: var(--separator-min-w);
  height: auto;
}
.yst-separator--short { width: 176px; height: auto; }

/* One barb · an inline SVG of the same tapered, round-capped stroke as the mark.
   Not a clipped box: clip-path cuts rounded corners away and yields a spearhead. */
.yst-marker {
  display: block;
  flex: none;
  height: var(--marker-h-section);
  width: calc(var(--marker-h-section) * var(--marker-aspect));
  fill: var(--chapter-scope);
}
/* Bullet = the soft chevron at 2.63px arm weight. Two tapered arms meeting at a
   mitred tip, round caps on the open ends, from the mark's own generator. It points
   into the text, which a dash cannot, and the rounded ends keep it clear of reading
   as a UI control. The upright barb stays for section markers, where vertical works
   because it sits beside a heading rather than inside a line of reading. */
.yst-marker--bullet {
  height: var(--bullet-h);
  width: calc(var(--bullet-h) * var(--bullet-aspect));
  transform: translateY(-1px);
}

.yst-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-eyebrow);
  font-weight: var(--w-body);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}

.yst-record {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  line-height: var(--lh-record);
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

.yst-display {
  -webkit-text-stroke: var(--display-stroke) currentColor;
  paint-order: stroke fill;
}

/* Chapter eyebrow · mono, uppercase, tracked, with room for a marker beside it.
   NOT a heading: .yst-h2 is the section heading and lives in type.css. */
.yst-chapter {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-eyebrow);
  font-weight: var(--w-mono-med);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  margin: 0 0 var(--sp-4);
}

.yst-bullets { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
.yst-bullets li { display: flex; gap: var(--sp-3); align-items: baseline; }
.yst-bullets li > span:last-child { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-primary); }

/* Legibility rules that outrank the typeface choice: never justify (rivers of
   white space are worse for a dyslexic reader than any face), never italicise
   running text, and keep the paper slightly off-white. */
p, li, td, dd { text-align: left; }

/* Chapter scoping · set one class on a section and the furniture follows. */
[data-chapter="scope"]    { --chapter: var(--chapter-scope); }
[data-chapter="method"]   { --chapter: var(--chapter-method); }
[data-chapter="findings"] { --chapter: var(--chapter-findings); }
[data-chapter="evidence"] { --chapter: var(--chapter-evidence); }
[data-chapter] .yst-marker { fill: var(--chapter); }
[data-chapter] .yst-chapter { color: var(--chapter); }


/* --------------------------------------------------------------------------
   Classification. ONE definition, shared by every template · the cover, both
   letterheads and anything added later. Two hooks the build system sets:
     class="classification classification--<level>"
     data-ownership="yst | customer | customer-personal | third-party"
   Depth answers how sensitive; form answers whose. Never hardcode either.
   -------------------------------------------------------------------------- */
.classification--public       { --class-depth: var(--class-public); }
.classification--internal     { --class-depth: var(--class-internal); }
.classification--confidential { --class-depth: var(--class-confidential); }
/* Restricted inverts, so the SHARED rule paints the field and reverses the label ·
   leaving that to each template meant four of them rendered a near-white bar on
   near-white paper, i.e. the most severe level as nothing. */
.classification--restricted {
  --class-depth: var(--ink-reversed);
  background: var(--class-restricted);
  padding: var(--sp-2) var(--sp-3);
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.classification--restricted .pg__class,
.classification--restricted .lh__class-label,
.classification--restricted .classification__label,
.classification--restricted .pg__title { color: var(--ink-reversed); }
.classification--restricted .pg__class-sep,
.classification--restricted .classification__sep { color: var(--rose-300); }

.yst-class-rule { background: var(--class-depth, var(--class-internal)); }
.yst-class-own  { background: var(--class-depth, var(--class-internal)); }

[data-ownership="customer"] .yst-class-own {
  background: linear-gradient(90deg, var(--rose-700) 0 42%, transparent 42% 58%, var(--rose-700) 58% 100%);
}
[data-ownership="customer-personal"] .yst-class-own {
  background: repeating-linear-gradient(135deg, var(--rose-700) 0 2.5px, transparent 2.5px 5px);
}
[data-ownership="third-party"] .yst-class-own {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--rose-700);
}
