/* ==========================================================================
   h2.css: the H2 Labs design system, shared by every page on h2.io.

   Load order on every page (keep it):
     1. the inline <style id="servo-theme"> block and its head script (servos theme
        mechanism: localStorage "servo-theme" -> <html data-theme>). Leave them as they are.
     2. <script>document.documentElement.classList.add('js')</script>
        (motion and menus only switch on when this class is present; without JS
        every section is simply visible)
     3. <link rel="stylesheet" href="/h2.css">
     4. the page's own <style> for its composition (never restyle a component
        there; add a modifier class or scope to an id).

   Direction "Night signal": a European night, precise hairline frames, square
   nodes, and one European blue (#1060a8, lifted to #6aa6f0 for text on dark
   grounds) with the red H2 square. Flat surfaces, 1px hairlines, no glass, no
   glow, no gradients on text. Designed light and dark with equal care.

   Type: Inter (variable, optical sizes) for reading and headlines; JetBrains
   Mono only for labels, keys, dates, figure labels and code. Self-hosted under
   /fonts/ (OFL, licence files beside the fonts). No request leaves the host.

   Red rule: the red square appears only as (1) the H2 mark, (2) the square at
   the start of each section head, (3) "denied / stopped" marks inside diagrams.
   Nowhere else.

   Motion rule: run once, then rest. Nothing loops. Every animation has a still
   final state that is shown under prefers-reduced-motion and without JS.

   ==========================================================================
   COMPONENT INDEX   (markup to copy is under each entry)
   ==========================================================================

   1  TOKENS  (light on :root, dark under prefers-color-scheme and [data-theme])
      Colour: --bg --bg-deep --surface --surface-2 --fg --fg2 --fg3 --border
        --border-strong --input-border (form field edges, >= 3:1) --hover --accent (text, links) --accent-fill (buttons)
        --accent-fill-hover --on-accent --accent-light --node (lit squares in
        figures) --link (network hairlines) --coast (dotted coastline) --red
        --red-text (red labels, AA) --grid (texture lines) --selection
        --field-bg --field-fg --field-fg2 (the blue field)
      Size: --wrap (1216px column incl. gutters) --pad (gutter) --section-y
        --header-h --radius --radius-sm
      Type: --font-sans --font-mono and the scale in 2.
      Motion: --ease (UI) --ease-draw (lines drawing)
      Scopes that re-declare the tokens, so components inside them just work:
        .band--night   dark in both schemes (the page's one tonal band)
        .cta-field     the European-blue field (the page's one call to action)

   2  TYPE SCALE (tokens; the classes below use them)
      --t-hero       h1 of a landing page           clamp 41 -> 74px, 640 wt
      --t-page       h1 of an inner page             clamp 34 -> 54px
      --t-section    h2 section title                clamp 31 -> 48px
      --t-statement  one pull statement per section  clamp 23 -> 33px
      --t-h3         card / row title                19-21px
      --t-lead       section intro, lede             16.3 -> 18.2px
      --t-body       reading text: every running paragraph and list, on every page
                     (askd, the documents, the homepage's terms, rows and notes in the
                     blue field)                     16.5px, line height --lh-body (1.65)
      --t-card       the compact reading size: text in dense cards and rows (pillars,
                     spec rows, log summaries) and in .note boxes    15.5px
                     (cards and rows at --lh-card 1.62, notes at --lh-body)
      --t-small      meta, footer                    14px
      --t-label      mono labels, keys, eyebrows     12px (uppercase .14em)
      --t-fig        labels inside figures           >= 11px desktop, >= 10px phone
      Measure: running text never wider than 66ch (.measure caps a block).

   3  LAYOUT
      .wrap          the column: <div class="wrap">...</div>
      .frame         a framed section. Hairline on top, the column's two vertical
                     hairlines run through it, square nodes where they cross:
                     <section class="frame" id="x"><div class="wrap">...</div></section>
                     Rhythm: .frame--tight (0.7x) / .frame--loose (1.25x) vary the
                     vertical space so chapters do not all breathe the same.
      .band--night   add to one .frame per page: the dark band (both schemes), with
                     a blueprint grid (12px minor, 48px major).
      .measure       caps a text block at 66ch.

   4  SECTION HEADS
      <div class="section-head section-head--split">
        <div>
          <p class="eyebrow num">What we do</p>      .num = numbered by CSS counter (01, 02 ...)
          <h2 class="sec-title">Title</h2>
        </div>
        <p class="sec-intro">One paragraph (max 66ch).</p>
      </div>
      The split head aligns the intro's foot with the title's (short intros).
      .section-head--split.is-top   an intro that runs far longer than the title (askd's
                     two-paragraph intros, <div class="txt"> in place of .sec-intro): both
                     columns start at the top and the intro's first line sits level with the title.
      Plain .section-head stacks eyebrow, title, intro. The eyebrow starts with
      the red square (the section mark). The homepage's eyebrows carry number and label
      ("01 What we do"); inner pages (askd) use the number alone, drawn by CSS
      (<span class="eyebrow num" aria-hidden="true"></span>), because their titles
      already name the section and no words may be added to their copy.
      .page-head     inner-page header: <header class="page-head"><p class="eyebrow">askd</p>
                     <h1 class="page-title">Title</h1><p class="lede">...</p></header>
                     Every inner page and document opens the same way: red-square eyebrow,
                     then the h1, then the lede or a mono meta line. The eyebrow-to-title gap
                     is 22px on every opener (.page-head, .doc-head in 11, askd's .hero-head);
                     the homepage's hero opens on its .badges instead.
      .back          the way back, above an inner page's head (mono, 44px tall):
                     <a class="back" href="/askd/">&larr; askd</a>
      .hero-title    the landing h1; <span class="accent">line</span> sets a line in blue.
      .statement     one large line per long section:
                     <p class="statement"><span class="k">(i)</span> The sentence.</p>
      .lede          intro paragraph under an h1.

   5  CONTROLS
      <a class="btn btn-primary" href="...">Label <span class="arrow" aria-hidden="true">&rarr;</span></a>
      <a class="btn btn-ghost" href="...">Label</a>          both 46px tall (touch safe)
      .btn--block    full width, same height and type: a form's send button
                     (<button class="btn btn-primary btn--block submit" id="submit-btn">).
      .cta           a wrapping row of buttons.
      .badges > .badge   mono labels with square separators; wraps two per line on phones.
      .k             mono key ("01 / sovereign").   .kicker  mono category (blue, caps).
      .tags > .tag   mono tags.                     .mono    inline mono run.
      .balloon       a keyed roman numeral in a ring: <span class="balloon">ii</span>
      .contents      numbered in-page contents (a <nav>). The number and label are drawn
                     from data-k / data-label and the accessible name is aria-label, so the
                     row adds no text to the page's reading flow (the hero's copy runs
                     straight from its buttons into section 01):
                     <nav class="contents" aria-label="Contents">
                       <a href="#what" aria-label="What we do" data-k="01" data-label="What we do"></a> ...
                     </nav>
      .contents--grid  a long page's contents (askd: twelve sections), the same links in
                     ruled cells: four across on desktop, three on tablets, two on phones.
      Contents blocks share one rule: 1px --border-strong on top (this row, and the
                     documents' .toc in 11). Heavy 2px ink rules belong to tables (8, 9).

   6  CARDS (article + one title link; the whole card is the hit area)
      <article class="card" id="zoya">
        ... figure, <p class="kicker">agent</p> ...
        <h3><a class="card-link" href="/x/">Zoya</a></h3>
        <p>One line.</p>
        <p class="card-dest" aria-hidden="true">labs.h2.io/x <svg ...arrow/></p>
      </article>
      The link's ::after covers the card; the focus ring is drawn on the card.
      Never put another link or button inside .card-link. Extra controls (the
      copy-link chip) are siblings and sit above the overlay (z-index 3).
      .log > .post   the same pattern as ruled rows on a rail (the labs log):
      <div class="log"><article class="post" id="slug">
        <p class="kicker">methodology</p><h3><a class="card-link" href="...">Title</a></h3>
        <p>Summary.</p><p class="pc-meta"><span>Author</span><span>2026-06-09</span></p>
        <svg class="post-arrow" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 8h10M9 4l4 4-4 4"/></svg></article></div>
      The arrow is drawn (not a text glyph) so it adds nothing to the copy. Phones: one
      column, and the arrow sits at the end of the author line (the corner is the chip's).
      .post.flag     the living (flagship) post: filled node, pulses three times.

   7  FIGURES AND DIAGRAMS
      Every diagram that explains something is a <figure> with a numbered one-line
      caption that restates the page's own words (the text equivalent of the
      aria-hidden drawing). When the copy right beside the figure already says what
      the drawing shows, the caption is only the number and a short label ("Fig. 1
      Zoya"), so no sentence is read twice. Number figures in reading order per page (Fig. 1, 2 ...)
      and tables separately (Table 1 ...). Purely decorative art (the homepage map)
      is a plain aria-hidden <div>, uncaptioned and unnumbered. One more exception: a
      drawing that only redraws the table beside it (the homepage perimeter: Table 1's six
      rows as six edges, desktop only) belongs to that table: aria-hidden, no caption and
      no number, so phone readers, who never see it, still meet Fig. 1 first.
      A caption starts at the figure frame's left edge, even when the drawing is centred:
      <figure class="fig fig--crop">
        <div class="fig-body" aria-hidden="true"><svg class="fig-svg" viewBox="0 0 340 190">...</svg></div>
        <figcaption class="fig-cap"><span class="fig-no">Fig. 2</span>Label or one line</figcaption>
      </figure>
      .fig--crop     crop marks at the four corners of the drawing.
      LABEL FLOOR: figure labels are >= 11px on desktop and >= 10px on phones,
      measured after scaling (font-size x rendered width / viewBox width).
        SVG drawings: design in a 340-unit-wide viewBox with labels at 12 units
        (mono advance about 7.4 units per character). .fig-svg caps the drawing
        at 380px and h2.css sets the label size per breakpoint (11u >= 600px,
        12u below), which keeps every label between about 10.5 and 13.5px.
        Wider drawings: use .plot (HTML labels over a stretched SVG line).
        pw/h2-figaudit.ts (run by h2io-check on every page that loads h2.css)
        fails any label under the floor, two labels that overlap, a label a
        drawn line runs through (mark a deliberate strike-through data-cross-ok),
        a label outside its figure, and any element that pokes out sideways.
      Classes inside the SVG (they read the tokens):
        .d-line hairline   .d-link network hairline   .d-acc accent stroke
        .d-thick heavy frame   .d-box outlined box   .d-node lit square
        .d-hatch hatched wall   .d-deny red stop mark   .d-sig one moving signal
        text: default mono fg3; .d-lbl-hi accent; .d-lbl-fg ink; .d-lbl-red red
        .d-dash dashed stroke  .d-ko knock-out behind a label sitting on a line
      One node kit for the same thing on every page (askd on the homepage and on /askd/):
        you = a .d-box with a terminal prompt (">_", .d-acc); a relay = a dashed rounded
        .d-box of .d-ink blocks (bytes it cannot read); your host = a .d-thick square with a
        .d-node inside; the wall = a narrow .d-hatch with .d-deny marks against the scans.
      Drawing on reveal: path pathLength="1" class="draw" inside a .reveal.
      .d-sig runs once when its .reveal gets .in (style="--len:120;--dur:3s;--delay:.4s").
      .plot          HTML-labelled line diagram: an SVG with
                     preserveAspectRatio="none" (lines only, vector-effect:
                     non-scaling-stroke) plus absolutely placed HTML labels at
                     style="--x:40%;--y:30%". Parts: .plot-lane .plot-node
                     .plot-lbl (.up/.down/.end) .plot-arrow. Labels never shrink.
      .timeline      a long ticked line with two end nodes and two labels:
                     <div class="timeline" aria-hidden="true"><span class="tl-a">initial work</span><span class="tl-b">long after</span></div>

   8  SPECIFICATION TABLE (a ruled list that reads as a table)
      <p class="spec-cap"><span class="fig-no">Table 1</span> Caption.</p>
      <ol class="spec">
        <li class="spec-head" aria-hidden="true"><span>Ref.</span><span>Constraint</span><span>Specification</span></li>
        <li class="spec-row" id="x"><div class="spec-ref"><span class="spec-sym"><svg/></span><span class="k">01 / x</span></div>
          <h3>Name</h3><p>Text.</p></li>
      </ol>
      Heavy rules top and bottom; three columns >= 700px, stacked blocks below.
      .spec--compact the Ref. column holds only a symbol and a two-digit number: it
                     shrinks to 96px so the name and the specification get the width.

   9  DATA TABLES (docs)
      <div class="table-wrap" tabindex="0" role="region" aria-label="..."><table class="table">
        <caption><span class="fig-no">Table 2</span> Caption.</caption>
        <thead><tr><th scope="col">Field</th>...</tr></thead><tbody>...</tbody></table></div>
      .num on a cell right-aligns tabular figures. The wrap scrolls sideways on phones,
      with a soft shadow at the edge that has more to show (so a cut-off column reads as one).

   10 CODE
      Inline: <code>askd knock</code>.  Keys: <kbd>Ctrl</kbd>.
      Inline code is one chip everywhere (.88em, a hairline box, tight side padding); in a
      heading it drops the chip and takes the heading's ink.
      Block: <figure class="code-block"><figcaption class="code-cap">shell</figcaption>
             <pre><code>...</code></pre></figure>
             The cap is optional (askd's block names its language; the spec's formula blocks
             have none). Set at 13px mono; scrolls sideways, and at 640px and below it wraps
             instead, each continuation hanging two characters in.
      .cmt / .str / .kw spans inside a block for light highlighting.

   11 PROSE (long documents: askd spec, compare, test vectors)
      <article class="prose">h2, h3, p, ul, ol, blockquote, hr, table, pre ...</article>
      .callout       a passage set off from the text by a 2px accent rule, in ink (the prose
                     blockquote's treatment, for a passage that is not a quotation):
                     <div class="callout"><p>...</p></div>
      .note          a boxed note: <div class="note"><p><strong>Lead.</strong> Text.</p></div>
                     Its text is set once, here: --t-card (15.5px) at --lh-body, in --fg2, the
                     lead in ink. Pages do not resize or recolour it.
                     (a <div>, not an <aside>, when it sits inside <main>: it is part of the
                     page's argument, not a separate landmark). A hairline frame with a square
                     node at each corner, the one box used for notes on every page; the
                     padding tightens on phones so the measure stays near 40ch.
      .note--open    the same frame dashed: something not done yet ("Not shipped.").
      .footnote      a numbered note: <p class="footnote"><span class="fn-k" aria-hidden="true">1</span> Text.</p>
                     mark in the text: <sup class="fn" aria-hidden="true">1</sup>
      THE DOCUMENT SHEET (askd's specification, comparison, test vectors): one frame,
      the way back, the opener, then the text with its contents beside it.
      <section class="frame doc-frame"><div class="wrap">
        <a class="back" href="/askd/">&larr; askd</a>
        <article class="doc prose doc--toc" id="doc">
          <header class="doc-head"><p class="eyebrow doc-kind" aria-hidden="true"><span data-label="askd &middot; kind"></span></p>
            <h1 class="page-title">Title</h1><p class="lede">...</p></header>
          <nav class="toc" aria-label="Contents"><p class="panel-k" data-label="Contents" aria-hidden="true"></p>
            <ul><li class="l2"><a href="#x" aria-label="Name" data-label="Name"></a></li>
                <li class="l3">...</li></ul></nav>
          <h2 id="x">Name</h2> ...
        </article></div></section>
      .doc           the reading column: text, tables and panels at a 60ch measure; each h2
                     opens on a hairline with a square node; notes grow outward by their padding.
      .doc-status    a mono meta line in the opener.     .panel-k   a ruled panel's mono label.
      .toc           the contents: a ruled list, inline where it stands; in .doc--toc it moves
                     to a sticky rail beside the text from 1100px. Every document shows it at
                     every width. Labels drawn from data-label (no words added) or real text.
      .files         mono file chips, a lit node in front, 44px tall: <p class="files"><a href="x.json">x.json</a> ...</p>

   12 FORMS (the contact form)
      <form class="form"> <div class="grid2">...</div>
        <div class="field"><label for="x">Label <span class="hint">optional</span></label>
          <input id="x"> (or select / textarea) <p class="field-error">Message</p></div>
        <button class="btn btn-primary" type="submit">Send</button>
      </form>
      Inputs are 46px tall, 16px text (no zoom on iOS). Their edge is --input-border
      (>= 3:1 on the sheet and on the field's fill, both schemes); focus is a 2px accent
      ring plus a soft halo. Forced colours: selects fall back to the native arrow.
      .field.invalid marks an error. .banner = an info strip. .dialog = a modal
      box (use <dialog class="dialog"> or .modal > .modal-box).

   13 CALL TO ACTION FIELD
      <div class="cta-field"> ... <div class="cta"><a class="btn btn-primary">...</a>
      <a class="btn btn-ghost">...</a></div></div>
      Solid European blue in both schemes, white type, white primary button.
      Use once per page.

   14 HEADER
      <header class="site-header"><div class="wrap nav">
        <div class="brand-wrap"><a class="brand" href="/" aria-describedby="brand-tip">mark + <span class="brand-name">H2 Labs</span></a>
          <div class="brand-tip" id="brand-tip" role="tooltip">...</div></div>   (homepage only; hidden until .open)
        <span class="run-head" aria-hidden="true"></span>     (desktop: names the section in view; keep
                                                               the empty span on every page, filled or not)
        <button class="menu-btn" aria-expanded="false" aria-controls="site-nav" aria-label="Menu">...</button>
        <nav class="nav-links" id="site-nav" aria-label="Main">
          <a href="https://labs.h2.io/">Labs</a>
          <a href="/#principles">Principles</a>
          <a href="/#work">Work with us</a>
          <a class="nav-cta" href="/contact/">Contact</a>
        </nav></div></header>
      The links are plain words, the same on every page (real text: found by find-in-page,
      translated, kept by reader modes). The nav is not numbered: numbers belong to the
      page's own sections (eyebrows and the running head), and the header shows on pages
      whose sections are numbered differently.
      Opaque paper background (no blur). Under 760px the nav folds behind the
      menu button (JS); without JS it lays out as a tidy 2 x 2 grid and the header
      scrolls away with the page instead of sticking. Every page
      that uses the header must carry the menu button and the page script's
      menu block (see index.html), or the nav stays folded on phones.

   15 FOOTER (the drawing sheet's title block)
      <footer class="site-footer"><div class="wrap foot">
        <div class="foot-sign"><svg mark/><p class="foot-copy">&copy; 2012-2026 H2&nbsp;Labs<span class="foot-sep"> &middot; </span><span class="nowrap">European&nbsp;&middot;&nbsp;Sovereign</span></p></div>
        <nav class="foot-links" aria-label="Footer"><a href="https://labs.h2.io/">Labs</a>...</nav>
      </div></footer>
      With a colophon (askd and its documents), the sign-off cell holds both lines:
        <div class="foot-sign"><svg mark/><div class="foot-doc">
          <p class="doc-colophon">askd &middot; a project of <a href="/">H2 Labs</a> ...</p>
          <p class="foot-copy">...</p></div></div>

   16 UTILITIES
      .skip (skip link, label from aria-label)  .sr-only  .anchor-chip
      .nowrap        keeps a compound together in display type (text-wrap:balance
                     otherwise breaks at its hard hyphen): <span class="nowrap">fixed-scope</span>;
                     also on a short inline code token with a hyphen or slash (a flag such
                     as --cred-ca-pub), which must not split into what reads as two tokens
      .title-anchor  the "#" that copies a section's link. The page script inserts it
                     right AFTER the heading, never inside it (a link inside a heading
                     would be read as part of the heading's name). It takes no space: a
                     zero-height block whose "#" hangs in the left margin beside the
                     heading's last line. Markup: <a class="title-anchor" href="#id"
                     aria-label="Copy link to this section"><span aria-hidden="true">#</span></a>
      .hl-pulse (deep-link highlight: one fading glow; a still outline under reduced motion;
                 the page script removes the class after 2.4s)
      .reveal/.in (fade-up once, JS + motion only)
      Copy controls (.anchor-chip, .title-anchor) are named by their target ("Copy link to
      Zoya"), and the page script announces a copy in one role="status" line.
      Sticky header: html{scroll-padding-top} keeps every focus move, anchor jump and
      scrollIntoView clear of it.
      Print: .reveal content, drawn lines and the page's figures print in their final state.
   ========================================================================== */


