/* ============================================================================
   L'ÉTABLI / THE WORKBENCH — main.css
   UN seul fichier. La DA du contrat (FICHE-TECHNIQUE.md §5) en jetons CSS.

   ARCHÉTYPE : « L'ATELIER AU PANNEAU PERFORÉ ». L'atelier impeccablement rangé.
   Le panneau perforé où chaque outil a sa silhouette dessinée à sa place, les
   étiquettes d'établi vissées sur les casiers, l'acier et le bois clair.

   LES QUATRE RÈGLES DE MATIÈRE, à ne pas casser :
     1. ZÉRO ARRONDI MOU. Les angles se COUPENT (clip-path), ils ne s'arrondissent
        pas. Rayon maximum toléré : 3 px, et seulement sur les champs de saisie.
     2. ZÉRO OMBRE MOLLE. Toute ombre est DURE (blur 0) : c'est l'épaisseur d'une
        plaque d'acier posée sur une planche, pas un halo.
     3. UN SEUL ACCENT : l'orange outil, réservé aux ACTES (boutons, liens).
     4. LE VERT DE CONTRÔLE est RÉSERVÉ à « traité localement ✓ ». Jamais en
        décor, jamais en lien, jamais en nappe. C'est le tampon de l'atelier.

   Le motif de panneau perforé est un radial-gradient, jamais un filtre SVG
   vivant : un filtre sur une surface de page coûte trop cher au processeur d'un
   téléphone (leçon de flotte, payée ailleurs).

   PASSE DESIGN (Fable, 2026-07-30) — le SPECTACULAIRE sans casser un verrou :
     · la MATIÈRE : perforations « percées » (ombre + éclat décalé d'1 px, stops
       durs), grain d'acier en tuile SVG feTurbulence FIGÉE en data-URI (160 px,
       rasterisée une fois puis répétée : ce n'est PAS un filtre vivant), et
       biseaux d'usinage en ombres INSET dures (blur 0, toujours).
     · le GESTE : la zone de dépôt invite (respiration du picto), puis guide
       (équerres de visée + liseré lumineux qui tourne pendant le drag).
     · la FRAPPE : le tampon écrase, rebondit, et reste posé à -0,5° comme un
       vrai tampon d'atelier. L'onde de choc est un box-shadow à spread animé :
       blur 0, et une ombre ne crée jamais de débordement mesurable.
     · la RÉVÉLATION : les lignes du constat arrivent en cascade et un trait de
       marqueur se souligne sous ce que la photo dit de vous.
     · la FLUIDITÉ : view transitions entre pages (cross-document), le wordmark
       reste en place pendant le fondu.
   TOUT mouvement est triple-gardé : @media (prefers-reduced-motion),
   :root[data-animations="off"], et transform/opacity/box-shadow seulement.
   Les gradients de ce fichier sont des PINCEAUX À MOTIFS (stops durs : trous,
   pointillés, traits) — jamais une nappe de couleur qui glisse, qui reste
   interdite par la fiche §5.
   ========================================================================== */

/* =================================================================== 1. JETONS */
:root {
  /* --- surfaces (le contrat, au caractère près) */
  --atelier: #EFEEE9;          /* le fond : gris atelier clair */
  --surface: #E5E3DC;          /* les surfaces posées dessus */
  --plan: #F7F6F2;             /* le plan de travail : la carte, l'outil */
  --panneau: #23272E;          /* le panneau graphite d'accroche */
  --panneau-2: #2E333B;        /* les perforations du panneau */

  /* --- encre */
  --encre: #23272E;
  --encre-2: #4A4F58;          /* 7,09:1 sur l'atelier — corps de texte admis */
  --encre-3: #656B75;          /* 4,96:1 sur le plan de travail (recalculé) */
  --filet: #D3D0C7;
  --filet-2: #B9B5A9;

  /* --- l'accent UNIQUE : orange outil */
  --accent: #D9480F;           /* surfaces d'acte, filets d'acte, marques */
  --accent-fonce: #B93B0A;     /* 4,89:1 sur l'atelier — le TEXTE des liens */
  --accent-noir: #8F2D07;      /* 7,10:1 — le survol d'un lien */
  --accent-fond: #FDEEE6;      /* le fond teinté */
  --accent-clair: #FF8A5B;     /* 6,45:1 sur le graphite */

  /* --- le vert de CONTRÔLE (réservé) */
  --vert: #2F9E44;             /* la coche, le filet du tampon */
  --vert-txt: #1E7A32;         /* 4,65:1 sur l'atelier — le texte du tampon */
  --vert-fond: #EAF6EC;
  --vert-clair: #5FD97C;       /* 8,35:1 sur le graphite */

  /* --- l'alerte (limites, échecs de fichier). Pas un accent : un signal. */
  --alerte: #8A5A00;
  --alerte-fond: #FBF1DC;

  /* --- typographie */
  --titre: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --corps: "Atkinson Hyperlegible", "Segoe UI", system-ui, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "Consolas", monospace;

  --t-base: 1.0625rem;         /* 17 px : le corps */
  --t-petit: 0.9375rem;
  --t-mini: 0.8125rem;
  --interligne: 1.62;

  /* --- géométrie : tout est multiple de 4 */
  --u: 0.25rem;
  --gouttiere: 1.5rem;
  --large: 74rem;              /* la largeur du plan de travail */
  --etroit: 44rem;             /* la largeur de lecture confortable */
  --coupe: 10px;               /* la COUPE d'angle : la signature de forme */
  --coupe-s: 6px;

  /* --- ombres DURES (blur 0, toujours) */
  --plaque: 3px 3px 0 var(--filet-2);
  --plaque-accent: 3px 3px 0 var(--accent);
  --plaque-encre: 4px 4px 0 var(--encre);
  /* l'objet SOULEVÉ vers la main : il monte d'un pixel, l'ombre s'allonge */
  --plaque-lever: 5px 5px 0 var(--encre);
  --plaque-lever-accent: 5px 5px 0 var(--accent);

  --transition: 120ms linear;
  /* le LEVER d'un objet qu'on saisit (bouton, porte) : vif à l'aller,
     posé au retour. Transform et box-shadow seulement. */
  --lever: 140ms ease-out;

  /* LE GRAIN D'ACIER : une tuile SVG de bruit (feTurbulence) FIGÉE en data-URI,
     160 px, rasterisée UNE fois par le navigateur puis répétée. Ce n'est pas un
     filtre vivant (leçon de flotte : un filtre sur une surface de page coûte
     trop cher à un téléphone). Bruit BLANC à 5,5 % d'alpha : il ne sert que les
     surfaces GRAPHITE, où il donne le grain du métal brossé. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.055 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");

  color-scheme: light dark;
}

/* --- LE THÈME SOMBRE. Règle de flotte : toute règle de thème sombre s'écrit
   DEUX fois (attribut explicite + media query) ou pas du tout. */
:root[data-theme="sombre"] {
  --atelier: #191C21;
  --surface: #22262C;
  --plan: #1E2227;
  --panneau: #12151A;
  --panneau-2: #1E2229;
  --encre: #E8E6E0;
  --encre-2: #B4B8BF;
  --encre-3: #8B9099;
  --filet: #343941;
  --filet-2: #454B54;
  --accent-fonce: #FF8A5B;
  --accent-noir: #FFB08C;
  --accent-fond: #2E1E17;
  --vert-txt: #5FD97C;
  --vert-fond: #16261A;
  --alerte: #E5B75A;
  --alerte-fond: #2B2314;
  --plaque: 3px 3px 0 #0D0F13;
  --plaque-encre: 4px 4px 0 #000;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) {
    --atelier: #191C21;
    --surface: #22262C;
    --plan: #1E2227;
    --panneau: #12151A;
    --panneau-2: #1E2229;
    --encre: #E8E6E0;
    --encre-2: #B4B8BF;
    --encre-3: #8B9099;
    --filet: #343941;
    --filet-2: #454B54;
    --accent-fonce: #FF8A5B;
    --accent-noir: #FFB08C;
    --accent-fond: #2E1E17;
    --vert-txt: #5FD97C;
    --vert-fond: #16261A;
    --alerte: #E5B75A;
    --alerte-fond: #2B2314;
    --plaque: 3px 3px 0 #0D0F13;
    --plaque-encre: 4px 4px 0 #000;
  }
}

/* --- les préférences du panneau latéral */
:root[data-taille="l"] { --t-base: 1.1875rem; --t-petit: 1.0625rem; --t-mini: 0.9375rem; }
:root[data-taille="xl"] { --t-base: 1.375rem; --t-petit: 1.1875rem; --t-mini: 1rem; }
:root[data-aeration="large"] { --interligne: 1.85; }
:root[data-contraste="haut"] {
  --encre-2: var(--encre); --encre-3: var(--encre);
  --filet: var(--encre); --filet-2: var(--encre);
  --accent-fonce: var(--accent-noir);
  --plaque: none; --plaque-accent: none; --plaque-encre: none;
  --plaque-lever: none; --plaque-lever-accent: none;
  /* le grain d'acier s'efface aussi : le contraste renforcé épure la matière */
  --grain: none;
}
:root[data-liens="marques"] main a { text-decoration: underline; text-decoration-thickness: 2px; }

