/* ============================================================
   tokens.css — KIVO
   Base del sistema. Se importa PRIMERO, antes de cualquier otro CSS.

   DIRECCIÓN: "Blanco, negro y magenta" (27/08)
   Tres familias y nada más, como pidió Juan: la gama del blanco, la del
   negro al 100% y la del magenta al 100%.

   ── Dos cosas para dejar escritas ──────────────────────────────────
   1. Los neutros son NEUTROS: croma 0. Antes eran grises teñidos de
      petróleo (hue 185) y eso es lo que arrastraba el verde. Ya no hay
      un solo hue que no sea el 355 del magenta.

   2. diseno.md prohíbe #FFF y #000 puros, y acá se usan los dos. Es un
      pedido explícito de Juan ("gama de blanco / gama de negro 100%"),
      no un descuido. Queda anotado para que nadie lo "arregle".

   El magenta al 100% es el hue de marca (355) empujado hasta el borde
   del gamut sRGB: medido, a L=0.65 el croma entra hasta 0.265 y ahí
   resuelve a #fd0797. Un punto más y clipea.

   Contraste medido (canvas 1x1 + fórmula WCAG, sobre Chrome):
     · blanco sobre negro ............... 21:1
     · negro sobre magenta 100% ......... 5,65:1 -> pasa AA
     · blanco sobre magenta 100% ........ 3,71:1 -> NO pasa AA
     · negro al 86% sobre magenta ....... 5,19:1 -> pasa AA (--texto-suave)
   Por eso todo bloque magenta lleva texto NEGRO, no blanco.

   DOS TRAMPAS al medir esto, las dos me dieron un número falso:

   1. getComputedStyle devuelve `oklch(0.65 0.265 355)` tal cual para
      background-color. Sacarle los números con un regex da [0.65, 0.265, 355],
      que no es un RGB: así el negro sobre magenta me dio 4,09 en vez de 5,65.
      Hay que pintar el color en un canvas de 1×1 y leer el píxel.

   2. Un color CON ALFA hay que componerlo sobre su fondo REAL. Pintar
      `oklch(0 0 0 / .86)` sobre papel y recién ahí compararlo contra el
      magenta daba 4,18 — un valor que no existe en la pantalla. Sobre
      magenta de verdad da 5,19.
   ============================================================ */

/* La trama del manual. Ya NO se usa de fondo de pagina: pasó por rayas y
   después por una grilla de puntos en canvas, y las dos se fueron. Queda
   sólo para .presu__trama, que es lo que el vidrio del formulario refracta
   — ahí sí hace falta que haya algo abajo que se pueda deformar. */
:root {
  --trama: radial-gradient(oklch(0 0 0 / 0.07) 1px, transparent 1px);
  --trama-tam: 24px 24px;
}

/* ------------------------------------------------------------
   1. LAS TRES FAMILIAS
   ------------------------------------------------------------ */
:root {
  /* --- Blanco --- */
  --blanco:    #ffffff;
  --blanco-2:  oklch(0.97 0 0);    /* #f5f5f5 */
  --blanco-3:  oklch(0.92 0 0);    /* #e4e4e4 */
  --blanco-4:  oklch(0.75 0 0);    /* #aeaeae */

  /* --- Negro --- */
  --negro:     #000000;
  --negro-2:   oklch(0.14 0 0);    /* #090909 */
  --negro-3:   oklch(0.24 0 0);    /* #1f1f1f */
  --negro-4:   oklch(0.40 0 0);    /* #484848 — 9,15:1 sobre blanco */
  --negro-5:   oklch(0.55 0 0);    /* #717171 — 4,88:1 sobre blanco */

  /* --- Magenta, al 100% del gamut en el hue de marca --- */
  --magenta:       oklch(0.65 0.265 355);   /* #fd0797 — el 100% del gamut */
  --magenta-texto: oklch(0.52 0.215 355);   /* para texto chico sobre blanco */
  --magenta-hondo: oklch(0.42 0.175 355);   /* hover de bloques */

  /* El magenta de los bloques a sangre. NO es el 100%: sobre el 100% el
     blanco da 3,71:1 y no pasa AA. Bajando la L a 0.54 (mismo hue 355)
     queda #c60475 y el blanco sube a 5,71:1. */
  --magenta-fondo: oklch(0.54 0.22 355);    /* #c60475 */

  /* Nombres viejos que todavía usa algún selector */
  --petroleo: var(--negro);
  --hueso:    var(--blanco-2);
  --papel:    var(--blanco);
  --noche:        var(--negro);
  --noche-honda:  var(--negro);
  --noche-panel:  var(--negro-3);
}

