/* ==========================================================================
   WAKAME - Sushi bar & grill
   Front public, transcription de la maquette Figma « Landing page ».

   La maquette mesure 3365 × 10099 px, soit 2,5× la taille réelle.
   Toutes les valeurs sont donc exprimées via --u (1 px Figma = 0,4 px CSS) :
   calc(64 * var(--u)) = 25,6 px  ⇢ on peut relire la maquette dans le code.

   Le héro est composé au pixel près : sa scène garde le rapport 3365/1731 et
   chaque élément reprend la matrice de transformation du fichier .fig
   (origine en haut à gauche, comme dans Figma).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Jetons

   Ils vivent dans public/style/tokens.css, chargée juste avant cette feuille
   par views/partials/wakame-head.ejs, pour que le back-office parle la même
   langue que la vitrine sans charger les 1 600 lignes qui suivent.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body.wakame {
  margin: 0;
  background: var(--cream);
  color: var(--brown);
  font-family: var(--f-body);
  font-size: var(--fs-40);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img, svg { display: block; }
img { max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--red); color: var(--paper); }

:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; border-radius: 4px; }
.wk-section--dark :focus-visible,
.wk-header :focus-visible { outline-color: var(--cream); }

.wk-skip {
  position: absolute;
  left: 50%; top: 0;
  translate: -50% -120%;
  z-index: 200;
  padding: .6rem 1.2rem;
  border-radius: 0 0 var(--r-btn) var(--r-btn);
  background: var(--paper);
  color: var(--brown);
  font-family: var(--f-round);
  font-weight: 600;            /* « Aller au contenu » garde sa casse */
  transition: translate .25s var(--ease);
}
.wk-skip:focus { translate: -50% 0; }

/* --------------------------------------------------------------------------
   3. Structures communes
   -------------------------------------------------------------------------- */
.wk-shell {
  width: min(100% - var(--gutter) * 2, var(--container));
  margin-inline: auto;
}

.wk-section { position: relative; padding-block: calc(150 * var(--u)); }
.wk-section--dark { background: var(--ink); color: var(--paper); }

/* Titres - Caveat Brush, capitales, comme dans la maquette. C'est le seul
   endroit où la brosse subsiste : dès qu'un titre garde sa casse, il repasse en
   Fredoka semi-bold. */
.wk-title {
  font-family: var(--f-hand);
  font-weight: 400;
  font-size: var(--fs-64);
  line-height: 1.27;
  text-transform: uppercase;
}

/* Variantes typographiques demandées, qui priment sur le fichier Figma.
   .wk-t-caveat garde son nom mais n'habille que des accroches à la casse
   d'origine : Fredoka semi-bold, pas la brosse. */
.wk-t-fredoka { font-family: var(--f-round); font-weight: 400; text-transform: none; }
.wk-t-caveat  { font-family: var(--f-round); font-weight: 600; }
.wk-title .accent { color: var(--red); }

.wk-lead   { font-size: var(--fs-48); line-height: 1.25; }
.wk-eyebrow { font-size: var(--fs-40); color: var(--red); }

/* Numéro de téléphone. Le site en affiche deux, au pied de page et dans le bloc
   contact de l'accueil, au milieu d'adresses et de liens de même corps : le
   semi-bold est là pour qu'on les distingue d'un coup d'œil quand on cherche à
   appeler. Semi-bold (600) et non gras (700) : c'est la graisse d'appui du
   projet (.wk-t-caveat), le 700 est réservé aux titres. */
.wk-tel { font-weight: 600; }

/* Boutons ---------------------------------------------------------------- */
.wk-btn {
  --btn-bg: var(--red);
  --btn-fg: var(--paper);
  --btn-bd: var(--red);
  /* L'épaisseur du contour passe par un jeton : les évidés la redessinent dans
     un ::before (voir plus bas) et doivent en connaître la valeur, que le héro
     redéfinit de son côté en cqw. */
  --bd-w: calc(5 * var(--u));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Écart entre le libellé et son icône (flèche « Continuer », « Retour ») :
     sans lui les deux se touchent, l'icône étant une lettre pour le moteur. */
  gap: calc(20 * var(--u));
  padding: calc(30 * var(--u)) calc(60 * var(--u));
  min-height: calc(105 * var(--u));
  border: var(--bd-w) solid var(--btn-bd);
  border-radius: var(--r-btn);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--f-body);
  font-size: var(--fs-40);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: var(--sh-lg);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), filter .18s var(--ease),
              background-color .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}
/* Bouton plein - décalque de « Bouton full.svg ». Le fichier empile quatre
   calques sur le rectangle, du fond vers la surface :

     1. le rouge plein                                     ⇢ background-color
     2. un dégradé vertical à 10 %, transparent en haut et
        blanc en bas : la face s'éclaircit vers le bas      ⇢ calque « face »
     3. un contour de 5 unités du même rouge                ⇢ la bordure
     4. le même contour sous un dégradé à 30 %, blanc en
        haut, éteint à mi-hauteur, noir 50 % en bas         ⇢ calque « liseré »

   Le relief vient donc du liseré - la lumière prend l'arête du haut, l'ombre
   celle du bas - et non de la face, qui s'éclaircit légèrement vers le bas.
   C'est l'inverse d'un bouton bombé : ne pas « redresser » ces dégradés.

   La bordure est rendue transparente pour que le liseré, qui est un fond,
   puisse s'y peindre (un fond passe sous la bordure, jamais dessus) ; le rouge
   du calque 1 remplit la boîte de bordure et la colore donc aussi. Le calque
   rouge opaque du milieu est ce qui empêche le liseré de traverser la face :
   il est rogné à la boîte de padding, le liseré à la boîte de bordure. Les
   dégradés, eux, sont mesurés sur la boîte de bordure des deux côtés, comme
   les rectangles du fichier qui vont tous de bord à bord.

   Les gris intermédiaires ne sont pas décoratifs : un dégradé SVG interpole en
   alpha non prémultiplié, donc du noir transparent vers le blanc opaque en
   passant par un gris à demi transparent, qui désature le rouge au lieu de
   l'éclaircir. Un dégradé CSS interpole en prémultiplié et sauterait ce gris.
   Ces points d'arrêt rejouent la courbe du fichier ; les retirer éclaircit la
   face et les flancs du liseré d'environ 4 %. */
.wk-btn--fill {
  --btn-bd: transparent;
  background-image:
    linear-gradient(180deg,
        rgb(  0   0   0 / 0),
        rgb(128 128 128 / .05) 50%,
        rgb(255 255 255 / .1)),
    linear-gradient(var(--btn-bg), var(--btn-bg)),
    linear-gradient(180deg,
        rgb(255 255 255 / .3),
        rgb(192 192 192 / .15)  24.76%,
        rgb(128 128 128 / 0)    49.52%,
        rgb( 64  64  64 / .075) 74.76%,
        rgb(  0   0   0 / .15));
  background-origin: border-box;
  background-clip: padding-box, padding-box, border-box;
}

.wk-btn:hover { transform: translateY(-2px); box-shadow: 3px 7px 14px var(--sh-ink); }
.wk-btn:active { transform: translateY(1px); box-shadow: var(--sh-sm); }

/* Bouton éteint : il ne se soulève plus et ne s'enfonce plus non plus, sinon
   il répond au clic qu'il refuse. */
.wk-btn:disabled { opacity: .3; cursor: not-allowed; }
.wk-btn:disabled:hover,
.wk-btn:disabled:active { transform: none; box-shadow: var(--sh-lg); }

/* Boutons évidés : l'ombre doit épouser le contour, pas remplir l'intérieur -
   d'où une ombre portée, qui suit le dessin, et non un box-shadow, qui suit le
   rectangle.

   Mais un filtre s'applique à tout l'élément, lettres comprises : chacune
   traînait sa propre ombre et le texte en ressortait sali. Le contour est donc
   redessiné à l'identique par un ::before, seul porteur du filtre ; l'ombre est
   inchangée, les lettres redeviennent nettes.

   L'évidé sombre ne vit que sur le crème, l'évidé clair que sur le bandeau
   rouge et les sections sombres : leurs ombres ne sont donc pas de la même
   couleur, voir le jeton --sh-ink. */
.wk-btn--ghost,
.wk-btn--ghost-light {
  position: relative;
  border-color: transparent;   /* le contour visible est celui du ::before */
  filter: none;
}
.wk-btn--ghost,
.wk-btn--ghost-light,
.wk-btn--ghost:hover,
.wk-btn--ghost-light:hover { box-shadow: none; }

/* Un enfant absolu se cale sur la boîte de padding : on le ressort de
   l'épaisseur du contour pour qu'il coïncide avec la boîte de bordure, dont il
   reprend aussi le rayon. */
.wk-btn--ghost::before,
.wk-btn--ghost-light::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--bd-w));
  border: var(--bd-w) solid var(--btn-bd);
  border-radius: inherit;
  pointer-events: none;
  transition: border-color .18s var(--ease), filter .18s var(--ease);
}
.wk-btn--ghost::before             { filter: drop-shadow(2px 4px 6px var(--sh-ink)); }
.wk-btn--ghost:hover::before       { filter: drop-shadow(3px 7px 10px var(--sh-ink)); }
.wk-btn--ghost-light::before       { filter: drop-shadow(2px 4px 6px rgb(0 0 0 / .25)); }
.wk-btn--ghost-light:hover::before { filter: drop-shadow(3px 7px 10px rgb(0 0 0 / .3)); }

