/* Generated by apps/www/scripts/build.mjs from system/dist/tokens.css. */
:root {
  color-scheme: light dark;
  --ground-default: oklch(97.3% 0.007 88);
  --ground-raised: oklch(99.6% 0.003 88);
  --ground-sunken: oklch(94.4% 0.009 88);
  --fg-default: oklch(21.5% 0.035 268);
  --fg-muted: oklch(42% 0.024 268);
  --fg-faint: oklch(54% 0.018 268);
  --line-hairline: oklch(89.8% 0.010 84);
  --line-default: oklch(83% 0.013 84);
  --line-strong: oklch(48% 0.02 268);
  --line-focus: oklch(58.5% 0.21 272);
  --tech-line: oklch(21.5% 0.035 268);
  --tech-label: oklch(44% 0.022 268);
  --tech-mark: oklch(58.5% 0.21 272);
  --selection-bg: oklch(90% 0.0482 272);
  --world-travail-voice: oklch(67% 0.205 36);
  --world-travail-line: oklch(58.5% 0.2003 36);
  --world-projets-voice: oklch(83.5% 0.17 96);
  --world-projets-line: oklch(58.5% 0.1203 96);
  --world-vision-voice: oklch(50% 0.2 272);
  --world-vision-line: oklch(58.5% 0.21 272);
  --world-outils-voice: oklch(58.5% 0.1246 164);
  --world-outils-line: oklch(58.5% 0.1246 164);
  --world-journal-voice: oklch(75.5% 0.133 322);
  --world-journal-line: oklch(58.5% 0.147 322);
  --world-vie-voice: oklch(75.5% 0.1895 344);
  --world-vie-line: oklch(58.5% 0.21 344);
  --motion-hover: 104ms;
  --ease-hover: cubic-bezier(0.2, 0, 0, 1);
  --motion-enter: 417ms;
  --ease-enter: cubic-bezier(0.2, 0, 0, 1);
  --motion-exit: 208ms;
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --motion-stagger: 208ms;
  --ease-stagger: cubic-bezier(0, 0, 1, 1);
  --motion-portal: 833ms;
  --ease-portal: cubic-bezier(0.2, 0, 0, 1);
  --motion-assemblage: 1667ms;
  --ease-assemblage: cubic-bezier(0.2, 0, 0, 1);
  --motion-snap: 417ms;
  --ease-snap: cubic-bezier(0.7, 0, 0.1, 1);
  --spring-arrive: linear(0, 0.0272, 0.0971, 0.1943, 0.3062, 0.423, 0.5374, 0.6441, 0.7397, 0.8223, 0.8913, 0.9469, 0.9898, 1.0215, 1.0433, 1.0568, 1.0637, 1.0654, 1.0632, 1.0584, 1.0519, 1.0445, 1.0369, 1.0294, 1.0225, 1.0164, 1.0111, 1.0067, 1.0031, 1.0004, 0.9984, 0.997, 0.9962, 0.9958, 0.9957, 0.9959, 0.9962, 0.9967, 0.9971, 0.9976, 1);
  --spring-arrive-ms: 680ms;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-32: 128px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground-default: oklch(19% 0.034 268);
    --ground-raised: oklch(25.5% 0.032 268);
    --ground-sunken: oklch(15% 0.03 268);
    --fg-default: oklch(97.2% 0.005 92);
    --fg-muted: oklch(83.5% 0.011 268);
    --fg-faint: oklch(58.5% 0.017 268);
    --line-hairline: oklch(33% 0.028 268);
    --line-default: oklch(41.5% 0.024 268);
    --line-strong: oklch(67% 0.015 268);
    --line-focus: oklch(75.5% 0.1252 272);
    --tech-line: oklch(97.2% 0.005 92);
    --tech-label: oklch(83.5% 0.011 268);
    --tech-mark: oklch(75.5% 0.1252 272);
    --selection-bg: oklch(41.5% 0.175 272);
    --world-travail-voice: oklch(67% 0.205 36);
    --world-travail-line: oklch(67% 0.205 36);
    --world-projets-voice: oklch(83.5% 0.17 96);
    --world-projets-line: oklch(83.5% 0.17 96);
    --world-vision-voice: oklch(67% 0.1744 272);
    --world-vision-line: oklch(67% 0.1744 272);
    --world-outils-voice: oklch(58.5% 0.1246 164);
    --world-outils-line: oklch(67% 0.1427 164);
    --world-journal-voice: oklch(75.5% 0.133 322);
    --world-journal-line: oklch(75.5% 0.133 322);
    --world-vie-voice: oklch(75.5% 0.1895 344);
    --world-vie-line: oklch(75.5% 0.1895 344);
  }
}
/* A theme the reader chose (Réglages, data-theme on <html>) wins over the device's. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] {
  color-scheme: dark;
  --ground-default: oklch(19% 0.034 268);
  --ground-raised: oklch(25.5% 0.032 268);
  --ground-sunken: oklch(15% 0.03 268);
  --fg-default: oklch(97.2% 0.005 92);
  --fg-muted: oklch(83.5% 0.011 268);
  --fg-faint: oklch(58.5% 0.017 268);
  --line-hairline: oklch(33% 0.028 268);
  --line-default: oklch(41.5% 0.024 268);
  --line-strong: oklch(67% 0.015 268);
  --line-focus: oklch(75.5% 0.1252 272);
  --tech-line: oklch(97.2% 0.005 92);
  --tech-label: oklch(83.5% 0.011 268);
  --tech-mark: oklch(75.5% 0.1252 272);
  --selection-bg: oklch(41.5% 0.175 272);
  --world-travail-voice: oklch(67% 0.205 36);
  --world-travail-line: oklch(67% 0.205 36);
  --world-projets-voice: oklch(83.5% 0.17 96);
  --world-projets-line: oklch(83.5% 0.17 96);
  --world-vision-voice: oklch(67% 0.1744 272);
  --world-vision-line: oklch(67% 0.1744 272);
  --world-outils-voice: oklch(58.5% 0.1246 164);
  --world-outils-line: oklch(67% 0.1427 164);
  --world-journal-voice: oklch(75.5% 0.133 322);
  --world-journal-line: oklch(75.5% 0.133 322);
  --world-vie-voice: oklch(75.5% 0.1895 344);
  --world-vie-line: oklch(75.5% 0.1895 344);
}

/* Composition 0.1.0 — fonts, self-hosted. Albert Sans, Jost, Martian Mono: SIL Open Font License 1.1 (assets/fonts/OFL-*.txt). */
@font-face { font-family: 'Albert Sans'; font-style: normal; font-weight: 300 700; font-display: swap; src: url("/fonts/albert-sans-latin-ext.78b26c5d5d.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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Albert Sans'; font-style: normal; font-weight: 300 700; font-display: swap; src: url("/fonts/albert-sans-latin.c2fb6fda41.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: 'Jost'; font-style: normal; font-weight: 300 700; font-display: swap; src: url("/fonts/jost-latin-ext.312ef2b80c.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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Jost'; font-style: normal; font-weight: 300 700; font-display: swap; src: url("/fonts/jost-latin.7726a5cd6f.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: 'Martian Mono'; font-style: normal; font-weight: 300 600; font-stretch: 75% 112.5%; font-display: swap; src: url("/fonts/martian-mono-latin-ext.21fce7e290.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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Martian Mono'; font-style: normal; font-weight: 300 600; font-stretch: 75% 112.5%; font-display: swap; src: url("/fonts/martian-mono-latin.f9c1655c2c.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; }

/* www.atecher.org — the arrival HUD. Zen instrument: hairlines, particle surfaces, one moving reticle.
   Colour carries meaning only: each path speaks in its tone, the instrument stays ink. */

@layer base, hud, motion;

@layer base {
  /* The paths' tones (his choice, 2026-10-30), each a voice and a line (the thin mark that must read on
     its own): a green a little brighter than the system's, a purple a little darker, the system's blue,
     and its gold for the experience still in preparation. Lighter at night. */
  /* On paper the lines carry text (a section's dates, a link's rule), so each is deep enough to read at
     4.5:1, and the gold voice deepens to an ochre that holds its own on cream (the system's yellow nearly
     vanished there). */
  :root {
    --tone-green: oklch(62% 0.16 158); --tone-green-line: oklch(49% 0.13 158);
    --tone-purple: oklch(55% 0.17 310); --tone-purple-line: oklch(48% 0.17 310);
    --tone-blue: var(--world-vision-voice); --tone-blue-line: oklch(50% 0.21 272);
    --tone-gold: oklch(74% 0.155 82); --tone-gold-line: oklch(52% 0.11 82);
  }
  /* The theme's material, beyond the system's roles.
     - `--sheet`: a card's or a window's ground. On paper a white sheet on the cream, at night a pane of
       the ground. A card lies flat on its hairline in both themes (no shadow: a cast shadow made the paper
       busier, and at night there was none to match).
     - `--construction`: how present the drawing behind the landing screens is. Behind a reading page it is
       gone on paper (`--construction-page`): its dark lines crossed the prose.
     - `--ink-gain`: how much the welcome scene strengthens its ink (bloch.js). The welcome screen stays as
       he left it (« don't modify welcome screen », 2026-10-31), so its value and the drawing's strength
       behind it (`--construction`) are kept, and the hidden centre point (`--construction-point`) spares it.
     - `--glyph-weight`, `--glyph-floor`: a glyph's particle size and least opacity. Small coloured dots on
       paper read as speckle; larger and firmer, drawn in the path's deeper line (`.glyph` below), they read
       as a form.
     - `--glow-lift`, `--glow-max`: how far a rising glyph lightens. At night it glows; on paper it would
       fade into the ground, so it lifts a little and stops well short of it.
     - `--locked`: how far the locked experience's name recedes on the welcome screen.
     - `--field`: a form field's ground. On paper a white sheet to write on, at night a step above the ground. */
  :root {
    --sheet: var(--ground-raised);
    --sheet-shadow: 0 1px 2px oklch(25% 0.03 268 / .06), 0 12px 28px -16px oklch(25% 0.03 268 / .22); /* floating layers only (a term's definition) */
    --construction: .62; --construction-page: 0; --construction-point: 0;
    --ink-gain: 1.45;
    --glyph-weight: 1.35; --glyph-floor: .7;
    --glow-lift: 9; --glow-max: 74;
    --locked: .6;
    --field: var(--ground-raised);
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) {
      --tone-green: oklch(74% 0.16 158); --tone-green-line: oklch(74% 0.16 158);
      --tone-purple: oklch(70% 0.15 310); --tone-purple-line: oklch(70% 0.15 310);
      --tone-blue-line: var(--world-vision-line);
      --tone-gold: var(--world-projets-voice); --tone-gold-line: var(--world-projets-line);
      --sheet: color-mix(in oklch, var(--ground-raised) 72%, transparent); --sheet-shadow: none;
      --construction: 1; --construction-page: .6; --construction-point: 1; --ink-gain: 1; --glyph-weight: 1; --glyph-floor: .45;
      --glow-lift: 20; --glow-max: 96; --locked: .45; --field: color-mix(in oklch, var(--ground-raised) 60%, var(--ground-default));
    }
    :root:not([data-theme='light']) .glyph { --glyph-ink: var(--path-color); }
  }
  :root[data-theme='dark'] {
    --tone-green: oklch(74% 0.16 158); --tone-green-line: oklch(74% 0.16 158);
    --tone-purple: oklch(70% 0.15 310); --tone-purple-line: oklch(70% 0.15 310);
    --tone-blue-line: var(--world-vision-line);
    --tone-gold: var(--world-projets-voice); --tone-gold-line: var(--world-projets-line);
    --sheet: color-mix(in oklch, var(--ground-raised) 72%, transparent); --sheet-shadow: none;
    --construction: 1; --construction-page: .6; --construction-point: 1; --ink-gain: 1; --glyph-weight: 1; --glyph-floor: .45;
    --glow-lift: 20; --glow-max: 96; --locked: .45; --field: color-mix(in oklch, var(--ground-raised) 60%, var(--ground-default));
  }
  :root[data-theme='dark'] .glyph { --glyph-ink: var(--path-color); }
  /* A glyph's ink is its path's line on paper (deep enough to hold as a form), its voice at night. Declared
     on the holder, where the path's tone is known. */
  .glyph { --glyph-ink: var(--path-line); }
  /* The wordmark's one colour is its point (system/STYLE.md §6). Unset, it is the house ultramarine
     (`mascot.body`, the vision world's line in either theme); on a path's page it takes that path's tone,
     its line on paper and its voice at night. The contact page and Présentation, in ink, keep the ultramarine. */
  /* Set on :root, not left to the wordmark's own fallback: the hover's line and particles read it too, and
     with it unset (the landing screens, the contact page) they would draw nothing. */
  :root { --mascot-body: var(--world-vision-line); --brand-point: var(--mascot-body); }
  .hud[data-path]:not([data-path='contact'], [data-path='presentation']) { --brand-point: var(--path-line); }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme='light']) .hud[data-path]:not([data-path='contact'], [data-path='presentation']) { --brand-point: var(--path-color); }
  }
  :root[data-theme='dark'] .hud[data-path]:not([data-path='contact'], [data-path='presentation']) { --brand-point: var(--path-color); }
  /* Two system icons as masks (externe, flèche droite), each with its one point. */
  :root {
    --icon-out: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75'%3E%3Cpath d='M9.2 14.8 18 6M10 6h8v8'/%3E%3Ccircle cx='6.6' cy='17.4' r='2' fill='%23000' stroke='none'/%3E%3C/svg%3E");
    --icon-next: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75'%3E%3Cpath d='M8.5 12H19M14 7l5 5-5 5'/%3E%3Ccircle cx='5' cy='12' r='2' fill='%23000' stroke='none'/%3E%3C/svg%3E");
  }
  /* The side a line starts drawing from and the side it withdraws to: the reading direction's. */
  :root { --start: left; --end: right; }
  :root[dir='rtl'] { --start: right; --end: left; }
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
  body {
    margin: 0;
    min-height: 100svh;
    background: var(--ground-default);
    color: var(--fg-default);
    font: 400 1rem/1.58 'Albert Sans', 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
  }
  ::selection { background: var(--selection-bg); }
  a { color: inherit; }
  :focus-visible { outline: 2px solid var(--line-focus); outline-offset: 3px; }
  abbr[title] { text-decoration: none; }
  kbd {
    display: inline-grid; place-items: center;
    min-width: 1.6em; height: 1.6em; padding: 0 .35em;
    border: 1px solid var(--line-default);
    font: 400 .6875rem/1 'Martian Mono', ui-monospace, monospace;
    color: var(--tech-label);
  }
}

