/* ── 0-fonts.css ──────────────────────────────────────────── */
/* GENERADO por scripts/fetch-fonts.mjs — no editar a mano.
   Fuentes auto-hospedadas (design-system.md §16.3). Regenerar:
   node scripts/fetch-fonts.mjs */

@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/anton-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/anton-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Shippori Antique';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/shippori-antique-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Shippori Antique';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/shippori-antique-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/inter-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/inter-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/inter-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/inter-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/inter-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(../fonts/inter-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/inter-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(../fonts/inter-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── 1-tokens.css ──────────────────────────────────────────── */
/**
 * Tokens — reskin siguiendo data/sitedemo.png (fondo crema, tipografía bold,
 * acento rojo, tarjetas blancas). Los 5 hex por sabor NO viven aquí:
 * build.mjs los genera desde src/data/flavors.js justo después de este archivo.
 */
:root {
  /* ── superficie principal: crema, como la referencia ────────────────── */
  --paper: #FAF3E4;
  --paper-2: #FFFFFF;
  --paper-3: #F0E4CC;
  --ink: #17130F;
  --ink-2: #4A423A;
  --ink-3: #746A5E;
  --rule: #E6D9BE;

  /* ── segunda superficie: blanco puro, para alternar contra el crema ──── */
  --night: #FFFFFF;
  --night-2: #FAF3E4;
  --night-3: #F0E4CC;
  --ink-inv: #17130F;
  --ink-inv-2: #4A423A;
  --rule-inv: #E6D9BE;

  /* ── color de casa: rojo, como la referencia ──────────────────────────── */
  --uzu: #D8302A;
  --uzu-deep: #B8221E;
  --uzu-glow: #E85B4C;
  --uzu-soft: #FBE0DA;

  /* ── funcionales ─────────────────────────────────────────────────────── */
  --focus: #127E9E;
  --error: #C0392B;
  --ok: #3F7D4E;
  --kori: #3F6484;
  --kori-glow: #5F86A8;

  /* ── espaciado, unidad base 4px ──────────────────────────────────────── */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px;
  --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px; --s-11: 160px;

  /* ── geometría ───────────────────────────────────────────────────────── */
  --radius-0: 0;
  --radius-1: 10px;
  --radius-pill: 999px;
  --radius-circle: 50%;
  --border-panel: 1px;
  --border-panel-hero: 1px;
  --gutter-panel: 16px;
  --shadow-ink: 0 12px 32px -12px rgba(23,19,15,.28);
  --shadow-ink-sm: 0 6px 16px -6px rgba(23,19,15,.28);

  /* ── medidas ─────────────────────────────────────────────────────────── */
  --w-read: 34rem;
  --w-wide: 1200px;

  /* ── tipografía: titular bold estilo marcador + voz + cuerpo ──────────── */
  --font-display: 'Anton', 'Zen Kaku Gothic New', 'Hiragino Sans',
                  'Yu Gothic', system-ui, sans-serif;
  --font-manga:   'Shippori Antique', 'Hiragino Mincho ProN', 'Yu Mincho',
                  Georgia, serif;
  --font-body:    'Inter', 'Zen Kaku Gothic New', -apple-system,
                  'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  /* ── escala tipográfica fluida ─────────────────────────────────────────── */
  --t-display-xl: clamp(2.75rem, 9vw, 5.5rem);
  --t-display-l:  clamp(1.875rem, 5.5vw, 3.25rem);
  --t-display-m:  clamp(1.375rem, 3.6vw, 2rem);
  /* SFX de FRANJA a ancho completo (§10.1 filas 4 y 12). Máx. 72px. */
  --t-sfx:        clamp(2rem, 9vw, 4.5rem);
  /* SFX dentro de viñeta/columna (§5.5.3). Máx. 36px: 4 glifos = 147px, por
     debajo del 80% de la columna de paso más estrecha del sistema (197px).
     No intercambiable con --t-sfx: a 72px desborda la viñeta ~70px. */
  --t-sfx-inline: clamp(1.5rem, 3.2vw, 2.25rem);
  --t-manga-l:    clamp(1.125rem, 2.4vw, 1.375rem);
  --t-manga-m:    1rem;
  --t-label:      0.75rem;
  --t-lead:       clamp(1.0625rem, 2vw, 1.25rem);
  --t-body:       1.0625rem;
  --t-body-s:     0.9375rem;
  --t-caption:    0.8125rem;
  --t-button:     1rem;

  /* ── movimiento ──────────────────────────────────────────────────────── */
  --ease-panel: cubic-bezier(.2, .7, .3, 1);
  --ease-sfx: cubic-bezier(.2, 1.1, .4, 1);

  /* ── v2.1 · slot de SFX (§5.4.1) y raíl de personaje (§9.12.4, §10.4.1) ──
     --sfx-slot-h es IDÉNTICO en todos los breakpoints y en los dos estados de
     `jaValidated`: es lo que garantiza que encender el flag no mueva el
     layout ni un píxel. No convertirlo en fluido ni en min-height. */
  --sfx-slot-h: 56px;
  --sfx-mark-w: 96px;
  --sfx-mark-h: 32px;
  /* El raíl de personaje NO existe por debajo de 900px (§10.4.1). */
  --char-rail: 0px;
}
@media (min-width: 900px)  { :root { --char-rail: 140px; } }
@media (min-width: 1200px) { :root { --char-rail: 200px; } }
@media (min-width: 1440px) { :root { --char-rail: 220px; } }

/* ── par de tokens por zona: dos superficies claras que alternan ────────── */
[data-zone="paper"] {
  --bg: var(--paper);
  --fg: var(--ink);
  --fg-2: var(--ink-2);
  --fg-3: var(--ink-3);
  --line: var(--rule);
  --accent-fg: var(--accent-deep);
  color-scheme: light;
}
[data-zone="night"] {
  --bg: var(--night);
  --fg: var(--ink-inv);
  --fg-2: var(--ink-inv-2);
  --fg-3: var(--ink-inv-2);
  --line: var(--rule-inv);
  /* Las dos zonas son claras en este reskin: el texto de acento usa
     siempre la variante oscura (--accent-deep), nunca --accent-on-night
     (pensada para fondo oscuro y con contraste insuficiente sobre blanco). */
  --accent-fg: var(--accent-deep);
  color-scheme: light;
}

/* GENERADO por build.mjs desde src/data/flavors.js — no editar a mano. */
/* Landing general sin sabor activo: acento neutralizado a --fg-3. */
[data-flavor="none"]{
  --accent:#6E6371; --accent-deep:#4E4450; --accent-on-night:#B9AEBF;
  --accent-tint:#EADCC0; --accent-glow:#B9AEBF;
}
[data-flavor="tonkotsu"]{
  --accent:#E8A02E; --accent-deep:#8A4B14; --accent-on-night:#F7BE55;
  --accent-tint:#FBEBCF; --accent-glow:#FFC864;
}
[data-flavor="tonkotsu-pollo"]{
  --accent:#D9902A; --accent-deep:#8A5518; --accent-on-night:#F0B860;
  --accent-tint:#FBE8CC; --accent-glow:#FFCB78;
}

/* ── 3-base.css ──────────────────────────────────────────── */
/**
 * Base — reset, tipografía de cuerpo, utilidades. design-system.md v2.0 §5, §10.5.
 */
*, *::before, *::after { box-sizing: border-box; }
/* Red de seguridad: bleeds decorativos con position:absolute (p. ej.
   .prep-watermark, §9.12) salen a propósito del borde de su sección sin
   overflow:hidden local. Sin este freno, ese sangrado empuja el ancho
   scrolleable de toda la página y dejaba un hueco en blanco a la derecha
   del header sticky por debajo de ~1362px de viewport. Se fija en `html`
   (no solo en `body`: la propagación de overflow de body a la raíz no
   basta para bloquear el scroll horizontal real) y con overflow-y:visible
   explícito porque, por spec, fijar solo overflow-x cambiaría overflow-y
   a auto (mismo motivo que en .hero, arriba en la cascada). */
html { -webkit-text-size-adjust: 100%; overflow-x: hidden; overflow-y: visible; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.65;
  text-wrap: pretty;
}
img, svg { display: block; max-width: 100%; }
/* <picture> es solo un envoltorio de <source>+<img> (lib/html.js · img()):
   que no forme caja propia y el <img> quede como hijo directo de su figure. */
picture { display: contents; }
ul, ol { margin: 0; padding: 0; list-style: none; }
ul[role="list"], ol[role="list"] { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

/* El sprite de símbolos (naruto + iconos) no tiene width/height propios:
   sin esta regla el navegador le da su tamaño por defecto (~300×150px) y
   empuja todo el contenido hacia abajo, dejando un hueco en blanco arriba
   del header. `position:absolute` + `width/height:0` lo saca del flujo sin
   romper las referencias <use> (más robusto entre navegadores que display:none). */
.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ── headings ────────────────────────────────────────────────────────────
   Un h1 por página, h2 por sección, h3 en fichas (§10.5). El display XL
   se reserva al h1 del hero; h2 de sección usa display L. */
.h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--t-display-l);
  line-height: 1.06;
  letter-spacing: -0.015em;
  margin: 0 0 var(--s-4);
  color: var(--fg, var(--ink));
  text-wrap: balance;
  max-width: 20ch;
}
.h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--t-display-m);
  line-height: 1.14;
  margin: 0;
  color: var(--fg, var(--ink));
}
.lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--fg-2, var(--ink-2));
  max-width: var(--w-read);
  margin: 0 0 var(--s-5);
}
.body {
  font-size: var(--t-body);
  line-height: 1.65;
  color: var(--fg-2, var(--ink-2));
  max-width: var(--w-read);
  margin: 0 0 var(--s-4);
}
.caption {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--t-caption);
  line-height: 1.45;
  letter-spacing: 0.01em;
  color: var(--fg-3, var(--ink-3));
  margin: var(--s-2) 0 0;
}

