/* LA POLICE — Inter (DA v2, fondateur 03/10), servie par l'app : aucun appel à un tiers à l'ouverture.
   Sous-ensemble latin (le français entier, l'euro) ; ce qu'il n'a pas retombe sur la police du téléphone.
   Licence : fonts/OFL-Inter.txt. */
@font-face{font-family:Inter;font-style:normal;font-weight:400 800;font-display:swap;src:url(/fonts/inter-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
  /* L'AMBIANCE — un seul état sur la racine, toute la lumière en dépend.
     Le fondu se fait par TRANSITION CSS sur les couches d'ambiance : le JS n'écrit
     que le nom de l'état. (Note de terrain : dans un onglet qui ne produit pas de
     frames, ni les transitions ni requestAnimationFrame n'avancent — getComputedStyle
     y renvoie alors la dernière valeur échantillonnée. Vérifier par capture, pas par
     lecture de style.) */
  :root{
    --air:#DCE6F3; --air-2:#C2D3E9; --deep:#A7BEDE; --void:#EFF5FB;
    --vig:rgba(70,108,148,.42); --shadow:rgba(24,62,102,.40);
    --pane:rgba(255,255,255,.80); --pane-2:rgba(255,255,255,.52);
    --edge:rgba(112,150,186,.30); --edge-2:rgba(112,150,186,.15);
    --grid:rgba(50,96,142,.22);
    --ink:#132230; --ink-2:#4C6579; --ink-3:#8299AD;
    --light:#1D93CC; --light-hi:#6ACEF2; --glow:rgba(29,147,204,.40);
    --warm:#BC8829;--rouge:#C9302C; --screen:#ECF2F9;
    --sh-1:0 6px 14px -8px rgba(18,58,92,.34), 0 1px 2px -1px rgba(18,58,92,.20);
    --sh-2:0 16px 40px -22px rgba(18,58,92,.50), 0 2px 6px -3px rgba(18,58,92,.22);
    --sh-3:0 34px 80px -30px rgba(18,58,92,.62), 0 6px 20px -10px rgba(18,58,92,.22);
    --grain:.055;
    --mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,monospace;
    --sans:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;   /* Inter : DA v2 du 03/10, servie par l’app (fonts/) */
    /* ══ L'ÉCHELLE TYPO (charte lot 3 — l'échelle d'Apple sur la pile système) ══
       SIX styles, tokens UNIQUES — toute taille de texte du fil se dit par eux :
       large 34/600/−.022  titre de panneau, grand total
       title 22/600/−.014  titre de carte étendue, prix vedette
       head  17/600/−.006  titre de rangée, prix en tête de fiche
       body  17/400        la parole du fil (et les champs : 17 ≥ 16, zoom iOS couvert)
       foot  13/400        provenance, réserves, méta
       cap   12/500        badges (nature datée, états)
       (le tableau de la charte donne 700 au Large title ; sa propre règle dit
       400/600 — 600 posé, la garde des graisses ne s'affaiblit pas : décision
       fondateur listée en passation) */
    --t-large:34px; --t-title:22px; --t-head:17px; --t-body:15px; --t-champ:16px; --t-foot:13px; --t-cap:12px;
    --t-large-ls:-.022em; --t-title-ls:-.014em; --t-head-ls:-.006em;
    /* ══ LES 4 RENDUS DE BOUTON (charte loi 4) — tokens uniques, consommés par les
       chefs de file ; les 22 classes gardent leur NOM (lexique interne figé), leur
       rendu s'aligne. LA TABLE :
       plein  (acte principal, 1-2/vue) : .cta-plein · .fcelui · .btn · .lv-ok ·
               .conf-go · .conf-oui · .btn-n armé (.sn-env/.fn-env)
       teinté (secondaire)              : .pill · .pack-opt · .cmd · .dmenu button ·
               .dtik-go · .recup · .replay · .evq/.evqi (stepper) · .cta-sec
       nu     (lien, repli, prise)      : .lien-sec · .dretour ·
               .dclose · .freposer · .garder · .dprise · .send · .plus · .cam ·
               .ligne-r · .dcorps-r · .cmd-go · .cmd-feedback
       argent (l'acte d'argent, SEUL à s'étirer, montant au libellé) :
               .cta-payer (.abo-payer) · .cta-plein.vert (.cmd-valider — Payer) */
    --btn-plein-bg:linear-gradient(180deg,var(--light-hi),var(--light));
    --btn-plein-ink:#03202B;
    --btn-teinte-bg:var(--pane); --btn-teinte-edge:var(--edge); --btn-teinte-ink:var(--ink);
    --btn-nu-ink:var(--ink-2);
    --btn-argent-bg:linear-gradient(180deg,#5fe3b2,#22c08a);
    --btn-argent-ink:#04241A;
    --btn-argent-halo:0 14px 34px -14px rgba(40,200,140,.4), 0 1px 0 rgba(255,255,255,.45) inset;
    --ease:cubic-bezier(.22,1,.36,1);
    --pw:min(340px, calc(100vw - 74px));
    /* MATIÈRE A — la plaque minérale (fondateur, planche matiere-cartes : « c'est A »).
       Déclinaison CLAIRE de la même logique : biseau clair en haut, tranche sombre en
       bas, ombre franche. Les valeurs sombres EXACTES vivent dans le bloc dark. */
    --carte-bg:linear-gradient(172deg, rgba(255,255,255,.95), rgba(255,255,255,.75) 45%, rgba(228,239,250,.62));
    --carte-edge:rgba(112,150,186,.38);
    --carte-biseau:rgba(255,255,255,.98);
    --carte-tranche:rgba(24,62,102,.45);

    /* les courbes de la famille — une scène, pas dix effets */
    --e-main :cubic-bezier(.22,.86,.28,1);  /* franche, longue queue, aucun rebond */
    --e-pouce:cubic-bezier(.22,.92,.26,1);  /* un geste humain : part vite, s'arrête net */
    --e-plat :cubic-bezier(.30,.70,.40,1);  /* rien à dire : ni attaque ni chute */
    --e-pic  :cubic-bezier(.18,.80,.24,1);  /* le verdict */
    --e-monde:cubic-bezier(.24,.62,.22,1);  /* ça vient de loin : longue approche, arrêt sourd */
    --e-chute:cubic-bezier(.55,0,.92,.42);  /* la SEULE accélération de la scène */

    /* ═══ LE CHEF D'ORCHESTRE ═══
       Un seul état, porté par la racine, pilote TOUTE la lumière de la page en même
       temps : le halo derrière l'appareil, l'horizon, l'aurore, la lueur de l'écran et
       la poussière. Aucune lumière n'est plus locale — c'est la condition pour que la
       lumière puisse dire quelque chose plutôt que briller.
       Le doigt écrit dans ce même état : quand tu tiens une carte, l'app retient son souffle. */
    --amb:.72;        /* l'intensité de l'ambiance, 0 → 1 */
    --amb-scale:1;    /* son étendue */
    --amb-rot:0deg;   /* sa température : 0 = le cyan de Rabbit · -154deg = l'ambre du doute */
    --amb-speed:1;    /* la vitesse de la poussière — lue par le canvas */
    --amb-dust:1;     /* sa présence */
    /* l'attitude de l'appareil, −0,5 → 0,5. Écrite par le gyroscope (ou la souris),
       elle ne nourrit QUE des reflets. Défaut à 0 : sans capteur, rien ne manque. */
    --tiltx:0; --tilty:0;
  }
  /* il attend                     */ :root[data-etat="ecoute"] {--amb:.50;--amb-scale:.96;--amb-speed:.85;}
  /* il regarde ta photo           */ :root[data-etat="regarde"]{--amb:.40;--amb-scale:.88;--amb-speed:1.55;}
  /* il sait ce que c'est          */ :root[data-etat="nomme"]  {--amb:.74;--amb-scale:1.03;--amb-speed:.95;}
  /* il travaille                  */ :root[data-etat="cherche"]{--amb:.64;--amb-scale:1.00;--amb-speed:1.95;}
  /* LE VERDICT — le pic           */ :root[data-etat="trouve"] {--amb:1.00;--amb-scale:1.20;--amb-speed:.70;}
  /* il ne sait pas                */ :root[data-etat="doute"]  {--amb:.34;--amb-scale:.90;--amb-rot:-154deg;--amb-speed:.60;}
  /* il refuse de faire partir     */ :root[data-etat="refuse"] {--amb:.24;--amb-scale:.86;--amb-rot:-154deg;--amb-speed:.45;}
  /* c'est gravé                   */ :root[data-etat="scelle"] {--amb:.86;--amb-scale:1.04;--amb-speed:.80;}
  /* le monde répond               */ :root[data-etat="revient"]{--amb:.42;--amb-scale:1.12;--amb-speed:1.25;}
  /* TU tiens quelque chose        */ :root[data-etat="tiens"]  {--amb:.26;--amb-scale:.88;--amb-speed:.10;--amb-dust:.45;}
  /* tu EXAMINES : le monde se tait */ :root[data-etat="examen"] {--amb:.16;--amb-scale:.82;--amb-speed:.04;--amb-dust:.30;}
  @media (prefers-color-scheme:dark){:root{
    --air:#04070B;--air-2:#081420;--deep:#1B2350;--void:#020407;
    --vig:rgba(1,3,6,.88);--shadow:rgba(0,0,0,.82);
    --pane:rgba(130,175,210,.11);--pane-2:rgba(130,175,210,.055);
    --edge:rgba(145,190,225,.19);--edge-2:rgba(145,190,225,.085);
    --grid:rgba(120,190,235,.11);
    --ink:#E8F2FA;--ink-2:#A0B8CA;--ink-3:#6B8394;
    --light:#6ACDF4;--light-hi:#B9EAFD;--glow:rgba(106,205,244,.34);
    --warm:#DFB04E;--rouge:#FF6B60;--screen:#060D14;--grain:.075;
    --carte-bg:linear-gradient(172deg, rgba(160,200,235,.16), rgba(130,175,210,.07) 45%, rgba(90,130,170,.05));
    --carte-edge:rgba(160,205,240,.32);
    --carte-biseau:rgba(220,240,255,.42);
    --carte-tranche:rgba(8,16,26,.9);
    --sh-1:0 6px 14px -8px rgba(0,0,0,.72), 0 1px 2px -1px rgba(0,0,0,.5);--sh-2:0 16px 40px -22px rgba(0,0,0,.82), 0 2px 6px -3px rgba(0,0,0,.5);--sh-3:0 30px 72px -32px rgba(0,0,0,.85);--p-atmo:#D8F2FF;--p-halo:color-mix(in srgb,var(--light) 46%,var(--deep));--p-file:#EAF7FF;--etoiles:.9;}}
  :root[data-theme="dark"],.vignette[data-design="dark"]{--air:#04070B;--air-2:#081420;--deep:#1B2350;--void:#020407;--vig:rgba(1,3,6,.88);--shadow:rgba(0,0,0,.82);--sh-1:0 6px 14px -8px rgba(0,0,0,.72), 0 1px 2px -1px rgba(0,0,0,.5);--pane:rgba(130,175,210,.11);--pane-2:rgba(130,175,210,.055);--edge:rgba(145,190,225,.19);--edge-2:rgba(145,190,225,.085);--grid:rgba(120,190,235,.11);--ink:#E8F2FA;--ink-2:#A0B8CA;--ink-3:#6B8394;--light:#6ACDF4;--light-hi:#B9EAFD;--glow:rgba(106,205,244,.34);--warm:#DFB04E;--rouge:#FF6B60;--screen:#060D14;--grain:.075;--carte-bg:linear-gradient(172deg, rgba(160,200,235,.16), rgba(130,175,210,.07) 45%, rgba(90,130,170,.05));--carte-edge:rgba(160,205,240,.32);--carte-biseau:rgba(220,240,255,.42);--carte-tranche:rgba(8,16,26,.9);--sh-2:0 16px 40px -22px rgba(0,0,0,.82), 0 2px 6px -3px rgba(0,0,0,.5);--sh-3:0 30px 72px -32px rgba(0,0,0,.85);--p-atmo:#D8F2FF;--p-halo:color-mix(in srgb,var(--light) 46%,var(--deep));--p-file:#EAF7FF;--etoiles:.9;}
  /* le SYSTÈME suit le thème : clavier iOS, barres, champs natifs — un clavier
     BLANC sur l'app nuit (capture fondateur 14/08, signet), c'est fini */
  :root[data-theme="dark"]{color-scheme:dark;}
  :root[data-theme="light"]{color-scheme:light;}
  :root[data-theme="light"],.vignette[data-design="light"]{--air:#DCE6F3;--air-2:#C2D3E9;--deep:#A7BEDE;--void:#EFF5FB;--vig:rgba(70,108,148,.42);--shadow:rgba(24,62,102,.40);--sh-1:0 6px 14px -8px rgba(18,58,92,.34), 0 1px 2px -1px rgba(18,58,92,.20);--pane:rgba(255,255,255,.80);--pane-2:rgba(255,255,255,.52);--edge:rgba(112,150,186,.30);--edge-2:rgba(112,150,186,.15);--grid:rgba(50,96,142,.22);--ink:#132230;--ink-2:#4C6579;--ink-3:#8299AD;--light:#1D93CC;--light-hi:#6ACEF2;--glow:rgba(29,147,204,.40);--warm:#BC8829;--rouge:#C9302C;--screen:#ECF2F9;--grain:.055;--carte-bg:linear-gradient(172deg, rgba(255,255,255,.95), rgba(255,255,255,.75) 45%, rgba(228,239,250,.62));--carte-edge:rgba(112,150,186,.38);--carte-biseau:rgba(255,255,255,.98);--carte-tranche:rgba(24,62,102,.45);--sh-2:0 16px 40px -22px rgba(18,58,92,.50), 0 2px 6px -3px rgba(18,58,92,.22);--sh-3:0 34px 80px -30px rgba(18,58,92,.62), 0 6px 20px -10px rgba(18,58,92,.22);--p-atmo:#FFFFFF;--p-halo:var(--light);--p-file:var(--light);--etoiles:0;}

  *{box-sizing:border-box;}
  body{background:var(--air);color:var(--ink);font-family:var(--sans);font-weight:400;line-height:1.6;
    -webkit-font-smoothing:antialiased;overflow-x:hidden;}

  /* ═══ LE FOND : quatre plans, du plus lointain au plus proche ═══ */

  /* 1. l'espace — un dégradé qui descend du vide vers l'horizon */
  .deepbg{position:fixed;inset:0;z-index:-5;pointer-events:none;
    background:
      radial-gradient(120% 78% at 50% 116%, color-mix(in srgb,var(--light) 20%,transparent), transparent 58%),
      radial-gradient(96% 62% at 50% 96%, color-mix(in srgb,var(--deep) 78%,transparent), transparent 66%),
      linear-gradient(178deg, var(--void) 0%, var(--air) 34%, var(--air-2) 74%, color-mix(in srgb,var(--deep) 42%,var(--air-2)) 100%);}
  /* la vignette : les bords tombent, le centre monte.
     Elle a sa propre teinte — en clair, réutiliser le fond l'aurait ÉCLAIRCIE. */
  .deepbg::after{content:"";position:absolute;inset:0;
    background:radial-gradient(126% 90% at 50% 42%, transparent 30%, var(--vig) 100%);}

  /* 2. l'aurore — trois masses lentes, jamais synchrones */
  .sky{position:fixed;inset:-30%;z-index:-4;pointer-events:none;
    filter:blur(64px) hue-rotate(var(--amb-rot));
    opacity:calc(.42 + var(--amb) * .58);
    transition:opacity 1.4s var(--e-main), filter 1.4s var(--e-main);}
  .cloud{position:absolute;border-radius:50%;}
  .c1{width:66vw;height:54vw;left:-14vw;top:-10vw;opacity:.42;background:radial-gradient(circle at 42% 42%, color-mix(in srgb,var(--light) 46%,transparent), transparent 66%);animation:d1 38s ease-in-out infinite;}
  .c2{width:58vw;height:48vw;right:-16vw;top:2vw;opacity:.52;background:radial-gradient(circle at 54% 46%, color-mix(in srgb,var(--deep) 88%,transparent), transparent 64%);animation:d2 47s ease-in-out infinite;}
  .c3{width:74vw;height:44vw;left:10vw;bottom:-14vw;opacity:.62;background:radial-gradient(circle at 50% 50%, color-mix(in srgb,var(--light-hi) 34%,transparent), transparent 66%);animation:d3 56s ease-in-out infinite;}
  @keyframes d1{0%,100%{transform:translate(0,0) scale(1);}50%{transform:translate(5vw,3vw) scale(1.12);}}
  @keyframes d2{0%,100%{transform:translate(0,0) scale(1.08);}50%{transform:translate(-6vw,4vw) scale(1);}}
  @keyframes d3{0%,100%{transform:translate(0,0) scale(1);}50%{transform:translate(-4vw,-3vw) scale(1.13);}}

  /* 3. le sol — une grille en perspective qui dérive vers toi */
  .floor{position:fixed;left:-60%;right:-60%;bottom:-6vh;height:62vh;z-index:-3;pointer-events:none;
    transform:perspective(560px) rotateX(76deg);transform-origin:50% 100%;opacity:.85;
    background:
      repeating-linear-gradient(90deg, transparent 0 82px, var(--grid) 82px 83px),
      repeating-linear-gradient(0deg, transparent 0 82px, var(--grid) 82px 83px);
    -webkit-mask-image:linear-gradient(to top, #000 4%, rgba(0,0,0,.35) 40%, transparent 76%);
    mask-image:linear-gradient(to top, #000 4%, rgba(0,0,0,.35) 40%, transparent 76%);
    animation:drift 26s linear infinite;}
  @keyframes drift{to{background-position:0 82px, 0 82px;}}
  /* la ligne d'horizon : là où le sol s'arrête, la lumière s'accumule */
  .horizon{position:fixed;left:50%;bottom:34vh;width:150vw;height:38vh;z-index:-3;pointer-events:none;
    filter:blur(48px) hue-rotate(var(--amb-rot));opacity:calc(var(--amb) * .68);
    transition:opacity 1.3s var(--e-main), filter 1.3s var(--e-main);
    background:radial-gradient(58% 50% at 50% 100%, color-mix(in srgb,var(--light) 58%,transparent), transparent 72%);
    animation:pulse 11s ease-in-out infinite;}
  @keyframes pulse{
    0%,100%{transform:translateX(-50%) scaleY(calc(var(--amb-scale) * .94));}
    50%    {transform:translateX(-50%) scaleY(calc(var(--amb-scale) * 1.12));}}

  /* 4. la poussière (canvas) + le grain */
  #dust{position:fixed;inset:0;z-index:-2;pointer-events:none;}
  /* le premier plan : peu de grains, gros, presque invisibles, deux fois plus
     rapides. C'est ce qui transforme une image en VOLUME — sans lui, le
     téléphone est un mur au fond d'un décor. */
  #dust2{position:fixed;inset:0;z-index:40;pointer-events:none;}
  .grain{position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:var(--grain);mix-blend-mode:overlay;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");}

  /* ═══ LA PAGE ═══ */
  .page{max-width:980px;margin:0 auto;padding:64px 20px 128px;display:flex;flex-direction:column;gap:48px;position:relative;}
  .word{font-size:12px;color:var(--ink-3);}
  h1{font-size:clamp(28px,6.4vw,44px);font-weight:400;letter-spacing:-.022em;line-height:1.08;margin:0;max-width:19ch;text-wrap:balance;}
  h1 em{font-style:normal;color:var(--light);text-shadow:0 0 44px var(--glow);}
  .sub{color:var(--ink-2);max-width:62ch;font-size:16px;margin:0;}
  .sub strong{color:var(--ink);font-weight:500;}
  .lockup{display:flex;align-items:center;gap:11px;}
  .lockup svg{width:26px;height:26px;color:var(--light);filter:drop-shadow(0 0 12px var(--glow));}

  .stagegrid{display:flex;flex-wrap:wrap;gap:52px 40px;align-items:flex-start;justify-content:center;}

  /* ═══ LE TÉLÉPHONE ═══ */
  .holder{perspective:1500px;perspective-origin:50% 42%;position:relative;flex:0 0 auto;}
  /* le halo derrière l'appareil : c'est lui qui le décolle du fond */
  /* Le halo n'a plus de vie propre : son intensité, son étendue et sa TEMPÉRATURE
     viennent de l'état de l'app. Le souffle ne porte que l'échelle, pour que
     l'opacité reste libre de transiter proprement d'un état à l'autre. */
  .holder::before{content:"";position:absolute;left:50%;top:46%;width:172%;height:96%;
    background:radial-gradient(52% 46% at 50% 50%, var(--glow), transparent 72%);
    filter:blur(38px) hue-rotate(var(--amb-rot));opacity:var(--amb);pointer-events:none;
    transition:opacity 1.2s var(--e-main), filter 1.2s var(--e-main);
    animation:breathe 8s ease-in-out infinite;}
  @keyframes breathe{
    0%,100%{transform:translate(-50%,-50%) scale(calc(var(--amb-scale) * .97));}
    50%    {transform:translate(-50%,-50%) scale(calc(var(--amb-scale) * 1.06));}}

  .device{position:relative;transform:rotateX(3deg) rotateY(-4.5deg);transform-style:preserve-3d;}
  /* les tranches */
  .side{position:absolute;border-radius:2px;pointer-events:none;
    background:linear-gradient(90deg, color-mix(in srgb,var(--ink) 26%,transparent), color-mix(in srgb,#fff 34%,transparent), color-mix(in srgb,var(--ink) 30%,transparent));
    box-shadow:0 0 6px -2px rgba(0,0,0,.5);}
  .side.v1{left:-3px;top:132px;width:3.5px;height:30px;}
  .side.v2{left:-3px;top:176px;width:3.5px;height:52px;}
  .side.v3{left:-3px;top:238px;width:3.5px;height:52px;}
  .side.pw{right:-3px;top:208px;width:3.5px;height:78px;}

  .phone{position:relative;border-radius:50px;padding:11px;overflow:hidden;
    background:linear-gradient(158deg, color-mix(in srgb,#fff 22%,var(--pane)), var(--pane) 44%, color-mix(in srgb,var(--ink) 17%,var(--pane)));
    backdrop-filter:blur(26px) saturate(1.35);-webkit-backdrop-filter:blur(26px) saturate(1.35);
    box-shadow:0 1px 0 rgba(255,255,255,.5) inset, var(--sh-3);}
  /* le liseré titane : une lumière qui court sur l'arête, pas un trait plat */
  .phone::before{content:"";position:absolute;inset:0;border-radius:inherit;padding:1.4px;pointer-events:none;z-index:4;
    background:conic-gradient(from calc(202deg + var(--tiltx) * 34deg),
      transparent 0 6%, color-mix(in srgb,var(--light-hi) 92%,transparent) 15%, transparent 28%,
      color-mix(in srgb,var(--edge) 90%,transparent) 40% 56%,
      rgba(255,255,255,.8) 70%, transparent 82%, color-mix(in srgb,var(--light) 60%,transparent) 92%, transparent 100%);
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);mask-composite:exclude;}
  /* l'éclat qui balaie la vitre, toutes les 11 s */
  .sheen{position:absolute;inset:-40% -60%;z-index:3;pointer-events:none;
    background:linear-gradient(102deg, transparent 43%, rgba(255,255,255,.20) 49%, rgba(255,255,255,.06) 52%, transparent 59%);
    transform:translateX(-80%);animation:sheen 11s cubic-bezier(.5,0,.2,1) infinite;}
  @keyframes sheen{0%,64%{transform:translateX(-80%);}100%{transform:translateX(80%);}}
  /* le reflet fixe du verre */
  /* le reflet du verre suit l'inclinaison : c'est ce qui fait qu'un objet a l'air
     posé sous une vraie lumière plutôt que dessiné. */
  .glare{position:absolute;inset:11px;border-radius:39px;z-index:3;pointer-events:none;
    background:linear-gradient(calc(157deg + var(--tiltx) * 30deg),
      rgba(255,255,255,.13) 0 calc(19% + var(--tilty) * 9%), transparent 42%);}

  .screen{position:relative;border-radius:39px;overflow:hidden;width:var(--pw);height:calc(var(--pw) * 2.16);
    display:flex;flex-direction:column;border:1px solid var(--edge-2);
    background:
      radial-gradient(150% 40% at 50% -8%, color-mix(in srgb,var(--light) 16%,transparent), transparent 62%),
      radial-gradient(120% 34% at 50% 106%, color-mix(in srgb,var(--light) 9%,transparent), transparent 60%),
      var(--screen);}

  /* la lueur de l'app elle-même : elle obéit au MÊME état que le halo, l'horizon et
     l'aurore. C'est ça, être orchestré — l'écran ne s'éclaire pas pour son compte.
     ::before, donc premier enfant : il passe DERRIÈRE le fil, jamais devant. */
  .screen::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
    background:radial-gradient(128% 40% at 50% -6%, color-mix(in srgb,var(--light) 26%,transparent), transparent 62%);
    filter:hue-rotate(var(--amb-rot));opacity:var(--amb);
    transition:opacity 1.2s var(--e-main), filter 1.2s var(--e-main);}

  /* la pilule caméra */
  .island{position:absolute;top:10px;left:50%;transform:translateX(-50%);width:92px;height:27px;border-radius:14px;
    background:#000;z-index:5;display:flex;align-items:center;justify-content:flex-end;padding-right:9px;
    box-shadow:0 1px 2px rgba(0,0,0,.6);}
  .island i{width:7px;height:7px;border-radius:50%;background:radial-gradient(circle at 34% 32%, #2C4C60, #05090C 72%);
    box-shadow:0 0 5px -1px var(--light);}

  .status{flex:0 0 auto;display:flex;justify-content:space-between;align-items:center;padding:16px 26px 6px;
    font-size:var(--t-cap);letter-spacing:.02em;color:var(--ink);position:relative;z-index:2;}
  .status .ic{display:flex;align-items:center;gap:6px;color:var(--ink);}
  .status svg{display:block;fill:currentColor;}
  .sig{width:17px;height:11px;}
  .wifi{width:15px;height:11px;}
  .bat{width:23px;height:11.5px;border:1px solid currentColor;border-radius:3.5px;padding:1.5px;position:relative;opacity:.85;}
  .bat::after{content:"";position:absolute;right:-3px;top:3.5px;width:1.5px;height:4px;background:currentColor;border-radius:0 1.5px 1.5px 0;opacity:.55;}
  .bat i{display:block;height:100%;width:66%;background:currentColor;border-radius:1.5px;}

  /* l'en-tête de l'app */
  .apphead{flex:0 0 auto;display:flex;align-items:center;gap:9px;padding:8px 20px 10px;position:relative;z-index:2;
    border-bottom:1px solid var(--edge-2);}
  /* 28 px, la MÊME taille que le logo de la conversation (fil.js:154) — « logo du bouton et
     logo de la conversation alignés » (fondateur, 25/08, point 12). Mesuré avant : 23 contre 28.
     Deux tailles pour un même objet, à deux centimètres l'un de l'autre, se lisent comme deux
     objets. C'est MA lecture du mot « alignés » : à revoir d'un coup d'œil si elle est fausse. */
  .apphead svg.mark{width:28px;height:28px;color:var(--light);flex:0 0 auto;filter:drop-shadow(0 0 7px var(--glow));}
  .apphead .nm{font-size:var(--t-foot);font-weight:500;letter-spacing:-.01em;}
  /* LA POSITION — un STATUT, pas une bannière : encre secondaire, 12px (l'échelle du
     fil en compte six, on n'en ajoute pas), et le tout se coupe avant de pousser le ◆
     hors de l'écran sur un petit téléphone. Chiffres tabulaires : l'heure change
     chaque minute et ne doit pas faire sauter la ligne. */
  /* LA POSITION PASSE À DROITE (fondateur, 25/08, point 12) — par sa PROPRE `margin-left:auto`,
     jamais en la réordonnant derrière `.tenu`. Raison mesurée : `.tenu` est `display:none`
     tant que le dossier est vide (fil.js:703), donc HORS FLUX — sur le premier écran de
     n'importe quel visiteur, plus AUCUN élément de l'en-tête ne porterait d'auto-marge, et
     la position resterait collée à « Rabbit ». */
  .apphead .ici{margin-left:auto;display:flex;align-items:baseline;gap:5px;min-width:0;
    font-size:var(--t-cap);color:var(--ink-2);white-space:nowrap;}
  .apphead .ici[hidden]{display:none;}
  .apphead .ici i{font-style:normal;opacity:.5;flex:0 0 auto;}
  /* 🔴 C'EST LA VILLE QUI SE COUPE, JAMAIS L'HEURE. Mesuré le 24/08 sur un écran de
     320 px : l'ellipsis posée sur le conteneur rendait « 04h4 » — une heure tronquée
     ne s'annonce pas tronquée, elle se lit comme une heure FAUSSE (loi 5), alors
     qu'une ville coupée porte ses trois points et dit d'elle-même qu'elle est coupée.
     D'où : la ville rétrécit, l'heure ne rétrécit jamais. */
  .apphead .ici b{font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;}
  .apphead .ici span{flex:0 0 auto;font-variant-numeric:tabular-nums;}
  /* le bouton de l'espace : 44pt pleins, à gauche, premier dans l'ordre de lecture
     comme dans l'ordre du DOM — un lecteur d'écran l'annonce donc en premier lui aussi. */
  .apphead #menubtn{flex:0 0 auto;width:44px;height:44px;margin-left:-8px;border-radius:50%;
    border:1px solid var(--edge);background:var(--pane-2);color:var(--ink-2);
    display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;
    -webkit-tap-highlight-color:transparent;}
  .apphead #menubtn:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  /* la pastille du CONNECTÉ (lot 4) — l'appartenance en vert commande, rien en invité */
  .apphead #menubtn{position:relative;}
  body[data-connecte] .apphead #menubtn::after{content:'';position:absolute;right:1px;bottom:1px;
    width:10px;height:10px;border-radius:50%;background:var(--fam-commande);
    border:2px solid var(--screen);}
  /* LE BLOC DE LIVRAISON — UNE SEULE ÉTAPE (loi §7, 25/08). Trois champs sous les
     yeux au lieu de quatre arrêts de conversation. Cible 46 px, libellé AU-DESSUS
     (un libellé en placeholder disparaît dès qu'on répond : on ne peut plus le
     relire), et la barre de suggestions s'ouvre sous le champ d'adresse. */
  .livf{display:grid;gap:5px;margin-top:3px;}
  .livg{display:grid;gap:4px;}
  .livn{font-size:var(--t-cap);color:var(--ink-2);}
  .livi{width:100%;min-height:44px;padding:0 10px;border-radius:10px;
    border:1px solid var(--edge);background:var(--pane-2);color:var(--ink);
    font:400 var(--t-body)/1.3 var(--sans);}
  .livi:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .livi:disabled{opacity:.55;}
  .livmsg{margin-top:8px;font-size:var(--t-cap);color:var(--warm);}
  .livmsg[hidden]{display:none;}
  .livok{margin-top:12px;}
  /* LES VARIANTES — UN MENU PAR AXE (loi §2, 25/08). Le `<select>` natif ouvre le
     sélecteur du téléphone : il porte 400 options sans occuper un pixel de plus, et
     c'est le geste que le client connaît déjà d'ailleurs. Cible 46 px comme les
     entrées du menu ; l'axe est nommé au-dessus, jamais en placeholder — un libellé
     qui disparaît quand on répond est un libellé qu'on ne peut plus relire. */
  /* ── « CE QUE TU PRENDS » (fondateur, 27/08 : « trop gros, ils prennent trop de place ») ──
     Les menus passent CÔTE À CÔTE et perdent leur étiquette : la première option porte le nom
     de l'axe (« Couleur », « Taille »), donc l'étiquette au-dessus était un doublon qui coûtait
     22 px par axe. Deux axes : 136 px avant, 46 px maintenant. */
  .evax{display:flex;gap:8px;margin-top:0;}
  .evax > .evcol{flex:1 1 0;min-width:0;}
  /* chaque rangée porte son nom — l'étiquette d'axe, discrète, rend le bloc lisible */
  .evcol{display:flex;flex-direction:column;gap:3px;}
  .evet{font-size:var(--t-cap);color:var(--ink-3);letter-spacing:.2px;padding-left:2px;}
  .evcorps > .evetl{margin-top:8px;}
  .evcorps .evax + .evetl{margin-top:9px;}
  .evas{width:100%;min-height:40px;padding:0 12px;border-radius:11px;
    border:1px solid var(--edge);background:var(--pane-2);color:var(--ink);
    font:500 var(--t-foot)/1.3 var(--sans);cursor:pointer;
    -webkit-appearance:none;appearance:none;
    background-image:linear-gradient(45deg,transparent 50%,var(--ink-2) 50%),linear-gradient(135deg,var(--ink-2) 50%,transparent 50%);
    background-position:calc(100% - 17px) 18px,calc(100% - 12px) 18px;
    background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:34px;}
  .evas:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .evamsg{margin-top:8px;font-size:var(--t-cap);color:var(--warm);}
  .evamsg[hidden]{display:none;}
  /* Les variantes — « 15 jaunes, 20 noirs » : des boutons compacts qui S'ENROULENT sur
     autant de rangées qu'il faut (l'intention du 28/08 — la ligne défilante qui coupait
     les libellés longs en plein mot est morte le 29/08 : « Ventilateur solaire Vert-X16 »
     arrivait tronqué et huit variantes sur neuf restaient invisibles). Un libellé plus
     large que l'écran se replie DANS son bouton — jamais d'ellipsis : la fin du nom est
     souvent ce qui distingue deux variantes. La quantité reste FIXE dessous. */
  .evtailles{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;}
  .evt{flex:0 1 auto;max-width:100%;min-height:36px;padding:7px 11px;border-radius:11px;border:1px solid var(--edge);
    background:none;color:var(--ink);font-size:var(--t-cap);font-variant-numeric:tabular-nums;
    white-space:normal;text-align:left;line-height:1.3;}
  .evt:active{background:var(--pane);}
  /* Le bouton qui porte une quantité l'affiche (« 38 · 15 ») et reste marqué ; l'élu
     — celui que la rangée du dessous règle — s'entoure. */
  .evt.porte{border-color:var(--light);font-weight:600;}
  .evt.elu{background:var(--pane);border-color:var(--light);box-shadow:0 0 0 1px var(--light) inset;}
  /* le compteur du bouton, détaché en couleur : « 12 cm nu » et « · 15 » sont deux choses */
  .evt .evtq{color:var(--light);font-weight:600;}
  /* le sujet du réglage : la variante que la rangée règle, une ligne, tronquée */
  .evqte .evql{max-width:32%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    font-size:var(--t-cap);font-weight:600;color:var(--ink-2);}
  .evqte .evql[hidden]{display:none;}
  /* ══════════ LE TIROIR (fondateur, 31/08 : « ça pousse le fil sur la droite ») ══════════
     C'ÉTAIT UNE BULLE FLOTTANTE : 286 px posés en haut à gauche, qui SURVOLAIENT la
     conversation. Le fil restait où il était, et le menu n'était qu'un calque de plus.
     Désormais il POUSSE — le fil se décale, s'assombrit, et devient la surface qu'on
     touche pour refermer. C'est ce qui fait la différence entre « une liste s'est
     ouverte » et « je suis passé dans mon espace ».

     ⚠️ LA POUSSÉE SE FAIT EN `translate`, PAS EN `transform`. Le casier et le bandeau
     d'annulation portent DÉJÀ un `transform:translateY(78px)` comme état caché : leur
     poser un `transform:translateX()` l'écraserait et les ferait APPARAÎTRE en même
     temps que le tiroir. `translate` est une propriété séparée qui se COMPOSE avec
     `transform` — chacun garde le sien.

     L'île, la barre d'état et la barre d'accueil ne bougent pas : c'est le châssis du
     téléphone, pas l'application. */
  .screen{--tw:min(300px,84%);}
  .screen > .apphead, .screen > .threadwrap, .screen > .composer,
  .screen > .casier, .screen > .annuler{transition:translate .34s var(--e-main);}
  .screen[data-tiroir="1"] > .apphead,
  .screen[data-tiroir="1"] > .threadwrap,
  .screen[data-tiroir="1"] > .composer,
  .screen[data-tiroir="1"] > .casier,
  .screen[data-tiroir="1"] > .annuler{translate:var(--tw) 0;}
  /* le fil poussé ne se manipule plus : un doigt qui le touche REFERME, il ne garde
     pas une carte au passage (le voile est au-dessus, il reçoit le geste). */
  .screen[data-tiroir="1"] > .threadwrap{pointer-events:none;}

  .app-menu{position:absolute;top:0;left:0;bottom:0;z-index:40;width:var(--tw);
    translate:-100% 0;transition:translate .34s var(--e-main);
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
    padding:calc(env(safe-area-inset-top,0px) + 10px) 10px 10px;border:1px solid var(--edge);border-left:0;   /* signet : sous l'heure (12/10) */
    border-radius:0 22px 22px 0;
    /* même correctif que la feuille : ce tiroir passe au-dessus de la conversation,
       il ne peut pas être translucide sans devenir illisible. */
    background:color-mix(in srgb,var(--screen) 92%,var(--pane));
    backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);
    box-shadow:var(--sh-3);display:grid;gap:3px;align-content:start;}
  .app-menu[hidden]{display:none;}
  .screen[data-tiroir="1"] .app-menu{translate:0 0;}
  /* Le mouvement réduit coupe le TRAJET, jamais l'information ni l'action : le tiroir
     est là, poussé, immédiatement — il n'y arrive simplement pas en glissant. */
  @media (prefers-reduced-motion:reduce){
    .app-menu, .screen > .apphead, .screen > .threadwrap, .screen > .composer,
    .screen > .casier, .screen > .annuler{transition:none;}
  }
  /* la lecture des compteurs et les réponses honnêtes (« aucun abonnement en cours »)
     s'affichent DANS le menu : ouvrir un écran pour trois nombres serait un voyage. */
  .app-menu .menu-lu{margin:2px 10px 4px;font-size:var(--t-cap);line-height:1.65;
    color:var(--ink-2);white-space:pre-line;}
  .app-menu .menu-lu[hidden]{display:none;}
  .app-menu .menu-title{padding:6px 10px 6px;font-size:var(--t-cap);
    color:var(--ink-3);}
  .app-menu a,.app-menu button{min-height:46px;width:100%;display:flex;align-items:center;gap:11px;
    padding:0 12px;border:0;border-radius:13px;background:transparent;color:var(--ink);
    font:500 var(--t-foot)/1.2 var(--sans);text-decoration:none;text-align:left;cursor:pointer;}
  .app-menu [hidden]{display:none!important;}
  .app-menu a:hover,.app-menu button:hover,.app-menu a:focus-visible,.app-menu button:focus-visible{
    background:var(--pane-2);outline:1px solid var(--edge);outline-offset:0;}
  /* Les glyphes (◆ □ ◇ ○ ▤ ◉ ☼ ↻) ne distinguaient rien : quatre losanges pour quatre
     destinations différentes (constat écran fondateur, 16/08). Des tracés, dans le trait
     du reste du fil — même viewBox 24, même stroke-width, mêmes bouts ronds. */
  .app-menu .mi{width:24px;display:inline-flex;align-items:center;justify-content:center;
    flex:0 0 auto;color:var(--light);}
  .app-menu .mi svg{width:17px;height:17px;display:block;}
  /* « Mon abonnement · résilier » mettait la lecture et l'acte destructeur sur LA MÊME
     ligne cliquable : on pouvait croire qu'un doigt résilie (constat écran fondateur,
     16/08). La doctrine ne bouge pas — on ne cache pas « résilier » derrière « gérer »,
     ce qu'on cache donne l'impression qu'on le retient. C'est la FORME qui change : la
     cible du doigt dit la consultation, la promesse reste écrite juste dessous. */
  /* ⛔ LES SOUS-EXPLICATIONS SOUS CHAQUE ENTRÉE SONT MORTES (fondateur, 31/08 : « enlève
     toutes les explications en dessous, ça ne sert à rien, personne ne fait ça »). Il a
     raison : aucune application ne commente ses propres entrées de menu — un libellé
     qui a besoin d'une glose est un libellé raté. Les règles `.ml` / `.ms` et l'alignement
     d'icône sur deux lignes partent avec elles ; toutes les entrées sont sur UNE ligne. */

  .app-menu .menu-primary{background:color-mix(in srgb,var(--light) 13%,var(--pane-2));}

  /* L'EN-TÊTE DU TIROIR — qui tu es, avant toute liste (modèle Claude, 31/08).
     Deux lignes seulement : l'identité domine, le palier la commente. */
  .menu-moi{display:grid;gap:2px;padding:8px 12px 10px;margin-bottom:0;
    border-bottom:1px solid var(--edge-2);}
  .menu-moi[hidden]{display:none;}
  .menu-moi .mm-id{font:600 var(--t-body)/1.3 var(--sans);color:var(--ink);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .menu-moi .mm-plan{font:400 var(--t-cap)/1.4 var(--sans);color:var(--ink-3);}

  /* LES TROIS DERNIERS GARDÉS. 44 pt de haut : c'est une prise, pas une décoration —
     et le tap tombe sur « Mon dossier » juste au-dessus, dont elles sont l'aperçu. */
  .menu-vign{display:flex;gap:6px;padding:0 12px 6px;margin-top:-2px;}
  .menu-vign[hidden]{display:none;}
  .menu-vign img{width:44px;height:44px;border-radius:11px;object-fit:cover;
    border:1px solid var(--edge-2);background:var(--pane-2);}

  /* LES CONVERSATIONS (tiroir, étape 5, 27/09) : une ligne par conversation — son titre coupé par « … », « et N
     autres » entier à sa suite. Sans photo (fondateur, 28/09 : elles prenaient trop de place pour choisir). La
     conversation ouverte se voit ; celle qu'on rouvre patiente. `min-width:0` partout : sans lui, un long titre
     élargissait toute la colonne du tiroir, qui défilait de côté (relecture du 27/09, mesuré à 375 px). */
  /* un trait sépare les entrées du tiroir de « Tes conversations » (fondateur, 02/10 : « un petit truc pour rendre plus clair ») */
  .menu-convs{display:grid;gap:0;margin-top:10px;padding-top:8px;border-top:1px solid var(--edge);min-width:0;}
  .app-menu .menu-convs .tc-ligne{min-height:38px;min-width:0;font-weight:400;}
  .app-menu .menu-convs .tc-ligne[aria-current="true"]{background:var(--pane-2);}
  .app-menu .menu-convs .tc-ligne[aria-busy="true"]{opacity:.6;}
  .menu-convs .tc-nom{display:flex;align-items:baseline;gap:.3em;flex:1;min-width:0;}
  .menu-convs .tc-titre{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .app-menu .menu-convs .tc-plus-anciennes,.app-menu .menu-convs .tc-reessayer{color:var(--ink-2);font-weight:400;}
  .menu-convs .tc-confirmer{display:grid;gap:6px;margin:2px 0 8px;padding:8px 10px 10px;border-radius:13px;background:var(--pane-2);}
  .menu-convs .tc-confirmer .menu-lu{margin:0;}
  .app-menu .menu-convs .tc-changer{justify-content:center;background:var(--pane);font-weight:600;}
  .app-menu .menu-convs .tc-rester{justify-content:center;}

  /* ── LES PANNEAUX DU TIROIR : commandes, recherches, livraison, confidentialité.
     Ils REPRENNENT la coque du dossier (`.dossier`) — voir fil.js. Ce qui suit ne
     concerne que leurs contenus propres. ── */
  /* Les rangées des panneaux SONT la rangée de l'art. 1 : `.dcand` + `.dcorps-r`
     portent toute la mise en page (vignette 60, prix qui domine, badges). Une
     deuxième mise en page aurait divergé au premier réglage — et la première
     rédaction, qui posait `.dcc/.dpx/.dmeta` SANS leur parent `.dcand`, affichait
     tout sur une seule ligne. Il ne reste ici que ce qui leur est propre. */
  .dossier .cmd-l + .cmd-l{border-top:1px solid var(--edge-2);}
  .dossier .cmd-l{min-height:64px;}                 /* pas de geste : moins haut qu'un candidat */
  /* 7a — la commande S'OUVRE (le « pas encore » est advenu) : la rangée est un bouton */
  .dossier .cmd-l > .dcorps-r{cursor:pointer;}
  .dossier .cmd-l > .dcorps-r:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  /* les boutons d'action des panneaux fusionnés (lot 8 : déconnexion, thème,
     conditions) — le rendu des entrées du tiroir, 44 pt, pleine largeur de section */
  .dossier .dcorps > button[data-menu-action]{display:flex;align-items:center;gap:10px;
    width:100%;min-height:46px;padding:0 10px;margin-top:8px;border:1px solid var(--edge);
    border-radius:12px;background:var(--pane);color:var(--ink);font-family:var(--sans);
    font-size:var(--t-body);cursor:pointer;text-align:left;}
  .dossier .dcorps > button[data-menu-action]:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  /* LES LISTES DE RÉGLAGES, GROUPÉES COMME SUR iOS (doctrine de l'écran, lot 3 — maquettes validées, planches 5, 6 et 10) :
     un bloc de verre, des rangées pleine largeur séparées d'un filet, un chevron à droite ; le geste qui détruit, centré, en
     rouge. Les rangées du bloc ne sont plus des enfants directs de `.dcorps` : elles ne prennent pas le verre des boutons. */
  .dossier .dgroupe{margin:16px 0 0;border-radius:12px;overflow:hidden;
    background:color-mix(in srgb, var(--pane) var(--lum-verre, 78%), transparent);box-shadow:inset 0 0 0 1px var(--carte-lisere, var(--edge));}
  .dossier .dcorps > .dgroupe:first-child{margin-top:4px;}
  .dossier .dgroupe > button{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:46px;
    padding:0 16px;margin:0;border:0;border-radius:0;background:transparent;box-shadow:none;color:var(--ink);
    font-family:var(--sans);font-size:var(--t-body);text-align:left;cursor:pointer;}
  .dossier .dgroupe > button + button{border-top:1px solid var(--edge);}
  .dossier .dgroupe > button::after{content:"›";flex:none;color:var(--ink-3);font-size:var(--t-head);line-height:1;}
  .dossier .dgroupe > button .mi{display:none;}
  .dossier .dgroupe > button:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  .dossier .dgroupe > button.dg-rouge{justify-content:center;color:var(--rouge, var(--warm));}
  .dossier .dgroupe > button.dg-rouge::after{content:none;}
  /* l'en-tête d'un bloc, ses rangées « libellé · valeur », et la ligne sous un bloc */
  .dossier .dentete{margin:18px 16px 6px;font-size:var(--t-foot);color:var(--ink-2);}
  .dossier .dcorps > .dentete:first-child{margin-top:4px;}
  .dossier .drangs{border-radius:12px;overflow:hidden;
    background:color-mix(in srgb, var(--pane) var(--lum-verre, 78%), transparent);box-shadow:inset 0 0 0 1px var(--carte-lisere, var(--edge));}
  .dossier .drangs:not(:has(.drang)){display:none;}
  .dossier .drangs .f-reste{display:contents;}
  /* un filet AU-DESSUS de chaque rangée, la première le cache sous le bord du bloc (−1 px) : il tient aussi quand des
     rangées arrivent plus tard dans un sous-bloc (`.f-reste`) */
  .dossier .drang{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:12px 16px;margin-top:-1px;
    border-top:1px solid var(--edge);font-size:var(--t-body);}
  .dossier .drang .k{color:var(--ink);}
  .dossier .drang .v{color:var(--ink-2);text-align:right;font-variant-numeric:tabular-nums;}
  .dossier .abo-tete + .drangs{margin-top:14px;}
  /* les replis de « Formule » (Inclus, Changer de formule, Facturation) : un bloc, une rangée par repli */
  .dossier .dgroupe-d{margin:16px 0 0;border-radius:12px;overflow:hidden;
    background:color-mix(in srgb, var(--pane) var(--lum-verre, 78%), transparent);box-shadow:inset 0 0 0 1px var(--carte-lisere, var(--edge));}
  .dossier .dgroupe-d > .drepli{border-top:0;padding:0 16px;}
  .dossier .dgroupe-d > .drepli + .drepli{border-top:1px solid var(--edge);}
  .dossier .dgroupe-d > .drepli[open]{padding-bottom:14px;}
  .dossier .dpied{margin:8px 16px 0;font-size:var(--t-foot);color:var(--ink-2);line-height:1.4;}
  .dossier .dpied a{color:inherit;}
  /* la page « Données personnelles » (lot 3) : ses blocs gardent le bord des autres, sans la grille ni la gouttière de `.conf` */
  .dossier .f-donnees .conf{display:block;padding:0 0 20px;}
  .dossier .f-donnees .conf > .conf-2{margin-top:12px;padding:0 12px;}
  /* l'adresse n'a plus de bandeau : la carte commence par son premier champ, à distance du bord */
  .dossier .f-livraison > .p-obj{padding-top:12px;}
  .dossier .p-amz .amz-dit:empty{display:none;}   /* Amazon non connecté : la carte ne garde que son geste */
  /* LA BASCULE VERS LE POSTE DE TRAVAIL (09/09), « Admin » depuis le 02/10 — un LIEN (il quitte le Fil), qui HÉRITE de
     `.app-menu a` comme les boutons du tiroir. Elle avait sa propre règle à identifiant, censée « reprendre à l'identique »
     et qui ne le faisait pas : texte plus gros, graisse normale, icône plus petite et grise (fondateur, 02/10 : « faire en
     sorte qu'il soit écrit comme les autres »). Une famille d'entrées, une seule règle. */
  /* la mini-galerie des photos de contrôle, dans le détail */
  .ddetail .qc-gal{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px;}
  .ddetail .qc-gal img{width:76px;height:76px;object-fit:cover;border-radius:10px;border:1px solid var(--edge-2);}
  /* les vidéos de l'entrepôt (03/10), sous les photos : la largeur du détail, la première image visible */
  .ddetail .qc-vids{display:flex;flex-direction:column;gap:8px;margin-top:4px;}
  .ddetail .qc-vid{margin:0;}
  .ddetail .qc-vid video{display:block;width:100%;max-height:300px;border-radius:var(--r-2);background:#000;}
  .ddetail .qc-vid figcaption{margin-top:4px;font-size:var(--t-cap);color:var(--ink-2);}
  /* un tap ouvre la preuve en grand (03/10) : la photo est un bouton, la vidéo une vignette marquée ▶ */
  .ddetail .qc-gal .qc-ph{padding:0;margin:0;border:0;background:none;line-height:0;cursor:zoom-in;}
  .ddetail .qc-vid-b{position:relative;display:block;width:100%;padding:0;margin:0;border:0;background:none;line-height:0;cursor:pointer;}
  .ddetail .qc-vid-b .qc-lire{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:52px;height:52px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.55);color:#fff;font-size:20px;line-height:1;}
  /* « Reprendre le paiement » vit À CÔTÉ de la rangée (jamais dedans : un bouton dans un bouton est fermé par le
     navigateur et s'étire — vu le 10/09), à la taille de son verbe, teinté ; le plein est réservé à « Payer ». */
  .dcand > .cmd-reprendre{align-self:center;flex:none;margin:0 10px 0 2px;min-height:44px;padding:8px 12px;border-radius:12px;
    background:var(--btn-teinte-bg);color:var(--btn-teinte-ink);border:1px solid var(--btn-teinte-edge);
    font-size:var(--t-foot);font-weight:600;line-height:1.15;max-width:8.5em;white-space:normal;text-align:center;cursor:pointer;}
  .dcand > .cmd-reprendre:disabled{opacity:.6;cursor:default;}
  .obj-cmd .dcand{min-height:72px;}
  .obj-cmd .dhead-t{margin-bottom:4px;}
  .obj-cmd .ddetail:not([hidden]){margin-top:6px;border-top:1px solid var(--edge-2);padding-top:6px;}
  .dossier .cmd-l > button.cmd-go{cursor:pointer;}
  .dossier .cmd-l > button.cmd-go:hover,
  .dossier .cmd-l > button.cmd-go:focus-visible{background:var(--pane-2);}

  /* Les formulaires du tiroir. 16 px dans les champs : en dessous, iOS ZOOME sur
     l'écran au focus et le client se retrouve ailleurs (piège de la 4e passe). */
  .dossier .lv-i{margin:10px 12px;font:400 var(--t-foot)/1.6 var(--sans);color:var(--ink-2);}
  .dossier .lv-i a{color:inherit;}
  .dossier .livr,.dossier .conf{display:grid;gap:10px;padding:4px 12px 20px;}
  .dossier .lv{display:grid;gap:5px;}
  .dossier .lv > span{font:500 var(--t-cap)/1.3 var(--sans);color:var(--ink-3);}
  .dossier .lv input{min-height:44px;padding:0 12px;font:400 var(--t-champ)/1.2 var(--sans);
    color:var(--ink);background:var(--pane);border:1px solid var(--edge);border-radius:13px;}
  .dossier .lv input:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  .dossier .lv-ok,.dossier .conf-go,.dossier .conf-oui{min-height:46px;}
  .dossier .lv-dit{margin:0 12px;font:400 var(--t-foot)/1.5 var(--sans);color:var(--ink-2);min-height:21px;}
  /* MON ABONNEMENT — le nom de la formule domine, son prix le commente. */
  .dossier .abo-tete{display:grid;gap:2px;padding:14px 12px 4px;}
  .dossier .abo-nom{font:600 var(--t-large)/1.2 var(--sans);letter-spacing:var(--t-large-ls);color:var(--ink);}
  .dossier .abo-px{font:500 var(--t-body)/1.3 var(--sans);font-variant-numeric:tabular-nums;color:var(--ink-2);}
  .dossier .abo-px small{font-weight:400;font-size:var(--t-foot);color:var(--ink-3);}
  .dossier .abo-l{margin:6px 12px 12px;padding-left:18px;
    font:400 var(--t-foot)/1.9 var(--sans);color:var(--ink);}
  /* LES BOUTONS DES PANNEAUX. `.btn` est dessiné pour les cartes TEINTÉES du fil :
     posé sur le fond clair d'un panneau, son halo bleu se lit comme un contour lourd,
     et il ne prenait que 199 px sur 375 (mesuré le 31/08) — un acte principal qui
     flotte au milieu de sa ligne ne se lit pas comme l'acte principal. */
  /* ⚠️ `width:auto` NE SUFFIT PAS : un <button> garde la largeur de son CONTENU même
     en `display:flex`, contrairement à un <div> de niveau bloc. Mesuré : 199 px sur
     375. Ailleurs dans le fil ces boutons vivent dans des colonnes flex qui les
     étirent — ici le parent est un bloc, donc la largeur se dit. */
  .dossier .btn{width:calc(100% - 24px);margin-left:12px;margin-right:12px;
    box-shadow:0 0 0 1px color-mix(in srgb,var(--glow) 55%,transparent),
               0 8px 22px -14px var(--glow),0 1px 0 rgba(255,255,255,.5) inset;}
  .dossier .abo-go{min-height:46px;}
  /* `.livr` et `.conf` portent déjà leur gouttière : le bouton n'ajoute pas la sienne,
     sinon la marge est comptée deux fois et il rétrécit sans raison lisible. */
  .dossier .livr .btn,.dossier .conf .btn{width:100%;margin-left:0;margin-right:0;}
  /* Le contrat, chargé depuis `legal.html` : on lui rend une typo de lecture, on ne
     lui laisse pas la sienne (elle repeindrait tout l'écran). */
  .dossier .legal-lu{padding:4px 14px 24px;font:400 var(--t-foot)/1.7 var(--sans);color:var(--ink);}
  .dossier .legal-lu h1,.dossier .legal-lu h2,.dossier .legal-lu h3{
    font:600 var(--t-body)/1.35 var(--sans);color:var(--ink);margin:18px 0 6px;}
  .dossier .legal-lu h1{font-size:var(--t-title);}
  .dossier .legal-lu p,.dossier .legal-lu li{margin:0 0 8px;color:var(--ink-2);}
  .dossier .legal-lu ul,.dossier .legal-lu ol{padding-left:20px;margin:0 0 10px;}
  .dossier .legal-lu a{color:var(--light);}
  .dossier .legal-lu img,.dossier .legal-lu table{max-width:100%;}
  /* UNE FORMULE SE LIT AVANT DE SE PRENDRE : son contenu est déplié, et le bouton qui
     engage l'argent est SOUS lui. */
  .dossier .abo-offre{margin:0 12px 14px;padding:12px 14px 14px;border-radius:16px;
    border:1px solid var(--edge);background:var(--pane);}
  .dossier .abo-offre-t{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
  .dossier .abo-offre-t b{font:600 var(--t-title)/1.25 var(--sans);}
  .dossier .abo-offre-px{font:500 var(--t-body)/1.3 var(--sans);color:var(--ink-2);white-space:nowrap;}
  .dossier .abo-offre-px small{font-weight:400;font-size:var(--t-cap);color:var(--ink-3);}
  .dossier .abo-offre-p{margin:2px 0 0;font:400 var(--t-foot)/1.5 var(--sans);color:var(--ink-2);}
  .dossier .abo-offre-r{margin:8px 0 0;font:400 var(--t-cap)/1.4 var(--sans);color:var(--ink-3);}
  /* le message d'un changement de formule, sous SON bouton (14/10) — rien tant qu'il n'y a rien à dire */
  .dossier .abo-offre .abo-offre-dit{margin:8px 0 0;text-align:center;}
  .dossier .abo-offre .abo-offre-dit:empty{display:none;}
  .dossier .abo-offre .abo-l{margin:6px 0 12px;}
  .dossier .abo-offre .btn{width:100%;margin:0;}
  /* LE SOLDE (lot 4, 13/10 — maquette validée) : le chiffre restant domine ; les packs en trois choix ; Business recommandé
     en couleur (permise sur ce qui vend l'abonnement, fondateur 13/10) */
  .dossier .drang .v.drang-fort{font-size:var(--t-title);font-weight:600;color:var(--ink);}
  .dossier .abo-packs{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:4px 0 10px;}
  .dossier .abo-pack{display:flex;flex-direction:column;align-items:center;gap:2px;padding:10px 4px;min-height:44px;border-radius:14px;
    border:1px solid var(--edge);background:var(--pane);font:400 var(--t-cap)/1.3 var(--sans);color:var(--ink-2);cursor:pointer;}
  .dossier .abo-pack b{font-size:var(--t-title);font-weight:600;line-height:1.1;color:var(--ink);}
  .dossier .abo-pack em{font-style:normal;font-weight:600;color:var(--ink);}
  .dossier .abo-pack:disabled{opacity:.5;}
  .dossier .abo-offre.abo-offre-reco{border:1.5px solid transparent;
    background:linear-gradient(var(--pane),var(--pane)) padding-box,linear-gradient(135deg,#3B82F6,#8B5CF6) border-box;}
  .dossier .abo-offre-reco .btn{background:linear-gradient(135deg,#3B82F6,#8B5CF6);color:#FFFFFF;border:0;}
  .dossier .abo-reco{display:inline-block;margin-left:8px;padding:3px 8px;border-radius:999px;vertical-align:2px;
    font-size:var(--t-cap);font-weight:600;line-height:1;color:#FFFFFF;background:linear-gradient(135deg,#3B82F6,#8B5CF6);}
  .dossier .abo-autre[data-arme="1"]{background:color-mix(in srgb,var(--light) 18%,transparent);
    border-color:var(--light);color:var(--ink);}
  .dossier .conf-2{display:grid;gap:10px;}
  .dossier .conf-2[hidden]{display:none;}
  /* l'acte irréversible se distingue — la couleur d'alarme du fil, jamais le vert d'argent */
  .dossier .conf-oui{background:var(--warm);color:#fff;}
  /* LE VOILE couvre le fil POUSSÉ (jamais le tiroir : z-index 39 < 40). C'est lui qui
     reçoit le doigt et referme — comme chez Claude, où toucher la conversation décalée
     ramène. Il s'assombrit franchement : à 18 % on ne voyait pas que le fil était
     devenu une surface, et on essayait de le manipuler. */
  .menu-veil{position:absolute;inset:0;z-index:39;background:rgba(4,8,16,.34);
    opacity:0;transition:opacity .34s var(--e-main);}
  .screen[data-tiroir="1"] .menu-veil{opacity:1;}
  .menu-veil[hidden]{display:none;}
  @media (prefers-reduced-motion:reduce){ .menu-veil{transition:none;} }

  /* la scène : les objets arrivent DE LOIN */
  /* ── LE COULOIR ──
     La conversation n'est pas une liste, c'est un couloir : ce qui est passé est
     LOIN, pas seulement pâle. Une seule rotation autour de l'axe bas fait reculer
     tout le haut du fil en permanence — la profondeur cesse d'être un événement
     d'une seconde pour devenir l'espace dans lequel la scène se joue.
     La perspective monte d'un cran (sur le wrapper) pour que le fil lui-même puisse
     être incliné tout en gardant la sienne pour ses enfants. */
  .threadwrap{flex:1;min-height:0;position:relative;perspective:1000px;perspective-origin:50% 88%;}
  /* la lecture a une LARGEUR (audit 01/09 : 95 car./ligne à 768, bloc de 1377 px à
     1440) : le fil se centre et plafonne — à 375 rien ne change (375 < 640) */
  /* ANCRÉ EN HAUT (fondateur 02/09 : « c'est trop bas dans le fil ») — le patron
     d'iMessage : une conversation courte COMMENCE en haut de l'écran ; quand elle
     dépasse, l'épinglage JS (thread.scrollTop) la tient en bas comme avant. Statique,
     aucun espace qui se recalcule au clavier — le défaut qui a tué l'espaceur ::after
     à la recette du 01/09 ne peut pas revenir par ici. */
  .thread{position:absolute;inset:0;max-width:640px;margin-inline:auto;
    padding:8px 12px 12px;display:flex;flex-direction:column;
    justify-content:flex-start;gap:0;overflow:hidden;
    transform:rotateX(5.5deg);transform-origin:50% 100%;transform-style:preserve-3d;}
  /* ⚠️ L'ESPACEUR ::after (lot 1 — « la parole démarre plus haut ») est RETIRÉ à la
     recette fondateur du 01/09 : « le fil ne fait que remonter, personne ne peut
     écrire ». Au téléphone, le clavier redimensionne le viewport
     (interactive-widget=resizes-content) : ce flex compressible se recalculait à
     CHAQUE ouverture/fermeture et à chaque mot écrit — tout l'écran sautait. Le
     critère « ≤50 % de ciel » de l'accueil retombe (54 %) : à re-viser par un
     mécanisme qui ne touche pas au layout vivant, jamais en re-posant ceci. */
  /* les fondus haut et bas : la conversation entre et sort du champ */
  .threadwrap::before,.threadwrap::after{content:"";position:absolute;left:0;right:0;height:34px;z-index:3;pointer-events:none;}
  .threadwrap::before{top:0;background:linear-gradient(var(--screen),transparent);}
  .threadwrap::after{bottom:0;background:linear-gradient(transparent,var(--screen));}

  /* ── LES CARACTÉRISTIQUES SE DÉPLIENT (fondateur, 27/08) ────────────────────────────
     Un pavé qu'on touche, pas un mur de texte. `<details>` natif : il s'ouvre sans JavaScript.
     La cible fait toute la largeur et 44 px de haut — on le touche au pouce, pas au millimètre. */
  .fiche .fcarac{padding:0;overflow:hidden;}
  .fiche .fcarac > summary{display:flex;align-items:center;justify-content:space-between;
    min-height:44px;padding:0 15px;cursor:pointer;list-style:none;
    -webkit-tap-highlight-color:transparent;user-select:none;}
  .fiche .fcarac > summary::-webkit-details-marker{display:none;}
  /* le chevron dit l'état — fermé il pointe en bas, ouvert il se retourne */
  .fiche .fcarac > summary::after{content:"";width:8px;height:8px;flex:0 0 auto;
    border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);
    transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s var(--e-main);}
  .fiche .fcarac[open] > summary::after{transform:rotate(-135deg) translate(-2px,-2px);}
  .fiche .fcarac > .row{margin:0 15px;}
  .fiche .fcarac > .row:last-child{padding-bottom:12px;}

  /* la quantité : deux cibles de 38 px (compact mobile, fondateur 28/08) et un champ au
     milieu — le prix à la pièce suit, à droite, parce que c'est LUI que le geste fait bouger. */
  .evqte{display:flex;align-items:center;gap:8px;margin-top:6px;}
  .evqte[hidden]{display:none;}
  .evqte .evq{width:38px;height:38px;flex:0 0 auto;border-radius:50%;border:1px solid var(--edge);
    background:var(--pane-2);color:var(--ink);font-size:var(--t-title);line-height:1;cursor:pointer;
    display:flex;align-items:center;justify-content:center;padding:0;
    -webkit-tap-highlight-color:transparent;}
  .evqte .evq:active{background:var(--pane);}
  /* le champ garde 16px : en dessous, iOS zoome la page au focus */
  .evqte .evqi{width:54px;height:38px;flex:0 0 auto;text-align:center;font-size:var(--t-champ);
    border:1px solid var(--edge);border-radius:11px;background:var(--pane-2);color:var(--ink);
    font-family:var(--sans);font-variant-numeric:tabular-nums;outline:none;}
  .evqte .evpu{margin-left:auto;font-size:var(--t-cap);color:var(--ink-2);font-variant-numeric:tabular-nums;}
  .evcorps .evbaisse{color:var(--light);padding-top:6px;padding-bottom:0;}
  /* cachée, elle ne laisse ni sa puce ni ses 11 px — le display du .fact écrasait [hidden] */
  .evcorps .evbaisse[hidden]{display:none;}
  /* le dépliant : la ligne fermée résume, le corps porte les gestes */
  .evpli > summary .evplis{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
    white-space:nowrap;margin-right:8px;}
  /* la prise, à droite du libellé stable : « Choisir les options · 35 pièces » */
  .evplis b{color:var(--light);font-weight:600;}
  /* « Ça vaut le coup ? » — l'avis gravé dans la fiche */
  .avcorps{padding:0 15px 12px;}
  .avcorps .travail .ph{white-space:nowrap;text-overflow:ellipsis;}
  .avtitre{font-size:var(--t-title);font-weight:600;margin:2px 0;}
  .av-fonce{color:var(--light);}
  .av-serre,.av-a_confirmer{color:var(--warm);}
  .av-laisse,.av-sans_marche,.av-sans_transport{color:var(--ink-2);}
  /* la phrase d'abord, et rien qu'elle (05/09) : le compte replié a quitté la fiche, ses règles avec lui */
  .avparle{font-size:var(--t-body);line-height:1.55;margin:2px 0 4px;}
  .avres{font-size:var(--t-cap);color:var(--ink-3);margin-top:7px;}
  /* la question du statut se répond d'un tap (06/09) : un libellé, deux pastilles pleine largeur */
  .avq{display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin:9px 0 2px;}
  .avq .lab{flex:0 0 100%;}
  .avq .btn{flex:1 1 auto;}
  /* 07/09 : les réponses sont TEINTÉES et serrées — le verdict garde la vedette (charte loi 4) */
  .avq .pill{flex:0 1 auto;min-height:34px;padding:0 13px;}
  .evcorps{padding:0 15px 12px;}
  /* LE TOTAL, au-dessus du bouton — §2. Discret : c'est le bouton qui doit attirer l'œil,
     le total ne fait que confirmer ce qu'on va payer. */
  .fpied{display:flex;align-items:center;gap:12px;justify-content:flex-end;}
  .fpied .ftot{flex:1;display:flex;flex-direction:column-reverse;align-items:flex-start;gap:1px;
    padding:0 4px 8px;font-variant-numeric:tabular-nums;}
  .fpied .ftot .k{font-size:var(--t-cap);color:var(--ink-2);}
  .fpied .ftot .v{font-size:var(--t-title);font-weight:600;letter-spacing:var(--t-title-ls);font-variant-numeric:tabular-nums;color:var(--ink);}
  .fpied .fcelui{flex:none;width:auto;padding:13px 26px;margin-top:0;}
  .fpied .ftot[hidden]{display:none;}

  /* la barre de saisie */
  /* ── UNE SEULE BARRE, ET TOUT DEDANS (fondateur, 26/08) ──────────────────────────
     « Je suis sur Claude et ChatGPT, ce n'est pas des boutons à part. »
     AVANT : quatre pastilles bordées, alignées côte à côte, séparées de 9 px — quatre objets
     à l'œil, dont un seul (le champ) portait la conversation. MAINTENANT : `.composer` n'est
     plus qu'une marge, et `.barre` est LE contenant — pleine largeur, une bordure, un fond.
     Les contrôles n'ont plus ni fond ni bordure : ils sont DANS l'endroit où on parle. */
  .composer{flex:0 0 auto;padding:8px 14px 4px;position:relative;z-index:2;
    width:100%;max-width:640px;margin-inline:auto;}
  /* les recherches récentes au focus (lot 8, recadré à la recette 01/09) — des
     pilules AU-DESSUS de la barre, en ABSOLU ancré au composer : leur apparition ne
     déplace RIEN dans le fil (zéro reflow au focus/blur — c'est ce qui faisait
     sauter l'écran pendant la frappe). Classe propre : `.sugg` appartient à la
     barre d'adresses de la feuille. */
  .composer .recentes{position:absolute;left:14px;right:14px;bottom:100%;margin-bottom:6px;
    display:flex;gap:6px;flex-wrap:wrap;z-index:3;}
  .composer .recentes-i{display:inline-flex;align-items:center;border:1px solid var(--edge);
    border-radius:19px;background:var(--pane);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);overflow:hidden;}
  .composer .recentes-go{border:0;background:none;min-height:44px;padding:0 4px 0 14px;
    font-family:var(--sans);font-size:var(--t-foot);color:var(--ink-2);cursor:pointer;
    max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .composer .recentes-x{border:0;background:none;min-height:44px;min-width:34px;
    color:var(--ink-3);cursor:pointer;font-size:var(--t-cap);}
  .composer .recentes-go:focus-visible,.composer .recentes-x:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  /* La flèche pour descendre (point 3 du 25/08) : posée au-dessus du composer, elle suit
     le clavier avec lui. `hidden` la retire net ; l'apparition est un fondu d'opacité —
     pas un mouvement, donc rien à couper sous prefers-reduced-motion.
     Retour fondateur 29/08 : plus petite, et en VERRE — le même verre que le reste de
     la scène (blur 22 + saturate 140, fond --pane-2), jamais un troisième dosage. */
  #aubas{position:absolute;top:-44px;right:16px;width:32px;height:32px;border-radius:50%;
    border:1px solid var(--edge-2);background:var(--pane-2);color:var(--ink-2);
    backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);
    display:flex;align-items:center;justify-content:center;box-shadow:var(--sh-1);
    cursor:pointer;opacity:1;transition:opacity .2s var(--ease);}
  #aubas[hidden]{display:none;}
  #aubas svg{width:16px;height:16px;}
  #aubas:active{background:var(--pane);}
  .composer .barre{display:flex;align-items:center;gap:2px;padding:4px;
    border:1px solid var(--edge);background:var(--pane-2);border-radius:24px;}
  .composer .field{flex:1;min-width:0;height:44px;border:0;background:none;border-radius:0;
    display:flex;align-items:center;padding:0 8px;font-size:var(--t-foot);color:var(--ink-3);}
  .composer .send{width:36px;height:36px;border-radius:50%;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
    background:var(--btn-plein-bg);color:var(--btn-plein-ink);box-shadow:none;}   /* le bouton plein du 05/09, par jetons (ticket Apparence 01) */
  .composer .send svg{width:15px;height:15px;}

  /* le + : même gabarit que l'envoi, matière du composeur — il n'engage que le
     travail de Rabbit, il n'a donc pas droit au plein cyan de l'acte d'envoyer. */
  /* Dans la barre, ils n'ont plus besoin de se dessiner : le contenant les tient déjà.
     Ni bordure ni fond — sinon on retrouve les « boutons à part » qu'on vient de retirer. */
  .composer .cam,
  .composer .plus{width:36px;height:36px;border-radius:50%;flex:0 0 auto;display:flex;
    align-items:center;justify-content:center;border:0;
    background:none;color:var(--light);cursor:pointer;padding:0;
    -webkit-tap-highlight-color:transparent;}
  .composer .cam:active,.composer .plus:active{background:var(--pane);}
  .composer .cam svg{width:17px;height:17px;}
  .composer .plus svg{width:16px;height:16px;transition:transform .18s var(--e-main);}
  .composer .plus[aria-expanded="true"] svg{transform:rotate(45deg);}  /* + devient × */
  .composer .plus[hidden],.composer .send[hidden]{display:none;}
  .composer .plus:focus-visible{outline:2px solid var(--light);outline-offset:2px;}

  /* LA FEUILLE — elle monte du composeur, elle ne tombe pas du ciel : ce qu'on va
     donner à Rabbit part de l'endroit où on lui parle. */
  /* le voile assombrit à peine : il ne cache pas la conversation, il la met en retrait
     le temps du choix — et il rattrape le tap à côté sans faire écran noir. */
  .feuille-veil{position:absolute;inset:0;z-index:38;
    background:color-mix(in srgb,var(--void) 34%,transparent);}
  .feuille-veil[hidden]{display:none;}
  /* OPAQUE, et c'est non négociable : posée en `var(--pane)` (11 % d'opacité), la
     feuille laissait la conversation traverser ses propres libellés — vu à l'écran,
     les deux textes se superposaient. Une surface qui porte un choix doit porter son
     fond ; le flou ne sert qu'à adoucir ses bords, il ne remplace jamais l'opacité. */
  .feuille{position:absolute;left:12px;right:12px;bottom:64px;z-index:39;
    border:1px solid var(--edge);border-radius:22px;
    background:color-mix(in srgb,var(--screen) 92%,var(--pane));
    backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);
    box-shadow:var(--sh-3);padding:6px;display:grid;gap:2px;
    animation:feuille-monte .22s var(--e-main);}
  .feuille[hidden]{display:none;}
  /* LES SKILLS (10/10) : la liste se range sous ses titres ; elle défile si elle dépasse (12 gestes sur un téléphone) */
  .feuille{max-height:min(64vh,560px);overflow-y:auto;overscroll-behavior:contain;}
  /* l'accordéon (10/10) : un titre = une rangée, sa flèche tourne quand il s'ouvre ; ses gestes en retrait */
  .feuille .sk-g{align-items:center;gap:6px;width:fit-content;min-height:44px;box-shadow:none;border-radius:12px;}
  .feuille .sk-g .pt b{font-weight:600;}
  .feuille .sk-chev{width:16px;height:16px;flex:0 0 auto;color:var(--ink-3);transition:transform .2s var(--ease);}
  .feuille .sk-g[aria-expanded="true"] .sk-chev{transform:rotate(90deg);}
  .feuille .sk-items{display:grid;gap:2px;padding-left:8px;}
  .feuille .sk-items[hidden]{display:none;}
  .feuille .sk-items > button:first-child{box-shadow:none;}
  @media (prefers-reduced-motion: reduce){ .feuille .sk-chev{transition:none;} }
  /* LE MENU DES SKILLS (fondateur 10/10 : « le carré du + il va pas… comme Claude ou GPT ») : un petit menu flottant
     au-dessus du +, pas un panneau d'un bord à l'autre — rangées basses, icône nue, la flèche au bord du menu étroit.
     Scopé par `.sk-menu` : la feuille d'avant (liste non servie) garde sa forme. */
  .feuille.sk-menu{right:auto;width:min(288px,calc(100% - 24px));}
  /* la même DA que le reste de l'appli (fondateur 10/10 : « on dirait une autre DA ») : rangées, puces de verre, rayon
     et ombre de la feuille d'origine — seule la LARGEUR change ; la flèche au bord du menu étroit */
  .feuille.sk-menu .sk-g{width:100%;}
  .feuille.sk-menu .sk-g .sk-chev{margin-left:auto;}
  /* la DA de l'appli (fondateur 10/10 : « la direction artistique n'est pas respectée ») : un titre porte la tuile de la
     marque des portes de l'accueil (`.portes-acc .pa-ic`), à la taille des puces ; ses gestes gardent les puces de verre
     et le filet de la feuille d'origine */
  .feuille.sk-menu .sk-tuile{flex:0 0 auto;width:34px;height:34px;border-radius:11px;display:grid;place-items:center;color:#FFFFFF;
    background:var(--marque);box-shadow:0 8px 18px -10px var(--marque-ombre);}
  .feuille.sk-menu .sk-tuile svg{width:18px;height:18px;}
  .feuille.sk-menu .sk-g .pt b{font-weight:600;font-size:var(--t-body);}
  .feuille.sk-menu .sk-g + .sk-items, .feuille.sk-menu .sk-items + .sk-g{box-shadow:0 -1px 0 var(--edge-2);}
  .feuille.sk-menu .sk-items > button + button{box-shadow:0 -1px 0 var(--edge-2);}
  .feuille.sk-menu .sk-items{padding-left:10px;}
  /* LA PHOTO QUI ATTEND (10/10, Q17) : la barre s'ouvre au-dessus du champ pour la vignette et sa ✕ */
  .composer .barre.ph-avec{flex-wrap:wrap;}
  .composer .ph-attente{flex:0 0 100%;display:flex;padding:4px 4px 2px;}
  .composer .ph-v{position:relative;width:64px;height:64px;border-radius:14px;overflow:hidden;border:1px solid var(--edge-2);}
  .composer .ph-v img{width:100%;height:100%;object-fit:cover;display:block;}
  .composer .ph-x{position:absolute;top:3px;right:3px;width:24px;height:24px;border-radius:50%;border:0;padding:0;
    background:rgba(15,20,30,.62);color:#fff;font-size:12px;line-height:24px;text-align:center;cursor:pointer;}
  .composer .ph-x::before{content:'';position:absolute;inset:-10px;}   /* 44 pt au doigt */
  /* les pastilles des gestes qui font quelque chose d'une photo (Q18) — au-dessus de la barre, comme les recherches
     récentes ; la rangée défile au doigt, un fondu dit qu'il y a une suite. En LARGEUR seulement (fondateur 11/10 : « ils
     bougent en hauteur ») : overflow-x:auto rendait aussi la hauteur défilable, et le doigt ne glisse que de côté. */
  .composer .ph-pastilles{position:absolute;left:14px;right:0;bottom:100%;margin-bottom:6px;display:flex;gap:6px;
    padding-right:28px;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;overscroll-behavior:contain;scrollbar-width:none;z-index:3;
    -webkit-mask-image:linear-gradient(90deg,#000 84%,transparent);mask-image:linear-gradient(90deg,#000 84%,transparent);}
  .composer .ph-pastilles::-webkit-scrollbar{display:none;}
  .composer .ph-pastilles button{flex:0 0 auto;min-height:44px;padding:0 14px;border-radius:22px;border:1px solid var(--edge);
    background:var(--pane);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);white-space:nowrap;
    font-family:var(--sans);font-size:var(--t-foot);color:var(--ink-2);cursor:pointer;}
  .composer .ph-pastilles button.defaut{background:var(--btn-plein-bg);color:var(--btn-plein-ink);border-color:transparent;}
  /* « LIRE LES AVIS » (lot 2) : un seul bord (16 px), le libellé et sa valeur sur la même ligne, la citation en retrait */
  .av-choix .av-ms{display:flex;flex-wrap:wrap;gap:6px;}
  .av-choix .av-m[aria-pressed="true"]{background:var(--btn-plein-bg);color:var(--btn-plein-ink);border-color:transparent;}
  .av-l{margin-top:12px;}
  .av-k{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:0 0 6px;font-size:var(--t-foot);
    font-weight:600;color:var(--ink);}
  .av-v{font-weight:400;color:var(--ink-3);font-variant-numeric:tabular-nums;}
  .av-src{display:flex;align-items:center;gap:10px;margin-top:6px;}
  .av-src .dvg{flex:0 0 auto;width:52px;height:52px;border-radius:12px;overflow:hidden;background:var(--pane-2);}
  .av-src .dvg img{width:100%;height:100%;object-fit:cover;display:block;}
  .av-src .dcc{flex:1;min-width:0;font-size:var(--t-foot);line-height:1.35;}
  .av-src .dcc b{font-weight:500;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
  .av-src .av-autre{flex:0 0 auto;min-height:44px;}
  .av-attente,.av-abs,.av-panne{margin:0;font-size:var(--t-foot);color:var(--ink-3);}
  .av-panne{margin-top:10px;}
  .av-choix .av-lire{margin-top:14px;}
  .av-res .av-b,.fo-avis .av-b{margin-top:12px;}
  .av-res .av-p,.fo-avis .av-p{margin:0;font-size:var(--t-body);line-height:1.4;color:var(--ink);}
  .av-res .av-c,.fo-avis .av-c{margin:4px 0 0;font-size:var(--t-foot);line-height:1.4;color:var(--ink-2);font-style:italic;}
  .av-res .av-s,.fo-avis .av-s{margin:4px 0 0;font-size:var(--t-cap);color:var(--ink-3);}
  .av-res .av-pied,.fo-avis .av-pied{margin:14px 0 0;font-size:var(--t-cap);color:var(--ink-3);}
  .av-res .av-agent{margin-top:10px;}
  /* Q14 : le résumé dans l'onglet Marché de la fiche, sous le prix en France */
  .fo-avis-zone:empty{display:none;}
  .fo-avis{margin-top:16px;}
  .fo-avis .fo-avis-relire{margin-top:10px;}
  /* « VOIR LES CONCURRENTS » (lot 3) : leurs photos en rangée, les arguments en lignes libellé + valeur */
  .cc-photos{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;margin-top:10px;padding-bottom:2px;}
  .cc-photos::-webkit-scrollbar{display:none;}
  .cc-ph{flex:0 0 auto;width:76px;height:76px;border-radius:12px;overflow:hidden;background:var(--pane-2);border:1px solid var(--edge-2);}
  .cc-ph img{width:100%;height:100%;object-fit:cover;display:block;}
  .cc-res .av-k{margin-top:14px;}
  .cc-arg{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:4px 0 0;font-size:var(--t-body);color:var(--ink);}
  .cc-res .cc-images,.cc-res .cc-biblio{margin-top:12px;}
  .cc-res a.cc-biblio{display:flex;align-items:center;justify-content:center;text-decoration:none;}
  /* LOT 4 : comparer (le choix, puis une rangée par produit), l'annonce */
    border:1px solid var(--edge-2);background:var(--pane-2);text-align:left;color:var(--ink);cursor:pointer;}
  .an-res .an-t{margin:0;font-size:var(--t-head);font-weight:600;line-height:1.3;color:var(--ink);}
  .an-res .an-pts{margin:10px 0 0;padding-left:18px;font-size:var(--t-body);line-height:1.45;color:var(--ink);}
  .an-res .an-pts li+li{margin-top:4px;}
  .an-res .an-copier{margin-top:12px;}
  @keyframes feuille-monte{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}
  .feuille button{display:flex;align-items:flex-start;gap:12px;width:100%;min-height:56px;
    padding:11px 12px;border:0;border-radius:17px;background:none;color:var(--ink);
    text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .feuille button+button{box-shadow:0 -1px 0 var(--edge-2);}
  .feuille button:hover,.feuille button:focus-visible{background:var(--pane-2);outline:none;}
  .feuille .pi{flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:flex;
    align-items:center;justify-content:center;background:var(--pane-2);
    border:1px solid var(--edge-2);color:var(--light);font-size:var(--t-foot);}
  .feuille .pi svg{width:18px;height:18px;display:block;}
  /* 🔴 PLUS DE SOUS-TITRE (fondateur, 26/08) : « dès qu'ils vont cliquer, ils vont voir le
     workflow direct. Il n'y a pas besoin. » Une entrée de menu n'a pas à décrire ce qui va se
     passer — le geste suivant le montre. La règle `.pt span` reste, sans usage aujourd'hui :
     la retirer ferait tomber un futur sous-titre à la taille du titre, sans prévenir. */
  .feuille .pt{display:grid;gap:2px;min-width:0;align-content:center;}
  .feuille .pt b{font-size:var(--t-foot);font-weight:500;letter-spacing:-.01em;}
  /* la seconde ligne fait tout le travail : elle annonce le métier sans promettre
     un bouton. C'est elle qui remplace un menu d'actes qui ne s'ouvriraient pas. */
  .feuille .pt span{font-size:var(--t-cap);line-height:1.45;color:var(--ink-3);}
  /* ── LA PORTE QUI SE PAIE ────────────────────────────────────────────────────────
     Elle ne fait pas la même chose que les autres : les quatre premières partent de ce
     que le CLIENT apporte, celle-ci part de ce que RABBIT va chercher — et elle coûte
     de l'argent à chaque passage. Une couleur qui ne dit rien serait du saupoudrage ;
     celle-ci ENSEIGNE la différence avant le clic, ce qui évite un refus surprise.
     `--warm` existe déjà dans les deux thèmes : on n'ajoute aucun vocabulaire. Le vert
     reste réservé à l'acte de payer, le bleu à la voix de Rabbit. */
  .feuille button[data-plus="ultra"] .pi{
    color:var(--warm);border-color:color-mix(in srgb,var(--warm) 42%,transparent);
    background:color-mix(in srgb,var(--warm) 12%,var(--pane-2));
    box-shadow:0 0 14px -4px color-mix(in srgb,var(--warm) 55%,transparent);}
  .feuille button[data-plus="ultra"] .pt b{color:var(--warm);}
  .feuille button[data-plus="ultra"]:hover,
  .feuille button[data-plus="ultra"]:focus-visible{background:color-mix(in srgb,var(--warm) 8%,var(--pane-2));}

  .homebar{flex:0 0 auto;display:flex;justify-content:center;padding:9px 0 9px;position:relative;z-index:2;}
  .homebar i{width:114px;height:4.5px;border-radius:3px;background:var(--ink-3);opacity:.42;}

  /* l'ombre au sol */
  .ground{position:absolute;left:50%;bottom:-44px;width:112%;height:56px;transform:translateX(-50%);
    background:radial-gradient(50% 50% at 50% 50%, var(--shadow), transparent 72%);
    filter:blur(19px);opacity:.9;pointer-events:none;}

  /* ═══ LA CONVERSATION ═══ */
  .r{display:flex;align-items:flex-start;gap:9px;margin-top:11px;}
  /* les OBJETS (cartes teintées) prennent la largeur du fil : la colonne d'avatar
     est VIDE devant eux (mesuré au banc, 0 caractère) — 308 → 351 px sur 375.
     La carte vit à 5 wrappers du rang : on retire la COLONNE, pas la carte.
     (Un navigateur sans :has garde l'ancienne largeur — rien ne casse.) */
  .r:has(.card.dobj) > .av{display:none;}
  .r.tight{margin-top:3px;}
  .av{width:30px;flex:0 0 auto;}
  .av svg{width:28px;height:28px;display:block;color:var(--light);filter:drop-shadow(0 0 8px var(--glow));}
  .rtxt{flex:1;font-size:var(--t-body);line-height:1.45;color:var(--ink);padding:1px 0 2px;min-width:0;}
  .rtxt b{font-weight:500;}
  /* LA RÉPONSE DE SAVOIR (fondateur, 26/09) — titres, listes, gras. « Tout ce qui est gras ou important
     dans les couleurs du thème, pour pas avoir un pavé noir » : la voix de Rabbit (--light) dans chacun des
     quatre thèmes, jamais une valeur en dur. Garde : savoir-fil. */
  .rtxt.savoir p{margin:0 0 8px;}
  .rtxt.savoir h3{margin:14px 0 4px;font:600 var(--t-head)/1.3 var(--sans);letter-spacing:var(--t-head-ls);color:var(--light);}
  .rtxt.savoir h3:first-child{margin-top:0;}
  .rtxt.savoir b{font-weight:600;color:var(--light);}
  .rtxt.savoir ul,.rtxt.savoir ol{margin:0 0 8px;padding:0;list-style:none;}
  .rtxt.savoir li{position:relative;padding-left:16px;margin:3px 0;}
  .rtxt.savoir ul > li::before{content:"";position:absolute;left:3px;top:.62em;width:6px;height:6px;border-radius:50%;background:var(--light);}
  .rtxt.savoir ol > li{padding-left:24px;}
  .rtxt.savoir ol > li::before{content:attr(data-n) ".";position:absolute;left:0;color:var(--light);font-weight:600;}
  .rtxt.savoir > :last-child{margin-bottom:0;}
  .rtxt span.w{display:inline-block;animation:wordin .34s var(--ease) backwards;}
  @keyframes wordin{from{opacity:0;transform:translateY(4px);filter:blur(2px);}to{opacity:1;transform:none;filter:none;}}

  /* la bulle du client suit la MAQUETTE (--bulle-bg) : bleu doux, texte encre —
     l'ancien dégradé saturé + glow jurait à côté des cartes (fondateur 30/08 :
     « il faut que ce soit harmonieux par rapport à nos résultats »). */
  /* LA MÊME TAILLE QUE RABBIT (fondateur 02/09, mesuré sur prod : Rabbit 17, le
     client 13 — 1,31× d'écart). Une conversation a UNE taille de corps : la parole
     du client est du fil autant que celle de Rabbit (charte loi 3, Body = la parole
     du fil). Le lot 3 avait monté .rtxt à 17 et oublié cette bulle. Interligne 1.45,
     celui de la compacité du lot 3. */
  .u{align-self:flex-end;max-width:80%;margin-top:7px;padding:9px 13px;border-radius:19px 19px 6px 19px;
    font-size:var(--t-body);line-height:1.45;background:var(--bulle-bg);color:var(--bulle-ink);
    border:1px solid var(--edge-2);box-shadow:var(--sh-1);}
  /* la bulle du client lit --bulle-bg / --bulle-ink : un design, un jeu de jetons (ticket Apparence 01) */
  /* une photo envoyée EST la bulle : pas de cadre coloré autour */
  .u.shot{padding:0;overflow:hidden;background:none;border-radius:20px 20px 7px 20px;max-width:62%;
    box-shadow:0 14px 34px -16px var(--shadow), 0 0 26px -10px var(--glow);}
  .u.shot .snap{border-radius:inherit;}
  .seen{align-self:flex-end;font-size:var(--t-cap);
    color:var(--ink-3);margin-top:4px;padding-right:4px;animation:parait .34s var(--e-pouce) backwards;}

  /* la photo que le client envoie */
  /* largeur EXPLICITE : la bulle se dimensionne sur son contenu, un bloc vide y sort en trait */
  .snap{position:relative;width:162px;height:206px;border-radius:16px;overflow:hidden;
    background:radial-gradient(64% 58% at 38% 28%, rgba(255,255,255,.62), transparent 60%),
      linear-gradient(158deg, #7EA8BE, #2C4757 62%, #16232C);}
  .snap::after{content:"";position:absolute;left:50%;top:14%;width:34%;height:74%;transform:translateX(-50%);
    border-radius:11px 11px 16px 16px;
    background:linear-gradient(96deg, rgba(255,255,255,.32), rgba(255,255,255,.06) 34%, rgba(0,0,0,.24));
    box-shadow:0 10px 22px -12px rgba(0,0,0,.7);}
  .snap .scan{position:absolute;left:0;right:0;height:34%;z-index:2;
    background:linear-gradient(transparent, color-mix(in srgb,var(--light-hi) 46%,transparent) 78%, color-mix(in srgb,var(--light-hi) 88%,transparent));
    box-shadow:0 6px 18px var(--glow);animation:scan 1.7s var(--ease) 2;}
  @keyframes scan{0%{transform:translateY(-40%);opacity:0;}18%{opacity:1;}82%{opacity:1;}100%{transform:translateY(300%);opacity:0;}}

  /* l'indicateur de frappe */
  .typing{display:inline-flex;gap:4px;align-items:center;padding:4px 0 2px;}
  .typing i{width:5.5px;height:5.5px;border-radius:50%;background:var(--ink-3);animation:dot 1.25s ease-in-out infinite;}
  .typing i:nth-child(2){animation-delay:.16s;} .typing i:nth-child(3){animation-delay:.32s;}
  @keyframes dot{0%,60%,100%{opacity:.28;transform:translateY(0);}30%{opacity:1;transform:translateY(-3px);}}

  .cur{display:inline-block;width:2px;height:15px;background:var(--light);vertical-align:-2px;
    margin-left:1px;box-shadow:0 0 10px var(--glow);animation:bl .85s step-start infinite;}
  @keyframes bl{50%{opacity:0;}}

  /* le repère de temps */
  .when{display:flex;align-items:center;gap:10px;margin:14px 2px 2px;
    font-size:var(--t-cap);color:var(--ink-3);
    animation:wordin .5s var(--ease) backwards;}
  .when::before,.when::after{content:"";flex:1;height:1px;background:var(--edge-2);}

  /* ═══════════════════ LES DIX ENTRÉES ═══════════════════
     UNE scène, quatre origines, et chaque ressource dépensée UNE SEULE FOIS.
     La DIRECTION dit d'où ça vient : ce qui vient du pouce du client naît au coin
     bas-droit sans une once de profondeur · ce que Rabbit construit ne voyage pas,
     ça s'ouvre sur place · ce qui t'engage monte de sous la surface sans jamais
     dépasser le plan · ce que TU scelles tombe du champ proche en accélérant ·
     ce qui vient du monde ou bien ne bouge pas, ou bien traverse la profondeur
     pendant que la conversation recule · et ce que Rabbit TRANCHE est le seul plan
     qui dépasse le plan de l'écran.

     LE BUDGET, tenu keyframe par keyframe :
       une seule naissance en champ proche (le tampon) · un seul dépassement du plan
       (le verdict) · une seule traversée de la profondeur (la pesée) · un seul
       égrenage vertical (le ticket) · une seule accélération (le tampon) · un seul
       objet qui ne bouge pas (les photos QC) · l'éclat et l'onde n'existent QU'AU
       verdict · AUCUN balayage de lumière nulle part — c'était le gadget commun.
     Le flou ne sert que ce qui vient du monde, et jamais sur une grande surface.  */

  .obj{opacity:0;backface-visibility:hidden;}
  /* le seul micro-geste partagé : « ça paraît ». Aucune position, aucune échelle. */
  @keyframes parait{from{opacity:0;}to{opacity:1;}}

  /* 1 — la photo du client : le geste. Zéro profondeur : ça vient de la main qui tient
        le téléphone, pas de loin. L'objet le plus léger fait le moins de bruit. */
  .envoie{transform-origin:100% 100%;animation:envoie .82s var(--e-pouce) both;}
  @keyframes envoie{
    0%  {opacity:0;transform:translateY(30px) rotate(-4deg) scale(.86);}
    44% {opacity:1;transform:translateY(14px) rotate(-1.8deg) scale(.94);}
    72% {opacity:1;transform:translateY(-3px) rotate(.6deg) scale(1.014);}
    100%{opacity:1;transform:translateY(0) rotate(0deg) scale(1);}
  }
  /* Rabbit ne lit pas une photo qui n'est pas encore posée */
  .envoie .scan{animation-delay:.86s;}

  /* 2 — la galerie : l'objet devient réel. Il ne voyage pas, il S'OUVRE — et il
        s'ouvre sur l'axe même du geste qu'on pourra faire dessus. */
  .materialise{animation:materialise 1.1s var(--e-main) both;}
  @keyframes materialise{
    0%  {opacity:0;clip-path:inset(0 46% 0 46% round 20px);transform:scale(1.05);}
    28% {opacity:1;}
    100%{opacity:1;clip-path:inset(0 0 0 0 round 20px);transform:scale(1);}
  }
  .materialise .vig{animation:vig .6s var(--e-main) both;}
  .materialise .vig:nth-child(1){animation-delay:.28s;}
  .materialise .vig:nth-child(2){animation-delay:.35s;}
  .materialise .vig:nth-child(3){animation-delay:.42s;}
  @keyframes vig{0%{opacity:0;transform:translateX(16px) scale(1.03);}100%{opacity:1;transform:translateX(0) scale(1);}}

  /* 3 — le chiffre qu'on va démentir. La seule entrée qui vient d'EN HAUT, la seule
        qui ne touche jamais l'accent cyan, la seule dont le contenu arrive d'un bloc.
        Son entrée doit être la plus pauvre, sinon le démenti ressemble à un revirement. */
  .depose{animation:depose .8s var(--e-plat) both;}
  @keyframes depose{0%{opacity:0;transform:translateY(-8px);}100%{opacity:1;transform:translateY(0);}}
  .depose .card>*{animation:parait .34s var(--e-plat) .22s backwards;}

  /* 4 — « Vas-y ». La même main que la photo, en version comprimée : la rime doit être
        immédiate pour qu'on reconnaisse qui parle sans lire. Le mode le moins original. */
  .repond{transform-origin:100% 100%;animation:repond .8s var(--e-pouce) both;}
  @keyframes repond{
    0%  {opacity:0;transform:translateY(16px) rotate(-2deg) scale(.92);}
    38% {opacity:1;transform:translateY(7px) rotate(-.9deg) scale(.96);}
    64% {opacity:1;transform:translateY(-2px) rotate(.3deg) scale(1.01);}
    100%{opacity:1;transform:translateY(0) rotate(0deg) scale(1);}
  }

  /* 5 — le plan de travail se déroule. Aucun secondaire, aucun décalage : les trois
        coches qui tombent ENSUITE sont la scène, l'entrée ne fait que leur ouvrir la place. */
  .ouvre{animation:ouvre 1s var(--e-main) both;}
  @keyframes ouvre{
    0%  {opacity:0;clip-path:inset(0 0 100% 0 round 22px);transform:translateY(-6px);}
    18% {opacity:1;}
    100%{opacity:1;clip-path:inset(0 0 0 0 round 22px);transform:translateY(0);}
  }

  /* 6 — LE VERDICT. 200 ms de vide absolu, puis le seul plan de la scène qui dépasse
        le plan de l'écran et s'arrête net. Seul détenteur de l'éclat, de l'onde,
        de l'égrenage vertical et du halo. */
  .tranche{position:relative;transform-style:preserve-3d;animation:tranche 1.25s var(--e-pic) both;}
  .tranche>*{position:relative;z-index:1;}
  @keyframes tranche{
    0%  {opacity:0;transform:translateZ(-180px) translateY(28px) rotateX(9deg) scale(.92);}
    16% {opacity:0;transform:translateZ(-180px) translateY(28px) rotateX(9deg) scale(.92);}
    48% {opacity:1;}
    70% {transform:translateZ(52px) translateY(-6px) rotateX(-3.5deg) scale(1.03);}
    100%{opacity:1;transform:translateZ(0) translateY(0) rotateX(0deg) scale(1);}
  }
  .tranche::before{content:"";position:absolute;inset:-16%;z-index:0;border-radius:50%;pointer-events:none;
    background:radial-gradient(circle at 50% 46%, var(--glow), transparent 62%);
    animation:eclat .72s var(--e-main) .78s both;}
  @keyframes eclat{0%{opacity:0;transform:scale(.55);}26%{opacity:.85;}100%{opacity:0;transform:scale(1.22);}}
  .tranche::after{content:"";position:absolute;inset:0;z-index:0;border-radius:22px;pointer-events:none;
    border:1px solid var(--light-hi);animation:onde .68s var(--e-main) .84s both;}
  @keyframes onde{0%{opacity:.9;transform:scale(1);}100%{opacity:0;transform:scale(1.075);}}
  /* le ticket ne commence QU'APRÈS l'immobilité : aucun chiffre n'est lu à travers
     une déformation, et aucun chiffre n'anime sa valeur. */
  .tranche .lg{animation:lg .42s var(--e-main) both;}
  .tranche .lg:nth-child(1){animation-delay:1.06s;}
  .tranche .lg:nth-child(2){animation-delay:1.17s;}
  .tranche .lg:nth-child(3){animation-delay:1.43s;}   /* 260 ms de SILENCE avant le bénéfice */
  @keyframes lg{0%{opacity:0;transform:translateY(9px);}100%{opacity:1;transform:translateY(0);}}
  .tranche .benef{animation:halo .55s ease-out 1.5s both;}
  @keyframes halo{0%{text-shadow:0 0 0 transparent;}55%{text-shadow:0 0 26px var(--glow);}100%{text-shadow:0 0 12px var(--glow);}}

  /* 7 — les actions. Elles ne viennent pas vers toi : elles se décollent de sous la
        surface et TIENNENT. Aucun dépassement — une cible qui rebondit est une cible
        qu'on rate, et ce serait un mini-verdict deux secondes après le pic. */
  .leve{opacity:1;transform-style:preserve-3d;}
  .leve .btn{--sink:-26px;animation:leve .9s var(--e-main) both;}
  .leve .btn.ghost{--sink:-10px;animation-delay:.09s;}
  @keyframes leve{
    0%  {opacity:0;transform:translateY(10px) translateZ(var(--sink)) scale(.984);}
    38% {opacity:1;}
    100%{opacity:1;transform:translateY(0) translateZ(0) scale(1);}
  }
  /* l'ombre est une COUCHE dont on anime l'OPACITÉ — jamais un box-shadow interpolé */
  .leve .btn:not(.ghost)::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
    box-shadow:0 8px 18px -6px var(--glow);opacity:1;animation:ombre .9s var(--e-main) both;}
  @keyframes ombre{0%,34%{opacity:0;}100%{opacity:1;}}

  /* 8 — LE TAMPON. Un engagement ne se dépose pas, il se FRAPPE : la seule entrée de
        la scène qui accélère au lieu de freiner. Une accélération se reconnaît en 200 ms. */
  .tampon{transform-origin:50% 0%;transform-style:preserve-3d;animation:tampon 1s linear both;}
  @keyframes tampon{
    0%  {opacity:0;transform:translateY(-14px) translateZ(56px) rotateX(7deg);animation-timing-function:var(--e-chute);}
    26% {opacity:1;transform:translateY(-9px) translateZ(38px) rotateX(4.6deg);animation-timing-function:var(--e-chute);}
    60% {opacity:1;transform:translateY(0) translateZ(0) rotateX(0deg);animation-timing-function:var(--e-main);}
    70% {opacity:1;transform:translateY(0) translateZ(-6px) rotateX(0deg);}
    100%{opacity:1;transform:translateY(0) translateZ(0) rotateX(0deg);}
  }
  /* les 3 ✓ s'impriment ENSEMBLE, au contact : un tampon n'égrène pas.
     C'est le contraste rythmique avec le ticket du verdict, qui, lui, égrène. */
  .tampon .ok{animation:encre .34s var(--e-main) .62s both;}
  @keyframes encre{0%{opacity:0;transform:scale(.7);}62%{opacity:1;transform:scale(1.06);}100%{opacity:1;transform:scale(1);}}
  .tampon .tamponne{animation:residu .4s linear .86s both;}
  @keyframes residu{0%{opacity:0;}100%{opacity:.72;}}

  /* 9 — les photos de contrôle. Prises ailleurs, il y a des jours : elles n'arrivent
        pas dans le fil, elles APPARAISSENT à leur place. Le conteneur ne bouge pas.
        Le flou est gagné ici : trois vignettes, pas une grande surface. */
  .developpe{opacity:1;}
  .developpe .qc{animation:developpe 1.25s var(--e-monde) both;}
  .developpe .qc:nth-child(2){animation-delay:.17s;}
  .developpe .qc:nth-child(3){animation-delay:.34s;}
  @keyframes developpe{
    0%  {opacity:0;transform:scale(1.035);filter:blur(7px) saturate(.2) brightness(1.25);}
    38% {opacity:1;transform:scale(1.02);filter:blur(3.4px) saturate(.55) brightness(1.12);}
    100%{opacity:1;transform:scale(1);filter:none;}
  }

  /* 10 — LA PESÉE. Le mouvement n'est pas dans la carte : il est dans tout ce qui
         recule derrière elle. Le seul moment où un objet gagne sa présence en
         RETIRANT de la présence aux autres. */
  .remonte{animation:remonte 1.3s var(--e-monde) both;}
  @keyframes remonte{
    0%  {opacity:0;transform:translateZ(-380px) translateY(10px);}
    14% {opacity:0;transform:translateZ(-380px) translateY(10px);}  /* le fil recule AVANT */
    52% {opacity:1;}
    100%{opacity:1;transform:translateZ(0) translateY(0);}
  }
  .remonte .poids{animation:parait .45s var(--e-monde) 1.15s both;}
  /* le contre-champ, sur UN SEUL wrapper : un flou par carte tuerait le mobile */
  .fil-recule{display:flex;flex-direction:column;flex:0 0 auto;
    animation:recule .9s cubic-bezier(.30,.70,.25,1) both;}
  @keyframes recule{
    0%  {opacity:1;transform:translateZ(0);filter:blur(0);}
    100%{opacity:.26;transform:translateZ(-190px);filter:blur(2.5px);}
  }

  /* ── LA MISE À L'ÉCART ──
     Un chiffre qu'on dément ne s'empile pas dans le fil : il est écarté.
     Seul mouvement LATÉRAL de la scène — la profondeur et la verticale disent
     « ça arrive », l'horizontale dit « ça ne compte plus ». */
  .r.ecarte{animation:ecarte 1s var(--ease) forwards;pointer-events:none;}
  @keyframes ecarte{
    0%  {opacity:1;transform:translateX(0) rotate(0deg);filter:none;}
    20% {opacity:1;transform:translateX(13px) rotate(.7deg);}
    100%{opacity:0;transform:translateX(-116%) rotate(-3.4deg) scale(.93);filter:blur(2.5px);}
  }

  /* ═══ LES CARTES ═══ */
  /* pan-y sur la carte : c'est le MAINTIEN IMMOBILE de 350 ms qui distingue la prise
     du défilement — un doigt qui fait défiler n'est jamais immobile. Confisquer la
     verticale sur toute la carte volerait le défilement de la page pour rien. */
  /* 🔴 « JE CLIQUE SUR AUGMENTER LES QUANTITÉS, ÇA ME ZOOME SUR LA FICHE » (fondateur,
     31/08, sur son téléphone). Ce n'était pas la police — tous ces champs sont déjà à
     16 px. C'est le DOUBLE-TAP : deux appuis rapprochés sur « + » sont lus par iOS comme
     le geste de zoom, et c'est exactement ce qu'on fait quand on monte une quantité.
     `touch-action:manipulation` retire le double-tap-pour-zoomer sans rien retirer
     d'autre (le pan et le pincement restent).
     ⚠️ `.garder` et `.dprise` en sont EXCLUS : ces deux boutons vivent dans une carte
     qui confisque la verticale pour son geste de prise — leur donner `manipulation`
     rendrait le pan au navigateur et casserait le glissé depuis le bouton. */
  button:not(.garder):not(.dprise), a, input, select, textarea, label,
  [role="button"], [role="menuitem"]{touch-action:manipulation;}
  .card[data-kind="candidate"]{touch-action:pan-y;cursor:grab;}
  /* ═══ MATIÈRE A — LA PLAQUE MINÉRALE, ET PAS DU VERRE (fondateur, séance 24/08 :
     « on suit Apple »).
     Le verre a été posé sur les cartes le matin même, puis RETIRÉ le jour même sur
     mesure : Apple réserve son matériau translucide à la couche FONCTIONNELLE
     (barres, contrôles) et l'interdit sur la couche CONTENU — « avoid quaternary
     on thin materials, the contrast is too low ». Notre mesure a donné la même
     réponse en chiffres : sur verre, l'encre tertiaire tombait à 2,07:1 au-dessus
     de la zone claire du fond, contre 4,64:1 sur cette plaque. Une carte porte les
     RÉSERVES du produit (« poids estimé », « prix vus en ligne ») : les rendre
     pâles, c'est rendre l'honnêteté décorative.
     Ce qui RESTE de la séance : la carte a maigri (paddings, rayons, ombres) —
     une carte du fil est un objet posé, pas un monument.
     Le verre du fil vit donc où Apple le met : `.sugg button`, `.replay`,
     `.gal figcaption` — des contrôles, jamais du contenu. ═══ */
  .card{position:relative;overflow:hidden;border-radius:17px;
    padding:9px 13px;display:flex;flex-direction:column;gap:6px;margin-top:7px;
    background:var(--carte-bg);
    border:1px solid var(--carte-edge);
    border-top:1.5px solid var(--carte-biseau);
    border-bottom:3px solid var(--carte-tranche);
    box-shadow:0 12px 28px -12px var(--shadow), 0 3px 8px -4px var(--shadow);}

  /* ── LES TAILLES DISENT L'ALTITUDE ──
     Trois formats, trois élévations. Une carte qui pèse dans le récit est plus
     GRANDE et plus HAUTE ; une carte qu'on va démentir est une note. Sans cet
     écart, aucune carte ne peut être proche ou loin : tout revient au même plan. */
  .card.note{align-self:flex-start;width:auto;max-width:74%;padding:9px 13px 9px 20px;
    border-radius:16px;box-shadow:0 3px 8px -6px var(--shadow);}
  .card.note .v.mid{font-size:var(--t-body);}
  /* LE VERDICT : le seul objet qui prend AUSSI la gouttière de l'avatar. Il est
     physiquement plus large que tout le reste, et c'est le seul à s'élever. */
  .tranche .card{margin-left:-39px;border-radius:21px;padding:13px 17px 13px 24px;
    box-shadow:0 18px 40px -16px var(--shadow), 0 5px 12px -6px var(--shadow);}
  .tranche .ddp{margin-left:-39px;}
  /* 🔴 RÈGLE : SUR UNE PLAQUE TRANSLUCIDE, L'ENCRE DE LECTURE EST --ink-2.
     (séance 24/08, mesuré.) La plaque minérale est elle-même translucide (16 %),
     donc --ink-3 y tombe à 2,65:1 au-dessus de la zone claire du fond — sous la
     norme, et précisément sur les mentions qui portent les RÉSERVES du produit.
     En --ink-2 : 5,53:1. C'est la règle Apple tenue jusqu'au bout (« avoid
     quaternary on thin materials »), et elle juge le PROCHAIN site, pas seulement
     ceux-ci : `.fact` l'appliquait déjà, `.lab` et `.stamp` en étaient les deux
     exceptions. Contenance vérifiée par les gabarits de fil.js le 24/08 : aucune
     autre encre tertiaire n'est rendue dans une carte vivante.
     Les cartes à famille gardent leur teinte propre (règle .card[data-famille]). */
  .lab{font-size:var(--t-cap);color:var(--ink-2);}

  /* ══ L'IDENTITÉ DES CARTES (fondateur, 17/08 : « elles se ressemblent toutes ») ══
     Chaque FAMILLE se reconnaît à trois signes, dans cet ordre d'importance :
       1. son GLYPHE dans le titre — il se lit sans couleur, c'est le signe premier ;
       2. son FILET DE TÊTE, un trait court sous le biseau, à gauche ;
       3. sa teinte, qui ne fait que confirmer. Jamais elle seule (loi des natures).
     Les cartes produit n'en ont pas besoin : leur grande photo EST leur identité. */
  .card[data-famille]{--fam:var(--ink-3);}
  /* ⚠️ LES SIX COULEURS DE FAMILLE SONT MORTES LE 14/09 — décision du fondateur : « Pour moi,
     seule la lumière parle de couleur. » Elles étaient :
        estimation #7FD0A8 · livraison #8FB6E8 · reception #E8B478
        recherche  #B79BE0 · commande  #7FD0A8 · palier    #E0C87F
     Trois grammaires de couleur vivaient sur le même objet — ces six teintes, les jetons
     `--fc` posés en style dans le JS, et la lumière déployée la veille. Le fondateur l'a vu
     avant nous : « c'est plus la même DA ».
     LA STRUCTURE RESTE, et c'est elle qui fait l'identité : le GLYPHE (il se lit sans couleur,
     signe premier de la doctrine du 17/08), le bandeau, l'arête, et le bord de bandeau qui dit
     la famille SANS couleur (perforé, double, pointillé, plein). Seule la TEINTE part : le repli
     `--fam:var(--ink-3)` ci-dessus prend, identique pour toutes.
     Garde : objet-couleur.test.js règle 1. */
  /* ⚠️ 17/08 : une première version ne posait qu'un glyphe de 11px et un filet de
     2px — « je vois pas trop de différence, c'est pratiquement les mêmes ». Une
     identité ne se dose pas en homéopathie : il faut de la STRUCTURE. D'où le
     bandeau de tête pleine largeur ci-dessous, l'arête verticale de famille, et
     un bord de bandeau qui diffère par famille (perforé, pointillé, plein…). */

  /* 1. LE BANDEAU DE TÊTE — le titre cesse d'être une ligne et devient une zone.
     Il déborde jusqu'aux bords de la carte (marges négatives = les paddings
     exacts de .card, y compris les 22px de l'arête). */
  .card[data-famille] > .lab:first-child{
    margin:-11px -15px 2px -22px;padding:8px 15px 7px 22px;
    background:color-mix(in srgb, var(--fam) 13%, transparent);
    border-bottom:1.5px solid color-mix(in srgb, var(--fam) 42%, transparent);
    color:color-mix(in srgb, var(--fam) 78%, var(--ink));
    display:flex;align-items:center;}
  .tranche .card[data-famille] > .lab:first-child{margin:-13px -17px 2px -24px;padding:9px 17px 8px 24px;}
  /* 2. L'ARÊTE DE FAMILLE — pleine hauteur, sous l'arête de prise (z-index 5). */
  .card[data-famille]::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;
    background:var(--fam);opacity:.6;z-index:0;}
  /* 3. LE BORD DU BANDEAU dit la famille SANS couleur : perforé = à détacher
     (estimation, commande), pointillé = en route (livraison), tirets = en cours
     (recherche), plein = enregistré (réception, palier). */
  .card[data-famille="estimation"] > .lab:first-child{border-bottom-style:dashed;border-bottom-width:2px;}
  .card[data-famille="commande"]   > .lab:first-child{border-bottom-style:double;border-bottom-width:4px;}
  .card[data-famille="livraison"]  > .lab:first-child{border-bottom-style:dotted;border-bottom-width:2px;}
  .card[data-famille="recherche"]  > .lab:first-child{border-bottom-style:dashed;
    background:color-mix(in srgb, var(--fam) 8%, transparent);}
  .lab .fi{width:14px;height:14px;flex:0 0 auto;margin-right:7px;
    stroke:var(--fam,var(--ink-3));fill:none;stroke-width:1.9;
    stroke-linecap:round;stroke-linejoin:round;}
  .card.gardee-mini::before{opacity:.35;}
  .row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:4px 0;}
  .row+.row{border-top:1px solid var(--edge-2);}
  .k{font-size:var(--t-foot);color:var(--ink-2);}
  /* un montant ne se coupe JAMAIS sur deux lignes (audit 01/09 : « 5,60 € » plié) */
  .v{font-weight:400;font-variant-numeric:tabular-nums;font-size:var(--t-body);white-space:nowrap;}
  .v.mid{font-size:var(--t-title);letter-spacing:-.02em;}
  /* le halo du bénéfice s'allume UNE fois et reste allumé (cf. .tranche .benef) :
     une pulsation perpétuelle le rendrait décoratif au lieu de conclusif. */
  .v.big{font-size:var(--t-large);color:var(--light);letter-spacing:-.02em;text-shadow:0 0 8px var(--glow);}
  /* doctrine de l'écran, lot 3 : ce qui manque se dit DANS la rangée (« non calculés »), la nature d'un prix sous son mot */
  .v.nc{font-size:var(--t-foot);font-weight:500;color:var(--ink-2);}
  .row .k small{display:block;font-size:var(--t-cap);color:var(--ink-3);}
  /* ══ LE PRIX SE DÉCOMPOSE AU TOUCHER (spec art. 4, 91e) : la ligne « livrée chez
     toi » porte un chevron et s'ouvre sur produit + livraison + douane, chaque
     ligne avec sa nature et sa date — le patron `decomp` de carte-vivante-v4. ══ */
  .row.rprix{cursor:pointer;min-height:44px;align-items:center;}
  .row.rprix .k::after{content:'❯';display:inline-block;margin-left:6px;font-size:var(--t-cap);
    color:var(--ink-3);transition:transform .3s var(--e-main);}
  .row.rprix.ouverte .k::after{transform:rotate(90deg);}
  .decomp{border:1px solid var(--edge-2);border-radius:12px;padding:2px 12px;
    background:var(--pane-2);margin:4px 0 6px;}
  .decomp .row{padding:7px 0;}
  .decomp .k small{display:block;font-size:var(--t-cap);color:var(--ink-3);}
  .decomp .v{font-size:var(--t-foot);font-weight:600;}

  .gal{position:relative;margin-top:9px;border-radius:20px;overflow:hidden;border:1px solid var(--edge);box-shadow:var(--sh-2);
    display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;}
  .gal::-webkit-scrollbar{display:none;}
  .gal figure{flex:0 0 100%;scroll-snap-align:center;height:196px;margin:0;position:relative;}
  .g1{background:radial-gradient(70% 74% at 32% 24%, rgba(255,255,255,.60), transparent 58%),linear-gradient(150deg, color-mix(in srgb,var(--light) 50%,var(--screen)), color-mix(in srgb,var(--ink) 42%,var(--screen)));}
  .g2{background:radial-gradient(64% 70% at 66% 30%, rgba(255,255,255,.52), transparent 60%),linear-gradient(200deg, color-mix(in srgb,var(--ink) 34%,var(--screen)), color-mix(in srgb,var(--light) 42%,var(--screen)));}
  .g3{background:radial-gradient(80% 60% at 50% 80%, rgba(255,255,255,.46), transparent 62%),linear-gradient(120deg, color-mix(in srgb,var(--light-hi) 46%,var(--screen)), color-mix(in srgb,var(--ink) 36%,var(--screen)));}
  .q1{background:radial-gradient(62% 66% at 40% 30%, rgba(255,255,255,.46), transparent 58%),linear-gradient(146deg, color-mix(in srgb,var(--warm) 36%,var(--screen)), color-mix(in srgb,var(--ink) 38%,var(--screen)));}
  .q2{background:radial-gradient(58% 62% at 62% 36%, rgba(255,255,255,.40), transparent 60%),linear-gradient(186deg, color-mix(in srgb,var(--ink) 32%,var(--screen)), color-mix(in srgb,var(--warm) 30%,var(--screen)));}
  .q3{background:radial-gradient(74% 58% at 48% 74%, rgba(255,255,255,.36), transparent 62%),linear-gradient(128deg, color-mix(in srgb,var(--ink-2) 42%,var(--screen)), color-mix(in srgb,var(--ink) 34%,var(--screen)));}
  .gal figcaption{position:absolute;left:11px;bottom:9px;font-size:var(--t-cap);
    color:var(--ink-2);background:var(--pane);
    padding:4px 8px;border-radius:11px;border:1px solid var(--edge);backdrop-filter:blur(10px);}
  /* LA BANDE SOUS LA RÉPONSE (05/10, maquette docs/mockups/photos-conversation-0410/) : une vidéo y tient comme une photo,
     ▶ au centre comme dans le détail de la commande (.qc-lire) */
  .gal figure video{width:100%;height:100%;object-fit:cover;display:block;background:#000;}
  .gal .gal-lire{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:52px;height:52px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.55);color:#fff;font-size:var(--t-title);line-height:1;pointer-events:none;}
  .gal-preuves figure{cursor:zoom-in;}
  .swipe{display:flex;align-items:center;gap:7px;margin-top:7px;font-size:var(--t-cap);
    color:var(--ink-3);}
  .swipe i{width:5px;height:5px;border-radius:50%;background:var(--edge);display:block;}
  .swipe i:first-child{background:var(--light);box-shadow:0 0 8px var(--glow);}

  /* pas d'overflow:hidden : la couche d'ombre de « leve » déborde par construction */
  .btn{position:relative;margin-top:9px;padding:0 18px;border-radius:15px;text-align:center;
    font-size:var(--t-body);font-weight:600;letter-spacing:-.01em;min-height:50px;display:flex;align-items:center;justify-content:center;
    background:var(--btn-plein-bg);color:var(--btn-plein-ink);box-shadow:none;}   /* le bouton plein par jetons, dès la base (ticket Apparence 03) */
  .btn.ghost{background:transparent;border:1px solid var(--edge);color:var(--ink-2);box-shadow:none;font-weight:400;}

  .step{display:flex;align-items:center;gap:10px;padding:7px 0;font-size:var(--t-foot);color:var(--ink-3);
    transition:color .5s ease;}
  .step+.step{border-top:1px solid var(--edge-2);}
  .step i{width:15px;height:15px;border-radius:50%;flex:0 0 auto;box-shadow:inset 0 0 0 1.5px var(--edge);
    display:flex;align-items:center;justify-content:center;font-style:normal;font-size:var(--t-cap);color:var(--light);
    transition:box-shadow .5s ease,background .5s ease,color .5s ease;}
  .step.on{color:var(--ink);} .step.on i{box-shadow:inset 0 0 0 1.5px var(--light);}
  .step.now i{background:var(--light);color:var(--screen);box-shadow:0 0 16px var(--glow);}

  /* ══ LA PROFONDEUR, EN SYSTÈME (17/08, fondateur) ═══════════════════════════
     « Je veux que toute l'app soit comme ça : tout arrive devant les yeux. »
     UN SEUL endroit l'applique — `drop()`, la porte unique par laquelle un objet
     entre dans le fil. Aucun écran n'a à s'en occuper, et aucun ne peut l'oublier.

     Le FLOU fait la profondeur : un objet lointain n'est pas net. Sans lui, un
     objet qui grandit n'est qu'un objet qui grandit. C'est la mesure du 17/08.

     TROIS INTENSITÉS, jamais une seule : si tout vole de la même façon, plus rien
     ne vole. La distance parcourue dit le poids de ce qui arrive.
     L'animation vit sur `.rtxt` — `.obj` garde la sienne (materialise, tranche…),
     et deux transforms sur le même élément s'écrasent. */
  .prof{perspective:1100px;perspective-origin:50% 45%;}
  .prof .rtxt{will-change:transform,filter,opacity;}
  .prof.p-loin  .rtxt{animation:vient-loin  1.5s var(--e-monde) both;}
  .prof.p-moyen .rtxt{animation:vient-moyen 1.1s var(--e-monde) both;}
  .prof.p-pres  .rtxt{animation:vient-pres  .78s var(--e-monde) both;}
  @keyframes vient-loin{
    0%  {opacity:0;filter:blur(16px);transform:translateZ(-960px) translateY(34px) rotateX(10deg);}
    20% {opacity:1;}
    66% {filter:blur(0);transform:translateZ(200px) translateY(-12px) rotateX(3deg);}
    100%{opacity:1;filter:blur(0);transform:none;}
  }
  @keyframes vient-moyen{
    0%  {opacity:0;filter:blur(9px);transform:translateZ(-440px) translateY(18px) rotateX(6deg);}
    24% {opacity:1;}
    68% {filter:blur(0);transform:translateZ(78px) translateY(-5px) rotateX(1.5deg);}
    100%{opacity:1;filter:blur(0);transform:none;}
  }
  @keyframes vient-pres{
    0%  {opacity:0;filter:blur(4px);transform:translateZ(-170px) translateY(9px);}
    30% {opacity:1;}
    70% {filter:blur(0);transform:translateZ(22px) translateY(-2px);}
    100%{opacity:1;filter:blur(0);transform:none;}
  }
  @media (prefers-reduced-motion:reduce){
    .prof .rtxt{animation:none !important;}
  }

  /* ── LA PHOTO ENVOYÉE (17/08) : grande, puis rangée ─────────────────────────
     Elle arrive pleine largeur le temps qu'on la voie, puis elle rétrécit à
     droite comme un message envoyé. Elle reste le repère de toute la recherche,
     ET APRÈS (fondateur 11/09) : elle ne part plus quand les cartes arrivent —
     le client compare. Un toucher la regrossit, un autre la range. */
  /* `flex:0 0 auto` : le fil est une COLONNE FLEX, et un enfant flex se laisse
     écraser quand la place manque. Mesuré le 17/08 : la photo rendait 315×250 au
     lieu de 315×420 — elle arrivait déjà aplatie, avant même de rétrécir. */
  .envoi-photo{flex:0 0 auto;margin:10px 0 6px auto;width:100%;max-width:var(--pw);
    border-radius:18px;overflow:hidden;
    border:1px solid var(--carte-edge);border-bottom:3px solid var(--carte-tranche);
    box-shadow:0 22px 44px -16px var(--shadow);
    transition:width .62s var(--e-main), border-radius .62s var(--e-main), box-shadow .5s ease;}
  .envoi-photo img{display:block;width:100%;aspect-ratio:3/4;object-fit:cover;}
  .envoi-photo.petite{width:86px;border-radius:12px;box-shadow:0 6px 14px -8px var(--shadow);}
  .envoi-photo.entre{animation:photo-entre .5s var(--e-pouce) both;}
  @keyframes photo-entre{from{opacity:0;transform:translateY(16px) scale(.94);}}
  .envoi-photo{cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .envoi-photo:focus-visible{outline:2px solid var(--light);outline-offset:2px;}

  /* ── LE MOMENT D'INTELLIGENCE (17/08, fondateur) ────────────────────────────
     UNE PHRASE À LA FOIS, un chrono, puis PLUS RIEN. Avant, le travail restait
     dans le fil sous forme de coche figée : le fil se remplissait du RÉCIT du
     travail, qu'il faut enjamber à chaque relecture. Désormais il ne garde que
     ce qu'on a TROUVÉ — les faits et les cartes. Ce qui méritait d'être gardé
     est déjà descendu en fait, et un fait est un résultat, pas un effort.
     Le chrono n'est pas un ornement : c'est lui qui dit « ça n'a pas planté »,
     et c'est lui qui achète la patience — pas l'animation. */
  .travail{display:flex;align-items:center;gap:10px;min-height:22px;padding:5px 0;}
  /* LE LAPIN DE LA LIGNE DE TRAVAIL — il occupe SA place, celle que `row(true)` réservait vide.
     ⚠️ Il vit dans `.av`, qui est le FRÈRE de `.rtxt` (lequel porte `.travail`) : une règle
     `.travail .lapin` ne toucherait RIEN. Mesuré au banc le 08/09 — l'éclat restait immobile,
     et la garde ne pouvait pas le voir : elle lit le code, pas la cascade.
     Deux calques du même trait : le fond reste lisible, l'éclat le parcourt. `pathLength="100"`
     (sur #head) rend la longueur du tiret indépendante du dessin. */
  /* la BOÎTE du lapin est déjà tenue par `.av svg` (28 px, la taille du repère partout ailleurs) :
     on ne la redéfinit pas, on ne peint que le trait. `overflow:visible` laisse l'éclat déborder. */
  .lapin{overflow:visible;}
  .lapin use{fill:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:4.4;}
  /* LE LAPIN S'ÉCRIT (fondateur, 08/09 : « je préfère le lapin qui pense, mais avec la vraie forme
     de Rabbit »). Le geste vient de l'avis de la fiche ; la forme est le REPÈRE DE LA MARQUE.
     Le trait de `#head` étant FERMÉ, il s'écrit d'un seul geste — là où le dessin sur mesure de
     l'avis devait orchestrer trois traits décalés. Pas de calque de fond : il part de rien, sinon
     ce serait un surlignage et non une écriture. */
  .lapin .trace{stroke:var(--light);stroke-dasharray:100;stroke-dashoffset:100;
    animation:lapin-trace 1.6s var(--ease) infinite;
    filter:drop-shadow(0 0 4px color-mix(in srgb,var(--light) 55%,transparent));}
  @keyframes lapin-trace{0%{stroke-dashoffset:100;opacity:.35;}55%{stroke-dashoffset:0;opacity:1;}100%{stroke-dashoffset:0;opacity:.35;}}
  .travail .ph{flex:1 1 auto;position:relative;height:19px;overflow:hidden;}
  .travail .ph span{position:absolute;left:0;top:0;right:0;font-size:var(--t-foot);line-height:19px;
    color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .travail .ph span.sort{animation:tv-sort .26s var(--e-main) both;}
  .travail .ph span.entre{animation:tv-entre .3s var(--e-main) both;}
  @keyframes tv-sort{to{transform:translateY(-17px);opacity:0;}}
  @keyframes tv-entre{from{transform:translateY(13px);opacity:0;}}
  /* ── LE RÉGIME ULTRA SE VOIT ─────────────────────────────────────────────────────
     Le passage dure plus d'une minute, et il coûte de l'argent. Pendant ce temps la
     ligne de travail passe en OR — la couleur de la porte qu'il vient d'ouvrir. Elle ne
     décore pas : elle dit dans quel régime Rabbit est, et qu'il n'est pas dans l'ordinaire.
     Le contour du rotor et le texte suffisent : on change la teinte, jamais la forme. */
  .ultra .lapin .trace{stroke:var(--warm);
    filter:drop-shadow(0 0 5px color-mix(in srgb,var(--warm) 70%,transparent));}
  .ultra .travail .ph span{color:color-mix(in srgb,var(--warm) 72%,var(--ink-2));}
  .ultra .travail .chr{color:color-mix(in srgb,var(--warm) 55%,var(--ink-3));}
  .travail .chr{flex:0 0 auto;font-size:var(--t-cap);color:var(--ink-3);
    font-variant-numeric:tabular-nums;}
  .travail.part{animation:tv-part .3s var(--e-main) both;}
  @keyframes tv-part{to{opacity:0;transform:translateY(-7px);height:0;min-height:0;padding:0;}}
  /* mouvement réduit : rien ne s'écrit, et le lapin reste ENTIER — un trait figé à mi-chemin
     serait un lapin coupé en deux, pas un repère */
  @media (prefers-reduced-motion:reduce){
    .lapin .trace{animation:none;stroke-dashoffset:0;stroke-dasharray:none;opacity:.85;}
  }

  .ddp{display:flex;gap:9px;padding:11px 13px;border-radius:18px;margin-top:9px;font-size:var(--t-foot);color:var(--ink);
    border:1px solid color-mix(in srgb,var(--light) 45%,transparent);
    background:color-mix(in srgb,var(--light) 8%,transparent);
    box-shadow:0 0 24px -14px var(--glow);}
  .ddp b{font-weight:500;color:var(--light);}

  /* le contrat */
  .pact{display:flex;gap:10px;align-items:flex-start;font-size:var(--t-foot);color:var(--ink);padding:5px 0;}
  .pact+.pact{border-top:1px solid var(--edge-2);}
  .pact b{flex:0 0 auto;width:16px;height:16px;border-radius:50%;font-size:var(--t-cap);font-weight:400;margin-top:2px;
    display:flex;align-items:center;justify-content:center;color:var(--light);
    box-shadow:inset 0 0 0 1.2px var(--light), 0 0 12px -4px var(--glow);}
  .pact em{font-style:normal;font-weight:500;}
  .stamp{font-size:var(--t-foot);color:var(--ink-2);
    padding-top:2px;}

  .fact{display:flex;align-items:center;gap:8px;font-size:var(--t-foot);color:var(--ink-2);padding:4px 0;}
  .fact::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--light);flex:0 0 auto;
    box-shadow:0 0 8px var(--glow);}
  .fact.warm{color:var(--warm);} .fact.warm::before{background:var(--warm);box-shadow:0 0 8px color-mix(in srgb,var(--warm) 50%,transparent);}

  /* ═══════════════ LA MAIN ═══════════════
     Le seul endroit de la page où la lumière n'est PAS causée par Rabbit.
     Le doigt écrit sur la racine exactement comme la scène : `data-main` (l'état)
     et `--doigt` (0→1, l'engagement). Il n'éclaire que des ARÊTES, jamais un aplat,
     et jamais un chiffre.
     Règle du lexique : un seul état continu à la fois. `tiens` éteint tout le reste. */

  /* L'ARÊTE DE PRISE — une seule marque, qui sert trois fois :
     au repos elle dit « ceci est un objet » · à l'appui elle DEVIENT LA JAUGE du
     maintien (le délai ne se subit pas, il se voit) · après enregistrement elle
     reste haute et pleine (l'état « gardé » se lit à la FORME, pas à la couleur).
     Elle est aussi le vrai bouton : le chemin sans doigt n'est pas un rattrapage. */
  .card{padding-left:22px;}                    /* la place de l'arête, jamais sous un texte */
  /* touch-action:none — SEUL endroit de la page à confisquer la verticale, parce que
     « ouvrir » et « revenir » SONT verticaux. En pan-y, le navigateur prenait le geste
     pour un défilement et envoyait un pointercancel, qui renvoie toujours la carte à
     son origine : le geste n'aurait jamais marché sur un vrai téléphone. Le JS rend
     l'axe tant que rien n'est soulevé (window.scrollBy du delta exact). */
  .garder{position:absolute;left:0;top:0;bottom:0;width:44px;z-index:5;
    border:0;background:none;padding:0;cursor:grab;
    -webkit-tap-highlight-color:transparent;touch-action:none;}
  .garder[disabled]{cursor:default;}
  .garder::before{content:"";position:absolute;left:8px;top:50%;width:2px;height:26px;
    transform:translateY(-50%);border-radius:2px;opacity:.55;
    background:linear-gradient(180deg,var(--edge),color-mix(in srgb,var(--light) 55%,transparent),var(--edge));
    transition:height .26s cubic-bezier(.4,0,.2,1) .09s, opacity .16s linear, background .16s linear;}
  .garder:hover::before{height:34px;}
  .garder:focus-visible{outline:2px solid var(--light);outline-offset:-3px;border-radius:20px;}
  .garder[data-charge]::before{height:76%;opacity:1;
    background:linear-gradient(180deg,var(--light),var(--light-hi),var(--light));}
  .garder[aria-pressed="true"]::before{height:56%;opacity:1;
    background:linear-gradient(180deg,var(--light),var(--light-hi),var(--light));
    transition:height .2s var(--e-main);}

  /* la réponse au contact : bordure et creux, JAMAIS un transform — le bloc
     « réduire les animations » neutralise les transforms et l'effacerait en silence. */
  .card.touchee{border-color:color-mix(in srgb,var(--light) 45%,var(--edge));
    box-shadow:0 1px 0 rgba(255,255,255,.42) inset, inset 0 0 22px -10px var(--glow), var(--sh-2);}
  .contact{position:absolute;inset:0;z-index:4;pointer-events:none;border-radius:inherit;opacity:0;
    background:radial-gradient(52px 52px at var(--px,50%) var(--py,50%),
      color-mix(in srgb,var(--light-hi) 34%,transparent), transparent 70%);
    transition:opacity .09s linear;}
  .card.touchee .contact{opacity:1;}

  /* LE VOL — le clone vit hors de tout ancêtre porteur de perspective ou de filtre,
     sinon un position:fixed s'y ancrerait au lieu du viewport. Il perd son
     backdrop-filter : un verre transformé échantillonne le mauvais fond. */
  #vol{position:fixed;inset:0;z-index:60;pointer-events:none;}
  #vol .card{position:fixed;margin:0;backdrop-filter:none;-webkit-backdrop-filter:none;
    background:var(--screen);background-image:var(--carte-bg);
    box-shadow:0 26px 60px -20px var(--shadow), 0 0 0 1px var(--carte-edge);
    will-change:transform;}
  .empreinte{opacity:.26;transition:opacity .18s linear;}

  /* LE CASIER — il n'existe pas avant la prise, et il meurt au relâchement.
     Les surfaces apparaissent quand la main engage : c'est ça, la citation. */
  .casier{position:absolute;left:14px;right:14px;bottom:8px;z-index:6;
    height:60px;border-radius:20px;display:flex;align-items:center;gap:10px;padding:0 15px;
    border:1px dashed color-mix(in srgb,var(--light) 45%,transparent);
    background:color-mix(in srgb,var(--light) 7%,transparent);
    color:var(--ink-2);font-size:var(--t-foot);
    transform:translateY(78px);opacity:0;pointer-events:none;
    transition:transform .26s var(--e-main), opacity .26s var(--e-main),
               border-color .16s linear, background .16s linear, height .2s var(--e-main);}
  :root[data-main="prise"] .casier,:root[data-main="survol"] .casier{transform:translateY(0);opacity:1;}
  :root[data-main="survol"] .casier{border-style:solid;height:66px;
    border-color:var(--light);color:var(--ink);
    background:
      radial-gradient(90px 40px at var(--fx,50%) 50%, color-mix(in srgb,var(--light) 26%,transparent), transparent 70%),
      color-mix(in srgb,var(--light) 10%,transparent);}
  .casier .cnt{margin-left:auto;font-variant-numeric:tabular-nums;
    font-size:var(--t-body);color:var(--light);}
  .casier .cnt.sort{opacity:0;transition:opacity .09s linear;}
  .casier svg{width:19px;height:19px;flex:0 0 auto;color:var(--light);}
  /* le cliquet du dépôt : UNE lumière, dure et brève, qui court vers les deux bords.
     Surtout pas un éclat radial — l'éclat et l'onde appartiennent au verdict. */
  .casier::after{content:"";position:absolute;left:var(--fx,50%);top:0;bottom:0;width:0;
    background:linear-gradient(90deg,transparent,var(--light-hi),transparent);opacity:0;
    transform:translateX(-50%);pointer-events:none;border-radius:20px;}
  .casier.encaisse::after{animation:cliquet .09s linear;}
  @keyframes cliquet{0%{width:0;opacity:.9;}100%{width:210%;opacity:0;}}
  .casier.encaisse{animation:encaisse .42s var(--e-main);}
  @keyframes encaisse{0%{transform:translateY(0);}22%{transform:translateY(3px);}100%{transform:translateY(0);}}

  /* AGRANDIR — la carte reste devant, tenue par le regard au lieu du doigt.
     Le voile ne décore pas : il retire le reste du champ pour que l'échelle se lise. */
  .scrim{position:absolute;inset:0;z-index:7;pointer-events:none;opacity:0;
    display:flex;align-items:flex-end;justify-content:center;padding-bottom:26px;
    background:color-mix(in srgb,var(--void) 68%,transparent);
    backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
    transition:opacity .3s var(--e-main);}
  .scrim span{font-size:var(--t-cap);
    color:var(--ink-3);}
  :root[data-main="ouverte"] .scrim{opacity:1;pointer-events:auto;}
  /* la carte agrandie est le seul objet allumé : le fil disparaît tout à fait */
  :root[data-main="ouverte"] .thread{opacity:.18;}

  /* LE MENU DES ISSUES — il nomme l'issue ET le geste qui la produit */
  /* [hidden] n'est que du display:none de feuille UA : toute règle d'auteur le bat.
     Sans ce garde, les trois menus s'affichent en permanence par-dessus les cartes. */
  .issues[hidden]{display:none!important;}
  /* Fond OPAQUE — la valeur du verre APLATI sur l'écran, thème par thème (audit
     01/09 : color-mix gardait l'alpha de --pane → 11 % en sombre, illisible ; et
     la charte interdit le translucide sans flou). Le vrai verre attend le lot 2.
     Position posée par `ancrerMenu()` au bouton ⋯ — plus d'offset figé. */
  .issues{position:absolute;top:8px;z-index:9;min-width:190px;
    display:flex;flex-direction:column;padding:5px;border-radius:16px;
    background:var(--pane);
    border:1px solid var(--edge);box-shadow:var(--sh-2);}
  :root[data-theme="dark"] .issues{background:var(--pane);}
  @media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .issues{background:var(--pane);}}
  /* VERSION VERRE — démo de banc (?banc=verre, décision fondateur ouverte) : le vrai
     verre porte SON flou et son adaptation, jamais du translucide nu (charte loi 1) */
  :root[data-banc-verre] .issues{
    background:color-mix(in srgb,var(--pane) 72%,transparent);
    backdrop-filter:blur(16px) saturate(1.15);
    -webkit-backdrop-filter:blur(16px) saturate(1.15);}
  /* Les sous-titres explicatifs sont TOMBÉS (fondateur, 31/08 : « pas besoin des
     sous-titres »). Le verbe seul, centré sur sa hauteur tactile de 44 pt. */
  .issues button{display:flex;align-items:center;
    min-height:44px;padding:7px 11px;border:0;border-radius:11px;background:none;
    color:var(--ink);font-family:var(--sans);font-size:var(--t-foot);text-align:left;cursor:pointer;}
  .issues button:hover{background:var(--pane-2);}
  .issues button:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  /* un geste refusé s'éteint et DIT pourquoi (lot 2). L'ÉTEINT se dit par la couleur
     du VERBE (un contrôle désactivé est exempté d'AA) — jamais par une opacité de
     bloc : elle écrasait la RAISON à 1,53:1 (audit adversarial 01/09), or la raison
     est de l'information (loi 10) et doit se lire. */
  .issues button[disabled]{cursor:default;flex-direction:column;align-items:flex-start;gap:1px;color:var(--ink-3);}
  .issues button[disabled]:hover{background:none;}
  .issues .iraison{display:block;font-size:var(--t-cap);color:var(--ink-2);}
  /* LE MENU SORT DE LA RANGÉE — mesuré le 31/08 : `.dobj` pose `overflow:hidden`,
     et depuis la compaction de la 4e passe (rangée 126 → 101 px) il rognait le menu
     de 57 px. « Écarter » se dessinait ENTIÈREMENT hors de la carte : offert par le
     code, invisible et intouchable au doigt. On ne libère la coupe QUE pendant
     l'ouverture — le reste du temps la rangée garde ses angles et son rognage. Le
     `z-index` va avec : `.dobj.teinte` porte un `backdrop-filter`, qui crée un
     contexte d'empilement — sans lui la rangée SUIVANTE repeindrait par-dessus. */
  .dobj:has(> .issues:not([hidden])){overflow:visible;z-index:20;}

  /* la récupération : une surface PERMANENTE, pas une barre de 6,5 s */
  .casier .recup{margin-left:auto;border:0;background:none;padding:6px 8px;min-height:36px;
    color:var(--warm);font-size:var(--t-cap);letter-spacing:.06em;cursor:pointer;}
  .casier .recup:focus-visible{outline:2px solid var(--warm);outline-offset:2px;border-radius:8px;}
  .casier .recup[hidden]{display:none;}
  /* les suggestions d'adresse (BAN) — au-dessus du composeur, tactiles, une ligne */
  .sugg{position:absolute;left:10px;right:10px;bottom:calc(env(safe-area-inset-bottom,0px) + 64px);
    z-index:11;display:flex;flex-direction:column;gap:6px;}
  .sugg button{min-height:44px;text-align:left;padding:10px 14px;border-radius:14px;
    border:1px solid var(--edge);background:var(--pane);color:var(--ink);
    font-family:var(--sans);font-size:var(--t-foot);backdrop-filter:blur(10px);cursor:pointer;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  /* LE DOSSIER — l'archive de ce qui est gardé : plein écran, sobre, lisible */
  .dossier{position:absolute;inset:0;z-index:60;display:flex;flex-direction:column;
    background:var(--screen);}
  /* LES PANNEAUX ENTRENT EN SCÈNE (lot 2 — « tout entre en scène pareil ») : la même
     scène `ouvre` que le plan de travail des objets ; la sortie est symétrique — le
     panneau se replie vers le haut. Sous mouvement réduit : aucune des deux. */
  .dossier{animation:ouvre .6s var(--e-main) both;}
  .dossier.dsort{animation:dferme .45s var(--e-main) both;pointer-events:none;}
  @keyframes dferme{
    0%  {opacity:1;clip-path:inset(0 0 0 0 round 22px);transform:translateY(0);}
    100%{opacity:0;clip-path:inset(0 0 100% 0 round 22px);transform:translateY(-6px);}
  }
  @media (prefers-reduced-motion:reduce){ .dossier{animation:none;} .dossier.dsort{animation:none;opacity:0;} }
  /* LA FLÈCHE RETOUR — ces panneaux s'ouvrent depuis le tiroir, on y revient.
     44 pt comme tout ce qui se touche. */
  .dossier .dretour{flex:none;width:44px;height:44px;margin-left:-8px;display:flex;
    align-items:center;justify-content:center;border:0;background:none;color:var(--ink-2);cursor:pointer;}
  .dossier .dretour svg{width:22px;height:22px;display:block;}
  .dossier .dretour:hover,.dossier .dretour:focus-visible{color:var(--ink);}
  .dossier .dhead{display:flex;align-items:center;justify-content:space-between;
    padding:calc(env(safe-area-inset-top,0px) + 14px) 16px 12px;
    border-bottom:1px solid var(--edge-2);font-weight:600;color:var(--ink);font-size:var(--t-body);}
  /* le TITRE du panneau en Title 22 (charte lot 3) — il reste DANS la barre : le
     Large 34 sous-barre serait une refonte d'anatomie, pas un alignement (noté) */
  .dossier .dhead > span:not(.dbadge){font-size:var(--t-title);letter-spacing:var(--t-title-ls);}
  .dossier .dclose{width:44px;height:44px;border-radius:50%;border:1px solid var(--edge);
    background:var(--pane-2);color:var(--ink-2);font-size:var(--t-body);cursor:pointer;}
  .dossier .dcorps{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;
    padding:8px 16px calc(env(safe-area-inset-bottom,0px) + 24px);}
  .dossier h3{font-size:var(--t-cap);font-weight:600;
    color:var(--light);margin:18px 0 4px;}
  .dossier .dentree{margin-top:10px;}
  .dossier .ddate{display:block;font-size:var(--t-cap);color:var(--ink-2);
    letter-spacing:.06em;margin-bottom:4px;}
  /* ══ LE DOSSIER À LA MAQUETTE (carte-vivante-v4, fondateur 30/08) ═══════════════
     Les tickets en haut (rangée 44), les gardés dessous : LA rangée candidat de
     l'art. 1 — vignette 76, le prix domine, badges de nature, la prise ⋯ pleine
     hauteur. Les OBJETS portent le verre teinté famille ; le panneau lui-même reste
     sobre et opaque (« plein écran, sobre, lisible ») — le ciel respirera derrière
     ces mêmes rangées quand elles vivront dans le fil (deck, passe suivante). */
  /* les cinq familles dérivées d'avant le 05/09 : retirées le 13/09 — même sélecteur que la
     couche du 05/09 plus bas, donc écrasées par elle et JAMAIS appliquées. */
  .dobj{position:relative;border-radius:18px;background:var(--carte-bg);
    border:1px solid var(--carte-edge);border-bottom:2px solid var(--carte-tranche);
    box-shadow:var(--sh-1);overflow:hidden;margin:8px 0;}
  .dobj.teinte{--verre:linear-gradient(135deg,
      color-mix(in srgb,var(--fc,var(--fam-neutre)) 26%, transparent),
      rgba(255,255,255,.55) 60%,
      color-mix(in srgb,var(--fc,var(--fam-neutre)) 12%, transparent));
    background:var(--verre);
    backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
    border:1px solid var(--carte-edge);
    border-bottom:2px solid var(--carte-tranche);}   /* par jetons (ticket Apparence 03) — la couche du 05/09 le redit, un design neuf n'hérite plus du clair */
  /* 🔴 LA NUIT N'EST PLUS TRANSLUCIDE (fondateur 30/08 : « en sombre, le transparent,
     on ne voit rien, on ne comprend rien ») : fond DENSE teinté famille — le patron
     de la maquette nuit (rgba(46,62,81,.96)…), poussé opaque ; le blur tombe (inutile
     sur un fond plein). Et la règle vit sous LES DEUX portes du sombre : le toggle
     (data-theme) ET le réglage système (media) — avant, le sombre système gardait le
     verre BLANC du jour sur fond nuit : le laiteux illisible constaté. */
  /* la nuit aux BLEUS-ARDOISE de la maquette (--carte nuit : 46,62,81 → 28,41,56),
     teintés famille — denses mais RICHES, jamais gris (retour fondateur : « en
     sombre elles sont ratées ») ; un reflet doux en haut, comme le jour. */
  /* les anciens blocs « verre » sombres de .dobj.teinte sont partis (ticket Apparence 01) : la couche du 05/09 rend
     l'objet opaque et bordé par jetons dans tous les designs ; leur bordure teintée l'emportait encore en sombre */
  .dbadge{display:inline-block;font-size:var(--t-cap);font-weight:600;border:1px solid var(--ink-3);
    color:var(--ink-2);border-radius:8px;padding:1px 7px;letter-spacing:.02em;white-space:nowrap;}
  .dbadge.vif{border-color:var(--fam-commande);color:var(--fam-commande);}
  /* le badge-bouton du suivi (lot 4) : copiable, donc TACTILE — 44 pt comme tout
     ce qui se touche (le stepper 38 reste l'unique compromis gravé, 28/08) */
  .dcopie{cursor:pointer;min-height:44px;display:inline-flex;align-items:center;
    background:var(--pane-2);font-family:var(--sans);}
  .dcopie:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  /* l'absence NOMMÉE d'une rangée (loi 10, lot 1) : une méta nue, jamais un badge —
     un cadre autour de « pas trouvé » en ferait une pastille qu'on croit cliquable */
  /* --ink-2, pas --ink-3 : l'absence nommée est de l'INFORMATION (loi 10) — l'audit
     adversarial l'a mesurée à 2,67:1 en clair, sous AA. Payé le 01/09. */
  .dabs{font-size:var(--t-foot);color:var(--ink-2);white-space:nowrap;}
  /* INTERTITRES DU DOSSIER : petites capitales grises, EXACTEMENT la maquette
     carte-vivante-v4 — décision fondateur du 30/08 (« je veux tout pareil »), qui
     l'emporte ICI sur la règle anti-capitales du 18/08. L'exception est gravée dans
     typo-echelle.test.js pour CE bloc seul ; seule la taille monte de 10,5 à 12 px :
     le plancher d'accessibilité ne se négocie pas, et l'œil ne voit pas l'écart. */
  /* CASSE DE PHRASE, partout (charte 01/09, loi 3 — elle retire EXPLICITEMENT
     l'exception petites-capitales du 30/08) : l'intertitre parle, il ne crie plus.
     La hiérarchie passe par la graisse, plus par la casse. */
  .dossier .dsect{font-size:var(--t-foot);font-weight:600;color:var(--ink-3);
    padding:12px 2px 2px;}
  /* LE REPLI DE PANNEAU (doctrine du contenu, PAROLE §4 ter — 01/09) : ce qui EXPLIQUE
     vit derrière un chevron ; le repos ne porte que la décision. Même anatomie que le
     `.fcarac` de la fiche — une seule mécanique de repli dans le fil, jamais deux. */
  .dossier .drepli{border-top:1px solid var(--edge-2);}
  .dossier .drepli > summary{list-style:none;cursor:pointer;display:flex;align-items:center;
    justify-content:space-between;gap:8px;min-height:44px;
    font-size:var(--t-body);font-weight:600;color:var(--ink);}
  .dossier .drepli > summary::-webkit-details-marker{display:none;}
  .dossier .drepli > summary::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);
    transition:transform .18s var(--e-pouce);}
  .dossier .drepli[open] > summary::after{transform:rotate(90deg);}
  .dossier .drepli > *:not(summary){margin-top:8px;}
  .dossier .drepli:focus-within > summary{outline:2px solid var(--light);outline-offset:2px;}
  /* la rangée ticket : ce qui est EN COURS — statut serveur, jamais inventé */
  .dtik{display:flex;align-items:center;gap:9px;padding:9px 12px;}
  /* une rangée-ticket TAPPABLE (recherche aboutie) : le même corps, en vrai bouton */
  button.dtik-go{width:100%;background:none;border:0;color:inherit;font:inherit;
    text-align:left;cursor:pointer;}
  button.dtik-go:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  button.dtik-go .chev{margin-left:auto;}
  .dtik+.dtik{border-top:1px solid var(--edge-2);}
  .dtik .dvg{width:40px;height:40px;border-radius:10px;flex:none;background:var(--pane-2);
    border:1px solid var(--edge-2);display:flex;align-items:center;justify-content:center;}
  .dtik .dvg svg{width:20px;height:20px;stroke:var(--ink-2);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .dtik .dt{min-width:0;flex:1;line-height:1.35;}
  .dtik .dt b{display:block;font-size:var(--t-foot);font-weight:600;white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis;}
  .dtik .dt small{font-size:var(--t-cap);color:var(--ink-2);}
  /* LA rangée candidat (art. 1) : compacte, le chiffre domine, la prise à droite.
     Deux VRAIS boutons (rangée, prise) — jamais un bouton dans un bouton. */
  .dentree-g+.dentree-g{border-top:1px solid var(--edge-2);}
  /* ══ LES IDÉES DE LA SEMAINE (25/09) — la maquette idees-niches-2409, validée : UN objet compact, les niches en
     pastilles DANS l'objet, cinq lignes à la fois ; le chiffre domine, une colonne = un libellé (Ton coût · Se vend dès ·
     Vendus par mois). Couleurs locales : le vert du coût et l'or des étoiles lisibles sur les deux fonds. */
  /* gap 0 : la carte est une colonne flex à 6 px d'écart (règle commune) — ici les marges disent déjà l'espacement,
     et ces 24 px ont été mesurés au banc (25/09) */
  #fiche .fnote{--id-or:#F5B941;}
  .idees{--id-or:#F5B941;--id-cols:36px minmax(0,1fr) 52px 54px 54px;padding:12px 12px 0;gap:0;}
  /* le titre et la semaine sur UNE ligne quand elle tient ; sinon la semaine passe dessous, jamais coupée */
  /* « Notre sélection » · « Ta recherche » (04/10) : deux onglets sur la MÊME carte — un segment, pas deux boutons */
  .idees .id-onglets{display:flex;gap:2px;padding:3px;margin:0 0 10px;border-radius:12px;background:var(--edge);}
  .idees .id-og{flex:1;min-height:36px;border:0;border-radius:9px;background:none;color:var(--ink-3, var(--ink));opacity:.75;
    font:600 var(--t-cap)/1.2 var(--sans);cursor:pointer;}
  .idees .id-og.on{background:var(--pane);color:var(--ink);opacity:1;box-shadow:0 1px 2px rgba(0,0,0,.18);}
  .idees .tr{padding:0 0 12px;display:flex;flex-direction:column;gap:8px;}
  .idees .tr-p{margin:4px 0;font-size:var(--t-body);line-height:1.45;color:var(--ink);}
  .idees .tr-k{font:600 var(--t-cap)/1.2 var(--sans);color:var(--ink);opacity:.7;margin-top:4px;}
  .idees .tr-ligne{display:flex;gap:6px;align-items:center;}
  .idees .tr-in{flex:1;min-width:0;min-height:44px;padding:0 12px;border-radius:12px;border:1px solid var(--edge);background:var(--pane);
    color:var(--ink);font:400 16px/1.2 var(--sans);}   /* 16 px : iOS ne zoome pas sur le champ */
  .idees .tr-eur{color:var(--ink);opacity:.6;}
  .idees .tr-chips{display:flex;flex-wrap:wrap;gap:6px;}
  .idees .tr-chip{display:inline-flex;align-items:center;gap:4px;min-height:36px;padding:0 4px 0 12px;border-radius:999px;
    border:1px solid var(--edge);background:var(--pane);color:var(--ink);font:500 var(--t-cap)/1.2 var(--sans);}
  .idees .tr-chip button{min-width:32px;min-height:32px;border:0;background:none;color:var(--ink);opacity:.55;font-size:16px;cursor:pointer;}
  .idees .tr-plus{padding:0 10px;border-style:dashed;}
  .idees .tr-plus input{width:96px;border:0;background:none;color:var(--ink);font:500 16px/1.2 var(--sans);}
  .idees .tr-mini{min-height:44px;padding:0 12px;border-radius:12px;border:1px solid var(--edge);background:var(--pane);color:var(--ink);
    font:600 var(--t-cap)/1.2 var(--sans);white-space:nowrap;cursor:pointer;}
  .idees .tr-go{min-height:48px;border:0;border-radius:14px;background:var(--btn-plein-bg);color:var(--btn-plein-ink);
    font:600 var(--t-body)/1.2 var(--sans);cursor:pointer;}
  .idees .tr-go:disabled{opacity:.45;cursor:default;}
  .idees .tr-pied{display:flex;justify-content:space-between;gap:8px;padding-top:8px;border-top:1px solid var(--edge);
    font-size:var(--t-cap);color:var(--ink);opacity:.8;}
  .idees .tr-tete{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;column-gap:8px;}
  .idees .tr-tete b{font:600 var(--t-body)/1.2 var(--sans);color:var(--ink);}
  .idees .tr-tete small{font-size:var(--t-cap);color:var(--ink);opacity:.6;white-space:nowrap;}
  .idees .tr-et{display:flex;align-items:center;gap:10px;min-height:36px;border-top:1px solid var(--edge);font-size:var(--t-cap);color:var(--ink);opacity:.55;}
  .idees .tr-et i{width:16px;height:16px;flex:none;border-radius:50%;border:1.5px solid currentColor;}
  .idees .tr-et.fait,.idees .tr-et.cours{opacity:1;}
  .idees .tr-et.fait i{border-color:var(--fam-argent);background:var(--fam-argent);}
  .idees .tr-et.cours i{border-color:var(--ink);border-width:4px;}
  .idees .tr-et em{margin-left:auto;font-style:normal;font-variant-numeric:tabular-nums;opacity:.75;}
  /* « Ta recherche » (maquette validée le 05/10) : une carte par produit — le nom, les deux photos côte à côte (la sienne,
     celle vue en France), le prix sous chacune, « Voir la fiche » et ses annonces françaises avec leurs liens. 1688 dans le
     bleu de l'écran, AliExpress en orange (les cartes du sourcing, maquette S1). */
  .idees .tr-cartes{display:flex;flex-direction:column;gap:10px;margin-top:10px;}
  .idees .tr-carte{display:flex;flex-direction:column;gap:8px;padding:12px;border-radius:16px;background:var(--pane);border:1px solid var(--edge);}
  .idees .tr-nom2{font:600 var(--t-body)/1.3 var(--sans);color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
  .idees .tr-ph2{position:relative;display:block;aspect-ratio:1 / 1;max-width:100%;border-radius:12px;overflow:hidden;background:#fff;}
  .idees .tr-ph2 img{width:100%;height:100%;object-fit:cover;display:block;}
  .idees .tr-tag{position:absolute;left:8px;top:8px;font:600 11px/1.2 var(--sans);padding:3px 8px;border-radius:999px;background:rgba(5,7,15,.72);color:#fff;}
  .idees .tr-tag.c{color:var(--light);}
  .idees .tr-tag.ae{color:color-mix(in srgb,#FF6A2B 70%,#fff);}
  .idees .tr-px{display:flex;align-items:baseline;flex-wrap:wrap;column-gap:6px;padding-left:2px;}
  .idees .tr-px b{font:600 20px/1.15 var(--sans);color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;}
  .idees .tr-px small{font-size:var(--t-cap);color:var(--ink-3);}
  .idees .tr-lien{justify-self:start;min-height:36px;padding:0 2px;border:0;background:none;color:var(--light);font:600 var(--t-cap)/1.2 var(--sans);cursor:pointer;text-align:left;}
  .idees .tr-solo{display:grid;grid-template-columns:112px minmax(0,1fr);gap:12px;align-items:stretch;}
  .idees .tr-txt{display:flex;flex-direction:column;justify-content:space-between;gap:6px;min-width:0;}
    .idees .tr-ordre{display:block;margin-top:6px;color:var(--ink-3);font-size:13px;}
  .idees .tr-faits{display:flex;align-items:center;gap:4px;color:var(--ink-2);font-size:13px;}
  .idees .tr-faits .et{width:13px;height:13px;fill:#F5B301;}
  .idees .tr-src{margin:2px 0 4px;}
  /* replié au repos : `display:grid` écrasait l'attribut `hidden` (vu au banc, 05/10 : toutes les annonces dépliées) */
  .idees .tr-suite[hidden]{display:none;}
  .idees .id-n:disabled{opacity:.45;cursor:default;}
  .idees .tr-rendu{display:flex;justify-content:space-between;align-items:center;min-height:44px;padding:0 14px;border-radius:12px;
    background:color-mix(in srgb, var(--fam-argent) 14%, transparent);color:var(--fam-argent);font-weight:600;}
  .idees .tr-actes{display:flex;gap:8px;}
  .idees .tr-actes > *{flex:1;}
  .idees .id-tete{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;column-gap:8px;margin-bottom:8px;}
  .idees .id-tete b{font:600 var(--t-body)/1.2 var(--sans);color:var(--ink);}
  .idees .id-tete small{font-size:var(--t-cap);line-height:1.2;color:var(--ink-3);white-space:nowrap;}
  /* les pastilles défilent de côté, et SEULEMENT de côté (fondateur, 26/09, au téléphone : « il se balaye en bougeant en
     hauteur aussi, il n'est pas fixé ») : `overflow-x:auto` seul rend aussi la verticale défilante, et le doigt qui
     balaie faisait monter la page avec lui — même patron que le carrousel `.deck.liste.carre` */
  .idees .id-niches{display:flex;gap:6px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;touch-action:pan-x;
    scrollbar-width:none;margin:0 -12px 8px;padding:0 12px;}
  .idees .id-niches::-webkit-scrollbar{display:none;}
  .idees .id-n{flex:none;min-height:32px;padding:4px 12px;border-radius:999px;border:1px solid var(--edge);background:var(--pane);
    color:var(--ink);font:500 var(--t-cap)/1.2 var(--sans);cursor:pointer;white-space:nowrap;}
  .idees .id-n span{color:var(--ink-3);margin-left:2px;}
  .idees .id-n.on{background:var(--ink);color:var(--pane-2, #10141f);border-color:var(--ink);font-weight:600;}
  .idees .id-n.on span{color:inherit;opacity:.7;}
  /* LE TABLEAU, UNE LIGNE PAR IDÉE (fondateur, 26/09 : « je préférais la première version, mais un petit peu mieux
     cadrée — juste mieux positionner les uns envers les autres » ; deux autres mises en page refusées le même soir). La
     première donnait 54 · 48 · 54 px aux chiffres : « 27,51 € » débordait sur « 50 € » au téléphone (« le texte se
     mange »). Les colonnes sont taillées sur la MESURE de leur plus long contenu dans la police servie (26/09 : un prix
     50 px, « boutiques » 58 px — il peut mordre sur la marge de la carte, c'est la dernière colonne —, « Europe » et sa
     flèche 53 px : à 50, elle venait toucher « Chine »), au plus juste : à 54 · 50 · 62, le nom n'avait plus
     que 85 px à 375 (« Coussin cervical… », et « Nouveau » sur une quatrième ligne) ; le nom prend le reste, sur deux
     lignes, ses étoiles dessous. Chiffres et entêtes à DROITE : ils se lisent en colonne, comme dans un tableau. */
  .idees .id-cols,.idees .id-l{display:grid;grid-template-columns:var(--id-cols);grid-template-areas:"ph nom cout fr mois";column-gap:4px;}
  .idees .id-cols{align-items:end;margin-top:-8px;}
  /* les idées sous la réponse (06/10) : ni onglets ni niches au-dessus, et des intitulés, pas des boutons de tri */
  .idees.id-mini .id-cols{margin-top:0;}
  .idees.id-mini .id-tri{min-height:0;cursor:default;}
  /* l'entête est un bouton de tri (« comme un tableau ») : 44 px au doigt ; il se lit comme le MOT de sa colonne (graisse
     d'appui, encre franche) ; actif, il se colore sans grossir — trier ne fait jamais bouger un libellé */
  .idees .id-tri{display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-end;min-width:0;min-height:44px;padding:0 0 6px;
    border:0;background:none;font:600 var(--t-cap)/1.15 var(--sans);color:var(--ink-2);text-align:right;cursor:pointer;}
  .idees .id-tri[data-tri="cout"]{grid-area:cout;color:var(--ink-2);}   /* 03/10 : un coût est neutre, le vert ne dit que l’argent qui revient */
  /* « Europe » au MILIEU de sa colonne, titre et chiffres (fondateur, 27/09 : « les chiffres de Europe sont trop proches
     des chiffres de vente — décale vers Chine ») : alignés à droite, ils se collaient à « 4 200+ » */
  .idees .id-tri[data-tri="france"]{grid-area:fr;align-items:center;text-align:center;}
  .idees .id-tri[data-tri="preuve"]{grid-area:mois;}
  .idees .id-tri.on{color:var(--ink);}
  .idees .id-tri[data-tri="cout"].on{color:var(--ink);}
  /* la flèche se pose AU-DESSUS de son mot, dans la hauteur libre de l'entête : elle ne prend aucune largeur. Devant le
     mot, elle se collait au mot voisin (« Se vend ▼Ventes », 320 px) ; derrière, elle collait « Europe ▲ » à « Chine »
     (banc 26-27/09). Elle suit l'alignement de sa colonne. */
  .idees .id-tri span{white-space:nowrap;}
  .idees .id-tri.on::before{content:"";flex:none;margin-bottom:3px;border-left:4px solid transparent;border-right:4px solid transparent;
    border-top:5px solid currentColor;}
  .idees .id-tri.on[data-sens="asc"]::before{border-top:0;border-bottom:5px solid currentColor;}
  /* des rangées ÉGALES (un nom sur deux lignes et ses étoiles) : tourner la page ne fait pas sauter l'objet */
  .idees .id-l{align-items:center;box-sizing:border-box;min-height:60px;padding:6px 0;border-top:1px solid var(--edge);cursor:pointer;}
  .idees .id-ph{grid-area:ph;position:relative;width:36px;height:36px;border-radius:10px;overflow:hidden;background:var(--pane-2);}
  .idees .id-ph img{width:100%;height:100%;object-fit:cover;display:block;}
  /* sous 375 px, la photo, les colonnes et leurs écarts cèdent quelques pixels ; sous 360 (petits iPhone, 320), encore */
  @media (max-width:374px){ .idees{--id-cols:32px minmax(0,1fr) 50px 54px 52px;} .idees .id-ph{width:32px;height:32px;} }
  @media (max-width:359px){ .idees{--id-cols:30px minmax(0,1fr) 46px 52px 50px;} .idees .id-ph{width:30px;height:30px;} }
  /* le nom sur deux lignes au plus, et SES étoiles dessous (« j'aimais bien les étoiles ») ; « Nouveau » : un mot, à la
     place de la note chiffrée — sur la ligne des étoiles, une pastille ne tient pas à 375 px */
  .idees .id-nom{grid-area:nom;min-width:0;font-size:var(--t-cap);line-height:1.2;}
  .idees .id-nom b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font:600 var(--t-foot)/1.2 var(--sans);color:var(--ink);}
  .idees .id-nv{margin-left:4px;font:600 var(--t-cap)/1.2 var(--sans);font-style:normal;color:var(--light);white-space:nowrap;}
  /* sans étoiles devant lui (produit sans note), « Nouveau » s'aligne sur le nom au lieu de se décaler d'un cran */
  .idees .id-nom b + .id-nv{margin-left:0;}
  .idees .id-et,#fiche .fnote .id-et{display:inline-block;vertical-align:-1px;width:47px;height:9px;margin-top:3px;
    background:linear-gradient(90deg,var(--id-or) var(--n),rgba(160,170,190,.45) var(--n));
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 10'%3E%3Cg%3E%3Cpolygon points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(10.5 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(21 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(31.5 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(42 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3C/g%3E%3C/svg%3E") 0 0/47px 9px no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 10'%3E%3Cg%3E%3Cpolygon points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(10.5 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(21 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(31.5 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3Cpolygon transform='translate(42 0)' points='5,0.4 6.2,3.7 9.7,3.8 6.9,5.9 8,9.4 5,7.4 2,9.4 3.1,5.9 0.3,3.8 3.8,3.7'/%3E%3C/g%3E%3C/svg%3E") 0 0/47px 9px no-repeat;}
  .idees .id-note{margin-left:4px;font-size:var(--t-cap);color:var(--ink-3);white-space:nowrap;}
  /* les chiffres : à droite, en chiffres de même largeur ; l'unité des ventes sous son nombre */
  .idees .id-cout,.idees .id-fr,.idees .id-mois{min-width:0;text-align:right;font:600 var(--t-foot)/1.2 var(--sans);font-variant-numeric:tabular-nums;white-space:nowrap;}
  .idees .id-cout{grid-area:cout;color:var(--ink-2);}
  .idees .id-fr{grid-area:fr;color:var(--ink);text-align:center;}
  .idees .id-mois{grid-area:mois;}
  .idees .id-mois b{display:block;color:var(--light);font-weight:600;}
  .idees .id-mois small{display:block;font:500 var(--t-cap)/1.15 var(--sans);color:var(--ink-3);}
  .idees .id-mois i{display:block;height:3px;margin-top:4px;border-radius:2px;background:linear-gradient(90deg,transparent var(--p),var(--edge) var(--p)),var(--marque);}
  /* 320 px : les chiffres en 12, et la note chiffrée s'efface derrière ses étoiles — le nom n'a plus que 60 px.
     ⚠️ APRÈS les règles qu'elle corrige : même spécificité, la dernière gagne */
  /* sous 375, les étoiles se font plus petites : « ★★★★★ Nouveau » doit tenir dans les 94 px du nom à 360 */
  @media (max-width:374px){ .idees .id-et{width:40px;height:8px;-webkit-mask-size:40px 8px;mask-size:40px 8px;} .idees .id-nv{margin-left:3px;} }
  @media (max-width:359px){ .idees .id-cout,.idees .id-fr,.idees .id-mois b{font-size:var(--t-cap);} .idees .id-note{display:none;} }
  .idees .id-pv-amazon b,.idees .id-pv-boutiques b{color:var(--ink);}
  /* la ligne dépliée (maquette idees-niches-2409) : les cartes, la France, « Voir la fiche » — le geste grossit l'objet */
  .idees .id-l.ouvert .id-nom b{color:var(--light);}
  .idees .id-det{padding:2px 0 12px;}
  /* LE DÉTAIL (27/09) : le même produit en photos — la nôtre, puis Amazon et les boutiques —, les deux prix en grand, les
     avis, les USA. Les photos défilent de côté si elles débordent, et SEULEMENT de côté (même patron que les pastilles). */
  .idees .id-memes{display:flex;gap:6px;margin:6px 0 10px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;touch-action:pan-x;
    scrollbar-width:none;}
  .idees .id-memes::-webkit-scrollbar{display:none;}
  .idees .id-m{flex:0 0 auto;width:96px;display:flex;flex-direction:column;gap:4px;color:var(--ink-2);text-decoration:none;}
  .idees .id-m img{display:block;width:96px;height:96px;border-radius:10px;object-fit:cover;background:var(--pane-2);}
  /* le nom de la boutique ENTIER, sur deux lignes s'il le faut (à 72 px, « ManoMano.fr » devenait « ManoMan… », banc 27/09) */
  .idees .id-m span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font:500 var(--t-cap)/1.2 var(--sans);}
  @media (max-width:359px){ .idees .id-m{width:80px;} .idees .id-m img{width:80px;height:80px;} }
  .idees a.id-m span{color:var(--light);}
  .idees .id-m b{margin-top:-2px;font:600 var(--t-cap)/1.2 var(--sans);font-variant-numeric:tabular-nums;color:var(--ink);}
  /* les deux prix, en gros (« Tu le paies → Il se vend ») : ce que le fondateur voulait voir d'une marge, sans en calculer */
  .idees .id-duo{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:10px 12px;border-radius:12px;background:var(--pane-2);}
  .idees .id-duo > div{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:2px;}
  .idees .id-duo small{font:500 var(--t-cap)/1.2 var(--sans);color:var(--ink-3);}
  .idees .id-duo b{font:600 var(--t-title)/1.1 var(--sans);font-variant-numeric:tabular-nums;color:var(--ink);white-space:nowrap;}
  .idees .id-duo > div:first-child b{color:var(--ink);}
  .idees .id-duo i{font:500 var(--t-cap)/1.3 var(--sans);font-style:normal;color:var(--ink-2);}
  .idees .id-fl{flex:none;font:600 var(--t-head)/1 var(--sans);color:var(--ink-3);}
  .idees .id-avis{display:flex;align-items:center;gap:6px;margin:0 0 6px;font:500 var(--t-cap)/1.3 var(--sans);color:var(--ink-2);}
  .idees .id-avis .id-et{margin-top:0;}
  .idees .id-us{display:block;margin:0 0 8px;font:500 var(--t-cap)/1.3 var(--sans);color:var(--light);text-decoration:none;}
  /* « Pourquoi un échantillon ? » (27/09) : le texte derrière un chevron, fermé au repos — la grammaire de `.pal-plus`,
     préfixée (une seule mécanique de repli dans le fil) ; puis UN bouton pleine largeur et la fiche en lien (PAROLE §4 ter) */
  .idees .id-pq{margin:2px 0 8px;border-top:1px solid var(--edge-2);}
  .idees .id-pq > summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
    gap:8px;min-height:44px;font:500 var(--t-foot)/1.3 var(--sans);color:var(--ink-2);}
  .idees .id-pq > summary::-webkit-details-marker{display:none;}
  .idees .id-pq > summary::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);transition:transform .18s ease;}
  .idees .id-pq[open] > summary::after{transform:rotate(90deg);}
  /* le cadre du clavier SEULEMENT : `:focus-within` le posait aussi au doigt (vu au banc, un rectangle bleu à chaque tap) */
  .idees .id-pq > summary:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .idees .id-pq p{margin:0 0 8px;font:500 var(--t-foot)/1.4 var(--sans);color:var(--ink-2);}
  .idees .id-actes{display:flex;flex-direction:column;align-items:stretch;gap:2px;}
  .idees .id-actes .btn-n{width:100%;}
  .idees .id-actes .id-voir{min-height:44px;border:0;background:none;cursor:pointer;
    font:600 var(--t-foot)/1 var(--sans);color:var(--light);}
  .idees .id-src{margin-top:6px;text-align:center;font:500 var(--t-cap)/1.2 var(--sans);color:var(--ink-3);}
  /* un bouton NU à la taille de son verbe (AGENTS §4-5 : la pleine largeur est à l'acte d'argent), tactile 44 */
  .idees .id-suite{display:block;margin:0 auto;min-height:44px;padding:0 16px;border:0;background:none;
    color:var(--light);font:500 var(--t-foot)/1.2 var(--sans);cursor:pointer;}
  .dcand{display:flex;align-items:stretch;width:100%;min-height:84px;}
  .ru-g+.ru-g{border-top:1px solid var(--edge-2);}
  .dcand .dcorps-r{display:flex;align-items:center;gap:9px;flex:1;min-width:0;
    padding:9px 5px 9px 10px;background:none;border:0;font:inherit;color:var(--ink);
    text-align:left;cursor:pointer;}
  .dcand .dcorps-r:focus-visible,.dcand .dprise:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  .dcand .dvg{width:60px;height:60px;border-radius:11px;flex:none;background:var(--pane-2);
    border:1px solid var(--edge-2);overflow:hidden;display:flex;align-items:center;justify-content:center;}
  .dcand .dvg img{width:100%;height:100%;object-fit:contain;display:block;}
  .dcand .dvg svg{width:26px;height:26px;stroke:var(--ink-2);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .dcand .dcc{min-width:0;flex:1;line-height:1.3;}
  .dcand .dcc b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;font-size:var(--t-head);font-weight:600;letter-spacing:var(--t-head-ls);}
  .dcand .dpx{margin-top:3px;font-size:var(--t-body);font-weight:600;letter-spacing:var(--t-head-ls);
    font-variant-numeric:tabular-nums;}
  .dcand .dpx small{font-weight:400;font-size:var(--t-cap);color:var(--ink-2);}
  .dcand .dmeta{margin-top:3px;display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
  /* LA LIGNE VENDEUR (27/09) : deux lignes sous le prix, posées après la carte — le type en encre, le reste en gris,
     l'étoile en chaud. Une ligne trop longue se coupe, elle ne pousse jamais la carte. Elle arrive en fondu (sa
     place n'est pas réservée : aucune carte ne bouge pour rien si le vendeur ne répond pas). */
  .dcand .dvend{display:block;margin-top:3px;font-size:var(--t-cap);line-height:1.35;color:var(--ink-2);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;animation:dvend-vient .4s ease both;}
  .dcand .dvend .ty{font-weight:600;color:var(--ink);}
  /* la plateforme d'achat sur la carte (05/10, maquette S1) : AliExpress en orange, 1688 dans le bleu de l'écran */
  .dcand .dvend .ty.ali{color:color-mix(in srgb,#FF6A2B 72%,var(--ink));}
  .dcand .dvend .ty.m1688{color:var(--light);}
  /* « VENDRE » (fondateur, 05/10 soir : « que les boutons ressemblent aux boutons des autres onglets ») — les deux fiches,
     1688 et AliExpress : les choix au motif des offres de Livraison (.lv-o, plus bas), deux lignes au plus, et le geste au
     PIED, le même bouton que partout. Le total du pied ne dit rien d'une vente en boutique ; sur AliExpress, il est dans le
     bouton. Consommateurs : vendreChoixHTML, vendreLigneHTML, vendreAEHTML (fil.js), seuls. */
  .fiche .vd-choix{display:grid;gap:6px;padding:12px 12px 2px;}
  .fiche .vd-lignes{padding:6px 16px 8px;}
  .fiche .vd-lignes:empty{display:none;}
  .fiche .vd-l{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:6px 0;font-size:var(--t-body);}
  .fiche .vd-k{flex:1;min-width:0;}
  .fiche .vd-v{font-weight:700;white-space:nowrap;font-variant-numeric:tabular-nums;}
  .fiche .vd-dit{padding:0 16px 14px;font-size:var(--t-foot);color:var(--ink-2);}
  .fiche .vd-dit:empty{display:none;}
  .fiche .vd-dit a{color:var(--light);font-weight:600;}
  /* Les photos refaites (lot 2, maquette validée le 09/10) : grisées pendant le travail, nettes une fois dans sa boutique. */
  .fiche .vd-photos{display:flex;gap:8px;margin-top:12px;}
  .fiche .vd-photos img{width:56px;height:56px;object-fit:cover;border-radius:10px;background:var(--line,rgba(127,127,127,.12));}
  .fiche .vd-photos-gris img{opacity:.38;}
  /* LE TABLEAU AMAZON de « Vendre » (08/10, maquette validée) — classes à lui (`vd-sim…`) : les sélecteurs partagés avec la
     fiche AliExpress (.vd-lignes, .vd-l, .vd-dit) ne bougent pas. Le pas − / + est celui de « Le produit » (.evqte). */
  .fiche .vd-sim .vd-l{padding:7px 0;}
  .fiche .vd-sim-prix .vd-k{white-space:nowrap;}
  .fiche .vd-sim-pas{display:flex;align-items:center;margin-top:0;}
  .fiche .vd-sim-pas .evstep{display:flex;align-items:center;border:1px solid var(--edge);border-radius:12px;background:var(--champ-fond,var(--pane));}
  .fiche .vd-sim-pas .evq{width:42px;min-height:44px;border:0;background:transparent;font-size:var(--t-title);color:var(--ink);cursor:pointer;}
  .fiche .vd-sim-pas .evqi{min-height:44px;width:80px;border:0;background:transparent;text-align:center;font-size:var(--t-body);font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;}
  .fiche .vd-sim-frais{all:unset;box-sizing:border-box;width:100%;display:flex;justify-content:space-between;align-items:center;gap:12px;padding:7px 0;font-size:var(--t-body);cursor:pointer;}
  .fiche .vd-sim-frais:focus-visible{outline:2px solid var(--light);outline-offset:4px;border-radius:6px;}
  .fiche .vd-sim-frais[disabled]{cursor:default;}
  .fiche .vd-sim-frais .vd-k{flex:1;min-width:0;}
  .fiche .vd-sim-chev{display:inline-block;margin-left:8px;color:var(--ink-3);font-weight:400;transition:transform .2s;}
  .fiche .vd-sim-frais[aria-expanded="true"] .vd-sim-chev{transform:rotate(90deg);}
  .fiche .vd-sim-detail{margin:0 0 6px;padding:4px 0 2px;border-top:1px solid color-mix(in srgb,var(--carte-edge) 60%,transparent);}
  .fiche .vd-sim-lig{display:flex;justify-content:space-between;gap:12px;padding:7px 0;font-size:var(--t-foot);border-bottom:1px solid color-mix(in srgb,var(--carte-edge) 40%,transparent);}
  .fiche .vd-sim-lig span:first-child{color:var(--ink-2);}
  .fiche .vd-sim-lig span:last-child{font-variant-numeric:tabular-nums;color:var(--ink);}
  .fiche .vd-sim-note{padding:8px 0 2px;font-size:var(--t-foot);color:var(--ink-3);}
  .fiche .vd-sim-sep{border-top:1px solid color-mix(in srgb,var(--carte-edge) 60%,transparent);margin:6px 0 2px;}
  .fiche .vd-sim-benef .vd-v{font-size:calc(var(--t-body) * 1.15);}
  .fiche .vd-sim-statut{display:flex;flex-wrap:wrap;gap:8px;padding:10px 0 4px;}
  .fiche .vd-sim-statut .pill{min-height:34px;padding:0 13px;}
  .fiche .vd-sim-statut .pill.on{background:color-mix(in srgb,var(--fam-estime) 12%,transparent);border-color:var(--fam-estime);}
  .fiche .vd-sim-etat{display:block;color:var(--fam-estime);font-weight:600;margin-bottom:4px;}
  .fiche .ae-moi{padding:0 16px 6px;}
  /* « TA BOUTIQUE » OUVERT SOUS LA FICHE (fondateur, 06/10, sur la prod : « c'est mal positionné ») : c'est l'objet de « Mon
     compte », qui tenait ses marges du panneau (`.dcorps .p-obj`) — ici, celles des choix ; le bouton passe sous sa phrase ;
     caché par un autre choix, il l'est vraiment (`display:flex` l'emportait sur `hidden`). Consommateurs : les deux refus
     de « Pousser en boutique » (fil.js, 1688 et AliExpress), seuls. */
  .fiche .fpan .ae-boutique.p-obj{margin:2px 12px 14px;padding:0 12px 12px;display:flex;flex-direction:column;gap:7px;}
  .fiche .fpan .ae-boutique[hidden]{display:none;}
  .fiche .fpan .ae-boutique .pied-n{flex-wrap:wrap;}
  .fiche .fpan .ae-boutique .pied-n .note-n{padding:0 2px;}
  .fiche .fpan .ae-boutique .pied-n .note-n:not(:empty){flex-basis:100%;}
  .fiche .fpan .ae-boutique .pied-n .note-n:not(:empty) ~ .btn-n{flex:1;}
  /* un choix hors d'atteinte (l'usine ne vend pas à la pièce, 06/10) : grisé, sa raison lisible dessous */
  .fiche .vd-choix .lv-o.off{cursor:default;}
  .fiche .vd-choix .lv-o.off .lv-rd,.fiche .vd-choix .lv-o.off .lv-nom{opacity:.45;}
  .fiche[data-source="aliexpress"] .fpied .ftot,.fiche[data-vendre="boutique"] .fpied .ftot{display:none;}
  /* envoyé en boutique, le pied se retire : un bouton n'est pas un statut — le fait vit dans la ligne, « Modifier » est son
     geste (maquette 4 et planche F1-F3 validées, 08-09/10) ; il revient avec un autre choix. Les deux fiches gardent leur
     ligne envoyée quand le choix change (sans elle, la fiche serait muette). */
  .fiche[data-vendre="boutique"][data-poussee] .fpied{display:none;}
  .fiche .ae-px{all:unset;cursor:pointer;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;}
  .fiche .ae-px:focus-visible{outline:2px solid var(--light);outline-offset:4px;border-radius:6px;}
  .fiche .ae-detail{margin:2px 0 10px;}
  /* la rangée de quantité de « Vendre » (`.ae-qte`) est partie le 06/10 : les pièces se règlent dans « Le produit », au pli de 1688 */
  .fiche .ae-dit{margin-top:8px;font-size:var(--t-foot);color:var(--ink-2);}
  /* le champ des pièces de la fiche AliExpress (le pli de 1688) garde 16 px : en dessous, iOS zoome (revue du 06/10) */
  .fiche .fcarac.evpli.ae-pli .evqte .evqi{font-size:var(--t-champ, 16px);}
  .fiche .ae-dit:empty{display:none;}
  .fiche .ae-cmd .livf{margin:12px 0 10px;}
  .dcand .dvend .et{width:.95em;height:.95em;vertical-align:-.12em;fill:var(--warm, var(--ink-2));}   /* une icône dessinée, pas un emoji (fil-voix-je) */
  @keyframes dvend-vient{from{opacity:0;}to{opacity:1;}}
  @media (prefers-reduced-motion:reduce){ .dcand .dvend{animation:none;} }
  .dcand .dprise{width:46px;flex:none;display:flex;align-items:center;justify-content:center;
    border:0;border-left:1px solid var(--edge-2);background:none;color:var(--ink-2);
    font-size:var(--t-title);font-family:var(--sans);cursor:pointer;}
  .dcand .dprise:active{background:color-mix(in srgb,var(--light) 8%, transparent);}
  /* le menu de la rangée : sous elle, des verbes, ≥44 pt */
  /* 🔴 le menu s'ouvre par [hidden] SEUL — l'ancienne classe `menu-la` n'était posée
     par personne : le menu du dossier était mort à l'écran (attrapé à l'audit Ultra). */
  .dmenu{display:flex;gap:8px;padding:9px 12px;border-top:1px solid var(--edge-2);}
  .dmenu[hidden]{display:none;}
  .dmenu button{flex:1;min-height:44px;border-radius:11px;border:1px solid var(--edge);
    background:var(--pane);font-family:var(--sans);font-size:var(--t-foot);font-weight:600;
    color:var(--ink);cursor:pointer;}
  .dmenu button:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
  /* ══ LA RANGÉE CANDIDAT DANS LE FIL (maquette §1, 91e) : la .card devient la
     rangée compacte — le corps .dcand à gauche, et le bouton .garder d'`armer()`
     DEVIENT la prise ⋯ pleine hauteur à droite (mêmes gestes, même menu). ══ */
  .card.rcand{padding:0;display:flex;flex-direction:row;align-items:stretch;
    user-select:none;-webkit-user-select:none;min-height:100px;gap:0;}
  .card.rcand .dcand{flex:1;min-width:0;display:flex;align-items:center;gap:9px;
    padding:9px 5px 9px 10px;}
  .card.rcand .contact{display:none;}
  .card.rcand .lab{display:block;margin:0;font-size:var(--t-foot);font-weight:600;
    letter-spacing:-.01em;line-height:1.3;}
  .card.rcand .garder{position:static;flex:none;width:46px;border:0;
    border-left:1px solid var(--edge-2);border-radius:0;background:none;
    box-shadow:none;color:var(--ink-2);font-size:var(--t-title);cursor:pointer;
    display:flex;align-items:center;justify-content:center;}
  .card.rcand .garder::before{content:'⋯';position:static;left:auto;top:auto;
    width:100%;height:auto;display:block;text-align:center;line-height:1;
    background:none;border-radius:0;box-shadow:none;transform:none;opacity:1;}
  .card.rcand .garder:hover::before,.card.rcand .garder[data-charge]::before,
  .card.rcand .garder[aria-pressed="true"]::before{height:auto;}
  .card.rcand .garder:active{background:color-mix(in srgb,var(--light) 8%, transparent);}
  /* le RENFORT de spécificité : la peau candidate des GRANDES cartes (bande 20px,
     trait-arête au halo, touch-action:none du carrousel) ne s'applique pas à la
     rangée — elle garde son verre, sa prise ⋯, et le SCROLL vertical du doigt. */
  /* 🔴 le renfort tuait le VERRE TEINTÉ (background-image:none écrasait le gradient
     de .dobj.teinte — les rangées étaient blanches, constat fondateur 30/08 au soir).
     Il repose le verre par sa variable, et rend leurs bords teinte aux flancs. */
  .card.rcand[data-kind="candidate"]{background-image:var(--verre);touch-action:pan-y;
    border-left-color:color-mix(in srgb,var(--fc,var(--fam-neutre)) 30%, rgba(255,255,255,.6));
    border-right-color:color-mix(in srgb,var(--fc,var(--fam-neutre)) 30%, rgba(255,255,255,.6));}
  .card.rcand[data-kind="candidate"] .garder::before{width:100%;height:auto;box-shadow:none;}
  /* la liste des résultats : les rangées empilées — plus un carrousel */
  .deckwrap.liste{overflow:visible;}
  .deck.liste{display:flex;flex-direction:column;gap:10px;transform:none !important;}
  .deck.liste .deck-slot{width:100%;flex:none;}
  /* LA PLANCHE DE QUATRE, EN CARRÉ (fondateur, 05/09) : la sélection se pose en 2 × 2, image
     dessus, trois lignes dessous — le prix, le prix de revente, le bénéfice net. */
  /* ══ LE CARRÉ EST UNE SUITE DE PAGES (fondateur, 14/09) ═══════════════════════════════
     « Ça doit pas s'étaler dans le fil. Pour ça, c'est horizontal. » Le 2 × 2 du 05/09 est
     conservé À L'INTÉRIEUR de chaque page ; ce sont les PAGES qui défilent.

     DÉFILEMENT NATIF, pas un `transform` tenu en JS : le doigt, l'inertie, le rebond, le
     clavier et le lecteur d'écran viennent avec le navigateur, et rien ne peut dériver.
     `.deck.liste` pose déjà `transform:none !important` — il reste vrai : on ne translate
     rien, c'est la boîte qui défile. Sans accrochage, un balayage laisse une demi-page à
     l'écran — exactement l'étalement qu'on retire. */
  .deck.liste.carre{display:flex;flex-direction:row;gap:12px;align-items:start;
    overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
    overscroll-behavior-x:contain;scrollbar-width:none;-ms-overflow-style:none;}
  .deck.liste.carre::-webkit-scrollbar{display:none;}
  .deck-page{flex:0 0 100%;min-width:0;display:grid;grid-template-columns:1fr 1fr;gap:10px;
    align-content:start;scroll-snap-align:start;}
  /* `.deck-slot` porte `margin-right:4%` pour le carrousel carte-par-carte ; dans une grille
     de page, cette marge pousserait la colonne de droite hors du carré. */
  .deck-page .deck-slot{margin-right:0;}
  .deck.liste.carre .deck-slot{width:auto;min-width:0;}
  .deck.liste.carre .card.rcand{position:relative;flex-direction:column;}
  .deck.liste.carre .card.rcand .dcand{flex-direction:column;align-items:stretch;gap:6px;min-height:0;padding:0 0 10px;}
  .deck.liste.carre .dvg{width:100%;height:auto;aspect-ratio:1;border-radius:16px 16px 0 0;flex:none;}
  .deck.liste.carre .dvg img{width:100%;height:100%;object-fit:cover;}
  .deck.liste.carre .dcc{padding:0 10px;min-width:0;}
  .deck.liste.carre .card.rcand .lab{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
  .deck.liste.carre .card.rcand .garder{position:absolute;top:6px;right:6px;left:auto;bottom:auto;width:28px;height:28px;border-radius:50%;background:var(--carte-bg,rgba(255,255,255,.85));opacity:.8;font-size:var(--t-foot);}   /* plus petit, plus discret (fondateur, 05/09 : « trop gros ») */
  .deck.liste.carre .dbadge{white-space:normal;max-width:100%;line-height:1.3;}
  .deck.liste.carre .dmeta{display:block;min-width:0;}
  .dben{display:block;margin-top:4px;font-size:var(--t-foot);font-weight:600;color:var(--ink);}
  .dben small{font-weight:500;color:var(--ink-2);}
  .dventes{display:block;margin-top:3px;}
  .dbadge.nat{border-color:var(--ink-3);color:var(--ink-2);vertical-align:middle;margin-left:4px;}
  /* ══ LA CARTE-NAISSANCE (maquette : « elle naît trouée, se remplit ») et LA
     CHRONOLOGIE des tickets — partagées par la recherche sur mesure et le bon de
     réception. Le bandeau prend la couleur de famille (--fc), pointillé : une
     demande en construction n'est pas encore scellée. ══ */
  .card.naiss{padding:0 12px 10px;display:flex;flex-direction:column;gap:7px;}
  .bandeau-n{display:flex;align-items:center;gap:8px;margin:0 -14px 2px;padding:9px 14px;
    background:color-mix(in srgb,var(--fc,var(--fam-neutre)) 14%,transparent);
    font-size:var(--t-cap);font-weight:600;color:var(--ink-2);}
  .bandeau-n .fi{width:14px;height:14px;flex:none;stroke:var(--fc,var(--fam-neutre));fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .bandeau-n .etat-n{margin-left:auto;}
  .ch-n{min-height:44px;padding:0 12px;border-radius:11px;border:1px solid var(--edge);
    background:var(--pane);font-size:var(--t-foot);color:var(--ink);font-family:var(--sans);width:100%;}
  .ch-n:focus{outline:none;border-color:var(--light);
    box-shadow:0 0 0 2px color-mix(in srgb,var(--light) 22%,transparent);}
  .lab-n{font-size:var(--t-cap);color:var(--ink-2);margin-bottom:4px;}
  .prov-n{font-size:var(--t-cap);color:var(--ink-3);margin-top:4px;}
  .naiss .deux-n{display:grid;grid-template-columns:1fr 1fr;gap:9px;}
  /* le bloc photo de la maquette : cadre pointillé, vignette quand elle est là */
  .photo-n{display:flex;align-items:center;gap:11px;background:none;border:0;padding:0;
    text-align:left;cursor:pointer;color:inherit;font:inherit;min-height:44px;}
  .photo-n .pn-cadre{width:52px;height:52px;flex:none;border-radius:12px;
    border:1.5px dashed color-mix(in srgb,var(--fc,var(--fam-neutre)) 55%, var(--ink-3));
    background:var(--pane-2);display:flex;align-items:center;justify-content:center;overflow:hidden;}
  .photo-n .pn-cadre svg{width:20px;height:20px;stroke:var(--ink-2);fill:none;stroke-width:1.9;
    stroke-linecap:round;stroke-linejoin:round;}
  .photo-n .pn-cadre img{width:100%;height:100%;object-fit:cover;display:block;}
  .photo-n .pn-txt{min-width:0;line-height:1.3;}
  .photo-n .pn-txt b{display:block;font-size:var(--t-foot);font-weight:600;}
  .photo-n .pn-txt small{font-size:var(--t-cap);color:var(--ink-2);}
  .pied-n{display:flex;align-items:center;gap:10px;padding-top:2px;}
  /* lot 3 (maquettes validées, planches 8 et 10) : quand le pied n'a plus de note, son geste prend la largeur de la carte */
  [data-role="fulfillment-naiss"] .pied-n .note-n:empty,[data-role="agent-brief"] .pied-n .note-n:empty,[data-role="connexion"] .pied-n .note-n:empty{display:none;}
  [data-role="fulfillment-naiss"] .pied-n .note-n:empty ~ .btn-n{flex:1 1 100%;}
  [data-role="agent-brief"] .pied-n,[data-role="connexion"] .pied-n{flex-wrap:wrap;}
  [data-role="agent-brief"] .pied-n .note-n,[data-role="connexion"] .pied-n .note-n:not(:empty){flex-basis:100%;}
  [data-role="agent-brief"] .pied-n .btn-n,[data-role="connexion"] .pied-n .btn-n{flex:1 1 100%;}
  .pied-n .note-n{font-size:var(--t-cap);color:var(--ink-3);flex:1;}
  .btn-n{min-height:46px;padding:0 22px;border-radius:13px;border:0;flex:none;
    font-family:var(--sans);font-size:var(--t-foot);font-weight:600;cursor:pointer;
    background:var(--light);color:#fff;}
  .btn-n[disabled]{opacity:.45;cursor:default;}
  .demande-n{font-size:var(--t-foot);color:var(--ink-2);margin:6px 2px 2px;line-height:1.4;}
  .chrono{margin:6px 2px 2px;display:flex;flex-direction:column;gap:6px;}
  .chrono .cr{display:flex;align-items:center;gap:9px;font-size:var(--t-foot);color:var(--ink-3);}
  .chrono .cr i{width:9px;height:9px;border-radius:50%;border:1.5px solid var(--ink-3);flex:none;}
  .chrono .cr.ok{color:var(--ink);}
  .chrono .cr.ok i{background:var(--fam-commande);border-color:var(--fam-commande);}
  .chrono .cr.en{color:var(--ink-2);}
  .chrono .cr.en i{border-color:var(--light);animation:bat-n 1.5s infinite;}
  @keyframes bat-n{50%{opacity:.3;}}
  @media (prefers-reduced-motion: reduce){.chrono .cr.en i{animation:none;}}
/* ── LE SUIVI EN CARTE (chantier « suivi en carte », ticket 04, 01/10) — maquette validée :
   docs/mockups/suivi-carte-coque-0110.html. Règles NEUVES, toutes sous .trj- : aucun sélecteur partagé touché. */
.obj-cmd .trj-cadre{margin:10px 0 0;border-radius:14px;overflow:hidden;border:1px solid var(--edge-2);
  background:radial-gradient(90% 90% at 60% 40%, color-mix(in srgb,var(--deep) 40%,transparent), var(--pane-2));aspect-ratio:340/110;}
/* plié au repos (bandeau, et les lignes du lieu se taisent), entier au toucher — fondateur 01/10 */
.obj-cmd.trj-ouvert .trj-cadre{aspect-ratio:340/200;}
/* dans « Mes commandes », la ligne déplie la même carte, déjà ouverte : le bouton « Détail » n'y a rien à faire */
.obj-cmd.trj-panneau .trj-plier{display:none;}
.obj-cmd:not(.trj-ouvert) .trj-lignes,.obj-cmd:not(.trj-ouvert) .trj-faits{display:none;}
.obj-cmd .trj-faits{display:flex;flex-wrap:wrap;gap:6px;margin:0 2px 10px;}
.obj-cmd .trj-plier{display:flex;align-items:center;gap:8px;margin:-8px -6px 0 auto;min-height:44px;min-width:44px;padding:0 6px;
  flex:none;border:0;background:none;font:inherit;font-size:var(--t-foot);color:var(--ink-2);cursor:pointer;
  -webkit-tap-highlight-color:transparent;}
.obj-cmd .trj-plier::after{content:"";width:7px;height:7px;border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s var(--e-main);}
.obj-cmd .trj-plier[aria-expanded="true"]::after{transform:rotate(-135deg) translate(-2px,-2px);}
.obj-cmd .trj-cadre:empty{background:var(--pane-2);}
.trj-map{display:block;width:100%;height:100%;}
/* LA CARTE DESSINÉE (fondateur, 03/10 : « Fais la carte dessinée ») — la mer, les terres pleines, les frontières des pays
   connus, les pays du trajet teintés, leurs noms ; une palette par thème (les points d'avant disparaissaient en clair). */
.trj-map{--geo-mer:#D5E3EF;--geo-sol:#F6F9FC;--geo-pays:#F1F5FA;--geo-al:#C9DEF2;--geo-ici:#AFD0EE;--geo-front:#A7BBCE;--geo-nom:#587187;}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .trj-map{--geo-mer:#08111A;--geo-sol:#172230;--geo-pays:#1A2634;--geo-al:#1F3B54;--geo-ici:#285577;--geo-front:#33495E;--geo-nom:#93ABBE;}}
:root[data-theme="dark"] .trj-map{--geo-mer:#08111A;--geo-sol:#172230;--geo-pays:#1A2634;--geo-al:#1F3B54;--geo-ici:#285577;--geo-front:#33495E;--geo-nom:#93ABBE;}
.trj-mer{fill:var(--geo-mer);}
.trj-sol{fill:var(--geo-sol);fill-rule:evenodd;}
.trj-pays{fill:var(--geo-pays);fill-rule:evenodd;stroke:var(--geo-front);stroke-width:.6;stroke-linejoin:round;}
.trj-pays.al{fill:var(--geo-al);}
.trj-pays.ici{fill:var(--geo-ici);}
.trj-nompays{font-family:var(--sans);font-size:8.5px;font-weight:600;letter-spacing:.14em;fill:var(--geo-nom);}
.trj-fait{fill:none;stroke:var(--light);stroke-width:1.6;opacity:.6;}
.trj-avenir{fill:none;stroke:color-mix(in srgb,var(--ink-2) 55%,transparent);stroke-width:1.4;stroke-dasharray:3 4;}
.trj-comete{fill:none;stroke:var(--light-hi);stroke-width:2.6;stroke-linecap:round;stroke-dasharray:9 91;
  filter:drop-shadow(0 0 4px var(--light));animation:trj-court 2.8s cubic-bezier(.4,0,.2,1) infinite;}
@keyframes trj-court{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
.trj-passe{fill:var(--light);}
.trj-futur{fill:none;stroke:var(--ink-2);stroke-width:1.5;}
.trj-ici{fill:var(--fam-commande);filter:drop-shadow(0 0 6px color-mix(in srgb,var(--fam-commande) 50%,transparent));}
.trj-halo{fill:none;stroke:var(--fam-commande);stroke-width:1.2;transform-box:fill-box;transform-origin:center;
  opacity:0;animation:trj-onde 2.4s ease-out infinite;}
.trj-halo.h2{animation-delay:1.2s;}
@keyframes trj-onde{from{transform:scale(.6);opacity:.8}to{transform:scale(3.2);opacity:0}}
.trj-livre{fill:var(--fam-commande);}
.trj-coche{fill:none;stroke:var(--screen);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
.trj-lab{font-family:var(--sans);font-size:var(--t-cap);font-weight:600;fill:var(--ink-2);letter-spacing:.02em;paint-order:stroke;
  stroke:var(--screen);stroke-width:3.5px;stroke-linejoin:round;}
.trj-lab.fort{font-size:var(--t-foot);fill:var(--ink);}
.obj-cmd .trj-statut{display:flex;gap:10px;align-items:flex-start;margin:12px 2px 10px;}
.trj-dot{width:9px;height:9px;border-radius:50%;background:var(--fam-commande);margin-top:6px;flex:none;animation:bat-n 1.5s infinite;}
.trj-dot.fixe{animation:none;}
.trj-s1{font-size:var(--t-head);font-weight:600;letter-spacing:var(--t-head-ls);color:var(--ink);}
.trj-s2{font-size:var(--t-foot);color:var(--ink-2);margin-top:2px;}
.obj-cmd .trj-lieux{list-style:none;display:grid;gap:3px;margin:0 2px 12px;padding:0;}
.trj-lieux b{display:block;height:4px;border-radius:2px;background:var(--pane);}
.trj-lieux li.ok b{background:var(--fam-commande);}
.trj-lieux li.ici b{background:linear-gradient(90deg,var(--fam-commande),color-mix(in srgb,var(--fam-commande) 20%,transparent));
  animation:bat-n 1.5s infinite;}
.trj-lieux span{display:block;font-size:var(--t-cap);color:var(--ink-3);margin-top:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.trj-lieux li.ok span{color:var(--ink-2);} .trj-lieux li.ici span{color:var(--ink);font-weight:600;}
.obj-cmd .trj-lignes{display:flex;flex-direction:column;gap:7px;margin:0 2px 10px;}
.trj-ln{display:flex;align-items:center;gap:9px;font-size:var(--t-foot);color:var(--ink-2);}
.trj-ln i{width:7px;height:7px;border-radius:50%;background:var(--ink-3);flex:none;}
.trj-ln.der{color:var(--ink);} .trj-ln.der i{background:var(--fam-commande);}
.trj-ln em{margin-left:auto;font-style:normal;font-size:var(--t-cap);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.trj-plus{font-size:var(--t-cap);color:var(--ink-3);padding-left:16px;}
.trj-grp{font-size:var(--t-cap);font-weight:600;color:var(--ink-3);margin:8px 0 1px;}
@media (prefers-reduced-motion: reduce){.trj-comete,.trj-halo,.trj-dot,.trj-lieux li.ici b{animation:none;}}
  .chrono .date{margin-left:auto;font-size:var(--t-cap);color:var(--ink-3);font-variant-numeric:tabular-nums;}
  .ligne-r{display:flex;align-items:center;gap:9px;width:100%;min-height:44px;
    padding:8px 14px;background:none;border:0;border-top:1px solid var(--edge-2);
    font:inherit;font-size:var(--t-foot);color:var(--ink);text-align:left;cursor:pointer;}
  .ligne-r .fi{width:16px;height:16px;flex:none;stroke:var(--ink-2);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .ligne-r .lr-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .ligne-r .chev::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);}
  /* la porte se PARCOURT au clavier (audit 01/09) : chaque ligne montre où on est */
  .ligne-r:focus-visible{outline:2px solid var(--light);outline-offset:-2px;border-radius:10px;}
  .reste-r{padding:8px 14px 10px;font-size:var(--t-foot);color:var(--ink-2);border-top:1px solid var(--edge-2);}
  /* LA COUVERTURE ULTRA : compacte, la DATE en vedette ; s'ouvre sur les rangées */
  .card.couv-u{padding:0;}
  .couv-tete{display:flex;align-items:center;gap:11px;width:100%;min-height:76px;
    padding:11px 14px;background:none;border:0;font:inherit;color:var(--ink);
    text-align:left;cursor:pointer;}
  .couv-tete .dvg{width:44px;height:44px;}
  .couv-tete .dvg svg{width:20px;height:20px;stroke:var(--ink-2);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .couv-tete .dcc{flex:1;min-width:0;}
  .couv-tete .lab{display:block;font-size:var(--t-foot);font-weight:600;}
  .date-vedette{display:block;margin-top:3px;font-size:var(--t-foot);font-weight:600;
    color:var(--fam-equipe);}
  .couv-tete .chev::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);
    display:inline-block;transition:transform .3s var(--e-main);}
  .card.couv-u.ouverte .couv-tete .chev::after{transform:rotate(90deg);}
  .couv-liste .dcand{border-top:1px solid var(--edge-2);cursor:pointer;}
  .couv-liste .dcand .dcc{padding:11px 6px 11px 0;}
  .couv-liste .dcand{display:flex;align-items:center;gap:9px;padding:0 12px;min-height:80px;}
  .voirplus{display:block;width:100%;min-height:44px;border:0;border-top:1px solid var(--edge-2);
    background:none;font-family:var(--sans);font-size:var(--t-foot);font-weight:600;
    color:var(--light);cursor:pointer;}
  /* LA FEUILLE de commande : la photo au bandeau, le lien CGV discret, le pied qui
     dit le manque — et le VERT réservé à l'acte d'argent (« Payer … aujourd'hui »). */
  .feuille-c .dcand .dvg{width:40px;height:40px;}
  .cgv-n{font-size:var(--t-cap);color:var(--ink-3);margin:4px 2px;}
  .cgv-n a{color:var(--ink-2);}
  .manque-n{text-align:center;min-height:16px;}
  .fx-dont{text-align:center;}   /* « dont livraison estimée X € », sous le bouton qui porte le total (24/09) */
  /* .vert = LE rendu argent (un seul dans l'app — même dégradé que .cta-payer) */
  .cta-plein.vert{background:var(--btn-argent-bg);color:var(--btn-argent-ink);
    box-shadow:var(--btn-argent-halo);}
  /* le retrait est RÉVERSIBLE 5 s — le patron « Écarté · Remettre » de la maquette */
  .dbandeau{display:flex;align-items:center;justify-content:space-between;gap:10px;
    padding:12px 14px;font-size:var(--t-foot);color:var(--ink-2);}
  .dbandeau button{min-height:38px;padding:0 16px;border-radius:11px;border:1px solid var(--edge);
    background:var(--pane);font-family:var(--sans);font-size:var(--t-foot);font-weight:600;
    color:var(--light);cursor:pointer;}
  /* la fiche rouverte : la même carte, dépliée sous la rangée */
  .ddetail{border-top:1px solid var(--edge-2);padding:12px 14px;}
  .ddetail .dphoto{height:160px;border-radius:12px;overflow:hidden;margin-bottom:8px;
    background:var(--pane-2);}
  .ddetail .dphoto img{width:100%;height:100%;object-fit:contain;display:block;}
  .ddetail .drow{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
    padding:7px 0;font-size:var(--t-foot);}
  .ddetail .drow+.drow{border-top:1px solid var(--edge-2);}
  .ddetail .drow .dk{color:var(--ink-2);}
  .ddetail .drow .dv{font-weight:600;flex:none;font-variant-numeric:tabular-nums;}
  .ddetail .drow .dtxt{font-size:var(--t-foot);text-align:right;}
  .ddetail .dlab{display:block;font-size:var(--t-foot);font-weight:600;margin-bottom:2px;}
  .ddetail .dfait{font-size:var(--t-cap);color:var(--ink-2);padding-top:7px;}
  .dossier .dvide{color:var(--ink-2);font-size:var(--t-foot);line-height:1.6;margin-top:22px;}
  .dossier .dvide-t{display:block;margin-bottom:4px;font-size:var(--t-head);font-weight:600;color:var(--ink);}   /* lot 3 : le titre de l'état vide */

  /* ══════ LA SCÈNE DIRECTE (?direct=1) ══════
     Sur un téléphone, dessiner un téléphone est un contresens : on juge un cadre au
     lieu de juger un geste. En direct, la scène occupe l'écran, sans châssis, sans
     préambule — trois secondes suffisent pour dire si la main y croit. */
  /* on masque les VOISINS du téléphone, pas son parent : .holder vit dans .page */
  /* !important assumé : le <header> porte un style="display:flex" EN LIGNE, qui bat
     toute règle de feuille. Un mode d'affichage a le droit de trancher. */
  body.direct .page > header,body.direct .argu,body.direct .note{display:none!important;}
  body.direct .page{max-width:none;margin:0;padding:0;gap:0;}
  body.direct .stagegrid{display:block;gap:0;}
  body.direct .sky,body.direct .floor,body.direct .horizon{display:none;}
  body.direct .holder{display:none!important;}        /* le châssis entier disparaît */
  body.direct .island,body.direct .status,body.direct .homebar{display:none!important;}
  /* l'écran est DÉPLACÉ dans <body> par le JS : plus rien n'hérite d'une mise en page */
  /* une sortie de secours : le banc occupe tout l'écran, il faut pouvoir en sortir */
  body.direct #sortir{position:fixed;top:calc(env(safe-area-inset-top) + 10px);right:10px;z-index:20;
    min-height:36px;padding:7px 12px;border-radius:14px;border:1px solid var(--edge);
    background:var(--pane);color:var(--ink-2);font-size:var(--t-cap);
    cursor:pointer;}
  #sortir{display:none;}
  /* prod : pas de bouton « quitter le banc » — le fil EST la page */
  .screen.plein{position:fixed;inset:0;width:auto;height:auto;border-radius:0;border:0;
    z-index:10;padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);}
  .screen.plein.clavier{padding-bottom:0;}   /* clavier ouvert : il recouvre la zone du geste d'accueil (12/10) */
  body.direct #dust2{z-index:5;}
  /* en banc, les trois candidats tiennent l'écran : le fil part du HAUT, pas du bas */
  /* prod : le fil est une CONVERSATION — il colle en bas quand il est court,
     et SE REMONTE quand il est long (l'historique est un droit). */
  body.direct .thread{justify-content:flex-start;transform:none;overflow-y:auto;
    -webkit-overflow-scrolling:touch;overscroll-behavior:contain;
    /* une décision financière ne se lit jamais coupée (audit 14/08) : de l'air
       sous le header en haut de course, et au-dessus du composeur en bas */
    padding-top:14px;
    padding-bottom:calc(env(safe-area-inset-bottom, 0px) + 122px);}
  /* LE POINT D'ÉQUILIBRE (fondateur, 02/09, deux corrections successives à l'œil :
     71 % de ciel « trop bas », 15 % « trop haut ») : la parole s'ouvre vers le tiers
     haut. Un margin FIXE en px — jamais auto (l'ancien second épinglage bas), jamais
     vh (le clavier redimensionne le viewport et ferait sauter l'écran, le défaut qui
     a tué l'espaceur ::after). Une fois la conversation longue, cet air ne se voit
     qu'en remontant tout en haut de l'historique — comme iMessage. */
  /* 03/10 — le fondateur, sur maquette : « la position dans le fil, c’est vrai qu’elle est mieux, elle fait plus normal ».
     Le fil s’ouvre en haut, comme une messagerie. (Était 150 px, réglé à l’œil le 02/09.) */
  body.direct .thread > :first-child{margin-top:20px;}
  /* ── APP, PAS DOCUMENT : l'appui long ne sélectionne JAMAIS de texte (le halo
     bleu de sélection détruisait le geste de prise). La saisie reste libre. ── */
  .screen, .screen *{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;}
  .screen input, .screen textarea{-webkit-user-select:text;user-select:text;}
  .screen .card{-webkit-tap-highlight-color:transparent;}
  /* ── LA PRISE SUR TÉLÉPHONE : pan-y laissait le navigateur confisquer le geste
     vertical (pointercancel → la carte revenait toujours). Cette page ne défile
     pas : les candidates confisquent TOUT le geste — prise, trajet, lancer. ── */
  /* la candidate garde la MATIÈRE A ; le liseré bleuté reste, en PLUS discret
     (« ça se prend ») : teinte cyan des flancs + l'arête de prise en bande gauche */
  .card[data-kind="candidate"]{touch-action:none;
    border-left-color:color-mix(in srgb,var(--light) 30%,var(--carte-edge));
    border-right-color:color-mix(in srgb,var(--light) 30%,var(--carte-edge));
    background-image:
      linear-gradient(90deg, color-mix(in srgb,var(--light) 11%,transparent) 0 20px, transparent 20px),
      var(--carte-bg);}
  .card[data-kind="candidate"] .garder::before{opacity:1;width:4px;height:44px;
    box-shadow:0 0 8px var(--glow);}
  /* ── PAS DE MOMENT MORT : le trait de scan VIT tant que l'analyse tourne
     (il s'arrête quand le serveur a répondu — le mouvement dit le travail). ── */
  .snap .scan-vie{animation:scan 1.7s var(--ease) infinite;}
  /* ── LE CLAVIER : police 16px (sinon iOS zoome au focus), et l'écran suit le
     viewport visuel — le bouton envoyer reste au-dessus du clavier. ── */
  /* la barre d'annulation n'existe qu'allumée — ni à l'œil, ni au lecteur d'écran */
  .annuler{visibility:hidden;}
  .annuler.on{visibility:visible;}
  /* cibles tactiles ≥ 44 px (audit) */
  /* 🔴 « Fais-les légèrement plus petits » (fondateur, 26/08) — 40 px au lieu de 44.
     JE LE DIS PLUTÔT QUE DE LE MAQUILLER : 44 px était une règle d'audit (cible tactile
     minimale). À 40 on passe dessous de 4 px. Le contenant, lui, fait 48 px de haut et le
     champ prend toute la largeur restante : la cible qui compte, celle où on écrit, a grossi.
     L'envoi reste à 44 : c'est l'acte, il garde le plein calibre. */
  .composer .cam,.composer .plus{width:44px;height:44px;}
  .composer .send{width:44px;height:44px;}
  /* libellés secondaires : contraste remonté (audit) */
  .when{color:var(--ink-2);}
  /* envoi désactivé à vide */
  /* 03/10 : à vide, un rond neutre et opaque — le bleu rendu transparent avait l’air cassé */
  .composer .send[data-vide]{opacity:1;pointer-events:none;}
  /* titre pour lecteur d'écran */
  .sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
  .composer input.field{font-size:var(--t-champ);}
  .screen.plein{inset:auto;top:0;left:0;right:0;width:auto;height:100dvh;}
  /* ── QUALITÉ « DA VALIDÉE » : en plein écran, l'ATMOSPHÈRE revit — l'écran
     devient transparent et laisse vivre l'aurore, l'horizon et la poussière,
     tous pilotés par l'état de Rabbit (l'orchestration validée le 13/08).
     Les surfaces à LIRE (fiche, demande) restent opaques — pas de verre sur
     une surface à lire. ── */
  body.direct .sky, body.direct .horizon{display:block;}
  .screen.plein{background:transparent;border:0;}
  body.direct .threadwrap::before, body.direct .threadwrap::after{display:none;}
  body.direct .scanscene{background:color-mix(in srgb,var(--screen) 46%,transparent);
    backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);}

  /* ── LA PAROLE SANS À-COUPS : le flou animé PAR MOT saturait le GPU des
     téléphones (lu comme « ça bug »). Opacité + translation seulement. ── */
  @keyframes wordin{from{opacity:0;transform:translateY(3px);}to{opacity:1;transform:none;}}
  /* ── L'ÉTAPE EN COURS RESPIRE : une onde douce sur la puce active — le
     mouvement dit « je travaille », il s'arrête avec la coche. Une seule
     boucle à l'écran, jamais au repos (elle n'existe que pendant un acte). ── */
  /* l'étape en cours MIROITE — le code visuel installé par ChatGPT/Claude :
     c'est le texte lui-même qui scintille, pas un rond qui émet. */
  .step.now{background:linear-gradient(100deg, var(--ink-3) 25%, var(--ink) 50%, var(--ink-3) 75%);
    background-size:220% 100%;-webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;animation:miroite 1.5s linear infinite;}
  .step.now .stacq{-webkit-text-fill-color:var(--ink-3);}
  .step.now i{-webkit-text-fill-color:#fff;animation:none;}
  @keyframes miroite{to{background-position:-220% 0;}}
  /* ── LES POINTS DE DÉTECTION : l'IA « voit » la photo — des points de
     reconnaissance scintillent pendant TOUTE la recherche, et meurent avec
     l'arrivée des candidats. Le mouvement dit le travail. ── */
  .pdet{position:absolute;width:5px;height:5px;border-radius:50%;z-index:3;pointer-events:none;
    background:var(--light-hi);box-shadow:0 0 9px var(--glow);
    animation:pdet 1.2s ease-out forwards;}
  @keyframes pdet{0%{opacity:0;transform:scale(.4);}25%{opacity:.95;transform:scale(1);}100%{opacity:0;transform:scale(.6);}}
  /* Le détail d'un palier est une surface de lecture, pas une particule de scan.
     Il reste dans le flux et change avec le palier sélectionné. */
  .plan-detail-panel{margin:10px 0 4px;padding:12px 14px;border:1px solid var(--edge-2);
    border-radius:16px;background:var(--pane-2);display:grid;gap:7px;}
  .plan-detail-panel .lab{margin:0 0 2px;}
  .plan-detail-panel .fact{margin:0;}
  /* 11/09 — LA CARTE DES FORMULES TIENT DANS L'ÉCRAN (fondateur : « trop grosse, il faut tout voir
     sans scroller »). Mesuré au banc 390×844 : 708 px avant. Rangées et faits resserrés, note en
     capitale, bouton plus bas — uniquement sous [data-famille="palier"], les autres cartes ne bougent pas. */
  .card[data-famille="palier"] .pack-opt.palier{padding:7px 12px;margin-top:6px;align-items:center;}
  .card[data-famille="palier"] .plan-detail-panel{margin:8px 0 2px;padding:8px 12px;}
  .card[data-famille="palier"] .plan-detail-panel .fact{padding:2px 0;line-height:1.3;}
  .card[data-famille="palier"] .fact.abo-note{font-size:var(--t-cap);color:var(--ink-3);padding:4px 0 0;}
  .card[data-famille="palier"] .cta-payer{margin-top:8px;min-height:46px;}

  /* ══ « TA FORMULE » AU REPOS (14/09) ═══════════════════════════════════════════════════
     Le 11/09 on avait déjà resserré cette carte — 708 px → 568 px — en rognant des paddings.
     Ça ne suffisait pas : 568 px, c'est encore 70 % de l'écran, et le fondateur l'a dit droit :
     « il respecte rien ». On ne rogne plus, on applique la loi n°1 — COMPACTE AU REPOS, le
     détail dans l'état ÉTENDU au toucher. Les trois paliers et l'inclus passent derrière un
     chevron : ils ne coûtent plus une seule ligne tant que le doigt ne les demande pas.
     Préfixe `pal-` : un nom partagé est un périmètre (doctrine du Fil §5). */
  .pal-tete{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:2px 0 8px;}
  .pal-qui{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .pal-nom{font-size:var(--t-head);font-weight:600;line-height:1.15;}
  .pal-pitch{font-size:var(--t-foot);color:var(--ink-3);}
  /* LE CHIFFRE DOMINE (doctrine §7) : c'est lui qu'on lit en premier, pas son étiquette. */
  .pal-px{display:flex;flex-direction:column;align-items:flex-end;gap:0;flex:none;
    font-size:var(--t-title);font-weight:600;font-variant-numeric:tabular-nums;line-height:1.1;}
  .pal-px small{font-size:var(--t-cap);font-weight:400;color:var(--ink-3);}
  /* LE CHEVRON — même grammaire que `.drepli` du dossier, mais préfixée : `.drepli` n'existe
     que sous `.dossier`, et l'emprunter aurait fait vivre une classe dans deux périmètres. */
  .pal-plus{border-top:1px solid var(--edge-2);}
  .pal-plus > summary{list-style:none;cursor:pointer;display:flex;align-items:center;
    justify-content:space-between;gap:8px;padding:9px 0;min-height:44px;
    font-size:var(--t-foot);color:var(--ink-2);}
  .pal-plus > summary::-webkit-details-marker{display:none;}
  .pal-plus > summary::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);
    transition:transform .18s ease;}
  .pal-plus[open] > summary::after{transform:rotate(90deg);}
  .pal-plus:focus-within > summary{outline:2px solid var(--light);outline-offset:2px;}
  .pal-o-nom{font-weight:500;}
  .pal-o-pitch{display:block;font-size:var(--t-foot);color:var(--ink-2);}
  /* LA RÉSERVE — dite UNE fois, sous l'acte, jamais gravée sur l'objet (doctrine §7).
     La simplicité ne mange JAMAIS une réserve (PAROLE). */
  .pal-note{font-size:var(--t-cap);color:var(--ink-3);padding:6px 0 0;text-align:center;}
  /* v7 (fondateur, 13/10) — la carte qui VEND l'abonnement : l'équipe en quatre étiquettes, le rythme du paiement, Business
     recommandé. La couleur y est PERMISE (fondateur, 13/10) ; les teintes sont translucides pour tenir sur les deux thèmes. */
  .pal-reco{display:inline-block;margin-left:8px;padding:3px 8px;border-radius:999px;vertical-align:3px;
    font-size:var(--t-cap);font-weight:600;line-height:1;color:#FFFFFF;background:linear-gradient(135deg,#3B82F6,#8B5CF6);}
  .pal-eq{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px;}
  .pal-eq span{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:10px;
    font-size:var(--t-cap);font-weight:600;color:var(--ink);}
  .pal-eq svg{width:15px;height:15px;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
  .pal-eq-a{background:rgba(5,150,105,.13);}   .pal-eq-a svg{stroke:#059669;}
  .pal-eq-b{background:rgba(234,88,12,.13);}   .pal-eq-b svg{stroke:#EA580C;}
  .pal-eq-c{background:rgba(37,99,235,.13);}   .pal-eq-c svg{stroke:#2563EB;}
  .pal-eq-d{background:rgba(124,58,237,.13);}  .pal-eq-d svg{stroke:#7C3AED;}
  .pal-per{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:0 0 6px;}
  .card[data-famille="palier"] .pack-opt.pal-per-o{margin-top:0;flex-direction:column;align-items:flex-start;gap:2px;
    padding:9px 12px;position:relative;min-height:44px;}
  .pal-per-o .tk{position:absolute;top:10px;right:10px;}
  .pal-per-o .pal-o-pitch{font-size:var(--t-cap);}
  .pal-offert{color:#16A34A;font-weight:600;}   /* un vert lisible sur les deux thèmes : pas de variante sombre à tenir */
  /* le rappel « Tout X, plus : » — gris, plus petit, SANS puce (maquette fondateur 25/08) */
  .fact.rappel-palier::before{display:none;}
  /* le fait réel qui tombe sous l'étape en cours — la preuve du travail */
  .step{flex-wrap:wrap;}
  .stacq{flex-basis:100%;padding-left:25px;font-size:var(--t-cap);color:var(--ink-3);letter-spacing:-.005em;}
  /* ── LA SCÈNE DE SCAN : la photo seule à l'écran, le moment filmable ── */
  .scanscene{position:absolute;inset:0;z-index:9;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:16px;background:var(--screen);
    padding:22px 18px calc(env(safe-area-inset-bottom,0px) + 22px);}
  .scanscene[hidden]{display:none;}
  .ss-part{position:absolute;inset:0;z-index:0;pointer-events:none;}
  .ss-cadre{z-index:1;}
  .ss-photo{position:relative;width:min(56vw,240px);aspect-ratio:3/4;border-radius:22px;
    overflow:hidden;background:#0B1220;box-shadow:var(--sh-3);
    animation:ssnee .5s var(--e-main);}
  .ss-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;}
  .ss-photo .scan{position:absolute;left:0;right:0;height:34%;z-index:2;
    background:linear-gradient(transparent, color-mix(in srgb,var(--light-hi) 46%,transparent) 78%, color-mix(in srgb,var(--light-hi) 88%,transparent));
    box-shadow:0 6px 18px var(--glow);animation:scan 1.7s var(--ease) infinite;}
  .ss-eq{position:absolute;width:30px;height:30px;z-index:3;border:2.5px solid var(--light-hi);
    opacity:.92;filter:drop-shadow(0 0 7px var(--glow));}
  .ss-eq.tl{top:12px;left:12px;border-right:0;border-bottom:0;border-radius:10px 0 0 0;}
  .ss-eq.tr{top:12px;right:12px;border-left:0;border-bottom:0;border-radius:0 10px 0 0;}
  .ss-eq.bl{bottom:12px;left:12px;border-right:0;border-top:0;border-radius:0 0 0 10px;}
  .ss-eq.br{bottom:12px;right:12px;border-left:0;border-top:0;border-radius:0 0 10px 0;}
  .ss-nom{min-height:40px;text-align:center;font-size:var(--t-body);font-weight:500;color:var(--ink);
    letter-spacing:-.015em;}
  .ss-nom small{display:block;font-size:var(--t-cap);
    color:var(--ink-3);margin-bottom:4px;}
  .ss-steps{width:min(80vw,330px);display:flex;flex-direction:column;z-index:1;}
  @keyframes ssnee{from{opacity:0;transform:scale(1.05);}to{opacity:1;transform:scale(1);}}
  .scanscene.fin{animation:ssfin .5s var(--e-main) forwards;}
  @keyframes ssfin{to{opacity:0;transform:scale(.9) translateY(26px);}}
  /* la SIGNATURE au verdict : le vrai chrono, jamais un chiffre d'ambiance */
  .ss-sign{display:block;margin-top:7px;font-size:var(--t-cap);
    color:var(--ink-2);opacity:0;animation:parait .4s var(--e-main) forwards;}
  @media (prefers-reduced-motion:reduce){ .ss-photo,.scanscene.fin{animation:none;} .scanscene.fin{opacity:0;} .ss-part{display:none;} }

  /* le squelette de la fiche : elle s'ouvre TOUT DE SUITE, le reste arrive */
  .sq{height:13px;border-radius:7px;margin:9px 0;
    background:linear-gradient(90deg,var(--pane-2),var(--pane),var(--pane-2));
    background-size:200% 100%;animation:sq 1.1s linear infinite;}
  @keyframes sq{to{background-position:-200% 0;}}
  @media (prefers-reduced-motion:reduce){ .step.now i,.pdet,.sq{animation:none;} }
  body.direct .threadwrap{perspective:none;}
  body.direct .card{margin-top:0;}
  body.direct .r{margin-top:10px;}

  /* le témoin d'entête : il dit combien tu en as gardé, sans jamais interpoler un nombre */
  /* le ◆ est un BOUTON (il ouvre Ton dossier) : cible réelle ≥44pt par un vrai
     padding compensé en marge — un span de 19px de haut se ratait au doigt
     (mesuré 24/08, et un ::after se faisait rogner par le header). */
  .apphead .tenu{background:none;border:0;font:inherit;color:inherit;cursor:pointer;
    padding:13px 12px;margin:-13px -12px;}
  .apphead .tenu{display:none;align-items:center;gap:5px;font-size:var(--t-cap);
    color:var(--light);padding-left:10px;}   /* plus de margin-left:auto : la position a le bord */
  .apphead .tenu.on{display:flex;}

  /* ── LA PRÉVISUALISATION D'ISSUE ──
     Avant que tu lâches, le monde montre ce qui va arriver. Jamais de texte permanent :
     l'affordance n'existe que tant que l'intention est claire, et disparaît avec elle. */
  .bord-ecart{position:absolute;left:0;top:0;bottom:0;width:54px;z-index:6;pointer-events:none;
    opacity:0;transform:translateX(-16px);
    background:linear-gradient(90deg, color-mix(in srgb,var(--warm) 26%,transparent), transparent);
    border-left:2px solid var(--warm);
    transition:opacity .16s linear, transform .22s var(--e-main);}
  :root[data-vise="ecarter"] .bord-ecart{opacity:1;transform:translateX(0);}
  /* en descendant, la PLACE de la carte se réveille : elle sait où elle va revenir */
  .empreinte{outline:1px dashed transparent;outline-offset:3px;border-radius:22px;
    transition:outline-color .2s linear;}
  :root[data-vise="revenir"] .empreinte{outline-color:color-mix(in srgb,var(--light) 55%,transparent);}
  /* en montant, l'horizon s'ouvre : le voile se lève AVANT le relâchement */
  :root[data-vise="ouvrir"] .scrim{opacity:.55;}

  /* ── LA BARRE D'ANNULATION ──
     Un écartement doit être PROUVABLEMENT réversible : l'objet est conservé dans le
     document, et le retour est offert sans qu'on ait à le chercher. */
  .annuler{position:absolute;left:14px;right:14px;bottom:8px;z-index:8;
    display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:18px;
    background:color-mix(in srgb,var(--warm) 14%,var(--screen));
    border:1px solid color-mix(in srgb,var(--warm) 42%,transparent);
    color:var(--ink);font-size:var(--t-foot);
    transform:translateY(78px);opacity:0;pointer-events:none;
    transition:transform .26s var(--e-main), opacity .26s var(--e-main);}
  .annuler.on{transform:translateY(0);opacity:1;pointer-events:auto;}
  .annuler button{margin-left:auto;border:0;background:none;padding:6px 4px;min-height:44px;min-width:44px;
    color:var(--warm);font-family:var(--sans);font-size:var(--t-foot);font-weight:500;cursor:pointer;}
  .annuler button:focus-visible{outline:2px solid var(--warm);outline-offset:2px;border-radius:8px;}
  .r.ecartee{display:none;}

  /* le casier devient PERSISTANT dès qu'il contient quelque chose : ce qui est gardé
     reste visible. C'est le premier pas vers un espace du temps long. */
  /* état PERSISTANT : il s'applique sans transition — une transition d'entrée se
     faisait recréer à chaque frame (figée à t=0) et le casier restait invisible. */
  .casier.plein{transform:translateY(0);opacity:1;pointer-events:auto;transition:none;}
  /* le casier SE PRÉSENTE pour un dépôt (vol de carte) puis repart — transitoire */
  .casier.montre{transform:translateY(0);opacity:1;pointer-events:auto;}
  /* 🔴 le casier persistant vit AU-DESSUS du compositeur, jamais dessus — posé en
     bas il recouvrait la barre d'écriture (« je ne peux même pas écrire »). Compact.
     La barre d'annulation remonte pareil. */
  body.direct .casier{bottom:calc(env(safe-area-inset-bottom,0px) + 70px);height:44px;
    padding:0 12px;font-size:var(--t-cap);border-radius:14px;}
  body.direct .casier svg{width:15px;height:15px;}
  body.direct .annuler{bottom:calc(env(safe-area-inset-bottom,0px) + 70px);}
  .casier .mini{display:flex;gap:4px;margin-left:8px;}
  .casier .mini i{width:14px;height:18px;border-radius:3px;display:block;
    background:linear-gradient(160deg,color-mix(in srgb,var(--light) 46%,var(--screen)),var(--screen));
    border:1px solid color-mix(in srgb,var(--light) 40%,transparent);}
  /* l'agent se TAIT pendant que tu examines : sa présence baisse, sans un mot */

  /* pendant un geste, le fil s'efface : le verdict n'est pas défendu par une
     exception, il domine PARCE QUE la règle le laisse seul allumé. */
  :root[data-main="prise"] .thread,:root[data-main="survol"] .thread{opacity:.55;
    transition:opacity .22s var(--e-main);}
  :root[data-main="prise"] .v.big,:root[data-main="survol"] .v.big{text-shadow:none;}

  /* ═══ L'ARGUMENTAIRE ═══ */
  .argu{flex:1 1 320px;min-width:290px;max-width:410px;display:flex;flex-direction:column;gap:0;}
  /* une bande qui suit la scène : le temps en cours vient toujours au centre.
     Sans ça, les temps 05 à 13 tombent sous la ligne de flottaison et la synchro ne se voit pas. */
  .reel{position:relative;overflow:hidden;margin-top:6px;
    height:min(calc(var(--pw) * 1.94), 68vh);
    -webkit-mask-image:linear-gradient(transparent 0, #000 10%, #000 90%, transparent 100%);
    mask-image:linear-gradient(transparent 0, #000 10%, #000 90%, transparent 100%);}
  .track{position:relative;transition:transform .8s var(--ease);will-change:transform;}
  .acte{font-size:var(--t-cap);color:var(--light);
    padding:24px 0 6px;display:flex;align-items:center;gap:10px;}
  .acte:first-of-type{padding-top:10px;}
  .acte::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--light) 40%,transparent),transparent);}
  .beat{padding:13px 0;border-top:1px solid var(--edge-2);display:flex;gap:14px;align-items:flex-start;
    opacity:.36;transition:opacity .5s ease,transform .5s var(--ease);}
  .beat.live{opacity:1;transform:translateX(3px);}
  .beat .n{font-size:12px;color:var(--ink-3);flex:0 0 24px;padding-top:3px;
    transition:color .5s ease,text-shadow .5s ease;}
  .beat.live .n{color:var(--light);text-shadow:0 0 14px var(--glow);}
  .beat .t b{display:block;font-size:14px;font-weight:500;}
  .beat .t span{font-size:14px;color:var(--ink-2);}

  .replay{align-self:flex-start;margin-top:20px;padding:12px 20px;border-radius:18px;min-height:44px;
    border:1px solid var(--edge);background:var(--pane);color:var(--ink);font-family:var(--sans);
    font-size:var(--t-foot);cursor:pointer;backdrop-filter:blur(12px);transition:border-color .3s ease,box-shadow .3s ease;}
  .replay:hover{border-color:color-mix(in srgb,var(--light) 55%,transparent);box-shadow:0 0 24px -10px var(--glow);}
  .replay:focus-visible{outline:2px solid var(--light);outline-offset:3px;}

  .note{color:var(--ink-3);font-size:14px;max-width:66ch;border-top:1px solid var(--edge-2);padding-top:24px;}
  .note strong{color:var(--ink-2);font-weight:500;}

  @media (max-width:640px){
    .page{padding:40px 16px 84px;gap:36px;}
    .stagegrid{gap:40px 0;}
    .floor{height:44vh;}
  }

  /* ═══ LES PILULES — ta parole, pré-écrite. Niveau 1 de l'échelle des boutons :
     ça n'engage que le travail de Rabbit. Matière du compositeur, jamais du cyan
     plein — et au tap, la pilule DEVIENT ta bulle : même naissance, même main. ═══ */
  .pills{align-self:flex-end;display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:10px;}
  /* ═══ BOUTONS STYLE A « LUMINEUX » (fondateur, planche boutons) — la famille exacte ═══ */
  .pill{min-height:38px;padding:0 16px;border-radius:19px;border:1px solid var(--edge);
    background:var(--pane);color:var(--ink);font-family:var(--sans);font-size:var(--t-foot);
    font-weight:500;cursor:pointer;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);}
  .pill:hover{border-color:color-mix(in srgb,var(--light) 55%,transparent);}
  .pill:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  /* les options non choisies se FANENT (charte, chorégraphie) : visibles — le journal
     se relit — mais inertes (disabled : hors tap ET hors tabulation), à l'opacité
     des inertes du fichier (.btn-n[disabled]) */
  .pill[disabled]{opacity:.45;cursor:default;}
  .pill[disabled]:hover{border-color:var(--edge);}

  /* Niveau 2 de l'échelle : LE BOUTON PLEIN — il OUVRE la demande, il n'encaisse jamais.
     Une seule fois par verdict, sous le ticket ; le paiement vit dans le tunnel React. */
  .cta-plein{display:block;width:100%;margin-top:10px;min-height:50px;padding:0 18px;
    border-radius:15px;border:0;
    background:var(--btn-plein-bg);color:var(--btn-plein-ink);
    font-family:var(--sans);font-size:var(--t-body);font-weight:600;letter-spacing:-.01em;cursor:pointer;
    box-shadow:0 0 0 1px var(--glow), 0 14px 34px -14px var(--glow), 0 1px 0 rgba(255,255,255,.5) inset;}
  .cta-plein:disabled{opacity:.55;cursor:default;}
  .cta-plein:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .cta-plein:active{transform:translateY(1px);filter:brightness(.96);}
  /* l'état PRESSÉ, partout pareil (charte loi 4) — le doigt sent la prise ;
     les prises de drag (.garder/.dprise) gardent leur propre grammaire de geste */
  button:not([disabled]):not(.garder):not(.dprise):active,
  [role="button"]:not([aria-disabled="true"]):active{transform:translateY(1px);}
  /* LE VERT reste RÉSERVÉ à l'acte de payer (le bouton qui part vers la banque),
     montant obligatoire dans le libellé — jamais un autre usage du vert. */
  .cta-payer{display:block;width:100%;margin-top:10px;min-height:52px;padding:0 18px;
    border-radius:15px;border:0;
    background:var(--btn-argent-bg);color:var(--btn-argent-ink);
    font-family:var(--sans);font-size:var(--t-body);font-weight:600;cursor:pointer;
    box-shadow:var(--btn-argent-halo);}
  .cta-payer:disabled{opacity:.55;cursor:default;}
  .cta-payer:focus-visible{outline:2px solid var(--btn-argent-bg);outline-offset:2px;}
  .cta-payer:active{transform:translateY(1px);filter:brightness(.96);}

  /* le compositeur devient réel */
  /* le focus du champ se VOIT (audit : outline:none sans remplacement) — l'anneau
     maison, sur le champ seul, jamais coupé par le rayon du composeur */
  .composer input.field{font-family:var(--sans);color:var(--ink);outline:none;}
  .composer input.field:focus-visible{outline:2px solid var(--light);outline-offset:-2px;border-radius:12px;}
  /* la rangée candidate armée est focusable (tabIndex posé par armer) : son anneau */
  .card.rcand:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .composer input.field::placeholder{color:var(--ink-3);}
  .composer .cam,.composer .plus,.composer .send{cursor:pointer;font:inherit;}
  .composer .send{border:0;}

  /* ═══ LA FICHE — l'objet ouvert : le monde se tait (posture OBJET, examen) ═══ */
  .fiche,.demande{position:absolute;inset:0;z-index:8;display:flex;flex-direction:column;gap:2px;
    background:var(--screen);padding:12px 16px calc(env(safe-area-inset-bottom,0px) + 14px);
    overflow-y:auto;overscroll-behavior:contain;}
  .fiche[hidden],.demande[hidden]{display:none;}
  .demande{padding-top:calc(env(safe-area-inset-top,0px) + 12px);}   /* signet : sous l'heure (12/10) */
  .barrex{display:flex;align-items:center;gap:10px;padding:2px 0 6px;flex:0 0 auto;}
  .fiche h2{font-size:var(--t-body);font-weight:600;letter-spacing:-.02em;margin:6px 2px 2px;line-height:1.3;}
  .fiche .gal,.fiche .card,.demande .card,.fiche .btn,.demande .btn{flex:0 0 auto;}

  /* ═══ LA GRAMMAIRE DES CARTES (13/08, resserrée le soir) ═══
     candidat = card image légère : TAP = fiche · balayage gauche = suivant (le libellé
     apparaît PENDANT le geste) · maintien-soulever = raccourci secondaire ·
     UNE seule commande explicite : « C'est celui-là ✓ » (la rétention, qui ouvre les
     actes). Le « garder pour plus tard » vit dans le GESTE (maintien → casier, menu
     de l'arête) et dans la FICHE (bouton secondaire) — jamais en doublon sur la carte.
     retenu = carte ANCRÉE (cycle configured : keep/dismiss/lift tombent par le CYCLE).
     verdict = objet DURABLE : ni lancé, ni déplacé, ni écarté. */
  /* le libellé d'issue : il n'existe que pendant le geste (porté par data-vise) */
  .bord-ecart span{position:absolute;left:12px;top:50%;transform:translateY(-50%) rotate(180deg);
    writing-mode:vertical-rl;white-space:nowrap;font-size:var(--t-cap);
    color:var(--warm);}
  /* les petites commandes de la carte candidate — jamais un plein */
  .cmds{display:flex;gap:8px;margin-top:10px;}
  .cmd{flex:1;min-height:34px;padding:0 13px;border-radius:11px;border:1px solid rgba(160,205,240,.35);
    background:rgba(130,175,210,.10);color:var(--ink);font-family:var(--sans);font-size:var(--t-cap);
    font-weight:600;cursor:pointer;-webkit-tap-highlight-color:transparent;}
  .cmd:disabled{opacity:.6;cursor:default;}
  .cmd:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .cmd-feedback{display:block;margin-top:8px;color:var(--light);font-family:var(--sans);
    font-size:var(--t-cap);line-height:1.35;}
  /* la marque du produit retenu */
  .retenu{display:flex;align-items:center;gap:6px;font-size:var(--t-cap);
    color:var(--light);}
  /* la carte retenue : ancrée — l'arête et les gestes tombent, le défilement revient */
  .card[data-kind="candidate"][data-cycle="configured"]{touch-action:pan-y;cursor:default;}
  .card[data-kind="candidate"][data-cycle="configured"] .garder{display:none;}
  /* le verdict durable : armé candidate pour le CONTRAT (keep au bouton), mais
     AUCUNE affordance de prise — il ne ressemble pas à ce qu'on lance */
  /* ⚠️ le raccourci `border:` efface haut ET bas — d'où la redéclaration des deux :
     elle éteint les flancs cyan et la bande de prise de .card[data-kind="candidate"].
     La TRANCHE suit la carte (3px depuis le 24/08) et l'ombre n'est plus recopiée :
     elle s'hérite, sinon cette règle fige l'épaisseur d'avant chaque fois que la
     carte maigrit — c'est ce qui venait d'arriver (audit adversarial, 24/08). */
  .card[data-kind="candidate"][data-verdict]{touch-action:auto;cursor:default;
    border:1px solid var(--carte-edge);border-top:1.5px solid var(--carte-biseau);
    border-bottom:3px solid var(--carte-tranche);background-image:var(--carte-bg);}
  /* le bouton secondaire du verdict : il garde, il n'encaisse jamais */
  .cta-sec{display:block;width:100%;margin-top:8px;min-height:44px;padding:0 18px;
    border-radius:14px;border:1px solid var(--edge);background:transparent;color:var(--ink-2);
    font-family:var(--sans);font-size:var(--t-foot);font-weight:500;cursor:pointer;}
  .cta-sec:disabled{opacity:.6;cursor:default;}
  .cta-sec:focus-visible{outline:2px solid var(--light);outline-offset:2px;}

  /* ═══ LA COMMANDE DANS LE FIL (tranche 2) : options & paliers — de petites
     surfaces à cocher. Jamais de vert (F3) : le cyan dit la sélection. ═══ */
  .pack-opt{display:flex;align-items:flex-start;gap:10px;width:100%;text-align:left;
    border:1px solid var(--edge);background:var(--pane-2);border-radius:14px;
    padding:10px 12px;margin-top:8px;color:var(--ink);cursor:pointer;
    font-family:var(--sans);font-size:var(--t-foot);-webkit-tap-highlight-color:transparent;}
  /* options = CASES À COCHER (cumulables — audit 14/08 : les ronds se lisaient
     « choix exclusif ») ; les paliers, eux, gardent le rond (un seul choix) */
  .pack-opt .tk{width:18px;height:18px;border-radius:6px;flex:0 0 auto;margin-top:1px;
    display:flex;align-items:center;justify-content:center;font-size:var(--t-cap);color:transparent;
    box-shadow:inset 0 0 0 1.5px var(--edge);}
  .pack-opt.palier .tk{border-radius:50%;}
  .pack-opt[aria-pressed="true"]{border-color:color-mix(in srgb,var(--light) 55%,var(--edge));
    background:color-mix(in srgb,var(--light) 10%,var(--pane-2));}
  .pack-opt[aria-pressed="true"] .tk{background:var(--light);color:var(--screen);box-shadow:none;}
  .pack-opt .pv{margin-left:auto;font-size:var(--t-cap);white-space:nowrap;font-variant-numeric:tabular-nums;
    color:var(--ink-2);padding-top:1px;}
  .pack-opt:focus-visible{outline:2px solid var(--light);outline-offset:2px;}

  /* ═══ LE CARROUSEL DE CANDIDATS (fondateur, planche : « écarté 2 ») — la rangée
     glissable : la courante ~84 %, LE SUIVANT DÉPASSE du bord droit (l'affordance),
     points de position dessous. On glisse, on REVIENT — rien ne disparaît. ═══ */
  .deckwrap{position:relative;overflow:hidden;border-radius:22px;margin-top:9px;}
  .deck{display:flex;align-items:stretch;transition:transform .4s var(--e-main);}
  .deck.drag{transition:none;}
  .deck-slot{flex:0 0 84%;margin-right:4%;min-width:0;display:flex;}
  .deck-slot.ecartee{display:none;}
  .deck-slot.rangee{display:none;}   /* gardée : elle vit dans Tes recherches, plus dans la rangée */
  /* LE RANGEMENT SE VOIT (fondateur, 17/08 : « qu'on comprenne qu'elle se range ») :
     la carte RÉTRÉCIT vers le casier (bas-gauche), puis sa place se referme.
     Transitions posées PAR la classe d'animation — jamais sur .card nue, le drag
     pilote transform en direct et une transition permanente le casserait. */
  .card.range-mini{transition:transform .55s var(--e-pouce), opacity .5s var(--e-main);
    transform:scale(.08);transform-origin:8% 96%;opacity:0;pointer-events:none;}
  .deck-slot.range-ferme{flex-basis:0%;margin-right:0;overflow:hidden;
    transition:flex-basis .38s var(--e-main), margin-right .38s var(--e-main);}
  .card.gardee-mini{padding:10px 14px;opacity:.85;}
  .card.gardee-mini > *:not(.lab){display:none !important;}
  .card.gardee-mini .lab::after{content:' · gardée ✓';color:var(--ink-2);}
  .deck-slot .card{margin-top:0;width:100%;}
  .points{display:flex;gap:6px;justify-content:center;margin-top:8px;}
  /* `display:flex` est une règle AUTEUR : elle bat `[hidden]{display:none}` de la feuille
     du navigateur, quelle que soit la spécificité. Sans cette ligne, `points.hidden = true`
     ne cache rien et laisse une bande vide sous un objet d'une seule page. Le dépôt a déjà
     payé ce piège ailleurs (`.evcorps .evbaisse[hidden]`). (Revue 14/09.) */
  .points[hidden]{display:none;}
  .points i{width:6px;height:6px;border-radius:50%;background:var(--edge);}
  .points i.on{background:var(--light);box-shadow:0 0 8px var(--glow);}

  /* ── LA PÉDAGOGIE D'ARRIVÉE (fondateur 13/08) : « on ne voit même pas qu'on
     sélectionne une carte ». Quand une candidate ARRIVE : un halo de lumière BREF
     autour d'elle (one-shot, jamais une boucle — loi DA), et les 2 premières fois
     seulement, un chevron blanc discret au bord gauche + UNE micro-oscillation
     horizontale qui montre qu'elle se déplace. Les classes ne sont posées que par
     le JS, jamais en reduced-motion. ── */
  .r.pedago-halo{position:relative;}
  .r.pedago-halo>*{position:relative;z-index:1;}
  .r.pedago-halo::before{content:"";position:absolute;inset:-14px -6px;z-index:0;
    border-radius:26px;pointer-events:none;
    background:radial-gradient(62% 78% at 54% 50%, var(--glow), transparent 68%);
    opacity:0;animation:halo-nee 1.2s var(--e-main) .8s 1 both;}
  @keyframes halo-nee{0%{opacity:0;transform:scale(.9);}30%{opacity:.9;}100%{opacity:0;transform:scale(1.08);}}
  /* l'oscillation : ~2 allers, 600 ms, UNE fois — « elle bouge », pas « elle danse » */
  .card.osc{animation:osc-nee .6s var(--e-main) .9s 1;}
  @keyframes osc-nee{0%,100%{transform:translateX(0);}22%{transform:translateX(-7px);}
    55%{transform:translateX(5px);}82%{transform:translateX(-3px);}}
  /* le chevron blanc : il vit au bord gauche, pointe le sens du geste, et meurt seul */
  .pedago-fleche{position:absolute;left:5px;bottom:12px;z-index:3;display:flex;
    color:#fff;opacity:0;pointer-events:none;filter:drop-shadow(0 0 6px var(--glow));
    animation:fleche-nee 2.4s ease 1s 1 both;}
  @keyframes fleche-nee{0%{opacity:0;transform:translateX(0);}12%{opacity:.92;}
    32%{opacity:.92;transform:translateX(-5px);}52%{opacity:.92;transform:translateX(0);}
    72%{opacity:.92;transform:translateX(-5px);}100%{opacity:0;transform:translateX(0);}}
  /* reduced-motion : rien ne bouge — l'indice devient un libellé texte, une fois */
  .pedago-note{display:block;margin:6px 2px 0 22px;font-size:var(--t-cap);color:var(--ink-3);}

  /* ═══ LA FICHE E-SHOP (fondateur 13/08) : « une VRAIE fiche produit » ═══
     Galerie principale HAUTE + vignettes cliquables · ligne prix proéminente ·
     variantes nommées qui changent l'image (jamais le prix : on ne l'a pas par
     variante) · caractéristiques · preuves avec leur nature · CTA sticky. */
  /* la photo vit sur le gris perle de la maquette (--vg) ; la nuit, bleu d'encre */
  .egal-main{position:relative;height:172px;border-radius:13px;overflow:hidden;margin:0;
    background:var(--pane-2);border:1px solid var(--edge-2);box-shadow:var(--sh-1);}
  :root[data-theme="dark"] .egal-main{background:var(--pane-2);}
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]) .egal-main{background:var(--pane-2);}
  }
  .egal-main .pts{position:absolute;bottom:9px;left:50%;transform:translateX(-50%);display:flex;gap:5px;}
  .egal-main .pts i{width:5px;height:5px;border-radius:50%;background:var(--edge);}
  .egal-main .pts i.on{background:var(--light);}
  .egal-main img{width:100%;height:100%;object-fit:contain;display:block;}
  .egal-thumbs{display:flex;gap:8px;overflow-x:auto;padding:8px 2px 2px;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;}
  .egal-thumbs::-webkit-scrollbar{display:none;}
  .egal-th{flex:0 0 auto;width:56px;height:56px;border-radius:12px;overflow:hidden;padding:0;
    background:#0B1220;border:1px solid var(--edge-2);cursor:pointer;}
  .egal-th img{width:100%;height:100%;object-fit:contain;display:block;}
  .egal-th[aria-current="true"]{border-color:var(--light);box-shadow:0 0 10px -3px var(--glow);}
  .egal-th:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
  .eprix{display:flex;align-items:baseline;gap:8px;margin:0 2px 3px;flex-wrap:wrap;}
  /* 91e : la vedette LIVRÉE se décompose au toucher (maquette §2) — et une ligne
     qui se touche fait 44 pt (lot 4) : le padding porte la cible, pas le texte */
  .eprix.eprixd{cursor:pointer;min-height:44px;align-items:center;}
  /* le chevron est du DÉCOR : il vit en CSS, jamais dans une chaîne de parole */
  .eprixd .chev{display:inline-block;font-size:var(--t-cap);color:var(--ink-3);
    transition:transform .3s var(--e-main);}
  .eprixd .chev::after{content:'❯';}
  .eprixd.ouverte .chev{transform:rotate(90deg);}
  .eprixd:focus-visible{outline:2px solid var(--light);outline-offset:2px;border-radius:8px;}
  .fdecomp{margin:0 2px 10px;}
  .eprix .ev{font-variant-numeric:tabular-nums;font-size:var(--t-title);font-weight:600;letter-spacing:var(--t-title-ls);
    color:var(--ink);}
  .eprix .eu{font-size:var(--t-foot);color:var(--ink-2);}
  .eprix .eu.warm{color:var(--warm);}
  /* le sélecteur de variantes : une vignette, son nom (name_fr), l'élue s'allume */
  .evar-btn{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:4px;
    width:64px;padding:0;border:0;background:none;cursor:pointer;font-family:var(--sans);}
  .evar-btn .im{width:56px;height:56px;border-radius:12px;overflow:hidden;display:block;
    background:#0B1220;border:1px solid var(--edge-2);}
  .evar-btn img{width:100%;height:100%;object-fit:contain;display:block;}
  .evar-btn .nm{font-size:var(--t-cap);color:var(--ink-2);max-width:64px;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap;}
  .evar-btn[aria-pressed="true"] .im{border-color:var(--light);box-shadow:0 0 10px -3px var(--glow);}
  .evar-btn:focus-visible{outline:2px solid var(--light);outline-offset:2px;border-radius:12px;}
  /* le pied sticky : les trois sorties toujours sous le pouce — surface OPAQUE
     (pas de verre sur une surface à lire), il consomme le padding du conteneur */
  .fpied{position:sticky;bottom:0;z-index:3;
    margin:auto -11px 0;
    padding:7px 11px 9px;
    border-radius:0 0 16px 16px;
    background:color-mix(in srgb,var(--light) 10%, var(--pane-2));border-top:1px solid var(--edge-2);}
  :root[data-theme="dark"] .fpied{background:color-mix(in srgb,var(--light) 12%, var(--pane-2));}
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]) .fpied{background:color-mix(in srgb,var(--light) 12%, var(--pane-2));}
  }
  .fpied .btn{margin-top:0;}
  .fpied .rangs{display:flex;gap:8px;margin-top:8px;}
  .fpied .rangs>*{flex:1;margin-top:0;}

  /* ── L'INTERRUPTEUR UNIQUE ──
     L'état de l'app continue de teindre la lumière (c'est une information, pas un
     mouvement) ; tout ce qui bouge s'arrête. */
  @media (prefers-reduced-motion:reduce){
    .cloud,.horizon,#dust,.sheen{display:none;}
    .floor,.holder::before{animation:none;}
    .obj,.obj *,.fil-recule{
      animation:none!important;opacity:1!important;transform:none!important;
      filter:none!important;clip-path:none!important;}
    .obj *::before,.obj *::after{animation:none!important;}
    .tranche::before,.tranche::after{display:none!important;}
    .u,.seen,.when,.rtxt span.w{animation:none!important;}
    .r.ecarte{animation:none!important;}
    .reel{height:auto;-webkit-mask-image:none;mask-image:none;}
    .track{transform:none!important;transition:none;}
    .beat{opacity:1;}
    .cur,.typing,.snap .scan{display:none;}
    /* la main : l'ACTE reste (le bouton et son arête), le TRAJET tombe.
       `.obj *{opacity:1!important}` allumerait sinon la lumière de contact en permanence. */
    .contact{display:none!important;}
    /* la pédagogie d'arrivée : le JS ne pose pas ces classes en reduced-motion,
       mais la ceinture ne coûte rien — rien ne bouge, rien ne s'allume */
    .r.pedago-halo::before{display:none!important;}
    .card.osc{animation:none!important;}
    .pedago-fleche{display:none!important;}
    .deck{transition:none;}
    /* le casier RESTE : c'est désormais une surface permanente avec un chemin
       sans geste (le bouton « Garder ») — le cacher volerait le compteur. */
  }

  /* la pile de vignettes de la couverture Ultra (maquette §8) */
  .pile-u{display:flex;flex:none;align-items:center;}
  .pile-u img{width:38px;height:38px;border-radius:10px;border:2px solid #fff;
    background:var(--pane-2);object-fit:contain;box-shadow:var(--sh-1);}
  .pile-u img+img{margin-left:-14px;}
  /* le badge d'état d'un ticket du dossier, à droite */
  .dtik .tik-b{margin-left:auto;flex:none;border-color:color-mix(in srgb,var(--fam-commande) 55%, transparent);color:var(--fam-commande);}
  .dtik .dvg img{width:100%;height:100%;object-fit:contain;display:block;border-radius:inherit;}
  button.dtik-go .tik-b{margin-left:auto;}
  button.dtik-go .chev{margin-left:6px;}

  /* le bandeau d'un ticket : titre à gauche, badge d'état à droite */
  .dhead-t{display:flex;align-items:center;justify-content:space-between;gap:8px;}
  .dhead-t .lab{margin:0;}

  /* « Modifier » : un lien discret sous le bouton d'argent — jamais un 2e pavé */
  .lien-sec{background:none;border:0;min-height:44px;padding:2px 0 0;cursor:pointer;
    font:inherit;font-size:var(--t-cap);color:var(--ink-2);text-decoration:underline;
    text-underline-offset:3px;align-self:center;}

  /* la feuille : les demi-champs vont par deux, comme la maquette */
  .livf{display:flex;flex-wrap:wrap;gap:9px;}
  .livf .livg{flex:1 1 100%;}
  .livf .livg.demi{flex:1 1 calc(50% - 5px);min-width:120px;}
  .livf .livn{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);}

  /* ══ 91e soir — LA RESSEMBLANCE (constat fondateur : « ça ne ressemble pas ») ══ */
  /* le bloc des choix est À PLAT — la maquette montre selects + stepper, pas un dépliant */
  /* NU sur la fiche (maquette : pas de sous-carte) — selects empilés pleine largeur */
  .evplat{margin-top:4px;background:none;border:0;box-shadow:none;padding:0;border-radius:0;overflow:visible;}
  .evplat .evcorps{display:flex;flex-direction:column;gap:7px;}
  /* auto-fit : deux colonnes quand la place y est, une seule sinon — le libellé
     d'une option ne se tronque plus à 375 (audit 01/09 : scrollWidth 157 > 147) */
  .evplat .evax{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:7px;}
  .evplat .evcol{display:flex;flex-direction:column;gap:4px;}
  .evplat .evet{font-size:var(--t-cap);color:var(--ink-2);}
  .evplat .evas{min-height:44px;width:100%;border-radius:11px;border:1px solid var(--edge);
    background:var(--pane);color:var(--ink);font:inherit;font-size:var(--t-body);padding:0 12px;
    -webkit-appearance:none;appearance:none;
    background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
    background-position:calc(100% - 19px) 50%,calc(100% - 14px) 50%;background-size:5px 5px;background-repeat:no-repeat;}
  /* le stepper de la maquette : UN cadre, − · valeur · + dedans, la baisse à droite */
  .evplat .evqte{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
  .evplat .evqte .evq{width:46px;min-height:44px;border:0;background:transparent;font-size:var(--t-title);
    color:var(--ink);cursor:pointer;}
  .evplat .evqte .evqi{min-width:44px;min-height:44px;width:52px;text-align:center;font-size:var(--t-body);font-weight:600;
    border:0;background:transparent;color:var(--ink);font-variant-numeric:tabular-nums;}
  .evplat .evstep{display:flex;align-items:center;border:1px solid var(--edge);border-radius:12px;
    background:var(--pane);}
  .evplat .evpu{font-size:var(--t-cap);color:var(--ink-2);}
  .evplat .evql{font-size:var(--t-cap);color:var(--ink-2);}
  .fact.evbaisse{color:var(--fam-argent);}
  :root[data-theme="dark"] .fact.evbaisse{color:var(--fam-argent);}
  @media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .fact.evbaisse{color:var(--fam-argent);}}
  /* LA FICHE EST UNE CARTE À CONTOURS (fondateur 31/08 : « on voit bien que c'est
     une fiche ») : le viewport garde le CIEL, la carte .fcarte porte le verre teinté
     résultat par .dobj.teinte — une seule vérité de teinte, jour et nuit. */
  /* 12/10 — en SIGNET (écran d'accueil), la page passe sous l'heure : la fiche, absolue à top:0, ignorait le padding
     de .screen.plein — la flèche et la croix étaient sous la barre d'état (« on n'arrive pas à revenir en arrière »).
     Dans Safari l'encart vaut 0 : rien ne change. Garde : signet-zone-sure. */
  .fiche{background:var(--screen);padding:env(safe-area-inset-top,0px) 8px calc(env(safe-area-inset-bottom,0px) + 10px);}
  /* en signet, le pied collant s'arrêtait au padding du conteneur : 44 px au-dessus du bas, le contenu défilant
     dessous (« une couche qui sépare »). Le pied descend jusqu'au bord et porte lui-même la zone du geste. */
  @media (display-mode: standalone){
    .fiche{padding-bottom:0;}
    .fiche[data-vendre="boutique"][data-poussee]{padding-bottom:env(safe-area-inset-bottom,0px);}   /* sans pied, le contenu garde la zone du geste */
    .fpied{padding-bottom:calc(env(safe-area-inset-bottom,0px) + 9px);}
  }
  .fcarte{border-radius:18px;margin:2px 0 0;padding:9px 11px 0;
    overflow:visible;}   /* .dobj pose hidden — il tuerait le sticky du pied */
  .fcarte .egal-main{margin:0 0 2px;}

  /* les replis de la fiche (maquette .repli) : lignes nues, filet, chevron qui tourne */
  details.fcarac{background:none;border:0;box-shadow:none;border-radius:0;overflow:visible;
    padding:9px 0 0;margin-top:4px;border-top:1px solid var(--edge-2);}
  details.fcarac summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;
    align-items:center;font-size:var(--t-body);font-weight:600;color:var(--ink);padding:2px 0;margin:0;}
  details.fcarac summary::-webkit-details-marker{display:none;}
  details.fcarac summary::after{content:'❯';font-size:var(--t-cap);color:var(--ink-3);
    transition:transform .3s var(--e-main);}
  details.fcarac[open] summary::after{transform:rotate(90deg);}
  details.fcarac>*:not(summary){margin-top:8px;}
  /* le retour de la fiche : la flèche nue de la maquette */
  .fiche .retour{width:44px;height:44px;border-radius:11px;border:0;background:transparent;
    font-size:var(--t-title);color:var(--ink-2);box-shadow:none;}

  /* le bandeau de la feuille de commande : la photo, « Ta commande », le nom */
  .feuille-c .fx-tete{width:100%;padding:2px 0;display:flex;align-items:center;gap:9px;}
  .feuille-c .fx-tete .dcc{flex:1;min-width:0;}
  /* le CTA éteint : le style du disabled, le tap VIVANT (la réaction du manque) */
  .cta-plein.eteint{opacity:.55;}
  /* les CASES de la nuit : OPAQUES et teintées — plus un voile translucide
     (fondateur 31/08 : « des objets fixes, pas transparents ») */
  @media (prefers-color-scheme:dark){
  }

/* ══════════════════════════════════════════════════════════════════════════════
   COUCHE VISUELLE DU 05/09 — décisions fondateur (sept réponses) : un seul objet
   d'un écran à l'autre. Opaque (plus de verre sur les objets, le ciel reste derrière),
   UNE largeur (la colonne, marges 16), TROIS rayons, TROIS familles (l'argent en vert,
   l'estimé ou à vérifier en ambre, l'entrepôt en kraft — le reste neutre), UN bouton
   plein aplat, le vert réservé à l'acte de payer. Cette couche vient en dernier et
   redéfinit les jetons ; les règles au-dessus restent le squelette. Retour en arrière =
   retirer ce bloc. Contrastes calculés : blanc sur #12719E 5,41 · sur #0F7A55 5,34 ·
   #8A5A0C sur blanc 5,92 · #1F7A4D 5,32 · #5B7086 5,11 (tous ≥ 4,5).
   ══════════════════════════════════════════════════════════════════════════════ */
:root{
  --r-1:8px; --r-2:12px; --r-3:18px;
  --carte-bg:#FFFFFF; --carte-edge:rgba(19,34,48,.26); --carte-biseau:#FFFFFF; --carte-tranche:rgba(19,34,48,.38);
  --pane:#FFFFFF; --pane-2:#F3F7FB;
  --ink-3:#5B7086;
  --btn-plein-bg:#12719E; --btn-plein-ink:#FFFFFF;
  --btn-argent-bg:#0F7A55; --btn-argent-ink:#FFFFFF; --btn-argent-halo:none;
  --glow:transparent;
  --fam-argent:#1F7A4D; --fam-estime:#8A5A0C; --fam-kraft:#B9863A; --fam-neutre:#5B7086;--fam-humain:#6B4FB0;--fam-humain-2:#4A36A0;
  --halo-1:rgba(29,147,204,.95);--halo-2:rgba(29,147,204,.45);--halo-3:rgba(106,206,242,.9);--halo-lettre:var(--ink);
  --bulle-bg:linear-gradient(180deg,#D7ECF7,#BFE0F2); --bulle-ink:#132230;
}
/* LE CLAIR A SON BLOC FINAL (ticket Apparence 01). Mesuré au banc le 05/09 : le bloc `:root[data-theme="light"]`
   du haut du fichier l'emportait par spécificité sur la couche du 05/09 écrite en `:root` — en clair, les objets
   restaient en verre (--carte-bg dégradé, --pane à 80 %, --pane-2 à 52 %), la lueur restait, et --ink-3 valait
   #8299AD : 2,62:1 sur le fond, sous le seuil. Un design = UN bloc qui gagne ; celui-ci redit les valeurs du 05/09. */
:root[data-theme="light"],.vignette[data-design="light"]{--carte-bg:#FFFFFF;--carte-edge:rgba(19,34,48,.26);--carte-biseau:#FFFFFF;--carte-tranche:rgba(19,34,48,.38);
  --pane:#FFFFFF;--pane-2:#F3F7FB;--ink-3:#5B7086;--btn-plein-bg:#12719E;--btn-plein-ink:#FFFFFF;--btn-argent-bg:#0F7A55;--btn-argent-ink:#FFFFFF;--btn-argent-halo:none;--glow:transparent;
  --fam-argent:#1F7A4D;--fam-estime:#8A5A0C;--fam-kraft:#B9863A;--fam-neutre:#5B7086;--fam-humain:#6B4FB0;--fam-humain-2:#4A36A0;
  --halo-1:rgba(29,147,204,.95);--halo-2:rgba(29,147,204,.45);--halo-3:rgba(106,206,242,.9);--halo-lettre:var(--ink);
  --bulle-bg:linear-gradient(180deg,#D7ECF7,#BFE0F2);--bulle-ink:#132230;}
:root[data-theme="dark"],.vignette[data-design="dark"]{--carte-bg:#16212C;--carte-edge:rgba(255,255,255,.10);--carte-biseau:#16212C;--carte-tranche:rgba(0,0,0,.35);
  --pane:#16212C;--pane-2:#1E2B38;--ink-3:#9DB0C2;--btn-plein-bg:#7CC4EA;--btn-plein-ink:#0B1A26;--btn-argent-bg:#7ED9B0;--btn-argent-ink:#062A1D;
  --fam-argent:#7ED9B0;--fam-estime:#F0C37A;--fam-kraft:#D9B27A;--fam-neutre:#9DB0C2;--fam-humain:#B79BE0;--fam-humain-2:#6E5CE6;
  --halo-1:rgba(106,205,244,.95);--halo-2:rgba(106,205,244,.45);--halo-3:rgba(185,234,253,.9);--halo-lettre:var(--halo-1);
  --bulle-bg:linear-gradient(180deg,#1E4258,#173548);--bulle-ink:#E8F2FA;}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){--carte-bg:#16212C;--carte-edge:rgba(255,255,255,.10);--carte-biseau:#16212C;--carte-tranche:rgba(0,0,0,.35);
    --pane:#16212C;--pane-2:#1E2B38;--ink-3:#9DB0C2;--btn-plein-bg:#7CC4EA;--btn-plein-ink:#0B1A26;--btn-argent-bg:#7ED9B0;--btn-argent-ink:#062A1D;
    --fam-argent:#7ED9B0;--fam-estime:#F0C37A;--fam-kraft:#D9B27A;--fam-neutre:#9DB0C2;--fam-humain:#B79BE0;--fam-humain-2:#6E5CE6;
    --halo-1:rgba(106,205,244,.95);--halo-2:rgba(106,205,244,.45);--halo-3:rgba(185,234,253,.9);--halo-lettre:var(--halo-1);
    --bulle-bg:linear-gradient(180deg,#1E4258,#173548);--bulle-ink:#E8F2FA;}
  :root:not([data-theme="light"]) .dobj.teinte{background:var(--carte-bg);backdrop-filter:none;-webkit-backdrop-filter:none;}
}
:root[data-theme="dark"] .dobj.teinte{background:var(--carte-bg);backdrop-filter:none;-webkit-backdrop-filter:none;}
/* trois familles : l'arête garde sa couleur, le fond ne se teinte plus */
:root{--fam-resultat:var(--fam-argent);--fam-commande:var(--fam-argent);--fam-equipe:var(--fam-neutre);--fam-bon:var(--fam-kraft);--fam-reprise:var(--fam-argent);}
/* opaque */
.card,.dobj,.dobj.teinte,.pill,.fx,.card.note{background:var(--carte-bg);backdrop-filter:none;-webkit-backdrop-filter:none;}
.dobj.teinte{border:1px solid var(--carte-edge);border-bottom:2px solid var(--carte-tranche);}
.card{border:1px solid var(--carte-edge);border-top:1px solid var(--carte-edge);border-bottom:2px solid var(--carte-tranche);box-shadow:0 8px 24px -14px var(--shadow);}
/* une largeur */
.thread{padding-left:16px;padding-right:16px;}
.card.note{align-self:stretch;width:100%;max-width:none;}
/* trois rayons */
.card,.dobj,.deckwrap,.fx,.dossier .dobj{border-radius:var(--r-3);}
.btn,.btn-n,.cta-plein,.cta-payer,.cta-sec,.ch-n,.livi{border-radius:var(--r-2);}
.pill{border-radius:999px;}
.u{border-radius:var(--r-3) var(--r-3) var(--r-1) var(--r-3);}
/* un seul bouton plein ; le vert seulement pour payer */
.btn,.cta-plein{background:var(--btn-plein-bg);color:var(--btn-plein-ink);box-shadow:none;border:0;}
:root[data-theme="dark"] .btn{color:var(--btn-plein-ink);}
.btn-n{background:var(--btn-plein-bg);color:var(--btn-plein-ink);min-height:48px;font-size:var(--t-body);}
.cta-payer{background:var(--btn-argent-bg);color:var(--btn-argent-ink);box-shadow:none;}
.btn.ghost,.cta-sec{background:transparent;border:1px solid var(--carte-edge);color:var(--ink-2);box-shadow:none;}
/* le glyphe sans halo ; les textes qui informent en couleur lisible */
.av svg{filter:none;}
.dbadge.vif{border-color:var(--fam-argent);color:var(--fam-argent);}
.fact.warm,.avcorps .fact.warm{color:var(--fam-estime);}
/* le verre des cartes candidates (background-image) tombe aussi : opaque partout */
.card.rcand[data-kind="candidate"],.card[data-kind="candidate"],.dobj.teinte,.card.teinte{background-image:none;background:var(--carte-bg);}
/* quatre d'abord : le reste d'une planche attend « Voir les N autres » */
.fsplit{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 2px 10px;color:var(--ink-2);}
.fsplit .fchip{display:inline-block;padding:3px 9px;border:1px solid var(--carte-edge);border-radius:999px;background:var(--pane-2);color:var(--ink);font-size:var(--t-foot);font-weight:500;font-variant-numeric:tabular-nums;}
.fsplit .fplus{font-size:var(--t-foot);color:var(--ink-3);}
.fsplit .fpour{font-size:var(--t-cap);color:var(--ink-3);margin-left:2px;}
/* les menus des variantes sur toute la largeur (fondateur, 05/09 : « le texte est tronqué, il faut
   qu'il rentre dans le bouton ») : une option par ligne sous 480 px, le libellé a la place */

.fcarac.evpli > summary .evplis{display:inline;}

/* LE DÉPLIANT DES OPTIONS (05/09) reprend les règles intérieures du bloc à plat : la grille des axes, le
   stepper en ligne, les champs. Seule la boîte change : un dépliant comme Détails. Règles COMPLÈTES
   (la première version, ligne par ligne, laissait des accolades ouvertes — vu à l'écran, corrigé). */
  .fcarac.evpli .evcorps{display:flex;flex-direction:column;gap:7px;}
  /* auto-fit : deux colonnes quand la place y est, une seule sinon — le libellé
     d'une option ne se tronque plus à 375 (audit 01/09 : scrollWidth 157 > 147) */
  .fcarac.evpli .evax{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:7px;}
  .fcarac.evpli .evcol{display:flex;flex-direction:column;gap:4px;}
  .fcarac.evpli .evet{font-size:var(--t-cap);color:var(--ink-2);}
  .fcarac.evpli .evas{min-height:44px;width:100%;border-radius:11px;border:1px solid var(--edge);
    background:var(--pane);color:var(--ink);font:inherit;font-size:var(--t-body);padding:0 12px;
    -webkit-appearance:none;appearance:none;
    background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
    background-position:calc(100% - 19px) 50%,calc(100% - 14px) 50%;background-size:5px 5px;background-repeat:no-repeat;}
  /* le stepper de la maquette : UN cadre, − · valeur · + dedans, la baisse à droite */
  .fcarac.evpli .evqte{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
  .fcarac.evpli .evqte .evq{width:46px;min-height:44px;border:0;background:transparent;font-size:var(--t-title);
    color:var(--ink);cursor:pointer;}
  .fcarac.evpli .evqte .evqi{min-width:44px;min-height:44px;width:52px;text-align:center;font-size:var(--t-body);font-weight:600;
    border:0;background:transparent;color:var(--ink);font-variant-numeric:tabular-nums;}
  .fcarac.evpli .evstep{display:flex;align-items:center;border:1px solid var(--edge);border-radius:12px;
    background:var(--pane);}
  .fcarac.evpli .evpu{font-size:var(--t-cap);color:var(--ink-2);}
  .fcarac.evpli .evql{font-size:var(--t-cap);color:var(--ink-2);}
  /* 26/09 (B) : les choix rapides « 1 · 10 · 50 » EN LIGNE, à côté du compteur — pas en colonne */
  .fcarac.evpli .evqchoix{display:flex;gap:8px;}
@media (prefers-color-scheme:dark){
}
.fcarac.evpli .evcorps{padding:2px 0 10px;}
/* L'IMAGE DE LA FICHE (fondateur, 05/09 : « une image carrée derrière un rectangle blanc, ça ne fait pas
   top ») : le cadre prend la forme de la photo — carré, comme les photos d'usine — et la photo le remplit
   sans être rognée. Plus de bandes blanches. */
.egal-main{height:auto;aspect-ratio:1/1;max-height:min(62vh,440px);}
.egal-main img{object-fit:contain;}
/* le dépliant Personnalisation (05/09) : les mêmes lignes que les options du tunnel, à plat dans la fiche */
.fpcorps{display:flex;flex-direction:column;gap:8px;padding:4px 0 10px;}
.fpopt .fpd{display:block;font-size:var(--t-cap);color:var(--ink-2);margin-top:2px;line-height:1.35;}
.fcarac.fperso > summary .fpersos b{color:var(--light);font-weight:600;}
/* les menus des variantes sur toute la largeur sous 480 px (fondateur, 05/09 : « le texte est tronqué,
   il faut qu'il rentre dans le bouton ») — posé en DERNIER pour gagner sur la grille à deux colonnes */
@media (max-width:480px){ .fcarac.evpli .evax{grid-template-columns:1fr;} }
.fcarac.evpli .evas{text-overflow:ellipsis;}
/* ── LA FICHE, RETOURS FONDATEUR DU 05/09 (après-midi) ───────────────────────────────── */
/* le pied collant ne ronge plus le dernier dépliant : la place est réservée en bas du contenu */
/* LE PIED NE RONGE PAS LE DERNIER DÉPLIANT (fondateur 05/09) : de l'air sous le dernier
   repli quand il est OUVERT — jamais un trou quand il est fermé (un rembourrage fixe de
   112 px laissait un vide de 112 px sous « Personnalisation », mesuré au banc). */
.fiche .fcontenu > details.fcarac:last-of-type[open]{padding-bottom:12px;}
/* la réflexion de Rabbit n'est plus tronquée : la ligne de travail passe à la ligne */
.avcorps .travail{align-items:flex-start;}
.avcorps .travail .ph{white-space:normal;height:auto;overflow:visible;text-overflow:clip;}
.avcorps .travail .ph span{position:static;display:block;line-height:1.35;white-space:normal;}
/* le lapin qui pense : les trois traits se dessinent en boucle */
/* 08/09 : le dessin sur mesure à trois traits est parti — c'est `#head` qui s'écrit, et tout
   son style vit sous `.lapin` (une seule définition, partagée avec la ligne de recherche).
   Il ne reste ici que la BOÎTE, et le mini qui signe le verdict sans s'animer. */
.lapin-pense{flex:0 0 auto;width:26px;height:27px;margin-top:-2px;}
/* l'avis rédigé : une phrase par ligne */
.avparle p{margin:0 0 6px;}
.avres{padding-right:0;}
/* ── LE VERDICT EST LA SECONDE LIGNE DU PRIX (08/09) ────────────────────────────────
   Sept montants à l'écran, il en fallait trois : ce qui décide reste dehors, ce qui
   explique s'ouvre au tap. La ligne n'a ni cadre ni fond — c'est Rabbit qui parle,
   pas une carte de plus. */
.avligne{margin:1px 0 9px;}
.avligne .avouvre{display:flex;align-items:baseline;gap:8px;width:100%;flex-wrap:wrap;
  background:none;border:0;padding:4px 2px;margin:0;font:inherit;color:inherit;
  text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.avligne .avtitre{font-size:var(--t-head);font-weight:600;letter-spacing:var(--t-head-ls);margin:0;flex:none;}
.avligne .avresume{font-size:var(--t-body);color:var(--ink);font-variant-numeric:tabular-nums;}
/* le chevron dit qu'il y a plus à lire — il se retourne quand c'est ouvert */
.avligne .avchev{width:7px;height:7px;flex:none;margin-left:auto;align-self:center;
  border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);
  transform:rotate(45deg);transition:transform .18s var(--e-plat);}
.avligne .avouvre[aria-expanded="true"] .avchev{transform:rotate(-135deg);}
.avligne .travail{padding:2px;}
.avligne .avgo{margin-top:8px;}
.avdetail{margin:0 0 10px;}
.avdetail .avcorps{padding:0;}
/* dans le détail, la décomposition et le marché reprennent leur place, sans marge de tête */
.avdetail .fsplit{margin-top:9px;}
.avtitre .lapin-mini{display:inline-block;width:15px;height:16px;margin-right:8px;
  vertical-align:-2px;color:var(--light);}
.lapin-mini use{stroke:currentColor;}
.av-serre .lapin-mini,.av-a_confirmer .lapin-mini{color:var(--warm);}
.av-laisse .lapin-mini{color:var(--ink-3);}
/* LA QUESTION QUI COÛTE LE PLUS CHER (cote 3) : sa phrase porte ce qu'elle vaut, en euros. */
.avqp{font-size:var(--t-foot);color:var(--ink-2);line-height:1.45;margin:11px 0 0;}
/* un recalcul ne fait pas écran noir : l'avis d'avant recule, il ne disparaît pas */
.avvieux{opacity:.42;}
.avrecompte{font-size:var(--t-cap);color:var(--ink-3);margin-top:7px;}
/* L'ACTE SUIVANT (cote 5) : un seul, jamais « Commander » — le pied le porte déjà. */
.avacte{margin-top:11px;}
@media (prefers-reduced-motion:no-preference){ .avcorps{transition:opacity .18s var(--e-plat);} }

/* MON AVIS — la tête de Rabbit devant le titre (fondateur 05/09 : « le logo avec Mon avis, court ») */
.avplis .lapin-mini{display:inline-block;width:15px;height:16px;margin-right:7px;vertical-align:-2px;color:var(--light);}
.avplis .lapin-mini svg{width:100%;height:100%;display:block;}

/* LE BLOC PRIX (fondateur 05/09) : un nombre, la bulle produit + transport, la bulle du marché */
.fmarche{margin:0 2px 10px;}
.fsplit .fchip.vif,.fmarche .fchip{display:inline-block;padding:3px 9px;border-radius:999px;font-size:var(--t-foot);font-weight:600;font-variant-numeric:tabular-nums;border:1px solid var(--fam-argent);color:var(--fam-argent);background:var(--pane-2);}
/* « Mon avis » d'abord, la tête de Rabbit après (fondateur 05/09) */
.avplis .lapin-mini{margin-right:0;margin-left:7px;}

/* L'ARRIVÉE DES CARTES — proposition C « Distribuées », choisie par le fondateur (05/09) : les quatre
   arrivent du bord droit une par une, avec un petit rebond à l'arrivée, comme une main de cartes qu'on
   distribue ; les quatre suivantes (« Voir quatre autres ») rejouent la même distribution. Le bloc ne se
   matérialise plus d'un coup : ce sont les cartes qui bougent. Le cadre CLIPPE le trajet : une carte
   translatée hors du cadre ferait défiler le fil de côté (mobile d'abord, jamais de défilement horizontal). */
.deckwrap.carre{overflow:hidden;overflow:clip;overflow-clip-margin:16px;}
.obj.materialise:has(.deckwrap.carre){animation:planche-apparait .2s var(--e-main) both;}
@keyframes planche-apparait{from{opacity:0;}to{opacity:1;}}
.deck.liste.carre .deck-slot{opacity:0;transform:translateX(420px) rotate(4deg);animation:distribuee .56s cubic-bezier(.34,1.35,.64,1) both;}
.deck.liste.carre .deck-slot:nth-child(4n+2){animation-delay:.11s;}
.deck.liste.carre .deck-slot:nth-child(4n+3){animation-delay:.22s;}
.deck.liste.carre .deck-slot:nth-child(4n+4){animation-delay:.33s;}
@keyframes distribuee{from{opacity:0;transform:translateX(420px) rotate(4deg);} 30%{opacity:1;} to{opacity:1;transform:none;}}
@media (prefers-reduced-motion: reduce){
  .deck.liste.carre .deck-slot{animation:none;opacity:1;transform:none;}
}

/* LA FEUILLE DE COMMANDE, CLAIRE (fondateur 05/09) : le nom sur sa ligne, la variante en mots dessous, « Livraison » avant les champs */
/* doctrine de l'écran, lot 3 : le nom EST l'en-tête (« Ta commande » au-dessus est parti) */
.feuille-c .fx-nom{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:var(--t-body);font-weight:600;color:var(--ink);line-height:1.3;text-wrap:balance;}
/* la seule réserve, au paiement, une fois (loi 7) */
.feuille-c .fx-reserve{font-size:var(--t-foot);color:var(--ink-2);text-align:center;margin:10px 0 8px;}
.feuille-c .fx-reserve[hidden]{display:none;}
.feuille-c .livt{display:block;font-size:var(--t-foot);font-weight:600;color:var(--ink);margin:12px 0 4px;}

/* LES VARIANTES DE LA COMMANDE, UNE PAR LIGNE (fondateur 05/09) : la quantité devant, les valeurs après */
.feuille-c .fxv{color:var(--ink);min-width:0;overflow-wrap:anywhere;}

/* LE TICKET AGENT, UN SEUL OBJET (fondateur 05/09) : la photo, la demande en une ligne, deux lignes d'état.
   Le filet pointillé sous le bandeau est retiré : il coupait la carte en deux objets à l'œil. */
.card.naiss .resume-n{display:flex;align-items:center;gap:10px;margin:2px 0;}
.card.naiss .resume-n img{width:44px;height:44px;border-radius:10px;object-fit:cover;flex:none;}
.card.naiss .resume-n b{display:block;font-size:var(--t-foot);line-height:1.3;}
.card.naiss .resume-n small{display:block;font-size:var(--t-cap);color:var(--ink-3);margin-top:2px;}
.card.naiss .ligne-n{display:flex;justify-content:space-between;gap:10px;font-size:var(--t-foot);padding:7px 0 0;border-top:1px solid var(--edge);}
.card.naiss .ligne-n span:last-child{color:var(--ink-2);white-space:nowrap;}

/* TA MARCHANDISE, UN SEUL OBJET (fondateur 05/09) : l'adresse à copier, le champ du suivi, le mode d'emploi replié */
.card.naiss .ligne-n.premiere{border-top:0;padding-top:2px;}
.card.naiss .adr-n{margin:6px 0 4px;padding:10px 12px;border:1px solid var(--edge);border-radius:11px;background:var(--pane);
  font-family:ui-monospace,Menlo,monospace;font-size:var(--t-foot);line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere;
  user-select:text;-webkit-user-select:text;color:var(--ink);}
/* 11/09 — la carte de connexion rejoint cette règle. Sans elle, son second bouton
   retombait en PLEIN : « Je n’ai pas de mot de passe » criait plus fort que « Entrer »
   (vu au banc). Une carte n’a qu’une action principale. */
.card.naiss .btn-n.sec,
.card[data-role="connexion"] .btn-n.sec,
.card[data-role="email-a-confirmer"] .btn-n.sec{background:transparent;color:var(--light);border:1px solid var(--edge);width:100%;}
/* 02/10 — « Envoyer à mon agent » est le second geste de la fiche : un contour, jamais un plein à côté de « Commander ». */
.fiche .foqenv{background:transparent;color:var(--light);border:1px solid var(--edge);width:100%;}
/* LA BASCULE ENTRE LES DEUX VISAGES est un MOT, pas un bouton : une carte n'a qu'une action
   principale, et « j'ai déjà un compte » n'est pas une action — c'est une correction de
   route. Jetons seulement, aucune couleur littérale. */
.card[data-role="connexion"] .cx-bascule{background:none;border:0;padding:10px 4px 2px;width:100%;
  color:var(--ink-2);font:inherit;font-size:var(--t-foot);text-decoration:underline;
  text-underline-offset:3px;cursor:pointer;min-height:44px;}
/* ══ LA CONFIRMATION D'E-MAIL (maquette v2 validée le 29/09) ═══════════════════════════════════════════════════════
   « Tu voulais dire … ? » sous le champ de la feuille et de la carte ; la carte « E-mail » du rappel ; la ligne « Suivi par
   e-mail · Corriger » du ticket. Le second bouton de la carte rejoint la règle du contour, plus haut. */
.fx-email-sugg{margin:2px 4px 0;font-size:var(--t-foot);line-height:1.4;color:var(--ink-2);}
.fx-email-sugg[hidden]{display:none;}
.livf .fx-email-sugg{flex:1 1 100%;}
.fx-email-sugg button,.fact .em-corriger{background:none;border:0;padding:0;font:inherit;font-weight:600;color:var(--light);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;}
.card[data-role="email-a-confirmer"] .em-val{font-size:var(--t-head);line-height:1.35;color:var(--ink);padding:4px 0;overflow-wrap:anywhere;}
.card[data-role="email-a-confirmer"] [hidden]{display:none;}
.card[data-role="connexion"] .cx-bascule:hover{color:var(--ink);}
.card[data-role="connexion"] .cx-cgv[hidden]{display:none;}
.card.naiss .pli-n{margin-top:4px;}
.card.naiss .pli-n > summary{font-size:var(--t-foot);color:var(--light);min-height:36px;}
.card.naiss .pli-n .fact{margin:4px 0;}

/* LES CHAMPS DES TICKETS FONT 16 PX (fondateur 05/09 : « à chaque fois que j'écris sur le ticket, ça me remonte tout
   en haut ») : sous 16 px, Safari iOS zoome la page à chaque focus et à chaque frappe. Même jeton que la feuille
   de commande et le composeur. Garde : champs-seize-pixels. */
.ch-n{font-size:var(--t-champ);}
/* la feuille de commande aussi : .livi était à 15 px par un raccourci font: — même zoom iOS */
.livi{font-size:var(--t-champ);}
/* le mode d'emploi du bon : quatre lignes, un mot en tête (05/09) */
.card.naiss .mode-n{font-size:var(--t-foot);line-height:1.45;color:var(--ink-2);margin:6px 0;}
.card.naiss .mode-n b{color:var(--ink);}

/* ══ LE MONDE DERRIÈRE LE FIL (ticket Apparence 01) ══
   Le ciel d'aujourd'hui — les trois masses, l'horizon, la poussière du canvas — est le monde de Clair et de Sombre.
   Un autre design ne l'hérite pas : il monte son propre monde dans #monde (calques CSS, tickets 03-06). Sans design
   connu, on reste sur le ciel : la garde de la liste vit dans fil.js. */
#monde{position:fixed;inset:0;z-index:-4;pointer-events:none;overflow:hidden;}
html[data-theme]:not([data-theme="light"]):not([data-theme="dark"]) .sky,
html[data-theme]:not([data-theme="light"]):not([data-theme="dark"]) .horizon,
html[data-theme]:not([data-theme="light"]):not([data-theme="dark"]) #dust,
html[data-theme]:not([data-theme="light"]):not([data-theme="dark"]) #dust2{display:none;}

/* ══ « APPARENCE » — six vignettes vivantes de la scène du fil (ticket Apparence 02) ══
   Chaque vignette est la scène à 390 px, réduite par transform : les tailles restent des jetons. Ses couleurs
   sont celles de SON design (le bloc de jetons sert aussi `.vignette[data-design]`), jamais du design en cours. */
.apparence{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;padding:12px;justify-items:center;}
.vignette{--vz:.36;position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;padding:8px 8px 10px;
  border:1px solid var(--edge);border-radius:var(--r-3);background:var(--pane);color:var(--ink);font-family:var(--sans);
  cursor:pointer;text-align:center;min-height:44px;}
@media (min-width:400px){.vignette{--vz:.4;}}
.vignette[aria-checked="true"]{border-color:var(--light);box-shadow:0 0 0 2px var(--light);}
.vignette[disabled]{cursor:default;}
.vignette[disabled] .vscene{opacity:.55;}
.vignette:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
.vscene{display:block;width:calc(390px * var(--vz));height:calc(760px * var(--vz));overflow:hidden;position:relative;
  border-radius:calc(28px * var(--vz));border:1px solid var(--carte-edge);}
.vtel{position:absolute;left:0;top:0;width:390px;height:760px;transform:scale(var(--vz));transform-origin:0 0;
  display:flex;flex-direction:column;overflow:hidden;background:var(--screen);color:var(--ink);font-size:var(--t-body);line-height:1.45;text-align:left;}
/* le ciel de Clair et de Sombre, figé dans leur vignette (la vraie poussière n'y tourne pas) */
.vignette[data-design="light"] .vtel,.vignette[data-design="dark"] .vtel{background:
  radial-gradient(120% 78% at 50% 116%, color-mix(in srgb,var(--light) 20%,transparent), transparent 58%),
  linear-gradient(178deg, var(--void) 0%, var(--air) 34%, var(--air-2) 74%, var(--deep) 100%);}
.vmonde{position:absolute;inset:0;pointer-events:none;overflow:hidden;}
.vtete{position:relative;display:flex;align-items:center;gap:9px;padding:14px 20px 10px;border-bottom:1px solid var(--edge-2);font-size:var(--t-foot);font-weight:500;}
.vtete svg,.vr svg{width:28px;height:28px;flex:0 0 auto;color:var(--light);}
.vfil{position:relative;flex:1;min-height:0;display:flex;flex-direction:column;justify-content:flex-end;padding:0 16px 8px;overflow:hidden;}   /* ce qui dépasse se coupe en haut, comme un fil qu'on a fait défiler — jamais par-dessus l'en-tête */
.vu{align-self:flex-end;max-width:80%;margin-top:7px;padding:9px 13px;border-radius:var(--r-3) var(--r-3) var(--r-1) var(--r-3);
  background:var(--bulle-bg);color:var(--bulle-ink);border:1px solid var(--edge-2);}
.vjour{display:flex;align-items:center;gap:10px;font-size:var(--t-cap);color:var(--ink-3);}
.vjour::before,.vjour::after{content:"";flex:1;height:1px;background:var(--edge-2);}
.vr{display:flex;align-items:flex-start;gap:9px;margin-top:12px;padding-right:8px;} .vr b{font-weight:400;font-size:var(--t-body);line-height:1.35;}
.vcomp{display:flex;align-items:center;gap:8px;margin:10px 0 0;padding:4px;border:1px solid var(--edge);background:var(--pane-2);border-radius:24px;}
.vcomp i{width:36px;height:36px;display:flex;align-items:center;justify-content:center;font-style:normal;color:var(--light);font-size:var(--t-title);} .vcomp i svg{width:22px;height:22px;}
.vcomp b{flex:1;font-weight:400;font-size:var(--t-foot);color:var(--ink-3);}
.vcomp u{width:36px;height:36px;border-radius:50%;background:var(--btn-plein-bg);color:var(--btn-plein-ink);display:flex;align-items:center;justify-content:center;text-decoration:none;}
.vnom{font-size:var(--t-body);font-weight:600;}
.vnote{font-size:var(--t-cap);color:var(--ink-3);}
.vetat{font-size:var(--t-cap);color:var(--ink-3);min-height:1em;}
.vignette[aria-checked="true"] .vetat{color:var(--light);font-weight:600;}

/* ══ HALO (ticket Apparence 03) — le bloc de jetons : les 25 de la maquette validée + le ciel, les ombres, le clavier ══
   Un design = UN bloc qui gagne, pour la racine ET pour sa vignette. Les couleurs viennent de docs/mockups/fil-cinq-designs-v0.html,
   contrastes calculés depuis ces jetons par la garde fil-apparence. */
:root[data-theme="halo"],.vignette[data-design="halo"]{color-scheme:dark;
  --air:#070A14;--air-2:#0A0F1E;--deep:#141C33;--void:#05070F;--vig:rgba(0,0,0,.6);--grain:.05;
  --sh-1:0 6px 14px -8px rgba(0,0,0,.72), 0 1px 2px -1px rgba(0,0,0,.5);--sh-2:0 16px 40px -22px rgba(0,0,0,.82), 0 2px 6px -3px rgba(0,0,0,.5);--sh-3:0 30px 72px -32px rgba(0,0,0,.85);
  --screen:#070A14;--ink:#EEF2FB;--ink-2:#BCC6DE;--ink-3:#B8C2DA;--light:#9FE1FF;--light-hi:#FFFFFF;--glow:transparent;--warm:#F0C37A;--rouge:#FF6B60;
  --pane:#18224A;--pane-2:#1E2A58;--edge:rgba(159,225,255,.24);--edge-2:rgba(159,225,255,.12);--grid:rgba(159,225,255,.13);
  --carte-bg:#18224A;--carte-edge:rgba(159,225,255,.22);--carte-biseau:#18224A;--carte-tranche:rgba(0,0,0,.40);--shadow:rgba(0,0,0,.72);
  --btn-plein-bg:#9FE1FF;--btn-plein-ink:#07192A;--btn-argent-bg:#7ED9B0;--btn-argent-ink:#062A1D;--btn-argent-halo:none;
  --fam-argent:#7ED9B0;--fam-estime:#F0C37A;--fam-kraft:#D9B27A;--fam-neutre:#B8C2DA;--fam-humain:#B79BE0;--fam-humain-2:#6E5CE6;
  --bulle-bg:#243055;--bulle-ink:#EEF2FB;
  --halo-1:rgba(159,225,255,.95);--halo-2:rgba(120,140,255,.9);--halo-3:rgba(200,110,255,.8);--halo-lettre:var(--halo-1);--p-atmo:#D8F2FF;--p-halo:color-mix(in srgb,var(--light) 46%,var(--deep));--p-file:#EAF7FF;--etoiles:.9;}

/* ══ LES MONDES — derrière le fil (#monde) et dans les vignettes (.vmonde), la même chaîne ══ */
#monde > .monde{display:none;}
/* l'identité d'un monde monté est son data-monde (deux designs partagent une structure — ticket 08) */
html[data-theme="halo-clair"] #monde > .monde[data-monde="halo-clair"],
html[data-theme="halo"] #monde > .monde[data-monde="halo"]{display:block;}
.monde,.monde > *{display:block;}
.monde{position:absolute;inset:0;overflow:hidden;pointer-events:none;}
.monde .deep{position:absolute;inset:0;}
/* Halo : un fond seul. Le liseré du bord est mort le 07/09 — la lumière ne vit plus que sur un objet qui attend. */
.monde.halo .deep{background:radial-gradient(80% 60% at 50% 50%, #070A14, #05070F);}
/* le mouvement réduit arrête les mondes : l'image reste, rien ne bouge (plein écran et miniature) */
@media (prefers-reduced-motion:reduce){
  #monde .monde *,.vmonde .monde *{animation:none !important;}
}

/* ══ LES CÔTÉS (ticket 08, fondateur 05/09 ~23 h : « chaque monde a son côté sombre et clair ») ══
   Même structure animée (fabrique M.<monde> de fil.js), autre lumière : le côté se pose par [data-monde="…"]. */

/* HALO CLAIR — le liseré tourne sur du blanc : les mêmes trois lumières, en multiply pour qu'elles se lisent sur clair */
:root[data-theme="halo-clair"],.vignette[data-design="halo-clair"]{color-scheme:light;
  --air:#D5E2FB;--air-2:#E4EBFC;--deep:#C4D5F7;--void:#FFFFFF;--vig:rgba(70,108,148,.25);--grain:0;
  --sh-1:0 6px 14px -8px rgba(18,58,92,.34), 0 1px 2px -1px rgba(18,58,92,.20);--sh-2:0 16px 40px -22px rgba(18,58,92,.50), 0 2px 6px -3px rgba(18,58,92,.22);--sh-3:0 34px 80px -30px rgba(18,58,92,.62), 0 6px 20px -10px rgba(18,58,92,.22);
  --screen:#D5E2FB;--ink:#0F1B2D;--ink-2:#43536A;--ink-3:#526278;--light:#0B74A3;--light-hi:#4FB6E6;--glow:transparent;--warm:#8A5A0C;--rouge:#C9302C;
  --pane:#FFFFFF;--pane-2:#EDF2FD;--edge:rgba(15,27,45,.16);--edge-2:rgba(15,27,45,.09);--grid:rgba(11,116,163,.14);
  --carte-bg:#FFFFFF;--carte-edge:rgba(15,27,45,.32);--carte-biseau:#FFFFFF;--carte-tranche:rgba(15,27,45,.34);--shadow:rgba(20,40,90,.30);
  --btn-plein-bg:#0B74A3;--btn-plein-ink:#FFFFFF;--btn-argent-bg:#0F7A55;--btn-argent-ink:#FFFFFF;--btn-argent-halo:none;
  --fam-argent:#1F7A4D;--fam-estime:#8A5A0C;--fam-kraft:#B9863A;--fam-neutre:#526278;--fam-humain:#6B4FB0;--fam-humain-2:#4A36A0;
  --bulle-bg:#D9F0FA;--bulle-ink:#0F1B2D;
  --halo-1:rgba(25,179,230,.95);--halo-2:rgba(79,107,255,.9);--halo-3:rgba(176,76,255,.8);--halo-lettre:var(--ink);--p-atmo:#FFFFFF;--p-halo:var(--light);--p-file:var(--light);--etoiles:0;}
.monde[data-monde="halo-clair"] .deep{background:#D5E2FB;}   /* un CHAMP, pas un ciel : Clair a déjà le ciel et la poussière */

/* ══════════════════════════════════════════════════════════════════════════════════════
   LE HALO D'ATTENTE (ticket 03, décision du fondateur des 06-07/09)
   Le liseré qui tournait au bord de l'écran est mort — « il ne peut pas rester là
   constamment ». La lumière ne vit plus que sur UN objet que Rabbit vient de faire
   apparaître et qui attend un geste : remplir, commander, approuver. Elle s'éteint dès
   que c'est fait. Ce n'est pas de la décoration, c'est une incitation.

   Qui l'allume : `poserHalo()` dans fil.js, seule porte, un objet à la fois. Ici, on ne
   décrit que la lumière. Celui qui PRODUIT un objet pose `data-halo="<raison>"` ; celui
   qui l'AFFICHE n'a rien d'autre à faire.

   LA LUMIÈRE RESPIRE, ELLE NE TOURNE PAS (fondateur, 08/09 : « pour moi le souffle »).
   Un anneau qui tourne dit « je travaille » — c'est le vocabulaire d'un chargement, et le halo
   veut dire l'inverse : « j'attends quelque chose de TOI ». Il monte et redescend, tout autour.
   Le même souffle dans les quatre designs : le halo est un COMPORTEMENT, et un signal qui se
   comporte de deux façons oblige le client à apprendre deux langues. Seule la couleur suit le
   design. La rotation (l'angle animé, @property --halo-a) est retirée : plus rien ne la porte.

   TROIS RÈGLES DE FABRICATION, mesurées :
    1. LE TOUR EST COMPLET. Sans rotation, un dégradé conique À TROU laisse l'anneau ÉTEINT là
       où le trou tombe — mesuré le 08/09, la lumière n'existait pas dans le coin haut-gauche.
    2. LES DEUX COUCHES SONT CONCENTRIQUES : même `inset`, même `border-radius`. Seules
       l'épaisseur (padding) et le flou changent. Une nappe posée sur un autre rayon
       dédouble le contour sur un petit objet.
    3. LE CREUX NE TOUCHE JAMAIS ZÉRO. Le halo est un ÉTAT, pas un clignotement : à 2,6 s
       personne ne l'aurait vu, mais à 6 s un creux à .30 laisse l'objet SANS MARQUE la moitié
       du temps. Le creux vaut .45 — le souffle module, il n'éteint pas.

   Le retrait vaut 0 : beaucoup d'objets du fil sont en `overflow:hidden` (`.dobj`), et un
   anneau dessiné en dehors de leur boîte serait rogné. Il épouse donc leur propre bord.
   Les couleurs sont les jetons --halo-1/2/3, que TOUS les designs déclarent : le halo est
   un comportement, pas un design — il s'allume aussi bien en Clair qu'en Halo. */
/* L'OBJET S'ALLUME (fondateur, 08/09) : ce n'est pas qu'un contour — un voile part du HAUT de
   l'objet, comme si la lumière de l'anneau entrait dedans. Il vient de --halo-1, donc de la
   couleur du design ; il se pose en `background-image` par-dessus le fond opaque de la carte. */
[data-halo]:not(button){position:relative;
  /* ⚠️ PAS `background-image` : `.dobj.teinte{background:…}` (0,2,0) et, en sombre,
     `:root[data-theme="dark"] .dobj.teinte` (0,4,0) l'écrasent — et `background` est un raccourci
     qui remet l'image à `none`. Mesuré au banc le 08/09 : le voile n'existait pas sur les cartes du
     fil, alors qu'il marchait sur celles de « Mon compte ». Une ombre INTÉRIEURE dit la même chose
     et personne ne la repose ici ; l'ombre portée de la carte est redite dans la même déclaration,
     sinon elle disparaîtrait. */
  /* 🔴 LE VOILE RESPIRE, ET C'EST LUI QUI PORTE LE SIGNAL (09/09 au soir). En affinant la nappe
     pour qu'elle cesse de marcher sur les mots, je l'avais rendue INVISIBLE : audit en pixels des
     sept objets allumés, les deux fonds, amplitude 1,2 à 2,6 — sous l'anneau de bouton qu'il avait
     refusé. Un contour de 1,5 px n'a pas l'aire d'un souffle de 11 s ; le VOILE en a.
     L'ombre PORTÉE est redite aux deux instants : `box-shadow` est un raccourci, l'oublier ferait
     clignoter l'élévation de l'objet au rythme du souffle. */
  /* ⏱ 10/09 : LE VOILE NE RESPIRE PLUS. Le fondateur, devant la production : « c'est comme si c'était
     un souffle, il apparaît, il repart, ce n'est pas comme s'il tournait autour de l'objet […]
     j'aimerais bien l'avoir avec le halo qui tourne ». La lumière TOURNE désormais (voir l'anneau) ;
     deux mouvements à la fois seraient du bruit. Le voile reste : allumé, immobile, deux couleurs. */
  /* ⏱ 14/09 — LE VOILE EST RETIRÉ. Le fondateur, devant les deux lumières séparées et mesurées :
     le voile figé ajoutait 15 à 18 sur 255 et NE BOUGEAIT PAS — le profil exact de ce qu'il avait
     refusé le 09/09 (« je n'ai aucun effet de halo »). Sa question a tranché : « sans mouvement,
     comment tu veux que je le voie ? » La carte allumée reprend donc l'ombre d'une carte ordinaire
     (recopiée de la règle `.card:not([data-halo])` plus bas) et toute la lumière passe dans la
     TRAVERSÉE ci-dessous. `overflow:hidden` parce que la bande vit DANS l'objet. */
  overflow:hidden;
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere),
             0 18px 40px -16px var(--surf-ombre), 0 2px 8px -4px var(--surf-ombre-2);}

/* ══ LA LUMIÈRE PASSE SUR L'OBJET (fondateur, 14/09) ═══════════════════════════════════════
   Sa maquette : `docs/mockups/lumiere-c-e-1309.html`, chapitre C. Une bande traverse l'objet —
   par-dessus le texte — puis se dépose en liseré. Mesuré au banc, carte réelle, temps réel :
   la traversée change 45,8 sur 255 sur 74 % de la carte au sombre, 35,3 sur 61 % au clair.
   L'anneau qu'elle remplace : 48 sur 255, mais sur 2,4 % — un trait de 1,5 px n'a pas d'aire.

   ⚠️ ELLE DÉPLACE L'ÉLÉMENT, PAS SON FOND. Payé le 14/09 : la première version animait
   `background-position` alors que la règle posait `background:…!important`. Une déclaration
   !important BAT une animation : le dégradé était peint et sa position gelée à `0% 0%`. Trois
   fois « on voit toujours rien bouger », et c'était vrai. Un `transform` ne se laisse pas geler.

   LA COULEUR SUIT LE FOND, et c'est sa décision : « en mode sombre je préfère la lumière du
   design, en mode clair je préfère le décor. » Ce n'est pas un compromis — le dépôt suit déjà
   cette loi (l. 3239-3240) : « une page presque blanche ne reçoit pas une lumière blanche ». */
@keyframes halo-passe{0%{transform:translateX(-115%)}27%,100%{transform:translateX(195%)}}
/* LA SOURCE : la lumière du design, --light et son point haut --light-hi. UNE déclaration, et
   elle suit quand même le fond — parce que ces deux jetons sont eux-mêmes redéclarés par thème
   (#5EE0FF au sombre, #1E4BC4 au clair). L'écrire deux fois serait deux endroits à tenir pour
   un seul fait.
   ⏱ 14/09, SECOND choix du fondateur. Il avait d'abord pris LE DÉCOR au clair
   (--deep/--p-atmo), en regardant une carte produit. Mesuré ensuite sur « Ton agent en Chine »
   — une carte blanche SANS photo, le cas faible : le décor y rendait 19,2 sur 255 contre 71,0
   pour la teinte. Un bleu très pâle sur du blanc n'a pas d'où monter. Quatre couleurs posées
   côte à côte, il a tranché sur l'objet le plus dur, pas sur le plus beau. */
:root{--passe-1:var(--light);--passe-2:var(--light-hi);--passe-3:var(--light);
  --passe-a:30%;--passe-b:60%;--passe-c:34%;
  --passe-s1:24%;--passe-s2:47%;--passe-s3:70%;}
/* ── AU CLAIR, UNE LUMIÈRE NE PEUT PAS ÊTRE UNE TEINTE : C'EST SON OMBRE QU'ON VOIT ──────────
   Fondateur, 14/09, devant les quatre façons EN MOUVEMENT dans sa propre page : « en clair la
   lumière qui traverse n'est pas adaptée, plus comme l'environnement, plus brillant ». Il a
   choisi F. Et la mesure dit pourquoi la précédente ratait : sur une carte BLANCHE, `--light`
   vaut un bleu profond (#1E4BC4) — la bande TERNISSAIT la carte au lieu de l'éclairer.
   F renverse : un bord d'attaque clair (`--light-hi`), puis la profondeur du monde (`--deep`)
   qui passe comme l'ombre d'une lumière qui approche. C'est ce qu'un œil lit comme de la
   lumière sur un fond clair — on ne peut pas éclaircir du blanc, on peut faire passer une ombre.
   ⚠️ Ces quatre-là ont été jugées EN MOUVEMENT, dans la vraie page. Quatre images fixes lui
   avaient été envoyées avant : « je ne vois rien du tout ». Une lumière ne se juge pas figée. */
:root[data-theme="halo-clair"],:root[data-theme="light"],
.vignette[data-design="halo-clair"],.vignette[data-design="light"]{
  --passe-1:var(--light-hi);--passe-2:var(--deep);--passe-3:var(--deep);
  --passe-a:45%;--passe-b:62%;--passe-c:40%;
  --passe-s1:18%;--passe-s2:42%;--passe-s3:66%;}
/* ⚠️ `inset:auto` AVANT les quatre côtés : c'est un raccourci, posé après il les remet à auto
   et la bande disparaît entière (mesuré le 14/09). */
[data-halo]:not(button)::before,.card[data-halo]:not(button)::before{
  content:"";position:absolute;z-index:4;pointer-events:none;
  inset:auto;top:-12%;bottom:-12%;left:0;right:auto;width:74%;height:auto;
  border-radius:0;padding:0;opacity:1;
  -webkit-mask:none;mask:none;-webkit-mask-composite:source-over;mask-composite:add;
  filter:blur(1.5px);
  background:linear-gradient(101deg,transparent 0%,
    color-mix(in srgb,var(--passe-1) var(--passe-a),transparent) var(--passe-s1),
    color-mix(in srgb,var(--passe-2) var(--passe-b),transparent) var(--passe-s2),
    color-mix(in srgb,var(--passe-3) var(--passe-c),transparent) var(--passe-s3),transparent 100%);
  /* ⏱ TROIS PASSAGES, PUIS ELLE SE TAIT (fondateur, 14/09). Sa maquette du 13/09 le disait
     déjà — « en vrai elle ne passe qu'une fois, à l'arrivée de l'objet » — et j'avais déployé
     le réglage du BANC, qui boucle sans fin pour qu'on puisse la regarder. Une lumière qui ne
     s'arrête jamais n'invite plus : elle décore. Trois, parce qu'un objet peut arriver pendant
     que l'œil est ailleurs ; ensuite le LISERÉ reste seul, et c'est lui la marque.
     `both` est obligatoire : sans lui la bande réapparaîtrait en plein milieu à la fin. */
  animation:halo-passe var(--halo-passe,5.2s) cubic-bezier(.33,.72,.28,1) 3 both;}
/* ── LE SILENCE (fondateur, 14/09) : « quand l'utilisateur commence à écrire, la traversée doit
   s'arrêter ». Elle a été comprise, elle se tait. Le LISERÉ, lui, ne bouge pas : l'objet attend
   toujours un geste, et c'est ce qu'il dit. Le `transform` est obligatoire — figer l'animation
   sans le poser laisserait la bande gelée en plein milieu de l'objet, sur les mots. */
[data-halo][data-lumiere="calme"]:not(button)::before,
.card[data-halo][data-lumiere="calme"]:not(button)::before{
  animation:none;transform:translateX(195%);}
/* LE LISERÉ — ce qui RESTE quand la lumière est passée. C'est lui qui marque l'objet entre
   deux passages : la traversée annonce, le liseré tient. */
[data-halo]:not(button)::after,.card[data-halo]:not(button)::after{
  content:"";display:block;position:absolute;z-index:5;pointer-events:none;
  inset:auto;right:0;top:13px;bottom:13px;left:auto;width:3px;height:auto;
  border-radius:2px;padding:0;opacity:1;animation:none;filter:none;
  -webkit-mask:none;mask:none;
  background:linear-gradient(180deg,var(--halo-1),var(--halo-2) 55%,var(--halo-3));}
/* la carte allumée CLIPPE : la bande ne doit jamais sortir de l'objet qu'elle traverse */
.card[data-halo]:not(button){overflow:hidden;}
/* ══ LA LUMIÈRE TOURNE (fondateur, 10/09) ═══════════════════════════════════════════════════
   Devant la production : « c'est comme si c'était un souffle, il apparaît, il repart, ce n'est pas
   comme s'il tournait autour de l'objet […] j'aimerais bien l'avoir avec le halo qui tourne. C'est
   vrai que j'avais choisi celui-là, mais je n'avais pas vu comme ça. » Sa décision du 08/09 (le
   souffle) est remplacée par lui, l'objet réel sous les yeux.
   Ce que le 07/09 avait établi se réapplique : c'est l'ANGLE du dégradé qui tourne, jamais la boîte
   (`transform:rotate` ferait pivoter le masque et couperait le texte) ; l'angle est une propriété
   ENREGISTRÉE, sinon il n'est pas animable ; le tour est COMPLET (pas de « transparent », qui
   laisserait un pan d'anneau éteint) ; la vitesse est CONSTANTE — une lumière qui accélère et
   freine sur un cercle a l'air cassée.
   ⏱ `--halo-tour` vaut 14 s depuis le 13/09 (doctrine lumière §4). Le commentaire disait encore
   « un tour en 6 s » : c'était faux, et un commentaire faux est ce qui fait recommencer la session
   suivante. Mesuré au banc le 13/09 : le tour change 53,6 sur 255 là où il passe en Halo sombre,
   30 en Halo clair, sur 2 % des pixels de la carte. ⏳ NON mesuré sur un téléphone réel. */
@property --halo-a{syntax:'<angle>';inherits:false;initial-value:0deg;}
@keyframes halo-tourne{to{--halo-a:360deg;}}
/* 🔴 CET ANNEAU EST MORT LE 14/09 — et il l'était déjà en pixels le 09/09.
   Ce jour-là le fondateur avait mesuré cinq formes en mouvement et choisi LA LUEUR (16,2 sur
   36 % des pixels) contre l'anneau fin (2,4 sur 7 %). Le 10/09 il a demandé « une seule langue »
   et l'anneau est revenu sur le bouton. L'audit re-pointé le 14/09 lui donne raison une seconde
   fois : l'anneau du bouton rend 3,4 sur 255 (seuil 8), et accélérer son tour de 14 s à 6 s n'a
   changé QUE la vitesse (0,7 → 1,5 %/s) — l'aire, elle, ne s'invente pas.
   CE QUI DÉNOUE SES DEUX DÉCISIONS : la traversée est pour ce qui a une SURFACE à traverser.
   La surface d'un bouton, c'est son MOT. Mesuré : une traversée sur « Envoyer » rend 73,7 mais
   délave le mot. La lueur vit DEHORS — 34,4 sur 59 % des pixels, et pas un pixel sur le texte.
   `drop-shadow` et non `box-shadow` : le bouton garde son élévation, et la lueur épouse ses
   coins arrondis sans qu'on les recopie.
   La règle ci-dessous est laissée INERTE (éteinte deux lignes plus bas) : son masque et son
   `inset:0` disent encore comment on dessine un anneau propre, si un objet en redemande un. */
button[data-halo]::before,button[data-halo]::after{
  /* DEHORS (10/09). Un anneau dessiné DANS la carte n'a que sa marge pour vivre : 1,5 px de trait
     sous peine de marcher sur les mots. Dehors, il peut être épais sans toucher une lettre. Deux
     rognages à lever : la carte (`overflow:hidden`) et l'enveloppe (`.obj.ouvre` porte un `clip-path`
     de révélation, `inset(0 round 22px)`, qui couperait tout ce qui dépasse). */
  /* L'ANNEAU (13/09, choix du fondateur devant l'avant/après) : sur le BORD, jamais dehors.
     Le servi d'avant vivait 7 px à l'extérieur avec une nappe de 12 px floutée à 10 px —
     « le halo est trop gros ». Mesuré : 9,7 % des pixels d'une carte allumée. */
  content:"";position:absolute;inset:0;
  border-radius:inherit;pointer-events:none;
  /* LA COMÈTE (10/09, deuxième passe). Le tour d'une aurore bleu-violet, mesuré en temps réel sur la
     vraie carte : 4,1 % des pixels bougent, 58 sur 255 au maximum — « il ne se passe rien ». Ce que
     l'œil suit, c'est une TÊTE brillante sur un anneau presque éteint : ici une tête presque blanche
     (`--lum-encre` mêlée à la lumière), une traînée, puis l'anneau à 16-22 % — jamais nul, sinon un pan
     s'éteint (règle du 07/09). Mesuré : max 159-171, 5,8 % des pixels — trois fois l'aurore. */
  /* DÉGRADÉ ENTIER : tout le pourtour est allumé, ce qui bouge est la POSITION de la couleur,
     pas une tête qui court. Une bande qui traverse un anneau fin ne montre rien (mesuré le
     13/09 : à 520 ms, zéro pixel visible). */
  background:conic-gradient(from var(--halo-a),
    var(--halo-1) 0deg, var(--halo-2) 100.8deg, var(--halo-3) 187.2deg,
    var(--halo-2) 266.4deg, var(--halo-1) 360deg);
  opacity:.85;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
  animation:halo-tourne var(--halo-tour,14s) linear infinite;}
/* ⏱ 14/09 : la carte allumée ne débordE plus — la lumière vit DEDANS. */
.obj:has(> [data-halo]){clip-path:none;}
button[data-halo]::before{padding:var(--halo-ep,1.5px);z-index:2;}
/* ── LA LUEUR DU BOUTON (fondateur, 14/09) — elle remplace l'anneau, et elle l'éteint ── */
button[data-halo]::before,button[data-halo]::after{display:none;}
@keyframes halo-lueur{
  0%,100%{filter:drop-shadow(0 0 3px color-mix(in srgb,var(--halo-1) 55%,transparent));}
  50%{filter:drop-shadow(0 0 14px var(--halo-1))
             drop-shadow(0 0 26px color-mix(in srgb,var(--halo-3) 75%,transparent));}}
/* La NAPPE est retirée (13/09) : un `::after` flouté de 12 px fabriquait un pâté hors du contour
   — « un gros tas, ce n'est vraiment pas joli » — et c'est l'interdit n°3 de la doctrine. */
button[data-halo]::after{display:none;}
/* ⏱ LE SOUFFLE DURE 5 s (fondateur, 09/09, après avoir vu cinq vitesses côte à côte en mouvement).
   Il était à 11 s depuis le 08/09 — et le 09/09, sur la production : « je n'ai aucun effet de halo ».
   La cause n'était NI l'intensité NI la couleur, les deux qu'on avait montées trois fois : c'était la
   VITESSE. Mesuré en pixels — l'amplitude est de 18 à 31 sur 255 dans les quatre designs, largement
   au-dessus du seuil, mais la lumière ne parcourait que 1,4 % de sa plage PAR SECONDE. L'œil s'adapte
   à une dérive aussi lente : il ne la voit pas, il ne peut que la découvrir en revenant dessus.
   À 5 s : 1,8 %/s. C'est son œil qui a tranché, sur les objets en mouvement — pas mon seuil calculé,
   qui donnait 3 s. Voir `scripts/banc-fil/audit-halo.js`. */
/* ══ LE HALO D'UN BOUTON EST UNE LUEUR, PAS UN ANNEAU (fondateur, 09/09) ══════════════════
   Deux remarques, dans cet ordre. « Du vert et du halo, ça ne passe pas » : l'anneau imposait
   les couleurs du DESIGN à un objet qui a la sienne. Puis, l'anneau aminci et reverdi :
   « on ne voit pas de mouvement » — et il avait raison. MESURÉ en pixels sur huit instants du
   cycle (écart moyen sur 255 · part des pixels qui bougent) : anneau fin 2,4 sur 7 % · anneau
   d'avant 12,6 sur 30 % · le bouton qui respire 10,8 sur 49 % · LA LUEUR 16,2 sur 36 % · la
   lumière qui traverse 44,4 sur 48 %. Il a choisi la lueur.
   La cause n'était pas la couleur, c'était l'AIRE : un trait de 1,5 px n'a pas assez de surface
   pour qu'un souffle de 11 s se perçoive. Sur une carte la nappe couvre de l'aire ; sur un
   bouton, un anneau n'en a presque pas.
   `drop-shadow` et non `box-shadow` : le bouton garde ainsi la sienne (l'élévation), et la lueur
   épouse ses coins arrondis sans qu'on ait à les recopier. */
/* SUR FOND SOMBRE, LA LUEUR PORTE MOINS (fondateur 09/09 : « remonte-la »). Mesuré en pixels sur la
   vraie app : 15,5 en Halo clair contre 12,2 en Halo — un vert sur bleu nuit a moins de marge de
   luminance au creux. On pousse donc le SOMMET, jamais le creux : remonter le creux réduirait
   l'amplitude au lieu de l'augmenter. */
/* LA COULEUR VIENT DE L'OBJET. Le bouton qui paie est vert (`--btn-argent-bg`, #5fe3b2 → #22c08a) ;
   celui qui envoie est bleu (`.btn-n{background:var(--light)}`) et prend donc le défaut ci-dessus. */
/* la nappe respire dans la même mesure, sans dépasser son opacité de repos */
/* mouvement réduit : la lumière ne respire plus, l'objet reste MARQUÉ — l'anneau ne disparaît pas */
@media (prefers-reduced-motion:reduce){
  /* la lueur cesse de respirer et se fige À SON SOMMET : l'objet reste MARQUÉ, on ne lui
     retire qu'un mouvement (règle de zone, `public-fil/AGENTS.md`). */
  button[data-halo]{animation:none;
    filter:drop-shadow(0 0 10px var(--halo-1))
           drop-shadow(0 0 20px color-mix(in srgb,var(--halo-3) 60%,transparent));}
  /* la traversée se fige À SA FIN — hors de l'objet — et le liseré reste allumé : l'objet
     demeure MARQUÉ, on ne lui retire qu'un mouvement (règle de zone, `public-fil/AGENTS.md`). */
  [data-halo]:not(button)::before,.card[data-halo]:not(button)::before{
    animation:none;transform:translateX(195%);}}

/* ══════════════════════════════════════════════════════════════════════════════════════
   LES PANNEAUX EN OBJETS (08/09) — « Mon compte » n'avait AUCUN objet : des intertitres et
   des boutons posés à même le fond. Mesuré : 0 objet, 5 éléments nus, à l'identique dans
   les quatre designs. Il n'y avait rien à teindre, donc aucun réglage de couleur ne pouvait
   le changer. Une section = une carte : c'est ce qui rend un design visible.
   Les classes du bon de marchandise sont réutilisées telles quelles (`.bandeau-n`, `.pied-n`,
   `.note-n`, `.btn-n`) — un deuxième jeu aurait divergé au premier réglage de teinte.
   ══════════════════════════════════════════════════════════════════════════════════════ */
.dcorps .p-obj{margin:0 0 12px;padding:0 12px 10px;display:flex;flex-direction:column;gap:7px;}
.p-obj .p-champs{display:grid;gap:7px;}
.p-obj .lv-dit:empty{display:none;}
/* des ITEMS courts, pas de la prose : le fait, puis le pourquoi en trois mots (registre d'une
   page de réglages — le fondateur : « c'est pas comme ça que communique Claude ou GPT ») */
.p-it{font-size:var(--t-foot);color:var(--ink);line-height:1.45;padding:8px 2px;
  border-top:1px solid var(--edge-2);}
.bandeau-n + .p-it{border-top:0;}   /* `:first-of-type` compte le TYPE : le premier div est le bandeau */
.p-it i{font-style:normal;color:var(--ink-3);}
.p-note{font-size:var(--t-cap);color:var(--ink-3);line-height:1.45;padding:4px 2px 0;margin:0;}
/* L'ACTE GRAVE (« Supprimer le compte ») : depuis le lot 3 de la doctrine de l'écran, une rangée rouge seule dans son bloc
   (`.dgroupe .dg-rouge`), sa conséquence dessous — et toujours la réécriture de l'e-mail avant l'effacement. */

/* ══════════════════════════════════════════════════════════════════════════════════════
   LA LUMIÈRE TRAVERSE LES LETTRES (fondateur, 08/09 : « lapin + texte »)
   Le lapin porte la lumière à gauche ; la phrase en cours la porte aussi, de gauche à droite.
   Le mouvement est DANS ce qu'il dit : c'est en train de se produire.

   Trois précautions, chacune payée d'avance :
    1. `background-clip:text` rend le texte TRANSPARENT — un navigateur qui l'ignore effacerait
       la phrase. Tout tient donc dans un `@supports`, et rien ne change sans lui.
    2. `.entre` et `.sort` portent leur propre `animation`, qui est un RACCOURCI : elle écrase.
       La lumière est donc redite dans `.entre` — et comme fil.js ne retire jamais cette classe,
       sans ça elle ne s'allumerait JAMAIS sur la phrase en cours.
    3. Le dégradé part de `currentColor` : le régime Ultra teinte par `color`, il garde donc
       sa couleur ici comme ailleurs.
   ══════════════════════════════════════════════════════════════════════════════════════ */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .travail .ph span:not(.cur){
    /* ⚠️ LA POLARITÉ DÉCIDE, PAS LE GOÛT. Mesuré le 08/09 : une bande claire sur un fond clair
       EFFACE la phrase — elle tombait de 5,41 à 3,23 en Clair, sous le seuil. `--halo-lettre` vaut
       l'encre forte sur fond clair (la bande FONCE) et la lumière du halo sur fond sombre (elle
       éclaire). Calculé : sous la bande, le contraste MONTE partout — 5,41→9,49 · 9,49→10,17 ·
       6,00→9,66 · 11,55→12,73. Jamais moins qu'au repos. */
    background:linear-gradient(100deg, currentColor 0 40%,
      color-mix(in srgb, var(--halo-lettre) 55%, currentColor) 47%,
      color-mix(in srgb, var(--halo-lettre) 55%, currentColor) 53%, currentColor 60%);
    background-size:280% 100%;
    -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
    animation:travail-lumiere 3.4s linear infinite;}
  .travail .ph span.entre:not(.cur){animation:tv-entre .3s var(--e-main) both, travail-lumiere 3.4s linear infinite;}
  .travail .ph span.sort:not(.cur){animation:tv-sort .26s var(--e-main) both;}
  @keyframes travail-lumiere{from{background-position:120% 0;}to{background-position:-60% 0;}}
  /* mouvement réduit : la spécificité de `.entre`/`.sort` (0,3,1) battait `.travail .ph span`
     (0,2,1) — le texte continuait de GLISSER dans le seul mode où on promet que rien ne bouge. */
  @media (prefers-reduced-motion:reduce){
    .travail .ph span,.travail .ph span.entre,.travail .ph span.sort{
      animation:none;-webkit-text-fill-color:currentColor;background:none;}
  }
}



/* ══════════════ L'ENTRÉE DU FIL — le trait, à chaque ouverture ══════════════
   Fondateur, 10/09, après l'avis de sa femme (« le logo devant nous, qui apparaît dans le fil,
   c'est mieux que le texte ») : « pourquoi il ne viendrait pas tout le temps ? Ça fait marque. »
   La Terre (09/09, une fois par jour — 2 s de rideau, une image à charger, une course perdue sur
   un lien lent) est retirée, son image aussi. Ce qui reste : A — Le trait
   (docs/mockups/entree-propositions-v1.html), porté ici avec de VRAIES durées :
     · 0 → 520 ms : la marque s'écrit d'un seul geste — le tracé `#head` est FERMÉ, la main ne
       se lève jamais : c'est une signature, pas un dessin (stroke-dasharray sur pathLength=100) ;
     · le voile (l'air du Fil) est plein 330 ms puis s'efface jusqu'à 600 ms : le Fil est là dessous
       pendant que la main finit son geste ;
     · 520 → 880 ms : il se range dans l'avatar du premier message — la cible est MESURÉE par le
       script de tête (translate + scale posés en style, transition ici), jamais une valeur devinée ;
     · l'avatar du premier message ne s'allume qu'à l'instant où le trait s'y pose (`entree-posee`).
   Un tap coupe tout ; `prefers-reduced-motion` ne joue rien ; une fois par session (script de tête).
   Garde : tests/unit/entree-trait.test.js (elle EXÉCUTE le script de tête, lit ces durées, refuse
   deux fois le même nom d'animation, et refuse toute trace de la Terre).
   ═══════════════════════════════════════════════════════════════════════════════════════ */
/* les durées de l'entrée vivent ICI, à un seul endroit (SOCLE §5) : trait, voile, pose */
/* 520 + 360 = 880 ms nominal — mesuré au banc (WebKit, 10/09) : le tracé, qui anime `stroke-dashoffset` sur le
   fil principal, GÈLE ~270 ms pendant que fil.js (676 Ko) se charge ; avec 620 + 400 la seconde était dépassée. */
:root{--E-trait:520ms;--E-voile:600ms;--E-pose:360ms}
html.entree-vue .entree{display:none}
.entree{position:fixed;z-index:90;inset:0;overflow:hidden;pointer-events:none}
.entree .voile{position:absolute;inset:0;background:var(--air);animation:voile var(--E-voile) linear both}
@keyframes voile{0%,55%{opacity:1}100%{opacity:0}}   /* plein 330 ms → parti à 600 ms */
/* le tracé `#head` n'est pas centré dans son viewBox : son encre va de x 29,8 à 79,9, centre 54,8.
   La boîte est décalée de 8,6 px pour que ce soit L'ENCRE qui tombe au milieu de l'écran. La cible
   (avatar, même viewBox) porte le même décalage à son échelle : aligner les boîtes aligne l'encre. */
.entree .glyphe{position:absolute;left:50%;top:36vh;width:180px;height:180px;margin-left:-98.6px;
  transform-origin:50% 50%;overflow:visible;
  transition:transform var(--E-pose) cubic-bezier(.22,.92,.26,1) /* --e-pouce */}
.entree .glyphe use{fill:none;stroke:var(--light);stroke-width:4;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:100;stroke-dashoffset:100;filter:drop-shadow(0 0 7px var(--glow));
  animation:g-trace var(--E-trait) cubic-bezier(.22,.86,.28,1) /* --e-main */ both}
@keyframes g-trace{from{stroke-dashoffset:100}to{stroke-dashoffset:0}}
/* la couche ne meurt qu'APRÈS que l'objet s'est posé : le vrai avatar s'allume dans la même
   fenêtre, à la même place — la couture est un fondu entre deux choses superposées. */
html.entree-posee .entree{opacity:0;transition:opacity 180ms linear}
html:not(.entree-vue):not(.entree-posee) .thread .r .av{opacity:0}   /* tous : seul le premier message en a un dans la première seconde */
/* ══════════ MOUVEMENT RÉDUIT — pas d'entrée du tout, jamais une version plus lente ══════════ */
@media (prefers-reduced-motion:reduce){
  .entree{display:none}
  /* l'avatar gardait `w-in` avec son délai de 800 ms : sous mouvement réduit il
     serait encore APPARU en fondu. Mesuré par emulateMedia — une animation restait. */
  .w,.bulle .av{animation:none;opacity:1}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   LA LUMIÈRE — direction A « verre et lumière » (fondateur, 10/09 : « je préfère le A »)
   ═══════════════════════════════════════════════════════════════════════════════════════
   Le 09/09 au soir, sur la production : « les couleurs du halo ne sont pas modernes. Le bleu
   pâle comme ça, il n'y a pas de lumière, pas de dégradé […] même la petite barre en bas […]
   rien n'est moderne. » Critique de l'existant AVANT toute maquette (leçon du 04/09), valeur par
   valeur : un TRAIT pâle dessinait la barre (`border:1px solid var(--edge)`, 24 % d'opacité) ; le
   bouton d'envoi était un DISQUE terne (`#9FE1FF`, `box-shadow:none`) — l'action principale, et
   l'objet le moins vivant de l'écran ; une seule teinte partout ; la barre posée, pas flottante.
   Et le contour de 2 px que le fondateur voyait sur le champ était l'anneau de FOCUS (l. 2112).

   UN SEUL OBJET à la fois — la barre d'abord. Le halo prendra ensuite la même lumière, puis les
   cartes, puis l'en-tête. Jamais 26 moments d'un coup.

   Ce bloc est EN FIN de fichier à dessein : `.composer .barre` (l. 713) et la couche du 05/09 ont
   la même spécificité — c'est l'ordre qui tranche, et il tranche pour ce qui est écrit en dernier.
   Retour arrière = retirer le bloc. */

/* La lumière est NOMMÉE une fois, en jetons — le bouton d'envoi la porte aujourd'hui, le halo la
   portera demain : une seule lumière dans l'app, pas deux systèmes de couleur côte à côte.
   Le reflet, le liseré et les ombres sont des jetons AUSSI : les règles ci-dessous n'écrivent aucune
   couleur en dur, et le sombre se règle ici, pas par une seconde règle qui le redessinerait. */
:root{--lum-1:#2F7BFF;--lum-2:#2358E6;--lum-3:#6A5CFF;--lum-glow:rgba(47,123,255,.75);--lum-encre:#FFFFFF;
  --lum-reflet:rgba(255,255,255,.55);--lum-lisere:rgba(255,255,255,.10);
  --lum-ombre:rgba(10,26,60,.55);--lum-ombre-2:rgba(10,26,60,.30);--lum-nappe:transparent;
  --lum-verre:78%;}
/* MESURÉ AU BANC (10/09) : sur fond clair, une flèche blanche sur le cyan #5EE0FF tombait à 2,05 de
   contraste — sous les 3:1 d'un composant d'interface. En CLAIR le dégradé part donc du bleu franc
   (#2F7BFF → #2358E6 → #6A5CFF : blanc ≥ 3,9 partout) ; le reflet cyan reste au SOMBRE, où il
   mesurait 4,33. Une lumière, deux calibrages — comme la lueur du halo. */
:root[data-theme="halo"],:root[data-theme="dark"]{
  --lum-1:#5EE0FF;--lum-2:#2F7BFF;--lum-3:#6A5CFF;
  --lum-reflet:rgba(255,255,255,.16);--lum-lisere:rgba(159,225,255,.10);
  --lum-ombre:rgba(0,0,0,.75);--lum-ombre-2:transparent;--lum-nappe:rgba(120,140,255,.28);
  --lum-verre:70%;}

/* la barre flotte : le fil se voit flou derrière elle ; son arête est un REFLET, pas un contour */
.composer .barre{border:0;padding:6px;border-radius:999px;
  background:color-mix(in srgb, var(--pane) var(--lum-verre), transparent);
  -webkit-backdrop-filter:blur(18px) saturate(1.4);backdrop-filter:blur(18px) saturate(1.4);
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--lum-lisere),
             0 12px 34px -14px var(--lum-ombre), 0 2px 8px -4px var(--lum-ombre-2),
             0 0 32px -10px var(--lum-nappe);}
/* le focus se dit par une lueur sur la barre entière, plus par un trait de 2 px sur le champ —
   il reste VISIBLE (accessibilité), il n'est plus un contour */
.composer .barre:focus-within{
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--lum-lisere),
             0 0 0 3px color-mix(in srgb, var(--lum-2) 40%, transparent),
             0 12px 34px -14px var(--lum-ombre);}
.composer input.field:focus-visible{outline:none;}
.composer .field{color:var(--ink-2);}

/* le bouton d'envoi est l'objet le plus VIVANT de l'écran : un vrai dégradé, et sa lueur.
   ⚠️ On ne touche PAS à `--btn-plein-bg` : la décision du 05/09 (un bouton plein aplat #12719E)
   vaut pour tous les autres boutons. Le dégradé est propre à celui-ci. */
.composer .send{
  background:linear-gradient(140deg, var(--lum-1) 0%, var(--lum-2) 58%, var(--lum-3) 100%);
  /* ⚠️ pas `--light-hi` : en clair c'est un cyan (#4FB6E6), et la flèche tombait à 2,54 sur le bleu.
     L'encre de la lumière est un jeton à elle — blanche dans les quatre designs. */
  color:var(--lum-encre);
  box-shadow:0 8px 22px -8px var(--lum-glow), inset 0 1px 0 var(--lum-reflet);}
.composer .send:active{filter:brightness(.92);}
.composer .cam,.composer .plus{color:var(--ink-2);}

/* ── LE HALO PREND LA LUMIÈRE DE LA BARRE (fondateur, 10/09 : « ok fais le halo ») ──────────
   Sa plainte du 09/09 : « les couleurs du halo ne sont pas modernes. Le bleu pâle comme ça, il n'y
   a pas de lumière, pas de dégradé. » Deux causes mesurées : `--halo-1/2/3` étaient un bleu pâle
   propre à chaque design ; et le VOILE — la seule partie du halo qui ait de l'aire — ne portait
   qu'une couleur, le dégradé vivant sur un anneau de 1,5 px que personne ne voit.
   Une seule lumière dans l'app : le halo lit `--lum-*`. `:root[data-theme]` couvre les quatre
   designs à la même spécificité que leurs blocs (0,2,0) — écrit en dernier, il gagne. Le voile,
   lui, porte désormais deux couleurs (voir `halo-veille`) : la lumière en haut, sa sœur en bas. */
:root[data-theme]{--halo-1:var(--lum-1);--halo-2:var(--lum-3);--halo-3:var(--lum-2);}

/* ── LE BOUTON PORTE LA MÊME COMÈTE (fondateur, 10/09 : « c'est parfait, c'est ça que je veux […]
   ça se fixe sur autre chose, sur le bouton, quand il a fini de remplir »). Mesuré sur les sept
   objets : la comète tournait sur les cartes et, sur le bouton, la lumière RESPIRAIT encore —
   deux langues pour un signal, ce que le 08/09 interdisait. La lueur qui respire est retirée.
   Serrée : le bouton vit dans une carte qui rogne à ~10 px sous lui. Et dans SA couleur : le
   vert de l'argent sur « Payer » — « du vert et du halo, ça ne passe pas » (09/09). */
/* ⏱ 14/09 — SON TOUR REVIENT À 6 s, et c'est une régression que je répare : le 13/09 je
   l'avais porté à 14 s pour suivre la doctrine lumière §4, SANS mesurer. L'audit re-pointé
   le lendemain le lit à 0,3-0,7 %/s contre un seuil de 2,5 : un tour de 14 s sur un anneau
   de 1,2 px ne se voit pas bouger. La doctrine avait écrit le risque elle-même (§6 : « c'est
   peut-être sous le seuil, et personne ne le sait encore »). Maintenant on le sait.
   Les 14 s ne concernaient de toute façon plus que lui : les cartes portent la traversée. */
button[data-halo]{position:relative;--halo-ep:1.2px;--halo-r:12px;--halo-tour:6s;
  animation:halo-lueur var(--halo-souffle,3s) ease-in-out infinite;}
.cta-plein.vert[data-halo],.cta-payer[data-halo],.cmd-valider[data-halo]{--halo-1:#2ACB95;--halo-2:#1F7A4D;--halo-3:#7ED9B0;}

/* ── LA CARTE : UNE ARÊTE DE LUMIÈRE, PAS UN TRAIT DESSINÉ (fondateur, 10/09 : « ok go » sur
   « les cartes — une arête de lumière à la place du trait dessiné »). Troisième objet de « rien
   n'est moderne », après la barre et le halo. Le bord était un trait (`--carte-edge`) plus une tranche
   sombre de 2 px : la même langue que la barre d'avant. Ici, la carte parle celle de la barre
   d'aujourd'hui — reflet d'un pixel en haut, liseré à peine là, ombre portée — avec SES jetons
   (`--lum-*`), pas un second système. La géométrie ne bouge pas : les largeurs de bordure restent
   (1 / 1 / 2 px), seule la couleur s'efface, et le fond s'arrête au padding pour que le reflet vive
   AU bord. Mesuré au banc, même cadre : le trait 41,6 → 15,3 (Halo clair), 38,3 → 18,4 (Halo) — ce
   qui reste est le dégradé de l'ombre ; la définition surface/page ne baisse pas ; zéro décalage.
   La carte ALLUMÉE garde le voile du halo : les règles d'ombre excluent `[data-halo]`. */
:root{--carte-lisere:var(--lum-lisere);}
:root[data-theme="halo"],:root[data-theme="dark"]{--carte-lisere:var(--lum-lisere);}
.card,.dobj.teinte{border-color:transparent;background-clip:padding-box;}
.card:not([data-halo]),.dobj.teinte:not([data-halo]){
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere),
             0 12px 30px -14px var(--lum-ombre), 0 2px 8px -4px var(--lum-ombre-2);}
.tranche .card:not([data-halo]){
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere),
             0 18px 40px -16px var(--lum-ombre), 0 5px 12px -6px var(--lum-ombre-2);}
.card.note:not([data-halo]){
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere),
             0 4px 10px -6px var(--lum-ombre);}

/* ── LE DISQUE DU LAPIN : la même lumière que la barre et les cartes (10/09, quatrième objet de
   « rien n'est moderne »). Le logo qui EST le bouton de l'espace était un aplat `--pane-2` cerné
   d'un trait, sans ombre, le lapin dans l'ancien bleu-vert (`--light`) et un `drop-shadow` posé sur
   `--glow` — transparent dans les quatre designs depuis le 05/09 : une lueur morte. Il parle
   maintenant la langue de la barre : verre au même dosage (`--lum-verre`, le fil flou derrière),
   reflet d'un pixel, liseré des cartes, ombre de la lumière ; et le lapin PREND la lumière — le bleu
   franc en clair, le cyan en sombre. La géométrie ne bouge pas (44 px, la bordure garde sa largeur).
   Mesuré au banc, même cadre : trait 13,7 → 1,1 (Halo clair), 40,9 → 21,1 (Halo) ; contraste du
   lapin 4,6 → 5,4 · 3,2 → 5,4 · 9,6 → 10,7 · 7,4 → 11,3. En sombre, le disque tient par son arête,
   plus par son aplat (définition disque/fond 27 → 14) — à l'œil du fondateur. */
:root{--disque-encre:var(--lum-2);}
:root[data-theme="halo"],:root[data-theme="dark"]{--disque-encre:var(--lum-1);}
.apphead #menubtn{border-color:transparent;background-clip:padding-box;
  background:color-mix(in srgb, var(--pane) var(--lum-verre), transparent);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere),
             0 8px 20px -10px var(--lum-ombre), 0 2px 6px -3px var(--lum-ombre-2);}
.apphead #menubtn:focus-visible{outline-color:var(--disque-encre);}
.apphead svg.mark{color:var(--disque-encre);filter:none;}

/* ── LES CHAMPS : UN CREUX DE LUMIÈRE, PLUS UNE BOÎTE CERNÉE DE GRIS (10/09, cinquième objet de
   « rien n'est moderne »). Trois familles de saisie — le bon de commande (.livi), le fulfillment
   (.ch-n), Mon compte (.dossier .lv input) — étaient trois boîtes cernées d'un trait sur trois fonds
   différents, avec trois focus différents, et un placeholder laissé au navigateur (2,1:1 en clair).
   Une seule recette : un fond légèrement enfoncé, une ombre intérieure d'un pixel en haut, pas de
   trait en clair (un liseré cyan à peine là en sombre) ; au focus, la lueur de la barre — bleu en
   clair, cyan en sombre — sur 3 px, visible ; le placeholder en encre tertiaire, par jeton. La
   géométrie ne bouge pas (bordure gardée, couleur effacée) ; le corps reste --t-champ = 16 px (iOS).
   La couche sombre du 05/09 ne redessine plus le trait par-dessus : .livi et .ch-n sont sortis de
   ses quatre listes — les jetons portent le sombre. Mesuré au banc, même cadre, dpr 3, sur « Prénom » :
   trait 35 → 15 (Halo clair), 41 → 7 (Halo) ; creux/carte 13 → 22 ; placeholder 2,1 → 5,1 ;
   anneau de focus au clavier 1,5 → 3,3 (clair), 5,2 → 5,6 (Halo). */
:root{--champ-fond:color-mix(in srgb, var(--pane-2) 94%, var(--ink-3));--champ-creux:rgba(10,26,60,.18);--champ-lisere:transparent;--champ-focus:color-mix(in srgb, var(--lum-2) 70%, transparent);}
:root[data-theme="halo"],:root[data-theme="dark"]{--champ-fond:color-mix(in srgb, var(--screen) 45%, var(--carte-bg));--champ-creux:rgba(0,0,0,.55);--champ-lisere:rgba(159,225,255,.14);--champ-focus:color-mix(in srgb, var(--lum-1) 70%, transparent);}
.livi,.ch-n,.dossier .lv input{border-color:transparent;background-clip:padding-box;background:var(--champ-fond);
  box-shadow:inset 0 1px 2px var(--champ-creux), inset 0 0 0 1px var(--champ-lisere);}
.livi:focus-visible,.ch-n:focus,.ch-n:focus-visible,.dossier .lv input:focus-visible{outline:none;border-color:transparent;
  box-shadow:inset 0 1px 2px var(--champ-creux), 0 0 0 3px var(--champ-focus);}
.livi::placeholder,.ch-n::placeholder,.dossier .lv input::placeholder{color:var(--ink-3);opacity:1;}

/* ── LA BULLE DU CLIENT : l'arête de lumière des cartes (10/09, sixième objet de « rien n'est
   moderne »). Ce que le client écrit était cerné d'un trait (`--edge-2`), juste au-dessus des cartes
   qui n'en ont plus. La bordure garde sa largeur et perd sa couleur ; un reflet d'un pixel en haut,
   l'ombre de la lumière. PAS de liseré ici : mesuré au banc, le liseré des cartes redessinait un trait
   plus fort que l'ancien sur une bulle déjà bien définie par son fond (11,5 → 16,6 en Sombre). Sans
   lui : trait 19,7 → 0,2 (Halo), 11,5 → 0,4 (Sombre), 6,1 → 0,3 (Clair) ; définition et contraste du
   texte inchangés. Le fond et l'encre (`--bulle-bg`, `--bulle-ink`) restent la décision du 05/09. */
.u{border-color:transparent;background-clip:padding-box;
  box-shadow:inset 0 1px 0 var(--lum-reflet), 0 8px 20px -12px var(--lum-ombre), 0 2px 6px -4px var(--lum-ombre-2);}

/* ── LA FICHE : SANS LES LIGNES, SES CONTRÔLES DANS LA LANGUE DE LA BARRE (10/09, septième objet de
   « rien n'est moderne »). Compté sur le vrai DOM, dépliants ouverts : six familles de traits. Devant
   « sans les lignes » et « avec un fil de lumière », le fondateur : « on voit pas la différence » —
   mesuré 0,3 % des pixels entre les deux ; les séparateurs sont retirés (3 dépliants, 2 rangées, le
   haut du pied). Les sélecteurs de variantes et le stepper prennent le creux des champs ; les options
   de pack, l'arête des cartes (l'option choisie : l'anneau de la lumière, plus un trait bleu) ; la
   photo se définit seule, avec l'ombre ; le pied garde sa bande, son bord devient un reflet. Tout sous
   `#fiche` : c'est l'objet, et ses règles de base (`.fcarac.evpli .evas`, 0,3,0) battraient une règle
   nue. Les quatre listes du sombre qui redessinaient le bord des sélecteurs sont retirées — les jetons
   portent le sombre. `.pack-opt` sert aussi aux paliers des formules : eux ne bougent pas ici. */
#fiche select.evas,#fiche .evstep{border-color:transparent;background-clip:padding-box;background:var(--champ-fond);
  box-shadow:inset 0 1px 2px var(--champ-creux), inset 0 0 0 1px var(--champ-lisere);}
#fiche select.evas:focus-visible{outline:none;box-shadow:inset 0 1px 2px var(--champ-creux), 0 0 0 3px var(--champ-focus);}
#fiche .pack-opt{border-color:transparent;background-clip:padding-box;
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 8px 20px -12px var(--lum-ombre);}
#fiche .pack-opt[aria-pressed="true"]{border-color:transparent;
  box-shadow:inset 0 1px 0 var(--lum-reflet), 0 0 0 2px var(--champ-focus), 0 8px 20px -12px var(--lum-ombre);}
#fiche .egal-main{border-color:transparent;box-shadow:0 12px 30px -14px var(--lum-ombre);}
#fiche .fpied{border-top-color:transparent;box-shadow:inset 0 1px 0 var(--lum-reflet);}
#fiche details.fcarac,#fiche .row{border-top-color:transparent;}

/* ── LES FORMULES : les paliers, même pièce que les options de la fiche (10/09, huitième objet de
   « rien n'est moderne »). « Ta formule » — l'objet où le halo vient quand il faut choisir un plan —
   alignait trois paliers cernés d'un trait, le choisi souligné d'un trait bleu (mesuré 86 / 101 sur
   255), alors que la même pièce (`.pack-opt`) porte l'arête des cartes dans la fiche depuis ce matin.
   Une pièce, une langue : reflet, liseré des cartes, ombre de la lumière ; le palier choisi prend
   l'anneau de la lumière (`--champ-focus`). La géométrie ne bouge pas. */
.card[data-famille="palier"] .pack-opt{border-color:transparent;background-clip:padding-box;
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 8px 20px -12px var(--lum-ombre);}
.card[data-famille="palier"] .pack-opt[aria-pressed="true"]{border-color:transparent;
  box-shadow:inset 0 1px 0 var(--lum-reflet), 0 0 0 2px var(--champ-focus), 0 8px 20px -12px var(--lum-ombre);}

/* ── CLAIR ET SOMBRE : LA LUMIÈRE, PAS L'AURORE (fondateur, 10/09 : « dans le mode clair et sombre,
   j'avais défini aussi un halo pour les cartes […] elle n'était pas colorée, c'était de la lumière »).
   Le 08/09 : une lumière d'une seule teinte pour Clair et Sombre, l'aurore à trois couleurs pour les
   deux Halo — seule la couleur suit le design. Le 10/09, « une seule lumière dans l'app » avait mis
   l'aurore partout. Mesuré en temps réel sur le bon de commande : en Clair le blanc pur est INVISIBLE
   (85 / 0,7 % des pixels, contre 160) — une page presque blanche ne reçoit pas une lumière blanche ;
   une seule teinte bleue reste visible (142). En Sombre, la lumière blanche avec son anneau cyan est la
   plus visible (190). Même comète, même vitesse, mêmes objets : la couleur seule change. Ces deux
   règles viennent APRÈS `:root[data-theme]{--halo-*:var(--lum-*)}` : même spécificité, l'ordre tranche. */
:root[data-theme="light"]{--halo-1:#2F7BFF;--halo-2:#2F7BFF;--halo-3:#7FA6FF;}
:root[data-theme="dark"]{--halo-1:#FFFFFF;--halo-2:#5EE0FF;--halo-3:#FFFFFF;}

/* ═══ LA LANGUE PARTOUT (fondateur, 10/09 : « tu ne veux pas me proposer tout d'un coup ce qu'il y a
   dans l'app ? […] à chaque fois que je te dis quelque chose pour un bouton, il faut voir pour les
   quatre thèmes […] tout doit être harmonisé »). Après neuf objets un à un, le reste d'un coup, par
   famille, avec les recettes déjà validées — les mêmes jetons dans les quatre designs.
   Compté sur le vrai DOM avant : 10 à 19 éléments encore cernés d'un trait par écran (puces de niche,
   « garder », badges, en-tête, menu…). Chaque sélecteur reprend EXACTEMENT celui de sa règle d'origine
   (même spécificité : l'ordre tranche). ═══ */

/* ── A. Les puces et les petits boutons : du verre, un reflet, plus de contour. */
.pill,.sugg button,.composer .recentes-i,.fsplit .fchip,.feuille .pi,.dossier .dclose,#aubas,.evqte .evq,
.dmenu button,.dbandeau button,.dossier .dcorps > button[data-menu-action],body.direct #sortir,.replay,.card.naiss .btn-n.sec,.card[data-role="connexion"] .btn-n.sec,.fiche .foqenv,
.btn.ghost,.cta-sec,.dossier .abo-offre,.gal figcaption,.cmd{
  border-color:transparent;background-clip:padding-box;
  background:color-mix(in srgb, var(--pane) var(--lum-verre), transparent);
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 4px 12px -8px var(--lum-ombre);}
/* les étiquettes (« vu le… », « en ligne ») : une teinte de leur propre couleur, plus de contour */
.dbadge,.dbadge.vif{border-color:transparent;background:color-mix(in srgb, currentColor 12%, transparent);}
/* deux traits verticaux qui servaient de séparateur dans une carte */
.card.rcand .garder,.dcand .dprise{border-left-color:transparent;}

/* ── B. Les surfaces : l'arête des cartes. */
.app-menu,.feuille,.issues,.gal,.decomp,.plan-detail-panel,.envoi-photo,.dobj,.menu-vign img,.ddetail .qc-gal img,
.dtik .dvg,.dcand .dvg,.egal-th,.evar-btn .im,.card.naiss .adr-n,.evt,.evqte .evqi,.card[data-kind="candidate"][data-verdict],.screen{
  border-color:transparent;background-clip:padding-box;}
.app-menu,.feuille{box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 24px 60px -24px var(--lum-ombre);}
.issues,.gal,.decomp,.plan-detail-panel,.envoi-photo,.dobj:not([data-halo]),.card.naiss .adr-n,.evt,.evqte .evqi,.egal-th,.evar-btn .im,.dtik .dvg,.dcand .dvg{
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 8px 20px -12px var(--lum-ombre);}
.card[data-kind="candidate"][data-verdict]:not([data-halo]){
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 12px 30px -14px var(--lum-ombre), 0 2px 8px -4px var(--lum-ombre-2);}

/* ── C. Les séparateurs : retirés (« on voit pas la différence » avec un fil, mesuré 0,3 %). */
.apphead,.menu-moi,.dossier .dhead{border-bottom-color:transparent;}
.dossier .cmd-l + .cmd-l,.row+.row,.step+.step,.pact+.pact,.dossier .drepli,.dtik+.dtik,.dentree-g+.dentree-g,.ru-g+.ru-g,.dmenu,
.ligne-r,.reste-r,.couv-liste .dcand,.ddetail,.ddetail .drow+.drow,.beat,.note,.card.naiss .ligne-n,.p-it{border-top-color:transparent;}
/* le casier (la zone où l'on dépose) garde ses tirets — c'est une affordance — mais dans la couleur de la lumière */
.casier{border-color:color-mix(in srgb, var(--lum-1) 45%, transparent);background:color-mix(in srgb, var(--lum-1) 7%, transparent);}
:root[data-main="survol"] .casier{border-color:var(--lum-1);}
.casier .mini i{border-color:color-mix(in srgb, var(--lum-1) 40%, transparent);}

/* ── REVENTE (10/09) : la barre des tranches dans le dépliant, et la carte du parcours ─────────
   La barre : une largeur par compte, le nombre dedans, le nom dessous ; une tranche vide reste
   dessinée, grise. La carte : trois moments dans un objet (tranche → angle → images), des boutons
   à la taille de leur verbe, une image par tap. Couleurs : la famille « estimé ». */
/* la ligne du dépliant est un flex (libellé + valeur) : la barre et sa légende s'empilent, pleine largeur */
.fiche .fcarac > .row.frbarre{display:block;}
.fiche .frbar{display:flex;gap:3px;height:26px;margin:8px 0 5px;border-radius:7px;overflow:hidden;}
.fiche .frseg{display:flex;align-items:center;justify-content:center;min-width:24px;background:color-mix(in srgb,var(--fam-estime) 30%,transparent);font-size:var(--t-foot);color:var(--ink);}
.fiche .frseg b{font-weight:600;}
.fiche .frseg.vide{background:color-mix(in srgb,var(--ink-3) 16%,transparent);color:var(--ink-3);}
.fiche .frleg{display:flex;justify-content:space-between;gap:6px;font-size:var(--t-foot);color:var(--ink-3);margin-bottom:8px;line-height:1.25;}
.fiche .frleg span{flex:1;text-align:center;} .fiche .frleg span:first-child{text-align:left;} .fiche .frleg span:last-child{text-align:right;}
.fiche .fcarac > .row.frbtn{padding:8px 0 12px;}
.fiche .frbtn .btn-n{--btn-plein-bg:var(--fam-estime);width:auto;padding:0 18px;}
.rv-prod{display:flex;gap:10px;align-items:center;margin:0 0 10px;}
.rv-vig{width:44px;height:44px;border-radius:10px;object-fit:cover;flex:0 0 auto;}
.rv-prod b{display:block;font-size:var(--t-body);font-weight:600;} .rv-prod small{color:var(--ink-3);font-size:var(--t-foot);}
.rv-q{font-size:var(--t-body);margin:6px 0 10px;line-height:1.35;}
.rv-choix{display:flex;justify-content:space-between;align-items:center;gap:10px;width:100%;min-height:48px;padding:10px 14px;margin:6px 0;border-radius:14px;
  border:1px solid color-mix(in srgb,var(--fam-estime) 45%,transparent);background:color-mix(in srgb,var(--fam-estime) 10%,transparent);color:var(--ink);font:inherit;font-size:var(--t-body);text-align:left;}
.rv-choix small{color:var(--ink-3);font-size:var(--t-foot);white-space:nowrap;} .rv-choix.libre small{color:var(--fam-estime);}
.rv-choix[disabled]{opacity:.5;}
.rv-note{color:var(--ink-3);font-size:var(--t-foot);margin:8px 0 0;line-height:1.35;}
.rv-fait{margin:4px 0 8px;font-size:var(--t-body);}
.rv-titre{font-size:var(--t-body);font-weight:600;margin:2px 0 4px;}
.rv-prix{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin:0 0 6px;} .rv-prix .ev{font-size:var(--t-large);letter-spacing:var(--t-large-ls);font-weight:600;} .rv-prix .eu{color:var(--ink-3);font-size:var(--t-foot);}
.rv-vivant{min-height:8px;} .rv-vivant .step{margin:6px 0;}
.rv-img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:14px;display:block;margin:10px 0 6px;background:color-mix(in srgb,var(--ink-3) 12%,transparent);}
.rv-vign{display:flex;gap:6px;overflow-x:auto;margin:0 0 8px;padding-bottom:2px;}
.rv-vign img{width:52px;height:52px;border-radius:9px;object-fit:cover;opacity:.65;flex:0 0 auto;background:color-mix(in srgb,var(--ink-3) 12%,transparent);}
.rv-vign img.on{opacity:1;outline:2px solid var(--fam-estime);}
.rv-decor{color:var(--ink-3);font-size:var(--t-foot);margin:0 0 8px;}
.rv-lev{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px;}
.rv-lev button{min-height:40px;padding:8px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--fam-estime) 45%,transparent);background:transparent;color:var(--ink);font:inherit;font-size:var(--t-foot);}
.rv-lev button[disabled],.rv-ligne button[disabled]{opacity:.45;}
.rv-ligne{display:flex;gap:6px;margin:0 0 8px;}
.rv-ligne input{flex:1;min-width:0;min-height:44px;padding:8px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--ink-3) 40%,transparent);background:transparent;color:var(--ink);font:inherit;font-size:var(--t-champ);}
.rv-ligne .btn-n{min-height:44px;padding:0 16px;}
.rv-garde{display:flex;justify-content:space-between;align-items:center;gap:8px;margin:0 0 10px;font-size:var(--t-foot);color:var(--ink-3);}
.rv-garde button{min-height:40px;padding:8px 12px;border-radius:12px;border:1px solid var(--fam-estime);background:transparent;color:var(--fam-estime);font:inherit;font-size:var(--t-foot);white-space:nowrap;}
.rv-garde button.on{background:var(--fam-estime);color:var(--btn-plein-ink);}
.rv-pied{display:flex;flex-direction:column;gap:6px;margin-top:6px;}
.rv-pied .btn-n{--btn-plein-bg:var(--fam-estime);width:auto;align-self:flex-start;padding:0 18px;}
.rv-nu{min-height:44px;padding:0;border:0;background:transparent;color:var(--ink);font:inherit;font-size:var(--t-body);text-decoration:underline;text-underline-offset:3px;text-align:left;}

/* ── LE FOND DES DEUX HALO : UNE LUMIÈRE EN HAUT (fondateur, 10/09 : « c'est normal que le fond soit
   plat ? il n'y a pas de jeu de lumière, pas de dégradé »). Clair et Sombre ont déjà leur ciel (mesuré
   18 puis 46 sur 255 du haut au bas en Clair). Les deux Halo étaient plats — Halo clair par la décision
   du 08/09 (« un champ, pas un ciel »), revue ici par le fondateur devant la mesure. Une lumière qui
   vient d'en haut, au centre, et en Halo clair un bleu plus profond en bas : mesuré au centre, Halo
   11 → 23 en haut ; Halo clair 223 → 231 en haut, 223 → 210 en bas — au-dessus du seuil de 10 qui
   avait condamné le fond du 15/08 (imperceptible). Les étoiles de Halo restent. */
/* 03/10 — LES AURAS B (DA v2 validée par le fondateur sur maquette) remplacent la lumière unique du 10/09 :
   trois lueurs aux couleurs de la marque — cyan en haut à gauche, violet en haut à droite (sombre) ou en
   bas à droite (clair). Garde : da-halo-v2.test.js. */
#monde .monde[data-monde="halo-clair"] .deep{background:
  radial-gradient(75% 42% at 0% 0%, rgba(25,179,230,.45), transparent 70%),
  radial-gradient(60% 40% at 100% 22%, rgba(79,107,255,.32), transparent 70%),
  radial-gradient(85% 45% at 100% 100%, rgba(176,76,255,.36), transparent 70%),
  radial-gradient(70% 40% at 0% 90%, rgba(25,179,230,.18), transparent 70%),
  #FBFCFF;}
#monde .monde[data-monde="halo"] .deep{background:
  radial-gradient(60% 32% at 10% -4%, rgba(60,200,255,.38), transparent 72%),
  radial-gradient(60% 34% at 95% 2%, rgba(150,90,255,.36), transparent 72%),
  radial-gradient(90% 30% at 50% 108%, rgba(200,110,255,.20), transparent 72%),
  #05070F;}

/* ═══ L'ACCORD (fondateur, 10/09 : « go » sur l'avis critique — « qu'on sente une application qui a
   gardé une harmonisation, pas des objets qui n'ont pas de cohérence les uns avec les autres »).
   Quatre points, quatre designs, un dépôt. ═══ */

/* ── 1. UN SEUL BLEU. L'ancien accent (`--light`, le bleu-vert du 05/09) vivait encore dans 117 règles :
   tous les boutons pleins, les liens, « Fonce. », le compteur du dossier (4,03 de contraste), la bulle,
   la coche des paliers. Il devient la lumière — par le JETON, pas règle à règle. Les boutons pleins
   restent plats (05/09) mais dans la lumière ; la bulle prend une teinte de la lumière. Pour le TEXTE et
   les boutons des designs clairs, la même teinte un cran plus profond (#1E4BC4) : mesuré, #2358E6 tombait
   à 3,6 sur le compteur « 0 gardé » posé sur le champ ; #1E4BC4 y fait 5,6, 7,3 sur blanc, et le blanc
   dessus 7,3. La lumière elle-même (barre, halo, focus) reste #2358E6 : une teinte, deux hauteurs. En
   hexadécimal : la garde des contrastes ne mesure que l'hexadécimal. */
:root[data-theme="light"],:root[data-theme="halo-clair"]{--light:#1E4BC4;--light-hi:#2F7BFF;--btn-plein-bg:#1E4BC4;--btn-plein-ink:#FFFFFF;--bulle-bg:#E3EAFC;--bulle-ink:#0F1B2D;}
:root[data-theme="halo"],:root[data-theme="dark"]{--light:#5EE0FF;--light-hi:#FFFFFF;--btn-plein-bg:#5EE0FF;--btn-plein-ink:#07192A;--bulle-bg:#274C72;--bulle-ink:#EEF2FB;}

/* ── 2. TROIS RAYONS (décidés le 05/09, quinze dans le fichier) : --r-2 (12) pour ce qu'on touche,
   --r-3 (18) pour ce qui porte, rond pour les puces. */
.livi,.ch-n,.dossier .lv input,#fiche select.evas,#fiche .evstep,.pack-opt,.sugg button,.dmenu button,.dbandeau button,.cmd,
.evqte .evqi,.card.naiss .adr-n,.dtik .dvg,.dcand .dvg,.menu-vign img,.ddetail .qc-gal img,.gal figcaption,.evt{border-radius:var(--r-2);}
.gal,.issues,.feuille,.plan-detail-panel,#fiche .egal-main,.tranche .card,.card.note,.dossier .abo-offre{border-radius:var(--r-3);}
.app-menu{border-radius:0 var(--r-3) var(--r-3) 0;}
.pill,.composer .recentes-i,.fsplit .fchip{border-radius:999px;}

/* ── 3. LES BANDEAUX DE FAMILLE : la teinte et le glyphe disent la famille ; le trait dessous — tirets,
   double, pointillés selon la famille — était la dernière trace de l'ancienne langue. */
.card[data-famille] > .lab:first-child{border-bottom-color:transparent;}

/* ── 5. LES TIRETS = « dépose ici », dans la lumière (le casier l'est déjà). */
.photo-n .pn-cadre{border-color:color-mix(in srgb, var(--lum-1) 55%, transparent);}
.fiche .retour{border-radius:var(--r-2);}
/* la planche « Lequel ? » de la porte images (10/09) */
.rv-pc{gap:12px;justify-content:flex-start;}
.rv-pct{display:flex;flex-direction:column;min-width:0;} .rv-pct b{font-weight:600;font-size:var(--t-body);overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;} .rv-pct small{color:var(--ink-3);font-size:var(--t-foot);}
.rv-pc .rv-vig{background:color-mix(in srgb,var(--ink-3) 14%,transparent);}

/* ═══ LA LUMIÈRE (10/09, « go je valide ») — trois gestes, mesurés dans le même cadre sur les quatre designs.
   La source ÉMET : le bouton plein, éclairé par le haut depuis SA couleur, sa lueur dessous. Les surfaces REÇOIVENT :
   un voile d'en haut à gauche, une ombre dans la couleur de la lumière. Le fond RESPIRE : trois masses de la lumière
   du design, dans l'écran, au-dessus du seuil de 20 sur 255, suivant l'état de Rabbit (--amb). Le halo reste la seule
   lumière qui se pose sur un objet qui attend. Le quatrième geste (le prix en dégradé) est écarté : un prix n'est pas
   un geste. Relief mesuré : bouton 0 → 45 (clairs) / 34 (sombres) ; carte 0 → 17 / 33 ; fond 10-28 → 42-58. */
:root{--surf-lum:linear-gradient(160deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 52%, color-mix(in srgb, var(--lum-1) 16%, transparent) 100%);--surf-ombre:color-mix(in srgb, var(--lum-2) 45%, transparent);--surf-ombre-2:color-mix(in srgb, var(--lum-2) 26%, transparent);--atmo:1;}
:root[data-theme="halo"],:root[data-theme="dark"]{--surf-lum:linear-gradient(160deg, color-mix(in srgb, var(--lum-1) 22%, transparent) 0%, rgba(255,255,255,0) 58%);--surf-ombre:color-mix(in srgb, var(--lum-1) 34%, transparent);--surf-ombre-2:rgba(0,0,0,.55);}
:root[data-theme="dark"]{--atmo:.5;}
:root[data-theme="halo"]{--atmo:.55;}
:root[data-theme="halo-clair"]{--atmo:.8;}
/* ── 1. LA SOURCE — une seule recette, depuis --plein ; le bouton d'argent y passe avec sa couleur. */
.btn,.btn-n,.cta-plein,.cta-payer,.composer .send,.vcomp u{--plein:var(--btn-plein-bg);--plein-lum:linear-gradient(180deg, color-mix(in srgb, var(--plein) 74%, #FFFFFF) 0%, var(--plein) 50%, color-mix(in srgb, var(--plein) 86%, #000000) 100%);--plein-ombre:inset 0 1px 0 rgba(255,255,255,.55), inset 0 -1px 0 rgba(0,0,0,.12), 0 10px 22px -8px color-mix(in srgb, var(--plein) 55%, transparent), 0 2px 6px -2px color-mix(in srgb, var(--plein) 35%, transparent);background:var(--plein-lum);box-shadow:var(--plein-ombre);}
.cta-plein.vert,.cta-payer{--plein:var(--btn-argent-bg);background:var(--plein-lum);box-shadow:var(--plein-ombre);}
/* ── 2. LES SURFACES — opaques et lisibles ; jamais un objet qui attend (le halo garde son voile). */
.card:not([data-halo]),.dobj.teinte:not([data-halo]),:root[data-theme="dark"] .dobj.teinte:not([data-halo]),.card[data-kind="candidate"][data-verdict]:not([data-halo]),.u,#fiche .pack-opt,.card[data-famille="palier"] .pack-opt,#fiche .fpied,.barre:not([data-halo]),.feuille,.app-menu{background-image:var(--surf-lum);}
.card:not([data-halo]),.dobj.teinte:not([data-halo]),.tranche .card:not([data-halo]),.card.note:not([data-halo]),.card[data-kind="candidate"][data-verdict]:not([data-halo]){box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 18px 40px -16px var(--surf-ombre), 0 2px 8px -4px var(--surf-ombre-2);}
.u{box-shadow:inset 0 1px 0 var(--lum-reflet), 0 14px 30px -14px var(--surf-ombre), 0 2px 6px -4px var(--surf-ombre-2);}
/* ── 3. LE FOND — Clair et Sombre : l'aurore existait (.sky), posée hors d'un écran de 390 px. Dans l'écran, dans la
   teinte du halo du design, elle suit l'état sans redescendre sous le seuil. Les deux Halo : trois masses dans leur monde. */
.sky{inset:0;filter:blur(40px) hue-rotate(var(--amb-rot));opacity:calc(var(--atmo) * (.55 + var(--amb) * .45));}
.c1{left:-12vw;top:6vh;width:92vw;height:72vw;opacity:.9;background:radial-gradient(circle at 42% 42%, color-mix(in srgb, var(--halo-1) 80%, transparent), transparent 66%);}
.c2{left:auto;right:-22vw;top:36vh;width:84vw;height:66vw;opacity:.8;background:radial-gradient(circle at 54% 46%, color-mix(in srgb, var(--halo-2) 70%, transparent), transparent 64%);}
.c3{left:8vw;top:auto;bottom:4vh;width:100vw;height:62vw;opacity:.85;background:radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--halo-3) 65%, transparent), transparent 66%);}
#monde .monde[data-monde="halo"] .deep::before,#monde .monde[data-monde="halo-clair"] .deep::before{content:"";position:absolute;inset:-12%;pointer-events:none;opacity:calc(var(--atmo) * (.55 + var(--amb) * .45));filter:blur(30px);background:radial-gradient(40% 30% at 20% 24%, color-mix(in srgb, var(--halo-1) 60%, transparent), transparent 70%), radial-gradient(44% 34% at 82% 56%, color-mix(in srgb, var(--halo-2) 50%, transparent), transparent 70%), radial-gradient(52% 34% at 42% 98%, color-mix(in srgb, var(--halo-3) 45%, transparent), transparent 70%);animation:nuage 46s ease-in-out infinite alternate;}
@keyframes nuage{to{transform:translate(4%,-3%) scale(1.08);}}
@media (prefers-reduced-motion:reduce){#monde .monde .deep::before{animation:none;}}

/* ── 4. LES CHIFFRES — le prix et le total dans la lumière du design (« go » du fondateur, 10/09 soir) :
   bleu vers bleu profond sur les clairs, blanc vers cyan sur les sombres. Contraste du plus faible arrêt sur
   son fond réel : 5,8 (carte) / 4,4 (pied) sur les clairs ; 9,9 / 7,0 sur les sombres — au-dessus de 3 (gros). */
:root{--chiffre-lum:linear-gradient(180deg, var(--lum-2), var(--light));}
:root[data-theme="halo"],:root[data-theme="dark"]{--chiffre-lum:linear-gradient(180deg, var(--light-hi), var(--light));}
#fiche span.ev,#fiche .fpied span.v{background-image:var(--chiffre-lum);-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;}

/* ═══ LA FICHE À CINQ ONGLETS (fondateur, 11/09 — après le test de l'utilisatrice sur la maquette P1 :
   « les quatre onglets qui glissent, et un cinquième pour poser une question à un humain, qui dépasse,
   pas rétréci »). Sous la photo, le nom et le prix. Quatre onglets visibles à leur taille, la barre défile,
   le cinquième vient sous le doigt ; la piste des panneaux s'aimante panneau par panneau. Chaque onglet a
   sa famille de couleur (les jetons --fam-*), comme les cartes du fil. Préfixe `fo` = fiche-onglets. ═══ */
.fiche .fonglets{display:flex;gap:5px;margin:10px 0 0;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.fiche .fonglets::-webkit-scrollbar{display:none;}
/* 02/10 (fondateur : « ils sont coupés ») — un quart fixe de 69 px rognait le mot et poussait l'icône hors du
   bouton. Chaque onglet prend la largeur de son nom : 335 px à 375, la place exacte ; plus étroit, la barre défile.
   L'icône reste en tête de la carte, plus dans l'onglet. */
.fiche .fong{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:5px;
  padding:9px 8px;border-radius:12px;border:1px solid var(--carte-edge);background:var(--pane-2);color:var(--ink-3);
  font-family:var(--sans);font-size:var(--t-cap);white-space:nowrap;overflow:hidden;cursor:pointer;scroll-snap-align:start;}
.fiche .fong[data-o="vend"]{--fc:var(--fam-argent);}
.fiche .fong[data-o="produit"]{--fc:var(--fam-neutre);}
.fiche .fong[data-o="livraison"]{--fc:var(--fam-estime);}
.fiche .fong[data-o="marque"]{--fc:var(--fam-kraft);}
.fiche .fong[data-o="question"]{--fc:var(--fam-equipe);}
.fiche .fong.on{background:color-mix(in srgb,var(--fc) 18%,transparent);border-color:var(--fc);color:var(--fc);font-weight:600;}
.fiche .fpiste{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch;margin-top:10px;}
.fiche .fpiste::-webkit-scrollbar{display:none;}
.fiche .fpan{flex:0 0 100%;scroll-snap-align:start;min-width:0;padding-bottom:12px;}
.fiche .fpan > details.fcarac{margin-top:8px;}
.fiche .fodit{align-items:flex-start;font-size:var(--t-body);color:var(--ink);line-height:1.4;}
.fiche .fodit .lapin{margin-top:3px;}
.fiche .foavq{margin-top:8px;}
.fiche .foest{color:var(--fam-estime);}
.fiche .fochaud{color:var(--fam-estime);}
.fiche .gris{color:var(--ink-3);font-size:var(--t-foot);}
/* 02/10 — « Tu importes où ? » sous « Les documents d'import » : rattachée à la puce qui l'ouvre, un seul choix. */
.fiche .foq-pays{margin-top:2px;padding-left:10px;border-left:2px solid var(--fam-equipe);}
.fiche .fpan .lab-n{margin-top:12px;}
.fiche .foqtxt,.fiche .foqmail{display:block;width:100%;margin-top:8px;border-radius:12px;border:1px solid var(--carte-edge);background:var(--pane-2);color:var(--ink);
  font-family:var(--sans);font-size:var(--t-champ);padding:10px;}   /* 16 px : jamais de zoom iOS sur un champ */
.fiche .foqtxt{min-height:76px;resize:vertical;}
/* 29/09 (revue) : dans une CARTE du fil — les puces des objets du « + » (plateforme, options, marchandises sensibles) —
   une puce choisie était identique à sa voisine. Même marque que la fiche : un seul langage pour « choisi ». */
.fiche .foqsujets .pill.foqsel,
.card .foqsujets .pill.foqsel{border-color:var(--fam-equipe);color:var(--fam-equipe);}
.fiche .foqfait a{color:inherit;}
.fiche .fpan .lapin.lapin-mini{width:16px;height:16px;flex:none;position:static;}   /* le repère signe la phrase, il ne l'envahit pas */
.fiche .fodit::before,.fiche .fpan > .fact::before{display:none;}                 /* pas de puce devant une phrase de Rabbit */
.fiche .fpan .avq{margin-top:8px;}

/* ═══ MON DOSSIER EN OBJETS (prototype 11/09) — chaque gardé est LA carte du fil : la rangée candidat des
   résultats, avec son verre, son arête, sa lumière ; le tap ouvre la fiche, le ⋯ rouvre ou retire. Plus de
   liste à traits, plus de dépli. Les cartes sont posées en colonne, comme la liste des résultats. ═══ */
.dossier .dliste{display:flex;flex-direction:column;gap:10px;padding:6px 0 0;}
.dossier .dgarde-w{display:flex;flex-direction:column;gap:6px;}
.dossier .card.dgarde{margin:0;min-height:96px;}
/* LA CARTE D’UN PRODUIT DANS UNE CONVERSATION ROUVERTE (tiroir, étape 3, 27/09) : la carte gardée du dossier, posée
   dans le fil (`carteGardeeHTML`) — les règles du dossier la couvrent par les mêmes sélecteurs (la copie d'avant avait
   déjà perdu l'anneau de focus, le pas du `.dmeta` et les flancs sans trait). Ici, ce qui lui est propre : sa marge
   dans le fil, et pas de prise ⋯ à sa droite. */
.rouvert-produit .dgarde .dcand.dcorps-r,.dossier .dgarde .dcand.dcorps-r{background:none;border:0;font:inherit;color:var(--ink);text-align:left;cursor:pointer;}
.rouvert-produit .dgarde .dcand.dinerte,.dossier .dgarde .dcand.dinerte{cursor:default;}
.rouvert-produit .dgarde .dvg,.dossier .dgarde .dvg{width:76px;height:76px;border-radius:var(--r-2);}
.rouvert-produit .card.dgarde{margin:10px 0 0;min-height:96px;}
.rouvert-produit .dgarde .dcand.dcorps-r{padding-right:10px;}
.dossier .dgarde .dprise{flex:none;width:46px;border:0;background:none;color:var(--ink-2);font-size:var(--t-title);font-family:var(--sans);cursor:pointer;display:flex;align-items:center;justify-content:center;}
.dossier .dgarde .dprise:active{background:color-mix(in srgb,var(--light) 8%, transparent);}
.rouvert-produit .dgarde .dcorps-r:focus-visible,.dossier .dgarde .dcorps-r:focus-visible,.dossier .dgarde .dprise:focus-visible{outline:2px solid var(--light);outline-offset:-2px;}
.rouvert-produit .dgarde .dmeta,.dossier .dgarde .dmeta{display:flex;flex-wrap:wrap;gap:4px 8px;align-items:center;margin-top:3px;}
.dossier .dgarde-w > .dmenu{border-top:0;padding:0 2px;gap:8px;}
.dossier .dgarde-w > .dmenu button{background:color-mix(in srgb, var(--pane) var(--lum-verre), transparent);border-color:transparent;box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 4px 12px -8px var(--lum-ombre);border-radius:var(--r-2);}
.dossier .dnote{margin:0 4px;font-size:var(--t-foot);color:var(--ink-2);}
.dossier .dnote[hidden]{display:none;}
.dossier .dbandeau{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:56px;padding:0 14px;border-radius:var(--r-3);background:var(--carte-bg);color:var(--ink-2);font-size:var(--t-foot);}
.dossier .dbandeau button{min-height:40px;padding:0 14px;border-radius:var(--r-2);border:0;background:var(--pane-2);color:var(--ink);font:inherit;font-weight:600;cursor:pointer;}
/* les flancs teintés de la rangée résultat ne se dessinent pas dans le dossier : aucun trait (accord 10/09) */
.rouvert-produit .card.rcand.dgarde[data-kind="candidate"],.dossier .card.rcand.dgarde[data-kind="candidate"]{border-left-color:transparent;border-right-color:transparent;}
.fiche.sur-dossier{z-index:61;}   /* ouverte depuis le dossier (60) : elle passe dessus */
/* chaque onglet est une CARTE du fil (P1 validée par l'utilisatrice, 11/09) : bandeau, glyphe, badge, famille, lumière */
.fiche .fo-carte{margin:8px 0 0;padding:0 14px 12px;}
.fiche .fo-carte .bandeau-n{margin:0 -14px 8px;}
.fiche .fo-carte > .fact{padding:5px 0;}
.fiche .fo-carte .rv-prod{margin:2px 0 6px;}
.fiche .fo-carte .rv-prod b{display:block;font-size:var(--t-head);line-height:1.15;}
.fiche .fo-carte .rv-prod small{display:block;color:var(--ink-3);font-size:var(--t-foot);margin-top:2px;}
.fiche .fo-carte > .row,.fiche .fo-carte .fosynth .row,.fiche .fo-carte .row.frang{display:flex;justify-content:space-between;gap:12px;padding:7px 0;border-top:1px dashed var(--carte-edge);font-size:var(--t-foot);}
.fiche .fo-carte .row .k{color:var(--ink-2);}
.fiche .fo-carte .row .v{font-weight:600;text-align:right;}
.fiche .fo-carte .row.frsyn.frbarre{display:block;}
.fiche .fo-carte .fosynth .row:first-child{border-top:0;padding-top:2px;}
.fiche .fo-carte .avq{margin-top:10px;}
.fiche .fo-carte > details.fcarac{margin:8px 0 0;}
.fiche .pill.plein{background:var(--btn-plein-bg);color:var(--btn-plein-ink);border-color:transparent;font-weight:600;}   /* le seul geste plein d'une carte */
.fiche .fo-carte .fact::before{display:none;}   /* dans une carte d'onglet, une ligne n'a pas de puce : le bandeau tient le rôle */
/* ═══ QUATRE ONGLETS (fondateur, 11/09 : l'analyse · le produit · la livraison · une question — et il commande) ═══ */
.fiche .fpiste{margin-top:14px;}                                   /* la lumière de la carte ne marche pas sur les onglets */
/* ══ CE QUE LES TROIS AUTRES ONGLETS PORTENT — RENDU LE 13/09/2026 ═══════════════════════════
   Ces règles ont été SUPPRIMÉES par erreur en réécrivant la grille au-dessus : elles vivaient
   dans le même bloc, le Fil continuait de les émettre, et Livraison est partie en production
   avec « Par avion15 à 25 jours ». Elles reviennent ici à l'identique de HEAD.
   PÉRIMÈTRE — qui consomme quoi (SOCLE §5, règle du 13/09) :
     .fodit2 (+ .lapin)  → Livraison · Une question · L'analyse (l'avis rédigé, à l'exécution)
     .fofiche/.fofeuille/.fovoile/.fofeuille-corps/.fopoignee → Le produit (la feuille technique)
     .fomode (+ i, b, small, .p) → Livraison, et elle seule
   Garde : tests/unit/fiche-onglets-structure.test.js — elle REND les quatre onglets et exige
   qu'aucune classe émise ne soit sans habit. */
.fiche .fodit2{display:flex;gap:8px;align-items:flex-start;margin-top:8px;padding-top:10px;border-top:1px dashed var(--carte-edge);font-size:var(--t-body);line-height:1.45;color:var(--ink);}
.fiche .fodit2 .lapin{width:18px!important;height:18px!important;flex:none;margin-top:2px;position:static!important;}
.fiche .fodit2 .foavis-v{display:block;margin-bottom:3px;font-weight:700;}   /* le verdict de l'avis, en tête (21/09) */
.fiche .fofiche{display:inline-flex;align-items:center;gap:8px;margin-top:12px;padding:9px 13px;border-radius:12px;border:1px solid var(--carte-edge);background:var(--pane-2);color:var(--ink);font-family:var(--sans);font-size:var(--t-foot);font-weight:600;cursor:pointer;}
.fiche .fofiche i{width:7px;height:7px;border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);transform:rotate(-45deg);}
.fiche .fofeuille{position:fixed;inset:0;z-index:40;}
.fiche .fofeuille[hidden]{display:none;}
.fiche .fovoile{position:absolute;inset:0;background:rgba(10,20,40,.35);}
.fiche .fofeuille-corps{position:absolute;left:0;right:0;bottom:0;max-width:430px;margin:0 auto;max-height:70vh;overflow:auto;background:var(--carte-bg);border-radius:18px 18px 0 0;padding:10px 4px calc(env(safe-area-inset-bottom,0px) + 16px);box-shadow:0 -12px 40px rgba(0,0,0,.25);}
.fiche .fopoignee{width:36px;height:4px;border-radius:2px;background:var(--ink-3);margin:0 auto 6px;opacity:.5;cursor:pointer;}
/* la feuille « Ma marque » hors de la fiche (10/10, skill « Créer mon logo ») : le même habit, posé sur la page */
.hors-fiche .fofeuille{position:fixed;inset:0;z-index:40;}
.hors-fiche .fofeuille[hidden]{display:none;}
.hors-fiche .fovoile{position:absolute;inset:0;background:rgba(10,20,40,.35);}
.hors-fiche .fofeuille-corps{position:absolute;left:0;right:0;bottom:0;max-width:430px;margin:0 auto;max-height:70vh;overflow:auto;background:var(--carte-bg);border-radius:18px 18px 0 0;padding:10px 4px calc(env(safe-area-inset-bottom,0px) + 16px);box-shadow:0 -12px 40px rgba(0,0,0,.25);}
.hors-fiche .fopoignee{width:36px;height:4px;border-radius:2px;background:var(--ink-3);margin:0 auto 6px;opacity:.5;cursor:pointer;}
/* LA FICHE DU VENDEUR (fondateur, 02/10) — libellé gris à gauche, valeur à droite qui passe à la ligne au lieu de
   déborder, 16 px de marge ; des titres de groupe dès 8 lignes. Préfixe `ft-`, ancré sous `.fo-vendeur` : la feuille
   de commande (`.fo-cmd`) partage `.fofeuille-corps` et n'en reçoit rien. */
.fiche .fo-vendeur{max-height:85vh;}
.fiche .fo-vendeur .ft-tete{padding:4px 16px 12px;border-bottom:1px solid var(--carte-edge);}
.fiche .fo-vendeur .ft-tete h3{margin:0;font-size:var(--t-head);font-weight:700;color:var(--ink);}
.fiche .fo-vendeur .ft-gr{margin:16px 16px 2px;font-size:var(--t-foot);font-weight:600;color:var(--ink-3);}
.fiche .fo-vendeur .ft-liste,.fiche[data-source="aliexpress"] .ft-liste{margin:0;}
.fiche .fo-vendeur .ft-lig,.fiche[data-source="aliexpress"] .ft-lig{display:grid;grid-template-columns:40% 1fr;gap:12px;padding:11px 16px;border-bottom:1px solid color-mix(in srgb,var(--carte-edge) 60%,transparent);font-size:var(--t-body);line-height:1.35;}
.fiche .fo-vendeur .ft-liste .ft-lig:last-child,.fiche[data-source="aliexpress"] .ft-liste .ft-lig:last-child{border-bottom:0;}
.fiche .fo-vendeur .ft-lig dt,.fiche[data-source="aliexpress"] .ft-lig dt{color:var(--ink-3);}
.fiche .fo-vendeur .ft-lig dd,.fiche[data-source="aliexpress"] .ft-lig dd{margin:0;color:var(--ink);overflow-wrap:anywhere;}
.fiche .fomode{display:grid;grid-template-columns:22px 1fr auto;column-gap:10px;align-items:center;padding:8px 0;}
.fiche .fomode i{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--carte-edge);display:inline-flex;align-items:center;justify-content:center;font-style:normal;font-size:var(--t-cap);}
.fiche .fomode.on i{background:var(--fam-estime);border-color:var(--fam-estime);color:#fff;}
.fiche .fomode b{display:block;font-size:var(--t-body);font-weight:600;color:var(--ink);}
.fiche .fomode small{display:block;color:var(--ink-3);font-size:var(--t-cap);}
.fiche .fomode .p{text-align:right;font-weight:700;font-variant-numeric:tabular-nums;color:var(--fam-estime);}
.fiche .fomode .p small{display:block;font-weight:400;color:var(--ink-3);font-size:var(--t-cap);}
.fiche .foecart{margin-top:8px;padding-top:8px;border-top:1px dashed var(--carte-edge);gap:8px;flex-wrap:wrap;}
.fiche .foecart small{color:var(--ink-3);font-size:var(--t-cap);}

/* ══════════════ « CRÉER MES IMAGES » — UNE CONVERSATION (26/09) ══════════════
   Maquette VALIDÉE par le fondateur : docs/mockups/images-conversation/. Le lot de trois (grille, cœurs,
   « Encore trois », vue de retouche) est parti avec son objet : « c'est lourd, c'est nul ». Tout ici vit
   dans des rangées de Rabbit. Préfixe .im- ; jetons du Fil seulement, aucune taille ni graisse nouvelle. */
/* sa photo, en bulle : entière — une capture d'écran se lit en hauteur */
.u.shot.im-bulle{flex-shrink:0;}   /* sinon la colonne du fil l'écrase à 2 px dès qu'elle déborde (overflow:hidden → min-height 0), vu au banc le 26/09 */
.snap.im-snap{width:auto;height:auto;max-width:200px;}
.snap.im-snap::after{content:none;}
.snap.im-snap img{display:block;width:100%;height:auto;max-height:340px;object-fit:cover;object-position:top;}
/* la concurrence : une rangée qu'on fait glisser, la boutique NOMMÉE sous sa photo, un tap ouvre sa page */
.im-conc{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;margin:0 -16px 0 0;padding:2px 16px 4px 0;scrollbar-width:none;}
.im-conc::-webkit-scrollbar{display:none;}
.im-c{flex:0 0 92px;scroll-snap-align:start;display:flex;flex-direction:column;gap:6px;text-decoration:none;}
.im-c img{width:92px;height:92px;object-fit:contain;background:#fff;border-radius:var(--r-2);border:1px solid var(--carte-edge);display:block;}
.im-c span{font-size:var(--t-cap);line-height:1.2;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* L'IMAGE : le squelette ondule, puis elle se découvre de haut en bas, du flou au net — une seule fois (l'effet
   de ChatGPT, mis en scène : le moteur ne rend pas d'aperçus). Aucun faux pourcentage. */
.im-gen{position:relative;width:100%;max-width:320px;aspect-ratio:1;border-radius:16px;overflow:hidden;background:var(--pane-2);border:1px solid var(--carte-edge);cursor:zoom-in;}
.im-gen[data-format="9:16"]{aspect-ratio:9/16;max-width:240px;}
.im-sq{position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(105deg,transparent 30%,color-mix(in srgb,var(--ink) 10%,transparent) 50%,transparent 70%),
    radial-gradient(circle at 28% 32%,color-mix(in srgb,var(--light) 22%,transparent),transparent 58%),
    radial-gradient(circle at 74% 70%,color-mix(in srgb,var(--ink) 12%,transparent),transparent 55%),var(--pane-2);
  background-size:250% 100%,100% 100%,100% 100%,100% 100%;animation:im-luit 1.6s linear infinite;}
@keyframes im-luit{from{background-position:130% 0,0 0,0 0,0 0}to{background-position:-30% 0,0 0,0 0,0 0}}
.im-gen img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
.im-flou{z-index:1;filter:blur(18px) saturate(1.1);transform:scale(1.08);opacity:0;}
.im-net{z-index:2;opacity:0;-webkit-mask-image:linear-gradient(to bottom,#000 40%,transparent 60%);mask-image:linear-gradient(to bottom,#000 40%,transparent 60%);
  -webkit-mask-size:100% 300%;mask-size:100% 300%;-webkit-mask-position:0 100%;mask-position:0 100%;}
.im-revele .im-sq{animation:im-sq .5s ease forwards;}
.im-revele .im-flou{animation:im-flou .5s ease forwards;}
.im-revele .im-net{opacity:1;animation:im-net 1.6s cubic-bezier(.4,0,.2,1) .25s forwards;}
@keyframes im-sq{to{opacity:0}}
@keyframes im-flou{to{opacity:1}}
@keyframes im-net{from{-webkit-mask-position:0 100%;mask-position:0 100%}to{-webkit-mask-position:0 0;mask-position:0 0}}
@media (prefers-reduced-motion:reduce){.im-sq,.im-revele .im-sq,.im-revele .im-flou,.im-revele .im-net{animation:none;}
  .im-revele .im-sq{opacity:0;} .im-revele .im-net{-webkit-mask-image:none;mask-image:none;}}
/* une image qui n'arrive pas jusqu'au téléphone (revue du 27/09) : l'attente S'ARRÊTE, la phrase le dit, « Réessayer » la relit */
.im-gen.im-echec{cursor:default;}
.im-echec .im-sq{animation:none;opacity:.5;}
.im-echec-m{position:absolute;inset:0;z-index:4;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:16px;text-align:center;font-size:var(--t-foot);line-height:1.4;color:var(--ink-2);}
/* sous l'image : une ligne FINE — Télécharger · 👍 · 👎 ; chaque geste ≥ 44 pt au doigt (AGENTS §4) */
.im-act{display:flex;align-items:center;flex-wrap:wrap;margin:4px 0 0 -10px;}
.im-ic{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:44px;min-height:44px;padding:0 10px;border:0;background:none;color:var(--ink-3);font:inherit;font-size:var(--t-foot);border-radius:var(--r-2);}
.im-ic svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}
.im-ic.on{color:var(--ink);} .im-ic.on svg{fill:currentColor;}
.im-sep{width:1px;height:16px;background:var(--edge);margin:0 2px;}
.im-plus{border:0;background:none;padding:0 6px;min-height:44px;color:var(--ink-3);font:inherit;font-size:var(--t-cap);text-decoration:underline;text-underline-offset:3px;}
/* « Tu veux m'en dire plus ? » : un petit champ SUR PLACE, à 16 px (sinon iOS zoome la page) */
.im-avis{margin:0 0 4px;display:flex;flex-direction:column;gap:6px;}
.im-avis-l{display:flex;gap:8px;align-items:center;}
.im-avis-c{flex:1;min-width:0;min-height:44px;padding:0 12px;border-radius:var(--r-2);border:1px solid var(--edge);background:var(--pane-2);font:inherit;font-size:var(--t-champ);color:var(--ink);}
.im-avis-l button{min-height:44px;padding:0 14px;border-radius:var(--r-2);border:1px solid var(--edge);background:var(--pane-2);color:var(--ink);font:inherit;font-size:var(--t-foot);}
.im-merci{font-size:var(--t-cap);color:var(--ink-3);margin:2px 0 4px;}
/* « Tu l’as trouvé ? » 👍 👎 sous la liste d'une recherche (28/09) : la même ligne fine, ses mots en dessous */
.rch-pouces{display:flex;align-items:center;flex-wrap:wrap;margin:0 0 0 -10px;}
.rch-q{padding:0 2px 0 10px;font-size:var(--t-foot);color:var(--ink-3);}
.rch-pouces .im-avis,.rch-pouces .im-merci{flex-basis:100%;margin-left:10px;}
/* « Copier » sous SA bulle (12/10) : né d'un tap sur elle, à droite, comme elle */
.u-copier{align-self:flex-end;margin:-6px -10px 0 0;}
/* l'invitation au compte (invité, une fois) */
.im-inv{display:flex;flex-direction:column;align-items:flex-start;margin:2px 0 0;font-size:var(--t-foot);line-height:1.4;color:var(--ink-2);}
.im-inv-b{border:0;background:none;padding:0;min-height:44px;color:var(--ink);font:inherit;font-size:var(--t-foot);font-weight:600;text-decoration:underline;text-underline-offset:3px;}
/* l'image en grand : un tap l'ouvre, un tap, ✕ ou Échap la referment — au-dessus du dossier (z 60) et du reste */
.im-plein{position:fixed;inset:0;z-index:95;background:rgba(0,0,0,.96);display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:env(safe-area-inset-top,0px) 0 env(safe-area-inset-bottom,0px);}
.im-plein img{max-width:100%;max-height:calc(100dvh - 120px);object-fit:contain;}
.im-plein video{max-width:100%;max-height:calc(100dvh - 120px);background:#000;}
.im-plein-t{color:#fff;font-size:var(--t-cap);opacity:.85;}
.im-plein-p{display:flex;gap:12px;align-items:center;margin-top:14px;}
.im-plein .im-ic{color:#fff;}
.im-plein-x{min-width:44px;min-height:44px;border-radius:999px;border:1px solid rgba(255,255,255,.3);background:transparent;color:#fff;font:inherit;font-size:var(--t-body);}
/* Mon dossier : la rangée « Tes images » */
.dimages .im-grille{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin:8px 0 14px;}
.im-vig{padding:0;border:1px solid var(--carte-edge);border-radius:var(--r-1);overflow:hidden;background:var(--pane-2);aspect-ratio:1;min-height:44px;}
.im-vig img{display:block;width:100%;height:100%;object-fit:cover;}
.dimages .im-inv{margin:6px 0 14px;}

/* ══ LES BADGES DE CONFIANCE (fondateur : validé sur maquette le 24/09, en prod le 26/09) ══════════
   Classes NEUVES — `bdg*` et `.ftitre` : aucune règle existante ne change, sauf une transition
   ajoutée à `.apphead .ici` (l'heure s'efface le temps que les badges sont dans le bandeau).
   Consommateurs : le bandeau d'accueil (`.bdg-tete`), le titre de la fiche (`.ftitre`), la pilule
   flottante (`.bdg-pil`). L'anneau est celui du 13/09 : 1,5 px masqué, le dégradé entier qui dérive. */
@property --bdg-a{syntax:'<angle>';inherits:false;initial-value:0deg;}
@keyframes bdg-derive{to{--bdg-a:360deg;}}
button.bdg{all:unset;box-sizing:border-box;position:relative;flex:0 0 auto;display:inline-grid;place-items:center;
  width:var(--bdg-t,26px);height:var(--bdg-t,26px);border-radius:50%;cursor:pointer;
  background:var(--carte-bg);color:var(--ink);box-shadow:inset 0 1px 0 var(--lum-reflet),var(--sh-1);
  -webkit-tap-highlight-color:transparent;}
button.bdg:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
.bdg svg,.bdg-pil svg{position:relative;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}
.bdg svg{width:46%;height:46%;}
.bdg-an{position:absolute;inset:0;border-radius:inherit;padding:1.5px;box-sizing:border-box;pointer-events:none;opacity:.9;
  background:conic-gradient(from var(--bdg-a),var(--halo-1),var(--halo-2) 28%,var(--halo-3) 52%,var(--halo-2) 74%,var(--halo-1));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
  animation:bdg-derive 14s linear infinite;}
/* l'accueil : la rangée prend la place de l'heure, le temps de l'accueil */
.bdg-tete{position:absolute;transform:translateY(-50%);display:flex;gap:8px;z-index:3;}
.apphead .ici{transition:opacity .38s ease;}
.apphead.bdg-la .ici{opacity:0;}
/* la fiche : sur la ligne du nom, calés à droite — le titre passe à la ligne à côté, jamais dessous.
   La place est RÉSERVÉE (min-width) dès le rendu provisoire : rien ne saute quand ils arrivent. */
.ftitre{display:flex;align-items:flex-start;gap:12px;}
.ftitre h2{flex:1 1 auto;min-width:0;}
.ftitre .bdg-rang{--bdg-t:24px;flex:0 0 auto;display:flex;gap:6px;min-width:114px;justify-content:flex-end;
  margin-top:calc(6px + (1.3 * var(--t-body) - 24px) / 2);}
/* la pilule : le badge ouvert, sur son nom ou sa phrase — flottante, elle ne reste jamais */
.bdg-pil{position:fixed;z-index:62;box-sizing:border-box;display:flex;align-items:center;gap:10px;min-height:40px;
  padding:0 16px 0 11px;border-radius:22px;overflow:hidden;white-space:nowrap;
  background:var(--carte-bg);color:var(--ink);box-shadow:inset 0 1px 0 var(--lum-reflet),var(--sh-2);
  -webkit-backdrop-filter:blur(20px) saturate(150%);backdrop-filter:blur(20px) saturate(150%);
  font-size:var(--t-foot);line-height:1.45;}
.bdg-pil.bdg-phrase{align-items:flex-start;white-space:normal;padding:11px 16px 12px 12px;}
.bdg-pil svg{flex:0 0 18px;width:18px;height:18px;}
.bdg-pil.bdg-phrase svg{margin-top:1.5px;}
.bdg-t{position:relative;min-width:0;flex:1 1 auto;}
.bdg-mot{display:inline-block;animation:wordin .34s var(--ease,ease) backwards;}
@media (prefers-reduced-motion:reduce){
  .bdg-an{animation:none;}
  .apphead .ici{transition:none;}
  .bdg-mot{animation:none;}
}

/* ══ « TON AGENT EN CHINE » — la conversation avec un humain (30/09 ; REFAITE le 01/10 sur les codes des messageries,
   maquette `docs/mockups/agent-chat-3009/` § « La conversation, refaite »). Tout ce qui est HUMAIN lit `--fam-humain`
   (violet, déclaré dans chaque thème) ; les bulles du client gardent celles du Fil (`--bulle-bg`). Aucune couleur
   littérale, aucune taille hors de la grille : chaque règle lit des jetons, dans tous les thèmes. */
/* 02/10 (fondateur : « plus premium, des dégradés ») — maquette `docs/mockups/agent-premium-0210/` : l'humain est un
   DÉGRADÉ de deux violets (`--fam-humain` → `--fam-humain-2`), sur le rond, l'en-tête, ses bulles et le bouton d'envoi. */
.ag-ini{position:relative;display:inline-grid;place-items:center;width:30px;height:30px;border-radius:50%;flex:none;font-size:var(--t-foot);font-weight:700;
  color:var(--screen);background:linear-gradient(135deg,var(--fam-humain),var(--fam-humain-2));
  box-shadow:0 0 0 2px color-mix(in srgb,var(--fam-humain) 22%,transparent),0 6px 16px -5px color-mix(in srgb,var(--fam-humain-2) 80%,transparent);}
/* « en ligne » : le point vert sur le rond, comme dans les messageries */
.ag-en-ligne .ag-ctete .ag-ini::after,.ag-conv.ag-en-ligne .dhead .ag-ini::after{content:"";position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;
  border-radius:50%;background:var(--fam-argent);box-shadow:0 0 0 2px var(--pane-2);}
.ag-qui{display:flex;flex-direction:column;min-width:0;line-height:1.2;}
.ag-qui b{font-size:var(--t-head);font-weight:600;}
.ag-qui small{font-size:var(--t-cap);color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* ── l'écran : le ciel du Fil derrière, l'en-tête teinté de l'humain, une seule sortie ── */
/* UN AUTRE LIEU (02/10 : « on comprend pas qu'on finit dans un chat ») : la conversation GLISSE depuis la droite par-dessus
   le Fil, comme on ouvre un chat — et son ciel est violet. Elle repart par la droite. */
.ag-conv{background:radial-gradient(130% 50% at 50% 6%,color-mix(in srgb,var(--fam-humain-2) 34%,transparent),transparent 70%),
  radial-gradient(80% 45% at 0% 100%,color-mix(in srgb,var(--light) 14%,transparent),transparent 70%),
  linear-gradient(178deg, var(--void) 0%, var(--air) 34%, var(--air-2) 100%);}
/* 03/10 (fondateur, maquette `docs/mockups/agent-entree-0310/`, B + D) : UNE FEUILLE monte du bas par-dessus le Fil, qui
   recule et s'assombrit — on voit qu'on l'a quitté, et qu'il est toujours là. Elle se ferme en la tirant vers le bas. */
.dossier.ag-conv{top:30px;border-radius:24px 24px 0 0;overflow:hidden;animation:agMonte .42s var(--e-main) both;
  box-shadow:0 -18px 40px -20px color-mix(in srgb,var(--fam-humain-2) 80%,transparent);transition:transform .25s var(--e-main);}
.dossier.ag-conv.dsort{animation:agDescend .32s var(--e-main) both;}
@keyframes agMonte{from{transform:translateY(100%);}to{transform:none;}}
@keyframes agDescend{from{transform:none;}to{transform:translateY(100%);}}
.screen:has(> .dossier.ag-conv:not(.dsort)) > :not(.dossier){filter:brightness(.45);transform:scale(.97);transition:filter .35s, transform .35s;}
.ag-conv .dhead{position:relative;padding-top:14px;border-radius:24px 24px 0 0;touch-action:none;}
.ag-poignee{position:absolute;top:6px;left:50%;width:36px;height:4px;margin-left:-18px;border-radius:4px;background:color-mix(in srgb,var(--ink) 35%,transparent);}
@media (prefers-reduced-motion:reduce){ .dossier.ag-conv,.dossier.ag-conv.dsort{animation:none;} .screen:has(> .dossier.ag-conv) > :not(.dossier){transform:none;} }
/* le visage : avant qu'un agent suive la demande, les initiales de l'équipe en petit groupe */
.ag-trio{display:inline-flex;flex:none;}
.ag-trio .ag-ini{box-shadow:0 0 0 2px var(--pane-2);}
.ag-trio .ag-ini + .ag-ini{margin-left:-10px;}
.ag-conv .dhead .ag-trio .ag-ini,.ag-ctete .ag-trio .ag-ini{width:28px;height:28px;font-size:var(--t-cap);}
/* L'ARRIVÉE (une fois par demande) : le visage en grand au centre, puis il se range dans l'en-tête */
.ag-grand{position:absolute;inset:0;z-index:5;display:grid;place-items:center;pointer-events:none;}
.ag-grand > .ag-ini{width:96px;height:96px;font-size:var(--t-large);box-shadow:0 20px 50px -12px var(--fam-humain-2);}
.ag-grand > .ag-trio .ag-ini{width:64px;height:64px;font-size:var(--t-title);box-shadow:0 0 0 3px var(--pane-2),0 14px 30px -10px var(--fam-humain-2);}
.ag-grand > .ag-trio .ag-ini + .ag-ini{margin-left:-16px;}
.ag-conv.ag-en-ligne .ag-grand > .ag-ini::after{content:"";position:absolute;right:6px;bottom:6px;width:22px;height:22px;border-radius:50%;background:var(--fam-argent);box-shadow:0 0 0 4px var(--pane-2);}
.ag-conv .dhead > span,.ag-conv .dcorps{transition:opacity .25s;}
.ag-conv.ag-arrive .dhead > span,.ag-conv.ag-arrive .dcorps{opacity:0;}
.ag-conv .dhead{border-bottom:1px solid color-mix(in srgb,var(--fam-humain) 30%,transparent);
  background:linear-gradient(180deg,color-mix(in srgb,var(--fam-humain-2) 46%,var(--pane-2)),color-mix(in srgb,var(--fam-humain-2) 22%,var(--pane-2)));
  box-shadow:0 10px 30px -14px color-mix(in srgb,var(--fam-humain-2) 70%,transparent);}
.ag-conv .dhead > span{display:flex;align-items:center;gap:10px;min-width:0;text-align:left;flex:1;}
.ag-conv .dhead .ag-ini{width:38px;height:38px;font-size:var(--t-body);}
.ag-conv .dhead .dretour{color:var(--fam-humain);}
.ag-conv .dhead .dclose{display:none;}
.ag-st{color:var(--ink-2);margin-top:2px;}
.ag-st.on{color:var(--fam-argent);font-weight:600;}
.ag-conv .dcorps{display:flex;flex-direction:column;padding:0 12px 96px;}
/* le ticket ÉPINGLÉ : il reste sous l'en-tête pendant qu'on fait défiler */
.ag-pin[hidden]{display:none;}
.ag-pin{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:10px;margin:10px 0 4px;padding:9px 12px;border-radius:14px;
  background:linear-gradient(135deg,color-mix(in srgb,var(--fam-humain-2) 20%,var(--pane-2)),var(--pane-2));border:1px solid color-mix(in srgb,var(--fam-humain) 30%,transparent);
  box-shadow:0 8px 24px -14px color-mix(in srgb,var(--fam-humain-2) 80%,transparent);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);}
.ag-pini{display:grid;place-items:center;width:30px;height:30px;border-radius:9px;flex:none;color:var(--fam-humain);background:color-mix(in srgb,var(--fam-humain) 14%,transparent);}
.ag-pini .fi{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.ag-pint{display:flex;flex-direction:column;min-width:0;line-height:1.3;}
.ag-pint b{font-size:var(--t-foot);font-weight:600;}
.ag-pint small{font-size:var(--t-foot);color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.ag-pin-cmd .ag-pint small{white-space:normal;}   /* « Ta commande n°17 » : son produit et le motif sur deux lignes, jamais coupés (maquette F, 05/10) */
.ag-fil{display:flex;flex-direction:column;gap:3px;margin-top:auto;padding:8px 0 4px;}
.ag-jour{align-self:center;margin:10px 0 8px;padding:3px 10px;border-radius:99px;font-size:var(--t-cap);color:var(--ink-2);
  background:color-mix(in srgb,var(--fam-humain-2) 18%,var(--pane-2));border:1px solid color-mix(in srgb,var(--fam-humain) 22%,transparent);}
.ag-avis{align-self:center;max-width:82%;margin:8px 0;text-align:center;font-size:var(--t-foot);line-height:1.4;color:var(--ink-3);}
/* ── les bulles : la pointe vers l'auteur, l'heure dans la bulle, ✓✓ bleu quand c'est lu ── */
.ag-ligne{display:flex;align-items:flex-end;gap:7px;margin:1px 0;}
.ag-ligne.moi{justify-content:flex-end;}
.ag-ligne.lui{margin-top:6px;}
.ag-ligne.lui.suite{margin-bottom:-1px;}
.ag-ligne.lui + .ag-ligne.lui{margin-top:0;}
.ag-ligne.lui.suite > .ag-ini{visibility:hidden;}
.ag-ligne .ag-ini{width:26px;height:26px;font-size:var(--t-cap);}
.ag-m{position:relative;max-width:78%;padding:8px 12px 7px;border-radius:18px;font-size:var(--t-champ);line-height:1.38;overflow-wrap:anywhere;text-wrap:pretty;}
.ag-m.moi{background:linear-gradient(140deg,color-mix(in srgb,var(--light) 28%,var(--bulle-bg)),var(--bulle-bg));color:var(--bulle-ink);border-bottom-right-radius:6px;
  box-shadow:0 10px 22px -16px color-mix(in srgb,var(--light) 70%,transparent);}
.ag-m.lui{color:var(--ink);background:linear-gradient(140deg,color-mix(in srgb,var(--fam-humain) 40%,var(--pane)),color-mix(in srgb,var(--fam-humain-2) 30%,var(--pane)));
  border:1px solid color-mix(in srgb,var(--fam-humain) 34%,transparent);border-bottom-left-radius:6px;
  box-shadow:0 10px 22px -16px color-mix(in srgb,var(--fam-humain-2) 90%,transparent);}
.ag-ligne.lui.suite .ag-m.lui{border-bottom-left-radius:6px;}
.ag-ligne.lui + .ag-ligne.lui .ag-m.lui{border-top-left-radius:6px;}
.ag-t{white-space:pre-wrap;}
.ag-h{display:inline-flex;align-items:center;gap:3px;float:right;margin:6px 0 -3px 10px;font-size:var(--t-cap);opacity:.62;}
.ag-vu svg{display:block;width:15px;height:10px;}
.ag-m.moi .ag-vu{opacity:.55;}
.ag-m.moi.lu .ag-vu{color:var(--light);opacity:1;}   /* « Vu » : le bleu du Fil, franc — pas un blanc à peine différent de l'envoyé */
.ag-m.moi.lu .ag-h{opacity:.9;}
/* une photo : bord à bord, l'heure posée dessus */
.ag-m.a-image{padding:4px;}
.ag-img{display:block;}
.ag-img img{display:block;max-width:100%;max-height:300px;border-radius:14px;}
.ag-img-ph{display:grid;place-items:center;width:200px;height:150px;border-radius:14px;font-size:var(--t-foot);color:var(--ink-3);background:var(--pane-2);}
.ag-m.a-image .ag-t{display:block;padding:6px 8px 0;}
.ag-m.a-image .ag-h{float:none;position:absolute;right:10px;bottom:10px;margin:0;padding:2px 7px;border-radius:9px;opacity:1;color:var(--ink);background:var(--pane-2);}
.ag-m.a-image .ag-t + .ag-h{position:static;float:right;background:none;margin:6px 6px 0 10px;}
.ag-doc{display:flex;align-items:center;gap:9px;width:100%;margin:0 0 4px;padding:9px 10px;border-radius:12px;font:inherit;font-size:var(--t-foot);text-align:left;
  color:inherit;background:var(--pane-2);border:1px solid var(--edge);}
.ag-doc svg{width:22px;height:22px;flex:none;}
.ag-doc span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ag-dots{display:inline-flex;gap:4px;padding:6px 2px;}
.ag-dots i{width:7px;height:7px;border-radius:50%;background:var(--fam-humain);animation:agDot 1.2s infinite ease-in-out;}
.ag-dots i:nth-child(2){animation-delay:.15s;} .ag-dots i:nth-child(3){animation-delay:.3s;}
@keyframes agDot{0%,80%,100%{opacity:.3;transform:translateY(0);}40%{opacity:1;transform:translateY(-3px);}}
@media (prefers-reduced-motion:reduce){ .ag-dots i{animation:none;opacity:.7;} }
/* ── LE DEVIS dans la conversation (ticket 06) : une carte dans la bulle de l'agent, « Payer » est le seul geste plein ── */
.ag-m.a-devis{padding:4px;max-width:88%;width:88%;}
.ag-devis{display:flex;flex-direction:column;gap:6px;padding:10px 11px;border-radius:14px;background:var(--pane);color:var(--ink);}
.ag-dh{display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:var(--t-foot);}
.ag-chip{font-weight:600;font-size:var(--t-cap);padding:2px 8px;border-radius:99px;color:var(--fam-humain);background:color-mix(in srgb,var(--fam-humain) 16%,transparent);}
.ag-chip.expire,.ag-chip.annule{color:var(--ink-3);background:var(--pane-2);}
.ag-chip.paye{color:var(--fam-argent);background:color-mix(in srgb,var(--fam-argent) 16%,transparent);}
.ag-dt{font-weight:600;font-size:var(--t-body);}
.ag-dl{display:flex;justify-content:space-between;gap:10px;font-size:var(--t-foot);}
.ag-dl span:last-child{white-space:nowrap;font-variant-numeric:tabular-nums;}
.ag-dl.total{padding-top:6px;border-top:1px solid var(--edge-2);font-size:var(--t-body);}
.ag-dn{font-size:var(--t-cap);color:var(--ink-2);line-height:1.35;}
.ag-payer,.ag-redemander{margin-top:4px;min-height:44px;border:0;border-radius:12px;font:inherit;font-weight:600;font-size:var(--t-body);}
.ag-payer{color:var(--btn-argent-ink);background:var(--btn-argent-bg);}
.ag-redemander{color:var(--ink);background:var(--pane-2);border:1px solid var(--edge);}
.ag-payer[disabled]{opacity:.5;}
/* la feuille du paiement (ticket 08) : monte dans la conversation, les champs de la feuille de la fiche */
.ag-feuille-pay{position:absolute;inset:0;z-index:6;}
.ag-fp-voile{position:absolute;inset:0;background:color-mix(in srgb,var(--void) 55%,transparent);}
.ag-fp-corps{position:absolute;left:0;right:0;bottom:0;max-height:86%;overflow:auto;display:flex;flex-direction:column;gap:8px;
  padding:8px 14px calc(env(safe-area-inset-bottom,0px) + 14px);border-radius:22px 22px 0 0;background:var(--carte-bg);
  border-top:1px solid color-mix(in srgb,var(--fam-humain) 30%,transparent);box-shadow:0 -12px 40px color-mix(in srgb,var(--void) 60%,transparent);
  animation:agMonte .3s var(--e-main) both;}
.ag-fp-corps .fopoignee{width:36px;height:4px;border-radius:2px;background:var(--ink-3);margin:0 auto 4px;opacity:.5;cursor:pointer;}
.ag-fp-corps .fx-compte-msg{flex:1 1 100%;font-size:var(--t-cap);color:var(--warm);}
@media (prefers-reduced-motion:reduce){ .ag-fp-corps{animation:none;} }
/* ── la barre de saisie : la barre vitrée du Fil ; le trombone ; un refus reste au-dessus du champ ── */
.ag-saisie{position:absolute;left:0;right:0;bottom:0;padding:6px 10px calc(env(safe-area-inset-bottom,0px) + 10px);
  background:color-mix(in srgb,var(--pane-2) 80%,transparent);backdrop-filter:blur(18px) saturate(140%);-webkit-backdrop-filter:blur(18px) saturate(140%);border-top:1px solid var(--edge-2);}
.ag-comp{display:flex;align-items:flex-end;gap:8px;}
.ag-pj{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;flex:none;cursor:pointer;color:var(--light);background:var(--pane);border:1px solid var(--edge);}
.ag-pj svg{width:21px;height:21px;}
.ag-saisie textarea{flex:1;min-height:44px;max-height:140px;resize:none;box-sizing:border-box;padding:11px 14px;border-radius:22px;
  font:inherit;font-size:var(--t-champ);line-height:1.35;color:var(--ink);background:var(--pane);border:1px solid var(--edge);}
.ag-env{width:44px;height:44px;border-radius:50%;border:0;flex:none;display:grid;place-items:center;color:var(--screen);
  background:linear-gradient(135deg,var(--fam-humain),var(--fam-humain-2));box-shadow:0 8px 20px -8px color-mix(in srgb,var(--fam-humain-2) 90%,transparent);}
.ag-env svg{width:20px;height:20px;}
.ag-env[disabled]{opacity:.35;}
.ag-refus{margin:2px 6px 8px;font-size:var(--t-foot);line-height:1.4;color:var(--warm);}
/* ── la liste « Tes demandes », le brief, l'annonce ── */
.ag-liste{display:flex;flex-direction:column;}
.ag-dem{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:12px 6px;background:none;border:0;border-bottom:1px solid var(--edge-2);color:var(--ink);font:inherit;}
.ag-dem .ag-ini{width:40px;height:40px;font-size:var(--t-champ);}
.ag-dem .ag-qui{flex:1;}
.ag-cote{display:flex;flex-direction:column;align-items:flex-end;gap:5px;flex:none;}
.ag-cote .dbadge{white-space:nowrap;}
.ag-n{display:grid;place-items:center;min-width:20px;height:20px;padding:0 5px;box-sizing:border-box;border-radius:10px;font-size:var(--t-cap);font-weight:700;
  background:var(--fam-humain);color:var(--screen);}
.ag-nouvelle{margin:14px 0 4px;padding:12px;border-radius:12px;font:inherit;color:var(--fam-humain);background:none;
  border:1px dashed color-mix(in srgb,var(--fam-humain) 60%,transparent);}
/* les demandes d'avant le 1er octobre (02/10) : un lien discret sous la nouvelle demande, jamais un second appel à l'action */
.ag-anciennes{margin:6px 0 4px;min-height:44px;padding:10px 12px;font:inherit;color:var(--ink-2);background:none;border:0;}
.card[data-role^="agent-"] .bandeau-n{color:var(--fam-humain);}
/* LA CARTE-CONVERSATION DU FIL (02/10) : le ticket envoyé DEVIENT la conversation — l'agent, ses dernières bulles,
   « Ouvrir la conversation » ; au retour, la MÊME carte avance. Elle parle la langue de l'écran qu'elle ouvre. */
.ag-carte{border-color:color-mix(in srgb,var(--fam-humain) 38%,transparent);
  background:radial-gradient(120% 80% at 0% 0%,color-mix(in srgb,var(--fam-humain-2) 34%,transparent),transparent 62%),var(--carte-bg);
  box-shadow:0 18px 40px -20px color-mix(in srgb,var(--fam-humain-2) 85%,transparent);}
.ag-ctete{display:flex;align-items:center;gap:10px;padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--fam-humain) 20%,transparent);}
.ag-ctete .ag-ini{width:36px;height:36px;font-size:var(--t-body);}
.ag-ctete .ag-qui{flex:1;}
.ag-ctete .dbadge{white-space:nowrap;}
.ag-ctete .dbadge.ag-neuf{color:var(--screen);background:linear-gradient(135deg,var(--fam-humain),var(--fam-humain-2));}
.ag-cfil{display:flex;flex-direction:column;gap:5px;margin:12px 0;}
.ag-cfil .ag-m{max-width:84%;font-size:var(--t-foot);padding:7px 11px;}
.ag-cfil .ag-m.moi{align-self:flex-end;}
.ag-cfil .ag-m.lui{align-self:flex-start;}
.ag-cfil .ag-t{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;}
.ag-carte .ag-ouvrir{width:100%;color:var(--screen);background:linear-gradient(135deg,var(--fam-humain),var(--fam-humain-2));border:0;
  box-shadow:0 10px 24px -10px color-mix(in srgb,var(--fam-humain-2) 95%,transparent);}
.ag-err{margin-top:8px;font-size:var(--t-foot);color:var(--warm);}
.ag-brief .pied-n{flex-wrap:wrap;row-gap:10px;}
.ag-brief .pied-n .note-n{flex:1 1 100%;}
.ag-brief .ag-envoyer{width:100%;}

/* ══ DA v2 DES DEUX HALO (fondateur, maquettes validées les 02-03/10) ═══════════════════════════════════
   Ne touche PAS aux objets. Pose : le jeton de marque, les auras B du fond, les boutons pleins, l'envoi à vide,
   les chiffres à largeur fixe. Garde : da-halo-v2.test.js. */
:root[data-theme="halo"],.vignette[data-design="halo"]{
  --marque:linear-gradient(135deg,#5EE0FF 0%,#7A8CFF 55%,#C46EFF 100%);--marque-ombre:rgba(122,140,255,.55);}
:root[data-theme="halo-clair"],.vignette[data-design="halo-clair"]{
  --marque:linear-gradient(135deg,#19B3E6 0%,#4F6BFF 55%,#B04CFF 100%);--marque-ombre:rgba(79,107,255,.45);}
/* les chiffres à largeur fixe : PAS sur le body (11/10, mesuré : le trait d'union d'Inter passe de 7,4 à 10,4 px en tnum) —
   chaque colonne de chiffres déclare les siens */
/* les boutons pleins : la marque, avec son ombre colorée (le reflet du haut reste) */
.btn,.btn-n,.cta-plein,.cta-plein.vert,.cta-payer,.composer .send{background:var(--marque);color:#FFFFFF;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32),0 12px 26px -12px var(--marque-ombre);}
.btn-n.sec{background:transparent;box-shadow:none;}
/* les boutons « estimé » gardent leur ambre : la couleur y dit la nature du chiffre, pas la marque */
.fiche .frbtn .btn-n,.rv-pied .btn-n{background:var(--plein-lum);box-shadow:var(--plein-ombre);}
/* ── LOT 3 (03/10) : l'en-tête, l'accueil, le tiroir des maquettes validées ── */
/* « Juste en dessous de Rabbit, tu mets Guangzhou, 20h21 » (fondateur) : une grille nommée, la ville sous le nom */
.apphead{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"btn nm tenu" "btn ici tenu";
  column-gap:10px;row-gap:0;align-items:center;}
.apphead #menubtn{grid-area:btn;}
/* l'avatar de Rabbit cerclé du dégradé de marque (maquette validée par le fondateur, 03/10) */
.apphead #menubtn{border:2px solid transparent;
  background:linear-gradient(var(--screen),var(--screen)) padding-box,var(--marque) border-box;
  box-shadow:inset 0 1px 0 var(--lum-reflet),0 6px 18px -8px var(--marque-ombre);}
.apphead .nm{grid-area:nm;align-self:end;font-size:var(--t-body);font-weight:700;letter-spacing:-.015em;line-height:1.2;}
.apphead .ici{grid-area:ici;align-self:start;margin-left:0;color:var(--ink-3);line-height:1.3;}
.apphead .tenu{grid-area:tenu;}
.apphead.bdg-la .ici{opacity:1;}   /* les badges ne la recouvrent plus : ils sont à droite */
/* le titre d'accueil : « Salut, moi c’est Rabbit. », le nom dans la marque */
.acc-titre{margin:4px 0 0;font:700 var(--t-title)/1.15 var(--sans);letter-spacing:-.025em;color:var(--ink);}
.acc-titre em{font-style:normal;background:var(--marque);-webkit-background-clip:text;background-clip:text;color:transparent;}
/* les trois portes : des cartes de verre, une icône dans la marque */
.pills.portes-acc{display:flex;flex-direction:column;gap:10px;margin:6px 0 0;padding:0;}
.portes-acc .porte-acc{display:flex;align-items:center;gap:14px;width:100%;min-height:76px;padding:12px 14px;border:0;border-radius:20px;
  text-align:left;font:inherit;color:var(--ink);cursor:pointer;background:color-mix(in srgb,var(--pane) 82%,transparent);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);box-shadow:inset 0 0 0 1px var(--edge-2),var(--sh-2);}
.portes-acc .porte-acc:active{transform:scale(.985);}
.portes-acc .pa-ic{flex:0 0 auto;width:52px;height:52px;border-radius:15px;display:grid;place-items:center;color:#FFFFFF;
  background:var(--marque);box-shadow:0 10px 22px -10px var(--marque-ombre);}
.portes-acc .pa-ic svg{width:24px;height:24px;}
/* la porte des idées montre quatre vraies photos et leur nombre (03/10) — le nombre en neutre : le vert dit « bénéfice » */
.portes-acc .pa-ic.pa-mos{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:2px;padding:0;overflow:hidden;background:#FFFFFF;}
.portes-acc .pa-ic.pa-mos img{width:100%;height:100%;object-fit:cover;display:block;}
.portes-acc .pa-n{display:inline-block;margin-left:7px;padding:1px 7px;border-radius:999px;vertical-align:1px;
  font-size:var(--t-cap);font-weight:600;color:var(--ink-2);background:color-mix(in srgb,var(--ink) 10%,transparent);}
.portes-acc .pa-t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px;}
.portes-acc .pa-t b{font:600 var(--t-body)/1.25 var(--sans);letter-spacing:-.01em;}
.portes-acc .pa-t small{font:400 var(--t-foot)/1.3 var(--sans);color:var(--ink-3);}
.portes-acc .pa-chev{flex:0 0 auto;font-size:var(--t-title);line-height:1;color:var(--ink-3);}
/* le tiroir : « Mon compte » en tête, cliquable ; « Nouvelle recherche » dans la marque ; Admin marqué « équipe » */
.app-menu .menu-moi{display:flex;align-items:center;gap:12px;width:100%;padding:10px 8px 14px;border:0;border-bottom:1px solid var(--edge-2);
  background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.app-menu .menu-moi[hidden]{display:none;}
.menu-moi .mm-ini{flex:0 0 auto;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;color:#FFFFFF;
  font:700 var(--t-head)/1 var(--sans);background:var(--marque);box-shadow:0 8px 18px -8px var(--marque-ombre);}
.menu-moi .mm-ini:empty::before{content:"";width:20px;height:20px;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='8' r='3.5'/%3E%3Cpath d='M5 20c1-3.5 3.8-5.5 7-5.5s6 2 7 5.5'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='8' r='3.5'/%3E%3Cpath d='M5 20c1-3.5 3.8-5.5 7-5.5s6 2 7 5.5'/%3E%3C/svg%3E") center/contain no-repeat;}
.menu-moi .mm-txt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px;}
.menu-moi .mm-id{font-weight:700;}
.menu-moi .mm-plan{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.menu-moi .mm-chev{flex:0 0 auto;font-size:var(--t-title);line-height:1;color:var(--ink-3);}
/* LA PASTILLE DU SOLDE (lot 4, 13/10 — validée : à côté du nom, le nom peut se couper) */
.menu-moi .mm-pil{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;padding:5px 8px;border-radius:999px;white-space:nowrap;
  font-size:var(--t-cap);font-weight:600;line-height:1;color:#4338CA;border:1.5px solid transparent;
  background:linear-gradient(#EEF2FF,#EEF2FF) padding-box,linear-gradient(135deg,#3B82F6,#8B5CF6) border-box;}
.menu-moi .mm-pil i{width:8px;height:8px;border-radius:50%;background:linear-gradient(135deg,#3B82F6,#8B5CF6);}
.app-menu .menu-moi:has(.mm-pil){min-width:0;}
.menu-moi:has(.mm-pil) .mm-id{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.app-menu .menu-primary{justify-content:center;margin:12px 4px 8px;min-height:48px;border-radius:15px;font-weight:700;color:#FFFFFF;
  background:var(--marque);box-shadow:inset 0 1px 0 rgba(255,255,255,.3),0 12px 26px -12px var(--marque-ombre);}
.app-menu .menu-primary .mi{color:#FFFFFF;}
/* les compteurs du tiroir (03/10) : neutres, à droite — « 2 réponses », « 4 en cours » */
.app-menu .me-n{margin-left:auto;padding:2px 9px;border-radius:999px;white-space:nowrap;font:600 var(--t-cap)/1.4 var(--sans);
  color:var(--ink-2);background:color-mix(in srgb,var(--ink) 10%,transparent);}
.app-menu .menu-equipe .me-tag{margin-left:auto;font:700 var(--t-cap)/1 var(--sans);color:var(--ink-3);
  border:1px solid var(--edge);padding:3px 7px;border-radius:7px;}
/* « Mes commandes » v2 (03/10, maquette validée) : une carte par commande — photo, titre, « n° · pièces », montant à droite,
   puis la ligne d'étapes (Payée · En préparation · Expédiée · Livrée). Portée : `.cmd-liste`, le seul conteneur de ce panneau. */
.dobj.cmd-liste{display:flex;flex-direction:column;gap:10px;padding:0;background:none;box-shadow:none;border:0;}
.cmd-liste .dentree-g{padding:14px;border-radius:20px;background:var(--pane);box-shadow:inset 0 0 0 1px var(--edge-2),var(--sh-2);}
.cmd-liste .dentree-g + .dentree-g{border-top:0;}
.cmd-liste .cmd-l{border:0;padding:0;}
.cmd-liste .cmd-l .dcorps-r{display:flex;align-items:flex-start;gap:12px;padding:0;}
.cmd-liste .cmd-l .dvg{flex:0 0 auto;width:56px;height:56px;border-radius:13px;}
.cmd-liste .cmd-l .dcc{flex:1 1 auto;min-width:0;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:10px;align-items:start;}
.cmd-liste .cmd-l .dcc > b{grid-column:1;font:600 var(--t-body)/1.3 var(--sans);letter-spacing:-.01em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.cmd-liste .cmd-l .dcc .dpx{grid-column:2;grid-row:1;font:700 var(--t-body)/1.3 var(--sans);color:var(--ink);white-space:nowrap;}
.cmd-liste .cmd-l .dcc .cmd-sous{grid-column:1 / -1;font:400 var(--t-foot)/1.3 var(--sans);color:var(--ink-3);margin-top:3px;}
.cmd-liste .cmd-l .dcc .dmeta{grid-column:1 / -1;margin-top:8px;}
.cmd-et{margin-top:13px;}
.cmd-et-b{display:flex;gap:5px;}
.cmd-et-b i{flex:1 1 0;height:4px;border-radius:2px;background:color-mix(in srgb,var(--ink) 9%,transparent);}
.cmd-et-b i.ok{background:var(--marque);}
.cmd-et-t{margin:0 0 6px;font:600 var(--t-foot)/1.2 var(--sans);color:var(--ink);}   /* l'étape atteinte, au-dessus de la barre (lot 3) */
.composer .send[data-vide]{background:color-mix(in srgb,var(--ink) 9%,transparent);color:var(--ink-3);box-shadow:none;}

/* ── LA FICHE v2 (03/10, maquette validée : « photos avec vignettes, cœur et partager en haut, étoiles et
   commandés à l'usine », « Commander 50 pièces » en violet) — onglets en une barre, le reste inchangé ── */
#fiche:has(.egal-act) .barrex{display:none;}   /* le retour est sur la photo */
#fiche .fcarte .egal-main.egal-v2{margin:-9px -11px 12px;height:auto;aspect-ratio:1/1;max-height:min(58vh,430px);
  border:0;border-radius:18px 18px 24px 24px;background:#FFFFFF;box-shadow:none;}
#fiche .egal-v2 .egal-img{width:100%;height:100%;object-fit:contain;display:block;cursor:pointer;}
#fiche .egal-act{position:absolute;top:12px;left:12px;right:12px;display:flex;align-items:center;gap:10px;}
#fiche .egal-esp{flex:1 1 auto;}
#fiche .egal-rond{width:44px;height:44px;flex:0 0 44px;padding:0;border:0;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.94);color:#0B1020;box-shadow:0 6px 16px -8px rgba(11,16,32,.45);cursor:pointer;}
#fiche .egal-rond svg{width:20px;height:20px;}
#fiche .egal-coeur[aria-pressed="true"]{color:#E5484D;}
#fiche .egal-coeur[aria-pressed="true"] svg{fill:currentColor;}
#fiche .egal-partager.copie{background:#E8FBF0;color:#16794C;}
#fiche .egal-vign{position:absolute;left:12px;bottom:12px;display:flex;gap:8px;max-width:calc(100% - 90px);overflow:hidden;}
#fiche .egal-v{width:44px;height:44px;flex:0 0 44px;padding:0;border-radius:11px;overflow:hidden;background:#FFFFFF;
  border:2px solid rgba(11,16,32,.08);box-shadow:0 4px 10px -6px rgba(11,16,32,.4);cursor:pointer;}
#fiche .egal-v.elue{border-color:var(--marque-ombre);}
#fiche .egal-v img{width:100%;height:100%;object-fit:cover;display:block;}
#fiche .egal-n{position:absolute;right:12px;bottom:12px;padding:3px 9px;border-radius:999px;background:rgba(255,255,255,.94);
  color:#0B1020;font-size:var(--t-cap);font-weight:600;}
#fiche .egal-n[hidden]{display:none;}   /* la photo d'une variante choisie n'est pas « 1 / 8 » */
/* LA BANDE DE PHOTOS DES VARIANTES (maquette validée 05/10) : une rangée qui défile, la photo choisie entourée comme la
   vignette de la galerie, le nom du choix en entier dessous — jamais coupé. 56 px : la cible tactile et assez pour
   distinguer deux flacons. */
#fiche .evcolph{grid-column:1 / -1;flex-basis:100%;}
#fiche .evphotos{display:flex;gap:8px;width:100%;overflow-x:auto;padding:3px 2px 5px;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity;}
#fiche .evphotos::-webkit-scrollbar{display:none;}
#fiche .evph{flex:0 0 56px;width:56px;height:56px;padding:0;border-radius:12px;overflow:hidden;background:#FFFFFF;
  border:2px solid rgba(11,16,32,.08);cursor:pointer;scroll-snap-align:start;}
#fiche .evph.elue{border-color:var(--marque-ombre);box-shadow:0 0 0 2px var(--marque-ombre);}
#fiche .evph:focus-visible{outline:2px solid var(--light);outline-offset:2px;}
#fiche .evph img{width:100%;height:100%;object-fit:cover;display:block;}
#fiche .evphnom{width:100%;padding-left:2px;color:var(--ink);font-size:var(--t-foot);line-height:1.35;}
#fiche .evmnom{width:100%;padding:2px 0 0 2px;color:var(--ink);font-size:var(--t-foot);line-height:1.35;}   /* le nom qu'un menu coupe (05/10) */
#fiche .evmnom[hidden]{display:none;}
#fiche .fnote{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin:4px 0 2px;color:var(--ink-2);font-size:var(--t-cap);}
#fiche .fnote i{font-style:normal;color:var(--ink-3);}
#fiche .fnote .fnote-et{display:inline-flex;align-items:center;gap:5px;}
#fiche .fnote .id-et{margin-top:0;width:62px;height:12px;-webkit-mask-size:62px 12px;mask-size:62px 12px;}
#fiche .fnote b{color:var(--ink);font-weight:600;}
/* les onglets : UNE barre, l'élu plein (maquette) — la couleur de famille reste sur le mot */
#fiche .fonglets{gap:2px;padding:3px;border-radius:14px;background:color-mix(in srgb,var(--ink) 7%,transparent);}
#fiche .fong{border:0;border-radius:11px;background:transparent;box-shadow:none;color:var(--ink-2);}
#fiche .fong.on{background:color-mix(in srgb,var(--ink) 14%,transparent);color:var(--ink);border:0;box-shadow:0 2px 8px -4px rgba(0,0,0,.35);}
:root[data-theme="halo-clair"] #fiche .fong.on{background:#FFFFFF;}
/* « Commander 50 pièces · 99,50 € » : le bouton prend le pied, le montant dans sa pastille */
#fiche .fpied .ftot{display:none;}
#fiche .fpied .fcelui{flex:1 1 auto;width:100%;display:flex;align-items:center;justify-content:center;gap:10px;}
#fiche .fpied .fcelui:has(.fcelui-m){justify-content:space-between;}
#fiche .fcelui-m{padding:4px 10px;border-radius:10px;background:rgba(255,255,255,.22);font-weight:600;}
/* « Refaire 4 photos sans texte » et sa pastille (lot 2) : mesuré à 375 px, 339 px pour 335 — ce bouton-là se resserre, une ligne */
#fiche .fpied .fcelui:has(.fcelui-long){padding-left:18px;padding-right:12px;}
#fiche .fpied .fcelui:has(.fcelui-long) > span{white-space:nowrap;}
/* ── MES COMMANDES v2, LES DÉTAILS (03/10, maquette validée) : rond retour + grand titre ; « Suivre › » ; « ● Livrée » ── */
.dossier.cmd-v2 .dhead{display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;row-gap:10px;padding-bottom:6px;}
.dossier.cmd-v2 .dhead .dclose{display:none;}
.dossier.cmd-v2 .dhead .dretour{width:44px;height:44px;border-radius:50%;background:color-mix(in srgb,var(--ink) 10%,transparent);}
.dossier.cmd-v2 .dhead > span{grid-column:1 / -1;justify-self:start;text-align:left;font-size:var(--t-large);font-weight:700;letter-spacing:var(--t-large-ls);}
.cmd-liste .cmd-suivre{display:flex;align-items:center;justify-content:space-between;gap:10px;width:calc(100% - 28px);margin:10px 14px 2px;
  padding:11px 14px;border:0;border-radius:12px;background:color-mix(in srgb,var(--ink) 7%,transparent);color:var(--ink-2);
  font:400 var(--t-foot)/1.3 var(--sans);text-align:left;cursor:pointer;}
.cmd-liste .cmd-suivre b{color:var(--light);font-weight:600;white-space:nowrap;}
.cmd-liste .cmd-livree{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:999px;font:600 var(--t-cap)/1.3 var(--sans);
  color:#2E9E5B;background:rgba(46,158,91,.14);}
.cmd-liste .cmd-livree::before{content:'';width:7px;height:7px;border-radius:50%;background:currentColor;}
.cmd-liste .cmd-suivi-n{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:8px 0;color:var(--ink-2);font-size:var(--t-foot);}
/* « MA MARQUE » (fondateur, 04-06/10 — option « Logo sur l'emballage ») : la feuille monte sur la fiche comme celle de la
   commande (`.fofeuille`), ses règles sont les SIENNES — préfixe `ma-`, ancrées sous `.fo-marque` : rien des autres
   feuilles n'en reçoit. Ce qu'elle montre sont les fichiers d'impression du serveur, pas un dessin. */
:is(.fiche,.hors-fiche) .fo-marque .fofeuille-corps{max-height:88vh;max-height:calc(100dvh - 48px);padding:8px 16px calc(env(safe-area-inset-bottom,0px) + 16px);}
:is(.fiche,.hors-fiche) .fo-marque .ma-t{margin:2px 0 0;font-size:var(--t-head);font-weight:700;color:var(--ink);}
:is(.fiche,.hors-fiche) .fo-marque .ma-s{margin:2px 0 0;font-size:var(--t-foot);color:var(--ink-3);}
:is(.fiche,.hors-fiche) .fo-marque .ma-lab{display:block;margin:16px 0 6px;font-size:var(--t-foot);font-weight:600;color:var(--ink-3);}
:is(.fiche,.hors-fiche) .fo-marque .ma-logo{display:flex;align-items:center;gap:12px;min-height:56px;padding:8px 12px;border-radius:14px;
  border:1px solid var(--carte-edge);background:var(--pane-2);cursor:pointer;-webkit-tap-highlight-color:transparent;}
:is(.fiche,.hors-fiche) .fo-marque .ma-logo img{width:44px;height:44px;border-radius:10px;object-fit:contain;background:#fff;}
:is(.fiche,.hors-fiche) .fo-marque .ma-vide{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:10px;
  border:1.5px dashed var(--carte-edge);color:var(--ink-3);font-size:var(--t-title);}
:is(.fiche,.hors-fiche) .fo-marque .ma-n{flex:1;min-width:0;font-weight:600;color:var(--ink);}
:is(.fiche,.hors-fiche) .fo-marque .ma-ch{color:var(--light);font-weight:600;font-size:var(--t-foot);}
:is(.fiche,.hors-fiche) .fo-marque .ma-err{margin-top:8px;font-size:var(--t-foot);color:var(--fam-estime);}
/* la scène : le sachet givré et son autocollant, la carte recto verso posée à côté */
:is(.fiche,.hors-fiche) .fo-marque .ma-scene{position:relative;height:178px;border-radius:16px;background:radial-gradient(circle at 40% 40%,color-mix(in srgb,var(--ink) 9%,transparent),transparent 70%);}
:is(.fiche,.hors-fiche) .fo-marque .ma-sachet{position:absolute;left:12px;top:14px;width:118px;height:150px;border-radius:8px;
  background:linear-gradient(180deg,rgba(255,255,255,.78),rgba(226,232,240,.62));box-shadow:0 10px 24px rgba(0,0,0,.28);
  display:flex;align-items:center;justify-content:center;}
:is(.fiche,.hors-fiche) .fo-marque .ma-sachet::before{content:'';position:absolute;left:8px;right:8px;top:12px;height:2px;border-radius:1px;background:rgba(0,0,0,.14);}
:is(.fiche,.hors-fiche) .fo-marque .ma-st{width:58px;height:58px;}
:is(.fiche,.hors-fiche) .fo-marque .ma-r,:is(.fiche,.hors-fiche) .fo-marque .ma-v{position:absolute;right:10px;width:46%;max-width:180px;aspect-ratio:1063/638;border-radius:4px;box-shadow:0 8px 18px rgba(0,0,0,.35);background:#fff;}
:is(.fiche,.hors-fiche) .fo-marque .ma-r{top:12px;transform:rotate(4deg);}
:is(.fiche,.hors-fiche) .fo-marque .ma-v{bottom:10px;transform:rotate(-3deg);}
:is(.fiche,.hors-fiche) .fo-marque .ma-leg{display:flex;justify-content:space-between;margin-top:6px;font-size:var(--t-cap);color:var(--ink-3);}
:is(.fiche,.hors-fiche) .fo-marque .ma-texte{width:100%;min-height:48px;padding:0 14px;border-radius:12px;border:1px solid var(--carte-edge);background:var(--pane-2);
  color:var(--ink);font-size:var(--t-champ);font-family:inherit;}
:is(.fiche,.hors-fiche) .fo-marque .ma-ok{display:block;margin:18px 0 0 auto;min-height:48px;padding:0 22px;border:0;border-radius:14px;
  background:var(--marque);color:var(--btn-plein-ink);font-weight:700;font-size:var(--t-body);font-family:inherit;cursor:pointer;}   /* bouton plein = --marque (doctrine des objets §5) */
/* la ligne « dont logo sur l'emballage » de la commande : LE logo qui sera imprimé, en vignette */
.fiche .fo-cmd .fx-logo{display:flex;align-items:center;gap:6px;}
.fiche .fo-cmd .fx-logo img{width:20px;height:20px;border-radius:4px;object-fit:contain;background:#fff;}
:is(.fiche,.hors-fiche) .fo-marque .ma-ok:disabled{opacity:.45;cursor:default;}
/* 08/10 — « Pas de logo ? Je t'en crée un » : son nom, trois propositions rondes ; et ce qu'un changement coûte */
:is(.fiche,.hors-fiche) .fo-marque .ma-creer{display:block;min-height:44px;margin:4px 0 0;padding:0;border:0;background:none;color:var(--light);font:inherit;font-size:var(--t-foot);font-weight:600;text-align:left;cursor:pointer;}
:is(.fiche,.hors-fiche) .fo-marque .ma-lab-nom{margin-top:0;}
:is(.fiche,.hors-fiche) .fo-marque .ma-props{display:flex;justify-content:center;gap:16px;min-height:84px;margin:14px 0 8px;}
:is(.fiche,.hors-fiche) .fo-marque .ma-prop{width:84px;height:84px;padding:0;border:0;border-radius:50%;background:none;cursor:pointer;}
:is(.fiche,.hors-fiche) .fo-marque .ma-prop img{display:block;width:100%;height:100%;border-radius:50%;}
:is(.fiche,.hors-fiche) .fo-marque .ma-prop.on{box-shadow:0 0 0 3px var(--light);}
:is(.fiche,.hors-fiche) .fo-marque .ma-prop:disabled{opacity:.6;cursor:default;}
:is(.fiche,.hors-fiche) .fo-marque .ma-imp{text-align:center;font-size:var(--t-foot);color:var(--ink-3);}
:is(.fiche,.hors-fiche) .fo-marque .ma-tirage{margin-top:8px;}
/* l'option logo dans la fiche : la ligne du tirage, son bénéfice avec le logo, et l'état « Dès 20 pièces » */
.fiche .fpopt[data-logo] .fpd-t,.fiche .fpopt[data-logo] .fpd-b{margin-top:6px;}
.fiche .fpopt[data-logo] .fpd-b{font-weight:700;color:var(--fam-argent);}
.fiche .fpopt[data-logo] .fpd-b:empty{display:none;}
.fiche .fpopt[data-logo]:disabled{opacity:.55;cursor:default;}
/* ══ LE PLACEMENT — doctrine de l'écran (docs/LEXIQUE.md, « Placer »), lot 1 des maquettes validées
   (docs/mockups/doctrine-texte-0810/). Fondateur : « tout le monde le voit, que quand c'est une IA, il y a des petits
   mauvais positionnements des chiffres, du texte ». Garde : tests/e2e/placement.spec.js — elle compare des BOÎTES,
   jamais ces règles ; réécrire ce bloc autrement doit la laisser verte. ══ */

/* la carte du bénéfice reste DANS l'écran. Elle reprenait la gouttière de l'avatar (-39 px) ; depuis que les cartes
   partent du bord du fil, elle commençait 23 px hors de l'écran (mesuré). Elle se distingue par son ombre, pas par sa largeur. */
.tranche .card,.tranche .ddp{margin-left:0;}

/* le menu + : un libellé d'une ligne se centre sur son icône — le haut servait au sous-titre, retiré (9 px d'écart mesurés) */
.feuille button{align-items:center;}

/* un titre de résultat coupé se coupe en deux lignes égales, jamais « Ventilateur de bureau » / « USB » */
.dcand .lab{text-wrap:balance;}

/* les idées : chaque colonne de chiffres finit au même bord que son titre. « Europe » s'aligne à droite comme les autres,
   avec son propre retrait vers Chine (fondateur, 27/09 : centrés, ses chiffres ne collaient plus aux ventes — le retrait
   garde cet écart). Les chiffres sur la ligne du nom (15 px d'écart mesurés) ; la photo, au milieu de la rangée. */
.idees .id-tri[data-tri="france"]{align-items:flex-end;text-align:right;padding-right:6px;}
.idees .id-fr{text-align:right;padding-right:6px;}
.idees .id-l{align-items:first baseline;}
.idees .id-ph{align-self:center;}
/* la rangée dépliée : ses photos prennent la largeur — une seule, en large ; deux ou trois, côte à côte et carrées
   (96 px calés à gauche d'une rangée de 332, mesuré) */
.idees .id-memes{overflow:visible;touch-action:auto;}   /* plus de bande qui défile : le doigt posé sur la photo fait défiler le fil */
.idees .id-m{flex:1 1 0;width:auto;min-width:0;}
.idees .id-m img{width:100%;height:auto;aspect-ratio:1;}
.idees .id-m:only-child img{aspect-ratio:16/10;}
@media (max-width:359px){ .idees .id-m{width:auto;} .idees .id-m img{width:100%;height:auto;} }
/* la fiche : dans chaque onglet, le contenu part du bord de la carte. Les blocs de « Vendre » ajoutaient leur propre
   retrait (12 à 24 px) à celui de la carte — six bords gauches mesurés d'un onglet à l'autre. */
.fiche .fo-carte .vd-choix{padding-left:0;padding-right:0;}
.fiche .fo-carte .vd-lignes{padding-left:0;padding-right:0;}
.fiche .fo-carte .vd-dit{padding-left:0;padding-right:0;}
.fiche .fo-carte .ae-boutique.p-obj{margin-left:0;margin-right:0;}
.fiche .fo-carte .fcarac > summary{padding-left:0;padding-right:0;}
.fiche .fo-carte .evet{padding-left:0;}

/* ══ LE LOT 2 — ce que la fiche et les idées écrivent (doctrine de l'écran ; maquettes validées, planches 0 et 2).
   Garde : tests/e2e/doctrine-lot2.spec.js (le texte) et placement.spec.js (les onglets égaux). ══ */
/* des onglets d'un mot, de même largeur : la grille partage la barre, quel que soit leur nombre */
#fiche .fonglets{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);}
.fiche .fong{padding-left:0;padding-right:0;}
/* une carte d'onglet sans bandeau : le haut que le bandeau tenait */
.fiche .fo-carte.fo-nu{padding-top:10px;}
/* le Marché : une rangée = un libellé et une valeur ; la source, un lien au bout de sa rangée */
.fiche .fo-carte.fo-nu > .row:first-child{border-top:0;}
.fiche .fo-carte > a.row.fo-src{color:var(--light);text-decoration:none;}
.fiche .fo-carte > a.row.fo-src .k{color:inherit;font-weight:600;}
.fiche .fo-carte > a.row.fo-src .v{color:var(--ink-3);font-weight:400;}
/* le Produit : le résumé « Variantes » se tait (Couleur, Taille et Quantité ont leur libellé), le dépliant reste ouvert */
.fiche .fo-carte.fo-nu .evpli > summary{display:none;}   /* la fiche 1688 seule : l'AliExpress garde « Quantité » et « Variantes » sur son pli */
.fiche .fo-carte .evqlab{display:block;margin:12px 0 6px;}
/* « Caractéristiques » : toute la largeur, le chevron au bout */
.fiche .fo-carte .fofiche{display:flex;justify-content:space-between;width:100%;box-sizing:border-box;}
.fiche .ft-src{margin:12px 16px 0;font-size:var(--t-cap);color:var(--ink-3);}   /* le bord des lignes de la feuille */
/* les idées : la légende d'une photo seule se tait ; d'où viennent les chiffres, en rangées */
.idees .id-m:only-child span{display:none;}
.idees .id-rangs{margin:2px 0 12px;}
.idees .id-r{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:10px 0;border-top:1px solid var(--edge);font-size:var(--t-foot);}
.idees .id-r:first-child{border-top:0;}
.idees .id-rk{color:var(--ink-2);}
.idees .id-rv{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums;text-decoration:none;}
.idees a.id-rv{color:var(--light);}
.idees .id-rv i{font-style:normal;font-weight:400;margin-left:6px;opacity:.6;}
/* ══ T4 (09/10) — LA PREUVE DU MARCHÉ ET CE QUE RABBIT RETIENT, maquettes validées le 08/10 (docs/mockups/marche-profil-0810/).
   Tout le reste est fait des classes du Fil (carte Revente, rangées, pastilles, `.seen`, `.p-it`) : ici, seulement ce qui manquait. */
/* M2c — la case dont le menu ⋯ est ouvert passe DEVANT ses voisines : chaque case de la planche est un contexte d'empilement
   (son animation d'arrivée reste appliquée) et la suivante se peignait par-dessus le menu (le patron de `.dobj:has(> .issues…)`) */
.deck-slot:has(.issues:not([hidden])){z-index:1;}
/* M2 — la zone « Vérifier le marché » et sa réponse se taisent sous le tableau Amazon (« Chez Amazon ») */
.fiche .fo-carte > [data-vdm][hidden]{display:none;}
/* M3 — « Corriger » sous sa bulle : la déclaration du « Corriger » de la ligne e-mail (`.fact .em-corriger`), élargie à `.seen` */
.seen .em-corriger{background:none;border:0;padding:0;font:inherit;font-weight:600;color:var(--light);text-decoration:underline;text-underline-offset:3px;cursor:pointer;}
/* M4 — le lien « conditions » prend la couleur de sa phrase (le précédent du même panneau : `.dossier .lv-i a`) */
.dossier .p-note a{color:inherit;}
.dossier .dgroupe > button[hidden]{display:none;}   /* « Effacer ce que Rabbit retient », rien de retenu : le `display:flex` des rangées battait `hidden` */
.dossier .dgroupe:not(:has(> button:not([hidden]))){display:none;}   /* un bloc dont toutes les rangées sont cachées (l'invité sans profil) */
.dossier .p-retenu:not(:has(.drang)){display:none;}   /* rien de retenu : ni l'en-tête ni le bloc (le bloc se cache seul, lot 3) */
.dossier .p-retenu .bandeau-n{display:none;}   /* l'ancre des rangées, sans titre : l'en-tête du lot 3 le porte */
.dossier .p-retenu .drang{cursor:pointer;line-height:1.35;border-top-color:var(--edge);}   /* `.row+.row` (filet --edge-2, transparent en Halo clair) battait le filet du lot 3 */
.dossier .p-retenu .drangs > .p-edit{padding:4px 16px 12px;}
.p-retenu-panne .em-corriger{background:none;border:0;padding:0;font:inherit;font-weight:600;color:var(--light);text-decoration:underline;text-underline-offset:3px;cursor:pointer;}
/* la correction d'un fait, sous sa rangée : ses choix en pastilles (comme le statut de la fiche), sinon un champ */
.p-edit{display:grid;gap:8px;padding:2px 2px 10px;}
.p-edit .avq{margin:0;}
.p-edit .pill.on{background:color-mix(in srgb,var(--fam-estime) 12%,transparent);border-color:var(--fam-estime);}
.p-edit .note-n:empty{display:none;}
.p-edit .note-n{font-size:var(--t-cap);color:var(--warm);}

/* ═══ L'ONGLET LIVRAISON (15/09) — destination · plaque · deux routes · taxes ═══════════
   Périmètre `lv-` : doctrine du Fil §5, un nom partagé est un périmètre. Payé une fois —
   une classe `u` d'accordéon avait hérité le fond de la BULLE du client (fil.css:828).
   Toutes les règles sont ancrées sous `.fiche` et préfixées ; aucune n'est réutilisable
   ailleurs par accident. */
.fiche .lv-surf{border:0;background-clip:padding-box;background:var(--pane);
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1px var(--carte-lisere), 0 8px 20px -12px var(--lum-ombre);}

/* la destination : c'est la première décision, elle a la taille de son rôle */
.fiche .lv-dest{border-radius:var(--r-3);margin:2px 0 0;overflow:hidden;}
.fiche .lv-dest > summary{list-style:none;display:flex;align-items:center;gap:12px;min-height:56px;padding:0 15px;cursor:pointer;}
.fiche .lv-dest > summary::-webkit-details-marker{display:none;}
.fiche .lv-dest .lvk{color:var(--ink-3);font-size:var(--t-foot);flex:none;}
.fiche .lv-dest .lvnom{font-weight:600;color:var(--ink);font-size:var(--t-title);letter-spacing:var(--t-title-ls);line-height:1.1;}
.fiche .lv-dest .lvchev{margin-left:auto;flex:none;width:9px;height:9px;border-right:2px solid var(--ink-3);border-bottom:2px solid var(--ink-3);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .22s var(--e-pouce);}
.fiche .lv-dest[open] .lvchev{transform:rotate(-135deg) translate(-2px,-2px);}
.fiche .lv-liste{max-height:236px;overflow-y:auto;padding:0 0 6px;-webkit-overflow-scrolling:touch;
  border-top:1px solid color-mix(in srgb,var(--ink) 8%,transparent);}
.fiche .lvgrp{font-size:var(--t-cap);color:var(--ink-3);padding:12px 15px 4px;position:sticky;top:0;background:var(--pane);}
.fiche .lv-liste .lv-p{display:block;width:100%;min-height:42px;padding:0 15px;border:0;background:transparent;
  font:inherit;font-size:var(--t-body);color:var(--ink);text-align:left;}
.fiche .lv-liste .lv-p.on{color:var(--fam-estime);font-weight:600;background:color-mix(in srgb,var(--fam-estime) 10%,transparent);}

/* LES OFFRES (lot 2, fondateur 26/09) : la plaque, les deux routes et l'interrupteur des taxes sont partis.
   Une offre = une rangée qu'on touche — celui qui livre et le prix du colis, le délai, ce qui reste à payer.
   La feuille de commande RAPPELLE l'offre choisie en une ligne (`resumeLivraison`) : même offre, même prix, jusqu'au paiement. */
.fiche .lv-offres{display:flex;flex-direction:column;gap:8px;margin-top:12px;}
.fiche .lv-tete{font-size:var(--t-foot);color:var(--ink-2);margin:0 2px 2px;}
.fiche .lv-o,.feuille-c .lv-o{display:flex;gap:12px;align-items:flex-start;width:100%;text-align:left;padding:12px 14px;border:0;border-radius:var(--r-2);
  background:var(--pane-2);box-shadow:inset 0 0 0 1px var(--carte-lisere);font:inherit;color:var(--ink);
  transition:background .2s var(--e-plat),box-shadow .2s var(--e-plat);}
.fiche .lv-o.on,.feuille-c .lv-o.on{background:color-mix(in srgb,var(--fam-estime) 12%,transparent);
  box-shadow:inset 0 1px 0 var(--lum-reflet), inset 0 0 0 1.5px color-mix(in srgb,var(--fam-estime) 55%,transparent);}
.fiche .lv-rd,.feuille-c .lv-rd{flex:none;width:18px;height:18px;margin-top:2px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--ink-3);}
.fiche .lv-o.on .lv-rd,.feuille-c .lv-o.on .lv-rd{box-shadow:inset 0 0 0 6px var(--fam-estime);}
.fiche .lv-c,.feuille-c .lv-c{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.fiche .lv-l1,.feuille-c .lv-l1{display:flex;justify-content:space-between;gap:10px;align-items:baseline;}
.fiche .lv-l1 b,.feuille-c .lv-l1 b{font-weight:600;font-size:var(--t-body);}
.fiche .lv-px,.feuille-c .lv-px{font-weight:600;font-size:var(--t-body);white-space:nowrap;font-variant-numeric:tabular-nums;}
.fiche .lv-j,.feuille-c .lv-j{font-size:var(--t-foot);color:var(--ink);}
.fiche .lv-t,.feuille-c .lv-t{font-size:var(--t-cap);color:var(--ink-2);line-height:1.35;}
.fiche .lv-garde{font-size:var(--t-foot);color:var(--fam-estime);font-weight:600;margin:10px 2px 0;}
.fiche .lv-l{display:flex;flex-direction:column;gap:8px;}
.fiche .lv-nom,.feuille-c .lv-nom{min-width:0;display:flex;flex-wrap:wrap;align-items:baseline;column-gap:.3em;}
.fiche .lv-nom i,.feuille-c .lv-nom i{font-style:normal;font-weight:400;color:var(--ink-2);}
/* le nom et le délai ne se coupent jamais en leur milieu : sur un nom long, le délai passe à la ligne d'un bloc (le flex
   ci-dessus coupe ENTRE eux — sans lui, deux blocs insécables débordent sur le prix) */
.fiche .lv-nom>*,.feuille-c .lv-nom>*{white-space:nowrap;}
.fiche .lv-o:focus-visible,.feuille-c .lv-o:focus-visible{outline:2px solid var(--fam-estime);outline-offset:2px;}
.fiche .lv-o.lecture{background:transparent;}

/* LA FEUILLE DE LA COMMANDE (fiche qui encaisse, 27/09 — docs/CHANTIER-FICHE-CAISSE-2709.md) : SA feuille, sur la fiche.
   Elle garde les classes de l'ancien récap (.feuille-c …) ; ce qui suit ne touche QUE .fo-cmd — ni « Détails », ni le fil. */
.fiche .fo-cmd .fofeuille-corps{max-height:82vh;max-height:calc(100dvh - 72px);padding:8px 0 calc(env(safe-area-inset-bottom,0px) + 14px);}
/* la poignée : une barre de 4 px, une zone de 44 px à toucher (relecture du 27/09 — sur iPhone la feuille couvre presque tout) */
.fiche .fo-cmd .fopoignee{position:relative;}
.fiche .fo-cmd .fopoignee::before{content:'';position:absolute;left:-44px;right:-44px;top:-8px;bottom:-32px;}
.fiche .fo-cmd .feuille-c{margin:0;box-shadow:none;background:transparent;border:0;}
.fiche .fo-cmd .fx-ligne{display:flex;align-items:center;gap:12px;width:100%;min-height:52px;margin:8px 0 0;padding:0 14px;
  border:0;border-radius:var(--r-3);background:var(--pane);color:var(--ink);font:inherit;text-align:left;cursor:pointer;}
.fiche .fo-cmd .fxk{flex:none;min-width:64px;color:var(--ink-3);font-size:var(--t-foot);}
.fiche .fo-cmd .fxv{flex:1;min-width:0;font-weight:600;}
.fiche .fo-cmd .fxm{display:inline-block;}   /* un morceau de ligne ne se coupe pas en deux (28/09) */
.fiche .fo-cmd .fxv.fxa{color:var(--fam-estime);}
.fiche .fo-cmd .fxchev{flex:none;width:8px;height:8px;border-right:2px solid var(--ink-3);border-bottom:2px solid var(--ink-3);transform:rotate(-45deg);}
.fiche .fo-cmd .fx-attente{padding:18px 16px;color:var(--ink-2);}
.fiche .fo-cmd .fx-lignes-f .lv-nat{margin:6px 14px 0;}
/* la phrase de Rabbit posée AVANT une carte (formule) : la marge de la feuille ; dans une carte, celle de la carte */
.fiche .fo-cmd .fo-cmd-c > .fx-parole{padding:6px 18px 10px;line-height:1.45;}
.fiche .fo-cmd .fx-choix{display:flex;flex-wrap:wrap;align-items:center;gap:8px 20px;margin:12px 0 0;}
/* un bouton a la taille de son verbe : la pleine largeur reste à « Payer » (doctrine des objets 4 et 5) */
.fiche .fo-cmd .fx-choix .cta-plein,.fiche .fo-cmd .fx-email-ok{display:inline-flex;align-items:center;justify-content:center;width:auto;margin-top:0;}
.fiche .fo-cmd .fx-email-ok{margin-top:10px;}
.fiche .fo-cmd .fx-compte-ok{display:inline-flex;align-items:center;justify-content:center;width:auto;margin-top:10px;}
.fiche .fo-cmd .fx-compte-aussi{display:flex;flex-wrap:wrap;align-items:center;gap:8px 20px;margin-top:10px;}
.fiche .fo-cmd .fx-oubli{justify-self:start;}
.fiche .fo-cmd .livf .fx-compte-msg{flex:1 1 100%;margin:2px 0 -3px;font-size:var(--t-cap);color:var(--warm);}
.fiche .fo-cmd .livf .fx-compte-msg[hidden]{display:none;}
.fiche .fo-cmd .fo-cmd-c > .fx-choix{padding:0 16px;}

/* ce qu'il paiera à l'arrivée — un fait nu, plus de parole de Rabbit ici (fondateur 15/09) */
.fiche .lv-taxe{font-size:var(--t-foot);line-height:1.45;color:var(--ink-2);margin-top:12px;padding-left:12px;
  border-left:2px solid color-mix(in srgb,var(--fam-estime) 38%,transparent);}
.fiche .lv-taxe:empty{display:none;}
.fiche .lv-nat{color:var(--ink-3);font-size:var(--t-cap);line-height:1.4;margin-top:10px;}

/* ══════ LE FIL SUR UN ORDINATEUR (fondateur, 13/10 : « sur ordi, c'est vraiment moche ») ══════
   Mesuré en prod à 1440 × 900 : la conversation tenait dans sa colonne de 640 px, mais l'en-tête
   collait aux coins de l'ÉCRAN (le menu à 388 px de la colonne) et tout ce qui couvre l'écran
   — fiche, demande, scan, dossier — était en inset:0 : la fiche s'étalait sur 1440 px.
   Au-delà de 700 px (tablette en portrait comprise), tout s'aligne sur LA colonne du fil ; en dessous, rien ne change.
   --marge-bureau : ce qui reste de chaque côté de la colonne (le % se résout chez l'élément
   qui l'emploie, contre la largeur de .screen). Garde : fil-grand-ecran. */
@media (min-width:700px){
  .screen.plein{--colonne:640px;--marge-bureau:max(0px, calc((100% - var(--colonne)) / 2));}
  .screen.plein .apphead{padding-inline:calc(var(--marge-bureau) + 20px);}
  .screen.plein .fiche,.screen.plein .demande,.screen.plein .scanscene,.screen.plein .dossier{
    left:var(--marge-bureau);right:var(--marge-bureau);
    border-inline:1px solid var(--edge-2);}
  .screen.plein .feuille,.screen.plein .casier,.screen.plein .annuler{
    left:calc(var(--marge-bureau) + 12px);right:calc(var(--marge-bureau) + 12px);}
}

/* ══════ LA BARRE DE GAUCHE ET LA FICHE À CÔTÉ (fondateur, 13/10 : « que tout ce qui est à gauche soit ouvert ») ══════
   Le patron de Claude et ChatGPT sur ordinateur. Dès 1024 px, le tiroir devient une barre TOUJOURS ouverte (fil.js :
   `BUREAU_MENU`) : il ne pousse plus le fil, il n'a plus de voile, l'en-tête monte en haut de la barre et le bouton
   menu disparaît. La colonne du fil se centre dans ce qui reste. Dès 1280 px, la fiche s'ouvre à DROITE de la
   conversation (`BUREAU_FICHE` : elle n'y est plus une couche modale). Les seuils sont ceux de fil.js — garde :
   fil-grand-ecran. Les cartes produits passent quatre par ligne : 320 px de photo par carte, c'était un téléphone agrandi. */
@media (min-width:1024px){
  .screen.plein{--barre:280px;padding-left:var(--barre);
    --marge-bureau:max(0px, calc((100% - var(--barre) - var(--colonne)) / 2));}
  .screen.plein[data-tiroir="1"] > .apphead,.screen.plein[data-tiroir="1"] > .threadwrap,
  .screen.plein[data-tiroir="1"] > .composer,.screen.plein[data-tiroir="1"] > .casier,
  .screen.plein[data-tiroir="1"] > .annuler{translate:none;}
  .screen.plein[data-tiroir="1"] > .threadwrap{pointer-events:auto;}
  .screen.plein .menu-veil{display:none;}
  .screen.plein .apphead #menubtn{pointer-events:none;}   /* il porte le logo et son cercle de marque : il reste, sans geste */
  /* les pastilles d'accueil se rangent au bord droit de l'en-tête — dans 280 px, c'est sur l'heure (vu en prod le 13/10,
     le banc ne les montrait pas : son visiteur n'est pas nouveau). L'heure s'efface tant qu'elles sont là, puis revient. */
  .screen.plein .apphead.bdg-la .ici{opacity:0;}
  .screen.plein .apphead{position:absolute;top:0;left:0;width:var(--barre);z-index:41;
    padding:calc(env(safe-area-inset-top,0px) + 12px) 18px 10px;border-bottom:0;}
  .screen.plein .app-menu{width:var(--barre);translate:none;transition:none;border:0;border-right:1px solid var(--edge-2);
    border-radius:0;box-shadow:none;padding-top:calc(env(safe-area-inset-top,0px) + 64px);}
  .screen.plein .fiche,.screen.plein .demande,.screen.plein .scanscene,.screen.plein .dossier{
    left:calc(var(--barre) + var(--marge-bureau));right:calc(var(--droite, 0px) + var(--marge-bureau));}
  .screen.plein .feuille,.screen.plein .casier,.screen.plein .annuler{
    left:calc(var(--barre) + var(--marge-bureau) + 12px);right:calc(var(--droite, 0px) + var(--marge-bureau) + 12px);}
  .screen.plein .deck-page{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));}
  /* l'ombre des cartes se coupait net sur le cadre qui les fait défiler (gauche et bas) : avec deux cartes sur quatre
     places, la coupure dessinait un rectangle clair (14/10). L'ombre a sa marge DANS le cadre, les cartes ne bougent pas. */
  .screen.plein .deck.liste.carre{padding:0 18px 26px;margin:0 -18px -26px;}
  .screen.plein .deck.liste.carre .deck-page{scroll-margin-inline:18px;}
  /* L'ACCUEIL CENTRÉ (14/10, maquette validée) : le salut, la saisie, puis les trois portes en cartes côte à côte, au milieu
     de l'écran. Le fil et sa boîte s'effacent (display:contents) pour que ses enfants se rangent avec la saisie ; fil.js
     pose et retire `.accueil-bureau` (`accueilCentre`). Les recherches récentes, posées AU-DESSUS de la saisie, y
     couvriraient le salut : elles attendent la conversation. */
  .screen.plein.accueil-bureau{justify-content:center;}
  .screen.plein.accueil-bureau > .threadwrap,.screen.plein.accueil-bureau #thread{display:contents;}
  .screen.plein.accueil-bureau #thread > .when{display:none;}
  .screen.plein.accueil-bureau #thread > *{flex:none;align-self:center;width:min(680px, calc(100% - 48px));margin:0;}
  .screen.plein.accueil-bureau #thread > .r{order:1;text-align:center;padding:0;}
  .screen.plein.accueil-bureau #thread > .r .av{display:none;}
  .screen.plein.accueil-bureau #thread > .r .rtxt{margin:0 auto;}
  .screen.plein.accueil-bureau #thread .acc-titre{font-size:var(--t-large);letter-spacing:-.025em;line-height:1.15;margin-bottom:8px;}
  .screen.plein.accueil-bureau #thread > .r:not(.prof){color:var(--ink-2);margin-bottom:26px;}
  .screen.plein.accueil-bureau > .composer{order:2;flex:none;align-self:center;width:min(680px, calc(100% - 48px));max-width:none;margin:0;padding:0;}
  .screen.plein.accueil-bureau .composer .recentes{display:none;}
  .screen.plein.accueil-bureau #thread > .portes-acc{order:3;margin-top:16px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
  .screen.plein.accueil-bureau .portes-acc .porte-acc{width:auto;flex-direction:column;align-items:flex-start;gap:10px;padding:14px;min-height:0;text-align:left;}
  .screen.plein.accueil-bureau .portes-acc .pa-chev{display:none;}
  .screen.plein.accueil-bureau .portes-acc .pa-t b{display:block;}
  .screen.plein.accueil-bureau .portes-acc .pa-t small{display:block;margin-top:3px;}
  .screen.plein.accueil-bureau .portes-acc .pa-n{display:inline-block;margin-left:6px;vertical-align:1px;}
  .screen.plein #fiche .fcarte .egal-main.egal-v2{aspect-ratio:auto;height:min(44vh,360px);max-height:none;}   /* toute la largeur, 360 px de haut :
     la photo laisse voir le prix et les choix sans défiler, et ne laisse pas un trou blanc à sa droite (relecture du 13/10) */
  /* le compte EN BAS de la barre, « Nouvelle recherche » en tête — le patron de Claude et ChatGPT (relecture du 13/10) ;
     au téléphone, le tiroir garde « Mon compte » en tête */
  .screen.plein .app-menu{display:flex;flex-direction:column;}
  .screen.plein .app-menu .menu-moi{order:99;margin-top:auto;position:sticky;bottom:-10px;flex:none;
    padding:12px 8px calc(env(safe-area-inset-bottom,0px) + 12px);border-bottom:0;border-top:1px solid var(--edge-2);
    background:color-mix(in srgb,var(--screen) 92%,var(--pane));}
}
@media (min-width:1280px){
  .screen.plein{--panneau:520px;}
  /* fiche ouverte, la conversation n'a plus que ce qui reste entre la barre et le panneau : tout ce qui se cale sur la colonne
     (la feuille du +, le dossier…) recalcule sa marge sur CET espace — vu en prod le 14/10 : le + ouvrait sa feuille 160 px
     à droite de sa croix, contre la fiche. */
  .screen.plein:has(> .fiche:not([hidden])){padding-right:var(--panneau);--droite:var(--panneau);
    --marge-bureau:max(0px, calc((100% - var(--barre) - var(--panneau) - var(--colonne)) / 2));}
  .screen.plein .fiche{left:auto;right:0;width:var(--panneau);border-inline:0;border-left:1px solid var(--edge-2);}
  /* la carte dont vient la fiche à côté se cercle dans la conversation (fil.js : `marquerCarteOuverte`, 14/10) */
  .screen.plein #thread [data-fiche-ouverte]{outline:2px solid var(--light);outline-offset:3px;}
}