.wk-btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--red); --btn-bd: var(--red);
  --bd-w: calc(3 * var(--u));
  background-image: none;
}
.wk-btn--ghost:hover { --btn-bg: var(--red); --btn-fg: var(--paper); }

.wk-btn--ghost-light {
  --btn-bg: transparent; --btn-fg: var(--paper); --btn-bd: var(--paper);
  --bd-w: calc(3 * var(--u));
  background-image: none;
}
.wk-btn--ghost-light:hover { --btn-bg: var(--paper); --btn-fg: var(--red); }

/* --------------------------------------------------------------------------
   4. En-tête  (Figma : 3365 × 130, padding 150, logo « Format=Small »)
   -------------------------------------------------------------------------- */
.wk-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  transition: box-shadow .3s var(--ease);
}
.wk-header.is-stuck { box-shadow: 0 6px 24px rgb(0 0 0 / .35); }

.wk-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--header-h);
  padding-block: calc(10 * var(--u));
}

/* À la hauteur commune des boutons (105 unités, 40 de texte + 60 de marge + 10
   de contour, soit 110 rendues), le « Réserver » remplissait le bandeau de bord
   à bord : 130 unités de haut moins ses 20 de marge intérieure, il ne restait
   rien autour. On ne reprend que la marge verticale - la marge latérale, le
   corps et le contour sont ceux de tous les autres boutons. */
.wk-header .wk-btn {
  min-height: calc(82 * var(--u));      /* 32,8 px au lieu de 44 */
  padding-block: calc(16 * var(--u));
}

.wk-brand {
  font-family: var(--f-display);
  font-size: var(--fs-96);
  line-height: 1.15;
  color: var(--paper);
  white-space: nowrap;
  transition: color .2s var(--ease);
}
.wk-brand:hover { color: var(--cream); }
.wk-brand small {
  display: block;
  margin-top: calc(-10 * var(--u));
  font-family: var(--f-body);
  font-size: var(--fs-40);
  line-height: 1.5;
}

.wk-nav ul { display: flex; align-items: center; gap: calc(100 * var(--u)); }
.wk-nav a {
  position: relative;
  display: inline-block;
  padding: calc(6 * var(--u)) 0;
  font-size: var(--fs-40);
  font-weight: 600;
  color: var(--paper);
  transition: color .2s var(--ease);
}
.wk-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .28s var(--ease);
}
.wk-nav a:hover { color: var(--cream); }
.wk-nav a:hover::after,
.wk-nav a.is-active::after { transform: scaleX(1); }
.wk-nav a.is-active { color: var(--cream); }

.wk-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px; height: 40px;
  padding: 0 8px;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.wk-burger span {
  display: block;
  height: 2px;
  background: var(--paper);
  border-radius: 2px;
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.wk-header.is-open .wk-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.wk-header.is-open .wk-burger span:nth-child(2) { opacity: 0; }
.wk-header.is-open .wk-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   5. Héro - composition reprise à l'identique du fichier Figma
   Scène de 3365 × 1731 : chaque enfant reçoit sa position (m02, m12) et sa
   matrice, avec transform-origin en haut à gauche comme dans Figma.
   -------------------------------------------------------------------------- */
.wk-hero {
  position: relative;
  overflow: hidden;
  background: var(--cream);
  /* La scène est en rapport fixe et pleine largeur : sa hauteur vaut toujours
     51,44 % (1731 / 3365) de la largeur du héro. Plafonner le héro en dessous
     de cette valeur ne raccourcit pas la scène, ça la rogne - et comme elle est
     centrée, la moitié du rognage tombe en haut, précisément là où se trouve le
     logotype (top: 4,448 %).

     Pas de plafond, donc : le héro suit sa scène. Un plafond de 880 px coupait
     50 px du haut de la scène dès 1920 px de large, davantage au moindre
     dézoom, et le logotype avec.

     Le plancher, lui, reste : en dessous, c'est la scène qui est plus courte
     que le héro, et --eau-debord comble (voir .wk-hero__bg). */
  min-height: max(560px, 51.44vw);
}

.wk-hero__stage {
  position: absolute;
  left: 50%; top: 50%;
  translate: -50% -50%;
  width: 100%;
  aspect-ratio: 3365 / 1731;
  container-type: inline-size;
  /* Débordement vertical de l'eau, en % de la hauteur de la scène (voir
     .wk-hero__bg). Une vingtaine de pixels suffisent au pire des cas, 6 %
     en font une cinquantaine : de la marge, sans gonfler le canvas. */
  --eau-debord: 6%;
}
.wk-hero__stage > * { position: absolute; transform-origin: 0 0; }

/* Le décor n'est pas interactif : ni sélection, ni survol */
.wk-hero__bg, .wk-hero__caustic, .wk-kanji,
.wk-water, .wk-surface, .wk-hero__logo {
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

/* L'eau (fond crème grainé, puis caustiques) déborde de la scène en haut et en
   bas. La scène garde le rapport de la maquette : elle est donc plus courte que
   le héro dès que la hauteur de celui-ci est bornée - plancher de 560 px, ou
   simplement la barre de défilement, que `vw` compte mais pas la largeur de la
   scène - et comme elle se centre, il restait une bande de crème nu sous
   l'en-tête et au dessus du tapis. Le débordement est rogné par l'`overflow`
   du héro.

   Les deux calques restent dans la scène, et non sur le héro : une fusion ne
   voit que ce qui est peint dans son contexte d'empilement, et la scène en est
   un (translate + container-type). Sortis de là, les kanjis n'auraient plus eu
   de fond avec quoi se fondre en « soft light » et seraient ressortis en brun
   brut, presque noir. */
.wk-hero__bg {
  inset: calc(var(--eau-debord) * -1) 0;
  background: var(--cream);
}

/* Caustiques : un <canvas> animé (voir /script/caustic.js), et rien d'autre -
   sans WebGL le canvas est retiré et il ne reste que le fond crème uni. Le
   motif sort en noir et blanc, la fusion « screen » l'imprime sur le fond
   crème : sa présence se règle donc ici (opacity), pas dans le shader.

   La hauteur est donnée en toutes lettres : sur un élément remplacé (canvas)
   les deux calages verticaux ne suffisent pas à étirer la boîte, le bas
   serait ignoré et le débordement ne tomberait qu'en haut. */
.wk-hero__caustic {
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--eau-debord) * -1);
  display: block;
  width: 100%; height: calc(100% + var(--eau-debord) * 2);
  object-fit: cover;
  mix-blend-mode: screen;
  opacity: .8;
  pointer-events: none;
}

/* Calques « in water » et « surface ».

   L'ombre est posée sur l'enveloppe de chaque décor et non sur ces deux calques
   d'ensemble, comme dans la maquette. Elle reste calculée dans le repère de la
   page (l'enveloppe n'est jamais pivotée, seule l'image qu'elle contient
   l'est), mais elle ne coûte plus rien : un enfant animé dans un parent filtré
   ne peut pas obtenir son propre calque, et forcerait le repeint puis le
   re-flou de tout le héro à chaque image du flottement. */
.wk-water, .wk-surface { inset: 0; pointer-events: none; }
.wk-water > *, .wk-surface > * { position: absolute; transform-origin: 0 0; }
.wk-water   > .wk-float { filter: drop-shadow(calc(-10 * var(--u)) calc(60 * var(--u))  calc(20 * var(--u)) var(--sh-ink)); }
.wk-surface > .wk-float { filter: drop-shadow(calc(-20 * var(--u)) calc(120 * var(--u)) calc(20 * var(--u)) var(--sh-ink)); }

/* L'enveloppe donne le cadre, l'image le remplit et ne porte que sa rotation :
   pivoter autour du coin haut-gauche d'une image qui occupe exactement la
   boîte revient au même qu'avant, quand position et matrice étaient sur la
   même balise. */
.wk-float > .wk-deco {
  width: 100%; height: 100%;
  transform-origin: 0 0;
}
/* Le crème reste net, sans grain. Il y en avait un ici et sur les deux autres
   sections crème : un feTurbulence, qui tire du bruit sur les trois canaux
   séparément. Chaque pixel partait donc dans une teinte différente, et sur un
   aplat aussi saturé ce bruit chromatique lisait comme un voile gris. */

/* Kanjis en filigrane. La maquette les pose en « soft light », mais leur fond
   est un aplat : .wk-hero__bg, uniformément --cream, et les caustiques sont
   peintes par-dessus, pas en dessous. Le résultat de la fusion est donc une
   couleur constante, calculée une fois pour toutes plutôt qu'à chaque image :
   soft-light(#ffdcb4, --brown #2d1408) = #ffc382. Rendu identique, sans le
   mode de fusion qui obligeait le héro à repasser par une couche séparée.
   Si le fond du héro change, recalculer cette valeur. */
