@charset "UTF-8";
@import "./polices/polices.css";

/* ==========================================================================
   TARIQ — feuille de style de l'identité
   --------------------------------------------------------------------------
   Source de vérité : ux-tariq-2026-08-15/DESIGN.md (14-15/08/2026).
   Cette feuille IMPLÉMENTE cette identité ; elle ne la réinvente pas.

   ┌ MISE EN CACHE ────────────────────────────────────────────────────────┐
   │ Le fichier est immuable et doit être servi avec un cache long          │
   │ (`Cache-Control: public, max-age=31536000, immutable`) MAIS le lien    │
   │ DOIT porter une empreinte de contenu :                                 │
   │     <link rel="stylesheet" href="/tariq.css?v=a1b2c3d4">               │
   │ L'empreinte = 8 premiers caractères du SHA-1 du fichier.               │
   │ Le script `empreinte.py` (même dossier) la recalcule et réécrit les    │
   │ liens. Sans empreinte, le cache de 7 jours du site actuel repousse la  │
   │ correction d'un défaut d'une semaine chez chaque visiteur : c'est le   │
   │ défaut n°1 relevé sur la production, il ne doit pas se reproduire.     │
   └────────────────────────────────────────────────────────────────────────┘

   RÈGLE QUI TIENT TOUT : le rouge AGIT, le vert PROUVE, l'encre PARLE.
   Un bouton vert est une faute. Un bouton rouge qui ne fait pas avancer
   dans le parcours est une faute.

   SOMMAIRE
     01. Jetons — couleurs
     02. Jetons — typographie et échelle
     03. Jetons — espacement, formes, ombres, mouvement, largeurs
     04. Réinitialisation
     05. Base typographique
     06. Mise en page — page, sections, conteneurs, grille
     07. Composant — bouton
     08. Composant — lien
     09. Composant — carte
     10. Composant — pastille d'état
     11. Composant — visa
     12. Composant — bloc de preuve et liste à puces hexagonales
     13. Composant — champ de formulaire
     14. Composant — tableau
     15. Composant — accordéon
     16. Composant — onglets
     17. Composant — bandeau de progression et jalons
     18. Composant — note / alerte
     19. Composant — en-tête
     20. Composant — pied de page
     21. Composant — sceau et filigrane zellige
     22. Motifs animables — convention TA-App (Framer Motion + 21st.dev)
     23. États transverses — focus, désactivé, attente
     24. Utilitaires
     25. Points de rupture
     26. Mouvement réduit
   ========================================================================== */


/* ==========================================================================
   01. JETONS — COULEURS
   --------------------------------------------------------------------------
   26/08/2026 — les valeurs sont celles du SITE PUBLIC, relevées dans
   `/opt/maison-tariq-site/public/site.css` (papier · encre · garance · or).
   Le client qui passe de tariq-ai.com à son compte ne doit pas changer
   d'univers au moment où il sort sa carte : c'est la raison de ce réglage.

   AUCUN JETON N'EST RENOMMÉ. Les 2 000 lignes qui suivent en dépendent :
   seules les valeurs changent, la cascade fait le reste.

   Les contrastes annoncés sont mesurés (WCAG 2.1) sur les trois fonds du
   système, dans cet ordre : papier · papier-creux · papier-haut.
   Plancher tenu : 4,5:1 pour tout texte, 3:1 pour tout contour d'élément.
   ========================================================================== */

:root {
  /* Fonds — LE PAPIER ------------------------------------------------------
     Les trois papiers du site public : --color-papier, --color-papier-creux,
     --color-papier-haut.                                                   */
  --tq-ivoire:        #F8F5F1;  /* papier — fond de page, partout            */
                                /* oklch(97.2% .006 85)                      */
  --tq-ivoire-2:      #EFECE7;  /* papier-creux — sections alternées, pied   */
                                /* oklch(94.5% .008 85)                      */
  /* Le blanc PUR a disparu du système : sur un papier chaud il creuse un
     trou froid, et c'est exactement ce qui trahissait l'espace compte. Les
     cartes et les champs prennent désormais le papier-haut du site public. */
  --tq-blanc:         #FCFBF8;  /* papier-haut — oklch(98.8% .004 85)        */

  /* Encre — brun-noir de manuscrit, jamais bleu-noir --------------------- */
  --tq-encre:         #251D0D;  /* titres et texte courant                   */
                                /* 15,33 · 14,14 · 16,10                     */
  --tq-encre-70:      #433C2F;  /* corps, légendes — 10,03 · 9,25 · 10,54    */
  --tq-encre-45:      #635D50;  /* mentions, provenance — 6,02 · 5,55 · 6,32 */
  /* CONTOUR D'ÉLÉMENT. Délimite tout ce qui doit se repérer comme
     ACTIONNABLE : champs, cases à cocher, interrupteurs, listes déroulantes.
     Le fond d'un champ ne se détache du papier que de 1,04:1 — autant dire
     pas du tout : ce liseré est la SEULE limite visible du champ, il doit
     donc tenir les 3:1 de la WCAG.
     Le `filet-fort` du site public (oklch 80 %) n'y rend que 1,72:1 : il
     habille des séparateurs, pas des contours de champ. On garde sa teinte
     et on la fonce jusqu'à oklch(60% .018 85), qui tient partout —
     3,62 · 3,34 · 3,80. Ne JAMAIS l'éclaircir.                            */
  --tq-encre-30:      #858074;
  /* DÉCORATIF UNIQUEMENT — 1,72:1 sur papier. C'est le `filet-fort` du site
     public : bordure du bouton secondaire au repos, survol de carte,
     poignée, ascenseur. Ne JAMAIS délimiter un champ avec ce jeton.        */
  --tq-encre-20:      #C2BDB2;  /* filet-fort — oklch(80% .016 85)           */
  --tq-lisere:        #DDD9D0;  /* filet — bordures et séparateurs, chaud,   */
                                /* jamais gris neutre — oklch(88.5% .012 85) */

  /* Garance — L'ACTION -----------------------------------------------------
     Le rouge du site public. La règle ne change pas : le rouge AGIT.       */
  --tq-rouge:         #9A303C;  /* 6,75 · 6,23 · 7,09 ; papier-haut dessus   */
                                /* 7,09:1 — oklch(47% .14 18)                */
  /* Survol et appui du bouton de progression, et texte des notes d'action.
     Le site public n'a pas de garance PLUS SOMBRE — sa `garance-vive` est
     plus claire, donc inutilisable ici. On descend la même teinte à
     oklch(38% .13 18) : 9,87 · 9,10 · 10,36, et 8,94:1 sur le voile.      */
  --tq-rouge-sombre:  #781827;
  /* La seule garance plus claire du site public (`garance-vive`).
     ILLUSTRATION UNIQUEMENT — 4,94:1 sur papier : aucun petit texte dessus,
     aucun aplat sous du texte clair.                                       */
  --tq-rouge-pale:    #B94149;  /* garance-vive — oklch(54.5% .155 20)       */
  --tq-rouge-voile:   #FAE6E5;  /* garance-pâle — fond d'alerte et de        */
                                /* pastille ; garance-sombre dessus 8,94:1   */
                                /* oklch(94% .022 20)                        */

  /* Vert-visa — LA PREUVE --------------------------------------------------
     Le `--color-visa` du site public. La règle ne change pas : le vert
     PROUVE — sceaux, visas, confirmations, état actif.                     */
  --tq-vert:          #316847;  /* 6,04 · 5,57 · 6,34 ; papier-haut dessus   */
                                /* 6,34:1 — oklch(47% .08 155)               */
  /* Glacis — coches, jalons accomplis, étiquette de preuve. Un cran plus
     sombre que le sceau, pour rester lisible sur le papier creux :
     7,50 · 6,92 · 7,88 — oklch(42% .085 155).                             */
  --tq-vert-clair:    #1E5A38;
  /* Voile de visa. Le site public n'a pas de vert pâle : on le dérive de sa
     propre teinte, oklch(94.5% .018 155). Le vert-visa y tient 5,64:1, le
     glacis 7,01:1.                                                         */
  --tq-vert-voile:    #E4F1E8;

  /* Attention — L'OR -------------------------------------------------------
     Aucune couleur inventée : c'est l'or du site public. Fond `or-pâle`,
     texte `or-texte` — 6,00:1 l'un sur l'autre, 6,77:1 sur papier.         */
  --tq-attention:       #F3E7CE;  /* or-pâle  — oklch(93% .035 85)           */
  --tq-attention-texte: #6C5212;  /* or-texte — oklch(45.5% .085 85)         */
  /* L'or plein du site public (oklch(66% .11 85), 2,89:1 sur papier) n'est
     PAS un jeton de texte : il ne sert qu'à des aplats et des filets.      */

  /* Voile de modale — l'encre du nouveau système, et non plus le bleu-noir.       */
  --tq-voile:         rgb(37 29 13 / .42);
}


/* ==========================================================================
   02. JETONS — TYPOGRAPHIE ET ÉCHELLE
   Échelle en tierce majeure (1,250), ancrée à 16 px.
   Spectral titre — Archivo parle — IBM Plex Mono ne sert QU'AUX VISAS.
   Les trois piles sont copiées À LA LETTRE de `site.css` (--font-titre,
   --font-corps, --font-mono) : deux écritures différentes des mêmes piles
   feraient diverger les replis quand la police web n'arrive pas.
   ========================================================================== */

