/* La Cueillette du CBD · feuille de style du site. Jetons tirés du brandbook. */

@font-face { font-family: Gloock; src: url('/assets/polices/Gloock-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Instrument Sans'; src: url('/assets/polices/InstrumentSans-Variable.woff2') format('woff2'); font-weight: 400 700; font-display: swap; }
@font-face { font-family: 'DM Mono'; src: url('/assets/polices/DMMono-Medium.woff2') format('woff2'); font-weight: 500; font-display: swap; }

:root {
  --papier: #F4EFE4; --ivoire: #FBF8F1; --lin: #E9E1D0; --trait: #D6CCB8;
  --encre: #1F2A22; --encre-douce: #4C554B; --sousbois: #1F2A22; --sur-sousbois: #F4EFE4;
  --laiton: #9C7535; --laiton-texte: #7A5A24; --laiton-sur-sousbois: #C9A45E;
  --action: #1F2A22; --sur-action: #F4EFE4; --action-survol: #3D5A45; --focus: #9C7535;
  --mousse: #3D5A45; --rouille: #9A4A26;
  --arome-zeste: #9F7B12; --arome-terre: #875B3A; --arome-baie: #5C3652; --arome-fleur: #A8697B;
  --font-titre: Gloock, Georgia, "Times New Roman", serif;
  --font-texte: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --font-etiquette: "DM Mono", ui-monospace, Menlo, monospace;
  --r-etiquette: 2px; --r-controle: 6px; --r-carte: 14px;
  --ombre-carte: 0 1px 2px rgba(31,42,34,.06), 0 8px 24px rgba(31,42,34,.06);
  --gouttiere: 16px;
  --sortie: cubic-bezier(.23, 1, .32, 1);
  /* Aplats : identiques en Jour et en Soir, ne pas les reporter dans les blocs Soir.
     Les arômes Soir (#D9B65A…) sont calibrés pour de petites marques ; en plein écran sous un texte ivoire, ils échoueraient au contraste. */
  --aplat-zeste: #9F7B12; --aplat-terre: #875B3A; --aplat-baie: #5C3652; --aplat-fleur: #A8697B;
  --aplat-sousbois: #1F2A22; --aplat-mousse: #3D5A45;
  --sur-aplat: #FBF8F1;            /* ivoire, seule encre sur un aplat */
  --laiton-clair: #C9A45E;         /* grands textes et traits sur sous-bois et Baie */
  /* Mouvement : courbes et durées partagées par tout le site */
  --entree-sortie: cubic-bezier(.65, 0, .35, 1);
  --rebond: cubic-bezier(.34, 1.56, .64, 1);
  --vol: cubic-bezier(.22, 1, .36, 1);
  --pose: linear(0, .36 18%, .75 32%, 1 42%, .88 52%, 1 64%, .97 76%, 1);
  --d-court: 180ms; --d-moyen: 600ms; --d-long: 900ms;
  --pas-delai: 80ms;               /* écart entre deux éléments révélés en cascade (.delai-1 à .delai-6) */
  /* Échelle typographique : un seul jeu de chiffres (cahier de création, § 1.2) */
  --t-mega: clamp(88px, 22vw, 320px);
  --t-display: clamp(56px, 12vw, 200px);
  --t-h2: clamp(36px, 6vw, 96px);
  --t-h3: clamp(24px, 2.4vw, 36px);
  --t-chiffre: clamp(96px, 20vw, 280px);
  --t-chapo: clamp(19px, 1.6vw, 24px);
  --t-titre: clamp(30px, 3.4vw, 48px);  /* titres de bloc */
  --t-grand: clamp(40px, 5vw, 72px);    /* titres de chapitre */
  --t-affiche: clamp(64px, 9.4vw, 136px); /* un mot ou un nombre en affiche */
  --t-corps: 17px;                      /* texte courant (18 px dès 900 px) */
  --t-petit: 16px;                      /* notes secondaires : jamais de texte courant sous 16 px */
  --t-mini: 13px;                       /* le plancher : rien de lisible en dessous */
  --t-etiquette: 13px;
  --haut-demo: 0px;                /* 32px quand le bandeau démo est affiché */
  --haut-entete: 77px;             /* l'en-tête collant : 44 px de zone de clic, 2 × 16 px, un filet (65 px sous 600 px) */
}
@media (max-width: 600px) { :root { --haut-entete: 65px; } }
@media (min-width: 900px) { :root { --gouttiere: 64px; --t-corps: 18px; } }
/* Posé sur la racine (et non sur body) : scroll-padding-top, lu sur html, doit voir la même valeur que l'en-tête.
   html.demo est posé par le serveur dès le HTML (serveur/index.js), et par app.js en repli : il ne dépend pas de :has(). */
:root.demo, :root:has([data-bandeau-demo]:not([hidden])) { --haut-demo: 32px; }

/* Les ombres des spécimens, du sol et du ticket, et la nuance Baie des petites marques posées sur le papier. */
:root {
  --ombre-specimen: drop-shadow(0 24px 22px rgba(31, 42, 34, .16)) drop-shadow(0 3px 4px rgba(31, 42, 34, .14));
  --ombre-sol: rgba(31, 42, 34, .20);
  --ombre-ticket: drop-shadow(0 1px 1px rgba(31, 42, 34, .08)) drop-shadow(0 16px 28px rgba(31, 42, 34, .11));
  --nuance-baie: var(--aplat-baie);
  --halo-specimen: none;
}

/* Thème Soir, valeurs du brandbook. Choisi par le visiteur (data-theme) ou, sans choix, par le réglage de l'appareil. */
/* Seuls --sousbois, les arômes et les ombres changent de valeur ici. Aucun jeton d'aplat, de mouvement ou d'échelle n'a
   de valeur Soir : c'est voulu. Sur le fond sombre, le détourage passe par #detourage (le liseré clair d'un pixel est rongé),
   un halo très léger détache le spécimen, et la nuance Baie des petites marques s'éclaircit (3,3:1 sur le papier Soir). */
:root[data-theme="soir"] {
  color-scheme: dark;
  --papier: #131915; --ivoire: #1C241F; --lin: #222B25; --trait: #34403A;
  --encre: #EEE7D8; --encre-douce: #AEB4A8; --sousbois: #2C3D33; --sur-sousbois: #F4EFE4;
  --laiton: #C9A45E; --laiton-texte: #C9A45E; --laiton-sur-sousbois: #C9A45E;
  --action: #C9A45E; --sur-action: #131915; --action-survol: #D9B977; --focus: #D9B977;
  --mousse: #8FB29A; --rouille: #D9875E;
  --arome-zeste: #D9B65A; --arome-terre: #C79A74; --arome-baie: #C08AB4; --arome-fleur: #D9A0AF;
  --ombre-carte: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.25);
  --ombre-specimen: url(#detourage) drop-shadow(0 24px 22px rgba(0, 0, 0, .45)) drop-shadow(0 3px 4px rgba(0, 0, 0, .4));
  --ombre-sol: rgba(0, 0, 0, .55);
  --ombre-ticket: drop-shadow(0 1px 1px rgba(0, 0, 0, .4)) drop-shadow(0 16px 28px rgba(0, 0, 0, .45));
  --nuance-baie: #8E5A86;
  --halo-specimen: radial-gradient(closest-side, rgb(255 255 255 / .06), transparent);
}
@media (prefers-color-scheme: dark) {
  /* Même bloc que ci-dessus, pour le visiteur qui n'a rien choisi : les deux restent identiques. */
  :root:not([data-theme="jour"]) {
    color-scheme: dark;
    --papier: #131915; --ivoire: #1C241F; --lin: #222B25; --trait: #34403A;
    --encre: #EEE7D8; --encre-douce: #AEB4A8; --sousbois: #2C3D33; --sur-sousbois: #F4EFE4;
    --laiton: #C9A45E; --laiton-texte: #C9A45E; --laiton-sur-sousbois: #C9A45E;
    --action: #C9A45E; --sur-action: #131915; --action-survol: #D9B977; --focus: #D9B977;
    --mousse: #8FB29A; --rouille: #D9875E;
    --arome-zeste: #D9B65A; --arome-terre: #C79A74; --arome-baie: #C08AB4; --arome-fleur: #D9A0AF;
    --ombre-carte: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.25);
    --ombre-specimen: url(#detourage) drop-shadow(0 24px 22px rgba(0, 0, 0, .45)) drop-shadow(0 3px 4px rgba(0, 0, 0, .4));
    --ombre-sol: rgba(0, 0, 0, .55);
    --ombre-ticket: drop-shadow(0 1px 1px rgba(0, 0, 0, .4)) drop-shadow(0 16px 28px rgba(0, 0, 0, .45));
    --nuance-baie: #8E5A86;
    --halo-specimen: radial-gradient(closest-side, rgb(255 255 255 / .06), transparent);
  }
}
/* La marque, en ligne (outils/marque.py). Deux encres seulement : --marque-encre pour le C et les lettres,
   --marque-laiton pour le bourgeon et « DU CBD ». Sur le papier, elles suivent le thème (--encre et --laiton changent en Soir) ;
   sur un aplat (.marque--claire), elles restent ivoire et laiton clair, en Jour comme en Soir. */
.marque { display: block; overflow: visible; --marque-encre: var(--encre); --marque-laiton: var(--laiton); }
.marque--claire { --marque-encre: var(--sur-aplat); --marque-laiton: var(--laiton-clair); }
.mono__c, .logo__c, .logo__mot, .logo__lettre, .totem__lettres { fill: var(--marque-encre); }
.mono__bourgeon, .logo__bourgeon, .logo__mention, .totem__bourgeon { fill: var(--marque-laiton); }
/* L'anneau d'empreinte : invisible tant qu'un geste ne le joue pas (.est-jouee). */
.mono__empreinte, .logo__empreinte { stroke: var(--marque-laiton); opacity: 0; pointer-events: none; }
.mono__bourgeon, .totem__bourgeon, .logo__bourgeon, .logo__empreinte, .mono__empreinte { transform-box: fill-box; transform-origin: center; }
.mono__empreinte.est-jouee, .logo__empreinte.est-jouee { animation: empreinte 500ms var(--sortie) both; }
/* Le C se dessine par son masque (modèle de la porte). Mouvement réduit : la règle globale le pose entier aussitôt. */
.mono__trace { stroke-dasharray: 1; stroke-dashoffset: 1; animation: trace 1200ms var(--entree-sortie) forwards; }
.fenetre-c__voile { fill: var(--fond-voile, var(--aplat-sousbois)); }
@keyframes trace { to { stroke-dashoffset: 0; } }
/* --chute : la hauteur de la chute, dans le repère du dessin (160 par défaut). */
@keyframes pose { from { translate: 0 var(--chute, -160px); opacity: 0; } 30% { opacity: 1; } to { translate: 0 0; opacity: 1; } }
@keyframes empreinte { from { scale: 1; opacity: .6; } to { scale: 2.6; opacity: 0; } }
/* Le semis : un point de laiton tous les 24 px, en quinconce. Seulement sur les aplats sous-bois. */
.semis { background-image: url('/assets/marque/semis.svg'); background-size: 96px 96px; }

* { box-sizing: border-box; }
/* overflow-x: clip sur html aussi : la valeur de body n'est plus reportée sur la fenêtre (où elle deviendrait hidden, qui
   compte encore dans scrollWidth). body rogne alors vraiment ce qui dépasse, au sous-pixel près (pivot du spécimen de l'ouverture).
   Repli : un navigateur sans overflow: clip (Safari 15 et avant) garde hidden, déclaré juste avant. */
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(96px + var(--haut-demo)); overflow-x: hidden; overflow-x: clip; }
body { margin: 0; overflow-x: hidden; overflow-x: clip; background: var(--papier); color: var(--encre); font-family: var(--font-texte); font-size: var(--t-corps); line-height: 1.55; font-synthesis: none; font-kerning: normal; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
@media (min-width: 900px) { body { font-size: var(--t-corps); } }
img { max-width: 100%; display: block; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
[hidden] { display: none !important; }
.filtres-svg { position: absolute; width: 0; height: 0; overflow: hidden; }
.cache { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Typographie. Gloock n'a qu'une graisse et pas d'italique : un mot se met en valeur par la couleur (.laiton), jamais autrement. */
h1, h2, h3 { font-family: var(--font-titre); font-weight: 400; margin: 0; text-wrap: balance; }
h1 { font-size: var(--t-grand); line-height: 1; letter-spacing: -.02em; }
h2 { font-size: var(--t-h3); line-height: 1.15; letter-spacing: -.01em; }
h3 { font-size: var(--t-h3); line-height: 1.1; }
p, li { text-wrap: pretty; }
.titre-3 { font-size: var(--t-h3); line-height: 1.1; margin-top: 16px; }
.laiton { color: var(--laiton); }
.chapo { font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: var(--encre-douce); max-width: 34em; }
.surtitre, .etiquette { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); line-height: 1.3; letter-spacing: .12em; text-transform: uppercase; }
/* L'échelle (§ 1.2) passe par ses jetons (--t-mega, --t-display, --t-h2…), repris par chaque titre. */
.surtitre { color: var(--laiton-texte); }
.muet { color: var(--encre-douce); }

/* Structure */
.page { padding: 0 var(--gouttiere); max-width: 1280px; margin: 0 auto; }
.section { padding: 64px 0; }
@media (min-width: 900px) { .section { padding: 96px 0; } }

/* En-tête, collant en haut de l'écran */
.entete { position: sticky; top: var(--haut-demo); z-index: 20; background: var(--papier); border-bottom: 1px solid var(--trait); }
.entete__interieur { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px var(--gouttiere); max-width: 1280px; margin: 0 auto; }
/* Le logo d'origine, au ras de l'encre : le dos du C tombe sur la gouttière. 36 px d'encre, 44 px de zone de clic.
   Sous 900 px, la boîte se resserre sur le monogramme du même dessin (le cadrage slice rogne le mot, qu'on masque). */
.entete__logo { display: inline-flex; align-items: center; min-height: 44px; flex: none; border-radius: var(--r-etiquette); color: inherit; }
.entete__logo .logo { height: 36px; width: calc(36px * 493 / 80.5); }
.entete__logo:focus-visible { outline-offset: 6px; }
@media (max-width: 899px) {
  .entete__logo .logo { height: 30px; width: 27px; }
  .entete__logo .logo__mot, .entete__logo .logo__mention { display: none; }
}
.entete nav { display: flex; gap: 24px; align-items: center; }
.entete nav a { text-decoration: none; font-weight: 600; font-size: var(--t-petit); min-height: 44px; display: inline-flex; align-items: center; }
@media (hover: hover) and (pointer: fine) { .entete nav a:hover { color: var(--laiton-texte); } }
/* Les icônes de l'en-tête ne servent que sur téléphone (plus bas) : l'épingle du comptoir, la lune ou le soleil du thème. */
.icone { display: block; width: 22px; height: 22px; flex: none; }
.entete__icone, .bascule-theme__icone { display: none; }
.bascule-theme { appearance: none; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--trait); background: none; color: var(--encre); border-radius: 999px; min-height: 44px; min-width: 64px; padding: 0 14px; font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .14em; text-transform: uppercase; cursor: pointer; touch-action: manipulation; transition: border-color 160ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .bascule-theme:hover { border-color: var(--encre-douce); } }
.bascule-theme[data-vers="jour"] .icone-lune, .bascule-theme:not([data-vers="jour"]) .icone-soleil { display: none; }
/* La pastille garde sa place, panier vide compris : la navigation ne se décale pas d'une page à l'autre. */
.pastille-panier { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 999px; background: var(--sousbois); color: var(--sur-sousbois); font-family: var(--font-etiquette); font-size: var(--t-mini); margin-left: 6px; }
.pastille-panier[hidden] { display: inline-grid !important; visibility: hidden; }
/* En Soir, la pastille passe en laiton sur encre : le vert foncé sur le papier sombre ne se voyait pas. */
:root[data-theme="soir"] .pastille-panier { background: var(--laiton); color: var(--sur-action); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="jour"]) .pastille-panier { background: var(--laiton); color: var(--sur-action); } }

/* Bandeau de démonstration : collant en haut, au-dessus de l'en-tête, qui se pose dessous (top: var(--haut-demo)).
   Une ligne de 32 px, DM Mono rouille sur ivoire ; sur mobile, la phrase se coupe en points de suspension.
   La rouille est réservée aux erreurs et à ce bandeau : jamais un aplat. */
.bandeau-demo { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; justify-content: center; height: 32px; margin: 0; padding: 0 var(--gouttiere); background: var(--ivoire); border-bottom: 1px solid var(--trait); color: var(--rouille); font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .02em; }
.bandeau-demo__texte { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* Le titre en capitales sur ordinateur. Sur téléphone, une phrase courte qui tient entière, sans points de suspension. */
.bandeau-demo__titre { text-transform: uppercase; letter-spacing: .12em; }
.bandeau-demo__court { display: none; }
@media (max-width: 719px) {
  .bandeau-demo { letter-spacing: 0; }
  .bandeau-demo__long { display: none; }
  .bandeau-demo__court { display: block; }
}

/* Bandeau d'offre, sous l'en-tête. Un message à la fois, en fondu enchaîné : l'entrant monte de 6 px pendant que le sortant
   s'efface (il part un peu avant, les deux textes ne se lisent jamais ensemble). Le bandeau n'est jamais vide. */
.bandeau-offre { display: grid; align-items: center; min-height: 40px; background: var(--sousbois); color: var(--sur-sousbois); padding: 10px var(--gouttiere); text-align: center; font-size: var(--t-petit); line-height: 20px; font-weight: 500; letter-spacing: .01em; }
.bandeau-offre__message { grid-area: 1 / 1; margin: 0; opacity: 0; translate: 0 6px; transition: opacity 180ms var(--sortie), translate 0s linear 180ms; }
.bandeau-offre__message.est-visible { opacity: 1; translate: 0 0; transition: opacity 360ms var(--sortie) 90ms, translate 360ms var(--sortie) 90ms; }
/* Mouvement réduit : le bandeau ne tourne pas. Les autres messages ne se montrent jamais : ils sortent de la page au lieu
   d'attendre invisibles sous le premier (chacun se retrouve ailleurs sur le site : remises au comptoir, livraison, retrait). */
@media (prefers-reduced-motion: reduce) {
  .bandeau-offre__message:not(.est-visible) { display: none; }
}

/* Accueil */
.accueil__actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.insecable { white-space: nowrap; }

/* Les spécimens : les vrais produits, détourés, posés sur le papier avec la même ombre. */
.specimen { filter: var(--ombre-specimen); }

/* L'ouverture (écran 1) : aplat Baie sur toute la largeur, le premier écran entier. Le titre en display, un vrai produit
   en très grand qui passe derrière la seconde ligne (le titre reste devant, finition du 27/10/2026), le chapo et les
   boutons au-dessus du pli, une légende de musée.
   L'aplat est peint par border-image, hors de la colonne : le texte reste aligné au pixel sur la gouttière de l'en-tête.
   --chrome : l'en-tête et le bandeau d'offre, au-dessus de l'écran (77 + 40 px, puis 65 + 40 px sous 600 px). */
.ouverture {
  --chrome: 117px; --focus: var(--sur-aplat);
  position: relative; isolation: isolate; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto 1fr auto; column-gap: 24px;
  min-height: max(560px, calc(100svh - var(--haut-demo) - var(--chrome))); padding: 48px 0 48px;
  background-color: var(--aplat-baie); border-image: linear-gradient(var(--aplat-baie) 0 0) fill 0 / / 0 100vw; color: var(--sur-aplat);
  overflow-x: visible; overflow-y: clip;
}
.ouverture__titre { grid-column: 1 / -1; grid-row: 1; position: relative; z-index: 5; width: fit-content; margin: 0; font-size: var(--t-display); line-height: .92; letter-spacing: -.02em; text-wrap: nowrap; color: var(--sur-aplat); }
.ouverture__ligne { display: block; width: fit-content; }
.ouverture__ligne + .ouverture__ligne { padding-left: .3em; }
/* Le spécimen, ancré en bas à droite, déborde dans la gouttière ; la section le rogne en bas.
   Le figure va de 140 px au bas de la section ; l'image, plus haute, en déborde et la section la rogne.
   Décalé de 4 vw au-delà de la gouttière : il passe devant la seconde ligne sans couvrir le « n » de « main ». */
.ouverture__specimen { position: absolute; z-index: 3; top: 140px; bottom: 0; right: calc(var(--gouttiere) * -1 - 4vw); width: min(56vw, 860px); margin: 0; }
.ouverture__lien { display: block; border-radius: var(--r-carte); }
.ouverture__lien:focus-visible { outline-offset: -12px; }
.ouverture__img { width: 100%; height: auto; filter: url(#detourage) drop-shadow(0 32px 28px rgba(24, 10, 22, .42)) drop-shadow(0 4px 6px rgba(24, 10, 22, .32)); transition: transform 240ms var(--sortie); }
/* La légende de musée : DM Mono 12 px ivoire, jamais de laiton clair en petit texte sur Baie. */
.legende-musee { display: grid; gap: 6px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; color: var(--sur-aplat); }
.legende-musee > span + span { color: rgba(251, 248, 241, .78); }
.ouverture .legende-musee { position: absolute; z-index: 4; right: var(--gouttiere); bottom: 48px; padding-top: 12px; border-top: 1px solid rgba(251, 248, 241, .4); text-align: right; }
.ouverture__texte { grid-column: 1 / 6; grid-row: 3; position: relative; z-index: 4; display: grid; gap: 28px; align-content: end; }
.ouverture__texte .chapo { margin: 0; max-width: 20em; color: rgba(251, 248, 241, .88); }
.ouverture .accueil__actions { margin: 0; }
@media (hover: hover) and (pointer: fine) { .ouverture__lien:hover .ouverture__img { transform: translateY(-6px); } }
@media (max-width: 899px) {
  /* Sur téléphone, la section prend toute la largeur par ses marges (pas de vw) et rogne le spécimen des deux côtés :
     sans cela, un navigateur mobile élargit la page à la taille de l'image. */
  .ouverture { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto 1fr; row-gap: 20px; margin-inline: calc(var(--gouttiere) * -1); padding: 28px var(--gouttiere) 0; overflow: hidden; overflow: clip; }
  .ouverture__titre { font-size: var(--t-affiche); }
  .ouverture__texte { grid-column: 1; grid-row: 2; gap: 24px; }
  .ouverture .accueil__actions { flex-direction: column; gap: 10px; }
  .ouverture .accueil__actions .btn { width: 100%; min-height: 48px; }
  /* La Blueberry en 130 vw, ancrée en bas à droite et rognée par la section. */
  .ouverture__specimen { position: relative; grid-row: 3; align-self: end; inset: auto; width: 130vw; margin: 0 0 0 calc(var(--gouttiere) * -1 - 12vw); }
  /* La légende passe sous l'image, dans la colonne : aucun fruit ne vient la couvrir. */
  .ouverture .legende-musee { position: static; width: calc(100vw - 2 * var(--gouttiere)); margin: 0 0 32px calc(12vw + var(--gouttiere)); text-align: left; }
}
@media (max-width: 600px) { .ouverture { --chrome: 105px; } }
/* Le titre se dévoile ligne à ligne, l'image monte en place. Jamais d'opacité nulle sur l'image : le LCP se mesure.
   html.majeur : la porte est passée (au clic sur « oui », ou dès le chargement pour un visiteur qui revient).
   La découpe déborde de la boîte de ligne (interligne .92) pour ne jamais rogner l'accent du « à » ni un jambage. */
.js.majeur .ouverture__ligne { animation: ligne 700ms var(--sortie) both; }
.js.majeur .ouverture__ligne + .ouverture__ligne { animation-delay: 90ms; }
.js.majeur .ouverture__img { animation: entree 1100ms var(--sortie) both; }
@keyframes ligne { from { clip-path: inset(-.3em -.1em calc(100% + .3em) -.1em); translate: 0 .1em; } to { clip-path: inset(-.3em -.1em -.3em -.1em); translate: 0 0; } }
@keyframes entree { from { translate: 0 6vh; scale: .94; } to { translate: 0 0; scale: 1; } }
/* Au défilement, le spécimen s'incline et s'éloigne en sortant. L'animation porte sur le lien qui enveloppe l'image
   (l'img a déjà la sienne) ; la légende de musée, elle, reste droite. Pivot en bas à droite de l'image : en s'inclinant,
   le spécimen part vers la gauche et ne déborde jamais de l'écran.
   Rien en mouvement réduit : la règle globale ferait de la timeline une animation d'une milliseconde, figée sur sa fin. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .ouverture__lien { transform-origin: 100% 100%; animation: sortie linear both; animation-timeline: view(); animation-range: exit 0% exit 100%; }
  }
}
@keyframes sortie { from { rotate: 0deg; scale: 1; translate: 0 0; } to { rotate: -4deg; scale: 1.08; translate: 0 -6vh; } }

/* Le mot-totem (écran 2) : « Cueillette » du logo, en ivoire sur sous-bois et semis, plus large que l'écran.
   Le point du i manque : c'est le bourgeon qui le pose (geste 2), une fois, quand la section est visible à 60 %.
   La section va d'un bord à l'autre de l'écran ; le mot, lui, tient entre les gouttières. */
.totem {
  position: relative; display: grid; align-content: center; justify-items: center; row-gap: clamp(36px, 4.4vw, 64px);
  min-height: 70svh; margin-inline: calc(50% - 50vw); padding: clamp(104px, 11vw, 152px) 0 clamp(80px, 9vw, 128px);
  overflow: hidden; overflow: clip; background-color: var(--aplat-sousbois); color: var(--sur-aplat); --focus: var(--laiton-clair);
}
.totem__mot { justify-self: stretch; margin: 0; line-height: 0; }
/* Finition, tour 3 : le mot tient entre les gouttières, à toutes les largeurs. Avant, il débordait de 6 vw de chaque
   côté et la dérive rognait le C ou le dernier e au hasard du défilement : on ne coupe pas la marque. La dérive reste,
   plus courte (24 px au plus de part et d'autre), et ne sort jamais de la gouttière. */
.totem__svg { --derive-de: min(2vw, 24px); --derive-a: max(-2vw, -24px); display: block; width: calc(100% - 2 * var(--gouttiere)); max-width: 1280px; height: auto; margin-inline: auto; }
/* Une phrase par ligne : la coupure tombe sur le point, jamais au milieu d'une proposition. */
.totem__phrase { margin: 0; padding-inline: var(--gouttiere); font-size: var(--t-chapo); line-height: 1.45; letter-spacing: -.005em; text-align: center; text-wrap: balance; color: rgba(251, 248, 241, .86); }
@media (max-width: 899px) {
  /* Sur téléphone, le mot tient entier dans l'écran (92 vw) : le C du monogramme se lit toujours. La dérive se réduit
     à 2 vw de part et d'autre, assez pour sentir le défilement sans jamais rogner une lettre. */
  .totem { min-height: 60svh; padding: 112px 0 96px; row-gap: 32px; }
  .totem__svg { --derive-de: 2vw; --derive-a: -2vw; width: 92vw; margin-inline: 4vw; }
  .totem__phrase { font-size: var(--t-chapo); }
}
/* Geste 2. La chute se compte dans le repère du mot (53 unités de haut) : un peu moins d'une hauteur de lettre,
   la même à toutes les largeurs. Sans JavaScript, à l'impression ou en mouvement réduit, le bourgeon est déjà posé. */
@media screen and (prefers-reduced-motion: no-preference) {
  .js .totem:not(.est-visible) .totem__bourgeon { opacity: 0; }
  .js .totem.est-visible .totem__bourgeon { --chute: -44px; animation: pose 900ms var(--pose) 160ms both; }
}
/* Le mot dérive au défilement, de droite à gauche, sur toute la traversée de l'écran. Le bourgeon suit son i. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .totem__svg { animation: derive linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
  }
}
.totem__phrase > span { display: block; }
@keyframes derive { from { translate: var(--derive-de) 0; } to { translate: var(--derive-a) 0; } }


/* Têtes de section : un titre, une phrase, rien d'autre. */
.chapitre { padding: 48px 0; }
@media (min-width: 900px) { .chapitre { padding: 72px 0; } }
.chapitre--page { padding-top: 48px; }
.etagere__tete { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px 32px; margin-bottom: 40px; }
.etagere__tete h1, .etagere__tete h2 { font-size: var(--t-grand); line-height: 1.02; letter-spacing: -.02em; }
.etagere__tete > p { margin: 0; max-width: 30em; }
.chapitre__suite { margin: 40px 0 0; }
/* La flèche est posée hors du flux : un soulignement ne se propage pas à un élément positionné, il s'arrête au dernier mot. */
.lien-laiton { position: relative; color: var(--laiton-texte); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; min-height: 44px; display: inline-flex; align-items: center; padding-right: 1.5em; }
.lien-laiton::after { content: "→"; position: absolute; right: 0; top: 50%; translate: 0 -50%; transition: translate 200ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .lien-laiton:hover::after { translate: 4px -50%; } }

/* Écran 3 · Le nuancier. Une seule scène épinglée : quatre temps, un par famille. L'aplat de la famille prend l'écran,
   son nom entre en très grand, un vrai produit s'y pose, une étiquette ivoire porte la phrase, le compte et le lien.
   Le défilement est la seule source de vérité (app.js, nuancierScene()) : il écrit data-temps, --pt, le compteur,
   .est-active et .est-passee. Remonter rejoue tout à l'envers. Aucune couleur ne change sur body.
   Les aplats ne suivent pas le thème. Toute encre est ivoire, en 24 px au moins sur Zeste et Fleur : ce qui est plus petit
   va sur l'étiquette ivoire (.sur-etiquette).
   L'aplat est peint par border-image, hors de la colonne : le texte reste aligné au pixel sur la gouttière de l'en-tête.
   Par défaut (sans JavaScript, à l'impression, en mouvement réduit), les quatre familles s'empilent, chacune sur son aplat. */
@property --fond-scene { syntax: '<color>'; inherits: false; initial-value: #9F7B12; }
.nuancier-scene { position: relative; color: var(--sur-aplat); --focus: var(--sur-aplat); }
.famille--zeste { --aplat: var(--aplat-zeste); }
.famille--terre { --aplat: var(--aplat-terre); }
.famille--baie { --aplat: var(--aplat-baie); }
.famille--fleur { --aplat: var(--aplat-fleur); }
.nuancier-scene__cadre { --fond-scene: var(--aplat-zeste); background-color: var(--fond-scene); border-image: linear-gradient(var(--fond-scene) 0 0) fill 0 / / 0 100vw; }
.nuancier-scene__tete { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px 32px; padding-top: 72px; }
.nuancier-scene__titre { margin: 0; font-size: var(--t-titre); line-height: 1.05; letter-spacing: -.01em; color: var(--sur-aplat); }
.nuancier-scene__repere { display: flex; align-items: flex-start; gap: 20px; }
/* Le compteur : DM Mono en 24 px, la plus petite taille permise directement sur Zeste et Fleur. */
.nuancier-scene__compteur { display: none; margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-h3); line-height: 40px; letter-spacing: -.01em; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* La bande nuancier (§ 1.6) : quatre nuances de 12 × 40, un filet ivoire les détache de l'aplat de la même couleur. */
.bande-nuancier { display: flex; gap: 4px; height: 40px; flex: none; }
.bande-nuancier > span { width: 12px; height: 40px; border-radius: 1px; background: var(--c); box-shadow: inset 0 0 0 1px rgba(251, 248, 241, .5); transform-origin: top; transition: scale 300ms var(--sortie), box-shadow 300ms var(--sortie); }
.bande-nuancier > [data-arome="zeste"] { --c: var(--aplat-zeste); }
.bande-nuancier > [data-arome="terre"] { --c: var(--aplat-terre); }
.bande-nuancier > [data-arome="baie"] { --c: var(--aplat-baie); }
.bande-nuancier > [data-arome="fleur"] { --c: var(--aplat-fleur); }

/* Une famille : le nom en Méga en bas à gauche, le produit au-dessus à droite (il passe devant le nom),
   l'étiquette en bas à droite. */
.famille {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 300px; grid-template-rows: minmax(0, 1fr) auto; column-gap: 48px;
  min-height: calc(100svh - var(--haut-demo) - var(--haut-entete)); padding: 40px 0 48px;
  background-color: var(--aplat); border-image: linear-gradient(var(--aplat) 0 0) fill 0 / / 0 100vw;
}
.famille__mega {
  grid-column: 1 / -1; grid-row: 2; align-self: end; justify-self: start; position: relative; z-index: 1;
  margin: 0 0 -.055em -.04em; font-size: var(--t-mega); line-height: .85; letter-spacing: -.03em; text-wrap: nowrap; color: var(--sur-aplat);
}
/* Le produit se pose au-dessus du nom, sans jamais passer devant lui : un titre ne se lit pas à travers une image. */
.famille__sol { grid-column: 1 / -1; grid-row: 1; align-self: end; justify-self: end; position: relative; z-index: 2; width: min(44vw, 580px); margin: 0 -8px 8px 0; pointer-events: none; }
.famille__img { max-height: calc(100svh - 420px); width: auto; max-width: 100%; margin-left: auto; }
.famille__img { height: auto; filter: url(#detourage) drop-shadow(0 30px 26px rgba(20, 12, 4, .38)) drop-shadow(0 4px 6px rgba(20, 12, 4, .3)); }
.famille__etiquette { grid-column: 2; grid-row: 2; align-self: end; position: relative; z-index: 3; }

/* L'étiquette ivoire : la seule place du petit texte sur un aplat. Ses encres sont celles du Jour, en Soir aussi :
   comme l'aplat, elle ne change pas avec le thème. Un œillet laisse voir l'aplat de la famille. */
.sur-etiquette {
  --encre: #1F2A22; --encre-douce: #4C554B; --laiton: #9C7535; --laiton-texte: #7A5A24; --trait: #D6CCB8; --focus: #7A5A24;
  background: var(--sur-aplat); color: var(--encre);
}
.famille__etiquette {
  display: grid; gap: 10px; padding: 22px 22px 8px; border-radius: var(--r-etiquette); rotate: -1.2deg;
  outline: 1px solid var(--laiton); outline-offset: -7px;
  box-shadow: 0 1px 2px rgba(20, 12, 4, .18), 0 18px 40px rgba(20, 12, 4, .22);
}
.famille__etiquette::before { content: ""; position: absolute; top: 14px; right: 16px; width: 9px; height: 9px; border-radius: 50%; background: var(--aplat); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35); }
.famille__numero, .famille__compte { margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; font-variant-numeric: tabular-nums; }
.famille__numero { color: var(--laiton-texte); }
.famille__notes { margin: 0; padding-right: 16px; font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; text-wrap: balance; }
.famille__compte { display: flex; align-items: center; gap: 8px; min-height: 16px; color: var(--encre-douce); }
.famille__compte:not(:empty)::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--aplat); }
/* Le lien : sur toute la largeur de l'étiquette, sous un filet pointillé. La flèche avance au survol. */
.lien-fleche {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 48px; margin-top: 2px; padding-top: 2px;
  border-top: 1px dashed var(--trait); color: var(--encre); font-size: var(--t-petit); line-height: 20px; font-weight: 600; text-decoration: none;
}
.lien-fleche::after { content: "→"; flex: none; color: var(--laiton-texte); transition: translate 200ms var(--sortie); }
.lien-fleche:focus-visible { outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .lien-fleche:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; }
  .lien-fleche:hover::after { translate: 4px 0; }
}

@media (max-width: 899px) {
  /* Sur téléphone : le Méga en haut, le produit en 92 vw au milieu, l'étiquette en bas, en pleine largeur. */
  .nuancier-scene__tete { padding-top: 56px; }
  .nuancier-scene__repere { flex: 1 1 100%; justify-content: space-between; }
  .famille { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; row-gap: 16px; padding: 28px 0 32px; }
  .famille__mega { grid-row: 1; align-self: start; margin: 0 0 0 -.04em; }
  .famille__sol { grid-column: 1; grid-row: 2; align-self: center; justify-self: center; width: 92vw; margin: 0; }
  .famille__etiquette { grid-column: 1; grid-row: 3; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; rotate: -.6deg; padding: 18px 18px 6px; }
  .famille__numero, .famille__notes, .famille__compte, .lien-fleche { grid-column: 1 / -1; }
  .famille__notes { font-size: var(--t-chapo); }
}

/* Le mode épinglé : seulement avec JavaScript et sans mouvement réduit. La piste fait 200 svh, soit un écran de course : quatre temps d’un quart d’écran (finition du 27/10/2026) ;
   le cadre reste collé sous le bandeau démo, l'en-tête passe devant son haut (d'où le retrait de --haut-entete). */
@media screen and (prefers-reduced-motion: no-preference) {
  .js .nuancier-scene { scroll-margin-top: calc(var(--haut-demo) - (96px + var(--haut-demo))); }
  .js .nuancier-scene__piste { height: 200svh; }
  .js .nuancier-scene__cadre {
    position: sticky; top: var(--haut-demo); height: calc(100svh - var(--haut-demo));
    display: grid; grid-template-rows: auto minmax(0, 1fr); padding: calc(var(--haut-entete) + 36px) 0 0;
    transition: --fond-scene 600ms var(--sortie);
  }
  .js .nuancier-scene__cadre[data-temps="1"] { --fond-scene: var(--aplat-terre); }
  .js .nuancier-scene__cadre[data-temps="2"] { --fond-scene: var(--aplat-baie); }
  .js .nuancier-scene__cadre[data-temps="3"] { --fond-scene: var(--aplat-fleur); }
  .js .nuancier-scene__tete { padding-top: 0; }
  .js .nuancier-scene__compteur { display: block; }
  .js .famille__numero { display: none; }
  .js [data-temps="0"] .bande-nuancier > :nth-child(1), .js [data-temps="1"] .bande-nuancier > :nth-child(2),
  .js [data-temps="2"] .bande-nuancier > :nth-child(3), .js [data-temps="3"] .bande-nuancier > :nth-child(4) { scale: 1 2.4; box-shadow: inset 0 0 0 1px var(--sur-aplat); }
  /* Les quatre familles occupent la même place ; seule la famille active se voit et se clique. Les autres restent
     dans l'ordre de lecture et atteignables au clavier (le focus fait défiler jusqu'à leur temps). */
  .js .famille { grid-row: 2; grid-column: 1; min-height: 0; padding-top: 24px; border-image: none; background-color: transparent; opacity: 0; pointer-events: none; transition: opacity 400ms var(--sortie), translate 500ms var(--sortie); }
  .js .famille.est-active { opacity: 1; pointer-events: auto; }
  .js .famille.est-passee { translate: 0 -8vh; }
  /* L'entrée : le nom se dévoile de gauche à droite, le produit monte en se redressant, l'étiquette suit. */
  .js .famille__mega { clip-path: inset(-.25em 100% -.25em -.1em); transition: clip-path 700ms var(--sortie); }
  .js .famille__sol { opacity: 0; translate: 0 12vh; rotate: 4deg; transition: opacity 500ms var(--sortie) 60ms, translate 700ms var(--sortie) 60ms, rotate 700ms var(--sortie) 60ms; will-change: translate, rotate; }
  .js .famille__etiquette { opacity: 0; translate: 0 24px; transition: opacity 500ms var(--sortie) 160ms, translate 600ms var(--sortie) 160ms; }
  .js .famille:is(.est-active, .est-passee) .famille__mega { clip-path: inset(-.25em -.1em -.25em -.1em); }
  .js .famille:is(.est-active, .est-passee) .famille__sol { opacity: 1; translate: 0 0; rotate: 0deg; }
  .js .famille:is(.est-active, .est-passee) .famille__etiquette { opacity: 1; translate: 0 0; }
  /* Dans son temps, le produit dérive doucement : 3 vh plus bas en entrant, 3 vh plus haut en sortant. */
  .js .famille__img { translate: 0 calc((.5 - var(--pt, .5)) * 6vh); will-change: translate; }
}
@media screen and (prefers-reduced-motion: no-preference) and (max-width: 899px) {
  .js .nuancier-scene__piste { height: 200svh; }
  .js .nuancier-scene__cadre { padding-top: calc(var(--haut-entete) + 20px); }
  .js .famille { padding: 28px 0 24px; }
}

/* Écran 3 bis · Hors nuancier : une ligne sur le papier. Le compte vient du catalogue (outils/pages.py). */
.hors-nuancier { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 20px; row-gap: 4px; margin: 0; padding: 36px 0 32px; border-bottom: 1px solid var(--trait); color: var(--encre); }
.hors-nuancier .etiquette { color: var(--laiton-texte); }
/* Suivie de « Deux formes », la ligne n'a pas besoin de filet : le lin de la moitié droite fait déjà la coupure. */
.hors-nuancier:has(+ .formes) { border-bottom: 0; }
.hors-nuancier .lien-laiton { min-height: 44px; margin-block: -12px; }
@media (max-width: 899px) {
  .hors-nuancier { flex-direction: column; align-items: flex-start; padding: 32px 0 20px; }
  .hors-nuancier .lien-laiton { margin-block: 4px 0; }
}

/* Écran 4 · Deux formes. Deux moitiés qui se touchent sur l'axe central : le papier à gauche, le lin à droite, peint par
   border-image jusqu'au bord de l'écran (le texte reste sur la gouttière). Chaque spécimen pose son bord coupé sur l'axe :
   la fleur entamée à droite, la résine entamée à gauche. Un filet d'encre leur sert de sol commun.
   Les comptes viennent du catalogue (outils/pages.py). */
.formes { position: relative; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); min-height: max(660px, 80svh); }
.formes__titre { position: absolute; z-index: 2; top: 64px; left: 0; display: flex; align-items: center; gap: 14px; margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-texte); }
.formes__titre::after { content: ""; width: 40px; height: 1px; background: currentColor; }
.formes::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--encre); pointer-events: none; }
.forme { position: relative; display: grid; grid-template-rows: auto minmax(0, 1fr); row-gap: 24px; padding: 128px 0 0; color: var(--encre); text-decoration: none; }
/* La résine arrive de la droite (+8 vw) : sa moitié la rogne au bord de l'écran (la gouttière), sinon la page
   s'élargirait avant son entrée. Le lin, peint par la moitié elle-même, n'est pas rogné. */
.forme--resine { justify-items: end; text-align: right; background-color: var(--lin); border-image: linear-gradient(var(--lin) 0 0) fill 0 / / 0 100vw 0 0; overflow: clip; overflow-clip-margin: var(--gouttiere); }
.forme:focus-visible { outline-offset: 4px; }
.forme__texte { display: grid; gap: 18px; justify-items: inherit; padding-inline: 0 40px; }
.forme--resine .forme__texte { padding-inline: 40px 0; }
.forme__nom { font-family: var(--font-titre); font-size: var(--t-affiche); line-height: .9; letter-spacing: -.025em; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .14em; text-decoration-color: transparent; transition: text-decoration-color 300ms var(--sortie); }
.forme__compte { display: inline-flex; align-items: center; gap: 10px; color: var(--laiton-texte); font-variant-numeric: tabular-nums; }
.forme__compte::after { content: "→"; letter-spacing: 0; transition: translate 200ms var(--sortie); }
/* Le spécimen, collé à l'axe par son bord coupé ; il repose sur le filet. En Soir, un halo très léger le détache du fond. */
.forme__sol { align-self: end; justify-self: end; display: block; width: min(36vw, 470px); line-height: 0; pointer-events: none; background: var(--halo-specimen); }
.forme--resine .forme__sol { justify-self: start; width: min(45vw, 590px); }
.forme__img { width: 100%; height: auto; filter: var(--ombre-specimen); transition: translate 240ms var(--sortie); }
@media (hover: hover) and (pointer: fine) {
  .forme:hover .forme__nom { text-decoration-color: var(--laiton); }
  .forme:hover .forme__compte::after { translate: 4px 0; }
  .forme:hover .forme__img { translate: 0 -6px; }
}
@media (max-width: 899px) {
  /* Sur téléphone, les moitiés s'empilent en zigzag : la fleur collée au bord droit de l'écran, la résine au bord gauche. */
  .formes { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .formes__titre { position: static; padding: 64px 0 0; }
  .formes::after { content: none; }
  /* Chaque moitié pose son spécimen sur son propre filet. */
  .forme::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--encre); }
  .forme { row-gap: 28px; padding: 28px 0 0; }
  .forme--resine { padding-top: 56px; background-color: var(--lin); border-image: linear-gradient(var(--lin) 0 0) fill 0 / / 0 100vw; }
  .forme__texte, .forme--resine .forme__texte { padding-inline: 0; }
  .forme__sol { width: 84vw; margin-right: calc(var(--gouttiere) * -1); }
  .forme--resine .forme__sol { width: 96vw; margin: 0 0 0 calc(var(--gouttiere) * -1); }
}
/* Les deux spécimens viennent l'un vers l'autre en entrant à l'écran, liés au défilement. Sans timeline, la révélation
   (app.js) pose .est-visible et une transition fait le même chemin. Rien en mouvement réduit. */
.forme--fleur .forme__sol { --depuis: -8vw; }
.forme--resine .forme__sol { --depuis: 8vw; }
@keyframes forme-entree { from { translate: var(--depuis) 0; } to { translate: 0 0; } }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .forme__sol { animation: forme-entree linear both; animation-timeline: view(); animation-range: entry 0% entry 80%; }
  }
}
@supports not (animation-timeline: view()) {
  @media screen and (prefers-reduced-motion: no-preference) {
    .js .forme__sol { transition: translate var(--d-long) var(--sortie); }
    .js .formes:not(.est-visible) .forme__sol { translate: var(--depuis) 0; }
  }
}

/* L'étiquette de lot, objet signature de la maison */
.etiquette-lot { position: relative; margin: 0; width: min(380px, 100%); display: grid; gap: 14px; padding: 28px 28px 20px; background: var(--ivoire); border: 1px solid var(--trait); border-radius: var(--r-etiquette); outline: 1px solid var(--laiton); outline-offset: -9px; box-shadow: var(--ombre-carte); rotate: 1.5deg; }
.etiquette-lot__maison, .etiquette-lot__pied, .etiquette-lot dt, .etiquette-lot dd { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .14em; text-transform: uppercase; }
.etiquette-lot__maison { margin: 0; color: var(--laiton-texte); text-align: center; }
.etiquette-lot__nom { margin: 0; font-family: var(--font-titre); font-size: 34px; line-height: 40px; letter-spacing: -.01em; text-align: center; text-wrap: balance; }
.etiquette-lot__lignes { margin: 0; display: grid; }
.etiquette-lot__lignes > div { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 8px 0; border-top: 1px dashed var(--trait); }
.etiquette-lot dt { color: var(--encre-douce); display: inline-flex; align-items: center; gap: 8px; }
.etiquette-lot dd { margin: 0; color: var(--encre); text-align: right; font-variant-numeric: tabular-nums; }
.etiquette-lot__pied { margin: 0; display: flex; justify-content: space-between; gap: 12px; padding-top: 12px; border-top: 1px solid var(--encre); color: var(--encre-douce); }
@media (max-width: 600px) { .etiquette-lot { padding: 24px 20px 16px; } .etiquette-lot__pied { letter-spacing: .08em; } }
.repere { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--sousbois); color: var(--sur-sousbois); font-size: var(--t-mini); letter-spacing: 0; }
/* La récolte partage le repère 2 avec l'origine : un cercle vide garde l'alignement, sans second numéro. */
.repere--vide { background: none; box-shadow: inset 0 0 0 1px var(--trait); }

/* La liste qui explique l'étiquette, repère par repère (écran 5). */
.anatomie__liste { list-style: none; margin: 0; padding: 0; display: grid; counter-reset: repere; }
.anatomie__liste li { counter-increment: repere; display: grid; grid-template-columns: 40px 1fr; column-gap: 12px; padding: 16px 0; border-top: 1px solid var(--trait); }
.anatomie__liste li::before { content: counter(repere); grid-row: span 2; font-family: var(--font-titre); font-size: 28px; line-height: 28px; color: var(--laiton); }
.anatomie__liste strong { font-weight: 600; }
.anatomie__liste span { color: var(--encre-douce); font-size: var(--t-petit); line-height: 24px; }

/* Écran 5 · L'étiquette, sur le lin. Le titre, l'étiquette en grand, puis « 0,3 % » en chiffre-titre, et la liste qui
   l'explique. Une révélation à 40 % (app.js) lance la suite : l'étiquette s'imprime ligne à ligne comme sur une imprimante
   thermique (14 pas en 1 400 ms), ses quatre équerres de laiton se posent (300 ms), puis « 0,3 % » arrive d'un
   seul bloc (400 ms, après 150 ms). Pas de compteur. Sans JavaScript, à l'impression ou en mouvement réduit : tout est là.
   L'image d'ambiance papier-lumiere (lot 12) viendra en fond de section, sous .analyse__scene. */
/* L'écran commence juste après le filet des deux formes : pas d'aplat vide entre les deux. */
.analyse { position: relative; display: grid; row-gap: 88px; min-height: 100svh; padding: 88px 0 120px; background-color: var(--lin); border-image: linear-gradient(var(--lin) 0 0) fill 0 / / 0 100vw; }
.analyse__scene { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; row-gap: 72px; align-items: start; }
.analyse__titre { grid-column: 1 / 7; grid-row: 1; max-width: 8.5em; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; }
/* Une proposition par ligne : la coupure ne tombe jamais entre « ce » et « que ». */
.analyse__titre > span { display: block; }
.analyse__planche { grid-column: 7 / 13; grid-row: 1; display: grid; justify-items: end; padding-top: 12px; }
.analyse__seuil { grid-column: 1 / -1; grid-row: 2; display: grid; grid-template-columns: subgrid; align-items: end; }
.chiffre-titre { grid-column: 1 / 9; margin: 0 0 0 -.05em; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-chiffre); line-height: .8; letter-spacing: -.04em; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--encre); word-spacing: -.32em; }
/* Recette du 27/10/2026 : en DM Mono, le zéro est barré et « 0,3 % » se lisait « Ø,3 % ». La police n'a ni variante
   « zero » ni autre graisse ici : les chiffres passent en Gloock, aux proportions de la maison, le signe % reste en
   DM Mono. Le chiffre réglementaire ne prête plus à confusion. */
.chiffre-titre__nombre { font-family: var(--font-titre); font-weight: 400; letter-spacing: -.02em; font-variant-numeric: lining-nums; }
.analyse__legende { grid-column: 9 / -1; margin: 0; padding: 20px 0 4px; border-top: 1px solid var(--encre); font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: var(--encre); text-wrap: balance; }
.analyse__liste { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; }
.analyse__liste li { padding: 20px 0 22px; }

/* L'étiquette en grand : mêmes champs, mêmes encres, à l'échelle de l'écran. Le pied est en laiton, jamais en rouille. */
/* Inclinée de 0,6° au plus : au-delà, la DM Mono se crénèle. */
.etiquette-lot--geante { width: min(560px, 100% - 32px); gap: 18px; padding: 44px 44px 28px; rotate: -.6deg; outline-offset: -11px; box-shadow: 0 1px 2px rgba(31, 42, 34, .08), 0 28px 56px rgba(31, 42, 34, .14); }
.etiquette-lot--geante :is(.etiquette-lot__maison, .etiquette-lot__pied, dt, dd) { font-size: var(--t-mini); line-height: 18px; }
.etiquette-lot--geante .etiquette-lot__nom { font-size: 52px; line-height: 1; padding: 4px 0 6px; }
.etiquette-lot--geante .etiquette-lot__lignes > div { padding: 13px 0; }
.etiquette-lot--geante .etiquette-lot__pied { color: var(--laiton-texte); }
/* Les quatre équerres de laiton, en repères de coupe aux coins : deux sur l'étiquette, deux sur sa liste. */
.etiquette-lot--geante::before, .etiquette-lot--geante::after,
.etiquette-lot--geante .etiquette-lot__lignes::before, .etiquette-lot--geante .etiquette-lot__lignes::after {
  content: ""; position: absolute; width: 22px; height: 22px; border: 0 solid var(--laiton); pointer-events: none;
}
.etiquette-lot--geante::before { top: -11px; left: -11px; border-top-width: 1.5px; border-left-width: 1.5px; }
.etiquette-lot--geante::after { top: -11px; right: -11px; border-top-width: 1.5px; border-right-width: 1.5px; }
.etiquette-lot--geante .etiquette-lot__lignes::before { bottom: -11px; left: -11px; border-bottom-width: 1.5px; border-left-width: 1.5px; }
.etiquette-lot--geante .etiquette-lot__lignes::after { bottom: -11px; right: -11px; border-bottom-width: 1.5px; border-right-width: 1.5px; }

@media (max-width: 899px) {
  .analyse { row-gap: 56px; min-height: 0; padding: 64px 0 72px; }
  .analyse__scene { grid-template-columns: minmax(0, 1fr); row-gap: 48px; }
  .analyse__titre, .analyse__planche, .analyse__seuil, .chiffre-titre, .analyse__legende { grid-column: 1; grid-row: auto; }
  .analyse__titre { font-size: var(--t-grand); line-height: 1.02; }
  .analyse__planche { justify-items: center; padding-top: 0; }
  .analyse__seuil { grid-template-columns: minmax(0, 1fr); row-gap: 20px; }
  .analyse__legende { padding-top: 16px; }
  .analyse__liste { grid-template-columns: minmax(0, 1fr); }
  .etiquette-lot--geante { gap: 14px; padding: 32px 24px 20px; rotate: -.5deg; outline-offset: -9px; }
  .etiquette-lot--geante :is(.etiquette-lot__maison, .etiquette-lot__pied, dt, dd) { font-size: var(--t-mini); line-height: 16px; }
  .etiquette-lot--geante .etiquette-lot__nom { font-size: 38px; }
  .etiquette-lot--geante .etiquette-lot__lignes > div { padding: 10px 0; }
}

@media screen and (prefers-reduced-motion: no-preference) {
  .js :is(.analyse__scene, .fiche__lot):not(.est-visible) .etiquette-lot--geante { clip-path: inset(0 0 100% 0); }
  .js :is(.analyse__scene, .fiche__lot).est-visible .etiquette-lot--geante { animation: imprime 1400ms steps(14, end); }
  .js .etiquette-lot--geante::before, .js .etiquette-lot--geante::after,
  .js .etiquette-lot--geante .etiquette-lot__lignes::before, .js .etiquette-lot--geante .etiquette-lot__lignes::after {
    transition: opacity 300ms var(--sortie) 1400ms, scale 300ms var(--sortie) 1400ms;
  }
  .js :is(.analyse__scene, .fiche__lot):not(.est-visible) .etiquette-lot--geante::before, .js :is(.analyse__scene, .fiche__lot):not(.est-visible) .etiquette-lot--geante::after,
  .js :is(.analyse__scene, .fiche__lot):not(.est-visible) .etiquette-lot--geante .etiquette-lot__lignes::before, .js :is(.analyse__scene, .fiche__lot):not(.est-visible) .etiquette-lot--geante .etiquette-lot__lignes::after {
    opacity: 0; scale: 1.5;
  }
  /* Finition, tour 3 : « 0,3 % » est un chiffre réglementaire, il ne se lit jamais tronqué. Il arrive d'un seul bloc
     (fondu et montée de 8 px, 400 ms), après 150 ms seulement : plus de balayage qui laissait lire « 0,3 » sans « % ». */
  .js .analyse__scene:not(.est-visible) .chiffre-titre { opacity: 0; }
  .js .analyse__scene.est-visible .chiffre-titre { animation: legende 400ms var(--sortie) 150ms both; }
  .js .analyse__scene:not(.est-visible) .analyse__legende { opacity: 0; }
  .js .analyse__scene.est-visible .analyse__legende { animation: legende 400ms var(--sortie) 300ms both; }
}
/* Le papier sort de l'imprimante : la découpe laisse passer l'ombre sur les côtés et dessous. À la fin, plus de découpe. */
@keyframes imprime { from { clip-path: inset(0 -64px 100% -64px); } to { clip-path: inset(0 -64px -64px -64px); } }
@keyframes legende { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }

/* Boutons */
.btn { appearance: none; border: 1px solid transparent; border-radius: var(--r-controle); font: inherit; font-size: var(--t-petit); line-height: 20px; font-weight: 600; letter-spacing: .01em; padding: 12px 24px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px; text-decoration: none; min-height: 44px; transition: background-color .16s ease, border-color .16s ease, transform 160ms var(--sortie); }
.btn:active:not([disabled]):not([aria-disabled="true"]) { transform: scale(.97); }
.btn, .filtre, .ticket, .quantite button { touch-action: manipulation; }
.carte__formats, .recap, .ticket { font-variant-numeric: tabular-nums; }
.btn--principal { background: var(--action); color: var(--sur-action); }
.btn--secondaire { background: transparent; color: var(--encre); border-color: var(--encre-douce); }
/* Un bouton inactif (disabled, ou aria-disabled pendant un appel) ne réagit pas au survol. Sur écran tactile, pas de survol collé. */
@media (hover: hover) and (pointer: fine) {
  .btn--principal:not([disabled]):not([aria-disabled="true"]):hover { background: var(--action-survol); }
  .btn--secondaire:not([disabled]):not([aria-disabled="true"]):hover { background: var(--lin); border-color: var(--encre); }
}
.btn--clair { background: var(--sur-sousbois); color: var(--sousbois); }
.btn--lien { background: none; border: 0; padding: 0; min-height: 44px; color: var(--laiton-texte); text-decoration: underline; text-underline-offset: 4px; font-weight: 600; cursor: pointer; }
.btn[disabled] { opacity: .45; cursor: not-allowed; }
.btn--plein { width: 100%; }
/* Boutons sur aplat : ivoire plein, ou contour ivoire. Au survol, l'ivoire prend le laiton clair. */
.btn--ivoire { background: var(--sur-aplat); color: var(--aplat-sousbois); }
.btn--contour-ivoire { background: transparent; color: var(--sur-aplat); border-color: rgba(251, 248, 241, .55); }
@media (hover: hover) and (pointer: fine) {
  .btn--ivoire:hover { background: var(--laiton-clair); }
  .btn--contour-ivoire:hover { border-color: var(--sur-aplat); background: rgba(251, 248, 241, .08); }
}


/* Pastille d'arôme */
.pastille { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px 4px 8px; border-radius: 999px; background: var(--lin); font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .14em; text-transform: uppercase; color: var(--encre); }
.pastille::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--c, var(--encre-douce)); }
[data-arome="zeste"] { --c: var(--arome-zeste); }
[data-arome="terre"] { --c: var(--arome-terre); }
[data-arome="baie"] { --c: var(--arome-baie); }
[data-arome="fleur"] { --c: var(--arome-fleur); }

/* Carte de lot (/lots et étagère de l'accueil) */
.carte { position: relative; display: flex; flex-direction: column; }
/* La boîte du visuel : --l est la largeur du produit, --g sa marge gauche (centré, ou collé au bord de sa coupe). */
/* En Soir, --halo-specimen pose une lueur très légère derrière le produit : les teintes sombres (myrtilles, résines) ne se perdent pas dans le fond. */
.carte__visuel { position: relative; flex: none; aspect-ratio: 4 / 3; border-bottom: 1px solid var(--encre); --l: 80%; --g: calc((100% - var(--l)) / 2); background: var(--halo-specimen) center 70% / 90% 90% no-repeat; }
/* La taille optique (app.js, tailleOptique()) : à largeur égale, un produit haut paraît plus gros qu'un produit plat.
   Haut (largeur / hauteur < 1,45) : 68 % de la boîte ; moyen (jusqu'à 2) : 84 % ; plat : toute la largeur. */
.carte__visuel:has(> .taille-haute) { --l: 68%; }
.carte__visuel:has(> .taille-moyenne) { --l: 84%; }
.carte__visuel:has(> .taille-plate) { --l: 100%; }
.carte__visuel[data-coupe="droite"] { --g: calc(100% - var(--l)); }
.carte__visuel[data-coupe="gauche"] { --g: 0%; }
/* Chaque produit repose sur le filet, quelle que soit sa forme. */
.carte__visuel img { position: absolute; z-index: 1; left: var(--g); bottom: 0; width: var(--l); height: auto; max-height: 88%; object-fit: contain; object-position: center bottom; transition: transform 300ms var(--sortie); }
.carte__visuel[data-coupe="droite"] img { object-position: right bottom; }
.carte__visuel[data-coupe="gauche"] img { object-position: left bottom; }
/* Sans détourage possible, la photo d'origine devient un tirage : passe-partout ivoire de 12 px, coins de laiton,
   légèrement de biais, posé debout sur le filet. Le tirage est un objet : il reste ivoire en thème Soir.
   Sa largeur (50,4 %) donne une hauteur de 84 % de la boîte en 4:5 ; il est centré (24,8 %). */
.carte__visuel.tirage { --l: 50.4%; --g: 24.8%; }
.carte__visuel.tirage img {
  max-height: none; aspect-ratio: 4 / 5; object-fit: cover; object-position: center; box-sizing: border-box;
  padding: 12px; background: var(--sur-aplat); border-image: url(/assets/marque/tirage-coins.svg) 24 / 12px;
  box-shadow: 0 1px 1px rgba(31, 42, 34, .10), 0 2px 3px rgba(31, 42, 34, .08), 0 14px 22px -6px rgba(31, 42, 34, .22);
  rotate: -1.5deg; transform-origin: 50% 100%;
}
.carte__photo2 { position: absolute; inset: 0; opacity: 0; transition: opacity 200ms var(--sortie); }
.carte__lien { text-decoration: none; }
/* Toute la carte est la cible (::before) ; le nom lui-même mesure aussi 44 px de haut, sans rien déplacer (en ligne). */
.carte__nom .carte__lien { padding-block: max(0px, calc((44px - 1lh) / 2)); }
.carte__lien::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: var(--r-carte); }
.carte__lien:focus-visible { outline: none; }
.carte__lien:focus-visible::before { outline: 2px solid var(--focus); outline-offset: 2px; }
.carte__certificat { position: relative; z-index: 2; justify-self: start; color: var(--laiton-texte); font-weight: 600; font-size: var(--t-petit); text-underline-offset: 4px; min-height: 44px; display: inline-flex; align-items: center; }
.carte__taux { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .1em; color: var(--encre); margin: 0; }
.carte__formats { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 2px; font-size: var(--t-petit); line-height: 22px; }
.carte__formats li { display: flex; gap: 8px; justify-content: space-between; align-items: baseline; border-top: 1px solid var(--trait); padding-top: 4px; white-space: nowrap; }
.carte__formats li > span:last-child { display: flex; flex-wrap: wrap; justify-content: flex-end; column-gap: 6px; }
.carte__formats li > span:first-child { font-weight: 600; }
.carte__formats .par-gramme { color: var(--encre-douce); font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .02em; }
.carte__formats .par-gramme::before { content: "· "; }
@media (max-width: 600px) {
  .carte__formats li > span:last-child { flex-direction: column; align-items: flex-end; }
  .carte__formats .par-gramme::before { content: none; }
}
.carte__formats .indispo { color: var(--encre-douce); }
@media (hover: hover) and (pointer: fine) {
  .carte:hover .specimen { transform: translateY(-6px); }
  .carte:hover .carte__photo2 { opacity: 1; }
}
.carte__corps { padding: 20px 0 0; display: grid; gap: 10px; flex: 1; align-content: start; }
.carte__faits { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .1em; text-transform: uppercase; color: var(--encre-douce); }
.carte__prix { font-weight: 600; margin-top: auto; }

/* Écran 6 · La cueillette de la semaine, en étagère.
   Trois produits posés sur un même filet de laiton, chacun avec son ombre au sol. Sur téléphone, l'étagère défile au doigt,
   carte par carte, et son filet court d'un bord à l'autre de l'écran ; la page, elle, ne défile jamais en largeur. */
.cueillette__tete { display: grid; grid-template-columns: auto 1fr; align-items: center; column-gap: 16px; row-gap: 20px; margin-bottom: 48px; }
.cueillette__titre { grid-column: 1 / -1; margin: 0; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; }
.cueillette__depuis { margin: 0; color: var(--laiton-texte); font-variant-numeric: tabular-nums; }
.bande-nuancier--filet { height: 4px; }
.bande-nuancier--filet > span { height: 4px; box-shadow: none; }
.cueillette__suite { margin-top: 32px; }
@media (min-width: 900px) { .cueillette__tete { margin-bottom: 40px; } .cueillette__suite { margin-top: 48px; } }

.etagere { --gap: 32px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--gap); }
@media (min-width: 1200px) { .etagere { --gap: 48px; } }
/* Place réservée avant l'arrivée du catalogue (un visuel 4:3 et quatre lignes de texte), pour que rien ne saute. */
[data-cueillette-grille]:empty { min-height: calc((min(100vw, 1280px) - 2 * var(--gouttiere) - 2 * var(--gap)) / 4 + 152px); }
.etagere .carte__visuel { border-bottom: 0; }
/* Le filet : un trait de laiton qui passe sous les trois produits, gouttières comprises. */
.etagere .carte__visuel::before { content: ""; position: absolute; z-index: 0; left: calc(var(--gap) / -2); right: calc(var(--gap) / -2); bottom: 0; height: 1px; background: var(--laiton); }
.etagere .carte:first-child .carte__visuel::before { left: 0; }
.etagere .carte:last-child .carte__visuel::before { right: 0; }
/* L'ombre au sol, sous le produit, de sa largeur. */
.etagere .carte__visuel::after {
  content: ""; position: absolute; z-index: 0; left: var(--g); width: var(--l); bottom: -9px; height: 18px;
  background: radial-gradient(closest-side, var(--ombre-sol), transparent); transform-origin: 50% 50%;
  transition: scale 300ms var(--sortie), opacity 300ms var(--sortie);
}
.carte--etagere .carte__corps { padding-top: 24px; gap: 8px; }
.carte__nom { margin: 0; font-size: var(--t-h3); line-height: 1.1; }
.carte--etagere .carte__faits { margin: 0; display: flex; align-items: center; flex-wrap: wrap; column-gap: .5em; }
.carte__famille { display: inline-flex; align-items: center; gap: 7px; }
.carte__famille::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--c); }
.carte__appel { margin: 4px 0 0; font-size: var(--t-corps); line-height: 24px; font-weight: 600; font-variant-numeric: tabular-nums; }
.carte__des { font-weight: 400; color: var(--encre-douce); }
/* Le prix au gramme, sous le prix d'appel : la même ligne sur chaque carte de l'étagère. */
.carte__gramme { margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .04em; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
/* Le compteur « 01 / 03 » de l'étagère, sur téléphone seulement. */
.etagere__compteur { display: none; margin: 20px 0 0; color: var(--laiton-texte); font-variant-numeric: tabular-nums; }
@media (max-width: 899px) {
  /* Un conteneur qui défile en largeur rogne aussi en hauteur : 40 px de marge intérieure en haut (rendus par une marge
     négative) gardent dans la zone visible la descente des produits (-40 px), le survol et le tirage incliné. */
  .etagere {
    --gap: 16px; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 78vw;
    overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none;
    margin: -40px calc(var(--gouttiere) * -1) 0; padding: 40px var(--gouttiere) 8px; scroll-padding-inline: var(--gouttiere);
  }
  .etagere__compteur:not(:empty) { display: block; }
  .etagere::-webkit-scrollbar { display: none; }
  .etagere > .carte { scroll-snap-align: start; }
  .etagere .carte:first-child .carte__visuel::before { left: calc(var(--gouttiere) * -1); }
  .etagere .carte:last-child .carte__visuel::before { right: calc(var(--gouttiere) * -1); }
  [data-cueillette-grille]:empty { min-height: calc(78vw * .75 + 192px); }
}
/* Au survol : le produit se soulève de 6 px et s'incline à peine, son ombre se resserre. Le tirage, lui, se redresse. */
@media (hover: hover) and (pointer: fine) {
  .carte--etagere:hover .carte__visuel img { transform: translateY(-6px) rotate(-2deg); }
  .carte--etagere:hover .carte__visuel.tirage img { transform: translateY(-6px) rotate(1.5deg); }
  .carte--etagere:hover .carte__visuel::after { scale: .86; opacity: .7; }
}
/* La pose : une fois l'étagère à l'écran, chaque produit descend de 40 px et se pose avec un léger rebond,
   90 ms après son voisin ; son ombre s'élargit de .6 à 1 en même temps. Rien n'est caché sans JS, à l'impression
   ni en mouvement réduit. */
@keyframes etagere-pose { from { translate: 0 -40px; opacity: 0; } 30% { opacity: 1; } to { translate: 0 0; opacity: 1; } }
@keyframes etagere-ombre { from { scale: .6; opacity: 0; } to { scale: 1; opacity: 1; } }
@keyframes etagere-texte { from { translate: 0 10px; opacity: 0; } to { translate: 0 0; opacity: 1; } }
@media screen and (prefers-reduced-motion: no-preference) {
  .etagere > .carte:nth-child(2) { --rang: 1; }
  .etagere > .carte:nth-child(3) { --rang: 2; }
  .js .etagere:not(.est-visible) .carte__visuel img, .js .etagere:not(.est-visible) .carte__visuel::after, .js .etagere:not(.est-visible) .carte__corps { opacity: 0; }
  .js .etagere.est-visible .carte__visuel img { animation: etagere-pose 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 90ms) backwards; }
  .js .etagere.est-visible .carte__visuel::after { animation: etagere-ombre 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 90ms) backwards; }
  .js .etagere.est-visible .carte__corps { animation: etagere-texte 600ms var(--sortie) calc(240ms + var(--rang, 0) * 90ms) backwards; }
}

/* Les lots (§ 4). En tête, le titre sur le papier ; avec une famille filtrée, l'en-tête prend son aplat (600 ms),
   le titre et la phrase passent en ivoire, et la nuance de la famille s'allonge dans la bande nuancier.
   L'aplat est peint par border-image hors de la colonne : le texte reste sur la gouttière de l'en-tête.
   Sur un aplat, aucun texte de moins de 24 px : la phrase passe à 24 px. */
@property --fond-tete { syntax: '<color>'; inherits: false; initial-value: transparent; }
.lots { padding-bottom: 72px; }
.lots__tete {
  --fond-tete: var(--papier);
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr auto auto; row-gap: 16px;
  min-height: 28svh; box-sizing: border-box; padding: 32px 0 36px;
  background-color: var(--fond-tete); border-image: linear-gradient(var(--fond-tete) 0 0) fill 0 / / 0 100vw; color: var(--encre);
  transition: --fond-tete 600ms var(--sortie), color 600ms var(--sortie);
}
.lots__tete[data-famille="zeste"] { --fond-tete: var(--aplat-zeste); }
.lots__tete[data-famille="terre"] { --fond-tete: var(--aplat-terre); }
.lots__tete[data-famille="baie"] { --fond-tete: var(--aplat-baie); }
.lots__tete[data-famille="fleur"] { --fond-tete: var(--aplat-fleur); }
.lots__tete[data-famille] { color: var(--sur-aplat); --focus: var(--sur-aplat); }
.lots__bande { align-self: start; margin-bottom: 56px; }
.lots__tete[data-famille="zeste"] .lots__bande > [data-arome="zeste"], .lots__tete[data-famille="terre"] .lots__bande > [data-arome="terre"],
.lots__tete[data-famille="baie"] .lots__bande > [data-arome="baie"], .lots__tete[data-famille="fleur"] .lots__bande > [data-arome="fleur"] { scale: 1 2.4; box-shadow: inset 0 0 0 1px var(--sur-aplat); }
.lots__titre { margin: 0 0 0 -.04em; font-size: var(--t-display); line-height: .92; letter-spacing: -.02em; color: inherit; }
.lots__chapo { margin: 0; max-width: 26em; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: var(--encre-douce); text-wrap: pretty; transition: color 600ms var(--sortie); }
.lots__tete[data-famille] .lots__chapo { font-size: var(--t-h3); line-height: 1.3; color: var(--sur-aplat); }
@media (min-width: 900px) {
  .lots__tete {
    grid-template-columns: minmax(0, 1fr) minmax(0, 24em); grid-template-rows: 1fr auto; column-gap: 64px;
    grid-template-areas: "bande bande" "titre chapo"; min-height: 40svh; padding: 48px 0 52px;
  }
  .lots__bande { grid-area: bande; margin-bottom: 64px; }
  .lots__titre { grid-area: titre; align-self: last baseline; }
  .lots__chapo { grid-area: chapo; align-self: last baseline; }
}

/* Les filtres : des onglets de nuancier de 44 px. Chaque famille porte sa nuance (12 × 40) à gauche.
   L'onglet choisi est sous-bois, son texte ivoire : jamais de petit texte ivoire sur Zeste ou Fleur.
   La rangée est construite par app.js : sa hauteur est réservée d'avance (rien ne saute à l'arrivée des boutons).
   « Tous les lots » n'apparaît qu'avec un filtre posé, au bout de la rangée. */
.filtres { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; padding: 24px 0; border-bottom: 1px solid var(--trait); }
.filtres:empty { min-height: 93px; }
.filtres__tout { appearance: none; margin-left: auto; border: 0; background: none; font: inherit; font-size: var(--t-petit); cursor: pointer; }
.filtres__groupe { display: flex; gap: 8px; }
.filtres__groupe--familles { padding-left: 20px; border-left: 1px solid var(--trait); }
.filtre {
  appearance: none; display: inline-flex; align-items: center; gap: 12px; box-sizing: border-box; height: 44px; margin: 0; padding: 0 18px;
  border: 1px solid var(--trait); border-radius: var(--r-controle); background: var(--ivoire); color: var(--encre);
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
  cursor: pointer; transition: background-color 200ms var(--sortie), border-color 200ms var(--sortie), color 200ms var(--sortie);
}
.filtres__groupe--familles .filtre { padding-left: 1px; }
.filtre__nuance { flex: none; width: 12px; height: 40px; border-radius: 4px; background: var(--c); box-shadow: inset 0 0 0 1px rgba(251, 248, 241, .35); }
.filtre__nuance[data-arome="zeste"], .lots__nuance[data-arome="zeste"] { --c: var(--aplat-zeste); }
.filtre__nuance[data-arome="terre"], .lots__nuance[data-arome="terre"] { --c: var(--aplat-terre); }
.filtre__nuance[data-arome="baie"], .lots__nuance[data-arome="baie"] { --c: var(--aplat-baie); }
.filtre__nuance[data-arome="fleur"], .lots__nuance[data-arome="fleur"] { --c: var(--aplat-fleur); }
/* Sur le papier, la petite marque Baie prend --nuance-baie : la même en Jour, plus claire en Soir (3:1 sur le fond). */
.filtre__nuance[data-arome="baie"], .lots__nuance[data-arome="baie"], .bande-nuancier--filet > [data-arome="baie"],
.lots__tete:not([data-famille]) .lots__bande > [data-arome="baie"] { --c: var(--nuance-baie); }
.filtre[aria-pressed="true"] { background: var(--sousbois); border-color: var(--sousbois); color: var(--sur-sousbois); }
.filtre[aria-pressed="true"] .filtre__nuance { box-shadow: inset 0 0 0 1px var(--sur-sousbois); }
@media (hover: hover) and (pointer: fine) {
  .filtre:hover { border-color: var(--encre-douce); }
  .filtre[aria-pressed="true"]:hover { border-color: var(--laiton); }
}
:root[data-theme="soir"] .filtre[aria-pressed="true"] { border-color: var(--laiton); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="jour"]) .filtre[aria-pressed="true"] { border-color: var(--laiton); } }
/* Sur téléphone, les filtres passent à la ligne au lieu de filer sous le bord de l'écran : une rangée coupée se lit
   comme rognée, pas comme un geste à faire (finition du 27/10/2026). Chaque groupe tient sur sa ligne. */
@media (max-width: 719px) {
  .filtres { gap: 8px 12px; margin: 0 calc(var(--gouttiere) * -1); padding: 12px var(--gouttiere); }
  .filtres:empty { min-height: 120px; }
  .filtres__groupe { flex-wrap: wrap; gap: 6px; }
  .filtres__groupe--familles { padding-left: 0; border-left: 0; }
  .filtre { padding: 0 11px; gap: 8px; letter-spacing: .08em; }
  /* Les libellés « Forme » et « Famille » restent lus, sans prendre de place : les pastilles de couleur disent la famille. */
  .filtres__libelle { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .filtres__groupe--familles .filtre { padding-left: 1px; }
  .filtres__tout { flex: none; margin-left: 0; white-space: nowrap; }
}

/* L'étagère des lots : un rayon par famille, dans l'ordre du nuancier, puis Hors nuancier.
   Chaque rangée de produits repose sur un même filet de laiton, prolongé jusqu'au bout de la rangée. */
/* La hauteur de l'écran est réservée sous les filtres, chargement compris : la réassurance et le pied restent sous la
   ligne de flottaison, qu'il y ait quinze lots ou deux (aucun décalage à l'arrivée du catalogue). */
.lots__etagere { display: grid; align-content: start; row-gap: 72px; min-height: calc(100svh - var(--haut-demo) - var(--haut-entete)); padding-top: 40px; }
.lots__etagere > .muet { margin: 0; }
.lots__groupe { display: grid; row-gap: 28px; }
.etagere__groupe { scroll-margin-top: 24px; }
.lots__groupe-tete { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; column-gap: 18px; row-gap: 6px; align-items: baseline; padding-bottom: 20px; border-bottom: 1px solid var(--trait); }
.lots__nuance { grid-row: 1 / span 2; align-self: stretch; width: 12px; min-height: 40px; border-radius: 1px; background: var(--c); }
.lots__groupe--hors .lots__nuance { background: none; box-sizing: border-box; border: 1px dashed var(--encre-douce); }
.etagere__groupe { grid-column: 2; margin: 0; font-size: var(--t-titre); line-height: 1; letter-spacing: -.015em; }
.lots__groupe-phrase { grid-column: 2; margin: 0; color: var(--encre-douce); font-size: var(--t-corps); line-height: 1.45; }
.lots__groupe-compte { grid-column: 3; grid-row: 1; margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-texte); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (min-width: 900px) { .lots__etagere { row-gap: 104px; padding-top: 56px; } .lots__groupe { row-gap: 40px; } .lots__groupe-tete { column-gap: 24px; } }
/* Sur grand écran, chaque famille pose sa tête à gauche (collante) et ses lots sur trois colonnes à droite : un rayon
   de trois lots remplit sa rangée, et tous les groupes ont la même grille. */
@media (min-width: 1100px) {
  .lots__groupe { grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); column-gap: 40px; align-items: start; }
  .lots__groupe-tete {
    position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 32px);
    grid-template-columns: 12px minmax(0, 1fr); row-gap: 10px; padding: 4px 0 0; border-bottom: 0;
  }
  .lots__nuance { grid-row: 1 / span 3; }
  .lots__groupe-compte { grid-column: 2; grid-row: auto; white-space: normal; line-height: 1.5; }
  .lots__groupe .rayon { --cols: 3; }
  /* Le filet sur trois colonnes : ces règles l'emportent sur celles des quatre colonnes (même forme, une classe de plus). */
  .lots__etagere .lots__groupe .rayon > .carte .carte__visuel::before { left: calc(var(--gap) / -2); right: calc(var(--gap) / -2); }
  .lots__etagere .lots__groupe .rayon > .carte:nth-child(3n + 1) .carte__visuel::before { left: 0; }
  .lots__etagere .lots__groupe .rayon > .carte:nth-child(3n) .carte__visuel::before { right: 0; }
  .lots__etagere .lots__groupe .rayon > .carte:last-child:nth-child(3n) .carte__visuel::before { right: 0; }
  .lots__etagere .lots__groupe .rayon > .carte:last-child:nth-child(3n + 1) .carte__visuel::before { right: calc(-2 * (100% + var(--gap))); }
  .lots__etagere .lots__groupe .rayon > .carte:last-child:nth-child(3n + 2) .carte__visuel::before { right: calc(-1 * (100% + var(--gap))); }
  /* Finition, tour 3 : une famille d'un ou deux lots. La tête prend la place libre, les cartes gardent la largeur d'une
     colonne sur trois et se calent à droite : le filet court sous les cartes seulement, aucune case vide. */
  .lots__groupe:has(> .rayon[data-places="2"]) { grid-template-columns: minmax(0, 2fr) minmax(0, 2fr); }
  .lots__groupe:has(> .rayon[data-places="1"]) { grid-template-columns: minmax(0, 3fr) minmax(0, 1fr); }
  .lots__groupe .rayon[data-places="2"] { --cols: 2; }
  .lots__groupe .rayon[data-places="1"] { --cols: 1; }
  .lots__groupe:has(> .rayon[data-places="1"]) .lots__groupe-tete, .lots__groupe:has(> .rayon[data-places="2"]) .lots__groupe-tete { max-width: 22rem; }
  .lots__etagere .lots__groupe .rayon:is([data-places="1"], [data-places="2"]) > .carte:last-child .carte__visuel::before { right: 0; }
  /* Les filtres restent sous l'en-tête pendant la lecture ; la tête de chaque famille se cale sous eux. */
  .filtres {
    position: sticky; top: calc(var(--haut-demo) + var(--haut-entete)); z-index: 6;
    margin-inline: calc(50% - 50vw); padding-inline: calc(50vw - 50%); padding-block: 16px; background: var(--papier);
  }
  .lots__groupe-tete { top: calc(var(--haut-demo) + var(--haut-entete) + 108px); }
}

.rayon { --gap: 16px; --cols: 2; display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); column-gap: var(--gap); row-gap: 48px; }
@media (min-width: 720px) { .rayon { --gap: 32px; --cols: 3; row-gap: 64px; } }
@media (min-width: 1100px) { .rayon { --gap: 40px; --cols: 4; row-gap: 72px; } .rayon--court { --cols: 3; } }
/* Sur téléphone, le compte du rayon passe sous la phrase : « 1 lot en vente · 2 bientôt de retour » ne tient pas à droite. */
@media (max-width: 719px) {
  .lots__nuance { grid-row: 1 / span 3; }
  .lots__groupe-compte { grid-column: 2; grid-row: auto; white-space: normal; }
}

/* La relance : une famille filtrée qui tient en moins d'une rangée propose la suivante du nuancier, sur son aplat.
   Le nom en Gloock sur l'aplat (24 px et plus), le lien dessous, sur le papier. */
.relance { display: flex; flex-direction: column; gap: 22px; color: var(--encre); text-decoration: none; }
.relance[data-arome="zeste"] { --aplat: var(--aplat-zeste); }
.relance[data-arome="terre"] { --aplat: var(--aplat-terre); }
.relance[data-arome="baie"] { --aplat: var(--aplat-baie); }
.relance[data-arome="fleur"] { --aplat: var(--aplat-fleur); }
.relance__aplat { display: flex; align-items: flex-end; aspect-ratio: 4 / 3; padding: 20px 22px; border-radius: var(--r-etiquette); background: var(--aplat); color: var(--sur-aplat); transition: translate 300ms var(--sortie); }
.relance__nom { font-family: var(--font-titre); font-size: var(--t-grand); line-height: .9; letter-spacing: -.02em; }
.relance__texte { position: relative; align-self: flex-start; padding-right: 1.5em; color: var(--laiton-texte); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
.relance__texte::after { content: "→"; position: absolute; right: 0; transition: translate 200ms var(--sortie); }
.relance:focus-visible { outline-offset: 4px; }
@media (hover: hover) and (pointer: fine) {
  .relance:hover .relance__aplat { translate: 0 -6px; }
  .relance:hover .relance__texte::after { translate: 4px 0; }
}
.rayon .carte__visuel { border-bottom: 0; }
.rayon .carte__visuel::before { content: ""; position: absolute; z-index: 0; left: calc(var(--gap) / -2); right: calc(var(--gap) / -2); bottom: 0; height: 1px; background: var(--laiton); }
.rayon .carte__visuel::after {
  content: ""; position: absolute; z-index: 0; left: var(--g); width: var(--l); bottom: -9px; height: 18px;
  background: radial-gradient(closest-side, var(--ombre-sol), transparent);
  transition: scale 300ms var(--sortie), opacity 300ms var(--sortie);
}
/* Le filet commence au bord de la colonne et finit au bout de la rangée, même quand la dernière rangée est incomplète :
   la dernière carte le prolonge sur les colonnes vides (100 % est la largeur d'une carte). */
@media (max-width: 719px) {
  .rayon > .carte:nth-child(2n + 1) .carte__visuel::before { left: 0; }
  .rayon > .carte:nth-child(2n) .carte__visuel::before { right: 0; }
  .rayon > .carte:last-child:nth-child(2n + 1) .carte__visuel::before { right: calc(-1 * (100% + var(--gap))); }
}
@media (min-width: 720px) and (max-width: 1099px) {
  .rayon > .carte:nth-child(3n + 1) .carte__visuel::before { left: 0; }
  .rayon > .carte:nth-child(3n) .carte__visuel::before { right: 0; }
  .rayon > .carte:last-child:nth-child(3n + 1) .carte__visuel::before { right: calc(-2 * (100% + var(--gap))); }
  .rayon > .carte:last-child:nth-child(3n + 2) .carte__visuel::before { right: calc(-1 * (100% + var(--gap))); }
}
@media (min-width: 1100px) {
  .rayon > .carte:nth-child(4n + 1) .carte__visuel::before { left: 0; }
  .rayon > .carte:nth-child(4n) .carte__visuel::before { right: 0; }
  .rayon > .carte:last-child:nth-child(4n + 1) .carte__visuel::before { right: calc(-3 * (100% + var(--gap))); }
  .rayon > .carte:last-child:nth-child(4n + 2) .carte__visuel::before { right: calc(-2 * (100% + var(--gap))); }
  .rayon > .carte:last-child:nth-child(4n + 3) .carte__visuel::before { right: calc(-1 * (100% + var(--gap))); }
}
.rayon .carte__corps { padding-top: 22px; }
@media (hover: hover) and (pointer: fine) {
  .rayon .carte:hover .carte__visuel img { transform: translateY(-6px) rotate(-2deg); }
  .rayon .carte:hover .carte__visuel.tirage img { transform: translateY(-6px) rotate(1.5deg); }
  .rayon .carte:hover .carte__visuel::after { scale: .86; opacity: .7; }
}
/* La pose, comme sur l'étagère de l'accueil, au premier affichage seulement : ensuite, c'est la transition de vue qui anime. */
@media screen and (prefers-reduced-motion: no-preference) {
  .rayon > .carte:nth-child(2) { --rang: 1; } .rayon > .carte:nth-child(3) { --rang: 2; } .rayon > .carte:nth-child(4) { --rang: 3; }
  .rayon > .carte:nth-child(5) { --rang: 4; } .rayon > .carte:nth-child(6) { --rang: 5; } .rayon > .carte:nth-child(n + 7) { --rang: 6; }
  .js .rayon:not(.est-visible) .carte__visuel img, .js .rayon:not(.est-visible) .carte__visuel::after, .js .rayon:not(.est-visible) .carte__corps { opacity: 0; }
  .js .rayon.est-visible .carte__visuel img { animation: etagere-pose 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 70ms) backwards; }
  .js .rayon.est-visible .carte__visuel::after { animation: etagere-ombre 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 70ms) backwards; }
  .js .rayon.est-visible .carte__corps { animation: etagere-texte 600ms var(--sortie) calc(200ms + var(--rang, 0) * 70ms) backwards; }
  .rayon.est-posee .carte__visuel img, .rayon.est-posee .carte__visuel::after, .rayon.est-posee .carte__corps { animation: none; }
}

/* Le filtrage, en transition de vue (app.js, changer()) : chaque carte glisse à sa nouvelle place en 350 ms,
   celles qui arrivent montent en fondu, celles qui partent s'effacent. L'en-tête du site reste au-dessus. */
@keyframes vt-entre { from { opacity: 0; translate: 0 16px; scale: .97; } }
@keyframes vt-sort { to { opacity: 0; scale: .97; } }
.vt-lots .entete { view-transition-name: entete; }
.vt-lots .bandeau-demo:not([hidden]) { view-transition-name: bandeau-demo; }
.vt-lots::view-transition-group(*) { animation-duration: 350ms; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
.vt-lots::view-transition-old(root), .vt-lots::view-transition-new(root) { animation-duration: 250ms; }
.vt-lots::view-transition-new(*):only-child { animation: vt-entre 350ms cubic-bezier(.22, 1, .36, 1) 80ms both; }
.vt-lots::view-transition-old(*):only-child { animation: vt-sort 180ms var(--sortie) both; }
.vt-lots::view-transition-group(entete), .vt-lots::view-transition-group(bandeau-demo) { z-index: 2; animation: none; }

/* Fiche produit (§ 4). Le premier écran prend l'aplat de la famille (le lin hors nuancier) : le nom en très grand,
   avant l'image dans le DOM, le spécimen rogné qui passe devant la fin du nom, un cartel de musée ivoire (le petit texte
   n'est jamais posé à même l'aplat). Puis les notes, les tickets à souche, la quantité et la barre d'ajout,
   l'étiquette du lot qui s'imprime. Sur ordinateur, l'achat tient dans une colonne collante à droite ;
   sur téléphone, la barre d'ajout reste collée en bas de l'écran tant que la fiche est à l'écran. */
.fiche { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; padding-bottom: 72px; }
/* Le temps du chargement, la fiche (puis le panier, puis les lots) réserve la hauteur de l'écran : ce qui suit reste
   sous la ligne de flottaison et rien ne saute quand le catalogue arrive (CLS). */
.chargement { min-height: calc(100svh - var(--haut-demo) - var(--haut-entete)); margin: 0; padding: 48px 0; }

/* Le fil d'Ariane, sur le papier au-dessus de l'aplat : Les lots / la famille / le lot. */
.ariane { padding: 18px 0 16px; }
.ariane ol { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 0; margin: 0; padding: 0; list-style: none; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.ariane li + li::before { content: "/"; margin: 0 10px; color: var(--trait); }
/* Finition, tour 3 : chaque lien fait 44 px de haut (cible tactile), sans déplacer la ligne (marges négatives). */
.ariane a { display: inline-flex; align-items: center; min-height: 44px; margin-block: -14px; padding-inline: 2px; margin-inline: -2px; color: var(--laiton-texte); text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px; transition: text-decoration-color 160ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .ariane a:hover { text-decoration-color: currentColor; } }
.ariane [aria-current] { color: var(--encre); }
.fiche__demo { margin: 14px 0 0; max-width: 34em; color: var(--rouille); text-transform: none; letter-spacing: .02em; }

.fiche__scene {
  --t-nom: clamp(56px, 12vw, 168px); --aplat: var(--lin);
  position: relative; isolation: isolate; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr;
  min-height: 70svh; margin-inline: calc(var(--gouttiere) * -1); padding: 28px var(--gouttiere) 32px;
  background-color: var(--aplat); color: var(--encre); overflow: hidden; overflow: clip;
}
.fiche__scene[data-famille="zeste"] { --aplat: var(--aplat-zeste); }
.fiche__scene[data-famille="terre"] { --aplat: var(--aplat-terre); }
.fiche__scene[data-famille="baie"] { --aplat: var(--aplat-baie); }
.fiche__scene[data-famille="fleur"] { --aplat: var(--aplat-fleur); }
.fiche__scene:not([data-famille="lin"]) { color: var(--sur-aplat); --focus: var(--sur-aplat); }
.fiche__nom { position: relative; z-index: 1; grid-row: 1; margin: 0 0 0 -.04em; font-size: var(--t-nom); line-height: .92; letter-spacing: -.02em; color: inherit; overflow-wrap: break-word; }

/* Le spécimen : sa largeur suit la taille optique (haut, moyen, plat), un produit coupé colle son bord coupé au bord
   de l'écran. --l est sa largeur ; la marge le centre dans la colonne, ou le pousse contre le bord. */
/* Sur téléphone, le spécimen occupe le milieu de la scène, plus large que l'écran (rogné des deux côtés) ;
   le cartel se pose en bas à gauche, sur son pied. */
.fiche__visuel { --l: 116vw; position: relative; z-index: 2; grid-area: 2 / 1; align-self: center; width: var(--l); margin: 24px calc((100% - var(--l)) / 2) 56px; line-height: 0; }
.fiche__visuel--taille-haute { --l: 88vw; }
.fiche__visuel--taille-plate { --l: 128vw; }
.fiche__visuel[data-coupe="droite"] { margin-inline: calc(100% + var(--gouttiere) - var(--l)) calc(var(--gouttiere) * -1); }
.fiche__visuel[data-coupe="gauche"] { margin-inline: calc(var(--gouttiere) * -1) calc(100% + var(--gouttiere) - var(--l)); }
.fiche__img { width: 100%; height: auto; }
.fiche__scene .specimen { filter: url(#detourage) drop-shadow(0 30px 26px rgba(20, 12, 4, .38)) drop-shadow(0 4px 6px rgba(20, 12, 4, .3)); }
.fiche__scene[data-famille="lin"] .specimen { filter: url(#detourage) var(--ombre-specimen); }
/* Sans détourage, la photo devient un tirage, comme sur l'étagère : passe-partout ivoire, coins de laiton, de biais. */
.fiche__visuel--photo { --l: 66vw; margin-bottom: 72px; }
.fiche__visuel--photo .fiche__img {
  aspect-ratio: 4 / 5; object-fit: cover; box-sizing: border-box; padding: 12px; background: var(--sur-aplat);
  border-image: url(/assets/marque/tirage-coins.svg) 24 / 12px; rotate: -1.5deg;
  box-shadow: 0 1px 1px rgba(31, 42, 34, .10), 0 2px 3px rgba(31, 42, 34, .08), 0 22px 36px -10px rgba(31, 42, 34, .30);
}

/* Le cartel de musée : forme, origine, famille, en DM Mono sur une étiquette ivoire épinglée. L'œillet laisse voir l'aplat. */
.fiche__cartel {
  position: relative; z-index: 3; grid-area: 2 / 1; align-self: end; justify-self: start; display: grid; gap: 4px; margin: 0; padding: 14px 20px 13px 34px;
  border-radius: var(--r-etiquette); rotate: -1.2deg; outline: 1px solid var(--laiton); outline-offset: -6px;
  box-shadow: 0 1px 2px rgba(20, 12, 4, .16), 0 14px 30px rgba(20, 12, 4, .2);
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase;
}
.fiche__cartel > span + span { color: var(--encre-douce); }
/* Un produit coupé à gauche colle à ce bord : le cartel passe à droite. */
.fiche__scene:has(.fiche__visuel[data-coupe="gauche"]) .fiche__cartel { justify-self: end; }
.fiche__cartel::before { content: ""; position: absolute; left: 14px; top: 22px; width: 9px; height: 9px; margin-top: -4.5px; border-radius: 50%; background: var(--aplat); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35); }
.fiche__scene[data-famille="lin"] .fiche__cartel::before { background: none; box-shadow: inset 0 0 0 1px var(--trait); }

/* Les notes, l'achat, l'étiquette. */
.fiche__notes { display: grid; gap: 18px; justify-items: start; align-content: start; padding-top: 44px; }
.fiche__texte { margin: 0; max-width: 18em; font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.18; letter-spacing: -.01em; text-wrap: pretty; }
.fiche__achat { display: contents; }
.fiche__consigne { margin: 40px 0 14px; color: var(--laiton-texte); }
/* Les deux modes de remise, en une ligne discrète sous la quantité. */
.fiche__remise { margin: 18px 0 0; font-size: var(--t-petit); line-height: 20px; color: var(--encre-douce); text-wrap: pretty; }

/* Les tickets à souche : un ticket par format. La souche, à gauche, est détachée par un pointillé de laiton et deux
   encoches ; le ticket choisi reçoit son poinçon (un disque de laiton de 8 px, 180 ms --rebond).
   Le nom accessible dit le poids, le prix et le prix au gramme. */
.tickets { display: grid; gap: 10px; }
.ticket {
  --souche: 44px;
  appearance: none; position: relative; display: grid; grid-template-columns: var(--souche) minmax(0, 1fr) auto; grid-template-rows: 1fr 1fr; column-gap: 18px; align-items: center;
  width: 100%; min-height: 72px; margin: 0; padding: 0 20px 0 0; border: 1px solid var(--trait); border-radius: 4px;
  background: var(--ivoire); color: var(--encre); font: inherit; text-align: left; cursor: pointer;
  -webkit-mask: radial-gradient(circle at var(--souche) 0, transparent 6px, #000 6.5px), radial-gradient(circle at var(--souche) 100%, transparent 6px, #000 6.5px);
  -webkit-mask-composite: source-in;
  mask: radial-gradient(circle at var(--souche) 0, transparent 6px, #000 6.5px), radial-gradient(circle at var(--souche) 100%, transparent 6px, #000 6.5px);
  mask-composite: intersect;
  transition: border-color 200ms var(--sortie), box-shadow 200ms var(--sortie), background-color 200ms var(--sortie);
}
.ticket__souche { position: relative; grid-row: 1 / -1; align-self: stretch; border-right: 1px dashed var(--laiton); }
/* La place du poinçon, puis le poinçon lui-même. */
.ticket__souche::before, .ticket__souche::after { content: ""; position: absolute; left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; }
.ticket__souche::before { box-shadow: inset 0 0 0 1px var(--trait); }
.ticket__souche::after { background: var(--laiton); scale: 0; transition: scale var(--d-court) var(--rebond); }
.ticket__poids { grid-row: 1 / -1; font-family: var(--font-titre); font-size: 28px; line-height: 1; letter-spacing: -.01em; white-space: nowrap; }
.ticket__prix { grid-column: 3; grid-row: 1; align-self: end; font-size: var(--t-corps); line-height: 22px; font-weight: 600; text-align: right; white-space: nowrap; }
.ticket__unite { grid-column: 3; grid-row: 2; align-self: start; margin-top: 2px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .04em; color: var(--encre-douce); text-align: right; white-space: nowrap; }
.ticket__prix--indispo { grid-row: 1 / -1; align-self: center; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.ticket[aria-pressed="true"] { border-color: var(--encre); box-shadow: inset 0 0 0 1px var(--encre); }
.ticket[aria-pressed="true"] .ticket__souche::after { scale: 1; }
.ticket[disabled] { cursor: not-allowed; background: transparent; }
.ticket[disabled] .ticket__poids { color: var(--encre-douce); }
/* Le masque rognerait le contour de focus : il est dessiné à l'intérieur du ticket. */
.ticket:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus); }
.ticket[aria-pressed="true"]:focus-visible { box-shadow: inset 0 0 0 1px var(--encre), inset 0 0 0 3px var(--focus); }
@media (hover: hover) and (pointer: fine) {
  .ticket:not([disabled]):not([aria-pressed="true"]):hover { border-color: var(--encre-douce); }
}

.fiche__quantite { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 20px; padding: 10px 0; border-block: 1px solid var(--trait); }
.fiche__quantite > .etiquette { color: var(--encre-douce); }
.fiche .quantite { border-color: var(--trait); background: var(--ivoire); }
.fiche .quantite button { width: 44px; height: 44px; border-radius: var(--r-controle); transition: opacity 160ms var(--sortie); }
.fiche .quantite button[disabled] { opacity: .3; cursor: default; }
.fiche .quantite output { min-width: 36px; font-variant-numeric: tabular-nums; }

/* La barre d'ajout. Sur téléphone, elle passe en dernier (order) et reste collée en bas de l'écran tant que la fiche est
   visible ; arrivée au bout de la fiche, elle se pose à sa place. Au clavier, elle suit la quantité (ordre du DOM). */
.fiche__barre { display: grid; gap: 10px; }
.fiche__ajouter { min-height: 56px; font-size: var(--t-corps); }
.fiche__retour:empty { display: none; }
.fiche__retour { text-align: center; }
@media (max-width: 899px) {
  .fiche__barre {
    order: 1; position: sticky; bottom: 0; z-index: 10; margin: 28px calc(var(--gouttiere) * -1) 0; padding: 12px var(--gouttiere) calc(12px + env(safe-area-inset-bottom));
    background: var(--papier); background: color-mix(in srgb, var(--papier) 90%, transparent); -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4);
    border-top: 1px solid var(--trait);
  }
  .fiche__ajouter { min-height: 52px; }
  /* Le bouton d'appel, s'il existe, se pose au-dessus de la barre. */
  body:has(.fiche__barre) .appel { bottom: calc(92px + env(safe-area-inset-bottom)); }
}

/* L'étiquette du lot, à la taille de la fiche. Sans certificat, chaque ligne dit « À venir », en laiton. */
.fiche__lot { display: grid; gap: 44px; justify-items: start; padding-top: 72px; }
.fiche__lot-titre { font-size: var(--t-titre); line-height: 1.02; letter-spacing: -.015em; }
.fiche__lot-texte p { margin: 14px 0 0; max-width: 30em; color: var(--encre-douce); }
.etiquette-lot--fiche { width: min(500px, 100% - 24px); margin-left: 12px; }
.etiquette-lot--fiche .etiquette-lot__nom { font-size: var(--t-titre); }
.etiquette-lot dd.a-venir { color: var(--laiton-texte); }
.etiquette-lot--fiche .etiquette-lot__pied { text-transform: none; letter-spacing: .02em; }
.etiquette-lot--fiche .etiquette-lot__pied a { color: var(--laiton-texte); text-underline-offset: 4px; text-decoration-thickness: 1px; min-height: 24px; }

@media (min-width: 900px) {
  .fiche { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 24px; padding-bottom: 128px; }
  .fiche > .muet, .fiche > .vide, .fiche > .ariane { grid-column: 1 / -1; }
  .ariane { padding: 24px 0 20px; }
  .fiche__scene {
    --debord: calc(max(0px, (100vw - 1280px) / 2) + var(--gouttiere));
    grid-column: 1 / -1; grid-row: 2; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto 1fr; column-gap: 24px;
    min-height: max(600px, 70svh); margin-inline: 0; padding: 56px 0 0; background: none;
    background-color: var(--aplat); border-image: linear-gradient(var(--aplat) 0 0) fill 0 / / 0 100vw; overflow: visible; overflow-y: clip;
  }
  .fiche__nom { grid-column: 1 / -1; max-width: 11em; }
  /* Le spécimen à droite, qui remonte sous la dernière ligne du nom et passe devant sa fin ; la scène rogne son pied. */
  .fiche__visuel { --l: min(52vw, 760px); grid-column: 4 / -1; grid-row: 2; align-self: end; justify-self: end; margin: calc(var(--t-nom) * -.3) 0 0; }
  .fiche__visuel--taille-haute { --l: min(40vw, 600px); }
  .fiche__visuel--taille-plate { --l: min(60vw, 900px); }
  .fiche__visuel .specimen { margin-bottom: -7%; }
  .fiche__visuel[data-coupe="droite"] { margin-inline: 0 calc(var(--debord) * -1); }
  .fiche__visuel[data-coupe="gauche"] { grid-column: 1 / 10; justify-self: start; margin-inline: calc(var(--debord) * -1) 0; }
  .fiche__cartel { grid-column: 1 / 5; grid-row: 2; align-self: end; margin: 0 0 56px; rotate: -1.5deg; }
  .fiche__scene:has(.fiche__visuel[data-coupe="gauche"]) .fiche__cartel { grid-column: 9 / -1; justify-self: end; }
  .fiche__visuel--photo { --l: min(26vw, 340px); grid-column: 6 / 12; justify-self: center; align-self: center; margin: 8px 0 72px; }

  .fiche__notes { grid-column: 1 / 7; grid-row: 3; padding-top: 88px; }
  .fiche__achat {
    grid-column: 8 / -1; grid-row: 3 / span 2; align-self: start; display: block;
    position: sticky; top: calc(96px + var(--haut-demo)); margin-top: 88px;
  }
  .fiche__consigne { margin-top: 0; }
  .fiche__barre { margin-top: 20px; }
  .fiche__lot { grid-column: 1 / 7; grid-row: 4; padding-top: 104px; }
}

/* L'entrée : le nom se dévoile, le spécimen monte en place (jamais d'opacité nulle : le LCP se mesure),
   le cartel suit. L'étiquette du lot s'imprime à 40 % de visibilité (règles de l'écran 5). Rien en mouvement réduit. */
@media screen and (prefers-reduced-motion: no-preference) {
  .fiche__nom { animation: ligne 700ms var(--sortie) both; }
  .fiche__visuel { animation: entree 1100ms var(--sortie) both; }
  .fiche__cartel { animation: legende 600ms var(--sortie) 420ms both; }
}

/* « De la même famille » (ou « De la même forme ») : l'étagère de l'accueil, après la bande. */
.parente { padding-top: 88px; }
.parente__tete { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: 32px; row-gap: 14px; margin-bottom: 40px; }
.parente__repere { grid-column: 1 / -1; margin: 0; color: var(--laiton-texte); }
.parente__titre { margin: 0; font-size: var(--t-grand); line-height: 1; letter-spacing: -.015em; }
.parente__lien { justify-self: end; }
@media (max-width: 719px) {
  .parente { padding-top: 64px; }
  .parente__tete { grid-template-columns: minmax(0, 1fr); margin-bottom: 28px; }
  .parente__lien { justify-self: start; }
}

/* Geste 3 : l'anneau d'empreinte qui s'échappe de la pastille du panier, et la pastille qui attend le bourgeon. */
.empreinte-vol { position: fixed; z-index: 60; border: 1.5px solid var(--laiton); border-radius: 999px; pointer-events: none; animation: empreinte 500ms var(--sortie) both; }
.pastille-panier.est-attendue { opacity: 0; }

/* Quantité */
.quantite { display: inline-flex; align-items: center; border: 1px solid var(--encre-douce); border-radius: var(--r-controle); }
.quantite button { appearance: none; background: none; border: 0; width: 40px; height: 40px; font-size: var(--t-corps); cursor: pointer; color: var(--encre); }
.quantite output { min-width: 32px; text-align: center; font-weight: 600; }

/* Panier : du papier, sans aplat d'arôme. À gauche les lignes, à droite le ticket de caisse (collant sur ordinateur).
   Chaque ligne : le spécimen de 64 px posé sur son filet de laiton, le nom en Gloock 24 px, la quantité et le montant en DM Mono. */
/* Le panier tient au moins l'écran, plein ou vide : le pied ne remonte jamais dans la vue quand le catalogue arrive (CLS). */
.panier { display: grid; gap: 56px; min-height: calc(100svh - var(--haut-demo) - var(--haut-entete)); padding: 40px 0 112px; }
@media (min-width: 900px) { .panier { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(48px, 6vw, 96px); align-items: start; padding-top: 72px; } }
.panier--vide { display: block; }
.panier__tete { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 24px; padding-bottom: 20px; border-bottom: 1px solid var(--encre); }
.panier__titre { font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; }
.panier__compte { margin: 0; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
.panier__lignes { list-style: none; margin: 0; padding: 0; }
.panier__suite { margin-top: 20px; }
/* Sur ordinateur, la colonne des lignes accompagne le ticket (collante sous les bandeaux) au lieu de laisser un vide.
   L'ancien encart « Le retrait » redisait la ligne du ticket : il est retiré, le plan est dans le ticket (finition, tour 1). */
@media (min-width: 900px) { .panier__colonne { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 24px); } }

/* Sur téléphone, la barre de paiement collée en bas de l'écran, reprise de la barre de la fiche : le total en DM Mono et
   le bouton. Elle s'efface quand le vrai bouton du ticket est à l'écran (app.js, pagePanier()) ; sa place naturelle, au
   bout du panier, remonte sous le ticket (marge négative) : rien ne s'ajoute à la hauteur de la page. */
.panier__barre { display: none; }
@media (max-width: 599px) {
  .panier__barre {
    position: sticky; bottom: 0; z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: 16px;
    margin: -128px calc(var(--gouttiere) * -1) 0; padding: 12px var(--gouttiere) calc(12px + env(safe-area-inset-bottom));
    background: var(--papier); border-top: 1px solid var(--trait);
    transition: opacity 200ms var(--sortie), translate 200ms var(--sortie), visibility 0s linear 0s;
  }
  .panier__barre.est-masquee { opacity: 0; translate: 0 100%; visibility: hidden; pointer-events: none; transition: opacity 160ms var(--sortie), translate 160ms var(--sortie), visibility 0s linear 160ms; }
  .panier__barre-total { display: grid; gap: 2px; margin: 0; font-family: var(--font-etiquette); font-variant-numeric: tabular-nums; }
  .panier__barre-total > span:first-child { font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
  .panier__barre-total > span:last-child { font-size: var(--t-chapo); line-height: 1.1; letter-spacing: -.03em; color: var(--encre); white-space: nowrap; }
  .panier__barre .btn { min-height: 52px; flex: 1 1 auto; max-width: 15rem; }
  body:has(.panier__barre:not(.est-masquee)) .appel { bottom: calc(92px + env(safe-area-inset-bottom)); }
}
/* Le plan du comptoir, sous l'adresse de la ligne de retrait du ticket. */
.recap__plan { grid-column: 1 / -1; grid-row: 3; justify-self: start; margin: -4px 0 -8px; font-size: var(--t-mini); }

.ligne { --vignette: 96px; display: grid; grid-template-columns: var(--vignette) minmax(0, 1fr) auto minmax(96px, auto); grid-template-areas: "visuel corps quantite montant"; align-items: center; column-gap: 24px; padding: 24px 0; border-bottom: 1px solid var(--trait); }
.ligne__visuel { grid-area: visuel; position: relative; isolation: isolate; display: flex; align-items: flex-end; justify-content: center; width: var(--vignette); height: var(--vignette); border-bottom: 1px solid var(--laiton); }
/* L'ombre au sol, sous le produit, comme sur l'étagère. */
.ligne__visuel::after { content: ""; position: absolute; z-index: -1; left: 14%; right: 14%; bottom: 0; height: 8px; translate: 0 50%; background: radial-gradient(closest-side, var(--ombre-sol), transparent); }
.ligne__visuel img { display: block; width: 84%; height: auto; max-height: 100%; object-fit: contain; object-position: bottom; transition: translate 240ms var(--sortie); }
.ligne__visuel .taille-haute { width: 68%; }
.ligne__visuel .taille-plate { width: 100%; }
/* Sans détourage, la photo devient un petit tirage, debout sur le filet. */
.ligne__visuel--photo img { width: 68px; height: 84px; max-height: none; object-fit: cover; object-position: center; border: 3px solid var(--sur-aplat); border-radius: 1px; rotate: -1.5deg; transform-origin: bottom center; box-shadow: 0 1px 1px rgba(31, 42, 34, .12), 0 6px 10px rgba(31, 42, 34, .14); }
.ligne__corps { grid-area: corps; min-width: 0; }
.ligne__nom { font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; }
.ligne__nom a { color: inherit; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 5px; transition: text-decoration-color 200ms var(--sortie); }
.ligne__format { margin: 6px 0 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; letter-spacing: .02em; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
.ligne__quantite { grid-area: quantite; border-color: var(--trait); background: var(--ivoire); }
.ligne__quantite button { width: 44px; height: 44px; border-radius: var(--r-controle); transition: background-color 160ms var(--sortie), opacity 160ms var(--sortie); }
.ligne__quantite button[disabled] { opacity: .3; cursor: default; }
.ligne__quantite output { min-width: 28px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-petit); font-variant-numeric: tabular-nums; }
.ligne__montant { grid-area: montant; margin: 0; text-align: right; font-family: var(--font-etiquette); font-size: var(--t-corps); font-weight: 500; letter-spacing: -.01em; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (hover: hover) and (pointer: fine) {
  .ligne__nom a:hover { text-decoration-color: var(--laiton); }
  .ligne:has(.ligne__visuel:hover, .ligne__nom a:hover) .ligne__visuel img { translate: 0 -3px; }
  .ligne__quantite button:not([disabled]):hover { background: var(--lin); }
}
@media (max-width: 599px) {
  .ligne { --vignette: 72px; grid-template-columns: var(--vignette) minmax(0, 1fr) auto; grid-template-areas: "visuel corps corps" "visuel quantite montant"; align-items: center; column-gap: 16px; row-gap: 12px; padding: 20px 0; }
  .ligne__visuel--photo img { width: 52px; height: 64px; }
  .ligne__visuel { align-self: start; }
  .ligne__quantite { justify-self: start; }
}

/* Le ticket de caisse : ivoire, le bord bas perforé (des demi-cercles de 6 px tous les 14 px), le total en DM Mono 48 px.
   Sous le total, la souche des coordonnées, détachée par un pointillé de laiton et deux encoches. */
.perfore {
  padding-bottom: 12px;
  -webkit-mask: radial-gradient(circle at 50% 100%, transparent 6px, #000 6.5px) 0 0 / 14px 100% repeat-x;
  mask: radial-gradient(circle at 50% 100%, transparent 6px, #000 6.5px) 0 0 / 14px 100% repeat-x;
}
.panier__ticket { filter: var(--ombre-ticket); }
@media (min-width: 900px) { .panier__ticket { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 24px); } }
.recap { display: grid; background: var(--ivoire); border-radius: 3px 3px 0 0; font-variant-numeric: tabular-nums; }
.recap__ticket { display: grid; padding: 28px 28px 24px; }
.recap__entete { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding-bottom: 14px; border-bottom: 1px solid var(--encre); }
.recap__titre { margin: 0; font-family: var(--font-etiquette); font-size: var(--t-etiquette); line-height: 1.3; letter-spacing: .12em; color: var(--encre); }
.recap__maison { margin: 0; color: var(--laiton-texte); }
.recap__articles { list-style: none; margin: 0; padding: 6px 0; }
.recap__ligne { display: flex; align-items: baseline; gap: 10px; margin: 0; padding: 9px 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; letter-spacing: .01em; color: var(--encre); }
/* Les points de conduite, entre l'article et son prix. */
.recap__ligne::after { content: ""; order: 1; flex: 1 1 16px; min-width: 16px; border-bottom: 1px dotted var(--encre-douce); opacity: .55; translate: 0 -4px; }
.recap__ligne > :last-child { order: 2; white-space: nowrap; }
.recap__fois { color: var(--laiton-texte); }
/* Le retrait : son libellé et son prix sur la ligne (points de conduite entre les deux), l'adresse dessous, en petit. */
.recap__retrait { display: grid; grid-template-columns: auto minmax(16px, 1fr) auto; column-gap: 10px; row-gap: 4px; align-items: baseline; padding: 12px 0; border-top: 1px dashed var(--trait); color: var(--encre-douce); }
.recap__retrait::after { grid-column: 2; grid-row: 1; }
.recap__retrait-libelle { grid-column: 1; grid-row: 1; color: var(--encre); }
.recap__retrait-prix { grid-column: 3; grid-row: 1; white-space: nowrap; }
.recap__retrait-adresse { grid-column: 1 / -1; grid-row: 2; font-size: var(--t-mini); line-height: 16px; }
.recap__total { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; padding-top: 18px; border-top: 1px solid var(--encre); }
.recap__total .etiquette { color: var(--encre-douce); }
.recap__montant { margin-left: auto; font-family: var(--font-etiquette); font-size: 48px; line-height: 1; letter-spacing: -.045em; white-space: nowrap; }
.recap__coordonnees { position: relative; display: grid; gap: 16px; padding: 28px 28px 24px; border-top: 1px dashed var(--laiton); }
.recap__coordonnees::before, .recap__coordonnees::after { content: ""; position: absolute; top: 0; width: 16px; height: 16px; border-radius: 50%; background: var(--papier); translate: 0 -50%; }
.recap__coordonnees::before { left: -8px; }
.recap__coordonnees::after { right: -8px; }
.recap__souche { margin: 0; color: var(--laiton-texte); }
.recap__cases { display: grid; gap: 10px; padding: 4px 0; }
.recap__payer { min-height: 52px; font-size: var(--t-corps); margin-top: 4px; }
.recap__note { text-wrap: pretty; }
/* La mention de viva.com, exigée par Viva près du bouton de paiement. En texte : le logo officiel n'a pas pu être récupéré. */
.recap__viva { margin: 0; display: flex; align-items: center; justify-content: center; gap: .5rem; font-size: var(--t-petit); color: var(--encre-douce); }
.recap__viva-logo { display: block; width: 29px; height: 40px; border-radius: 3px; }
/* Le sous-total des articles, quand des frais de livraison s'y ajoutent : une ligne du ticket, en retrait. */
.recap__sous-total { padding: 10px 0 4px; border-top: 1px dashed var(--trait); color: var(--encre-douce); }
.recap__sous-total[hidden] { display: none; }
.recap__sous-total + .recap__retrait { border-top: 0; padding-top: 6px; }
/* La réduction d'un code, juste au-dessus du total : une ligne du ticket, comme les frais. */
.recap__reduction { padding: 6px 0 12px; }
.recap__reduction[hidden] { display: none; }
/* Le code de réduction, replié sous le total : un lien qui s'ouvre sur un champ et son bouton. */
.code-reduction { margin-top: 14px; }
.code-reduction__titre { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; list-style: none; cursor: pointer; font-size: var(--t-petit); font-weight: 600; color: var(--laiton-texte); text-decoration: underline; text-underline-offset: 4px; }
.code-reduction__titre::-webkit-details-marker { display: none; }
.code-reduction__titre::after { content: "+"; text-decoration: none; font-weight: 500; }
.code-reduction[open] .code-reduction__titre::after { content: "−"; }
.code-reduction__titre:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 2px; }
.code-reduction__corps { display: grid; gap: 8px; padding-top: 4px; }
.code-reduction__saisie { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: end; }
.code-reduction__saisie input { width: 100%; min-width: 0; box-sizing: border-box; text-transform: uppercase; letter-spacing: .04em; }
.code-reduction__appliquer { min-height: 48px; }
.code-reduction__applique { display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; margin: 0; font-size: var(--t-petit); }
.code-reduction__applique[hidden] { display: none; }
.code-reduction__message:empty { display: none; }

/* La remise : deux tickets à souche, comme les formats de la fiche, sur le papier de la souche. Le bouton radio est
   invisible mais reste le contrôle (clavier, lecteur d'écran) ; le choisi reçoit son poinçon de laiton. */
/* Une seule colonne qui peut rétrécir : une adresse enregistrée très longue ne pousse plus les champs hors du ticket. */
.remises, .livraison { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; min-width: 0; margin: 0; padding: 0; border: 0; }
.remises > legend, .livraison > legend { float: left; width: 100%; margin-bottom: 2px; padding: 0; }
.livraison { gap: 16px; }
.livraison[hidden] { display: none; }
/* Les deux champs s'alignent par le bas : « Code postal » peut passer sur deux lignes sans décaler les cases. */
.livraison__ville { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 5fr); gap: 12px; align-items: end; }
.livraison .champ input { width: 100%; min-width: 0; }
.remise {
  --souche: 40px;
  position: relative; display: grid; grid-template-columns: var(--souche) minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 16px; row-gap: 2px; align-items: center;
  min-height: 64px; padding: 12px 16px 12px 0; border: 1px solid var(--trait); border-radius: 4px; background: var(--papier); color: var(--encre); cursor: pointer;
  -webkit-mask: radial-gradient(circle at var(--souche) 0, transparent 6px, #000 6.5px), radial-gradient(circle at var(--souche) 100%, transparent 6px, #000 6.5px);
  -webkit-mask-composite: source-in;
  mask: radial-gradient(circle at var(--souche) 0, transparent 6px, #000 6.5px), radial-gradient(circle at var(--souche) 100%, transparent 6px, #000 6.5px);
  mask-composite: intersect;
  transition: border-color 200ms var(--sortie), box-shadow 200ms var(--sortie);
}
.remise__choix { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.remise__souche { position: relative; grid-column: 1; grid-row: 1 / -1; align-self: stretch; margin: -12px 0; border-right: 1px dashed var(--laiton); pointer-events: none; }
.remise__souche::before, .remise__souche::after { content: ""; position: absolute; left: 50%; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; }
.remise__souche::before { box-shadow: inset 0 0 0 1px var(--trait); }
.remise__souche::after { background: var(--laiton); scale: 0; transition: scale var(--d-court) var(--rebond); }
.remise__titre { grid-column: 2; font-size: var(--t-corps); line-height: 22px; font-weight: 600; pointer-events: none; }
.remise__detail { grid-column: 2; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .02em; color: var(--encre-douce); pointer-events: none; text-wrap: pretty; }
.remise:has(.remise__choix:checked) { border-color: var(--encre); box-shadow: inset 0 0 0 1px var(--encre); }
.remise:has(.remise__choix:checked) .remise__souche::after { scale: 1; }
/* Le masque rognerait le contour de focus : il est dessiné à l'intérieur du ticket. */
.remise:has(.remise__choix:focus-visible) { box-shadow: inset 0 0 0 2px var(--focus); }
@media (hover: hover) and (pointer: fine) { .remise:hover:not(:has(.remise__choix:checked)) { border-color: var(--encre-douce); } }
@media (prefers-reduced-motion: reduce) { .remise__souche::after { transition: none; } }
/* Finition, tour 3 : la remise sous les lignes du panier, dans la colonne de gauche. Sur ordinateur, les deux tickets
   côte à côte ; leur papier est l'ivoire, pour se détacher de la page. */
.remises__options { display: grid; gap: 10px; }
.panier__colonne .remises { margin-top: 40px; }
.panier__colonne .remises > legend { margin-bottom: 14px; color: var(--laiton-texte); }
.panier__colonne .remise { background: var(--ivoire); }
@media (min-width: 900px) { .panier__colonne .remises__options { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } .panier__colonne .remise { min-height: 76px; } }
/* Trois modes (retrait, domicile, soir) : le retrait sur toute la largeur, les deux livraisons dessous. */
@media (min-width: 900px) { .panier__colonne .remises__options--trois > .remise:first-child { grid-column: 1 / -1; } }
.panier__fermetures { margin: 0; }
.champ select { font: inherit; font-size: var(--t-corps); min-height: 48px; padding: 12px 14px; border: 1px solid var(--encre-douce); border-radius: var(--r-controle); background: var(--papier); color: var(--encre); width: 100%; min-width: 0; max-width: 100%; text-overflow: ellipsis; }
.champ select:focus-visible { outline: none; border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }
.champ input[type="date"] { min-width: 0; width: 100%; appearance: none; -webkit-appearance: none; text-align: left; }
.champ[hidden] { display: none; }
.champ__groupe { display: grid; gap: 6px; }
.champ__aide { margin: 0; font-size: var(--t-mini); line-height: 18px; color: var(--encre-douce); }
/* L'erreur d'un champ, posée juste sous lui (aria-describedby), et son contour rouille. */
.champ__erreur { margin: 0; font-size: var(--t-mini); line-height: 18px; font-weight: 600; color: var(--rouille); }
.champ__erreur[hidden] { display: none; }
.champ input[aria-invalid="true"] { border-color: var(--rouille); box-shadow: 0 0 0 1px var(--rouille); }
.case input[aria-invalid="true"] { border-color: var(--rouille); }
@media (max-width: 599px) {
  .recap__ticket, .recap__coordonnees { padding-inline: 20px; }
  .recap__montant { font-size: 44px; }
}
.champ { display: grid; gap: 6px; min-width: 0; font-size: var(--t-petit); }
.champ input { font: inherit; font-size: var(--t-corps); min-height: 48px; padding: 12px 14px; border: 1px solid var(--encre-douce); border-radius: var(--r-controle); background: var(--papier); color: var(--encre); transition: border-color 160ms var(--sortie), box-shadow 160ms var(--sortie); }
.champ input:focus-visible { outline: none; border-color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }
@media (hover: hover) and (pointer: fine) { .champ input:hover:not(:focus) { border-color: var(--encre); } }
/* Les cases : 22 px, dessinées (coche de laiton), toute la ligne cliquable sur 44 px de haut au moins. */
.case { display: flex; gap: 12px; align-items: center; min-height: 44px; font-size: var(--t-petit); line-height: 20px; color: var(--encre-douce); cursor: pointer; }
.case input {
  appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 22px; height: 22px; margin: 0;
  border: 1.5px solid var(--encre-douce); border-radius: 4px; background: var(--ivoire); cursor: pointer;
  transition: border-color 160ms var(--sortie), background-color 160ms var(--sortie);
}
.case input::after {
  content: ""; position: absolute; left: 6px; top: 2px; width: 6px; height: 11px; border: solid var(--laiton); border-width: 0 2px 2px 0;
  rotate: 45deg; scale: .5; opacity: 0; transition: scale var(--d-court) var(--sortie), opacity var(--d-court) var(--sortie);
}
.case input:checked { border-color: var(--laiton); }
.case input:checked::after { scale: 1; opacity: 1; }
.case input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .case:hover input:not(:checked) { border-color: var(--encre); } }
.message { font-size: var(--t-petit); margin: 0; }
.message--ok { color: var(--mousse); }
.message--erreur { color: var(--rouille); }
.vide { min-height: 56svh; padding: 64px 0; display: grid; gap: 16px; align-content: center; justify-items: center; text-align: center; }
.vide__etiquette { margin: 0; color: var(--laiton-texte); }
.vide__titre { max-width: 13em; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; }
.vide__texte { margin: 0 0 8px; }
/* Le panier vide : le bourgeon du monogramme pour point final du titre, puis l'étagère de la cueillette (mêmes cartes,
   même filet de laiton que l'accueil), sous l'appel. */
.vide__bourgeon { display: inline-block; width: .17em; height: .17em; margin-left: .06em; border-radius: 50%; background: var(--laiton); }
.panier--vide .vide { min-height: 0; padding-bottom: 80px; }
.vide__bande { margin-bottom: 12px; }
/* Les erreurs de l'espace client (code faux ou expiré, adresse refusée) : en DM Mono, rouille, ouvertes par un point
   rouille ; le champ en cause prend un filet rouille. La rouille ne sert qu'aux erreurs (finition, tour 3). */
.connexion__form .message--erreur, .espace .message--erreur {
  display: flex; align-items: baseline; gap: 10px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 19px; letter-spacing: .01em; color: var(--rouille);
}
.connexion__form .message--erreur::before, .espace .message--erreur::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--rouille); translate: 0 -1px; }
.connexion__form input[aria-invalid="true"] { border-color: var(--rouille); box-shadow: 0 0 0 1px var(--rouille); }
.panier__vitrine { padding-top: 28px; border-top: 1px solid var(--trait); }
.panier__vitrine-titre { margin: 0 0 40px; color: var(--laiton-texte); }

/* Réassurance */
/* Le filet entre les garanties vient de l'espace de 1px sur fond trait : il suit le nombre de garanties affichées. */
.reassurance { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1px; background: var(--trait); border: 1px solid var(--trait); border-radius: var(--r-carte); overflow: hidden; }
.reassurance > div { padding: 24px; display: grid; gap: 6px; background: var(--lin); }
.reassurance strong { font-size: var(--t-petit); }
.reassurance span { font-size: var(--t-mini); line-height: 20px; color: var(--encre-douce); }

/* Pleine largeur sans sortir de la colonne : la section déborde jusqu'aux bords de l'écran par ses marges, et ses marges
   intérieures la ramènent exactement sur la colonne de 1 280 px. Les deux pourcentages se rapportent à la même largeur
   (celle de .page) : le texte tombe au pixel sur la gouttière de l'en-tête, barre de défilement comptée ou non. */
.invite-bulletin, .maison { margin-inline: calc(50% - 50vw); padding-inline: calc(50vw - 50%); }

/* Écran 7 · L'invitation au Bulletin : aplat mousse, une composition de lettre. Le cachet de cire (Baie) scelle un filet
   ivoire qui court sur toute la colonne ; le titre, une phrase et un seul bouton, qui ouvre la fenêtre existante. */
.invite-bulletin {
  position: relative; display: grid; justify-items: center; text-align: center;
  padding-block: clamp(96px, 11vw, 152px) clamp(104px, 11vw, 160px);
  background-color: var(--aplat-mousse); color: var(--sur-aplat); --focus: var(--sur-aplat);
}
.invite-bulletin__cachet { position: relative; justify-self: stretch; display: grid; place-items: center; margin-bottom: clamp(40px, 4.4vw, 56px); }
.invite-bulletin__cachet::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: rgba(251, 248, 241, .26); }
.cachet { position: relative; width: clamp(112px, 11vw, 148px); height: auto; aspect-ratio: 1; overflow: visible; rotate: -4deg; filter: drop-shadow(0 14px 18px rgba(12, 20, 14, .32)) drop-shadow(0 2px 3px rgba(12, 20, 14, .3)); }
.cachet__cire { fill: var(--aplat-baie); }
.cachet__bord { stroke: rgba(251, 248, 241, .2); }
.cachet__mono { fill: var(--sur-aplat); fill-opacity: .55; }
.invite-bulletin__titre { margin: 0; max-width: 12em; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; color: var(--sur-aplat); }
.invite-bulletin__texte { margin: 28px 0 0; max-width: 28em; text-wrap: balance; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: rgba(251, 248, 241, .86); }
/* Le formulaire, dans l'encart (aucune fenêtre) : un champ, la case d'accord décochée, un bouton, la mention.
   Ses encres sont fixes, comme l'aplat mousse : ivoire, laiton clair. Les messages restent ivoire (la mousse et la rouille
   ne se lisent pas l'une sur l'autre) ; l'erreur porte un point rouille clair. */
.invite-bulletin__surtitre { margin: 0 0 18px; color: rgba(251, 248, 241, .86); }
.invite-bulletin__formulaire { display: grid; gap: 14px; width: min(30rem, 100%); margin-top: 40px; text-align: left; }
.champ--clair { color: rgba(251, 248, 241, .9); }
.champ--clair input { border-color: rgba(251, 248, 241, .55); background: rgba(251, 248, 241, .06); color: var(--sur-aplat); }
.champ--clair input:focus-visible { border-color: var(--laiton-clair); box-shadow: 0 0 0 1px var(--laiton-clair); }
.case--clair { color: rgba(251, 248, 241, .86); }
.case--clair input { border-color: rgba(251, 248, 241, .7); background: transparent; }
.case--clair input::after { border-color: var(--laiton-clair); }
.case--clair input:checked { border-color: var(--laiton-clair); }
.invite-bulletin__bouton { min-height: 52px; padding-inline: 32px; justify-self: start; }
.invite-bulletin__formulaire :disabled { opacity: .55; cursor: not-allowed; }
.invite-bulletin__message:empty { display: none; }
.invite-bulletin .message { color: var(--sur-aplat); font-size: var(--t-petit); }
.invite-bulletin .message--erreur::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; background: #E8A07D; }
.invite-bulletin__rgpd { margin: 6px 0 0; font-size: var(--t-mini); line-height: 20px; color: rgba(251, 248, 241, .78); }
.invite-bulletin__rgpd a { color: var(--sur-aplat); text-underline-offset: 3px; }
/* Après la demande : le champ, la case et le bouton laissent la place à une phrase qui rappelle l'adresse, et au bouton
   « Changer d'adresse ». Rien de grisé sur la mousse. */
.invite-bulletin__message:focus { outline: none; }
.invite-bulletin__message:focus-visible { outline: 2px solid var(--sur-aplat); outline-offset: 4px; }
.invite-bulletin__changer { justify-self: start; color: var(--sur-aplat); }
.invite-bulletin__changer[hidden] { display: none; }
.invite-bulletin__formulaire [hidden] { display: none; }
/* Inscriptions fermées (pages.py, invite_bulletin()) : une ligne en DM Mono et la mention repliée, pas de bouton grisé.
   Ouvertes (app.js, formulaireBulletin()) : le formulaire. L'encart se resserre tant qu'il est fermé. */
/* Finition, tour 3 : l'encart fermé finit sur sa mention, sans bande de mousse vide dessous (la fenêtre C n° 2 s'accroche
   juste après, en tête de la maison). */
.invite-bulletin[data-bulletin-etat="ferme"] { padding-block: clamp(72px, 8vw, 112px) clamp(40px, 4vw, 56px); }
.invite-bulletin[data-bulletin-etat="ferme"] .invite-bulletin__formulaire,
.invite-bulletin[data-bulletin-etat="ouvert"] :is(.invite-bulletin__bientot, .invite-bulletin__details) { display: none; }
.invite-bulletin__bientot { display: inline-flex; align-items: center; gap: 12px; margin: 36px 0 0; color: var(--sur-aplat); }
.invite-bulletin__bientot::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--laiton-clair); }
.invite-bulletin__details { width: min(34rem, 100%); margin-top: 12px; text-align: left; }
.invite-bulletin__details summary {
  display: flex; justify-content: center; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; list-style: none;
  font-size: var(--t-petit); color: rgba(251, 248, 241, .86); text-decoration: underline; text-decoration-color: rgba(251, 248, 241, .4); text-underline-offset: 4px;
}
.invite-bulletin__details summary::-webkit-details-marker { display: none; }
.invite-bulletin__details summary::after { content: "+"; font-family: var(--font-etiquette); color: var(--laiton-clair); }
.invite-bulletin__details[open] summary::after { content: "\2212"; }
.invite-bulletin__details .invite-bulletin__rgpd { margin-top: 8px; }
@media (hover: hover) and (pointer: fine) { .case--clair:hover input:not(:checked) { border-color: var(--sur-aplat); } }
@media (max-width: 599px) {
  .invite-bulletin__titre { font-size: var(--t-grand); }
  .invite-bulletin__bouton { justify-self: stretch; }
}
/* Le cachet se pose une fois, à 50 % de visibilité : il arrive de plus haut et plus penché, et s'écrase un peu (--rebond). */
@media screen and (prefers-reduced-motion: no-preference) {
  .js .invite-bulletin:not(.est-visible) .cachet { opacity: 0; }
  .js .invite-bulletin.est-visible .cachet { animation: cachet 420ms var(--rebond) both; }
}
@keyframes cachet { from { scale: 1.3; rotate: -8deg; opacity: 0; } 40% { opacity: 1; } to { scale: 1; rotate: -4deg; opacity: 1; } }

/* Écran 8 · La maison : sous-bois et semis, un titre en deux temps (le lieu en laiton clair), une phrase sur le retrait,
   et le carton du comptoir (l'adresse, les horaires et le téléphone s'ils sont fournis, le plan). Sur ordinateur, le texte
   à gauche, le carton à droite. Le pied vient après une bande de papier : la maison et le pied ne font plus un seul bloc.
   Lot 12 : l'image mains-etiquette se branche en premier enfant de .maison__interieur, à gauche (règles .maison__image).
   overflow: clip seul (pas de repli hidden) : il contient le voile collant de la fenêtre C n° 2. */
.maison { position: relative; overflow: clip; background-color: var(--aplat-sousbois); color: var(--sur-aplat); --focus: var(--laiton-clair); }
.maison__interieur { position: relative; display: grid; grid-template-rows: auto auto; row-gap: 48px; padding-block: clamp(96px, 10vw, 144px); }
.maison__texte { align-self: end; }
.maison__titre { margin: 0; max-width: 11em; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; color: var(--sur-aplat); }
/* Deux lignes sur ordinateur ; sur téléphone, le texte coule et « au » rejoint la ligne d'avant : le lieu reste entier. */
.maison__ligne { display: block; }
.maison__lieu { color: var(--laiton-clair); white-space: nowrap; }
.maison__phrase { margin: 36px 0 0; max-width: 27em; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: rgba(251, 248, 241, .8); }
/* Le carton du comptoir : un liseré de laiton clair, comme une étiquette posée sur le sous-bois. */
.maison__pied {
  display: grid; gap: 12px; justify-items: start; align-self: end; padding: 30px 30px 18px;
  border: 1px solid rgba(201, 164, 94, .5); border-radius: var(--r-etiquette); outline: 1px solid rgba(201, 164, 94, .22); outline-offset: -8px;
}
.maison__pied > * { margin: 0; }
.maison__carton-titre { color: var(--laiton-clair); }
.maison__adresse { display: grid; gap: 2px; font-style: normal; font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.12; color: var(--sur-aplat); }
.maison__adresse > span { white-space: nowrap; }
.maison__point { display: none; }
.maison__coordonnees__horaires, .maison__coordonnees__telephone { font-size: var(--t-petit); line-height: 1.5; color: rgba(251, 248, 241, .8); font-variant-numeric: tabular-nums; }
.maison__coordonnees__telephone a { color: var(--sur-aplat); }
@media (min-width: 900px) {
  /* Sur la grille de 12 colonnes de la page : le texte de 1 à 7, le carton de 8 à 12, alignés en bas. */
  .maison__interieur { grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: auto; column-gap: 24px; }
  .maison__texte { grid-column: 1 / 8; }
  .maison__pied { grid-column: 8 / -1; justify-self: end; width: min(100%, 26rem); }
  .maison__interieur:has(> .maison__image) { grid-template-columns: 5fr 7fr; grid-template-rows: 1fr auto; column-gap: 64px; }
  .maison__interieur:has(> .maison__image) .maison__pied { justify-self: start; }
  .maison__interieur:has(> .maison__image) > :not(.maison__image) { grid-column: 2; }
  .maison__image { grid-row: 1 / span 2; align-self: center; margin: 0; }
  .maison__image img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; }
}
@media (max-width: 599px) {
  .maison__interieur { row-gap: 40px; }
  .maison__titre { font-size: var(--t-titre); }
  .maison__ligne { display: inline; }
  .maison__pied { padding: 24px 22px 12px; }
}
/* Un lien sur aplat sombre : ivoire, souligné d'un filet, la flèche hors du flux (le soulignement s'arrête au dernier mot). */
.lien-clair { position: relative; display: inline-flex; align-items: center; min-height: 44px; padding-right: 1.5em; color: var(--sur-aplat); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; text-decoration-color: rgba(251, 248, 241, .45); transition: text-decoration-color 200ms var(--sortie); }
.lien-clair:focus-visible { border-radius: var(--r-etiquette); }
.lien-clair::after { content: "→"; position: absolute; right: 0; top: 50%; translate: 0 -50%; color: var(--laiton-clair); transition: translate 200ms var(--sortie); }
@media (hover: hover) and (pointer: fine) {
  .lien-clair:hover { text-decoration-color: var(--laiton-clair); }
  .lien-clair:hover::after { translate: 4px -50%; }
}

/* La fenêtre C n° 2 : le voile mousse (la couleur de l'écran précédent) percé du C, posé sur la maison. Le C entre par
   le bas, à sa taille, comme une fenêtre découpée dans la mousse (la limite entre les deux sections ne se voit pas :
   même couleur), et le défilement l'ouvre × 80 depuis le dos du C pendant que la section entre (entry 20 % à cover 35 %) :
   plus d'avant-champ, plus d'écran où l'on ne voit que le C (finition, tour 1). Le voile s'efface sur les 15 % finaux,
   le texte se lève sur les 20 % finaux : aucun arrêt du défilement ne montre un titre coupé par le C, ni voilé.
   Sans prise en charge ou en mouvement réduit, rien n'est posé : ni voile, ni avant-champ, ni attente du texte. */
.maison__voile { display: none; }
@supports (animation-timeline: view()) {
  @media screen and (prefers-reduced-motion: no-preference) {
    .maison { view-timeline: --maison block; }
    .maison__voile { --c: clamp(168px, 22vw, 280px); --fond-voile: var(--aplat-mousse); display: block; position: absolute; inset: 0; z-index: 2; pointer-events: none; }
    /* Finition, tour 3 : le C n'est plus collant au milieu de l'écran (il laissait environ 400 px de mousse vide sous le
       Bulletin). Il est accroché en tête de la maison, juste sous le texte du Bulletin, et s'ouvre pendant que la maison
       entre : c'est lui qui ouvre « Une maison de quartier ». */
    .maison__voile .fenetre-c__svg { display: block; width: var(--c); height: var(--c); margin: 8px auto 0; }
    .maison__voile .fenetre-c__voile { transform: scale(var(--ouverture)); animation: fenetre-maison linear both; animation-timeline: --maison; animation-range: entry 5% entry 85%; }
    .maison__interieur > * { animation: maison-texte linear both; animation-timeline: --maison; animation-range: entry 5% entry 85%; }
  }
  @media screen and (prefers-reduced-motion: no-preference) and (max-width: 720px) {
    .maison__voile { --c: 56vw; }
  }
}
@keyframes maison-texte { 0%, 80% { opacity: 0; } 100% { opacity: 1; } }
/* L'échelle passe par une propriété déclarée, et non par transform : le navigateur repeint alors le voile à chaque image,
   net à toute taille (une transformation animée serait agrandie comme une image, floue). Une montée presque exponentielle :
   l'œil lit une échelle en rapports, le C s'ouvre donc d'un même pas sur toute la course. */
@property --ouverture { syntax: '<number>'; inherits: false; initial-value: 1; }
@keyframes fenetre-maison { 0% { --ouverture: 1; opacity: 1; } 30% { --ouverture: 1.15; } 50% { --ouverture: 1.8; } 65% { --ouverture: 3.5; } 78% { --ouverture: 8; } 85% { opacity: 1; } 90% { --ouverture: 24; } 100% { --ouverture: 80; opacity: 0; } }

/* Le fil de progression (§ 1.5) : un état, pas un geste. Un rail fixe à droite, le bourgeon descend avec la lecture.
   Accueil seulement, à partir de 1 100 px, sous @supports : sans prise en charge, pas de fil, et aucun repli en JS. */
.fil { display: none; }
@supports (animation-timeline: scroll()) {
  @media screen and (min-width: 1100px) and (prefers-reduced-motion: no-preference) {
    /* Dans la gouttière (16 px du bord). Il s'efface au-dessus des écrans qui vont jusqu'au bord (app.js, filDiscret()). */
    .fil { display: block; position: fixed; z-index: 15; top: 20vh; right: 16px; width: 1px; height: 60vh; background: var(--trait); pointer-events: none; transition: opacity 240ms var(--sortie); }
    .fil.est-discret { opacity: 0; }
    .fil__bourgeon { position: absolute; top: -4px; left: -3.5px; width: 8px; height: 8px; border-radius: 50%; background: var(--laiton); box-shadow: 0 0 0 2px var(--papier); animation: fil linear both; animation-timeline: scroll(root block); }
  }
}
@keyframes fil { from { translate: 0 0; } to { translate: 0 60vh; } }

/* Pied de page : aplat sous-bois et semis. Le logo d'origine, découpé lettre par lettre, à une taille de signature
   (le mot en très grand est réservé au totem de l'accueil), puis quatre colonnes en ivoire : la devise avec les horaires
   et le téléphone (dès qu'ils sont fournis), la maison, le comptoir, les informations.
   Le dos du C, la devise et les colonnes s'alignent sur la même gouttière. */
.pied { background-color: var(--aplat-sousbois); color: var(--sur-aplat); margin-top: 64px; overflow: hidden; }
/* Après la maison (même sous-bois), plus de bande de papier : la bande nuancier en filet (quatre pastilles de 12 × 4 px,
   cahier § 1.6) marque le changement de chapitre, sur la gouttière, au ras de la jointure (finition, tour 1). */
.page:has(> .maison:last-child) + .pied { margin-top: 0; }
.page:has(> .maison:last-child) + .pied .pied__interieur {
  --x: var(--gouttiere);
  background:
    linear-gradient(var(--aplat-zeste) 0 0) var(--x) 0 / 12px 4px no-repeat,
    linear-gradient(var(--aplat-terre) 0 0) calc(var(--x) + 16px) 0 / 12px 4px no-repeat,
    linear-gradient(var(--aplat-baie) 0 0) calc(var(--x) + 32px) 0 / 12px 4px no-repeat,
    linear-gradient(var(--aplat-fleur) 0 0) calc(var(--x) + 48px) 0 / 12px 4px no-repeat;
}
.pied__interieur { padding: 56px var(--gouttiere) 48px; max-width: 1280px; margin: 0 auto; display: grid; gap: 32px; }
@media (min-width: 600px) { .pied__interieur { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; } }
@media (min-width: 900px) { .pied__interieur { grid-template-columns: 1.3fr 1fr 1fr 1.2fr; column-gap: 40px; row-gap: 48px; padding-top: 80px; padding-bottom: 64px; } }
.pied__logo { grid-column: 1 / -1; display: block; justify-self: start; width: min(62%, 300px); padding-bottom: 28px; border-radius: 0; }
@media (min-width: 900px) { .pied__logo { width: min(40%, 460px); padding-bottom: 8px; } }
.pied__interieur::before { content: ""; grid-column: 1 / -1; grid-row: 2; height: 1px; background: rgba(251, 248, 241, .16); }
.pied__logo .logo { width: 100%; height: auto; aspect-ratio: 493 / 80.5; }
.pied .pied__devise { display: grid; align-content: start; gap: 14px; }
.pied .coordonnees__horaires { font-variant-numeric: tabular-nums; }
.pied .coordonnees__telephone a { font-family: var(--font-etiquette); font-variant-numeric: tabular-nums; }
.pied__logo:focus-visible { outline-offset: 8px; }
.pied p { margin: 0; font-size: var(--t-petit); line-height: 22px; color: rgba(251, 248, 241, .78); }
.pied .pied__devise p { font-family: var(--font-titre); font-size: 28px; line-height: 32px; letter-spacing: -.01em; color: var(--sur-aplat); }
.pied a { color: var(--sur-aplat); text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: rgba(251, 248, 241, .4); transition: text-decoration-color 160ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .pied p a:hover { text-decoration-color: var(--laiton-clair); } }
/* Les liens du pied, de « Vos données » et du pied de l'étiquette : 44 px de haut à toucher, sans changer la ligne
   (la marge négative rend exactement ce que la boîte prend en plus de sa hauteur de ligne). */
.pied p a, .invite-bulletin__rgpd a, .recap__note a, .connexion__note a, .etiquette-lot--fiche .etiquette-lot__pied a {
  display: inline-flex; align-items: center; min-height: 44px; margin-block: calc((44px - 1lh) / -2);
}
.pied .surtitre { color: var(--laiton-clair); margin-bottom: 8px; }
/* Le logo se lève lettre par lettre, une fois, quand il est vu à 30 % : le monogramme d'abord, puis les douze lettres
   (40 ms d'écart, 600 ms --sortie), puis « DU CBD ». translate en % se compte sur chaque lettre (fill-box).
   Sans JavaScript, à l'impression ou en mouvement réduit, le logo est posé d'emblée. */
.pied__logo :is(.logo__lettre, .logo__mention, .logo__c) { transform-box: fill-box; }
.l-1 { --n: 1; } .l-2 { --n: 2; } .l-3 { --n: 3; } .l-4 { --n: 4; } .l-5 { --n: 5; } .l-6 { --n: 6; }
.l-7 { --n: 7; } .l-8 { --n: 8; } .l-9 { --n: 9; } .l-10 { --n: 10; } .l-11 { --n: 11; } .l-12 { --n: 12; }
@media screen and (prefers-reduced-motion: no-preference) {
  .js .pied__logo:not(.est-visible) :is(.logo__lettre, .logo__mention, .logo__c, .logo__bourgeon) { opacity: 0; }
  .js .pied__logo.est-visible :is(.logo__c, .logo__bourgeon) { animation: pied-mono 600ms var(--sortie) both; }
  .js .pied__logo.est-visible .logo__lettre { animation: pied-lettre 600ms var(--sortie) calc(80ms + var(--n) * 40ms) both; }
  .js .pied__logo.est-visible .logo__mention { animation: pied-lettre 400ms var(--sortie) 680ms both; }
}
@keyframes pied-mono { from { opacity: 0; scale: .92; } to { opacity: 1; scale: 1; } }
@keyframes pied-lettre { from { opacity: 0; translate: 0 40%; } to { opacity: 1; translate: 0 0; } }

/* La porte d'âge (écran 0) : aplat sous-bois et semis, le monogramme qui se dessine. Le C se trace (1 200 ms),
   le bourgeon se pose à 900 ms (520 ms, --rebond), le texte monte en fondu entre les deux.
   Les aplats ne changent pas en Soir : le voile de la fenêtre C a exactement la couleur de la porte. */
.porte { position: fixed; inset: 0; z-index: 50; display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: 24px var(--gouttiere); overflow: hidden; background-color: var(--aplat-sousbois); color: var(--sur-aplat); text-align: center; --focus: var(--laiton-clair); }
.porte::before { content: ""; position: absolute; inset: 0; z-index: 1; background: url('/assets/marque/semis.svg') 0 0 / 96px 96px; pointer-events: none; transition: opacity 200ms var(--sortie); }
.porte__boite { position: relative; z-index: 2; width: min(100%, 34rem); display: grid; justify-items: center; transition: opacity 200ms var(--sortie); }
.porte__marque { width: 96px; height: 96px; margin-bottom: 32px; }
.porte__marque .mono { width: 100%; height: 100%; }
.porte h2 { font-size: var(--t-grand); line-height: 1; letter-spacing: -.015em; color: var(--sur-aplat); }
.porte p { margin: 18px 0 0; max-width: 30ch; font-size: var(--t-corps); line-height: 1.55; color: rgba(251, 248, 241, .8); }
.porte__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 36px; }
.porte .mono__bourgeon { animation: pose-porte 520ms var(--rebond) 900ms both; }
/* Le texte et les boutons arrivent vite (400 ms, pas de 60 ms) : le focus est posé sur « J'ai 18 ans ou plus » dès
   l'ouverture, le bouton doit être lisible presque aussitôt. Seul le bourgeon, décoratif, garde son retard. */
.porte__boite > :not(.porte__marque) { animation: porte-texte 400ms var(--sortie) both; }
.porte__boite > h2 { animation-delay: 60ms; }
.porte__boite > p { animation-delay: 120ms; }
.porte__boite > .porte__actions { animation-delay: 180ms; }
@keyframes pose-porte { from { opacity: 0; translate: 0 -18px; } to { opacity: 1; translate: 0 0; } }
@keyframes porte-texte { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: 0 0; } }
@media (max-width: 600px) {
  .porte__marque { width: 72px; height: 72px; margin-bottom: 28px; }
  .porte__actions { flex-direction: column; justify-self: stretch; gap: 10px; }
  .porte__actions .btn { width: 100%; min-height: 48px; }
}
/* Au « oui » : la boîte s'efface en 200 ms ; avec la fenêtre C, le fond devient transparent et le voile prend le relais. */
.porte--ouverte { pointer-events: none; }
.porte--ouverte .porte__boite, .porte--ouverte::before { opacity: 0; }
.porte--fenetre { background-color: transparent; }
.porte .mono__bourgeon.est-parti { opacity: 0; animation: none; }
/* Tant que la porte n'est pas posée (le script tourne une fois la page lue), la page ne se montre pas une image
   avant elle. Garde-fou : si le script ne tourne pas, ce voile d'attente s'efface seul au bout de 4 s, même en mouvement réduit. */
html.js:not(.majeur):not(.porte-posee) body::after { content: ""; position: fixed; inset: 0; z-index: 49; background: var(--aplat-sousbois); animation: attente 1ms linear 4s forwards; }
@keyframes attente { to { visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { html.js:not(.majeur):not(.porte-posee) body::after { animation-delay: 4s !important; } }

/* La fenêtre C : un voile percé du C, posé sur le monogramme, qui grandit (× 80) depuis le dos du C (20 % 50 %).
   On anime le chemin SVG, repeint net à chaque image, plutôt qu'un calque agrandi et flou. */
.fenetre-c { position: absolute; z-index: 0; pointer-events: none; }
.fenetre-c__svg { display: block; width: 100%; height: 100%; overflow: visible; }
.fenetre-c__voile { transform-box: view-box; transform-origin: 20% 50%; }

/* Le bourgeon en vol (geste 1) : un clone, au-dessus de tout, le temps du trajet. */
.bourgeon-vol { position: fixed; z-index: 60; pointer-events: none; }
.bourgeon-vol__axe, .bourgeon-vol__point { position: absolute; inset: 0; }
.bourgeon-vol__point { border-radius: 50%; background: var(--laiton-clair); }
/* Le bourgeon de l'en-tête attend le sien : masqué pendant la porte et pendant le vol. Sans JavaScript, il reste là. */
html.js:not(.majeur) .entete .logo__bourgeon, html.bourgeon-en-vol .entete .logo__bourgeon { opacity: 0; }

/* Pages d'état (Merci, Échec, et les pages de texte court). Merci : le monogramme en 96 px au-dessus du titre ; son anneau
   d'empreinte ne joue qu'au statut payee. Échec : le papier, aucune animation. */
.etat { max-width: 760px; margin: 0 auto; padding: clamp(56px, 8vh, 96px) 0 clamp(80px, 12vh, 136px); display: grid; gap: 20px; text-align: center; justify-items: center; }
.etat > * { margin: 0; }
.etat h1 { max-width: 12em; font-size: var(--t-grand); line-height: .98; letter-spacing: -.02em; }
.etat .chapo { max-width: 30em; text-wrap: balance; }
/* Les CGV en attente : les points qu'elles couvriront, sur une fiche ivoire au filet de laiton, numérotés en DM Mono. */
.cgv-points { width: 100%; max-width: 640px; margin-top: 12px; padding: 24px clamp(20px, 4vw, 36px) 12px; background: var(--ivoire); border-top: 2px solid var(--laiton); border-radius: 0 0 3px 3px; text-align: left; }
.cgv-points__titre { margin: 0 0 6px; color: var(--laiton-texte); }
.cgv-points__liste { list-style: none; margin: 0; padding: 0; counter-reset: point; }
.cgv-points__liste li { counter-increment: point; position: relative; padding: 14px 0 14px 2.6em; border-top: 1px dashed var(--trait); font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); text-wrap: pretty; }
.cgv-points__liste li:first-child { border-top: 0; }
.cgv-points__liste li::before { content: counter(point, decimal-leading-zero); position: absolute; left: 0; top: 14px; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 22px; letter-spacing: .08em; color: var(--laiton-texte); }
.cgv-points__liste strong { color: var(--encre); font-weight: 600; }
.cgv-points__liste a { color: var(--encre); text-underline-offset: 3px; }
/* Mentions légales : l'identité, puis « Vos données », trois cartes ivoire comme celles des CGV. */
.etat--mentions { padding-bottom: clamp(40px, 6vh, 64px); }
.vos-donnees { max-width: 760px; margin: 0 auto; padding: 0 0 clamp(80px, 12vh, 136px); display: grid; gap: 28px; justify-items: center; scroll-margin-top: calc(var(--haut-entete) + 24px); }
.vos-donnees__tete { display: grid; gap: 16px; justify-items: center; text-align: center; padding-top: 32px; border-top: 1px dashed var(--trait); width: 100%; }
.vos-donnees__tete > * { margin: 0; }
.vos-donnees__titre { max-width: 14em; font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; text-wrap: balance; }
.vos-donnees .chapo { max-width: 32em; text-wrap: pretty; }
.vos-donnees .cgv-points { margin-top: 0; }

/* Les conditions de vente (data/cgv.html, outils/pages.py cgv_corps()) : un texte long, lu d'une traite, en une colonne. */
.legal { max-width: 720px; margin: 0 auto; padding: clamp(48px, 7vh, 88px) 0 clamp(80px, 12vh, 136px); display: grid; gap: 40px; }
.legal > * { min-width: 0; }
.legal__tete { display: grid; gap: 16px; justify-items: center; text-align: center; }
.legal__tete > * { margin: 0; }
.legal__titre { max-width: 12em; font-size: var(--t-grand); line-height: .98; letter-spacing: -.02em; }
.legal__tete .chapo { max-width: 32em; text-wrap: pretty; }
.legal__version { color: var(--laiton-texte); }
.legal__sommaire { padding: 20px clamp(20px, 4vw, 32px); background: var(--ivoire); border-top: 2px solid var(--laiton); border-radius: 0 0 3px 3px; }
.legal__sommaire-titre { margin: 0 0 10px; color: var(--laiton-texte); }
.legal__sommaire ol { margin: 0; padding-left: 1.6em; columns: 2 220px; column-gap: 32px; font-size: var(--t-petit); line-height: 1.7; }
.legal__sommaire a { color: var(--encre); text-underline-offset: 3px; }
.legal__partie { display: grid; gap: 14px; padding-top: 28px; border-top: 1px dashed var(--trait); scroll-margin-top: calc(var(--haut-entete) + 24px); }
.legal__partie > * { margin: 0; }
.legal__h2 { display: flex; align-items: baseline; gap: 14px; font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; text-wrap: balance; }
.legal__numero { flex: none; color: var(--laiton-texte); }
.legal__h3 { margin: 10px 0 0; font-size: var(--t-corps); font-weight: 600; }
.legal__partie p, .legal__partie li { line-height: 1.6; color: var(--encre-douce); text-wrap: pretty; }
.legal__partie a { color: var(--encre); text-underline-offset: 3px; overflow-wrap: anywhere; }
.legal__liste, .legal__etapes { margin: 0; padding-left: 1.4em; display: grid; gap: 8px; }
.legal__encadre { display: grid; gap: 12px; padding: 20px clamp(18px, 4vw, 28px); background: var(--ivoire); border: 1px solid var(--trait); border-radius: 3px; font-size: var(--t-petit); }
.legal__encadre > * { margin: 0; }
.legal__encadre ol { padding-left: 1.4em; display: grid; gap: 6px; }
.legal__formulaire p { padding-bottom: 10px; border-bottom: 1px dotted var(--trait); }
.legal__formulaire p:first-child, .legal__formulaire p:nth-child(2) { border-bottom: 0; }
@media print {
  .legal__sommaire { display: none; }
  .legal__partie { break-inside: avoid-page; }
}
.etat__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 32px; margin-top: 16px; }
.etat--merci, .etat--echec { min-height: calc(100svh - var(--haut-demo) - var(--haut-entete) - 40px); align-content: center; }
.etat__marque { margin-bottom: 12px; }
.etat__marque .mono { width: 96px; height: 96px; }
@media (max-width: 599px) {
  .etat__actions { flex-direction: column; align-self: stretch; }
  .etat__actions .btn { width: 100%; min-height: 48px; }
}
/* Le ticket de la commande, sur Merci : le même papier perforé que le ticket du panier. */
.ticket-caisse { width: min(440px, 100%); margin-top: 12px; filter: var(--ombre-ticket); }
.ticket-caisse__papier { margin: 0; padding: 14px 24px 26px; background: var(--ivoire); border-radius: 3px 3px 0 0; text-align: left; }
.ticket-caisse__papier > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 12px 0; border-top: 1px dashed var(--trait); }
.ticket-caisse__papier > div:first-child { border-top: 0; }
.ticket-caisse dt { flex: none; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.ticket-caisse dd { margin: 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; text-align: right; color: var(--encre); font-variant-numeric: tabular-nums; }
@media screen and (prefers-reduced-motion: no-preference) {
  .etat .est-change { animation: etat-change 420ms var(--sortie) both; }
  .etat .chapo.est-change { animation-delay: 60ms; }
  .ticket-caisse:not([hidden]) { animation: etat-change 520ms var(--sortie) 160ms both; }
}
@keyframes etat-change { from { opacity: 0; translate: 0 8px; } }

/* Le lien de l'email du Bulletin (/bulletin/confirmer) : le cachet de cire de l'encart scelle la page, un seul état
   visible à la fois (le serveur choisit). Le cachet se pose une fois, comme dans l'encart ; en mouvement réduit, il est là. */
.etat--bulletin { min-height: calc(100svh - var(--haut-demo) - var(--haut-entete) - 40px); align-content: center; }
.etat__variante { display: grid; gap: 20px; justify-items: center; }
.etat__variante > * { margin: 0; }
.etat__cachet { margin-bottom: 4px; }
.etat__cachet .cachet { width: clamp(96px, 9vw, 120px); }
.etat__note { font-size: var(--t-petit); color: var(--encre-douce); }
@media screen and (prefers-reduced-motion: no-preference) {
  .etat--bulletin .cachet { animation: cachet 420ms var(--rebond) 120ms both; }
}

/* La boîte d'envoi de démonstration (/dev/emails, jamais en production) : chaque email est un ticket ivoire, l'en-tête en
   DM Mono sur des pointillés, le sujet en Gloock sous un filet d'encre, le texte tel qu'il partirait, ses liens cliquables. */
.boite { max-width: 760px; margin: 0 auto; padding: clamp(48px, 7vh, 88px) 0 clamp(80px, 12vh, 136px); }
.boite__tete { display: grid; gap: 16px; margin-bottom: clamp(32px, 5vw, 56px); }
.boite__tete > * { margin: 0; }
.boite__tete h1 { font-size: var(--t-grand); line-height: .98; }
.boite__alerte { padding: 12px 16px; border-left: 2px solid var(--laiton); background: var(--lin); font-size: var(--t-petit); }
.boite__vide { margin: 0; padding: 28px; border: 1px dashed var(--trait); border-radius: var(--r-controle); color: var(--encre-douce); text-align: center; }
.boite__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 40px; }
.boite__email { filter: var(--ombre-ticket); min-width: 0; }
.boite__papier { display: grid; gap: 18px; padding: 22px clamp(20px, 4vw, 32px) 34px; background: var(--ivoire); border-top: 2px solid var(--laiton); border-radius: 3px 3px 0 0; }
.boite__entete { margin: 0; display: grid; }
.boite__entete > div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 10px 0; border-top: 1px dashed var(--trait); }
.boite__entete > div:first-child { border-top: 0; padding-top: 0; }
.boite__entete dt { flex: none; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.boite__entete dd { min-width: 0; margin: 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; text-align: right; overflow-wrap: anywhere; color: var(--encre); font-variant-numeric: tabular-nums; }
.boite__sujet { min-width: 0; overflow-wrap: anywhere; padding-top: 18px; border-top: 1px solid var(--encre); font-size: var(--t-h3); line-height: 1.15; }
.boite__texte { display: grid; gap: 12px; min-width: 0; overflow-wrap: anywhere; font-size: var(--t-corps); line-height: 1.55; color: var(--encre); }
.boite__texte p { margin: 0; }
.boite__texte p:first-child { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; color: var(--laiton-texte); }
.boite__texte p:last-child { font-size: var(--t-mini); color: var(--encre-douce); }
.boite__lien { color: var(--laiton-texte); overflow-wrap: anywhere; text-underline-offset: 3px; }
.boite__apercu { margin: 0; padding-top: 14px; border-top: 1px dashed var(--laiton); }
/* Les modèles de la boîte d'envoi : un exemple de chaque type d'email, une ligne par modèle, deux liens à droite. */
.modeles { display: grid; gap: 16px; margin-bottom: clamp(48px, 7vw, 72px); }
.modeles > h2, .boite__envoyes { margin: 0; font-size: var(--t-h3); line-height: 1.15; }
.boite__envoyes { margin-bottom: 24px; }
.modeles__aide { margin: 0; color: var(--encre-douce); font-size: var(--t-petit); }
.modeles__liste { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--encre); }
.modeles__ligne { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 24px; padding: 10px 0; border-bottom: 1px dashed var(--trait); min-width: 0; }
.modeles__nom { display: grid; gap: 2px; margin: 0; min-width: 0; flex: 1 1 18rem; overflow-wrap: anywhere; }
.modeles__groupe { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-texte); }
.modeles__liens { display: flex; flex-wrap: wrap; gap: 0 20px; margin: 0; }

/* Votre espace (/compte). Deux états : la connexion (le texte à gauche, le ticket ivoire perforé du panier à droite, qui
   porte les deux étapes), puis l'espace, ouvert par la carte du Carnet (brandbook, CarteCarnet : aplat sous-bois et semis,
   chiffres en laiton clair) et suivi de cinq chapitres numérotés, le titre à gauche et le contenu à droite sur ordinateur. */
.compte { padding: clamp(40px, 7vh, 88px) 0 clamp(80px, 12vh, 136px); }
.compte__attente { min-height: 40svh; display: grid; place-items: center; margin: 0; }

.connexion { display: grid; grid-template-columns: minmax(0, 1fr); gap: 48px; }
@media (min-width: 900px) {
  .connexion { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: clamp(48px, 7vw, 112px); align-items: start; min-height: calc(100svh - var(--haut-demo) - var(--haut-entete) - 260px); }
}
.connexion__texte { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-content: start; }
.connexion__texte > * { margin: 0; }
.connexion__titre { max-width: 8em; font-size: var(--t-h2); line-height: .92; letter-spacing: -.02em; }
.connexion__texte .chapo { max-width: 24em; }
.connexion__liste { list-style: none; margin: 8px 0 0; padding: 0; max-width: 30em; border-top: 1px solid var(--encre); }
.connexion__liste li { display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--trait); font-size: var(--t-corps); }
.connexion__liste .etiquette { color: var(--laiton-texte); }
/* Finition, tour 3 : sur téléphone, l'action d'abord. Le ticket (l'adresse email et « Recevoir un code ») passe avant
   la liste des quatre points, et tient dans le premier écran de 844 px. Le DOM ne change pas : au clavier et au lecteur
   d'écran, le titre et la phrase restent lus avant le formulaire. */
@media (max-width: 899px) {
  .connexion { gap: 0; }
  .connexion__texte { display: contents; }
  .connexion__texte > .surtitre { margin-bottom: 10px; }
  .connexion__titre { font-size: var(--t-grand); }
  .connexion__texte .chapo { margin-top: 14px; font-size: var(--t-corps); }
  .connexion__ticket { order: 1; margin-top: 24px; }
  .connexion__liste { order: 2; margin-top: 40px; }
  .connexion__papier { gap: 16px; padding: 20px 20px 32px; }
}
.connexion__ticket { filter: var(--ombre-ticket); }
@media (min-width: 900px) { .connexion__ticket { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 24px); } }
.connexion__papier { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; padding: 26px 28px 40px; background: var(--ivoire); border-radius: 3px 3px 0 0; }
.connexion__entete { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding-bottom: 14px; border-bottom: 1px solid var(--encre); }
.connexion__entete > * { margin: 0; }
.connexion__maison { color: var(--laiton-texte); }
.connexion__etape { color: var(--encre-douce); }
.connexion__form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.connexion__form > * { margin: 0; }
.connexion__sous-titre { font-size: var(--t-h3); line-height: 1.1; }
.connexion__bouton { min-height: 52px; font-size: var(--t-corps); }
.connexion__note, .connexion__envoi { font-size: var(--t-petit); line-height: 21px; color: var(--encre-douce); }
.connexion__adresse { color: var(--encre); font-weight: 600; overflow-wrap: anywhere; }
.connexion__autres { display: flex; flex-wrap: wrap; gap: 0 24px; }
/* Le code : six chiffres en DM Mono, espacés comme sur un ticket, centrés (le retrait à gauche compense l'approche). */
.champ--code { grid-template-columns: minmax(0, 1fr); }
.champ--code input { width: 100%; min-width: 0; min-height: 64px; padding-left: calc(14px + .42em); font-family: var(--font-etiquette); font-size: 30px; letter-spacing: .42em; text-align: center; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: no-preference) {
  .connexion__form:not([hidden]) { animation: etat-change 420ms var(--sortie) both; }
}

.espace { display: grid; grid-template-columns: minmax(0, 1fr); }
.espace__tete { display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; padding-bottom: clamp(48px, 7vw, 96px); }
@media (min-width: 900px) { .espace__tete { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(48px, 6vw, 96px); align-items: end; } }
.espace__accueil { display: grid; gap: 20px; align-content: end; }
.espace__accueil > * { margin: 0; }
.espace__titre { font-size: var(--t-affiche); line-height: .92; letter-spacing: -.02em; overflow-wrap: anywhere; }
.espace__sommaire { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.espace__sommaire a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border: 1px solid var(--trait); border-radius: 999px; font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; text-decoration: none; transition: border-color 160ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .espace__sommaire a:hover { border-color: var(--encre); } }

/* La carte du Carnet : au format d'une carte (1,586), sans jamais rogner son contenu (aucun overflow posé). */
.carnet { position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: 20px; width: 100%; max-width: 500px; aspect-ratio: 1.586; padding: clamp(20px, 2.4vw, 28px); border: 1px solid rgba(201, 164, 94, .28); border-radius: var(--r-carte); background-color: var(--aplat-sousbois); color: var(--sur-aplat); box-shadow: 0 1px 2px rgba(12, 20, 14, .2), 0 22px 44px rgba(12, 20, 14, .2); --focus: var(--laiton-clair); }
@media (min-width: 900px) { .carnet { --incline: -1.5deg; justify-self: end; rotate: var(--incline); } }
/* Elle se pose une fois, à l'ouverture de l'espace : de -6° et 16 px plus bas à son inclinaison (420 ms, --rebond). */
@media screen and (prefers-reduced-motion: no-preference) {
  .carnet { animation: carnet-pose 420ms var(--rebond) 120ms both; }
  .compte .message--ok::before { animation: coche 180ms var(--sortie) both; }
}
@keyframes carnet-pose { from { rotate: -6deg; translate: 0 16px; opacity: 0; } 35% { opacity: 1; } to { rotate: var(--incline, 0deg); translate: 0 0; opacity: 1; } }
/* « Enregistré » : une coche de laiton devant le message (180 ms), dans l'espace et à la connexion. */
.compte .message--ok::before { content: ""; display: inline-block; width: 11px; height: 6px; margin: 0 10px 0 2px; border-left: 2px solid var(--laiton); border-bottom: 2px solid var(--laiton); rotate: -45deg; translate: 0 -3px; }
@keyframes coche { from { scale: .5; opacity: 0; } to { scale: 1; opacity: 1; } }
.carnet > * { margin: 0; }
.carnet__haut { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.carnet__marque .mono { display: block; width: 40px; height: 40px; }
.carnet__nom { margin: 0; padding: 4px 10px; border: 1px solid var(--laiton-clair); border-radius: var(--r-etiquette); font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .16em; text-transform: uppercase; color: var(--laiton-clair); }
.carnet__milieu { display: grid; gap: 8px; }
.carnet__milieu > * { margin: 0; }
.carnet__points { display: flex; align-items: baseline; gap: 10px; }
.carnet__chiffre { font-family: var(--font-titre); font-size: var(--t-grand); line-height: .9; letter-spacing: -.02em; color: var(--laiton-clair); font-variant-numeric: tabular-nums; }
.carnet__unite { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .14em; text-transform: uppercase; color: var(--laiton-clair); }
.carnet__palier { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1; color: var(--laiton-clair); }
.carnet__annonce { max-width: 15em; font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.12; color: var(--sur-aplat); text-wrap: balance; }
.carnet__bas { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 0; padding-top: 14px; border-top: 1px solid rgba(251, 248, 241, .18); }
.carnet__bas dt { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 14px; letter-spacing: .12em; text-transform: uppercase; color: rgba(251, 248, 241, .7); }
.carnet__bas dd { margin: 4px 0 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; color: var(--sur-aplat); overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.carnet__bas .carnet__montant { color: var(--laiton-clair); }

.espace__bloc { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; padding: 40px 0 48px; border-top: 1px solid var(--encre); scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 16px); }
@media (min-width: 900px) { .espace__bloc { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); column-gap: clamp(48px, 6vw, 96px); padding: 56px 0 72px; } }
.espace__repere { display: grid; gap: 12px; align-content: start; }
.espace__repere > * { margin: 0; }
@media (min-width: 900px) { .espace__repere { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 32px); } }
.espace__numero { color: var(--laiton-texte); }
.espace__sous-titre { font-size: var(--t-titre); line-height: 1; letter-spacing: -.015em; }
.espace__note { max-width: 24em; font-size: var(--t-petit); line-height: 23px; color: var(--encre-douce); }
.espace__contenu { display: grid; gap: 20px; align-content: start; justify-items: start; min-width: 0; }
.espace__contenu > * { margin: 0; }
.espace__contenu > ol, .espace__contenu > ul, .espace__contenu > form, .espace__contenu > .donnees, .espace__contenu > .espace__vide { justify-self: stretch; }
.espace__vide { display: grid; gap: 8px; justify-items: start; padding: 24px; border: 1px dashed var(--trait); border-radius: var(--r-controle); color: var(--encre-douce); }
.espace__vide p { margin: 0; max-width: 34em; }
.espace__vide--ligne { padding: 16px 20px; }
.espace__petit { font-size: var(--t-mini); line-height: 20px; color: var(--encre-douce); max-width: 40em; }

/* Les commandes : chacune son ticket, comme au panier. Les lignes reprennent le pointillé du ticket (.recap__ligne). */
.commandes { list-style: none; padding: 0; display: grid; gap: 24px; }
.commande { filter: var(--ombre-ticket); min-width: 0; }
.commande__papier { display: grid; gap: 4px; padding: 18px clamp(18px, 3vw, 26px) 30px; background: var(--ivoire); border-radius: 3px 3px 0 0; font-variant-numeric: tabular-nums; }
.commande__tete { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 16px; padding-bottom: 12px; border-bottom: 1px solid var(--encre); }
.commande__tete > * { margin: 0; }
.commande__reference { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-petit); line-height: 20px; letter-spacing: .1em; text-transform: uppercase; }
.commande__lignes { list-style: none; margin: 0; padding: 4px 0; }
.commande__faits { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 14px 16px; margin: 0; padding-top: 14px; border-top: 1px dashed var(--trait); }
.commande__faits dt { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.commande__faits dd { margin: 4px 0 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 18px; color: var(--encre); }
.commande__faits .commande__total dd { font-size: var(--t-h3); line-height: 1; letter-spacing: -.03em; }
.statut { display: inline-flex; align-items: center; gap: 8px; padding: 5px 11px; border: 1px solid currentColor; border-radius: 999px; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 14px; letter-spacing: .12em; text-transform: uppercase; }
.statut::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.statut--payee { color: var(--mousse); }
.statut--attente { color: var(--laiton-texte); }
.statut--anomalie { color: var(--rouille); }
.statut--fini { color: var(--encre-douce); }
.commande__adresse { grid-column: 1 / -1; }
.commande__adresse dd { overflow-wrap: anywhere; }
/* « Commander à nouveau » : sous les faits, séparé par le pointillé du ticket. Les formats qui ne sont plus en vente sont
   nommés, chacun avec son lien pour être prévenu de son retour. */
.commande__reprise { display: grid; gap: 10px; justify-items: start; margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--trait); }
.commande__reprise-retour { display: grid; gap: 6px; }
.commande__reprise-retour:empty { display: none; }
.commande__reprise-retour .message { text-wrap: pretty; }
.commande__indisponibles { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; font-size: var(--t-petit); line-height: 20px; color: var(--encre-douce); }
.commande__indisponibles .lien-laiton { font-size: var(--t-petit); }
/* Les pièces d'une commande (lot 1c) : factures, avoirs, récapitulatif accepté, puis « Renoncer au contrat ici » tant que
   le délai court. Sous les faits, séparées par le pointillé du ticket. */
.commande__pieces { display: grid; gap: 12px; justify-items: start; margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--trait); }
.commande__documents { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0; }
.commande__documents .lien-laiton { display: inline-flex; align-items: center; min-height: 44px; font-size: var(--t-petit); overflow-wrap: anywhere; }
.commande__retractation { display: grid; gap: 10px; justify-items: start; }
.commande__retractation p { margin: 0; font-size: var(--t-petit); line-height: 20px; color: var(--encre-douce); text-wrap: pretty; }

/* Les adresses : des étiquettes ivoire, le destinataire en Gloock. Le formulaire, sous un filet de laiton. */
.adresses { list-style: none; padding: 0; display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 248px), 1fr)); }
.adresse { display: grid; gap: 12px; align-content: space-between; padding: 18px 20px 12px; background: var(--ivoire); border: 1px solid var(--trait); border-radius: var(--r-etiquette); }
.adresse address { font-style: normal; display: grid; gap: 2px; color: var(--encre-douce); overflow-wrap: anywhere; }
.adresse__nom { font-family: var(--font-titre); font-size: var(--t-chapo); line-height: 1.15; color: var(--encre); }
.adresse__actions { display: flex; flex-wrap: wrap; gap: 0 20px; border-top: 1px dashed var(--trait); }
.adresse-form { display: grid; gap: 16px; max-width: 560px; padding: 22px clamp(18px, 3vw, 26px) 24px; background: var(--ivoire); border-top: 2px solid var(--laiton); border-radius: 0 0 3px 3px; }
.adresse-form > * { margin: 0; }
.adresse-form__titre { font-size: var(--t-h3); line-height: 1.15; }
.adresse-form__ville { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 5fr); gap: 12px; }
.adresse-form__actions, .coordonnees-form__actions, .suppression__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; }

.coordonnees-form { display: grid; gap: 16px; max-width: 520px; }
.coordonnees-form > * { margin: 0; }
.coordonnees-form__email { display: grid; gap: 4px; padding-bottom: 14px; border-bottom: 1px dashed var(--trait); overflow-wrap: anywhere; }
.coordonnees-form__email .etiquette { color: var(--encre-douce); }

/* Les accords : un interrupteur par canal. Accordé, la piste passe au sous-bois et le bourgeon de laiton glisse à droite. */
.accords { list-style: none; padding: 0; border-top: 1px solid var(--trait); }
.accord { display: grid; gap: 4px; padding: 16px 0 18px; border-bottom: 1px solid var(--trait); }
.accord > * { margin: 0; }
.interrupteur { display: flex; align-items: center; gap: 16px; min-height: 44px; font-size: var(--t-corps); line-height: 22px; color: var(--encre); cursor: pointer; }
.interrupteur input { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 50px; height: 30px; margin: 0; border: 1.5px solid var(--encre-douce); border-radius: 999px; background: var(--ivoire); cursor: pointer; transition: background-color var(--d-court) var(--sortie), border-color var(--d-court) var(--sortie); }
.interrupteur input::after { content: ""; position: absolute; top: 4px; left: 4px; width: 19px; height: 19px; border-radius: 50%; background: var(--encre-douce); transition: translate 260ms var(--rebond), background-color var(--d-court) var(--sortie); }
.interrupteur input:checked { background: var(--sousbois); border-color: var(--sousbois); }
.interrupteur input:checked::after { translate: 20px 0; background: var(--laiton-clair); }
.interrupteur input:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.interrupteur input:disabled { opacity: .55; cursor: progress; }
.accord__date { padding-left: 66px; color: var(--encre-douce); }

.donnees { display: grid; border-top: 1px solid var(--trait); }
.donnees__ligne { display: grid; gap: 12px; justify-items: start; padding: 22px 0 26px; border-bottom: 1px solid var(--trait); }
.donnees__ligne > * { margin: 0; }
.donnees__ligne p { max-width: 34em; color: var(--encre-douce); }
.donnees__titre { font-size: var(--t-h3); line-height: 1.15; }
.donnees__ligne--sortie { border-bottom: 0; }
/* La suppression : la rouille, réservée aux erreurs et aux gestes sans retour ; jamais un rouge vif. */
.btn--sobre-rouille { background: transparent; color: var(--rouille); border-color: currentColor; }
@media (hover: hover) and (pointer: fine) { .btn--sobre-rouille:hover { background: var(--lin); } }
.btn--rouille { background: var(--rouille); color: var(--ivoire); }
.suppression { display: grid; gap: 12px; justify-self: stretch; padding: 16px 18px; border-left: 2px solid var(--rouille); background: var(--lin); }
.suppression > * { margin: 0; }
.suppression__titre { font-weight: 600; color: var(--encre); }

/* L'en-tête : « Votre espace » à la même encre que les autres entrées (grisé, il passait pour inactif). La page où l'on
   est porte aria-current="page" (outils/pages.py) : un filet de laiton de 1,5 px sous son libellé, ou sous l'icône. */
.entete nav a { position: relative; }
.entete nav a[aria-current="page"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 1.5px; border-radius: 1px; background: var(--laiton); }
@media (max-width: 600px) {
  .entete nav .entete__compte { justify-content: center; min-width: 44px; }
  .entete nav :is(.entete__compte, .entete__boutique)[aria-current="page"]::after { left: 12px; right: 12px; bottom: 6px; }
}

/* Utilitaires */
.espace-haut { margin-top: 8px; }
.sans-marge { margin: 0; }
.petit { font-size: var(--t-mini); line-height: 20px; }

/* Ajustements après relecture visuelle */
.carte__corps .pastille { justify-self: start; }
.entete nav a { white-space: nowrap; }
/* Sur téléphone, « Le comptoir » devient une épingle et le thème une lune (ou un soleil), chacun dans 44 × 44 px :
   la navigation garde ses quatre entrées sans que le thème pèse autant qu'elles. Les libellés restent lus. */
@media (max-width: 600px) {
  .entete__interieur { padding-top: 10px; padding-bottom: 10px; }
  .entete nav { gap: 6px; }
  .entete nav .entete__boutique { justify-content: center; min-width: 44px; }
  .entete__icone, .bascule-theme__icone { display: block; }
  .entete__libelle, .bascule-theme__texte { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .bascule-theme { width: 44px; min-width: 44px; padding: 0; border-color: transparent; }
  .entete nav a[href="/panier"] { padding-left: 6px; }
}
@media (max-width: 600px) { .carte__corps { padding-top: 14px; } .carte h3 { font-size: var(--t-h3); line-height: 28px; } }

/* Bande de réassurance, immobile (finition, tour 3) : une ligne en DM Mono, centrée, des points de laiton entre les
   phrases. Sur téléphone, elle passe à la ligne, toujours centrée.
   Dernier bloc de la fiche (« De la même famille » masquée) : le pied la suit sans bande de papier vide. */
.page:has(> .defile + .parente[hidden]:last-child) + .pied { margin-top: 0; }
.defile { margin: 0 calc(50% - 50vw); padding: 0 var(--gouttiere); background: var(--ivoire); border-block: 1px solid var(--trait); }
.defile__liste { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 0; max-width: 1280px; margin: 0 auto; padding: 14px 0; list-style: none; }
.defile__liste li { display: flex; align-items: center; white-space: nowrap; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .14em; text-transform: uppercase; color: var(--encre); }
.defile__liste li + li::before { content: ""; width: 5px; height: 5px; margin: 0 22px; border-radius: 50%; background: var(--laiton); }
.defile__liste li[hidden] { display: none; }
/* Sur téléphone : une phrase par ligne, centrée, chaque ligne ouverte par son point de laiton. */
@media (max-width: 599px) {
  .defile__liste { flex-direction: column; gap: 8px; padding: 16px 0; }
  .defile__liste li::before { content: ""; width: 5px; height: 5px; margin: 0 10px 0 0; border-radius: 50%; background: var(--laiton); }
  .defile__liste li + li::before { margin: 0 10px 0 0; }
}

/* Le comptoir. Un bandeau sous-bois et semis, pleine largeur : le titre en ivoire à gauche, l'adresse en plaque à droite.
   Le texte tombe au pixel sur la gouttière (padding-inline: calc(50vw - 50%)). Dessous, sur le papier : le retrait,
   expliqué ici et nulle part ailleurs en détail, le plan, puis les villes voisines.
   Lot 12 : l'image laiton-brosse (21:9) se branche en premier enfant de .lieu, en fond (.lieu__fond). */
.lieu { position: relative; display: grid; gap: 48px; margin-inline: calc(50% - 50vw); padding: 64px calc(50vw - 50%) 72px; background-color: var(--aplat-sousbois); color: var(--sur-aplat); border-top: 1px solid rgba(201, 164, 94, .2); overflow: hidden; overflow: clip; --focus: var(--laiton-clair); }
@media (min-width: 900px) { .lieu { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); column-gap: clamp(48px, 7vw, 112px); align-items: end; min-height: min(72svh, 680px); padding-block: 104px 96px; } }
.lieu__fond { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.lieu > :not(.lieu__fond) { position: relative; }
.lieu__texte { display: grid; gap: 24px; align-content: end; }
.lieu__texte > * { margin: 0; }
.lieu .surtitre { color: var(--laiton-clair); }
.lieu h1 { max-width: 9em; font-size: var(--t-grand); line-height: .95; letter-spacing: -.02em; color: var(--sur-aplat); }
.lieu .chapo { max-width: 26em; color: rgba(251, 248, 241, .84); }
.lieu .accueil__actions { margin-top: 12px; }
.lieu .accueil__actions .btn { min-height: 52px; padding-inline: 28px; }
@media (max-width: 599px) {
  .lieu .accueil__actions { flex-direction: column; gap: 10px; }
  .lieu .accueil__actions .btn { width: 100%; }
}
/* La plaque : le numéro en grand, en laiton clair, comme gravé ; la rue en Gloock, la ville en étiquette. */
.plaque { font-style: normal; display: grid; justify-items: start; align-self: end; padding: 28px 28px 30px; border: 1px solid rgba(201, 164, 94, .55); border-radius: 2px; outline: 1px solid rgba(201, 164, 94, .24); outline-offset: -9px; }
.plaque > span { display: block; }
.plaque__nom, .plaque__ville { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); line-height: 1.3; letter-spacing: .14em; text-transform: uppercase; }
.plaque__nom { color: var(--laiton-clair); }
.plaque__numero { margin-top: 28px; font-family: var(--font-titre); font-size: var(--t-affiche); line-height: .78; letter-spacing: -.03em; color: var(--laiton-clair); }
.plaque__voie { margin-top: 20px; font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; color: var(--sur-aplat); }
.plaque__ville { align-self: stretch; margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(251, 248, 241, .18); color: rgba(251, 248, 241, .8); }

.retrait { display: grid; gap: 48px; padding: 80px 0 24px; }
/* Sur ordinateur, les trois étapes en colonnes, puis le plan redessiné sur toute la largeur : ses noms de communes
   restent lisibles (à 640 px de large, ils tombaient sous 7 px). */
@media (min-width: 900px) {
  .retrait { padding-top: 112px; }
  .retrait__etapes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: clamp(32px, 4vw, 56px); }
}
.retrait h2 { font-size: var(--t-titre); line-height: 1; letter-spacing: -.015em; }
.retrait__etapes { list-style: none; margin: 32px 0 0; padding: 0; counter-reset: etape; border-top: 1px solid var(--encre); }
.retrait__etapes li { counter-increment: etape; display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: 12px; padding: 22px 0 24px; border-bottom: 1px solid var(--trait); }
.retrait__etapes li::before { content: counter(etape, decimal-leading-zero); grid-row: 1 / span 2; padding-top: 7px; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 1; letter-spacing: .12em; color: var(--laiton-texte); }
.retrait__etapes h3 { font-size: var(--t-h3); line-height: 1.15; letter-spacing: -.005em; }
.retrait__etapes p { margin: 6px 0 0; color: var(--encre-douce); }
.retrait__infos:has(> *) { display: grid; gap: 12px; margin-top: 32px; }
/* Le plan du quartier, redessiné d'après OpenStreetMap (assets/marque/plan-quartier-*.svg, plan confiance et image, E1) :
   déjà dans la palette, aucun filtre. Le plan papier en Jour, le plan sous-bois en Soir, la version rognée sous 600 px.
   Jamais d'object-fit: cover : il rognerait la mention « © contributeurs OpenStreetMap », dessinée en bas à droite. */
.lieu__plan { margin: 0; display: grid; gap: 10px; align-content: start; }
.lieu__plan img { display: block; width: 100%; height: auto; border-radius: var(--r-etiquette); border: 1px solid var(--trait); }
.plan { display: block; }
.plan--soir { display: none; }
:root[data-theme="soir"] .plan--jour { display: none; }
:root[data-theme="soir"] .plan--soir { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="jour"]) .plan--jour { display: none; }
  :root:not([data-theme="jour"]) .plan--soir { display: block; }
}
.lieu__credit { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .02em; color: var(--encre-douce); }

.villes { padding: 80px 0 56px; }
.acces { list-style: none; margin: 32px 0 0; padding: 0; display: grid; border-top: 1px solid var(--encre); }
@media (min-width: 720px) { .acces { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(32px, 6vw, 96px); } }
.acces__ville { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 20px 0 14px; border-bottom: 1px solid var(--trait); }
.acces__ville h3 { font-size: var(--t-h3); line-height: 1.15; }
.acces__texte { margin: 0; color: var(--encre-douce); }
.horaires { border-collapse: collapse; font-size: var(--t-petit); }
.horaires th { text-align: left; font-weight: 600; padding: 6px 24px 6px 0; }
.horaires td { padding: 6px 0; color: var(--encre-douce); }

/* Bouton d'appel flottant */
.appel { position: fixed; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 30; min-height: 48px; padding: 0 20px; display: inline-flex; align-items: center; border-radius: 999px; background: var(--action); color: var(--sur-action); font-weight: 600; text-decoration: none; box-shadow: var(--ombre-carte); }

/* Révélations. Un seul observateur (app.js) pose .est-visible sur [data-reveler] une fois, quand le bloc entre à l'écran.
   Seuls ses enfants .revele (ou le bloc lui-même s'il porte .revele) montent de 24 px en fondu ; .delai-1 à .delai-6 les décalent.
   Sans JavaScript, à l'impression ou en mouvement réduit, rien n'est jamais caché. */
.delai-1 { --delai: calc(var(--pas-delai) * 1); }
.delai-2 { --delai: calc(var(--pas-delai) * 2); }
.delai-3 { --delai: calc(var(--pas-delai) * 3); }
.delai-4 { --delai: calc(var(--pas-delai) * 4); }
.delai-5 { --delai: calc(var(--pas-delai) * 5); }
.delai-6 { --delai: calc(var(--pas-delai) * 6); }
@media screen and (prefers-reduced-motion: no-preference) {
  .js .revele { transition: opacity var(--d-long) var(--sortie) var(--delai, 0ms), translate var(--d-long) var(--sortie) var(--delai, 0ms); }
  .js [data-reveler]:not(.est-visible) .revele, .js .revele[data-reveler]:not(.est-visible) { opacity: 0; translate: 0 24px; transition: none; }
}

/* Mouvement réduit : rien ne bouge tout seul, rien ne glisse. Toute animation et toute transition se posent aussitôt sur leur état final.
   Exception : le bandeau d'offre (un seul message, jamais de rotation). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *:not(.bandeau-offre__message), ::before, ::after {
    animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important; transition-delay: 0s !important; animation-timeline: auto !important;
  }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
/* Le bloc global ci-dessus pose déjà toute transition à 1 ms : seul l'écrasement au clic est à retirer ici. */
@media (prefers-reduced-motion: reduce) {
  .carte:hover, .btn:active { transform: none; }
}

/* ── Finition, tour 2 ───────────────────────────────────────────────────────────────────────────────────────────── */

/* L'étiquette spécimen en petit : l'objet signature, à la place de ce qui manque. En DM Mono, sur l'ivoire de l'étiquette
   de lot, avec son filet de laiton intérieur. Deux usages : à la place d'une photo sans détourage propre (posée debout sur
   le filet, avec l'ombre au sol des produits), et à la place des formats d'un lot qui attend son retour. */
.etiquette-mini {
  position: relative; display: grid; gap: 8px; margin: 4px 0 0; padding: 14px 16px 12px; background: var(--ivoire); color: var(--encre);
  border: 1px solid var(--trait); border-radius: var(--r-etiquette); outline: 1px solid var(--laiton); outline-offset: -6px; box-shadow: var(--ombre-carte);
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; font-variant-numeric: tabular-nums;
}
.etiquette-mini > * { margin: 0; }
.etiquette-mini__maison { color: var(--laiton-texte); text-align: center; font-size: var(--t-mini); }
.etiquette-mini__statut { text-align: center; color: var(--encre); }
.etiquette-mini__nom { font-family: var(--font-titre); font-weight: 400; font-size: 26px; line-height: 1; letter-spacing: -.01em; text-transform: none; text-align: center; text-wrap: balance; }
.etiquette-mini__lignes { margin: 0; display: grid; }
.etiquette-mini__lignes > div { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0 5px; border-top: 1px dashed var(--trait); }
.etiquette-mini dt { color: var(--encre-douce); }
.etiquette-mini dd { margin: 0; color: var(--laiton-texte); text-align: right; }
.etiquette-mini__pied { padding-top: 7px; border-top: 1px solid var(--encre); color: var(--encre-douce); font-size: var(--t-mini); letter-spacing: .08em; text-transform: none; text-align: center; }
/* À la place de la photo : debout sur le filet, centrée, de biais comme les étiquettes de la maison. */
.carte__visuel--etiquette { --l: 72%; --g: 14%; }
/* L'étiquette reste dans le flux de sa case : le 4/3 n'est plus qu'un minimum (min-height: auto), une étiquette plus haute
   agrandit la case au lieu d'être rognée par le rayon qui défile. Le nom tient en deux lignes au plus (titre complet en title). */
.carte__visuel--etiquette { display: flex; align-items: flex-end; justify-content: center; padding: 16px 0 10px; box-sizing: border-box; }
.carte__visuel--etiquette .etiquette-mini { position: relative; left: auto; bottom: auto; max-width: 260px; }
.etiquette-mini--visuel .etiquette-mini__nom { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.etiquette-mini--visuel { position: absolute; z-index: 1; left: var(--g); bottom: 10px; width: var(--l); box-sizing: border-box; rotate: -1.5deg; transform-origin: 50% 100%; transition: transform 300ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .carte:hover .etiquette-mini--visuel { transform: translateY(-6px) rotate(1deg); } }
@media screen and (prefers-reduced-motion: no-preference) {
  .js .etagere:not(.est-visible) .etiquette-mini--visuel, .js .rayon:not(.est-visible) .etiquette-mini--visuel { opacity: 0; }
  .js .etagere.est-visible .etiquette-mini--visuel { animation: etagere-pose 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 90ms) backwards; }
  .js .rayon.est-visible .etiquette-mini--visuel { animation: etagere-pose 700ms cubic-bezier(.34, 1.3, .64, 1) calc(var(--rang, 0) * 70ms) backwards; }
  .rayon.est-posee .etiquette-mini--visuel { animation: none; }
}
/* Sur la fiche : l'étiquette en grand, au milieu de la scène du lin. */
.fiche__visuel--etiquette { --l: min(78vw, 340px); align-self: center; margin: 24px auto 88px; line-height: normal; }
.fiche__visuel--etiquette .etiquette-mini { position: static; translate: none; width: 100%; box-sizing: border-box; padding: 24px 24px 18px; gap: 12px; rotate: -1.5deg; box-shadow: 0 1px 2px rgba(31, 42, 34, .08), 0 28px 56px rgba(31, 42, 34, .16); }
.fiche__visuel--etiquette .etiquette-mini__nom { font-size: 40px; }
@media (min-width: 900px) { .fiche__visuel--etiquette { --l: 360px; grid-column: 7 / 12; justify-self: center; align-self: end; margin: 64px 0 72px; } }

/* Les formats d'une carte de /lots : une rangée par format, poids, prix et prix au gramme sur trois colonnes, sur une ligne.
   Le plus petit format est un bouton d'ajout (« + 1 g · 7,50 € »), les autres mènent à la fiche. Chaque rangée fait 44 px. */
.carte__formats { gap: 0; margin-top: 2px; position: relative; z-index: 2; }
.carte__formats li.carte__format { display: block; border-top: 1px solid var(--trait); padding: 0; }
.carte__format > :is(a, button), .carte__formats li.carte__format--indispo {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 10px; box-sizing: border-box;
  width: 100%; min-height: 44px; padding: 0; color: var(--encre); text-decoration: none; font: inherit; font-size: var(--t-petit); line-height: 20px;
}
.carte__formats li.carte__format--indispo { grid-template-columns: auto 1fr; color: var(--encre-douce); }
.carte__formats li > span:last-child { display: inline; }
.carte__format--indispo .indispo { text-align: right; font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .1em; text-transform: uppercase; }
.carte__poids { font-weight: 600; white-space: nowrap; }
.carte__montant { justify-self: end; white-space: nowrap; font-variant-numeric: tabular-nums; }
.carte__formats .par-gramme { min-width: 6.6em; text-align: right; white-space: nowrap; font-size: var(--t-mini); }
.carte__formats .par-gramme::before { content: none; }
.carte__formats .par-gramme:empty { visibility: hidden; }
.carte__format-lien { border-radius: 2px; }
.carte__format-lien .carte__poids { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px; transition: text-decoration-color 160ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .carte__format-lien:hover .carte__poids { text-decoration-color: var(--laiton); } }
.carte__format > .carte__ajout {
  appearance: none; grid-template-columns: 24px auto minmax(0, 1fr) auto; margin: 4px 0 6px; padding: 0 12px 0 8px;
  border: 1px solid var(--laiton); border-radius: var(--r-controle); background: var(--ivoire); cursor: pointer; text-align: left;
  transition: background-color 160ms var(--sortie), border-color 160ms var(--sortie), transform 160ms var(--sortie);
}
.carte__formats li.carte__format--ajout { border-top-color: transparent; }
.carte__plus { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--laiton); color: #FBF8F1; font-family: var(--font-etiquette); font-size: var(--t-corps); line-height: 1; }
:root[data-theme="soir"] .carte__plus { color: #131915; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="jour"]) .carte__plus { color: #131915; } }
.carte__ajout .carte__montant { font-weight: 600; justify-self: start; }
.carte__ajout .carte__montant::before { content: "·"; margin-right: .45em; font-weight: 400; color: var(--encre-douce); }
.carte__ajout:active { transform: scale(.98); }
@media (hover: hover) and (pointer: fine) { .carte__ajout:hover { background: var(--lin); border-color: var(--encre-douce); } }
.carte__retour { position: relative; z-index: 2; margin: 0; font-size: var(--t-petit); line-height: 20px; }
.carte__retour:empty { display: none; }
.carte__retour a { color: var(--laiton-texte); font-weight: 600; text-underline-offset: 3px; }

/* Les deux axes des filtres : un petit libellé mono devant chaque groupe. */
.filtres__groupe { align-items: center; }
.filtres__libelle { flex: none; margin-right: 4px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); letter-spacing: .14em; text-transform: uppercase; color: var(--laiton-texte); }
/* « Famille Fleur » : le mot « Famille » en petit, au-dessus du nom de la famille. */
.etagere__famille { display: block; margin-bottom: 6px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-etiquette); line-height: 1.2; letter-spacing: .14em; text-transform: uppercase; color: var(--laiton-texte); }

/* La relance : la famille suivante, avec la vraie photo d'un de ses lots, posée sur le filet comme les autres cartes. */
.relance { position: relative; gap: 0; }
.relance__visuel { display: block; }
.relance__corps { display: grid; grid-template-columns: 12px minmax(0, 1fr); column-gap: 14px; row-gap: 6px; padding-top: 22px; }
.relance__nuance { grid-row: 1 / span 3; align-self: stretch; width: 12px; border-radius: 1px; background: var(--c); }
.relance__nuance[data-arome="zeste"] { --c: var(--aplat-zeste); }
.relance__nuance[data-arome="terre"] { --c: var(--aplat-terre); }
.relance__nuance[data-arome="baie"] { --c: var(--nuance-baie); }
.relance__nuance[data-arome="fleur"] { --c: var(--aplat-fleur); }
.relance__nom { font-size: var(--t-h3); line-height: 1.05; color: var(--encre); }
.relance__compte { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-texte); }
.relance__texte { margin-top: 6px; justify-self: start; }
@media (hover: hover) and (pointer: fine) { .relance:hover .relance__visuel img { transform: translateY(-6px) rotate(-2deg); } }

/* /lots sur téléphone : une rangée par famille qui défile au doigt, une carte à 78 vw et l'aperçu du lot suivant.
   Le nom en Gloock 26 px, l'origine sur une ligne, les filtres collés sous l'en-tête. */
@media (max-width: 719px) {
  .filtres { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete)); z-index: 6; background: var(--papier); }
  .lots__etagere { row-gap: 40px; }
  .lots__etagere .rayon {
    --gap: 16px; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 78vw; row-gap: 0;
    overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none;
    margin: -40px calc(var(--gouttiere) * -1) 0; padding: 40px var(--gouttiere) 8px; scroll-padding-inline: var(--gouttiere);
  }
  .lots__etagere .rayon::-webkit-scrollbar { display: none; }
  .lots__etagere .rayon > * { scroll-snap-align: start; }
  .lots__etagere .rayon > :is(.carte, .relance):nth-child(n) .carte__visuel::before { left: calc(var(--gap) / -2); right: calc(var(--gap) / -2); }
  .lots__etagere .rayon > :is(.carte, .relance):first-child .carte__visuel::before { left: calc(var(--gouttiere) * -1); }
  .lots__etagere .rayon > :is(.carte, .relance):last-child .carte__visuel::before { right: calc(var(--gouttiere) * -1); }
  .rayon .carte__nom { font-size: var(--t-h3); line-height: 1.1; }
  .lots__etagere .rayon .carte__visuel { aspect-ratio: 16 / 10; }
  .lots__etagere .rayon .carte__corps { padding-top: 16px; gap: 6px; }
  .lots__groupe { row-gap: 20px; }
  .lots__groupe-tete { padding-bottom: 14px; }
  .carte__faits { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
/* L'aperçu du lot suivant (étagère de l'accueil, rangées de /lots, suite de la fiche) : la carte coupée par le bord montre
   son produit, pas un nom amputé. Son texte revient dès qu'elle entre (app.js, apercuDefilant()). */
@media (max-width: 899px) {
  :is(.etagere, .rayon) > * :is(.carte__corps, .relance__corps) { transition: opacity 200ms var(--sortie); }
  :is(.etagere, .rayon) > .est-hors-champ :is(.carte__corps, .relance__corps) { opacity: 0; pointer-events: none; }
}

/* La fiche : le prix dès le premier écran, une seule fois, en dernière ligne du cartel (finition, tour 3). Une seule
   étiquette dans la scène, posée en bas à gauche sur la grille : un nom, un prix, une phrase. */
.fiche__cartel .fiche__appel-prix {
  margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--laiton);
  font-size: var(--t-corps); line-height: 22px; letter-spacing: 0; text-transform: none; color: var(--encre); font-variant-numeric: tabular-nums; white-space: nowrap;
}
@media (min-width: 900px) {
  .fiche__cartel .fiche__appel-prix { font-size: var(--t-chapo); line-height: 26px; }
  .fiche__achat { scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 24px); }
}

/* La suite de la fiche : le lien vers l'étiquette expliquée de l'accueil. */
.parente__suite { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 20px; margin: 56px 0 0; padding-top: 24px; border-top: 1px solid var(--trait); }
.parente__suite-surtitre { color: var(--encre-douce); }
.parente__tete[hidden], .parente .etagere[hidden], .parente__suite[hidden] { display: none; }
/* Finition, tour 3 : une étagère courte (un ou deux voisins) se complète d'un panneau « Lire une étiquette de lot », sur
   le lin, liseré de laiton comme l'étiquette du lot. Il prend toute la place libre : jamais de case vide sur la rangée. */
.parente__panneau {
  position: relative; display: grid; align-content: end; justify-items: start; gap: 12px; min-height: 100%; box-sizing: border-box;
  padding: clamp(24px, 3vw, 40px); border-radius: var(--r-etiquette); background: var(--lin); color: var(--encre); text-decoration: none;
  outline: 1px solid var(--laiton); outline-offset: -8px; transition: background-color 200ms var(--sortie);
}
.parente__panneau:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.parente__panneau-surtitre { color: var(--laiton-texte); }
.parente__panneau-titre { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; }
.parente__panneau-texte { max-width: 26em; color: var(--encre-douce); font-size: var(--t-corps); line-height: 1.5; text-wrap: pretty; }
.parente__panneau-lien { margin-top: 4px; }
@media (min-width: 900px) {
  .etagere--courte[data-places="2"] .parente__panneau { grid-column: span 2; }
  .etagere--courte[data-places="2"] .parente__panneau-titre { font-size: var(--t-titre); line-height: 1.02; }
}
@media (hover: hover) and (pointer: fine) { .parente__panneau:hover .lien-laiton::after { translate: 4px -50%; } }

/* L'étiquette de l'accueil : cinq repères, une légende de cinq numéros. */
@media (min-width: 1100px) { .analyse__liste { grid-template-columns: repeat(5, minmax(0, 1fr)); column-gap: 32px; } }

/* Accueil en téléphone : pas de fenêtre C entre le Bulletin et la maison (un grand bloc vide pendant le défilement). */
@media (max-width: 720px) {
  .maison__voile { display: none !important; }
  .maison__interieur > * { animation: none !important; }
}

/* Le panier : le lien « Retirer » sous chaque ligne, le message « Annuler » et le total qui bat à chaque changement. */
.ligne__corps .ligne__retirer { justify-self: start; min-height: 44px; min-width: 44px; margin: -4px 0 -8px; font-size: var(--t-mini); }
.panier__annonce { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin: 16px 0 0; padding: 6px 14px; border: 1px solid var(--trait); border-radius: var(--r-controle); background: var(--ivoire); font-size: var(--t-petit); line-height: 20px; }
.panier__annonce:empty { display: none; }
/* Les lignes qui ne se vendent plus : à part, sous leur titre, sans quantité ni montant, hors du total. */
.panier__indispo { margin-top: 32px; }
.panier__indispo-titre { padding-bottom: 12px; border-bottom: 1px solid var(--encre); color: var(--encre-douce); }
.ligne--indispo .ligne__visuel { opacity: .55; }
.ligne__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 20px; margin: 0; }
.ligne__actions .ligne__prevenir { min-height: 44px; display: inline-flex; align-items: center; font-size: var(--t-petit); }
.panier__limite { margin: 16px 0 0; }
@keyframes total-bat { 50% { scale: 1.06; } }
.recap__montant.est-change { transform-origin: 100% 50%; animation: total-bat 150ms var(--sortie); }
@media (prefers-reduced-motion: reduce) { .recap__montant.est-change { animation: none; } }
/* Plus de hauteur minimale sous un panier plein : le pied suit le ticket, sans bande vide. */
.panier:not(.panier--vide) { min-height: 0; }
@media (min-width: 900px) { .panier:not(.panier--vide) { padding-bottom: 72px; } }

/* Le pied compact (panier, espace) : une ligne, l'adresse, les conditions de vente et les mentions légales. */
.pied--compact .pied__ligne { max-width: 1280px; margin: 0 auto; padding: 24px var(--gouttiere) calc(24px + env(safe-area-inset-bottom)); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 28px; }
.pied--compact .pied__marque { font-family: var(--font-titre); font-size: var(--t-chapo); line-height: 1; color: var(--sur-aplat); }
.pied--compact .pied__liens { display: flex; flex-wrap: wrap; gap: 0 20px; }
.pied--compact .pied__liens a { display: inline-flex; align-items: center; min-height: 44px; }

/* L'espace : les pastilles de navigation collent sous l'en-tête et suivent la lecture (aria-current). */
.espace__sommaire {
  position: sticky; top: calc(var(--haut-demo) + var(--haut-entete)); z-index: 6; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(var(--gouttiere) * -1) 32px; padding: 12px var(--gouttiere); background: var(--papier); border-bottom: 1px solid var(--trait);
}
.espace__sommaire::-webkit-scrollbar { display: none; }
.espace__sommaire a { flex: none; color: var(--encre); }
.espace__sommaire a[aria-current="true"] { background: var(--sousbois); border-color: var(--sousbois); color: var(--sur-sousbois); }
:root[data-theme="soir"] .espace__sommaire a[aria-current="true"] { border-color: var(--laiton); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="jour"]) .espace__sommaire a[aria-current="true"] { border-color: var(--laiton); } }
.espace__bloc { scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 88px); }
.carnet__bas a { color: var(--laiton-clair); text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* L'anneau de focus laiton de 2 px sur les commandes de choix : filtres, formats, quantité, ajout rapide. */
:is(.filtre, .quantite button, .carte__ajout, .carte__format-lien, .espace__sommaire a):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ══ L'Herbier, la FAQ et le lexique ═══════════════════════════════════════════════════════════════════════════════
   Le journal se compose comme une revue de maison : de grands titres en Gloock, des filets d'encre et de trait, les
   numéros et les rubriques en DM Mono, une seule étiquette ivoire par écran. Papier et encre, le laiton pour signer ;
   le sous-bois pour l'article à la une, seul aplat de l'index. Aucune image d'archive : le texte porte la page. */

/* L'en-tête : L'Herbier entre « Les lots » et « Le comptoir ». Sur téléphone, un livre ouvert dans 44 × 44 px, et les
   entrées se resserrent pour que les six tiennent en 390 px (et en 360 px). */
@media (max-width: 600px) {
  .entete__interieur { gap: 8px; }
  .entete nav { gap: 2px; }
  .entete nav .entete__herbier { justify-content: center; min-width: 44px; }
  .entete nav .entete__herbier[aria-current]::after { left: 12px; right: 12px; bottom: 6px; }
}
@media (max-width: 374px) {
  :root { --gouttiere: 12px; }
  .entete nav .entete__herbier, .entete nav .entete__boutique, .entete nav .entete__compte, .bascule-theme { min-width: 40px; width: 40px; }
}
.entete nav a[aria-current="true"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 1.5px; border-radius: 1px; background: var(--laiton); }

/* Le repère de l'aperçu : une étiquette en DM Mono, au trait pointillé de laiton. Discret, jamais rouille (la rouille
   est aux erreurs et au bandeau démo). Il disparaît avec la génération --publication. */
.apercu { display: flex; margin: 0; }
.apercu__texte {
  display: inline-flex; align-items: center; min-height: 26px; padding: 3px 10px; border: 1px dashed var(--laiton); border-radius: var(--r-etiquette);
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .1em; text-transform: uppercase; color: var(--encre-douce);
}
.a-confirmer {
  font-family: var(--font-etiquette); font-size: .78em; letter-spacing: .02em; color: var(--laiton-texte);
  border-bottom: 1px dashed var(--laiton); padding-bottom: 1px; white-space: normal;
}
.a-confirmer::before { content: "["; }
.a-confirmer::after { content: "]"; }

/* Un terme du lexique, lié depuis un article : souligné de points de laiton, sans changer d'encre. */
.lien-terme { color: inherit; text-decoration: underline dotted var(--laiton); text-decoration-thickness: 1.5px; text-underline-offset: 4px; }
@media (hover: hover) and (pointer: fine) { .lien-terme:hover { color: var(--laiton-texte); text-decoration-style: solid; } }

/* ── L'index de L'Herbier */
.herbier { padding-bottom: 24px; }
.herbier__tete { display: grid; gap: 16px; padding: 8px 0 48px; }
.herbier__tete > * { margin: 0; }
.herbier__titre { font-size: var(--t-display); line-height: .92; letter-spacing: -.02em; }
.herbier__bande { margin-top: 8px; }
.herbier__chapo { max-width: 28em; }
.herbier__edition { color: var(--encre-douce); }
@media (min-width: 900px) {
  .herbier__tete { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: 64px; padding: 24px 0 72px; }
  .herbier__surtitre, .herbier__titre, .herbier__bande { grid-column: 1; }
  .herbier__chapo { grid-column: 2; grid-row: 2; align-self: end; }
  .herbier__edition { grid-column: 2; grid-row: 3; align-self: center; }
}

/* L'article à la une : le sous-bois et son semis, d'un bord à l'autre ; l'« En bref » sur l'étiquette ivoire. */
.une {
  display: grid; gap: 40px; margin: 0 calc(var(--gouttiere) * -1); padding: 48px var(--gouttiere) 56px;
  background-color: var(--aplat-sousbois); color: var(--sur-aplat); --focus: var(--laiton-clair);
}
.une > * { min-width: 0; }
.une__texte { display: grid; gap: 20px; align-content: start; }
.une__texte > * { margin: 0; }
.une__rubrique { color: var(--laiton-clair); }
.une__titre { font-size: var(--t-grand); line-height: .98; letter-spacing: -.02em; }
.une__lien { color: inherit; text-decoration: none; background-image: linear-gradient(var(--laiton-clair), var(--laiton-clair)); background-size: 0 1.5px; background-position: 0 92%; background-repeat: no-repeat; transition: background-size 240ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .une__lien:hover { background-size: 100% 1.5px; } }
.une__chapo { font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: rgba(251, 248, 241, .86); max-width: 30em; }
.une .une__meta { display: flex; flex-wrap: wrap; gap: 4px 0; color: rgba(251, 248, 241, .72); }
.une .une__meta > span + span::before { content: "·"; margin: 0 12px; color: var(--laiton-clair); }
.une__bref {
  position: relative; display: grid; gap: 14px; align-content: start; padding: 30px 28px 18px; border-radius: var(--r-etiquette);
  outline: 1px solid var(--laiton); outline-offset: -9px; rotate: 1.2deg; justify-self: center; width: min(440px, 100%);
  box-shadow: 0 1px 2px rgba(20, 12, 4, .18), 0 18px 40px rgba(20, 12, 4, .26);
}
.une__bref-titre { margin: 0; color: var(--laiton-texte); text-align: center; }
.une__bref-liste { list-style: none; margin: 0; padding: 0; counter-reset: bref; }
.une__bref-liste li { counter-increment: bref; display: grid; grid-template-columns: 32px minmax(0, 1fr); padding: 12px 0; border-top: 1px dashed var(--trait); font-size: var(--t-corps); line-height: 1.45; }
.une__bref-liste li::before { content: counter(bref, decimal-leading-zero); font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 24px; color: var(--laiton-texte); }
.une__bref .lien-laiton { justify-self: stretch; justify-content: center; border-top: 1px solid var(--encre); }
@media (min-width: 900px) {
  .une { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: clamp(48px, 6vw, 96px); align-items: center; padding: 88px var(--gouttiere) 96px; }
  .une__bref { justify-self: end; }
}

/* La suite : les autres articles en sommaire de revue, numérotés, sur des filets. */
.herbier__suite { padding-top: 64px; }
.herbier__suite-tete { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 16px 32px; padding-bottom: 20px; }
.herbier__suite-titre { font-size: var(--t-titre); line-height: 1; }
.herbier__rubriques { padding: 0; border: 0; gap: 8px; }
.filtre__compte { margin-left: -4px; color: var(--laiton-texte); }
.filtre[aria-pressed="true"] .filtre__compte { color: var(--laiton-clair); }
@media (max-width: 719px) { .herbier__rubriques { padding: 4px var(--gouttiere); position: static; } }
@media (min-width: 720px) { .herbier__rubriques { margin: 0; position: static; background: none; } }
.sommaire-herbier { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--encre); }
.entree { border-bottom: 1px solid var(--trait); }
.entree__lien {
  display: grid; grid-template-columns: 36px minmax(0, 1fr); column-gap: 12px; row-gap: 8px; padding: 26px 0 28px;
  color: inherit; text-decoration: none;
}
.entree__lien > * { grid-column: 2; margin: 0; }
.entree__numero { grid-column: 1; grid-row: 1 / span 4; padding-top: 1px; color: var(--laiton-texte); }
.entree__rubrique { color: var(--encre-douce); }
.entree__titre { font-size: var(--t-h3); line-height: 1.06; letter-spacing: -.01em; transition: color 200ms var(--sortie); }
.entree__titre::after { content: " →"; color: var(--laiton-texte); opacity: 0; transition: opacity 200ms var(--sortie); }
.entree__description { color: var(--encre-douce); max-width: 36em; }
.entree__meta { color: var(--encre-douce); }
@media (hover: hover) and (pointer: fine) {
  .entree__lien:hover .entree__titre { color: var(--laiton-texte); }
  .entree__lien:hover .entree__titre::after { opacity: 1; }
}
.entree__lien:focus-visible { outline-offset: 4px; }
@media (min-width: 900px) {
  .herbier .entree__lien { grid-template-columns: 72px minmax(0, 7fr) minmax(0, 5fr); column-gap: 32px; padding: 36px 0 40px; }
  .herbier .entree__rubrique { grid-column: 2; grid-row: 1; }
  .herbier .entree__titre { grid-column: 2; grid-row: 2 / span 2; }
  .herbier .entree__description { grid-column: 3; grid-row: 2; }
  .herbier .entree__meta { grid-column: 3; grid-row: 3; }
}

/* Les deux renvois, le lexique et la FAQ, sur le lin. */
.renvois { display: grid; gap: 16px; margin-top: 80px; }
@media (min-width: 720px) { .renvois { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; } }
.renvoi {
  display: grid; gap: 10px; align-content: start; padding: 28px 28px 32px; border: 1px solid var(--trait); border-radius: var(--r-etiquette);
  background: var(--lin); color: inherit; text-decoration: none; transition: border-color 200ms var(--sortie);
}
.renvoi__compte { color: var(--laiton-texte); }
.renvoi__titre { font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1; letter-spacing: -.015em; }
.renvoi__titre::after { content: " →"; color: var(--laiton-texte); }
.renvoi__texte { color: var(--encre-douce); max-width: 26em; }
@media (hover: hover) and (pointer: fine) { .renvoi:hover { border-color: var(--laiton); } }

/* ── L'article */
.article { padding-bottom: 24px; }
.article__tete { display: grid; gap: 20px; padding: 8px 0 40px; max-width: 1000px; }
.article__tete > * { margin: 0; }
.article__rubrique { color: var(--encre-douce); }
.article__rubrique a { color: var(--laiton-texte); text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; margin-block: -14px; }
@media (hover: hover) and (pointer: fine) { .article__rubrique a:hover { text-decoration: underline; text-underline-offset: 4px; } }
.article__titre { font-size: var(--t-grand); line-height: .98; letter-spacing: -.02em; }
.article__chapo { max-width: 32em; color: var(--encre); }
.article__meta { display: flex; flex-wrap: wrap; gap: 6px 0; color: var(--encre-douce); }
.article__meta > span + span::before { content: "·"; margin: 0 12px; color: var(--laiton); }

.en-bref {
  margin: 0; padding: 30px 28px 18px; max-width: 760px; background: var(--ivoire); border: 1px solid var(--trait); border-radius: var(--r-etiquette);
  outline: 1px solid var(--laiton); outline-offset: -9px; box-shadow: var(--ombre-carte); rotate: -.5deg;
}
.en-bref__titre { margin: 0 0 8px; color: var(--laiton-texte); font-size: var(--t-etiquette); line-height: 1.3; font-family: var(--font-etiquette); }
.en-bref__liste { list-style: none; margin: 0; padding: 0; counter-reset: bref; }
.en-bref__liste li { counter-increment: bref; display: grid; grid-template-columns: 36px minmax(0, 1fr); padding: 14px 0; border-top: 1px dashed var(--trait); font-size: var(--t-corps); line-height: 1.5; font-weight: 500; }
.en-bref__liste li:first-child { border-top: 0; }
.en-bref__liste li::before { content: counter(bref, decimal-leading-zero); font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 26px; color: var(--laiton-texte); }
@media (min-width: 900px) { .en-bref { padding: 36px 40px 22px; } .en-bref__liste li { font-size: var(--t-corps); } }
@media (min-width: 1000px) { .en-bref { margin-left: calc(240px + clamp(48px, 7vw, 120px)); } }

.article__corps { display: grid; gap: 40px; margin-top: 56px; }
.article__corps > * { min-width: 0; }
.sommaire__titre { margin: 0 0 12px; color: var(--laiton-texte); font-family: var(--font-etiquette); font-size: var(--t-etiquette); line-height: 1.3; }
.sommaire__liste { list-style: none; margin: 0; padding: 0; counter-reset: sommaire; border-top: 1px solid var(--encre); }
.sommaire__liste li { counter-increment: sommaire; border-bottom: 1px solid var(--trait); }
.sommaire__liste a {
  display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: baseline; min-height: 44px; padding: 11px 0;
  font-size: var(--t-petit); line-height: 1.35; color: var(--encre-douce); text-decoration: none; transition: color 160ms var(--sortie);
}
.sommaire__liste a::before { content: counter(sommaire, decimal-leading-zero); font-family: var(--font-etiquette); font-size: var(--t-mini); color: var(--laiton-texte); }
.sommaire__liste a[aria-current="true"] { color: var(--encre); }
@media (hover: hover) and (pointer: fine) { .sommaire__liste a:hover { color: var(--encre); } }
.sommaire__liste a[aria-current="true"] { font-weight: 600; }
@media (min-width: 1000px) {
  .article__corps { grid-template-columns: 240px minmax(0, 700px); column-gap: clamp(48px, 7vw, 120px); }
  .sommaire { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 32px); align-self: start; max-height: calc(100vh - var(--haut-demo) - var(--haut-entete) - 64px); overflow-y: auto; scrollbar-width: thin; }
}
.article__texte { min-width: 0; }
.article__texte p { margin: 0 0 1em; }
.article__section, .article__faq, .article__sources, .article__lots, .article__suite { scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 24px); }
.article__section + .article__section { margin-top: 56px; }
.article__h2 { font-size: var(--t-titre); line-height: 1.1; letter-spacing: -.01em; margin: 0 0 20px; }
.article__liste { list-style: none; margin: 0 0 1em; padding: 0; }
.article__liste li { position: relative; margin: 0 0 12px; padding-left: 26px; }
.article__liste li::before { content: ""; position: absolute; left: 4px; top: .68em; width: 7px; height: 7px; border-radius: 50%; background: var(--laiton); }
.article__faq, .article__lots, .article__suite, .article__sources { margin-top: 80px; padding-top: 28px; border-top: 1px solid var(--encre); }
.article__liens { list-style: none; margin: 0; padding: 0; display: grid; }
.article__liens .lien-fleche { margin: 0; }
.article__liens li:last-child .lien-fleche { border-bottom: 1px dashed var(--trait); }
.article__signature { margin: 32px 0 0; padding-top: 16px; border-top: 1px dashed var(--trait); font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }

/* Les questions, en <details> (article et FAQ) : un filet, la question en Instrument Sans, un + de laiton qui pivote. */
.question { border-bottom: 1px solid var(--trait); }
.question__q {
  list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 20px; min-height: 60px; padding: 16px 0;
  font-weight: 600; font-size: var(--t-corps); line-height: 1.35; cursor: pointer; border-radius: var(--r-etiquette);
}
.question__q::-webkit-details-marker { display: none; }
.question__q::after { content: "+"; flex: none; font-family: var(--font-etiquette); font-size: var(--t-chapo); line-height: 1; color: var(--laiton-texte); transition: rotate 240ms var(--sortie); }
.question[open] > .question__q::after { rotate: 45deg; }
@media (hover: hover) and (pointer: fine) { .question__q:hover { color: var(--laiton-texte); } }
.question__r { display: grid; gap: 10px; padding: 0 0 22px; color: var(--encre-douce); max-width: 40em; }
.question__r > *, .question__r p { margin: 0; }
.question__lien .lien-laiton { min-height: 40px; }
.question__sources { display: grid; gap: 4px; font-size: var(--t-petit); }
.question__sources .etiquette, .terme__sources .etiquette { color: var(--laiton-texte); margin: 0; }

/* Les lots cités : le spécimen détouré sur le lin, le nom, la forme et la famille. */
.lots-cites { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 16px; }
@media (min-width: 720px) { .lots-cites { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px 24px; } }
.lot-cite__lien { display: grid; gap: 6px; color: inherit; text-decoration: none; }
.lot-cite__sol { display: grid; place-items: center; aspect-ratio: 5 / 4; margin-bottom: 8px; padding: 14px; background: var(--lin); border-radius: var(--r-etiquette); overflow: hidden; }
.lot-cite__img { width: 100%; height: 100%; object-fit: contain; filter: var(--ombre-specimen); transition: translate 300ms var(--sortie); }
.lot-cite__sans { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1; color: var(--encre-douce); text-align: center; }
.lot-cite__nom { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; }
.lot-cite__legende { color: var(--encre-douce); }
.lot-cite__texte { font-size: var(--t-petit); line-height: 1.45; color: var(--encre-douce); }
@media (hover: hover) and (pointer: fine) { .lot-cite__lien:hover .lot-cite__img { translate: 0 -4px; } .lot-cite__lien:hover .lot-cite__nom { color: var(--laiton-texte); } }

/* Les sources, en fin d'article (et sous une réponse ou un terme). */
.sources__liste { margin: 0; padding-left: 1.5em; font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }
.sources__liste li { margin: 0 0 10px; padding-left: 4px; overflow-wrap: anywhere; }
.sources__liste li::marker { font-family: var(--font-etiquette); font-size: var(--t-mini); color: var(--laiton-texte); }
.sources__liste a { color: var(--encre); text-decoration-color: var(--laiton); text-underline-offset: 3px; }
.question__sources .sources__liste, .terme__sources .sources__liste { font-size: var(--t-petit); }

/* ── La FAQ */
.faq { padding-bottom: 32px; }
.faq__grille { display: grid; gap: 40px; padding: 8px 0 0; }
.faq__grille > * { min-width: 0; }
.faq__tete { display: grid; gap: 20px; align-content: start; }
.faq__tete > * { margin: 0; }
.faq__titre { font-size: var(--t-grand); line-height: .95; letter-spacing: -.02em; }
.recherche { display: grid; gap: 8px; }
.recherche input { width: 100%; min-width: 0; -webkit-appearance: none; appearance: none; }
.recherche__statut { margin: 0; color: var(--encre-douce); }
.faq__sommaire ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.faq__sommaire a {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border: 1px solid var(--trait); border-radius: 999px;
  font-size: var(--t-petit); font-weight: 600; color: var(--encre); text-decoration: none; transition: border-color 160ms var(--sortie);
}
@media (hover: hover) and (pointer: fine) { .faq__sommaire a:hover { border-color: var(--laiton); } }
@media (min-width: 1000px) {
  .faq__grille { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(48px, 7vw, 112px); align-items: start; }
  .faq__tete { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 32px); }
}
.faq__groupe { scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 24px); }
.faq__groupe + .faq__groupe { margin-top: 56px; }
.faq__theme { display: flex; align-items: baseline; gap: 12px; margin: 0; padding-bottom: 14px; border-bottom: 1px solid var(--encre); font-size: var(--t-titre); line-height: 1.1; }
.faq__compte { color: var(--laiton-texte); }
.faq__vide { display: grid; gap: 8px; justify-items: start; padding: 32px 0; }
.faq__vide p { margin: 0; color: var(--encre-douce); }
.faq__vide .faq__vide-titre { font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1.1; color: var(--encre); }
.faq__suite { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin: 56px 0 0; color: var(--encre-douce); }
.question__apercu { margin-bottom: 2px; }

/* ── Le lexique */
.lexique { padding-bottom: 32px; }
.lexique__tete { display: grid; gap: 20px; padding: 8px 0 40px; max-width: 980px; }
.lexique__tete > * { margin: 0; }
.lexique__titre { font-size: var(--t-display); line-height: .92; letter-spacing: -.02em; }
.alphabet {
  position: sticky; top: calc(var(--haut-demo) + var(--haut-entete)); z-index: 5; margin: 0 calc(var(--gouttiere) * -1); padding: 0 var(--gouttiere);
  background: var(--papier); border-top: 1px solid var(--encre); border-bottom: 1px solid var(--trait);
}
.alphabet ol { list-style: none; margin: 0; padding: 0; display: flex; justify-content: space-between; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.alphabet ol::-webkit-scrollbar { display: none; }
.alphabet li { flex: none; }
.alphabet a, .alphabet__vide { display: inline-grid; place-items: center; min-width: 36px; min-height: 44px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-petit); }
.alphabet a { color: var(--encre); text-decoration: none; border-radius: var(--r-etiquette); }
@media (hover: hover) and (pointer: fine) { .alphabet a:hover { color: var(--laiton-texte); text-decoration: underline; text-underline-offset: 4px; } }
.alphabet__vide { color: var(--trait); }
/* Sous 600 px, les 26 lettres sur deux rangées de 13 : tout l'index se voit, rien ne se cache hors de l'écran. */
@media (max-width: 599px) {
  .alphabet ol { display: grid; grid-template-columns: repeat(13, minmax(0, 1fr)); overflow: visible; }
  .alphabet ol a, .alphabet ol .alphabet__vide { display: grid; min-width: 0; min-height: 44px; }
}
.lettre { display: grid; gap: 8px; padding: 40px 0 24px; border-bottom: 1px solid var(--trait); scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 60px); }
@media (max-width: 599px) { .lettre { scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 100px); } }
.lettre__titre { font-size: var(--t-affiche); line-height: .9; color: var(--laiton); }
.termes { margin: 0; display: grid; }
.terme { padding: 22px 0; border-top: 1px dashed var(--trait); scroll-margin-top: calc(var(--haut-demo) + var(--haut-entete) + 64px); }
.terme:first-child { border-top: 0; padding-top: 8px; }
.terme__nom { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; margin-bottom: 10px; }
.terme__definition { margin: 0; display: grid; gap: 10px; max-width: 40em; }
.terme__definition > *, .terme__definition p { margin: 0; }
.terme__voir { font-size: var(--t-petit); color: var(--encre-douce); }
.terme__voir .etiquette { margin-right: 6px; color: var(--laiton-texte); }
.terme__voir a { color: var(--encre); text-decoration-color: var(--laiton); text-underline-offset: 3px; }
.terme__sources { display: grid; gap: 4px; }
.terme:target .terme__nom { color: var(--laiton-texte); }
@media screen and (prefers-reduced-motion: no-preference) {
  .terme:target { animation: terme-cible 1800ms var(--sortie); }
}
@keyframes terme-cible { from { background: var(--lin); box-shadow: -16px 0 0 var(--lin), 16px 0 0 var(--lin); } to { background: transparent; box-shadow: none; } }
@media (min-width: 900px) {
  .lettre { grid-template-columns: 180px minmax(0, 1fr); column-gap: 48px; padding: 48px 0 32px; }
  .lettre__titre { position: sticky; top: calc(var(--haut-demo) + var(--haut-entete) + 76px); align-self: start; }
  .terme { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); column-gap: 32px; }
  .terme__nom { margin: 0; }
}
.lexique__suite { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 24px; margin: 56px 0 0; }
.lexique__suite .etiquette { flex-basis: 100%; color: var(--encre-douce); }

/* ── Le chapitre « L'Herbier » de l'accueil : sur le papier, entre la cueillette et le Bulletin. */
.herbier-accueil__tete { display: grid; gap: 14px; margin-bottom: 40px; }
.herbier-accueil__tete > * { margin: 0; }
.herbier-accueil__titre { font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; }
.herbier-accueil__phrase { max-width: 32em; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: var(--encre-douce); }
.herbier-accueil__corps { display: grid; gap: 32px; }
.herbier-accueil__corps > * { min-width: 0; }
.herbier-accueil__une {
  display: grid; gap: 16px; align-content: start; padding: 30px 28px 26px; background: var(--ivoire); border: 1px solid var(--trait);
  border-radius: var(--r-etiquette); outline: 1px solid var(--laiton); outline-offset: -9px; box-shadow: var(--ombre-carte);
  color: inherit; text-decoration: none; rotate: -.6deg; transition: border-color 200ms var(--sortie);
}
.herbier-accueil__une > * { margin: 0; }
.herbier-accueil__rubrique, .herbier-accueil__meta { color: var(--laiton-texte); }
.herbier-accueil__une-titre { font-size: var(--t-h3); line-height: 1.02; letter-spacing: -.015em; }
.herbier-accueil__une-texte { color: var(--encre-douce); max-width: 30em; }
.herbier-accueil__meta { padding-top: 12px; border-top: 1px dashed var(--trait); }
.herbier-accueil__meta::after { content: "  →"; }
@media (hover: hover) and (pointer: fine) { .herbier-accueil__une:hover { border-color: var(--laiton); } .herbier-accueil__une:hover .herbier-accueil__une-titre { color: var(--laiton-texte); } }
.sommaire-herbier--accueil .entree__lien { padding: 22px 0 24px; }
@media (min-width: 900px) {
  .herbier-accueil__tete { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: 64px; align-items: end; margin-bottom: 56px; }
  .herbier-accueil__tete > .surtitre, .herbier-accueil__titre, .herbier-accueil__tete > .bande-nuancier { grid-column: 1; }
  .herbier-accueil__phrase { grid-column: 2; grid-row: 2 / span 2; align-self: end; }
  .herbier-accueil__corps { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: 64px; align-items: start; }
  .herbier-accueil__une { padding: 44px 44px 32px; }
}

/* ── Le comptoir : la photo de l'intérieur et la sélection d'avis (aperçu tant qu'elles ne sont pas validées). */
.comptoir-apercus { display: grid; gap: 56px; border-top: 1px solid var(--trait); }
.comptoir-apercus > * { min-width: 0; }
.interieur { margin: 0; display: grid; gap: 12px; }
.interieur__img { width: 100%; height: auto; border-radius: var(--r-etiquette); }
.interieur__legende { color: var(--encre-douce); }
@media (min-width: 900px) { .comptoir-apercus:not(.comptoir-apercus--seul) { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: 64px; align-items: start; } }

/* ══ L'accueil enrichi : la recherche, la livraison du soir, le guide des familles, vos mots, Instagram ══════════════
   Chaque section prend un fond du Nuancier qui lui est propre : le sous-bois pour le soir, le lin pour le guide, le
   papier pour vos mots et pour le fil du comptoir.
   Aucun dégradé. Gloock jamais sous 24 px ; sur Zeste et Fleur, l'ivoire seulement à 24 px ou plus. */

/* La loupe de l'en-tête : une icône à toutes les largeurs, son nom « Rechercher » toujours lu. */
.entete nav .entete__recherche { justify-content: center; min-width: 44px; }
.entete__recherche .entete__loupe { display: block; }
.entete__recherche .entete__libelle { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.entete nav .entete__recherche[aria-current]::after { left: 12px; right: 12px; bottom: 6px; }
/* Avec la loupe, sept entrées : sous 430 px, les icônes passent à 36 px de large (44 px de haut, la zone de clic reste
   à la hauteur du doigt) pour que tout tienne en 390 px, et en 360 px. */
@media (max-width: 430px) {
  .entete nav .entete__recherche, .entete nav .entete__herbier, .entete nav .entete__boutique, .entete nav .entete__compte, .entete .bascule-theme { min-width: 36px; width: 36px; }
  .entete nav a[href="/panier"] { padding-left: 2px; }
}
@media (max-width: 374px) {
  .entete nav .entete__recherche, .entete nav .entete__herbier, .entete nav .entete__boutique, .entete nav .entete__compte, .entete .bascule-theme { min-width: 32px; width: 32px; }
}

/* La livraison du soir : le sous-bois et son semis, « Après 20 h » en grand, un croissant au trait de laiton. */
.soir { position: relative; overflow: clip; margin-inline: calc(50% - 50vw); padding: clamp(80px, 9vw, 136px) calc(50vw - 50%); background-color: var(--aplat-sousbois); color: var(--sur-aplat); --focus: var(--laiton-clair); }
.soir__interieur { position: relative; display: grid; gap: 40px; }
.soir__lune { position: absolute; top: -40px; right: -12px; width: clamp(104px, 18vw, 220px); height: auto; color: var(--laiton-clair); opacity: .9; pointer-events: none; }
.soir__texte { position: relative; display: grid; gap: 24px; align-content: start; }
.soir__texte > * { margin: 0; }
.soir__surtitre { color: var(--laiton-clair); }
.soir__titre { font-size: var(--t-h2); line-height: .98; letter-spacing: -.015em; color: var(--sur-aplat); max-width: 10em; }
.soir__ligne { display: block; }
.soir__heure { color: var(--laiton-clair); white-space: nowrap; }
.soir__phrase { max-width: 30em; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: rgba(251, 248, 241, .82); }
.soir__apercu .apercu__texte { color: rgba(251, 248, 241, .86); border-color: var(--laiton-clair); }
.soir .a-confirmer { color: var(--laiton-clair); border-bottom-color: var(--laiton-clair); }
.soir__fiche { position: relative; display: grid; gap: 14px; align-content: start; }
.soir__fiche > * { margin: 0; }
.soir__faits { margin: 0; display: grid; border-top: 1px solid rgba(251, 248, 241, .5); }
.soir__faits > div { display: grid; grid-template-columns: minmax(0, 9em) minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 12px 0; border-bottom: 1px dashed rgba(251, 248, 241, .22); }
.soir__faits dt { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: rgba(251, 248, 241, .7); }
.soir__faits dd { margin: 0; font-size: var(--t-petit); color: var(--sur-aplat); }
.soir__appel { padding-top: 10px; }
.soir__bouton { min-height: 52px; padding-inline: 28px; }
.soir__numero { color: var(--laiton-clair); font-variant-numeric: tabular-nums; }
@media (min-width: 900px) {
  .soir__interieur { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); column-gap: clamp(48px, 7vw, 120px); align-items: end; }
  .soir__lune { top: -72px; right: auto; left: 40%; }
}
@media (max-width: 599px) { .soir__ligne { display: inline; } .soir__titre { font-size: var(--t-grand); } .soir__bouton { width: 100%; } }

/* Le guide des familles : sur le lin, une carte ivoire, une question à la fois. */
.guide { margin-inline: calc(50% - 50vw); padding: clamp(72px, 8vw, 120px) calc(50vw - 50%); background: var(--lin); display: grid; gap: 40px; }
.guide__tete { display: grid; gap: 16px; }
.guide__tete > * { margin: 0; }
.guide__tete .surtitre { color: var(--laiton-texte); }
.guide__titre { font-size: var(--t-grand); line-height: 1; letter-spacing: -.015em; max-width: 12em; }
.guide__phrase { max-width: 32em; font-size: var(--t-chapo); line-height: 1.4; color: var(--encre-douce); }
/* Une carte ivoire posée sur le lin : un pas de ton la détache, sans filet ni ombre. */
.guide__carte, .guide__resultat { background: var(--ivoire); border-radius: var(--r-carte); }
.guide__carte { display: grid; gap: 20px; padding: clamp(20px, 3vw, 40px); }
.guide__progression { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
.guide__progression span { height: 4px; border-radius: 1px; background: var(--trait); transition: background-color 300ms var(--sortie); }
.guide__progression span.est-faite:nth-child(1) { background: var(--aplat-zeste); }
.guide__progression span.est-faite:nth-child(2) { background: var(--aplat-terre); }
.guide__progression span.est-faite:nth-child(3) { background: var(--aplat-baie); }
.guide__progression span.est-faite:nth-child(4) { background: var(--aplat-fleur); }
.guide__progression span.est-faite:nth-child(5) { background: var(--aplat-mousse); }
/* La question vient d'abord dans le code (legend), le compteur s'affiche au-dessus : la legend flotte, elle n'est plus
   « rendue » à part et suit l'ordre de la grille. */
.guide__etape { display: grid; margin: 0; padding: 0; border: 0; min-width: 0; }
.guide__etape[hidden] { display: none; }
.guide__etape > .guide__numero { order: -1; margin: 0 0 10px; }
.guide__question { float: left; width: 100%; padding: 0; margin-bottom: 20px; font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1.08; letter-spacing: -.01em; }
.guide__numero { font-family: var(--font-etiquette); font-size: var(--t-etiquette); color: var(--laiton-texte); letter-spacing: .12em; }
.guide__choix { display: grid; gap: 10px; }
@media (min-width: 700px) { .guide__choix { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.choix { position: relative; display: flex; align-items: center; gap: 14px; min-height: 60px; padding: 12px 16px; border: 1px solid var(--trait); border-radius: var(--r-controle); background: var(--papier); cursor: pointer; font-size: var(--t-corps); line-height: 1.3; transition: border-color 160ms var(--sortie), background-color 160ms var(--sortie); }
.choix input { appearance: none; -webkit-appearance: none; flex: none; width: 22px; height: 22px; margin: 0; border: 1.5px solid var(--encre-douce); border-radius: 50%; display: grid; place-items: center; background: transparent; }
.choix input::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--laiton); scale: .5; opacity: 0; transition: scale var(--d-court) var(--sortie), opacity var(--d-court) var(--sortie); }
.choix input:checked { border-color: var(--encre); }
.choix input:checked::after { scale: 1; opacity: 1; }
.choix:has(input:checked) { border-color: var(--encre); background: var(--ivoire); box-shadow: inset 0 0 0 1px var(--encre); }
.choix:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.choix input:focus-visible { outline: none; }
@media (hover: hover) and (pointer: fine) { .choix:hover { border-color: var(--encre); } }
.guide__message { margin: 0; min-height: 1.4em; font-size: var(--t-petit); color: var(--rouille); }
.guide__nav { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px; }
.guide__nav [data-guide-suivant] { margin-left: auto; min-height: 52px; padding-inline: 28px; }
.guide__resultat { overflow: hidden; display: grid; }
.guide__resultat[hidden] { display: none; }
.guide__aplat { display: grid; gap: 14px; padding: clamp(28px, 4vw, 56px); background: var(--aplat-sousbois); color: var(--sur-aplat); }
.guide__aplat > * { margin: 0; }
.guide__aplat[data-famille="zeste"] { background: var(--aplat-zeste); }
.guide__aplat[data-famille="terre"] { background: var(--aplat-terre); }
.guide__aplat[data-famille="baie"] { background: var(--aplat-baie); }
.guide__aplat[data-famille="fleur"] { background: var(--aplat-fleur); }
.guide__votre { justify-self: start; padding: 5px 10px; border-radius: var(--r-etiquette); background: var(--sur-aplat); color: #1F2A22; }
.guide__famille { font-size: var(--t-display); line-height: .9; letter-spacing: -.02em; color: var(--sur-aplat); }
.guide__famille:focus { outline: none; }
.guide__famille:focus-visible { outline: 2px solid var(--sur-aplat); outline-offset: 6px; }
.guide__notes { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.15; color: var(--sur-aplat); }
.guide__suite { display: grid; gap: 20px; padding: clamp(20px, 3vw, 40px); }
.guide__suite > * { margin: 0; }
.guide__remarque { color: var(--encre-douce); }
.guide__lots { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.guide__lot-lien { display: grid; gap: 6px; align-content: start; height: 100%; padding-bottom: 8px; text-decoration: none; color: inherit; border-bottom: 1px solid var(--trait); }
.guide__lot-img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; filter: var(--ombre-specimen); }
.guide__lot-sans { display: block; aspect-ratio: 1; background: var(--lin); border-radius: var(--r-etiquette); }
.guide__lot-nom { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.05; }
.guide__lot-repere { color: var(--encre-douce); font-size: var(--t-mini); }
@media (hover: hover) and (pointer: fine) { .guide__lot-lien:hover .guide__lot-nom { color: var(--laiton-texte); } }
@media (max-width: 599px) {
  .guide__lots { grid-template-columns: minmax(0, 1fr); }
  .guide__lot-lien { grid-template-columns: 88px minmax(0, 1fr); align-items: center; column-gap: 14px; }
  .guide__lot-img, .guide__lot-sans { grid-row: 1 / span 2; }
}
.guide__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 24px; }
.guide__actions .lien-fleche { flex: 1 1 16em; }
@media (min-width: 900px) {
  .guide { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(48px, 6vw, 96px); align-items: start; }
  .guide__tete { position: sticky; top: calc(var(--haut-entete) + var(--haut-demo) + 32px); }
  .guide__resultat, .guide__carte { grid-column: 2; grid-row: 1; }
}

/* Vos mots : la seule section des avis (27/10/2026, demande de Rayan : les avis se noyaient dans la marque). Un aplat
   sous-bois et son semis, pleine largeur, comme la maison. En tête, la note de la fiche Google en affiche (Gloock, laiton
   clair), ses étoiles au trait et « Laisser un avis sur Google ». Dessous, chaque avis est une carte en relief, posée de
   biais comme l'étiquette de lot, ouverte par un grand guillemet de Gloock. Au thème Soir, la carte ivoire deviendrait
   l'aplat lui-même : elle prend le sous-bois Soir, un filet de laiton et une ombre plus noire. */
.vos-mots {
  --carte-fond: var(--ivoire); --carte-bord: rgba(31, 42, 34, .08); --carte-ombre: 0 1px 2px rgba(0, 0, 0, .22), 0 18px 40px rgba(0, 0, 0, .34);
  margin-inline: calc(50% - 50vw); padding: clamp(80px, 8vw, 112px) calc(50vw - 50%) clamp(80px, 8vw, 104px);
  display: grid; gap: clamp(40px, 4.4vw, 56px); background-color: var(--aplat-sousbois); color: var(--sur-aplat); --focus: var(--laiton-clair);
}
:root[data-theme="soir"] .vos-mots { --carte-fond: var(--sousbois); --carte-bord: rgba(201, 164, 94, .32); --carte-ombre: 0 1px 2px rgba(0, 0, 0, .5), 0 18px 40px rgba(0, 0, 0, .55); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="jour"]) .vos-mots { --carte-fond: var(--sousbois); --carte-bord: rgba(201, 164, 94, .32); --carte-ombre: 0 1px 2px rgba(0, 0, 0, .5), 0 18px 40px rgba(0, 0, 0, .55); }
}
.vos-mots__tete { display: grid; gap: 16px; align-content: start; }
.vos-mots__tete > * { margin: 0; }
.vos-mots__tete .surtitre { color: var(--laiton-clair); }
.vos-mots__titre { font-size: var(--t-h2); line-height: 1; letter-spacing: -.015em; max-width: 12em; color: var(--sur-aplat); }
.vos-mots__selection { max-width: 34em; font-size: var(--t-petit); line-height: 1.5; color: rgba(251, 248, 241, .78); }
.vos-mots .apercu__texte { color: rgba(251, 248, 241, .82); border-color: var(--laiton-clair); }

/* La note Google : le chiffre en affiche, les étoiles, le nombre, la date du relevé et le seul bouton de la section. */
.vos-mots__note {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: end; gap: 20px 28px;
  padding: 28px 0; border-block: 1px solid rgba(251, 248, 241, .22);
}
.vos-mots__note > * { margin: 0; }
.vos-mots__chiffre { margin: 0; display: flex; align-items: baseline; gap: 10px; }
.vos-mots__valeur { font-family: var(--font-titre); font-size: var(--t-affiche); line-height: .82; letter-spacing: -.02em; color: var(--laiton-clair); font-variant-numeric: lining-nums; }
.vos-mots__sur { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1; color: var(--sur-aplat); }
.vos-mots__google { display: grid; gap: 8px; padding-bottom: 6px; }
.vos-mots__google > p { margin: 0; }
.etoiles { display: block; width: 136px; height: 24px; overflow: visible; }
.etoiles__trait use { fill: none; stroke: var(--laiton-clair); stroke-width: 1.4; stroke-linejoin: round; }
.etoiles__plein use { fill: var(--laiton-clair); fill-opacity: .9; }
.vos-mots__nombre { font-size: var(--t-petit); line-height: 1.4; color: var(--sur-aplat); }
.vos-mots__releve { color: rgba(251, 248, 241, .7); }
.vos-mots__laisser { grid-column: 1 / -1; justify-self: start; }

/* Les cartes d'avis : en relief, de biais, le guillemet de Gloock en laiton qui dépasse en haut à gauche. */
.vos-mots__cartes { list-style: none; margin: 0; padding: 12px 0 0; display: grid; gap: 40px 32px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); align-items: start; }
.vos-mots__carte {
  position: relative; margin: 0; padding: 40px 28px 24px; background: var(--carte-fond); color: var(--encre);
  border: 1px solid var(--carte-bord); border-radius: var(--r-carte); box-shadow: var(--carte-ombre); rotate: -.8deg;
}
.vos-mots__carte:nth-child(even) { rotate: .7deg; }
.vos-mots__carte figure { margin: 0; display: grid; gap: 18px; }
.vos-mots__guillemet {
  position: absolute; top: -26px; left: 20px; font-family: var(--font-titre); font-size: 88px; line-height: 1; color: var(--laiton);
  pointer-events: none; user-select: none;
}
.vos-mots__texte, .vos-mots__citation { margin: 0; }
.vos-mots__texte p { margin: 0; font-size: var(--t-corps); line-height: 1.6; color: var(--encre); }
.vos-mots__carte--une { grid-column: 1 / -1; padding: 48px clamp(28px, 4vw, 56px) 28px; rotate: -.4deg; }
.vos-mots__citation p { margin: 0; max-width: 26em; font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1.16; letter-spacing: -.01em; color: var(--encre); }
.vos-mots__source { display: flex; flex-wrap: wrap; gap: 4px 12px; padding-top: 14px; border-top: 1px dashed var(--trait); color: var(--laiton-texte); }
.vos-mots__prenom { color: var(--encre); }
.vos-mots__controle { margin: 0; max-width: 52em; color: rgba(251, 248, 241, .72); }
.vos-mots__controle .a-confirmer { color: var(--laiton-clair); border-color: var(--laiton-clair); }
@media (min-width: 900px) {
  .vos-mots { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(48px, 6vw, 96px); }
  .vos-mots__note { align-self: end; column-gap: 36px; }
  .vos-mots__cartes, .vos-mots__controle { grid-column: 1 / -1; }
  .vos-mots__cartes { padding-top: 20px; }
  /* Sans avis publiable : la note seule, sur toute la largeur, le bouton à droite (revue du 27/10/2026). */
  .vos-mots--note-seule { grid-template-columns: minmax(0, 1fr); }
  .vos-mots--note-seule .vos-mots__note { grid-template-columns: auto minmax(0, 1fr) auto; align-self: auto; }
  .vos-mots--note-seule .vos-mots__laisser { grid-column: auto; justify-self: end; }
}

/* Le fil du comptoir : l'actualité de la boutique, reprise de son compte Instagram (outils/pages.py, fil_comptoir()).
   Sur le papier, des cartes datées : la photo en 4:5, ou une carte typographique sur le sous-bois et son semis. Sur
   téléphone, un fil horizontal au pouce, la carte suivante en aperçu ; sur ordinateur, une grille. Aucun défilement
   automatique. L'appel à suivre le compte ferme la section sur le sous-bois. Gloock jamais sous 24 px. */
.actualites { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; padding: clamp(56px, 7vw, 104px) 0; border-top: 1px solid var(--trait); }
.actualites__tete { display: grid; gap: 12px; align-content: start; }
.actualites__tete > * { margin: 0; }
.actualites__surtitre, .actualites__recente { color: var(--laiton-texte); }
.actualites__titre { font-size: var(--t-grand); line-height: 1.02; letter-spacing: -.02em; max-width: 12em; }
.actualites__phrase { max-width: 34em; font-size: var(--t-chapo); line-height: 1.4; font-weight: 500; color: var(--encre-douce); }
.actualites__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 32px 24px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.actualites__vide { margin: 0; max-width: 34em; padding: 20px 0; border-top: 1px solid var(--trait); border-bottom: 1px solid var(--trait); color: var(--encre-douce); }
.actualites__pied { display: grid; gap: 14px; }
.actualites__abonnes { margin: 0; color: var(--encre-douce); font-variant-numeric: tabular-nums; }
.actualites__suite { margin: 0; }

.actu { position: relative; min-width: 0; } /* contient les .cache des liens : sans lui, ils sortent du fil et élargissent la page */
.actu__carte { display: flex; flex-direction: column; gap: 12px; height: 100%; }
.actu__carte > * { margin: 0; }
.actu__visuel { position: relative; aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--r-etiquette); background: var(--lin); }
.actu__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.actu__meta { color: var(--laiton-texte); }
.actu__meta time { white-space: nowrap; }
.actu__titre { font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; text-wrap: balance; overflow-wrap: anywhere; hyphens: auto; }
.actu__texte { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); max-width: 34em; }
/* Le repère d'un reel : une étiquette ivoire, le triangle de lecture au trait et le mot. Rien ne joue. */
.actu__reel { position: absolute; top: 10px; left: 10px; display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px 4px 6px; border-radius: var(--r-etiquette); background: var(--sur-aplat); color: var(--aplat-sousbois); }
.actu__lecture { width: 18px; height: 18px; flex: none; color: var(--laiton); }
/* La carte typographique : le sous-bois et son semis, au même format que les photos, le titre en grand. */
.actu__affiche { aspect-ratio: 4 / 5; display: flex; flex-direction: column; justify-content: flex-end; gap: 14px; padding: clamp(20px, 2.4vw, 28px); border-radius: var(--r-etiquette); background-color: var(--aplat-sousbois); color: var(--sur-aplat); }
.actu__affiche > * { margin: 0; }
.actu__affiche .actu__meta { color: var(--laiton-clair); }
.actu__affiche .actu__titre { font-size: clamp(28px, 3vw, 40px); line-height: 1.04; color: var(--sur-aplat); }
.actu__affiche .actu__reel { position: static; align-self: flex-start; }
.actu__conditions { display: grid; gap: 6px; padding: 12px 14px; border-left: 2px solid var(--laiton); background: var(--lin); border-radius: 0 var(--r-etiquette) var(--r-etiquette) 0; }
.actu__conditions > * { margin: 0; }
.actu__conditions-titre { color: var(--laiton-texte); }
.actu__conditions p:last-child { font-size: var(--t-petit); line-height: 1.5; }
.actu__liens { margin-top: auto !important; display: flex; flex-wrap: wrap; align-items: center; gap: 0 20px; }
.actu__lot { --c: var(--aplat-sousbois); }
.actu__lot::before { content: ""; width: 9px; height: 9px; margin-right: 8px; border-radius: 50%; background: var(--c); flex: none; }
.actu__lot[data-arome="zeste"] { --c: var(--aplat-zeste); }
.actu__lot[data-arome="terre"] { --c: var(--aplat-terre); }
.actu__lot[data-arome="baie"] { --c: var(--aplat-baie); }
.actu__lot[data-arome="fleur"] { --c: var(--aplat-fleur); }
.actu__instagram { display: inline-flex; align-items: center; min-height: 44px; font-size: var(--t-petit); color: var(--encre-douce); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; text-decoration-color: var(--trait); }
@media (hover: hover) and (pointer: fine) {
  .actu__instagram:hover { color: var(--encre); text-decoration-color: var(--laiton); }
}
@media (max-width: 899px) {
  /* Le fil au pouce : une carte et le bord de la suivante. L'aimantation reste souple (proximity) : un lien atteint au
     clavier n'est jamais ramené hors de l'écran. Une carte ne dépasse pas 340 px, pour qu'une tablette voie la suivante. */
  .actualites__liste {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: min(74vw, 340px); column-gap: 16px;
    overflow-x: auto; scroll-snap-type: x proximity; overscroll-behavior-x: contain; scrollbar-width: thin; scrollbar-color: var(--laiton) transparent;
    margin-inline: calc(var(--gouttiere) * -1); padding: 0 var(--gouttiere) 8px; scroll-padding-inline: var(--gouttiere);
  }
  .actu { scroll-snap-align: start; }
  /* Au clavier, l'aimantation se suspend : le navigateur amène le lien à l'écran et rien ne le ramène en arrière. */
  .actualites__liste:focus-within { scroll-snap-type: none; }
  /* Les liens d'une carte, l'un sous l'autre : aucun ne déborde de sa carte. */
  .actu__liens { flex-direction: column; align-items: flex-start; }
}
/* La barre de défilement ne se cache qu'au toucher. À la souris, elle reste, fine et laiton. */
@media (max-width: 899px) and (pointer: coarse) {
  .actualites__liste { scrollbar-width: none; }
  .actualites__liste::-webkit-scrollbar { display: none; }
}
@media (min-width: 900px) {
  .actualites { column-gap: clamp(48px, 6vw, 96px); }
  .actualites__liste { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* L'appel à suivre le compte : les trois raisons, le bouton, la mention de majorité. Sur le lin (Merci, votre espace),
   ou sur le sous-bois et son semis à la fin du fil. Ni cadeau, ni case, ni fenêtre. */
.suivre { display: grid; gap: 14px; align-content: start; padding: clamp(24px, 3vw, 36px); border-top: 2px solid var(--laiton); border-radius: 0 0 var(--r-carte) var(--r-carte); background: var(--lin); color: var(--encre); text-align: left; }
.suivre > * { margin: 0; }
.suivre__surtitre { color: var(--laiton-texte); }
.suivre__titre { font-family: var(--font-titre); font-weight: 400; font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.01em; }
.suivre__raisons { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.suivre__raisons li { position: relative; padding-left: 20px; font-size: var(--t-petit); line-height: 1.5; }
.suivre__raisons li::before { content: ""; position: absolute; left: 2px; top: .62em; width: 7px; height: 7px; border-radius: 50%; background: var(--laiton); }
.suivre__action { padding-top: 4px; }
.suivre__bouton { min-height: 48px; padding-inline: 24px; }
.suivre__mention { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }
.suivre--fil { background-color: var(--aplat-sousbois); background-image: url('/assets/marque/semis.svg'); background-size: 96px 96px; color: var(--sur-aplat); border-top-color: var(--laiton-clair); --focus: var(--laiton-clair); }
.suivre--fil .suivre__surtitre { color: var(--laiton-clair); }
.suivre--fil .suivre__titre { color: var(--sur-aplat); }
.suivre--fil .suivre__raisons li::before { background: var(--laiton-clair); }
.suivre--fil .suivre__mention { color: rgba(251, 248, 241, .8); }
.suivre--fil .apercu__texte, .film__apercu .apercu__texte { color: rgba(251, 248, 241, .86); border-color: var(--laiton-clair); }
.suivre--merci { width: 100%; max-width: 560px; margin-top: 40px; }
.suivre--espace { margin-top: 8px; margin-bottom: 48px; }
@media (min-width: 900px) {
  .suivre--fil { grid-template-columns: minmax(0, 4fr) minmax(0, 5fr) auto; column-gap: clamp(32px, 4vw, 64px); align-items: center; }
  .suivre--fil > .apercu, .suivre--fil > .suivre__surtitre { grid-column: 1 / -1; }
  .suivre--fil .suivre__mention { grid-column: 1 / -1; }
  .suivre--espace { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); column-gap: clamp(48px, 6vw, 96px); }
  .suivre--espace > * { grid-column: 2; }
  .suivre--espace > .suivre__titre { grid-column: 1; grid-row: 1 / span 4; }
}
@media (max-width: 599px) {
  .suivre__bouton { width: 100%; }
}
/* Le pied : la mention de majorité du compte, et son repère d'aperçu sur le sous-bois. */
.pied__mention { color: rgba(251, 248, 241, .7); }
.pied .a-confirmer { color: var(--laiton-clair); border-bottom-color: var(--laiton-clair); }

/* Le carton du comptoir : téléphone, horaires, remises en boutique. Une étiquette ivoire, des filets. */
.carton { display: grid; align-content: start; padding: clamp(24px, 3vw, 40px); background: var(--ivoire); border: 1px solid var(--trait); border-radius: var(--r-carte); box-shadow: var(--ombre-carte); }
.carton__nom { font-size: var(--t-titre); line-height: 1; margin-bottom: 12px; }
.carton__bloc { display: grid; gap: 8px; padding: 18px 0; border-top: 1px dashed var(--trait); }
.carton__bloc > * { margin: 0; }
.carton__titre { font-family: var(--font-etiquette); font-size: var(--t-etiquette); line-height: 1.3; color: var(--laiton-texte); }
.carton__telephone { font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1.05; font-variant-numeric: tabular-nums; }
.carton__tel { display: inline-flex; min-height: 44px; align-items: center; color: inherit; text-decoration-thickness: 1px; text-underline-offset: 6px; text-decoration-color: var(--laiton); white-space: nowrap; }
.carton__horaires { font-variant-numeric: tabular-nums; }
.carton__precision { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }
.carton__remises { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.carton__remises li { display: flex; align-items: baseline; gap: 14px; }
.carton__remise { font-family: var(--font-titre); font-size: 40px; line-height: 1.1; color: var(--laiton-texte); min-width: 3.2em; font-variant-numeric: tabular-nums; }

/* La recherche : un grand titre, un champ, des résultats en lignes sur filets, les mots trouvés surlignés de lin. */
.chercher { display: grid; gap: 40px; padding-bottom: 32px; }
.chercher__tete { display: grid; gap: 18px; max-width: 46rem; }
.chercher__tete > * { margin: 0; }
.chercher__tete .surtitre { color: var(--laiton-texte); }
.chercher__titre { font-size: var(--t-display); line-height: .9; letter-spacing: -.02em; }
.chercher__form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: end; }
.chercher__form .btn { min-height: 48px; }
.chercher__champ input { width: 100%; min-width: 0; -webkit-appearance: none; appearance: none; }
.chercher__statut { color: var(--encre-douce); }
.chercher__resultats { display: grid; gap: 48px; }
.chercher__groupe { display: grid; gap: 8px; align-content: start; }
.chercher__groupe-titre { display: flex; align-items: baseline; gap: 12px; font-size: var(--t-titre); padding-bottom: 12px; border-bottom: 1px solid var(--encre); }
.chercher__compte { color: var(--laiton-texte); }
.chercher__liste { list-style: none; margin: 0; padding: 0; }
.resultat { display: grid; gap: 4px; padding: 16px 0; border-bottom: 1px dashed var(--trait); color: inherit; text-decoration: none; }
.resultat__repere { color: var(--encre-douce); font-size: var(--t-mini); }
.resultat__titre { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.1; }
.resultat__extrait { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); max-width: 46em; overflow-wrap: anywhere; }
.resultat mark { background: var(--lin); color: var(--encre); border-radius: 2px; padding: 0 1px; box-shadow: inset 0 -2px 0 var(--laiton); }
@media (hover: hover) and (pointer: fine) { .resultat:hover .resultat__titre { color: var(--laiton-texte); } }
.chercher__vide { display: grid; gap: 8px; }
.chercher__vide > * { margin: 0; }
.chercher__vide-titre { font-family: var(--font-titre); font-size: var(--t-titre); line-height: 1.1; }
.chercher__pistes { display: flex; flex-wrap: wrap; gap: 4px 24px; }
@media (min-width: 900px) { .chercher__resultats { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 64px; align-items: start; } }
@media (max-width: 599px) { .chercher__titre { font-size: var(--t-affiche); } }

/* Mouvement réduit : le choix se coche d'un coup. */
@media screen and (prefers-reduced-motion: reduce) {
  .choix input::after, .guide__progression span { transition: none !important; }
}

/* Le bouton d'appel flottant : sur téléphone seulement, là où un numéro se compose d'un geste. Sur ordinateur, le
   numéro est dans le pied, le carton du comptoir et la livraison du soir ; le bouton fixe y masquait du contenu. */
@media (min-width: 900px) { .appel { display: none; } }

/* ── « Prévenez-moi quand il revient » (app.js, formulaireRetour). Sur la fiche d'un lot épuisé : un carton ivoire au filet
   de laiton, comme les étiquettes de la maison, le titre en Gloock. Sur la carte de /lots : un lien qui déplie le même
   formulaire sur place, au-dessus du lien qui couvre la carte. Aucune fenêtre. */
.retour-lot { display: grid; gap: 10px; margin-top: 28px; padding: 22px 22px 18px; background: var(--ivoire); color: var(--encre); border: 1px solid var(--trait); border-radius: var(--r-etiquette); outline: 1px solid var(--laiton); outline-offset: -6px; }
.retour-lot > * { margin: 0; }
.retour-lot__surtitre { color: var(--laiton-texte); }
.retour-lot__titre { font-size: var(--t-h3); line-height: 1.08; letter-spacing: -.01em; text-wrap: balance; }
.retour-lot__texte { color: var(--encre-douce); font-size: var(--t-petit); line-height: 22px; text-wrap: pretty; }
.retour-lot__formulaire { display: grid; gap: 12px; margin-top: 6px; }
.retour-lot__formulaire[hidden], .retour-lot__formulaire [hidden] { display: none; }
.retour-lot__bouton { justify-self: start; }
.retour-lot__message:empty { display: none; }
.retour-lot__message:focus { outline: none; }
.retour-lot__note { margin: 0; font-size: var(--t-mini); line-height: 18px; color: var(--encre-douce); text-wrap: pretty; }
.retour-lot--carte { position: relative; z-index: 2; gap: 0; margin-top: 2px; padding: 0; background: none; border: 0; outline: 0; }
.retour-lot__ouvrir { justify-self: start; font-size: var(--t-petit); text-align: left; }
.retour-lot--carte .retour-lot__formulaire { margin-top: 4px; padding: 16px 16px 14px; background: var(--ivoire); border: 1px solid var(--trait); border-radius: var(--r-etiquette); }
.retour-lot--carte .retour-lot__bouton { justify-self: stretch; }
@media (min-width: 900px) {
  /* La colonne d'achat ne reste plus collée quand elle porte le formulaire : il resterait sous le bas de l'écran. */
  .fiche__achat:has(.retour-lot) { position: static; }
}

/* ══ Relecture du 26/10/2026 ════════════════════════════════════════════════════════════════════════════════════════
   Accessibilité (WCAG 2.4.7, 2.4.11, 2.4.12, 2.5.8), un seul système de composants, et l'étiquette de lot rendue à son
   seul usage : désigner un lot. */

/* Le lien d'évitement devient visible au clavier, sous le bandeau démo ; la cible #contenu reçoit le focus (tabindex). */
.cache:focus-visible {
  position: fixed !important; top: calc(var(--haut-demo) + 8px); left: 16px; z-index: 100; width: auto; height: auto; clip: auto;
  overflow: visible; padding: 12px 16px; background: var(--papier); color: var(--encre); font-weight: 600;
  outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-etiquette);
}
main:focus { outline: none; }

/* Une carte d'une rangée qui défile, quand elle porte le focus, montre son texte tout de suite (app.js la ramène). */
@media (max-width: 899px) {
  :is(.etagere, .rayon) > .est-hors-champ:focus-within :is(.carte__corps, .relance__corps) { opacity: 1; pointer-events: auto; }
}

/* Rien ne se cache sous le bouton d'appel ni sous une barre d'achat : le défilement vers un élément s'arrête au-dessus. */
@media (max-width: 899px) {
  html { scroll-padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  html:has(.fiche__barre), html:has(.panier__barre:not(.est-masquee)) { scroll-padding-bottom: calc(164px + env(safe-area-inset-bottom)); }
  .pied { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
}

/* Le bouton d'appel : un rond de 48 px, un combiné au trait, nommé par aria-label. Il attend qu'on ait quitté le premier
   écran (app.js, boutonAppel()) et s'efface quand un champ de formulaire a le focus. */
.appel { width: 48px; height: 48px; min-height: 48px; padding: 0; justify-content: center; }
/* Recette du 27/10/2026 : sur le sous-bois de la maison et du pied, le disque d'encre se fondait dans l'aplat et seul le
   combiné restait. Un anneau de papier de 2 px le détache de tout fond : clair sur les aplats sombres, à peine visible
   sur le papier, où le disque d'encre suffit. En Soir, le disque de laiton garde son anneau d'encre de nuit. */
.appel { box-shadow: 0 0 0 2px var(--papier), 0 0 0 3px rgba(31, 42, 34, .18), 0 8px 24px rgba(31, 42, 34, .22); }
/* Sur un fond trop proche du disque (app.js, contrasteAppel()), le disque change d'encre : ivoire sur les aplats sombres,
   encre sur les fonds clairs. Le combiné prend la couleur opposée. */
.appel.appel--sur-sombre { background: var(--sur-aplat); color: #1F2A22; box-shadow: 0 0 0 2px rgba(31, 42, 34, .5), 0 8px 24px rgba(0, 0, 0, .3); }
.appel.appel--sur-clair { background: #1F2A22; color: var(--sur-aplat); }
.appel__icone { width: 22px; height: 22px; }
.appel__texte { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.appel__sentinelle { position: absolute; top: 0; left: 0; width: 1px; height: 100vh; height: 100svh; pointer-events: none; }
html.appel-differe .appel { transition: opacity 200ms var(--sortie), translate 200ms var(--sortie), visibility 0s linear 0s; }
html.appel-differe .appel:not(.est-visible) { opacity: 0; visibility: hidden; translate: 0 12px; }
body:has(:is(input, select, textarea):focus) .appel { opacity: 0; visibility: hidden; }
@media screen and (prefers-reduced-motion: reduce) { html.appel-differe .appel { transition: none; translate: none; } }

/* L'en-tête : les rubriques à gauche (Les lots, L'Herbier, Le comptoir), les outils à droite (loupe, espace, thème,
   panier). Sur ordinateur, les rubriques en texte ; sur téléphone, tout en pictos de 44 px, chacun nommé. */
.entete nav { flex: 1; justify-content: space-between; gap: 24px; margin-left: clamp(24px, 4vw, 56px); }
.entete__rubriques, .entete__outils { display: flex; align-items: center; gap: 24px; }
.entete__outils { gap: 16px; }
.entete nav .entete__panier .entete__icone, .entete nav .entete__lots .entete__icone { display: none; }
@media (max-width: 600px) {
  .entete__logo { min-width: 44px; justify-content: center; }
  .entete nav { justify-content: flex-end; gap: 0; margin-left: 0; }
  .entete__rubriques, .entete__outils { gap: 0; }
  .entete nav :is(.entete__lots, .entete__herbier, .entete__boutique, .entete__recherche, .entete__compte, .entete__panier),
  .entete .bascule-theme { justify-content: center; min-width: 44px; width: 44px; padding: 0; }
  .entete nav .entete__panier { position: relative; }
  .entete nav .entete__panier .entete__icone, .entete nav .entete__lots .entete__icone { display: block; }
  .entete nav .entete__panier .pastille-panier { position: absolute; top: 2px; right: -2px; min-width: 18px; height: 18px; padding: 0 4px; margin: 0; font-size: var(--t-mini); }
  .entete nav :is(.entete__panier, .entete__lots)[aria-current="page"]::after { left: 12px; right: 12px; bottom: 6px; }
}
@media (max-width: 374px) {
  .entete nav :is(.entete__lots, .entete__herbier, .entete__boutique, .entete__recherche, .entete__compte, .entete__panier),
  .entete .bascule-theme { min-width: 42px; width: 42px; }
  .entete__logo { min-width: 42px; }
}
/* Sous 360 px (iPhone SE de première génération, ou zoom à 200 %) : des cibles de 36 × 44 px, et le panier reste à
   l'écran. Il n'est jamais l'élément sacrifié. */
@media (max-width: 359px) {
  .entete__interieur { gap: 4px; }
  .entete nav :is(.entete__lots, .entete__herbier, .entete__boutique, .entete__recherche, .entete__compte, .entete__panier),
  .entete .bascule-theme { min-width: 36px; width: 36px; }
  .entete__logo { min-width: 36px; }
}

/* Cibles tactiles : 44 px au moins. */
.maison a[href^="tel:"] { min-height: 44px; display: inline-flex; align-items: center; }
.faq .lien-laiton, .question__lien .lien-laiton { min-height: 44px; }
.alphabet a, .alphabet__vide { min-width: 44px; }

/* Un seul rayon (celui de l'étiquette), une seule ombre, réservée à l'étiquette de lot. */
.carton, .guide__carte, .guide__resultat, .reassurance, .lieu__plan img, .ouverture__lien, .carte__lien::before { border-radius: var(--r-etiquette); }
.carton, .guide__carte, .guide__resultat, .etiquette-mini, .herbier-accueil__une { box-shadow: none; }

/* Les thèmes de la FAQ : le même filtre que l'Herbier (DM Mono, capitales, coins carrés). */
.faq__sommaire a {
  min-height: 44px; padding: 0 16px; border-radius: var(--r-controle); background: var(--ivoire);
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase;
}
.faq__compte { font-family: var(--font-etiquette); font-size: var(--t-etiquette); font-weight: 500; letter-spacing: .08em; color: var(--laiton-texte); }

/* « En bref » à plat : papier, filet de laiton de 2 px à gauche, numéros en DM Mono. Ni rotation, ni ombre, ni double
   filet : c'est un résumé, pas un lot. Même chose pour l'encadré de l'article à la une et la carte de l'accueil. */
.en-bref { background: transparent; border: 0; border-left: 2px solid var(--laiton); border-radius: 0; outline: 0; box-shadow: none; rotate: none; padding: 4px 0 4px 24px; }
@media (min-width: 900px) { .en-bref { padding: 4px 0 4px 32px; } }
.une__bref { rotate: none; outline: 0; box-shadow: none; border-radius: 0; background: transparent; color: inherit; border-left: 2px solid var(--laiton-clair); padding: 4px 0 4px 24px; }
.une__bref .une__bref-titre { color: var(--laiton-clair); text-align: left; }
.une__bref .une__bref-liste li { border-top-color: rgba(251, 248, 241, .22); }
.une__bref .une__bref-liste li::before { color: var(--laiton-clair); }
.une__bref .lien-laiton { color: var(--laiton-clair); border-top-color: rgba(251, 248, 241, .4); justify-content: flex-start; }
.herbier-accueil__une { rotate: none; outline: 0; background: transparent; border: 0; border-top: 1px solid var(--encre); border-left: 2px solid var(--laiton); border-radius: 0; padding: 24px 0 24px 24px; }
.herbier-accueil__une:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

/* L'étiquette de lot en spécimen, dans un article (Lire un certificat, 0,3 % de THC). */
.article__etiquette { margin: 32px 0 8px; display: flex; justify-content: center; }
.etiquette-lot--article { width: min(340px, 100%); }

/* Le repère d'aperçu dans une ligne de liste (index de l'Herbier, recherche). */
.apercu__texte--ligne { display: inline-flex; margin-left: 12px; padding: 1px 8px; min-height: 0; font-size: var(--t-mini); letter-spacing: .1em; vertical-align: 1px; }
.resultat .apercu__texte--ligne { margin: 4px 0 0; justify-self: start; }
.une__apercu .apercu__texte { color: rgba(251, 248, 241, .86); border-color: var(--laiton-clair); }

/* Les bandeaux de famille de l'article « Les quatre familles » : l'aplat de la famille, le titre en ivoire, ses lots. */
.famille-bandeau { display: grid; gap: 20px; margin: 0 0 24px; padding: 28px 24px 0; background: var(--aplat-sousbois); color: var(--sur-aplat); border-radius: var(--r-etiquette); overflow: hidden; }
.famille-bandeau[data-arome="zeste"] { background: var(--aplat-zeste); }
.famille-bandeau[data-arome="terre"] { background: var(--aplat-terre); }
.famille-bandeau[data-arome="baie"] { background: var(--aplat-baie); }
.famille-bandeau[data-arome="fleur"] { background: var(--aplat-fleur); }
.famille-bandeau__titre.article__h2 { margin: 0; color: var(--sur-aplat); font-size: var(--t-titre); line-height: 1.05; }
.famille-bandeau__lots { list-style: none; margin: 0; padding: 0; display: flex; align-items: flex-end; gap: 12px; }
.famille-bandeau__lots li { flex: 0 1 160px; min-width: 0; }
.famille-bandeau__img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; object-position: 50% 100%; filter: url(#detourage) drop-shadow(0 10px 12px rgba(20, 12, 4, .28)); }
@media (max-width: 599px) { .famille-bandeau { margin-inline: calc(var(--gouttiere) * -1); padding-inline: var(--gouttiere); border-radius: 0; } }

/* Le certificat spécimen de « Lire un certificat » : un dessin maison, aucune valeur, cinq renvois. */
.certificat { margin: 32px 0 8px; display: grid; gap: 16px; }
.certificat__dessin { width: 100%; max-width: 560px; height: auto; }
.certificat__papier { fill: var(--ivoire); stroke: var(--trait); stroke-width: 1.5; }
.certificat__trait { fill: var(--trait); }
.certificat__filet { stroke: var(--trait); stroke-width: 1; }
.certificat__filet--fort { stroke: var(--encre); stroke-width: 1.5; }
.certificat__libelle, .certificat__case { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; fill: var(--encre-douce); }
.certificat__case { font-size: var(--t-corps); letter-spacing: .04em; fill: var(--encre); }
.certificat__case--vide { fill: var(--encre-douce); }
.certificat__tampon { font-family: var(--font-etiquette); font-size: 64px; letter-spacing: .2em; fill: none; stroke: var(--laiton); stroke-width: 1.5; opacity: .55; }
.certificat__appel circle { fill: var(--laiton); }
.certificat__appel text { font-family: var(--font-etiquette); font-size: var(--t-petit); font-weight: 500; fill: #FBF8F1; }
.certificat__legende { display: grid; gap: 10px; }
.certificat__legende .etiquette { color: var(--laiton-texte); }
.certificat__renvois { list-style: none; margin: 0; padding: 0; display: grid; border-top: 1px solid var(--encre); }
.certificat__renvois li { display: flex; align-items: center; gap: 14px; min-height: 44px; border-bottom: 1px solid var(--trait); }
.certificat__renvois .repere { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--laiton); color: #FBF8F1; font-family: var(--font-etiquette); font-size: var(--t-mini); flex: none; }
.certificat__renvois a { color: var(--encre); text-decoration-color: var(--laiton); text-underline-offset: 5px; min-height: 44px; display: inline-flex; align-items: center; }

/* Les lots cités : quatre colonnes au plus, le sol teinté de l'aplat de la famille. */
@media (min-width: 720px) { .lots-cites { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); } }
@media (min-width: 1100px) { .lots-cites { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.lot-cite[data-arome="zeste"] .lot-cite__sol { background: color-mix(in srgb, var(--aplat-zeste) 18%, var(--lin)); }
.lot-cite[data-arome="terre"] .lot-cite__sol { background: color-mix(in srgb, var(--aplat-terre) 18%, var(--lin)); }
.lot-cite[data-arome="baie"] .lot-cite__sol { background: color-mix(in srgb, var(--aplat-baie) 18%, var(--lin)); }
.lot-cite[data-arome="fleur"] .lot-cite__sol { background: color-mix(in srgb, var(--aplat-fleur) 18%, var(--lin)); }

/* La méta d'un article : chaque segment insécable, le point en fin du segment précédent (jamais seul en début de ligne). */
.article__meta > span + span::before, .une .une__meta > span + span::before { content: none; }
.article__meta-segment { white-space: nowrap; }
.article__meta-segment:not(:last-child)::after { content: "·"; margin: 0 12px; color: var(--laiton); }
.une .une__meta .article__meta-segment:not(:last-child)::after { color: var(--laiton-clair); }

/* Le fil d'Ariane : sous 900 px, le dernier maillon (le titre, que le H1 répète) se tait. */
@media (max-width: 899px) {
  .ariane li:last-child:not(:first-child) { display: none; }
}

/* Le sommaire d'un article, dans un <details> : ouvert sur ordinateur, fermé sous 900 px (app.js, sommairePlie()). */
.sommaire__plier > summary { list-style: none; cursor: pointer; display: flex; align-items: center; }
.sommaire__plier > summary::-webkit-details-marker { display: none; }
.sommaire__compte { display: none; }
@media (max-width: 899px) {
  .sommaire { border: 1px solid var(--trait); border-radius: var(--r-etiquette); padding: 0 16px; }
  .sommaire__plier > summary { margin: 0; min-height: 48px; }
  .sommaire__plier > summary::after { content: "+"; margin-left: auto; font-family: var(--font-etiquette); font-size: var(--t-corps); color: var(--laiton-texte); }
  .sommaire__plier[open] > summary::after { content: "−"; }
  .sommaire__plier[open] > .sommaire__liste { margin-bottom: 16px; }
  .sommaire__compte { display: inline; white-space: pre; }
}
/* Sur ordinateur, le titre du sommaire n'est plus un bouton (app.js, sommairePlie() : hors tabulation, sans repli). */
@media (min-width: 900px) { .sommaire__plier > summary { cursor: default; } }

/* Les renvois de l'index : la flèche reste collée au dernier mot. */
.renvoi__titre::after { content: "\00a0→"; }

/* La recherche, page utilitaire : un titre de section, une seule colonne, une vignette pour les lots. */
.chercher__titre { font-size: var(--t-h2); line-height: .95; }
@media (max-width: 599px) { .chercher__titre { font-size: var(--t-h2); } }
@media (min-width: 900px) { .chercher__resultats { grid-template-columns: minmax(0, 1fr); max-width: 52rem; } }
.resultat--lot { grid-template-columns: 64px minmax(0, 1fr); column-gap: 16px; align-items: start; }
.resultat--lot > :not(.resultat__vignette) { grid-column: 2; }
.resultat__vignette { grid-column: 1; grid-row: 1 / span 4; width: 64px; height: 64px; object-fit: contain; background: var(--lin); border-radius: var(--r-etiquette); }

/* Le comptoir : les villes voisines en une ligne de liens sous le plan. */
.villes { padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0 18px; }
.villes__titre { margin: 0; color: var(--encre-douce); }
.villes__liste { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 18px; }
.villes__liste a { display: inline-flex; align-items: center; min-height: 44px; font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .06em; color: var(--laiton-texte); text-underline-offset: 5px; }

/* L'accueil : la livraison du soir en une ligne, expliquée au comptoir. */
.soir-renvoi { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 20px; margin: 0; padding: 28px 0; border-top: 1px solid var(--trait); border-bottom: 1px solid var(--trait); }
.soir-renvoi__surtitre { color: var(--laiton-texte); }

/* La quantité d'un lot qu'on ne peut pas choisir : grisée comme ses boutons. */
.quantite output.est-inactive { color: var(--encre-douce); }
.btn[aria-disabled="true"] { opacity: .6; cursor: progress; }

/* Le chapitre L’Herbier de l’accueil, sur une seule rangée sur ordinateur : trois articles côte à côte (un écran). */
@media (min-width: 900px) {
  .herbier-accueil__tete { margin-bottom: 40px; }
  .herbier-accueil__corps { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); column-gap: 40px; }
  .herbier-accueil__une { padding: 24px 0 24px 24px; }
  .herbier-accueil__une-titre { font-size: var(--t-h3); }
  .sommaire-herbier--accueil { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 40px; }
  .sommaire-herbier--accueil .entree { border-bottom: 0; }
}

/* Un écran par promesse : les respirations de l’accueil se resserrent sur ordinateur (12 479 px avant la relecture). */
@media (min-width: 900px) {
  .totem { min-height: 60svh; padding-block: clamp(88px, 8vw, 112px) clamp(72px, 7vw, 96px); }
  .analyse { row-gap: 64px; padding: 72px 0 80px; }
  .invite-bulletin { padding-block: clamp(72px, 7vw, 104px) clamp(80px, 7vw, 112px); }
  .invite-bulletin__cachet { margin-bottom: 32px; }
}
@media (min-width: 900px) {
  .chapitre.herbier-accueil { padding-block: 40px 16px; }
  .herbier-accueil__tete { margin-bottom: 32px; }
  .soir-renvoi { padding-block: 20px; }
}

/* L'accueil sous 9 000 px sur ordinateur : les formes et l'analyse sur un écran resserré, la cueillette sans marge haute en double. */
@media (min-width: 900px) {
  .formes { min-height: max(560px, 70svh); }
  .analyse { row-gap: 48px; padding: 64px 0 64px; }
  .chapitre.cueillette { padding-block: 40px; }
  .maison__interieur { padding-block: 88px; }
  .hors-nuancier { padding-block: 24px 20px; }
  .cueillette__tete { margin-bottom: 32px; }
  .invite-bulletin { padding-block: 56px 64px; }
  .invite-bulletin__cachet { margin-bottom: 24px; }
  .invite-bulletin__formulaire { margin-top: 28px; }
  .analyse { padding: 48px 0 56px; }
  .chapitre.herbier-accueil { padding-block: 32px 8px; }
  .analyse__scene { row-gap: 40px; }
  .totem { min-height: 0; padding-block: 88px 72px; }
  .maison { min-height: 0; }
}

/* ══ Confiance, preuve et image : les pièces de la maison (docs/plan-confiance-et-image.md) ═══════════════════════════
   Chaque pièce sert une preuve réelle. Papier, sous-bois, laiton ; Gloock jamais sous 24 px ; DM Mono pour ce qui se
   vérifie (registre, identité, numéros). Aucune couleur d'alerte, aucun cadenas, aucune étoile. */

/* Les pictogrammes de service (assets/pictos/) : 24 px, trait de laiton, toujours à côté de leur texte. */
.picto { flex: none; display: block; width: 24px; height: 24px; color: var(--laiton); }
/* Posé par le script (étiquette de la fiche) : le même dessin en masque, au laiton du thème. */
.picto-masque { display: inline-block; flex: none; width: 1.3em; height: 1.3em; margin-right: .35em; vertical-align: -.3em; background: var(--laiton); -webkit-mask: var(--picto) center / contain no-repeat; mask: var(--picto) center / contain no-repeat; }
.picto-masque--document { --picto: url('/assets/pictos/document-en-attente.svg'); }

/* Les empreintes (G2) : le contour d'un vrai détourage, en masque, au laiton du thème. Décoratives, états vides seulement. */
.empreinte { display: block; width: min(220px, 56vw); aspect-ratio: var(--ratio, 2); background: var(--laiton); -webkit-mask: var(--forme) center / contain no-repeat; mask: var(--forme) center / contain no-repeat; }
.empreinte--3-fois-filtre { --forme: url('/assets/empreintes/3-fois-filtre.svg'); --ratio: 491 / 238; }
.empreinte--afghan { --forme: url('/assets/empreintes/afghan.svg'); --ratio: 491 / 222; }
.empreinte--amnesia-premium { --forme: url('/assets/empreintes/amnesia-premium.svg'); --ratio: 491 / 291; }
.empreinte--beldia { --forme: url('/assets/empreintes/beldia.svg'); --ratio: 491 / 371; }
.empreinte--blueberry { --forme: url('/assets/empreintes/blueberry.svg'); --ratio: 325 / 182; }
.empreinte--caramelo { --forme: url('/assets/empreintes/caramelo.svg'); --ratio: 491 / 272; }
.empreinte--cookie-cream { --forme: url('/assets/empreintes/cookie-cream.svg'); --ratio: 491 / 381; }
.empreinte--creme { --forme: url('/assets/empreintes/creme.svg'); --ratio: 491 / 296; }
.empreinte--ct-hq { --forme: url('/assets/empreintes/ct-hq.svg'); --ratio: 491 / 154; }
.empreinte--ice-o-lator { --forme: url('/assets/empreintes/ice-o-lator.svg'); --ratio: 491 / 258; }
.empreinte--jaune { --forme: url('/assets/empreintes/jaune.svg'); --ratio: 490 / 328; }
.empreinte--moonrock { --forme: url('/assets/empreintes/moonrock.svg'); --ratio: 491 / 247; }
.empreinte--purple { --forme: url('/assets/empreintes/purple.svg'); --ratio: 491 / 279; }
.empreinte--white-custum { --forme: url('/assets/empreintes/white-custum.svg'); --ratio: 491 / 225; }
.vide__empreinte { margin-bottom: 4px; }
.chercher__empreinte { width: min(180px, 48vw); margin-bottom: 12px; }
.lots__vide { display: grid; gap: 18px; justify-items: center; padding: 56px 0 24px; text-align: center; }
.lots__vide > p { margin: 0; }

/* A3. « Avant de commander » : quatre faits sous la fiche, sur des filets, en deux colonnes dès 700 px. */
.faits { display: grid; gap: 18px; padding: 56px 0 8px; }
.faits__titre { margin: 0; color: var(--laiton-texte); }
.faits__liste { list-style: none; margin: 0; padding: 0; display: grid; border-top: 1px solid var(--encre); }
.fait { display: flex; gap: 16px; align-items: flex-start; padding: 22px 0; border-bottom: 1px solid var(--trait); }
.fait__picto { margin-top: 1px; }
.fait__texte { min-width: 0; }
.fait__texte > p { margin: 0; }
.fait__nom { font-weight: 600; line-height: 1.4; }
.fait__texte > .fait__detail { margin-top: 4px; font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }
.fait__lien { display: inline-flex; align-items: center; min-height: 44px; margin-block: -12px; font-family: var(--font-etiquette); font-size: var(--t-corps); letter-spacing: .04em; color: var(--laiton-texte); text-underline-offset: 4px; font-variant-numeric: tabular-nums; }
@media (min-width: 700px) { .faits__liste { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 48px; } }

/* A4. Le paiement en trois temps : le dessin, puis trois colonnes alignées sur ses cadres (14, 50, 86 %). */
.paiement-schema { margin: 0; display: grid; gap: 14px; min-width: 0; }
.paiement-schema__titre { color: var(--laiton-texte); }
.paiement-schema__img { display: block; width: 100%; height: auto; }
.paiement-schema__temps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; text-align: center; }
.paiement-schema__temps li { display: grid; gap: 4px; align-content: start; }
.paiement-schema__numero { color: var(--laiton-texte); }
.paiement-schema__temps strong { font-weight: 600; font-size: var(--t-petit); line-height: 1.35; }
.paiement-schema__temps li > span:last-child { font-size: var(--t-mini); line-height: 1.5; color: var(--encre-douce); text-wrap: pretty; }
/* Au panier (dans le ticket) et sous 600 px : une liste, le numéro à gauche. */
.paiement-schema--ticket { padding: 18px 0 20px; border-block: 1px dashed var(--trait); }
.paiement-schema--ticket .paiement-schema__temps { grid-template-columns: minmax(0, 1fr); gap: 10px; text-align: left; }
.paiement-schema--ticket .paiement-schema__temps li { grid-template-columns: 30px minmax(0, 1fr); column-gap: 8px; row-gap: 2px; }
.paiement-schema--ticket .paiement-schema__numero { grid-row: span 2; padding-top: 2px; }
@media (max-width: 599px) {
  .paiement-schema__temps { grid-template-columns: minmax(0, 1fr); gap: 10px; text-align: left; }
  .paiement-schema__temps li { grid-template-columns: 30px minmax(0, 1fr); column-gap: 8px; row-gap: 2px; }
  .paiement-schema__numero { grid-row: span 2; padding-top: 2px; }
}
.paiement-schema--merci { width: 100%; max-width: 680px; margin-top: 16px; padding-top: 28px; border-top: 1px solid var(--trait); }
.paiement-schema--faq { margin: 20px 0 8px; padding: 18px 0; border-block: 1px solid var(--trait); }

/* A1. La carte d'identité de la maison : DM Mono, filet de laiton, rien à croire sur parole. */
.identite { display: grid; gap: 32px; padding: 72px 0; border-top: 1px solid var(--trait); }
.identite__tete { display: grid; gap: 14px; align-content: start; }
.identite__tete > * { margin: 0; }
.identite__titre { max-width: 11em; font-size: var(--t-titre); line-height: 1; letter-spacing: -.015em; }
.identite__phrase { max-width: 30em; color: var(--encre-douce); }
.identite__carte { display: grid; gap: 14px; align-content: start; padding: clamp(20px, 3vw, 32px); background: var(--ivoire); border: 1px solid var(--trait); border-top: 2px solid var(--laiton); border-radius: var(--r-etiquette); }
.identite__carte > p { margin: 0; }
.identite__lignes { margin: 0; display: grid; }
.identite__lignes div { display: grid; grid-template-columns: minmax(0, 11em) minmax(0, 1fr); gap: 4px 16px; padding: 11px 0; border-bottom: 1px solid var(--trait); }
.identite__lignes dt { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 20px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.identite__lignes dd { margin: 0; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-petit); line-height: 20px; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.identite__tel { display: flex; align-items: center; gap: 12px; }
.identite__tel-lien { display: inline-flex; align-items: center; min-height: 44px; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-corps); letter-spacing: .04em; color: var(--encre); text-underline-offset: 4px; font-variant-numeric: tabular-nums; }
@media (max-width: 599px) { .identite__lignes div { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 900px) { .identite { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: clamp(48px, 6vw, 96px); padding-block: 96px; } }

/* C2. Le Carnet expliqué en public : trois temps, sa règle (ou « barème à confirmer »), et la carte spécimen. */
.carnet-public { display: grid; gap: 40px; padding: 80px 0; border-top: 1px solid var(--trait); }
.carnet-public__texte { display: grid; gap: 18px; align-content: start; }
.carnet-public__texte > * { margin: 0; }
.carnet-public__titre { font-size: var(--t-h2); line-height: .95; letter-spacing: -.015em; }
.carnet-public__temps { list-style: none; padding: 0; border-top: 1px solid var(--encre); }
.carnet-public__temps li { display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--trait); }
.carnet-public__temps .etiquette { padding-top: 4px; color: var(--laiton-texte); }
.carnet-public__temps p { margin: 0; }
.carnet-public__regles { display: grid; gap: 10px; padding: 18px 20px; background: var(--lin); border-left: 2px solid var(--laiton); border-radius: var(--r-etiquette); }
.carnet-public__regles div { display: grid; grid-template-columns: minmax(0, 8em) minmax(0, 1fr); gap: 4px 16px; }
.carnet-public__regles dt { font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 22px; letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-texte); }
.carnet-public__regles dd { margin: 0; font-weight: 500; }
.carnet-public__garde, .carnet-public__distinct { max-width: 34em; font-size: var(--t-petit); line-height: 1.55; color: var(--encre-douce); }
.carnet-public__specimen { margin: 0; display: grid; gap: 14px; justify-items: center; align-content: center; }
.carnet-public__svg { display: block; width: min(100%, 428px); height: auto; border-radius: 18px; box-shadow: 0 1px 2px rgba(12, 20, 14, .2), 0 22px 44px rgba(12, 20, 14, .2); }
.carnet-public__legende { color: var(--encre-douce); }
@media (max-width: 599px) { .carnet-public__regles div { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 900px) {
  .carnet-public { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: clamp(48px, 6vw, 96px); padding-block: 112px; }
  .carnet-public__svg { rotate: -1.5deg; }
}
/* La carte de l'espace : les points restent, avec leur règle en dessous (décision de Rayan, 26/10/2026). */
.carnet__bareme { margin: 0; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .06em; color: rgba(251, 248, 241, .78); }

/* F1. Le film de marque, dans la maison (écran 8) : une fenêtre sur le sous-bois, son bouton toujours visible. */
.film { margin: 0; display: grid; gap: 12px; min-width: 0; }
.film__video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; background: var(--aplat-sousbois); border: 1px solid rgba(201, 164, 94, .28); border-radius: var(--r-etiquette); }
.film__legende { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; }
.film__titre { color: rgba(251, 248, 241, .72); }
.film__commandes { display: flex; flex-wrap: wrap; gap: 8px; }
.film__bouton[aria-pressed="true"] { background: rgba(201, 164, 94, .16); }
.film__bouton { min-height: 44px; padding: 0 18px; border: 1px solid rgba(201, 164, 94, .7); border-radius: var(--r-controle); background: transparent; color: var(--sur-aplat); font: 500 12px/1 var(--font-etiquette); letter-spacing: .12em; text-transform: uppercase; cursor: pointer; transition: background-color 160ms var(--sortie); }
.film__bouton:focus-visible { outline: 2px solid var(--laiton-clair); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .film__bouton:hover { background: rgba(201, 164, 94, .16); } }
/* Sur ordinateur, le film à droite du titre, le carton du comptoir dessous : l'écran garde sa hauteur et son titre. */
@media (min-width: 900px) {
  .maison__interieur:has(> .maison__film) .maison__texte { grid-column: 1 / 7; grid-row: 1; }
  .maison__film { grid-column: 7 / -1; grid-row: 1; align-self: center; }
  .maison__interieur:has(> .maison__film) .maison__pied { grid-column: 7 / -1; grid-row: 2; justify-self: start; }
  .maison__interieur:has(> .maison__film) .maison__titre { font-size: var(--t-titre); }
}

/* D1. Le registre des certificats : un tableau en DM Mono, vide aujourd'hui, et il le dit. */
.registre, .parcours, .engagements { display: grid; gap: 40px; padding-bottom: clamp(72px, 9vw, 120px); }
.registre__tete, .parcours__tete, .engagements__tete { display: grid; gap: 16px; justify-items: start; max-width: 46em; }
.registre__tete > *, .parcours__tete > *, .engagements__tete > * { margin: 0; }
.registre__titre, .parcours__titre, .engagements__titre { max-width: 12em; font-size: var(--t-h2); line-height: .95; letter-spacing: -.015em; }
.registre__attente { display: flex; gap: 14px; align-items: flex-start; max-width: 46em; padding: 20px 22px; background: var(--lin); border-left: 2px solid var(--laiton); border-radius: var(--r-etiquette); }
.registre__attente p { margin: 0; }
.registre__cadre { overflow-x: auto; border-block: 1px solid var(--encre); }
.registre__cadre:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
.registre__table { width: 100%; min-width: 600px; border-collapse: collapse; font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 1.4; font-variant-numeric: tabular-nums; }
.registre__table th { padding: 14px 12px 12px 0; text-align: left; font-weight: 500; font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); border-bottom: 1px solid var(--trait); }
.registre__table td { padding: 16px 12px 16px 0; border-bottom: 1px solid var(--trait); }
.registre__table tr:last-child td { border-bottom: 0; }
.registre__table a { color: var(--laiton-texte); text-underline-offset: 3px; }
.registre__vide-ligne td { padding-block: 36px; color: var(--encre-douce); }
.registre__suite, .parcours__suite { display: flex; flex-wrap: wrap; gap: 4px 32px; margin: 0; }

/* D2. Le parcours d'un lot : le dessin, puis ses cinq stations alignées (10, 30, 50, 70, 90 %). */
.parcours__schema { position: relative; margin: 0; }
.parcours__img { display: block; width: 100%; height: auto; }
.parcours__stations { list-style: none; margin: 28px 0 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); column-gap: 24px; }
.station { display: grid; gap: 8px; align-content: start; text-align: center; }
.station > * { margin: 0; }
.station__numero { color: var(--laiton-texte); }
.station__titre { font-size: var(--t-h3); line-height: 1.1; letter-spacing: -.005em; text-wrap: balance; }
.station__texte { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); text-wrap: pretty; }
/* Sous 700 px, le dessin vertical : chaque texte se pose à droite de sa station (à partir de 47 % de la largeur). */
@media (max-width: 699px) {
  .parcours__stations { position: absolute; inset: 0 0 0 47%; margin: 0; padding-left: 6px; grid-template-columns: minmax(0, 1fr); grid-template-rows: repeat(5, minmax(0, 1fr)); }
  .station { gap: 4px; align-content: center; text-align: left; }
  .station__titre { font-family: var(--font-texte); font-weight: 600; font-size: var(--t-corps); line-height: 1.25; letter-spacing: 0; }
  .station__texte { font-size: var(--t-petit); line-height: 1.4; }
}

/* A2. Nos engagements : l'engagement en Gloock, « Où le vérifier » en DM Mono. */
.engagements__cachet .cachet { width: 96px; }
.engagements__date { color: var(--encre-douce); }
.engagements__liste { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--encre); }
.engagement { display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; row-gap: 10px; padding: 26px 0; border-bottom: 1px solid var(--trait); }
.engagement > * { margin: 0; }
.engagement__numero { grid-row: span 2; padding-top: 8px; color: var(--laiton-texte); }
.engagement__texte { font-family: var(--font-titre); font-size: var(--t-h3); line-height: 1.15; letter-spacing: -.005em; text-wrap: pretty; }
.engagement__verifier { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); }
.engagement__ou { display: block; margin-bottom: 2px; color: var(--laiton-texte); }
.engagement__verifier .lien-laiton { margin-left: 2px; }
.engagements__suite { margin: 0; }
@media (min-width: 900px) {
  .engagement { grid-template-columns: 56px minmax(0, 7fr) minmax(0, 5fr); column-gap: 40px; align-items: baseline; padding-block: 32px; }
  .engagement__numero { grid-row: auto; }
}

/* Le guide des familles en tête de /lots : replié sous son titre, sur le lin ; il s'ouvre d'un geste. */
.guide--lots { padding-block: clamp(36px, 5vw, 64px); gap: 24px; }
.guide--lots .guide__titre { font-size: var(--t-titre); }
.guide__pli { min-width: 0; }
.guide__ouvrir { display: inline-flex; align-items: center; min-height: 52px; padding: 0 28px; border-radius: var(--r-controle); background: var(--action); color: var(--sur-action); font-weight: 600; cursor: pointer; list-style: none; }
.guide__ouvrir::-webkit-details-marker { display: none; }
.guide__ouvrir:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.guide__pli[open] > .guide__ouvrir { margin-bottom: 20px; background: transparent; color: var(--encre); border: 1px solid var(--trait); }
@media (min-width: 900px) {
  .guide--lots .guide__pli { grid-column: 2; grid-row: 1; align-self: center; }
  .guide--lots .guide__tete { position: static; }
}
/* Le résultat ouvre l'aplat de sa famille, de bas en haut ; la suite arrive après. Mouvement réduit : posé d'emblée. */
@media (prefers-reduced-motion: no-preference) {
  .guide__resultat.est-ouvert .guide__aplat { animation: guide-aplat 640ms var(--sortie) both; }
  .guide__resultat.est-ouvert .guide__suite { animation: guide-suite 480ms var(--sortie) 220ms both; }
}
@keyframes guide-aplat { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes guide-suite { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: 0 0; } }

/* Les liens de la preuve : sous l'étagère des lots, sous l'étiquette de l'accueil. */
.lots__preuve, .analyse__suite { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 28px; margin: 0; }
.lots__preuve { margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--trait); }
.lots__preuve .etiquette { color: var(--encre-douce); }
.analyse__suite { grid-column: 1 / -1; }
.etiquette-lot__attente { display: inline; }
.pied .pied__identite { margin-top: 12px; font-size: var(--t-mini); }
.pied__identite .etiquette { display: block; color: rgba(251, 248, 241, .6); }

/* Le résumé des erreurs (finition du 27/10/2026) : en tête du formulaire refusé, sur le lin, un filet de laiton à gauche.
   Jamais de rouge vif : le titre en rouille, chaque ligne mène à son champ. Une seule alerte prioritaire à l'écran. */
.resume-erreurs { display: grid; gap: 8px; margin: 0 0 20px; padding: 16px 18px; border-left: 3px solid var(--rouille); background: var(--lin); border-radius: var(--r-etiquette); }
.resume-erreurs:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
.resume-erreurs__titre { margin: 0; font-weight: 600; color: var(--rouille); }
.resume-erreurs__liste { margin: 0; padding-left: 18px; display: grid; gap: 4px; }
.resume-erreurs__liste a { color: var(--encre); text-underline-offset: .2em; }

/* ══ La bibliothèque des créations (/dev/bibliotheque, hors production) ══════════════════════════════════════════
   Un catalogue de maison : un en-tête sous-bois et semis, un sommaire numéroté, puis chaque rubrique en planches et
   cartels, comme un nuancier de parfumeur. Les planches gardent leurs couleurs en Jour comme en Soir : un logo encre
   sous-bois doit rester sur un fond clair, quel que soit le thème. Les pastilles et les tailles d'exemple sont posées
   par app.js (bibliotheque()), par le CSSOM : aucun style en ligne. */
.biblio { --planche-papier: #FBF8F1; --planche-lin: #E9E1D0; --encre-planche: #1F2A22; padding-bottom: clamp(48px, 8vw, 96px); }
.biblio__tete { margin-inline: calc(50% - 50vw); padding: clamp(56px, 9vw, 120px) var(--gouttiere) clamp(48px, 7vw, 88px); color: var(--sur-aplat); background-color: var(--aplat-sousbois); }
.biblio__tete-interieur { max-width: 1280px; margin: 0 auto; display: grid; gap: 20px; }
.biblio__tete-interieur > * { margin: 0; }
.biblio__surtitre { color: var(--laiton-clair); }
.biblio__titre { font-size: var(--t-affiche); line-height: .92; letter-spacing: -.03em; max-width: 11ch; }
.biblio__chapo { max-width: 36em; font-size: var(--t-chapo); line-height: 1.4; color: rgba(251, 248, 241, .82); }
.biblio__bande { height: 12px; }
.biblio__bande > span { height: 12px; width: 48px; }
.biblio__chiffres { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 32px; margin-top: 12px; padding-top: 24px; border-top: 1px solid rgba(201, 164, 94, .45); }
.biblio__chiffres > div { display: grid; gap: 6px; align-content: start; }
.biblio__chiffres dt { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; color: var(--laiton-clair); }
.biblio__chiffres dd { margin: 0; font-family: var(--font-titre); font-size: clamp(28px, 3.4vw, 44px); line-height: 1.05; font-variant-numeric: tabular-nums; }
.biblio__heure { display: block; margin-top: 8px; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .08em; color: rgba(251, 248, 241, .72); }
@media (min-width: 900px) { .biblio__chiffres { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Le sommaire et la légende */
.biblio__guide { display: grid; gap: 40px; padding: clamp(40px, 6vw, 72px) 0; border-bottom: 1px solid var(--encre); }
@media (min-width: 900px) { .biblio__guide { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 64px; } }
.sommaire-bib ol { list-style: none; margin: 0; padding: 0; columns: 1; }
@media (min-width: 600px) { .sommaire-bib ol { columns: 2; column-gap: 32px; } }
.sommaire-bib li { break-inside: avoid; }
.sommaire-bib__lien { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: baseline; gap: 12px; min-height: 52px; padding: 10px 0; border-top: 1px dashed var(--trait); color: var(--encre); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .sommaire-bib__lien:hover .sommaire-bib__titre { color: var(--laiton-texte); } }
.sommaire-bib__numero, .sommaire-bib__compte { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .12em; color: var(--laiton-texte); font-variant-numeric: tabular-nums; }
.sommaire-bib__titre { font-family: var(--font-titre); font-size: 24px; line-height: 1.15; transition: color 180ms var(--sortie); }
.biblio__legende { display: grid; gap: 16px; align-content: start; }
.biblio__legende-titre { margin: 0; color: var(--encre-douce); }
.legende-bib { margin: 0; display: grid; }
.legende-bib > div { display: grid; grid-template-columns: 196px minmax(0, 1fr); align-items: baseline; gap: 12px; padding: 10px 0; border-top: 1px dashed var(--trait); }
.legende-bib dt, .legende-bib dd { margin: 0; }
@media (max-width: 599px) { .legende-bib > div { grid-template-columns: minmax(0, 1fr); gap: 6px; } }
.legende-bib dd { font-size: var(--t-petit); line-height: 1.45; color: var(--encre-douce); }
.biblio__filtres { display: grid; gap: 12px; margin-top: 12px; }
.filtres-bib { display: flex; flex-wrap: wrap; gap: 8px; }
.filtre-bib { appearance: none; min-height: 44px; padding: 0 14px; border: 1px solid var(--trait); border-radius: var(--r-controle); background: var(--ivoire); color: var(--encre); font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); letter-spacing: .12em; text-transform: uppercase; cursor: pointer; touch-action: manipulation; transition: background-color 180ms var(--sortie), color 180ms var(--sortie), border-color 180ms var(--sortie); }
@media (hover: hover) and (pointer: fine) { .filtre-bib:hover { border-color: var(--encre-douce); } }
.filtre-bib[aria-pressed="true"] { background: var(--action); border-color: var(--action); color: var(--sur-action); }
.biblio__decompte { margin: 0; min-height: 24px; font-size: var(--t-petit); color: var(--encre-douce); }

/* Les statuts : une étiquette DM Mono, un point de couleur. Jamais de rouge vif : le bloqué est en rouille. */
.statut { display: inline-flex; align-items: center; gap: 8px; width: fit-content; margin: 0; padding: 4px 10px 4px 8px; border: 1px solid currentColor; border-radius: var(--r-etiquette); font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 16px; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; }
.statut::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.statut--publiable { color: var(--mousse); }
.statut--apercu { color: var(--laiton-texte); }
.statut--a-valider { color: var(--laiton-texte); border-style: dashed; }
.statut--a-valider::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.statut--controle { color: var(--encre-douce); border-style: dotted; }
.statut--bloque { color: var(--rouille); }
.statut--remplace { color: var(--encre-douce); }
.statut--remplace::before { border-radius: 1px; height: 1.5px; width: 9px; }

/* Les rubriques */
.rubrique-bib { padding-top: clamp(56px, 8vw, 104px); scroll-margin-top: calc(var(--haut-entete) + var(--haut-demo) + 16px); }
.rubrique-bib__tete { display: grid; gap: 12px 32px; margin-bottom: clamp(32px, 5vw, 56px); padding-top: 20px; border-top: 1px solid var(--encre); }
.rubrique-bib__tete > * { margin: 0; }
.rubrique-bib__numero { font-family: var(--font-titre); font-size: clamp(56px, 8vw, 112px); line-height: .85; color: var(--laiton); font-variant-numeric: tabular-nums; }
.rubrique-bib__titre { font-size: var(--t-grand); line-height: 1; letter-spacing: -.02em; }
.rubrique-bib__phrase { max-width: 40em; color: var(--encre-douce); }
@media (min-width: 900px) {
  .rubrique-bib__tete { grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); }
  .rubrique-bib__numero { grid-row: 1 / span 2; }
}
.rubrique-bib__note, .biblio__hors, .biblio__fin { max-width: 48em; margin: 0 0 32px; font-size: var(--t-petit); color: var(--encre-douce); }
.biblio__fin { margin: clamp(56px, 8vw, 96px) 0 0; padding-top: 20px; border-top: 1px solid var(--trait); }
.rubrique-bib__fournir { max-width: 48em; margin: 0 0 32px; }

/* Les planches : le fond sur lequel chaque pièce se lit. Couleurs fixes, en Jour comme en Soir. */
.planche--papier { background-color: var(--planche-papier); color: var(--encre-planche); box-shadow: inset 0 0 0 1px #D6CCB8; }
.planche--lin { background-color: var(--planche-lin); color: var(--encre-planche); }
.planche--sousbois { background-color: var(--aplat-sousbois); color: var(--sur-aplat); }
.planche--zeste { background-color: var(--aplat-zeste); color: var(--sur-aplat); }
.planche--terre { background-color: var(--aplat-terre); color: var(--sur-aplat); }
.planche--baie { background-color: var(--aplat-baie); color: var(--sur-aplat); }
.planche--fleur { background-color: var(--aplat-fleur); color: var(--sur-aplat); }
.planche--sousbois.semis { background-image: url('/assets/marque/semis.svg'); background-size: 96px 96px; }

/* Les pièces : douze colonnes sur ordinateur, une planche et son cartel. */
.pieces { list-style: none; margin: 0; padding: 0; display: grid; gap: 56px 32px; grid-template-columns: minmax(0, 1fr); }
.piece { min-width: 0; }
.piece__fiche { display: grid; gap: 20px; align-content: start; height: 100%; }
@media (min-width: 600px) {
  .pieces { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .piece { grid-column: span 6; }
  .piece--petite, .piece--portrait, .piece--specimen, .piece--bloc { grid-column: span 3; }
}
@media (min-width: 900px) {
  .pieces { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 72px 40px; }
  .piece { grid-column: span 6; }
  .piece--large { grid-column: 1 / -1; }
  .piece--large .piece__fiche { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 40px; }
  .piece--petite, .piece--portrait, .piece--specimen { grid-column: span 4; }
  .piece--bloc { grid-column: span 6; }
}
@media (min-width: 1200px) { .piece--specimen { grid-column: span 3; } }

.piece__planche { position: relative; display: flex; align-items: center; justify-content: center; gap: 16px; min-height: 200px; padding: clamp(20px, 3vw, 40px); border-radius: var(--r-etiquette); overflow: hidden; }
.piece--large .piece__planche { min-height: 280px; align-self: start; }
.piece--portrait .piece__planche { aspect-ratio: 4 / 5; min-height: 0; }
.piece--specimen .piece__planche { aspect-ratio: 1; min-height: 0; padding: 12px; }
.piece__image { max-width: 100%; max-height: 420px; width: auto; height: auto; object-fit: contain; }
.piece--portrait .piece__image { max-height: 100%; }
.piece__image--specimen { width: 100%; height: 100%; max-height: none; filter: var(--ombre-specimen); }
.piece__planche--serie { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr)); align-items: center; justify-items: center; gap: 20px; }
.piece__planche--serie .piece__image { max-height: 200px; min-width: 0; }
.piece--large .piece__planche--serie { grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); }
.piece--bloc .piece__planche { padding: 16px; background-color: var(--planche-lin); }
.piece--bloc .piece__planche--serie { grid-template-columns: repeat(auto-fit, minmax(min(110px, 100%), 1fr)); gap: 12px; }
.piece--bloc .piece__planche--serie .piece__image { max-height: 360px; box-shadow: var(--ombre-carte); }
.piece__planche--video { padding: 0; min-height: 0; background-color: var(--aplat-sousbois); }
.piece__video { display: block; width: 100%; height: auto; max-height: 640px; background: var(--aplat-sousbois); }
.piece--portrait .piece__planche--video { aspect-ratio: auto; }
.piece__planche--motif { min-height: 220px; }
.piece__planche--picto { min-height: 160px; }
.piece__picto { width: 72px; height: 72px; }
.piece__planche--police { justify-content: flex-start; min-height: 220px; }
.piece__planche--vide { min-height: 72px; padding: 16px; border: 1px dashed var(--trait); background: transparent; }
.piece__sans-apercu { margin: 0; color: var(--encre-douce); text-align: center; }
.specimen-police { margin: 0; text-wrap: balance; }
.specimen-police--titre { font-family: var(--font-titre); font-size: clamp(44px, 6vw, 88px); line-height: 1; letter-spacing: -.02em; }
.specimen-police--texte { font-family: var(--font-texte); font-size: 24px; line-height: 1.35; font-weight: 500; }
.specimen-police--etiquette { font-family: var(--font-etiquette); font-size: 18px; letter-spacing: .14em; text-transform: uppercase; }

/* Le cartel : la fiche de musée sous la planche. */
.piece__cartel { display: grid; gap: 14px; align-content: start; min-width: 0; padding-top: 16px; border-top: 1px solid var(--encre); }
.piece--large .piece__cartel { align-self: start; }
.piece__cartel > * { margin: 0; }
.piece__nom { font-size: 24px; line-height: 1.15; letter-spacing: -.01em; overflow-wrap: anywhere; }
.piece--large .piece__nom { font-size: var(--t-h3); }
.piece__donnees { display: grid; margin: 0; }
.piece__donnees > div { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; padding: 8px 0; border-top: 1px dashed var(--trait); }
.piece__donnees > div:first-child { border-top: 0; padding-top: 0; }
.piece__donnees dt { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 22px; letter-spacing: .12em; text-transform: uppercase; color: var(--encre-douce); }
.piece__donnees dd { margin: 0; font-size: var(--t-petit); line-height: 1.5; }
.piece__note { font-size: var(--t-petit); line-height: 1.5; color: var(--encre-douce); padding-left: 12px; border-left: 2px solid var(--trait); }
.piece__fournir { padding: 12px 14px; background: var(--lin); border-left: 2px solid var(--laiton); border-radius: var(--r-etiquette); font-size: var(--t-petit); line-height: 1.5; }
.piece__fournir-titre { display: block; margin-bottom: 4px; color: var(--laiton-texte); }
.piece__fichiers { list-style: none; margin: 0; padding: 0; display: grid; }
.piece__fichiers li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 16px; padding: 6px 0; border-top: 1px dashed var(--laiton); }
.fichier { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; min-width: 0; color: var(--laiton-texte); font-weight: 600; font-size: var(--t-petit); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; overflow-wrap: anywhere; }
.fichier::before { content: "↓"; flex: none; font-weight: 500; }
.fichier__chemin { font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 22px; overflow-wrap: anywhere; color: var(--encre); }
.fichier__meta { min-width: 0; overflow-wrap: anywhere; font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 22px; letter-spacing: .06em; color: var(--encre-douce); font-variant-numeric: tabular-nums; }

/* Les couleurs et les lettres */
.jetons { display: grid; gap: clamp(40px, 6vw, 72px); margin-bottom: clamp(48px, 7vw, 88px); }
.nuancier-bib { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; }
@media (min-width: 900px) { .nuancier-bib { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.nuancier-bib__bande { display: grid; grid-template-rows: 1fr auto auto; min-height: clamp(220px, 32vw, 380px); padding: 16px; border-radius: var(--r-etiquette); }
.nuancier-bib__nom { font-family: var(--font-titre); font-size: clamp(32px, 4vw, 56px); line-height: 1; }
.nuancier-bib__valeur { align-self: end; margin-top: 8px; padding: 6px 8px; width: fit-content; max-width: 100%; background: var(--sur-aplat); color: var(--encre-planche); font-family: var(--font-etiquette); font-size: var(--t-mini); line-height: 16px; letter-spacing: .04em; border-radius: var(--r-etiquette); overflow-wrap: anywhere; }
.nuances { display: grid; gap: 32px; }
@media (min-width: 600px) { .nuances { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .nuances { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.nuances__titre { margin: 0 0 12px; color: var(--encre-douce); }
.nuances__liste { list-style: none; margin: 0; padding: 0; display: grid; }
.nuance { display: grid; grid-template-columns: 44px minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 12px; align-items: center; padding: 10px 0; border-top: 1px dashed var(--trait); }
.nuance__pastille { grid-row: 1 / span 2; width: 44px; height: 44px; border-radius: var(--r-controle); box-shadow: inset 0 0 0 1px var(--trait); }
.nuance__nom { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .06em; color: var(--encre); }
.nuance__valeurs { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .04em; color: var(--encre-douce); }
.echelle__liste { list-style: none; margin: 0; padding: 0; display: grid; }
.echelle__pas { display: grid; gap: 4px 24px; align-items: baseline; padding: 14px 0; border-top: 1px dashed var(--trait); min-width: 0; }
@media (min-width: 900px) { .echelle__pas { grid-template-columns: 280px minmax(0, 1fr); } }
.echelle__jeton { font-family: var(--font-etiquette); font-size: var(--t-mini); letter-spacing: .06em; color: var(--encre-douce); overflow-wrap: anywhere; }
.echelle__exemple { min-width: 0; overflow-wrap: anywhere; line-height: 1.1; }
.echelle__exemple--titre { font-family: var(--font-titre); font-size: 24px; letter-spacing: -.01em; }
.echelle__exemple--texte { font-family: var(--font-texte); line-height: 1.4; }
.echelle__exemple--etiquette { font-family: var(--font-etiquette); letter-spacing: .12em; text-transform: uppercase; }
.echelle__note { margin: 16px 0 0; font-size: var(--t-petit); color: var(--encre-douce); }

/* Les familles d'arômes : l'aplat, le lot de référence en très grand, puis le cartel. */
.familles-bib { list-style: none; margin: 0 0 32px; padding: 0; display: grid; gap: 48px 24px; }
@media (min-width: 600px) { .familles-bib { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .familles-bib { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.famille-bib { display: grid; gap: 20px; align-content: start; min-width: 0; }
.famille-bib__aplat { position: relative; display: grid; grid-template-rows: auto minmax(0, 1fr); aspect-ratio: 3 / 4; padding: 24px; border-radius: var(--r-etiquette); overflow: hidden; }
.famille-bib__nom { margin: 0; font-family: var(--font-titre); font-size: clamp(48px, 6vw, 80px); line-height: .95; letter-spacing: -.02em; }
.famille-bib__specimen { align-self: end; justify-self: center; width: 100%; height: 100%; object-fit: contain; object-position: center bottom; filter: var(--ombre-specimen); }
.famille-bib__cartel { display: grid; gap: 14px; padding-top: 16px; border-top: 1px solid var(--encre); }
.famille-bib__cartel > * { margin: 0; }

/* ══ L'en-tête sur téléphone : le menu (recette du 27/10/2026) ═══════════════════════════════════════════════════════
   Huit pictogrammes sans libellé ne se lisaient pas en trois secondes. Sur téléphone, avec le script : le logo, le panier
   (picto, mot « Panier » et pastille, toujours à l'écran) et un bouton « Menu » écrit en toutes lettres. Le menu tombe
   sous l'en-tête : les trois rubriques en Gloock, puis la recherche, l'espace et le thème, chacun avec son libellé.
   Sans script, l'ancienne rangée de pictos nommés reste (les règles ci-dessus). Sur ordinateur, rien ne change. */
.entete__tiroir { display: flex; flex: 1; align-items: center; justify-content: space-between; gap: 24px; min-width: 0; }
.entete nav { justify-content: flex-start; }
.entete__menu { display: none; }
@media (min-width: 601px) { .entete nav .entete__panier { margin-left: -8px; } }
@media (max-width: 600px) {
  html.js .entete nav { flex: none; margin-left: auto; gap: 8px; }
  html.js .entete__tiroir { display: none; }
  /* Le panier : le picto, le mot et la pastille. Il n'est jamais rangé dans le menu. */
  html.js .entete nav .entete__panier { width: auto; min-width: 44px; gap: 6px; padding: 0 6px; }
  html.js .entete nav .entete__panier .entete__libelle { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
  html.js .entete nav .entete__panier .pastille-panier { position: static; margin: 0; }
  html.js .entete nav .entete__panier[aria-current="page"]::after { left: 6px; right: 6px; }
  /* Le bouton « Menu » : la pilule du thème, deux traits d'encre qui se croisent quand le menu est ouvert. */
  html.js .entete__menu {
    appearance: none; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 16px 0 14px;
    border: 1px solid var(--trait); border-radius: 999px; background: none; color: var(--encre); cursor: pointer; touch-action: manipulation;
    font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); letter-spacing: .14em; text-transform: uppercase;
  }
  html.js .entete__menu[aria-expanded="true"] { border-color: var(--encre); }
  .entete__menu-traits { position: relative; display: block; width: 16px; height: 10px; }
  .entete__menu-traits::before, .entete__menu-traits::after { content: ""; position: absolute; left: 0; right: 0; height: 1.5px; border-radius: 1px; background: currentColor; transition: translate 180ms var(--sortie), rotate 180ms var(--sortie); }
  .entete__menu-traits::before { top: 1px; }
  .entete__menu-traits::after { bottom: 1px; }
  .entete__menu[aria-expanded="true"] .entete__menu-traits::before { translate: 0 3.5px; rotate: 45deg; }
  .entete__menu[aria-expanded="true"] .entete__menu-traits::after { translate: 0 -3.5px; rotate: -45deg; }
  /* Le menu ouvert : une feuille de papier sous l'en-tête, aussi haute que son contenu, jamais plus que l'écran. */
  html.js .entete__tiroir.est-ouvert {
    position: absolute; top: 100%; left: 0; right: 0; display: grid; gap: 8px; align-content: start;
    max-height: calc(100svh - var(--haut-demo) - var(--haut-entete)); overflow-y: auto; overscroll-behavior: contain;
    padding: 8px var(--gouttiere) 28px; background: var(--papier); border-bottom: 1px solid var(--trait); box-shadow: 0 24px 40px rgba(31, 42, 34, .14);
  }
  html.js .est-ouvert .entete__rubriques { display: grid; gap: 0; }
  html.js .est-ouvert .entete__rubriques a {
    width: auto; min-width: 0; min-height: 60px; justify-content: flex-start; gap: 14px; padding: 0;
    border-bottom: 1px solid var(--trait); font-family: var(--font-titre); font-weight: 400; font-size: 32px; line-height: 1; letter-spacing: -.01em;
  }
  html.js .est-ouvert .entete__rubriques .entete__icone { display: none; }
  html.js .est-ouvert .entete__outils { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; padding-top: 12px; }
  html.js .est-ouvert .entete__outils a { width: auto; min-width: 0; gap: 8px; padding: 0; font-size: var(--t-corps); }
  html.js .est-ouvert .entete__outils .entete__icone, html.js .est-ouvert .entete__outils .entete__loupe { display: block; }
  html.js .est-ouvert :is(.entete__libelle, .entete__recherche .entete__libelle, .bascule-theme__texte) { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
  html.js .est-ouvert .bascule-theme { width: auto; min-width: 0; gap: 8px; padding: 0 16px 0 12px; border-color: var(--trait); }
  html.js .est-ouvert .bascule-theme__icone { display: block; }
  /* La page en cours : un trait de laiton court, sous le mot, pas sur toute la largeur. */
  html.js .est-ouvert a[aria-current]::after { left: 0; right: auto; width: 28px; bottom: 10px; }
  html.js .est-ouvert .entete__outils a[aria-current]::after { bottom: 6px; }
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="jour"]) .entete__tiroir.est-ouvert { box-shadow: 0 24px 40px rgba(0, 0, 0, .45); } }
:root[data-theme="soir"] .entete__tiroir.est-ouvert { box-shadow: 0 24px 40px rgba(0, 0, 0, .45); }
@media (prefers-reduced-motion: reduce) { .entete__menu-traits::before, .entete__menu-traits::after { transition: none; } }

/* ══ Le repère d'aperçu, plus discret (recette du 27/10/2026) ═════════════════════════════════════════════════════════
   Le cadre pointillé en capitales espacées prenait deux lignes et attirait l'œil avant le contenu. Il reste partout où il
   était, mais sur une ligne : DM Mono 13 px en bas de casse, un point de laiton devant, aucun cadre. S'il ne tient pas,
   il se coupe en points de suspension (le texte entier reste lu). Sur les aplats sombres, l'ivoire atténué. */
.apercu { max-width: 100%; }
.apercu__texte, .apercu__texte--ligne {
  display: inline-block; max-width: 100%; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0;
  font-family: var(--font-etiquette); font-weight: 500; font-size: var(--t-mini); line-height: 18px; letter-spacing: .02em; text-transform: none;
  color: var(--encre-douce); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: baseline;
}
.apercu__texte::before { content: ""; display: inline-block; width: 6px; height: 6px; margin-right: 8px; border-radius: 50%; background: var(--laiton); vertical-align: 1px; }
.apercu__texte--ligne { display: block; margin-top: 6px; }
.soir__apercu .apercu__texte, .suivre--fil .apercu__texte, .film__apercu .apercu__texte, .une__apercu .apercu__texte { color: rgba(251, 248, 241, .78); }
.soir__apercu .apercu__texte::before, .suivre--fil .apercu__texte::before, .film__apercu .apercu__texte::before, .une__apercu .apercu__texte::before { background: var(--laiton-clair); }
/* Dans la carte 01 de L'Herbier de l'accueil, la flèche suit la durée de lecture : elle ne tombe plus seule sous le repère. */
.herbier-accueil__meta::after { content: none; }
.herbier-accueil__duree::after { content: "  →"; white-space: pre; }

/* ══ La croix d'effacement des champs de recherche (recette du 27/10/2026) ═══════════════════════════════════════════
   Le navigateur la dessinait en bleu. Elle prend l'encre douce de la maison, au trait de 1,6 px comme les pictos de
   l'en-tête, et le laiton au survol. Le dessin est un masque : la couleur suit le thème. */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none; width: 18px; height: 18px; margin-left: 8px; cursor: pointer;
  background-color: var(--encre-douce);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") center / 18px 18px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") center / 18px 18px no-repeat;
}
@media (hover: hover) and (pointer: fine) { input[type="search"]::-webkit-search-cancel-button:hover { background-color: var(--laiton-texte); } }

/* La FAQ à 390 px (recette du 27/10/2026) : en flex, un titre de thème sur deux lignes rejetait « · 6 » en colonne à
   sa droite. Le titre redevient un bloc de texte ; le compteur suit le dernier mot, accroché par des insécables. */
.faq__theme { display: block; }
.faq__compte { white-space: nowrap; margin-left: .2em; vertical-align: .15em; }

/* ══ Le fil du comptoir sur ordinateur (recette du 27/10/2026) ═══════════════════════════════════════════════════════
   1. Au comptoir, cinq cartes sur quatre colonnes laissaient la cinquième seule sur sa rangée. À cinq (ou neuf), la plus
      récente passe à la une : deux colonnes, deux rangées, et les quatre autres se rangent à côté. Le nombre vient de la
      génération, puis du navigateur et du serveur quand une actualité expire (data-fil-compte).
   2. Les liens d'une carte, toujours l'un sous l'autre, en bas de carte : « Voir sur Instagram » tombe à la même
      hauteur d'une carte à l'autre, qu'il y ait un « Voir le lot » ou non.
   3. Le titre d'une carte typographique ne se coupe plus au milieu d'un mot (« d'Hallowee / n ») : un corps plus juste. */
.actu__liens { flex-direction: column; align-items: flex-start; gap: 0; }
.actu__titre { overflow-wrap: break-word; }
.actu__affiche .actu__titre { font-size: clamp(26px, 2.2vw, 36px); }
@media (min-width: 900px) {
  .actualites__liste[data-fil-max="0"]:is([data-fil-compte="5"], [data-fil-compte="9"]) > .actu:not([hidden]):not(.actu:not([hidden]) ~ .actu) { grid-column: span 2; grid-row: span 2; }
  .actualites__liste[data-fil-max="0"]:is([data-fil-compte="5"], [data-fil-compte="9"]) > .actu:not([hidden]):not(.actu:not([hidden]) ~ .actu) .actu__affiche .actu__titre { font-size: clamp(40px, 4.4vw, 72px); }
  /* La carte à la une remplit ses deux rangées : son affiche ou sa photo s'étire, le texte reste dessous. */
  .actualites__liste[data-fil-max="0"]:is([data-fil-compte="5"], [data-fil-compte="9"]) > .actu:not([hidden]):not(.actu:not([hidden]) ~ .actu) :is(.actu__affiche, .actu__visuel) { aspect-ratio: auto; flex: 1 1 auto; min-height: 360px; }
}
