/* Site Commerce · css/fx-store.css : Lot 1 · Signature.
   ──────────────────────────────────────────────────────────────────────────
   Le store rayé de la boutique (fx/store.js) : l'effet signature de la
   coquille. Une toile rayée terre cuite et crème qui descend sur la scène
   pendant qu'une vitrine charge, un volant festonné, un coffre, une enseigne
   suspendue qui porte le nom du modèle, une ligne de progression sur la
   tranche du volant. Le même dessin que le logo Site Commerce.

   Tout est dessiné en CSS : rayures en dégradé répété, festons en dégradés
   radiaux (un demi-disque par rayure, de la couleur de sa rayure), ombres en
   dégradés. Aucune image binaire, aucun masque.

   Deux dessins identiques, au pixel :
   - le PREMIER RENDU, avant tout script de module : le fond de `.stage`
     porte le store baissé (`html.cv-js` est posé par le noyau, synchrone,
     dans le <head>), pour qu'aucun écran crème n'apparaisse avant que
     store.js ne construise le vrai store. Ce fond vit SOUS les cadres : si
     store.js manque, la première vitrine le recouvre d'elle-même ;
   - le store construit par store.js (`.cv-store`), qui le remplace dès qu'il
     existe (`html.cv-store-pret`).
   Les deux lisent les mêmes mesures (`--cv-store-*`) : les rayures, les
   festons et le volant tombent au même endroit, la relève ne se voit pas.

   Moins de mouvement (l'appareil, sauf « Animations : toujours », ou le
   réglage « Réduites ») : jamais de store, ni au premier rendu ni ensuite.
   Le noyau retourne les @media (prefers-reduced-motion) de cette feuille
   quand le visiteur a choisi « Toujours » ; le `:not([data-mouvement=…])`
   couvre le premier rendu, avant ce retournement. */

/* ── 1 · Les mesures ────────────────────────────────────────────────────── */
:root{
  --cv-store-l:28px;                 /* une rayure */
  --cv-store-r:14px;                 /* un feston : un demi-disque large d'une rayure */
  --cv-store-ourlet:8px;             /* l'ourlet du volant, au-dessus des festons */
  --cv-store-v:calc(var(--cv-store-ourlet) + var(--cv-store-r));
  --cv-store-dx:24px;                /* la toile déborde de la scène : l'inclinaison ne découvre jamais un bord */
  --cv-store-coffre:10px;
  --cv-store-s:0px;                  /* le bas de la scène couvert par le chrome (le dock, au téléphone) */
  /* Un store est un objet : il ne change pas la nuit. Le coffre et les fils
     sont d'encre dans les deux thèmes ; les rayures, assourdies en sombre,
     viennent des jetons --cv-store-a / --cv-store-b de la coquille. */
  --cv-store-ink:#16130f;
  --cv-store-fil:rgba(22,19,15,.62);
  --cv-store-ombre:rgba(0,0,0,.2);
  --cv-store-plus-sombre:rgba(0,0,0,.09);
  --cv-store-piste:rgba(22,19,15,.26);
  /* La lumière sur la toile : un store est penché vers la rue, le jour
     tombe sur son haut (sous l'ombre du coffre) et quitte son bas. */
  --cv-store-lumiere:linear-gradient(180deg,rgba(0,0,0,0) 0,rgba(255,255,255,.08) 16%,rgba(255,255,255,0) 44%,rgba(0,0,0,.035) 78%,rgba(0,0,0,.09) 100%);
  /* Les trois points du coffre : le store du logo est posé sous une barre de
     fenêtre de navigateur. */
  --cv-store-point:rgba(243,230,210,.55);
  --cv-store-points:
    radial-gradient(circle at 14px 50%,var(--cv-store-point) 1.7px,rgba(0,0,0,0) 2.3px),
    radial-gradient(circle at 24px 50%,var(--cv-store-point) 1.7px,rgba(0,0,0,0) 2.3px),
    radial-gradient(circle at 34px 50%,var(--cv-store-point) 1.7px,rgba(0,0,0,0) 2.3px);
}
@media (min-width:901px){
  :root{--cv-store-l:40px;--cv-store-r:20px}
}
/* Au téléphone, le dock flotte sur le bas de la scène : le store s'arrête
   au-dessus de lui (même hauteur que le canal insets de chooser.js : le
   dock, sa marge de 10 px, 8 px d'air), le sol occupe la zone du dock. */
