/* Garde-robe — composants (htdocs/assets/garderobe/composants.css), lot 0.
   Les classes g-* du cahier des charges (§ 6). Un écran n'en redéfinit aucune : il les place
   et les dimensionne dans sa propre racine (.ec-*). Aucune couleur en dur : tout vient des
   jetons (jetons.css), sauf le repli du voile des feuilles pour les navigateurs qui ne
   transmettent pas les propriétés au ::backdrop.
   Les sélecteurs .s-* (silhouettes) vivent dans jetons.css et restent sans contexte. */

/* =====================================================================
   Base commune
   ===================================================================== */
/* Spécificité nulle (:where) : ces remises à zéro ne battent jamais une classe de composant. */
:where(.gr) *, :where(.gr) *::before, :where(.gr) *::after { box-sizing: border-box; }
:where(.gr) button { font: inherit; color: inherit; }
:where(.gr) a { color: inherit; }
:where(.gr) :where(h1, h2, h3, h4, p) { margin: 0; }
html.gr:has(dialog[open]) { overflow: hidden; }
/* Le focus clavier ne passe jamais sous une barre collée (WCAG 2.4.11) : une page qui en a pose ces deux
   variables sur <html> (l'outil du jour : la barre basse) ; accueil.css règle l'accueil. */
/* Défilement instantané par défaut : style.css des Tools pose html { scroll-behavior: smooth }, qui rendrait
   animés (et asynchrones) la position rendue au retour d'un écran et chaque window.scrollTo ; un défilement
   doux se demande explicitement ({ behavior: 'smooth' }). */
html.gr { scroll-padding-top: var(--g-scroll-haut, 0px); scroll-padding-bottom: var(--g-scroll-bas, 0px); scroll-behavior: auto; }
.gr [hidden] { display: none !important; }

/* L'encre de la pièce, partout où --c1 est posé en ligne (pastilles, barres, cases du rythme). */
.gr [style*="--c1"] { --c-encre: color-mix(in oklab, var(--c1) 50%, var(--gr-texte)); }