/* ── focus ring — visible en ambas zonas (§10.5) ──────────────────────── */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* ── verify marker — visible en staging, bloquea --check ──────────────── */
.verify {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.75em;
  font-weight: 600;
  color: var(--error);
  background: color-mix(in srgb, var(--error) 12%, transparent);
  padding: 0 0.35em;
  border-radius: var(--radius-1);
}

/* ── seal — dato ya verificado, variante afirmativa de .verify (no bloquea) ── */
.seal {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.75em;
  font-weight: 600;
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  padding: 0 0.35em;
  border-radius: var(--radius-1);
}

/* ── skip link ───────────────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  left: var(--s-4);
  top: -100px;
  z-index: 100;
  background: var(--uzu-deep);
  color: var(--paper);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--radius-1);
  transition: top 150ms var(--ease-panel);
}
.skip-link:focus { top: var(--s-4); }

/* ── reveal / motion — §6.4. Cero animación bajo prefers-reduced-motion ─ */
.reveal-ready .reveal { opacity: 0; transform: translateY(12px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 220ms var(--ease-panel), transform 220ms var(--ease-panel);
}
@media (prefers-reduced-motion: reduce) {
  .reveal-ready .reveal { opacity: 1; transform: none; transition: opacity 100ms linear; }
  /* El halo del personaje no anima, así que no hace falta apagarlo: solo el
     vapor y la respiración (§6.4, "todo bajo prefers-reduced-motion"). */
  .steam, .character-slot, .btn, .flavor-card { animation: none; transition: none; }
  .steam .wisp { opacity: 0; animation: none; }
  .step, .step__num-ring { animation: none; transition: none; }
  .step-reveal-ready .step { opacity: 1; transform: none; }
}

/* ── Transición entre páginas — nativa, cero JS. Solo actúa en navegadores
   con View Transitions cross-document (Chrome/Edge); el resto navega normal. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
  ::view-transition-old(root) { animation: uzu-page-out 200ms var(--ease-panel) both; }
  ::view-transition-new(root) { animation: uzu-page-in 260ms var(--ease-panel) both; }
  @keyframes uzu-page-out { to { opacity: 0; } }
  @keyframes uzu-page-in { from { opacity: 0; transform: translateY(10px); } }
}

/* ── ArtistCredit — design-system.md §9.16, obligatorio ────────────────── */
.artist-credit {
  font-size: var(--t-caption);
  color: var(--fg-3, var(--ink-inv-2));
  margin: var(--s-3) 0 0;
}
.artist-credit__handle { text-decoration: underline; text-underline-offset: 2px; }

/* ── 4-layout.css ──────────────────────────────────────────── */
/**
 * Layout — grid, zonas, geometría de sección. design-system.md v2.0 §3, §6.2, §10.4.
 */

/* ── ZoneBand — cualquier elemento con data-zone pinta su superficie ─────
   (no solo .zone-band: header/footer ponen data-zone directo en su tag). */
[data-zone] {
  background: var(--bg);
  color: var(--fg);
}
[data-zone] .h1, [data-zone] .h3 { color: var(--fg); }
[data-zone] .lead, [data-zone] .body { color: var(--fg-2); }
[data-zone] .caption { color: var(--fg-3); }

/* ── Grid — 4/8/12 columnas, contenedor centrado (§6.2) ─────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-4);
  padding-inline: 20px;
  margin-inline: auto;
  align-items: start;
}
@media (min-width: 600px) {
  .grid { grid-template-columns: repeat(8, 1fr); gap: 20px; padding-inline: 32px; }
}
@media (min-width: 900px) {
  .grid { grid-template-columns: repeat(12, 1fr); gap: 24px; padding-inline: 40px; max-width: 1080px; }
}
@media (min-width: 1200px) {
  .grid { gap: 24px; padding-inline: 56px; max-width: 1200px; }
}
@media (min-width: 1440px) {
  .grid { gap: 32px; padding-inline: 0; max-width: 1320px; }
}

.col { min-width: 0; grid-column: 1 / -1; }
.col--wide, .col--full { grid-column: 1 / -1; }

/* ── Personajes decorativos — REGLA ÚNICA (§10.4.1) ───────────────────────
   Un personaje decorativo se muestra a partir de `md` (≥900px) y no existe por
   debajo. Punto. La regla vive AQUÍ, en .character-slot, y no en cada uso:
   antes había tres valores distintos (700 / 900 / 1200) y ningún criterio.
   No añadir excepciones por uso — si un personaje necesita otro breakpoint, el
   que está mal es el personaje.
   Además: fuera del orden de foco siempre (pointer-events + aria-hidden en el
   componente), nunca portador de información.

   El contorno punteado es el estado vacío de §8.5: debe verse PENDIENTE, no
   resuelto mal. Desaparece solo con --filled. */
.character-slot {
  display: none;
  aspect-ratio: var(--ratio);
  border: 1.5px dashed var(--rule);
  border-radius: var(--radius-1);
  position: relative;
  pointer-events: none;
}
@media (min-width: 900px) { .character-slot { display: block; } }
.character-slot::after {
  content: "espacio para imagen";
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  text-align: center; padding: var(--s-2);
  font-family: var(--font-body); font-size: var(--t-caption);
  color: var(--fg-3); opacity: 0.6;
}
/* Con imagen puesta: sin marco punteado ni texto de marcador, la ilustración flota como en D10. */
.character-slot--filled { border: none; }
.character-slot--filled::after { content: none; }
.character-slot--filled img { display: block; width: 100%; height: 100%; object-fit: contain; }

/* Pares media/texto: DOM = orden de foco siempre; la posición visual se
   resuelve con grid-column, nunca con `order` (§10.5). */
@media (min-width: 900px) {
  .col--media { grid-column: 1 / span 6; grid-row: 1; }
  .col--text { grid-column: 7 / span 6; grid-row: 1; }
  .col--media-alt { grid-column: 7 / span 6; grid-row: 1; }
  .col--text-end { grid-column: 1 / span 6; grid-row: 1; }
}

/* ── Section — ritmo vertical (§6.1) ─────────────────────────────────────── */
.section { padding-block: var(--s-8); }
@media (min-width: 900px) { .section { padding-block: var(--s-9); } }

/* ── Hero — composición de referencia (data/sitedemo.png) ─────────────────
   Texto a la izquierda, foto + badge + slot de personaje a la derecha.
   DOM = orden de foco: copy antes que media en todos los breakpoints. */
/* overflow-x:hidden = red de seguridad para que .hero__character nunca
   empuje scroll horizontal de toda la página. overflow-y explícito en
   visible: por spec, fijar solo overflow-x pone overflow-y en `auto`, lo que
   recortaría verticalmente al personaje — justo el corte que no queremos. */
.hero { padding-block: var(--s-9); padding-inline: 20px; max-width: 1320px; margin-inline: auto; overflow-x: hidden; overflow-y: visible; }
@media (min-width: 600px) { .hero { padding-inline: 32px; } }
@media (min-width: 900px) { .hero { padding-inline: 40px; padding-block: var(--s-10); } }
.hero__grid { display: grid; grid-template-columns: 1fr; gap: var(--s-8); align-items: center; }
@media (min-width: 900px) { .hero__grid { grid-template-columns: 6fr 6fr; gap: var(--s-9); } }

.hero__copy { display: flex; flex-direction: column; gap: var(--s-4); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.hero__media { display: flex; flex-direction: column; gap: var(--s-3); }
.hero__media-row { display: flex; align-items: flex-end; gap: var(--s-2); }
/* position:relative es el ancla real de .hero__character (position:absolute):
   el personaje se calcula siempre contra el marco del tazón, nunca contra el
   espacio sobrante que deja el flex a la derecha en pantallas anchas. */
.hero__photo-wrap { position: relative; flex: 1 1 260px; min-width: 0; max-width: 480px; }
.hero__photo { width: 100%; border-radius: var(--radius-1); box-shadow: var(--shadow-ink); }
/* Cerca de la cabeza del personaje a propósito (§ composición hero): queda
   por encima de todo (z-index más alto) para que nunca quede tapada. */
.hero__bubble {
  position: absolute; top: -6%; right: 4%;
  display: inline-flex; align-items: center; gap: var(--s-2);
  background: var(--paper-2); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--radius-1);
  padding: var(--s-2) var(--s-4);
  font-family: var(--font-manga); font-size: var(--t-body-s);
  box-shadow: var(--shadow-ink-sm);
  z-index: 4;
}
/* Tira de sellos — centrada sobre el borde inferior de la foto. Reemplaza el
   badge circular único. Va sobre la franja oscurecida de .photo--provisional.
   La esquina superior la ocupan burbuja + personaje. */
.hero__facts {
  position: absolute; left: 50%; bottom: var(--s-3);
  transform: translateX(-50%);
  z-index: 2; margin: 0; padding: 0; list-style: none;
  display: flex; align-items: stretch;
  max-width: calc(100% - 2 * var(--s-4));
}
.hero__fact {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: var(--s-1);
  text-align: center; padding: var(--s-3);
  font-family: var(--font-display); font-size: var(--t-caption);
  line-height: 1.1; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--uzu-deep);
}
.hero__fact + .hero__fact { border-left: 1px solid var(--rule); }
.hero__fact-icon { color: var(--uzu); flex-shrink: 0; }
/* Personaje — segundo protagonista, no un adorno de esquina. Entra desde el
   lado derecho a la altura del tazón y sangra deliberadamente fuera del
   marco (right negativo): .hero__photo-wrap no recorta (overflow visible por
   defecto) y .hero (más arriba en la cascada) solo pone overflow-x:hidden
   como red de seguridad para no empujar scroll horizontal de la página.
   z-index por encima de la foto — puede solaparse con el borde derecho del
   tazón, pero la posición/escala están calibradas para dejar el centro,
   los camarones, el chashu y el naruto sin tapar; no se resuelve el
   solape bajando su z-index. */
