/* La Decoupe — chrome du microsite. Tokens du design system Umay (static/styles.css), pas de
   palette inventee: --ink, --bone, --paper, --lime, --cobalt, bordures franches, ombres dures. */
:root {
  --ink: #15130f;
  --bone: #f4eedf;
  --paper: #fffaf0;
  --soft: #ebe2cf;
  --lime: #c9ff3b;
  --cobalt: #2457ff;
  --navy: #1d2447;
  --carmin: #a81d2f;
  --r-pill: 999px;
  --r-lg: 20px;
  --r-md: 16px;
  --r-sm: 10px;
  --sh-card: 4px 4px 0 var(--ink);
  --sh-int: 2px 2px 0 var(--ink);
}

* { box-sizing: border-box; }

html { scroll-behavior: auto; }
body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: Archivo, system-ui, sans-serif;
  overscroll-behavior-y: none;
}
/* Papier quadrille de planche anatomique derriere le Geste et la Traversee: le canvas est
   transparent (alpha), le motif vit sur le body et disparait avec la prairie et l'etal. */
body[data-mode="atlas"][data-chapter="geste"],
body[data-mode="atlas"][data-chapter="traversee"] {
  background-image:
    linear-gradient(rgba(21, 19, 15, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(21, 19, 15, .05) 1px, transparent 1px);
  background-size: 56px 56px;
}

@font-face { font-family: Druk; src: url(fonts/DrukHeavy.woff2) format('woff2'); font-display: swap; }
@font-face { font-family: Archivo; src: url(fonts/Archivo-ExtraBold.woff2) format('woff2'); font-weight: 800; font-display: swap; }

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 20; background: var(--ink); color: var(--bone); padding: 12px 18px; text-decoration: none; }
.skip-link:focus { left: 12px; top: 12px; }

/* La scene et le chart sont fixes; #meat-track donne sa hauteur au document, donc au scroll. */
#meat-stage { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }
#meat-chart { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .3s ease; }
#meat-traversal-overlay { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 1; display: none;
  pointer-events: none; opacity: 0; transition: opacity .3s ease; }
#meat-traversal-overlay path { fill: none; stroke: var(--ink); stroke-linecap: round; stroke-linejoin: round; }
#meat-traversal-overlay .traversal-route { stroke-width: 5; stroke-dasharray: 1 19; opacity: .45; }
/* Le meme trace, plein, revele par dasharray au rythme du scroll (voir updateTraversalOverlay). */
#meat-traversal-overlay .traversal-route-done { stroke-width: 5; stroke-linecap: round; }
#meat-traversal-overlay .traversal-ticks { stroke-width: 4; stroke-dasharray: none; }
#meat-traversal-overlay .traversal-arrow { stroke-width: 4; stroke-dasharray: none; }
#meat-traversal-overlay .traversal-piece-leader { stroke-width: 4; stroke-dasharray: 14 12; }
/* La zone survolee, delimitee sur la bete: les empreintes des pieces deja parties. */
#meat-traversal-overlay .traversal-region-holes { stroke-width: 3; stroke-dasharray: 7 6; opacity: .55; }
#meat-traversal-overlay .traversal-shoulder-fill { fill: var(--navy); stroke: none; }
#meat-traversal-overlay .traversal-shoulder-edge { stroke: #f8e9bc; stroke-width: 11; }
#meat-traversal-overlay .traversal-shoulder-ink { stroke: var(--ink); stroke-width: 2.5; }
#meat-etal-labels { position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .3s ease; }
#meat-track { height: 100vh; }

/* Le « bleep » d'intro: chaque piece du chart clignote une fois, de la tete a la queue, pour
   annoncer qu'elle se survole. Pilote par chartBleep(), une fois par entree dans l'atlas. */
@keyframes chart-bleep {
  0% { filter: none; }
  35% { filter: brightness(1.45) saturate(1.35); }
  100% { filter: none; }
}
#meat-chart path.bleep { animation: chart-bleep .46s ease; }

/* Les traits de decoupe sont vectoriels et RUNTIME: ils doivent se redessiner quand on bascule
   FR / US, ce qu'une image ne sait pas faire. La transition porte sur la geometrie SVG. */
#meat-chart rect,
#meat-chart path.cut-shape {
  fill: none; stroke: var(--ink); stroke-width: 2; stroke-dasharray: 7 5;
  transition: x .5s cubic-bezier(.4,0,.2,1), y .5s cubic-bezier(.4,0,.2,1),
              width .5s cubic-bezier(.4,0,.2,1), height .5s cubic-bezier(.4,0,.2,1), opacity .35s ease;
}
/* Les rects des clips de camp sont pilotes au frame par la barre FR / US: la transition
   generique sur x leur faisait suivre le curseur avec 500 ms de retard. */
#meat-chart clipPath rect { transition: none; }
#meat-chart rect.is-internal,
#meat-chart path.cut-shape.is-internal { stroke: var(--carmin); stroke-dasharray: 3 4; }
#meat-chart rect.is-off,
#meat-chart path.cut-shape.is-off { opacity: 0; }
/* Le primal americain est un trait de scie, pas un contour de muscle: plein, continu, plus epais,
   et il partage son bord avec le voisin. Le pointille servait a dire « ce morceau est la-dedans »;
   ici le trait dit « on coupe ici », ce n'est pas la meme phrase. */
#meat-chart .cut-shape.is-primal { stroke-dasharray: none; stroke-width: 3; stroke: var(--carmin); fill: rgba(122, 26, 34, .07); }
/* Le nom doit tenir DANS son bloc: « SHORT LOIN » au lettrage francais debordait de son primal et
   se faisait masquer. Ici c'est le texte qui se resserre, jamais le mot qui disparait. */
#meat-chart text.is-primal { font-size: 10px; letter-spacing: .06em; }
#meat-chart text {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  fill: var(--ink); paint-order: stroke; stroke: var(--paper); stroke-width: 4px;
  transition: x .5s cubic-bezier(.4,0,.2,1), y .5s cubic-bezier(.4,0,.2,1);
}
#meat-chart line.chart-leader {
  stroke: var(--ink); stroke-width: 1.5; opacity: .78; pointer-events: none;
  transition: x1 .5s cubic-bezier(.4,0,.2,1), y1 .5s cubic-bezier(.4,0,.2,1),
              x2 .5s cubic-bezier(.4,0,.2,1), y2 .5s cubic-bezier(.4,0,.2,1);
}
#meat-chart text.is-callout { font-size: 12px; letter-spacing: .12em; }
#meat-chart path.cow-template {
  /* Le gabarit reste dans le DOM et fournit le clip de placement, mais ne pollue pas la
     composition finale avec un second contour pointille. Pour le diagnostic visuel, on peut
     temporairement remettre opacity: .82 dans l'inspecteur. */
  fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: 4 5;
  opacity: 0; pointer-events: none;
}
#meat-chart .chart-profile-base {
  opacity: .72;
  pointer-events: none;
}
#meat-chart path.split-region {
  stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: none;
  /* Le chart est une couche de lecture, pas la cible DOM du clic: hoverTarget() teste le
     remplissage SVG puis laisse le click remonter au canvas qui possede la fiche. */
  pointer-events: none; transition: opacity .25s ease, filter .25s ease;
}
#meat-chart path.split-region:hover { filter: brightness(1.08) saturate(1.08); }
#meat-chart path.split-region.is-hovered {
  filter: brightness(1.1) saturate(1.12) drop-shadow(0 3px 0 rgba(21,19,15,.28));
  stroke-width: 4;
}
/* Le primal americain du First Cut est un aplat plein, comme la piece francaise: c'est la meme
   planche, pas un calque de diagnostic. Le trait entre deux blocs est le coup de scie: continu,
   epais, partage. Ses bords exterieurs debordent la bete et disparaissent sous le clip. */