/* ------------------------------------------------------------
   2. TIPOGRAFÍA Y RADIOS DEL MANUAL
   ------------------------------------------------------------ */
:root {
  --f-display: "Outfit", system-ui, sans-serif;
  --f-texto:   "Outfit", system-ui, sans-serif;
  --f-mono:    "IBM Plex Mono", ui-monospace, monospace;

  /* Sobre papel el Light no florece, así que el cuerpo puede ir más
     fino que en el modo noche. */
  --peso-cuerpo: 340;

  --radio: 0px;          /* estructura a escuadra, como el manual */
  --radio-panel: 20px;
  --radio-vidrio: 20px;
}

/* ------------------------------------------------------------
   3. ROLES — TEMA DÍA (el default)

   Ojo con la diferencia entre tokens de MARCA (--magenta, --negro) y
   tokens de ROL (--fondo, --texto). Usar los de marca donde va un rol es
   lo que dejó media página oscura la primera vez que entró el tema claro.
   ------------------------------------------------------------ */
:root {
  color-scheme: light;
  --fondo:       var(--blanco);
  --fondo-hondo: var(--blanco-2);
  --superficie:  var(--blanco);
  --superficie-alta: var(--blanco);

  --acento:      var(--magenta);
  --acento-texto: var(--magenta-texto);   /* 6,19:1 sobre papel */

  --texto:       var(--negro);       /* 21:1 */
  --texto-suave: var(--negro-4);     /* 9,15:1 */
  --texto-tenue: var(--negro-5);     /* 4,88:1 */

  --linea-tenue:  oklch(0 0 0 / 0.09);
  --linea:        oklch(0 0 0 / 0.15);
  --linea-fuerte: oklch(0 0 0 / 0.30);
  --linea-acento: oklch(0.65 0.265 355 / 0.55);

  /* El panel que viaja en hover.js (ver kivo.css, .hover-panel). Sobre
     papel el texto es oscuro, así que el lavado es de tinta, no de luz. */
  --panel-hover: oklch(0 0 0 / 0.055);

  --vidrio-lavado:  var(--blanco);
  --vidrio-borde:   oklch(0 0 0 / 0.14);
  --vidrio-luz:     oklch(1 0 0 / 0.85);
  --vidrio-canto:   oklch(0 0 0 / 0.05);
  --vidrio-sombra:  oklch(0 0 0 / 0.10);
  --vidrio-satura:  100%;

  --nav-fondo:   oklch(1 0 0 / 0.86);
  --nav-link:    var(--negro-4);
  --menu-fondo:  oklch(1 0 0 / 0.98);
  --barra:       var(--blanco-4) transparent;

  --velo-alto:   oklch(0 0 0 / 0.50);
  --velo-bajo:   oklch(0 0 0 / 0.82);
  --chapa:       oklch(0 0 0 / 0.70);

  --iso-disco:   var(--negro);
  --grano: 0.028;
  --grano-parche: 0.04;
}

/* ------------------------------------------------------------
   4. TEMA NOCHE

   A propósito NO sigue a prefers-color-scheme: la elección del usuario
   manda y se guarda. El anti-parpadeo va inline en el <head>, antes de
   este archivo — si esperara al CSS externo se vería el flash del tema
   que no es.

   El peso del cuerpo sube a 380: sobre negro el Light florece y se lee
   más fino de lo que es.
   ------------------------------------------------------------ */
:root[data-tema="oscuro"] {
  color-scheme: dark;
  --peso-cuerpo: 380;
  --fondo:       var(--negro);
  --fondo-hondo: var(--negro);
  --superficie:  var(--negro-3);
  --superficie-alta: oklch(0.28 0 0);

  --acento-texto: var(--magenta);    /* 5,65:1 sobre negro */

  --texto:       var(--blanco);
  --texto-suave: var(--blanco-4);
  --texto-tenue: oklch(0.66 0 0);

  --linea-tenue:  oklch(1 0 0 / 0.10);
  --linea:        oklch(1 0 0 / 0.17);
  --linea-fuerte: oklch(1 0 0 / 0.34);
  --linea-acento: oklch(0.65 0.265 355 / 0.55);

  /* de noche el fondo es negro y el texto blanco: el lavado se invierte */
  --panel-hover: oklch(1 0 0 / 0.13);

  --vidrio-lavado:  var(--negro-3);
  --vidrio-borde:   oklch(1 0 0 / 0.14);
  --vidrio-luz:     oklch(1 0 0 / 0.20);
  --vidrio-canto:   oklch(1 0 0 / 0.07);
  --vidrio-sombra:  oklch(0 0 0 / 0.60);
  --vidrio-satura:  100%;

  --nav-fondo:   oklch(0 0 0 / 0.84);
  --nav-link:    var(--blanco-4);
  --menu-fondo:  oklch(0 0 0 / 0.98);
  --barra:       var(--negro-4) transparent;

  --iso-disco:   var(--negro);
  --grano: 0.045;
  --grano-parche: 0.06;
}