.hero__character {
  position: absolute; top: 10%; right: -24%;
  width: 66%; max-width: 380px; min-width: 190px;
  z-index: 3; pointer-events: none;
}
@media (min-width: 1200px) {
  .hero__character { top: 4%; right: -32%; width: 78%; max-width: 520px; }
}
/* El display/ocultado lo decide .character-slot (§10.4.1, ≥900px). Aquí NO
   hay media query de visibilidad: era una de las tres decisiones ad hoc. */

/* ── Vapor — VOCABULARIO COMPARTIDO (§9.12.4-b, §16.7-15) ─────────────────
   Un solo grupo de reglas y UNOS SOLOS @keyframes (`steam-rise`) para el hero
   y para el raíl de preparación. `.steam` define el movimiento; los
   modificadores `--hero` / `--prep` solo dicen DÓNDE se ancla el grupo.
   Nunca cruza al área de una fotografía (§6.4: cero animación sobre foto).
   [SUPUESTO] El spec no fija breakpoint para el vapor; sigue el de los
   personajes (≥900px, §10.4.1) porque es el mismo tipo de decoración y en
   apilado cada píxel vertical es del contenido. */
.steam { display: none; pointer-events: none; }
@media (min-width: 900px) { .steam { display: block; } }
.steam .wisp {
  position: absolute; bottom: 0; left: var(--wisp-left, 8%);
  width: var(--wisp-w, 22%); height: 100%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(246,243,237,.5), transparent 70%);
  filter: blur(3px);
  opacity: 0;
  animation: steam-rise 4.5s ease-in infinite;
  will-change: transform, opacity;
}
[data-zone="night"] .steam .wisp { background: radial-gradient(closest-side, rgba(255,255,255,.28), transparent 70%); }
.steam .wisp--1 { --wisp-left: 8%; --wisp-w: 20%; animation-duration: 4.2s; }
.steam .wisp--2 { --wisp-left: 40%; --wisp-w: 26%; animation-delay: 1.1s; animation-duration: 5s; }
.steam .wisp--3 { --wisp-left: 70%; --wisp-w: 18%; animation-delay: 2.2s; animation-duration: 4.6s; }