@media (max-width:900px),(max-height:520px){
  :root{--cv-store-s:calc(var(--cv-dock-h, 56px) + 18px + env(safe-area-inset-bottom))}
}

/* ── 2 · Le premier rendu : le store baissé, peint dans le fond de la scène ──
   Le fond est SOUS les cadres : le premier cadre est invisible tant qu'il ne
   porte pas de chemin (`.frame:not([data-path])`), donc c'est ce dessin qui
   se voit au premier rendu ; une vitrine révélée le recouvre toujours. */
html.cv-js:not(.cv-store-pret):not([data-mouvement="reduit"]) .stage{
  background:
    /* le coffre, ses trois points, son filet de lumière, l'ombre qu'il jette sur la toile */
    var(--cv-store-points) 0 0 / 100% var(--cv-store-coffre) no-repeat,
    linear-gradient(rgba(255,255,255,.09),rgba(255,255,255,.09)) 0 calc(var(--cv-store-coffre) - 1px) / 100% 1px no-repeat,
    linear-gradient(var(--cv-store-ink),var(--cv-store-ink)) 0 0 / 100% var(--cv-store-coffre) no-repeat,
    linear-gradient(var(--cv-store-ombre),rgba(0,0,0,0)) 0 0 / 100% calc(var(--cv-store-coffre) + 36px) no-repeat,
    /* la piste de la progression, sur la tranche du volant */
    linear-gradient(var(--cv-store-piste),var(--cv-store-piste)) 0 calc(100% - var(--cv-store-s) - var(--cv-store-v) + 3px) / 100% 3px no-repeat,
    /* l'ourlet du volant */
    linear-gradient(var(--cv-store-plus-sombre),var(--cv-store-plus-sombre)) 0 calc(100% - var(--cv-store-s) - var(--cv-store-r)) / 100% var(--cv-store-ourlet) no-repeat,
    repeating-linear-gradient(90deg,var(--cv-store-a) 0 var(--cv-store-l),var(--cv-store-b) var(--cv-store-l) calc(var(--cv-store-l) * 2)) 0 calc(100% - var(--cv-store-s) - var(--cv-store-r)) / 100% var(--cv-store-ourlet) no-repeat,
    /* les festons, un par rayure, et l'ombre qu'ils portent */
    radial-gradient(circle at 50% 0,var(--cv-store-plus-sombre) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) 0 calc(100% - var(--cv-store-s)) / var(--cv-store-l) var(--cv-store-r) repeat-x,
    radial-gradient(circle at calc(var(--cv-store-l) / 2) 0,var(--cv-store-a) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) 0 calc(100% - var(--cv-store-s)) / calc(var(--cv-store-l) * 2) var(--cv-store-r) repeat-x,
    radial-gradient(circle at calc(var(--cv-store-l) * 1.5) 0,var(--cv-store-b) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) 0 calc(100% - var(--cv-store-s)) / calc(var(--cv-store-l) * 2) var(--cv-store-r) repeat-x,
    radial-gradient(circle at 50% 2px,rgba(0,0,0,.2) calc(var(--cv-store-r) - 1.5px),rgba(0,0,0,0) calc(var(--cv-store-r) + 3.5px)) 0 calc(100% - var(--cv-store-s) + 6px) / var(--cv-store-l) calc(var(--cv-store-r) + 6px) repeat-x,
    /* la toile : sa lumière, ses plis, puis ses rayures */
    var(--cv-store-lumiere) 0 0 / 100% calc(100% - var(--cv-store-s) - var(--cv-store-v)) no-repeat,
    repeating-linear-gradient(90deg,rgba(0,0,0,.07) 0,rgba(0,0,0,0) 5px,rgba(255,255,255,.05) calc(var(--cv-store-l) / 2),rgba(0,0,0,0) calc(var(--cv-store-l) - 5px),rgba(0,0,0,.07) var(--cv-store-l)) 0 0 / 100% calc(100% - var(--cv-store-s) - var(--cv-store-v)) no-repeat,
    repeating-linear-gradient(90deg,var(--cv-store-a) 0 var(--cv-store-l),var(--cv-store-b) var(--cv-store-l) calc(var(--cv-store-l) * 2)) 0 0 / 100% calc(100% - var(--cv-store-s) - var(--cv-store-v)) no-repeat,
    /* le sol, sous les festons et sous le dock */
    var(--cv-scene);
}