#meat-chart path.split-primal {
  stroke: var(--ink); stroke-width: 3.5; stroke-dasharray: none;
  pointer-events: none; transition: opacity .25s ease;
}
#meat-chart text.split-primal-label {
  font-size: clamp(9px, .82vw, 13px); letter-spacing: .06em; pointer-events: none;
}
/* Un nom dont le camp est passe de l'autre cote de la barre se fond, il ne clignote pas. Les
   etiquettes gardent au passage la transition de placement des autres textes du chart. */
#meat-chart [data-split-fx] {
  transition: opacity .3s ease, x .5s cubic-bezier(.4,0,.2,1), y .5s cubic-bezier(.4,0,.2,1);
}
#meat-chart line.chart-split-divider {
  stroke: var(--ink); stroke-width: 2; stroke-dasharray: 8 8; opacity: .9;
  pointer-events: none;
}
#meat-chart text.split-callout {
  font-size: clamp(10px, 1.05vw, 15px); font-weight: 800; letter-spacing: .14em;
  pointer-events: none;
}
#meat-chart rect.split-callout-box {
  fill: var(--paper); stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: none; pointer-events: none;
}
#meat-chart path.split-callout-line {
  fill: none; stroke: var(--ink); stroke-width: 1.5; opacity: .9; pointer-events: none;
}
#meat-chart circle.split-callout-dot { fill: var(--ink); pointer-events: none; }

/* Les noms de l'étal sont des tags runtime : ils suivent l'anneau, mais restent hors de la carte
   pour que le dessin de viande demeure lisible. La largeur est volontairement contrainte : sur
   mobile le nom passe sur plusieurs lignes au lieu de devenir une micro-étiquette horizontale. */
.etal-label {
  position: absolute; width: var(--etal-label-width, 118px); min-height: 22px;
  transform: translate(-50%, 0); padding: 4px 6px 5px;
  border: 2px solid var(--ink); border-radius: 3px;
  background: var(--paper); color: var(--ink); box-shadow: 3px 3px 0 rgba(21,19,15,.32);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: clamp(8px, .72vw, 11px); font-weight: 800; line-height: 1.08;
  letter-spacing: .035em; text-align: center; text-transform: uppercase;
  overflow-wrap: anywhere; opacity: 0; transition: left .18s ease, top .18s ease, opacity .18s ease;
}
.etal-label::before {
  content: ''; position: absolute; left: 50%; bottom: 100%; width: 2px; height: 12px;
  background: var(--ink); opacity: .7;
}
.etal-label.is-visible { opacity: 1; }

/* Les noms de la Traversee reprennent exactement le tag kraft de l'Etal: meme papier, meme trait,
   meme trait d'attache. Ils ne vivent que le temps de la fenetre d'une piece, donc leur conteneur
   est separe de celui de l'Etal, qui se fond avec son chapitre. */
#meat-cut-labels { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
.cut-label {
  position: absolute; width: var(--cut-label-width, 132px);
  transform: translate(-50%, 0); padding: 5px 7px 6px;
  border: 2px solid var(--ink); border-radius: 3px;
  background: var(--paper); color: var(--ink); box-shadow: 3px 3px 0 rgba(21,19,15,.32);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: clamp(9px, .78vw, 12px); font-weight: 800; line-height: 1.1;
  letter-spacing: .04em; text-align: center; text-transform: uppercase;
  overflow-wrap: anywhere; opacity: 0; transition: opacity .16s ease;
}
.cut-label::before {
  content: ''; position: absolute; left: 50%; bottom: 100%; width: 2px; height: 12px;
  background: var(--ink); opacity: .7;
}

/* Le survol de la Traversee: la silhouette fantome a l'emplacement anatomique d'une piece encore
   attachee, et le pointille qui relie une piece rangee au trou d'ou elle vient. */
#meat-traversal-overlay .traversal-ghost {
  fill: rgba(29, 36, 71, .16); stroke: var(--navy); stroke-width: 2.5; stroke-dasharray: 7 6;
}
#meat-traversal-overlay .traversal-hover-hole {
  fill: rgba(29, 36, 71, .28); stroke: var(--navy); stroke-width: 2.5;
}
#meat-traversal-overlay .traversal-hover-leader {
  stroke: var(--navy); stroke-width: 4; stroke-dasharray: 12 10;
}
/* La carte de survol de la Traversee porte un descriptif, pas seulement un nom: elle ne peut pas
   rester sur une ligne. Elle garde la pastille encre du hint, elle gagne une largeur. */
body[data-mode="atlas"][data-chapter="traversee"] .hint {
  white-space: normal; width: max-content; max-width: min(268px, 62vw); text-align: left;
  padding: 11px 14px 12px; border-radius: 14px; line-height: 1.35; letter-spacing: .04em;
}
body[data-mode="atlas"][data-chapter="traversee"] .hint b {
  margin-bottom: 5px; font-size: 19px; line-height: 1.18;
}

.meat-world { position: fixed; inset: 0; z-index: 2; pointer-events: none; display: flex; flex-direction: column; }
.meat-world a, .meat-world button, .meat-world select { pointer-events: auto; }

/* Chrome de scène : même grammaire que le design system Umay — papier bone, trait ink,
   rayon contenu, ombre franche. Un seul bouton, le retour à l'app. */
.scene-rail { position: fixed; z-index: 5; left: 14px; top: 24px; }
.rail-button { width: 48px; height: 48px; display: grid; place-items: center; padding: 9px;
  border: 2px solid var(--ink); border-radius: var(--r-md); background: var(--paper); color: var(--ink);
  box-shadow: var(--sh-int); cursor: pointer; transition: transform .14s ease, background .14s ease; }