.wk-kanji {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18.484%;
  height: 32.813%;
  font-family: var(--f-jp);
  font-weight: 300;
  line-height: 1;
  color: #ffc382;
  user-select: none;
}
.wk-kanji--suiren { left: 49.718%; top:  4.910%; font-size:  8.915cqw; }
.wk-kanji--hana   { left:  9.866%; top: 34.084%; font-size: 11.887cqw; }
.wk-kanji--sakana { left: 62.883%; top: 47.603%; font-size: 14.859cqw; }

/* Carpe koï et nénuphars - matrices exactes du fichier */
.wk-deco { object-fit: cover; }

/* Cadre sur l'enveloppe, matrice du fichier sur l'image qu'elle contient. */
.wk-koi      { left: 81.938%; top: 115.956%; width: 25.532%; height: 71.247%; }
.wk-pad--1   { left: 82.951%; top:  27.209%; width: 14.935%; height: 26.231%; }
.wk-pad--2   { left: 65.802%; top:  25.513%; width: 18.203%; height: 31.970%; }
.wk-pad--3   { left: 86.536%; top:  54.650%; width: 23.428%; height: 41.147%; }
.wk-pad--4   { left: 13.826%; top:  59.443%; width: 13.592%; height: 23.871%; }
.wk-pad--5   { left: 33.917%; top:  69.438%; width: 18.424%; height: 32.359%; }
.wk-lotus--1 { left:  4.012%; top:  52.280%; width: 18.484%; height: 34.258%; }
.wk-lotus--2 { left: 85.087%; top:   4.777%; width: 12.897%; height: 23.917%; }

.wk-koi      > .wk-deco { transform: matrix(-.9162, -.4006,  .4006, -.9162, 0, 0); }
.wk-pad--1   > .wk-deco { transform: matrix(-.6885,  .7253, -.7253, -.6885, 0, 0); }
.wk-pad--2   > .wk-deco { transform: matrix(-.7187, -.6953,  .6953, -.7187, 0, 0); }
.wk-pad--3   > .wk-deco { transform: matrix( .7583, -.6519, -.6519, -.7583, 0, 0); }
.wk-pad--4   > .wk-deco { transform: matrix(-.5224, -.8527, -.8527,  .5224, 0, 0); }
.wk-pad--5   > .wk-deco { transform: matrix( .3472,  .9378, -.9378,  .3472, 0, 0); }
.wk-lotus--2 > .wk-deco { transform: matrix(-.9586, -.2846, -.2846,  .9586, 0, 0); }

/* Bloc logo (instance « Format=Big », 1361,2 × 482,2) ---------------------- */
.wk-hero__logo {
  left: 3.388%; top: 4.448%;
  width: 40.452%; height: 27.858%;
}
.wk-hero__logo > * { position: absolute; transform-origin: 0 0; }

/* Le logotype entier (trait rouge, kana, mot, signature) vient du SVG exporté
   de la maquette : les lettres y sont des tracés, pas du texte, donc le rendu
   est identique partout sans dépendre du chargement d'« Edo SZ » ni de sa
   police de repli. Le viewBox du fichier (1702 × 603) reprend exactement le
   cadre du bloc, l'image le remplit donc au pixel. */
.wk-hero__mark {
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}

/* Accroche et boutons ----------------------------------------------------- */
/* La boîte de la maquette (27,608 % de large, 4,795 % de haut : une ligne de 64
   unités interlignée à 1,3) épouse l'accroche au serif d'origine, plus étroit
   que Fredoka, qui la ferait passer à deux lignes et déborder sur les boutons.

   Le cadre reste celui du fichier mais la ligne ne se coupe pas : elle déborde
   à droite et à gauche de la même quantité, donc reste sur l'axe où la maquette
   la pose. Rien ne se trouve à cette hauteur en dehors des kanjis en filigrane,
   qui sont un fond. */
.wk-hero__pitch {
  left: 36.196%; top: 38.590%;
  width: 27.608%; height: 4.795%;
  display: flex; align-items: center; justify-content: center;
  white-space: nowrap;
  font-family: var(--f-body);
  font-size: 1.902cqw;
  font-weight: 400;
  line-height: 1.3;
  color: var(--ink);
}
.wk-hero__pitch .accent { color: var(--red); }

.wk-hero__cta {
  left: 40.921%; top: 52.802%;
  width: 17.831%; height: 15.020%;
  display: flex;
  flex-direction: column;
  gap: 1.486cqw;                    /* 50 px Figma */
}
.wk-hero__cta .wk-btn {
  width: 100%;
  min-height: 0;
  height: 3.12cqw;                  /* 105 px Figma */
  padding: 0 1.783cqw;
  --bd-w: .149cqw;
  border-radius: .594cqw;
  font-size: 1.189cqw;
}

/* --------------------------------------------------------------------------
   6. Tapis roulant - défile en continu, ne s'arrête jamais

   Le tapis est une CHAÎNE : chaque latte est un maillon, dont le nez s'emboîte
   dans le creux de la suivante autour d'une charnière commune (voir le tracé
   dans partials/wakame-tapis.ejs). La latte de gauche recouvre celle de droite.

   Rien de ce mouvement ne se décrit ici : /script/tapis.js trace le parcours
   d'après la page, y accroche la chaîne et en tire des @keyframes de
   translate/rotate, qu'il pose dans une feuille sur le tapis. Le CSS ne fait
   que nommer l'animation (--tapis-anim) et accrocher les dessins.

   Un tapis droit (l'accueil) est un parcours à deux points, le circuit de
   /kaiten un parcours à quatre - c'est la seule différence entre les deux, et
   il n'y a qu'un moteur.
   -------------------------------------------------------------------------- */
.wk-belt {
  position: relative;
  z-index: 5;
  user-select: none;
  pointer-events: none;
}

/* Le tapis droit de l'accueil : un bandeau pleine largeur. Sa couleur est
   posée ici et non seulement dans le SVG du parcours, pour que la bande
   sombre reste en place quand le script ne répond pas.

   `overflow-x: clip` : le tapis entre et sort hors champ, ses lattes et son
   tracé s'étendent donc bien au delà de l'écran. `body { overflow-x: hidden }`
   les cachait, mais cacher ne suffit pas : sur téléphone, le navigateur
   MESURE d'abord la largeur du contenu et élargit le cadre de mise en page
   jusqu'à elle, puis dézoome la page pour la faire tenir. Toute la page se
   retrouvait rendue à 81 % de la largeur de l'écran, avec une bande morte
   à droite. La coupe ici empêche le débord de compter dans cette mesure.

   `clip` et non `hidden` : `hidden` sur un seul axe force l'autre à `auto`,
   ce qui ferait de la bande un conteneur de défilement et ROGNERAIT les
   assiettes, qui dépassent volontairement en haut et en bas. `clip` laisse
   l'axe vertical en `visible`. La boîte fait toute la largeur de la page :
   couper à son bord, c'est couper au bord de l'écran - le rendu ne bouge
   pas d'un pixel, sur téléphone comme sur poste de travail. */
.wk-belt--droit {
  height: var(--belt-h);
  background: var(--ink);
  overflow-x: clip;
}

/* Le bandeau : le parcours peint en trait épais. Il déborde de sa boîte aux
   deux bouts (le tapis entre et sort hors champ), d'où overflow: visible. */
.wk-belt__band {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
}
.wk-belt__band path { fill: none; stroke: var(--ink); }

.wk-belt__slats  { position: absolute; inset: 0; z-index: 1; }
.wk-belt__plates { position: absolute; inset: 0; z-index: 3; pointer-events: none; }

/* Lattes et assiettes avancent de la même façon : un tour complet du parcours,
   à la même cadence. Les lattes bouclent sans fin, décalées d'un cycle par un
   délai négatif (posé par le script) ; une assiette ne fait qu'un passage.

   Ce sont de simples POINTS - une boîte de taille nulle qui porte le mouvement,
   et à laquelle le dessin est accroché par un décalage. Le point posé sur le
   parcours est ainsi le même pour tout le monde : le milieu du maillon pour une
   latte, le centre pour une assiette.

   Le mouvement, lui, ne se décrit pas en CSS : il est calculé par
   /script/tapis.js, qui l'écrit en @keyframes de translate/rotate dans une
   feuille posée sur le tapis, et en donne le nom par --tapis-anim. Une chaîne
   ne se laisse pas dire par `offset-path` - voir l'en-tête de tapis.js.

   --tapis-anim et --tapis-tour sont écrits sur .wk-belt par le script. */
.wk-slat,
.wk-plate-rider {
  position: absolute;
  left: 0; top: 0;
  width: 0; height: 0;
  animation-name: var(--tapis-anim, none);
  animation-timing-function: linear;
  /* Chacune sa couche : elles sont dessinées une fois, puis seule leur
     position change. Sans cela, tout ce que le tapis survole - colonnes de
     prix, plateau du simulateur - est repeint à chaque image. */
  will-change: translate, rotate;
}

.wk-slat {
  /* Un cycle par maillon, et le tour en compte autant qu'il y a de lattes. */
  animation-duration: var(--tapis-tour, 20s);
  animation-iteration-count: infinite;
}
/* La latte est accrochée au point par le MILIEU DE SON MAILLON - à mi-chemin
   de ses deux charnières, tout près de son bord arrière. C'est le point qui la
   garde centrée sur le bandeau dans un virage : ses deux charnières s'en
   écartent alors vers l'extérieur, du même côté et d'autant l'une que l'autre.
   --slat-ancre est posée par le script, qui la lit sur le dessin. */