/* ── 3 · Le store construit par store.js ────────────────────────────────── */
.cv-store{position:absolute;inset:0;z-index:5;overflow:hidden;pointer-events:none;visibility:hidden;contain:strict}
.cv-store.is-actif{visibility:visible}

/* Le sol : la scène, sous les festons et sous le dock, quand le store est
   fermé. Il ne bouge pas avec la toile (c'est le trottoir, pas le store). */
.cv-store-sol{position:absolute;left:0;right:0;bottom:0;height:calc(var(--cv-store-s) + var(--cv-store-r));
  background:var(--cv-scene);opacity:0;transition:opacity var(--cv-dur-court, 160ms) var(--cv-ease-standard, ease)}
.cv-store.is-ferme .cv-store-sol{opacity:1}

/* Le rideau : la partie qui descend et remonte. Remonté, il est caché au-dessus
   de la scène (12 px de plus : l'ombre des festons). */
.cv-store-rideau{position:absolute;top:0;left:calc(var(--cv-store-dx) * -1);right:calc(var(--cv-store-dx) * -1);
  height:calc(100% - var(--cv-store-s));transform:translateY(calc(-100% - 12px))}
.cv-store.is-bas .cv-store-rideau{transform:none}
.cv-store.is-actif .cv-store-rideau{will-change:transform}

/* Le drap (toile et volant) s'incline dans le sens du geste pendant la
   descente : le pivot est en haut, écrit ici (jamais dans les images clés). */
.cv-store-drap{position:absolute;inset:0;transform-origin:50% 0}
.cv-store-toile{position:absolute;left:0;right:0;top:0;bottom:var(--cv-store-v);
  background:
    linear-gradient(var(--cv-store-ombre),rgba(0,0,0,0)) 0 0 / 100% calc(var(--cv-store-coffre) + 36px) no-repeat,
    var(--cv-store-lumiere),
    repeating-linear-gradient(90deg,rgba(0,0,0,.07) 0,rgba(0,0,0,0) 5px,rgba(255,255,255,.05) calc(var(--cv-store-l) / 2),rgba(0,0,0,0) calc(var(--cv-store-l) - 5px),rgba(0,0,0,.07) var(--cv-store-l)) var(--cv-store-dx) 0,
    repeating-linear-gradient(90deg,var(--cv-store-a) 0 var(--cv-store-l),var(--cv-store-b) var(--cv-store-l) calc(var(--cv-store-l) * 2)) var(--cv-store-dx) 0}