/* ============================================================== 2. POLICES */
@font-face {
  font-family: "Space Grotesk"; font-style: normal; font-weight: 500;
  src: url("../fonts/space-grotesk-latin-500-normal.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk"; font-style: normal; font-weight: 700;
  src: url("../fonts/space-grotesk-latin-700-normal.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 400;
  src: url("../fonts/atkinson-hyperlegible-latin-400-normal.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 700;
  src: url("../fonts/atkinson-hyperlegible-latin-700-normal.woff2") format("woff2");
  font-display: swap;
}

/* =============================================================== 3. SOCLE */
*, *::before, *::after { box-sizing: border-box; }
/* ⚠ `[hidden]` NE GAGNE PAS contre un `display` déclaré : la règle du
   navigateur est `[hidden]{display:none}`, et n'importe quelle classe qui pose
   `display:flex` la bat. La barre d'état de l'outil restait donc à l'écran
   après le traitement, jauge à 70 %, alors que le script l'avait bien cachée.
   Vu à l'œil sur une capture, pas deviné. Cette ligne vaut pour tout le site. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
:root[data-animations="off"] html { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--atelier);
  color: var(--encre);
  font-family: var(--corps);
  font-size: var(--t-base);
  line-height: var(--interligne);
  font-synthesis: none;
  /* LE PANNEAU PERFORÉ DU FOND, très discret : on le devine, on ne le lit pas.
     Chaque trou est PERCÉ, pas imprimé : une ombre dans le trou, et l'éclat du
     chanfrein 1 px PLUS BAS (la lumière vient du plafond de l'atelier). Deux
     radials à stops durs : un pinceau à motifs, pas un dégradé. */
  background-image:
    radial-gradient(circle at center, rgba(35, 39, 46, 0.075) 1.1px, transparent 1.3px),
    radial-gradient(circle at center, rgba(255, 255, 255, 0.85) 1.1px, transparent 1.3px);
  background-size: 22px 22px, 22px 22px;
  background-position: 0 0, 0 1px;
}
:root[data-theme="sombre"] body {
  background-image:
    radial-gradient(circle at center, rgba(0, 0, 0, 0.5) 1.1px, transparent 1.3px),
    radial-gradient(circle at center, rgba(232, 230, 224, 0.055) 1.1px, transparent 1.3px);
  background-size: 22px 22px, 22px 22px;
  background-position: 0 0, 0 1px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) body {
    background-image:
      radial-gradient(circle at center, rgba(0, 0, 0, 0.5) 1.1px, transparent 1.3px),
      radial-gradient(circle at center, rgba(232, 230, 224, 0.055) 1.1px, transparent 1.3px);
    background-size: 22px 22px, 22px 22px;
    background-position: 0 0, 0 1px;
  }
}

/* les bandes de la page montent au-dessus du motif.
   ⚠ LEÇON DE FLOTTE : `body > *` met toutes les bandes à la MÊME altitude, et à
   égalité l'ordre du document gagne. Un composant flottant qui doit sortir de sa
   bande vers le BAS (menu, liste de langues) ne peut pas y arriver par son propre
   z-index : il faut lever SA BANDE. C'est pourquoi `.utilite` porte 45. */
body > * { position: relative; z-index: 1; }
.utilite { position: relative; z-index: 45; }

h1, h2, h3, h4 {
  font-family: var(--titre);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.015em;
  margin: 0 0 calc(var(--u) * 3);
  text-wrap: balance;
}
h1 { font-size: clamp(1.85rem, 1.2rem + 2.6vw, 3rem); }
h2 { font-size: clamp(1.4rem, 1.05rem + 1.3vw, 2rem); }
h3 { font-size: 1.1875rem; }
h4 { font-size: 1.0625rem; }
p, ul, ol, dl, figure, table { margin: 0 0 calc(var(--u) * 4); }
p:last-child, ul:last-child, ol:last-child { margin-bottom: 0; }
strong, b { font-weight: 700; }
small { font-size: var(--t-mini); }
hr { border: 0; border-top: 2px solid var(--filet); margin: calc(var(--u) * 8) 0; }
img, svg, picture, video { max-width: 100%; height: auto; }
code, kbd, samp, pre { font-family: var(--mono); font-size: 0.9em; }
kbd {
  background: var(--surface); border: 1px solid var(--filet-2);
  padding: 1px 5px; font-size: 0.85em;
}
cite { font-style: normal; }
cite, cite a, .url { overflow-wrap: anywhere; }

a { color: var(--accent-fonce); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--accent-noir); text-decoration-thickness: 2px; }
a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, select:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
[tabindex="-1"]:focus-visible { outline: none; }

.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.saut {
  position: absolute; inset-inline-start: var(--gouttiere); inset-block-start: -3rem;
  z-index: 99; background: var(--accent); color: #fff;
  padding: calc(var(--u) * 2) calc(var(--u) * 4); font-weight: 700;
  text-decoration: none;
}
.saut:focus { inset-block-start: calc(var(--u) * 2); color: #fff; }

.wrap { max-width: var(--large); margin-inline: auto; padding-inline: var(--gouttiere); }

/* la COUPE d'angle : la forme signature. Deux variantes, jamais d'arrondi. */
.coupe { clip-path: polygon(var(--coupe) 0, 100% 0, 100% calc(100% - var(--coupe)), calc(100% - var(--coupe)) 100%, 0 100%, 0 var(--coupe)); }
.coupe-4 {
  clip-path: polygon(var(--coupe-s) 0, calc(100% - var(--coupe-s)) 0, 100% var(--coupe-s),
    100% calc(100% - var(--coupe-s)), calc(100% - var(--coupe-s)) 100%, var(--coupe-s) 100%,
    0 calc(100% - var(--coupe-s)), 0 var(--coupe-s));
}

/* ======================================================== 4. BARRE D'UTILITÉ */
.utilite {
  background: var(--panneau);
  color: #fff;
  font-size: var(--t-mini);
  border-bottom: 3px solid var(--accent);
  background-image:
    var(--grain),
    radial-gradient(circle at center, var(--panneau-2) 1.2px, transparent 1.4px);
  background-size: 160px 160px, 16px 16px;
}
.utilite__in { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--u) * 2) calc(var(--u) * 5); padding-block: calc(var(--u) * 2); }
.utilite__liens { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 5); margin-inline-end: auto; }
.utilite a { color: #fff; text-decoration: none; display: inline-flex; align-items: center; gap: calc(var(--u) * 1.5); }
.utilite a:hover { color: var(--accent-clair); text-decoration: underline; text-decoration-thickness: 2px; }
.utilite__langue { margin: 0; display: inline-flex; align-items: center; gap: calc(var(--u) * 1.5); }

.langues { position: static; }        /* la LISTE s'ancre à la barre, pas au bouton */
.langues__b {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  gap: calc(var(--u) * 1.5); padding: calc(var(--u)) calc(var(--u) * 2);
  border: 1px solid transparent; color: #fff;
}
.langues__b::-webkit-details-marker { display: none; }
.langues__b:hover { border-color: var(--accent); }
.langues__chev { transition: transform var(--transition); }
.langues[open] .langues__chev { transform: rotate(180deg); }
.langues__liste {
  position: absolute; z-index: 40; margin: calc(var(--u)) 0 0; padding: calc(var(--u)); list-style: none;
  min-width: 11rem; background: var(--panneau); border: 2px solid var(--accent);
  /* le bord droit du CONTENU, jamais celui de la fenêtre : sous 540 px la barre
     passe en deux lignes et une liste ancrée au bouton sortirait de l'écran. */
  inset-inline-end: calc(max((100% - var(--large)) / 2, 0px) + var(--gouttiere));
  box-shadow: var(--plaque-encre);
}
.langues__liste a { display: block; padding: calc(var(--u) * 1.5) calc(var(--u) * 3); }
.langues__liste a[aria-current] { background: var(--accent); color: #fff; font-weight: 700; }

/* ============================================================== 5. EN-TÊTE */
.tete { background: var(--atelier); border-bottom: 2px solid var(--filet); }
.tete__in {
  display: flex; align-items: center; gap: calc(var(--u) * 4);
  padding-block: calc(var(--u) * 4); flex-wrap: wrap;
}
.marque { display: inline-flex; align-items: center; gap: calc(var(--u) * 3); text-decoration: none; color: var(--encre); margin-inline-end: auto; }
.marque:hover { color: var(--encre); }
.marque__signe { flex: 0 0 auto; display: block; }
.marque__txt { display: block; }
.marque__nom {
  display: block; font-family: var(--titre); font-weight: 700;
  font-size: 1.375rem; line-height: 1.05; letter-spacing: -0.02em;
}
.marque__sous { display: block; font-size: var(--t-mini); color: var(--encre-2); line-height: 1.25; }

.tete__bascule {
  display: none; align-items: center; gap: calc(var(--u) * 2);
  background: var(--surface); color: var(--encre); border: 2px solid var(--encre);
  font-family: var(--titre); font-weight: 700; font-size: var(--t-petit);
  padding: calc(var(--u) * 2) calc(var(--u) * 3); cursor: pointer;
}
.nav ul { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 1); list-style: none; margin: 0; padding: 0; }
.nav a {
  display: block; text-decoration: none; color: var(--encre);
  font-family: var(--titre); font-weight: 500; font-size: var(--t-petit);
  padding: calc(var(--u) * 2) calc(var(--u) * 3);
  border-bottom: 3px solid transparent;
}
.nav a:hover { color: var(--accent-noir); border-bottom-color: var(--accent); }
.nav a[aria-current] { font-weight: 700; border-bottom-color: var(--accent); }

/* ========================================================= 6. LE BANDEAU */
.bandeau {
  background: var(--surface); border-bottom: 2px solid var(--filet);
  font-size: var(--t-mini); color: var(--encre-2);
}
.bandeau__in {
  display: flex; flex-wrap: wrap; gap: calc(var(--u) * 2) calc(var(--u) * 6);
  padding-block: calc(var(--u) * 2.5); align-items: center;
}
.bandeau__nom { display: inline-flex; align-items: center; gap: calc(var(--u) * 1.5); font-weight: 700; color: var(--encre); }
.bandeau__fait { margin-inline-start: auto; }

/* ======================================================== 7. LES PICTOS */
.ic { width: 1.5rem; height: 1.5rem; flex: 0 0 auto; vertical-align: -0.28em; }
.ic--s { width: 1.125rem; height: 1.125rem; vertical-align: -0.2em; }
.ic--l { width: 2.25rem; height: 2.25rem; }
[dir="rtl"] .ic--miroir { transform: scaleX(-1); }

/* ==================================================== 8. L'ÉTIQUETTE D'ÉTABLI
   Le composant signature du projet : le cartouche vissé sur le casier. Angles
   coupés, filet franc, capitales espacées. Il ÉTIQUETTE, il ne décore pas. */
.etiquette {
  display: inline-flex; align-items: center; gap: calc(var(--u) * 2);
  background: var(--surface); border: 2px solid var(--filet-2);
  padding: calc(var(--u) * 1.5) calc(var(--u) * 3);
  font-family: var(--titre); font-weight: 700;
  font-size: var(--t-mini); letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--encre-2);
  clip-path: polygon(var(--coupe-s) 0, calc(100% - var(--coupe-s)) 0, 100% var(--coupe-s),
    100% calc(100% - var(--coupe-s)), calc(100% - var(--coupe-s)) 100%, var(--coupe-s) 100%,
    0 calc(100% - var(--coupe-s)), 0 var(--coupe-s));
}
.etiquette--accent { border-color: var(--accent); color: var(--accent-fonce); background: var(--accent-fond); }
/* LE TAMPON DE CONTRÔLE : la SEULE place du vert dans toute la DA. */
.etiquette--controle { border-color: var(--vert); color: var(--vert-txt); background: var(--vert-fond); }
.etiquette--controle .ic { color: var(--vert); }
/* LE SIGNAL : l'étiquette d'un échec ou d'une réserve, aux couleurs d'alerte
   de la maison (la même lecture que le « en partie » de la matrice). Ni vert
   ni orange : un échec n'est ni un contrôle réussi, ni un acte à presser. */