/* ---- 0. fonts (self-hosted, OFL; licences in /fonts/) ---- */
@font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;
  src:url(fonts/inter.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:"Inter";font-style:normal;font-weight:100 900;font-display:swap;
  src:url(fonts/inter-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* arrows, not-equal, check, square: a 4 KB subset of the same Inter */
@font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;
  src:url(fonts/inter-symbols.woff2) format("woff2");
  unicode-range:U+2190,U+2192-2193,U+2197,U+2260,U+25A0,U+2713}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:100 800;font-display:swap;
  src:url(fonts/jetbrains-mono.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:"JetBrains Mono";font-style:normal;font-weight:100 800;font-display:swap;
  src:url(fonts/jetbrains-mono-latin-ext.woff2) format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}


/* ---- 1. tokens: light (porcelain and ink) ---- */
:root{
  color-scheme:light;
  --bg:#f5f7fa; --bg-deep:#edf1f5; --surface:#ffffff; --surface-2:#eef2f6;
  --fg:#0b1422; --fg2:#3b4758; --fg3:#586476;
  --border:#dde3ea; --border-strong:#c3ccd8; --hover:#e9eef4;
  --input-border:#7d8999;  /* a form field's edge: >= 3:1 on the sheet and on the field's own fill */
  --accent:#1060a8; --accent-fill:#1060a8; --accent-fill-hover:#0c528f; --on-accent:#ffffff;
  --accent-light:#e3edf7;
  --node:#1060a8; --link:rgba(16,96,168,.24); --coast:rgba(16,96,168,.55);
  --red:#d63327; --red-text:#c42a1f; --red-light:#fbe6e3;
  --grid:rgba(11,20,34,.055);
  --selection:#cfe0f3; --selection-fg:#0b1422;
  --shadow:0 1px 2px rgba(11,20,34,.05),0 8px 24px -12px rgba(11,20,34,.12);
  --field-bg:#1060a8; --field-fg:#ffffff; --field-fg2:rgba(255,255,255,.86); --field-line:rgba(255,255,255,.5);

  --font-sans:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --wrap:1216px; --pad:clamp(20px,4vw,48px);
  --section-y:clamp(72px,9vw,128px); --header-h:64px;
  --radius:10px; --radius-sm:6px;

  /* 2. type scale */
  --t-hero:clamp(2.6rem,1.05rem + 4.3vw,4.6rem);
  --t-page:clamp(2.1rem,1.3rem + 2.8vw,3.4rem);
  --t-section:clamp(1.95rem,1.2rem + 2.2vw,3rem);
  --t-statement:clamp(1.42rem,1.08rem + 1.2vw,2.05rem);
  --t-h3:clamp(1.18rem,1.1rem + .3vw,1.32rem);
  --t-lead:clamp(1.02rem,.95rem + .3vw,1.14rem);
  --t-body:16.5px; --lh-body:1.65;
  --t-card:15.5px; --lh-card:1.62;
  --t-small:14px;
  --t-label:12px;
  --t-fig:12px;

  --ease:cubic-bezier(.2,.7,.2,1); --ease-draw:cubic-bezier(.45,.05,.2,1);
}
/* ---- tokens: dark (the European night) ---- */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --bg:#0a0f17; --bg-deep:#060a10; --surface:#0e1520; --surface-2:#121b28;
    --fg:#e7ecf3; --fg2:#a9b4c3; --fg3:#8390a2;
    --border:#1a2431; --border-strong:#2a3747; --hover:#111a26; --input-border:#5b6b80;
    --accent:#6aa6f0; --accent-fill:#1466b3; --accent-fill-hover:#1a74c7; --on-accent:#ffffff;
    --accent-light:#0f2034;
    --node:#6aa6f0; --link:rgba(128,178,240,.2); --coast:rgba(128,178,240,.5);
    --red:#e0483b; --red-text:#f07366; --red-light:#2a1210;
    --grid:rgba(150,180,220,.05);
    --selection:#1d3a5f; --selection-fg:#f2f6fb;
    --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px -16px rgba(0,0,0,.6);
    --field-bg:#0f5aa0;
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --bg:#0a0f17; --bg-deep:#060a10; --surface:#0e1520; --surface-2:#121b28;
  --fg:#e7ecf3; --fg2:#a9b4c3; --fg3:#8390a2;
  --border:#1a2431; --border-strong:#2a3747; --hover:#111a26; --input-border:#5b6b80;
  --accent:#6aa6f0; --accent-fill:#1466b3; --accent-fill-hover:#1a74c7; --on-accent:#ffffff;
  --accent-light:#0f2034;
  --node:#6aa6f0; --link:rgba(128,178,240,.2); --coast:rgba(128,178,240,.5);
  --red:#e0483b; --red-text:#f07366; --red-light:#2a1210;
  --grid:rgba(150,180,220,.05);
  --selection:#1d3a5f; --selection-fg:#f2f6fb;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px -16px rgba(0,0,0,.6);
  --field-bg:#0f5aa0;
}


