/* Tokens de marca — LifeSugar
 *
 * COPIA de apps/panel/static/tokens.css. Cambiar los dos.
 * No se hereda el @media dark: este panel es modo claro (se imprime).
 *
 * Copiados de los tokens canónicos: lifesugar-hub/packages/brand/06-tokens/.
 * Aquí no se inventa ningún color. Cuando el fan-out de tokens del hub alcance a
 * este repo, este fichero se regenerará desde allí; hasta entonces, cambiar un
 * color es cambiarlo en el hub primero.
 *
 * Los valores y los nombres son los MISMOS que usa la web pública
 * (`lifesugar-web/src/brand/colors.css` + su bloque `@theme`), a propósito: el
 * panel es interno, pero que se parezca a la web no es coquetería — es que
 * quien salta de una a otro no tiene que releer qué significa cada color.
 *
 * Reglas de marca que este fichero respeta:
 *  - Ratio 60/30/10: mandan los neutrales, el azul es el acento de interacción y
 *    el crimson aparece solo en los números que señalan un problema.
 *  - `brand.crimson` (#DC143C) y `state.error` (#EF4444) son colores DISTINTOS.
 *    Crimson es marca (una cifra que exige atención); error es interfaz (una
 *    consulta que falló). No se usan juntos en el mismo bloque.
 *  - Nunca texto neutral-500 sobre neutral-100: no llega a contraste.
 */

