/* ============================================================================
   tokens.css — Link in bio · Dra. Jessica Castañeda
   ---------------------------------------------------------------------------
   ÚNICA fuente de valores literales del proyecto: styles.css no contiene ni un
   hex, solo consume estos tokens. Cambiar la marca entera = cambiar este
   archivo, y esa promesa solo se sostiene mientras nadie escriba un color a
   mano en la hoja de estilos —`tools/check-rules.py` lo vigila—.

   Los valores salen medidos del CSS de drajessicacastaneda.com, no de un
   cuentagotas sobre una captura. El detalle y las tres desviaciones
   deliberadas por accesibilidad están en docs/brand/jessica-brand-extract.md.
   ========================================================================= */

/* ── Tipografía autohospedada · 0 peticiones a terceros ──────────────────────
   Manrope es variable (200→800): un solo archivo por rango cubre los tres
   pesos que usa la página, y cambiar un peso no añade ninguna descarga.

   El `format()` va como "woff2" a secas y NO como "woff2-variations", que es
   lo que usaba el proyecto anterior. "woff2-variations" viene de una propuesta
   temprana y no todos los motores la reconocen; el que no la reconoce descarta
   el @font-face ENTERO y en silencio, y la página cae a la tipografía del
   sistema sin que nada avise. Google Fonts sirve fuentes variables con
   "woff2" a secas, y ahí es donde conviene estar.
   Libre Baskerville Italic es estática y solo existe en 400, que es el único
   peso en el que se usa.                                                     */