.wk-slat > svg {
  position: absolute;
  left: calc(-1 * var(--slat-ancre, 0px));
  top: calc(-1 * var(--slat-h, 0px) / 2);
  width: var(--slat-w); height: var(--slat-h);
}

/* L'assiette suit le tapis, virages compris : elle est posée sur les lattes et
   tourne avec elles. Comme elle est ronde, cela ne se voit que sur la découpe
   de sushi - et c'est justement ce qui manquait, une assiette qui traverse un
   virage sans que rien ne bouge dessus a l'air collée à l'écran. */
.wk-plate-rider { animation-fill-mode: forwards; }
/* Accrochée par son centre. La hauteur d'une assiette vaut 204/203 de sa
   largeur (le rapport de assiette.svg), d'où la demi-hauteur en 102/203. */
.wk-plate-rider > .wk-plate {
  position: absolute;
  left: calc(var(--plate-size) / -2);
  top: calc(var(--plate-size) * -102 / 203);
}

/* Sans `translate`/`rotate` animables, lattes et assiettes s'empileraient
   toutes au coin haut gauche du tapis. Il ne reste alors que le bandeau,
   immobile. */
@supports not ((translate: 1px 1px) and (rotate: 1deg)) {
  .wk-belt__slats, .wk-belt__plates { display: none; }
}

/* Hors écran ou onglet en arrière-plan, le tapis n'a plus personne à divertir :
   on fige les lattes et les assiettes. /script/tapis.js coupe aussi le semeur
   d'assiettes et repeuple à la réapparition, pour que le tapis ait l'air de
   n'avoir jamais cessé de tourner. */
.wk-belt.is-paused .wk-slat,
.wk-belt.is-paused .wk-plate-rider { animation-play-state: paused; }

/* Assiette : dessin fourni (assiette.svg), inséré une fois puis réutilisé.
   --body pilote le fond, --ring le liseré. */
.wk-plate {
  position: relative;
  display: block;
  width: var(--plate-size, calc(299 * var(--u)));
  flex: none;
  aspect-ratio: 203 / 204;
}
.wk-plate__dish {
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(calc(15 * var(--u)) calc(3 * var(--u)) calc(7.5 * var(--u)) rgb(0 0 0 / .25));
}

/* Assiette illustrée d'une PHOTO au lieu du dessin (réglé par assiette dans
   /admin/assiettes). Elle occupe exactement la même case et porte la même
   ombre : dans une pile, une photo et un dessin s'alignent au pixel près.

   Le disque gris est sur l'enveloppe et non sur l'image : il reste visible si
   la photo ne charge pas (wkImgVide y met alors un pixel transparent), ce qui
   laisse une assiette vide plutôt qu'une icône cassée. */
.wk-plate--photo {
  border-radius: 50%;
  background: var(--ph);
  filter: drop-shadow(calc(15 * var(--u)) calc(3 * var(--u)) calc(7.5 * var(--u)) rgb(0 0 0 / .25));
}
.wk-plate__photo {
  width: 100%;
  height: 100%;
  /* `cover` : une photo au format libre remplit le disque sans se déformer,
     quitte à être recadrée - une assiette aplatie se verrait tout de suite. */
  object-fit: cover;
  border-radius: 50%;
}
/* La découpe est mise à l'échelle de l'assiette quelles que soient ses
   dimensions d'origine : `contain` l'inscrit dans la case sans la déformer,
   qu'elle soit plus grande (elle rétrécit) ou plus petite (elle grandit).

   Cette case donne la même *boîte* à toutes les découpes, donc pas la même
   surface : une image carrée la remplit dans les deux sens, une image allongée
   dans un seul, et le roll paraît deux fois plus gros que le nigiri. D'où
   --food-scale, mesuré par /script/tapis.js sur les pixels visibles de chaque
   image pour qu'elles couvrent toutes la même surface. Le repli 1 laisse le
   rendu d'origine si le script ne tourne pas. */
.wk-plate__food {
  position: absolute;
  left: 50%; top: 50%;
  width: var(--food-w);
  height: var(--food-h);
  object-fit: contain;
  z-index: 2;
  transform: translate(-50%, -50%) translate(2.9%, -2.9%)
             rotate(var(--food-rot, -48.7deg))
             scale(calc(var(--food-scale, 1) * var(--food-pop, 1)))
             scaleX(var(--food-flip, 1));
  filter: drop-shadow(-4px 3px 4px rgb(0 0 0 / .3));
}

/* --- On attrape l'assiette au passage ---------------------------------
   Le bandeau est traversant : seules l'assiette et sa découpe reçoivent le
   pointeur. Le cadre carré de .wk-plate, lui, reste transparent au clic -
   sinon ses quatre coins, hors du disque, seraient cliquables eux aussi.
   Un <svg> ne répond que là où il est peint : la zone sensible épouse donc
   le dessin de l'assiette. */
.wk-belt__plates .wk-plate {
  cursor: pointer;
  pointer-events: none;
  transition: transform .32s var(--ease);   /* var(--ease) = ease-out */
}
.wk-belt__plates .wk-plate__dish,
.wk-belt__plates .wk-plate__food,
/* Une assiette photo s'attrape comme les autres. Elle est rectangulaire au
   sens du DOM, mais découpée en disque par border-radius : la zone sensible
   suit le dessin, ses quatre coins ne sont pas cliquables. */
.wk-belt__plates .wk-plate__photo { pointer-events: auto; }
.wk-belt__plates .wk-plate:hover { transform: scale(1.12); }

/* Assiette cliquée : elle garde le grossissement du survol pendant sa chute
   (le pointeur ne la suit plus, :hover est déjà retombé). */
.wk-plate.is-taken { transform: scale(1.12); }

/* La découpe prend un peu d'élan - une simple anticipation, elle ne doit pas
   se remarquer - puis se rétracte jusqu'à disparaître.
   --food-pop est déclaré pour que le navigateur sache l'interpoler : une
   variable non déclarée passerait de 1 à 0 d'un seul bond au milieu de
   l'animation. Le repli var(--food-pop, 1) garde le rendu d'origine là où
   @property n'existe pas. */
@property --food-pop {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}
.wk-plate__food.is-eaten { animation: wk-food-burst .3s forwards; }
@keyframes wk-food-burst {
  0%   { --food-pop: 1;    animation-timing-function: var(--ease); }
  30%  { --food-pop: 1.12; animation-timing-function: cubic-bezier(.5, 0, .75, .2); }
  100% { --food-pop: 0; }
}

/* L'assiette tombe sur toute la hauteur de l'écran, bien au delà du bandeau
   et des sections qui le suivent : /script/tapis.js la sort du tapis et la
   confie à cette couche, calée sur la vue (et non sur la page) le temps de la
   chute. Sous l'en-tête, qui reste au-dessus de tout. */
.wk-plate-drop {
  position: fixed;
  z-index: 90;
  pointer-events: none;
  animation: wk-plate-fall var(--fall-time, .8s) cubic-bezier(.5, 0, .9, .4) forwards;
}
@keyframes wk-plate-fall {
  to { transform: translate3d(0, var(--fall-distance, 100vh), 0); }
}

/* --------------------------------------------------------------------------
   7. Section « Le kaiten »  (Figma 3365 × 1900, fond crème)
   -------------------------------------------------------------------------- */
.wk-kaiten { background: var(--cream); }

.wk-headrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(50 * var(--u)) calc(100 * var(--u));
  margin-bottom: calc(50 * var(--u));
}
.wk-headrow__titles { display: flex; flex-direction: column; gap: calc(10 * var(--u)); }
.wk-headrow__cta { display: flex; align-items: center; gap: calc(50 * var(--u)); flex-wrap: wrap; }
/* Texte du CMS, à la casse saisie : Fredoka semi-bold, pas la brosse. */
.wk-headrow__cta p { font-family: var(--f-round); font-weight: 600; font-size: var(--fs-48); line-height: 1.25; }

.wk-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(100 * var(--u));
}
.wk-step {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--u));
  padding: calc(50 * var(--u));
  background: var(--paper);
  border-radius: var(--r-card);
  box-shadow: var(--sh-lg);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.wk-step:hover { transform: translateY(-8px); box-shadow: 4px 16px 26px var(--sh-ink); }
.wk-step__head { display: flex; align-items: center; gap: calc(50 * var(--u)); }
.wk-step__num {
  flex: none;
  display: grid;
  place-items: center;
  width: calc(100 * var(--u)); height: calc(100 * var(--u));
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--f-display);
  font-size: var(--fs-64);
  line-height: 1;
  transition: transform .3s var(--ease);
}
.wk-step:nth-child(2) .wk-step__num { background: var(--red); }
.wk-step:hover .wk-step__num { transform: rotate(-8deg) scale(1.08); }
/* La casse est celle du texte saisi dans le CMS : « Installez-vous… », donc
   Fredoka semi-bold et non la brosse, réservée aux capitales. */