/* ── Geist, autoalojada ──────────────────────────────────────────────────────
 * Los mismos ficheros que sirve la web (`lifesugar-web/public/fonts/`), y por la
 * misma razón por la que allí se dejó de usar Google Fonts: cargarla desde
 * fonts.gstatic.com manda la IP de cada visitante a Google en cada carga. Aquí
 * además el panel vive detrás de IAP, así que una petición a un tercero sería la
 * única que sale del perímetro.
 *
 * Antes de esto el panel declaraba `font-family: "Geist"` sin servirla, así que
 * caía a la fuente del sistema: decía Geist y se veía Segoe UI.
 *
 * `font-display: swap` — el texto se pinta ya con la fuente del sistema y cambia
 * al cargar. Un panel que tarda en pintar el primer número no sirve para nada.
 */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/geist-latin-wght-normal.woff2") format("woff2-variations");
  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: "Geist";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/geist-latin-ext-wght-normal.woff2") format("woff2-variations");
  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 {
  /* Marca */
  --primary:       #1976D2;
  --primary-dark:  #0D47A1;
  --primary-light: #42A5F5;
  --crimson:       #DC143C;
  --crimson-dark:  #A30E2E;
  /* Tintes del azul de marca. Los mismos que la web mapea sobre `blue-*`, y son
   * lo que hace que una pastilla de acento no parezca un botón. */
  --primary-50:    #E3F2FD;
  --primary-100:   #BBDEFB;
  --primary-700:   #0D47A1;

  /* Neutrales */
  --white: #FFFFFF;
  --n50:   #F8FAFC;
  --n100:  #F1F5F9;
  --n200:  #E2E8F0;
  --n300:  #CBD5E1;
  --n500:  #64748B;
  --n700:  #334155;
  --n900:  #0F172A;

  /* Estados de interfaz */
  --success: #10B981;
  --warning: #F59E0B;
  --error:   #EF4444;

  /* Roles: lo que el resto del CSS nombra. Cambiar el modo cambia estos, no los
   * colores de arriba. */
  --fondo:        var(--n50);
  --superficie:   var(--white);
  --superficie-2: var(--n100);
  --borde:        var(--n200);
  --borde-suave:  var(--n100);
  --texto:        var(--n900);
  --texto-medio:  var(--n700);
  --texto-suave:  var(--n500);
  --acento-fondo: var(--primary-50);
  --acento-borde: var(--primary-100);
  --acento-texto: var(--primary-700);

  /* Crimson, pero como ROL y no como color de marca suelto.
   *
   * `--crimson` es el color de la marca y no se toca. Esto es el color con el
   * que se ESCRIBE una alerta, que no es lo mismo: sobre fondo claro coinciden,
   * pero sobre el oscuro el crimson de marca da 3,42:1 contra la superficie
   * —medido en el panel— y un texto de 13px necesita 4,5:1. Quien no distingue
   * bien el rojo se queda sin leer justo el dato que más urge.
   *
   * Los rellenos grandes (el trozo KO de una barra) sí pueden llevar el crimson
   * de marca: una superficie de color no es texto y no juega en esa liga.
   *
   * Lo mismo pasa con el verde y el ámbar, y es más fácil de pasar por alto
   * porque en oscuro se ven perfectos. Medido sobre blanco: `--success` da
   * 2,54:1 y `--warning` 2,15:1 — una cifra de 25px en verde éxito sobre una
   * tarjeta blanca NO se lee, ni siquiera con el umbral relajado de texto
   * grande. Son colores pensados para rellenar, no para escribir.
   *
   * De ahí estos tres roles: el mismo significado, el tono que hace falta en
   * cada modo. Se usan SIEMPRE que el estado va en letra o en un punto pequeño;
   * las barras y los rellenos siguen usando el color de estado a secas. */
  --alerta:      var(--crimson-dark);
  /* Con qué se escribe ENCIMA del azul de marca. En claro es blanco; en oscuro
   * el azul se aclara a #42A5F5 y el blanco encima da 2,65:1 —medido, sobre la
   * hoja seleccionada de la barra—, o sea que el rótulo que dice dónde estás era
   * el texto menos legible de la pantalla. Sobre ese azul claro hay que escribir
   * en oscuro. */
  --sobre-primary: var(--white);
  --texto-bien:  #047857;
  --texto-aviso: #B45309;

  /* Alias shadcn: mismos roles que lifesugar-web/src/brand/colors.css.
   * El CSS del panel sigue nombrando --fondo/--texto; estos existen para que
   * el vocabulario sea el mismo y no se invente un segundo sistema. */
  --background:          var(--fondo);
  --foreground:          var(--texto);
  --card:                var(--superficie);
  --card-foreground:     var(--texto);
  --popover:             var(--superficie);
  --popover-foreground:  var(--texto);
  --primary-foreground:  var(--sobre-primary);
  --secondary:           var(--superficie-2);
  --secondary-foreground: var(--acento-texto);
  --muted:               var(--superficie-2);
  --muted-foreground:    var(--texto-suave);
  --accent:              var(--superficie-2);
  --accent-foreground:   var(--acento-texto);
  --destructive:         var(--error);
  --border:              var(--borde);
  --input:               var(--borde);
  --ring:                var(--primary);
  --radius:              var(--radio);

  /* Tipografía */
  --fuente: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --fuente-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  /* `letterSpacing.widest` de los tokens. La web lo usa en todas sus eyebrows y
   * Tailwind trae 0.1em por defecto, que está fuera de spec. */
  --track-eyebrow: 0.18em;
  --track-titular: -0.02em;

  /* ── Escala tipográfica ───────────────────────────────────────────────────
   * Siete escalones, y ni uno más. Había ONCE tamaños distintos en la hoja
   * —9, 10, 11, 11.5, 12, 12.5, 13, 14, 15, 22 y 25— que no salían de ninguna
   * escala: cada componente eligió el suyo al escribirlo. Eso no se ve como un
   * error concreto, se ve como que la pantalla «no está cuadrada», porque dos
   * textos del mismo rango se pintan a 12 y 12,5 sin que nada lo justifique.
   *
   * Cada escalón tiene un trabajo. Si un componente nuevo no encaja en ninguno,
   * el que sobra es el componente, no el escalón. */
  --t-micro:   10px;   /* versalitas: eyebrow, cabecera de tabla, etiqueta de KPI */
  --t-menor:   12px;   /* notas, ejes, pie de gráfico, traza */
  --t-denso:   13px;   /* controles, pastillas, títulos de sección */
  --t-base:    14px;   /* cuerpo */
  --t-destaca: 16px;   /* la marca */
  --t-titular: 22px;   /* h1 */
  --t-cifra:   26px;   /* el número de un KPI */

  /* Radios. El canónico es 0.75rem, el mismo `--radius` de la web.
   * Los tres escalones existen para poder anidar de forma CONCÉNTRICA: el radio
   * interior es el exterior menos el relleno, o las esquinas anidadas se ven
   * pellizcadas. */
  --radio:         12px;
  --radio-pequeno:  8px;
  --radio-menor:    6px;

  /* ── Anillo: lo que separa una tarjeta del fondo ──────────────────────────
   *
   * Sombras para elevación, bordes para estructura — y una tarjeta no es
   * estructura. Antes llevaba `border: 1px solid` Y sombra: se dibujaba dos
   * veces, y el filete es lo que convierte una página de datos en una hoja de
   * cajas. Con quince bloques en pantalla, quince rectángulos perfilados pesan
   * más que el contenido.
   *
   * Tres capas: la primera hace de filete de 1px, la segunda levanta, la tercera
   * da ambiente. Al ser transparentes funcionan sobre cualquier fondo, cosa que
   * un borde de color fijo no hace.
   *
   * Negro PURO, no el gris azulado de la paleta: un neutral teñido recoge el
   * color de la superficie de debajo y se lee como suciedad en el canto. */
  --anillo:
    0 0 0 1px rgba(0, 0, 0, .06),
    0 1px 2px -1px rgba(0, 0, 0, .06),
    0 2px 4px rgba(0, 0, 0, .04);
  --anillo-fuerte:
    0 0 0 1px rgba(0, 0, 0, .08),
    0 1px 2px -1px rgba(0, 0, 0, .08),
    0 2px 4px rgba(0, 0, 0, .06);

  /* Una sola curva para toda la interacción. Es la de la web
   * (`lsg-fade-up`), y usar la misma en los dos sitios es lo que hace que el
   * movimiento se reconozca sin pensarlo. */
  --curva: cubic-bezier(0.25, 0.4, 0.25, 1);
  --rapido: 130ms;
  --medio: 220ms;
}

/* Quien pide menos movimiento no lo pide a medias. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