.etiquette--signal { border-color: var(--alerte); color: var(--alerte); background: var(--alerte-fond); }
.etiquette--signal .ic { color: var(--alerte); }

/* ======================================================= 9. LES BOUTONS */
/* LA PHYSIQUE DES OBJETS D'ATELIER (passe design) : ce qui se SAISIT se
   soulève d'un pixel (l'ombre dure s'allonge d'autant), ce qui se PRESSE
   s'enfonce dans son ombre. Transform et box-shadow seulement : le
   compositeur fait tout, rien ne reflow. */
.b {
  display: inline-flex; align-items: center; justify-content: center; gap: calc(var(--u) * 2);
  font-family: var(--titre); font-weight: 700; font-size: var(--t-petit);
  padding: calc(var(--u) * 2.5) calc(var(--u) * 5);
  border: 2px solid var(--encre); background: var(--surface); color: var(--encre);
  text-decoration: none; cursor: pointer; text-align: center;
  transition: transform var(--lever), box-shadow var(--lever), background var(--transition);
}
.b:hover { color: var(--encre); background: var(--atelier); }
.b:active { transform: translate(2px, 2px); }
.b[disabled], .b[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.b[disabled]:active { transform: none; }

/* L'ACTE : le bouton d'action. Le seul plein orange de la page.
   Le libellé est à 1,1875 rem / 700 (donc « grand texte » au sens WCAG) :
   c'est ce qui rend le blanc sur l'orange du contrat conforme (4,30:1 mesuré,
   seuil 3:1 pour le grand texte). Le survol descend à 5,68:1. */
.b--acte {
  background: var(--accent); border-color: var(--accent); color: #fff;
  font-size: 1.1875rem; box-shadow: var(--plaque-encre);
}
.b--acte:hover {
  background: var(--accent-fonce); border-color: var(--accent-fonce); color: #fff;
  transform: translate(-1px, -1px);
  box-shadow: var(--plaque-lever);
}
.b--acte:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--encre); }
.b--grand { padding: calc(var(--u) * 3.5) calc(var(--u) * 7); }
.b--fin { border-width: 2px; background: transparent; }
.b--rang { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 3); }

/* ====================================================== 10. LE PLAN DE TRAVAIL
   La CARTE : une plaque posée sur l'établi. Filet franc + ombre DURE. */