:root {
  --tq-fonte-titre: "Spectral", "Iowan Old Style", Georgia, serif;
  --tq-fonte-ui:    "Archivo", "Helvetica Neue", Arial, sans-serif;
  --tq-fonte-mono:  "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Échelle nue — tierce majeure à partir de 16 px (référence).
     -2 = 10,24px · -1 = 12,8px · 0 = 16px · 1 = 20px · 2 = 25px
      3 = 31,25px · 4 = 39,06px · 5 = 48,83px                              */
  --tq-echelle--2: .64rem;
  --tq-echelle--1: .8rem;
  --tq-echelle-0:  1rem;
  --tq-echelle-1:  1.25rem;
  --tq-echelle-2:  1.5625rem;
  --tq-echelle-3:  1.9531rem;
  --tq-echelle-4:  2.4414rem;
  --tq-echelle-5:  3.0518rem;

  /* Tailles d'usage — table DESIGN.md § Typography, valeurs littérales.   */
  --tq-t-titre-page:    clamp(2.5rem, 5vw, 3.8rem);
  --tq-t-titre-section: clamp(1.75rem, 3vw, 2.4rem);
  --tq-t-sous-titre:    1.5rem;
  --tq-t-chapeau:       1.125rem;
  --tq-t-courant:       1rem;
  --tq-t-bouton:        .9375rem;
  --tq-t-etiquette:     .75rem;
  --tq-t-visa:          .8125rem;
  --tq-t-mention:       .8125rem;

  /* Interlignes */
  --tq-i-titre-page:    1.08;
  --tq-i-titre-section: 1.15;
  --tq-i-sous-titre:    1.3;
  --tq-i-chapeau:       1.6;
  --tq-i-courant:       1.65;
  --tq-i-serre:         1.3;
  --tq-i-visa:          1.45;
  --tq-i-mention:       1.55;
}


/* ==========================================================================
   03. JETONS — ESPACEMENT, FORMES, OMBRES, MOUVEMENT, LARGEURS
   ========================================================================== */

:root {
  /* Rythme d'espacement — base 4 px.
     AUCUNE autre valeur n'est admise pour la MISE EN PAGE (marges, gouttières,
     écarts entre blocs, retrait des sections).
     4 · 8 · 12 · 16 · 24 · 32 · 48 · 64 · 96 · 128                        */
  --tq-e-1:   4px;
  --tq-e-2:   8px;
  --tq-e-3:  12px;
  --tq-e-4:  16px;
  --tq-e-6:  24px;
  --tq-e-8:  32px;
  --tq-e-12: 48px;
  --tq-e-16: 64px;
  --tq-e-24: 96px;
  --tq-e-32: 128px;   /* PLAFOND ABSOLU : aucun vide vertical ne le dépasse */

  /* Retraits internes des composants — valeurs littérales de DESIGN.md
     § Components. Elles sortent volontairement du rythme de mise en page :
     ce sont des mesures de composant (l'aire de clic d'un bouton, la boîte
     d'un visa), pas du rythme de page. Elles ne servent qu'ici.           */
  --tq-p-bouton:   14px 22px;   /* bouton                                   */
  --tq-p-champ:    12px 14px;   /* champ de formulaire                      */
  --tq-p-pastille:  4px 10px;   /* pastille d'état                          */
  --tq-p-visa:      3px  8px;   /* visa                                     */
  --tq-p-carte:    24px;        /* intérieur de carte (dans le rythme)      */

  /* Formes — le site public n'a qu'UN rayon : --radius-tq, 4 px. Aucune
     pilule, aucun 2 px, aucun 8 px. La pastille cesse donc d'être ronde :
     c'est une étiquette, pas un jeton de couleur. `r-net` reste à zéro,
     c'est l'angle franc et non un rayon.                                   */
  --tq-r-net:      0;
  --tq-r-bouton:   4px;
  --tq-r-carte:    4px;
  --tq-r-pastille: 4px;

  /* Élévation — le zellige est plat, l'identité aussi.
     Niveau 0 = AUCUNE ombre + 1px solid liseré.
     Recalée sur l'encre brune : une ombre bleu-noir sur un papier chaud
     grise les bords au lieu de les poser.                                  */
  --tq-ombre-1: 0 1px 3px rgb(37 29 13 / .07);      /* survol cliquable     */
  --tq-ombre-2: 0 8px 28px -18px rgb(37 29 13 / .28); /* panneau, menu      */
  --tq-ombre-3: 0 24px 64px -32px rgb(37 29 13 / .38);/* modale             */

  /* Mouvement — rien au-dessus de 400 ms (voir mouvement.md).              */
  --tq-duree-1: 120ms;  /* réaction directe : survol, appui                 */
  --tq-duree-2: 200ms;  /* apparition d'un élément                          */
  --tq-duree-3: 320ms;  /* transition d'écran, remplissage de jalon         */
  --tq-courbe-sortie: cubic-bezier(.2, .7, .3, 1);
  --tq-courbe-std:    cubic-bezier(.3, .6, .3, 1);
  --tq-courbe-entree: cubic-bezier(.5, 0, .9, .6);

  /* Largeurs — toujours passées par min() pour interdire tout débordement
     horizontal. Une mesure en `ch` seule déborde en fenêtre étroite : c'est
     le défaut qui coupe aujourd'hui la démonstration sur mobile.           */
  --tq-l-texte:  68ch;   /* contenu éditorial                               */
  --tq-l-large:  72rem;  /* contenu large                                   */
  --tq-l-tunnel: 34rem;  /* tunnel d'achat, une décision par écran          */
  --tq-marge-page: var(--tq-e-4);   /* 16px en mobile, 24px au-delà         */

  /* Rythme vertical entre sections (surchargé en desktop, § 24).           */
  --tq-rythme-section: var(--tq-e-16); /* 64px mobile → 96px desktop        */
}


/* ==========================================================================
   04. RÉINITIALISATION
   Minimale et sans surprise. Le but est de neutraliser les défauts du
   navigateur, pas d'imposer un second système.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Décale les ancres sous l'en-tête collant. */
  scroll-padding-top: 88px;
  /* Aucun défilement horizontal n'est possible sur le document. */
  overflow-x: hidden;
}

body {
  margin: 0;
  min-height: 100%;
  background: var(--tq-ivoire);
  color: var(--tq-encre);
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-courant);
  line-height: var(--tq-i-courant);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }

ul, ol { margin: 0; padding: 0; }
ul[class], ol[class] { list-style: none; }

img, svg, video, canvas { display: block; max-width: 100%; height: auto; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}

button { background: none; border: 0; }

table { border-collapse: collapse; border-spacing: 0; }

hr {
  border: 0;
  border-top: 1px solid var(--tq-lisere);
  margin: var(--tq-e-8) 0;
}

/* Tout enfant de flex/grid peut rétrécir : la garantie anti-débordement. */
:where(.tq-grille, .tq-rangee, .tq-colonne) > * { min-width: 0; }

::selection { background: var(--tq-rouge-voile); color: var(--tq-rouge-sombre); }


/* ==========================================================================
   05. BASE TYPOGRAPHIQUE
   ========================================================================== */

/* Titres — Spectral, équilibrés, jamais en chasse fixe.
   Les `font-variation-settings` ci-dessous ("SOFT", "opsz") sont les axes de
   Fraunces, la fonte de titre d'avant. Spectral est une fonte statique : ces
   axes n'existent pas chez elle et la déclaration est simplement ignorée. On
   les laisse — les retirer ne change rien au rendu, et les garder évite de
   toucher cinq règles de composant pour un gain nul. */
.tq-titre-page,
.tq-titre-section,
.tq-sous-titre,
h1, h2, h3 {
  font-family: var(--tq-fonte-titre);
  font-optical-sizing: auto;
  color: var(--tq-encre);
  text-wrap: balance;
  letter-spacing: -.01em;
}

.tq-titre-page, h1 {
  font-size: var(--tq-t-titre-page);
  font-weight: 600;
  line-height: var(--tq-i-titre-page);
  font-variation-settings: "SOFT" 0, "opsz" 120;
}

.tq-titre-section, h2 {
  font-size: var(--tq-t-titre-section);
  font-weight: 600;
  line-height: var(--tq-i-titre-section);
  font-variation-settings: "SOFT" 0, "opsz" 48;
}

.tq-sous-titre, h3 {
  font-size: var(--tq-t-sous-titre);
  font-weight: 500;
  line-height: var(--tq-i-sous-titre);
  font-variation-settings: "SOFT" 0, "opsz" 24;
  letter-spacing: 0;
}

/* Chapeau — Archivo, JAMAIS de monospace ici. C'est le défaut le plus
   visible du site actuel : les chapeaux en chasse fixe grise sont les
   passages les moins lisibles, précisément aux endroits décisifs. */
.tq-chapeau {
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-chapeau);
  font-weight: 400;
  line-height: var(--tq-i-chapeau);
  color: var(--tq-encre-70);
  max-width: min(60ch, 100%);
}