/* ---- base ---- */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
/* No global smooth scrolling: in-page links scroll smoothly on click (page script),
   so programmatic scrolls, focus moves and captures never drift. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* the sticky header never covers what the browser scrolls to: anchor jumps, scrollIntoView and,
   above all, keyboard focus moving up the page (WCAG 2.4.11) */
html{scroll-padding-top:calc(var(--header-h) + 16px)}
/* The scrollbar: the same lane, width and colours as labs.h2.io, so switching between the
   two sites moves nothing; the lane is reserved even when a page does not scroll. */
html{overflow-y:scroll;scrollbar-gutter:stable;scrollbar-width:auto;scrollbar-color:var(--border-strong) var(--bg)}
html::-webkit-scrollbar{width:12px;-webkit-appearance:none;background:var(--bg)}
html::-webkit-scrollbar-track{background:var(--bg);border-left:1px solid var(--border)}
html::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:6px;border:3px solid var(--bg)}
html::-webkit-scrollbar-thumb:hover{background:var(--fg3)}
/* Big screens: the page scales as a whole at three widths (same steps as labs.h2.io). */
@media (min-width:1600px){html{zoom:1.15}}
@media (min-width:2000px){html{zoom:1.3}}
@media (min-width:2500px){html{zoom:1.45}}

/* body never clips sideways: anything that pokes out must show up in the overflow checks */
body{
  font-family:var(--font-sans);font-size:var(--t-body);line-height:var(--lh-body);font-optical-sizing:auto;
  background:var(--bg);color:var(--fg);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;
}
::selection{background:var(--selection);color:var(--selection-fg)}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
p{text-wrap:pretty}
h1,h2,h3,h4{text-wrap:balance;font-weight:620;letter-spacing:-.015em;line-height:1.2}
.mono{font-family:var(--font-mono);font-size:.92em;letter-spacing:0}
.measure{max-width:66ch}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Focus: one visible ring everywhere. */
:focus{outline:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
/* a section that receives focus from an in-page link: the deep-link pulse marks it instead */
[tabindex="-1"]:focus-visible{outline:none}

/* Skip link: the label comes from aria-label (keeps page copy untouched), shown on focus. */
.skip{position:absolute;left:12px;top:-60px;z-index:100;display:inline-flex;align-items:center;min-height:44px;padding:10px 16px;border-radius:var(--radius-sm);
  background:var(--accent-fill);color:var(--on-accent);font-weight:600;font-size:14px;transition:top .15s}
.skip::after{content:attr(aria-label)}
.skip:focus-visible{top:10px}


/* ---- 3. layout ---- */
.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad)}
.frame{position:relative;border-top:1px solid var(--border)}
.frame > .wrap{position:relative;padding-block:var(--section-y)}
.frame--tight > .wrap{padding-block:calc(var(--section-y) * .7)}
.frame--loose > .wrap{padding-block:calc(var(--section-y) * 1.12)}
@media (min-width:760px){
  .frame > .wrap,.site-header > .wrap,.site-footer > .wrap{border-inline:1px solid var(--border)}
  /* the square nodes where the column lines cross the section rule */
  .frame > .wrap::before,.frame > .wrap::after{
    content:"";position:absolute;top:-4px;width:7px;height:7px;
    background:var(--bg);border:1px solid var(--border-strong);z-index:2}
  .frame > .wrap::before{left:-4px}
  .frame > .wrap::after{right:-4px}
}

/* The night band: dark in both schemes, on blueprint paper (12px minor grid, 48px major).
   It re-declares the dark tokens so every component inside it just works. In dark mode it
   lifts to a navy surface (a step of its own, not "a little darker", which would vanish into
   the page) and its two edges are drawn as blue hairlines. Use once per page. */