.rail-button:hover, .rail-button:focus-visible { transform: translate(-2px, -2px); background: var(--lime); }
.rail-button svg { width: 27px; height: 27px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
/* Bouton son: haut-parleur barre tant que le son est coupe, ondes quand il joue. */
#meat-sound[aria-pressed="true"] .sound-slash { display: none; }
#meat-sound:not([aria-pressed="true"]) .sound-wave { display: none; }

.chapter-panel { position: fixed; z-index: 4; left: 84px; top: 50%; width: min(270px, calc(100vw - 110px));
  transform: translateY(-50%); pointer-events: none; }
/* Scrollytelling plein ecran: seul le bandeau de l'Etal subsiste, ses onglets sont la porte
   des abats. Les colonnes du Geste et de la Traversee ont ete retirees du HTML. */
.chapter-panel-view { display: none; pointer-events: auto; }
/* display: flex et pas block: le bandeau est UNE ligne (titre, pastilles, porte des abats);
   en block, les pastilles et Abats s'empilaient et debordaient sur la scene. */
body[data-mode="atlas"][data-chapter="etal"] .chapter-panel-view[data-panel-chapter="etal"] { display: flex; }
.chapter-kicker { display: block; margin-bottom: 12px; font: 900 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: .14em; text-transform: uppercase; }
.chapter-panel h2 { margin: 0; font: 400 clamp(36px, 5vw, 68px)/.84 Druk, Archivo, sans-serif; letter-spacing: .01em; text-transform: uppercase; }
.primary, .secondary, .btn-ghost { min-height: 42px; border: 2px solid var(--ink); border-radius: var(--r-pill); padding: 10px 17px;
  font: inherit; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; cursor: pointer; text-decoration: none;
  box-shadow: var(--sh-int); transition: transform .14s ease, box-shadow .14s ease; }
.primary { background: var(--lime); color: var(--ink); }
.secondary { background: var(--cobalt); color: var(--paper); }
.btn-ghost { background: var(--paper); color: var(--ink); }
.primary:hover, .secondary:hover, .btn-ghost:hover, .primary:focus-visible, .secondary:focus-visible, .btn-ghost:focus-visible {
  transform: translate(-2px, -2px); box-shadow: 4px 4px 0 var(--ink); }
/* Bandeau de l'Etal, sans chrome: le titre porte la scene, les pastilles restent petites,
   la porte des abats est un simple cartouche mono. Pas de boite, la bande bone de la page
   au-dessus du cadre-vitrine suffit. */
/* Pas de display ici: c'est la regle de chapitre (etal -> flex) qui allume la vue, sinon
   cette classe, plus tardive a meme specificite, battait le display:none des autres chapitres. */
.counter-panel { align-items: center; gap: 26px; width: 100%; }
.counter-panel h2 { flex: 0 0 auto; font-size: clamp(32px, 4vw, 58px); }
.counter-abats {
  flex: 0 0 auto; margin-left: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  border: 2px solid var(--ink); border-radius: 999px; padding: 7px 14px;
  background: var(--paper); color: var(--ink); cursor: pointer;
}
.counter-abats:hover, .counter-abats:focus-visible { background: var(--lime); }

.masthead { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 20px 14px 84px; }
.masthead .wordmark img { width: 84px; height: auto; display: block; }
body[data-mode="atlas"] .masthead .wordmark { visibility: hidden; }
body[data-mode="atlas"] .masthead .tools { display: none; }
.tools { display: flex; align-items: center; gap: 10px; }
.badge, .back, .toggle button {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  border: 2px solid var(--ink); border-radius: 999px; padding: 6px 12px; background: var(--paper); color: var(--ink);
}
.back { cursor: pointer; font-weight: 700; }
.toggle { display: flex; gap: 4px; }
.toggle button { cursor: pointer; }
.toggle button[aria-pressed="true"] { background: var(--lime); }

/* Le retour et la bascule n'existent que la ou ils veulent dire quelque chose. */
body[data-mode="hub"] .back, body[data-mode="hub"] .toggle { display: none; }
body[data-toggle="off"] .toggle { opacity: 0; pointer-events: none; }
.toggle { transition: opacity .3s ease; }

.title-block { margin-left: 84px; padding: 4vh 20px 0 0; max-width: 760px; transition: opacity .4s ease, transform .4s ease; }
/* The column is text over the scene: only its buttons take the pointer, so an animal next to a
   line of text stays hoverable and clickable through the empty part of the block. */
.title-block { pointer-events: none; }
.title-block .roster button { pointer-events: auto; }
h1 { font-family: Druk, Archivo, sans-serif; font-size: clamp(56px, 13vw, 168px); line-height: .84; letter-spacing: -.01em; margin: 0; text-transform: uppercase; }
.lede { margin: 14px 0 0; font-size: clamp(15px, 2.2vw, 20px); max-width: 30ch; font-weight: 500; }

/* Largeur bornee sur la colonne de texte: en pleine largeur, la troisieme pastille venait se
   poser sur la tete de Marguerite. */
.roster { margin: 22px 0 0; max-width: 430px; display: flex; flex-wrap: wrap; gap: 10px; }
.roster button {
  font: inherit; font-weight: 800; font-size: 13px;
  border: 2px solid var(--ink); border-radius: 999px; padding: 10px 16px;
  background: var(--paper); color: var(--ink); cursor: pointer; box-shadow: 3px 3px 0 var(--ink);
  transition: transform .12s ease, box-shadow .12s ease;
}
.roster button:hover, .roster button:focus-visible { transform: translate(-2px, -2px); box-shadow: 5px 5px 0 var(--ink); }
.roster button[disabled] { opacity: .45; cursor: default; box-shadow: none; transform: none; }
.roster button.is-live { background: var(--lime); }

/* Passe la prairie, le titre et le roster s'effacent: la traversee n'a pas besoin d'eux. */
body[data-mode="atlas"] .title-block { opacity: 0; transform: translateY(-12px); pointer-events: none; }
body[data-mode="atlas"][data-chapter="prairie"] .title-block { opacity: 1; transform: none; }
body[data-mode="atlas"]:not([data-chapter="prairie"]) .title-block { opacity: 0 !important; transform: translateY(-12px) !important; }
/* The roster is visually gone outside the prairie, so its generated live buttons must not leave
   invisible hit targets over the Traversée gallery on touch screens. */
body[data-mode="atlas"]:not([data-chapter="prairie"]) .title-block .roster,
body[data-mode="atlas"]:not([data-chapter="prairie"]) .title-block .roster button {
  visibility: hidden; pointer-events: none;
}

/* The Counter quitte la colonne de chapitre et devient la barre de titre de la référence V9. */
body[data-mode="atlas"][data-chapter="etal"] .chapter-panel { left: 14px; right: 14px; top: 14px; width: auto; transform: none; }
body[data-mode="atlas"] .scene-rail { display: none; }
body[data-mode="atlas"][data-chapter="geste"] .chapter-panel { display: none; }
body[data-mode="atlas"][data-chapter="geste"] .gesture-hero { display: block; }
body[data-mode="atlas"][data-chapter="geste"] .masthead,
body[data-mode="atlas"][data-chapter="geste"] .title-block { display: none; }
body[data-mode="atlas"]:not([data-chapter="etal"]):not([data-chapter="geste"]) .chapter-panel { left: 32px; }

/* The Counter is a framed shop-window, not a full-bleed canvas. The page-specific stylesheet
   carries its own design tokens, so this chrome remains faithful even when the global shell is
   not loaded by the microsite route. */
body[data-mode="atlas"][data-chapter="etal"] .chapter-panel {
  left: 13px;
  right: 13px;
  top: 13px;
}
body[data-mode="atlas"][data-chapter="etal"]::after {
  content: '';
  position: fixed;
  z-index: 3;
  inset: 13px 13px clamp(82px, 14vh, 132px);
  border: 3px solid var(--ink);
  border-radius: var(--r-lg);
  pointer-events: none;
}
body[data-mode="atlas"][data-chapter="etal"] #meat-stage {
  clip-path: inset(clamp(58px, 10vh, 104px) 8px clamp(82px, 14vh, 132px) 8px round 0 0 var(--r-lg) var(--r-lg));
}
body[data-mode="atlas"][data-chapter="etal"] #meat-etal-labels {
  clip-path: inset(clamp(58px, 10vh, 104px) 8px clamp(82px, 14vh, 132px) 8px round 0 0 var(--r-lg) var(--r-lg));
}
body[data-mode="atlas"][data-chapter="etal"] .counter-panel {
  padding: 9px 38px 0 49px;
}
body[data-mode="atlas"][data-chapter="etal"] .counter-panel h2 {
  font-size: clamp(42px, 5vw, 78px);
  line-height: .82;
  transform: translateY(4px) scaleX(1.09);
  transform-origin: left top;
  margin-right: clamp(8px, 2vw, 40px);
}
/* « Qu'est-ce que j'en fais ? »: la rangee de gestes de cuisson du bandeau de l'Etal. */
.counter-cook { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.counter-cook-kicker {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  margin-right: 3px;
}
.counter-cook button {
  border: 2px solid var(--ink); border-radius: var(--r-pill); background: var(--paper);
  color: var(--ink); padding: 6px 12px; font: inherit; font-size: 11px; font-weight: 900;
  letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
}
.counter-cook button.is-active, .counter-cook button:hover, .counter-cook button:focus-visible {
  background: var(--lime);
}

/* Le boucher: tanuki en canotier, bulle au-dessus de la tete, coin bas gauche de l'etal.
   Purement commentatif: aucun pointeur ne lui appartient. */
.etal-barker {
  position: fixed; z-index: 4; left: 22px; bottom: 16px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 9px;
  pointer-events: none; opacity: 0; transform: translateY(12px);
  transition: opacity .3s ease, transform .3s ease;
}
body[data-mode="atlas"][data-chapter="etal"] .etal-barker.is-on { opacity: 1; transform: none; }
.etal-barker img { width: 112px; height: auto; filter: drop-shadow(2px 3px 0 rgba(21, 19, 15, .25)); }
.etal-barker-bubble {
  position: relative; margin: 0 0 0 6px; max-width: 300px;
  border: 2px solid var(--ink); border-radius: var(--r-md);
  background: var(--paper); box-shadow: var(--sh-card);
  padding: 10px 13px; font-size: 13px; font-weight: 800; line-height: 1.35;
}
.etal-barker-bubble::after {
  content: ''; position: absolute; left: 34px; bottom: -8px; width: 13px; height: 13px;
  background: var(--paper); border-right: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
  transform: rotate(45deg);
}

/* Counter labels stay quiet until a cut is actually hovered. Once revealed, they use the same
   paper/ink badge grammar as the rest of Umay instead of becoming a second layer of signage. */
body[data-mode="atlas"][data-chapter="etal"] .etal-label {
  min-height: 22px;
  padding: 4px 7px 5px;
  border-width: 2px;
  border-radius: var(--r-sm);
  background: var(--paper);
  color: var(--ink);
  font-size: clamp(8px, .72vw, 11px);
  line-height: 1.08;
  box-shadow: var(--sh-int);
  opacity: 0;
  transform: translate(-50%, 0) scale(.94);
  transition: opacity .16s ease, transform .16s ease;
}
body[data-mode="atlas"][data-chapter="etal"] .etal-label.is-visible.is-hovered {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}
body[data-mode="atlas"][data-chapter="etal"] .hint { display: none; }

.gesture-hero { position: fixed; z-index: 3; inset: 22px 8vw auto; display: none; pointer-events: none; }
.gesture-hero h2 { margin: 0; text-align: center; font: 400 clamp(42px, 8.6vw, 140px)/.82 Druk, Archivo, sans-serif;
  letter-spacing: .005em; text-transform: uppercase; transform: scaleX(1.30); transform-origin: center top; }
/* Ces deux commandes suivent les pastilles du panneau étal, pas leur propre échelle: un bouton
   de 84 px de haut et 26 px de texte n'appartient à aucun écran du design system. */
.gesture-actions { position: fixed; left: 50%; bottom: 44px; transform: translateX(-50%); display: flex; align-items: center;
  gap: 12px; pointer-events: auto; }
.gesture-actions .secondary { min-width: 0; min-height: 0; padding: 8px 14px; font-size: 12px; letter-spacing: .08em; }
/* Le toggle est le segctl canonique (styles.css): conteneur 4 px, crans pilule sans min-width.
   Les cotes maison (72 px de large, padding 22 px) le faisaient deux fois plus gros que l'app. */
.gesture-toggle { display: inline-flex; gap: 4px; padding: 4px; border: 2px solid var(--ink); border-radius: var(--r-pill); background: var(--paper); box-shadow: var(--sh-int); }
.gesture-toggle button { border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink); padding: 6px 13px; font: inherit;
  font-size: 13px; font-weight: 900; letter-spacing: .08em; cursor: pointer; }