.plaque {
  background: var(--plan); border: 2px solid var(--filet-2);
  box-shadow: var(--plaque); padding: calc(var(--u) * 5);
}
.plaque--accent { border-color: var(--accent); box-shadow: var(--plaque-accent); }
.plaque--sombre { background: var(--panneau); color: #fff; border-color: var(--panneau); }
.plaque--sombre h2, .plaque--sombre h3 { color: #fff; }
.plaque--sombre a { color: var(--accent-clair); }

.section { padding-block: calc(var(--u) * 14); }
.section--serre { padding-block: calc(var(--u) * 9); }
/* la BANDE GRAPHITE : le grain du métal brossé, des trous PERCÉS (ombre +
   éclat de chanfrein décalé), et le chant de la plaque pris dans la lumière
   (deux ombres INSET dures, blur 0 : l'arête haute éclairée, la basse dans
   l'ombre). C'est l'éclairage d'atelier simulé, sans une seule image. */
.section--panneau {
  background: var(--panneau); color: #fff;
  background-image:
    var(--grain),
    radial-gradient(circle at center, rgba(0, 0, 0, 0.55) 1.6px, transparent 1.8px),
    radial-gradient(circle at center, rgba(255, 255, 255, 0.07) 1.6px, transparent 1.8px);
  background-size: 160px 160px, 20px 20px, 20px 20px;
  background-position: 0 0, 0 0, 0 1.5px;
  border-block: 3px solid var(--accent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
}
.section--panneau h2, .section--panneau h3 { color: #fff; }
/* ⚠ une plaque CLAIRE posée dans une bande SOMBRE doit reprendre l'encre
   sombre : sinon elle hérite du blanc de la bande et son texte disparaît.
   Défaut vu à l'œil sur la première capture d'accueil, pas deviné. */
.section--panneau .plaque { color: var(--encre); }
.section--panneau .plaque h2,
.section--panneau .plaque h3 { color: var(--encre); }
.section--panneau .plaque a { color: var(--accent-fonce); }
.section--panneau a { color: var(--accent-clair); }
.section--surface { background: var(--surface); border-block: 2px solid var(--filet); }
.chapeau { font-size: 1.1875rem; color: var(--encre-2); max-width: var(--etroit); }
.lecture { max-width: var(--etroit); }
.tete-section { display: flex; flex-wrap: wrap; align-items: end; gap: calc(var(--u) * 4); margin-bottom: calc(var(--u) * 7); }
.tete-section > :first-child { margin-inline-end: auto; margin-bottom: 0; }

/* ===================================================== 11. LE HÉROS D'ACCUEIL */
.hero { padding-block: calc(var(--u) * 14) calc(var(--u) * 12); }
.hero__in { display: grid; gap: calc(var(--u) * 10); grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: center; }
.hero h1 { letter-spacing: -0.03em; }
.hero__punch { font-size: 1.3125rem; color: var(--encre-2); max-width: 34rem; }
.hero__actes { margin-top: calc(var(--u) * 8); }
.hero__preuves { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 3); margin-top: calc(var(--u) * 8); }

/* LE PANNEAU DE DÉMONSTRATION : le mur d'outils, avec les places tracées.
   La plaque est VISSÉE au mur (quatre têtes de vis peintes en radials à stops
   durs), percée (ombre dans le trou, éclat de chanfrein en dessous), grainée
   comme du métal brossé, et son chant prend la lumière (insets durs). */
.mur {
  position: relative;
  background: var(--panneau); border: 3px solid var(--encre);
  box-shadow:
    var(--plaque-encre),
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  padding: calc(var(--u) * 6);
  background-image:
    var(--grain),
    radial-gradient(circle at center, rgba(0, 0, 0, 0.6) 1.8px, transparent 2px),
    radial-gradient(circle at center, rgba(255, 255, 255, 0.075) 1.8px, transparent 2px);
  background-size: 160px 160px, 24px 24px, 24px 24px;
  background-position: 0 0, 0 0, 0 1.5px;
}
/* les quatre vis : une TUILE de 12 px par vis (⚠ un gradient sans
   background-size couvre toute la zone : la vis partirait au centre).
   Dans la tuile, trois cercles à stops durs : le trou d'ombre, la tête
   d'acier, l'éclat de lumière posé en haut à gauche de la tête. Un calque
   décoratif, aucun contenu : pointer-events none. */
.mur::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(circle at 5px 4.5px, rgba(255, 255, 255, 0.55) 1.2px, transparent 1.5px),
    radial-gradient(circle at 6px 6px, #5A626E 3.2px, transparent 3.5px),
    radial-gradient(circle at 6px 6px, rgba(0, 0, 0, 0.6) 4.6px, transparent 4.9px),
    radial-gradient(circle at 5px 4.5px, rgba(255, 255, 255, 0.55) 1.2px, transparent 1.5px),
    radial-gradient(circle at 6px 6px, #5A626E 3.2px, transparent 3.5px),
    radial-gradient(circle at 6px 6px, rgba(0, 0, 0, 0.6) 4.6px, transparent 4.9px),
    radial-gradient(circle at 5px 4.5px, rgba(255, 255, 255, 0.55) 1.2px, transparent 1.5px),
    radial-gradient(circle at 6px 6px, #5A626E 3.2px, transparent 3.5px),
    radial-gradient(circle at 6px 6px, rgba(0, 0, 0, 0.6) 4.6px, transparent 4.9px),
    radial-gradient(circle at 5px 4.5px, rgba(255, 255, 255, 0.55) 1.2px, transparent 1.5px),
    radial-gradient(circle at 6px 6px, #5A626E 3.2px, transparent 3.5px),
    radial-gradient(circle at 6px 6px, rgba(0, 0, 0, 0.6) 4.6px, transparent 4.9px);
  background-repeat: no-repeat;
  background-size: 12px 12px;
  background-position:
    8px 8px, 8px 8px, 8px 8px,
    calc(100% - 8px) 8px, calc(100% - 8px) 8px, calc(100% - 8px) 8px,
    8px calc(100% - 8px), 8px calc(100% - 8px), 8px calc(100% - 8px),
    calc(100% - 8px) calc(100% - 8px), calc(100% - 8px) calc(100% - 8px), calc(100% - 8px) calc(100% - 8px);
}
.mur__grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(var(--u) * 4); }
/* une place TRACÉE : la silhouette au pochoir de l'outil qui viendra. */
.mur__place {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1; border: 2px dashed rgba(255, 255, 255, 0.22);
}
.mur__place svg { width: 68%; height: 68%; color: rgba(255, 255, 255, 0.3); }
/* une place POSÉE : l'outil est accroché DEVANT le panneau. Il porte son
   ombre (drop-shadow DUR, blur 0 — un filtre minuscule et statique, jamais
   une surface de page), et il se DÉCROCHE quand la main s'approche. */
.mur__place--pose {
  border-style: solid; border-color: var(--accent);
  background-color: color-mix(in srgb, var(--accent) 10%, transparent);
  transition: background-color var(--lever);
}
.mur__place--pose svg {
  color: var(--accent);
  filter: drop-shadow(3px 4px 0 rgba(0, 0, 0, 0.55));
  transition: transform var(--lever), filter var(--lever);
}
.mur__place--pose:hover { background-color: color-mix(in srgb, var(--accent) 18%, transparent); }
.mur__place--pose:hover svg {
  transform: translate(-2px, -3px);
  filter: drop-shadow(5px 7px 0 rgba(0, 0, 0, 0.55));
}
.mur__pied { margin: calc(var(--u) * 5) 0 0; color: #C9CDD4; font-size: var(--t-mini); }

/* ================================================ 12. LES COINS DE L'ATELIER */
.coins { display: grid; gap: calc(var(--u) * 5); grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.coin {
  display: flex; flex-direction: column; gap: calc(var(--u) * 3);
  background: var(--plan); border: 2px solid var(--filet-2); box-shadow: var(--plaque);
  padding: calc(var(--u) * 5); position: relative;
}
.coin__tete { display: flex; align-items: start; gap: calc(var(--u) * 3); }
.coin__signe { color: var(--accent); flex: 0 0 auto; }
.coin h3 { margin: 0; }
.coin__num {
  font-family: var(--titre); font-weight: 700; font-size: var(--t-mini);
  letter-spacing: 0.12em; color: var(--encre-2); text-transform: uppercase;
}
.coin__quoi { margin: 0; color: var(--encre-2); font-size: var(--t-petit); }
.coin__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 1.5); }
.coin__liste li { display: flex; align-items: baseline; gap: calc(var(--u) * 2); font-size: var(--t-petit); }
.coin__liste .ic { color: var(--encre-3); }
.coin__liste li[data-etat="pose"] .ic { color: var(--accent); }
.coin__liste li[data-etat="pose"] { font-weight: 700; }
.coin__liste li[data-etat="trace"] { color: var(--encre-2); }
.coin__pied { margin-top: auto; }
.coin--vide { background: var(--surface); border-style: dashed; box-shadow: none; }

/* ================================================= 13. LA PAGE OUTIL (le moteur)
   Anatomie du contrat (fiche §3) : zone de dépôt → réglages → action →
   résultat → bandeau de confiance → des PORTES, et rien d'autre. */
.outil { padding-block: calc(var(--u) * 8) calc(var(--u) * 12); }
.outil__tete { max-width: 52rem; margin-bottom: calc(var(--u) * 8); }
.outil__fil { font-size: var(--t-mini); color: var(--encre-2); margin-bottom: calc(var(--u) * 3); }
.outil__fil a { color: var(--accent-fonce); }
.outil__punch { font-size: 1.1875rem; color: var(--encre-2); }
.outil__limites { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 2); margin-top: calc(var(--u) * 5); }

/* LA ZONE DE DÉPÔT : elle ACCUEILLE physiquement le fichier. La mâchoire
   d'étau s'ouvre au survol du fichier, et le vert n'y apparaît JAMAIS : c'est
   le résultat qui est tamponné, pas le dépôt.
   TROIS ÉTATS, trois intensités (règle UX du geste) :
     repos  — le picto respire doucement : l'invitation ;
     survol — la zone se signale (bordure d'acte, fond teinté) ;
     drag   — l'établi se prépare : les mors se referment et un liseré de
              pointillés TOURNE autour de la zone (le chenillard d'atelier). */
.depot {
  position: relative; display: block; width: 100%;
  background: var(--surface); border: 3px dashed var(--filet-2);
  padding: calc(var(--u) * 12) calc(var(--u) * 6);
  text-align: center; cursor: pointer;
  transition: border-color var(--transition), background var(--transition), transform var(--transition);
}
.depot:hover { border-color: var(--accent); background: var(--accent-fond); }
.depot:active { transform: scale(0.997); }
/* le focus CLAVIER vit sur l'input caché : la zone entière le montre. */
.depot:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.depot[data-survol="oui"] {
  border-color: var(--accent); border-style: solid;
  background-color: var(--accent-fond);
  transform: scale(1.008);
  /* le chenillard : quatre rangs de pointillés (stops durs), un par côté.
     Chaque calque dépasse de 24 px pour que le motif GLISSE sans découvrir
     le bord. L'animation ne touche que background-position. */
  background-image:
    repeating-linear-gradient(90deg, var(--accent) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(180deg, var(--accent) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(90deg, var(--accent) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(180deg, var(--accent) 0 12px, transparent 12px 24px);
  background-repeat: no-repeat;
  background-size: calc(100% + 24px) 3px, 3px calc(100% + 24px), calc(100% + 24px) 3px, 3px calc(100% + 24px);
  /* 6 px d'air entre la bordure et le liseré : deux traits collés se lisent
     comme une double bordure, deux traits espacés comme un guide. */
  background-position: -24px 6px, calc(100% - 6px) -24px, 0 calc(100% - 6px), 6px 0;
}
.depot__signe { color: var(--encre-3); width: 4rem; height: 4rem; }
.depot[data-survol="oui"] .depot__signe, .depot:hover .depot__signe { color: var(--accent); }
.depot__signe { display: block; margin-inline: auto; }
.depot__titre {
  display: block; font-family: var(--titre); font-weight: 700; font-size: 1.375rem;
  margin: calc(var(--u) * 4) 0 calc(var(--u) * 2);
}
.depot__sous { display: block; margin: 0 auto; max-width: 34rem; color: var(--encre-2); font-size: var(--t-petit); }
.depot__ou { display: block; margin: calc(var(--u) * 5) 0 0; }
.depot input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* les mâchoires : deux mors d'étau qui se referment quand le fichier arrive */
.depot::before, .depot::after {
  content: ""; position: absolute; inset-block: 12%; width: 7px;
  background: var(--accent); opacity: 0; transition: opacity var(--transition), transform var(--transition), inset-block var(--transition);
}
.depot::before { inset-inline-start: 0; }
.depot::after { inset-inline-end: 0; }
.depot[data-survol="oui"]::before, .depot[data-survol="oui"]::after { opacity: 1; inset-block: 9%; }
.depot[data-survol="oui"]::before { transform: translateX(8px); }
.depot[data-survol="oui"]::after { transform: translateX(-8px); }
/* le MOUVEMENT du dépôt, triple-gardé (préférence système, préférence du
   panneau). Sans lui, tout reste : les états, les mors, le liseré immobile. */
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-animations="off"]) .depot__signe { animation: depot-respire 2.6s ease-in-out infinite alternate; }
  :root:not([data-animations="off"]) .depot[data-survol="oui"] { animation: depot-chenille 0.9s linear infinite; }
}
@keyframes depot-respire {
  from { transform: translateY(0); }
  to { transform: translateY(-5px); }
}
@keyframes depot-chenille {
  from { background-position: -24px 6px, calc(100% - 6px) -24px, 0 calc(100% - 6px), 6px 0; }
  to { background-position: 0 6px, calc(100% - 6px) 0, -24px calc(100% - 6px), 6px -24px; }
}

/* LA ZONE DE SAISIE : l'AUTRE entrée d'outil, au même rang que le dépôt, pour
   ce qui part d'un texte tapé ou collé (un lien à nettoyer, un contenu de QR,
   une phrase). Le dépôt est un emplacement VIDE qui attend (bordure en tirets) ;
   la saisie est une ARDOISE FIXÉE à l'établi : cadre plein, champ usiné en
   creux (inset dur), et la police à chasse fixe parce qu'ici chaque signe
   compte — on y colle des adresses, pas de la prose. Le cadre prend la couleur
   d'acte quand on écrit dedans : l'établi sait qu'on travaille. */
.saisie {
  background: var(--surface); border: 3px solid var(--filet-2);
  padding: calc(var(--u) * 5) calc(var(--u) * 6);
  display: grid; gap: calc(var(--u) * 2);
  transition: border-color var(--transition);
}
.saisie:focus-within { border-color: var(--accent); }
.saisie__titre {
  display: block; font-family: var(--titre); font-weight: 700; font-size: 1.375rem;
  cursor: pointer;
}
.saisie__sous { display: block; color: var(--encre-2); font-size: var(--t-petit); }
.saisie textarea {
  width: 100%; min-height: 6.5rem; margin-top: calc(var(--u) * 2);
  font-family: var(--mono); font-size: var(--t-petit); line-height: 1.55;
  color: var(--encre); background: var(--plan);
  border: 2px solid var(--filet-2); border-radius: 3px;   /* la seule tolérance d'arrondi : un champ de saisie */
  padding: calc(var(--u) * 3);
  resize: vertical;
  /* le creux d'usinage : le champ est fraisé DANS l'ardoise (inset dur, blur 0) */
  box-shadow: inset 2px 2px 0 rgba(0, 0, 0, 0.06);
}
.saisie textarea:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.saisie__pied {
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--u) * 3);
  margin-top: calc(var(--u) * 2);
}
.saisie__signes { font-family: var(--mono); font-size: var(--t-mini); color: var(--encre-2); }
.saisie__pied .b--acte { margin-inline-start: auto; }
.saisie__raccourci { display: block; font-size: var(--t-mini); color: var(--encre-2); }

.outil__grille { display: grid; gap: calc(var(--u) * 6); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 60rem) {
  .outil__grille--deux { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
}

.reglages { display: grid; gap: calc(var(--u) * 4); }
.reglage { display: grid; gap: calc(var(--u) * 2); }
.reglage__label { font-family: var(--titre); font-weight: 700; font-size: var(--t-petit); }
.reglage__aide { font-size: var(--t-mini); color: var(--encre-2); margin: 0; }
.reglage input[type="text"], .reglage input[type="number"], .reglage select {
  font: inherit; font-size: var(--t-petit); padding: calc(var(--u) * 2) calc(var(--u) * 3);
  border: 2px solid var(--filet-2); background: var(--plan); color: var(--encre); border-radius: 3px;
}
.case { display: flex; align-items: start; gap: calc(var(--u) * 3); font-size: var(--t-petit); }
.case input { margin: 0.28em 0 0; width: 1.15rem; height: 1.15rem; accent-color: var(--accent); flex: 0 0 auto; }

/* le RÉSULTAT : la pièce sortie de l'étau. Elle porte le tampon de contrôle. */
.resultat { display: grid; gap: calc(var(--u) * 5); }
.resultat__tete { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--u) * 4); }
.resultat__apercu {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 2px solid var(--filet-2); padding: calc(var(--u) * 3);
  min-height: 8rem;
}
.resultat__apercu img { max-height: 22rem; width: auto; box-shadow: var(--plaque); }
.resultat__poids { font-size: var(--t-mini); color: var(--encre-2); }

/* LE CANEVAS INTERACTIF : la pièce prise dans l'étau, avec UNE zone à régler
   dessus (recadrer, flouter). Deux modes, deux lectures :
     cadre — ce qui est HORS de la zone s'assombrit d'un voile dur (c'est ce
             qui va tomber), et la règle des tiers se trace dans la zone ;
     zone  — la zone se HACHURE au pochoir orange (c'est ce qui va être
             traité), et un geste sur l'image en dessine une neuve.
   Les huit poignées sont des têtes de boulon : carrées, bordées d'encre,
   ombre portée dure. Leur surface de prise est PLUS LARGE que leur dessin
   (24 px, 32 px au doigt : les cibles tactiles se prennent, elles ne se
   visent pas), et `touch-action: none` sur la scène empêche l'écran de
   défiler pendant le réglage — le geste appartient à l'étau.
   ⚠ Le canevas lui-même est BORNÉ (max-width, max-height) : un canvas non
   stylé sort à sa taille de pixels et déborde à 500 px — la recette mesure. */
.canevas { display: grid; gap: calc(var(--u) * 3); justify-items: start; }
.canevas__scene {
  position: relative; display: inline-block; max-width: 100%;
  overflow: hidden;                 /* le voile du mode cadre s'arrête à la pièce */
  touch-action: none;               /* le doigt règle la zone, il ne fait pas défiler */
  background: var(--surface); border: 2px solid var(--filet-2);
  box-shadow: var(--plaque);
}
.canevas__image { display: block; max-width: 100%; height: auto; max-height: 26rem; width: auto; }
.canevas__zone {
  position: absolute; cursor: move;
  border: 2px solid var(--accent);
  /* le liseré clair rend le cadre lisible sur une photo sombre : une ombre
     à étalement, blur 0, jamais un halo. */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.65);
}
.canevas--cadre .canevas__zone {
  /* LE VOILE : ce qui est hors zone s'assombrit. Une ombre géante à bord NET
     (spread, blur 0), taillée par l'overflow de la scène : le dedans reste
     la photo, le dehors devient l'atelier éteint. */
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.65),
    0 0 0 200vmax color-mix(in srgb, var(--panneau) 55%, transparent);
}
/* la règle des tiers, tracée au pinceau (stops durs) : quatre filets d'1 px */
.canevas--cadre .canevas__zone::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(90deg, transparent calc(33.333% - 1px), rgba(255, 255, 255, 0.45) calc(33.333% - 1px) 33.333%, transparent 33.333%),
    linear-gradient(90deg, transparent calc(66.666% - 1px), rgba(255, 255, 255, 0.45) calc(66.666% - 1px) 66.666%, transparent 66.666%),
    linear-gradient(180deg, transparent calc(33.333% - 1px), rgba(255, 255, 255, 0.45) calc(33.333% - 1px) 33.333%, transparent 33.333%),
    linear-gradient(180deg, transparent calc(66.666% - 1px), rgba(255, 255, 255, 0.45) calc(66.666% - 1px) 66.666%, transparent 66.666%);
}
/* le pochoir du mode zone : des hachures d'acte, un marquage, pas une nappe */
.canevas--zone .canevas__zone {
  background-image: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--accent) 45%, transparent) 0 2px, transparent 2px 9px);
}
/* les poignées : la tête carrée dessinée petite, la PRISE large autour */
.canevas__p {
  --prise: 24px;
  position: absolute; width: var(--prise); height: var(--prise);
  display: grid; place-items: center;
}
.canevas__p::before {
  content: ""; width: 12px; height: 12px;
  background: var(--plan); border: 2px solid var(--encre);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.45);
}
@media (pointer: coarse) { .canevas__p { --prise: 32px; } }
.canevas__p--nw { top: calc(var(--prise) / -2); left: calc(var(--prise) / -2); cursor: nwse-resize; }
.canevas__p--ne { top: calc(var(--prise) / -2); right: calc(var(--prise) / -2); cursor: nesw-resize; }
.canevas__p--sw { bottom: calc(var(--prise) / -2); left: calc(var(--prise) / -2); cursor: nesw-resize; }
.canevas__p--se { bottom: calc(var(--prise) / -2); right: calc(var(--prise) / -2); cursor: nwse-resize; }
.canevas__p--n { top: calc(var(--prise) / -2); left: calc(50% - var(--prise) / 2); cursor: ns-resize; }
.canevas__p--s { bottom: calc(var(--prise) / -2); left: calc(50% - var(--prise) / 2); cursor: ns-resize; }
.canevas__p--w { left: calc(var(--prise) / -2); top: calc(50% - var(--prise) / 2); cursor: ew-resize; }
.canevas__p--e { right: calc(var(--prise) / -2); top: calc(50% - var(--prise) / 2); cursor: ew-resize; }
.canevas__aide { font-size: var(--t-mini); color: var(--encre-2); margin: 0; max-width: 36rem; }