.band--night{
  color-scheme:dark;
  --bg:#0b1220; --bg-deep:#08101c; --surface:#101a2a; --surface-2:#142033;
  --fg:#e9eef5; --fg2:#adb8c7; --fg3:#8f9cb0;
  --border:#1c2838; --border-strong:#2e3d52; --hover:#111b2b;
  --accent:#6aa6f0; --accent-fill:#1466b3; --accent-fill-hover:#1a74c7; --on-accent:#fff;
  --accent-light:#10223a;
  --node:#6aa6f0; --link:rgba(128,178,240,.28); --coast:rgba(128,178,240,.5);
  --red:#ef5a4c; --red-text:#f58276; --grid:rgba(150,180,220,.06); --grid-minor:rgba(150,180,220,.025);
  --selection:#1d3a5f; --selection-fg:#f2f6fb;
  background:var(--bg);color:var(--fg);
  background-image:
    linear-gradient(to right,var(--grid) 1px,transparent 1px),
    linear-gradient(to bottom,var(--grid) 1px,transparent 1px),
    linear-gradient(to right,var(--grid-minor) 1px,transparent 1px),
    linear-gradient(to bottom,var(--grid-minor) 1px,transparent 1px);
  background-size:48px 48px,48px 48px,12px 12px,12px 12px;background-position:center top;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .band--night{
  --bg:#0e1929; --bg-deep:#0b1422; --surface:#132238; --surface-2:#172a44; --hover:#12213a;
  --border:#1f2d42; --border-strong:#30425c; --grid:rgba(150,180,220,.08); --grid-minor:rgba(150,180,220,.035)}}
:root[data-theme="dark"] .band--night{
  --bg:#0e1929; --bg-deep:#0b1422; --surface:#132238; --surface-2:#172a44; --hover:#12213a;
  --border:#1f2d42; --border-strong:#30425c; --grid:rgba(150,180,220,.08); --grid-minor:rgba(150,180,220,.035)}
.band--night.frame{border-top-color:var(--border-strong)}
.band--night + .frame{border-top-color:var(--border-strong)}
/* dark: the chapter change is drawn, top and bottom, in the network's blue */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .band--night.frame,:root:not([data-theme="light"]) .band--night + .frame{border-top-color:rgba(106,166,240,.42)}}
:root[data-theme="dark"] .band--night.frame,:root[data-theme="dark"] .band--night + .frame{border-top-color:rgba(106,166,240,.42)}


/* ---- 4. section heads ---- */
body{counter-reset:sec}
.section-head{margin-bottom:clamp(40px,5vw,64px);max-width:760px}
.section-head--split{max-width:none;display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:24px clamp(32px,6vw,96px);align-items:end}
.section-head--split .sec-intro{margin:0}
/* .is-top: a long intro starts level with the title (the eyebrow's line and its 18px margin above it) */
.section-head--split.is-top{align-items:start}
@media (min-width:900px){.section-head--split.is-top > :last-child{padding-top:calc(var(--t-label) * 1.4 + 18px)}}
@media (max-width:899px){.section-head--split{grid-template-columns:1fr}}
/* the eyebrow opens with the red section mark */
.eyebrow{
  font-family:var(--font-mono);font-size:var(--t-label);font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);margin-bottom:18px;display:flex;align-items:center;gap:12px;line-height:1.4}
.eyebrow::before{content:"";width:8px;height:8px;background:var(--red);flex:none;order:-2}
.eyebrow.num{counter-increment:sec}
.eyebrow.num::after{content:counter(sec,decimal-leading-zero);content:counter(sec,decimal-leading-zero) / "";order:-1;color:var(--fg3);letter-spacing:.08em}
.sec-title{font-size:var(--t-section);font-weight:600;letter-spacing:-.032em;line-height:1.04;color:var(--fg)}
.sec-intro{color:var(--fg2);font-size:var(--t-lead);line-height:1.7;margin-top:20px;max-width:62ch}
.hero-title{font-size:var(--t-hero);font-weight:640;letter-spacing:-.04em;line-height:.98}
.hero-title .accent,.page-title .accent{color:var(--accent)}
.page-head{max-width:820px;margin-bottom:clamp(40px,5vw,64px)}
.page-title{font-size:var(--t-page);font-weight:640;letter-spacing:-.035em;line-height:1.04;margin-bottom:22px}
/* every inner page's opener: one gap from the red-square eyebrow to the h1 */
:is(.page-head,.doc-head,.hero-head) .eyebrow{margin-bottom:22px}
/* the way back to the parent page, above the opener */
.back{display:inline-flex;align-items:center;min-height:44px;font-family:var(--font-mono);font-size:12.5px;letter-spacing:.02em;color:var(--fg2);transition:color .15s}
.back:hover{color:var(--accent)}
.lede{font-size:clamp(1.06rem,.98rem + .35vw,1.22rem);line-height:1.66;color:var(--fg2);max-width:62ch}
.statement{font-size:var(--t-statement);font-weight:560;letter-spacing:-.022em;line-height:1.3;color:var(--fg);max-width:34em;text-wrap:balance}
.statement > .k{display:block;font-weight:500;margin-bottom:12px;color:var(--accent);font-size:var(--t-label)}


/* ---- 5. controls ---- */
.cta{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:46px;padding:0 20px;
  border-radius:8px;font-size:15px;font-weight:600;letter-spacing:-.005em;line-height:1.2;
  border:1px solid var(--border-strong);transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease)}
.btn-primary{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--on-accent)}
.btn-primary:hover{background:var(--accent-fill-hover);border-color:var(--accent-fill-hover)}
.btn-ghost{color:var(--fg)}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
.btn .arrow{display:inline-block;transition:transform .2s var(--ease)}
.btn:hover .arrow{transform:translateX(3px)}
.btn--block{display:flex;width:100%}
/* every badge carries its separator in front; the row is shifted left by one separator width
   and clips that strip, so whichever badge starts a line shows none */
.badges{display:flex;flex-wrap:wrap;align-items:center;gap:8px 0;margin-left:-32px;clip-path:inset(0 0 0 32px);
  font-family:var(--font-mono);font-size:11.5px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--fg2)}
.badge{display:inline-flex;align-items:center;white-space:nowrap}
.badge::before{content:"";width:4px;height:4px;background:var(--fg3);margin:0 14px;opacity:.7;flex:none}
/* phones: two badges per line, never one left alone */
@media (max-width:519px){.badges{display:grid;grid-template-columns:auto auto;justify-content:start}}
.k,.kicker{font-family:var(--font-mono);font-size:var(--t-label);letter-spacing:.04em;color:var(--fg3);line-height:1.4}
.kicker{color:var(--accent);text-transform:uppercase;letter-spacing:.14em;font-size:11.5px;font-weight:500}
.tags{display:flex;flex-wrap:wrap;gap:8px}
.tag{font-family:var(--font-mono);font-size:12px;color:var(--fg2);border:1px solid var(--border-strong);
  border-radius:4px;padding:5px 10px;white-space:nowrap;line-height:1.3}
.balloon{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:26px;padding:0 5px;border:1px solid currentColor;
  border-radius:13px;font-family:var(--font-mono);font-size:11.5px;line-height:1;color:var(--accent);background:var(--bg);letter-spacing:0}

/* numbered in-page contents */
.contents{display:grid;grid-template-columns:auto repeat(5,minmax(0,auto));justify-content:space-between;align-items:center;gap:0 24px;
  border-top:1px solid var(--border-strong);font-size:14.5px;color:var(--fg2)}
.contents::before{content:"Contents";content:"Contents" / "";font-family:var(--font-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
.contents a{display:inline-flex;align-items:baseline;gap:9px;min-height:52px;padding-top:15px;transition:color .15s}
/* labels come from data-k / data-label; the link's accessible name is its aria-label */
.contents a::before{content:attr(data-k);content:attr(data-k) / "";font-family:var(--font-mono);font-size:11.5px;letter-spacing:.04em;color:var(--accent)}
.contents a::after{content:attr(data-label);content:attr(data-label) / ""}  /* plain value first: browsers without the alt-text syntax still draw the label */
.contents a:hover{color:var(--fg)}
@media (max-width:899px){
  .contents{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 20px}
  .contents::before{grid-column:1 / -1;padding-top:18px}
  .contents a{min-height:44px;padding-top:10px;border-bottom:1px solid var(--border)}
}
/* .contents--grid: many sections in ruled cells; the label takes its own line */
.contents--grid{grid-template-columns:repeat(4,minmax(0,1fr));justify-content:stretch;align-items:stretch;gap:0 32px}
.contents--grid::before{grid-column:1 / -1;padding:18px 0 4px}
.contents--grid a{min-height:48px;padding:12px 0 11px;border-bottom:1px solid var(--border);line-height:1.4}
@media (max-width:1099px){.contents--grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:0 24px}}
@media (max-width:899px){.contents--grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 20px}.contents--grid a{min-height:44px;padding:10px 0 9px}}


/* ---- 6. cards: article + one title link, the whole card is the hit area ---- */
.card{position:relative}
.card-link{color:inherit}
.card-link::after{content:"";position:absolute;inset:0;z-index:1}
.card .anchor-chip{z-index:3}
@supports selector(:has(a)){
  .card-link:focus-visible{outline:none}
  .card:has(.card-link:focus-visible){outline:2px solid var(--accent);outline-offset:-2px}
}
.card-dest{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;color:var(--fg3);transition:color .2s}
.card-dest svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.5;transition:transform .2s var(--ease)}
.card:hover .card-dest,.card:focus-within .card-dest{color:var(--accent)}
.card:hover .card-dest svg{transform:translateX(3px)}

/* the log: ruled rows on a rail, a node per entry, newest first */
.log{position:relative;border-top:1px solid var(--border)}
.post{position:relative;display:grid;grid-template-columns:156px minmax(0,1fr) 28px;column-gap:28px;padding:30px 20px 32px 0;
  border-bottom:1px solid var(--border);transition:background .2s var(--ease)}