/* ------------------------------------------------------------
   5. BLOQUE MAGENTA — las secciones a sangre

   Ojo con el nombre: el fondo NO es --magenta sino --magenta-fondo, que
   es el mismo hue a menos luminancia. Sobre el magenta 100% el blanco da
   3,71:1 y no pasa AA; sobre #c60475 da 5,71:1.

   Y adentro de este bloque el magenta 100% no existe como acento: sobre
   #c60475 mide 1,54:1. Son dos luminancias del mismo color, no dos
   colores. La paleta acá es magenta profundo + blanco.
   ------------------------------------------------------------ */
.magenta {
  color-scheme: dark;
  --peso-cuerpo: 360;
  --fondo:       var(--magenta-fondo);
  --fondo-hondo: var(--magenta-fondo);
  --superficie:  oklch(1 0 0 / 0.10);
  --superficie-alta: oklch(1 0 0 / 0.16);

  /* Medido sobre #c60475: blanco 5,71:1 · al 90% 4,79:1 · al 88% 4,62:1 ·
     al 86% 4,46:1 (ya no pasa) · al 70% 3,30:1.

     Sobre un fondo de luminancia media NO hay lugar para una escalera de
     grises: entre "blanco" y "no pasa AA" hay 12 puntos de alfa. Los tres
     roles entran ahí y la diferencia entre ellos es sutil a propósito.
     El --texto-tenue de .70 que había acá reprobaba: la etiqueta
     "02 — AUTOMATIZACIÓN CON IA" medía 3,30:1. */
  --texto:       var(--blanco);
  --texto-suave: oklch(1 0 0 / 0.90);
  --texto-tenue: oklch(1 0 0 / 0.88);

  /* El acento acá NO puede ser el magenta 100%: sobre este fondo da
     1,54:1. El acento es el blanco y la jerarquía la hacen el peso,
     la mono y la posición. */
  --acento:       var(--blanco);
  --acento-texto: var(--blanco);

  --linea-tenue:  oklch(1 0 0 / 0.18);
  --linea:        oklch(1 0 0 / 0.30);
  --linea-fuerte: oklch(1 0 0 / 0.46);
  --linea-acento: oklch(1 0 0 / 0.58);

  /* el valor original de .hover-panel, ahora token: iba fijo porque acá
     era el único lugar que lo usaba. Iba a sangre en el bloque, no cambia
     con el tema (.magenta ya es color-scheme:dark siempre). */
  --panel-hover: oklch(1 0 0 / 0.13);

  --vidrio-lavado:  oklch(1 0 0 / 0.12);
  --vidrio-borde:   oklch(1 0 0 / 0.26);
  --vidrio-luz:     oklch(1 0 0 / 0.34);
  --vidrio-canto:   oklch(0 0 0 / 0.10);
  --vidrio-sombra:  oklch(0 0 0 / 0.20);

  --nav-link:    oklch(1 0 0 / 0.80);
  --iso-disco:   var(--blanco);
  --barra:       oklch(1 0 0 / 0.45) transparent;
  --grano: 0.05;

  background: var(--fondo);
  color: var(--texto);
}

/* ------------------------------------------------------------
   6. CONTRASTE — la sección que va al revés del tema ambiente

   La de Diseño & Merch: la fotografía de producto necesita un fondo
   parejo, y romper el corrido de una sola temperatura es lo que le da
   ritmo a la página.
   ------------------------------------------------------------ */
