/* ============================================================
   Page Design System : composants propres à cette page.
   Tout le reste (hero, sections, behind, subnav, reveal .rv)
   vient de base.css et projet.css. Accent : --pc = --c-ds.
   ============================================================ */

/* ---- Hero : sous-titre et ligne d'attribution ---- */
.ds-sub{font-family:var(--title-font),serif;font-style:italic;font-size:clamp(19px,2.2vw,26px);color:var(--on-night-soft);margin-top:14px}
.ds-attrib{margin-top:26px;font-size:13.5px;letter-spacing:.04em;color:var(--on-night-soft)}

/* ============================================================
   L'ouverture : la planche de composants
   La composition de Marie-Liesse : la planche quadrillée au centre,
   et autour, ce qui vole : les mots du système, les icônes 3D, la
   carte squelette et un champ échappés. En mobile, seule la planche
   reste, coiffée du mot Composants. Tout s'assemble à l'apparition
   puis se tait.
   ============================================================ */
.pj-section:has(.ds-open){padding-top:clamp(18px,3vh,44px)}
/* .full:has(img) impose un padding : on le neutralise à spécificité égale */
.pj-figure.full:has(.ds-open){background:none;border:0;box-shadow:none;padding:0;margin-top:0;
  width:100vw;margin-left:calc(50% - 50vw)}
.ds-open{position:relative;max-width:1400px;margin-inline:auto;
  padding:clamp(8px,1.4vw,18px) clamp(20px,4vw,54px) clamp(24px,3.5vw,44px)}
/* le décalage haut est porté par la scène : un margin sur la planche
   s'effondrerait avec son parent et la colle en haut */
.ds-open-stage{position:relative;padding-top:6%;padding-bottom:3%}
.ds-open .sheet{position:relative;z-index:2;width:70%;margin:0 0 0 15%;padding:1.6% 2%;
  border-radius:clamp(20px,2.6vw,36px);
  background:
    repeating-linear-gradient(0deg,rgba(28,28,38,.05) 0 1px,transparent 1px 32px),
    repeating-linear-gradient(90deg,rgba(28,28,38,.05) 0 1px,transparent 1px 32px),
    #fff;
  border:1px solid rgba(28,28,38,.09);
  box-shadow:0 60px 110px -44px rgba(18,26,32,.42), 0 3px 12px rgba(18,26,32,.06);
  opacity:0;transform:translateY(24px)}
.rv.in .ds-open .sheet{opacity:1;transform:none;transition:opacity .9s ease,transform 1.05s cubic-bezier(.16,.9,.3,1)}
.ds-open .sheet img{display:block;width:100%;height:auto}
.ds-open .sheet .ds-open-mob{display:none}
/* les mots du système */
.ds-kw{position:absolute;z-index:4;font-size:clamp(12px,1.05vw,14px);letter-spacing:.12em;
  text-transform:uppercase;font-weight:700;
  color:color-mix(in srgb,var(--pc) 30%,var(--on-night-soft));white-space:nowrap;
  padding:10px 18px;border-radius:999px;background:#fff;
  box-shadow:0 18px 38px -12px rgba(18,26,32,.28), 0 2px 6px rgba(18,26,32,.06);
  opacity:0;transform:translateY(16px)}
.ds-kw.big{font-size:clamp(14px,1.5vw,20px);padding:12px 24px;letter-spacing:.14em}
.rv.in .ds-open .ds-kw{opacity:1;transform:var(--tf,none);
  transition:opacity .7s ease,transform .9s cubic-bezier(.16,.9,.3,1)}
/* les pièces et la 3D qui volent */
.ds-fly{position:absolute;z-index:4;filter:drop-shadow(0 18px 26px rgba(18,26,32,.20));
  opacity:0;transform:translateY(18px)}
.ds-3d{position:absolute;z-index:5;filter:drop-shadow(0 22px 30px rgba(18,26,32,.28));
  pointer-events:none;opacity:0;transform:translateY(18px)}
.rv.in .ds-open .ds-fly,.rv.in .ds-open .ds-3d{opacity:1;transform:var(--tf,none);
  transition:opacity .8s ease,transform 1s cubic-bezier(.16,.9,.3,1)}