.wk-step__title {
  font-family: var(--f-round);
  font-weight: 600;
  font-size: var(--fs-48);
  line-height: 1.25;
}
.wk-step p { font-size: var(--fs-40); }

.wk-rule {
  height: calc(3 * var(--u));
  border: 0;
  border-radius: 3px;
  background: rgb(30 24 48 / .5);
  margin-block: calc(100 * var(--u));
}

/* Tarifs ------------------------------------------------------------------ */
.wk-prices {
  display: grid;
  grid-template-columns: calc(991 * var(--u)) minmax(0, 1fr) auto;
  grid-template-areas: "photo texte cols";
  gap: calc(150 * var(--u));
  align-items: center;
}
.wk-prices__photo { grid-area: photo; }
.wk-prices__text  { grid-area: texte; }
.wk-prices__cols  { grid-area: cols; }

/* Grille tarifaire vide (aucune assiette réglée dans /admin/assiettes) : la
   troisième colonne n'est pas rendue. Il faut aussi la retirer du gabarit,
   sinon sa gouttière laisse une bande vide à droite du texte. */
.wk-prices--sans-cols {
  grid-template-columns: calc(991 * var(--u)) minmax(0, 1fr);
  grid-template-areas: "photo texte";
}

/* La maquette pose trois colonnes de prix à droite du texte, et c'est tout ce
   que la rangée peut tenir : la quatrième se paierait sur la largeur du texte,
   qui n'a déjà que 1fr. Au delà, la grille descend sur sa propre ligne, pleine
   largeur, où elle s'étale et passe à la ligne librement.
   Le regroupement fait par utils/assietteColonnes.js maintient le cas courant
   à trois colonnes - la mise en page de la maquette est donc la règle, celle-ci
   la soupape. */
.wk-prices--large {
  grid-template-columns: calc(991 * var(--u)) minmax(0, 1fr);
  grid-template-areas:
    "photo texte"
    "cols  cols";
}
/* Visuels pilotés depuis /admin/images : ils viennent uniquement de Cloudinary,
   il n'existe aucun fichier local de secours. Le fond gris tient donc lieu de
   placeholder dans les trois cas - image non définie, en cours de chargement
   (une <img> est transparente tant qu'elle n'est pas peinte), ou en erreur
   (wkImgVide remplace alors la source par un pixel transparent). */
.wk-ph { background: var(--ph); }

.wk-prices__photo {
  width: 100%;
  aspect-ratio: 991 / 743;
  object-fit: cover;
  border-radius: var(--r-card);
  border: calc(15 * var(--u)) solid var(--paper);
  box-shadow: var(--sh-lg);
}
.wk-prices__text { display: flex; flex-direction: column; gap: calc(10 * var(--u)); }
.wk-prices__cols {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: calc(50 * var(--u));
  min-width: 0;
}

.wk-pricecol { position: relative; padding-top: calc(15 * var(--u)); width: calc(263 * var(--u)); }
/* L'étiquette de prix, à cheval sur le haut de la pile (.wk-pricecol__tag) ou
   posée à côté d'une assiette seule dans la colonne « à l'unité ». */
.wk-pricetag {
  padding: 0 calc(30 * var(--u));
  height: calc(45 * var(--u));
  display: inline-flex; align-items: center;
  border-radius: 999px;
  background: var(--red);
  color: var(--paper);
  font-family: var(--f-ui);   /* les prix sont en Fredoka, pas à la brosse */
  font-size: var(--fs-40);
  white-space: nowrap;
  box-shadow: 1px 2px 6px var(--sh-ink);
}
.wk-pricecol__tag {
  position: absolute;
  left: 50%; top: 0;
  translate: -50% 0;
  z-index: 3;
}
.wk-pricecol__stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: calc(50 * var(--u)) calc(30 * var(--u));
  border-radius: var(--r-card);
  background: var(--ink);
  box-shadow: var(--sh-lg);
}
.wk-pricecol__stack .wk-plate {
  --plate-size: calc(203 * var(--u));
  margin-bottom: calc(-50 * var(--u));
  transition: transform .28s var(--ease);
}
.wk-pricecol__stack .wk-plate:last-child { margin-bottom: 0; }
.wk-pricecol__stack:hover .wk-plate { transform: translateX(3px) rotate(4deg); }

/* Colonne « à l'unité » : les prix qui n'ont qu'une assiette sont réunis ici
   plutôt que de faire chacun une colonne haute d'une seule assiette (voir
   utils/assietteColonnes.js). Les assiettes ne s'y chevauchent plus - il n'y a
   plus de pile à suggérer - et chacune garde son étiquette à côté d'elle.
   Largeur libre : c'est l'étiquette la plus longue qui décide. */
.wk-pricecol--seuls { width: auto; min-width: calc(263 * var(--u)); }
.wk-pricecol--seuls .wk-pricecol__stack {
  align-items: stretch;
  gap: calc(25 * var(--u));
  padding: calc(40 * var(--u));
}
.wk-pricecol--seuls .wk-pricecol__stack .wk-plate {
  --plate-size: calc(150 * var(--u));
  margin-bottom: 0;
}
.wk-priceline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(30 * var(--u));
}

/* --------------------------------------------------------------------------
   8. Bandeau « La carte »  (Figma 3365 × 481, fond rouge, padding 150/100)
   -------------------------------------------------------------------------- */
.wk-band {
  background: var(--red);
  color: var(--paper);
  padding-block: calc(100 * var(--u));
}
.wk-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(50 * var(--u)) calc(100 * var(--u));
}
.wk-band__text { display: flex; flex-direction: column; gap: calc(10 * var(--u)); }

/* --------------------------------------------------------------------------
   9. Notre histoire  (Figma 3365 × 1923, fond sombre)
   Le collage occupe toute la largeur, le texte flotte par-dessus.
   -------------------------------------------------------------------------- */
.wk-story {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--ink);
  color: var(--paper);
  min-height: clamp(620px, 57.15vw, 892px);   /* 1923 / 3365 */
}
.wk-story__kana {
  position: absolute;
  left: 34.56%; top: 5.1%;
  width: 15.69%;                                   /* 528 / 3365 */
  z-index: 0;
  font-family: var(--f-jp);
  font-weight: 300;
  font-size: calc(400 * var(--u));
  line-height: 1.45;                               /* 1737 / 3 / 400 */
  color: #000000;
  user-select: none;
  pointer-events: none;
}
.wk-story__inner { position: relative; z-index: 2; }

.wk-collage {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  translate: -50% 0;
  width: min(100%, 1560px);
  z-index: 1;
  pointer-events: none;
}
/* Rectangles : exports fournis (photo + découpe déjà composées).
   Positions déduites de la maquette, coins vifs comme dans le fichier.

   Chaque fichier porte le même rectangle plein de 438 × 876 (le 1:2 de la
   maquette) et la photo qui déborde autour, en transparence. Les jetons
   --img-* / --rec-* situent ce rectangle dans le fichier - relevés sur les
   pixels opaques - pour pouvoir caler une mise en page sur le rectangle plutôt
   que sur le cadre de l'image (voir la grille du format téléphone). */
.wk-collage__item {
  position: absolute;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(-8px 12px 8px rgb(0 0 0 / .3));
  --img-w: 438; --img-h: 876;
  --rec-x: 0;   --rec-y: 0;
  --rec-w: 438; --rec-h: 876;
}
.wk-collage__bambou { left:  0.921%; top: 22.413%; width: 18.573%; --img-w: 625; --rec-x: 187; }
.wk-collage__sakura { left: 79.406%; top:  7.072%; width: 17.415%; --img-w: 586; --img-h: 880; --rec-x: 74; --rec-y: 3; }
.wk-collage__arbre  { left: 60.743%; top: 46.854%; width: 18.365%; --img-w: 618; --rec-x: 93; }
.wk-collage__fuji   { left: 71.025%; top: 14.821%; width: 13.016%; }   /* l'image est le rectangle */


.wk-story__text {
  display: flex;
  flex-direction: column;
  gap: calc(100 * var(--u));
  width: calc(1147 * var(--u));                    /* 458,8 px */
  margin-left: clamp(0px, 19.76vw, calc(665 * var(--u)));
}
.wk-story__body { display: flex; flex-direction: column; gap: calc(30 * var(--u)); }
.wk-story__body p { font-size: var(--fs-40); color: rgb(255 255 255 / .8); }

/* Carte d'avis ------------------------------------------------------------ */
.wk-review {
  position: relative;
  padding: calc(30 * var(--u));
  border-radius: var(--r-card);
  background: var(--paper);
  color: var(--brown);
  overflow: hidden;
}
.wk-review__slide {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--u));
  transition: opacity .45s var(--ease), transform .45s var(--ease);
}
.wk-review.is-swapping .wk-review__slide { opacity: 0; transform: translateY(10px); }
.wk-review__head { display: flex; align-items: center; gap: calc(30 * var(--u)); }
.wk-review__avatar {
  width: calc(100 * var(--u)); height: calc(100 * var(--u));
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--cream);
}
/* Une initiale, capitalisée par le gabarit : elle reste donc à la brosse. */
.wk-review__avatar--empty {
  display: grid; place-items: center;
  font-family: var(--f-hand);
  font-size: var(--fs-48);
  color: var(--red);
}
.wk-review__name {
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: var(--fs-40);
  line-height: 1.5;
}
.wk-review__stars { display: flex; }
/* Icônes Material : c'est la taille de caractère qui les dimensionne, pas une
   largeur - une icône de fonte est une lettre. L'étoile vide n'est pas un autre
   dessin mais la même, contour seul (axe FILL), et éteinte. */