/* Texte courant — jamais au-delà de 68 caractères. */
.tq-texte, p {
  font-size: var(--tq-t-courant);
  line-height: var(--tq-i-courant);
  max-width: min(var(--tq-l-texte), 100%);
}

.tq-texte + .tq-texte, p + p { margin-top: var(--tq-e-4); }

/* Entre un titre et son texte : 12px. */
:where(h1, h2, h3, .tq-titre-page, .tq-titre-section, .tq-sous-titre) + :where(p, .tq-texte, .tq-chapeau) {
  margin-top: var(--tq-e-3);
}

/* Étiquette — capitales espacées, sert de sur-titre de section.
   Elle remplace définitivement l'emoji comme marqueur de section. */
.tq-etiquette {
  display: block;
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-etiquette);
  font-weight: 700;
  letter-spacing: .09em;
  line-height: var(--tq-i-serre);
  text-transform: uppercase;
  color: var(--tq-encre-45);
}

.tq-etiquette--action { color: var(--tq-rouge); }
.tq-etiquette--preuve { color: var(--tq-vert); }

/* Mention — provenance, notes de bas de bloc. */
.tq-mention {
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-encre-45);
  max-width: min(var(--tq-l-texte), 100%);
}

/* Chiffres en colonne. */
.tq-nombres, .tq-tableau td, .tq-prix { font-variant-numeric: tabular-nums; }

.tq-prix {
  font-family: var(--tq-fonte-titre);
  font-weight: 600;
  font-size: var(--tq-echelle-3);
  line-height: 1.1;
  font-variation-settings: "SOFT" 0, "opsz" 48;
}

.tq-prix small {
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-mention);
  font-weight: 400;
  color: var(--tq-encre-45);
}

/* Listes ordinaires dans du contenu éditorial. */
.tq-liste {
  list-style: disc;
  padding-left: var(--tq-e-6);
  max-width: min(var(--tq-l-texte), 100%);
}
.tq-liste li + li { margin-top: var(--tq-e-2); }
.tq-liste::marker { color: var(--tq-encre-45); }


/* ==========================================================================
   06. MISE EN PAGE — PAGE, SECTIONS, CONTENEURS, GRILLE
   Mobile d'abord. Les points de rupture sont au § 24.
   ========================================================================== */

/* Conteneur — largeur large par défaut, marges latérales garanties. */
.tq-conteneur {
  width: 100%;
  max-width: var(--tq-l-large);
  margin-inline: auto;
  padding-inline: var(--tq-marge-page);
}

.tq-conteneur--texte  { max-width: min(var(--tq-l-texte), var(--tq-l-large)); }
.tq-conteneur--tunnel { max-width: var(--tq-l-tunnel); }

/* Section — 64px de retrait vertical en mobile, 96px au-delà.
   PLAFOND : jamais plus de 128px de vide vertical, nulle part. */
.tq-section {
  padding-block: var(--tq-rythme-section);
}

/* Alternance de fond, sans bordure entre les sections :
   le changement de fond suffit. */
.tq-section--alt   { background: var(--tq-ivoire-2); }
.tq-section--blanc { background: var(--tq-blanc); }

/* Espacement interne d'une section : 32px entre ses blocs. */
.tq-section > .tq-conteneur > * + * { margin-top: var(--tq-e-8); }

/* Un en-tête de section : étiquette + titre + chapeau, resserrés. */
.tq-tete-section > * + * { margin-top: var(--tq-e-3); }
.tq-tete-section { max-width: min(var(--tq-l-texte), 100%); }

/* Grille — 4 colonnes en mobile (gouttière 16px),
   12 colonnes au-delà (gouttière 24px). */
.tq-grille {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--tq-e-4);
}

/* Raccourcis de disposition les plus courants, exprimés en fractions
   du nombre de colonnes courant. En mobile tout occupe la largeur. */
.tq-col-2, .tq-col-3, .tq-col-4, .tq-col-6, .tq-col-8, .tq-col-12 {
  grid-column: span 4;
}

/* Rangée horizontale d'éléments qui doivent TOUJOURS pouvoir passer à la
   ligne (visas, pastilles, boutons). Aucun débordement possible. */
.tq-rangee {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tq-e-2);
}
.tq-rangee--large { gap: var(--tq-e-3); }
.tq-rangee--actions { gap: var(--tq-e-3); align-items: stretch; }

.tq-colonne {
  display: flex;
  flex-direction: column;
  gap: var(--tq-e-4);
}

/* Conteneur défilant — pour tout bloc dont la largeur minimale dépasse
   celle de l'écran (tableau large, démonstration chiffrée). Le contenu
   défile DANS son conteneur, il ne pousse jamais la page. */
.tq-defilant {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--tq-encre-20) transparent;
}
.tq-defilant:focus-visible { outline: 2px solid var(--tq-rouge); outline-offset: 2px; }
.tq-defilant::-webkit-scrollbar { height: 8px; }
.tq-defilant::-webkit-scrollbar-thumb {
  background: var(--tq-encre-20);
  border-radius: var(--tq-r-pastille);
}


/* ==========================================================================
   07. COMPOSANT — BOUTON
   Trois niveaux, et un seul est rouge.

   ⚠️ IL N'EXISTE PAS DE CLASSE « bouton plein » GÉNÉRIQUE.
   Le rouge plein s'appelle `.tq-bouton--progression` parce qu'il ne sert
   qu'à ça : faire avancer le client dans le parcours (s'inscrire, payer,
   valider une étape). Un retour à l'accueil, une remontée en haut de page
   ou un lien de documentation prennent `--contour` ou `--lien`.
   UN SEUL bouton de progression par écran. Jamais deux côte à côte.
   ========================================================================== */

.tq-bouton {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tq-e-2);
  padding: var(--tq-p-bouton);
  border: 1px solid transparent;
  border-radius: var(--tq-r-bouton);
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-bouton);
  font-weight: 600;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  /* Aire de clic confortable au doigt sans casser le rythme. */
  min-height: 48px;
  transition:
    background-color var(--tq-duree-1) var(--tq-courbe-std),
    border-color     var(--tq-duree-1) var(--tq-courbe-std),
    color            var(--tq-duree-1) var(--tq-courbe-std),
    transform        var(--tq-duree-1) var(--tq-courbe-std);
}

/* Niveau 1 — PROGRESSION. Le seul rouge plein du système. */
.tq-bouton--progression {
  background: var(--tq-rouge);
  border-color: var(--tq-rouge);
  color: var(--tq-blanc);   /* papier-haut sur garance : 7,09:1 */
}
.tq-bouton--progression:hover {
  background: var(--tq-rouge-sombre);
  border-color: var(--tq-rouge-sombre);
  color: var(--tq-blanc); /* prime sur le a:hover global — sinon libellé invisible */
  /* aucun déplacement au survol */
}
.tq-bouton--progression:active { transform: translateY(1px); }

/* Niveau 2 — CONTOUR. Action secondaire, jamais concurrente. */
.tq-bouton--contour {
  background: transparent;
  border-color: var(--tq-encre-20);
  color: var(--tq-encre);
}
.tq-bouton--contour:hover {
  border-color: var(--tq-encre);
  /* Teinte de survol à l'encre BRUNE : l'ancien bleu-noir grisait le
     papier au lieu de l'assombrir. */
  background: rgb(37 29 13 / .04);
  color: var(--tq-encre); /* prime sur le a:hover global */
}
.tq-bouton--contour:active { transform: translateY(1px); }

/* Niveau 3 — LIEN. Action tertiaire, dans le fil du texte. */
.tq-bouton--lien {
  padding: var(--tq-e-2) 0;
  min-height: 0;
  background: none;
  border-color: transparent;
  color: var(--tq-rouge);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.tq-bouton--lien:hover {
  color: var(--tq-rouge-sombre);
  text-decoration-thickness: 2px;
}
.tq-bouton--lien:active { transform: none; }

/* Bouton pleine largeur — usage : tunnel d'achat, mobile. */
.tq-bouton--pleine-largeur { display: flex; width: 100%; }

/* Attente — le libellé est masqué, la LARGEUR NE BOUGE PAS. */
.tq-bouton[aria-busy="true"] { cursor: progress; pointer-events: none; }
.tq-bouton[aria-busy="true"] .tq-bouton__libelle { visibility: hidden; }
.tq-bouton[aria-busy="true"]::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 16px; height: 16px;
  margin: -8px 0 0 -8px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--tq-r-pastille);
  animation: tq-rotation 640ms linear infinite;
}

@keyframes tq-rotation { to { transform: rotate(360deg); } }


/* ==========================================================================
   08. COMPOSANT — LIEN
   ========================================================================== */

a, .tq-lien {
  color: var(--tq-rouge);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: color var(--tq-duree-1) var(--tq-courbe-std);
}
a:hover, .tq-lien:hover {
  color: var(--tq-rouge-sombre);
  text-decoration-thickness: 2px;
}

/* Lien discret — navigation, pied de page : l'encre, pas le rouge. */
.tq-lien--discret {
  color: var(--tq-encre-70);
  text-decoration-color: var(--tq-encre-20);
}
.tq-lien--discret:hover { color: var(--tq-encre); text-decoration-color: currentColor; }