.post > *{grid-column:2}
.post .pc-meta{display:contents}
.post .pc-meta > :last-child{grid-column:1;grid-row:1 / span 2;font-family:var(--font-mono);font-size:12px;color:var(--fg3);padding-left:22px;position:relative;line-height:1.5;white-space:nowrap}
.post .pc-meta > :first-child{grid-column:2;font-size:14px;color:var(--fg3);margin-top:14px}
.post::before{content:"";position:absolute;left:3.5px;top:0;bottom:0;width:1px;background:var(--border-strong)}
.post::after{content:"";position:absolute;left:0;top:35px;width:8px;height:8px;background:var(--bg);border:1px solid var(--accent)}
.post.flag::after{background:var(--accent);box-shadow:0 0 0 4px var(--accent-light)}
/* the living post: its node breathes twice when it comes into view, and again on hover */
@media (prefers-reduced-motion:no-preference){
  .js .post.flag.in::after{animation:living 2.2s var(--ease) .4s 2}
  .post.flag:hover::after{animation:living 2.2s var(--ease) 1}
}
@keyframes living{0%,100%{box-shadow:0 0 0 4px var(--accent-light)}50%{box-shadow:0 0 0 8px color-mix(in srgb,var(--accent-light) 50%,transparent)}}
.post h3{font-size:var(--t-h3);letter-spacing:-.022em;line-height:1.25;margin:10px 0 10px;transition:color .2s}
.post.flag h3{font-size:clamp(1.5rem,1.25rem + .8vw,1.9rem);letter-spacing:-.028em}
.post h3 + p{color:var(--fg2);font-size:var(--t-card);line-height:var(--lh-card)}
.post-arrow{grid-column:3;grid-row:1 / span 3;align-self:start;width:20px;height:20px;margin-top:30px;fill:none;stroke:var(--fg3);stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;transition:stroke .2s,transform .2s var(--ease)}
/* the whole row is the target: a quiet surface tint on hover and on keyboard focus */
.post:hover,.post:focus-within{background:linear-gradient(to right,transparent 0 22px,var(--hover) 22px)}
.post:hover h3{color:var(--accent)}
.post:hover .post-arrow,.post:focus-within .post-arrow{stroke:var(--accent);transform:translateX(3px)}
/* phones: one column, so the title and summary get the full measure; the arrow leaves the flow
   and sits at the end of the author line (the top right corner is the copy-link chip's) */
@media (max-width:599px){
  .post{grid-template-columns:minmax(0,1fr);padding:26px 0 28px 26px}
  .post > *,.post .pc-meta > :first-child,.post .pc-meta > :last-child{grid-column:1}
  .post .pc-meta > :last-child{grid-row:1;padding-left:0;margin-bottom:8px}
  .post .pc-meta > :first-child{padding-right:32px}
  .post-arrow{position:absolute;right:0;bottom:31px;margin:0;grid-area:auto}  /* auto: placed against the row, not a grid area */
  .post::after{top:31px}
  .post:hover,.post:focus-within{background:linear-gradient(to right,transparent 0 12px,var(--hover) 12px)}
}


/* ---- 7. figures and diagrams ---- */
.fig{margin:0}
.fig-body{position:relative}
.fig-svg{display:block;width:100%;max-width:380px;height:auto;margin-inline:auto;overflow:visible}
.fig--crop > .fig-body{padding:22px 20px;
  background:
    linear-gradient(var(--fg3),var(--fg3)) left top / 10px 1px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) left top / 1px 10px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) right top / 10px 1px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) right top / 1px 10px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) left bottom / 10px 1px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) left bottom / 1px 10px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) right bottom / 10px 1px no-repeat,
    linear-gradient(var(--fg3),var(--fg3)) right bottom / 1px 10px no-repeat}
@media (max-width:599px){.fig--crop > .fig-body{padding:18px 0}}
.fig-cap{margin-top:14px;font-size:13.5px;line-height:1.5;color:var(--fg2);text-wrap:pretty}
.fig-no{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin-right:10px;white-space:nowrap}

/* SVG labels: 11 units from 600px up, 12 units below (see LABEL FLOOR in the index) */
.fig-svg text,.fig text{font-family:var(--font-mono);font-size:11px;letter-spacing:.02em;fill:var(--fg3)}
@media (max-width:599px){.fig-svg text{font-size:12px}}
.fig-svg .d-lbl-hi{fill:var(--accent)}
.fig-svg .d-lbl-fg{fill:var(--fg)}
.fig-svg .d-lbl-red{fill:var(--red-text)}
.fig-svg .d-ko{paint-order:stroke;stroke:var(--bg);stroke-width:5px;stroke-linejoin:round}
.d-line{fill:none;stroke:var(--border-strong);stroke-width:1}
.d-link{fill:none;stroke:var(--link);stroke-width:1}
.d-acc{fill:none;stroke:var(--accent);stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.d-thick{fill:none;stroke:var(--fg);stroke-width:3}
.d-dash{stroke-dasharray:4 4}
.d-node{fill:var(--node)}
.d-ink{fill:var(--fg2)}
.d-box{fill:var(--surface);stroke:var(--border-strong);stroke-width:1}
.d-hatch{fill:url(#h2-hatch);stroke:var(--fg3);stroke-width:1}
.d-deny{fill:none;stroke:var(--red);stroke-width:1.8;stroke-linecap:round}
.d-sig{fill:none;stroke:var(--node);stroke-width:2.2;stroke-linecap:round;stroke-dasharray:6 400;stroke-dashoffset:6;opacity:0}
@media (prefers-reduced-motion:no-preference){
  .js .reveal .draw{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 1.2s var(--ease-draw) .15s}
  .js .reveal.in .draw{stroke-dashoffset:0}
  /* one pass when the figure enters view, then rest */
  .js .reveal.in .d-sig{animation:d-sig var(--dur,3.2s) linear calc(var(--delay,0s) + .5s) 1 both}
}
@keyframes d-sig{0%{stroke-dashoffset:6;opacity:0}8%{opacity:1}80%{opacity:1}100%{stroke-dashoffset:calc(var(--len,300) * -1px);opacity:0}}

/* .plot: a line diagram with HTML labels (they never shrink with the drawing) */
.plot{position:relative;height:var(--plot-h,150px)}
.plot > svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.plot > svg *{vector-effect:non-scaling-stroke}
.plot-node,.plot-lbl,.plot-arrow,.plot .balloon{position:absolute;left:var(--x);top:var(--y)}
.plot-node{width:10px;height:10px;margin:-5px 0 0 -5px;background:var(--node)}
.plot-lbl{font-family:var(--font-mono);font-size:var(--t-fig);letter-spacing:.02em;line-height:1.35;color:var(--fg3);white-space:nowrap;
  display:flex;align-items:center;gap:8px;transform:translate(0,-100%);padding-bottom:10px}
.plot-lbl.down{transform:none;padding:10px 0 0}
.plot-lbl.end{transform:translate(-100%,-100%)}
.plot-lbl.end.down{transform:translate(-100%,0)}
.plot-lbl.mid{transform:translate(-50%,-100%)}
.plot-lbl.mid.down{transform:translate(-50%,0)}
.plot-lbl.hi{color:var(--accent)}
.plot-lbl .balloon{position:static}
.plot-arrow{width:9px;height:9px;margin:-5px 0 0 -9px;border:solid var(--accent);border-width:1.5px 1.5px 0 0;transform:rotate(45deg)}

/* .timeline: years, not quarters */
.timeline{position:relative;height:56px;margin-top:28px}
.timeline::before{content:"";position:absolute;left:0;right:0;top:9px;height:9px;
  background:linear-gradient(var(--fg3),var(--fg3)) left 4px / 100% 1px no-repeat,
    repeating-linear-gradient(to right,var(--fg3) 0 1px,transparent 1px 28px) left top / 100% 9px no-repeat;opacity:.8}
.timeline::after{content:"";position:absolute;right:-1px;top:6px;width:14px;height:14px;background:var(--node)}
.timeline .tl-a,.timeline .tl-b{position:absolute;top:30px;font-family:var(--font-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg2)}
.timeline .tl-a{left:0}
.timeline .tl-a::before{content:"";position:absolute;left:0;top:-24px;width:14px;height:14px;border:1.5px solid var(--node);background:var(--bg)}
.timeline .tl-b{right:0;color:var(--accent)}


/* ---- 8. specification table ---- */
.spec-cap{font-size:13.5px;color:var(--fg2);margin-bottom:14px}
.spec{list-style:none;border-top:2px solid var(--fg);border-bottom:2px solid var(--fg)}
.spec-head{display:grid;grid-template-columns:minmax(180px,2fr) minmax(0,3fr) minmax(0,4fr);gap:24px;padding:10px 0;border-bottom:1px solid var(--fg);
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
.spec-row{position:relative;display:grid;grid-template-columns:minmax(180px,2fr) minmax(0,3fr) minmax(0,4fr);gap:8px 24px;align-items:start;
  padding:24px 44px 24px 0;border-top:1px solid var(--border)}
.spec-head + .spec-row{border-top:0}
.spec-ref{display:flex;align-items:center;gap:14px;min-height:28px}
.spec-sym{flex:none;width:30px;height:30px;color:var(--fg2)}
.spec-sym svg{width:30px;height:30px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.spec-sym .acc{stroke:var(--accent)}
.spec-sym .dot{fill:var(--accent);stroke:none}
.spec-sym .stop{stroke:currentColor}  /* the six rows are equal: red stays inside the numbered figures */
.spec-row .k{color:var(--accent)}
.spec-row h3{font-size:1.14rem;letter-spacing:-.015em;line-height:1.3;text-wrap:balance}
.spec-row p{color:var(--fg2);font-size:var(--t-card);line-height:var(--lh-card)}
@media (min-width:700px){
  .spec--compact .spec-head,.spec--compact .spec-row{grid-template-columns:96px minmax(0,3fr) minmax(0,5fr)}
}
@media (max-width:699px){
  .spec-head{display:none}
  .spec-row{grid-template-columns:1fr;padding:22px 0 24px}
  .spec-ref{padding-right:44px}
  .spec-row h3{margin-top:6px}
}


/* ---- 9. data tables ---- */
/* the wrap scrolls sideways; a soft shadow shows at whichever edge has more to show */
.table-wrap{overflow-x:auto;max-width:100%;margin:28px 0;
  background:
    linear-gradient(to right,var(--bg) 30%,transparent) left center / 40px 100% no-repeat local,
    linear-gradient(to left,var(--bg) 30%,transparent) right center / 40px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,color-mix(in srgb,var(--fg) 26%,transparent),transparent) left center / 16px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,color-mix(in srgb,var(--fg) 26%,transparent),transparent) right center / 16px 100% no-repeat scroll}
.table-wrap:focus-visible{outline-offset:-2px}
.table{width:100%;border-collapse:collapse;font-size:14px;line-height:1.5;border-top:2px solid var(--fg);border-bottom:2px solid var(--fg)}
.table caption{caption-side:top;text-align:left;font-size:13.5px;color:var(--fg2);padding-bottom:12px}
.table th{font-family:var(--font-mono);font-size:11.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--fg3);text-align:left;
  padding:10px 20px 10px 0;border-bottom:1px solid var(--fg);vertical-align:bottom}
.table td{padding:12px 20px 12px 0;border-top:1px solid var(--border);vertical-align:top;color:var(--fg2)}
.table :is(th,td):last-child{padding-right:0}
.table td:first-child{color:var(--fg)}
.table .num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-mono);font-size:13px}
.table code{white-space:nowrap}
.table td code{font-size:.9em}
/* phones: tighter columns; a long token in the last column may break rather than push the table wider */
@media (max-width:479px){
  .table :is(th,td){padding-right:12px}
  .table td:last-child code{white-space:normal;overflow-wrap:anywhere}
}
@media (max-width:379px){.table :is(th,td){padding-right:9px}}
/* the smallest phones: table code a step smaller, so a token such as
   SealedBox_seal(AuditEvent[112]) fits its cell instead of breaking inside a number */