/* Anclaje en el hero: margen sobre el marco de la foto, trasladado fuera de él. */
.steam--hero {
  position: absolute; top: 0; left: 15%; right: 15%; height: var(--s-6);
  transform: translateY(-92%);
  z-index: 1;
}

/* ── Respiración del personaje — un solo loop lento, solo transform (§16.5) */
.character-slot { animation: char-breathe 4s var(--ease-panel) infinite; }
@keyframes char-breathe {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
@keyframes steam-rise {
  0% { transform: translateY(0) scaleY(0.6); opacity: 0; }
  20% { opacity: 0.55; }
  70% { opacity: 0.18; }
  100% { transform: translateY(-140%) scaleY(1.15); opacity: 0; }
}

/* ── Franjas SFX estrechas (§10.1, filas 4 y 12) ─────────────────────────── */
.sfx-band-wrap, .order-sfx-wrap { display: flex; }
.sfx-band, .order-sfx {
  width: 100%;
  min-height: 88px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: var(--s-4);
}
.order-sfx { min-height: 112px; }

/* ── PillarRow (§9, wireframe fila 2) ────────────────────────────────────── */
.pillar-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  margin-top: var(--s-6);
}
@media (min-width: 600px) { .pillar-row { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .pillar-row { grid-template-columns: repeat(4, 1fr); } }

/* ── Anatomía (§9.10) ────────────────────────────────────────────────────── */
.anatomy__lead { margin-top: var(--s-2); }
.anatomy__figure { position: relative; }
.anatomy__list { display: flex; flex-direction: column; gap: var(--s-5); margin-top: var(--s-4); }
@media (min-width: 900px) { .anatomy__list { margin-top: 0; } }

/* ── Kit / ColdChain / FlavorSheet / MakerBlock — pares media+texto ─────── */
.kit-list, .coldchain__facts, .order__allergens { display: flex; flex-direction: column; gap: var(--s-3); margin-top: var(--s-5); }

/* ── Roster (§9.5) ───────────────────────────────────────────────────────── */
.flavor-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  margin-top: var(--s-6);
  align-items: stretch;
}
@media (min-width: 600px) { .flavor-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .flavor-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); } }

/* ── Preparación (§9.12) ──────────────────────────────────────────────────
   `.prep-watermark` sangra a propósito fuera del borde derecho de la sección
   (§10.4.1-4/9.12.4-b) — sin recortarla ahí, ese sangrado empujaba el ancho
   scrolleable de TODA la página (hueco a la derecha del `<html>`, visible en
   el inspector, en cualquier viewport por debajo de ~1600px). overflow-x
   la recorta en el eje horizontal; overflow-y:visible explícito porque, por
   spec, fijar solo overflow-x cambiaría overflow-y a auto, lo que SÍ cortaría
   el halo y el vapor que bleedean por arriba (mismo patrón que en `.hero`).
   `isolation:isolate` crea su propio contexto de apilado para que la marca de
   agua (z-index negativo) quede detrás del contenido de ESTA sección sin
   filtrarse a otras. */
.section--steps { position: relative; isolation: isolate; overflow-x: hidden; overflow-y: visible; }

/* Marca de agua decorativa — el naruto de la propia casa (nunca IA, nunca un
   personaje con copyright ajeno). Mismo tono que el halo del personaje
   (`--accent-glow`, §9.12.4-b): no introduce un color nuevo en la sección. */
.prep-watermark {
  position: absolute; z-index: -1;
  top: 50%; right: -110px; transform: translateY(-50%);
  width: 360px; height: 360px;
  color: var(--accent-glow); opacity: 0.12;
  pointer-events: none;
}
.prep-watermark svg { display: block; width: 100%; height: 100%; }
@media (min-width: 900px) { .prep-watermark { width: 560px; height: 560px; right: -140px; } }