.contraste {
  color-scheme: dark;
  --peso-cuerpo: 380;
  --fondo:       var(--negro);
  --fondo-hondo: var(--negro);
  --superficie:  var(--negro-3);
  --texto:       var(--blanco);
  --texto-suave: var(--blanco-4);
  --texto-tenue: oklch(0.66 0 0);
  --acento-texto: var(--magenta);
  --linea-tenue:  oklch(1 0 0 / 0.10);
  --linea:        oklch(1 0 0 / 0.17);
  --linea-fuerte: oklch(1 0 0 / 0.34);
  --nav-link:     var(--blanco-4);
  --iso-disco:    var(--negro);
  --barra:        var(--negro-4) transparent;
  --vidrio-lavado: var(--negro-3);
  --vidrio-borde:  oklch(1 0 0 / 0.14);

  background: var(--fondo);
  color: var(--texto);
  font-weight: var(--peso-cuerpo);
}

/* De noche la sección de contraste va al revés: pasa a blanco */
:root[data-tema="oscuro"] .contraste {
  color-scheme: light;
  --peso-cuerpo: 340;
  --fondo:       var(--blanco);
  --fondo-hondo: var(--blanco-2);
  --superficie:  var(--blanco);
  --texto:       var(--negro);
  --texto-suave: var(--negro-4);
  --texto-tenue: var(--negro-5);
  --acento-texto: var(--magenta-texto);
  --linea-tenue:  oklch(0 0 0 / 0.09);
  --linea:        oklch(0 0 0 / 0.15);
  --linea-fuerte: oklch(0 0 0 / 0.30);
  --nav-link:     var(--negro-4);
  --iso-disco:    var(--negro);
  --barra:        var(--blanco-4) transparent;
  --vidrio-lavado: var(--blanco);
  --vidrio-borde:  oklch(0 0 0 / 0.14);
}

/* ------------------------------------------------------------
   7. ESCALA
   ------------------------------------------------------------ */
:root {
  --t-display: clamp(3rem, 10.5vw, 8.5rem);
  --t-h1:      clamp(2.1rem, 5.4vw, 4rem);
  --t-h2:      clamp(1.7rem, 3.4vw, 2.6rem);
  --t-h3:      clamp(1.35rem, 1.9vw, 1.65rem);
  --t-h4:      1.22rem;
  --t-body:    1.0625rem;
  --t-small:   0.9rem;
  --t-label:   0.72rem;

  --tr-display: -0.045em;
  --tr-titulo:  -0.03em;
  --tr-label:    0.20em;
}

/* ------------------------------------------------------------
   8. ESPACIO
   ------------------------------------------------------------ */
:root {
  --s-seccion:          clamp(5.5rem, 13vw, 13rem);
  --s-seccion-amplia:   clamp(7rem, 17vw, 17rem);
  --s-seccion-apretada: clamp(4rem, 9vw, 8.5rem);
  --s-borde:   clamp(1.35rem, 5vw, 5rem);

  --ancho-angosto: 40rem;
  --ancho-normal:  74rem;
  --ancho-ancho:   82rem;
  --ancho-amplio:  92rem;
}

/* ------------------------------------------------------------
   9. MOVIMIENTO
   ------------------------------------------------------------ */
:root {
  --ease-suave:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-entrada: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-rapida: 200ms;
  --dur-media:  460ms;
  --dur-lenta:  900ms;
}

/* ------------------------------------------------------------
   10. BASE
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
  background: var(--fondo);
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--f-texto);
  font-size: var(--t-body);
  font-weight: var(--peso-cuerpo);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: var(--tr-titulo);
  text-wrap: balance;
  margin: 0;
  color: var(--texto);
}

p {
  max-width: 62ch;
  text-wrap: pretty;
  margin: 0 0 1.2em;
}

a { color: inherit; text-decoration: none; }

img, video, svg { max-width: 100%; height: auto; display: block; }

button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--acento-texto);
  outline-offset: 3px;
}

::selection { background: var(--magenta); color: var(--negro); }

* { scrollbar-color: var(--barra); }

/* ------------------------------------------------------------
   11. PATRONES
   ------------------------------------------------------------ */
.display {
  font-family: var(--f-display);
  font-size: var(--t-display);
  font-weight: 700;
  line-height: 0.88;
  letter-spacing: var(--tr-display);
  text-wrap: balance;
}

.et {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--texto-tenue);
  line-height: 1.6;
}
/* En mono chico el magenta pleno no llega a AA sobre papel: va el de texto */
.et--acento { color: var(--acento-texto); }

.seccion { padding: var(--s-seccion) var(--s-borde); position: relative; }
.seccion--amplia   { padding-block: var(--s-seccion-amplia); }
.seccion--apretada { padding-block: var(--s-seccion-apretada); }

