/* ═══════════════════════════════════════════════════════════════════════
   CARA NUEVA — hoja propia de la nueva portada de Fluidity (bloque 01, 7 sep 2026)

   Reglas de esta hoja, y por qué:
   · NO importa ni depende de styles.css (8.400 líneas) ni de tokens.css. Nace
     limpia; lo que la portada nueva necesite se escribe aquí.
   · CLARO es el tema principal y el oscuro se deriva token a token con
     light-dark(). Cada token de color lleva sus DOS caras en UNA declaración.
     Cero reglas [data-theme]: el interruptor solo cambia `color-scheme` en el
     <html>, y sin interruptor manda la preferencia del sistema.
   · Los pocos colores que son iguales en los dos temas van marcados «fija» en un comentario
     — el check _tools/verificar_tema.js exige una de las dos cosas.
   · Las fuentes viajan en assets/fonts/: cero peticiones externas salvo GA4.
   · Orden de capas: reset < base < layout < componentes < motion. Una regla en
     una capa posterior gana siempre a una anterior, sea cual sea su
     especificidad — por eso aquí no hace falta ningún !important.

   Cómo se midió lo que hay aquí (7 sep 2026):
   · Elevación: composición alfa sobre el fondo de cada tema y contraste WCAG
     entre vecinos. Claro: bg→panel 1,104 · panel→strong 1,108 · strong→high 1,113.
     Oscuro: 1,106 · 1,114 · 1,135. Todos por encima del 1,10 donde el ojo empieza
     a separar dos superficies grandes.
   · Texto: cada color de texto se midió sobre el fondo y sobre --panel-high, que
     es la superficie más alta donde puede caer. Por eso --muted y --brand-text
     claros NO son los del taller (#5f6b7a daba 3,65 y #b91c1c 4,35 sobre
     panel-high: por debajo de 4,5). Los de aquí dan 4,57 y 5,10.
   · Foco: --focus da 3,34 (claro) y 5,03 (oscuro) sobre panel-high; AA pide 3.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── tipografía alojada ──────────────────────────────────────────────────
   IBM Plex Sans llega de Google como fuente VARIABLE (tabla fvar, eje wght
   100-700): las cuatro caras que declaraba fonts.css (400/500/600/700) eran el
   MISMO archivo cuatro veces. Aquí se declara una vez por subconjunto.
   IBM Plex Mono es estática; esta hoja solo la usa a 400 (auditado sobre la
   prueba de techo: cero reglas mono con otro peso), así que solo viaja el 400.
   Si algún día hace falta el 500, se añade su @font-face y su .woff2 aquí.
   Total: 4 archivos, 85 KB. Licencia SIL OFL. */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 100 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(../assets/fonts/ibm-plex-sans-var-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: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 100 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(../assets/fonts/ibm-plex-sans-var-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../assets/fonts/ibm-plex-mono-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../assets/fonts/ibm-plex-mono-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;
}

@layer reset, base, layout, componentes, motion;

/* ─── reset mínimo ─────────────────────────────────────────────────────── */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  body { margin: 0; }
  img { display: block; max-width: 100%; height: auto; }
  h1, h2, h3, p { margin: 0; }
  ul { margin: 0; padding: 0; list-style: none; }
  button { font: inherit; }
}