/* Reveal de las viñetas — conecta el IntersectionObserver que ya disparaba
   site.js sin que ningún CSS lo aprovechara. Gated por `.step-reveal-ready`
   (solo la pone `site.js`, y solo si `prefers-reduced-motion` está apagado):
   sin JS, o con movimiento reducido, las viñetas se ven normales desde el
   primer render — nunca dependen de la animación para ser visibles. */
.step-reveal-ready .step { opacity: 0; transform: translateY(10px) scale(0.96); }
.step.is-in {
  opacity: 1; transform: none;
  transition: opacity 420ms var(--ease-panel), transform 420ms var(--ease-panel);
}
.steps .step:nth-child(2) { transition-delay: 80ms; }
.steps .step:nth-child(3) { transition-delay: 160ms; }
.steps .step:nth-child(4) { transition-delay: 240ms; }

/* Pulso de acento en el número al revelarse — un solo disparo, no un loop. */
.step__num-ring {
  position: absolute; inset: -4px; z-index: -1;
  border-radius: var(--radius-circle);
  background: radial-gradient(circle, var(--accent-glow), transparent 70%);
  opacity: 0;
}
.step.is-in .step__num-ring { animation: step-num-pulse 700ms var(--ease-panel) both; }
@keyframes step-num-pulse {
  0% { opacity: 0.6; transform: scale(0.6); }
  100% { opacity: 0; transform: scale(1.8); }
}

/* Retícula de la tira + raíl (§9.12.4-a). Por debajo de 900px hay UNA columna:
   el raíl no existe, no es una columna de 0px con hueco. `align-items:end`
   apoya al personaje en la base de la tira. */
.prep-layout { display: grid; gap: var(--s-5); margin-top: var(--s-6); }
@media (min-width: 900px) {
  .prep-layout {
    grid-template-columns: minmax(0, 920px) var(--char-rail);
    align-items: end;
  }
}
.prep-layout__strip { min-width: 0; }
.prep-layout__rail { min-width: 0; position: relative; }

.steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-4);
}
@media (min-width: 600px) { .steps { grid-template-columns: repeat(2, 1fr); } }
/* grid-auto-rows:1fr = paridad de altura entre las cuatro viñetas SIN reservar
   un slot de SFX vacío en las viñetas 1, 2 y 4 (§9.12.2). */
@media (min-width: 900px) { .steps { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 1fr; } }
.step { display: flex; flex-direction: column; }
.step__media { position: relative; }
/* El slot de SFX se pega al fondo de la viñeta: así las cuatro alinean su
   última línea de texto aunque solo una lleve SFX. */
.step .step__sfx { margin-top: auto; padding-top: var(--s-3); }

/* Personaje de preparación — ocupa el raíl, NUNCA position:absolute sobre la
   sección (§9.12.4-a: si la tira crece, el raíl crece con ella).
   El -32px de solape sobre el borde derecho de la tira es el único autorizado,
   y está calibrado para no tapar el número, el título ni el texto del paso 4. */
.prep-character {
  position: relative;
  margin-inline-start: -32px;
  pointer-events: none;
}
/* Halo (§9.12.4-b): elipse radial anclada a la BASE de la figura, 120%×38%,
   opacidad efectiva 32% (tope del sistema: 35%, §4.5 y test 5 de §4.7).
   Sin `filter: blur` a propósito — el degradado ya difumina y blur cuesta capa
   de composición. `--accent-glow` es el token que §4.5 llama "aura del
   personaje": el color lo pone el sabor, aquí no hay ningún hex. */
.prep-character::before {
  content: "";
  position: absolute;
  left: -10%; bottom: 0;
  width: 120%; height: 38%;
  background: radial-gradient(ellipse at center, var(--accent-glow), transparent 70%);
  opacity: 0.32;
  pointer-events: none;
}
.prep-character__figure { position: relative; }
/* Vapor del raíl: sale de la olla del paso 3 y sube hasta el personaje — por
   eso se ancla al cuadrante inferior IZQUIERDO, entre la viñeta 3 y él.
   La opacidad tope de la voluta en `steam-rise` es .55; el 0.5 del grupo la
   deja en 0,275 ≤ 0,28 sobre noche (§9.12.4-b). */
.steam--prep {
  position: absolute;
  left: -18%; bottom: 12%;
  width: 62%; height: var(--s-9);
  opacity: 0.5;
  z-index: 0;
}

/* ── VideoCarousel — tira de videos de estilo de vida ─────────────────────
   Scroll-snap nativo, sin JS: funciona con swipe, trackpad o rueda+shift.
   Aspect-ratio 31:53 (491×848 real) para que los seis clips del sitio
   compartan un solo recorte. */
.video-carousel {
  display: flex; gap: var(--s-4);
  /* Centrado en pantalla: la tira se encoje a lo que miden los clips activos
     (`width: max-content`) y se centra como bloque (`margin-inline: auto`).
     Si algún día vuelven los 6 clips y no caben, `max-width: 100%` + el
     `overflow-x` de abajo la vuelven scrollable desde el borde izquierdo
     sin recortar el primer video. */
  width: max-content; max-width: 100%;
  padding-block: var(--s-2);
  margin: 0 auto; list-style: none;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
}
.video-carousel__item {
  flex: 0 0 auto; scroll-snap-align: start;
  width: 200px;
  display: flex; flex-direction: column; gap: var(--s-2);
}
@media (min-width: 600px) { .video-carousel__item { width: 220px; } }
@media (min-width: 900px) { .video-carousel__item { width: 240px; } }
.video-carousel__video {
  display: block; width: 100%;
  aspect-ratio: 31 / 53;
  border-radius: var(--radius-1);
  background: var(--night-2);
  object-fit: cover;
}
.video-carousel__item .caption { text-align: center; }


/* ── Newsletter — franja final, composición de referencia ────────────────── */
.newsletter { padding-block: var(--s-8); position: relative; }
.newsletter__grid {
  padding-inline: 20px; max-width: 1320px; margin-inline: auto;
  display: grid; grid-template-columns: 1fr; gap: var(--s-5); align-items: center;
}
@media (min-width: 600px) { .newsletter__grid { padding-inline: 32px; } }
@media (min-width: 900px) {
  .newsletter__grid { grid-template-columns: auto 1fr auto; padding-inline: 40px; }
}
/* Visibilidad ≥900px: la da .character-slot (§10.4.1). Aquí solo el tamaño. */
.newsletter__character { width: 96px; }
.newsletter__social { display: flex; align-items: center; gap: var(--s-2); }
.newsletter__social-label {
  font-family: var(--font-body); font-weight: 500; font-size: var(--t-caption);
  color: var(--fg-3); white-space: nowrap;
}
.newsletter__social-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--radius-circle);
  background: var(--ink); color: var(--paper);
}
.newsletter__social-link--pending { opacity: 0.35; }