.wk-review__stars .msr { font-size: calc(44 * var(--u)); color: var(--gold); }
.wk-review__stars .msr.is-off { color: rgb(45 20 8 / .18); }
.wk-review__text {
  font-family: var(--f-ui);
  font-size: var(--fs-40);
  line-height: 1.5;
}
.wk-review__dots { display: flex; gap: 6px; margin-top: calc(20 * var(--u)); }
.wk-review__dot {
  width: 8px; height: 8px;
  padding: 0; border: 0; border-radius: 50%;
  background: rgb(45 20 8 / .22);
  cursor: pointer;
  transition: background-color .25s var(--ease), transform .25s var(--ease);
}
.wk-review__dot.is-active { background: var(--red); transform: scale(1.25); }

/* --------------------------------------------------------------------------
   10. Petite mise en bouche  (Figma 3365 × 1679, fond crème)
   -------------------------------------------------------------------------- */
.wk-taste {
  position: relative;
  overflow: hidden;
  background: var(--cream);
  padding-block: calc(109.3 * var(--u)) calc(301.5 * var(--u));
}
.wk-taste__temple {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 17.801%;                                  /* 599 / 3365 */
  height: 100%;
  object-fit: fill;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.wk-taste__inner {
  position: relative;
  z-index: 2;
  width: min(100%, calc(2638 * var(--u)));
  margin-inline: auto;
}

.wk-polas {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(243.8 * var(--u));
  margin-top: calc(152 * var(--u));
}
.wk-pola {
  position: relative;
  padding: calc(45 * var(--u)) calc(46 * var(--u)) 0;
  background: var(--paper);
  border-radius: 2px;
  box-shadow: 2px 4px 4px var(--sh-ink);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.wk-pola:nth-child(2) { rotate: 1.74deg; }
.wk-pola:nth-child(3) { rotate: -1.16deg; }
.wk-pola:nth-child(4) { rotate: 2.11deg; }
.wk-pola:hover { rotate: 0deg; transform: translateY(-10px); box-shadow: 4px 18px 26px var(--sh-ink); }
.wk-pola img,
.wk-pola .wk-ph { width: 100%; aspect-ratio: 628 / 639; object-fit: cover; }
.wk-pola { display: block; color: inherit; }
/* Noms de plats, à la casse du CMS : Fredoka semi-bold, pas la brosse. */
.wk-pola__nom {
  padding: calc(53 * var(--u)) 0 calc(76 * var(--u));
  font-family: var(--f-round);
  font-weight: 600;
  display: block;
  font-size: var(--fs-48);
  line-height: 1.25;
  text-align: center;
}
/* --------------------------------------------------------------------------
   11. Réserver + Foodease  (Figma 3365 × 1413, fond sombre)
   -------------------------------------------------------------------------- */
.wk-book { background: var(--ink); color: var(--paper); }
.wk-book__card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(50 * var(--u));
  padding: calc(30 * var(--u));
  border-radius: var(--r-panel);
  background: var(--paper);
  color: var(--brown);
}
.wk-book__info {
  display: flex;
  flex-direction: column;
  gap: calc(50 * var(--u));
  padding: calc(50 * var(--u));
}
.wk-book__info p { font-size: var(--fs-40); }
.wk-book__info p a:hover { color: var(--red); text-decoration: underline; }
.wk-book__map {
  display: block;
  width: 100%;
  height: 100%;
  min-height: calc(400 * var(--u));
  border: 0;
  border-radius: var(--r-btn);
  object-fit: cover;
}

.wk-foodease {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(50 * var(--u));
  margin-top: calc(150 * var(--u));
}
.wk-foodease__id { display: flex; align-items: center; gap: calc(50 * var(--u)); }
.wk-foodease__id img {
  width: calc(243 * var(--u));
  height: calc(243 * var(--u));
  object-fit: contain;
  flex: none;
}
.wk-foodease__txt { display: flex; flex-direction: column; }
.wk-foodease strong {
  font-family: var(--f-hand);
  font-size: var(--fs-64);
  font-weight: 400;
  line-height: 1.27;
  text-transform: uppercase;
  color: var(--foodease);
}
.wk-foodease p { font-size: var(--fs-40); }
.wk-foodease .wk-btn {
  --btn-bg: var(--foodease); --btn-bd: var(--foodease); --btn-fg: var(--brown);
  font-weight: 400;
}
.wk-foodease .wk-btn:hover { --btn-bg: #5cdcf7; --btn-bd: #5cdcf7; }

/* --------------------------------------------------------------------------
   12. Pied de page  (Figma 3365 × 570)
   -------------------------------------------------------------------------- */
.wk-footer {
  background: var(--ink);
  color: var(--paper);
  border-top: calc(3 * var(--u)) solid var(--red);
  padding-block: calc(50 * var(--u));
}
.wk-footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: calc(100 * var(--u));
}
.wk-footer__brand { display: flex; flex-direction: column; align-items: center; }
.wk-footer__cols { display: flex; gap: calc(300 * var(--u)); }
.wk-footer__cols h3 {
  font-family: var(--f-ui);
  font-weight: 700;
  font-size: var(--fs-48);
  line-height: 1.5;
  margin-bottom: calc(10 * var(--u));
}
.wk-footer__cols li,
.wk-footer__cols a { font-family: var(--f-ui); font-size: var(--fs-40); line-height: 1.5; }
.wk-footer__cols a { transition: color .2s var(--ease); }
.wk-footer__cols a:hover { color: var(--cream); }
.wk-footer__sep { height: 1px; border: 0; background: rgb(255 247 247 / .18); margin-block: calc(50 * var(--u)); }
.wk-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: calc(20 * var(--u)) calc(100 * var(--u));
  font-family: var(--f-ui);
  font-size: var(--fs-40);
}
.wk-footer__bottom a:hover { color: var(--cream); text-decoration: underline; }

/* Signature du studio : une ligne à part, sous les mentions, pour ne pas
   entrer dans la répartition en deux blocs de .wk-footer__bottom. */
.wk-footer__signature { display: flex; justify-content: center; margin-top: calc(60 * var(--u)); }
.wk-signature {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(25 * var(--u));
  font-family: var(--f-ui);
  font-size: var(--fs-40);
  line-height: 1.5;
  color: rgb(255 247 247 / .7);
  transition: color .2s var(--ease);
}
.wk-signature__logo {
  flex: none;
  width: calc(70 * var(--u));   /* 28 px */
  height: auto;
  border-radius: 50%;
}
.wk-signature strong { font-weight: 700; }
.wk-signature:hover { color: var(--cream); }
.wk-signature:hover strong { text-decoration: underline; }

/* --------------------------------------------------------------------------
   13. Apparition au défilement
   -------------------------------------------------------------------------- */
.js .wk-reveal {
  opacity: 0;
  translate: 0 22px;
  transition: opacity .7s var(--ease), translate .7s var(--ease);
}
.js .wk-reveal.is-in { opacity: 1; translate: none; }
/* Ces éléments portent à la fois l'apparition et un survol : la transition
   doit couvrir les deux, sinon .js .wk-reveal l'écrase et le survol est sec. */
.js .wk-step,
.js .wk-pola,
.js .wk-btn {
  transition: opacity .7s var(--ease), translate .7s var(--ease),
              transform .35s var(--ease), box-shadow .35s var(--ease),
              filter .35s var(--ease), rotate .35s var(--ease),
              background-color .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease);
}
/* .wk-post (public/style/article.css) tombe dans le même piège : sa carte
   porte l'apparition ET l'élévation au survol. Sa propre déclaration
   `transition` n'y survivait pas - `.js .wk-reveal` (deux classes, spécificité
   plus forte que le seul `.wk-post`) l'écrasait par un raccourci qui ne
   couvrait que opacity/translate, laissant transform et box-shadow sans
   transition du tout : le survol sautait au lieu de glisser.
   Durée et courbe reprennent celles d'article.css - une grande carte
   qui apparaît en douceur ne doit pas s'élever d'un coup sec ensuite. */
.js .wk-post {
  transition: opacity .7s var(--ease), translate .7s var(--ease),
              transform .6s cubic-bezier(.22, 1, .36, 1),
              box-shadow .6s cubic-bezier(.22, 1, .36, 1);
}

.js .wk-reveal[data-delay="1"] { transition-delay: .09s; }
.js .wk-reveal[data-delay="2"] { transition-delay: .18s; }
.js .wk-reveal[data-delay="3"] { transition-delay: .27s; }