.gesture-toggle button[aria-pressed="true"] { background: var(--lime); box-shadow: inset 0 0 0 2px var(--ink); }

/* La barre FR / US. La colonne est posee au pixel par le runtime (left/top/height), centree sur
   le trait; elle ne capte rien, pour qu'un glissement du doigt le long de la bete continue de
   faire defiler la page. */
.split-bar { position: fixed; z-index: 4; width: 0; pointer-events: none; }
.split-bar-stem {
  position: absolute; left: -2px; top: 0; width: 4px; height: 100%;
  background: var(--ink); border-radius: 2px;
}
/* La poignee est la seule cible: 44 px de large, autant de haut, et le doigt qui la tient ne
   defile plus (touch-action). */
.split-bar-grip {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 52px; box-sizing: border-box;
  border: 3px solid var(--ink); border-radius: var(--r-pill);
  background: var(--paper); box-shadow: var(--sh-int);
  cursor: col-resize; pointer-events: auto; touch-action: none;
}
/* Les deux traits de prise: c'est ce qui dit « ca se saisit » sans ajouter d'icone. */
.split-bar-grip::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 12px; height: 18px;
  border-left: 3px solid var(--ink); border-right: 3px solid var(--ink);
}
.split-bar-grip:focus-visible { outline: 3px solid var(--carmin); outline-offset: 3px; }
/* Le halo d'invitation: la poignee respire tant que personne ne l'a jamais saisie. */
.split-bar-grip.is-virgin::after { content: ""; position: absolute; inset: -9px;
  border-radius: var(--r-pill); border: 3px solid var(--lime);
  animation: grip-pulse 2.2s ease-out infinite; pointer-events: none; }
@keyframes grip-pulse {
  0% { opacity: .9; transform: scale(.88); }
  60% { opacity: 0; transform: scale(1.22); }
  100% { opacity: 0; transform: scale(1.22); }
}
/* L'intro revele chaque piece a son bleep: laisser l'opacite inline s'animer. */
path.split-region, path.split-primal { transition: opacity .18s ease; }

/* Le bloc d'explication: une phrase par camp, celle du camp dominant sous la barre. Il se pose
   dans la bande libre au-dessus des commandes, jamais sur la bete. */