.rv.in .ds-open .o1{transition-delay:.12s}.rv.in .ds-open .o2{transition-delay:.24s}
.rv.in .ds-open .o3{transition-delay:.36s}.rv.in .ds-open .o4{transition-delay:.48s}
.rv.in .ds-open .o5{transition-delay:.6s}
/* les positions, calées sur la composition d'origine */
.ds-open .w-composants{left:17%;top:7.5%;--tf:none}
.ds-open .w-variants{right:1.5%;top:42%;--tf:rotate(3deg)}
.ds-open .w-doc{left:0;top:68%;--tf:rotate(-1.5deg)}
.ds-open .w-resp{right:5%;top:64%;--tf:rotate(-3deg)}
.ds-open .p-tile{left:60%;top:3%;width:19.5%;height:auto;--tf:rotate(7deg)}
.ds-open .p-input{left:9.5%;top:44%;width:11%;height:auto;--tf:none}
.ds-open .i-food{left:5.5%;top:-2%;width:5%;height:auto;--tf:rotate(-4deg)}
.ds-open .i-heart{left:1.5%;top:8%;width:4.4%;height:auto;--tf:rotate(-8deg)}
.ds-open .i-gift{left:8.5%;top:11%;width:3.8%;height:auto;--tf:rotate(6deg)}
.ds-open .i-rocket{right:3%;bottom:-2%;width:8.5%;height:auto;--tf:rotate(6deg)}
@media (max-width:820px){
  /* seule la planche reste, coiffée du mot Composants */
  /* la planche seule, à 20 px des bords de l'écran */
  .ds-open{padding:0 20px}
  .ds-open-stage{padding-top:0;padding-bottom:0}
  .ds-open .sheet{width:100%;margin:0;padding:0;border-radius:16px;overflow:hidden}
  .ds-open .sheet .ds-open-desk{display:none}
  .ds-open .sheet .ds-open-mob{display:block}
  .ds-kw,.ds-fly,.ds-3d,.ds-open .w-composants{display:none}
}
@media (prefers-reduced-motion:reduce){
  .ds-open .sheet,.ds-kw,.ds-fly,.ds-3d{opacity:1 !important;transform:var(--tf,none) !important;transition:none !important}
  .ds-open .sheet{transform:none !important}
}

/* ---- Le produit : encart léger, sur la colonne de lecture ---- */
.ds-prod{max-width:var(--measure);margin-inline:auto;border:1px solid rgba(28,28,38,.06);border-left:4px solid var(--pc);border-radius:14px;background:#FFFFFF;box-shadow:var(--pj-card);padding:clamp(22px,3vw,32px) clamp(22px,3.5vw,38px)}
.ds-prod .lbl{font-size:13px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:var(--pc-ink);margin-bottom:12px}
.ds-prod p{font-size:clamp(15px,1.3vw,17px);line-height:1.65;color:var(--on-night-soft);max-width:70ch}
.ds-prod a{display:inline-block;margin-top:14px;font-size:14.5px;color:var(--on-night);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--pc) 60%,transparent);padding-bottom:2px;transition:color .2s,border-color .2s}
.ds-prod a:hover{color:var(--pc-ink);border-color:var(--pc)}

/* ---- Les composants : deux familles, chacune avec ses blocs ---- */
/* Tout le texte de la page se ferre sur le même bord gauche : celui de la
   colonne de lecture. Les blocs plus larges que la colonne (familles,
   duos) partent de ce bord et s'étendent vers la droite. Seuls les
   visuels ont le droit de déborder des deux côtés. */
.ds-wide{margin-left:calc((100% - min(100%,760px))/2)}
/* l'en-tête de famille : un titre serif et un filet qui court */
.ds-fam{display:flex;align-items:baseline;gap:20px;margin-top:clamp(44px,6.5vw,84px)}
.ds-fam h3{font-family:var(--title-font),serif;font-weight:400;font-size:clamp(24px,2.9vw,38px);color:var(--on-night);white-space:nowrap}
.ds-fam h3 em{font-style:italic}
.ds-fam::after{content:"";flex:1;height:1px;background:var(--night-line);transform:translateY(-6px)}
.ds-fam-p{max-width:var(--measure);margin:14px auto 0;font-size:clamp(15px,1.35vw,17.5px);line-height:1.7;color:var(--on-night-soft)}