/* LA FILE D'ATTENTE : le lot posé sur l'établi, une ligne par fichier, chacune
   avec SON état et SON résultat. Un « terminé » global qui cacherait deux
   échecs sur trente serait un mensonge : la ligne dit, le lot ne résume pas.
   Les états parlent par un texte (l'étiquette) ET par le chant de la ligne
   (le filet de gauche) — jamais par la seule couleur. Le vert reste au tampon :
   une ligne « fait » porte l'étiquette de contrôle, qui est SA famille. */
.file { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 2); counter-reset: f; }
.file__item {
  background: var(--plan); border: 2px solid var(--filet-2);
  border-inline-start-width: 6px;
  padding: calc(var(--u) * 3) calc(var(--u) * 4);
  display: grid; gap: calc(var(--u) * 2);
  counter-increment: f;
  position: relative;
}
.file__tete { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--u) * 2) calc(var(--u) * 3); }
.file__nom { font-family: var(--titre); font-weight: 700; font-size: var(--t-petit); overflow-wrap: anywhere; }
.file__nom::before {
  /* le numéro d'ordre du casier : compté par la feuille, jamais écrit */
  content: counter(f);
  display: inline-grid; place-items: center;
  min-width: 1.5rem; height: 1.5rem; margin-inline-end: calc(var(--u) * 2);
  background: var(--surface); border: 1px solid var(--filet-2);
  font-size: var(--t-mini); color: var(--encre-2);
}
.file__poids { font-size: var(--t-mini); color: var(--encre-2); }
.file__etat { margin-inline-start: auto; }
.file__corps { font-size: var(--t-petit); display: grid; gap: calc(var(--u) * 2); justify-items: start; }
.file__corps p { margin: 0; }
.file__motif { color: var(--alerte); }
/* le chant de la ligne suit l'état */
.file__item[data-etat="encours"] { border-inline-start-color: var(--accent); }
.file__item[data-etat="fait"] { border-inline-start-color: var(--encre); }
.file__item[data-etat="echec"] { border-inline-start-color: var(--alerte); }
/* pendant le travail, le chant DÉFILE : le chenillard d'atelier, sur le seul
   filet de gauche. Triple-gardé, et il n'anime que background-position. */
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-animations="off"]) .file__item[data-etat="encours"]::before {
    content: ""; position: absolute; inset-block: 0; inset-inline-start: -6px; width: 6px;
    background-image: repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0 8px, transparent 8px 16px);
    animation: file-chenille 0.8s linear infinite;
  }
}
@keyframes file-chenille {
  from { background-position: 0 0; }
  to { background-position: 0 16px; }
}