.split-explain {
  position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%);
  /* Au-dessus de la barre (z 4): la carte « Et ailleurs ? » vit dans ce contexte et la barre,
     plus tard dans le DOM, passait sinon a travers l'image. */
  z-index: 5; width: min(880px, 84vw); display: flex; gap: 10px; pointer-events: none;
}
.split-explain-line {
  flex: 1; margin: 0; padding: 9px 13px;
  border: 2px solid var(--ink); border-radius: var(--r-sm);
  background: var(--paper); box-shadow: var(--sh-int);
  font-family: Archivo, system-ui, sans-serif; font-size: 14px; line-height: 1.32;
  transition: opacity .3s ease;
}
.split-explain[data-side="fr"] .split-explain-line[data-explain="second"],
.split-explain[data-side="second"] .split-explain-line[data-explain="fr"] { display: none; }
.split-explain[data-side="fr"] .split-explain-line[data-explain="fr"],
.split-explain[data-side="second"] .split-explain-line[data-explain="second"] { flex: 0 1 auto; margin: 0 auto; }

/* « Et ailleurs ? » — la note de bas de page du First Cut: trois drapeaux, une carte d'ambiance
   au survol. Le bloc reprend la grammaire des lignes d'explication (bordure ink, coin r-sm) mais
   sur fond bone: il commente, il ne rivalise pas. Le parent est pointer-events:none. */
.split-elsewhere {
  flex: 0 0 auto; display: flex; align-items: center; gap: 7px; padding: 6px 11px;
  border: 2px solid var(--ink); border-radius: var(--r-sm);
  background: var(--bone); box-shadow: var(--sh-int); pointer-events: auto;
}
.split-elsewhere-kicker {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  white-space: nowrap;
}
.split-elsewhere-item { position: relative; display: inline-flex; }
.split-elsewhere-item > button {
  width: 30px; height: 30px; padding: 0; border: 2px solid var(--ink); border-radius: 50%;
  background: var(--paper); font-size: 15px; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
}
.split-elsewhere-item > button:hover, .split-elsewhere-item:focus-within > button {
  background: var(--lime);
}
.split-elsewhere-card {
  position: absolute; right: -12px; bottom: calc(100% + 14px); z-index: 6;
  width: 264px; margin: 0; overflow: hidden;
  border: 2px solid var(--ink); border-radius: var(--r-md);
  background: var(--paper); box-shadow: var(--sh-card);
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
  pointer-events: none;
}
.split-elsewhere-item:hover .split-elsewhere-card,
.split-elsewhere-item:focus-within .split-elsewhere-card {
  opacity: 1; visibility: visible; transform: none;
}
.split-elsewhere-card img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.split-elsewhere-card figcaption { display: grid; gap: 4px; padding: 10px 12px 12px; }
.split-elsewhere-card b { font-size: 13px; letter-spacing: .02em; }
.split-elsewhere-card span { font-size: 12px; line-height: 1.35; }
/* Les decoupes stars du pays (2-3 max): une vignette generee par piece, nom dessous. */
.split-elsewhere-card .split-elsewhere-cuts { display: flex; gap: 6px; margin-top: 5px; }
.split-elsewhere-cut { flex: 1 1 0; min-width: 0; display: grid; gap: 3px; align-content: start; }
.split-elsewhere-cut img {
  display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border: 2px solid var(--ink); border-radius: var(--r-sm);
}
.split-elsewhere-cut i {
  font-style: normal;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 9px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  line-height: 1.2; text-align: center;
}

/* Le rail de chapitres se lit par-dessus la scene, donc par-dessus tout: prairie verte, mur
   carmin de l'etal. Sans fond, son encre disparaissait sur le lambris. */
.chapters { list-style: none; margin: auto 0 0; padding: 26px 20px 22px; display: flex; gap: 18px;
  opacity: 0; transition: opacity .4s ease;
  background: linear-gradient(to top, var(--paper) 62%, rgba(244, 238, 223, 0)); }
body[data-mode="atlas"] .chapters { opacity: 1; }
.chapters li { font-family: ui-monospace, Menlo, monospace; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; opacity: .32; padding-top: 8px; border-top: 3px solid var(--ink); flex: 1; max-width: 190px; }
body[data-chapter="prairie"] li[data-chapter="prairie"],
body[data-chapter="geste"] li[data-chapter="geste"],
body[data-chapter="traversee"] li[data-chapter="traversee"],
body[data-chapter="etal"] li[data-chapter="etal"] { opacity: 1; border-color: var(--carmin); }
/* La progression reste pilotée par le scroll; son ancien bandeau n'est pas le langage des
   écrans-cibles. Le rail latéral et les panneaux de chapitre portent désormais cette information. */
.chapters { display: none; }

.scroll-cue { position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%); margin: 0;
  font-family: ui-monospace, Menlo, monospace; font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  opacity: 0; transition: opacity .4s ease; }
body[data-mode="atlas"][data-chapter="prairie"] .scroll-cue { opacity: .55; }

/* Rail des régions « Head to Tail » : pur DOM, alimenté par state.catalog.regions et la
   progression de la traversée. Le runtime le remplit, le CSS seul décide de sa présence — il
   n'existe à l'écran que pendant la traversée de l'atlas. Passif: pointer-events à none pour que
   la scène garde tous ses gestes, et seule la région active reçoit un marquage. */
.region-rail { position: fixed; z-index: 4; right: 28px; top: 18%; bottom: 27%;
  display: none; flex-direction: column; justify-content: space-between; width: 142px; padding: 0;
  pointer-events: none; }
body[data-mode="atlas"][data-chapter="traversee"] .region-rail { display: flex; }
.region-rail::before { content: ''; position: absolute; left: 15px; top: 0; bottom: 0; width: 2px; background: var(--ink); }
/* La pilule FR / US en tete du rail: seule commande cliquable du bloc (le rail reste passif). */
.region-rail-swap { position: absolute; left: -3px; top: -58px; display: flex; gap: 4px; pointer-events: auto; }
.region-rail-swap button { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; font-weight: 800; letter-spacing: .07em; padding: 7px 11px;
  border: 2px solid var(--ink); border-radius: var(--r-pill); background: var(--paper);
  color: var(--ink); cursor: pointer; box-shadow: var(--sh-int); }
.region-rail-swap button[aria-pressed="true"] { background: var(--lime); }
.region-rail-item { position: relative; display: block; padding: 8px 0 8px 52px; border: 0; border-radius: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; opacity: .72; }
.region-rail-item::before { content: ''; position: absolute; left: 5px; top: 50%; width: 20px; height: 20px;
  transform: translateY(-50%); border: 2px solid var(--ink); border-radius: 50%; background: var(--bone); }
.region-rail-item.is-active { opacity: 1; }
.region-rail-item.is-active::before { background: var(--lime); }
.cut-picker { position: fixed; z-index: 4; right: 20px; bottom: 20px; display: grid; gap: 5px;
  width: min(300px, calc(100vw - 40px)); padding: 10px 12px 12px; background: var(--paper);
  border: 2px solid var(--ink); box-shadow: 4px 4px 0 var(--ink); }
.cut-picker[hidden] { display: none; }
/* Le selecteur sert le clavier: au doigt et a la souris la scene se touche directement, il ne
   s'affiche donc qu'au focus CLAVIER. :focus-within seul le revelait a la fermeture d'une fiche
   ouverte au doigt, puisque le focus y revient. */