/* Lien sans soulignement — réservé aux blocs entièrement cliquables. */
.tq-lien--nu { text-decoration: none; }


/* ==========================================================================
   09. COMPOSANT — CARTE
   Fond blanc, 1px liseré, rayon 4px, intérieur 24px.
   AUCUNE ombre au repos : la carte existe par son liseré sur l'ivoire.
   ========================================================================== */

.tq-carte {
  background: var(--tq-blanc);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  padding: var(--tq-p-carte);
  /* niveau 0 — aucune ombre */
}

.tq-carte > * + * { margin-top: var(--tq-e-3); }

/* Carte cliquable — élévation 1 et liseré encre-20 au survol seulement. */
.tq-carte--cliquable {
  display: block;
  color: inherit;
  text-decoration: none;
  transition:
    border-color var(--tq-duree-1) var(--tq-courbe-std),
    box-shadow   var(--tq-duree-1) var(--tq-courbe-std);
}
.tq-carte--cliquable:hover {
  border-color: var(--tq-encre-20);
  box-shadow: var(--tq-ombre-1);
}

/* Carte de produit — liseré supérieur de 3px à la couleur du connecteur.
   La couleur se pose par `style="--tq-accent: var(--tq-vert)"` ou par une
   classe de connecteur. Ce n'est PAS un liseré d'accent à gauche : cette
   signature-là est explicitement interdite. */
.tq-carte--produit {
  border-top: 3px solid var(--tq-accent, var(--tq-encre-20));
  padding-top: 21px;  /* 24px - 3px de liseré, pour garder l'aplomb */
}

.tq-carte__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--tq-e-3);
}

.tq-carte__pied {
  margin-top: var(--tq-e-6);
  padding-top: var(--tq-e-4);
  border-top: 1px solid var(--tq-lisere);
}

/* Panneau flottant (menu, infobulle) — élévation 2. */
.tq-panneau {
  background: var(--tq-blanc);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  padding: var(--tq-e-4);
  box-shadow: var(--tq-ombre-2);
}

/* Modale — élévation 3 + voile. */
.tq-modale {
  background: var(--tq-blanc);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  padding: var(--tq-e-8);
  box-shadow: var(--tq-ombre-3);
  max-width: min(var(--tq-l-tunnel), calc(100vw - var(--tq-e-8)));
}
.tq-modale::backdrop { background: var(--tq-voile); }
.tq-voile { position: fixed; inset: 0; background: var(--tq-voile); }


/* ==========================================================================
   10. COMPOSANT — PASTILLE D'ÉTAT
   Ronde, 4 couleurs sémantiques, capitales espacées.
   AUCUNE pastille ne s'affiche sans libellé : une pilule colorée muette
   est pire qu'aucune pastille. La règle est appliquée par le CSS.
   ========================================================================== */

.tq-pastille {
  display: inline-flex;
  align-items: center;
  gap: var(--tq-e-1);
  padding: var(--tq-p-pastille);
  border-radius: var(--tq-r-pastille);
  font-family: var(--tq-fonte-ui);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: var(--tq-i-serre);
  text-transform: uppercase;
  /* Un libellé long passe à la ligne DANS la pastille : jamais coupé,
     jamais débordant. « Paiement à régulariser » sur un écran de 390 px
     dépassait de 4 px avec `nowrap`. */
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
  background: var(--tq-ivoire-2);
  color: var(--tq-encre-70);
  border: 1px solid transparent;  /* voir --termine ci-dessous */
}

/* Garde-fou : une pastille sans texte disparaît. */
.tq-pastille:empty { display: none !important; }

.tq-pastille--actif     { background: var(--tq-vert-voile);   color: var(--tq-vert); }
.tq-pastille--essai     { background: var(--tq-rouge-voile);  color: var(--tq-rouge-sombre); }
/* « Terminé » a le même fond que les sections alternées : sans liseré, elle
   disparaît quand on la pose sur `ivoire-2`. Le liseré la maintient lisible
   partout, sans toucher aux couleurs fixées par DESIGN.md. */
.tq-pastille--termine   { background: var(--tq-ivoire-2);     color: var(--tq-encre-70);
                          border-color: var(--tq-lisere); }
.tq-pastille--attention { background: var(--tq-attention);    color: var(--tq-attention-texte); }

/* Point de tête optionnel, à la couleur du texte. */
.tq-pastille__point {
  width: 6px; height: 6px;
  border-radius: var(--tq-r-pastille);
  background: currentColor;
  flex: none;
}


/* ==========================================================================
   11. COMPOSANT — VISA
   La signature du produit : la référence vérifiable.
   IBM Plex Mono, fond vert voilé, texte vert. C'EST LE SEUL USAGE DE LA
   CHASSE FIXE dans tout le système.
   Un visa n'est JAMAIS tronqué : sur écran étroit il passe à la ligne.
   ========================================================================== */

.tq-visa {
  display: inline-block;
  max-width: 100%;
  padding: var(--tq-p-visa);
  border-radius: var(--tq-r-bouton);
  background: var(--tq-vert-voile);
  color: var(--tq-vert);
  font-family: var(--tq-fonte-mono);
  font-size: var(--tq-t-visa);
  font-weight: 500;
  line-height: var(--tq-i-visa);
  /* Jamais coupé, jamais en ellipse : il passe à la ligne. */
  white-space: normal;
  overflow-wrap: anywhere;
  text-decoration: none;
}

/* Survol du visa : le voile de visa assombri d'un cran (oklch(90.5% .03
   155)) — le vert-visa y tient encore 5,00:1. Un survol doit se voir
   sans faire tomber le texte sous le plancher. */
a.tq-visa:hover { background: #D1E6D7; color: var(--tq-vert); }

/* Groupe de visas — passe à la ligne, ne déborde jamais. */
.tq-visas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--tq-e-2);
  min-width: 0;
  max-width: 100%;
}

.tq-visas__titre { margin-bottom: var(--tq-e-2); }


/* ==========================================================================
   12. COMPOSANT — BLOC DE PREUVE ET PUCES HEXAGONALES
   Le vert atteste. Ces blocs ne se cliquent pas.
   ========================================================================== */

.tq-preuve {
  background: var(--tq-vert-voile);
  /* Filet de visa — oklch(88% .035 155), la teinte du vert du site public
     portée à la clarté d'un séparateur. Décoratif : le bloc est délimité
     par son fond, pas par ce trait. */
  border: 1px solid #C6DFCE;
  border-radius: var(--tq-r-carte);
  padding: var(--tq-e-6);
  min-width: 0;
}
.tq-preuve > * + * { margin-top: var(--tq-e-3); }
.tq-preuve .tq-etiquette { color: var(--tq-vert); }

/* Liste de preuve — puces hexagonales (usage autorisé de l'hexagone). */
.tq-liste-preuve { list-style: none; padding: 0; }
.tq-liste-preuve li {
  position: relative;
  padding-left: var(--tq-e-6);
  max-width: min(var(--tq-l-texte), 100%);
}
.tq-liste-preuve li + li { margin-top: var(--tq-e-3); }
.tq-liste-preuve li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .45em;
  width: 10px; height: 11px;
  background: var(--tq-vert-clair);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}


/* ==========================================================================
   13. COMPOSANT — CHAMP DE FORMULAIRE
   Libellé AU-DESSUS, jamais à l'intérieur.
   ========================================================================== */

.tq-groupe {
  display: block;
  min-width: 0;
}
.tq-groupe + .tq-groupe { margin-top: var(--tq-e-6); } /* 24px dans le tunnel */

.tq-libelle {
  display: block;
  margin-bottom: var(--tq-e-2);
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-mention);
  font-weight: 600;
  color: var(--tq-encre);
}
.tq-libelle__facultatif {
  font-weight: 400;
  color: var(--tq-encre-45);
}

.tq-champ {
  display: block;
  width: 100%;
  padding: var(--tq-p-champ);
  background: var(--tq-blanc);
  /* CONTOUR D'ÉLÉMENT, pas un séparateur : le blanc du champ ne se détache
     de l'ivoire qu'à 1,05:1, donc ce liseré est la seule limite visible du
     champ. Il tient les 3:1 exigés (`encre-30`), jamais `encre-20`. */
  border: 1px solid var(--tq-encre-30);
  border-radius: var(--tq-r-bouton);
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-courant);
  line-height: 1.4;
  color: var(--tq-encre);
  transition:
    border-color var(--tq-duree-1) var(--tq-courbe-std),
    box-shadow   var(--tq-duree-1) var(--tq-courbe-std);
}

.tq-champ::placeholder { color: var(--tq-encre-45); }

.tq-champ:hover { border-color: var(--tq-encre-45); }

/* Focus au pointeur : liseré rouge + halo léger (DESIGN.md § Champ).
   Focus CLAVIER : en plus, l'outline du § 22 — jamais une ombre seule. */
.tq-champ:focus {
  outline: none;
  border-color: var(--tq-rouge);
  box-shadow: 0 0 0 3px rgb(154 48 60 / .14);   /* halo de garance */
}
.tq-champ:focus-visible {
  outline: 2px solid var(--tq-rouge);
  outline-offset: 2px;
  box-shadow: none;
}