/* Texte réservé aux lecteurs d'écran. */
.g-lecteur { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
             clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Cible de 44 px autour d'un visuel plus petit (§ 3.4). */
.g-cible { position: relative; }
.g-cible::before { content: ''; position: absolute; inset: -4px; }

/* Matière des barres (§ 3.6). */
.g-barre {
    background: var(--gr-barre);
    -webkit-backdrop-filter: blur(20px) saturate(1.6);
    backdrop-filter: blur(20px) saturate(1.6);
}
/* Replis sans flou et en transparence réduite : en FIN de fichier (même spécificité que les règles de base). */
.g-verre { background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }

/* =====================================================================
   § 6.1 Vignettes (.g-vg dans jetons.css) : tailles d'emploi (§ 5.5)
   xs 24 · s 32 à 40 (--vg, défaut 40) · m et l fluides (largeur de la grille) · xl : bandeau
   ===================================================================== */
.g-vg.xs { width: 24px; flex: none; }
.g-vg.s  { width: var(--vg, 40px); flex: none; }
.g-vg.m, .g-vg.l { width: 100%; }
.g-vg.xl { width: 100%; height: 100%; aspect-ratio: auto; }
.g-vg.xl > svg { inset: 6% auto auto 50%; height: 88%; width: auto; aspect-ratio: 1; transform: translateX(-50%); }
.g-vg.xl.photo > img { inset: 0 auto auto 50%; width: auto; height: 100%; aspect-ratio: 1; transform: translateX(-50%); }
/* Pastille « pas de photo » de la grille de l'accueil (seulement là). */
.g-vg-camera { position: absolute; right: 8px; bottom: 8px; color: var(--gr-texte); opacity: .4; }

/* Pastilles de couleur (GR.pastillesCouleur) : point plein, liseré à l'encre de la couleur. */
.g-pastilles { display: inline-flex; gap: 4px; align-items: center; vertical-align: middle; }
.g-pastille-couleur {
    width: var(--t, 14px); height: var(--t, 14px); border-radius: 50%; flex: none; display: block;
    background: var(--c1); box-shadow: inset 0 0 0 1px var(--c-encre);
}

/* =====================================================================
   § 6.1 Cellule de saisie (outil du jour, Journal, panneau) — construite par saisie.js
   <button class="g-cellule" aria-pressed>
     <span class="g-cellule-visuel"> .g-vg.m · <span class="g-pastille">9</span>
       [<span class="g-pastille hier">hier</span>] [<span class="g-coche">check</span>] </span>
     <span class="g-cellule-nom">555 noir</span>
   </button>
   États : [aria-pressed="true"] cochée · .memoire (de mémoire) · .attenuee · .appui (appui long en cours)
   ===================================================================== */
.g-cellule {
    position: relative; display: block; width: 100%; padding: 0; margin: 0; border: 0; background: none;
    text-align: left; color: var(--gr-texte); border-radius: var(--r-ctrl); cursor: pointer; text-decoration: none;
    touch-action: manipulation; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
    transition: transform var(--d-instant) var(--c-standard);
}
.g-cellule:active { transform: scale(.96); }
.g-cellule:focus-visible { outline: 2px solid var(--gr-focus); outline-offset: 4px; border-radius: 12px; }
.g-cellule-visuel { position: relative; display: block; border-radius: var(--r-tirage);
                    transition: box-shadow var(--d-court) var(--c-standard), outline-color var(--d-court); }
.g-cellule-visuel > .g-vg { transition: opacity var(--d-court), filter var(--d-court); }
.g-cellule-nom {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    margin-top: 6px; height: 32px; font: 600 13px/16px var(--gr-sans); overflow-wrap: anywhere;
    transition: color var(--d-court);
}
.g-pastille {
    position: absolute; right: 4px; bottom: 4px; height: 20px; min-width: 20px; padding: 0 6px; border-radius: 10px;
    background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    color: var(--gr-texte); font: 600 12px/20px var(--gr-sans); font-variant-numeric: tabular-nums;
    text-align: center; white-space: nowrap; display: block;   /* pas de flex : l'ordinal 8<sup>e</sup> reste surélevé */
}
.g-pastille .g-ic { width: 12px; height: 12px; vertical-align: -2px; margin-right: 1px; }
.g-pastille.hier { right: auto; bottom: auto; left: 4px; top: 4px; font: 600 11px/20px var(--gr-sans); color: var(--gr-texte-2); }
/* « suggérée » (compositeur de tenues, GR.suggererPieces) : même place et même ton que « hier ».
   <span class="g-pastille suggeree">suggérée</span> */
.g-pastille.suggeree { right: auto; bottom: auto; left: 4px; top: 4px; font: 600 11px/20px var(--gr-sans); color: var(--gr-texte-2); }
.g-coche {
    position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%;
    background: var(--gr-texte); color: var(--gr-inverse); display: grid; place-items: center;
    box-shadow: 0 0 0 2px var(--gr-fond); transform: scale(.6); opacity: 0;
    transition: transform var(--d-court) var(--c-ressort), opacity var(--d-court);
}
.g-coche .g-ic { width: 16px; height: 16px; stroke-width: 2; }
.g-cellule[aria-pressed="true"] .g-cellule-visuel { box-shadow: 0 0 0 2px var(--gr-fond), 0 0 0 4px var(--gr-texte); }
.g-cellule[aria-pressed="true"] .g-coche { transform: scale(1); opacity: 1; }
.g-cellule[aria-pressed="true"] .g-pastille:not(.hier):not(.suggeree) { background: var(--gr-texte); color: var(--gr-inverse); }
.g-cellule[aria-pressed="true"].memoire .g-cellule-visuel { box-shadow: none; outline: 2px dashed var(--gr-texte); outline-offset: 2px; }
.g-cellule.attenuee .g-cellule-visuel > .g-vg { opacity: .55; filter: saturate(.5); }
.g-cellule.attenuee .g-cellule-nom { color: var(--gr-texte-2); }
/* Appui long : un anneau conique se dessine autour du visuel (--p de 0 à 360deg). */
@property --p { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.g-cellule-visuel::after {
    content: ''; position: absolute; inset: -4px; border-radius: 4px; pointer-events: none; opacity: 0;
    background: conic-gradient(var(--gr-texte) var(--p), transparent 0);
    -webkit-mask: linear-gradient(var(--gr-texte) 0 0) content-box exclude, linear-gradient(var(--gr-texte) 0 0);
    mask: linear-gradient(var(--gr-texte) 0 0) content-box exclude, linear-gradient(var(--gr-texte) 0 0);
    padding: 2px;
}
.g-cellule.appui .g-cellule-visuel::after { opacity: 1; animation: g-anneau var(--duree-appui, 300ms) linear forwards; }
@keyframes g-anneau { from { --p: 0deg; } to { --p: 360deg; } }
/* Variante compacte (hauteur < 700) : nom sur une ligne. */
@media (max-height: 700px) {
    .g-cellule-nom { -webkit-line-clamp: 1; height: 16px; }
}
/* Case « Toutes (12) » et case vide « Ajouter un bas » : même gabarit que la cellule. */
.g-cellule-plus .g-cellule-visuel {
    aspect-ratio: 1; display: grid; place-items: center; background: var(--gr-puits); color: var(--gr-texte-2);
}
.g-cellule-vide .g-cellule-visuel {
    aspect-ratio: 1; display: grid; place-items: center; background: none; color: var(--gr-texte-2);
    border: 1.5px dashed var(--gr-ligne-forte);
}

/* Tuile de la grille de l'accueil : <a class="g-tuile"> .g-vg.l · nom · méta. Aucun état coché. */
.g-tuile { display: block; color: var(--gr-texte); text-decoration: none; border-radius: var(--r-tirage); }
.g-tuile:focus-visible { outline: 2px solid var(--gr-focus); outline-offset: 4px; border-radius: 4px; }
.g-tuile > .g-vg > img, .g-tuile > .g-vg > svg { transition: transform var(--d-moyen) var(--c-standard); }
.g-tuile-nom { display: block; margin-top: 8px; font: 600 15px/20px var(--gr-sans);
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-tuile-meta { display: block; margin-top: 2px; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2);
                font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-tuile-etiquette { position: absolute; left: 8px; top: 8px; height: 20px; padding: 0 8px; border-radius: 10px;
                     display: inline-flex; align-items: center; gap: 4px; font: 600 11px/20px var(--gr-sans);
                     background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.g-tuile-etiquette .g-ic { width: 12px; height: 12px; }
/* La marque (19/10/2026) : DANS la vignette, en haut à gauche, sur une ligne (coupée au besoin). L'étiquette « À recevoir »
   passe alors juste en dessous. */
.g-tuile-marque { position: absolute; left: 8px; top: 8px; max-width: calc(100% - 16px); height: 20px; padding: 0 8px; border-radius: 10px;
                  display: block; font: 600 11px/20px var(--gr-sans); color: var(--gr-texte); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                  background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.g-vg:has(> .g-tuile-marque) > .g-tuile-etiquette { top: 34px; }
/* Nombre d'exemplaires d'une référence (cahier quantités § 6.3), DANS la vignette de la tuile, en bas à droite ;
   le libellé de la tuile le dit en toutes lettres (« 7 paires »).
   <span class="g-vg l …">… <span class="g-tuile-nombre" aria-hidden="true">× 7</span></span>
   Mêmes mesures que la pastille de la cellule. La pastille « pas de photo » (.g-vg-camera) lui laisse le coin et
   passe en bas à gauche. */
.g-tuile-nombre {
    position: absolute; right: 8px; bottom: 8px; height: 20px; min-width: 20px; padding: 0 6px; border-radius: 10px;
    background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    color: var(--gr-texte); font: 600 12px/20px var(--gr-sans); font-variant-numeric: tabular-nums;
    text-align: center; white-space: nowrap; display: block;
}
.g-vg:has(> .g-tuile-nombre) > .g-vg-camera { right: auto; left: 8px; }
@media (hover: hover) {
    .g-tuile:hover > .g-vg > img, .g-tuile:hover > .g-vg > svg { transform: scale(1.02); }
    .g-tuile:hover .g-tuile-nom { text-decoration: underline; text-underline-offset: 3px; }
    .g-tuile:hover > .g-vg.xl > svg, .g-tuile:hover > .g-vg.xl > img { transform: translateX(-50%) scale(1.02); }
}

/* Repère « en rodage » (chaussures qui font encore mal, GR.faites(p).etat === 'rodage'), en ligne avant un nom :
   <span class="g-tuile-nom">GR.ic('bandage', 'g-rodage') + nom</span> ; le libellé de l'élément dit « en rodage ».
   Deux classes : il bat les tailles d'icône des conteneurs (.g-pastille .g-ic…). */
.g-ic.g-rodage { width: 14px; height: 14px; color: var(--gr-texte-2); vertical-align: -2px; margin-right: 4px; }

/* =====================================================================
   § 6.2 Boutons
   ===================================================================== */
.g-bouton {
    position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    height: 48px; padding: 0 20px; border: 0; border-radius: 24px; cursor: pointer;
    background: var(--gr-texte); color: var(--gr-inverse); font: 600 17px/1 var(--gr-sans);
    text-decoration: none; white-space: nowrap; -webkit-tap-highlight-color: transparent;
    transition: transform var(--d-instant) var(--c-standard), background-color var(--d-court), opacity var(--d-court);
}
.g-bouton:active { transform: scale(.97); }
.g-bouton:disabled, .g-bouton[aria-disabled="true"] { opacity: .4; cursor: default; transform: none; }
.g-bouton .g-ic { width: 20px; height: 20px; }
/* Un libellé avec un ordinal s'écrit dans un <span> (« <span>Comme le 1<sup>er</sup></span> ») : en flex,
   chaque morceau de texte serait sinon un élément à part. Filet de sécurité pour un <sup> enfant direct :
   collé au chiffre (l'écart du flex annulé) et remonté. */
.g-bouton > sup, .g-puce > sup { position: relative; top: -.4em; line-height: 1; margin-left: -8px; }
.g-puce > sup { margin-left: -6px; }
.g-bouton.bas { height: 52px; border-radius: 26px; }
.g-bouton.plein { width: 100%; }
.g-bouton.secondaire { background: var(--gr-surface-2); color: var(--gr-texte); }
.g-bouton.texte { height: 44px; padding: 0 12px; background: none; color: var(--gr-texte); border-radius: var(--r-ctrl); }
.g-bouton.texte.danger { color: var(--gr-danger); }
.g-bouton.petit { height: 36px; padding: 0 14px; border-radius: 18px; font: 600 15px/1 var(--gr-sans); }
.g-bouton.petit::before { content: ''; position: absolute; inset: -4px 0; }
.g-bouton-ic {
    position: relative; display: inline-grid; place-items: center; width: 44px; height: 44px; flex: none;
    padding: 0; border: 0; border-radius: var(--r-ctrl); background: none; color: var(--gr-texte); cursor: pointer;
    text-decoration: none; transition: background-color var(--d-court), transform var(--d-instant);
}
.g-bouton-ic:active { transform: scale(.94); }
.g-bouton-ic.rond { width: 36px; height: 36px; border-radius: 50%;
                    background: var(--gr-verre); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
.g-bouton-ic.rond::before { content: ''; position: absolute; inset: -4px; }
/* Sur une photo, l'encre seule peut tomber sous 3:1 : un liseré du fond la détache (focus, pas sélection). */
.g-bouton-ic.rond:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--gr-fond), 0 0 0 4px var(--gr-focus); }
.g-bouton-ic:disabled { opacity: .35; cursor: default; }
@media (hover: hover) {
    .g-bouton.texte:hover, .g-bouton-ic:not(.rond):hover { background: var(--gr-survol); }
}
/* Pastille de compteur sur une icône (onglet Aujourd'hui) : un point encre de 6 px. */
.g-point { position: absolute; top: 2px; right: -2px; width: 6px; height: 6px; border-radius: 50%; background: var(--gr-texte); }

/* =====================================================================
   § 6.3 Puces, segmenté, interrupteur
   ===================================================================== */
.g-puces { display: flex; gap: 8px; flex-wrap: wrap; }
.g-puces.defile { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
                  -webkit-mask: linear-gradient(to right, var(--gr-texte) calc(100% - 16px), transparent);
                  mask: linear-gradient(to right, var(--gr-texte) calc(100% - 16px), transparent);
                  padding-right: 16px; }
.g-puces.defile::-webkit-scrollbar { display: none; }
.g-puces.defile > :focus-visible { outline-offset: -2px; }
.g-puce {
    position: relative; display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px; flex: none;
    border: 0; border-radius: 18px; background: var(--gr-surface-2); color: var(--gr-texte); cursor: pointer;
    font: 500 15px/1 var(--gr-sans); white-space: nowrap; text-decoration: none;
    transition: background-color var(--d-court), color var(--d-court);
}
.g-puce::before { content: ''; position: absolute; inset: -4px 0; }
.g-puce .nb { color: var(--gr-texte-3); font-variant-numeric: tabular-nums; }
.g-puce .g-ic { width: 16px; height: 16px; }
.g-puce[aria-pressed="true"], .g-puce[aria-checked="true"], .g-puce.active { background: var(--gr-texte); color: var(--gr-inverse); }
.g-puce[aria-pressed="true"] .nb, .g-puce[aria-checked="true"] .nb, .g-puce.active .nb { color: inherit; opacity: .72; }
.g-puce.ajout { background: transparent; border: 1px dashed var(--gr-ligne-forte); color: var(--gr-texte-2); }
.g-puce .g-vg.xs { margin-left: -8px; }

.g-segmente {
    display: inline-flex; align-items: stretch; height: 36px; padding: 2px; gap: 2px;
    border-radius: var(--r-ctrl); background: var(--gr-surface-2);
}
.g-segmente > [role="radio"] {
    position: relative;
    flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 0 12px; border: 0; border-radius: 10px; background: none; cursor: pointer;
    color: var(--gr-texte-2); font: 500 15px/1 var(--gr-sans); white-space: nowrap;
    transition: background-color var(--d-court), color var(--d-court), box-shadow var(--d-court);
}
.g-segmente > [role="radio"][aria-checked="true"] { background: var(--gr-segment); box-shadow: var(--gr-o-segment);
                                                    color: var(--gr-texte); font-weight: 600; }
.g-segmente > [role="radio"] .g-ic { width: 16px; height: 16px; }
.g-segmente > [role="radio"]::before { content: ''; position: absolute; inset: -6px 0; }   /* 32 + 12 = 44 */
.g-segmente.plein { display: flex; width: 100%; }

.g-interrupteur {
    -webkit-appearance: none; appearance: none; position: relative; flex: none; margin: 0; cursor: pointer;
    width: 51px; height: 31px; border-radius: 16px; background: var(--gr-surface-2);
    border: 1px solid var(--gr-ligne-forte); transition: background-color var(--d-court), border-color var(--d-court);
}
.g-interrupteur::after {
    content: ''; position: absolute; top: 1px; left: 1px; width: 27px; height: 27px; border-radius: 50%;
    background: var(--gr-surface); box-shadow: var(--gr-o-segment);
    transition: transform var(--d-court) var(--c-standard), background-color var(--d-court);
}
.g-interrupteur:checked { background: var(--gr-texte); border-color: var(--gr-texte); }
/* style.css bleuit le bord d'un input qui a le focus : l'interrupteur garde le sien (l'anneau encre dit le focus). */
.g-interrupteur:focus { border-color: var(--gr-ligne-forte); }
.g-interrupteur:checked:focus { border-color: var(--gr-texte); }
.g-interrupteur:checked::after { transform: translateX(20px); background: var(--gr-inverse); }

/* =====================================================================
   § 6.4 Champs (la base est dans jetons.css)
   ===================================================================== */
.gr .g-champ-nu { border: 0; background: none; padding: 0; border-radius: 0; box-shadow: none; text-align: right; color: var(--gr-texte-2); }
.gr .g-champ-nu:focus { box-shadow: none; color: var(--gr-texte); }
.gr .g-champ-titre {
    font: 400 34px/40px var(--gr-serif); border: 0; border-bottom: 1px solid var(--gr-ligne-forte);
    border-radius: 0; background: none; padding: 4px 0 8px;
}
.gr .g-champ-titre:focus { box-shadow: 0 1px 0 0 var(--gr-texte); border-bottom-color: var(--gr-texte); }
/* Pilule : <label class="g-champ-pilule"> icône · <input> · [bouton d'envoi .g-envoyer] </label> */
.g-champ-pilule {
    position: relative; display: flex; align-items: center; height: 52px; border-radius: 26px;
    background: var(--gr-surface); border: 1px solid var(--gr-ligne-forte); color: var(--gr-texte-2);
}
.g-champ-pilule:focus-within { border-color: var(--gr-texte); box-shadow: 0 0 0 1px var(--gr-texte); }
.g-champ-pilule > .g-ic { position: absolute; left: 14px; pointer-events: none; }
.gr .g-champ-pilule > input { height: 50px; border: 0; background: none; box-shadow: none; border-radius: 26px;
                              padding: 0 52px 0 46px; }
.gr .g-champ-pilule > input:focus { box-shadow: none; }
.g-envoyer {
    position: absolute; right: 9px; width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer;
    background: var(--gr-texte); color: var(--gr-inverse); display: grid; place-items: center;
}
.g-envoyer::before { content: ''; position: absolute; inset: -6px; }
.g-envoyer .g-ic { width: 20px; height: 20px; stroke-width: 2; }
.gr [aria-invalid="true"] { border-color: var(--gr-danger) !important; }
.g-erreur { margin: 6px 0 0; font: 500 13px/18px var(--gr-sans); color: var(--gr-danger); display: flex; gap: 6px; align-items: flex-start; }
.g-erreur .g-ic { width: 16px; height: 16px; margin-top: 1px; }
.gr textarea { resize: none; min-height: calc(3 * 24px + 28px); field-sizing: content; }
.g-libelle { display: block; margin-bottom: 8px; font: 600 15px/20px var(--gr-sans); }

/* Autocomplétion (GR.autocompletion, ui.js) : <div class="g-ac"> <input role="combobox"> <ul class="g-ac-liste"> ; la
   liste flotte sous le champ, six options visibles, 44 px chacune ; l'option active (flèches) en surface pressée ;
   la partie reconnue de la frappe soulignée (<mark>), le nombre de pièces à droite. */
.g-ac { position: relative; display: block; }
.g-ac-liste {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; margin: 0; padding: 4px; list-style: none;
    max-height: calc(6 * 44px + 8px); overflow-y: auto; overscroll-behavior: contain;
    background: var(--gr-surface); border: 1px solid var(--gr-ligne-forte); border-radius: 12px; box-shadow: var(--gr-o-flottant);
}
.g-ac-liste[hidden] { display: none; }
.g-ac-option {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: 0 12px;
    border-radius: 8px; cursor: pointer; font: 500 16px/20px var(--gr-sans); color: var(--gr-texte);
}
.g-ac-option:hover { background: var(--gr-survol); }
.g-ac-option[aria-selected="true"] { background: var(--gr-presse); }
.g-ac-valeur { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-ac-valeur mark { background: none; color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.g-ac-detail { flex: none; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2); font-variant-numeric: tabular-nums; }
@media (forced-colors: active) { .g-ac-option[aria-selected="true"] { outline: 2px solid Highlight; } }

/* Case à cocher (cahier quantités § 6.3 : « Faites », consignes de la simulation). L'input reste NATIF (clavier,
   lecteur d'écran, :indeterminate), visuellement masqué ; la boîte le dessine.
   <label class="g-case"><input type="checkbox" [aria-labelledby="X-nom" aria-describedby="X-etat"]>
     <span class="g-case-boite" aria-hidden="true">GR.ic('check')</span>
     <span class="g-case-texte"><span id="X-nom">Faites</span><small id="X-etat">Faites au 14<sup>e</sup> port, le 3 nov.</small></span></label>
   Avec une phrase d'état, aria-labelledby ne nomme la case que par son libellé : sans lui, le <label> mettrait la
   phrase dans le nom, et aria-describedby la ferait lire une seconde fois. Sans phrase, le <label> suffit.
   Cochée : boîte encre, coche inverse ; indéterminée (input.indeterminate = true, même cochée) : un tiret ;
   désactivée : .4. */
.g-case { position: relative; display: flex; align-items: flex-start; gap: 12px; min-height: 48px; padding: 12px 0;
          cursor: pointer; color: var(--gr-texte); -webkit-tap-highlight-color: transparent; }
.g-case > input { position: absolute; left: 0; top: 12px; width: 24px; height: 24px; margin: 0; opacity: 0; pointer-events: none; }
.g-case-boite {
    position: relative; flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 6px;
    border: 1px solid var(--gr-ligne-forte); background: var(--gr-surface); color: var(--gr-inverse);
    transition: background-color var(--d-court), border-color var(--d-court);
}
.g-case-boite > .g-ic, .g-case-boite::after { grid-area: 1 / 1; }
.g-case-boite > .g-ic { width: 16px; height: 16px; stroke-width: 2; opacity: 0; transform: scale(.6);
                        transition: opacity var(--d-court), transform var(--d-court) var(--c-ressort); }
.g-case > input:checked + .g-case-boite { background: var(--gr-texte); border-color: var(--gr-texte); }
.g-case > input:checked + .g-case-boite > .g-ic { opacity: 1; transform: none; }
.g-case > input:indeterminate + .g-case-boite::after { content: ''; width: 12px; height: 2px; border-radius: 1px; background: var(--gr-texte); }
.g-case > input:indeterminate + .g-case-boite { background: var(--gr-surface); border-color: var(--gr-ligne-forte); }
.g-case > input:indeterminate + .g-case-boite > .g-ic { opacity: 0; }
.g-case > input:focus-visible + .g-case-boite { outline: 2px solid var(--gr-focus); outline-offset: 2px; }
.g-case-texte { flex: 1; min-width: 0; font: 400 17px/24px var(--gr-sans); overflow-wrap: anywhere; }
.g-case-texte > small { display: block; margin-top: 2px; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2); }
.g-case:has(> input:disabled) { opacity: .4; cursor: default; }
@media (hover: hover) { .g-case:not(:has(> input:disabled)):hover > input:not(:checked) + .g-case-boite { border-color: var(--gr-texte-2); } }
/* Couleurs forcées (contraste élevé) : les fonds y deviennent Canvas, le tiret disparaîtrait et l'état indéterminé se
   confondrait avec le décoché. Boîte cochée et tiret prennent les couleurs système d'une case native. */
@media (forced-colors: active) {
    .g-case > input:checked:not(:indeterminate) + .g-case-boite { forced-color-adjust: none; background: Highlight; border-color: Highlight; color: HighlightText; }
    .g-case > input:indeterminate + .g-case-boite::after { forced-color-adjust: none; background: CanvasText; }
    .g-case > input:focus-visible + .g-case-boite { outline-color: CanvasText; }
}

/* =====================================================================
   § 6.5 Rangées et groupes (façon Réglages)
   <h3 class="g-groupe-titre t-titre">…</h3>
   <div class="g-groupe"> <a|button|label class="g-rangee"> [ic] libellé · <span class="g-valeur"> · chevron </…> </div>
   <p class="g-aide">Une phrase.</p>  <details class="g-plus"><summary>En savoir plus</summary>…</details>
   ===================================================================== */
.g-groupe { background: var(--gr-surface); border-radius: var(--r-ctrl); overflow: hidden; margin: 0 var(--gr-marge); }
.g-groupe-titre { margin: 0 var(--gr-marge) 8px; }
.g-rangee {
    position: relative; display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0 16px;
    border: 0; background: none; color: var(--gr-texte); text-align: left; text-decoration: none; cursor: pointer;
    font: 400 17px/24px var(--gr-sans);
}
.g-rangee.deux { min-height: 64px; }
.g-rangee:active { background: var(--gr-presse); }
@media (hover: hover) { .g-rangee:hover { background: var(--gr-survol); } }
.g-rangee + .g-rangee::before, .g-rangee + * > .g-rangee::before {
    content: ''; position: absolute; top: 0; left: 16px; right: 0; border-top: 1px solid var(--gr-ligne);
}
.g-groupe.ic .g-rangee + .g-rangee::before { left: 52px; }
.g-rangee > .g-ic { color: var(--gr-texte); width: 20px; height: 20px; }
.g-rangee-libelle { flex: 1; min-width: 0; }
.g-rangee-libelle small { display: block; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2); }
.g-valeur { margin-left: auto; color: var(--gr-texte-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60%; }
.g-rangee > .g-chevron { width: 20px; height: 20px; color: var(--gr-texte-3); margin-left: 4px; flex: none; }
.g-rangee.danger { color: var(--gr-danger); }
.g-rangee.danger > .g-ic { color: var(--gr-danger); }
.g-rangee.action { font-weight: 500; }
/* Un <select> natif transparent posé sur toute la rangée : la roue d'iOS s'ouvre au toucher. */
.gr .g-rangee > select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
.g-rangee:focus-within { outline: 2px solid var(--gr-focus); outline-offset: -2px; border-radius: var(--r-ctrl); }
.g-rangee:focus-visible { outline: 2px solid var(--gr-focus); outline-offset: -2px; border-radius: var(--r-ctrl); }
.g-aide { margin: 8px var(--gr-marge) 0; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2); }
.g-plus { margin: 8px var(--gr-marge) 0; font: 500 13px/18px var(--gr-sans); color: var(--gr-texte-2); }
.g-plus > summary { list-style: none; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; cursor: pointer; border-radius: var(--r-ctrl); }
.g-plus > summary::-webkit-details-marker { display: none; }
.g-plus > summary .g-ic { width: 16px; height: 16px; }

/* =====================================================================
   § 6.6 Feuilles (<dialog class="g-feuille">, GR.feuille / GR.actions / GR.confirmer)
   ===================================================================== */
.g-feuille {
    position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: none; max-height: 92dvh;
    padding: 0 0 env(safe-area-inset-bottom); border: 0; border-radius: var(--r-feuille) var(--r-feuille) 0 0;
    background: var(--gr-surface); color: var(--gr-texte); box-shadow: var(--gr-o-feuille);
    overscroll-behavior: contain; overflow: hidden; flex-direction: column;
    font: 400 17px/24px var(--gr-sans);
}
.g-feuille[open] { display: flex; animation: g-feuille-entree var(--d-moyen) var(--c-sortie); }
.g-feuille.moyenne { height: 60dvh; }
.g-feuille.grande { height: 92dvh; }
/* .pose : l'entrée est jouée (sinon, après un glisser relâché, elle se rejouerait) ; .sortie la suit dans le fichier. */
.g-feuille.pose { animation: none; }
.g-feuille.sortie { animation: g-feuille-sortie 200ms var(--c-entree) forwards; }
.g-feuille.retour { transition: transform var(--d-court) var(--c-sortie); }
.g-feuille::backdrop {
    background: var(--gr-voile, rgb(0 0 0 / .5));
    animation: g-fondu var(--d-court, 180ms) linear;
}
.g-feuille.sortie::backdrop { animation: g-fondu-sortie 200ms linear forwards; }
@keyframes g-feuille-entree { from { transform: translateY(100%); } to { transform: none; } }
@keyframes g-feuille-sortie { from { transform: var(--depart, none); } to { transform: translateY(100%); } }
@keyframes g-fondu { from { opacity: 0; } to { opacity: 1; } }
@keyframes g-fondu-sortie { from { opacity: 1; } to { opacity: 0; } }
.g-feuille-poignee { flex: none; height: 21px; display: grid; place-items: start center; padding-top: 8px; cursor: grab; touch-action: none; }
.g-feuille-poignee::before { content: ''; width: 36px; height: 5px; border-radius: 3px; background: var(--gr-texte-3); opacity: .4; }
.g-feuille-entete { flex: none; display: flex; align-items: center; gap: 8px; min-height: 56px; padding: 0 8px 0 var(--gr-marge); touch-action: none; }
.g-feuille-titre { flex: 1; min-width: 0; margin: 0; font: 400 22px/28px var(--gr-serif); outline: none; overflow-wrap: anywhere; }
.g-feuille-titre:focus-visible { outline: 2px solid var(--gr-focus); outline-offset: 2px; }
.g-feuille-corps { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 0 16px; }
.g-feuille-corps > .g-texte { margin: 0 var(--gr-marge) 12px; color: var(--gr-texte-2); font: 500 15px/21px var(--gr-sans); }
.g-feuille-pied { flex: none; display: flex; gap: 8px; padding: 8px var(--gr-marge) 8px; border-top: 1px solid var(--gr-ligne); }
.g-feuille-pied > .g-bouton { flex: 1; }
@media (min-width: 1024px) {
    .g-feuille {
        inset: 0; margin: auto; width: 520px; height: fit-content; max-height: 86vh;
        border-radius: var(--r-feuille); padding-bottom: 8px; box-shadow: var(--gr-o-flottant);
    }
    .g-feuille.moyenne, .g-feuille.grande { height: min(86vh, 720px); }
    .g-feuille[open] { animation: g-feuille-entree-bureau var(--d-court) var(--c-sortie); }
    .g-feuille.sortie { animation: g-feuille-sortie-bureau var(--d-court) var(--c-entree) forwards; }
    .g-feuille-poignee { height: 12px; padding: 0; }
    .g-feuille-poignee::before { display: none; }
    @keyframes g-feuille-entree-bureau { from { transform: scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes g-feuille-sortie-bureau { to { transform: scale(.96); opacity: 0; } }
}

/* Feuille d'actions (GR.actions) : rangées de 56, puis « Annuler » à 8 px. */
.g-actions { display: flex; flex-direction: column; gap: 8px; padding: 0 var(--gr-marge) 8px; }
.g-actions > .g-groupe { margin: 0; }
.g-action {
    position: relative; display: flex; align-items: center; gap: 14px; width: 100%; min-height: 56px; padding: 0 16px;
    border: 0; background: none; color: var(--gr-texte); text-align: left; cursor: pointer; font: 500 17px/22px var(--gr-sans);
}
.g-action + .g-action::before { content: ''; position: absolute; top: 0; left: 54px; right: 0; border-top: 1px solid var(--gr-ligne); }
.g-action.sans-ic + .g-action::before, .g-action + .g-action.sans-ic::before { left: 16px; }
.g-action:active { background: var(--gr-presse); }
@media (hover: hover) { .g-action:hover { background: var(--gr-survol); } }
.g-action.danger { color: var(--gr-danger); }
.g-action:disabled { opacity: .4; cursor: default; }
.g-action:focus-visible { outline: 2px solid var(--gr-focus); outline-offset: -2px; border-radius: var(--r-ctrl); }
.g-action > .g-ic { width: 24px; height: 24px; }
.g-actions > .g-bouton { width: 100%; }
.g-feuille.actions .g-feuille-titre { font: 400 22px/28px var(--gr-serif); }

/* =====================================================================
   § 6.7 Confirmation « Annuler », bandeau, toast
   <div class="g-confirmation" role="status"> check · <span class="g-confirmation-texte"> · Annuler · filet </div>
   ===================================================================== */
.g-confirmation {
    position: relative; display: flex; align-items: center; gap: 8px; min-width: 0; height: 48px; padding: 0 4px 0 14px;
    border-radius: 24px; background: var(--gr-texte); color: var(--gr-inverse); overflow: hidden;
    box-shadow: var(--gr-o-flottant); animation: g-confirmation-entree var(--d-court) var(--c-sortie);
}
.g-confirmation.sans-action { padding-right: 18px; }
.g-confirmation.deplacee { animation: none; }
.g-confirmation.sort { animation: g-confirmation-sortie var(--d-court) var(--c-entree) forwards; }
.g-confirmation > .g-ic { width: 20px; height: 20px; flex: none; }
.g-confirmation-texte { flex: 1; min-width: 0; font: 600 15px/20px var(--gr-sans); font-variant-numeric: tabular-nums;
                        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-confirmation-annuler {
    flex: none; height: 40px; padding: 0 14px; border: 0; border-radius: 20px; cursor: pointer;
    background: color-mix(in srgb, var(--gr-inverse) 16%, transparent); color: var(--gr-inverse); font: 600 15px/1 var(--gr-sans);
}
.g-confirmation-annuler:focus-visible { outline: 2px solid var(--gr-inverse); outline-offset: -4px; }
.g-filet {
    position: absolute; left: 14px; right: 14px; bottom: 3px; height: 2px; border-radius: 1px; pointer-events: none;
    background: var(--gr-filet); transform-origin: left center;
    animation: g-filet var(--duree, var(--d-annuler)) linear forwards;
}
.g-confirmation.pause .g-filet { animation-play-state: paused; }
@keyframes g-filet { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes g-confirmation-entree { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes g-confirmation-sortie { to { opacity: 0; transform: translateY(8px); } }
.g-confirmation.erreur { background: var(--gr-danger-doux); color: var(--gr-danger); }
.g-confirmation.annule .g-confirmation-annuler, .g-confirmation.annule .g-filet { display: none; }
@media (max-width: 389px) { .g-confirmation:not(.sans-action) > .g-ic.coche { display: none; } }
/* Le filet de 5 s porte une information : il reste en mouvement réduit (§ 3.7). */
@media (prefers-reduced-motion: reduce) {
    .gr .g-confirmation .g-filet { animation-duration: var(--duree, var(--d-annuler)) !important; }
}

/* Emplacement des annonces (bandeau, toast) : en bas de la page, ou dans la feuille ouverte (au-dessus de son pied,
   au-dessus d'elle, ou à sa place réservée : voir plus bas). */
.g-annonce {
    position: fixed; left: 0; right: 0; bottom: var(--g-annonce-bas, calc(24px + env(safe-area-inset-bottom)));
    z-index: var(--z-annonce); display: flex; justify-content: center; padding: 0 var(--gr-marge); pointer-events: none;
}
.g-annonce > .g-confirmation { pointer-events: auto; width: 100%; max-width: 343px; }
/* Une pilule sans action (toast) ne prend jamais le pointeur : le clic passe au contrôle qu'elle couvre (au bureau,
   « Tenue … enregistrée. » couvrait 2,6 s la rangée Modifier · Simuler · Supprimer). Avec « Annuler », elle reste
   cliquable (et se met en pause sous le doigt ou la souris, ui.js). */
.g-confirmation.sans-action, .g-annonce > .g-confirmation.sans-action, .g-confirmation.sans-action * { pointer-events: none; }
.g-feuille > .g-annonce { position: absolute; bottom: calc(var(--g-pied, 0px) + 8px + var(--g-feuille-bas, env(safe-area-inset-bottom))); }
/* Une annonce ne couvre jamais un contrôle de la feuille (ui.js, placer) : hors d'une réponse au pied, elle flotte
   8 px AU-DESSUS de la feuille, sur le voile (lisible, et son « Annuler » reste actif : elle est dans le <dialog>,
   donc jamais inerte) ; faute de place au-dessus (feuille haute, paysage), sa place est réservée au bas de la
   feuille, avant le pied, et le corps (hauteur de la feuille figée) la lui cède. */
.g-feuille.annonce-dessus { overflow: visible; }
.g-feuille.annonce-dessus > .g-annonce { bottom: calc(100% + 8px); }
.g-feuille.annonce-reservee > .g-annonce { position: static; order: 1; flex: none; padding: 8px var(--gr-marge); }
.g-feuille.annonce-reservee > .g-feuille-pied { order: 2; }
@media (min-width: 1024px) { .g-feuille { --g-feuille-bas: 8px; } }

/* =====================================================================
   § 6.8 En-tête d'écran et barre compacte
   <header class="g-entete"><div class="g-entete-ligne"><p class="t-surtitre">…</p><div class="g-entete-actions">…</div></div>
     <h1 class="t-affiche">…</h1></header> <span class="g-sentinelle"></span>
   ===================================================================== */
.g-entete { padding: 4px var(--gr-marge) 0; }
.g-entete-ligne { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 44px; }
.g-entete-ligne > .t-surtitre { margin: 0; color: var(--gr-texte-2); min-width: 0; }
.g-entete-actions { display: flex; align-items: center; margin-right: -10px; flex: none; }
.g-entete > .t-affiche, .g-entete > h1, .g-entete > h2 { margin: 8px 0 0; }
.g-entete-affiche { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 8px; }
.g-entete-affiche > .t-affiche { margin: 0; }
.g-sentinelle { display: block; height: 1px; }
.g-barre-compacte {
    position: sticky; top: 0; z-index: var(--z-barre); height: 44px; display: flex; align-items: center; justify-content: center;
    margin-bottom: -44px; padding: 0 calc(var(--gr-marge) - 10px);
    background: var(--gr-barre); -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6);
    opacity: 0; pointer-events: none; transition: opacity var(--d-court) var(--c-standard);
}
/* Le filet bas est tiré SOUS la barre (un bord la réduirait à 43 de haut : ses boutons de 44 débordaient d'un
   demi-pixel en haut, hors de l'écran). Un bord, pas une ombre : il reste en couleurs forcées. */
.g-barre-compacte::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; border-top: 1px solid var(--gr-ligne); pointer-events: none; }
.g-barre-compacte.visible { opacity: 1; pointer-events: auto; }
/* Le titre, posé par-dessus la barre, ne prend jamais le toucher : transparent (barre au repos) ou non, il couvrait
   la moitié droite d'un « ‹ Réglages » plus large que ses 60 px de marge. */
.g-barre-compacte .g-barre-titre { position: absolute; left: 60px; right: 60px; text-align: center; font: 600 17px/22px var(--gr-sans);
                                    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
.g-barre-compacte .g-barre-gauche { margin-right: auto; display: flex; align-items: center; }
.g-barre-compacte .g-barre-droite { margin-left: auto; display: flex; align-items: center; }
.g-barre-compacte.toujours { opacity: 1; pointer-events: auto; margin-bottom: 0; }
.g-barre-compacte.toujours:not(.visible) { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
.g-barre-compacte.toujours:not(.visible)::after { border-top-color: transparent; }
.g-barre-compacte.toujours:not(.visible) .g-barre-titre { opacity: 0; }
.g-retour { display: inline-flex; align-items: center; gap: 2px; height: 44px; padding: 0 8px 0 2px; border: 0; background: none;
            color: var(--gr-texte); font: 400 17px/1 var(--gr-sans); text-decoration: none; cursor: pointer; border-radius: var(--r-ctrl); }

/* =====================================================================
   § 6.10 Bande des jours et marque de jour (construite par jour.js)
   <nav class="g-bande" aria-label="Jours"><div class="g-bande-piste">
     <div class="g-bande-semaine"> 7 × <button class="g-jour [aujourdhui] [futur]" aria-label aria-current>
        <span class="g-jour-initiale t-micro">L</span><span class="g-jour-num">12</span>
        <span class="g-marque"><i class="g-seg sur|memoire|autre|manquant|trou"></i><i …></i></span>
        (trou : tous les segments en .trou ; le premier se dessine en anneau, les autres s'effacent)
        (inconnu : <span class="g-marque inconnu"><i></i></span>) </button></div> …</div></nav>
   Le disque du jour affiché : par défaut sur le numéro de [aria-current="date"] ; avec .glisse,
   un seul élément .g-bande-disque que jour.js déplace (280 ms).
   ===================================================================== */
.g-bande { margin: 0 calc(var(--gr-marge) - 4px) 16px; position: relative; }
.g-bande-piste { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.g-bande-piste::-webkit-scrollbar { display: none; }
.g-bande-semaine { flex: 0 0 100%; display: grid; grid-template-columns: repeat(7, 1fr); scroll-snap-align: start; position: relative; }
.g-jour {
    position: relative; height: 52px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 0;
    border: 0; background: none; color: var(--gr-texte); cursor: pointer; border-radius: var(--r-ctrl);
}
.g-jour-initiale { color: var(--gr-texte-3); height: 13px; }
.g-jour-num {
    position: relative; z-index: 1; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
    font: 500 15px/1 var(--gr-sans); font-variant-numeric: tabular-nums;
    transition: background-color var(--d-moyen) var(--c-standard), color var(--d-moyen);
}
.g-bande:not(.glisse) .g-jour[aria-current="date"] .g-jour-num { background: var(--gr-texte); color: var(--gr-inverse); font-weight: 600; }
.g-bande.glisse .g-jour[aria-current="date"] .g-jour-num { color: var(--gr-inverse); font-weight: 600; }
.g-jour.aujourdhui:not([aria-current="date"]) .g-jour-num { box-shadow: inset 0 0 0 1.5px var(--gr-texte); }
.g-jour:focus-visible { outline-offset: -2px; }
.g-jour.futur, .g-jour:disabled { cursor: default; }
.g-jour.futur .g-jour-num, .g-jour.avant .g-jour-num { opacity: .35; }
.g-bande-disque { position: absolute; z-index: 0; top: 15px; left: 0; width: 28px; height: 28px; border-radius: 50%;
                  background: var(--gr-texte); transition: transform var(--d-moyen) var(--c-standard); pointer-events: none; }
.g-marque { display: flex; gap: 2px; height: 4px; margin-top: 2px; }
.g-seg { width: 9px; height: 4px; border-radius: 1px; display: block; }
.g-seg.sur { background: var(--gr-texte); }
.g-seg.memoire { background: var(--gr-memoire); }
.g-seg.autre { background: var(--gr-texte-3); }
.g-seg.manquant { box-shadow: inset 0 0 0 1px var(--gr-texte-3); }
/* Trou : une FORME, pas seulement une couleur (§ 11, capture en gris) : un anneau rouille de 8 px (1,5 px) à la place
   des segments, comme la capsule du Journal (§ 6.11). Le premier segment devient l'anneau, les suivants s'effacent. */
.g-seg.trou { width: 8px; height: 8px; margin: -3px 0 -1px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--gr-accent); }
.g-seg.trou ~ .g-seg.trou { display: none; }
.g-marque.inconnu { align-items: center; }
.g-marque.inconnu > i { display: block; width: 20px; height: 1.5px; border-radius: 1px; background: var(--gr-texte-3); }
@media (max-height: 700px) {
    .g-bande { margin-bottom: 8px; }
    .g-bande-piste { padding-block: 4px; margin-block: -4px; }      /* de quoi loger la cible de 44 */
    .g-jour { height: 36px; }
    .g-jour::before { content: ''; position: absolute; inset: -4px 0; }
    .g-jour-initiale { display: none; }
    .g-bande-disque { top: 0; }
}

/* =====================================================================
   § 6.11 Capsule de tenue (Journal)
   <span class="g-capsule [memoire] [trou] [inconnu]"><i style="--c1:…"></i><i class="autre|manquant"></i></span>
   ===================================================================== */
.g-capsule { display: inline-flex; flex-direction: column; gap: 2px; width: 24px; }
.g-capsule > i { display: block; width: 24px; height: 7px; border-radius: 2px; background: var(--c1, transparent);
                 box-shadow: inset 0 0 0 1px var(--c-encre, transparent); }
.g-capsule > i.autre { background: color-mix(in srgb, var(--gr-texte-3) 50%, transparent); box-shadow: none; }
.g-capsule > i.manquant { background: none; box-shadow: none; outline: 1px dotted var(--gr-ligne-forte); outline-offset: -1px; }
.g-capsule.memoire > i:not(.autre):not(.manquant) { opacity: .55; }
.g-capsule.inconnu > i { background: repeating-linear-gradient(135deg, var(--gr-texte-3) 0 1.5px, transparent 1.5px 4px); box-shadow: none; }
.g-capsule.trou { width: 24px; height: 16px; align-items: center; justify-content: center; }
.g-capsule.trou > i { display: none; }
.g-capsule.trou::before { content: ''; width: 10px; height: 10px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--gr-accent); }

/* =====================================================================
   § 6.12 Barre de vie (fiche, Durée de vie)
   <div class="g-vie" role="img" aria-label="…" style="--max:20;--c1:…">
     <div class="g-vie-piste">
       <span class="g-vie-avant" style="--de:0;--a:3"></span>   ports avant le suivi
       <span class="g-vie-sur" style="--de:3;--a:9"></span>     ports sûrs
       <span class="g-vie-memoire" style="--de:9;--a:14"></span> ports de mémoire
       <span class="g-vie-zone" style="--de:12;--a:17"><span class="g-vie-etiquette">dague 12–17</span></span>
       <span class="g-vie-projection" style="--de:6;--a:12"></span>
       <i class="g-vie-usure" style="--a:7"></i> <i class="g-vie-rebut" style="--a:12"></i>
       <span class="g-vie-valeur" style="--a:6">6</span>
     </div>
     <div class="g-vie-axe t-micro" style="--max:20"><span style="--a:0">0</span>…</div>
   </div>
   Positions en ports, rapportées à --max = ceil((max(zone.max, total) + 2) / 5) × 5.
   ===================================================================== */
.g-vie { --max: 20; position: relative; padding-top: 22px; }
.g-vie-piste { position: relative; height: 8px; border-radius: 2px; background: var(--gr-surface-2); }
.g-vie-piste > * { position: absolute; top: 0; bottom: 0; left: calc(var(--de, 0) / var(--max) * 100%);
                   width: calc((var(--a, 0) - var(--de, 0)) / var(--max) * 100%); border-radius: 2px; }
.g-vie-avant { background: color-mix(in srgb, var(--gr-texte-3) 30%, transparent); }
.g-vie-sur { background: var(--c1); box-shadow: inset 0 0 0 1px var(--c-encre); transform-origin: left; animation: g-remplir var(--d-long) var(--c-sortie) 120ms both; }
.g-vie-memoire { background: repeating-linear-gradient(135deg, var(--c1) 0 2px, transparent 2px 4px); box-shadow: inset 0 0 0 1px var(--c-encre);
                 transform-origin: left; animation: g-remplir var(--d-long) var(--c-sortie) 120ms both; }
.g-vie-zone { top: -10px; bottom: -10px; border-radius: 0; border-left: 1px solid var(--gr-accent); border-right: 1px solid var(--gr-accent);
              background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--gr-accent) 12%, transparent) 0 2px, transparent 2px 5px);
              animation: g-fondu var(--d-long) linear 120ms both; }
.g-vie-etiquette { position: absolute; left: -1px; bottom: calc(100% + 2px); display: inline-flex; align-items: center; gap: 2px;
                   font: 600 12px/16px var(--gr-sans); color: var(--gr-accent); white-space: nowrap; font-variant-numeric: tabular-nums; }
.g-vie-etiquette .g-ic { width: 12px; height: 12px; }
.g-vie-projection { top: 3.5px; bottom: auto; height: 0; border-radius: 0; border-top: 1px dashed var(--gr-texte-3); }
.g-vie-piste > i { width: 10px; height: 10px; top: -1px; left: calc(var(--a) / var(--max) * 100% - 5px); }
.g-vie-usure { border-radius: 50%; background: var(--gr-attention); box-shadow: 0 0 0 2px var(--gr-fond); }
.g-vie-rebut { border-radius: 1px; background: var(--gr-accent); transform: rotate(45deg) scale(.8); box-shadow: 0 0 0 2px var(--gr-fond); }
.g-vie-valeur { width: auto; left: calc(var(--a) / var(--max) * 100%); top: auto; bottom: calc(100% + 4px); transform: translateX(-50%);
                font: 600 12px/16px var(--gr-sans); font-variant-numeric: tabular-nums; color: var(--gr-texte); }
.g-vie-axe { position: relative; height: 13px; margin-top: 6px; color: var(--gr-texte-3); }
.g-vie-axe > span { position: absolute; left: calc(var(--a) / var(--max) * 100%); transform: translateX(-50%); }
.g-vie-axe > span:first-child { transform: none; }
.g-vie-axe > span:last-child { transform: translateX(-100%); }
@keyframes g-remplir { from { transform: scaleX(0); } to { transform: none; } }
/* Mini-barre du tableau (96 × 6) : remplissage et zone, sans étiquettes. */
.g-vie.mini { padding-top: 0; width: 96px; }
.g-vie.mini .g-vie-piste { height: 6px; }
.g-vie.mini .g-vie-zone { top: -3px; bottom: -3px; }
.g-vie.mini .g-vie-etiquette, .g-vie.mini .g-vie-valeur, .g-vie.mini .g-vie-axe { display: none; }

/* =====================================================================
   Planche d'une tenue (GR.planche, dessins.js ; cahier quantités § 6.3, venue de tenues.css)
   <span class="g-planche [avec-cote] [classe de l'écran]" aria-hidden="true">
     <span class="g-planche-pile"> 1 à 3 × <span class="g-planche-sil haut|bas|pieds [rebut]" style="--c1…"><svg><use href="#sil-…"/></svg></span> </span>
     [<span class="g-planche-cote"> 1 à 4 × <span class="g-planche-sil mini [rebut]" style="…">…</span> </span>]
   </span>
   3:4, largeur de son conteneur (l'écran la dimensionne : carte, fiche, bande du compositeur). Silhouettes teintées
   (les règles .s-* restent celles de jetons.css, sans contexte). Marges en px : un pourcentage de padding se
   rapporterait à la largeur du parent, pas à celle de la planche. min-height: 0 : une boîte à aspect-ratio a pour
   hauteur minimale son contenu ; sans lui, les silhouettes (hauteurs en %, aspect-ratio 1) l'agrandissaient.
   ===================================================================== */
.g-planche {
    position: relative; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr);
    aspect-ratio: 3 / 4; width: 100%; min-height: 0; overflow: hidden; padding: 12px; border-radius: var(--r-tirage); background: var(--gr-puits);
    transition: transform var(--d-instant) var(--c-standard);
}
.g-planche.avec-cote { grid-template-columns: minmax(0, 1fr) 26%; column-gap: 4%; }
.g-planche-pile { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 0; }
.g-planche-cote { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: 0; }
.g-planche-sil { display: block; flex: none; aspect-ratio: 1; }
.g-planche-sil > svg { display: block; width: 100%; height: 100%; }
.g-planche-pile > .haut { height: 38%; }
.g-planche-pile > .bas { height: 40%; margin-top: -3%; }
.g-planche-pile > .pieds { height: 26%; margin-top: -1%; }
.g-planche-cote > .mini { width: 100%; height: auto; max-height: 24%; --trait: none; }
.g-planche-sil.rebut { filter: grayscale(1); opacity: .5; }

/* =====================================================================
   § 6.13 Squelettes et états vides
   ===================================================================== */
.g-squelette { display: block; border-radius: var(--r-tirage); background: var(--gr-puits); position: relative; overflow: hidden; }
.g-squelette.vg { aspect-ratio: 1; width: 100%; }
.g-squelette.ligne { height: 12px; margin-top: 8px; width: 70%; border-radius: 2px; }
.g-squelette::after {
    content: ''; position: absolute; inset: 0; transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgb(var(--gr-encre-rgb) / .06), transparent);
    animation: g-balayage 1.2s linear infinite;
}
@keyframes g-balayage { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .g-squelette::after { display: none; } }

/* <div class="g-vide"><span class="g-vide-sil" aria-hidden="true"> 3 × <svg viewBox="0 0 64 64"><use href="#sil-jean"/></svg></span>
     <h2 class="t-affiche">…</h2><p class="t-chapo">…</p> une seule action </div> */
.g-vide { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; padding: 48px var(--gr-marge); }
.g-vide-sil { display: flex; gap: 8px; margin-bottom: 8px;
              --c1: transparent; --c2: transparent; --tr: color-mix(in srgb, var(--gr-texte) 28%, transparent); }
.g-vide-sil > svg { width: 64px; height: 64px; }
.g-vide > .t-affiche { font-size: 32px; line-height: 36px; margin: 0; }
.g-vide > .t-chapo { margin: 0; color: var(--gr-texte-2); max-width: 30ch; }
.g-vide > .g-bouton { margin-top: 12px; }

/* =====================================================================
   Carte « Aujourd'hui » (Pièces mobile, aperçu du bureau) — § 8.2
   <a class="g-carte-jour" href="garderobe-jour.html"> <span class="g-carte-jour-vgs"> 2 × (.g-vg.s | .g-emplacement) </span>
     <span class="g-carte-jour-texte"><span class="t-surtitre">Aujourd'hui</span><span class="g-carte-jour-titre">À noter</span></span>
     actions | chevron </a>
   ===================================================================== */
.g-carte-jour {
    display: flex; align-items: center; gap: 6px; min-height: 76px; padding: 12px; border-radius: var(--r-ctrl);
    background: var(--gr-surface); color: var(--gr-texte); text-decoration: none; position: relative;
}
/* Les deux visuels se chevauchent de 8 px (comme dans « Comme hier ») : à 375 px, le texte garde sa place. */
.g-carte-jour-vgs { display: flex; flex: none; --vg: 52px; }
.g-carte-jour-vgs > * + * { margin-left: -8px; box-shadow: 0 0 0 2px var(--gr-surface); }
.g-carte-jour-texte .t-surtitre, .g-carte-jour-titre { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Opaque (la surface de la carte) : le second recouvre les tirets du premier là où ils se chevauchent. */
.g-emplacement { width: var(--vg, 52px); aspect-ratio: 1; border-radius: var(--r-tirage); border: 1px dashed var(--gr-ligne-forte); flex: none;
                 background: var(--gr-surface); }
.g-carte-jour-texte { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.g-carte-jour-texte .t-surtitre { color: var(--gr-texte-2); }
.g-carte-jour-titre { font: 400 22px/26px var(--gr-serif); }
.g-carte-jour-titre.noms { font: 500 15px/20px var(--gr-sans); }
.g-carte-jour .g-chevron { color: var(--gr-texte-3); flex: none; }
.g-lien-trous { display: inline-flex; align-items: center; gap: 2px; min-height: 44px; color: var(--gr-accent);
                font: 600 13px/16px var(--gr-sans); text-decoration: none; border-radius: var(--r-ctrl); }
.g-lien-trous .g-ic { width: 16px; height: 16px; }

/* =====================================================================
   § 3.6 Replis de la matière (en FIN de fichier : ils battent les règles de base de même spécificité)
   Sans flou disponible, ou transparence réduite demandée : fonds pleins, sans flou.
   ===================================================================== */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .g-barre, .g-barre-compacte.visible, .g-barre-compacte.toujours.visible { background: var(--gr-fond); }
    .g-pastille, .g-bouton-ic.rond, .g-verre, .g-tuile-etiquette, .g-tuile-nombre, .g-tuile-marque { background: var(--gr-surface); }
}
@media (prefers-reduced-transparency: reduce) {
    .g-barre, .g-barre-compacte.visible, .g-barre-compacte.toujours.visible { background: var(--gr-fond); -webkit-backdrop-filter: none; backdrop-filter: none; }
    .g-barre-compacte { -webkit-backdrop-filter: none; backdrop-filter: none; }
    .g-pastille, .g-bouton-ic.rond, .g-verre, .g-tuile-etiquette, .g-tuile-nombre, .g-tuile-marque { background: var(--gr-surface); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* L'installation « seed » (les Tools, où chaque nouveauté s'éprouve avant dégaine) : une pastille à côté du nom. */
.g-seed { display: inline-block; margin-left: .35em; padding: 2px 7px; border-radius: 999px; vertical-align: .55em;
    font: 600 11px/13px var(--gr-sans); letter-spacing: .04em; text-transform: uppercase;
    color: var(--gr-accent); background: var(--gr-accent-doux); }