.cut-picker:not(:has(select:focus-visible)) { clip-path: inset(50%); width: 1px; height: 1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap; }
.cut-picker label { font-family: ui-monospace, Menlo, monospace; font-size: 10px;
  font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.cut-picker select { min-height: 42px; width: 100%; border: 2px solid var(--ink); border-radius: 0;
  padding: 7px 34px 7px 9px; background: var(--bone); color: var(--ink); font: 700 14px/1.2 Archivo, sans-serif; }

/* Etiquette qui suit l'objet survole. Positionnee par le runtime depuis la projection 3D. */
.hint {
  position: fixed; z-index: 5; pointer-events: none; transform: translate(-50%, -100%);
  background: var(--ink); color: var(--bone);
  font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 7px 12px; border-radius: 999px; white-space: nowrap;
}
.hint b { display: block; font-family: Druk, sans-serif; font-size: 17px; line-height: 1.12;
  letter-spacing: 0; text-transform: none; } /* Druk deborde de sa boite sans interligne explicite */

/* Fiche piece. Composants du design system: pastilles 1-5, chips de cuisson, cartes recettes. */
.sheet {
  position: fixed; z-index: 6; right: 0; bottom: 0; top: 0; width: min(440px, 100%);
  overflow: auto; background: var(--paper); border-left: 3px solid var(--ink);
  padding: 20px 22px 40px; box-shadow: -8px 0 0 rgba(21,19,15,.08);
}
.sheet header { position: relative; padding-right: 40px; }
.sheet .badge { display: inline-block; border-width: 2px; margin-bottom: 10px; }
/* Le morceau lui-meme, en tete de sa fiche. Fond bone plutot que transparent: le papier decoupe
   se lit sur une page, pas sur du vide. */
.sheet .piece { display: block; width: 100%; max-height: 210px; object-fit: contain;
  margin: 14px 0 4px; background: var(--bone); border: 3px solid var(--ink); border-radius: 18px;
  padding: 10px; }
.sheet h2 { font-family: Druk, sans-serif; font-size: clamp(30px, 6vw, 44px); line-height: .9; margin: 0; text-transform: uppercase; }
.sheet-grip { display: none; position: relative; width: 72px; height: 22px; margin: -10px auto 8px;
  border: 0; background: transparent; cursor: pointer; }
.sheet-grip::before { content: ''; position: absolute; left: 50%; top: 50%; width: 44px; height: 5px;
  border-radius: 3px; background: var(--ink); opacity: .35; transform: translate(-50%, -50%); }
.sheet-grip::after { content: ''; position: absolute; inset: -11px 0; }
.sheet-close { position: absolute; top: -4px; right: -6px; font-size: 28px; line-height: 1; background: none; border: 0; cursor: pointer; color: var(--ink); }
.story { font-size: 15px; line-height: 1.5; margin: 16px 0 0; }
.attrs { display: grid; grid-template-columns: auto 1fr; gap: 8px 14px; align-items: center; margin: 22px 0 0; }
.attrs dt { font-family: ui-monospace, Menlo, monospace; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
.attrs dd { margin: 0; }
.dots { display: inline-flex; gap: 5px; }
.dots i { width: 12px; height: 12px; border: 2px solid var(--ink); border-radius: 50%; }
.dots i.on { background: var(--ink); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 20px 0 0; }
.chip { border: 2px solid var(--ink); border-radius: 999px; padding: 6px 12px; font-size: 12px; font-weight: 700; text-transform: capitalize; }
/* Pont FR <-> US et taille reelle : meme grille que les attributs. La piece de l'autre tradition
   ouvre sa fiche, donc bordure cobalt pour la distinguer d'une chip de cuisson, qui ne se clique pas. */
.bridge .chips { margin: 0; }
/* La chip pont se clique, contrairement aux chips de cuisson: elle tient donc le plancher tactile
   de 44 px comme les actions primaires, au lieu des 30 px herites du padding de .chip. */
.chip-bridge { font: inherit; font-size: 12px; font-weight: 700; text-transform: none;
  min-height: 44px; display: grid; place-items: center;
  border-color: var(--cobalt); color: var(--cobalt); background: var(--paper); cursor: pointer; }
.chip-bridge:hover, .chip-bridge:focus-visible { background: var(--cobalt); color: var(--paper); }
/* L'emballage: le paquet kraft qui se plie sur la piece cliquee a l'etal, ficelle croisee,
   tampon, puis file vers la fiche. Purement decoratif, retire du DOM a la fin. */
.wrap-pack { position: fixed; z-index: 6; width: 128px; height: 96px;
  transform: translate(-50%, -50%); pointer-events: none; }
.wrap-pack i, .wrap-pack b { position: absolute; display: block; }
.wrap-paper { inset: 0;
  background: #d9bd8b linear-gradient(115deg, rgba(21, 19, 15, .07) 0 18%, transparent 18% 56%, rgba(21, 19, 15, .09) 56% 100%);
  border: 2px solid var(--ink); border-radius: 9px; box-shadow: 4px 4px 0 rgba(21, 19, 15, .28);
  animation: wrap-paper .2s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes wrap-paper {
  from { transform: scale(.25) rotate(-14deg); opacity: 0; }
  to { transform: scale(1) rotate(-2deg); opacity: 1; }
}
.wrap-string { inset: 0; }
.wrap-string::before, .wrap-string::after { content: ""; position: absolute; background: var(--ink); }
.wrap-string::before { left: -4px; right: -4px; top: 50%; height: 3px;
  transform: scaleX(0); animation: wrap-string .14s .20s ease-out both; }
.wrap-string::after { top: -4px; bottom: -4px; left: 50%; width: 3px;
  transform: scaleY(0); animation: wrap-string-v .14s .28s ease-out both; }
@keyframes wrap-string { to { transform: scaleX(1); } }
@keyframes wrap-string-v { to { transform: scaleY(1); } }
.wrap-stamp { right: 10px; bottom: 8px; padding: 9px 7px; border: 3px double #a81d2f;
  border-radius: 50%; color: #a81d2f; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  animation: wrap-stamp .18s .36s cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes wrap-stamp {
  from { transform: scale(2.1) rotate(4deg); opacity: 0; }
  62% { transform: scale(.92) rotate(-14deg); opacity: 1; }
  to { transform: scale(1) rotate(-14deg); opacity: 1; }
}
.wrap-pack.is-away { transition: transform .24s ease-in, opacity .24s ease-in;
  transform: translate(-38%, -64%) scale(.66); opacity: 0; }

/* L'ardoise du boucher: le coin bas-gauche de la Traversee etait vide. Au repos elle raconte
   la region en cours; au survol d'une piece elle donne le dossier (prix, gestes, recettes). */
.ardoise { position: fixed; left: 26px; bottom: 24px; z-index: 4; width: 300px;
  background: #24211b; color: #f0e9d6; border: 2px solid var(--ink); border-radius: 12px;
  box-shadow: inset 0 0 0 2px rgba(244, 238, 223, .16), 5px 5px 0 rgba(21, 19, 15, .30);
  padding: 14px 16px 15px; transform: rotate(-1.2deg);
  opacity: 0; pointer-events: none; transition: opacity .3s ease; }
.ardoise.is-on { opacity: 1; }
.ardoise > b { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  border-bottom: 1px dashed rgba(240, 233, 214, .45); padding-bottom: 7px; margin-bottom: 9px; }
.ardoise-price { margin: 0 0 2px; font-family: Archivo, system-ui, sans-serif; font-size: 21px; font-weight: 800; }
.ardoise-modes { margin: 0; font-size: 12px; opacity: .8; }
.ardoise-fact { margin: 0; font-size: 13px; line-height: 1.45; }
.ardoise-recipes { margin: 9px 0 0; font-size: 12px; color: var(--lime); }
.ardoise-thumbs { display: flex; gap: 7px; margin-top: 8px; }
.ardoise-thumbs img { width: 78px; height: 58px; object-fit: cover; border-radius: 7px;
  border: 2px solid rgba(244, 238, 223, .35); }


.recipes-title { margin: 24px 0 10px; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }
/* Des cartes, pas des liens texte: la photo du catalogue Umay est l'argument, le titre suit. */
.recipes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0; }
.recipe { display: block; overflow: hidden; border: 2px solid var(--ink); border-radius: 14px; background: var(--bone);
  color: var(--ink); text-decoration: none; font-weight: 700; font-size: 13px; box-shadow: 3px 3px 0 var(--ink); }
.recipe:hover, .recipe:focus-visible { background: var(--lime); }
.recipe-thumb { display: block; aspect-ratio: 4 / 3; border-bottom: 2px solid var(--ink); background: var(--paper); }
.recipe-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.recipe-thumb.no-image { display: grid; place-items: center; font-size: 30px; opacity: .35; }
.recipe-title { display: block; padding: 9px 11px 11px; line-height: 1.25; }
.no-recipe { margin: 24px 0 0; font-size: 13px; opacity: .55; }

/* Vue Abats : une planche éditoriale distincte, accessible depuis l'Étal. Les images restent les
   mêmes contours catalogue, mais leur grille et leurs états sont propres à cette lecture : aucun
   morceau ne réapparaît derrière la vache ou sous le rail. */
body[data-subview="abats"] { overflow: hidden; }
.abats-screen { position: fixed; inset: 0; z-index: 7; overflow: auto; padding: 16px 22px 34px;
  background: var(--bone); color: var(--ink); }
.abats-header { border-bottom: 2px solid var(--ink); padding-bottom: 10px; }
.abats-nav { display: flex; gap: 16px; flex-wrap: wrap; }
.abats-nav button, .abats-nav a { min-height: 38px; border: 2px solid var(--ink); border-radius: var(--r-pill);
  padding: 7px 22px; background: var(--paper); color: var(--ink); box-shadow: var(--sh-int);
  font: inherit; font-size: 12px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase;
  cursor: pointer; transition: transform .14s ease, background .14s ease; }
.abats-nav a { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.abats-nav button:hover, .abats-nav button:focus-visible, .abats-nav button.is-active,
.abats-nav a:hover, .abats-nav a:focus-visible {
  background: var(--cobalt); color: var(--paper); transform: translate(-2px, -2px); }
.abats-intro { padding: 24px 0 4px; }
.abats-intro h2 { margin: 0; font: 400 clamp(58px, 9vw, 142px)/.82 Druk, Archivo, sans-serif; text-transform: uppercase; }
.abats-intro p { margin: 8px 0 0; font: 800 clamp(14px, 1.6vw, 22px)/1.1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .08em; text-transform: uppercase; }
.abats-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px 28px;
  align-items: end; margin: 22px auto 0; max-width: 1420px; }
.abats-list-item { min-width: 0; width: 100%; }
.abats-card { min-width: 0; display: grid; justify-items: center; gap: 10px; padding: 0; border: 0;
  width: 100%; background: transparent; color: var(--ink); cursor: pointer; font: inherit; }
.abats-card img { display: block; width: 100%; height: min(28vh, 290px); object-fit: contain;
  transform: translateY(0) rotate(0); filter: drop-shadow(0 5px 0 rgba(21,19,15,.12));
  transition: transform .2s cubic-bezier(.2,.8,.2,1), filter .2s ease; }
.abats-card span { width: min(78%, 220px); min-height: 44px; display: grid; place-items: center;
  border: 2px solid var(--ink); border-radius: 12px; background: var(--paper); color: var(--ink);
  padding: 8px 10px; font: 900 12px/1 Archivo, sans-serif; letter-spacing: .08em; text-transform: uppercase;
  box-shadow: var(--sh-int); transition: color .16s ease, transform .16s ease, background .16s ease; }
.abats-card:hover img, .abats-card:focus-visible img { transform: translateY(-7px) rotate(-1deg); filter: drop-shadow(0 9px 0 rgba(21,19,15,.2)); }
.abats-card:hover span, .abats-card:focus-visible span { color: var(--ink); background: var(--lime); transform: translateY(-3px); }
.abats-next { display: block; margin: 24px 0 0 auto; min-width: 160px; }

/* Le miroir exact de isCompact() dans meat-world.js. La tablette debout (768x1024) tombait entre
   les deux contrats: CSS desktop et board portrait, donc la colonne de controles se posait sur la
   tete de la bete. Une seule regle ici, un seul predicat la-bas. Le telephone couche (moins de
   500 px de haut) y entre aussi: en composition bureau, titres et blocs se posaient sur la bete. */
@media (max-width: 720px), (orientation: portrait), (max-height: 500px) {
  /* Le rail des regions passe en bandeau horizontal en haut: masque, il emportait le seul repere
     de progression de la Traversee et sa pilule, la seule bascule FR/US du chapitre. */
  .region-rail { left: 10px; right: 10px; top: 16px; bottom: auto; width: auto;
    flex-direction: row; align-items: center; justify-content: flex-start; gap: 2px; }
  .region-rail::before { display: none; }
  .region-rail-swap { position: relative; left: auto; top: auto; flex: 0 0 auto; margin-right: 8px; }
  .region-rail-swap button { padding: 6px 9px; font-size: 11px; }
  .region-rail-item { flex: 1 1 0; padding: 6px 2px 6px 18px; font-size: 10px; letter-spacing: .04em;
    background: var(--paper); white-space: nowrap; }
  .region-rail-item::before { left: 2px; width: 12px; height: 12px; }
  /* L'ardoise tient la bande vide sous la bete: fait de la region au repos, dossier de la piece
     touchee. */
  .ardoise { left: 10px; right: 10px; bottom: 14px; width: auto; transform: none;
    padding: 10px 13px 11px; max-height: 34vh; overflow: hidden; }
  .ardoise > b { font-size: 11px; padding-bottom: 5px; margin-bottom: 6px; }
  .ardoise-price { font-size: 18px; }
  .ardoise-fact { font-size: 12px; line-height: 1.38; }
  .ardoise-thumbs img { width: 64px; height: 48px; }
  body[data-mode="atlas"][data-chapter="traversee"]::before { content: none; }
  .masthead { padding-left: 62px; }
  .scene-rail { left: 10px; top: 14px; }
  .rail-button { width: 42px; height: 42px; padding: 8px; }
  .rail-button svg { width: 23px; height: 23px; }
  .chapter-panel { left: 66px; top: 50%; width: calc(100vw - 78px); }
  body[data-mode="atlas"][data-chapter="etal"] .chapter-panel { left: 10px; right: 10px; top: 10px; width: auto; }
  .gesture-hero { inset: 18px 64px auto; }
  .gesture-hero h2 { font-size: clamp(38px, 10vw, 70px); }
  .gesture-actions { left: 10px; right: 10px; bottom: 12px; transform: none; justify-content: center; gap: 8px; }
  /* Debout, les phrases se rangent juste au-dessus du toggle, dans la bande laissee libre par la
     rangee de noms du bas. */
  .split-explain { left: 10px; right: 10px; bottom: 62px; width: auto; transform: none; gap: 6px; flex-wrap: wrap; }
  .split-explain-line { padding: 7px 9px; font-size: 12px; line-height: 1.28; }
  .split-explain[data-side="both"] .split-explain-line { font-size: 11px; }
  /* Debout, la note passe sous les phrases, centree; la carte s'ouvre au tap (focus-within).
     Elle s'ancre au VIEWPORT, pas au drapeau: centree sur le drapeau d'un bord, elle sortait
     de l'ecran (l'Espagne, la plus a droite, perdait un tiers de sa carte). */
  .split-elsewhere { flex: 1 1 100%; justify-content: center; padding: 5px 9px; }
  /* La carte s'ouvre en panneau du bas, comme la fiche: centree au-dessus des drapeaux, elle
     couvrait la bete et les deux explications. */
  .split-elsewhere-card {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 7; width: auto;
    display: grid; grid-template-columns: 38% 1fr; align-items: stretch;
    border-width: 3px 0 0; border-radius: var(--r-md) var(--r-md) 0 0; transform: translateY(12px);
  }
  .split-elsewhere-card > img { aspect-ratio: auto; height: 100%; min-height: 128px; }
  .split-elsewhere-item:hover .split-elsewhere-card,
  .split-elsewhere-item:focus-within .split-elsewhere-card { transform: none; }
  .gesture-toggle { flex: 1; }
  /* Le conteneur segctl (4 px + bordure) porte le cran a ~44 px de cible tactile. */
  .gesture-toggle button { min-height: 32px; flex: 1; padding: 6px 8px; font-size: 13px; }
  .gesture-actions .secondary { flex: 1; min-height: 40px; padding: 8px; font-size: 13px; }
  .chapter-panel h2 { font-size: clamp(34px, 12vw, 58px); }
  /* Debout, le bandeau passe en deux lignes: titre + porte des abats, puis les pastilles.
     Il garde une carte compacte: sans elle, les pastilles flottaient sur les crochets
     (le cadre-vitrine ne clippe la scene qu'a 84 px du haut). */
  .counter-panel { flex-wrap: wrap; gap: 8px 12px; padding: 10px 12px;
    background: var(--bone); border: 2px solid var(--ink); border-radius: var(--r-md); }
  .counter-cook { order: 3; flex: 1 1 100%; gap: 5px; }
  .counter-cook button { padding: 5px 9px; font-size: 10px; }
  .counter-abats { padding: 6px 11px; font-size: 10px; }
  .etal-barker { left: 10px; bottom: 12px; }
  .etal-barker img { width: 78px; }
  .etal-barker-bubble { max-width: min(230px, calc(100vw - 40px)); font-size: 12px; padding: 8px 10px; }
  .title-block { margin-left: 62px; padding: 2vh 20px 0 0; }
  .chapters { gap: 10px; padding-bottom: 16px; }
  .chapters li { font-size: 9px; letter-spacing: .08em; }
  /* La fiche s'ouvre a mi-hauteur pour laisser la piece visible; la poignee la deplie. */
  .sheet { width: 100%; top: auto; max-height: 56vh; border-left: 0; border-top: 3px solid var(--ink);
    transition: max-height .25s ease; }
  .sheet.is-expanded { max-height: 90vh; }
  .sheet-grip { display: block; }
  /* Cibles tactiles: 44 px de zone de prise sans grossir le dessin (le pseudo-element deborde). */
  .counter-cook button, .counter-abats, .split-elsewhere-item > button, .region-rail-swap button { position: relative; }
  .counter-cook button::after, .counter-abats::after, .split-elsewhere-item > button::after,
  .region-rail-swap button::after { content: ''; position: absolute; inset: -9px -3px; }
  .sheet-close { width: 44px; height: 44px; top: -10px; right: -10px; }
  .roster button { min-height: 44px; }
  /* Le padding bureau du bandeau (selecteur de chapitre, plus specifique) ecrasait celui-ci et
     decalait le titre de 49 px. */
  body[data-mode="atlas"][data-chapter="etal"] .counter-panel { padding: 10px 12px; }
  .etal-label {
    --etal-label-width: 58px; padding: 3px 3px 4px; border-width: 1.5px; box-shadow: 2px 2px 0 rgba(21,19,15,.28);
    letter-spacing: .015em;
  }
  .cut-label {
    --cut-label-width: 96px; padding: 4px 5px 5px; border-width: 1.5px;
    box-shadow: 2px 2px 0 rgba(21,19,15,.28); font-size: 9px; letter-spacing: .02em;
  }
  .abats-screen { padding: 10px 12px 24px; }
  .abats-header { padding-bottom: 8px; }
  .abats-nav { gap: 6px; }
  .abats-nav button, .abats-nav a { min-height: 44px; padding: 6px 10px; font-size: 9px; letter-spacing: .05em; }
  .abats-intro { padding-top: 16px; }
  .abats-intro h2 { font-size: clamp(54px, 17vw, 82px); }
  .abats-intro p { font-size: 11px; letter-spacing: .04em; }
  .abats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 10px; margin-top: 16px; }
  .abats-card img { height: 20vh; min-height: 112px; }
  .abats-card span { width: 92%; min-height: 44px; font-size: 9px; }
  .abats-next { margin-top: 18px; }
  /* Le select mobile recouvrait le rail de chapitres (64 px de haut sous 720px) : on le hisse
     au-dessus du rail au lieu de le laisser lui marcher dessus. Le desktop (bottom: 20px,
     rail hors du champ) ne change pas. */
  .cut-picker { right: 14px; bottom: 82px; width: min(280px, calc(100vw - 28px)); }
}

/* Telephone couche: il partage les commandes du compact mais n'a que 390 px de haut. Le titre,
   les deux explications et l'ardoise pleine largeur se posaient sur la bete; la fiche a mi-hauteur
   ne laissait voir que quatre lignes. On revient aux panneaux lateraux du bureau, en plus petit. */
@media (max-height: 500px) and (orientation: landscape) {
  .gesture-hero h2 { font-size: clamp(26px, 8vh, 38px); }
  .split-explain { bottom: 58px; }
  .split-explain-line { display: none; }
  .gesture-actions { left: 50%; right: auto; bottom: 8px; transform: translateX(-50%); width: min(560px, 70vw); }
  .ardoise { left: auto; right: 10px; bottom: 10px; width: 270px; max-height: 42vh; }
  .ardoise-fact { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
  .ardoise-thumbs { display: none; }
  .sheet { top: 0; left: auto; width: min(420px, 52vw); max-height: none; border-top: 0; border-left: 3px solid var(--ink); }
  .sheet-grip { display: none; }
  .split-elsewhere-card { left: auto; width: min(520px, 62vw); max-height: 100vh; }
}

@media (prefers-reduced-motion: reduce) {
  .roster button, .title-block, .chapters, .scroll-cue, #meat-chart, #meat-chart rect, #meat-chart path.cut-shape, #meat-chart text,
  #meat-chart [data-split-fx], .split-explain-line,
  #meat-traversal-overlay, #meat-etal-labels, #meat-cut-labels, .cut-label, .toggle,
  .abats-nav button, .abats-nav a, .abats-card, .abats-card img, .abats-card span, .abats-next { transition: none; }
}