textarea.tq-champ { min-height: 128px; resize: vertical; }

select.tq-champ {
  appearance: none;
  padding-right: var(--tq-e-8);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--tq-encre-70) 50%),
    linear-gradient(135deg, var(--tq-encre-70) 50%, transparent 50%);
  background-position: right 20px center, right 14px center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

/* Erreur — le message dit QUOI CORRIGER, pas seulement ce qui est faux. */
.tq-champ--erreur,
.tq-champ[aria-invalid="true"] { border-color: var(--tq-rouge); }

.tq-erreur {
  display: block;
  margin-top: var(--tq-e-2);
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-rouge-sombre);
  max-width: min(var(--tq-l-texte), 100%);
}

.tq-aide {
  display: block;
  margin-top: var(--tq-e-2);
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-encre-45);
  max-width: min(var(--tq-l-texte), 100%);
}

/* Case à cocher et bouton radio.
   Ils sont redessinés (`appearance: none`) pour une seule raison : le contour
   d'une case native est tracé par le navigateur, on ne peut pas lui imposer
   les 3:1. Ici, c'est `encre-30` qui délimite — comme pour un champ. */
.tq-case {
  display: flex;
  align-items: flex-start;
  gap: var(--tq-e-3);
  min-width: 0;
}
.tq-case input[type="checkbox"],
.tq-case input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  display: grid;
  place-content: center;
  width: 18px; height: 18px;
  margin-top: 2px;
  background: var(--tq-blanc);
  border: 1px solid var(--tq-encre-30);   /* contour d'élément — 3,62:1 */
  border-radius: var(--tq-r-bouton);
  cursor: pointer;
  transition:
    background-color var(--tq-duree-1) var(--tq-courbe-std),
    border-color     var(--tq-duree-1) var(--tq-courbe-std);
}
/* Une case à cocher est carrée, un bouton radio est ROND : c'est ce qui
   dit à l'utilisateur qu'il choisit UN seul élément. C'est une affordance,
   pas une décoration — le rayon unique de la charte (4 px) gouverne les
   surfaces, pas la forme d'un contrôle natif. */
.tq-case input[type="radio"] { border-radius: 999px; }

.tq-case input[type="checkbox"]:hover,
.tq-case input[type="radio"]:hover { border-color: var(--tq-encre-45); }

.tq-case input[type="checkbox"]:checked,
.tq-case input[type="radio"]:checked {
  background: var(--tq-rouge);
  border-color: var(--tq-rouge);
}

/* La coche et le point, dessinés en CSS — pas d'image, pas d'emoji. */
.tq-case input[type="checkbox"]:checked::before {
  content: "";
  width: 9px; height: 5px;
  border-left: 2px solid var(--tq-blanc);
  border-bottom: 2px solid var(--tq-blanc);
  transform: rotate(-45deg) translate(1px, -1px);
}
.tq-case input[type="radio"]:checked::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 999px;   /* le point d'un radio est rond, voir ci-dessus */
  background: var(--tq-blanc);
}

/* En contraste forcé (Windows), on rend la main au système : nos couleurs
   n'y ont plus cours et une case redessinée y deviendrait invisible. */
@media (forced-colors: active) {
  .tq-case input[type="checkbox"],
  .tq-case input[type="radio"] { appearance: auto; -webkit-appearance: auto; }
}
.tq-case label {
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-encre-70);
  cursor: pointer;
}


/* ==========================================================================
   14. COMPOSANT — TABLEAU
   Un tableau vit TOUJOURS dans un `.tq-defilant` : sur écran étroit il
   défile dans son conteneur, il ne pousse jamais la page.
   ========================================================================== */

.tq-tableau {
  width: 100%;
  min-width: 32rem;   /* en deçà, le conteneur défile */
  background: var(--tq-blanc);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  font-size: var(--tq-t-mention);
  text-align: left;
}

.tq-tableau thead th {
  padding: var(--tq-e-3) var(--tq-e-4);
  background: var(--tq-ivoire-2);
  border-bottom: 1px solid var(--tq-lisere);
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-etiquette);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tq-encre-70);
  white-space: nowrap;
}

.tq-tableau tbody td,
.tq-tableau tbody th {
  padding: var(--tq-e-3) var(--tq-e-4);
  border-top: 1px solid var(--tq-lisere);
  vertical-align: top;
  color: var(--tq-encre-70);
}

.tq-tableau tbody th {
  font-weight: 600;
  color: var(--tq-encre);
}

.tq-tableau tbody tr:first-child td,
.tq-tableau tbody tr:first-child th { border-top: 0; }

.tq-tableau tbody tr:hover { background: var(--tq-ivoire); }

.tq-tableau .tq-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Dans un tableau, le visa reste sur une ligne : la cellule est déjà dans un
   conteneur qui défile, le faire passer à la ligne ne ferait qu'étirer les
   rangées inutilement. Il n'est toujours ni tronqué ni coupé. */
.tq-tableau .tq-visa { white-space: nowrap; overflow-wrap: normal; }

.tq-tableau caption {
  caption-side: top;
  padding-bottom: var(--tq-e-3);
  text-align: left;
  font-size: var(--tq-t-mention);
  color: var(--tq-encre-45);
}


/* ==========================================================================
   15. COMPOSANT — ACCORDÉON
   Bâti sur <details>/<summary> : il fonctionne sans JavaScript.
   ========================================================================== */

.tq-accordeon {
  border-top: 1px solid var(--tq-lisere);
  min-width: 0;
}

.tq-accordeon__item { border-bottom: 1px solid var(--tq-lisere); }

.tq-accordeon__tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--tq-e-4);
  padding: var(--tq-e-4) 0;
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-chapeau);
  font-weight: 600;
  color: var(--tq-encre);
  cursor: pointer;
  list-style: none;
  transition: color var(--tq-duree-1) var(--tq-courbe-std);
}
.tq-accordeon__tete::-webkit-details-marker { display: none; }
.tq-accordeon__tete:hover { color: var(--tq-rouge); }

/* Chevron dessiné en CSS — pas d'emoji, pas d'image. */
.tq-accordeon__tete::after {
  content: "";
  flex: none;
  width: 9px; height: 9px;
  margin-top: 6px;
  border-right: 2px solid var(--tq-encre-45);
  border-bottom: 2px solid var(--tq-encre-45);
  transform: rotate(45deg);
  transition: transform var(--tq-duree-2) var(--tq-courbe-sortie);
}
.tq-accordeon__item[open] > .tq-accordeon__tete::after {
  transform: rotate(-135deg);
  margin-top: 10px;
}

.tq-accordeon__corps {
  padding-bottom: var(--tq-e-4);
  color: var(--tq-encre-70);
  max-width: min(var(--tq-l-texte), 100%);
}
.tq-accordeon__corps > * + * { margin-top: var(--tq-e-3); }

.tq-accordeon__item[open] > .tq-accordeon__corps {
  animation: tq-apparition var(--tq-duree-2) var(--tq-courbe-sortie) both;
}


/* ==========================================================================
   16. COMPOSANT — ONGLETS
   Le liseré actif est rouge : c'est une action de navigation dans l'écran.
   ========================================================================== */

.tq-onglets {
  display: flex;
  gap: var(--tq-e-6);
  border-bottom: 1px solid var(--tq-lisere);
  /* Sur écran étroit, la barre d'onglets défile — elle ne se replie pas
     et ne déborde jamais. */
  overflow-x: auto;
  scrollbar-width: none;
  min-width: 0;
}
.tq-onglets::-webkit-scrollbar { display: none; }

.tq-onglet {
  flex: none;
  position: relative;
  padding: var(--tq-e-3) 0;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-bouton);
  font-weight: 600;
  color: var(--tq-encre-45);
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition:
    color var(--tq-duree-1) var(--tq-courbe-std),
    border-color var(--tq-duree-1) var(--tq-courbe-std);
}
.tq-onglet:hover { color: var(--tq-encre); }
/* La barre d'onglets défile : un outline posé À L'EXTÉRIEUR de l'onglet
   serait rogné par le conteneur. On le dessine à l'intérieur — il reste
   entièrement visible, et c'est toujours un outline, jamais une ombre. */
.tq-onglet:focus-visible { outline-offset: -2px; }
.tq-onglet[aria-selected="true"],
.tq-onglet.est-actif {
  color: var(--tq-encre);
  border-bottom-color: var(--tq-rouge);
}

.tq-panneau-onglet { padding-top: var(--tq-e-6); }
.tq-panneau-onglet[hidden] { display: none; }


/* ==========================================================================
   17. COMPOSANT — BANDEAU DE PROGRESSION ET JALONS
   Les jalons sont des hexagones : c'est l'un des trois usages autorisés de
   la forme signature (sceau, puces de preuve, jalons).
   Le vert remplit — il atteste de ce qui est accompli.
   ========================================================================== */

