/* Copyright (c) 2026 LB IT Cloud SAS. All rights reserved.
   Proprietary source of the LB IT Cloud website. See LICENSE. */

/* ---------------------------------------------------------------------------
   THE PRESENTATION FORMAT, IN THE SITE'S PALETTE — direction « Signalétique », 09/10/2026.

   Julien wants the whole site off the look every generated site shares (soft glows, pills,
   rounded everything, large diffuse shadows), and in the site's palette — the five WGSN 2027
   palettes the header's button switched until 12/10/2026, Le Corbusier's ultramarine alone since. The home page carries it through site.css and theme.css. These three pages
   — Entris, eXact and the resellers, in both languages — cannot: they are written in
   presentation-format.css, eXact's PRE-COMPILED Tailwind bundle (HANDOFF §4.5), which spells
   every colour out as a literal, two hundred of them, with a dark default and a
   [data-theme=light] copy of the common ones. And site.css cannot be loaded here: it styles
   `body`, `section`, `a` and `h1`–`h4`, and would rewrite the layout the bundle draws.

   So this page loads theme.css, exactly as every other page does, and this file maps the
   bundle's utilities onto its tokens, one hue at a time. Nothing in the markup changes; a
   palette or a theme chosen in the header recolours these pages the moment it is chosen,
   because every colour below is a token.

   THE NAMES MEAN THE SAME HERE AS EVERYWHERE, AND THAT WAS CHECKED BEFORE LOADING theme.css.
   --ground, --ink, --line… could have collided: chrome.css's banner warns that the deck and the
   mock-up "define their OWN" on :root. The mock-up does (demo.css, not loaded here). On these
   pages nothing does: the bundle declares no custom property but its own --tw-* ones, and
   utilities.css, present.css and deck-export.css declared none at all (they used literals for
   exactly that reason). chrome.css declares its tokens on header.site itself, so it is
   untouched either way.

   WHY EVERY SELECTOR STARTS WITH :root[data-theme]. The bundle writes a colour twice: `.x`
   for the dark default and `[data-theme=light] .x` for the light theme (0,2,0), and
   utilities.css adds `:root[data-theme="light"] .x` (0,3,0). `:root[data-theme] .x` is
   (0,3,0) and loads after both, so it wins in either theme without !important. theme-boot.js
   always writes data-theme, light by default, so the prefix always matches; the bundle reads
   the attribute's absence as dark, and on these pages it is never absent.

   THE POWERPOINT READS THIS FILE. deck-export.js takes the deck's colours from the page with
   getComputedStyle — the body's ground, the first h2, [data-deck-body], [data-deck-accent]
   and [data-deck-surface] — and its hex() only reads #hex and rgb(). So those five resolve to
   plain tokens here, never to a color-mix(): a computed color-mix comes back as color(srgb …)
   and the export would quietly fall back to its defaults. The tints that DO use color-mix are
   hover states, which nobody is in when they press the export button.

   KEPT AS THEY ARE: every text, every capture and recording, the layout, the eXact word-mark's
   face (Mansalva is the product's logotype, not a text face — only its two colours follow the
   palette, as the LB logo's do since 09/10/2026), and the two Azure service icons, which are
   Microsoft's drawings.
   --------------------------------------------------------------------------- */

/* What no palette changes, as site.css's :root states it — that file is not loaded here (see
   above), so these are copied, and must move with it. */
:root {
  --ok: #17794b;     --ok-bg: #e6f5ed;
  --warn: #935701;   --warn-bg: #fdf2e0;
  --danger: #b42a2a; --danger-bg: #fceded;
  /* --a2, --a3, --a4: written into theme.css from the palette since 12/10/2026 (two colours). */
  --cut: 12px;
  --display: "Archivo", "Segoe UI", system-ui, sans-serif;
  --body: "Archivo", "Segoe UI", system-ui, sans-serif;
  --mono: "Martian Mono", "Cascadia Mono", Consolas, ui-monospace, monospace;
}
html[data-theme="dark"] {
  --ok: #6ee7a8;     --ok-bg: rgba(74, 222, 128, .12);
  --warn: #f0a132;   --warn-bg: rgba(240, 161, 50, .14);
  --danger: #ef5a63; --danger-bg: rgba(239, 90, 99, .14);
}