@keyframes wk-drift {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -10px; }
}
.wk-koi      { animation: wk-drift 12s ease-in-out infinite; }
.wk-pad--1   { animation: wk-drift 11s ease-in-out infinite; }
.wk-pad--2   { animation: wk-drift 14s ease-in-out infinite reverse; }
.wk-pad--3   { animation: wk-drift 13s ease-in-out infinite; }
.wk-pad--4   { animation: wk-drift 15s ease-in-out infinite reverse; }
.wk-pad--5   { animation: wk-drift 12.5s ease-in-out infinite; }
.wk-lotus--1 { animation: wk-drift 11s ease-in-out infinite; }
.wk-lotus--2 { animation: wk-drift 13s ease-in-out infinite reverse; }

/* --------------------------------------------------------------------------
   14. Adaptatif
   -------------------------------------------------------------------------- */

/* Grands écrans -----------------------------------------------------------
   La maquette ne réserve que 150 unités de chaque côté du contenu, soit 4,5 %
   de sa largeur. Le conteneur étant figé à 1226 px, un écran de 2560 en
   laissait 667 : un quart de l'écran de marge de chaque côté, quand le héro et
   le tapis, eux, occupent toute la largeur.

   Tout est mesuré en --u (1 px de maquette) : agrandir ce seul jeton remet la
   page entière à l'échelle - conteneur, corps de texte, gouttières, bandeau et
   assiettes - sans toucher une règle de mise en page, et sans déformer le
   rapport d'aucun bloc. On reste très en deçà de l'échelle de la maquette
   (2560 / 3365 = 0,76) : les lignes de texte y deviendraient interminables.

   /script/tapis.js relit --u à chaque redimensionnement : les assiettes du
   tapis suivent d'elles-mêmes. Des paliers plutôt qu'une interpolation en vw,
   pour que la valeur reste une longueur simple, que le script sait lire. */
@media (min-width: 1400px) { :root { --u: .45px; } }   /* conteneur 1379 px */
@media (min-width: 1800px) { :root { --u: .52px; } }   /* conteneur 1594 px */
@media (min-width: 2200px) { :root { --u: .58px; } }   /* conteneur 1778 px */

@media (max-width: 1240px) {
  /* La photo n'a plus sa largeur de maquette : la rangée ne tient plus trois
     zones, la grille de prix passe dessous quel qu'en soit le nombre. */
  .wk-prices,
  .wk-prices--large {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "photo texte"
      "cols  cols";
  }
  .wk-prices--sans-cols { grid-template-areas: "photo texte"; }
  .wk-story__text { margin-left: clamp(0px, 14vw, 200px); }
  .wk-footer__cols { gap: calc(150 * var(--u)); }
}

/* En dessous de 1024 px la composition paysage de la maquette devient
   illisible : le héro passe au format portrait, celui du cadre « Hero-tel »
   du fichier Figma (268 × 468). Le contenu repasse en flux normal - logotype
   en haut, accroche et boutons aux deux tiers - et le décor (carpe,
   nénuphars) occupe le bas et les angles. */
@media (max-width: 1024px) {
  .wk-hero {
    display: flex;
    align-items: stretch;
    padding-block: 0;
    /* le héro occupe l'écran, sans jamais écraser son contenu */
    min-height: max(540px, calc(100vh - var(--header-h)));
    min-height: max(540px, calc(100svh - var(--header-h)));
    /* Unité du décor : 1 = 1 % de la largeur du cadre portrait. Le cadre fait
       468 de haut pour 268 de large, soit 175 unités : dès que le héro est
       plus court que ça (écran bas, paysage), c'est la hauteur qui donne
       l'unité, sinon le décor déborderait au lieu de se réduire. */
    --deco: min(1vw, calc(max(540px, 100vh - var(--header-h)) / 175));
    --deco: min(1vw, calc(max(540px, 100svh - var(--header-h)) / 175));
  }
  .wk-hero__stage {
    position: relative;
    left: auto; top: auto;
    translate: none;
    width: 100%;
    aspect-ratio: auto;
    /* la scène s'étire ici sur toute la hauteur du héro : plus de bande à
       couvrir, et autant de pixels en moins à calculer pour le shader */
    --eau-debord: 0px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: clamp(.75rem, 4vw, 1.5rem);
    /* le bas de la scène est réservé au décor */
    padding: clamp(1rem, 3.5vh, 2rem) var(--gutter) clamp(150px, 34vh, 340px);
    padding-bottom: clamp(150px, 34svh, 340px);
  }
  .wk-hero__stage > .wk-hero__logo,
  .wk-hero__stage > .wk-hero__pitch,
  .wk-hero__stage > .wk-hero__cta { position: relative; left: auto; top: auto; height: auto; }

  /* centré comme dans le cadre portrait, où il garde les mêmes marges à
     gauche et à droite ; en dessous de 560 px il occupe de toute façon
     toute la gouttière */
  .wk-hero__logo { align-self: center; width: min(100%, 520px); aspect-ratio: 1361.2 / 482.2; }
  .wk-hero__pitch {
    margin-top: auto;                 /* accroche et boutons descendent sur le décor */
    width: auto;
    justify-content: center;
    text-align: center;
    /* en portrait la ligne doit se couper : elle n'a plus la largeur d'une
       scène paysage pour s'étaler */
    white-space: normal;
    font-size: clamp(1rem, 4.4vw, 1.35rem);
  }
  .wk-hero__cta {
    width: clamp(200px, 56%, 320px);
    margin-inline: auto;
    gap: calc(50 * var(--u));
  }
  .wk-hero__cta .wk-btn {
    height: auto;
    min-height: calc(105 * var(--u));
    padding: calc(30 * var(--u)) calc(60 * var(--u));
    --bd-w: calc(5 * var(--u));
    border-radius: var(--r-btn);
    font-size: var(--fs-40);
  }
  /* L'évidé du héro retrouve son contour fin, comme dans le corps de page :
     la règle ci-dessus, plus spécifique, vaut aussi pour lui. */
  .wk-hero__cta .wk-btn--ghost,
  .wk-hero__cta .wk-btn--ghost-light { --bd-w: calc(3 * var(--u)); }
  .wk-kanji { display: none; }        /* l'eau suffit, comme dans la maquette */

  /* Décor : chaque image est ancrée par son centre (left/top = le centre, le
     translate du transform fait le reste). Le translate reste dans `transform`
     car la propriété `translate` est déjà prise par l'animation de flottement.

     Largeurs, positions et transformations viennent du cadre portrait du
     fichier Figma, converties en --deco (1 = 1 % de la largeur du cadre) :
     la composition est rigide, elle ne fait que changer d'échelle d'un
     téléphone à l'autre. Un téléphone est plus élancé que le cadre (2 fois sa
     largeur contre 1,75) : le groupe du haut est donc accroché au bord haut,
     celui du bas au bord bas, et seule l'eau qui les sépare respire. Les
     positionner en % de la hauteur, au contraire, donnait un agencement
     différent sur chaque appareil, la hauteur du héro suivant celle de
     l'écran alors que les tailles suivent la largeur.

        élément    largeur   centre x             centre y
        pad-3       43,2      3,6 hors du bord    49,3 du haut
        pad-1       27,5     27,1 de droite       38,5 du haut
        lotus-2     23,8     12,6 de droite       39,9 du haut
        pad-2       33,5      8,8 de gauche       57,1 du haut
        koï         47,0     23,3 de droite       58,0 du bas
        pad-4       25,0     11,3 de gauche       46,4 du bas
        lotus-1     34,1     19,4 de gauche       30,5 du bas
        pad-5       34,0     39,2 de gauche       14,3 du bas

     Trois feuilles sont retournées dans la maquette (matrices à déterminant
     négatif) : `scaleY(-1)` reproduit le miroir, sans quoi l'échancrure du
     nénuphar pointe du mauvais côté. */
  /* Chaque décor est enveloppé (voir « Calques in water / surface »). Le
     partage est le même qu'en paysage, et pour la même raison : l'enveloppe
     ne prend que ce qui ne tourne pas - position et centrage - et l'image
     prend la rotation. Si l'enveloppe tournait, son ombre tournerait avec
     elle, puisqu'un filtre s'applique avant la transformation de l'élément
     qui le porte ; le centrage, lui, est une simple translation, qui déplace
     l'ombre sans la faire pivoter.

     La hauteur est laissée libre : la table ci-dessus ne donne que des
     largeurs, c'est le rapport de l'image qui décide du reste. */
  .wk-water > .wk-float, .wk-surface > .wk-float {
    height: auto;
    transform: translate(-50%, -50%);
    transform-origin: 50% 50%;
  }
  .wk-float > .wk-deco { height: auto; transform: none; transform-origin: 50% 50%; }
  /* Groupe du haut, accroché au bord haut : la grande feuille (pad-3) déborde
     du bord droit, la petite (pad-1) se glisse sous le logotype, la fleur
     flotte entre les deux. */
  .wk-pad--3   { left: calc(100% +  3.6 * var(--deco)); top: calc(49.3 * var(--deco)); width: calc(43.2 * var(--deco)); }
  .wk-pad--1   { left: calc(100% - 27.1 * var(--deco)); top: calc(38.5 * var(--deco)); width: calc(27.5 * var(--deco)); }
  .wk-lotus--2 { left: calc(100% - 12.6 * var(--deco)); top: calc(39.9 * var(--deco)); width: calc(23.8 * var(--deco)); }
  .wk-pad--2   { left: calc(          8.8 * var(--deco)); top: calc(57.1 * var(--deco)); width: calc(33.5 * var(--deco)); }
  /* Groupe du bas, accroché au bord bas : la carpe monte de la droite, sa
     nageoire passant derrière les boutons, et les feuilles ferment l'angle. */
  .wk-koi      { left: calc(100% - 23.3 * var(--deco)); top: calc(100% - 58   * var(--deco)); width: calc(47   * var(--deco)); }
  .wk-pad--4   { left: calc(         11.3 * var(--deco)); top: calc(100% - 46.4 * var(--deco)); width: calc(25   * var(--deco)); }
  .wk-lotus--1 { left: calc(         19.4 * var(--deco)); top: calc(100% - 30.5 * var(--deco)); width: calc(34.1 * var(--deco)); }
  .wk-pad--5   { left: calc(         39.2 * var(--deco)); top: calc(100% - 14.3 * var(--deco)); width: calc(34   * var(--deco)); }

  /* Rotations du cadre portrait, posées sur l'image (voir juste au dessus).
     Elles écrasent les matrices du cadre paysage, d'où leur place après la
     règle générique qui les annule. */
  .wk-pad--3   > .wk-deco { transform: rotate(-40.7deg)  scaleY(-1); }
  .wk-pad--1   > .wk-deco { transform: rotate(133.5deg); }
  .wk-lotus--2 > .wk-deco { transform: rotate(-163.5deg) scaleY(-1); }
  .wk-pad--2   > .wk-deco { transform: rotate(-136deg); }
  .wk-koi      > .wk-deco { transform: rotate(-156.4deg); }
  .wk-pad--4   > .wk-deco { transform: rotate(-121.5deg) scaleY(-1); }
  .wk-pad--5   > .wk-deco { transform: rotate(69.7deg); }

  /* « Petite mise en bouche » : .wk-taste__inner écrase la largeur héritée de
     .wk-shell, la gouttière disparaissait et le titre, l'accroche et le bouton
     se collaient au bord gauche. */
  .wk-taste__inner { width: min(100% - var(--gutter) * 2, calc(2638 * var(--u))); }
}

