/*
    La scène de l'inscription : la boutique d'angle en CSS 3D.

    **Origine.** Extrait du prototype `Wanapos_Onboarding_A3`, dossier `source/generateur`, qui
    est la source d'origine de la piste A3. La scène SceneKit de l'app iOS
    (`VitrineSceneView.swift`) en est la transposition : son commentaire dit « exactement ce que
    fait le prototype source, où ces éléments sont des div posées sur un plan ». Le web ne refait
    donc pas le chemin à l'envers, il repart de la source.

    ⚠️ **COMMENT CE FICHIER A ÉTÉ CONSTITUÉ, ET L'ERREUR À NE PAS REFAIRE.**

    Première tentative : garder du CSS du prototype les seules règles dont la classe apparaissait
    dans le HTML de la boutique. **Ça a silencieusement jeté 45 règles**, dont les deux plus
    importantes du fichier :

        .world{transform-style:preserve-3d}
        .world *{transform-style:preserve-3d}

    Sans elles, tous les plans s'aplatissent : l'immeuble perd son volume et devient une image
    plate légèrement penchée. Avec elles disparaissaient aussi les stores, les vitrines, les
    ampoules et toutes les transitions.

    La raison : ces classes sont **injectées dynamiquement** (`{{d.worldCls}}`, `{{d.awnCls}}`,
    `{{d.washCls}}`…) et n'apparaissent donc nulle part en dur dans le HTML. Un filtre fondé sur
    ce qu'on lit dans le markup rate exactement les classes d'état, qui sont le cœur du système.

    Le fichier est donc reconstitué **par exclusion** : on garde tout le CSS de la scène, et on
    n'écarte que ce qui est explicitement l'interface du prototype (champs, boutons, panneau,
    cadres d'appareil), refaite en Tailwind. En cas de doute, on garde.

    **Pourquoi du CSS custom ici, alors que le projet est en Tailwind.** Une scène en perspective
    ne s'écrit pas en classes utilitaires : il y a une `perspective`, un `transform-style:
    preserve-3d`, des plans tournés dans l'espace et des dégradés qui portent l'ombrage.
    Dérogation accordée par Maxime le 04/11/2026, strictement limitée à la scène. **Toute
    l'interface du parcours reste en Tailwind.**

    **Structure.**
        .scene-web
          .sky      le fond, et ses couches de crépuscule, d'horizon, de nuit, de flux
          .cam      la perspective
            .anchor le point visé, en pourcentage de la zone
              .world la boutique, transformée par la caméra de l'étape courante

    La caméra est pilotée par six nombres, comme dans le prototype et comme en SceneKit :
    position x, y, z, zoom, inclinaison, rotation. Ils vivent dans `inscription.js`.

    **L'éclairage est peint, pas calculé.** Les dégradés portent déjà l'ombrage. La nuit, c'est
    la classe `.nuit` posée sur la scène qui allume les couches d'émission.
*/

/*
    LA POLICE : une vraie famille « Rota », avec ses graisses.

    `rota_4.css` déclare une famille par graisse (« Rota-Bold », « Rota-SemiBold »…) et aucune
    famille « Rota ». Or la scène demande `'Rota'` partout, et le panneau ne demandait rien : la
    page entière s'affichait en police système, néon de l'enseigne compris, sans la moindre
    erreur. Constaté le 04/11/2026 en comparant à l'iOS, qui est tout en Rota.

    Déclarée ici et non dans `rota_4.css`, pour ne rien changer aux autres pages du site.
*/
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Light.otf') format('opentype');font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-LightItalic.otf') format('opentype');font-weight:300;font-style:italic;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Regular.otf') format('opentype');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Italic.otf') format('opentype');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Medium.otf') format('opentype');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-SemiBold.otf') format('opentype');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Bold.otf') format('opentype');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-ExtraBold.otf') format('opentype');font-weight:800;font-style:normal;font-display:swap}
@font-face{font-family:'Rota';src:url('../../../../design/polices/Rota/Rota-Black.otf') format('opentype');font-weight:900;font-style:normal;font-display:swap}
.inscription-racine{font-family:'Rota',system-ui,sans-serif}