/* ── Footer (§9.20) ──────────────────────────────────────────────────────── */
.footer__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  padding-block: var(--s-9);
}
@media (min-width: 600px) { .footer__cols { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .footer__cols { grid-template-columns: 1.4fr repeat(3, 1fr); } }
.footer__bar {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-block: var(--s-5);
  border-top: 1px solid var(--rule-inv);
}
@media (min-width: 600px) { .footer__bar { flex-direction: row; justify-content: space-between; align-items: baseline; } }

/* ── Header (§9.1) ───────────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 50;
  border-bottom: 2px solid var(--uzu);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  height: 64px;
  padding-inline: 20px;
  max-width: 1320px;
  margin-inline: auto;
}
@media (min-width: 600px) { .site-header__inner { padding-inline: 32px; } }
@media (min-width: 900px) { .site-header__inner { height: 76px; padding-inline: 40px; } }
.site-nav { display: none; gap: var(--s-5); }
@media (min-width: 900px) { .site-nav { display: flex; } }
.site-nav__link { font-size: var(--t-body-s); font-weight: 500; }
.site-nav__link:hover { color: var(--uzu-deep); }
.newsletter__copy { display: flex; flex-direction: column; gap: var(--s-1); }
.footer__col--brand { display: flex; flex-direction: column; gap: var(--s-1); }

/* ── Order block ─────────────────────────────────────────────────────────── */
.section--order { padding-block: var(--s-9); }

/* ── 5-components.css ──────────────────────────────────────────── */
/**
 * Componentes — design-system.md v2.0 §6.3 (geometría), §9 (librería).
 * Ningún componente contiene un #hex: todo sale de var(--*).
 */

/* ── Hero copy — data/sitedemo.png: eyebrow rojo + titular bold enorme ───── */
.hero__eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--uzu-deep);
  margin: 0 0 var(--s-2);
}
.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--t-display-xl);
  line-height: 0.98;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 var(--s-4);
  text-wrap: balance;
  max-width: 14ch;
}
.hero__canonical {
  font-family: var(--font-manga);
  font-size: var(--t-manga-l);
  color: var(--uzu-deep);
  margin: 0 0 var(--s-3);
}

/* ── TrustStrip — segunda franja de confianza (referencia) ───────────────── */
.section--trust { padding-block: var(--s-7); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.trust-strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  text-align: center;
}
@media (min-width: 600px) { .trust-strip { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .trust-strip { grid-template-columns: repeat(4, 1fr); } }
.trust-badge { display: flex; flex-direction: column; align-items: center; gap: var(--s-2); }
.trust-badge__icon { color: var(--uzu-deep); }
.trust-badge__title { font-family: var(--font-body); font-weight: 700; font-size: var(--t-body-s); margin: 0; }
.trust-badge__body { font-size: var(--t-caption); color: var(--fg-3); margin: 0; max-width: 24ch; }

/* ── FlavorCard: descripción + alérgenos visibles (P5, nunca ocultos) ────── */
.flavor-card__desc { font-size: var(--t-body-s); color: var(--fg-2); margin: 0; }
.flavor-card__allergens { font-size: var(--t-caption); color: var(--fg-3); margin: 0; padding-top: var(--s-2); border-top: 1px solid var(--rule); }

/* ── SectionLabel (§9.4) ─────────────────────────────────────────────────── */
.section-label {
  display: flex; align-items: center; gap: var(--s-3);
  font-family: var(--font-body); font-weight: 600; font-size: var(--t-label);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--fg-3); margin: 0 0 var(--s-4);
}
.section-label__rule { flex: 1; height: 1px; background: var(--line); }
.section-label__jp {
  font-family: var(--font-manga); font-size: 1.25rem; letter-spacing: 0;
  text-transform: none; color: var(--fg-2);
}
.section-label__jp--slot { display: inline-block; width: 1.25rem; height: 1.25rem; }

/* ── NarrationBox (§9.9) ───────────────────────────────────────────────────
   Filete izquierdo de 4px en --accent-fg: es lo que la distingue de un pie de
   foto de un vistazo, junto con la familia manga y la caja. Sin sombra y sin
   radio (--radius-0) por spec: es una caja de narración de manga, no una card. */
.narration-box {
  font-family: var(--font-manga);
  font-size: var(--t-manga-l);
  line-height: 1.5;
  color: var(--fg);
  background: var(--paper-2);
  border: var(--border-panel) solid var(--line);
  border-left: 4px solid var(--accent-fg);
  border-radius: var(--radius-0);
  box-shadow: none;
  padding: var(--s-4) var(--s-5);
  margin: var(--s-5) 0;
  max-width: var(--w-read);
}
[data-zone="night"] .narration-box { background: var(--night-3); border-color: var(--rule-inv); border-left-color: var(--accent-fg); }
/* Remate de la sección de preparación (§9.12.3): alineado al borde izquierdo
   de la tira y separado de ella por --s-6. */
.narration-box--prep { margin: var(--s-6) 0 0; }

/* ── UzuMark — el emblema, siempre tokens de casa (§7.2) ─────────────────── */
.uzu-mark { display: inline-flex; color: var(--uzu); }
.uzu-mark--glow { color: var(--uzu-glow); }
[data-zone="night"] .uzu-mark--default { color: var(--uzu-glow); }
.naruto { display: block; }

/* ── SFX · SfxSlot (§5.4.1, §5.5.2, §5.5.3) ────────────────────────────────
   REGLA DURA: la caja es la misma con y sin `jaValidated`. `.sfx-slot--inline`
   tiene alto FIJO --sfx-slot-h y su contenido no lo decide. Encender el flag
   solo sustituye líneas por glifos; ni el color ni la altura se mueven.
   Si esto vuelve a ser `height:auto`, vuelve el desbordamiento de §5.4.1. */
.sfx-slot {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  overflow: visible;
}
.sfx-slot--inline { height: var(--sfx-slot-h); }
/* Las franjas de ancho completo centran y respiran; su alto lo fija su propia
   banda (.sfx-band / .order-sfx), nunca el glifo. */
.sfx-slot--band { justify-content: center; min-height: var(--sfx-slot-h); }