@font-face {
  font-family: "Manrope";
  src: url("../assets/fonts/manrope-latin-var.woff2") format("woff2");
  font-weight: 200 800;
  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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  src: url("../assets/fonts/manrope-latin-ext-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  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: "Libre Baskerville";
  src: url("../assets/fonts/libre-baskerville-italic-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Libre Baskerville";
  src: url("../assets/fonts/libre-baskerville-italic-latin-ext.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  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;
}

:root {
  color-scheme: light;

  /* ══ 1 · Paleta · Dra. Jessica Castañeda ═════════════════════════════════
     Medida del CSS de drajessicacastaneda.com, no de un cuentagotas sobre una
     captura. El detalle completo está en docs/brand/jessica-brand-extract.md.

     La familia entera es CÁLIDA: no hay un solo gris neutro. Los canales bajan
     R>G>B en todos los tonos, y eso es lo que hace que la página se lea como
     porcelana y no como papel de oficina. Un #f5f5f5 metido aquí se ve sucio
     al instante aunque sobre el papel parezca más limpio.                    */

  /* Cremas — el fondo de la página */
  --cream: #fbf7f4;         /* el fondo de todo */
  --cream-warm: #f7efe8;    /* bloques diferenciados */
  --cream-deep: #f4eae6;    /* el más oscuro de la familia */
  --card: #ffffff;          /* tarjetas sobre crema */

  /* Bordo — el respiro oscuro */
  --bordo: #ac5a53;         /* fondo del bloque de tratamientos y del footer */
  --bordo-lit: #c7827c;     /* terracota clara */
  --bordo-card: #854c47;    /* tarjeta dentro del bloque bordo */
  --bordo-deep: #753d38;    /* tarjeta honda dentro del bloque bordo */

  /* Coral — el acento */
  --coral-ink: #bb5047;     /* eyebrows · 4.53:1. Oscurecido desde el #cd7e77
                               de su web, que mide 2.88:1: el eyebrow es texto
                               que hay que leer, no un adorno. Mismo hue. */
  --coral: #d97f79;         /* asteriscos e iconos, uso no textual */
  --coral-soft: #d0b0ae;    /* filetes de acento */

  /* Las dos paradas del degradado del itálico. Van como tokens y no dentro del
     degradado porque check-contrast.py mide la parada clara por separado: es el
     peor punto del titular y tiene que poder comprobarse sola. */
  /* Las paradas de su web son #eba4a0 → #c4726b, y la clara mide 1.90:1 sobre
     la crema: por debajo del 3:1 que WCAG exige a texto grande. Se desplaza el
     recorrido entero hacia abajo en vez de solo levantar la parada clara,
     porque subir únicamente el extremo alto deja el degradado plano (amplitud
     3.0 frente a los 21.9 del suyo) y entonces no compensa tenerlo. Así
     conserva 16.7 de amplitud: sigue leyéndose como un recorrido. */
  --italic-from: #df6e68;   /* 3.00:1 */
  --italic-to: #8f4a44;     /* 6.10:1 */

  /* Tinta — marrón, nunca negro */
  --ink: #422924;           /* titulares y cuerpo */
  --ink-deep: #1c110c;      /* casi negro cálido */
  --ink-darkest: #360906;   /* marrón muy oscuro rojizo */

  /* Durazno — el wordmark sobre bordo */
  --peach: #fed5b6;

  /* Componentes RGB, para construir alphas sin repetir literales.
     Uso: rgb(var(--rgb-ink) / 12%)                                           */
  --rgb-cream: 251 247 244;
  --rgb-ink: 66 41 36;
  --rgb-bordo: 172 90 83;
  --rgb-coral: 217 127 121;
  --rgb-peach: 254 213 182;

  /* ══ 2 · Bordes ══════════════════════════════════════════════════════════
     Un solo filete para toda la página. Sobre fondo claro el borde es la única
     señal de que una tarjeta blanca es un control, así que mide 3:1 contra la
     crema y no puede aclararse "para que se vea más limpio".                 */
  --stroke-soft: #b48480;   /* filete de tarjeta · 3.01:1. Oscurecido desde el
                               #e8d9d8 de su web, que mide 1.28:1 — invisible
                               para quien no distinga bien los tonos claros, y
                               es lo único que dice dónde empieza el botón. */
  --stroke-w: 1px;

  /* ══ 3 · Texto · ratios medidos sobre --cream ════════════════════════════ */
  --text-primary: var(--ink);        /* 12.52:1 sobre la crema */
  --text-body: #5a3f39;              /*  8.94:1 — cuerpo largo */
  --text-muted: #7a5a53;             /*  5.77:1 — pies y notas */
  --text-on-bordo: var(--cream);     /*  4.54:1 sobre --bordo, 6.31:1 sobre
                                        --bordo-card. Por eso el footer, que
                                        lleva texto atenuado, usa el segundo. */
  --text-on-bordo-muted: rgb(var(--rgb-cream) / 82%);

  /* ══ 4 · Degradados ══════════════════════════════════════════════════════ */

  /* El itálico de acento. Es el gesto que más define su marca: arriba rosa
     claro, abajo terracota, recortado sobre las letras. Sin él el titular se
     lee plano y la página deja de parecerse a la suya aunque el color medio
     coincida. */
  --grad-italic: linear-gradient(180deg, var(--italic-from) 0%, var(--italic-to) 100%);

  /* Botón primario. Los cuatro puntos de parada y el ángulo salen tal cual de
     su web. Las paradas intermedias no son redondas y no hay que redondearlas:
     son lo que hace que el rosa parezca iluminado por la izquierda en vez de
     un degradado de dos colores. */
  --grad-cta: linear-gradient(263deg,
    #ecbab5 0%, #f7cdc9 46.05%, #f5bfbc 70.95%, #db8e87 100%);

  /* El asterisco va en un data: URI y no en un archivo suelto: son 180 bytes,
     menos de lo que costaría la petición para traerlos. */
  --aster-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g stroke="black" stroke-width="3" stroke-linecap="round"><path d="M12 3v18M4.2 7.5l15.6 9M4.2 16.5l15.6-9"/></g></svg>');

  /* Las mismas cuatro curvas del fondo, para repetirlas por debajo de la
     primera pantalla. Es una COPIA del SVG en línea de index.html y tiene que
     seguir siéndolo: si se cambia un trazo allí, hay que cambiarlo aquí o
     aparecerá una costura donde el mosaico empieza.

     El color va escrito porque en un data: URI no existe `currentColor`: la
     imagen se resuelve fuera del documento y no hereda nada. Es el mismo
     #d0b0ae de --coral-soft. */
  --curvas: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 900" fill="none" preserveAspectRatio="xMidYMid slice"><g stroke="%23d0b0ae" stroke-width="1"><path d="M-40 210C220 210 300 40 520 40s300 170 560 170"/><path d="M-40 470C260 470 340 250 620 250s340 220 660 220"/><path d="M-40 730C300 730 380 500 700 500s360 230 680 230"/><circle cx="980" cy="330" r="150"/></g></svg>');

  /* ══ 5 · Tipografía ══════════════════════════════════════════════════════ */
  --font-sans: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "Libre Baskerville", Georgia, "Times New Roman", serif;
  /* La página no usa monoespaciada. El token sigue declarado porque
     check-rules.py lo exige en la única forma en que permite versales —la
     etiqueta micro— y borrarlo dejaría esa regla apuntando al vacío. */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semi: 600;
  --fw-bold: 700;
  --fw-extra: 800;   /* el peso máximo de Manrope, para las cifras del hero */
  --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.       */
  /* Bajado de 32→56 a 28→46 a petición del cliente: a 56px el titular pesaba
     más que la propia foto y empujaba los botones. Lo consume solo
     `.hero__title`, así que el cambio no toca ningún otro bloque. */
  --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 — pero hoy ninguno de los tres tiene
     consumidor: `.links__num` y `.bio__handle`, las dos etiquetas que iban a
     usar `--ls-wide`, no existen en el marcado actual. Se dejan declarados
     porque son parte de la escala del sistema, no de un componente concreto,
     y el día que una etiqueta corta los necesite ya están medidos. */
  --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;

  /* ══ 6 · 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 */

  /* ══ 7 · Anchos ══════════════════════════════════════════════════════════ */
  /* --w-col es el max-width que reutiliza `.shell` (styles.css, sección 4) en
     enlaces, bio, redes y footer. NO produce un margen izquierdo único: cada
     `.shell` centra dentro de un contenedor distinto y esos contenedores no
     comparten ancho, así que a 1440px de viewport el margen medido varía por
     bloque (hero 102px, bio 200px, enlaces/redes/footer 450px). El detalle de
     por qué difiere está en el comentario de `.shell` en styles.css. */
  --w-col: 38.75rem;  /* 620px — CTA y footer */
  --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 */

  /* ══ 8 · 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-xl: 2.25rem;    /* 36 */
  --r-full: 999px;

  /* ══ 9 · Sombras ════════════════════════════════════════════════════════
     Todas son MARRONES, no negras, y mucho más suaves que en la página
     oscura. Una sombra negra al 55% sobre crema no se lee como profundidad
     sino como una mancha: el ojo la interpreta como polvo sobre el papel.    */
  --sh-1: 0 1px 2px rgb(var(--rgb-ink) / 6%);
  --sh-2: 0 6px 18px -6px rgb(var(--rgb-ink) / 10%);
  --sh-3: 0 18px 40px -14px rgb(var(--rgb-ink) / 14%);
  --sh-4: 0 28px 64px -20px rgb(var(--rgb-ink) / 18%);
  --sh-lip: inset 0 1px 0 rgb(255 255 255 / 70%);
  --sh-tile: var(--sh-2), var(--sh-lip);
  --sh-cta: 0 10px 26px -10px rgb(var(--rgb-coral) / 45%);
  --sh-cta-hi: 0 14px 34px -10px rgb(var(--rgb-coral) / 58%);

  /* ══ 10 · 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;
  --d-ital-brillo: 7s;   /* barrido del itálico: corto de barrido, larga la pausa */
  --d-trazo: 1.9s;       /* las curvas del fondo dibujándose */
  --d-respirar: 8s;      /* latido del resplandor tras la figura */
  --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 */

  /* ══ 11 · 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;

  /* ══ 12 · Foco ═══════════════════════════════════════════════════════════
     El anillo se invierte respecto a la página oscura: antes era un halo
     oscuro con aro claro, ahora es un halo claro con aro de tinta. La
     estructura de tres capas se mantiene porque es lo que hace que el foco se
     vea tanto sobre la crema como sobre el bordo.                            */
  --focus-halo: var(--cream);
  --focus-ring: var(--ink);
  --focus-aura: rgb(var(--rgb-ink) / 18%);
  --focus-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 5px var(--focus-ring),
                  0 0 0 9px var(--focus-aura);
}