body{margin:0}
a{color:#604CF3}
a:hover{color:#4A38D4}
*{box-sizing:border-box}
button{font-family:inherit;cursor:pointer}
input{font-family:inherit}
sc-if,sc-for{display:contents}
/* ---------- sky ---------- */
/*
    Le ciel de jour, repris de `VitrineCielView.ciel(_:)`.

    **Le centre lumineux est tout en haut, à `50% 0%`, et non derrière le bâtiment.** C'est
    délibéré côté iOS : « le centre lumineux du ciel est remonté au-dessus du bâtiment, ce qui
    est en dessous s'assombrit, donc la silhouette se détache ». Le prototype le plaçait à 30 %
    de hauteur, donc juste derrière la boutique, qui se fondait dans le fond.

    Arrêts et rayon repris tels quels : blanc au centre, `#F1EDFF` à 45 %, `#E2D9FF` au bord,
    rayon `max(largeur × 1.2, hauteur × 0.8)`.
*/
.sky{position:absolute;inset:0;background:radial-gradient(circle max(120vw, 80vh) at 50% 0%,#FFFFFF 0%,#F1EDFF 45%,#E2D9FF 100%)}
.sky .dusk{position:absolute;inset:0;background:linear-gradient(180deg,#F4EEFF 0%,#EADCFF 45%,#F6D9F2 72%,#E6D6FF 100%);opacity:0;transition:opacity 1.8s ease}
/*
    L'horizon du crépuscule : une LUEUR sans contour qui monte du bas de l'écran, comme la lumière
    d'un soleil couché derrière la ville. Le prototype dessinait un grand disque clair au bord net,
    une petite planète sous la maquette. Cohérent tant que la boutique flottait seule ; faux depuis
    que la rue s'étend jusqu'aux bords (05/11/2026) : les routes semblaient traverser le disque et
    son bord coupait la chaussée. Remplacé à la demande de Maxime. La lueur garde la chaleur du
    crépuscule, qui marque l'approche de la fin du parcours, sans forme qui puisse entrer en
    conflit avec la scène, quelle que soit la caméra ou la taille de la fenêtre.
*/
.sky .horizon{position:absolute;left:-15%;right:-15%;bottom:0;height:70%;background:radial-gradient(ellipse 60% 85% at 38% 100%,rgba(255,226,244,.95) 0%,rgba(246,206,240,.7) 30%,rgba(222,198,255,.35) 60%,rgba(222,198,255,0) 100%);opacity:0;transform:translateY(80px);transition:opacity 1.6s ease,transform 2s cubic-bezier(.2,.8,.2,1)}
.sky .night{position:absolute;inset:0;background:radial-gradient(100% 70% at 50% 30%,#2E17C9 0%,#180A86 45%,#0B0336 100%);opacity:0;transition:opacity 2s ease}
.sky .flow{position:absolute;left:50%;top:50%;width:1900px;transform:translate(-50%,-58%) rotate(-10deg);opacity:0;mix-blend-mode:screen;-webkit-mask:radial-gradient(closest-side,#000 55%,transparent 100%);mask:radial-gradient(closest-side,#000 55%,transparent 100%);transition:opacity 2.6s ease 1s;pointer-events:none}
.scene-web .sky .flow{width:2600px;left:38%}
.sky .stars{position:absolute;inset:0;opacity:0;transition:opacity 2s ease 1.2s}
.star{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;box-shadow:0 0 8px 2px rgba(190,160,255,.8);animation:tw 3s ease-in-out infinite}
@keyframes tw{0%,100%{opacity:.25}50%{opacity:1}}
/* Le crépuscule : étapes entreprise et clés, comme `VitrinePlan.registre` (iOS). */
.crepuscule .sky .dusk{opacity:1}
.crepuscule .sky .horizon{opacity:1;transform:none}
.nuit .sky .night,.nuit .sky .flow,.nuit .sky .stars{opacity:1}
.nuit .sky .flow{opacity:.9}
/* ---------- 3D ---------- */
.cam{position:absolute;inset:0;perspective:1700px}
.scene-web .cam{perspective-origin:36% 52%}
.anchor{position:absolute;width:0;height:0;transform-style:preserve-3d}
.scene-web .anchor{left:36%;top:52%}
.world{position:absolute;left:0;top:0;width:0;height:0;transform-style:preserve-3d;transition:transform 2.3s cubic-bezier(.62,0,.22,1)}
.world *{transform-style:preserve-3d}
.scene-web .world.orbit{animation:orbitI 18s 2.4s ease-in-out infinite alternate}
@keyframes orbitP{from{transform:scale(.6) rotateX(-17deg) rotateY(-54deg) translate3d(0px,300px,50px)}50%{transform:scale(.6) rotateX(-21deg) rotateY(-36deg) translate3d(0px,316px,50px)}to{transform:scale(.6) rotateX(-17deg) rotateY(-16deg) translate3d(0px,300px,50px)}}
@keyframes orbitI{from{transform:scale(1.18) rotateX(-17deg) rotateY(-54deg) translate3d(0px,190px,50px)}50%{transform:scale(1.18) rotateX(-21deg) rotateY(-36deg) translate3d(0px,204px,50px)}to{transform:scale(1.18) rotateX(-17deg) rotateY(-16deg) translate3d(0px,190px,50px)}}
.bx{position:absolute;left:0;top:0;width:var(--w);height:var(--h);transform:translate3d(calc(var(--x,0px) - var(--w) / 2),calc(var(--y,0px) - var(--h)),var(--z,0px))}
.bx>i{position:absolute;left:0;top:0;width:var(--w);height:var(--h);backface-visibility:hidden;display:block}
.bx>.f{transform:translateZ(calc(var(--d) / 2))}
.bx>.k{transform:rotateY(180deg) translateZ(calc(var(--d) / 2))}
.bx>.r{width:var(--d);left:calc((var(--w) - var(--d)) / 2);transform:rotateY(90deg) translateZ(calc(var(--w) / 2))}
.bx>.l{width:var(--d);left:calc((var(--w) - var(--d)) / 2);transform:rotateY(-90deg) translateZ(calc(var(--w) / 2))}
.bx>.t{height:var(--d);top:calc((var(--h) - var(--d)) / 2);transform:rotateX(90deg) translateZ(calc(var(--h) / 2))}
.pl{position:absolute;left:0;top:0;backface-visibility:hidden}
/*
    ⚠️ Cette règle vaut 0,1,1 et l'emporte donc sur toute règle à une seule classe (`.awn`,
    `.wash`) : elle remplaçait leur transition, et le store comme le cache des vitrines
    sautaient d'un coup au lieu de s'animer (constaté le 05/11/2026). Un élément de la scène qui
    a sa propre transition doit être écrit `.world .x` pour passer devant.
*/
.world i,.world div{transition:background-color 1.6s ease,box-shadow 1.6s ease,opacity 1.2s ease}
/* palette jour */
.wall .f{background:#FFFFFF}
.wall .r{background:#DCD4FF}
.wall .l,.wall .k{background:#E9E4FF}
.wall .t{background:#0B0336}
.plinth .t{background:#FFFFFF;background-image:linear-gradient(90deg,rgba(96,76,243,.07) 1px,transparent 1px),linear-gradient(rgba(96,76,243,.07) 1px,transparent 1px);background-size:34px 34px}
.plinth .f{background:#D9D1FF}
.plinth .r,.plinth .l,.plinth .k{background:#C6BBFF}
.road .t{background:#E7E3F6;background-image:repeating-linear-gradient(90deg,#fff 0 26px,transparent 26px 52px);background-size:100% 3px;background-repeat:repeat-x;background-position:0 50%}
.road .f{background:#C9C2EA}
.road .r,.road .l{background:#BDB4E4}
.hedge .f{background:#C9BEFF}
.hedge .r{background:#B3A6FA}
.hedge .l{background:#C9BEFF}
.hedge .t{background:#DDD5FF}
.pole .f,.pole .r,.pole .l,.pole .k,.pole .t{background:#0B0336}
.lantern .f,.lantern .r,.lantern .l,.lantern .k{background:linear-gradient(#0B0336 0 3px,#EDE9FE 3px calc(100% - 3px),#0B0336 0)}
.lantern .t{background:#0B0336}
.wallp.pf{background:linear-gradient(180deg,#FFFFFF,#F7F5FF)}
.wallp.pd{background:linear-gradient(180deg,#F1EEFF,#E9E4FF)}
.wallp.pr{background:linear-gradient(180deg,#E9E4FF,#DCD4FF)}
.cornp.pf{background:#fff}
.cornp.pd{background:#F1EEFF}
.cornp.pr{background:#DDD5FF}
/*
    La corniche et le toit sont **la même couleur**, `#D9D3F7`.

    Côté iOS, `VitrinePalette.corniche` et `VitrinePalette.toit` valent toutes deux `0xD9D3F7`,
    et le commentaire précise que les corniches sont « volontairement plus claires que les
    façades : c'est ce liseré clair en haut des volumes qui découpe la silhouette sur le ciel ».
    Plus claires que les façades, pas blanches.

    Le prototype mettait `cornt` en blanc pur. Comme c'est ce plan qu'on voit par-dessus depuis
    l'angle du web, tout le dessus du bâtiment ressortait blanc et plat.
*/
.cornt{background:#D9D3F7}
.rooft{background:#D9D3F7}
.shadow{position:absolute;width:470px;height:360px;transform:translate3d(-235px,-196px,-30px) rotateX(90deg);background:radial-gradient(42% 34% at 58% 44%,rgba(60,30,180,.42),transparent 72%)}
.ao{position:absolute;left:0;right:0;pointer-events:none}
.ao.c0{top:0;height:12px;background:linear-gradient(rgba(40,20,150,.14),transparent)}
/* palette nuit */
.nuit .wallp.pf{background:linear-gradient(180deg,#2A18B0,#1F108F)}
.nuit .wallp.pd{background:linear-gradient(180deg,#22129E,#1A0C82)}
.nuit .wallp.pr{background:linear-gradient(180deg,#170A78,#120664)}
.nuit .cornp.pf{background:#3A27C8}
.nuit .cornp.pd{background:#2E1DB0}
.nuit .cornp.pr{background:#1C0E86}
.nuit .cornt{background:#3A27C8}
.nuit .rooft{background:#2E1DB0}
.nuit .wall .f{background:#2A18B0}
.nuit .wall .r{background:#170A78}
.nuit .wall .l{background:#22129E}
.nuit .plinth .t{background:#1E1092;background-image:linear-gradient(90deg,rgba(201,182,255,.08) 1px,transparent 1px),linear-gradient(rgba(201,182,255,.08) 1px,transparent 1px);background-size:34px 34px}
.nuit .plinth .f{background:#170A78}
.nuit .plinth .r,.nuit .plinth .l{background:#120664}
.nuit .road .t{background:#160A6E;background-image:repeating-linear-gradient(90deg,rgba(201,182,255,.5) 0 26px,transparent 26px 52px);background-size:100% 3px;background-repeat:repeat-x;background-position:0 50%}
.nuit .road .f{background:#0E0458}
.nuit .hedge .f{background:#2E1DB0}
.nuit .hedge .r{background:#1C0E86}
.nuit .hedge .t{background:#3A27C8}
.nuit .lantern .f,.nuit .lantern .r,.crepuscule .lantern .f,.crepuscule .lantern .r{background:linear-gradient(#0B0336 0 3px,#FFFFFF 3px calc(100% - 3px),#0B0336 0);box-shadow:0 0 20px 6px rgba(220,200,255,.8)}
.nuit .shadow{background:radial-gradient(30% 16% at 40% 82%,rgba(235,215,255,.95),rgba(180,140,255,.4) 50%,transparent 80%),radial-gradient(22% 14% at 82% 46%,rgba(235,215,255,.7),transparent 80%),radial-gradient(12% 14% at 14% 96%,rgba(235,215,255,.7),transparent 80%)}
/* façade */
.win{position:absolute;background:linear-gradient(160deg,#EEEAFF 0%,#D6CCFF 55%,#C4B6FF 100%);box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 4.5px #CFC6FF,inset 0 -10px 18px rgba(96,76,243,.18)}
.win::before{content:'';position:absolute;left:50%;top:4px;bottom:4px;width:2px;margin-left:-1px;background:#fff}
.win::after{content:'';position:absolute;left:4px;right:4px;top:38%;height:2px;background:#fff}
.nuit .win{background:radial-gradient(120% 90% at 50% 70%,#FFF6FF 0%,#E2D2FF 45%,#A88BFF 100%);box-shadow:inset 0 0 0 3px #D9C8FF,0 0 18px 4px rgba(200,170,255,.55)}
.nuit .win:nth-of-type(3n){background:linear-gradient(160deg,#3A27C8,#2A18B0);box-shadow:inset 0 0 0 3px #4A36D8}
.rail{position:absolute;background:repeating-linear-gradient(90deg,#1B0F6E 0 1.5px,transparent 1.5px 7px);border-top:2.5px solid #1B0F6E;border-bottom:2px solid #1B0F6E}
.nuit .rail{background:repeating-linear-gradient(90deg,#C9B6FF 0 1.5px,transparent 1.5px 7px);border-color:#C9B6FF}
.bfloor{position:absolute;transform-origin:50% 0;transform:rotateX(90deg);background:#FFFFFF;box-shadow:inset 0 0 0 1px #DCD4FF}
.nuit .bfloor{background:#4A34E8}
.dev{position:absolute;background:#22168A;box-shadow:inset 0 0 0 3px #2D1FA6,inset 0 0 0 5px #1A0F70}
.nuit .dev{background:#140870}
.band{position:absolute;top:6px;height:30px;background:#170C66;box-shadow:inset 0 0 0 1.5px #3A2BB8;display:flex;align-items:center;justify-content:center;overflow:hidden}
/*
    L'enseigne est centrée **sur l'encre**, pas sur la boîte de ligne.

    Le prototype montait le texte de 3 px (`margin-top:-3px`), ce qui est l'inverse de ce qu'il
    faut : une ligne tout en capitales n'a aucune descendante, donc un centrage par boîte de
    ligne la place déjà trop haut, et la remonter encore l'écrase sous le bord du bandeau.

    On la redescend donc, de `0.1325em`, valeur **mesurée** et non calculée. C'est le même défaut
    que le badge « Conseillé » de l'app iOS, corrigé le 04/11/2026 pour la même raison.

    ⚠️ **Le décalage se fait par `position:relative;top`, surtout pas par `margin-top`.** Le
    bandeau est un conteneur flex en `align-items:center`, et un conteneur flex centre la
    **boîte de marge** de son enfant : une marge haute de M ne descend l'élément que de M/2, le
    centrage rattrapant l'autre moitié. Mesuré ici : une marge de `.1825em` n'a corrigé que la
    moitié de l'écart attendu. `top` ne passe pas par la mise en page et décale de la valeur
    exacte.
*/
.name{font-family:'Rota',system-ui;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#FFFFFF;white-space:nowrap;line-height:1;position:relative;top:.1325em}
.name .ph{color:#6E62C9;letter-spacing:.3em;font-size:9px}
.ltr{display:inline-block;animation:ign 1s cubic-bezier(.2,.8,.2,1) both;text-shadow:0 0 3px #E9DEFF,0 0 8px #A98BFF}
@keyframes ign{0%{opacity:0;filter:blur(6px);transform:scale(1.7)}35%{opacity:1}55%{opacity:.4}70%{opacity:1}100%{filter:blur(0);transform:none}}
.nuit .name{text-shadow:0 0 4px #E9DEFF,0 0 12px #A98BFF,0 0 26px #7A55FF}
.bulbs{position:absolute;left:10px;right:10px;bottom:2px;display:flex;justify-content:space-between}
.bulb{width:3px;height:3px;border-radius:50%;background:#3A2E86;transition:background .3s,box-shadow .3s}
.bulb.on{background:#fff;box-shadow:0 0 4px 1.5px #C9B6FF}
.nuit .bulb.on{animation:chase 1.2s linear infinite}
.bulb:nth-child(2n){animation-delay:.3s}
.bulb:nth-child(3n){animation-delay:.6s}
/* La veille : une seule ampoule allumée parcourt le bandeau, 1/14 du cycle chacune.
   Le décalage par ampoule est posé en style inline par le composant. Repris de
   ampouleDeVeille() côté iOS : 2,8 s la boucle. */
.bulb.veille{animation:veille 2.8s linear infinite}
@keyframes veille{0%,7.14%{background:#fff;box-shadow:0 0 4px 1.5px #C9B6FF}7.15%,100%{background:#3A2E86;box-shadow:none}}
@keyframes chase{0%,100%{opacity:1}50%{opacity:.35}}
.cone{position:absolute;left:10px;right:10px;top:0;height:40px;background:radial-gradient(60% 100% at 25% 0%,rgba(255,240,255,.55),transparent 70%),radial-gradient(60% 100% at 75% 0%,rgba(255,240,255,.55),transparent 70%);opacity:0}
.nuit .cone{opacity:1}
/*
    ⚠️ **`clip-path` et pas seulement `overflow:hidden`.**

    La vitrine vit à l'intérieur de `.world`, qui est en `transform-style: preserve-3d`. Dans un
    contexte 3D, **`overflow:hidden` ne découpe pas ses descendants** : les articles posés en
    vitrine et les reflets du verre sortaient par la gauche et flottaient à côté du bâtiment,
    sous le store. Remettre `transform-style:flat` sur la vitrine ne suffit pas, le contexte
    englobant reste 3D.

    `clip-path: inset(0)` découpe au rectangle de l'élément et s'applique, lui, quel que soit le
    contexte de transformation. `overflow:hidden` est conservé pour le défilement et pour les
    navigateurs qui s'en contentent.
*/
.shop{position:absolute;overflow:hidden;clip-path:inset(0);background:linear-gradient(170deg,#F4F1FF 0%,#E1D9FF 60%,#CFC3FF 100%);box-shadow:inset 0 0 0 3px #3A2BB8;transform-style:flat}
.shop *{transform-style:flat}
.nuit .shop,.nuit .shop .pane{background:radial-gradient(110% 100% at 50% 40%,#FFFFFF 0%,#F0E6FF 40%,#C3A9FF 100%)}
.nuit .shop{box-shadow:inset 0 0 0 3px #3A2BB8,0 0 30px 8px rgba(200,170,255,.6)}
.refl{position:absolute;left:-30px;top:-20px;width:40px;height:160px;background:rgba(255,255,255,.55);transform:rotate(24deg);pointer-events:none}
.nuit .refl{opacity:.12}
/* Le reflet en diagonale du prototype est retiré (04/11/2026) : l'iOS n'en a pas, et sur la
   vitrine blanchie il se lisait comme un contour coupé en plein milieu. L'élément reste dans le
   markup pour garder la structure du prototype. */
.refl{display:none}
.pend{position:absolute;top:0;width:1px;background:#3A2BB8}
.pend i{position:absolute;left:-6px;bottom:-8px;width:13px;height:8px;border-radius:7px 7px 2px 2px;background:#3A2BB8}
.nuit .pend i{background:#fff;box-shadow:0 4px 14px 4px rgba(255,240,255,.9)}
.shelf{position:absolute;left:8px;right:8px;height:3px;background:#B6A8FF;border-radius:1px}
/*
    Les articles posés en vitrine.

    `overflow:hidden` est **obligatoire** : sans lui, un article dont l'animation de chute part
    d'au-dessus déborde par le haut et se voit flotter sur la devanture, au-dessus du dormant.
    L'app iOS fait la même chose par un `c.clip(to: rect)` sur le rectangle du verre
    (`VitrineFacadesRenderer`, dessin des articles).
*/
.goods{position:absolute;inset:0;overflow:hidden;clip-path:inset(0)}
.goods .g,.goods .shelf,.goods .vinyl{opacity:0}
.goods.in .shelf{opacity:1;transition:opacity .4s .2s}
.goods.in .g{position:absolute;display:block;box-shadow:0 1px 0 rgba(11,3,54,.2);animation:drop .7s cubic-bezier(.3,1.5,.5,1) both}
.goods .g{position:absolute;display:block}
.goods.in .g:nth-of-type(2){animation-delay:.55s}
.goods.in .g:nth-of-type(3){animation-delay:.62s}
.goods.in .g:nth-of-type(4){animation-delay:.69s}
.goods.in .g:nth-of-type(5){animation-delay:.76s}
.goods.in .g:nth-of-type(6){animation-delay:.83s}
.goods.in .g:nth-of-type(7){animation-delay:.9s}
.goods.in .g:nth-of-type(8){animation-delay:.97s}
.goods.in .g:nth-of-type(1){animation-delay:.48s}
@keyframes drop{from{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:none}}
/*
    La vitrophanie, le nom de l'enseigne répété sur le verre de la vitrine.

    **Retirée**, décision portée par l'app iOS. Elle alourdissait une vitrine déjà chargée et
    répétait une information que le bandeau porte juste au-dessus, en plus lisible. L'élément
    reste dans le markup, masqué, pour ne pas désaligner les `nth-of-type` des articles.
*/
.vinyl{display:none}
.goods.in .vinyl{opacity:1;transition:opacity .6s 1.1s}
.nuit .vinyl{color:#2A15B8}
.world .wash{position:absolute;inset:3px;background:repeating-linear-gradient(115deg,rgba(255,255,255,.96) 0 6px,rgba(244,240,255,.96) 6px 9px);display:flex;align-items:center;justify-content:center;clip-path:inset(0 0 0 0);transition:clip-path 1.1s cubic-bezier(.7,0,.2,1)}
.wash span{font:300 italic 15px/1 'Rota',system-ui;color:#8C80D9;letter-spacing:.02em;transform:rotate(-6deg)}
.wash.off{clip-path:inset(0 0 0 100%)}
.counter{position:absolute;left:18px;right:18px;bottom:6px;height:14px;background:#fff;border-radius:2px;box-shadow:0 2px 0 #C9BEFF;animation:drop .7s cubic-bezier(.3,1.5,.5,1) both}
.counter i{position:absolute;left:50%;top:-12px;width:14px;height:11px;margin-left:-7px;border-radius:2px;background:#0B0336;box-shadow:0 0 6px #8F6BFF}
.door{position:absolute;background:#1A0F70;box-shadow:inset 0 0 0 3px #3A2BB8}
.door .gl{position:absolute;top:7px;height:64px;background:linear-gradient(170deg,#EAE5FF,#C9BDFF);box-shadow:inset 0 0 0 1.5px #3A2BB8}
.nuit .door .gl{background:radial-gradient(circle at 50% 40%,#FFF,#CDB8FF);box-shadow:0 0 14px 3px rgba(200,170,255,.7)}
.door .hd{position:absolute;top:76px;width:3px;height:14px;border-radius:2px;background:#E7DFFF}
.open{position:absolute;left:6px;top:14px;width:24px;height:12px;transform-origin:50% -6px;animation:swing 2.6s .8s ease-in-out infinite both}
.open::before{content:'';position:absolute;left:4px;right:4px;top:-6px;height:7px;border:1px solid #fff;border-bottom:none;border-radius:6px 6px 0 0}
.open span{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:2px;background:#fff;font:900 4.6px/1 'Rota',system-ui;letter-spacing:.06em;color:#4124FD;box-shadow:0 1px 4px rgba(11,3,54,.4)}
@keyframes swing{0%{transform:rotate(-16deg)}50%{transform:rotate(12deg)}100%{transform:rotate(-16deg)}}
.lamp{position:absolute;top:-2px;width:10px;height:6px;border-radius:0 0 6px 6px;background:#0B0336;transform:translateZ(14px)}
.arm{position:absolute;top:-8px;width:2px;height:16px;background:#0B0336;transform-origin:50% 0;transform:translateZ(7px) rotateX(-60deg)}
.world .awn{position:absolute;height:30px;transform-origin:50% 0;transform:rotateX(0deg) scaleY(0);transition:transform 1.2s cubic-bezier(.3,1.35,.45,1);background:repeating-linear-gradient(90deg,#604CF3 0 14px,#FFFFFF 14px 28px);box-shadow:inset 0 -6px 10px rgba(11,3,54,.12)}
.awn.up{transform:rotateX(56deg) scaleY(1)}
.nuit .awn{background:repeating-linear-gradient(90deg,#3A26C9 0 14px,#C9B6FF 14px 28px)}
/*
    Le lambrequin, la bande suspendue au bord du store.

    **Bord droit, pas de festons.** Le prototype découpait des demi-lunes avec un masque radial.
    L'app iOS a tranché pour une finition droite (`VitrineSceneView.store()` : un lambrequin
    `SCNBox` rayé comme le tablier), et c'est l'iOS qui fait foi. Le masque est donc retiré.
*/
.val{position:absolute;left:0;right:0;top:30px;height:12px;transform-origin:50% 0;transform:rotateX(-56deg);background:repeating-linear-gradient(90deg,#604CF3 0 14px,#FFFFFF 14px 28px)}
.nuit .val{background:repeating-linear-gradient(90deg,#3A26C9 0 14px,#C9B6FF 14px 28px)}
.rshop{position:absolute;overflow:hidden;clip-path:inset(0);box-shadow:inset 0 0 0 3px #3A2BB8;background:#1A0C7C;transform-style:flat}
.rshop *{transform-style:flat}
.rshop .inside{position:absolute;inset:3px;background:radial-gradient(90% 80% at 50% 70%,#6A52FF,#2A15B8 60%,#170A78)}
.rshop .hcounter{position:absolute;left:-3px;right:-3px;bottom:0;height:18px;background:#fff;box-shadow:0 -3px 0 #C9BEFF}
.rshop .phone{position:absolute;left:54px;bottom:20px;width:14px;height:22px;border-radius:3px;background:#0B0336;box-shadow:0 0 0 1.5px #B79CFF,0 0 14px 4px rgba(183,156,255,.9)}
.rshop .pane{position:absolute;inset:0;overflow:hidden;background:linear-gradient(170deg,#F4F1FF 0%,#E1D9FF 60%,#CFC3FF 100%);box-shadow:inset 0 0 0 3px #3A2BB8;transition:transform 1.1s cubic-bezier(.6,0,.2,1)}
.rshop.hatch .pane{transform:translateY(-86%)}
/* ---------- familles en lévitation ---------- */
.fams{position:absolute;z-index:4;animation:fade .7s 1.3s both}
.scene-web .fams{left:30px;width:700px;top:60px;height:700px}
.fams::before{content:'';position:absolute;inset:-60px;background:radial-gradient(closest-side,rgba(247,245,255,.96),rgba(247,245,255,.85) 55%,rgba(247,245,255,0));backdrop-filter:blur(3px);-webkit-mask:radial-gradient(closest-side,#000 60%,transparent);mask:radial-gradient(closest-side,#000 60%,transparent)}
@keyframes fade{from{opacity:0}to{opacity:1}}
.tok{position:absolute;transform:translate(-50%,-50%);border:0;background:rgba(255,255,255,.88);border-radius:22px;min-height:36px;padding:0 13px 0 10px;display:flex;align-items:center;gap:7px;font:600 12.5px/1 'Rota',system-ui;color:#1B1550;white-space:nowrap;box-shadow:0 0 0 1px rgba(96,76,243,.14),0 10px 24px -12px rgba(60,30,180,.5);transition:left 1s cubic-bezier(.6,0,.2,1),top 1s cubic-bezier(.6,0,.2,1),opacity .6s,background .4s,color .4s,transform .6s}
.scene-web .tok{font-size:15px;min-height:44px;padding:0 16px 0 12px}
.tok i{width:9px;height:9px;border-radius:50%;background:#604CF3;box-shadow:0 0 0 3px rgba(96,76,243,.18);flex:none}
.tok span{display:block;animation:bob 5s ease-in-out infinite}
.tok.dim{opacity:.0;pointer-events:none}
.tok.sel{background:#0B0336;color:#fff;transform:translate(-50%,-50%) scale(1.12);box-shadow:0 0 0 6px rgba(96,76,243,.18),0 18px 40px -12px rgba(11,3,54,.7)}
.tok.sel i{background:#B79CFF;box-shadow:0 0 8px #B79CFF}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
.tok:nth-child(3n) span{animation-delay:-1.6s}
.tok:nth-child(3n+1) span{animation-delay:-3.1s}
.ring{position:absolute;left:50%;top:50%;border:1.5px dashed rgba(96,76,243,.3);border-radius:50%;transform:translate(-50%,-50%);animation:ringin 1.1s .5s cubic-bezier(.2,.8,.2,1) both;pointer-events:none}
@keyframes ringin{from{opacity:0;transform:translate(-50%,-50%) scale(.4)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.sat{position:absolute;border:0;background:transparent;padding:0;width:0;height:0;animation:satin .8s cubic-bezier(.2,.9,.2,1.2) both}
@keyframes satin{from{opacity:0;transform:translate(var(--fx),var(--fy)) scale(.3)}to{opacity:1;transform:none}}
.sat span{position:absolute;left:0;top:0;transform:translate(-50%,-50%);white-space:nowrap;font:600 12.5px/1 'Rota',system-ui;color:#1B1550;padding:10px 13px;border-radius:18px;background:#fff;box-shadow:0 0 0 1.5px #D8D0FF,0 10px 22px -12px rgba(60,30,180,.5);transition:all .3s}
.scene-web .sat span{font-size:15px;padding:12px 16px}
.sat:hover span{box-shadow:0 0 0 1.5px #604CF3}
.sat.on span{background:#604CF3;color:#fff;box-shadow:0 0 0 5px rgba(96,76,243,.2),0 12px 26px -10px rgba(96,76,243,.9)}
.nuit .scrimT,.nuit .scrimB{opacity:0}
.nuit .scrimB.dark{opacity:1;background:linear-gradient(rgba(11,3,54,0),rgba(11,3,54,.8) 50%)}
.nuit .panel{background:rgba(20,8,100,.45);box-shadow:0 0 0 1px rgba(201,182,255,.18),0 30px 60px -30px rgba(0,0,0,.5)}
@keyframes rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.devcol{display:flex;flex-direction:column;align-items:center;gap:34px}

/*
    `x-cloak` masque un élément tant qu'Alpine n'a pas démarré. Sans cette règle l'attribut ne
    fait rien, et toutes les étapes du parcours apparaissent en même temps pendant la fraction
    de seconde qui précède l'initialisation.
*/
[x-cloak]{display:none !important}

/* =====================================================================================
   LA GRILLE DES FAMILLES (étape du métier)

   Sur le web, une grille et non le carrousel de l'iOS : décision de Maxime du 04/11/2026, un
   défilement horizontal n'a pas sa place à la souris. Les animations restent celles de
   `VitrineCarteFamilleView` (iOS) et portent des variables par carte (période, déphasage,
   retard d'entrée) que des classes utilitaires ne savent pas exprimer.

   Deux couches par carte, une par mouvement, pour qu'aucun ne remplace l'autre :
     .carte-entree   l'entrée échelonnée, jouée une seule fois
     .carte-lev      la lévitation, continue
   ===================================================================================== */

/* Quand la grille défile, ses bords s'estompent au lieu de couper une carte net. Le fondu tient
   dans les 5 px de marge de la grille : sans défilement, il ne touche aucune carte. */
.grille-familles{scrollbar-width:thin;scrollbar-color:#DCD5FF transparent;
  mask-image:linear-gradient(to bottom,transparent 0,#000 5px,#000 calc(100% - 5px),transparent 100%)}

/* L'entrée vient d'en bas, comme si la carte montait se mettre en place : 16 px, 0,52 s,
   échelonnée de 0,06 s par rang. */
.carte-entree{animation:carte-monte .52s cubic-bezier(.16,1,.3,1) var(--entree) both}
.grille-familles.deja-entre .carte-entree{animation:none}
@keyframes carte-monte{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* Amplitude de 3,5 px : les objets lévitent, ils ne rebondissent pas. Période propre à chaque
   carte, pour que la rangée flotte au lieu de respirer en bloc. */
.carte-lev{height:100%;animation:carte-flotte var(--periode) ease-in-out var(--dephasage) infinite alternate both}
@keyframes carte-flotte{from{transform:translateY(3.5px)}to{transform:translateY(-3.5px)}}

/* L'appui : échelle 0,97, sans décalage de mise en page. */
.carte-btn{transition:transform .3s cubic-bezier(.3,1.4,.5,1)}
.carte-btn:active{transform:scale(.97)}

/* Le halo, et non une ombre portée grise : c'est la signature de la charte. */
.carte-fond{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:20px;
  background:rgba(255,255,255,.92);box-shadow:0 0 0 1px rgba(220,213,255,.9),0 8px 32px -6px rgba(96,76,243,.16)}

/* La capsule de la famille choisie : son fond seul voyage depuis la carte. */
.capsule-fond{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:9999px;background:#604CF3}
.capsule-texte{animation:capsule-texte .38s .14s ease-out both}
@keyframes capsule-texte{from{opacity:0}to{opacity:1}}

@media (prefers-reduced-motion: reduce){
  .carte-entree,.carte-lev,.capsule-texte{animation:none}
}

/* ---------- l'étape de la caisse (transposée de `VitrineServiceView`) ---------- */
/*
    Le voile : même flou (22) et même lavande (#EDE9FE à 46 %) que l'iOS. Assez pour que la
    boutique devienne une ambiance et non un décor lisible, pas assez pour effacer ses couleurs.
*/
.voile-caisse{-webkit-backdrop-filter:blur(22px);backdrop-filter:blur(22px);background:rgba(237,233,254,.46)}
/*
    Les cartes. Choisie : fond blanc plein, filet indigo de 3, très légèrement grossie. L'autre,
    une fois un choix fait : estompée et un peu réduite, pour que le choix se lise d'un coup
    d'œil. Le ressort reprend celui de l'iOS (réponse 0,5 s, amorti 0,62).
*/
.carte-caisse{border-radius:26px;background:rgba(255,255,255,.78);box-shadow:inset 0 0 0 1.5px rgba(220,213,255,.9),0 14px 34px -14px rgba(60,30,180,.35);transition:transform .5s cubic-bezier(.3,1.35,.45,1),opacity .4s ease,background-color .3s ease,box-shadow .3s ease}
.carte-caisse:hover{background:rgba(255,255,255,.92)}
.carte-caisse.choisie{background:#fff;transform:scale(1.015);box-shadow:inset 0 0 0 3px #604CF3,0 14px 34px -14px rgba(60,30,180,.45)}
.carte-caisse.estompee{opacity:.52;transform:scale(.975)}
.carte-caisse.estompee:hover{opacity:.8}
@media (prefers-reduced-motion:reduce){.carte-caisse{transition:none}}

/* ---------- le décor de rue, web seulement (05/11/2026) ---------- */
/*
    Les voisins et la rue prolongée. Tout est pâle : la devanture indigo doit rester le seul
    élément saturé, l'œil va toujours à la boutique. Pas de `filter: blur` pour le lointain, il
    aplatirait la 3D (même piège que `overflow:hidden`) : le recul se fait par la couleur, et
    les sols prolongés s'effacent dans le ciel par un masque posé sur leurs faces, qui sont des
    feuilles sans enfant 3D.
*/
.rue-ext.ext-d>i{-webkit-mask-image:linear-gradient(to left,transparent 0,#000 70%);mask-image:linear-gradient(to left,transparent 0,#000 70%)}
.rue-ext.ext-g>i{-webkit-mask-image:linear-gradient(to right,transparent 0,#000 70%);mask-image:linear-gradient(to right,transparent 0,#000 70%)}
/* La face du dessus est tournée de 90° : son haut local pointe vers l'arrière de la scène. */
.rue-ext.ext-ar>.t{-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 65%);mask-image:linear-gradient(to bottom,transparent 0,#000 65%)}
.rue-ext.ext-ar>.r,.rue-ext.ext-ar>.l{-webkit-mask-image:linear-gradient(to left,transparent 0,#000 65%);mask-image:linear-gradient(to left,transparent 0,#000 65%)}
/* La route latérale court selon la profondeur : ses tirets aussi. */
.road-z .t{background:#E7E3F6;background-image:repeating-linear-gradient(180deg,#fff 0 26px,transparent 26px 52px);background-size:3px 100%;background-repeat:repeat-y;background-position:50% 0}
.nuit .road-z .t{background:#160A6E;background-image:repeating-linear-gradient(180deg,rgba(201,182,255,.5) 0 26px,transparent 26px 52px);background-size:3px 100%;background-repeat:repeat-y;background-position:50% 0}

.voisin .f,.voisin .r{background:#F3F0FF}
.voisin .l,.voisin .k{background:#E6E1FB}
.voisin .t{background:#E9E5FA}
/* Les étages : une grille de fenêtres de 40 × 56, en un seul fond répété. */
.vz-etages{position:absolute;top:14px;width:160px;height:168px;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='56'%3E%3Crect x='7' y='8' width='26' height='38' rx='2' fill='%23E1DBF8'/%3E%3Crect x='5' y='44' width='30' height='3' fill='%23E9E4FB'/%3E%3C/svg%3E") 0 0/40px 56px repeat}
/*
    Le rez-de-chaussée : une vraie devanture, deux vitrines encadrées chacune sous son petit store
    et une porte vitrée entre les deux. La première version (un aplat pleine largeur sous un
    store continu) se lisait comme une porte de garage, remarque de Maxime du 05/11/2026.
*/
.vz-rdc{position:absolute;left:12px;right:12px;bottom:0;height:64px;border-top:4px solid #E6E1FB}
.vz-vitrine{position:absolute;bottom:4px;width:38%;height:42px;border-radius:2px;background:linear-gradient(160deg,#F1EEFF 0%,#E2DCF8 60%,#D9D2F6 100%);box-shadow:inset 0 0 0 3px #FAF9FF,inset 0 0 0 4px #E2DCF8;background-image:linear-gradient(115deg,transparent 40%,rgba(255,255,255,.55) 41%,rgba(255,255,255,.55) 48%,transparent 49%),linear-gradient(160deg,#F1EEFF 0%,#E2DCF8 60%,#D9D2F6 100%)}
.vz-store{position:absolute;left:-3px;right:-3px;top:-12px;height:9px;border-radius:0 0 3px 3px;background:repeating-linear-gradient(90deg,#DDD6F8 0 8px,#FAF9FF 8px 16px);box-shadow:0 2px 0 rgba(150,130,230,.12)}
.vz-porte{position:absolute;left:50%;bottom:0;width:15%;height:50px;transform:translateX(-50%);border-radius:2px 2px 0 0;background:linear-gradient(#E9E4FB 0 58%,#E2DCF8 58%);box-shadow:inset 0 0 0 3px #FAF9FF,inset 0 0 0 4px #E2DCF8}
.vz-allumee{position:absolute;width:26px;height:38px;border-radius:2px;opacity:0;transition:opacity 1.6s ease 1.4s}

.nuit .voisin .f,.nuit .voisin .r{background:#1C0F84}
.nuit .voisin .l,.nuit .voisin .k{background:#150A6C}
.nuit .voisin .t{background:#24159A}
.nuit .vz-etages{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='56'%3E%3Crect x='7' y='8' width='26' height='38' rx='2' fill='%23281A9E'/%3E%3C/svg%3E")}
.nuit .vz-rdc{border-top-color:#24159A}
.nuit .vz-vitrine{background-image:linear-gradient(160deg,#3423B4 0%,#2A1AA0 100%);box-shadow:inset 0 0 0 3px #1C0F84,inset 0 0 0 4px #2E1FA8}
.nuit .vz-store{background:repeating-linear-gradient(90deg,#3A28B8 0 8px,#24159A 8px 16px);box-shadow:none}
.nuit .vz-porte{background:linear-gradient(#2E1FA8 0 58%,#24159A 58%);box-shadow:inset 0 0 0 3px #1C0F84}
/* La nuit, quelques fenêtres des voisins s'allument, plus tard et plus doucement que la boutique. */
.nuit .vz-allumee{opacity:.85;background:radial-gradient(120% 90% at 50% 70%,#F3EAFF 0%,#CDB8FF 55%,#8E70F0 100%);box-shadow:0 0 12px 2px rgba(200,170,255,.35)}

/*
    Le voisin de derrière a son propre style, pour que la rue ne se lise pas comme un motif
    copié-collé (demande de Maxime du 05/11/2026) : façade d'un ton plus chaud, fenêtres
    cintrées, et au rez-de-chaussée une porte sur le côté et une seule grande vitrine cintrée
    sous un store uni, là où le voisin de gauche a deux vitrines rayées et une porte centrale.
*/
.voisin-b .f,.voisin-b .r{background:#F7F2FF}
.voisin-b .vz-etages{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='56'%3E%3Cpath d='M9 46V18a11 11 0 0 1 22 0v28z' fill='%23E6DCF8'/%3E%3C/svg%3E")}
.voisin-b .vz-rdc{border-top:6px solid #EDE5FB}
.vz-porte-b{left:6px;transform:none;width:20%;height:52px;border-radius:12px 12px 0 0}
.vz-vitrine-b{right:0;width:66%;height:44px;border-radius:22px 22px 2px 2px}
.vz-store-b{left:8%;right:8%;top:-10px;height:7px;border-radius:4px;background:#E3D9F7;box-shadow:0 2px 0 rgba(150,130,230,.12)}
.nuit .voisin-b .f,.nuit .voisin-b .r{background:#1E1088}
.nuit .voisin-b .vz-etages{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='56'%3E%3Cpath d='M9 46V18a11 11 0 0 1 22 0v28z' fill='%232B1CA2'/%3E%3C/svg%3E")}
.nuit .voisin-b .vz-rdc{border-top-color:#2A1AA0}
.nuit .vz-store-b{background:#3A28B8}
/* Les fenêtres allumées épousent le cintre. */
.voisin-b .vz-allumee{width:22px;height:38px;border-radius:11px 11px 2px 2px;margin:0 0 0 2px}

/* ---------- inscription allégée (petits écrans) ---------- */
/*
    Sous 900 px de large ou 560 px de haut, `inscription.js` pose la classe `leger` sur la racine
    (voir `suivreLeFormat`). Tout le mode allégé tient dans ce bloc, sans toucher au markup du
    desktop : quelques classes repères seulement (`zone-scene`, `panneau`, `panneau-contenu`,
    `etape-ecran`, `ligne-mobile-pays`, `titre-accueil`, `titre-arrivee`).

    **Ce bloc doit rester le dernier du fichier, et hors de toute couche** : c'est ce qui lui
    permet de l'emporter sur les classes Tailwind (rangées dans `@layer utilities`) et, à
    spécificité égale, sur les règles de la scène écrites plus haut.

    La mise en page :
    - la racine n'est plus fixe : **c'est la page qui défile**, le seul défilement qui se
      comporte à coup sûr quand le clavier d'un téléphone s'ouvre ;
    - le ciel reste fixe derrière, avec son crépuscule et sa nuit ;
    - la boutique devient un bandeau en haut, réduite par `--k` sur l'ancre de la scène ;
    - le panneau devient une feuille qui monte sur le bandeau, coins arrondis en haut ;
    - les étapes ne sont plus superposées en absolu mais posées dans le flux. Le fondu
      d'Alpine est donc neutralisé (sinon l'ancienne et la nouvelle étape s'empileraient le
      temps de la transition) et remplacé par une courte apparition en CSS.
*/
.inscription-racine.leger{position:relative;inset:auto;min-height:100vh;min-height:100svh;overflow:visible;overflow-x:clip}
.leger .zone-scene{position:relative;inset:auto;height:clamp(210px,36svh,330px)}
.leger .sky,.leger .voile-caisse{position:fixed}
.leger .scrimT{display:none}
.leger .cam{clip-path:inset(0);perspective-origin:50% 58%}
.leger .anchor{left:50%;top:58%;transform:scale(var(--k,.45))}
.leger .panneau{position:relative;inset:auto;width:auto;margin-top:-28px;border-radius:28px 28px 0 0;
    min-height:calc(100vh - clamp(210px,36svh,330px) + 28px);min-height:calc(100svh - clamp(210px,36svh,330px) + 28px)}
.leger .panneau-contenu{height:auto;max-width:560px;margin:0 auto;padding:22px 22px calc(32px + env(safe-area-inset-bottom))}
.leger .etape-ecran{position:static;inset:auto;margin-top:22px;transition:none !important;animation:apparitionLegere .45s cubic-bezier(.2,.8,.2,1) both}
@keyframes apparitionLegere{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.leger .grille-familles{overflow:visible;flex-shrink:0}
.leger .carte-caisse{flex-shrink:0}
.leger .miniature-caisse{height:118px;flex-shrink:0}
.leger .ligne-mobile-pays{grid-template-columns:minmax(0,1fr)}
.leger .titre-accueil{font-size:36px}
.leger .titre-arrivee{font-size:34px}
@media (prefers-reduced-motion:reduce){.leger .etape-ecran{animation:none}}