@media (max-width: 900px) {
  .wk-nav {
    position: absolute;
    left: 0; right: 0; top: 100%;
    display: grid;
    grid-template-rows: 0fr;
    background: var(--ink);
    box-shadow: 0 18px 30px rgb(0 0 0 / .4);
    transition: grid-template-rows .35s var(--ease);
  }
  .wk-nav > ul { overflow: hidden; flex-direction: column; align-items: stretch; gap: 0; }
  .wk-header.is-open .wk-nav { grid-template-rows: 1fr; }
  .wk-nav a { display: block; padding: .85rem var(--gutter); border-top: 1px solid rgb(255 247 247 / .1); }
  .wk-nav a::after { left: var(--gutter); right: auto; width: 28px; }
  .wk-burger { display: flex; }
  .wk-header__inner { position: relative; }
  .wk-header .wk-btn { margin-left: auto; }

  .wk-steps { grid-template-columns: 1fr; }
  .wk-prices,
  .wk-prices--large {
    grid-template-columns: 1fr;
    grid-template-areas: "photo" "texte" "cols";
  }
  .wk-prices--sans-cols { grid-template-areas: "photo" "texte"; }
  .wk-prices__photo { aspect-ratio: 16 / 10; }

  .wk-story { display: block; min-height: 0; }
  .wk-story__kana { display: none; }
  .wk-collage {
    position: relative;
    inset: auto;
    translate: none;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: calc(100 * var(--u));
    width: min(560px, 100% - var(--gutter) * 2);
    margin: 0 auto calc(150 * var(--u));
  }
  /* La colonne cadre le rectangle plein, pas le fichier : l'image est agrandie
     pour que son rectangle fasse la largeur de la colonne, et son débord
     transparent repasse en marges négatives, donc hors de la grille. Les trois
     rectangles ont ainsi la même taille et la même ligne de base, la photo
     débordant librement par-dessus les gouttières. */
  .wk-collage { align-items: end; }
  .wk-collage__item {
    position: relative; left: auto; top: auto;
    min-width: 0;      /* sinon la colonne 1fr suivrait la largeur propre du fichier */
    max-width: none;
    width:         calc(100% * var(--img-w) / var(--rec-w));
    margin-left:   calc(-100% * var(--rec-x) / var(--rec-w));
    margin-right:  calc(-100% * (var(--img-w) - var(--rec-x) - var(--rec-w)) / var(--rec-w));
    margin-top:    calc(-100% * var(--rec-y) / var(--rec-w));
    margin-bottom: calc(-100% * (var(--img-h) - var(--rec-y) - var(--rec-h)) / var(--rec-w));
  }
  /* Trois rectangles seulement : bambou, fuji, sakura - l'arbre ne sert qu'au
     paysage. Le DOM garde l'ordre de la maquette, `order` fixe celui d'ici. */
  .wk-collage__arbre  { display: none; }
  .wk-collage__bambou { order: 1; }
  .wk-collage__fuji   { order: 2; }
  .wk-collage__sakura { order: 3; }
  .wk-story__text { width: 100%; max-width: 640px; margin-inline: auto; }

  .wk-book__card { grid-template-columns: 1fr; }
  .wk-book__map { min-height: 220px; }
  .wk-polas { grid-template-columns: 1fr; max-width: 380px; margin-inline: auto; }
  /* le temple est un bandeau vertical calé sur la composition paysage : réduit
     à la largeur d'un téléphone il n'est plus qu'une trace étirée */
  .wk-taste__temple { display: none; }
  .wk-footer__top { flex-direction: column; align-items: center; text-align: center; }
  .wk-footer__cols { flex-wrap: wrap; justify-content: center; text-align: left; gap: calc(100 * var(--u)); }
  .wk-footer__bottom { justify-content: center; text-align: center; }
}

@media (max-width: 640px) {
  /* 220 / 267 : le tapis se réduit d'un bloc, lattes et assiettes comprises */
  :root { --belt-k: .824; }

  .wk-header .wk-brand { font-size: calc(80 * var(--u)); }
  .wk-header .wk-btn { padding: .5rem .9rem; min-height: 38px; }

  /* Empilés, les polaroids prenaient toute la largeur de l'écran et écrasaient
     le reste de la section : on les ramène à une taille de vignette. */
  .wk-polas { max-width: 250px; gap: calc(150 * var(--u)); }

  .wk-headrow { flex-direction: column; align-items: flex-start; }
  .wk-headrow__cta { flex-direction: column; align-items: flex-start; }
  .wk-band__inner { flex-direction: column; align-items: flex-start; }
  .wk-foodease { flex-direction: column; align-items: flex-start; }
  .wk-foodease__id { flex-direction: column; align-items: flex-start; }
  .wk-footer__cols { flex-direction: column; text-align: center; }
}

/* --------------------------------------------------------------------------
   15. Animations réduites
   Le tapis continue de tourner - c'est le principe du kaiten - mais tout le
   reste se fige.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .wk-reveal { opacity: 1; translate: none; transition: none; }
  .wk-koi, .wk-pad--1, .wk-pad--2, .wk-pad--3, .wk-pad--4, .wk-pad--5,
  .wk-lotus--1, .wk-lotus--2 { animation: none; }
  .wk-btn:hover, .wk-step:hover, .wk-pola:hover, .wk-collage__item:hover { transform: none; }

  /* Le tapis ralentit d'un seul geste : --belt-cycle est la durée d'un pas,
     donc la vitesse de tout ce qui roule. /script/tapis.js relit ce jeton pour
     en déduire celle des assiettes - lire la vitesse ailleurs, c'était les
     laisser doubler les lattes sur toute machine où le système coupe les
     animations (réglage d'accessibilité de Windows, économiseur de batterie). */
  :root { --belt-cycle: 3.41s; }   /* 1,55 × 2,2 */

  /* On continue de prendre les assiettes : c'est le geste du site, pas un
     effet. Seul son DÉPART change - au lieu de traverser l'écran, l'assiette
     et sa découpe s'effacent là où on les a prises. Un fondu n'est pas un
     mouvement : rien ne se déplace, rien ne glisse sous l'œil.

     Les animations gardent leur nom : le script attend toujours un
     `animationend` pour faire le ménage, sans quoi l'assiette resterait sur
     l'écran pour de bon. Cela vaut aussi pour une assiette déjà en vol quand
     le réglage bascule - l'économiseur de batterie qui s'enclenche pendant la
     chute.

     Le simulateur de /kaiten suit la même règle : l'assiette disparaît du
     tapis et reparaît dans la zone, sans le vol (voir /script/kaiten.js). */
  .wk-plate.is-taken { transform: none; }
  .wk-plate__food.is-eaten { animation: wk-fade-out .2s linear forwards; }
  .wk-plate-drop { animation: wk-fade-out .3s linear forwards; }
  @keyframes wk-fade-out { to { opacity: 0; } }
  /* Le grossissement au survol tombe : il n'annonce plus une prise en vol, il
     ne servait qu'à faire bouger l'assiette sous le pointeur. Le curseur, lui,
     reste une main - l'assiette se prend toujours. */
  .wk-belt__plates .wk-plate:hover { transform: none; }
}