/* ─── tokens: claro primero, oscuro derivado ───────────────────────────── */
@layer base {
  :root {
    /* Las dos caras están permitidas. Sin interruptor, el navegador elige la
       del sistema; el interruptor escribe color-scheme en línea en el <html>. */
    color-scheme: light dark;

    /* ── marca ── */
    --brand: #d7282f; /* fija */
    /* El rojo cuando hace de TEXTO. --brand a secas da 4,55 sobre papel pero
       3,34 sobre panel-high, y 3,92 sobre el fondo oscuro: no llega a AA.
       Claro 5,10 sobre panel-high · oscuro 5,03. */
    --brand-text: light-dark(#a51a20, #ff6b72);
    --brand-soft: light-dark(rgba(215, 40, 47, 0.12), rgba(215, 40, 47, 0.18));
    --brand-glow: light-dark(rgba(215, 40, 47, 0.22), rgba(215, 40, 47, 0.28));
    /* resaltado de chips: sobre blanco el rosa #f87171 da 2,8 → rojo oscuro */
    --chip-hl: light-dark(#a51a20, #f87171);
    /* tonos DERIVADOS del rojo de marca, no escritos a mano */
    --brand-halo:  color-mix(in oklab, var(--brand) 22%, transparent);
    --brand-suave: color-mix(in oklab, var(--brand) 12%, transparent);
    --brand-gradient-start: #d7282f; /* fija */
    --brand-gradient-end: #ef4444; /* fija */

    /* ── fondos y texto ── */
    --bg:    light-dark(#f4f5f7, #0b0d10);
    --bg-2:  light-dark(#ffffff, #12161c);
    --text:  light-dark(#111827, #f5f7fb);
    /* Claro 6,23 sobre papel y 4,57 sobre panel-high (el #5f6b7a del taller
       daba 3,65 ahí). Oscuro 9,70 / 6,94. */
    --muted: light-dark(#515c6a, #aeb8c6);
    --white: #ffffff; /* fija */
    /* verde de éxito: el claro de #88d3a6 sobre papel daba 1,62 */
    --success: light-dark(#0f5e3a, #88d3a6);
    /* indicador de foco: ≥ 3:1 sobre cualquier superficie de su tema */
    --focus: light-dark(#d7282f, #ff6b72);

    /* ── elevación: tres superficies y dos líneas ──
       Cada salto supera 1,10 de contraste sobre el anterior (medido sobre el
       fondo de cada tema, ver cabecera). La tinta translúcida es gris azulado
       (17,24,39) en claro y blanco en oscuro. */
    --panel:        light-dark(rgba(17, 24, 39, 0.05), rgba(255, 255, 255, 0.05));
    --panel-strong: light-dark(rgba(17, 24, 39, 0.10), rgba(255, 255, 255, 0.09));
    --panel-high:   light-dark(rgba(17, 24, 39, 0.15), rgba(255, 255, 255, 0.13));
    --line:         light-dark(rgba(17, 24, 39, 0.12), rgba(255, 255, 255, 0.10));
    --line-strong:  light-dark(rgba(17, 24, 39, 0.24), rgba(255, 255, 255, 0.20));
    /* la máscara que apaga las capas de estudio del loop2.0 en claro */
    --mascara-estudio: light-dark(transparent, #000);

    /* ── sombras ── */
    --shadow:       0 24px 80px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.45));
    --shadow-card:  0 4px 16px  light-dark(rgba(0, 0, 0, 0.06), rgba(0, 0, 0, 0.10));
    --shadow-hover: 0 12px 40px light-dark(rgba(0, 0, 0, 0.10), rgba(0, 0, 0, 0.14));

    /* ── tipografía ── */
    --font-heading: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-body:    'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-mono:    'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    /* Escala fluida del taller (6 sep 2026), seis pasos */
    --fs-display: clamp(2.125rem, 1.35rem + 3vw, 3.5rem);     /* 34 → 56 */
    --fs-1: clamp(1.625rem, 1.2rem + 1.7vw, 2.5rem);          /* 26 → 40 */
    --fs-2: clamp(1.375rem, 1.2rem + 0.75vw, 1.75rem);        /* 22 → 28 */
    --fs-3: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);     /* 18 → 21 */
    --fs-4: 1rem;
    --fs-5: 0.9375rem;
    --lh-display: 1.04;
    --lh-heading: 1.15;
    --ls-display: -0.03em;
    --ls-heading: -0.015em;

    /* ── espaciado: la escala del taller ── */
    --space-2xs: 4px;
    --space-xs: 8px;
    --space-sm: 12px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: clamp(28px, 3.2vw, 40px);
    --space-2xl: clamp(40px, 5vw, 64px);
    --space-3xl: clamp(56px, 7vw, 96px);

    /* ── forma y contenedores ── */
    --radius-xl: 28px;
    --radius-lg: 20px;
    --radius-md: 14px;
    --radius-sm: 10px;
    --container: 1360px;
    --hero-container: 1480px;
    --container-padding: clamp(16px, 4vw, 48px);

    --ease-out: cubic-bezier(.2,.7,.2,1);
    /* Los dos de la regla de movimiento (web-estandares). Mario los elige el
       9 sep 2026 tras ver las tres curvas disparadas a la vez: hasta hoy tres
       transiciones no tenían curva ninguna y heredaban `ease`, que arranca
       despacio y en 180 ms se lee como un retraso al empezar. */
    --e-salida: cubic-bezier(.19, 1, .22, 1);   /* entradas, reveals, layout */
    --e-suave:  cubic-bezier(.22, 1, .36, 1);   /* hover, focus, micro-interacción */
    /* 🔴 --ciclo vivia AQUI y tambien en portada.css, y ganaba esta: al pasar
       el hero a 6 series se cambio alla y el navegador seguia sirviendo 6,43 s.
       Un token declarado en dos hojas es un token que solo se cambia a medias,
       y no da ningun error. Se queda en UNA: la que lo usa. */
    --ciclo: 3.215s;            /* medio ciclo del loop2.0 original (6,43 s) */
  }

  html { background: var(--bg); scroll-behavior: smooth; overflow-x: clip; }
  body {
    font-family: var(--font-body);
    font-variant-numeric: tabular-nums;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;               /* clip, no hidden: los sticky lo necesitan */
  }
  a { color: inherit; text-decoration: none; }
  .mono { font-family: var(--font-mono); }
  .num  { font-family: var(--font-mono); font-weight: 400; letter-spacing: .04em; }

  /* foco por teclado: el mismo patrón que ya tenía la portada, con el token */
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  :focus:not(:focus-visible) { outline: none; }
}


/* ═══════════════════════════════════════════════════════════════════════
   COMPONENTES COMPARTIDOS — la cabecera y los botones
   Viven en los cimientos y no en la hoja de una página porque los usan la
   prueba de techo, la portada nueva y lo que venga. Estaban en techo.css y
   la portada nacía sin cabecera ni botones, con todo el texto pegado al
   borde: se vio mirando la captura, no midiendo.
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {
  .top {
    position: sticky; top: 0; z-index: 10;
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px clamp(16px, 4vw, 48px);
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
  }
  .top__marca { font-weight: 700; letter-spacing: .12em; font-size: 13px; }
  /* el rojo como TEXTO va con --brand-text: --brand a secas daba 3,92 sobre el fondo oscuro */
  .top__marca span { color: var(--brand-text); }
  .top__nota { font-family: var(--font-mono); font-size: 11px; color: var(--muted); letter-spacing: .06em; }

  /* 🔴 El nav vivía en `portada.css` y la cabecera entera vive aquí. Al montar
     la ficha de serie salió sin estilo: carga los cimientos pero no la portada,
     así que el nav se veía como una lista de enlaces sueltos. Una pieza de la
     cabecera pertenece a los cimientos, no a una página concreta. */
  .nav { display: flex; gap: clamp(10px, 1.6vw, 22px); flex-wrap: wrap; justify-content: center; }
  .nav a {
    font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted);
    padding: 4px 2px; border-bottom: 1px solid transparent; transition: color .16s var(--e-suave), border-color .16s var(--e-suave);
  }
  .nav a:hover { color: var(--text); border-color: var(--brand); }
  .nav a:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
  @media (max-width: 900px) { .nav { display: none; } }
  .btn {
    display: inline-flex; align-items: center; gap: 12px;
    min-height: 48px; padding: 0 22px;
    border-radius: 999px; font-weight: 600; font-size: 15px;
    transition: transform .16s var(--e-suave), box-shadow .16s var(--e-suave), background .16s var(--e-suave);
  }
  .btn--marca { background: var(--brand); color: var(--white); box-shadow: 0 10px 30px var(--brand-halo); }
  .btn--marca::after { content: "→"; font-family: var(--font-mono); }
  .btn--marca:hover { transform: translateY(-1px); box-shadow: 0 16px 40px var(--brand-halo); }
  .btn--marca:active { transform: translateY(1px) scale(.985); transition-duration: .06s; }
  .btn--linea { border: 1px solid var(--line-strong); color: var(--text); }
  .btn--linea:hover { border-color: var(--text); }
}

/* ═══════════════════════════════════════════════════════════════════════
   INTERRUPTOR DE TEMA — js/tema.js lo crea si la página no lo trae
   Solo cambia color-scheme; el resto lo hace light-dark().
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {
  .tema {
    display: inline-grid; place-items: center;
    width: 40px; height: 40px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    background: var(--panel);
    color: var(--text);
    cursor: pointer;
    font-family: var(--font-mono); font-size: 15px; line-height: 1;
    transition: background .16s var(--e-suave), border-color .16s var(--e-suave);
  }
  .tema:hover { background: var(--panel-strong); border-color: var(--text); }
  .tema:active { background: var(--panel-high); }
  .top__acciones { display: flex; align-items: center; gap: var(--space-md); }
}


/* ═══════════════════════════════════════════════════════════════════════
   TRÁNSITO ENTRE PÁGINAS — la foto de la serie no parpadea, viaja
   ═══════════════════════════════════════════════════════════════════════
   De la tarjeta de la portada a la ficha, la MISMA foto y el MISMO nombre
   son el mismo objeto: en vez de que la página se apague y se encienda otra,
   la pieza crece hasta su sitio y el título la sigue. Es lo que convierte
   veinticuatro páginas sueltas en un sitio que se recorre.

   🔴 Esto solo se puede hacer porque las fichas son PÁGINAS DE VERDAD. Con la
   ficha dinámica de antes —una sola `serie.html?s=01f` que se repintaba— no
   había navegación entre documentos y no había nada que enlazar.

   Dos cosas que no son evidentes:

   · `view-transition-name` tiene que ser ÚNICO en cada documento. En la ficha
     sobra con ponerlo fijo, porque solo hay una foto; en la portada hay 24
     tarjetas, así que el nombre lo pone `js/transito.js` sobre la que se pulsa
     y lo quita después. Dárselo a las 24 en CSS no anima de más: rompe la
     transición entera, porque el nombre deja de identificar a nadie.

   · El navegador que no lo soporta navega y ya está. No hay que detectar nada
     ni escribir un camino alternativo: la regla entera se ignora.
   ══════════════════════════════════════════════════════════════════════ */
@view-transition { navigation: auto; }

@layer componentes {
  /* la ficha: única foto y único título, así que van fijos */
  .fh__foto { view-transition-name: pieza; }
  .fh__t    { view-transition-name: nombre-serie; }

  /* la portada: solo la tarjeta que se pulsa, marcada por el script */
  .tj.va-a-ficha .tj__media img { view-transition-name: pieza; }
  .tj.va-a-ficha .tj__nom       { view-transition-name: nombre-serie; }
}

@layer motion {
  /* la pieza manda el ritmo; el resto de la página cruza más rápido para que
     no compita con ella */
  ::view-transition-group(pieza)        { animation-duration: .42s; }
  ::view-transition-group(nombre-serie) { animation-duration: .36s; }
  ::view-transition-old(root)           { animation-duration: .18s; }
  ::view-transition-new(root)           { animation-duration: .26s; }

  /* 🔴 La foto NO se recorta al viajar: cambia de TAMAÑO, no de encuadre.
     Esto era `object-fit: cover` con `height: 100%`, y con el cover la pieza
     alta llegaba recortada a un extremo del viaje y entera al otro, así que el
     movimiento daba un salto en vez de crecer. Ahora que la tarjeta la enseña
     completa, las dos capas tienen la MISMA proporción —la de la foto— y
     `contain` deja que el grupo interpole la caja sin cortar nada por el
     camino. */
  ::view-transition-old(pieza),
  ::view-transition-new(pieza) {
    height: 100%; object-fit: contain; animation-duration: .42s;
  }

  @media (prefers-reduced-motion: reduce) {
    /* aquí sí se apaga entera, y no por prudencia: una vista que crece y se
       desplaza por la pantalla es exactamente el movimiento intrusivo que esa
       preferencia pide quitar. Los hovers y los fades siguen. */
    @view-transition { navigation: none; }
  }
}