/* Barre simple, pilotée par --tq-avancement (0 à 100). */
.tq-progression {
  width: 100%;
  height: 4px;
  background: var(--tq-lisere);
  border-radius: var(--tq-r-pastille);
  overflow: hidden;
}
.tq-progression__remplissage {
  height: 100%;
  width: calc(var(--tq-avancement, 0) * 1%);
  background: var(--tq-vert-clair);
  border-radius: var(--tq-r-pastille);
  transition: width var(--tq-duree-3) var(--tq-courbe-sortie);
}

/* Jalons — VERTICAUX en mobile (aucun risque de débordement),
   horizontaux à partir de 600px (§ 24). */
.tq-jalons {
  display: flex;
  flex-direction: column;
  gap: var(--tq-e-4);
  min-width: 0;
  list-style: none;
  padding: 0;
}

.tq-jalon {
  display: flex;
  align-items: flex-start;
  gap: var(--tq-e-3);
  min-width: 0;
}

.tq-jalon__marque {
  flex: none;
  width: 18px; height: 20px;
  margin-top: 2px;
  background: var(--tq-lisere);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  transition: background-color var(--tq-duree-3) var(--tq-courbe-sortie);
}
.tq-jalon--fait    .tq-jalon__marque { background: var(--tq-vert-clair); }
.tq-jalon--courant .tq-jalon__marque { background: var(--tq-vert); }

.tq-jalon__libelle {
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-encre-45);
  min-width: 0;
}
.tq-jalon--fait    .tq-jalon__libelle { color: var(--tq-encre-70); }
.tq-jalon--courant .tq-jalon__libelle { color: var(--tq-encre); font-weight: 600; }


/* ==========================================================================
   18. COMPOSANT — NOTE / ALERTE
   Fond voilé, liseré à gauche INTERDIT (signature de gabarit générique) :
   le fond et le liseré complet suffisent.
   ========================================================================== */

.tq-note {
  padding: var(--tq-e-4);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  background: var(--tq-ivoire-2);
  font-size: var(--tq-t-mention);
  line-height: var(--tq-i-mention);
  color: var(--tq-encre-70);
  min-width: 0;
}
.tq-note > * + * { margin-top: var(--tq-e-2); }
.tq-note strong { color: var(--tq-encre); }

.tq-note--attention {
  background: var(--tq-attention);
  border-color: #E7D6B3;   /* filet d'or — oklch(88% .05 85) */
  color: var(--tq-attention-texte);
}
.tq-note--attention strong { color: var(--tq-attention-texte); }

.tq-note--action {
  background: var(--tq-rouge-voile);
  border-color: #F1CECD;   /* filet de garance — oklch(88% .04 20) */
  color: var(--tq-rouge-sombre);
}
.tq-note--action strong { color: var(--tq-rouge-sombre); }

.tq-note--preuve {
  background: var(--tq-vert-voile);
  border-color: #C6DFCE;   /* filet de visa — oklch(88% .035 155) */
  color: var(--tq-vert);
}
.tq-note--preuve strong { color: var(--tq-vert); }


/* ==========================================================================
   19. COMPOSANT — EN-TÊTE
   Collant, sur ivoire, séparé par un simple liseré.
   Mobile : la navigation est repliée dans un tiroir <details>, sans JS.
   ========================================================================== */

.tq-entete {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--tq-ivoire);
  border-bottom: 1px solid var(--tq-lisere);
}

.tq-entete__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tq-e-4);
  min-height: 64px;
  padding-block: var(--tq-e-2);
}

.tq-entete__marque {
  display: inline-flex;
  align-items: center;
  gap: var(--tq-e-3);
  text-decoration: none;
  color: var(--tq-encre);
  flex: none;
}

.tq-entete__nom {
  font-family: var(--tq-fonte-titre);
  font-size: var(--tq-echelle-1);
  font-weight: 600;
  font-variation-settings: "SOFT" 0, "opsz" 24;
  letter-spacing: -.01em;
  line-height: 1;
}

.tq-entete__sous-nom {
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-etiquette);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tq-encre-45);
  line-height: 1;
  margin-top: var(--tq-e-1);
  display: block;
}

/* Tiroir mobile. */
.tq-entete__tiroir { position: relative; }

.tq-entete__declencheur {
  display: inline-flex;
  align-items: center;
  gap: var(--tq-e-2);
  padding: var(--tq-e-3);
  border: 1px solid var(--tq-encre-20);
  border-radius: var(--tq-r-bouton);
  font-size: var(--tq-t-bouton);
  font-weight: 600;
  color: var(--tq-encre);
  cursor: pointer;
  list-style: none;
  min-height: 44px;
}
.tq-entete__declencheur::-webkit-details-marker { display: none; }

.tq-entete__barres {
  display: block;
  width: 16px; height: 2px;
  background: currentColor;
  position: relative;
}
.tq-entete__barres::before,
.tq-entete__barres::after {
  content: "";
  position: absolute;
  left: 0;
  width: 16px; height: 2px;
  background: currentColor;
}
.tq-entete__barres::before { top: -5px; }
.tq-entete__barres::after  { top:  5px; }

.tq-entete__nav {
  display: flex;
  flex-direction: column;
  gap: var(--tq-e-1);
  position: absolute;
  right: 0;
  top: calc(100% + var(--tq-e-2));
  min-width: 14rem;
  max-width: calc(100vw - var(--tq-e-8));
  padding: var(--tq-e-3);
  background: var(--tq-blanc);
  border: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte);
  box-shadow: var(--tq-ombre-2);
  animation: tq-apparition var(--tq-duree-2) var(--tq-courbe-sortie) both;
}

.tq-entete__lien {
  display: block;
  padding: var(--tq-e-3);
  border-radius: var(--tq-r-bouton);
  font-size: var(--tq-t-bouton);
  font-weight: 600;
  color: var(--tq-encre-70);
  text-decoration: none;
}
.tq-entete__lien:hover { background: var(--tq-ivoire-2); color: var(--tq-encre); }
.tq-entete__lien[aria-current="page"] { color: var(--tq-encre); }

.tq-entete__actions { display: none; }


/* ==========================================================================
   20. COMPOSANT — PIED DE PAGE
   Zone calme : ivoire-2. Aucun bouton rouge n'y a sa place.
   ========================================================================== */

.tq-pied {
  background: var(--tq-ivoire-2);
  border-top: 1px solid var(--tq-lisere);
  padding-block: var(--tq-e-16);
}

.tq-pied__grille {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--tq-e-8);
}

.tq-pied__titre {
  font-family: var(--tq-fonte-ui);
  font-size: var(--tq-t-etiquette);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tq-encre-45);
  margin-bottom: var(--tq-e-3);
}

.tq-pied__liste { list-style: none; padding: 0; }
.tq-pied__liste li + li { margin-top: var(--tq-e-2); }
.tq-pied__liste a {
  font-size: var(--tq-t-mention);
  color: var(--tq-encre-70);
  text-decoration: none;
}
.tq-pied__liste a:hover { color: var(--tq-encre); text-decoration: underline; }

.tq-pied__bas {
  margin-top: var(--tq-e-12);
  padding-top: var(--tq-e-6);
  border-top: 1px solid var(--tq-lisere);
  display: flex;
  flex-wrap: wrap;
  gap: var(--tq-e-4);
  justify-content: space-between;
  align-items: center;
}


/* ==========================================================================
   21. COMPOSANT — SCEAU ET FILIGRANE ZELLIGE
   Trois usages de l'hexagone, et trois seulement : le sceau de marque,
   les puces de preuve (§ 12), les jalons (§ 17).
   ========================================================================== */

.tq-sceau {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px; height: 36px;
  background: var(--tq-rouge);
  color: var(--tq-blanc);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  font-family: var(--tq-fonte-titre);
  font-size: var(--tq-echelle-0);
  font-weight: 600;
  line-height: 1;
  font-variation-settings: "SOFT" 0, "opsz" 24;
}
.tq-sceau--preuve { background: var(--tq-vert); }
.tq-sceau--grand  { width: 56px; height: 64px; font-size: var(--tq-echelle-2); }

/* Filigrane — maillage hexagonal, opacité 0,045, UNIQUEMENT en fond de
   section d'ouverture ou de clôture. JAMAIS derrière du texte courant :
   le motif est cantonné aux marges par le dégradé de masque. */