@media (max-width:400px){.table td code{font-size:.82em}}


/* ---- 10. code ---- */
code,kbd,samp{font-family:var(--font-mono);font-size:.88em}
/* code shows the characters as typed: no ligatures ("->" stays two characters, never an arrow) */
code,kbd,samp,pre{font-variant-ligatures:none;font-feature-settings:"calt" 0,"liga" 0}
:not(pre) > code{padding:.06em .22em;border-radius:4px;background:var(--surface-2);border:1px solid var(--border);color:var(--fg);overflow-wrap:anywhere}
/* in a heading, code is set in the heading's own ink: no chip, which would read as a UI box */
:is(h1,h2,h3,h4) code{background:none;border:0;padding:0;font-size:.9em;color:inherit}
kbd{padding:.1em .4em;border:1px solid var(--border-strong);border-bottom-width:2px;border-radius:4px;background:var(--surface);font-size:.82em}
.code-block{margin:24px 0;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--surface);overflow:hidden}
.code-cap{display:flex;justify-content:space-between;gap:12px;padding:8px 14px;border-bottom:1px solid var(--border);
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--fg3);background:var(--surface-2)}
pre{font-family:var(--font-mono);font-size:13px;line-height:1.6;overflow-x:auto;tab-size:4;padding:16px 18px;color:var(--fg);white-space:pre}
pre code{font-size:inherit}
pre:focus-visible{outline-offset:-2px}
/* phones: rather than hide the end of a long line behind a sideways scroll, a block wraps,
   each continuation hanging two characters in */
@media (max-width:640px){
  .code-block pre{white-space:pre-wrap;word-break:normal;overflow-wrap:anywhere}
}
@supports (text-indent:1ch each-line){
  @media (max-width:640px){.code-block pre{padding-left:calc(18px + 2ch);text-indent:-2ch each-line}}
}
pre .cmt{color:var(--fg3)} pre .str{color:var(--accent)} pre .kw{font-weight:650}


/* ---- 11. prose (long documents) ---- */
/* documents quote wire formats: Inter's contextual alternates are off, so "->" and "<->" stay as
   typed in the text and the contents; the code chip is tighter, since nearly every line has one */