@layer hud {
  .hud {
    --gutter: clamp(16px, 3.2vw, 44px);
    --corner: clamp(14px, 1.6vw, 22px);
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-height: 100svh;
    padding: calc(var(--gutter) + env(safe-area-inset-top)) calc(var(--gutter) + env(safe-area-inset-right))
      calc(var(--gutter) + env(safe-area-inset-bottom)) calc(var(--gutter) + env(safe-area-inset-left));
    position: relative;
    isolation: isolate;
    overflow-x: clip;
  }

  .hud-label {
    font: 400 .6875rem/1.5 'Martian Mono', ui-monospace, monospace;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tech-label);
  }

  .skip {
    position: absolute; inset-inline-start: var(--gutter); top: var(--gutter); z-index: 10;
    padding: 8px 12px; background: var(--ground-raised); border: 1px solid var(--line-strong);
  }
  .skip:not(:focus) { clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; white-space: nowrap; padding: 0; border: 0; }

  /* The frame: four corner brackets and the construction drawing behind everything. */
  .hud-frame { position: fixed; inset: 0; z-index: -1; pointer-events: none; }
  .hud-frame > i {
    position: absolute; width: var(--corner); height: var(--corner);
    border: 0 solid var(--tech-line); opacity: .55;
  }
  .hud-frame > i:nth-child(1) { top: 10px; left: 10px; border-width: 1.5px 0 0 1.5px; }
  .hud-frame > i:nth-child(2) { top: 10px; right: 10px; border-width: 1.5px 1.5px 0 0; }
  .hud-frame > i:nth-child(3) { bottom: 10px; right: 10px; border-width: 0 1.5px 1.5px 0; }
  .hud-frame > i:nth-child(4) { bottom: 10px; left: 10px; border-width: 0 0 1.5px 1.5px; }
  .hud-construction { position: absolute; inset: 0; width: 100%; height: 100%; }
  .hud-construction * { fill: none; stroke: var(--tech-mark); stroke-width: 1; vector-effect: non-scaling-stroke; }
  .c-orbit { opacity: calc(.16 * var(--construction)); }
  .c-orbit--inner { opacity: calc(.1 * var(--construction)); stroke-dasharray: 2 6; }
  .c-axis { opacity: calc(.14 * var(--construction)); stroke: var(--tech-line); }
  .c-point { fill: var(--fg-default); stroke: none; opacity: calc(.7 * var(--construction) * var(--construction-point)); }
  .hud--gate .c-point { opacity: calc(.7 * var(--construction)); }
  /* Behind a reading page the drawing would cross the prose: gone on paper, faint at night. */
  :is(.hud--page, .hud--stub) .hud-construction { opacity: var(--construction-page); }

  .hud-top, .hud-bottom {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
  }
  .hud-mark { display: inline-flex; padding: 6px 0; text-decoration: none; }
  .hud-mark svg { height: clamp(20px, 2vw, 26px); width: auto; display: block; overflow: visible; }
  /* The wordmark's hover (web/brand-hover.js): the line the point draws under the name (2 px at any size,
     like the header links'), the burst's particles near and far of the ink, and the particles that broke
     free, wandering the window. */
  .v-front line, .v-back line { stroke: var(--brand-point); stroke-linecap: round; }
  .v-back .v-line { stroke-width: 1px; vector-effect: non-scaling-stroke; } /* its gradient rides inline */
  .v-line-stop { stop-color: var(--brand-point); stop-opacity: 1; }
  .v-line-stop--far { stop-opacity: .22; }
  .v-wanderers { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 10; overflow: visible; }

  /* On a content page the header stays: wordmark, the paths, the language. It runs to the screen's
     edges over the ground, tightens once the page scrolls (hud.js `is-scrolled`) and draws a hairline. */
  :is(.hud--page, .hud--stub) {
    --top-pad: clamp(10px, 1.6vw, 20px);
    --sticky-h: calc(44px + 2 * var(--top-pad));
  }
  :is(.hud--page, .hud--stub) .hud-top {
    position: sticky; top: 0; z-index: 5;
    margin: calc(-1 * (var(--gutter) + env(safe-area-inset-top))) calc(-1 * var(--gutter)) 0;
    padding: calc(var(--top-pad) + env(safe-area-inset-top)) var(--gutter) var(--top-pad);
    background: color-mix(in oklch, var(--ground-default) 96%, transparent);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    transition: box-shadow var(--motion-enter) var(--ease-enter);
  }
  .is-scrolled .hud-top { box-shadow: 0 1px 0 var(--line-hairline); }
  /* The paths: names only. The current one is underlined in its colour; on hover a line draws in
     under the name from the left, in that path's colour, and on leaving it withdraws to the right. */
  .hud-paths { display: flex; gap: 4px; margin-inline: auto; }
  .hud-paths__link {
    position: relative; display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px;
    color: var(--fg-muted); text-decoration: none; font: 500 .9375rem/1 'Albert Sans', system-ui, sans-serif; white-space: nowrap;
    transition: color var(--motion-hover) var(--ease-hover);
  }
  .hud-paths__link::after {
    content: ''; position: absolute; left: 14px; right: 14px; bottom: 8px; height: 2px; background: var(--path-color);
    transform: scaleX(0); transform-origin: var(--end); transition: transform 280ms var(--ease-enter);
  }
  .hud-paths__link[aria-current] { color: var(--fg-default); }
  .hud-paths__link[aria-current]::after { height: 3px; transform: none; }
  @media (hover: hover) {
    .hud-paths__link:hover { color: var(--fg-default); }
    .hud-paths__link:hover::after { transform: scaleX(1); transform-origin: var(--start); }
  }
  /* Chosen from the keyboard (Tab, or ← → from hud.js), a link is marked as a hover marks it. */
  .hud-paths__link:focus-visible { outline: none; color: var(--fg-default); }
  .hud-paths__link:focus-visible::after { transform: scaleX(1); transform-origin: var(--start); }
  /* Écrire, the contact page: the same gesture in ink, beside the language, apart from the paths. */
  .hud-contact { margin-inline-start: auto; }
  .hud-paths + .hud-contact { margin-inline-start: 0; }
  /* A phone: the paths take their own row under the wordmark, Écrire and the language. */
  @media (max-width: 719px) {
    :is(.hud--page, .hud--stub) { --sticky-h: calc(44px + 40px + 2 * var(--top-pad)); }
    :is(.hud--page, .hud--stub) .hud-top { flex-wrap: wrap; row-gap: 0; }
    .hud-paths { order: 3; width: 100%; margin: 0 -10px; justify-content: space-between; gap: 0; }
    /* Four links share the row (Présentation and the three paths): tighter, and a name too long for its
       share clips rather than widening the page. */
    .hud-paths__link { min-width: 0; min-height: 40px; padding: 0 6px; font-size: .8125rem; overflow: hidden; text-overflow: ellipsis; }
    .hud-paths__link::after { left: 6px; right: 6px; bottom: 6px; }
    .hud-paths + .hud-contact { margin-inline-start: auto; }
    .hud-tool { min-width: 38px; padding: 0 8px; }
    /* Écrire runs long in some languages (« Escreva para mim »): the row tightens, the language tool
       keeps its globe alone, and the label clips rather than pushing the row past the screen. */
    .hud-top { gap: 8px; min-width: 0; }
    .hud-tool__code { display: none; }
    .hud-contact { min-width: 0; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; }
    .hud-contact::after { left: 6px; right: 6px; }
  }

  /* The header's tools: language (with its code), accessibility, settings, in one hairline box. */
  .hud-tools { display: flex; border: 1px solid var(--line-default); }
  .hud-tool {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-width: 42px; min-height: 40px; padding: 0 10px; margin: 0;
    border: 0; background: none; color: var(--fg-muted); cursor: pointer;
    font: 500 .75rem/1 'Martian Mono', ui-monospace, monospace; letter-spacing: .08em;
    transition: color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .hud-tool + .hud-tool { box-shadow: inset 1px 0 0 var(--line-hairline); }
  .hud-tool__icon { width: 20px; height: 20px; flex: none; }
  .hud-tool:hover, .hud-tool:focus-visible { color: var(--fg-default); background: var(--ground-raised); }
  .hud-tool:focus-visible { outline-offset: -2px; }
  /* A tool whose window is open stands inked. */
  body:has(#modal-lang:popover-open) .hud-tool--lang, body:has(#modal-a11y:popover-open) .hud-tool--a11y,
  body:has(#modal-settings:popover-open) .hud-tool--settings { color: var(--ground-default); background: var(--fg-default); }
  .hud-tool__code { color: inherit; }
  html:not(.js) :is(.hud-tool--a11y, .hud-tool--settings) { display: none; }

  /* The windows (popovers in the top layer): a raised sheet with the reticle's corners, its title and
     key, then its content. Escape or a click outside closes it. */
  .modal {
    position: fixed; inset: 0; margin: auto;
    width: min(500px, calc(100vw - 32px)); height: fit-content; max-height: calc(100svh - 32px); overflow: auto;
    padding: clamp(20px, 3vw, 30px); border: 1px solid var(--line-default);
    background: var(--ground-raised); color: var(--fg-default);
    box-shadow: 0 24px 64px -24px color-mix(in oklch, var(--fg-default) 30%, transparent);
  }
  .modal::backdrop { background: color-mix(in oklch, var(--ground-default) 62%, transparent); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
  .modal__corners { position: absolute; inset: 6px; pointer-events: none; }
  .modal__corners > i { position: absolute; width: 12px; height: 12px; border: 0 solid var(--tech-mark); }
  .modal__corners > i:nth-child(1) { top: 0; left: 0; border-width: 1.5px 0 0 1.5px; }
  .modal__corners > i:nth-child(2) { top: 0; right: 0; border-width: 1.5px 1.5px 0 0; }
  .modal__corners > i:nth-child(3) { bottom: 0; right: 0; border-width: 0 1.5px 1.5px 0; }
  .modal__corners > i:nth-child(4) { bottom: 0; left: 0; border-width: 0 0 1.5px 1.5px; }
  .modal__head { display: flex; align-items: center; gap: 12px; margin-bottom: 22px; }
  .modal__title { margin: 0; font: 450 clamp(1.5rem, 1.3rem + .8vw, 2rem)/1.1 'Jost', 'Futura', system-ui, sans-serif; letter-spacing: -.01em; }
  .modal__close {
    display: grid; place-items: center; width: 40px; height: 40px; margin: -8px -8px -8px auto; padding: 0;
    border: 0; background: none; color: var(--fg-muted); cursor: pointer;
  }
  .modal__close:hover { color: var(--fg-default); }
  .modal__close .hud-tool__icon { width: 18px; height: 18px; }
  .modal__note, .pref__hint { margin: 16px 0 0; color: var(--fg-muted); font-size: .875rem; line-height: 1.5; }

  /* Language: the ten most spoken, each in its own name; only the site's own two can be chosen. */
  .langs { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
  .langs__opt {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    min-height: 44px; padding: 0 14px; border: 1px solid var(--line-hairline);
    color: var(--fg-default); text-decoration: none; font-size: 1rem;
    transition: border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .langs__code { font: 400 .6875rem/1 'Martian Mono', ui-monospace, monospace; letter-spacing: .08em; color: var(--tech-label); }
  a.langs__opt:hover, a.langs__opt:focus-visible { border-color: var(--line-strong); background: var(--ground-default); }
  .langs__opt[aria-current] { border-color: var(--fg-default); box-shadow: inset 0 0 0 1px var(--fg-default); }
  .langs__opt[aria-current] .langs__code::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-inline-end: 8px; border-radius: 50%; background: var(--fg-default); vertical-align: .05em; }
  .langs__opt[aria-disabled] { opacity: .38; cursor: not-allowed; }

  /* Accessibility and settings: one row of choices per preference, the chosen one inked. */
  .prefs { display: grid; gap: 20px; }
  .pref { margin: 0; padding: 0; border: 0; min-width: 0; }
  .pref__name { margin: 0 0 10px; padding: 0; font: 400 .6875rem/1.5 'Martian Mono', ui-monospace, monospace; letter-spacing: .08em; text-transform: uppercase; color: var(--tech-label); }
  .pref__opts { display: flex; flex-wrap: wrap; gap: 6px; }
  .pref__opt { position: relative; }
  .pref__opt input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
  .pref__opt span {
    display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px;
    border: 1px solid var(--line-hairline); font-size: .9375rem;
    transition: border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .pref__opt:hover span { border-color: var(--line-strong); }
  .pref__opt input:checked + span { background: var(--fg-default); color: var(--ground-default); border-color: var(--fg-default); }
  .pref__opt input:focus-visible + span { outline: 2px solid var(--line-focus); outline-offset: 2px; }
  .prefs + .pref__name { margin-top: 26px; }
  .keys { display: grid; gap: 8px; margin: 0; }
  .keys > div { display: flex; align-items: center; gap: 14px; }
  .keys dt { display: flex; align-items: center; min-width: 9.5rem; }
  .keys dt kbd + kbd { margin-inline-start: -1px; }
  .keys dd { margin: 0; color: var(--fg-muted); font-size: .9375rem; }
  .modal__actions { margin: 24px 0 0; }

  .hud-main {
    align-self: center;
    width: min(100%, 1120px);
    margin: 0 auto;
    padding: clamp(32px, 7vh, 88px) 0;
  }
  .hud-kicker { margin: 0 0 18px; display: flex; align-items: center; gap: 12px; }
  .hud-kicker::before { content: ''; width: 28px; height: 1px; background: var(--tech-line); opacity: .6; }
  .hud-title {
    margin: 0;
    font: 450 clamp(2.5rem, 1.6rem + 4.2vw, 5.4rem)/.95 'Jost', 'Futura', 'Avenir Next', system-ui, sans-serif;
    letter-spacing: -.022em;
    text-wrap: balance;
  }
  .hud-role {
    margin: 20px 0 0; max-width: 36rem;
    font-size: clamp(1rem, .95rem + .25vw, 1.125rem);
    color: var(--fg-muted); text-wrap: pretty;
  }

  /* The four paths: a row on wide screens, two by two in between, a column on phones. */
  .paths { position: relative; margin-top: clamp(32px, 6vh, 64px); }
  .paths__list {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 18px);
  }
  /* The classical home: where to start, large and centred, the line under it, then the paths. */
  .hero { display: grid; justify-items: center; text-align: center; }
  .hero__title { font-size: clamp(2.8rem, 1.7rem + 5vw, 6.4rem); line-height: .95; letter-spacing: -.03em; }
  .hero__role { margin: clamp(18px, 2.4vh, 28px) auto 0; max-width: 38rem; }
  .hero__name { justify-content: center; }
  .hud--landing .paths { margin-top: clamp(40px, 7vh, 80px); }

  /* The welcome screen: the sentence, then the choice on one axis: the classical pole's name above the
     Bloch sphere (web/bloch.js), the quantum pole's below, dimmed and locked. */
  .gate { display: grid; justify-items: center; gap: clamp(14px, 2.4vh, 28px); text-align: center; }
  .gate__title { max-width: 22ch; font-size: clamp(2rem, 1.2rem + 2.8vw, 3.9rem); line-height: 1.04; }
  .gate__ask { display: block; margin-top: .35em; font-size: .52em; letter-spacing: -.01em; color: var(--fg-muted); }
  .gate__choice { display: grid; justify-items: center; gap: 0; }
  .gate__sphere { position: relative; width: min(34vh, 360px); aspect-ratio: 1; }
  /* The sphere and the floor under it (web/bloch.js): one canvas, the whole screen, behind the page; the
     holder places the sphere and takes the pointer. Without script or WebGL it shows a still point. The full
     experience stands on the floor at the foot of the screen, under the throat. */
  .gate__floor { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
  .js .hud--gate .gate__pole--quantum { position: fixed; left: 50%; bottom: max(clamp(12px, 4svh, 48px), env(safe-area-inset-bottom, 0px)); translate: -50% 0; width: max-content; max-width: calc(100vw - 32px); }
  :is(html:not(.js) .gate__sphere, .gate__sphere.is-still) { background: radial-gradient(circle, var(--fg-default) 0 3px, transparent 4px); }
  .gate__pole { display: grid; justify-items: center; gap: 4px; padding: 8px 18px; color: var(--fg-default); text-decoration: none; }
  .gate__name { position: relative; font: 450 clamp(1.6rem, 1.2rem + 1.2vw, 2.4rem)/1.2 'Jost', 'Futura', system-ui, sans-serif; letter-spacing: -.01em; }
  /* The two names lettered like their hemispheres (web/bloch.js): a canvas over the real text, which
     stays for screen readers and selection and turns transparent once the lettering is drawn. Without
     script the text simply shows. */
  .gate__word { position: absolute; inset: -.45em -.35em; width: calc(100% + .7em); height: calc(100% + .9em); pointer-events: none; }
  .gate__name.is-lettered { color: transparent; }
  /* The classical pole underlines as the header's links do: a line drawn in from the left. */
  .gate__pole--classical .gate__name::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px; background: var(--fg-default);
    transform: scaleX(0); transform-origin: var(--end); transition: transform 280ms var(--ease-enter);
  }
  .gate__pole--classical:focus-visible .gate__name::after { transform: scaleX(1); transform-origin: var(--start); }
  @media (hover: hover) { .gate__pole--classical:hover .gate__name::after { transform: scaleX(1); transform-origin: var(--start); } }
  /* Dimmed, not erased: the name recedes, and its status stays legible (it is the one thing to read here). */
  .gate__pole--quantum > .gate__name { opacity: var(--locked); }
  .gate__status { margin-top: 6px; padding: 3px 8px; border: 1px dashed var(--line-strong); }
  /* What the experience will need, said where it would not run well: a phone, a small or touch screen. */
  .gate__device { display: none; max-width: 32ch; margin: 10px 0 0; font-size: .875rem; line-height: 1.45; color: var(--fg-muted); text-wrap: balance; }
  @media (max-width: 1023px), (pointer: coarse) { .gate__device { display: block; } }
  @media (max-width: 760px) { .gate__sphere { width: min(78vw, 320px); } }
  .paths__item:nth-child(2) { --i: 1; }
  .paths__item:nth-child(3) { --i: 2; }
  .paths__item:nth-child(4) { --i: 3; }
  .path {
    position: relative;
    display: grid; grid-template-rows: auto 1fr; gap: 28px; align-content: start;
    height: 100%; min-height: 248px;
    padding: clamp(20px, 2vw, 28px);
    border: 1px solid var(--line-hairline);
    background: var(--sheet);
    text-decoration: none;
    transition: border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  /* The card under the pointer or the keys stays where it is (his remark, 2026-11-01: it used to lift a
     hair, which read as the card slipping); its hairline firms instead. */
  .path:focus-visible { outline-offset: 6px; }
  /* On the classical home the reticle is the focus mark: the arrows, A, D and Tab move its corners onto the
     card, so no outline doubles them. Where the reticle is hidden (touch screens), the outline stays. */
  @media (hover: hover) { .path:focus-visible { outline: none; } }
  .paths[data-active] .path.is-active { border-color: var(--line-default); }
  .path:active { border-color: var(--path-line); }
  @media (hover: hover) { .path:hover { border-color: var(--line-default); } }
  .path__glyph { display: block; width: clamp(96px, 8vw, 120px); aspect-ratio: 1; margin: -8px 0 0 -8px; }

  /* The glyph: a holder hud.js fills with its path's particle surface on a canvas (web/surfaces.js).
     Without script, a still point in the path's colour stands in. */
  .glyph { position: relative; display: block; width: 100%; height: 100%; }
  /* The canvas reaches a fifth past the holder on every side (hud.js ROOM), room for rising particles. */
  .glyph__canvas { position: absolute; inset: -20%; width: 140%; height: 140%; pointer-events: none; }
  html:not(.js) .glyph { background: radial-gradient(circle, var(--path-color) 0 18%, transparent 19%); }
  /* A touch screen has no hover to aim with: the reticle stays away. */
  @media (hover: none) { .reticle { display: none; } }
  /* A small marker is a particle in its section's colour. */
  .mark, .cv-section__title::before, .page-index a::before, .cv-essay__tag::before, .cv-cta__link::before, .cv-head__meta > * + *::before {
    border-radius: 50%;
  }

  .path__body { display: grid; align-content: start; gap: 6px; }
  .path__name {
    font: 450 clamp(1.5rem, 1.2rem + 1vw, 2.1rem)/1.12 'Jost', 'Futura', system-ui, sans-serif;
    letter-spacing: -.01em;
  }
  .path__text { color: var(--fg-muted); font-size: .9375rem; line-height: 1.5; max-width: 30ch; text-wrap: pretty; }

  /* The reticle locks onto the active path; its brackets take that path's voice. */
  .reticle {
    position: absolute; left: 0; top: 0; width: 0; height: 0;
    pointer-events: none;
    --rc: var(--tech-mark);
    transition: translate var(--motion-snap) var(--ease-snap), width var(--motion-snap) var(--ease-snap),
      height var(--motion-snap) var(--ease-snap), opacity var(--motion-hover) linear;
    opacity: 0;
  }
  .reticle.is-placed { opacity: 1; }
  /* Nothing is preselected for the reader: the reticle shows once they aim, with the pointer over the
     cards or a key (arrows, A, D, Tab move focus onto a card). */
  .paths:not(:hover, :focus-within) .reticle { opacity: 0; }
  .paths[data-active]:not(:hover, :focus-within) .path.is-active { border-color: var(--line-hairline); }
  .reticle.is-instant { transition: none; }
  .reticle > i { position: absolute; width: 16px; height: 16px; border: 0 solid var(--rc);
    transition: border-color var(--motion-enter) var(--ease-enter); }
  .reticle > i:nth-child(1) { top: -7px; left: -7px; border-width: 2px 0 0 2px; }
  .reticle > i:nth-child(2) { top: -7px; right: -7px; border-width: 2px 2px 0 0; }
  .reticle > i:nth-child(3) { bottom: -7px; right: -7px; border-width: 0 2px 2px 0; }
  .reticle > i:nth-child(4) { bottom: -7px; left: -7px; border-width: 0 0 2px 2px; }
  .paths[data-active='presentation'] .reticle { --rc: var(--tone-blue-line); }
  .paths[data-active='work'] .reticle { --rc: var(--tone-purple-line); }
  .paths[data-active='together'] .reticle { --rc: var(--tone-green-line); }

  .hud-bottom { flex-wrap: wrap; row-gap: 8px; }
  .hud-bottom { justify-content: flex-end; }
  .hud-keys { margin: 0; display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; }
  .hud-keys { font: 400 .75rem/1.5 'Martian Mono', ui-monospace, monospace; color: var(--fg-muted); }
  .hud-keys > span { display: inline-flex; align-items: center; gap: 4px; }
  html:not(.js) .hud-keys, html[data-keys='off'] .hud-keys { display: none; }
  .hud-keys kbd + kbd { margin-inline-start: -1px; }
  .hud-keys__or { margin: 0 3px; opacity: .6; }

  /* Stub pages: one form, its status, the way back. */
  .stub__glyph { display: block; width: clamp(72px, 9vw, 112px); aspect-ratio: 1; margin-bottom: 32px; }
  .stub__status {
    display: inline-block; margin: 24px 0 0; padding: 4px 10px;
    border: 1px solid var(--path-line); color: var(--fg-default);
  }
  .stub__actions { margin: 28px 0 0; }
  .hud--stub .hud-main { width: min(100%, 980px); }

  /* Path pages (Ingénierie, Enseignement, Réalisations): the path's form, its name, one lead. */
  .page { width: min(100%, 980px); align-self: start; }
  .page-head { padding-bottom: clamp(28px, 4vh, 44px); }
  .page-head__glyph { width: clamp(96px, 8vw, 120px); margin: 0 0 16px -10px; }
  .page-head__lead {
    margin: 22px 0 0; max-width: 62ch;
    font: 400 clamp(1.125rem, 1.05rem + .35vw, 1.35rem)/1.55 'Jost', 'Futura', system-ui, sans-serif; text-wrap: pretty;
  }
  /* A section whose title the page head already says keeps it for assistive technology only. */
  .cv-section--untitled > .cv-section__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .cv-section--untitled { padding-top: 0; border-top: 0; }
  /* A product's real screen tops its card. */
  .cv-essay__shot { display: block; width: calc(100% + 44px); max-width: none; height: auto; aspect-ratio: 16 / 9; object-fit: cover; object-position: top left; margin: -20px -22px 18px; border-bottom: 1px solid var(--line-hairline); }

  /* CV: one column of record under the HUD; section labels ride a left rail, dates a second one. */
  .cv-head { padding-bottom: clamp(32px, 5vh, 56px); border-bottom: 1px solid var(--line-hairline); }
  /* Présentation's head beside his portrait: the text in a column, the portrait standing at its side, its
     top on the name. A phone stacks it under the name. */
  .cv-head--portrait { display: grid; grid-template-columns: minmax(0, 1fr) clamp(200px, 22vw, 290px); column-gap: clamp(28px, 4vw, 64px); align-items: start; }
  .cv-head--portrait > * { grid-column: 1; }
  .cv-head--portrait > .cv-portrait { grid-column: 2; grid-row: 1 / span 20; }
  /* His portrait: painted, so nothing offers to save it, drag it or long-press it. At rest a little
     toward ink, held a touch close. Awake (hovered, or once in view on a touch screen: hud.js `is-on`;
     his choice of 2026-10-31) its colour comes back as it settles into its frame, as on a breath out, and
     a hairline frame in the path's tone draws itself round it from the top left corner. Nothing is drawn
     over the face. */
  .cv-portrait { position: relative; margin: 0; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
  /* The window clips and borders; the photo inside it settles by a GPU scale (animating background-size
     repainted it in whole pixels) and ends on neutral filter values, not `none` (dropping the filter at
     the end redrew it differently): both made it jump as it came to rest. */
  .cv-portrait__window { display: block; aspect-ratio: 4 / 5; overflow: hidden; border: 1px solid var(--line-hairline); background-color: var(--ground-raised); }
  .cv-portrait__photo {
    display: block; width: 100%; height: 100%;
    background-position: 50% 40%; background-size: 100%; background-repeat: no-repeat;
    scale: 1.015; filter: saturate(.78) contrast(.985); will-change: scale, filter;
    transition: filter 600ms var(--ease-enter), scale 900ms var(--ease-enter);
  }
  /* The frame: four hairline sides, all drawn at once, each from its corner clockwise (top from the left,
     right from the top, bottom from the right, left from the bottom; his ask of 2026-10-31); on leaving,
     they withdraw together. */
  .cv-portrait__frame { position: absolute; inset: -7px; pointer-events: none; }
  .cv-portrait__frame > i { position: absolute; background: var(--path-line); transition: scale 280ms var(--ease-enter); }
  .cv-portrait__frame > i:nth-child(1) { top: 0; left: 0; right: 0; height: 1px; transform-origin: left; scale: 0 1; }
  .cv-portrait__frame > i:nth-child(2) { top: 0; right: 0; bottom: 0; width: 1px; transform-origin: top; scale: 1 0; }
  .cv-portrait__frame > i:nth-child(3) { bottom: 0; left: 0; right: 0; height: 1px; transform-origin: right; scale: 0 1; }
  .cv-portrait__frame > i:nth-child(4) { top: 0; left: 0; bottom: 0; width: 1px; transform-origin: bottom; scale: 1 0; }
  .cv-portrait.is-on .cv-portrait__photo { filter: saturate(1) contrast(1); scale: 1; }
  .cv-portrait.is-on .cv-portrait__frame > i { scale: 1; transition-duration: 600ms; transition-delay: 60ms; }
  @media (hover: hover) {
    .cv-portrait:hover .cv-portrait__photo { filter: saturate(1) contrast(1); scale: 1; }
    .cv-portrait:hover .cv-portrait__frame > i { scale: 1; transition-duration: 600ms; transition-delay: 60ms; }
  }
  @media (max-width: 760px) {
    .cv-head--portrait { grid-template-columns: minmax(0, 1fr); }
    .cv-head--portrait > .cv-portrait { grid-column: 1; grid-row: auto; width: min(240px, 64vw); margin: 22px 0 6px; }
  }
  .cv-head__glyph { width: clamp(96px, 8vw, 120px); margin: 0 0 16px -10px; }
  .cv-head__name { font-size: clamp(2.4rem, 1.7rem + 3.2vw, 4.4rem); }
  .cv-head__role {
    margin: 18px 0 0; max-width: 34ch;
    font: 450 clamp(1.25rem, 1.1rem + .6vw, 1.6rem)/1.25 'Jost', 'Futura', system-ui, sans-serif;
  }
  .cv-head__motto { margin-top: 12px; max-width: 34ch; color: var(--fg-default); font-size: clamp(1.0625rem, .95rem + .45vw, 1.25rem); line-height: 1.45; text-wrap: balance; }
  .cv-head__meta { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 22px 0 0; }
  .cv-head__email {
    text-transform: none; letter-spacing: .02em; color: var(--fg-default); text-decoration: none;
    background: linear-gradient(var(--path-line), var(--path-line)) 0 100% / 100% 1px no-repeat;
  }
  .cv-head__email:hover { background-size: 100% 2px; }
  .cv-head__meta > * + *::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-inline-end: 20px; background: var(--path-color); vertical-align: .05em; }
  /* The record's address is for paper only. */
  .cv-record__url { display: none; }
  .cv-actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 28px 0 0; }
  .cv-record__summary { margin: 18px 0 0; max-width: 64ch; font-size: 1.0625rem; line-height: 1.6; text-wrap: pretty; }

  .cv-section {
    display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: 0 32px;
    padding: clamp(28px, 4vh, 40px) 0; border-bottom: 1px solid var(--line-hairline);
  }
  .cv-section__title { align-self: start; margin: 4px 0 16px; display: flex; align-items: center; gap: 10px; color: var(--fg-default); }
  .cv-section__title::before { content: ''; width: 10px; height: 10px; background: var(--sec-voice, var(--fg-default)); flex: none; }
  /* A section in a world colour carries it on its marker, its rules, its lead and its dates. */
  .cv-section[style] { border-top: 2px solid var(--sec); margin-top: -1px; }
  .cv-section[style] .cv-entry__when { color: var(--sec); }
  .cv-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 26px; }
  .cv-entry { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: 0 24px; break-inside: avoid; }
  .cv-entry__when { margin: 3px 0 0; font: 400 .75rem/1.5 'Martian Mono', ui-monospace, monospace; color: var(--tech-label); font-variant-numeric: tabular-nums; }
  .cv-entry__role { margin: 0; font: 500 1.125rem/1.3 'Jost', 'Futura', system-ui, sans-serif; letter-spacing: -.005em; }
  .cv-entry__org { margin: 2px 0 0; font-size: .9375rem; color: var(--fg-muted); }
  .cv-entry__text { margin: 8px 0 0; max-width: 62ch; font-size: .9375rem; line-height: 1.55; text-wrap: pretty; }
  .cv-head__summary { margin: 22px 0 0; max-width: 64ch; display: grid; gap: 12px; }
  .cv-head__summary p { margin: 0; font-size: 1.0625rem; line-height: 1.65; text-wrap: pretty; }
  .cv-entry__text + .cv-entry__text { margin-top: 6px; }

  /* Essays: interests and expertise, a heading and a paragraph each, set for reading. */
  .cv-essays { display: grid; gap: 26px 40px; }
  .cv-essays--axes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cv-essays--axes .cv-essay:first-child { grid-column: 1 / -1; max-width: 72ch; }
  .cv-essays--grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cv-essay { break-inside: avoid; }
  .cv-essay--wide { grid-column: 1 / -1; max-width: 80ch; }
  .cv-essay__text + .cv-essay__text { margin-top: 12px; }
  .cv-essay__name { margin: 0; font: 500 1.125rem/1.3 'Jost', 'Futura', system-ui, sans-serif; letter-spacing: -.005em; }
  .cv-essay__name::after { content: ''; display: block; width: 24px; height: 1.5px; margin-top: 10px; background: var(--sec, var(--path-line)); }
  /* Ragged right, no hyphenation: a broken word costs a dyslexic reader (and a phone reader) more than
     an uneven edge. */
  .cv-essay__text { margin: 10px 0 0; font-size: .96875rem; line-height: 1.65; text-wrap: pretty; }
  .cv-prose { margin: 0; max-width: 72ch; font-size: .96875rem; line-height: 1.65; text-wrap: pretty; }
  .cv-prose + .cv-prose { margin-top: 14px; }
  .cv-section--direction > .cv-section__body > .cv-prose { max-width: 76ch; font-size: 1.03125rem; }

  /* The two directions are the CV's pillars: a full-width heading, a lead in display type, essays. */
  .cv-section--direction { grid-template-columns: 1fr; padding-top: clamp(40px, 6vh, 64px); }
  .cv-section--direction > .cv-section__title {
    margin: 0 0 18px; font: 450 clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem)/1.1 'Jost', 'Futura', system-ui, sans-serif;
    letter-spacing: -.015em; text-transform: none; gap: 14px;
  }
  .cv-section--direction > .cv-section__title::before { width: 18px; height: 18px; }
  .cv-lead {
    margin: 0 0 32px; max-width: 64ch; padding-inline-start: 18px; border-inline-start: 3px solid var(--sec, var(--line-strong));
    font: 400 clamp(1.125rem, 1.05rem + .3vw, 1.3rem)/1.55 'Jost', 'Futura', system-ui, sans-serif; text-wrap: pretty;
  }
  .cv-lead--small { margin-bottom: 26px; font-size: 1.0625rem; }
  .cv-section--direction .cv-essays--grid { gap: 30px 44px; }

  /* Reading pages (Présentation, Ingénierie, Enseignement, Réalisations) share one grid (his remark, 2026-10-31:
     « layout is hard to make sense of »). The printable record keeps its rails.
     - Every section opens the same way: a rule, its marker and its title in the display face. The
       crafts are titled largest, the others a step below; no section speaks in small capitals.
     - All prose runs in one size at one measure (`--measure`), headings step down clearly (no stub
       under them), and essays stack in one column (side-by-side pairs left gaps beside short blocks).
     - Product cards keep their grid. Two passages that carry a section (the families one, the mission
       told end to end) take the lead's treatment. */
  :is(.hud--presentation, .hud--work, .hud--together) { --measure: 38rem; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section { padding: clamp(48px, 7vh, 72px) 0 clamp(36px, 5vh, 52px); border-bottom: 0; border-top: 1px solid var(--line-hairline); }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section[style] { border-top: 2px solid var(--sec); }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section:not(.cv-section--direction) { grid-template-columns: minmax(0, 1fr); }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section:not(.cv-section--direction) > .cv-section__title {
    margin: 0 0 22px; gap: 12px; text-transform: none; letter-spacing: -.01em;
    font: 450 1.625rem/1.15 'Jost', 'Futura', system-ui, sans-serif;
  }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section:not(.cv-section--direction) > .cv-section__title::before { width: 12px; height: 12px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-section--direction > .cv-section__title { margin-bottom: 22px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-lead { max-width: 44rem; margin-bottom: 44px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essays--grid:not(:has(.cv-essay--tagged)) { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay:not(.cv-essay--tagged) { max-width: var(--measure); }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay__name { font-size: 1.375rem; line-height: 1.25; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay--tagged .cv-essay__name { font-size: 1.25rem; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay__name::after { display: none; }
  :is(.hud--presentation, .hud--work, .hud--together) :is(.cv-essay__text, .cv-prose, .cv-entry__text, .cv-coda) { max-width: var(--measure); font-size: 1.0625rem; line-height: 1.68; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay--tagged .cv-essay__text { font-size: 1rem; line-height: 1.62; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay__text { margin-top: 12px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-entry__text { margin-top: 10px; }
  :is(.hud--presentation, .hud--work, .hud--together) .cv-essay__figure { max-width: var(--measure); margin-bottom: 18px; }
  :is(#cv-ped-families, #cv-offer-case) { max-width: calc(var(--measure) + 24px); padding-inline-start: 21px; border-inline-start: 3px solid var(--sec); }
  :is(#cv-ped-families, #cv-offer-case) .cv-essay__text { font: 400 1.1875rem/1.6 'Jost', 'Futura', system-ui, sans-serif; }
  /* An anchor lands below the sticky header (and Présentation's index row, `--index-h`). */
  .cv-section, .cv-essay { scroll-margin-top: calc(var(--sticky-h, 0px) + var(--index-h, 0px) + 20px); }
  .cv-essay:target { outline: 2px solid var(--sec-voice, var(--line-focus)); outline-offset: 10px; }

  /* Présentation's index (src/pages.mjs pageIndex): each section in its world's form; hud.js marks the
     one in view (`aria-current`). Narrow: a row of chips that sticks under the header. */
  .cv-section__title { scroll-margin-top: calc(var(--sticky-h, 0px) + var(--index-h, 0px) + 20px); }
  .page-index ol { list-style: none; margin: 0; padding: 0; }
  .page-index a {
    display: flex; align-items: center; gap: 10px; color: var(--fg-muted); text-decoration: none;
    font: 500 .875rem/1.3 'Albert Sans', system-ui, sans-serif;
    transition: color var(--motion-hover) var(--ease-hover), border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .page-index a::before { content: ''; width: 9px; height: 9px; flex: none; background: var(--sec-voice, var(--fg-default)); opacity: .5; transition: opacity var(--motion-hover) var(--ease-hover); }
  .page-index a[aria-current] { color: var(--fg-default); }
  .page-index a[aria-current]::before { opacity: 1; }
  @media (hover: hover) { .page-index a:hover { color: var(--fg-default); } }
  @media (max-width: 1359px) {
    :is(.hud--presentation, .hud--work, .hud--together) { --index-h: 52px; }
    .page-index {
      position: sticky; top: var(--sticky-h); z-index: 4;
      margin: 0 calc(-1 * var(--gutter)); padding: 8px var(--gutter);
      background: color-mix(in oklch, var(--ground-default) 96%, transparent);
      -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
      box-shadow: 0 1px 0 var(--line-hairline);
    }
    /* `contain: inline-size` keeps the row's width out of the page's: it scrolls instead of widening it. */
    .page-index ol { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; contain: inline-size; }
    .page-index ol::-webkit-scrollbar { display: none; }
    .page-index a { white-space: nowrap; min-height: 36px; padding: 0 12px; border: 1px solid var(--line-hairline); }
    .page-index a[aria-current] { border-color: var(--sec-voice, var(--line-strong)); background: var(--ground-raised); }
  }
  /* Wide: a rail in the left margin, outside the page, so the page's left edge is the site's one edge; a
     hairline with the current section barred, held in view as the page scrolls. */
  @media (min-width: 1360px) {
    :is(.hud--presentation, .hud--work, .hud--together) .page { position: relative; }
    :is(.hud--presentation, .hud--work, .hud--together) .page > .page-index {
      position: absolute; top: 0; bottom: 0; inset-inline-end: calc(100% + clamp(24px, 2.4vw, 44px));
      width: clamp(120px, calc((100vw - 980px) / 2 - 80px), 200px);
    }
    .page-index ol { position: sticky; top: calc(var(--sticky-h) + 40px); border-inline-start: 1px solid var(--line-hairline); }
    .page-index a { position: relative; padding-block: 7px; padding-inline: 14px 0; font-size: .8125rem; }
    .page-index a[aria-current]::after { content: ''; position: absolute; inset-inline-start: -1px; top: 6px; bottom: 6px; width: 2px; background: var(--sec-voice, var(--fg-default)); }
  }
  /* Leaving the site: the system's « externe » icon; going further on it: « flèche droite ». */
  .cv-essay__link a::after {
    content: ''; display: inline-block; flex: none; width: 1em; height: 1em; margin-inline-start: .3em; vertical-align: -.12em;
    background: currentColor; -webkit-mask: var(--icon-out) center / contain no-repeat; mask: var(--icon-out) center / contain no-repeat;
    transition: translate var(--motion-hover) var(--ease-hover);
  }
  .cv-essay__link a:hover::after { translate: 2px -2px; }
  /* A screen inside a running essay: framed, at reading width. */
  .cv-essay__figure { display: block; width: 100%; max-width: 640px; height: auto; aspect-ratio: 16 / 9; object-fit: cover; object-position: top left; margin: 0 0 14px; border: 1px solid var(--line-default); }
  .cv-essay__link { margin: 14px 0 0; display: flex; flex-wrap: wrap; gap: 8px 22px; }
  .cv-essay__link a {
    font: 500 .9375rem/1.3 'Albert Sans', system-ui, sans-serif; color: var(--fg-default); text-decoration: none;
    background: linear-gradient(var(--sec-voice), var(--sec-voice)) 0 100% / 100% 1px no-repeat; padding-bottom: 2px;
  }
  .cv-coda { margin: 28px 0 0; max-width: 64ch; font-size: 1rem; line-height: 1.6; text-wrap: pretty; }

  /* Products: a tagged essay is a card, its audience and status read first. */
  .cv-essays--grid .cv-essay--tagged { display: flex; flex-direction: column; padding: 20px 22px 22px; background: var(--ground-raised); border: 1px solid var(--line-hairline); border-top: 2px solid var(--sec); }
  .cv-essays--grid:has(.cv-essay--tagged) { align-items: start; }
  /* A world is named by its form and neutral text, never by text in its warm voice (STYLE.md). */
  .cv-essay__tag { margin: 0 0 10px; display: flex; align-items: baseline; gap: 8px; color: var(--fg-muted); }
  .cv-essay__tag.hud-label { font: 500 .8125rem/1.4 'Albert Sans', system-ui, sans-serif; letter-spacing: 0; text-transform: none; }
  .cv-essay__tag::before { content: ''; width: 9px; height: 9px; align-self: center; background: var(--sec-voice); flex: none; }
  .cv-section--direction .cv-essays--grid:has(.cv-essay--tagged) { gap: 16px; }
  /* Three essays (the offer) stand side by side instead of leaving a hole in a pair grid. */
  .cv-essays--grid:has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Every action that stays on the site has one form and one hover (his remark, 2026-10-30: a solid slab
     beside an outline beside an underline read as three kinds of thing, and the slab turned white at
     night). Ink on a hairline, never a world's warm voice as a fill (STYLE.md: no vermilion buttons): the
     section's colour rides on the particle before the label, and on hover it takes the border and a faint
     wash while the arrow reaches further. Links that leave the site stay text, with their « externe ». */
  .cv-cta { margin: 32px 0 0; display: flex; flex-wrap: wrap; gap: 12px; }
  .cv-cta__link {
    --cta: var(--sec-voice, var(--path-color)); --cta-line: var(--sec, var(--path-line));
    display: inline-flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 20px; margin: 0;
    border: 1px solid var(--line-strong); background: transparent; color: var(--fg-default); text-decoration: none;
    font: 500 1rem/1 'Albert Sans', system-ui, sans-serif; cursor: pointer;
    transition: border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .cv-cta__link::before { content: ''; width: 10px; height: 10px; background: var(--cta); flex: none; }
  .cv-cta__link::after { content: ''; width: 16px; height: 1.5px; background: currentColor; transition: width var(--motion-hover) var(--ease-hover); }
  .cv-cta__link:is(:hover, :focus-visible) { border-color: var(--cta-line); background: color-mix(in oklch, var(--cta) 9%, transparent); }
  .cv-cta__link:is(:hover, :focus-visible)::after { width: 24px; }
  .cv-cta__link:disabled { opacity: .6; cursor: progress; }
  .cv-cta__link[hidden] { display: none; }
  .cv-cta--essay { margin: 16px 0 0; }

  /* Contact: the kind of request is chosen first, and only its own fields show (CSS :has, no script). */
  .contact { display: grid; gap: 22px; max-width: 760px; }
  .contact fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
  .contact__kinds { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  @media (max-width: 760px) { .contact__kinds { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .contact__kinds legend { margin-bottom: 12px; }
  /* « Vous êtes » is the contact page's first question, so it reads as one, not as a label. */
  .hud--contact .contact__kinds legend {
    margin-bottom: 16px; padding: 0; color: var(--fg-default); text-transform: none; letter-spacing: -.01em;
    font: 450 clamp(1.4rem, 1.2rem + .8vw, 1.9rem)/1.15 'Jost', 'Futura', system-ui, sans-serif;
  }
  .hud--contact .cv-section--contact { padding-top: 0; border-bottom: 0; }
  /* His profiles: outward links in the page's ink, at the foot of the contact page and under the CV's
     head (where print shows their addresses). */
  .socials__links { --sec-voice: var(--path-color); }
  .socials { margin: 8px 0 clamp(40px, 6vw, 72px); padding-top: 24px; border-top: 1px solid var(--line-hairline); }
  .socials__label { margin: 0; }
  .cv-head__socials { margin-top: 14px; }
  .contact__kind { position: relative; }
  .contact__kind input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
  .contact__kind span {
    display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 14px;
    border: 1px solid var(--line-default); font: 500 .9375rem/1.25 'Albert Sans', system-ui, sans-serif;
    transition: border-color var(--motion-hover) var(--ease-hover), background-color var(--motion-hover) var(--ease-hover);
  }
  .contact__kind span::before { content: ''; width: 10px; height: 10px; border: 1.5px solid var(--line-strong); border-radius: 50%; flex: none; }
  .contact__kind:hover span { border-color: var(--line-strong); }
  .contact__kind input:checked + span { border-color: var(--path-color); background: var(--ground-raised); }
  .contact__kind input:checked + span::before { background: var(--path-color); border-color: var(--path-color); }
  .contact__kind input:focus-visible + span { outline: 2px solid var(--line-focus); outline-offset: 3px; }
  .contact__group { display: none; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .contact__group .contact__hint, .contact__group .contact__checks { grid-column: 1 / -1; }
  .contact:has(input[name='kind'][value='parent']:checked) .contact__group[data-kind='parent'],
  .contact:has(input[name='kind'][value='student']:checked) .contact__group[data-kind='student'],
  .contact:has(input[name='kind'][value='researcher']:checked) .contact__group[data-kind='researcher'],
  .contact:has(input[name='kind'][value='mission']:checked) .contact__group[data-kind='mission'],
  .contact:has(input[name='kind'][value='coaching']:checked) .contact__group[data-kind='coaching'],
  .contact:has(input[name='kind'][value='partner']:checked) .contact__group[data-kind='partner'],
  .contact:has(input[name='kind'][value='other']:checked) .contact__group[data-kind='other'] { display: grid; }
  @supports not selector(:has(*)) { .contact__group { display: grid; } }
  .contact__hint { margin: 0; max-width: 64ch; color: var(--fg-muted); font-size: .9375rem; line-height: 1.55; text-wrap: pretty; }
  .contact__common { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .contact__field { display: grid; gap: 6px; min-width: 0; }
  .contact__field--wide { grid-column: 1 / -1; }
  .contact__label, .contact__checks legend { font: 500 .875rem/1.3 'Albert Sans', system-ui, sans-serif; color: var(--fg-default); }
  .contact :is(input[type='text'], input[type='email'], select, textarea) {
    width: 100%; min-height: 44px; padding: 10px 12px; border: 1px solid var(--line-default); border-radius: 0;
    background: var(--field); color: var(--fg-default); font: 400 1rem/1.4 'Albert Sans', system-ui, sans-serif;
    transition: border-color var(--motion-hover) var(--ease-hover);
  }
  .contact textarea { resize: vertical; min-height: 9rem; }
  .contact :is(input, select, textarea):hover { border-color: var(--line-strong); }
  .contact :is(input, select, textarea):focus-visible { outline: 2px solid var(--line-focus); outline-offset: 1px; border-color: var(--line-strong); }
  .contact__checks { display: flex; flex-wrap: wrap; gap: 8px 18px; }
  .contact__checks legend { margin-bottom: 8px; }
  .contact__check { display: inline-flex; align-items: center; gap: 8px; min-height: 32px; font-size: .9375rem; cursor: pointer; }
  .contact__check input { width: 16px; height: 16px; margin: 0; accent-color: var(--path-color); }
  /* Out of sight without leaving the page's box (pushed off to one side, it would widen a page read
     right to left). */
  .contact__trap { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .contact__privacy { margin: 0; max-width: 64ch; font-size: .8125rem; line-height: 1.5; color: var(--fg-muted); }
  .contact__actions { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; }
  .contact__status { font-size: .9375rem; }
  .contact__status[data-state='sent'] { color: var(--fg-default); }
  .contact__status[data-state='error'] { color: var(--fg-default); font-weight: 500; }
  .contact.is-sent :is(.contact__kinds, .contact__group, .contact__common, .contact__privacy, button) { display: none; }
  .contact.is-sent .contact__status { font: 400 1.125rem/1.5 'Jost', 'Futura', system-ui, sans-serif; }

  .hud--page .hud-main { padding-bottom: 48px; }

  .portal { position: fixed; inset: 0; z-index: 20; pointer-events: none; background: var(--portal-color, transparent); visibility: hidden; }
  /* Open while leaving, and on arrival until hud.js closes it into the page's glyph. */
  .portal.is-open, [data-portal-in] .portal { visibility: visible; }

  @media (max-width: 760px) {
    .paths__list { grid-template-columns: 1fr; gap: 10px; }
    .path { min-height: 0; grid-template-rows: none; grid-template-columns: auto 1fr; align-items: center; gap: 18px; padding: 16px 18px; }
    .path__glyph { width: 68px; margin: -6px 0; }
    .path__body { align-content: center; gap: 2px; }
    .path__name { font-size: 1.375rem; }
    .path__text { font-size: .875rem; }
    .hud-keys { display: none; }
    .hud-frame > i { opacity: .4; }
    .hud-main { padding: 28px 0; }
    .cv-section { grid-template-columns: 1fr; }
    .cv-entry { grid-template-columns: 1fr; }
    .cv-entry__when { margin: 0 0 2px; }
    .cv-essays--axes, .cv-essays--grid, .cv-essays--grid:has(> :nth-child(3):last-child) { grid-template-columns: 1fr; }
    .contact__group, .contact__common { grid-template-columns: 1fr; }
  }
  @media (hover: none) { .hud-keys { display: none; } }

  /* The two landing screens hold in one screen, never scrolled (his rule, 2026-10-30): their sizes
     follow the screen's height (svh), and on a short phone the cards drop their line of description. */
  :is(.hud--gate, .hud--landing) .hud-main { padding-block: clamp(6px, 2.4svh, 32px); }
  .hud--gate .gate { gap: clamp(8px, 2svh, 26px); }
  .hud--gate .gate__title { font-size: clamp(1.6rem, 1rem + 3.4svh, 3.9rem); }
  .hud--gate .gate__sphere { width: min(30svh, 360px); }
  .hud--gate .gate__pole { padding-block: clamp(2px, .8svh, 8px); }
  .hud--gate .gate__name { font-size: clamp(1.4rem, .7rem + 2.4svh, 2.4rem); }
  .hud--landing .hero__title { font-size: clamp(2rem, .8rem + 5.6svh, 5.6rem); }
  .hud--landing .hero__role { margin-top: clamp(6px, 1.6svh, 22px); }
  .hud--landing .paths { margin-top: clamp(14px, 4svh, 64px); }
  .hud--landing .path { min-height: clamp(150px, 27svh, 248px); gap: clamp(10px, 2.4svh, 28px); padding: clamp(14px, 2.4svh, 28px); }
  .hud--landing .path__glyph { width: clamp(60px, 11svh, 120px); }
  @media (max-width: 760px) {
    .hud--gate .gate__title { font-size: clamp(1.5rem, .6rem + 3.2svh, 2.4rem); }
    .hud--gate .gate__sphere { width: min(78vw, 34svh); }
    .hud--gate .gate__device { margin-top: 6px; font-size: .8125rem; }
    .hud--landing .hero__title { font-size: clamp(1.7rem, .5rem + 4svh, 2.6rem); }
    .hud--landing .hero__role { font-size: .9375rem; line-height: 1.45; }
    .hud--landing .path { min-height: 0; padding: clamp(8px, 1.4svh, 16px) 14px; gap: 14px; }
    .hud--landing .path__glyph { width: clamp(44px, 7svh, 64px); margin: 0; }
    .hud--landing .path__name { font-size: 1.2rem; }
    .hud--landing .path__text { font-size: .8125rem; line-height: 1.4; }
    .hud--landing .paths__list { gap: 8px; }
  }
  @media (max-width: 760px) and (max-height: 760px) {
    .hud--landing .path__text { display: none; }
    /* A short phone gives the sentence the room: longer languages (Russian) wrap less. */
    .hud--gate .gate__title { max-width: none; font-size: clamp(1.4rem, .5rem + 3svh, 2.2rem); }
    .hud--gate .gate__sphere { width: min(78vw, 28svh); }
  }

  /* Print: the record alone, ink on paper, on A4. */
  @media print {
    @page { size: A4; margin: 12mm 15mm; }
    /* Paper's ink is set at the end of this file, outside the layers (see there). */
    body { background: #fff; font-size: 9.5pt; }
    .hud { display: block; min-height: 0; padding: 0; }
    .hud-frame, .hud-top, .hud-bottom, .cv-actions, .page-index, .cv-cta, .cv-essay__link, .cv-section--contact, .cv-head__email, .page-head__glyph, .cv-essay__shot, .skip, .portal, .cv-head__glyph, .hud-kicker { display: none !important; }
    /* His profiles stay on paper, as their addresses. */
    .cv-essay__link.cv-head__socials { display: flex !important; margin-top: 4pt; gap: 2pt 14pt; }
    .cv-head__socials a { font-size: 8.5pt; background: none; padding: 0; }
    .cv-head__socials a::after { display: none; }
    .cv-coda { display: none; }
    /* The short closing sections (volunteering, career, languages) carry their title as a run-in label. */
    .cv-section:has(> .cv-section__body > .cv-prose:first-child) > .cv-section__title { float: left; margin: 1.5pt 8pt 0 0; }
    .cv-essays--grid .cv-essay--tagged { padding: 0; background: none; border: 0; }
    .cv-essay__tag { margin: 0 0 1pt; font-size: 7pt; color: var(--fg-muted); }
    .hud-main, .page, .hud--page .hud-main { width: auto; padding: 0; }
    .cv-head { padding-bottom: 10pt; }
    .cv-head__name { font-size: 24pt; }
    .cv-head__role { margin-top: 6pt; font-size: 13pt; max-width: none; }
    .cv-head__motto { margin-top: 2pt; font-size: 10pt; }
    .cv-head__meta { margin-top: 8pt; }
    .cv-record__url { display: inline; }
    /* Block flow, not a one-column grid: Chromium then breaks pages between essays, not before a section. */
    .cv-section { display: block; padding: 5pt 0; }
    .cv-section__title { margin: 0 0 5pt; font-size: 7.5pt; break-after: avoid; }
    /* The education list runs in two columns on paper, like the essays, to hold four pages. */
    .cv-list { display: block; columns: 2; column-gap: 7mm; }
    .cv-entry { grid-template-columns: 20mm 1fr; gap: 0 2.5mm; margin-bottom: 4pt; }
    .cv-entry__when { margin-top: 1pt; font-size: 7.5pt; white-space: nowrap; }
    .cv-entry__role { font-size: 9.5pt; }
    .cv-entry__org { font-size: 8.5pt; }
    .cv-entry__text, .cv-essay__text, .cv-prose { margin-top: 2pt; max-width: none; font-size: 8.4pt; line-height: 1.33; }
    .cv-prose + .cv-prose { margin-top: 4pt; }
    .cv-lead { padding-inline-start: 6pt; border-inline-start-width: 2pt; }
    .cv-section[style], .cv-section[style] .cv-lead { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
    .cv-head__summary { margin-top: 6pt; max-width: none; gap: 4pt; }
    .cv-head__summary p { font-size: 9.25pt; line-height: 1.45; }
    .cv-essays { gap: 7pt 7mm; }
    .cv-essays--axes .cv-essay:first-child { max-width: none; }
    .cv-essay__name { font-size: 10pt; }
    .cv-essay__name::after { display: none; }
    .cv-section--direction { padding-top: 10pt; }
    .cv-section--direction > .cv-section__title { margin-bottom: 5pt; font-size: 15pt; }
    .cv-section--direction > .cv-section__title::before { width: 8pt; height: 8pt; }
    .cv-lead { margin-bottom: 7pt; max-width: none; font-size: 9.5pt; line-height: 1.4; }
    .cv-lead--small { margin-bottom: 5pt; font-size: 8.4pt; line-height: 1.36; }
    /* Columns, not a grid, on paper: Chromium moves a whole essay grid (or a column set with full-width
       spanners) to the next page rather than splitting it, which left half-empty pages. So every
       essay flows in the two columns, and only short ones refuse to split. */
    .cv-section--direction .cv-essays--grid, .cv-essays--grid:has(> :nth-child(3):last-child) { display: block; columns: 2; column-gap: 7mm; }
    .cv-essays--grid .cv-essay { margin-bottom: 5pt; }
    .cv-essays--grid .cv-essay--wide { max-width: none; break-inside: auto; }
    .cv-essays--grid:has(> :nth-child(3):last-child) { columns: 3; column-gap: 6mm; }
    .cv-section__title::before, .cv-head__meta > * + *::before { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  }
}

/* Arrival: the three forms begin as one point and unfold onto their cards (point, line, plane).
   Gated on .js so the prerendered page is whole without it; reduced motion skips straight to rest. */
@layer motion {
  @media (prefers-reduced-motion: no-preference) {
    .arrive .hud:not(.is-arrived) .hud-frame > i { translate: var(--fx, 0) var(--fy, 0); opacity: 0; }
    .arrive .hud:not(.is-arrived) .hud-frame > i:nth-child(1) { --fx: -10px; --fy: -10px; }
    .arrive .hud:not(.is-arrived) .hud-frame > i:nth-child(2) { --fx: 10px; --fy: -10px; }
    .arrive .hud:not(.is-arrived) .hud-frame > i:nth-child(3) { --fx: 10px; --fy: 10px; }
    .arrive .hud:not(.is-arrived) .hud-frame > i:nth-child(4) { --fx: -10px; --fy: 10px; }
    .arrive .hud:not(.is-arrived) .hud-construction { opacity: 0; }
    .arrive .hud:not(.is-arrived) :is(.hud-kicker, .hud-title, .hud-role, .hud-bottom > *, .gate__choice) { opacity: 0; translate: 0 12px; }
    /* The header arrives on the welcome screen only; past it, it stays put and only the content comes in. */
    .arrive .hud--gate:not(.is-arrived) .hud-top > * { opacity: 0; translate: 0 12px; }
    /* The cards build themselves on the classical home. */
    .arrive .hud--landing:not(.is-arrived) .path { border-color: transparent; background-color: transparent; }
    .arrive .hud--landing:not(.is-arrived) .path__body { opacity: 0; translate: 0 8px; }
    .arrive .hud--landing:not(.is-arrived) .path__glyph { translate: var(--dx, 0) var(--dy, 0); scale: .14; }
    .arrive :is(.hud--stub, .hud--page):not(.is-arrived) .stub__glyph { scale: .14; }
    .arrive .hud--page:not(.is-arrived) :is(.cv-head__role, .cv-portrait, .cv-head__meta, .page-index, .cv-actions, .page-head__lead, .cv-section) { opacity: 0; translate: 0 12px; }
    .hud--page.is-arrived :is(.cv-head__role, .cv-portrait, .cv-head__meta, .page-index, .cv-actions, .page-head__lead, .cv-section) {
      transition: opacity var(--motion-enter) var(--ease-enter), translate var(--motion-enter) var(--ease-enter);
      transition-delay: calc(180ms + var(--i, 0) * var(--motion-stagger) / 2);
    }
    .hud--page .cv-section:nth-of-type(1) { --i: 2; }
    .hud--page .cv-section:nth-of-type(2) { --i: 3; }
    .hud--page .cv-section:nth-of-type(3) { --i: 4; }
    .hud--page .cv-section:nth-of-type(4) { --i: 5; }
    .hud--page .cv-section:nth-of-type(5) { --i: 6; }
    .hud--page .cv-section:nth-of-type(n+6) { --i: 7; }
    /* The reticle locks on last, once the cards stand. */
    .arrive .hud:not(.is-arrived) .reticle.is-placed { opacity: 0; }
    .hud.is-arrived:not(.is-settled) .reticle { transition-delay: 0ms, 0ms, 0ms, 1000ms; }

    .hud.is-arrived .hud-frame > i { transition: translate var(--motion-enter) var(--ease-enter), opacity var(--motion-enter) var(--ease-enter); }
    .hud.is-arrived .hud-construction { transition: opacity var(--motion-assemblage) var(--ease-enter) 400ms; }
    .hud.is-arrived :is(.hud-kicker, .hud-title, .hud-role, .hud-top > *, .hud-bottom > *, .gate__choice) {
      transition: opacity var(--motion-enter) var(--ease-enter), translate var(--motion-enter) var(--ease-enter);
    }
    .hud.is-arrived .hud-title { transition-delay: 60ms; }
    .hud.is-arrived .hud-role { transition-delay: 120ms; }
    .hud.is-arrived .gate__choice { transition-delay: 320ms; }
    .hud.is-arrived .hud-bottom > * { transition-delay: 900ms; }
    .hud.is-arrived :is(.path__glyph, .stub__glyph) {
      transition: translate var(--spring-arrive-ms) var(--spring-arrive), scale var(--spring-arrive-ms) var(--spring-arrive);
      transition-delay: calc(320ms + var(--i, 0) * var(--motion-stagger));
    }
    .hud.is-arrived .path {
      transition: border-color var(--motion-enter) var(--ease-enter), background-color var(--motion-enter) var(--ease-enter);
      transition-delay: calc(560ms + var(--i, 0) * var(--motion-stagger));
    }
    .hud.is-arrived .path__body {
      transition: opacity var(--motion-enter) var(--ease-enter), translate var(--motion-enter) var(--ease-enter);
      transition-delay: calc(640ms + var(--i, 0) * var(--motion-stagger));
    }
    /* After arrival the per-element delays must not slow hover and focus. */
    .hud.is-settled :is(.path, .path__body, .path__glyph) { transition-delay: 0ms; }
    .hud.is-settled .path { transition: border-color var(--motion-hover) var(--ease-hover); }


    [data-i18n].is-swapping { opacity: 0; translate: 0 -4px; }
    .is-swap-in { transition: opacity var(--motion-enter) var(--ease-enter), translate var(--motion-enter) var(--ease-enter); }

    /* A window rises a little as it opens and sinks as it closes; its backdrop fades with it. */
    .modal, .modal::backdrop {
      transition: opacity var(--motion-enter) var(--ease-enter), translate var(--motion-enter) var(--ease-enter),
        overlay var(--motion-enter) allow-discrete, display var(--motion-enter) allow-discrete;
      opacity: 0;
    }
    .modal { translate: 0 10px; }
    .modal:popover-open, .modal:popover-open::backdrop { opacity: 1; translate: 0 0; }
    @starting-style {
      .modal:popover-open, .modal:popover-open::backdrop { opacity: 0; }
      .modal:popover-open { translate: 0 10px; }
    }
  }
}

/* The reader's preferences (Accessibilité, Réglages), set on <html> by the boot script. Outside the
   layers, so they win over every rule of the page and over the generated tokens. */
:root[data-text='115'] { font-size: 115%; }
:root[data-text='130'] { font-size: 130%; }
:root[data-contrast='more'] {
  --fg-muted: var(--fg-default); --tech-label: var(--fg-default);
  --line-hairline: var(--line-strong); --line-default: var(--line-strong);
}
/* Arabic and Urdu join their letters: any letter spacing would break the words apart. */
:lang(ar), :lang(ur) { letter-spacing: normal !important; }
/* WCAG 1.4.12's spacing: letters .12em, words .16em, lines 1.5 and more. */
:root[data-spacing='wide'] :is(p, li, dd, label, legend, .path__text, .path__name, .cv-essay__name, .cv-entry__role) {
  letter-spacing: .12em; word-spacing: .16em; line-height: 1.7;
}
:root[data-motion='reduce'] *, :root[data-motion='reduce'] *::before, :root[data-motion='reduce'] *::after,
:root[data-motion='reduce'] ::backdrop {
  transition-duration: 0s !important; animation-duration: 0s !important; scroll-behavior: auto !important;
}

/* The glossary (src/pages.mjs gloss, web/terms.js): a technical term reads as text, lightly dotted in
   its section's tone, and its definition opens in a small sheet beside it. No motion beyond a fade. */
@layer hud {
  .term {
    display: inline; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit;
    letter-spacing: inherit; text-align: inherit; cursor: help;
    text-decoration: underline dotted color-mix(in oklch, var(--sec, var(--fg-muted)) 70%, transparent);
    text-decoration-thickness: 1.5px; text-underline-offset: .22em;
    -webkit-tap-highlight-color: transparent;
  }
  .term:hover, .term[data-open] { text-decoration-color: var(--sec, var(--fg-default)); text-decoration-style: solid; }
  .term:focus-visible { outline: 1.5px solid var(--sec, var(--tech-mark)); outline-offset: 2px; border-radius: 2px; }
  .term-tip {
    position: fixed; top: 0; left: 0; z-index: 50; translate: 0 0;
    width: max-content; max-width: min(340px, calc(100vw - 32px));
    padding: 10px 14px 11px; border: 1px solid var(--line-default); border-top: 2px solid var(--term-tone, var(--tech-mark));
    background: var(--ground-raised); color: var(--fg-default); box-shadow: var(--sheet-shadow);
    font-size: .875rem; line-height: 1.5; pointer-events: none;
    opacity: 0; visibility: hidden; transition: opacity .14s ease, visibility 0s linear .14s;
  }
  .term-tip.is-open { opacity: 1; visibility: visible; transition: opacity .14s ease, visibility 0s; }
  @media print {
    .term { text-decoration: none; cursor: auto; }
    .term-tip { display: none; }
  }
}

/* « Ce que je fais », the projects hub and the project pages (his brief, 2026-11-01): the skill set as
   groups of plain tags, every project as a card (picture, icon, status, name, a line, tags), and a page
   per project. A family keeps one colour on its tiles and icons (`--fam`); the text stays in ink. */
@layer hud {
  [data-family='products'] { --fam: var(--tone-purple-line); }
  [data-family='games'] { --fam: var(--tone-gold-line); }
  [data-family='infra'] { --fam: var(--tone-blue-line); }
  [data-family='tools'] { --fam: var(--tone-green-line); }
  .proj-icon { flex: none; width: 24px; height: 24px; }

  /* The way back (to the hub, or from it to « Ce que je fais »), above a page's head. */
  .crumb { margin: 0 0 18px; font-size: .9375rem; }
  .crumb a { color: var(--fg-muted); text-decoration: none; border-bottom: 1px solid var(--line-default); }
  .crumb a:is(:hover, :focus-visible) { color: var(--fg-default); border-color: var(--path-line); }

  /* The skill set: a group per domain, its argument, its tools as plain tags (no logos, no meters). */
  /* Capped relative to its column: a fixed cap would size the auto-filled grid at three columns on a phone. */
  .stack { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: 32px 40px; max-width: min(100%, 62rem); }
  .stack__name { margin: 0; font: 500 1.1875rem/1.3 'Jost', system-ui, sans-serif; }
  :is(.stack__tools, .proj-tags) { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 0; padding: 0; list-style: none; }
  :is(.stack__tools, .proj-tags) li { padding: 2px 9px; border: 1px solid var(--line-default); border-radius: 999px; font-size: .8125rem; line-height: 1.5; color: var(--fg-muted); }

  /* The hub's filter: radio buttons read by CSS (:has), so it works without script; the chosen one inked. */
  .hub-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 clamp(20px, 3vh, 32px); padding: 0; border: 0; }
  .hub-filter legend { float: inline-start; margin-inline-end: 12px; padding: 6px 0; }
  .hub-filter__option { position: relative; }
  .hub-filter__option input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
  .hub-filter__option span { display: inline-block; padding: 6px 14px; border: 1px solid var(--line-default); border-radius: 999px; font-size: .9375rem; }
  .hub-filter__option input:checked + span { background: var(--fg-default); border-color: var(--fg-default); color: var(--ground-default); }
  .hub-filter__option input:focus-visible + span { outline: 2px solid var(--line-focus); outline-offset: 2px; }
  .hub:has(input[value='products']:checked) .hub-group:not([data-family='products']),
  .hub:has(input[value='games']:checked) .hub-group:not([data-family='games']),
  .hub:has(input[value='infra']:checked) .hub-group:not([data-family='infra']),
  .hub:has(input[value='tools']:checked) .hub-group:not([data-family='tools']) { display: none; }

  /* A family, then its cards. */
  .hub-group { padding: clamp(20px, 3vh, 32px) 0; border-top: 1px solid var(--line-hairline); }
  /* A family is a section of the hub: its title in the display face, as every page's sections are. */
  .hub-group > .cv-section__title { margin: 0 0 18px; font: 500 1.625rem/1.2 'Jost', system-ui, sans-serif; letter-spacing: 0; text-transform: none; color: var(--fg-default); }
  .hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: 20px; margin: 0; padding: 0; list-style: none; }
  .hub-card__link {
    display: flex; flex-direction: column; height: 100%; overflow: hidden; color: inherit; text-decoration: none;
    background: var(--ground-raised); border: 1px solid var(--line-hairline); border-radius: 2px; transition: border-color .2s ease;
  }
  .hub-card__link:is(:hover, :focus-visible) { border-color: var(--fam); }
  :is(.hub-card__thumb, .proj-head__thumb) { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; background: var(--ground-sunken); }
  :is(.hub-card__thumb--tile, .proj-head__thumb--tile) { display: grid; place-items: center; color: var(--fam); background: color-mix(in oklab, var(--fam) 10%, var(--ground-default)); }
  .hub-card__thumb--tile .proj-icon { width: 56px; height: 56px; }
  .hub-card__body { display: flex; flex: 1; flex-direction: column; gap: 6px; padding: 14px 16px 16px; }
  .hub-card__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--fam); }
  .hub-card__status { color: var(--fg-muted); }
  .hub-card__name { margin: 2px 0 0; font: 500 1.1875rem/1.25 'Jost', system-ui, sans-serif; }
  .hub-card__line { font-size: .9375rem; line-height: 1.5; color: var(--fg-muted); }
  .hub-card .proj-tags { margin-top: auto; padding-top: 8px; }

  /* A project's page: its picture beside its name, family, status, line, tags and public addresses, then
     what it is, how it works, why it exists, and the projects on either side. */
  .proj-head { display: grid; gap: clamp(20px, 3vw, 40px); align-items: center; padding-bottom: clamp(28px, 4vh, 44px); }
  @media (min-width: 900px) { .proj-head { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); } }
  .proj-head__thumb { border: 1px solid var(--line-hairline); border-radius: 2px; }
  .proj-head__thumb--tile .proj-icon { width: 96px; height: 96px; }
  .proj-head__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0; color: var(--path-line); }
  .proj-head__meta .hud-label { color: var(--fg-muted); }
  .proj-head__name { margin: 10px 0 0; font-size: clamp(2.2rem, 1.4rem + 2.6vw, 3.6rem); line-height: 1.02; }
  .proj-head .page-head__lead { margin-top: 14px; }
  .proj-head .cv-cta { margin-top: 18px; }
  .proj-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: clamp(28px, 4vh, 44px) 0; border-top: 1px solid var(--line-hairline); }
  .proj-nav__link { display: grid; gap: 4px; color: inherit; text-decoration: none; }
  .proj-nav__link--next { text-align: end; }
  .proj-nav__link span:last-child { font: 500 1.125rem/1.3 'Jost', system-ui, sans-serif; border-bottom: 1px solid transparent; justify-self: start; }
  .proj-nav__link--next span:last-child { justify-self: end; }
  .proj-nav__link:is(:hover, :focus-visible) span:last-child { border-color: var(--path-line); }
}

/* Paper's ink, outside the layers: the theme tokens are unlayered and pinned on <html> (pages.mjs
   THEME), so inside a layer this lost to them and the printed CV came out in the dark theme's near-white
   ink on white. */
@media print {
  :root, :root[data-theme] { color-scheme: light; --fg-default: #000; --fg-muted: #333; --tech-label: #444; --line-hairline: #ccc; --ground-default: #fff; }
}