.cv-store-volant{position:absolute;left:0;right:0;top:calc(100% - var(--cv-store-v));
  height:calc(var(--cv-store-v) + 8px);
  background:
    linear-gradient(var(--cv-store-piste),var(--cv-store-piste)) 0 0 / 100% 3px no-repeat,
    linear-gradient(var(--cv-store-plus-sombre),var(--cv-store-plus-sombre)) 0 0 / 100% var(--cv-store-ourlet) no-repeat,
    repeating-linear-gradient(90deg,var(--cv-store-a) 0 var(--cv-store-l),var(--cv-store-b) var(--cv-store-l) calc(var(--cv-store-l) * 2)) var(--cv-store-dx) 0 / 100% var(--cv-store-ourlet) no-repeat,
    radial-gradient(circle at 50% 0,var(--cv-store-plus-sombre) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) var(--cv-store-dx) var(--cv-store-ourlet) / var(--cv-store-l) var(--cv-store-r) repeat-x,
    radial-gradient(circle at calc(var(--cv-store-l) / 2) 0,var(--cv-store-a) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) var(--cv-store-dx) var(--cv-store-ourlet) / calc(var(--cv-store-l) * 2) var(--cv-store-r) repeat-x,
    radial-gradient(circle at calc(var(--cv-store-l) * 1.5) 0,var(--cv-store-b) calc(var(--cv-store-r) - .6px),rgba(0,0,0,0) var(--cv-store-r)) var(--cv-store-dx) var(--cv-store-ourlet) / calc(var(--cv-store-l) * 2) var(--cv-store-r) repeat-x,
    radial-gradient(circle at 50% 2px,rgba(0,0,0,.2) calc(var(--cv-store-r) - 1.5px),rgba(0,0,0,0) calc(var(--cv-store-r) + 3.5px)) var(--cv-store-dx) var(--cv-store-ourlet) / var(--cv-store-l) calc(var(--cv-store-r) + 6px) repeat-x}

/* La progression : sur la tranche du volant, de la largeur de la scène.
   Estimée, plafonnée à 90 % tant que la vitrine n'a rien dit, puis pleine.
   Le pivot à gauche est écrit ici ; seul `transform` est animé. */
.cv-store-progres{position:absolute;top:0;left:var(--cv-store-dx);right:var(--cv-store-dx);height:3px;
  background:var(--cv-accent);transform-origin:0 50%;transform:scaleX(0)}
.cv-store.is-charge .cv-store-progres{transform:scaleX(.9)}
.cv-store.is-pret .cv-store-progres{transform:scaleX(1)}

/* Le coffre : la boîte d'où la toile se déroule. Il ne descend qu'avec le store. */
.cv-store-coffre{position:absolute;top:0;left:0;right:0;height:var(--cv-store-coffre);border-radius:0 0 5px 5px;
  background:var(--cv-store-points),var(--cv-store-ink);box-shadow:inset 0 -1px rgba(255,255,255,.09);transform:translateY(-100%)}
.cv-store.is-bas .cv-store-coffre{transform:none}

/* ── 4 · L'enseigne ─────────────────────────────────────────────────────── */
/* Le pendule : une boîte posée dans le rideau (il descend avec lui), qui ne
   bouge pas elle-même ; l'enseigne y pivote autour du haut de ses fils. */
.cv-store-pendule{position:absolute;top:0;left:var(--cv-store-dx);right:var(--cv-store-dx);
  height:calc(41% + 32px);min-height:118px;display:flex;justify-content:center}
.cv-store-enseigne{position:relative;display:flex;flex-direction:column;align-items:stretch;height:100%;
  width:clamp(228px, 62%, 300px);transform-origin:50% 0}
.cv-store-fils{position:relative;flex:1 1 auto;min-height:0}
.cv-store-fil{position:absolute;top:0;bottom:-3px;width:1px;background:var(--cv-store-fil)}
.cv-store-fil:first-child{left:20%}
.cv-store-fil:last-child{right:20%}
/* les œillets où les fils prennent la plaque */
.cv-store-fil::after{content:"";position:absolute;bottom:0;left:-2.5px;width:4px;height:4px;border-radius:50%;
  border:1px solid var(--cv-store-fil);background:var(--cv-card)}

/* Une plaque émaillée : un second filet, en retrait de 4 px, la distingue
   d'une carte d'interface. */
.cv-store-plaque{position:relative;flex:none;padding:14px 22px 13px;border:1px solid var(--cv-line);
  border-radius:10px;background:var(--cv-card);color:var(--cv-fg);
  box-shadow:inset 0 0 0 3px var(--cv-card),inset 0 0 0 4px var(--cv-line-strong, rgba(0,0,0,.16)),var(--cv-shadow);
  text-align:center;backface-visibility:hidden}