/* LA TABLE DES MÉTADONNÉES : la fiche de ce que le fichier raconte. */
.tableau-hote { overflow-x: auto; }
table.fiche { width: 100%; border-collapse: collapse; font-size: var(--t-petit); }
table.fiche th, table.fiche td { text-align: start; padding: calc(var(--u) * 2) calc(var(--u) * 3); border-bottom: 1px solid var(--filet); vertical-align: top; }
table.fiche thead th { font-family: var(--titre); font-size: var(--t-mini); text-transform: uppercase; letter-spacing: 0.08em; color: var(--encre-2); border-bottom: 2px solid var(--encre); }
table.fiche tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface) 55%, transparent); }
table.fiche td.val { font-family: var(--mono); font-size: 0.9em; overflow-wrap: anywhere; }
table.fiche tr[data-sensible="oui"] { background: var(--accent-fond) !important; }
table.fiche tr[data-sensible="oui"] th { color: var(--accent-fonce); }
.groupe-tete th {
  background: var(--surface); font-family: var(--titre); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em; font-size: var(--t-mini);
}

/* le CARTOUCHE d'alerte : ce que le fichier révèle de vous. Orange = un ACTE
   à faire, pas une décoration. C'est LA scène du site : le constat tombe
   ligne par ligne (cascade), et un trait de marqueur SE TRACE sous chaque
   information qui vous situe. Dramatiser le fait, jamais angoisser : le
   rythme fait le travail, les mots restent ceux du contenu. */
.revele {
  background: var(--accent-fond); border: 2px solid var(--accent);
  border-inline-start-width: 8px; padding: calc(var(--u) * 4);
}
.revele h3 {
  margin-bottom: calc(var(--u) * 2); color: var(--accent-fonce);
  font-size: 1rem; text-transform: uppercase; letter-spacing: 0.08em;
}
.revele p:last-child { margin-bottom: 0; }
.revele__liste { list-style: none; margin: calc(var(--u) * 3) 0 0; padding: 0; display: grid; gap: calc(var(--u) * 2.5); }
.revele__liste li { display: flex; gap: calc(var(--u) * 2); align-items: baseline; }
.revele__liste .ic { color: var(--accent); }
/* le trait de marqueur : un APLAT peint au gradient dégénéré (une seule
   couleur : c'est un pinceau, pas un dégradé), déclaré à l'état FINAL —
   sans animation (préférence, vieux navigateur), le trait est simplement là. */