.tq-filigrane {
  position: relative;
  isolation: isolate;
}
.tq-filigrane::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .045;
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='56' height='64' viewBox='0 0 56 64'>\
<g fill='none' stroke='%23251D0D' stroke-width='1.4'>\
<path d='M28 1 L54 16 L54 47 L28 62 L2 47 L2 16 Z'/>\
<path d='M28 -31 L54 -16 L54 15 M2 15 L2 -16 L28 -31'/>\
<path d='M28 65 L54 80 M2 80 L28 65'/>\
</g></svg>");
  background-size: 56px 64px;
  /* Le motif s'efface au centre : il reste au bord, jamais sous le texte. */
  -webkit-mask-image: radial-gradient(120% 90% at 50% 50%, transparent 38%, #000 100%);
          mask-image: radial-gradient(120% 90% at 50% 50%, transparent 38%, #000 100%);
}


/* ==========================================================================
   22. MOTIFS ANIMABLES — CONVENTION TA-APP (Framer Motion + 21st.dev)
   --------------------------------------------------------------------------
   Reprise de la convention déjà en vigueur chez le propriétaire :
   `2claude/ta-app/ta-app/frontend/design.md`, § 4 (Animation — Framer
   Motion 12) et § 5 (Patterns inspirés 21st.dev).

   ⚠️ 21st.dev n'est NI un serveur NI une bibliothèque : les motifs sont
   RECOPIÉS À LA MAIN dans un dossier `ui-21st/`. Rien à installer.

   Ce bloc pose l'HABILLAGE des motifs concernés ; le MOUVEMENT est piloté
   par Framer Motion côté React. Les règles, les durées et surtout les
   interdits sont dans `mouvement.md`. Rappel du principal :
   on n'anime JAMAIS `width`, `height`, `top` ni `left` — uniquement
   `scale`, `x`, `y`. Toutes les classes ci-dessous sont écrites pour ça.
   ========================================================================== */

/* ── Animated tabs underline ───────────────────────────────────────────────
   Le trait glisse d'un onglet à l'autre (`layoutId="tq-onglet-trait"`).
   Il est dessiné avec une largeur de 1px et mis à l'échelle : aucune
   animation de `width`. Sans JS, il reste positionné par les variables
   `--tq-onglet-x` (décalage) et `--tq-onglet-l` (facteur d'échelle).
   Usage Tariq : la bascule Douane / Fiscal (page d'offre, espace compte). */
.tq-onglets { position: relative; }

.tq-onglets--anime .tq-onglet[aria-selected="true"],
.tq-onglets--anime .tq-onglet.est-actif { border-bottom-color: transparent; }

.tq-onglet__trait {
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 1px;          /* jamais animée */
  height: 2px;
  background: var(--tq-rouge);
  transform-origin: left center;
  transform: translateX(var(--tq-onglet-x, 0px)) scaleX(var(--tq-onglet-l, 0));
  transition: transform var(--tq-duree-2) var(--tq-courbe-sortie);
  pointer-events: none;
}

/* ── Number ticker ─────────────────────────────────────────────────────────
   Prix, montant économisé, compteurs. Interpolation ~600 ms ease-out côté
   Framer (`useSpring`, stiffness 80 / damping 20 — jamais damping < 20).
   Le CSS garantit qu'aucun chiffre ne fait sauter la mise en page. */
.tq-chiffre {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  white-space: nowrap;
  display: inline-block;
}

/* ── Magnetic CTA ──────────────────────────────────────────────────────────
   Micro-attraction du bouton d'engagement vers le curseur. Framer écrit
   `--tq-mx` / `--tq-my` (quelques pixels, jamais plus de 8).
   RÈGLE : effet de POINTEUR uniquement, donc jamais porteur d'information —
   le mobile n'a pas de survol, l'action doit être complète sans lui. */
.tq-magnetique {
  transform: translate3d(var(--tq-mx, 0px), var(--tq-my, 0px), 0);
  transition: transform var(--tq-duree-1) var(--tq-courbe-sortie);
  will-change: transform;
}
@media (hover: none) {
  .tq-magnetique { transform: none; --tq-mx: 0px; --tq-my: 0px; }
}

/* ── Glow border on focus ──────────────────────────────────────────────────
   Champs critiques (ICE, e-mail de facturation, numéro de carte).
   Le halo est un renfort au pointeur ; le focus CLAVIER reste l'outline
   du § 23, jamais une ombre seule. */
.tq-champ--critique:focus {
  border-color: var(--tq-rouge);
  box-shadow: 0 0 0 3px rgb(154 48 60 / .20), 0 0 0 1px var(--tq-rouge) inset;
}
.tq-champ--critique:focus-visible {
  outline: 2px solid var(--tq-rouge);
  outline-offset: 2px;
  box-shadow: none;
}

/* ── Bento grid ────────────────────────────────────────────────────────────
   Une section de preuve : une carte maîtresse + des cartes de tailles
   inégales. Mobile : empilement pur. */
.tq-bento {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--tq-e-4);
}
.tq-bento > * { min-width: 0; }

/* ── Vaul drawer — feuille glissante mobile ────────────────────────────────
   Filtres, actions secondaires, choix de connecteur sur petit écran.
   Elle monte du bas : `y: 100% → 0`, spring ferme (stiffness 380,
   damping 28). Ici encore, on translate — on n'anime pas `height`. */
.tq-feuille {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  max-height: 85vh;
  overflow-y: auto;
  padding: var(--tq-e-6);
  background: var(--tq-blanc);
  border-top: 1px solid var(--tq-lisere);
  border-radius: var(--tq-r-carte) var(--tq-r-carte) 0 0;
  box-shadow: var(--tq-ombre-3);
  transform: translateY(0);
  transition: transform var(--tq-duree-3) var(--tq-courbe-sortie);
}
.tq-feuille[hidden], .tq-feuille[data-etat="ferme"] {
  display: block;
  transform: translateY(100%);
  visibility: hidden;
}
.tq-feuille__poignee {
  width: 32px; height: 4px;
  margin: 0 auto var(--tq-e-4);
  background: var(--tq-encre-20);
  border-radius: var(--tq-r-pastille);
}
/* En bureau, la feuille redevient un panneau centré. */
@media (min-width: 900px) {
  .tq-feuille {
    left: 50%; bottom: auto; top: 10vh; right: auto;
    width: min(var(--tq-l-tunnel), 90vw);
    margin-left: calc(min(var(--tq-l-tunnel), 90vw) / -2);
    border-radius: var(--tq-r-carte);
    border: 1px solid var(--tq-lisere);
  }
}

/* ── Skeleton shimmer ──────────────────────────────────────────────────────
   Balayage de 1,5 s en boucle (convention TA-App). C'est un indicateur de
   chargement, pas une transition d'état : il échappe volontairement au
   plafond de 400 ms. Voir mouvement.md, « les deux exceptions ». */
.tq-squelette--balayage {
  background-image: linear-gradient(
    90deg,
    var(--tq-lisere) 0%,
    var(--tq-ivoire-2) 40%,
    var(--tq-lisere) 80%
  );
  background-size: 300% 100%;
  animation: tq-balayage 1500ms linear infinite;
}
@keyframes tq-balayage {
  from { background-position: 150% 0; }
  to   { background-position: -150% 0; }
}


/* ==========================================================================
   23. ÉTATS TRANSVERSES — FOCUS, DÉSACTIVÉ, ATTENTE
   ========================================================================== */

/* FOCUS CLAVIER — règle unique et non négociable.
   Ce n'est JAMAIS une ombre : une ombre disparaît sur fond coloré et ne
   passe pas en mode contraste élevé. */
:where(a, button, input, select, textarea, summary, [tabindex], .tq-defilant):focus-visible {
  outline: 2px solid var(--tq-rouge);
  outline-offset: 2px;
  border-radius: var(--tq-r-bouton);
}

/* Le focus au pointeur ne dessine rien (sauf sur les champs, § 13). */
:where(a, button, summary):focus:not(:focus-visible) { outline: none; }

/* Saut au contenu — visible seulement au clavier. */
.tq-saut {
  position: absolute;
  left: var(--tq-e-4);
  top: var(--tq-e-4);
  z-index: 100;
  padding: var(--tq-e-3) var(--tq-e-4);
  background: var(--tq-encre);
  color: var(--tq-blanc);
  border-radius: var(--tq-r-bouton);
  text-decoration: none;
  transform: translateY(-200%);
}
.tq-saut:focus { transform: translateY(0); }

/* DÉSACTIVÉ — lisible, mais manifestement inerte. */
:disabled,
[aria-disabled="true"],
.est-desactive {
  cursor: not-allowed;
  opacity: .45;
  filter: saturate(.4);
  pointer-events: none;
}
/* Un champ désactivé garde son fond : c'est un contenant, pas un bouton. */
.tq-champ:disabled {
  opacity: 1;
  filter: none;
  background: var(--tq-ivoire-2);
  color: var(--tq-encre-45);
  border-color: var(--tq-lisere);
}

/* ATTENTE — squelette de chargement, sans clignotement.
   La pulsation est une variation d'opacité douce ; elle est neutralisée
   sous `prefers-reduced-motion` (§ 25). */
.tq-squelette {
  background: var(--tq-lisere);
  border-radius: var(--tq-r-bouton);
  color: transparent !important;
  min-height: 1em;
  animation: tq-pulsation 1200ms var(--tq-courbe-std) infinite alternate;
}
.tq-squelette--ligne  { height: 12px; width: 100%; }
.tq-squelette--titre  { height: 24px; width: 60%; }
.tq-squelette--court  { height: 12px; width: 40%; }

@keyframes tq-pulsation { to { opacity: .45; } }

@keyframes tq-apparition {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}


/* ==========================================================================
   24. UTILITAIRES
   Peu nombreux, et tous justifiés.
   ========================================================================== */