.cv-store-txt{display:block}
.cv-store-nom,.cv-store-style{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cv-store-nom{font:600 17px/1.2 var(--cv-disp);letter-spacing:-.012em}
.cv-store-style{margin-top:3px;font:500 13px/1.25 var(--cv-body);color:var(--cv-muted)}
/* L'ancien nom qui sort pendant que le nouveau entre : un fantôme posé
   exactement sur le texte, retiré dès sa sortie jouée. */
.cv-store-txt--fantome{position:absolute;left:22px;right:22px;top:14px;pointer-events:none}

/* Sur grand écran, la scène fait 600 px de haut : la plaque grandit un peu. */
@media (min-width:901px) and (min-height:521px){
  .cv-store-enseigne{width:clamp(264px, 30%, 340px)}
  .cv-store-plaque{padding:16px 26px 15px}
  .cv-store-txt--fantome{left:26px;right:26px;top:16px}
  .cv-store-nom{font-size:19px}
  .cv-store-style{font-size:14px}
}

/* L'échec : la plaque dit que ça tarde et offre de réessayer. */
.cv-store-echec{display:flex;flex-direction:column;align-items:center;gap:4px}
.cv-store-echec-txt{margin:0;font:600 15px/1.3 var(--cv-disp);letter-spacing:-.01em}
.cv-store-echec-modele{margin:0;font:500 12.5px/1.3 var(--cv-body);color:var(--cv-muted);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cv-store-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:44px;margin-top:8px;
  padding:0 18px;border:0;border-radius:var(--cv-r-btn, 12px);background:var(--cv-cta);color:var(--cv-on-cta);
  font:600 14px/1 var(--cv-body);cursor:pointer;pointer-events:auto;
  transition:background-color var(--cv-dur-court, 160ms) var(--cv-ease-standard, ease)}
.cv-store-btn svg{width:16px;height:16px;flex:none}
.cv-store-btn:hover{background:var(--cv-accent);color:var(--cv-on-accent)}
.cv-store-btn:focus-visible{outline:2px solid var(--cv-accent);outline-offset:2px}
.cv-store-btn[disabled],.cv-store-btn[aria-disabled="true"]{opacity:.6;cursor:progress}

/* Mouvement réduit, et le chargement échoue : pas de store, la plaque seule,
   posée sur la vitrine, sans fils. */
.cv-store.is-seul .cv-store-rideau{transform:none}
.cv-store.is-seul .cv-store-drap,
.cv-store.is-seul .cv-store-fils,
.cv-store.is-seul .cv-store-coffre,
.cv-store.is-seul .cv-store-sol{display:none}
/* Seule, la plaque se pose au milieu de la scène (au-dessus du dock), pas
   sur l'en-tête de la vitrine. */
.cv-store.is-seul .cv-store-pendule{height:100%;align-items:center}
.cv-store.is-seul .cv-store-enseigne{height:auto}

/* ── 5 · Le dock de l'arrivée ──────────────────────────────────────────────
   À la toute première image, le dock attend en bas, hors de l'écran : il
   monte avec le store (fx/store.js le relâche en ressort). Une animation de
   garde, sans remplissage tenu : si store.js ne vient pas, le dock reparaît
   seul au bout de 2,4 s. */
@keyframes cv-store-dock-attente{
  from,to{transform:translateY(calc(100% + 26px + env(safe-area-inset-bottom)))}
}
@media (max-width:900px),(max-height:520px){
  html.cv-js:not(.cv-store-dock-libre):not([data-mouvement="reduit"]) .cv-dock{animation:cv-store-dock-attente 2.4s linear}
}

/* ── 6 · Moins de mouvement : ni store, ni dock retenu ──────────────────── */
@media (prefers-reduced-motion:reduce){
  html.cv-js:not(.cv-store-pret):not([data-mouvement="toujours"]) .stage{background:var(--cv-scene)}
  html.cv-js:not(.cv-store-dock-libre):not([data-mouvement="toujours"]) .cv-dock{animation:none}
}

/* `:hover` colle après un tap : neutralisé sans souris, en fin de feuille
   (une media query n'ajoute aucune priorité, seul l'ordre tranche). */
@media (hover:none){
  .cv-store-btn:hover{background:var(--cv-cta);color:var(--cv-on-cta)}
}