.prose{max-width:72ch;color:var(--fg2);font-feature-settings:"calt" 0}
.prose > * + *{margin-top:1.1em}
.prose h2{font-size:clamp(1.5rem,1.2rem + 1vw,2rem);letter-spacing:-.025em;color:var(--fg);margin-top:2.2em;line-height:1.15}
.prose h3{font-size:1.2rem;color:var(--fg);margin-top:1.8em}
.prose h4{font-size:1rem;color:var(--fg);margin-top:1.5em}
.prose a{color:var(--accent);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.prose a:hover{text-decoration-thickness:2px}
.prose ul,.prose ol{padding-left:1.4em}
.prose li + li{margin-top:.4em}
.prose li::marker{color:var(--fg3)}
.prose blockquote,.callout{border-left:2px solid var(--accent);padding:2px 0 2px 18px;color:var(--fg)}
.callout{max-width:calc(66ch + 20px)}
.callout p + p{margin-top:1em}
.prose hr{border:0;border-top:1px solid var(--border-strong);margin:2.4em 0}
.prose strong{color:var(--fg);font-weight:620}
.note{position:relative;border:1px solid var(--border-strong);background:var(--surface);padding:20px 22px;
  font-size:var(--t-card);line-height:var(--lh-body);color:var(--fg2)}
.note > * + *{margin-top:.8em}
.note :is(p,li){color:inherit;font-size:inherit;line-height:inherit}
.note :is(strong,b){color:var(--fg);font-weight:620}
.note :is(ul,ol){padding-left:1.2em}
.note::before{content:"";position:absolute;inset:-4px;pointer-events:none;
  background:
    linear-gradient(var(--bg),var(--bg)) left 1px top 1px / 5px 5px no-repeat,
    linear-gradient(var(--bg),var(--bg)) right 1px top 1px / 5px 5px no-repeat,
    linear-gradient(var(--bg),var(--bg)) left 1px bottom 1px / 5px 5px no-repeat,
    linear-gradient(var(--bg),var(--bg)) right 1px bottom 1px / 5px 5px no-repeat,
    linear-gradient(var(--border-strong),var(--border-strong)) left top / 7px 7px no-repeat,
    linear-gradient(var(--border-strong),var(--border-strong)) right top / 7px 7px no-repeat,
    linear-gradient(var(--border-strong),var(--border-strong)) left bottom / 7px 7px no-repeat,
    linear-gradient(var(--border-strong),var(--border-strong)) right bottom / 7px 7px no-repeat}
.note--open{border-style:dashed;background:transparent}
.note .kicker{margin-bottom:6px}
/* phones: a long note keeps a readable measure (about 38-40ch at 390px) */
@media (max-width:599px){.note{padding:14px 14px 16px 16px}}
.footnote{display:flex;gap:10px;font-size:13.5px;line-height:1.55;color:var(--fg3);padding-top:12px;border-top:1px solid var(--border);max-width:36em}
.fn-k,.fn{font-family:var(--font-mono);font-size:11px;color:var(--accent)}
.fn{vertical-align:super;line-height:0;margin-left:2px}

/* ---- 11b. the document sheet (askd's specification, comparison and test vectors) ---- */
.doc-frame > .wrap{padding-block:clamp(14px,2vw,24px) clamp(72px,9vw,120px)}
/* the opener: eyebrow (drawn from data-label where the document has no words for it), h1, lede or meta */
.doc-kind span::after{content:attr(data-label);content:attr(data-label) / ""}
.doc-head{max-width:880px;padding:clamp(24px,3.6vw,52px) 0 clamp(28px,3.4vw,44px)}
.doc-head .page-title{margin:0;color:var(--fg)}
.doc-head .lede{margin-top:24px;max-width:52ch}
.doc-status{margin-top:18px;font-family:var(--font-mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
/* the reading column: running text, tables and panels share one measure (60ch, about 75
   characters of Inter); notes grow outward by their padding; code blocks and the section
   rules use the column */
.doc.prose{max-width:none}
.doc :is(p,ul,ol,h3,h4){max-width:60ch}
.doc h2{position:relative;margin-top:clamp(56px,6vw,84px);padding-top:24px;border-top:1px solid var(--border-strong)}
/* the square node where a section rule starts (the frame's node, not the red mark) */
.doc h2::before{content:"";position:absolute;left:0;top:-4px;width:7px;height:7px;background:var(--bg);border:1px solid var(--border-strong)}
.doc h3{margin-top:2.1em}
.doc :is(h2,h3) + *,.doc :is(h2,h3) + .title-anchor + *{margin-top:.75em}
.doc hr{display:none}
.doc .table-wrap{margin:1.3em 0 0;max-width:60ch}
.doc .code-block{margin-top:1.2em}
.doc .note{max-width:calc(60ch + 46px)}
.doc .toc{max-width:60ch}   /* inline, the contents are a panel of the column */
/* a ruled panel's label (the contents, the downloads), as the homepage's Contents label */
.panel-k{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
/* the contents: a ruled list (the same 1px rule as the homepage's .contents) */
.toc{border-top:1px solid var(--border-strong);border-bottom:1px solid var(--border-strong);padding:14px 0 12px}
.toc .panel-k{margin-bottom:6px}
.toc [data-label]::after{content:attr(data-label);content:attr(data-label) / ""}
.toc ul{list-style:none;padding:0}
.toc li + li{margin-top:0}
.toc a{display:flex;align-items:center;min-height:34px;padding:5px 0;font-size:14px;line-height:1.35;color:var(--fg);text-decoration:none;transition:color .15s,border-color .15s}
.toc li.l3 a{margin-left:3px;padding-left:16px;border-left:1px solid var(--border-strong);font-size:13.5px;color:var(--fg2)}
.toc li a:hover,.toc li a[aria-current]{color:var(--accent)}
.toc li.l3 a[aria-current]{border-left-color:var(--accent)}
@media (pointer:coarse){.toc a{min-height:44px}}
@media (prefers-reduced-motion:reduce){.toc a{transition:none}}   /* the marker just moves */
/* from 1100px the contents stand in a rail beside the text and stay in view */
@media (min-width:1100px){
  .doc--toc{display:grid;grid-template-columns:minmax(0,1fr) 248px;column-gap:clamp(48px,5vw,80px);align-items:start}
  .doc--toc > *{grid-column:1}
  .doc--toc > .toc{grid-column:2;grid-row:1 / span 400;position:sticky;top:calc(var(--header-h) + 28px);
    margin-top:clamp(24px,3.6vw,52px);max-height:calc(100vh - var(--header-h) - 56px);overflow-y:auto}
}
/* file chips: mono names, a lit node in front, touch-sized */
.files{display:flex;flex-wrap:wrap;gap:8px}
.files a{display:inline-flex;align-items:center;gap:10px;min-height:44px;padding:0 14px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);
  background:var(--bg);font-family:var(--font-mono);font-size:13px;line-height:1.3;color:var(--fg);text-decoration:none;transition:border-color .15s,color .15s}
.files a::before{content:"";width:6px;height:6px;background:var(--node);flex:none}
.files a:hover{border-color:var(--accent);color:var(--accent)}


/* ---- 12. forms ---- */
.form{display:grid;gap:18px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media (max-width:519px){.grid2{grid-template-columns:1fr}}
.field{display:grid;gap:7px;align-content:start}
.field label{font-size:14px;font-weight:560;color:var(--fg)}
.hint{font-weight:400;color:var(--fg3);font-size:13px;margin-left:6px}
.field input,.field select,.field textarea,.input{
  width:100%;min-height:46px;padding:11px 14px;font:inherit;font-size:16px;line-height:1.4;color:var(--fg);
  background:var(--surface);border:1px solid var(--input-border);border-radius:8px;transition:border-color .15s,box-shadow .15s;appearance:none}
.field select{padding-right:38px;background-image:linear-gradient(45deg,transparent 50%,var(--fg3) 50%),linear-gradient(135deg,var(--fg3) 50%,transparent 50%);
  background-position:calc(100% - 20px) 50%,calc(100% - 15px) 50%;background-size:5px 5px;background-repeat:no-repeat}
.field textarea{min-height:120px;resize:vertical}
.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--fg3)}
/* focus: a 2px accent ring (the border plus one more pixel), then the soft halo */
.field :is(input,select,textarea):focus-visible{outline:none;border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 0 0 4px var(--accent-light)}
.field.invalid input,.field.invalid select,.field.invalid textarea{border-color:var(--red)}
.field-error{font-size:13px;color:var(--red-text)}
.check{display:flex;gap:10px;align-items:flex-start;font-size:14.5px;min-height:44px;padding-top:10px}
.check input{width:18px;height:18px;accent-color:var(--accent-fill);margin-top:2px}
fieldset.group{border:0;display:grid;gap:10px}
fieldset.group legend{font-size:14px;font-weight:560;margin-bottom:6px}
.banner{border:1px solid var(--accent);background:var(--accent-light);color:var(--fg);padding:14px 16px;border-radius:var(--radius-sm);font-size:14.5px;line-height:1.55}
.dialog,.modal-box{background:var(--surface);color:var(--fg);border:1px solid var(--border-strong);border-radius:var(--radius);box-shadow:var(--shadow);padding:28px;max-width:min(480px,calc(100vw - 32px))}
.dialog::backdrop{background:rgba(6,10,17,.55)}


/* ---- 13. the call-to-action field: solid European blue, both schemes, once per page ---- */
.cta-field{
  --bg:var(--field-bg); --fg:var(--field-fg); --fg2:var(--field-fg2); --fg3:var(--field-fg2);
  --accent:#ffffff; --node:#ffffff; --border:var(--field-line); --border-strong:var(--field-line);
  --accent-fill:#ffffff; --accent-fill-hover:#e6eef8; --on-accent:#0b4a86; --accent-light:rgba(255,255,255,.18);
  background:var(--field-bg);color:var(--field-fg);position:relative}
.cta-field .btn-ghost{color:#fff;border-color:rgba(255,255,255,.75)}
.cta-field .btn-ghost:hover{background:rgba(255,255,255,.1);border-color:#fff;color:#fff}
.cta-field :focus-visible{outline-color:#fff}


/* ---- 14. header ---- */
.site-header{position:sticky;top:0;z-index:50;background:var(--bg);border-bottom:1px solid var(--border)}
.nav{display:flex;align-items:center;gap:24px;min-height:var(--header-h)}
.brand-wrap{position:relative}
.brand{display:flex;align-items:center;gap:11px;min-height:44px}
.brand-icon{display:flex}
.brand-mark{width:26px;height:26px;display:block}
.brand-name{font-weight:650;letter-spacing:-.02em;font-size:18px;line-height:1}
.brand-tip{
  position:absolute;top:calc(100% + 10px);left:0;width:320px;padding:18px 20px 18px;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius);
  box-shadow:var(--shadow);opacity:0;pointer-events:none;transform:translateY(-4px);visibility:hidden;
  transition:opacity .18s var(--ease),transform .18s var(--ease),visibility 0s linear .18s;z-index:200}
/* closed, it is hidden outright (not found by find-in-page, not read out of place); its text still
   reaches screen readers as the brand link's description (aria-describedby) */
.brand-tip.open{opacity:1;transform:none;pointer-events:auto;visibility:visible;transition-delay:0s}
.brand-tip svg{width:112px;height:auto;margin-bottom:12px}
.brand-tip p{color:var(--fg2);font-size:14px;line-height:1.65;user-select:text;-webkit-user-select:text}
/* the running head: names the section being read (desktop only, set by the page script) */
.run-head{display:none;min-width:0;font-family:var(--font-mono);font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3);white-space:nowrap}
.run-head span{overflow:hidden;text-overflow:ellipsis}   /* a long section name ends in an ellipsis */
@media (min-width:1100px){
  .run-head:not(:empty){display:flex;align-items:center;gap:10px;padding-left:22px;border-left:1px solid var(--border-strong);min-height:22px}
  .run-head b{font-weight:500;color:var(--accent)}
}
.nav-links{display:flex;align-items:center;gap:6px;margin-left:auto;font-size:14.5px;color:var(--fg2)}
.nav-links a{display:inline-flex;align-items:center;min-height:44px;padding:0 12px;border-radius:6px;transition:color .15s}
.nav-links a:hover{color:var(--fg)}
.nav-links .nav-cta{margin-left:8px;min-height:44px;padding:0 18px;border:1px solid var(--border-strong);color:var(--fg);border-radius:8px}
.nav-links .nav-cta:hover{border-color:var(--accent);color:var(--accent)}
.menu-btn{display:none;width:44px;height:44px;margin-left:auto;align-items:center;justify-content:center;border-radius:8px;border:1px solid var(--border)}
.menu-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round}
.menu-btn .x{display:none}
.menu-btn[aria-expanded="true"] .x{display:block}
.menu-btn[aria-expanded="true"] .bars{display:none}
@media (max-width:759px){
  /* The nav wraps here (the links fold under the brand), so the flex lines pack to the top.
     The brand and the menu button carry their own vertical margin instead of relying on
     min-height + centring: the first row stays --header-h tall, and the brand and the
     button sit at the same place whether the menu is open or closed. */
  .nav{flex-wrap:wrap;gap:0 12px;min-height:0}
  .brand-wrap,.menu-btn{margin-block:calc((var(--header-h) - 44px) / 2)}
  /* without JS the links cannot fold away, so a pinned header would keep a third of a phone
     screen: let it scroll away with the page, and land anchors near the top */
  html:not(.js) .site-header{position:static}
  html:not(.js){scroll-padding-top:24px}
  /* without JS: a tidy 2 x 2 grid under the brand */
  .nav-links{display:grid;grid-template-columns:1fr 1fr;width:100%;gap:0 12px;margin:0 0 10px;font-size:15px}
  .nav-links a{padding:0 2px;border-top:1px solid var(--border);border-radius:0}
  .nav-links .nav-cta{margin:0;border:0;border-top:1px solid var(--border);border-radius:0;padding:0 2px;color:var(--accent)}
  /* with JS: folded behind the menu button */
  .js .menu-btn{display:inline-flex}
  .js .nav-links{display:none;grid-template-columns:1fr;margin:0;padding:6px 0 14px;font-size:17px}
  .js .nav-links.open{display:grid}
  .js .nav-links a{min-height:52px;color:var(--fg)}
  .js .nav-links .nav-cta{margin:10px 0 0;border:1px solid var(--border-strong);border-radius:8px;justify-content:center;color:var(--fg)}
  .brand-tip{width:min(320px,calc(100vw - 40px))}
}


/* ---- 15. footer: the sheet's title block ----
   The frame closes as a drawing sheet closes on its title block: one row of hairline cells
   between the column lines (the sign-off, then one cell per link), a rule under it, and a
   square node wherever a divider meets a rule. */
.site-footer{border-top:1px solid var(--border-strong);color:var(--fg3);font-size:var(--t-small);padding-bottom:clamp(48px,7vw,88px)}
.site-footer > .wrap{padding-block:0}
.foot{position:relative;display:flex;align-items:stretch;border-bottom:1px solid var(--border-strong)}
.foot-sign{flex:1 1 auto;display:flex;align-items:center;gap:16px;min-height:104px;padding:28px 24px 28px 0;line-height:1.5}
.foot-sign svg{width:30px;height:30px;flex:none}
.foot-copy{font-family:var(--font-mono);font-size:12.5px;letter-spacing:.02em;color:var(--fg2)}
/* the sign-off is "(c) years H2 Labs <span.foot-sep> . </span><span.nowrap>European . Sovereign</span>":
   on phones it sets as two lines, the name, then the motto, and the separator between them is
   kept for screen readers only, so no line ever ends on a dot */
@media (max-width:599px){
  .foot-copy .foot-sep{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
  .foot-copy .nowrap{display:block}
}
/* askd and its documents: the sign-off cell carries the page's colophon above the copyright */
.foot-doc{display:grid;gap:8px}
.doc-colophon{font-size:13.5px;line-height:1.6;color:var(--fg2);max-width:60ch}
.doc-colophon a{color:var(--accent);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.doc-colophon strong{font-weight:600;color:var(--fg)}
.foot-links{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(118px,auto);margin-right:calc(var(--pad) * -1)}
.foot-links a{position:relative;display:flex;align-items:flex-end;padding:14px 18px 16px;border-left:1px solid var(--border-strong);
  color:var(--fg2);font-size:14.5px;line-height:1.3;min-height:52px;transition:color .15s,background .15s}
.foot-links a::after{content:"\2192";content:"\2192" / "";position:absolute;top:12px;right:14px;font-size:13px;color:var(--fg3);transition:transform .2s var(--ease),color .15s}
.foot-links a:hover{color:var(--fg);background:var(--hover)}
.foot-links a:hover::after{color:var(--accent);transform:translateX(2px)}
@media (min-width:900px){
  .foot-links a::before{content:"";position:absolute;left:-4px;top:-5px;bottom:-5px;width:7px;pointer-events:none;
    background:
      linear-gradient(var(--bg),var(--bg)) center top 1px / 5px 5px no-repeat,
      linear-gradient(var(--bg),var(--bg)) center bottom 1px / 5px 5px no-repeat,
      linear-gradient(var(--border-strong),var(--border-strong)) center top / 7px 7px no-repeat,
      linear-gradient(var(--border-strong),var(--border-strong)) center bottom / 7px 7px no-repeat}
}
@media (min-width:760px){
  .foot::before,.foot::after{content:"";position:absolute;bottom:-4px;width:7px;height:7px;background:var(--bg);border:1px solid var(--border-strong);z-index:2}
  .foot::before{left:-4px}
  .foot::after{right:-4px}
  .site-footer{position:relative}
  .site-footer::before,.site-footer::after{content:"";position:absolute;top:-4px;width:7px;height:7px;background:var(--bg);border:1px solid var(--border-strong);z-index:2}
  .site-footer::before{left:calc(max(0px,(100% - var(--wrap)) / 2) - 4px)}
  .site-footer::after{right:calc(max(0px,(100% - var(--wrap)) / 2) - 4px)}
  .site-header > .wrap{position:relative}
  .site-header > .wrap::before,.site-header > .wrap::after{content:"";position:absolute;bottom:-4px;width:7px;height:7px;
    background:var(--bg);border:1px solid var(--border-strong);z-index:2}
  .site-header > .wrap::before{left:-4px}
  .site-header > .wrap::after{right:-4px}
}
@media (max-width:899px){
  .foot{flex-direction:column}
  .foot-sign{min-height:0;padding:28px 0}
  .foot-links{grid-auto-flow:row;grid-template-columns:repeat(2,minmax(0,1fr));margin:0 calc(var(--pad) * -1);border-top:1px solid var(--border-strong)}
  .foot-links a{min-height:64px;border-left:0;padding-inline:var(--pad) 18px}
  .foot-links a:nth-child(even){border-left:1px solid var(--border-strong)}
  .foot-links a:nth-child(n+3){border-top:1px solid var(--border-strong)}
}
@media (min-width:600px) and (max-width:899px){
  .foot-links{grid-template-columns:repeat(4,minmax(0,1fr))}
  .foot-links a + a{border-left:1px solid var(--border-strong)}
  .foot-links a:nth-child(n+3){border-top:0}
}


/* ---- 16. copy-link chips, title anchors, the deep-link pulse ---- */
.anchor-chip{
  position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:6px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-mono);font-size:13px;line-height:1;color:var(--fg3);
  background:var(--surface);border:1px solid var(--border);
  opacity:0;transition:opacity .15s,color .15s,border-color .15s;z-index:3}
.anchor-chip:hover,.anchor-chip:focus-visible{color:var(--accent);border-color:var(--accent)}
:is(.pillar,.spec-row,.card,.post,.track):is(:hover,:focus-within) > .anchor-chip,.anchor-chip:focus-visible{opacity:1}
/* touch screens: no hover to reveal it, so the chip is always drawn, in a quiet ink that still clears 3:1 */
@media (hover:none){.anchor-chip{opacity:1;color:var(--fg2)}}
@media (pointer:coarse){.anchor-chip{top:0;right:0;width:44px;height:44px;border-color:transparent;background:none}}
.nowrap{white-space:nowrap}
/* The "#" after a heading. The page script inserts <a class="title-anchor" aria-label="..."><span
   aria-hidden="true">#</span></a> as the heading's next sibling: a zero-height block, so it moves
   nothing and adds nothing to the heading's name. Its glyph box is one heading line tall (--lh),
   sits on the heading's last line and hangs in the left margin (the gutter is >= 20px). */
.title-anchor{display:block;position:relative;height:0;margin:0!important;padding:0;border:0;text-decoration:none!important;
  --lh:calc(var(--t-section) * 1.04)}
.prose h2 + .title-anchor{--lh:calc(clamp(1.5rem,1.2rem + 1vw,2rem) * 1.15)}
.prose h3 + .title-anchor{--lh:calc(1.2rem * 1.2)}
.title-anchor > span{position:absolute;right:100%;bottom:0;height:var(--lh);margin-right:clamp(6px,1.2vw,14px);
  display:flex;align-items:center;font-family:var(--font-mono);font-size:16px;font-weight:400;line-height:1;
  color:var(--fg3);opacity:0;transition:opacity .15s,color .15s}
:is(h1,h2,h3):hover + .title-anchor > span,.title-anchor:hover > span,.title-anchor:focus-visible > span{opacity:1}
.title-anchor:hover > span{color:var(--accent)}
.title-anchor:focus-visible{outline:none}
.title-anchor:focus-visible > span{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px;color:var(--accent)}
/* touch screens: no hover to reveal them, so they are not there to be tapped by accident */
@media (hover:none){.title-anchor{display:none}}
/* the deep-link highlight: one glow that fades; with reduced motion, a still outline instead
   (the page script removes the class again on the next deep link) */
@media (prefers-reduced-motion:no-preference){.hl-pulse{animation:hlpulse 2.4s var(--ease)}}
@media (prefers-reduced-motion:reduce){.hl-pulse{outline:2px solid var(--accent);outline-offset:4px}}
@keyframes hlpulse{
  0%{box-shadow:0 0 0 0 var(--accent)}
  12%{box-shadow:0 0 0 2px var(--accent),0 12px 36px -8px color-mix(in srgb,var(--accent) 40%,transparent)}
  100%{box-shadow:0 0 0 0 transparent}
}


/* ---- 17. reveal on scroll: only with JS and motion allowed; one class, "in" ---- */
@media (prefers-reduced-motion:no-preference){
  .js .reveal{opacity:0;transform:translateY(12px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
  .js .reveal.in{opacity:1;transform:none}
}


/* ---- 17b. print: everything in its final state (nothing waits for a scroll that never comes) ---- */
@media print{
  .js .reveal{opacity:1!important;transform:none!important}
  .js .reveal .draw{stroke-dashoffset:0!important}
  *,*::before,*::after{transition:none!important;animation-duration:0s!important;animation-delay:0s!important}
  .site-header{position:static}
  .menu-btn,.anchor-chip,.title-anchor,.skip{display:none!important}
}


/* ---- 18. forced colours: keep meaning that lives in fills, fields and drawn labels ----
   Backgrounds and gradients are dropped in forced colours and SVG paint is not forced, so
   the drawings switch to CanvasText/Canvas themselves, and filled marks opt out. */
@media (forced-colors:active){
  .cta-field{border:2px solid CanvasText}
  .eyebrow::before,.plot-node,.timeline::after{forced-color-adjust:none;background:CanvasText}
  .timeline::before{background:none;border-top:1px solid CanvasText;top:13px;height:0;opacity:1}
  .timeline .tl-a::before{border-color:CanvasText}
  .fig-svg text,.fig-svg text[class]{fill:CanvasText}
  .d-line,.d-box,.d-acc,.d-thick,.d-hatch{stroke:CanvasText}
  .d-deny{stroke:CanvasText;stroke-width:2.6}
  .d-box{fill:Canvas}
  .d-node,.d-ink{fill:CanvasText}
  .plot > svg path{stroke:CanvasText}
  .plot-arrow{border-color:CanvasText}
  .card:has(.card-link:focus-visible){outline-color:Highlight}
  /* the drawn select arrow is a background image, which forced colours drop: use the native one */
  .field select{appearance:auto;background-image:none;padding-right:14px}
}

/* Text links stay visibly clickable without hover. Brand marks and buttons retain
   their existing affordances. Applies to homepage, articles and service pages. */
body a[href]:not(.brand):not(.migration-brand):not(.btn):not(.button):not(.nav-cta){text-decoration-line:underline;text-decoration-thickness:1px;text-underline-offset:3px}
body a[href]:not(.brand):not(.migration-brand):not(.btn):not(.button):not(.nav-cta):hover{text-decoration-thickness:2px}