.ds-comp{margin-top:clamp(34px,4.5vw,58px)}
.ds-comp-head{max-width:var(--measure);margin-inline:auto}
.ds-comp-head h3,.ds-comp-head h4{font-family:var(--title-font),serif;font-weight:400;font-size:clamp(21px,2.3vw,28px);color:var(--on-night);margin-bottom:10px}
.ds-comp-head p{font-size:clamp(14.5px,1.25vw,16.5px);line-height:1.65;color:var(--on-night-soft)}
.ds-comp-head a{color:var(--on-night);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--pc) 60%,transparent);transition:color .2s}
.ds-comp-head a:hover{color:var(--pc-ink)}
/* les facettes documentées, en pastilles */
.ds-comp-doc{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.ds-comp-doc span{font-size:12px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;color:var(--on-night-faint);border:1px solid var(--night-line);border-radius:999px;padding:5px 12px}
/* galerie */
.ds-comp-gal{margin-top:clamp(22px,3vw,34px)}
.ds-comp-gal figure{margin:0}
.ds-comp-gal img{display:block;width:100%;height:auto;border-radius:10px;border:1px solid rgba(28,28,38,.10);box-shadow:0 16px 40px color-mix(in srgb,var(--pc) 18%,rgba(28,28,38,.10));background:#fff}
.ds-comp-gal figcaption{margin-top:12px;font-size:13.5px;line-height:1.5;color:var(--on-night-soft)}
.ds-comp-gal figcaption b{color:var(--on-night);font-weight:600}
.ds-comp-gal.one{max-width:340px}
.ds-comp-gal.two{display:grid;grid-template-columns:1fr 1fr;gap:clamp(16px,2.6vw,30px);align-items:start}
.ds-comp-gal.stack{display:grid;gap:clamp(18px,2.6vw,28px)}
/* La rangée bannière : la matrice à gauche, les deux exemples à droite.
   Les trois visuels n'ont pas la même hauteur. On leur donne une rangée
   commune pour les images et une autre pour les légendes : les images se
   ferrent par le bas, et les trois légendes partent de la même ligne, au
   lieu que celle de la matrice remonte toute seule. */
.ds-comp-gal.banner-row{display:grid;grid-template-columns:1.16fr .47fr .47fr;
  grid-template-rows:auto auto;column-gap:clamp(14px,2.2vw,26px);row-gap:12px}
/* la figure épouse les deux rangées de la grille : c'est la seule façon
   d'avoir la même ligne de légende pour les trois. L'écart entre l'image
   et sa légende devient celui de la grille, sinon les rangées de la
   figure se décalent de celles de la rangée. */
.ds-comp-gal.banner-row > figure{display:grid;grid-row:span 2;grid-template-rows:subgrid}
/* premier enfant, et non l'image : le zoom glisse un bloc autour d'elle
   quand la figure porte aussi une légende. */
.ds-comp-gal.banner-row > figure > :first-child{align-self:end}
.ds-comp-gal.banner-row > figure figcaption{margin-top:0}
/* le menu et sa règle, côte à côte */
.ds-split{display:grid;grid-template-columns:.92fr 1.08fr;gap:clamp(20px,3vw,40px);align-items:start;margin-top:clamp(18px,2.5vw,28px)}
/* les trois petits titres, chacun au-dessus de sa maquette */
.ds-menu-titles{position:relative;height:20px;margin-bottom:10px}
.ds-menu-titles span{position:absolute;transform:translateX(-50%);font-size:14.5px;font-weight:600;color:var(--on-night);white-space:nowrap}
.ds-split > figure{margin:0}
.ds-split img{display:block;width:100%;height:auto;border-radius:10px;border:1px solid rgba(28,28,38,.10);box-shadow:0 16px 40px color-mix(in srgb,var(--pc) 14%,rgba(28,28,38,.10));background:#fff}
.ds-split figcaption{margin-top:12px;font-size:13.5px;line-height:1.5;color:var(--on-night-soft)}
.ds-split figcaption b{color:var(--on-night);font-weight:600}
/* la règle du sélecteur : un encart, pas une section */
.ds-rule{border:1px solid rgba(28,28,38,.06);border-left:4px solid var(--pc);border-radius:14px;background:#FFFFFF;box-shadow:var(--pj-card);padding:clamp(20px,2.8vw,30px) clamp(20px,3vw,34px)}
.ds-rule .lbl{font-size:13px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:var(--pc-ink);margin-bottom:10px}
.ds-rule h5{font-family:var(--title-font),serif;font-weight:400;font-size:clamp(18px,1.8vw,23px);color:var(--on-night);margin-bottom:10px}
.ds-rule p{font-size:clamp(14px,1.2vw,15.5px);line-height:1.65;color:var(--on-night-soft);margin-bottom:.8em}
.ds-rule p:last-of-type{margin-bottom:0}
/* les deux écrans du sélecteur, côte à côte : les exports portent déjà
   leur panneau blanc et leur ombre, pas de cadre en plus */
.ds-rule .duo{display:grid;grid-template-columns:1fr 1fr;gap:12px;max-width:420px;margin:16px auto 0}
.ds-rule img{display:block;width:100%;height:auto;
  background:none;border:0;box-shadow:none;border-radius:0}
.ds-rule .caps{display:flex;gap:12px;max-width:420px;margin:8px auto 0}
.ds-rule .caps span{flex:1;text-align:center;font-size:12.5px;color:var(--on-night-faint)}
/* header et footer en parallèle */
.ds-duo{display:grid;grid-template-columns:1fr 1fr;gap:clamp(22px,3.4vw,44px);align-items:start}
.ds-duo .ds-comp{margin-top:clamp(34px,4.5vw,58px)}
.ds-duo .ds-comp-head{max-width:none;margin-inline:0}
/* la table assemblée : le desktop et le mobile à la même hauteur */
.ds-comp-gal.table-duo{display:grid;grid-template-columns:2.16fr .65fr;gap:clamp(16px,2.6vw,30px);align-items:start}
/* les briques détachées : chaque pièce à sa proportion réelle */
.ds-pieces{display:flex;flex-wrap:wrap;gap:clamp(10px,1.6vw,18px);margin-top:clamp(22px,3vw,34px);align-items:flex-end}
.ds-pieces figure{margin:0;min-width:110px}
.ds-pieces img{display:block;width:100%;height:auto;border-radius:8px;border:1px solid rgba(28,28,38,.10);box-shadow:0 10px 26px color-mix(in srgb,var(--pc) 14%,rgba(28,28,38,.08));background:#fff}
.ds-pieces figcaption{margin-top:6px;font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;color:var(--on-night-faint);text-align:center}
@media (max-width:820px){
  .ds-comp-gal.two{grid-template-columns:1fr;gap:22px}
  .ds-comp-gal.one{max-width:none}
  .ds-comp-gal.banner-row{grid-template-columns:1fr 1fr}
  .ds-comp-gal.banner-row figure:first-child{grid-column:1/-1}
  .ds-comp-gal.table-duo{grid-template-columns:1fr}
  .ds-comp-gal.table-duo figure:last-child{max-width:60%;margin-inline:auto}
  .ds-split{grid-template-columns:1fr}
  .ds-duo{grid-template-columns:1fr}
  .ds-wide{margin-left:0}
  .ds-fam::after{transform:translateY(-4px)}
}

/* ---- Transitions : une ligne qui respire ---- */
/* ---- Les états : le défilé traverse l'écran, ferré sur la colonne
   de texte comme les autres bandes du site ---- */
.ds-note{font-size:13px;color:var(--on-night-soft);margin:26px auto 14px;max-width:var(--measure)}
.ds-states{position:relative;width:100vw;margin-left:calc(50% - 50vw)}
.ds-rail{overscroll-behavior-x:contain;display:flex;gap:clamp(28px,3.6vw,56px);overflow-x:auto;scroll-snap-type:x mandatory;padding:18px var(--band-pad) 40px;scroll-padding-inline:var(--band-pad);-webkit-overflow-scrolling:touch;scrollbar-width:thin}
/* La carte a été élargie de 440 à 720 px. À 440, la capture desktop était
   posée à un tiers de sa taille réelle et on n'y lisait plus ni les champs
   ni les messages d'erreur, c'est-à-dire précisément ce que cette section
   raconte. Le rembourrage droit et bas n'est pas décoratif : c'est la place
   réservée au médaillon mobile, qui est en absolu. Sans lui, le téléphone
   débordait sur la carte suivante. */
.ds-st{flex:0 0 clamp(480px,60vw,780px);scroll-snap-align:start;position:relative;
  display:flex;flex-direction:column;gap:10px;padding-right:18%;padding-bottom:8%}
.ds-st-lbl{font-size:13.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--on-night)}
.ds-st-lbl b{color:var(--pc-ink);font-weight:600;margin-right:6px}
/* la légende vient sous le sous-titre, avec une hauteur réservée : les
   écrans de toutes les colonnes démarrent à la même ligne */
.ds-st-txt{min-height:64px}
/* Le mobile n'est plus empilé sous le desktop, il s'appuie sur son coin.
   Empilé, il prenait plus de hauteur que le desktop lui-même, puisqu'un
   écran de téléphone est deux fois plus haut que large : la carte montait
   à 800 px pour deux images qu'on ne lisait ni l'une ni l'autre. Posé en
   médaillon, le couple se lit d'un seul regard et il ne recouvre que le
   bord droit de la capture, là où il n'y a rien. */
.ds-st-d{position:relative}
.ds-st-m{position:absolute;right:0;bottom:0;width:22%;margin:0}
.ds-st-d img,.ds-st-m img{display:block;width:100%;height:auto;border-radius:8px;border:1px solid rgba(28,28,38,.10);box-shadow:0 12px 30px color-mix(in srgb,var(--pc) 16%,rgba(28,28,38,.08))}
/* l'ombre du médaillon est plus marquée : c'est elle qui le décolle de la
   capture sur laquelle il est posé */
.ds-st-m img{border-radius:12px;box-shadow:0 18px 44px -8px color-mix(in srgb,var(--pc) 26%,rgba(28,28,38,.22))}
.ds-st-txt{font-size:13px;line-height:1.55;color:var(--on-night-soft);margin:0 0 4px}
/* indicateur de scroll : fondu sur le bord droit */
.ds-states::after{content:"";position:absolute;top:0;right:0;bottom:18px;width:64px;background:linear-gradient(90deg,transparent,var(--night));pointer-events:none;opacity:1;transition:opacity .3s}
.ds-states.at-end::after{opacity:0}
.ds-dots{display:none;gap:8px;justify-content:center;margin-top:6px}
.ds-dots button{width:8px;height:8px;border-radius:5px;border:0;padding:0;background:var(--on-night-faint);cursor:pointer;transition:width .25s,background .25s}
.ds-dots button.on{width:22px;background:var(--pc)}
.ds-states:focus-visible,.ds-dots button:focus-visible,.ds-prod a:focus-visible,.ds-comp-head a:focus-visible{outline:2px solid var(--pc);outline-offset:3px;border-radius:4px}
@media (max-width:1023px){.ds-st{flex-basis:calc((100% - clamp(28px,3.6vw,56px))/2)}}
@media (max-width:767px){
  .ds-st{flex-basis:86%}
  .ds-dots{display:flex}
  .ds-states::after{width:36px}
}
@media (prefers-reduced-motion:reduce){
  .ds-rail{scroll-behavior:auto}
}

/* La note de fin d'encart : une fois la règle montrée, elle dit où vivent
   toutes les autres. Elle venait du chapeau de section, où elle annonçait
   des règles qu'on ne voyait nulle part. */
.ds-rule .ds-ou{margin-top:18px;padding-top:14px;font-size:13.5px;
  border-top:1px solid rgba(28,28,38,.08);color:var(--on-night-faint)}