.revele__liste li > span {
  background: linear-gradient(var(--accent) 0 0) no-repeat bottom left / 100% 2px;
  padding-bottom: calc(var(--u) * 0.5);
}
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-animations="off"]) .revele__liste li {
    animation: revele-ligne 240ms cubic-bezier(0.2, 0.8, 0.4, 1) both;
  }
  :root:not([data-animations="off"]) .revele__liste li > span {
    animation: revele-marque 420ms ease-out both;
  }
  /* la cascade : les huit premières lignes suffisent (le constat en montre
     rarement plus), les suivantes arrivent avec la dernière vague. */
  :root:not([data-animations="off"]) .revele__liste li:nth-child(1) { animation-delay: 60ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(2) { animation-delay: 140ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(3) { animation-delay: 220ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(4) { animation-delay: 300ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(5) { animation-delay: 380ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(6) { animation-delay: 460ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(7) { animation-delay: 540ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(n+8) { animation-delay: 620ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(1) > span { animation-delay: 320ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(2) > span { animation-delay: 400ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(3) > span { animation-delay: 480ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(4) > span { animation-delay: 560ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(5) > span { animation-delay: 640ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(6) > span { animation-delay: 720ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(7) > span { animation-delay: 800ms; }
  :root:not([data-animations="off"]) .revele__liste li:nth-child(n+8) > span { animation-delay: 880ms; }
}
@keyframes revele-ligne {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
@keyframes revele-marque {
  from { background-size: 0% 2px; }
  to { background-size: 100% 2px; }
}
/* le même marqueur rappelé dans la fiche complète : les lignes sensibles
   portent leur trait latéral (inset dur, pas une bordure : zéro décalage). */
table.fiche tr[data-sensible="oui"] th { box-shadow: inset 4px 0 0 var(--accent); }

/* le message de LIMITE : un fichier refusé DIT pourquoi. Jamais un écran mort. */
.limite {
  background: var(--alerte-fond); border: 2px solid var(--alerte);
  border-inline-start-width: 8px; padding: calc(var(--u) * 4);
}
.limite h3 { margin-bottom: calc(var(--u) * 2); color: var(--alerte); }
.limite p:last-child, .limite ul:last-child { margin-bottom: 0; }

/* LE BANDEAU DE CONFIANCE, sur CHAQUE page outil. Il vit dans le gabarit :
   personne ne peut l'oublier. */
.confiance {
  background: var(--panneau); color: #fff; border: 3px solid var(--encre);
  background-image: var(--grain);
  background-size: 160px 160px;
  box-shadow:
    var(--plaque-encre),
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  padding: calc(var(--u) * 5) calc(var(--u) * 6);
  display: grid; gap: calc(var(--u) * 3);
}
.confiance__tete { display: flex; align-items: center; gap: calc(var(--u) * 3); }
.confiance__tete .ic { color: var(--vert-clair); }
.confiance h2 { margin: 0; font-size: 1.1875rem; color: #fff; }
.confiance p { margin: 0; color: #D6D9DE; font-size: var(--t-petit); }
.confiance code { background: rgba(255, 255, 255, 0.1); padding: 1px 6px; color: #fff; }
.confiance a { color: var(--accent-clair); }
.confiance__pas { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 2); counter-reset: p; }
.confiance__pas li { display: flex; gap: calc(var(--u) * 3); align-items: baseline; font-size: var(--t-petit); color: #D6D9DE; counter-increment: p; }
.confiance__pas li::before {
  content: counter(p); flex: 0 0 1.5rem; height: 1.5rem; display: grid; place-items: center;
  background: var(--accent); color: #fff; font-family: var(--titre); font-weight: 700; font-size: var(--t-mini);
}

/* LE TAMPON « TRAITÉ LOCALEMENT ✓ » : la seule chose verte du site. Il apparaît
   quand le travail est FAIT, jamais avant — et c'est LE moment de vérité du
   site, alors il FRAPPE comme un tampon d'atelier :
     1. il tombe (chute accélérée), ÉCRASE la page, rebondit, et reste posé à
        -0,75° — un tampon posé à la main n'est jamais parfaitement droit ;
     2. l'impact pousse une ONDE : un box-shadow à spread animé, blur 0 (une
        ombre dure ne crée jamais de débordement mesurable, ni de reflow) ;
     3. la coche SE TRACE, comme un paraphe.
   ⚠ Règle machine du vert (audit) : var(--vert…) ne s'écrit QUE sous un
   sélecteur de la famille du tampon. Les @keyframes passent donc par les
   variables --onde/--onde-0 déclarées ICI, jamais par var(--vert) direct. */
.tampon {
  --onde: color-mix(in srgb, var(--vert) 45%, transparent);
  --onde-0: color-mix(in srgb, var(--vert) 0%, transparent);
  display: inline-flex; align-items: center; gap: calc(var(--u) * 2.5);
  background: var(--vert-fond); border: 3px solid var(--vert); color: var(--vert-txt);
  padding: calc(var(--u) * 2.5) calc(var(--u) * 4);
  font-family: var(--titre); font-weight: 700; font-size: var(--t-petit);
  letter-spacing: 0.05em; text-transform: uppercase;
}
.tampon .ic { color: var(--vert); }
.tampon--anime {
  animation:
    tampon-frappe 560ms both,
    tampon-onde 520ms 200ms both;
}
.tampon--anime .ic path { animation: tampon-coche 300ms 360ms both; }
@keyframes tampon-frappe {
  0% { transform: scale(2.2) rotate(-5deg); opacity: 0; animation-timing-function: cubic-bezier(0.5, 0, 0.85, 0.4); }
  10% { opacity: 1; }
  36% { transform: scale(0.93) rotate(0.7deg); animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1); }
  60% { transform: scale(1.04) rotate(-1.1deg); }
  80% { transform: scale(0.99) rotate(-0.6deg); }
  100% { transform: scale(1) rotate(-0.75deg); opacity: 1; }
}
@keyframes tampon-onde {
  from { box-shadow: 0 0 0 0 var(--onde); }
  to { box-shadow: 0 0 0 18px var(--onde-0); }
}
@keyframes tampon-coche {
  from { stroke-dasharray: 24; stroke-dashoffset: 24; }
  to { stroke-dasharray: 24; stroke-dashoffset: 0; }
}
/* sans mouvement (préférence système OU réglage du panneau) : le tampon est
   POSÉ, droit, immédiat. Le changement d'état reste parfaitement lisible. */
@media (prefers-reduced-motion: reduce) {
  .tampon--anime, .tampon--anime .ic path { animation: none; }
}
:root[data-animations="off"] .tampon--anime,
:root[data-animations="off"] .tampon--anime .ic path { animation: none; }

/* LES PORTES : ce qui vit SOUS l'outil. Rien d'autre que des portes. */
.portes { display: grid; gap: calc(var(--u) * 4); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.porte {
  display: flex; flex-direction: column; gap: calc(var(--u) * 2);
  background: var(--plan); border: 2px solid var(--filet-2); box-shadow: var(--plaque);
  padding: calc(var(--u) * 4); text-decoration: none; color: var(--encre);
  transition: transform var(--lever), box-shadow var(--lever), border-color var(--lever);
}
/* une porte se SAISIT : elle se soulève vers la main, l'ombre s'allonge. */
.porte:hover {
  color: var(--encre); border-color: var(--accent);
  transform: translate(-2px, -2px);
  box-shadow: var(--plaque-lever-accent);
}
.porte:active { transform: none; box-shadow: var(--plaque-accent); }
.porte__quoi { font-family: var(--titre); font-size: var(--t-mini); text-transform: uppercase; letter-spacing: 0.09em; color: var(--encre-2); }
.porte__titre { font-family: var(--titre); font-weight: 700; font-size: 1.0625rem; display: flex; align-items: center; gap: calc(var(--u) * 2); }
.porte__titre .ic { color: var(--accent); }
.porte p { margin: 0; font-size: var(--t-petit); color: var(--encre-2); }

/* la barre d'état de l'outil (progression réelle, jamais fausse) */
.etat { display: flex; align-items: center; gap: calc(var(--u) * 3); font-size: var(--t-petit); }
.jauge { flex: 1; height: 10px; background: var(--surface); border: 2px solid var(--filet-2); overflow: hidden; }
.jauge__barre { height: 100%; width: 0; background: var(--accent); transition: width 90ms linear; }

/* LES PAS NUMÉROTÉS, EN PAGE.
   ⚠ Ils ont leur PROPRE classe : le bandeau de confiance a les siens, clairs
   sur graphite (`.confiance__pas li { color: #D6D9DE }`), et réutiliser sa
   classe en page rendait le texte gris pâle sur papier — illisible. Un style
   en ligne sur le `<ol>` n'y changeait rien : la règle du `li` est plus
   spécifique. Vu à l'œil sur la page « La preuve ». */
.pas { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 5); counter-reset: p; }
.pas li {
  display: flex; gap: calc(var(--u) * 3); align-items: baseline;
  color: var(--encre); counter-increment: p;
}
.pas li::before {
  content: counter(p); flex: 0 0 1.75rem; height: 1.75rem;
  display: grid; place-items: center; background: var(--accent); color: #fff;
  font-family: var(--titre); font-weight: 700; font-size: var(--t-mini);
}

/* --- utilitaires NOMMÉS. Le générateur n'écrit AUCUN style en ligne : c'est
   une règle du projet, et l'audit la tient. Une DA qu'une passe design va
   reprendre doit vivre entièrement dans la feuille de style. */
.u-rang { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 3) calc(var(--u) * 6); }
.u-apres { margin-top: calc(var(--u) * 6); }
.u-apres-l { margin-top: calc(var(--u) * 10); }
.u-note { color: var(--encre-2); font-size: var(--t-petit); }
.u-mini { color: var(--encre-2); font-size: var(--t-mini); }
.plaque--clair { background: var(--plan); }
.matrice .note-l { text-align: start; color: var(--encre-2); }

/* ============================================== 14. BLOCS DE PAGE (le socle) */
.bloc { margin-bottom: calc(var(--u) * 10); }
.bloc:last-child { margin-bottom: 0; }
.bloc h2 { margin-bottom: calc(var(--u) * 4); }
.liste-marquee { list-style: none; padding: 0; display: grid; gap: calc(var(--u) * 3); }
.liste-marquee li { display: flex; gap: calc(var(--u) * 3); align-items: baseline; }
.liste-marquee .ic { color: var(--accent); }
.regles { display: grid; gap: calc(var(--u) * 4); }
.regle { border-inline-start: 5px solid var(--accent); padding-inline-start: calc(var(--u) * 4); }
.regle h3 { margin-bottom: calc(var(--u) * 1.5); }
.regle p { margin: 0; color: var(--encre-2); }
.qr { border: 2px solid var(--filet-2); background: var(--plan); margin-bottom: calc(var(--u) * 3); }
.qr > summary {
  cursor: pointer; padding: calc(var(--u) * 3) calc(var(--u) * 4);
  font-family: var(--titre); font-weight: 700; list-style: none;
  display: flex; gap: calc(var(--u) * 3); align-items: center; justify-content: space-between;
}
.qr > summary::-webkit-details-marker { display: none; }
.qr > summary .ic { color: var(--accent); transition: transform var(--transition); }
.qr[open] > summary .ic { transform: rotate(180deg); }
.qr > div { padding: 0 calc(var(--u) * 4) calc(var(--u) * 4); }
.chiffres { display: grid; gap: calc(var(--u) * 4); grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.chiffre { background: var(--plan); border: 2px solid var(--filet-2); box-shadow: var(--plaque); padding: calc(var(--u) * 4); }
.chiffre__n { display: block; font-family: var(--titre); font-weight: 700; font-size: 2.5rem; line-height: 1; letter-spacing: -0.03em; }
.chiffre__q { display: block; font-size: var(--t-mini); color: var(--encre-2); margin-top: calc(var(--u) * 2); }
.note { background: var(--surface); border-inline-start: 6px solid var(--encre); padding: calc(var(--u) * 4); }
.note--accent { border-inline-start-color: var(--accent); background: var(--accent-fond); }
.liens-blocs { display: grid; gap: calc(var(--u) * 3); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); list-style: none; padding: 0; }
.liens-blocs a { display: flex; align-items: center; gap: calc(var(--u) * 2); background: var(--plan); border: 2px solid var(--filet-2); padding: calc(var(--u) * 3) calc(var(--u) * 4); text-decoration: none; font-weight: 700; }
.liens-blocs a:hover { border-color: var(--accent); }
.plan-liste { list-style: none; padding: 0; columns: 2; column-gap: calc(var(--u) * 8); }
.plan-liste li { break-inside: avoid; margin-bottom: calc(var(--u) * 2); }
.polices { display: grid; gap: calc(var(--u) * 4); }
.police { border: 2px solid var(--filet-2); background: var(--plan); padding: calc(var(--u) * 4); }
.police__nom { font-family: var(--titre); font-weight: 700; font-size: 1.375rem; }
.journal-entree { border-inline-start: 5px solid var(--filet-2); padding-inline-start: calc(var(--u) * 4); margin-bottom: calc(var(--u) * 8); }
.journal-entree time { font-family: var(--titre); font-size: var(--t-mini); letter-spacing: 0.08em; text-transform: uppercase; color: var(--encre-3); }

/* la MATRICE de compatibilité : le tableau daté qui dit la vérité. */
.matrice { width: 100%; border-collapse: collapse; font-size: var(--t-mini); }
.matrice th, .matrice td { padding: calc(var(--u) * 2); border: 1px solid var(--filet); text-align: center; }
.matrice thead th { background: var(--panneau); color: #fff; font-family: var(--titre); text-transform: uppercase; letter-spacing: 0.06em; }
.matrice tbody th { text-align: start; font-weight: 700; background: var(--surface); }
/* ⚠ NI VERT NI ORANGE ICI. Le vert est réservé au tampon « traité
   localement » et l'orange aux ACTES (fiche §5) : un « oui » de tableau n'est
   ni l'un ni l'autre. L'encre pleine dit oui, l'encre discrète dit non, et le
   signal d'alerte dit « en partie », qui est exactement une réserve à lire. */
.matrice td[data-o="oui"] { color: var(--encre); font-weight: 700; }
.matrice td[data-o="non"] { color: var(--encre-3); }
.matrice td[data-o="partiel"] { color: var(--alerte); font-weight: 700; }

/* ============================================================ 15. LE PIED */
.pied {
  background: var(--panneau); color: #C9CDD4;
  background-image: var(--grain);
  background-size: 160px 160px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
  padding-block: calc(var(--u) * 12) calc(var(--u) * 8);
  border-top: 4px solid var(--accent); font-size: var(--t-petit);
}
.pied a { color: #fff; text-decoration: none; }
.pied a:hover { color: var(--accent-clair); text-decoration: underline; text-decoration-thickness: 2px; }
.pied__grille { display: grid; gap: calc(var(--u) * 8); grid-template-columns: 1.4fr repeat(4, 1fr); }
.pied h2 { font-size: var(--t-mini); text-transform: uppercase; letter-spacing: 0.1em; color: #fff; margin-bottom: calc(var(--u) * 3); }
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 2); }
.pied__nom { font-family: var(--titre); font-weight: 700; font-size: 1.1875rem; color: #fff; margin: calc(var(--u) * 3) 0 calc(var(--u) * 2); }
.pied__contact { display: grid; gap: calc(var(--u)); margin-top: calc(var(--u) * 3); }
.pied__contact span { color: #9AA0A9; font-size: var(--t-mini); }
.pied__bas { border-top: 1px solid #3A4048; margin-top: calc(var(--u) * 10); padding-top: calc(var(--u) * 6); display: grid; gap: calc(var(--u) * 3); font-size: var(--t-mini); color: #9AA0A9; }
.pied__bas p { margin: 0; }
/* le cachet dateur vit aussi DANS une page (la matrice le porte) : au pied il
   est clair sur graphite, en page il doit reprendre l'encre. Sans cette règle
   il était un cadre vide sur la page méthode. Vu à l'œil. */
main .pied__cachet { color: var(--encre-2); border-color: var(--filet-2); }
.pied__cachet {
  justify-self: start; display: inline-flex; align-items: center; gap: calc(var(--u) * 2);
  border: 2px solid #4A5058; color: #C9CDD4; padding: calc(var(--u) * 1.5) calc(var(--u) * 3);
  font-family: var(--titre); font-size: var(--t-mini); letter-spacing: 0.08em; text-transform: uppercase;
}

/* =================================================== 16. LE PANNEAU LATÉRAL */
.panneau-b {
  position: fixed; inset-inline-end: 0; inset-block-start: 42vh; z-index: 46;
  display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 2);
  background: var(--panneau); color: #fff; border: 0; border-inline-start: 3px solid var(--accent);
  padding: calc(var(--u) * 4) calc(var(--u) * 2); cursor: pointer;
  font-family: var(--titre); font-weight: 700; font-size: var(--t-mini);
}
.panneau-b__txt { writing-mode: vertical-rl; letter-spacing: 0.12em; text-transform: uppercase; }
.panneau-voile {
  position: fixed; inset: 0; z-index: 47; background: rgba(20, 22, 26, 0.55);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 200ms linear, visibility 0s 200ms;
}
.panneau-voile[data-ouvert="oui"] { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity 200ms linear, visibility 0s; }
.panneau {
  position: fixed; inset-block: 0; inset-inline-end: 0; z-index: 48;
  width: min(26rem, 100%); background: var(--atelier); color: var(--encre);
  border-inline-start: 4px solid var(--accent);
  display: flex; flex-direction: column;
  transform: translateX(101%); visibility: hidden;
  transition: transform 200ms ease-out, visibility 0s 200ms;
}
/* ⚠ La VISIBILITÉ ne transitionne qu'à la FERMETURE : au focus() synchrone de
   l'ouverture, une visibility en cours de transition vaut encore « hidden » et
   le focus échoue EN SILENCE (le piège à focus ne s'amorce pas). */
.panneau[data-ouvert="oui"] { transform: none; visibility: visible; transition: transform 200ms ease-out, visibility 0s; }
.panneau__tete { display: flex; align-items: center; justify-content: space-between; gap: calc(var(--u) * 4); padding: calc(var(--u) * 5); border-bottom: 2px solid var(--filet); }
.panneau__tete h2 { margin: 0; font-size: 1.1875rem; }
.panneau__x { background: none; border: 2px solid var(--encre); color: var(--encre); padding: calc(var(--u)); cursor: pointer; }
.panneau__corps { overflow-y: auto; padding: calc(var(--u) * 5); display: grid; gap: calc(var(--u) * 7); }
.panneau__bloc h3 { font-size: var(--t-mini); text-transform: uppercase; letter-spacing: 0.1em; color: var(--encre-2); margin-bottom: calc(var(--u) * 3); }
.panneau__ligne { display: flex; align-items: center; justify-content: space-between; gap: calc(var(--u) * 3); margin-bottom: calc(var(--u) * 3); }
.panneau__label { font-size: var(--t-petit); }
.panneau__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 1); }
.panneau__liste a, .panneau__liste button {
  display: flex; align-items: center; gap: calc(var(--u) * 3); width: 100%;
  background: none; border: 0; font: inherit; font-size: var(--t-petit); color: var(--encre);
  text-align: start; padding: calc(var(--u) * 2); cursor: pointer; text-decoration: none;
}
.panneau__liste a:hover, .panneau__liste button:hover { background: var(--surface); color: var(--encre); }
.panneau__liste .ic { color: var(--accent); }
.panneau__danger:hover { background: var(--accent-fond); }
.panneau__langues { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: calc(var(--u) * 2); }
.panneau__langues a { display: block; border: 2px solid var(--filet-2); padding: calc(var(--u) * 1.5) calc(var(--u) * 3); text-decoration: none; font-size: var(--t-petit); }
.panneau__langues a[aria-current] { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
.panneau__note { display: flex; align-items: center; gap: calc(var(--u) * 2); margin: 0; font-size: var(--t-petit); }
.panneau__pied { margin: 0; padding: calc(var(--u) * 4) calc(var(--u) * 5); border-top: 2px solid var(--filet); font-size: var(--t-mini); color: var(--encre-2); }
.seg { display: inline-flex; border: 2px solid var(--filet-2); }
.seg__b {
  background: var(--plan); border: 0; border-inline-end: 2px solid var(--filet-2);
  font-family: var(--titre); font-weight: 700; font-size: var(--t-mini);
  padding: calc(var(--u) * 1.5) calc(var(--u) * 3); cursor: pointer; color: var(--encre);
}
.seg__b:last-child { border-inline-end: 0; }
.seg__b[aria-pressed="true"] { background: var(--accent); color: #fff; }
.raccourcis { display: grid; grid-template-columns: auto 1fr; gap: calc(var(--u) * 2) calc(var(--u) * 4); margin: 0; font-size: var(--t-mini); }
.raccourcis dt, .raccourcis dd { margin: 0; }

/* ======================================================== 17. LE RESPONSIVE */
@media (max-width: 68rem) {
  .pied__grille { grid-template-columns: 1fr 1fr; }
  .hero__in { grid-template-columns: minmax(0, 1fr); }
  .mur__grille { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 52rem) {
  :root { --gouttiere: 1.125rem; }
  .tete__bascule { display: inline-flex; }
  .nav { flex-basis: 100%; display: none; }
  .nav[data-ouvert="oui"] { display: block; }
  .nav ul { flex-direction: column; gap: 0; border-top: 2px solid var(--filet); }
  .nav a { padding-block: calc(var(--u) * 3); border-bottom: 2px solid var(--filet); }
  .nav a[aria-current], .nav a:hover { border-bottom-color: var(--accent); }
  .plan-liste { columns: 1; }
  .chiffre__n { font-size: 2rem; }
  .panneau-b { inset-block-start: auto; inset-block-end: 0; inset-inline-end: 0; flex-direction: row; border-inline-start: 0; border-top: 3px solid var(--accent); }
  .panneau-b__txt { writing-mode: horizontal-tb; }
}
@media (max-width: 34rem) {
  .pied__grille { grid-template-columns: 1fr; }
  .mur__grille { grid-template-columns: repeat(2, 1fr); }
  .b--rang { flex-direction: column; align-items: stretch; }
  .b { width: 100%; }
  .b--rang .b { width: auto; }
  .depot { padding: calc(var(--u) * 8) calc(var(--u) * 4); }
  .resultat__tete { flex-direction: column; align-items: stretch; }
}

/* ===================================================== 18. LECTURE, IMPRESSION */
:root[data-lecture="oui"] .utilite,
:root[data-lecture="oui"] .bandeau,
:root[data-lecture="oui"] .nav,
:root[data-lecture="oui"] .chercher,
:root[data-lecture="oui"] .portes { display: none; }
:root[data-lecture="oui"] .wrap { max-width: var(--etroit); }

@media print {
  .utilite, .bandeau, .nav, .tete__bascule, .panneau, .panneau-b, .panneau-voile,
  .saut, .portes, .depot, .saisie, .canevas__p, .canevas__aide, .b, .jauge { display: none !important; }
  /* le PAPIER ne défile pas : toute animation (révélations au défilement,
     tampon, cascade du constat, chenillard de la file) se neutralise, et
     l'état de base est l'état PLEIN. Sans cette règle, une page imprimée
     sortirait avec des sections à opacité nulle (piège du scroll-driven en
     média paginé). */
  .coin, .porte, .chiffre, .regle, .police, .journal-entree,
  .tampon--anime, .tampon--anime .ic path, .file__item[data-etat="encours"]::before,
  .revele__liste li, .revele__liste li > span { animation: none !important; }
  body { background: #fff; color: #000; background-image: none; font-size: 11pt; }
  .plaque, .coin, .chiffre, .porte, .confiance, .mur { box-shadow: none !important; border-color: #666 !important; }
  .confiance, .section--panneau, .plaque--sombre, .pied { background: #fff !important; color: #000 !important; }
  .confiance p, .pied, .pied__bas { color: #333 !important; }
  a { color: #000; text-decoration: underline; }
  .section { padding-block: 8pt; }
  /* Chrome ≥ 131 masque le contenu d'un <details> fermé par content-visibility
     sur ::details-content : la règle moderne s'écrit SÉPARÉMENT, sinon un
     sélecteur inconnu jette toute la règle. */
  details.qr > div { display: block !important; }
  details.qr:not([open])::details-content { content-visibility: visible; display: block; }
}

/* ============================================== 19. LE MOUVEMENT DE PAGE
   (passe design) Deux étages, tous deux en AMÉLIORATION PROGRESSIVE : un
   navigateur qui ne les connaît pas rend exactement le site d'avant.

   A. LES RÉVÉLATIONS AU DÉFILEMENT (scroll-driven animations, CSS pur).
      Ce qui entre dans la fenêtre SE POSE sur l'établi : 16 px de descente,
      rien d'autre. La timeline est le défilement lui-même (animation-timeline:
      view()) : aucun JavaScript, aucun observateur. Un élément déjà visible au
      chargement est déjà posé (sa plage « entry » est derrière lui).
      ⚠ Règles de recette tenues : jamais l'axe X, jamais un scale > 1 —
      aucun débordement mesurable, même en cours d'animation.
      ⚠ Ordre des déclarations : animation-timeline TOUJOURS après la
      shorthand animation (la shorthand la réinitialise).

   B. LES TRANSITIONS DE PAGE (view transitions cross-document). Un fondu de
      160 ms entre deux pages du site, et le wordmark RESTE EN PLACE pendant
      le fondu : l'atelier ne bouge pas, on change d'établi. Chrome et Safari
      les jouent ; Firefox les ignore et navigue comme avant. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    :root:not([data-animations="off"]) :is(.coin, .porte, .chiffre, .regle, .police, .journal-entree) {
      animation: se-poser linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }
  }
}
@keyframes se-poser {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 160ms; }
.marque { view-transition-name: marque; }
/* sans mouvement (préférence système OU réglage du panneau) : navigation
   franche, immédiate — la transition se résout sur-le-champ. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none; }
}
:root[data-animations="off"]::view-transition-group(*),
:root[data-animations="off"]::view-transition-old(*),
:root[data-animations="off"]::view-transition-new(*) { animation: none; }

/* ============================================== 20. LES FINITIONS D'ATELIER */
/* la sélection de texte : le pochoir inversé, franc, lisible dans les deux
   thèmes (l'encre et l'atelier échangent leurs places). */
::selection { background: var(--encre); color: var(--atelier); }
/* la barre de défilement prend les filets de l'établi (et suit le thème). */
html { scrollbar-color: var(--filet-2) transparent; }
/* les chapeaux ne laissent pas un mot orphelin en dernière ligne. */
.chapeau, .hero__punch, .outil__punch { text-wrap: pretty; }