.tq-visuellement-cache {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.tq-centre { text-align: center; }
.tq-centre .tq-texte,
.tq-centre .tq-chapeau { margin-inline: auto; }

/* Écarts verticaux — toujours pris dans le rythme, jamais au-delà de 128px. */
.tq-pile > * + *      { margin-top: var(--tq-e-4); }
.tq-pile-6 > * + *    { margin-top: var(--tq-e-6); }
.tq-pile-8 > * + *    { margin-top: var(--tq-e-8); }
.tq-pile-12 > * + *   { margin-top: var(--tq-e-12); }

.tq-texte-secondaire { color: var(--tq-encre-70); }
.tq-texte-tertiaire  { color: var(--tq-encre-45); }
.tq-texte-preuve     { color: var(--tq-vert); }
.tq-texte-action     { color: var(--tq-rouge); }

/* Toute boîte susceptible de contenir un contenu large. */
.tq-sans-debordement { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }

.tq-separateur {
  border: 0;
  border-top: 1px solid var(--tq-lisere);
  margin-block: var(--tq-e-8);
}


/* ==========================================================================
   25. POINTS DE RUPTURE
   Mobile d'abord. Trois seuils : 600px, 900px, 1200px.
   ========================================================================== */

/* ── ≥ 600px — petite tablette ─────────────────────────────────────────── */
@media (min-width: 600px) {
  :root {
    --tq-marge-page: var(--tq-e-6);   /* 24px */
  }

  /* Les jalons passent à l'horizontale, avec un trait de liaison. */
  .tq-jalons {
    flex-direction: row;
    align-items: flex-start;
    gap: 0;
  }
  .tq-jalon {
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--tq-e-2);
    padding-inline: var(--tq-e-2);
    position: relative;
  }
  /* Trait de liaison entre deux jalons — derrière les marques. */
  .tq-jalon + .tq-jalon::before {
    content: "";
    position: absolute;
    top: 11px;
    right: 50%;
    left: -50%;
    height: 2px;
    background: var(--tq-lisere);
    z-index: 0;
  }
  .tq-jalon--fait::before,
  .tq-jalon--courant::before { background: var(--tq-vert-clair) !important; }
  .tq-jalon__marque { position: relative; z-index: 1; margin-top: 0; }

  .tq-pied__grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── ≥ 900px — tablette large et ordinateur ────────────────────────────── */
@media (min-width: 900px) {
  :root {
    /* Rythme vertical entre sections : 96px. */
    --tq-rythme-section: var(--tq-e-24);
  }

  /* Grille à 12 colonnes, gouttière 24px. */
  .tq-grille {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: var(--tq-e-6);
  }
  .tq-col-2  { grid-column: span 2; }
  .tq-col-3  { grid-column: span 3; }
  .tq-col-4  { grid-column: span 4; }
  .tq-col-6  { grid-column: span 6; }
  .tq-col-8  { grid-column: span 8; }
  .tq-col-12 { grid-column: span 12; }

  /* En-tête : la navigation se déplie, le tiroir disparaît. */
  .tq-entete__tiroir > .tq-entete__declencheur { display: none; }
  .tq-entete__nav {
    position: static;
    flex-direction: row;
    align-items: center;
    gap: var(--tq-e-6);
    min-width: 0;
    max-width: none;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    animation: none;
  }
  .tq-entete__lien { padding: var(--tq-e-2) 0; border-radius: 0; }
  .tq-entete__lien:hover { background: none; }
  .tq-entete__lien[aria-current="page"] {
    box-shadow: inset 0 -2px 0 0 var(--tq-rouge);
  }
  .tq-entete__actions { display: inline-flex; align-items: center; gap: var(--tq-e-4); }

  .tq-pied__grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* Bento — une carte maîtresse à gauche, des satellites à droite. */
  .tq-bento {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: minmax(0, auto);
    gap: var(--tq-e-6);
  }
  .tq-bento__maitre { grid-column: span 2; grid-row: span 2; }
  .tq-bento__haut   { grid-column: span 1; }
  .tq-bento__large  { grid-column: span 3; }

  /* Le tableau n'a plus besoin de défiler. */
  .tq-tableau { min-width: 0; }
}

/* ── ≥ 1200px — grand écran ────────────────────────────────────────────── */
@media (min-width: 1200px) {
  :root { --tq-marge-page: var(--tq-e-8); } /* 32px */
}

/* ── Impression ────────────────────────────────────────────────────────── */
@media print {
  .tq-entete, .tq-pied, .tq-bouton { display: none !important; }
  body { background: #fff; color: #000; }
  .tq-carte, .tq-preuve { border-color: #999; }
}


/* ==========================================================================
   26. MOUVEMENT RÉDUIT
   Le système respecte `prefers-reduced-motion` PARTOUT. Aucune exception :
   même l'indicateur d'attente cesse de tourner (il devient un anneau fixe).
   Voir mouvement.md.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto; }

  /* L'anneau d'attente devient un anneau complet, immobile. */
  .tq-bouton[aria-busy="true"]::after {
    animation: none !important;
    border-top-color: currentColor;
    opacity: .5;
  }
  /* Le squelette ne pulse plus et ne balaie plus : il reste posé. */
  .tq-squelette { animation: none !important; opacity: 1; }
  .tq-squelette--balayage {
    animation: none !important;
    background-image: none;
    background: var(--tq-lisere);
  }
  /* Le bouton ne s'enfonce plus à l'appui. */
  .tq-bouton:active { transform: none !important; }
  /* Le CTA magnétique cesse d'être attiré par le curseur. */
  .tq-magnetique { transform: none !important; }
  /* Le trait d'onglet se pose directement sous l'onglet actif, sans glisser
     (il conserve sa position : c'est une information, pas une décoration). */
  .tq-onglet__trait { transition: none !important; }
  /* La feuille apparaît sans glisser. */
  .tq-feuille { transition: none !important; }
}


/* ==========================================================================
   27. RACCORDS AU SITE PUBLIC
   --------------------------------------------------------------------------
   26/08/2026. Ce bloc remplaçait auparavant TOUS les jetons pour ramener la
   charte « L'Épure ». Les § 01-03 portent désormais eux-mêmes les valeurs du
   site public : ce bloc ne redéfinit plus aucun jeton — deux déclarations
   du même jeton à 90 lignes d'écart, c'est la garantie qu'un jour l'une des
   deux sera oubliée.

   Ne restent ici que les quatre raccords qui ne peuvent PAS passer par un
   jeton : une couche de fond, une image de marque, un encombrement de bande,
   une nuance d'étiquette.
   ========================================================================== */

/* ── Le grain du papier ─────────────────────────────────────────────
   Le site public pose un bruit fixe très léger sur son élément racine
   (`html.grain`, site.css) : c'est ce qui donne au papier son épaisseur.
   L'espace compte ne peut pas porter cette classe — le balisage des écrans
   ne bouge pas — donc la couche se pose directement sur <html>, avec
   EXACTEMENT la même image et la même opacité.

   Le zellige plein écran de l'ancienne charte disparaît avec ce bloc : le
   site public ne le porte plus, et c'était l'écart le plus voyant entre les
   deux univers. Le motif hexagonal reste, là où il a un sens : le sceau,
   les puces de preuve, les jalons, le filigrane de section (§ 21).

   Le voile est uniforme (env. 2,75 % d'encre) : il assombrit le texte ET
   son fond dans la même proportion, donc il ne coûte que quelques
   centièmes de rapport de contraste. Les mesures du § 01 restent tenues —
   le pire cas, le contour de champ sur papier-creux, passe de 3,34 à 3,29.
   Sans capture de pointeur, au ras du fond (z-index 0, comme le --z-fond du
   site public) : l'en-tête collant (20), la feuille (40), le saut au
   contenu (100) et les <dialog> restent au-dessus.                        */
html::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix values='0 0 0 0 .14 0 0 0 0 .11 0 0 0 0 .06 0 0 0 .055 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── La marque : le logo reprend la place du sceau hexagonal ──────────────
   Le site public ouvre sur `/logo.png` ; l'espace compte doit ouvrir sur la
   même image. Le composant n'est pas touché : le même
   <span class="tq-sceau">T</span> sert de support, l'hexagone de garance
   cède la place à l'image, et le « T » de secours s'efface derrière elle.
   Le sceau garde son rôle partout ailleurs (visas, preuves, filigranes).  */
.tq-entete__marque .tq-sceau {
  width: 26px;
  height: 26px;
  background: url("/logo.png") center / contain no-repeat;
  clip-path: none;
  border-radius: var(--tq-r-carte);
  color: transparent;
  font-size: 0;
}

/* ── La bande de séparation ──────────────────────────────────────────
   `.tq-bandeau` n'avait aucune règle propre : la bande tenait sa hauteur de
   ses attributs, donc d'une page à l'autre elle ne faisait pas la même
   hauteur. On la fixe ici pour que la gravure garde toujours le même
   encombrement.                                                           */
.tq-bandeau {
  display: block;
  width: 100%;
  height: 190px;
  object-fit: cover;
  object-position: center 62%;
}

/* ── L'étiquette de preuve : le glacis, pas le sceau ────────────────────
   Le vert-visa (#316847) est la couleur du SCEAU. L'étiquette de preuve,
   elle, se pose aussi sur les sections creuses : le glacis y gagne un cran
   de lisibilité (6,92:1 contre 5,57:1) pour un écart de teinte invisible.
   Le sceau marque, le glacis parle.                                       */
.tq-etiquette--preuve { color: var(--tq-vert-clair); }