/* ===========================================================================
   THE GROUND, THE INK AND THE FACES
   =========================================================================== */
:root[data-theme] { font-family: var(--body); color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme] body { background: var(--ground); color: var(--ink); font-family: var(--body); }

/* Space Grotesk out, Archivo in, condensed through its width axis (fonts.css) the way the home
   page's titles are. The weights the markup asks for (font-bold, font-extrabold) give way to the
   one weight every title on the site has. */
:root[data-theme] :is(h1, h2, h3, h4) { font-family: var(--display); font-weight: 760; letter-spacing: -.005em; }
:root[data-theme] h1 { font-stretch: 72%; }
:root[data-theme] h2 { font-stretch: 72%; }
:root[data-theme] h3 { font-stretch: 72%; }
:root[data-theme] h4 { font-stretch: 100%; }
/* The bold first line of each point of a list. */
:root[data-theme] strong.block.text-lg { font-family: var(--display); font-weight: 700; }

/* References and labels — the small spaced capitals — take the reference face. */
:root[data-theme] .font-mono,
:root[data-theme] .uppercase:is(.tracking-wider, .tracking-widest, .tracking-\[0\.2em\]) {
  font-family: var(--mono); font-weight: 500; letter-spacing: .08em;
}

:root[data-theme] body ::selection,
:root[data-theme] body::selection { background: var(--brand-line); color: var(--ink); }
:root[data-theme] ::-webkit-scrollbar-track { background: var(--ground-2); }
:root[data-theme] ::-webkit-scrollbar-thumb { background: var(--line); border-radius: 0; }

/* ===========================================================================
   NEUTRALS — the bundle's slate and white, onto the grounds, panels, lines and inks
   =========================================================================== */
:root[data-theme] .text-white,
:root[data-theme] .text-slate-200,
:root[data-theme] .hover\:text-slate-300:hover { color: var(--ink); }
:root[data-theme] .text-slate-300,
:root[data-theme] .text-slate-400 { color: var(--ink-2); }
:root[data-theme] .text-slate-500 { color: var(--ink-3); }

