/* ============================================================================
   tokens.css — Link in bio · Jhei Trujillo
   ---------------------------------------------------------------------------
   ÚNICA fuente de valores literales del proyecto. styles.css no contiene ni un
   hex ni un px de espaciado: solo consume estos tokens.
   Paleta y tipografía heredadas de docs/brand/aivi-brand-extract.md.
   Cambiar la marca entera = cambiar este archivo.
   ========================================================================= */

/* ── Tipografía auto-hospedada · 0 peticiones a terceros ─────────────────── */
@font-face {
  font-family: "Hanken Grotesk";
  src: url("../assets/fonts/hanken-grotesk-latin-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("../assets/fonts/hanken-grotesk-latin-ext-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    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;
}

:root {
  color-scheme: dark;

  /* ══ 1 · Paleta oficial AIVI ═════════════════════════════════════════════
     Los 5 valores de la guía. Prohibido añadir un 6º color de marca.        */
  --ink: #101010;          /* "inteligencia y control" */
  --paper: #fafafa;        /* "simplicidad y entendimiento" */
  --fire-red: #ff413b;     /* tono de acción */
  --fire-orange: #fe803f;  /* tono de acción */
  --fire-gold: #ffc252;    /* tono de acción */

  /* Componentes RGB, para construir alphas sin repetir literales.
     Uso: rgb(var(--rgb-paper) / 12%)                                        */
  --rgb-ink: 16 16 16;
  --rgb-paper: 250 250 250;
  --rgb-red: 255 65 59;
  --rgb-orange: 254 128 63;
  --rgb-gold: 255 194 82;

  /* Derivados: oscurecimientos y aclarados del MISMO hue, no colores nuevos.
     Necesarios para los fondos profundos y el núcleo de luz de los haces.   */
  --ink-deep: #060606;     /* caída a negro en los bordes del viewport */
  --ink-warm: #1a1310;     /* núcleo cálido del fondo, zona superior */
  --fire-800: #a8280c;     /* pie de la card de colaboración */
  --fire-glare: #fff3d0;   /* núcleo casi blanco del haz de luz */
  --rgb-glare: 255 243 208;

  /* ══ 1 bis · Rampa de acero · el decorado de la página ═══════════════════
     La página es NEUTRA: filos, resplandores, filetes y titulares van en
     grises fríos, no en fuego. El fuego de AIVI sigue declarado arriba y
     sigue disponible (`row--fire`), pero ya no decora nada.

     El motivo es de jerarquía, no de gusto. Los dos talleres se venden con
     color —teal y verde— y el color solo funciona como señal si es escaso.
     Con el naranja repartido por filos, fondos, titulares y flechas, la
     página tenía color en todas partes y los talleres no destacaban por
     tenerlo, sino a pesar de tenerlo todo el mundo. En gris, los dos únicos
     bloques de color de la página son justo los dos que hay que pulsar.

     El gris tiene un punto de azul (los canales suben R<G<B): un gris neutro
     puro sobre negro se lee sucio, y el frío es lo que da la lectura de metal
     en vez de la de polvo.

     Ratios sobre --ink: deep 2.34:1 (solo decorativo, nunca texto ni límite
     de control), soft 9.98:1, steel 6.72:1, lit 13.56:1, glare 17.42:1.     */
  --steel-deep: #4b5058;
  --steel: #949aa4;
  --steel-soft: #b8bec7;
  --steel-lit: #d6dae0;
  --steel-glare: #f3f5f8;

  /* ── Acentos de contenido · NO son colores de marca ──────────────────────
     Excepción consciente a la prohibición de arriba, y el ÚNICO color que
     queda en la página: todo el decorado es gris. Existen porque hay dos
     talleres distintos en la lista y con el mismo tratamiento se leían como
     el mismo producto duplicado.

     Cada uno RELLENA su fila entera. Es la razón de que funcionen: sobre
     vidrio negro, un icono de color dentro de una fila idéntica a las demás
     sigue siendo una fila oscura más.

     Van APAGADOS. La primera versión usaba el hue casi a saturación plena
     (teal al 70%, verde al 98%) y leía como neón — el color puro y brillante
     es señal de barato, no de caro. Al 42% y 40% cada taller se sigue
     identificando de un vistazo y deja de gritar.

     Bajar la saturación manteniendo la luz SUBE el contraste, no lo baja: el
     peor punto pasó de 4.75:1 a 4.95:1. Desaturar hacia el gris a la misma
     luminosidad nunca oscurece; lo que oscurece es bajar la luz, y eso aquí
     no se toca.

     Las paradas -deep y -lit son oscurecimiento y aclarado del MISMO hue, no
     colores nuevos — la misma lógica que --fire-800 y --fire-glare tienen con
     el fuego. La -deep es además el punto de MENOR contraste de todo el
     degradado, así que es la que decide si el texto negro se lee. Las mide
     tools/check-contrast.py, pareja por pareja. */
  --accent-aesthetic-deep: #3da79e;
  --accent-aesthetic: #4fb8ae;   /* azul verdoso — taller de estética */
  --accent-aesthetic-lit: #6ac8bf;
  --accent-aesthetic-glare: #85d5cd;
  --rgb-aesthetic: 79 184 174;

  --accent-sales-deep: #3ea466;
  --accent-sales: #52b578;       /* verde — taller de contenido que vende */
  --accent-sales-lit: #71c793;
  --accent-sales-glare: #8dd3aa;
  --rgb-sales: 82 181 120;

  /* ══ 2 · Superficies de vidrio ═══════════════════════════════════════════
     Blanco a alpha creciente sobre negro. Nunca gris opaco (regla AIVI).    */
  --surface-glass: rgb(var(--rgb-paper) / 4.5%);
  --surface-glass-hi: rgb(var(--rgb-paper) / 8.5%);
  --surface-fire: rgb(var(--rgb-orange) / 14%);
  --surface-load: #141414;  /* color de carga bajo las imágenes */

  /* Vidrio OSCURO, al revés que los de arriba: negro a alpha alta en vez de
     blanco a alpha baja. Va encima de fotos que el cliente puede cambiar por
     cualquier otra, así que el texto no puede depender de lo que haya debajo.
     Al 85% el peor caso posible es una foto blanca pura: el fondo compuesto
     queda en rgb(52 52 52) y ahí el texto blanco mide 11.92:1 y el atenuado
     4.93:1. Los dos por encima del mínimo. Bajar de 85% rompe eso. */
  --surface-glass-dark: rgb(var(--rgb-ink) / 85%);

  /* Fila de enlace: apenas más clara que el fondo. Es el componente principal
     de la página y tiene que leerse como vidrio sobre negro, no como un
     botón de color. */
  --surface-row: rgb(var(--rgb-paper) / 3%);
  --surface-row-hi: rgb(var(--rgb-paper) / 6.5%);

  --grad-row: linear-gradient(160deg,
    rgb(var(--rgb-paper) / 5.5%) 0%,
    rgb(var(--rgb-paper) / 1.5%) 60%,
    rgb(var(--rgb-paper) / 2.5%) 100%);

  /* Lustre que se enciende bajo los círculos de redes al pasar el cursor.
     Fue la baldosa del icono de las filas hasta que la baldosa se retiró;
     sobrevive porque el efecto de las redes es exactamente el mismo vidrio. */
  --grad-sheen: linear-gradient(155deg,
    rgb(var(--rgb-paper) / 14%) 0%,
    rgb(var(--rgb-paper) / 5%) 100%);


  /* ══ 3 · Bordes ══════════════════════════════════════════════════════════
     -hair   → separadores decorativos
     -soft   → bordes de panel de vidrio
     -strong → 3.03:1 sobre --ink. Único válido si el borde ES la señal
               de que algo es un control (WCAG 1.4.11).                      */
  --border-hair: rgb(var(--rgb-paper) / 10%);
  --border-soft: rgb(var(--rgb-paper) / 12%);
  --border-strong: rgb(var(--rgb-paper) / 34%);
  --border-marker: rgb(var(--rgb-paper) / 34%);  /* marcador de dato pendiente */

  /* Filo plano de reserva para `.stroke`. Solo entra donde el trazo en
     degradado no puede pintarse: sin soporte de máscara y en transparencia
     reducida. Nunca se ve a la vez que el degradado. */
  --border-edge: rgb(var(--rgb-paper) / 22%);

  /* ══ 4 · Texto · ratios medidos sobre --ink ══════════════════════════════ */
  --text-primary: var(--paper);                  /* 18.23:1 */
  --text-secondary: rgb(var(--rgb-paper) / 88%); /* 14.15:1 */
  --text-body: rgb(var(--rgb-paper) / 82%);      /* 12.33:1 */
  --text-muted: rgb(var(--rgb-paper) / 56%);     /*  6.19:1 — mínimo del sistema */
  /* Etiquetas, cifras, flechas encendidas y todo lo que antes iba dorado.
     Plata fría, no blanco: a 11.41:1 se separa del texto principal (18.23:1)
     lo justo para leerse como una capa distinta sin pedir más atención.     */
  --text-accent: #c3c9d1;                        /* 11.41:1 */
  --text-orange: var(--fire-orange);             /*  7.59:1 — sin uso hoy */

  /* Texto sobre el degradado de fuego: NEGRO, no blanco.
     Blanco sobre #FFC252 da 1.54:1 (fallo grave). Negro da 11.86:1 sobre el
     dorado, 7.59:1 sobre el naranja y 5.50:1 sobre el rojo — AA en todo el
     recorrido del degradado, incluido su estado caliente de hover.          */
  --text-on-fire: var(--ink);

  /* Subtítulo sobre el relleno de fuego. Medido en el extremo ROJO (#FF413B),
     que es el peor punto del degradado: 4.67:1 — AA para texto normal. No
     bajar del 84%: al 82% cae a 4.54:1 y el margen desaparece.
     Lo verifica tools/check-contrast.py. */
  --text-on-fire-soft: rgb(var(--rgb-ink) / 84%);

  /* El texto sobre CUALQUIER relleno saturado de la página es el mismo negro,
     venga del fuego o de un acento de taller. Los alias existen para que el
     CSS del componente no tenga que saber de qué color se rellenó la fila.
     Sobre el teal el blanco mide 1.86:1 y sobre el verde 1.49:1: los dos son
     fallos graves, así que aquí no hay elección de estilo que tomar. */
  --text-on-fill: var(--text-on-fire);
  --text-on-fill-soft: var(--text-on-fire-soft);

  /* ══ 5 · Degradados ══════════════════════════════════════════════════════ */
  --grad-fire: linear-gradient(118deg,
    var(--fire-red) 0%, var(--fire-orange) 52%, var(--fire-gold) 100%);

  /* Estado caliente del CTA. No se mueven los stops (eso sería repaint):
     se cruza por opacidad con el degradado base.                            */
  --grad-fire-hot: linear-gradient(118deg,
    #ff5a46 0%, #ff9a52 38%, #ffd887 76%, var(--fire-glare) 100%);

  /* ── Rellenos de acento · las dos filas de taller ─────────────────────────
     Mismo ángulo (118deg) y misma estructura que --grad-fire: profundo →
     base → aclarado. Que compartan geometría es lo que hace que las tres
     filas rellenas de la página se lean como el mismo componente en tres
     colores, y no como tres botones de tres sitios distintos.

     El estado caliente arranca en la parada BASE, no en la profunda: así
     todo el degradado encendido queda por encima del color de reposo y el
     contraste del texto negro solo puede subir, nunca bajar. */
  --grad-fill-aesthetic: linear-gradient(118deg,
    var(--accent-aesthetic-deep) 0%,
    var(--accent-aesthetic) 52%,
    var(--accent-aesthetic-lit) 100%);

  --grad-fill-aesthetic-hot: linear-gradient(118deg,
    var(--accent-aesthetic) 0%,
    var(--accent-aesthetic-lit) 55%,
    var(--accent-aesthetic-glare) 100%);

  --grad-fill-sales: linear-gradient(118deg,
    var(--accent-sales-deep) 0%,
    var(--accent-sales) 52%,
    var(--accent-sales-lit) 100%);

  --grad-fill-sales-hot: linear-gradient(118deg,
    var(--accent-sales) 0%,
    var(--accent-sales-lit) 55%,
    var(--accent-sales-glare) 100%);

  /* ── Trazo en degradado ───────────────────────────────────────────────────
     El trazo se pinta con un pseudo-elemento enmascarado, NO con border-image:
     border-image ignora el border-radius y todas estas píldoras son redondas.
     El estado en reposo lleva alpha para que el trazo acompañe sin gritar; el
     caliente va a alpha plena y remata en el destello.

     El recorrido es claro → apagado → claro, no de un color a otro: eso es
     lo que lee como canto de metal biselado y no como una línea de color.
     Que el punto apagado esté en MEDIO importa — con el apagado en un
     extremo, el filo parece mal impreso en vez de torneado.

     Alphas fijadas por contraste NO TEXTUAL (WCAG 1.4.11): en `.social` el
     trazo es la ÚNICA señal de que el círculo es un control (el vidrio de
     fondo da 1.10:1 contra --ink), así que ninguna parada puede bajar de
     3:1 contra --ink. Medido: 66% → 8.23:1, 38% → 3.46:1, 62% → 7.40:1. La
     parada del medio es la que manda: por debajo del 34% deja de cumplir.
     Lo vigila tools/check-contrast.py. */
  --grad-stroke: linear-gradient(135deg,
    rgb(var(--rgb-paper) / 66%) 0%,
    rgb(var(--rgb-paper) / 38%) 46%,
    rgb(var(--rgb-paper) / 62%) 100%);

  --grad-stroke-hot: linear-gradient(135deg,
    var(--steel-glare) 0%,
    rgb(var(--rgb-paper) / 72%) 42%,
    var(--paper) 78%,
    var(--steel-glare) 100%);

  /* Para background-clip:text. Solo en titulares ≥26px (§jerarquía).

     Brillo de plata: apenas se mueve de --steel-soft a casi blanco. Un
     degradado de gris más abierto se lee como texto mal renderizado, no como
     un reflejo; el recorrido corto es lo que lo hace parecer material.

     Arranca en --steel-soft (10.17:1 sobre --ink) y no más abajo porque este
     token también pinta la palabra clave del hero, que va sobre el velo de
     la FOTO y no sobre negro plano. Ahí el ratio cae en torno a un 15% y
     --steel (6.72:1) dejaría el peor punto rozando el mínimo. */
  --grad-text-shine: linear-gradient(92deg,
    var(--steel-soft) 0%, var(--steel-lit) 55%, var(--steel-glare) 100%);

  /* Filete ornamental y punto separador: el mismo metal, con volumen. */
  --grad-steel: linear-gradient(118deg,
    var(--steel-deep) 0%, var(--steel) 52%, var(--steel-lit) 100%);

  /* Vidrio: la luz entra por arriba-izquierda, como en las piezas AIVI.     */
  --grad-glass: linear-gradient(158deg,
    rgb(var(--rgb-paper) / 8.5%) 0%,
    rgb(var(--rgb-paper) / 3.5%) 46%,
    rgb(var(--rgb-paper) / 2%) 100%);

  /* Núcleo de luz del CTA: se coloca SIEMPRE en el lado del mockup.         */
  --grad-core: radial-gradient(130% 190% at 88% 6%,
    rgb(var(--rgb-glare) / 44%) 0%,
    rgb(var(--rgb-glare) / 14%) 30%,
    rgb(var(--rgb-glare) / 0%) 62%);

  /* ══ 6 · Tipografía ══════════════════════════════════════════════════════ */
  --font-sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;

  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semi: 600;
  --fw-bold: 700;
  --fw-black: 900;

  /* Escala fluida resuelta para dar el mínimo a 360px exactos y el máximo a
     1440px exactos. Pendiente = (max − min) / 1080px, expresada en vw.       */
  --fs-display: clamp(2.5rem, 1.4167rem + 4.8148vw, 5.75rem);   /* 40 → 92 */
  --fs-h1: clamp(2rem, 1.5rem + 2.2222vw, 3.5rem);              /* 32 → 56 */
  --fs-h2: clamp(1.625rem, 1.25rem + 1.6667vw, 2.75rem);        /* 26 → 44 */
  --fs-h3: clamp(1.25rem, 1.0833rem + 0.7407vw, 1.75rem);       /* 20 → 28 */
  --fs-lead: clamp(1.0625rem, 1rem + 0.2778vw, 1.25rem);        /* 17 → 20 */
  --fs-body: clamp(1rem, 0.9583rem + 0.1852vw, 1.125rem);       /* 16 → 18 */
  --fs-small: clamp(0.875rem, 0.8542rem + 0.0926vw, 0.9375rem); /* 14 → 15 */
  --fs-micro: clamp(0.6875rem, 0.6458rem + 0.1852vw, 0.8125rem);/* 11 → 13 */
  --fs-row: clamp(1.0625rem, 0.9792rem + 0.3704vw, 1.375rem);   /* 17 → 22 */
  --fs-eyebrow: clamp(0.6875rem, 0.6042rem + 0.3704vw, 0.9375rem);/* 11 → 15 */

  /* Tracking. La página no usa mayúscula sostenida en ningún selector, y
     tools/check-rules.py lo vigila sin excepciones. Los negativos afinan el
     peso 900 de los títulos grandes, que sin ellos se leen sueltos. Los
     positivos son un recurso de énfasis para texto pequeño en caja baja, no
     una compensación de mayúscula: de ellos, hoy solo `--ls-wide` está en
     uso, en dos etiquetas cortas — `.links__num` y `.bio__handle` — que
     necesitan algo de aire para leerse como etiqueta y no como prosa. */
  --ls-display: -0.042em;
  --ls-h1: -0.032em;
  --ls-h2: -0.026em;
  --ls-h3: -0.018em;
  --ls-none: 0em;
  --ls-wide: 0.06em;
  --ls-wider: 0.12em;
  --ls-widest: 0.16em;
  --ls-chip: 0.01em;

  --lh-display: 0.88;
  --lh-tight: 1;
  --lh-snug: 1.12;
  --lh-normal: 1.4;
  --lh-relaxed: 1.65;

  --measure: 46ch;  /* máximo de línea en párrafos */

  /* ══ 7 · Espaciado · base 4px ════════════════════════════════════════════ */
  --sp-1: 0.25rem;   /*   4 */
  --sp-2: 0.5rem;    /*   8 */
  --sp-3: 0.75rem;   /*  12 */
  --sp-4: 1rem;      /*  16 */
  --sp-5: 1.25rem;   /*  20 */
  --sp-6: 1.5rem;    /*  24 */
  --sp-7: 2rem;      /*  32 */
  --sp-8: 2.5rem;    /*  40 */
  --sp-9: 3rem;      /*  48 */
  --sp-10: 3.5rem;   /*  56 */
  --sp-11: 4rem;     /*  64 */
  --sp-12: 5rem;     /*  80 */

  /* Ritmo fluido del documento */
  --sp-section: clamp(3.5rem, 2.3333rem + 5.1852vw, 7rem); /* 56 → 112 */
  --sp-gutter: clamp(1.25rem, 0.8333rem + 1.8519vw, 2.5rem); /* 20 → 40 */
  --sp-stack: clamp(1rem, 0.8333rem + 0.7407vw, 1.5rem);   /* 16 → 24 */

  /* ══ 8 · Anchos ══════════════════════════════════════════════════════════ */
  /* Eje único: 465px de margen izquierdo a 1440px de viewport en TODOS los
     bloques (hero, enlaces, colaboraciones, bio, redes, footer), incluida su
     chip, su titular y el botón de pausa. La cinta de tarjetas es la única
     excepción a propósito: no lleva `.shell`, se desborda al viewport
     completo, y su chip/titular/botón vuelven al mismo eje que el resto. */
  --w-col: 38.75rem;  /* 620px — CTA, footer, chip y titular de colaboraciones */
  --w-read: 34rem;    /* 544px — párrafos */

  /* 1120px — bloques anchos: el hero y la bio. Son los dos únicos con
     contenido a dos lados, y en 620px uno de los dos lados queda en una tira.
     Se centran como el resto, así que su borde exterior NO cae en el eje de
     las demás secciones; el texto de dentro sí, porque lleva su propio
     `.shell`. */
  --w-wide: 70rem;
  --tap-min: 44px;    /* objetivo táctil mínimo */

  /* ══ 9 · Radios ══════════════════════════════════════════════════════════ */
  --r-xs: 0.5rem;     /*  8 */
  --r-sm: 0.75rem;    /* 12 */
  --r-md: 1rem;       /* 16 */
  --r-lg: 1.375rem;   /* 22 */
  --r-cta: 1.5rem;    /* 24 */
  --r-cta-lg: 1.75rem;/* 28 */
  --r-full: 999px;

  /* EXCEPCION: 1.5px queda fuera de la escala de 4px. Es el grosor mínimo al
     que un trazo en degradado se sigue leyendo COMO degradado a 1x; a 1px el
     antialiasing se come los stops intermedios y queda un borde naranja plano. */
  --sw-stroke: 1.5px;

  /* ══ 10 · Sombras ════════════════════════════════════════════════════════
     Sobre #101010 una sombra negra apenas se lee: la elevación se comunica
     con el filo interior superior (--sh-lip) y con el glow de fuego.        */
  --sh-1: 0 1px 2px rgb(0 0 0 / 40%);
  --sh-2: 0 6px 18px -6px rgb(0 0 0 / 55%);
  --sh-3: 0 18px 40px -14px rgb(0 0 0 / 70%);
  --sh-4: 0 28px 64px -20px rgb(0 0 0 / 78%);

  --sh-lip: inset 0 1px 0 rgb(255 255 255 / 30%);
  --sh-lip-in: inset 0 -1px 0 rgb(0 0 0 / 22%);
  --sh-glass: inset 0 1px 0 rgb(var(--rgb-paper) / 10%);

  --sh-fire: 0 10px 30px -14px rgb(var(--rgb-red) / 42%);
  --sh-fire-soft: 0 8px 24px -10px rgb(var(--rgb-orange) / 28%);

  /* Elevación y resplandor de las filas de taller. Alphas más bajas que las
     del fuego: con el color ya apagado, un halo fuerte lo devolvía al
     registro de neón por la puerta de atrás. La fila tiene que parecer
     apoyada sobre la página, no encendida. */
  --sh-fill-aesthetic: 0 10px 30px -16px rgb(var(--rgb-aesthetic) / 40%);
  --sh-fill-aesthetic-hi: 0 0 38px -14px rgb(var(--rgb-aesthetic) / 30%);
  --sh-fill-sales: 0 10px 30px -16px rgb(var(--rgb-sales) / 40%);
  --sh-fill-sales-hi: 0 0 38px -14px rgb(var(--rgb-sales) / 30%);
  /* Halo de las filas de vidrio y del retrato del hero. Blanco, no dorado:
     en una página neutra el único color que se derrama fuera de un borde es
     el de los dos talleres. Si el halo genérico también tuviera color, esa
     señal dejaría de ser suya. */
  --sh-halo: 0 0 34px -14px rgb(var(--rgb-paper) / 22%);
  --sh-halo-hi: 0 0 44px -12px rgb(var(--rgb-paper) / 32%);

  /* ══ 11 · Movimiento ═════════════════════════════════════════════════════
     Asimetría de ignición: encender rápido, apagar lento — como una brasa.
     La transición corta vive en el estado (:hover), la larga en la base.    */
  --d-tap: 90ms;     /* feedback táctil — presupuesto duro <100ms */
  --d-fast: 160ms;   /* ignición de color */
  --d-base: 240ms;   /* cambio de estado */
  --d-out: 320ms;
  /* Bucle de la cinta de colaboraciones. Largo a propósito: por debajo de
     ~40s el movimiento compite con la lectura en lugar de acompañarla. */
  --d-ribbon-cards: 70s;    /* apagado */
  --d-enter: 400ms;  /* entrada de bloque */
  --d-hero: 520ms;   /* foto del hero */
  --d-sweep: 700ms;  /* barrido de brillo del CTA */


  /* Sin overshoot en ninguna curva: la luz no rebota. */
  --e-light: cubic-bezier(0.16, 1, 0.3, 1);    /* propagación, toda entrada */
  --e-glide: cubic-bezier(0.22, 0.61, 0.36, 1);/* cambio de estado */
  --e-press: cubic-bezier(0.4, 0, 0.2, 1);     /* presión */
  --e-breathe: cubic-bezier(0.45, 0, 0.55, 1); /* respiración, simétrica */
  --e-sweep: cubic-bezier(0.32, 0, 0.12, 1);   /* barrido de luz */
  --e-fade: cubic-bezier(0.4, 0, 0.6, 1);      /* apagado */

  /* ══ 12 · z-index ════════════════════════════════════════════════════════
     El rango 1–9 está reservado a subárboles aislados (las capas de .bg).   */
  --z-backdrop: 0;
  --z-content: 10;
  --z-raised: 20;
  --z-skip: 100;

  /* ══ 13 · Foco ═══════════════════════════════════════════════════════════
     Anillo de DOS tonos, obligatorio. El anillo blanco sobre el relleno teal
     de un taller da 1.86:1 y sobre el verde 1.49:1: solo, fallaría 1.4.11 en
     los dos sitios donde más falta hace. El separador oscuro de 2px es lo
     que lo salva — mide 9.80:1 contra el teal, 12.28:1 contra el verde y
     18.23:1 contra el anillo, así que el indicador cumple 3:1 contra sus dos
     vecinos con un único tratamiento para toda la página.

     El anillo pasó de dorado a blanco con el resto del decorado. Como el
     blanco es más claro que el dorado contra los mismos vecinos, el cambio
     sube todos los ratios: no hubo que recalibrar nada.                     */
  --focus-halo: var(--ink);
  --focus-ring: var(--paper);
  --focus-aura: rgb(var(--rgb-paper) / 18%);
  --focus-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 5px var(--focus-ring),
    0 0 0 9px var(--focus-aura);
}