/* Estado A — SFX real, tipografiada (ruta de respaldo de §5.5 mientras no haya
   rótulo a mano). Rotación -3° con origen a la izquierda: el ancho crece hacia
   dentro de la caja, no hacia fuera de la columna. */
.sfx {
  font-family: var(--font-display);
  font-size: var(--t-sfx);
  line-height: 0.9;
  letter-spacing: 0.02em;
  color: var(--uzu-glow);          /* SFX de franja: color de CASA (§5.5.2) */
  transform: rotate(-3deg);
  transform-origin: left center;
  white-space: nowrap;
}
[data-zone="paper"] .sfx { color: var(--uzu-deep); }
/* SFX de viñeta: pertenece a la escena del sabor, no a la casa (§5.5.2 fila 2).
   --accent-fg resuelve solo por zona; ningún componente elige entre deep/onNight. */
.sfx--inline { font-size: var(--t-sfx-inline); }
.sfx--inline, [data-zone="paper"] .sfx--inline { color: var(--accent-fg); }

/* Estado B — marcador P10 (§5.4.1). 96×32 EXACTOS, sin escalar: a otro tamaño
   el trazo deja de medir 2,5px. Opacidad 1 y color de acento a propósito —
   el gris atenuado que había aquí se leía como "no hay nada", no como "falta
   algo", y ningún punto del sistema lo autorizaba. */
.sfx-mark {
  position: relative;
  flex: 0 0 auto;
  width: var(--sfx-mark-w);
  height: var(--sfx-mark-h);
  color: var(--uzu-glow);
  opacity: 1;
}
[data-zone="paper"] .sfx-mark { color: var(--uzu-deep); }
.sfx-mark--inline, [data-zone="paper"] .sfx-mark--inline { color: var(--accent-fg); }
/* Trama de 6×6 confinada a la caja y DETRÁS de las líneas. No es el screentone
   A16 de §8.2 y no lo sustituye: es CSS propio del tamaño de una estampilla. */
.sfx-mark::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 6px 6px;
  opacity: 0.16;
}
.sfx-mark__lines { position: relative; display: block; }
.step__sfx { margin-top: var(--s-3); display: flex; }

/* ── Button (§9.19) ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 48px;
  padding-inline: var(--s-5);
  font-family: var(--font-body); font-weight: 600; font-size: var(--t-button);
  border-radius: var(--radius-1);
  border: 2px solid transparent;
  transition: transform 90ms ease-out, box-shadow 150ms var(--ease-panel);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translate(2px, 2px); }
.btn--primary { background: var(--uzu-deep); color: var(--paper); box-shadow: var(--shadow-ink-sm); }
.btn--primary:hover { box-shadow: var(--shadow-ink); }
.btn--primary:active { box-shadow: none; }
.btn--secondary { background: transparent; color: var(--fg); border-color: var(--line); }
[data-zone="night"] .btn--secondary { border-color: var(--ink-inv-2); }
.btn--tertiary { background: transparent; color: var(--uzu-deep); border: none; text-decoration: underline; text-underline-offset: 3px; padding-inline: 0; min-height: auto; }
[data-zone="night"] .btn--tertiary { color: var(--uzu-glow); }
.btn--sm { min-height: 40px; padding-inline: var(--s-4); font-size: var(--t-body-s); }
.btn--lg { min-height: 52px; padding-inline: var(--s-6); }
.btn--block { width: 100%; }
.btn[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }

/* ── FlavorBadge / chips (§9.6, §9.7) ─────────────────────────────────────── */
.flavor-badge {
  display: inline-block; font-size: var(--t-caption); font-weight: 600;
  border: 1px solid var(--accent-fg); color: var(--accent-fg);
  padding: var(--s-1) var(--s-3); border-radius: var(--radius-pill);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.chip {
  display: inline-flex; align-items: center; min-height: 40px; padding-inline: var(--s-4);
  border-radius: var(--radius-pill); border: 1px solid var(--line);
  font-size: var(--t-body-s); font-weight: 500; color: var(--fg);
}
.chip--active { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.chip--disabled { color: var(--fg-3); border-style: dashed; }

/* ── Photo (§9, Figure) ───────────────────────────────────────────────────── */
.photo { position: relative; aspect-ratio: var(--ratio); overflow: hidden; margin: 0; border: var(--border-panel) solid var(--line); }
.photo img { width: 100%; height: 100%; object-fit: cover; }
.photo--provisional::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(transparent 70%, rgba(0,0,0,.25));
  pointer-events: none;
}
.photo--pending, .illustration--pending {
  aspect-ratio: var(--ratio);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: var(--s-2); padding: var(--s-5);
  border: var(--border-panel) dashed var(--line);
  background: var(--paper-2);
}
[data-zone="night"] .photo--pending, [data-zone="night"] .illustration--pending { background: var(--night-2); }
.photo-pending__title, .illustration-pending__title { font-family: var(--font-display); font-size: var(--t-body); color: var(--fg-2); margin: 0; }
.illustration-pending__subtitle { font-family: var(--font-manga); font-size: var(--t-manga-m); color: var(--accent-fg); margin: 0; }
.photo-pending__spec, .photo-pending__note, .illustration-pending__note { font-size: var(--t-caption); color: var(--fg-3); margin: 0; max-width: 34ch; }

/* ── IllustrationPanel — estado de degradación (§8.5) ─────────────────────── */
.illustration, .illustration--pending { border: var(--border-panel) solid var(--rule-inv); margin: 0; }
.illustration { aspect-ratio: var(--ratio); overflow: hidden; }
.illustration img { width: 100%; height: 100%; object-fit: cover; display: block; }
[data-zone="paper"] .illustration--pending { background: var(--night-2); border-color: var(--rule-inv); color: var(--ink-inv); }
.hero__illustration .illustration--pending,
.hero__illustration .illustration { width: 100%; height: 100%; }
.illustration-pending__mark { opacity: 0.5; }

/* ── Pillar (§9, wireframe fila 2) ────────────────────────────────────────── */
.pillar { border-top: 2px solid var(--line); padding-top: var(--s-4); }
.pillar__icon { color: var(--accent-fg); margin-bottom: var(--s-3); }
.pillar__title { font-family: var(--font-display); font-weight: 400; font-size: var(--t-display-m); margin: 0 0 var(--s-2); }
.pillar__body { font-size: var(--t-body-s); color: var(--fg-2); margin: 0; }

/* ── BowlAnatomy (§9.10) ──────────────────────────────────────────────────── */
.anatomy__marker {
  position: absolute; left: var(--mx); top: var(--my); transform: translate(-50%, -50%);
  width: 44px; height: 44px; border-radius: var(--radius-circle);
  background: var(--paper); color: var(--ink); border: 2px solid var(--ink);
  font-family: var(--font-body); font-weight: 600; font-size: 0.9rem;
  display: flex; align-items: center; justify-content: center;
}
.anatomy__marker[aria-pressed="true"] { background: var(--uzu); color: var(--paper); border-color: var(--uzu); }
.anatomy__item { scroll-margin-top: 96px; }
.anatomy__item.is-highlighted { outline: 2px dashed var(--uzu); outline-offset: 6px; }
.anatomy__num { font-family: var(--font-display); color: var(--accent-fg); margin-right: var(--s-2); }
.anatomy__name { display: inline; font-family: var(--font-manga); font-size: var(--t-manga-l); margin: 0; }
.anatomy__body { font-size: var(--t-body-s); color: var(--fg-2); margin: var(--s-1) 0 0; max-width: var(--w-read); }

/* ── KitContents (§9.11) ──────────────────────────────────────────────────── */
.kit-item { display: flex; align-items: baseline; gap: var(--s-2); padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.kit-item__bullet { color: var(--accent-fg); flex-shrink: 0; align-self: center; }
.kit-item__name { font-weight: 600; }
.kit-item__micro { color: var(--fg-3); font-size: var(--t-body-s); }

/* ── PreparationSteps / "Así de fácil" ────────────────────────────────────── */
.step__num {
  position: absolute; top: var(--s-2); left: var(--s-2);
  width: 32px; height: 32px; border-radius: var(--radius-circle);
  background: var(--uzu-deep); color: var(--paper);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 0.9rem;
  box-shadow: var(--shadow-ink-sm);
}
.step__title { font-family: var(--font-manga); font-size: var(--t-manga-l); margin: var(--s-3) 0 var(--s-1); }
.step__body { font-size: var(--t-body-s); color: var(--fg-2); margin: 0; }

/* ── ColdChain (§9.13) ────────────────────────────────────────────────────── */
.coldchain__fact { display: flex; align-items: center; gap: var(--s-2); color: var(--kori-glow); }
.coldchain__icon { flex-shrink: 0; }
.batch-badge { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-caption); color: var(--fg-3); margin-top: var(--s-4); }

/* ── FlavorCard / RosterGrid — tarjeta de producto, como la referencia ───── */
.flavor-card {
  display: flex; flex-direction: column; gap: var(--s-3);
  border: 1px solid var(--rule);
  border-radius: var(--radius-1);
  padding: var(--s-4);
  background: var(--paper-2);
  box-shadow: var(--shadow-ink-sm);
  transition: transform 200ms var(--ease-panel), box-shadow 200ms var(--ease-panel);
}
/* Card completa (marco + sombra), nunca zoom sobre la foto embebida (§6.4). */
.flavor-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-ink); }
.flavor-card--active { border-color: var(--accent); border-width: 2px; }
.flavor-card__media { border-radius: var(--radius-1); overflow: hidden; }
.flavor-card__media .photo, .flavor-card__media .photo--pending { border: none; }
.flavor-card__meta { display: flex; align-items: center; justify-content: space-between; }
.flavor-card__availability { font-size: var(--t-caption); color: var(--ink-3); }
.flavor-card__name { font-family: var(--font-display); font-weight: 400; font-size: var(--t-display-m); color: var(--accent-fg); margin: 0; }
.flavor-card__gloss { font-family: var(--font-manga); font-size: var(--t-manga-m); color: var(--ink-2); margin: 0; }
.flavor-card__character { font-family: var(--font-manga); font-size: var(--t-manga-m); color: var(--accent-fg); margin: 0; }
.flavor-card__cta { margin-top: auto; padding-top: var(--s-2); }