.cont          { max-width: var(--ancho-normal);  margin-inline: auto; }
.cont--angosto { max-width: var(--ancho-angosto); margin-inline: auto; }
.cont--ancho   { max-width: var(--ancho-ancho);   margin-inline: auto; }
.cont--amplio  { max-width: var(--ancho-amplio);  margin-inline: auto; }

.filete {
  display: inline-block;
  width: 34px;
  height: 2px;
  background: var(--acento-texto);
  flex-shrink: 0;
}

.reveal {
  opacity: 0;
  transform: translateY(1.6rem);
  transition:
    opacity   var(--dur-media) var(--ease-suave) calc(var(--i, 0) * 70ms),
    transform var(--dur-media) var(--ease-suave) calc(var(--i, 0) * 70ms);
}
.reveal.visible { opacity: 1; transform: none; }

/* ------------------------------------------------------------
   12. ISOTIPO — el anillo del manual, en SVG

   Antes se dibujaba con border-radius + border-right-color:transparent.
   Ese truco exige fijar width Y height: donde faltaba el height (las
   marcas de agua sobre foto) el círculo colapsaba en una elipse chata
   que, rotada 45°, se veía como una mancha. Medido: 24×10 y 27×11.

   En SVG el viewBox garantiza la proporción y el bug no puede volver.
   Geometría del manual: grosor = diámetro × 0,2217 y corte de 90° sobre
   el eje diagonal. El dash de un <circle> arranca a las 3 en punto, así
   que el hueco cae solo a la 1:30: no lleva rotate.
   ------------------------------------------------------------ */
.iso {
  display: block;
  flex-shrink: 0;
  width: 22px;
  aspect-ratio: 1;
  color: var(--magenta);
}
.iso circle { stroke: currentColor; }
.iso__disco { fill: var(--iso-disco); stroke: none; }
/* Sobre un bloque magenta el anillo se pierde: pasa a papel */
.magenta .iso { color: var(--blanco); }

/* ------------------------------------------------------------
   13. GRANO — port de "noise-texture" (Magic UI), re-teñido

   El grano que había no declaraba width/height en el data URI, así que
   el navegador rasterizaba la turbulencia a pantalla completa: medido,
   144,2 ms de pintado a 1920×1080 contra 33,1 ms con el tile de 180px.
   color-interpolation-filters='sRGB' es obligatorio — por defecto los
   filtros SVG corren en linearRGB y todo sale ~50% más claro.

   OJO: el 180 del tile tiene que coincidir con el width/height de
   adentro del data URI. Son dos lugares y se tocan juntos.
   ------------------------------------------------------------ */
:root {
  --grano-tile: 180px;
  --grano-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: var(--grano);
  background-image: var(--grano-img);
  background-size: var(--grano-tile) var(--grano-tile);
  background-repeat: repeat;
}

.ruido {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: var(--grano-parche);
  background-image: var(--grano-img);
  background-size: var(--grano-tile) var(--grano-tile);
  background-repeat: repeat;
  -webkit-mask-image: radial-gradient(
    var(--ruido-radio, 620px) circle at var(--ruido-x, 50%) var(--ruido-y, 34%),
    #000 0%, oklch(0 0 0 / 0.55) 45%, transparent 74%);
  mask-image: radial-gradient(
    var(--ruido-radio, 620px) circle at var(--ruido-x, 50%) var(--ruido-y, 34%),
    #000 0%, oklch(0 0 0 / 0.55) 45%, transparent 74%);
}

/* ------------------------------------------------------------
   14. CAMBIO DE TEMA — View Transitions

   La animación ES el recorte circular, no un fundido. Si se deja el
   cross-fade del navegador, pisa al clip-path y sale todo lavado.
   NO poner transition sobre los colores del tema: corre al mismo tiempo
   que la snapshot y se ve el fondo degradando adentro del recorte.
   ------------------------------------------------------------ */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-old(root) { z-index: 0; }
::view-transition-new(root) { z-index: 1; }

html[data-tema-vt="activo"]::view-transition-group(root) {
  animation-duration: var(--tema-vt-dur, 520ms);
}
html[data-tema-vt="activo"]::view-transition-new(root) {
  clip-path: var(--tema-vt-clip);
}

/* ------------------------------------------------------------
   15. ACCESIBILIDAD
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

.solo-lector {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