/* The two bands the pages alternate with, ruled top and bottom like site.css's section.alt. */
:root[data-theme] .bg-slate-900 { background-color: var(--ground-2); }
:root[data-theme] .bg-slate-900:is(section, .py-24) { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
/* Cards, frames and the boxes inside them. */
:root[data-theme] :is(.bg-slate-950, .bg-slate-950\/70, .bg-slate-800,
  .bg-slate-900\/40, .bg-slate-900\/50, .bg-slate-900\/60, .bg-slate-900\/80) { background-color: var(--panel); }
:root[data-theme] :is(.bg-slate-950\/40, .bg-slate-950\/50, .bg-slate-950\/60) { background-color: var(--ground-2); }
:root[data-theme] .bg-slate-700 { background-color: var(--fill); }
:root[data-theme] .bg-slate-700\/50 { background-color: var(--line); }
:root[data-theme] .bg-slate-500 { background-color: var(--ink-3); }
:root[data-theme] .bg-white\/5 { background-color: var(--fill); }
:root[data-theme] .hover\:bg-white\/10:hover { background-color: var(--brand-line); }
:root[data-theme] .hover\:bg-slate-800\/60:hover { background-color: color-mix(in srgb, var(--panel) 90%, var(--plate)); }

:root[data-theme] :is(.border-white\/5, .border-white\/10, .border-slate-600, .border-slate-700,
  .border-slate-700\/50, .border-slate-800) { border-color: var(--line); }
/* The bundle's preflight gives every border Tailwind's grey (#e5e7eb) until a class says
   otherwise. The site's line instead — at no specificity at all (:where), so any class, and
   chrome.css's own rules for the header, still say otherwise. */
:where(:root[data-theme]) *,
:where(:root[data-theme]) ::before,
:where(:root[data-theme]) ::after { border-color: var(--line); }
:root[data-theme] .group:hover .group-hover\:border-slate-400 { border-color: var(--ink-3); }
:root[data-theme] .ring-white\/10 { --tw-ring-color: var(--line); }

/* ===========================================================================
   THE HUES — nine Tailwind families onto the site's four accents and its states
     blue                  → --a1, the palette's own (--brand)
     cyan, teal, sky       → --a2 teal
     purple, indigo        → --a3 violet
     amber, orange         → --a4 amber
     emerald               → --ok      (what the pages use it for: a tick, "by design")
     rose                  → --danger  (and here: the friction, the attack surface)
   =========================================================================== */
:root[data-theme] :is(.text-blue-300, .text-blue-400, .text-blue-500, .hover\:text-blue-400:hover) { color: var(--a1); }
:root[data-theme] :is(.text-cyan-400, .text-cyan-500, .text-teal-500, .text-sky-400, .text-sky-500, .hover\:text-sky-400:hover) { color: var(--a2); }
:root[data-theme] :is(.text-purple-400, .text-purple-500, .text-indigo-400, .text-indigo-500) { color: var(--a3); }
:root[data-theme] :is(.text-amber-400, .text-amber-500, .text-orange-500) { color: var(--a4); }
:root[data-theme] :is(.text-emerald-300, .text-emerald-400, .text-emerald-500, .hover\:text-emerald-400:hover) { color: var(--ok); }
:root[data-theme] :is(.text-rose-400, .text-rose-500) { color: var(--danger); }

/* Tints. Where they survive the shape rules further down (the kicker and the icon squares lose
   theirs), they become the accent's own soft colour, opaque. */
:root[data-theme] :is(.bg-blue-500\/5, .bg-blue-500\/10, .bg-blue-500\/15, .bg-blue-900\/10) { background-color: var(--a1-soft); }
:root[data-theme] :is(.bg-cyan-500\/5, .bg-cyan-500\/10, .bg-teal-500\/5, .bg-sky-500\/5) { background-color: var(--a2-soft); }
:root[data-theme] :is(.bg-purple-500\/5, .bg-purple-500\/10, .bg-indigo-500\/5, .bg-indigo-500\/10) { background-color: var(--a3-soft); }
:root[data-theme] :is(.bg-amber-500\/5, .bg-amber-500\/10, .bg-amber-500\/15, .bg-amber-900\/10, .bg-orange-500\/5) { background-color: var(--a4-soft); }
:root[data-theme] :is(.bg-emerald-500\/5, .bg-emerald-500\/10) { background-color: var(--ok-bg); }
:root[data-theme] :is(.bg-rose-500\/5, .bg-rose-500\/10) { background-color: var(--danger-bg); }
/* Dots: the three of a window's title bar, a state lamp, a list marker. */
:root[data-theme] .bg-rose-500\/70,
:root[data-theme] .group:hover .group-hover\:bg-rose-500 { background-color: var(--danger); }
:root[data-theme] .bg-amber-500\/70 { background-color: var(--a4); }
:root[data-theme] :is(.bg-emerald-500\/70, .bg-emerald-400) { background-color: var(--ok); }

:root[data-theme] :is(.border-blue-500\/20, .border-blue-500\/30, .border-blue-800\/40) { border-color: var(--a1-line); }
:root[data-theme] :is(.border-blue-500, .border-blue-500\/50, .border-blue-400\/80, .hover\:border-blue-500\/50:hover) { border-color: var(--a1); }
:root[data-theme] .group:hover .group-hover\:border-blue-400 { border-color: var(--a1); }
:root[data-theme] .border-cyan-500\/20 { border-color: var(--a2-line); }
:root[data-theme] :is(.border-purple-500\/20, .border-indigo-500\/20) { border-color: var(--a3-line); }
:root[data-theme] :is(.border-amber-500\/20, .border-amber-800\/30) { border-color: var(--a4-line); }
:root[data-theme] :is(.border-amber-400, .border-amber-400\/80, .border-amber-500\/50) { border-color: var(--a4); }
:root[data-theme] .group:hover .group-hover\:border-amber-400 { border-color: var(--a4); }
:root[data-theme] .border-emerald-500\/20 { border-color: color-mix(in srgb, var(--ok) 32%, transparent); }
:root[data-theme] .border-emerald-500 { border-color: var(--ok); }
:root[data-theme] .border-rose-500\/20 { border-color: color-mix(in srgb, var(--danger) 32%, transparent); }

/* THE PLATE. The bundle's one solid blue — the first button, a step's badge, the rule under a
   title, a list marker — is the palette's colour as a surface, with the ink that reads on it
   (dark on some palettes, white on others: --on-plate decides, not this file). */
:root[data-theme] .bg-blue-600 { background-color: var(--plate); }
:root[data-theme] .bg-blue-600.text-white,
:root[data-theme] .bg-blue-600 .text-white { color: var(--on-plate); }
:root[data-theme] .hover\:bg-blue-500:hover { background-color: color-mix(in srgb, var(--plate) 88%, var(--on-plate)); }
/* The third step's amber badge: the palette's colour since 12/10/2026 — the touch carries no text. */
:root[data-theme] .bg-amber-500 { background-color: var(--plate); }
:root[data-theme] .text-amber-950 { color: var(--on-plate); }

/* ===========================================================================
   NO GLOW, NO GRADIENT, NO SOFT SHADOW
   =========================================================================== */
/* The halos behind the page, behind each capture and behind each card: decorations, every one
   absolutely positioned and empty. Gone rather than recoloured — a flat halo is a smudge. The
   markup stays (the cover's tabs check reads it), it is simply not drawn. */
:root[data-theme] .glow-bg,
:root[data-theme] :is(.blur, .blur-xl, .blur-2xl, .blur-3xl).absolute { display: none; }
:root[data-theme] .bg-gradient-to-r { background-image: none; }
/* The two gradient words of eXact's headlines, in the accent instead. */
:root[data-theme] .text-transparent.bg-clip-text { background-image: none; color: var(--a1); }
/* « Pourquoi choisir eXact ? » — a gradient band, now a plate's pastel, as the home page's
   plate is inside. Its own hover overlay goes with the gradient. */
:root[data-theme] .bg-gradient-to-r.rounded-3xl { background-color: var(--plate-soft); }
:root[data-theme] .bg-gradient-to-r.rounded-3xl > .absolute.inset-0 { display: none; }
/* The architecture's flowing dash, drawn with an SVG gradient, in the accent. */
:root[data-theme] .animate-flow-data { stroke: var(--a1); }

/* Every Tailwind shadow is its --tw-shadow; emptying it leaves the 1px rings (--tw-ring-shadow,
   the hairline round each capture) where they are. */
:root[data-theme] [class*="shadow-"] { --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; }
/* The two pulsing glows round the architecture's nodes. */
:root[data-theme] :is(.pulse-blue, .pulse-amber) { animation: none; }
:root[data-theme] :is(.backdrop-blur-sm, .backdrop-blur-md) { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* A card does not float off the page when the pointer reaches it; its fill answers instead. */
:root[data-theme] .hover\:-translate-y-1:hover,
:root[data-theme] .group:hover .group-hover\:-translate-y-1 { --tw-translate-y: 0; }

/* ===========================================================================
   SQUARE, AND CUT
   =========================================================================== */
:root[data-theme] :is(.rounded-lg, .rounded-xl, .rounded-2xl, .rounded-3xl, .rounded-full,
  .rounded-bl-full, .rounded-\[2rem\], .rounded-\[2\.5rem\]) { border-radius: 0; }
/* …except what is a circle: the dots, and the three nodes of the architecture with the badge on
   the second one. Everything else `rounded-full` drew was a pill. */
:root[data-theme] .rounded-full:is(.w-1\.5, .w-2, .w-2\.5, .inset-2, .-bottom-1) { border-radius: 50%; }

/* THE CHAMFER, as site.css cuts it: two opposite corners, clipped where the engine cannot shape
   the corner itself, and shaped (border and focus ring following) where it can. These elements
   are filled rather than bordered for the same reason site.css gives — a clipped border loses
   its diagonal — so their borders go and their fill does the work. The cards whose first child
   is a capture (`p-0`) stay square: a cut corner there would cut the capture. */
:root[data-theme] :is(.bento-card:not(.p-0), .rounded-3xl, .rounded-2xl.p-5, .rounded-2xl.p-6,
  a.rounded-full.bg-blue-600, a.rounded-full.bg-white\/5, .hero-arrow) {
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  border-width: 0;
}
@supports (corner-shape: bevel) {
  :root[data-theme] :is(.bento-card:not(.p-0), .rounded-3xl, .rounded-2xl.p-5, .rounded-2xl.p-6,
    a.rounded-full.bg-blue-600, a.rounded-full.bg-white\/5, .hero-arrow) {
    clip-path: none; border-radius: var(--cut) 0 var(--cut) 0; corner-shape: bevel;
  }
}

/* THE CARD — an inventory tag, as on the home page: a fill, no border, no blur, no shadow, and
   no lift; the pointer tints it toward the plate. */
:root[data-theme] .bento-card {
  --cut: 16px;
  background: var(--panel); border-color: transparent; border-radius: 0;
  -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none;
  transition: background-color .15s;
}
:root[data-theme] .bento-card:hover {
  transform: none; box-shadow: none; border-color: transparent;
  background: color-mix(in srgb, var(--panel) 90%, var(--plate));
}
:root[data-theme] .rounded-3xl { --cut: 16px; }
:root[data-theme] :is(.rounded-2xl.p-5, .rounded-2xl.p-6) { --cut: 12px; }
@media (prefers-reduced-motion: reduce) { :root[data-theme] .bento-card { transition: none; } }

/* THE BUTTONS — site.css's .btn: the plate, then the fill, in condensed spaced capitals. */
:root[data-theme] a.rounded-full:is(.bg-blue-600, .bg-white\/5) {
  --cut: 9px;
  font: 650 12.5px/1.1 var(--display); text-transform: uppercase; letter-spacing: .08em;
}
:root[data-theme] a.rounded-full:is(.bg-blue-600, .bg-white\/5):focus-visible { outline: 2px solid currentColor; outline-offset: -5px; }

/* THE KICKER — the pill above each title becomes the home page's reference line: the reference
   face, no pill, and a short rule in the palette's touch ahead of it, where a drawing puts its
   datum mark. Its text keeps its accent, which is also what the PowerPoint's accent is read
   from ([data-deck-accent], on the cover's). */
:root[data-theme] .inline-flex.rounded-full.uppercase {
  gap: 10px; padding: 0; background: transparent; border: 0;
  font-family: var(--mono); font-weight: 500; letter-spacing: .08em;
}
:root[data-theme] .inline-flex.rounded-full.uppercase::before {
  content: ""; width: 22px; height: 3px; background: var(--touch); flex: none;
}

/* THE ICON SQUARES — not a pastel chip behind the mark, its outline in the mark's own colour,
   as site.css's .card .ico has drawn it since the direction changed. */
:root[data-theme] :is(.w-10, .w-12, .w-14).justify-center {
  background: transparent; border: 1.5px solid currentColor; border-radius: 0;
}

/* The captures' frames and their window bar are square and ruled by the ring above; the
   recordings in them (utilities.css) and the stills keep their whole picture. */

/* THE CAROUSEL'S ARROWS AND DOTS (eXact's cover). The arrows are site.css's .shotnav, with its
   literal colours and for its reason: they sit on a capture, not on the page, so a token that
   follows the theme would vanish on half the frames. */
:root[data-theme] .hero-arrow {
  --cut: 8px;
  color: #fff; background: rgba(14, 20, 34, .62); border: 0;
}
:root[data-theme] .hero-arrow:hover { background: rgba(14, 20, 34, .82); }
:root[data-theme] .hero-arrow:focus-visible { outline: 2px solid #fff; outline-offset: -5px; }
:root[data-theme] .hero-dot { border-radius: 0; background-color: var(--line); }
:root[data-theme] .hero-dot:hover { background-color: var(--ink-3); }
:root[data-theme] .hero-dot.is-active { background-color: var(--touch); }

/* The eXact word-mark: its face stays, its two tones are the palette's, like the LB logo's. */
:root[data-theme] .logo-font .text-blue-500 { color: var(--logo-dark); }
:root[data-theme] .logo-font .text-emerald-500 { color: var(--logo-light); }

/* DMI's logo is light lettering: on the light theme it keeps a dark ground behind it, squared. */
:root[data-theme="light"] img[alt=DMI] { background: var(--ink); border-radius: 0; }

/* The enlarged capture. */
:root[data-theme] .zoom-modal {
  background: color-mix(in srgb, var(--ground) 94%, transparent);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
:root[data-theme] .zoom-modal img { border-radius: 0; box-shadow: none; }

/* ===========================================================================
   LA FEUILLE DE ROUTE — hero d'eXact, 15/10/2026.

   REPLIÉE, ET C'EST LE FOND DU SUJET. Ce qui n'existe pas encore ne doit pas occuper
   la même surface que ce que le produit fait aujourd'hui : déplié d'office, le hero
   annoncerait cinq promesses avant d'avoir montré une seule fonction. Un <details>,
   comme l'anonymizer et les conseillers en portent déjà — il s'ouvre au clavier et au
   clic, sans une ligne de script, et son contenu est dans le HTML même replié, donc un
   robot le lit et le prérendu le capture.

   Le bouton reprend trait pour trait les deux appels à l'action voisins (le chamfer à
   9 px, la face de titrage en capitales espacées) ; le panneau reprend la barre orange
   de 22 × 3 px du « kicker » ci-dessus, qui est la marque du site.
   =========================================================================== */
:root[data-theme] .roadmap { --cut: 9px; }

:root[data-theme] .roadmap-btn {
  display: inline-flex; align-items: center; gap: .7em;
  padding: .85rem 2rem;
  background: var(--panel); color: var(--ink);
  font: 650 12.5px/1.1 var(--display); text-transform: uppercase; letter-spacing: .08em;
  cursor: pointer;
  /* `list-style` pour Firefox, le pseudo-élément pour WebKit : sans les deux, le
     triangle du navigateur s'ajoute au chevron et on en voit deux. */
  list-style: none;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
:root[data-theme] .roadmap-btn::-webkit-details-marker { display: none; }
@supports (corner-shape: bevel) {
  :root[data-theme] .roadmap-btn { clip-path: none; border-radius: var(--cut) 0 var(--cut) 0; corner-shape: bevel; }
}
:root[data-theme] .roadmap-btn:hover { background: color-mix(in srgb, var(--panel) 88%, var(--ink)); }
:root[data-theme] .roadmap-caret { font-size: 1.1em; line-height: 1; transition: transform .2s; }
:root[data-theme] .roadmap[open] .roadmap-caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { :root[data-theme] .roadmap-caret { transition: none; } }

/* LE PANNEAU, REFAIT LE 15/10/2026. Il s'ouvrait sur « CE QUI EST EN CONSTRUCTION. LES
   SUJETS SONT FERMES, LES DATES NE LE SONT PAS. » en capitales monospace, sur trois
   lignes : des capitales espacées se lisent mal au-delà de trois mots — c'est une
   étiquette, pas un corps de texte. Et un filet entre chaque entrée donnait à cinq
   lignes l'allure d'un tableau.

   LA PHRASE N'A PAS ÉTÉ DÉPLACÉE, ELLE A ÉTÉ RETIRÉE. Clément : « Enleve cette phrase
   qui ne veut rien dire "les sujets sont fermes" ! Tu ne sais pas. » Elle était de mon
   fait et n'engageait que moi : rien ne dit que ces cinq sujets soient arrêtés. Il
   reste l'étiquette « En construction », qui dit ce qu'on sait et rien de plus. */
:root[data-theme] .roadmap-panel {
  margin-top: .75rem; padding: 1.25rem 1.25rem 1.1rem;
  background: var(--panel); border-left: 3px solid var(--touch);
}
:root[data-theme] .roadmap-label {
  margin: 0 0 1rem; color: var(--touch);
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  line-height: 1; text-transform: uppercase; letter-spacing: .14em;
}
:root[data-theme] .roadmap-list { margin: 0; padding: 0; list-style: none; }
:root[data-theme] .roadmap-list li {
  position: relative; padding: 0 0 0 18px; margin-bottom: .7rem;
  color: var(--ink); font-size: .95rem; line-height: 1.45;
}
:root[data-theme] .roadmap-list li:last-child { margin-bottom: 0; }
/* Un carré de 5 px plutôt qu'une barre : la barre de 22 px est la marque du titre de
   section, et la répéter cinq fois dans un panneau lui retirerait ce qu'elle vaut. */
:root[data-theme] .roadmap-list li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 5px; height: 5px; background: var(--touch);
}
:root[data-theme] .roadmap-list a { color: var(--a1); text-underline-offset: 3px; }

/* À PARTIR DE 1024 px, LA FEUILLE DE ROUTE REMONTE DANS LE VIDE À DROITE DU TITRE.
   Clément, 15/10/2026, flèche à l'appui : « tu peux pas essayer de mettre le bouton
   Roadmap par ici ? » — là où le hero ne porte rien.

   HORS DU FLUX, ET C'EST TOUT L'INTÉRÊT. Le hero est déjà `relative` ; en absolu, le
   bloc n'occupe aucune place, donc le panneau qui s'ouvre ne pousse ni le titre ni la
   capture : il se déplie dans le vide, qui est précisément ce qu'on vient y chercher.
   Le haut s'aligne sur la ligne de référence (96 px, le padding de la section) et la
   droite sur son bord (24 px), pour que le bouton tienne la même marge que tout le reste.

   LA BASCULE EST À 1140 px, ET CE N'EST PAS LE TITRE QUI LA FIXE. Posée d'abord à
   1024 px parce que le titre n'y fait que 422 px de texte, la règle recouvrait le
   paragraphe : il est en `max-w-2xl`, donc 672 px FIXES quelle que soit la fenêtre. Le
   chiffre qui avait l'air de suffire était celui du titre ; c'est le plus long des trois
   qui décide. 672 de paragraphe + 40 de gouttière + 368 de bloc + 48 de marges donnent
   1128, arrondis à 1140. En dessous, le bloc reprend sa place dans le flux, sous les deux
   appels à l'action, où il a été vérifié à 375 px.

   LA LARGEUR EST 23rem, SOIT ENVIRON 40 SIGNES PAR LIGNE une fois les marges et le
   retrait de puce retirés. C'est la mesure à tenir en écrivant une entrée : au-delà,
   elle passe à deux lignes et le dernier mot se retrouve seul. Seule la deuxième entrée
   déborde, et c'est assumé — « DISA Windows 11 STIG » ne se raccourcit pas. */
@media (min-width: 1140px) {
  :root[data-theme] .roadmap-anchor {
    position: absolute; top: 96px; right: 24px; z-index: 2;
    width: 23rem; max-width: none; margin-top: 0;
    /* Le bouton est de niveau ligne : c'est l'alignement du texte qui le pousse à droite,
       sans faire du <details> un conteneur flex — le panneau, lui, se relit à gauche. */
    text-align: right;
  }
  :root[data-theme] .roadmap-anchor .roadmap-panel { text-align: left; }
}