/* ── FlavorSheet + PortionScale (§9, wireframe fila 8) ────────────────────── */
.flavor-sheet__character { font-family: var(--font-manga); font-size: var(--t-manga-l); color: var(--accent-fg); margin: 0 0 var(--s-4); }
.flavor-sheet__differentiator { font-family: var(--font-manga); font-size: var(--t-manga-m); color: var(--fg-2); border-left: 3px solid var(--accent); padding-left: var(--s-3); }
.portion__figure { display: flex; align-items: baseline; gap: var(--s-2); margin: var(--s-3) 0 0; }
.portion__jp { font-family: var(--font-manga); font-size: 1.5rem; color: var(--accent-fg); }

/* ── OrderBlock (§9.18) ───────────────────────────────────────────────────── */
.order__price { color: var(--fg); margin: 0 0 var(--s-4); }
.order__availability, .order__cooking { max-width: var(--w-read); }

/* ── Footer (§9.20) ───────────────────────────────────────────────────────── */
.logo { display: inline-flex; align-items: center; color: var(--fg); }
/* Lockup SVG (src/lib/svg.js · logoLockup). Altura fija; el ancho lo da el
   viewBox. `currentColor` = tinta de la zona; la espiral lleva --uzu propio.
   `overflow: visible` deja salir el japonés (§5.4) sin agrandar la caja. */
.logo-svg { height: 34px; width: auto; overflow: visible; }
.logo-svg__word { font-family: var(--font-display); font-size: 29px; letter-spacing: 0.005em; fill: currentColor; }
.logo-svg__tag { font-family: var(--font-body); font-size: 16px; font-weight: 600; letter-spacing: 2.6px; fill: currentColor; opacity: 0.7; }
.logo-svg__jp { font-family: var(--font-manga); font-size: 12px; fill: var(--uzu); }
.footer__col--brand .logo-svg { height: 40px; }
.footer__tagline { font-family: var(--font-manga); font-size: var(--t-manga-m); color: var(--ink-inv-2); margin: var(--s-3) 0 0; }
.footer__title { font-size: var(--t-caption); text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-inv-2); margin: 0 0 var(--s-3); }
.footer__list { display: flex; flex-direction: column; gap: var(--s-2); }
.footer__link { color: var(--ink-inv); }
.footer__link--pending { color: var(--ink-inv-2); }
.footer__note { font-size: var(--t-caption); color: var(--ink-inv-2); margin-top: var(--s-3); }
.footer__legal { font-size: var(--t-body-s); color: var(--ink-inv); margin: 0; }
.footer__legal-micro { font-size: var(--t-caption); color: var(--ink-inv-2); margin: var(--s-1) 0 0; }
