/* ============================================================================
   Samapp 1.0 — Tokens
   ----------------------------------------------------------------------------
   Regla de composición: 90% neutro / 10% color contextual.

   Los neutros construyen TODA la estructura: fondos, superficies, texto,
   bordes y controles. El color solo aparece cuando comunica algo — el área a
   la que pertenece algo, el estado de un pago, una acción destructiva. Si un
   color no responde a "¿qué significa esto?", no va.

   No hay gradientes decorativos. El único degradado permitido es funcional
   (la máscara de desvanecido al final de una lista con scroll).
   ========================================================================== */

/* ============================================================================
   SAMAPP 1.9.3 · TIPOGRAFÍA — QUICKSAND EN TODO
   ----------------------------------------------------------------------------
   Una sola voz, elegida por Ricardo: Quicksand (geométrica redondeada,
   28 KB, variable 400-700) para títulos, texto y cifras. Auto-hospedada:
   cero CDN, funciona offline, precacheada por el SW. La jerarquía la hacen
   el peso y el tamaño, no un cambio de familia. */
@font-face {
  font-family: 'Quicksand';
  src: url('../fonts/quicksand-latin-var.woff2?v=1.9.1') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* 2.1.2 — Emojis en línea, de un color, como los iconos SVG. El dueño no quiere
   emojis a color en la interfaz: los que escribe el usuario en sus nombres
   («Súper 🛒») se dibujan con Noto Emoji monocroma (Google, SIL OFL 1.1; licencia
   en fonts/noto-emoji/OFL.txt), que hereda el color del texto. Alojada aquí (la
   CSP sólo permite fuentes propias), partida por unicode-range: el navegador
   baja sólo la parte que necesita y el SW la guarda al primer uso. Va en la
   pila justo después de Quicksand, así que sólo toma lo que Quicksand no tiene. */
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.0.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1f1e6-1f1ff;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.1.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+2620, U+26a7, U+fe0f, U+1f308, U+1f38c, U+1f3c1, U+1f3f3-1f3f4, U+1f6a9, U+e0062-e0063, U+e0065, U+e0067, U+e006c, U+e006e, U+e0073-e0074, U+e0077, U+e007f;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.2.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+23, U+2a, U+30-39, U+a9, U+ae, U+200d, U+203c, U+2049, U+20e3, U+2122, U+2139, U+2194-2199, U+21a9-21aa, U+23cf, U+23e9-23ef, U+23f8-23fa, U+24c2, U+25aa-25ab, U+25b6, U+25c0, U+25fb-25fe, U+2611, U+2622-2623, U+2626, U+262a, U+262e-262f, U+2638, U+2640, U+2642, U+2648-2653, U+2660, U+2663, U+2665-2666, U+2668, U+267b, U+267e-267f, U+2695, U+269b-269c, U+26a0, U+26a7, U+26aa-26ab, U+26ce, U+26d4, U+2705, U+2714, U+2716, U+271d, U+2721, U+2733-2734, U+2747, U+274c, U+274e, U+2753-2755, U+2757, U+2764, U+2795-2797, U+27a1, U+27b0, U+27bf, U+2934-2935, U+2b05-2b07, U+2b1b-2b1c, U+2b55, U+3030, U+303d, U+3297, U+3299, U+fe0f, U+1f170-1f171, U+1f17e-1f17f, U+1f18e, U+1f191-1f19a, U+1f201-1f202, U+1f21a, U+1f22f, U+1f232-1f23a, U+1f250-1f251, U+1f310, U+1f3a6, U+1f3b5-1f3b6, U+1f3bc, U+1f3e7, U+1f441, U+1f499-1f49c, U+1f49f-1f4a0, U+1f4ac-1f4ad, U+1f4b1-1f4b2, U+1f4b9, U+1f4db, U+1f4f2-1f4f6, U+1f500-1f507, U+1f515, U+1f518-1f524, U+1f52f-1f53d, U+1f549, U+1f54e, U+1f5a4, U+1f5e8, U+1f5ef, U+1f6ab, U+1f6ad-1f6b1, U+1f6b3, U+1f6b7-1f6bc, U+1f6be, U+1f6c2-1f6c5, U+1f6d0-1f6d1, U+1f6d7, U+1f6dc, U+1f7e0-1f7eb, U+1f7f0, U+1f90d-1f90e, U+1f9d1-1f9d2, U+1f9e1, U+1fa75-1fa77, U+1faaf;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.3.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+231a-231b, U+2328, U+23f0-23f3, U+2602, U+260e, U+2692, U+2694, U+2696-2697, U+2699, U+26b0-26b1, U+26cf, U+26d1, U+26d3, U+2702, U+2709, U+270f, U+2712, U+fe0f, U+1f302, U+1f321, U+1f392-1f393, U+1f3a9, U+1f3bd, U+1f3ee, U+1f3f7, U+1f3fa, U+1f451-1f462, U+1f484, U+1f489-1f48a, U+1f48c-1f48e, U+1f4a1, U+1f4a3, U+1f4a5, U+1f4b0, U+1f4b3-1f4b8, U+1f4bb-1f4da, U+1f4dc-1f4f1, U+1f4ff, U+1f508-1f514, U+1f516-1f517, U+1f526-1f529, U+1f52c-1f52e, U+1f550-1f567, U+1f56f-1f570, U+1f576, U+1f587, U+1f58a-1f58d, U+1f5a5, U+1f5a8, U+1f5b1-1f5b2, U+1f5c2-1f5c4, U+1f5d1-1f5d3, U+1f5dc-1f5de, U+1f5e1, U+1f5f3, U+1f6aa, U+1f6ac, U+1f6bd, U+1f6bf, U+1f6c1, U+1f6cb, U+1f6cd-1f6cf, U+1f6d2, U+1f6e0-1f6e1, U+1f6f0, U+1f97b-1f97f, U+1f9af, U+1f9ba, U+1f9e2-1f9e6, U+1f9ea-1f9ec, U+1f9ee-1f9f4, U+1f9f7-1f9ff, U+1fa71-1fa74, U+1fa79-1fa7b, U+1fa86, U+1fa8e-1fa8f, U+1fa91-1fa93, U+1fa96, U+1fa99-1faa0, U+1faa2-1faa7, U+1faaa-1faae;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.4.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+265f, U+26bd-26be, U+26f3, U+26f8, U+fe0f, U+1f004, U+1f0cf, U+1f380-1f384, U+1f386-1f38b, U+1f38d-1f391, U+1f396-1f397, U+1f399-1f39b, U+1f39e-1f39f, U+1f3a3-1f3a5, U+1f3a7-1f3a9, U+1f3ab-1f3b4, U+1f3b7-1f3bb, U+1f3bd-1f3c0, U+1f3c5-1f3c6, U+1f3c8-1f3c9, U+1f3cf-1f3d3, U+1f3f8-1f3f9, U+1f47e, U+1f4e2, U+1f4f7-1f4fd, U+1f52b, U+1f579, U+1f58c-1f58d, U+1f5bc, U+1f6f7, U+1f6f9, U+1f6fc, U+1f93f, U+1f941, U+1f945, U+1f947-1f94f, U+1f9e7-1f9e9, U+1f9f5-1f9f6, U+1fa70-1fa71, U+1fa80-1fa81, U+1fa83-1fa85, U+1fa87-1fa8a, U+1fa94-1fa95, U+1fa97-1fa98, U+1faa1, U+1faa9, U+1fadf;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.5.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2693, U+26e9-26ea, U+26f1-26f2, U+26f4-26f5, U+26fa, U+26fd, U+2708, U+fe0f, U+1f301, U+1f303, U+1f306-1f307, U+1f309, U+1f310, U+1f3a0-1f3a2, U+1f3aa, U+1f3cd-1f3ce, U+1f3d5, U+1f3d7-1f3db, U+1f3df-1f3e6, U+1f3e8-1f3ed, U+1f3ef-1f3f0, U+1f488, U+1f492, U+1f4ba, U+1f54b-1f54d, U+1f5fa-1f5ff, U+1f680-1f6a2, U+1f6a4-1f6a8, U+1f6b2, U+1f6d1, U+1f6d5-1f6d6, U+1f6dd-1f6df, U+1f6e2-1f6e5, U+1f6e9, U+1f6eb-1f6ec, U+1f6f3-1f6f6, U+1f6f8, U+1f6fa-1f6fb, U+1f9bc-1f9bd, U+1f9ed, U+1f9f3, U+1fa7c;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.6.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+2615, U+fe0f, U+1f32d-1f330, U+1f336, U+1f33d, U+1f344-1f37f, U+1f382, U+1f52a, U+1f7e9, U+1f7eb, U+1f942-1f944, U+1f950-1f96f, U+1f99e, U+1f9aa, U+1f9c0-1f9cb, U+1fad0-1fadc;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.7.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+2600-2601, U+2603-2604, U+2614, U+2618, U+26a1, U+26c4-26c5, U+26c8, U+26f0, U+2728, U+2744, U+2b1b, U+2b50, U+fe0f, U+1f300, U+1f304-1f305, U+1f308, U+1f30a-1f30f, U+1f311-1f321, U+1f324-1f32c, U+1f331-1f335, U+1f337-1f33c, U+1f33e-1f344, U+1f3d4, U+1f3d6, U+1f3dc-1f3de, U+1f3f5, U+1f400-1f43f, U+1f490, U+1f4a7, U+1f4ae, U+1f525, U+1f54a, U+1f573, U+1f577-1f578, U+1f648-1f64a, U+1f6d8, U+1f940, U+1f980-1f9ae, U+1f9ba, U+1fa90, U+1faa8, U+1fab0-1fabf, U+1facd-1facf, U+1fae7;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.8.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+2640, U+2642, U+2695-2696, U+26f7, U+26f9, U+2708, U+2764, U+27a1, U+fe0f, U+1f33e, U+1f373, U+1f37c, U+1f384-1f385, U+1f393, U+1f3a4, U+1f3a8, U+1f3c2-1f3c4, U+1f3c7, U+1f3ca-1f3cc, U+1f3eb, U+1f3ed, U+1f3fb-1f3ff, U+1f430, U+1f466-1f469, U+1f46b-1f478, U+1f47c, U+1f481-1f483, U+1f486-1f487, U+1f48b, U+1f48f, U+1f491, U+1f4bb-1f4bc, U+1f527, U+1f52c, U+1f574-1f575, U+1f57a, U+1f645-1f647, U+1f64b, U+1f64d-1f64e, U+1f680, U+1f692, U+1f6a3, U+1f6b4-1f6b6, U+1f6c0, U+1f6cc, U+1f91d, U+1f926, U+1f930-1f931, U+1f934-1f93a, U+1f93c-1f93e, U+1f977, U+1f9af-1f9b3, U+1f9b8-1f9b9, U+1f9bc-1f9bd, U+1f9cc-1f9cf, U+1f9d1-1f9df, U+1fa70, U+1fa82, U+1fac3-1fac5, U+1fac8, U+1faef;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.9.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+200d, U+2194-2195, U+2603, U+261d, U+2620, U+2639-263a, U+2665, U+26a1, U+26c4, U+270a-270d, U+2728, U+2763-2764, U+2b50, U+fe0f, U+1f31a-1f31f, U+1f32b, U+1f389-1f38a, U+1f3fb-1f3ff, U+1f440-1f450, U+1f463-1f465, U+1f479-1f47b, U+1f47d-1f480, U+1f485, U+1f48b-1f48c, U+1f493-1f49f, U+1f4a2, U+1f4a4-1f4a6, U+1f4a8-1f4ab, U+1f4af, U+1f525, U+1f573, U+1f590, U+1f595-1f596, U+1f5a4, U+1f5e3, U+1f600-1f644, U+1f648-1f64a, U+1f64c, U+1f64f, U+1f90c-1f925, U+1f927-1f92f, U+1f932-1f933, U+1f970-1f976, U+1f978-1f97a, U+1f9a0, U+1f9b4-1f9b7, U+1f9bb, U+1f9be-1f9bf, U+1f9d0, U+1f9e0-1f9e1, U+1fa75-1fa79, U+1fac0-1fac2, U+1fac6, U+1fae0-1fae6, U+1fae8-1faea, U+1faef-1fafa;
}
@font-face {
  font-family: 'Noto Emoji';
  src: url('../fonts/noto-emoji/noto-emoji.10.woff2?v=2.1.2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1f6d9, U+1fa8b-1fa8d, U+1facc, U+1fadd, U+1faeb;
}

:root {
  color-scheme: light dark;

  /* ------------------------------------------------------------- NEUTROS --
     1.15.0 — Salen de los CUATRO neutros de la lámina pastel de Ricardo
     (topo #B9A99A, arena #D2BC8E, gris #E0E0E0, pizarra #5B6670), que es la
     única parte de una referencia de pintura que se puede usar tal cual en una
     interfaz. El papel es crema #FBE7CE muy diluido: mantiene el punto de
     hueso que ya tenía Samapp pero ahora viene de la referencia y no de una
     estimación. El gris de línea es literal (#E0E0E0) y el separador fuerte
     es topo diluido, así que los bordes ya no son grises fríos sobre papel
     cálido. Pizarra entra como --ink-muted: medido, 5.87 sobre blanco y 5.55
     sobre papel, contra 4.83 del #6B7280 anterior. */
  --paper:            #FCF8F3;  /* fondo de la app — crema al mínimo */
  --surface:          #FFFFFF;  /* superficies elevadas: filas, tarjetas */
  --surface-sunken:   #F3EFE9;  /* campos, pills inactivas, zonas hundidas */
  --surface-hover:    #EBE5DC;

  --ink:              #22262B;  /* texto principal: pizarra a fondo */
  --ink-strong:       #14171A;  /* títulos */
  --ink-muted:        #5B6670;  /* metadatos — pizarra de la referencia, tal cual */
  --ink-faint:        #98A0A8;  /* placeholders, texto deshabilitado */

  --line:             #E0E0E0;  /* gris claro de la referencia, tal cual */
  --line-strong:      #CDC5BB;  /* topo diluido: separador cálido, no gris frío */

  /* ------------------------------------------------------- CONTEXTUALES --
     Muestreados directamente de los mockups. Cada uno tiene un significado
     asignado y no se usa fuera de él. */
  --ctx-atencion:     #F9594E;  /* urgencia, vencido, destructivo */
  --ctx-calendario:   #55AFFB;  /* eventos y agenda */
  --ctx-finanzas:     #31755E;  /* dinero: verde petróleo, sólido y serio */
  --ctx-finanzas-soft:#6DAA91;  /* variante clara para íconos sobre neutro */
  --ctx-sillasmx:     #FDB22A;  /* área de trabajo SillasMX */
  --ctx-personal:     #AF6FEC;  /* área personal */
  --ctx-tasks:        #8276A8;  /* pendientes en briefings */
  --ctx-lists:        #A78A3C;  /* listas/checklists */
  --ctx-expense:      #B67862;  /* salida de dinero */
  --ctx-income:       #5D9470;  /* entrada de dinero */

  /* Tintes: fondo de fila cuando pertenece a un área. Casi imperceptibles a
     propósito — tiñen sin convertir la lista en un semáforo. */
  --tint-atencion:    #FEF1EF;
  --tint-calendario:  #EFF7FE;
  --tint-finanzas:    #EFF5F2;
  --tint-sillasmx:    #FEF9EB;
  --tint-personal:    #F8F1FE;
  --tint-tasks:       #F4F1FB;
  --tint-lists:       #FBF7E8;
  --tint-expense:     #FBF1ED;
  --tint-income:      #EEF7F1;

  /* ------------------------------------------------------------ ACCIÓN --
     El botón primario es tinta, no color de marca. Es la decisión que más
     aleja a Samapp del "SaaS de IA": lo importante no grita. */
  /* Superficie navy fija para bloques editoriales de marca. A diferencia de\n     --ink, NO cambia a blanco en dark mode. */
  --hero-navy:        #101B2A;

  --action:           #101B2A;
  --action-ink:       #FFFFFF;
  --action-hover:     #1E2C3F;
  --focus-ring:       #55AFFB;

  /* ------------------------------------------------------------- FORMA --
     Radios generosos pero no de burbuja. 14px es el radio de fila; las
     superficies grandes suben a 18px. */
  --r-xs:   8px;
  --r-sm:   11px;
  --r-md:   14px;
  --r-lg:   18px;
  --r-full: 999px;

  /* Una sola sombra, muy baja. Las superficies se separan por borde, no por
     elevación: es lo que evita la sensación de "card dentro de card". */
  --shadow-low:  0 1px 2px rgba(16, 27, 42, .05);
  --shadow-lift: 0 6px 20px rgba(16, 27, 42, .10);
  /* Sombra de dos capas para los briefings de Sam: un contacto casi
     imperceptible más un halo largo y muy tenue. Sigue leyéndose como borde
     con algo de aire detrás, no como una tarjeta flotante — 1.0.6 la separa
     de --shadow-low porque ese token sigue usándose en superficies que NO
     deben ganar la misma profundidad (auth-tabs). */
  --shadow-card: 0 1px 1px rgba(16, 27, 42, .04), 0 8px 24px -16px rgba(16, 27, 42, .16);

  /* ------------------------------------------------------- TIPOGRAFÍA --
     Display: ui-serif resuelve a New York en Apple y a Georgia en el resto.
     Cero dependencia de red, cero layout shift, cero peticiones a un CDN
     externo — requisito de despliegue en Hostinger.
     Texto: la pila de sistema, que en móvil es SF Pro / Roboto. */
  --font-display: 'Quicksand', 'Noto Emoji', -apple-system, BlinkMacSystemFont, "Segoe UI",
                  Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-text:    'Quicksand', 'Noto Emoji', -apple-system, BlinkMacSystemFont, "Segoe UI",
                  Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-num:     'Quicksand', 'Noto Emoji', -apple-system, BlinkMacSystemFont, "Segoe UI",
                  Roboto, "Helvetica Neue", Arial, sans-serif;

  /* 1.32.0 — LA ESCALA AHORA DESCRIBE LA APP, que es lo que no hacía.
     Medido en el DOM real: seis tokens declarados, CUARENTA Y CUATRO
     combinaciones tamaño/peso pintadas en pantalla. Entre 9px y 16px había
     quince tamaños distintos, seis de ellos con medio píxel (12.5, 13.5,
     10.5…), que en píxel fraccionario emborronan los remates redondeados de
     Quicksand. Los medios píxeles se fueron; los enteros que quedaban vivos y
     que NO tenían nombre (10, 12, 14, 18) lo tienen ahora, en vez de fingir
     que la app se las arregla con seis pasos. Ocho pasos para ocho trabajos. */
  /* 2.1.1 — LA ESCALA PASA A `rem`, QUE ES LO QUE HACE QUE LA LETRA DEL
     SISTEMA SIRVA PARA ALGO. Medido antes: 433 tamaños en px y CERO en
     rem/em; forzando `html{font-size:32px}` (la letra al 200% de Android y de
     Chrome) los paneles medían exactamente lo mismo, 589/812px con y sin.
     Quien sube la letra porque no ve no veía ningún cambio.
     Los valores son los mismos a 16px de raíz —1rem = 16px—, así que la app
     por defecto se ve idéntica al píxel; lo que cambia es que ahora escala.
     El paso es ESCALONADO a propósito: aquí y en los tamaños de lectura y de
     control (10-19px) de las cinco hojas. Las cifras grandes que dependen del
     ancho (el importe de Finanzas, con su `clamp(30px, 6.4vw, 42px)`) y los
     rótulos de 20px para arriba siguen en px hasta poder medirlos uno a uno:
     son los que rompen rejillas al duplicarse. */
  --t-display:  1.75rem;   /* 28px · título de pantalla */
  --t-title:    1.25rem;   /* 20px */
  --t-subtitle: 1.125rem;  /* 18px · 1.32.0 — títulos de tarjeta y de hoja */
  --t-heading:  1rem;      /* 16px */
  --t-body:     0.9375rem; /* 15px */
  --t-body-sm:  0.875rem;  /* 14px · 1.32.0 — cuerpo en filas densas */
  --t-meta:     0.8125rem; /* 13px */
  --t-meta-sm:  0.75rem;   /* 12px · 1.32.0 — fichas, contadores */
  --t-micro:    0.6875rem; /* 11px */
  --t-nano:     0.625rem;  /* 10px · 1.32.0 — SUELO. Nada por debajo: a 9px no se lee,
                          se adivina. Sólo para mayúsculas con letter-spacing
                          dentro de una rejilla (iniciales de día del mes). */

  --lh-tight: 1.18;
  --lh-body:  1.5;

  /* -------------------------------------------------------------- RITMO --
     Escala de 4. El espaciado hace el trabajo que en 0.1.5 hacían los bordes. */
  /* 1.32.0 — DOS SUB-PASOS, porque la app los pedía a gritos.
     Medido antes de inventarlos: en las 10,892 líneas de CSS había 27 usos de
     gap:6px y 14 de gap:10px. No son descuidos — son la distancia real entre
     un icono y su etiqueta, o entre dos líneas de una misma fila, donde 4px
     aprieta y 8px separa de más. Un token los legitima y evita que mañana
     aparezcan 5, 7, 9 y 11 haciendo el mismo trabajo sin nombre.
     Sólo viven por debajo de --s3: a partir de 12px la escala de 4 basta. */
  --s1h: 6px;   /* medio paso entre --s1 y --s2 */
  --s2h: 10px;  /* medio paso entre --s2 y --s3 */

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px; --s9: 48px;

  --tap: 44px;  /* altura mínima de cualquier control táctil */

  /* -------------------------------------------------------- SEGURIDAD --
     Insets del dispositivo. El composer y la tabbar dependen de esto para no
     quedar debajo del gesto de inicio en iPhone. */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  --tabbar-h: 62px;

  --ease: cubic-bezier(.2, .7, .3, 1);
  --dur:  .18s;
}

/* ============================================================================
   MODO OSCURO
   ----------------------------------------------------------------------------
   No es el modo claro invertido. La base es el navy #102235 muestreado del
   mockup, no un negro puro: mantiene la calidez y evita el contraste hiriente
   del blanco sobre #000 en pantalla OLED de noche.
   ========================================================================== */
[data-theme="dark"] {
  --paper:            #0D1B2A;
  --surface:          #142433;
  --surface-sunken:   #182C3D;
  --surface-hover:    #1D3346;

  --ink:              #EDF1F5;
  --ink-strong:       #FFFFFF;
  --ink-muted:        #97A6B5;
  --ink-faint:        #64748B;

  --line:             #22374A;
  --line-strong:      #2E4459;

  /* Los contextuales suben en luminosidad para conservar contraste sobre el
     navy. El significado no cambia; la legibilidad sí lo exige. */
  --ctx-atencion:     #FF7466;
  --ctx-calendario:   #6FBCFF;
  --ctx-finanzas:     #4E9C80;
  --ctx-finanzas-soft:#7FBEA4;
  --ctx-sillasmx:     #FFC352;
  --ctx-personal:     #C08BF5;
  --ctx-tasks:        #A89BCD;
  --ctx-lists:        #D2B65F;
  --ctx-expense:      #D9957E;
  --ctx-income:       #78B58D;

  --tint-atencion:    #2A1F22;
  --tint-calendario:  #16293A;
  --tint-finanzas:    #172C29;
  --tint-sillasmx:    #2A2519;
  --tint-personal:    #241E33;
  --tint-tasks:       #242238;
  --tint-lists:       #2A271C;
  --tint-expense:     #30221F;
  --tint-income:      #192D23;

  --action:           #EDF1F5;
  --action-ink:       #0D1B2A;
  --action-hover:     #FFFFFF;

  --shadow-low:  0 1px 2px rgba(0, 0, 0, .35);
  --shadow-lift: 0 8px 24px rgba(0, 0, 0, .45);
  --shadow-card: 0 1px 1px rgba(0, 0, 0, .3), 0 10px 28px -16px rgba(0, 0, 0, .55);
}

/* Preferencia del sistema cuando el usuario no ha elegido explícitamente. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* 1.15.0 — Mismos neutros de pizarra que el bloque explícito de más abajo.
       Hay que repetirlos AQUÍ porque este selector vale (0,2,0) y le gana al
       [data-theme="dark"] de (0,1,0): quien tenga el sistema en oscuro y no
       haya elegido tema —la mayoría— sólo ve este bloque. */
    --paper: #14181C;          --surface: #232930;
    --surface-sunken: #1A1F24; --surface-hover: #2D343C;
    --ink: #EDF0F3;            --ink-strong: #FFFFFF;
    --ink-muted: #A7B0B9;      --ink-faint: #78828C;
    --line: #333B43;           --line-strong: #454E58;
    --ctx-atencion: #FF7466;   --ctx-calendario: #6FBCFF;
    --ctx-finanzas: #4E9C80;   --ctx-finanzas-soft: #7FBEA4;
    --ctx-sillasmx: #FFC352;   --ctx-personal: #C08BF5;
    --ctx-tasks: #A89BCD;       --ctx-lists: #D2B65F;
    --ctx-expense: #D9957E;     --ctx-income: #78B58D;
    --tint-atencion: #2A1F22;  --tint-calendario: #16293A;
    --tint-finanzas: #172C29;  --tint-sillasmx: #2A2519;
    --tint-personal: #241E33;  --tint-tasks: #242238;
    --tint-lists: #2A271C;      --tint-expense: #30221F;
    --tint-income: #192D23;
    --action: #EDF1F5;         --action-ink: #0D1B2A;
    --action-hover: #FFFFFF;
    --shadow-low: 0 1px 2px rgba(0,0,0,.35);
    --shadow-lift: 0 8px 24px rgba(0,0,0,.45);
    --shadow-card: 0 1px 1px rgba(0,0,0,.3), 0 10px 28px -16px rgba(0,0,0,.55);
  }
}

/* ============================================================================
   SAMAPP 1.1.0 · PALETA CONTEXTUAL + PERSONALIDAD VISUAL
   ----------------------------------------------------------------------------
   Dos ejes, una sola arquitectura:
     data-theme="light|dark"        -> luminosidad
     data-color-mode="sober|color" -> presencia contextual
   El modo legacy sin atributo cae en sober por construcción.
   ========================================================================== */
:root {
  --palette-blue:    #98B7F8;
  --palette-sky:     #9CD8F0;
  --palette-mint:    #77E0D3;
  --palette-green:   #7CD591;
  --palette-sand:    #EDDB96;
  --palette-orange:  #FFB35C;
  --palette-coral:   #FF9661;
  --palette-red:     #FA6863;
  --palette-pink:    #F197C2;
  --palette-magenta: #D58FE5;
  --palette-purple:  #AB93ED;
  --palette-dark:    #1A2941;

  --ctx-atencion:   var(--palette-red);
  --ctx-calendario: var(--palette-blue);
  --ctx-finanzas:   var(--palette-green);
  --ctx-finanzas-soft: var(--palette-green);
  --ctx-sillasmx:   var(--palette-orange);
  --ctx-hoc:        var(--palette-coral);
  --ctx-kam:        var(--palette-mint);
  --ctx-personal:   var(--palette-purple);
  --ctx-incubadora: var(--palette-dark);
  --ctx-lists:      var(--palette-pink);
  --ctx-tasks:      var(--palette-purple);
  --ctx-expense:    var(--palette-coral);
  --ctx-income:     var(--palette-green);
  --ctx-azul:       var(--palette-blue);
  --ctx-cielo:      var(--palette-sky);
  --ctx-menta:      var(--palette-mint);
  --ctx-verde:      var(--palette-green);
  --ctx-arena:      var(--palette-sand);
  --ctx-naranja:    var(--palette-orange);
  --ctx-coral:      var(--palette-coral);
  --ctx-rojo:       var(--palette-red);
  --ctx-rosa:       var(--palette-pink);
  --ctx-magenta:    var(--palette-magenta);
  --ctx-morado:     var(--palette-purple);
  --ctx-oscuro:     var(--palette-dark);

  /* Sobrio: apenas firma el contexto. */
  --tint-atencion:   color-mix(in srgb, var(--ctx-atencion) 10%, var(--tone-canvas));
  --tint-calendario: color-mix(in srgb, var(--ctx-calendario) 10%, var(--tone-canvas));
  --tint-finanzas:   color-mix(in srgb, var(--ctx-finanzas) 10%, var(--tone-canvas));
  --tint-sillasmx:   color-mix(in srgb, var(--ctx-sillasmx) 10%, var(--tone-canvas));
  --tint-hoc:        color-mix(in srgb, var(--ctx-hoc) 10%, var(--tone-canvas));
  --tint-kam:        color-mix(in srgb, var(--ctx-kam) 10%, var(--tone-canvas));
  --tint-personal:   color-mix(in srgb, var(--ctx-personal) 10%, var(--tone-canvas));
  --tint-incubadora: color-mix(in srgb, var(--ctx-incubadora) 10%, var(--tone-canvas));
  --tint-tasks:      color-mix(in srgb, var(--ctx-tasks) 10%, var(--tone-canvas));
  --tint-lists:      color-mix(in srgb, var(--ctx-lists) 10%, var(--tone-canvas));
  --tint-expense:    color-mix(in srgb, var(--ctx-expense) 10%, var(--tone-canvas));
  --tint-income:     color-mix(in srgb, var(--ctx-income) 10%, var(--tone-canvas));
  --tint-azul:       color-mix(in srgb, var(--ctx-azul) 10%, var(--tone-canvas));
  --tint-cielo:      color-mix(in srgb, var(--ctx-cielo) 10%, var(--tone-canvas));
  --tint-menta:      color-mix(in srgb, var(--ctx-menta) 10%, var(--tone-canvas));
  --tint-verde:      color-mix(in srgb, var(--ctx-verde) 10%, var(--tone-canvas));
  --tint-arena:      color-mix(in srgb, var(--ctx-arena) 10%, var(--tone-canvas));
  --tint-naranja:    color-mix(in srgb, var(--ctx-naranja) 10%, var(--tone-canvas));
  --tint-coral:      color-mix(in srgb, var(--ctx-coral) 10%, var(--tone-canvas));
  --tint-rojo:       color-mix(in srgb, var(--ctx-rojo) 10%, var(--tone-canvas));
  --tint-rosa:       color-mix(in srgb, var(--ctx-rosa) 10%, var(--tone-canvas));
  --tint-magenta:    color-mix(in srgb, var(--ctx-magenta) 10%, var(--tone-canvas));
  --tint-morado:     color-mix(in srgb, var(--ctx-morado) 10%, var(--tone-canvas));
  --tint-oscuro:     color-mix(in srgb, var(--ctx-oscuro) 10%, var(--tone-canvas));
}

/* Color: la misma familia, ahora sí visible como superficie. */
[data-color-mode="color"] {
  --tint-atencion:   color-mix(in srgb, var(--ctx-atencion) 28%, var(--tone-canvas));
  --tint-calendario: color-mix(in srgb, var(--ctx-calendario) 30%, var(--tone-canvas));
  --tint-finanzas:   color-mix(in srgb, var(--ctx-finanzas) 28%, var(--tone-canvas));
  --tint-sillasmx:   color-mix(in srgb, var(--ctx-sillasmx) 32%, var(--tone-canvas));
  --tint-hoc:        color-mix(in srgb, var(--ctx-hoc) 30%, var(--tone-canvas));
  --tint-kam:        color-mix(in srgb, var(--ctx-kam) 30%, var(--tone-canvas));
  --tint-personal:   color-mix(in srgb, var(--ctx-personal) 28%, var(--tone-canvas));
  --tint-incubadora: color-mix(in srgb, var(--ctx-incubadora) 22%, var(--tone-canvas));
  --tint-tasks:      color-mix(in srgb, var(--ctx-tasks) 13%, var(--tone-canvas));
  --tint-lists:      color-mix(in srgb, var(--ctx-lists) 28%, var(--tone-canvas));
  --tint-expense:    color-mix(in srgb, var(--ctx-expense) 27%, var(--tone-canvas));
  --tint-income:     color-mix(in srgb, var(--ctx-income) 13%, var(--tone-canvas));
  --tint-azul:       color-mix(in srgb, var(--ctx-azul) 30%, var(--tone-canvas));
  --tint-cielo:      color-mix(in srgb, var(--ctx-cielo) 30%, var(--tone-canvas));
  --tint-menta:      color-mix(in srgb, var(--ctx-menta) 30%, var(--tone-canvas));
  --tint-verde:      color-mix(in srgb, var(--ctx-verde) 28%, var(--tone-canvas));
  --tint-arena:      color-mix(in srgb, var(--ctx-arena) 32%, var(--tone-canvas));
  --tint-naranja:    color-mix(in srgb, var(--ctx-naranja) 32%, var(--tone-canvas));
  --tint-coral:      color-mix(in srgb, var(--ctx-coral) 30%, var(--tone-canvas));
  --tint-rojo:       color-mix(in srgb, var(--ctx-rojo) 28%, var(--tone-canvas));
  --tint-rosa:       color-mix(in srgb, var(--ctx-rosa) 28%, var(--tone-canvas));
  --tint-magenta:    color-mix(in srgb, var(--ctx-magenta) 28%, var(--tone-canvas));
  --tint-morado:     color-mix(in srgb, var(--ctx-morado) 28%, var(--tone-canvas));
  --tint-oscuro:     color-mix(in srgb, var(--ctx-oscuro) 22%, var(--tone-canvas));
}

/* Dark mantiene el matiz, pero la superficie se mezcla con navy en vez de
   usar pasteles de light. Sobrio y Color conservan la diferencia de presencia. */
[data-theme="dark"] {
  --ctx-atencion: #FF7466;
  --ctx-calendario: #A7C2FA;
  --ctx-finanzas: #89D99B;
  --ctx-finanzas-soft: #89D99B;
  --ctx-sillasmx: #FFC56F;
  --ctx-hoc: #FFA17A;
  --ctx-kam: #86E5DA;
  --ctx-personal: #BCA7F3;
  --ctx-incubadora: #6F85A9;
  --ctx-lists: #F4A4C9;
  --ctx-tasks: #BCA7F3;
  --ctx-expense: #FFA17A;
  --ctx-income: #89D99B;
}
[data-theme="dark"][data-color-mode="color"] {
  --tint-atencion:   color-mix(in srgb, var(--ctx-atencion) 13%, var(--tone-canvas));
  --tint-calendario: color-mix(in srgb, var(--ctx-calendario) 13%, var(--tone-canvas));
  --tint-finanzas:   color-mix(in srgb, var(--ctx-finanzas) 13%, var(--tone-canvas));
  --tint-sillasmx:   color-mix(in srgb, var(--ctx-sillasmx) 13%, var(--tone-canvas));
  --tint-hoc:        color-mix(in srgb, var(--ctx-hoc) 13%, var(--tone-canvas));
  --tint-kam:        color-mix(in srgb, var(--ctx-kam) 13%, var(--tone-canvas));
  --tint-personal:   color-mix(in srgb, var(--ctx-personal) 13%, var(--tone-canvas));
  --tint-incubadora: color-mix(in srgb, var(--ctx-incubadora) 13%, var(--tone-canvas));
  --tint-tasks:      color-mix(in srgb, var(--ctx-tasks) 13%, var(--tone-canvas));
  --tint-lists:      color-mix(in srgb, var(--ctx-lists) 13%, var(--tone-canvas));
  --tint-expense:    color-mix(in srgb, var(--ctx-expense) 13%, var(--tone-canvas));
  --tint-income:     color-mix(in srgb, var(--ctx-income) 13%, var(--tone-canvas));
}


/* ============================================================================
   SAMAPP 1.5.1 · SOBRIO REAL — CAPA GLOBAL MONOCROMÁTICA
   ----------------------------------------------------------------------------
   Sobrio NO significa "menos color": significa ausencia de color decorativo.
   Conservamos únicamente --ctx-atencion para errores/urgencias funcionales
   reales. Todos los contextos editoriales, áreas, finanzas, calendario,
   listas, checks y gráficos resuelven a neutros mediante los mismos tokens.
   Esto evita parches por pantalla y mantiene Color intacto.
   ========================================================================== */
[data-color-mode="sober"],
:root:not([data-color-mode]) {
  /* Contextos decorativos → neutros. */
  --ctx-calendario: var(--ink-muted);
  --ctx-finanzas: var(--ink);
  --ctx-finanzas-soft: var(--ink-muted);
  --ctx-sillasmx: var(--ink-muted);
  --ctx-hoc: var(--ink-muted);
  --ctx-kam: var(--ink-muted);
  --ctx-personal: var(--ink-muted);
  --ctx-incubadora: var(--ink-muted);
  --ctx-lists: var(--ink-muted);
  --ctx-tasks: var(--ink-muted);
  --ctx-expense: var(--ink);
  --ctx-income: var(--ink);
  --ctx-azul: var(--ink-muted);
  --ctx-cielo: var(--ink-muted);
  --ctx-menta: var(--ink-muted);
  --ctx-verde: var(--ink-muted);
  --ctx-arena: var(--ink-muted);
  --ctx-naranja: var(--ink-muted);
  --ctx-coral: var(--ink-muted);
  --ctx-rojo: var(--ink-muted);
  --ctx-rosa: var(--ink-muted);
  --ctx-magenta: var(--ink-muted);
  --ctx-morado: var(--ink-muted);
  --ctx-oscuro: var(--ink-muted);

  /* Superficies contextuales → una sola familia neutral. */
  --tint-calendario: var(--surface-sunken);
  --tint-finanzas: var(--surface-sunken);
  --tint-sillasmx: var(--surface-sunken);
  --tint-hoc: var(--surface-sunken);
  --tint-kam: var(--surface-sunken);
  --tint-personal: var(--surface-sunken);
  --tint-incubadora: var(--surface-sunken);
  --tint-tasks: var(--surface-sunken);
  --tint-lists: var(--surface-sunken);
  --tint-expense: var(--surface-sunken);
  --tint-income: var(--surface-sunken);
  --tint-azul: var(--surface-sunken);
  --tint-cielo: var(--surface-sunken);
  --tint-menta: var(--surface-sunken);
  --tint-verde: var(--surface-sunken);
  --tint-arena: var(--surface-sunken);
  --tint-naranja: var(--surface-sunken);
  --tint-coral: var(--surface-sunken);
  --tint-rojo: var(--surface-sunken);
  --tint-rosa: var(--surface-sunken);
  --tint-magenta: var(--surface-sunken);
  --tint-morado: var(--surface-sunken);
  --tint-oscuro: var(--surface-sunken);

  /* El foco también es neutro en Sobrio; sigue siendo visible por contraste. */
  --focus-ring: var(--ink-muted);
}

/* En claro/sobrio el lenguaje es blanco + carbón + gris. */
[data-theme="light"][data-color-mode="sober"] {
  --paper: #FAFAFA;
  --surface: #FFFFFF;
  --surface-sunken: #F5F5F5;
  --surface-hover: #EEEEEE;
  --ink: #171717;
  --ink-strong: #111111;
  /* 1.15.0 — #6B7280 daba 4.43 sobre la superficie hundida y 4.17 sobre la de
     hover: por debajo de AA en los chips, las pestañas y las cifras en cero.
     Es un fallo anterior a este encargo (el comentario de --area-tasks-ink de
     más abajo ya lo tenía medido) y no depende de la paleta, así que Sobrio
     sigue siendo idéntico en Pastel y en Vivo. #636973 conserva el mismo gris
     templado y sube a 5.07 y 4.76. */
  --ink-muted: #636973;
  --ink-faint: #A3A3A3;
  --line: #E5E7EB;
  --line-strong: #D4D4D4;
}

/* En oscuro/sobrio el lenguaje es carbón + gris + blanco, sin tinte azul. */
[data-theme="dark"][data-color-mode="sober"] {
  --paper: #0F1113;
  --surface: #171A1D;
  --surface-sunken: #1D2024;
  --surface-hover: #23272C;
  --ink: #F2F2F2;
  --ink-strong: #FAFAFA;
  --ink-muted: #A3A3A3;
  --ink-faint: #737373;
  --line: #2A2E33;
  --line-strong: #383D43;
  --action: #F2F2F2;
  --action-ink: #111315;
  --action-hover: #FFFFFF;
}

/* Mapa de área → color contextual. Se aplica con data-ctx en cualquier fila,
   ícono o marcador, y así el color siempre entra por significado. */
[data-ctx="atencion"]   { --ctx: var(--ctx-atencion);   --ctx-tint: var(--tint-atencion); }
[data-ctx="calendario"] { --ctx: var(--ctx-calendario); --ctx-tint: var(--tint-calendario); }
[data-ctx="finanzas"]   { --ctx: var(--ctx-finanzas);   --ctx-tint: var(--tint-finanzas); }
[data-ctx="sillasmx"]   { --ctx: var(--ctx-sillasmx);   --ctx-tint: var(--tint-sillasmx); }
[data-ctx="personal"]   { --ctx: var(--ctx-personal);   --ctx-tint: var(--tint-personal); }
[data-ctx="hoc"]        { --ctx: var(--ctx-hoc);        --ctx-tint: var(--tint-hoc); }
[data-ctx="kam"]        { --ctx: var(--ctx-kam);        --ctx-tint: var(--tint-kam); }
[data-ctx="incubadora"] { --ctx: var(--ctx-incubadora); --ctx-tint: var(--tint-incubadora); }
[data-ctx="lists"],
[data-ctx="rosa"]       { --ctx: var(--ctx-lists);      --ctx-tint: var(--tint-lists); }
[data-ctx="azul"]       { --ctx: var(--ctx-azul);       --ctx-tint: var(--tint-azul); }
[data-ctx="cielo"]      { --ctx: var(--ctx-cielo);      --ctx-tint: var(--tint-cielo); }
[data-ctx="menta"]      { --ctx: var(--ctx-menta);      --ctx-tint: var(--tint-menta); }
[data-ctx="verde"]      { --ctx: var(--ctx-verde);      --ctx-tint: var(--tint-verde); }
[data-ctx="arena"]      { --ctx: var(--ctx-arena);      --ctx-tint: var(--tint-arena); }
[data-ctx="naranja"]    { --ctx: var(--ctx-naranja);    --ctx-tint: var(--tint-naranja); }
[data-ctx="coral"]      { --ctx: var(--ctx-coral);      --ctx-tint: var(--tint-coral); }
[data-ctx="rojo"]       { --ctx: var(--ctx-rojo);       --ctx-tint: var(--tint-rojo); }
[data-ctx="magenta"]    { --ctx: var(--ctx-magenta);    --ctx-tint: var(--tint-magenta); }
[data-ctx="morado"]     { --ctx: var(--ctx-morado);     --ctx-tint: var(--tint-morado); }
[data-ctx="oscuro"]     { --ctx: var(--ctx-oscuro);     --ctx-tint: var(--tint-oscuro); }
[data-ctx="neutro"]     { --ctx: var(--ink-muted);      --ctx-tint: var(--surface-sunken); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   SAMAPP 1.7.0 · COLOR SYSTEM
   ----------------------------------------------------------------------------
   Paleta semántica en cinco intensidades. El color aparece en navegación,
   estado, categoría visual, calendario, Sam y dinero.

   ----------------------------------------------------------------------------
   1.15.0 · LOS TONOS SALEN DE LA LÁMINA PASTEL DE RICARDO

   La lámina trae doce matices cromáticos (rosa, salmón, durazno, amarillo,
   lima, verde, menta, cielo, aciano, lavanda, magenta) más cuatro neutros. Son
   pintura, no un sistema de interfaz: doce muestras no cubren trece familias y
   ninguna trae los extremos claro/oscuro que hace falta para texto.

   CÓMO SE TRADUJO, y por qué así:

   1. LOS MATICES DE LA APP NO SE MUEVEN. El reparto de áreas de 1.14.1 (azul
      266°, magenta 321°, teal 182°, ámbar 88° en OKLCH; mínimo 54° de
      separación) costó todo aquel trabajo y la lámina no tiene por qué
      reproducirlo. Lo que se importa es la ENVOLVENTE: se leen los doce
      valores en OKLCH, se construyen las curvas L(matiz) y C(matiz) y se
      MUESTREAN en los trece matices de la app, interpolando entre los dos
      vecinos cuando la lámina no tiene ese matiz exacto (le falta teal puro,
      por ejemplo: sale entre menta y cielo).
   2. La crema #FBE7CE se dejó FUERA de la envolvente. Es papel, no matiz: con
      C .040 metida entre durazno y amarillo hundía el croma de toda la banda
      cálida. Se reutiliza arriba como --paper.
   3. Croma al 100% de la referencia, sin subirlo. Es lo que Ricardo pidió:
      tonos suaves, luminosos, muy desaturados, de gouache. Croma OKLCH del
      relleno de ficha resultante: media .021 (antes .030) — más pastel que la
      versión que no le gustó, no menos.

   Medido, banda de la referencia y de las trece familias: L .764–.952,
   C .047–.118. Las trece caben dentro sin recortes. */
:root {
  --color-red-strong:#DD817E;       --color-red:#F69996;      --color-red-soft:#FFD8D6;
  --color-coral-strong:#DE8271;     --color-coral:#F69A89;    --color-coral-soft:#FFD9D1;
  --color-orange-strong:#E4AA76;    --color-orange:#FDC28F;   --color-orange-soft:#FFDBBE;
  --color-yellow-strong:#E7C87B;    --color-yellow:#FFE095;   --color-yellow-soft:#F4E1B6;
  --color-lime-strong:#AECE81;      --color-lime:#C6E79A;     --color-lime-soft:#D7EBBE;
  --color-green-strong:#84CF9F;     --color-green:#9DE7B7;    --color-green-soft:#C4EFD2;
  --color-teal-strong:#83CFC2;      --color-teal:#9CE7DA;     --color-teal-soft:#C2EEE5;
  --color-cyan-strong:#98C4D9;      --color-cyan:#B1DCF1;     --color-cyan-soft:#CEE8F4;
  --color-blue-strong:#94AADE;      --color-blue:#ABC2F6;     --color-blue-soft:#D6E3FF;
  --color-indigo-strong:#9DA6DE;    --color-indigo:#B4BEF6;   --color-indigo-soft:#DBE1FF;
  --color-purple-strong:#AC9FDB;    --color-purple:#C3B7F3;   --color-purple-soft:#E4DEFF;
  --color-magenta-strong:#D49FDE;   --color-magenta:#ECB8F6;  --color-magenta-soft:#F6D6FC;
  --color-pink-strong:#E49ABC;      --color-pink:#FCB2D4;     --color-pink-soft:#FFD6E8;

  --color-blue-surface:color-mix(in srgb,var(--color-blue) 12%,var(--surface));
  --color-cyan-surface:color-mix(in srgb,var(--color-cyan) 12%,var(--surface));
  --color-teal-surface:color-mix(in srgb,var(--color-teal) 12%,var(--surface));
  --color-green-surface:color-mix(in srgb,var(--color-green) 12%,var(--surface));
  --color-yellow-surface:color-mix(in srgb,var(--color-yellow) 12%,var(--surface));
  --color-orange-surface:color-mix(in srgb,var(--color-orange) 12%,var(--surface));
  --color-coral-surface:color-mix(in srgb,var(--color-coral) 12%,var(--surface));
  --color-pink-surface:color-mix(in srgb,var(--color-pink) 12%,var(--surface));
  --color-magenta-surface:color-mix(in srgb,var(--color-magenta) 12%,var(--surface));
  --color-purple-surface:color-mix(in srgb,var(--color-purple) 12%,var(--surface));
  --color-indigo-surface:color-mix(in srgb,var(--color-indigo) 12%,var(--surface));
  --color-red-surface:color-mix(in srgb,var(--color-red) 12%,var(--surface));

  /* 1.9 — Tinta única para texto sobre rellenos de color (chips activos,
     botones tonales). Antes había cinco hex distintos regados por base.css.
     1.15.0 — Pasa a pizarra a fondo (#22262B) para acompañar a --ink: el navy
     anterior tenía matiz propio y sobre un relleno cálido se leía azulado.
     Medido sobre los rellenos sólidos reales de esta paleta: 8.53 (Pendientes),
     9.24 (Calendario), 10.76 (Finanzas), 11.85 (Listas). */
  --ink-on-color:#22262B;

  --color-blue-border:color-mix(in srgb,var(--color-blue) 30%,var(--line));
  --color-cyan-border:color-mix(in srgb,var(--color-cyan) 30%,var(--line));
  --color-teal-border:color-mix(in srgb,var(--color-teal) 30%,var(--line));
  --color-green-border:color-mix(in srgb,var(--color-green) 30%,var(--line));
  --color-yellow-border:color-mix(in srgb,var(--color-yellow) 30%,var(--line));
  --color-orange-border:color-mix(in srgb,var(--color-orange) 30%,var(--line));
  --color-coral-border:color-mix(in srgb,var(--color-coral) 30%,var(--line));
  --color-pink-border:color-mix(in srgb,var(--color-pink) 30%,var(--line));
  --color-magenta-border:color-mix(in srgb,var(--color-magenta) 30%,var(--line));
  --color-purple-border:color-mix(in srgb,var(--color-purple) 30%,var(--line));
  --color-indigo-border:color-mix(in srgb,var(--color-indigo) 30%,var(--line));
  --color-red-border:color-mix(in srgb,var(--color-red) 30%,var(--line));

  /* ------------------------------------------------ 1.14.1 · TIER "INK" --
     POR QUÉ EXISTE: la paleta 1.7 no tenía extremo oscuro. Medidos los 13
     tonos base, su luminosidad HSL cabía entera entre 0.61 y 0.75 — un rango
     de 0.14. Trece matices con el MISMO valor y saturación parecida no se
     leen como trece colores: se leen como un material único al que le
     cambiaron el filtro. Ese es el origen literal de "son muy repetitivos":
     no faltaban matices, faltaba RANGO TONAL.

     El tier `-strong` tampoco resolvía el problema, porque nació para
     rellenos, no para tinta: medido sobre blanco puro sólo purple (4.86) e
     indigo (5.04) alcanzan AA; cyan (2.65), teal (2.74), yellow (2.25) y
     orange (2.58) ni siquiera llegan al umbral de texto grande. Sobre su
     propio tinte al 26% fallan los trece menos dos.

     `-ink` es el extremo que faltaba. Y hay que DERIVARLO, no sacarlo de la
     referencia: una lámina de pintura da UN valor por matiz y ninguno de los
     doce sirve como texto (el más oscuro, salmón, da 2.1 sobre blanco).

     1.15.0 — Se resuelve por búsqueda, con el croma FIJO al 58% del gamut de
     cada matiz y la luminosidad MÁS ALTA que a ese croma cumple los cinco
     umbrales reales a la vez: blanco (>=5.9), papel (>=5.4), superficie
     hundida (>=5.2) y su propio relleno al 24% y al 28% (>=4.55). El croma
     constante es lo que hace que las trece tintas se lean como UNA familia;
     dejar que cada una llegue al máximo del gamut daba textos eléctricos
     (#254EF8 en el azul) que cumplen el número y cansan de leer, y bajarlo
     mucho las volvía grises verdosos, que es exactamente el "verde oliva" del
     que se quejó Ricardo. 58% es el punto medio medido entre las dos cosas.

     Comentario de cada línea: contraste sobre blanco · sobre su relleno al 24%
     (la ficha de Hoy) · al 28% (esa misma ficha en hover, el peor caso real). */
  --color-red-ink:#A04647;        /* 6.07 · 5.13 · 4.94 */
  --color-coral-ink:#9E493B;      /* 6.05 · 5.11 · 4.95 */
  --color-orange-ink:#805B3B;     /* 6.04 · 5.42 · 5.33 */
  --color-yellow-ink:#71613A;     /* 6.05 · 5.71 · 5.62 */
  --color-lime-ink:#566939;       /* 6.04 · 5.59 · 5.53 */
  --color-green-ink:#3E6D4F;      /* 5.99 · 5.47 · 5.40 */
  --color-teal-ink:#3E6B63;       /* 6.02 · 5.53 · 5.45 */
  --color-cyan-ink:#3E697B;       /* 5.98 · 5.49 · 5.39 */
  --color-blue-ink:#3A5DC0;       /* 5.99 · 5.25 · 5.14 */
  --color-indigo-ink:#5358C0;     /* 5.96 · 5.21 · 5.11 */
  --color-purple-ink:#704EBC;     /* 5.99 · 5.24 · 5.11 */
  --color-magenta-ink:#8C4799;    /* 6.04 · 5.38 · 5.28 */
  --color-pink-ink:#9B4572;       /* 6.02 · 5.35 · 5.21 */

  /* ------------------------------------------- 1.14.1 · IDENTIDAD DE ÁREA --
     Las cuatro áreas navegables tenían su tono escrito a mano en 30 reglas de
     base.css, así que "cambiar la paleta" significaba 30 ediciones y una
     colisión garantizada. Ahora el tono de cada área vive AQUÍ y sólo aquí.

     REPARTO MEDIDO. El anterior (cian/morado/teal/rosa) tenía a Pendientes en
     cian (198°) y Finanzas en teal (171°): 27° de separación y 0.06 de
     diferencia de luminosidad. De cuatro colores se percibían tres. Finanzas
     NO puede moverse — su teal está anclado por la política de color de
     finanzas.css, donde el verde y el rojo están reservados para la excepción
     y no pueden reciclarse como identidad de área. Así que se mueve
     Pendientes, y al moverse a azul (223°) chocaba con Calendario en morado
     (255°, 32°), de modo que Calendario se corre a magenta: mismo carácter
     violeta, 34° de desplazamiento, separación recuperada.

     Separación mínima entre las cuatro: 27° antes -> 51° ahora.
     Y Listas pasa de rosa (330°) a ámbar (43°) para que el conjunto deje de
     ser cuatro fríos: tres fríos y un cálido tienen composición; cuatro
     fríos son una mancha. */
  --area-tasks:var(--color-blue);          /* 223° — el trabajo, el ancla */
  --area-calendar:var(--color-magenta);    /* 289° — el tiempo */
  --area-finance:var(--color-teal);        /* 171° — anclado por finanzas.css */
  --area-lists:var(--color-yellow);        /* 43°  — el único cálido */

  --area-tasks-ink:var(--color-blue-ink);
  --area-calendar-ink:var(--color-magenta-ink);
  --area-finance-ink:var(--color-teal-ink);
  --area-lists-ink:var(--color-yellow-ink);

  /* No hay tier --area-*-soft a propósito: como -ink ya se invierte por tema,
     un "claro para oscuro" separado no haría falta en ningún sitio. */

  /* ------------------------------------------ 1.14.1 · LIENZO DE MEZCLA --
     EL HALLAZGO QUE MÁS EXPLICA "TODO SE VE IGUAL", y no estaba en la paleta
     sino en la operación de mezcla.

     `color-mix` contra un color CROMÁTICO arrastra el matiz hacia ese color.
     Contra blanco o contra un gris no pasa: mezclar con un neutro suma la
     misma cantidad a los tres canales, las diferencias entre canales se
     escalan por igual y el matiz se conserva EXACTO. Por eso en claro
     —donde --surface es #FFFFFF— los tintes nunca derivaron.

     En oscuro --surface ERA el navy #1A2F44 (1.15.0 lo sustituye por la
     pizarra neutra #232930, pero el razonamiento vale igual para cualquier
     superficie con matiz propio). Medida la deriva de las cuatro áreas al 22%
     sobre aquel navy:

         ámbar    43° -> 120°   (+77°, aterriza en VERDE)
         magenta 289° -> 240°   (-49°, aterriza en AZUL-VIOLETA)
         teal    171° -> 194°   (+23°)
         azul    223° -> 216°   (-7°)

     Las cuatro tarjetas terminaban a 22° unas de otras: el navy se comía la
     paleta y devolvía cuatro versiones de sí mismo. Daba igual qué tonos
     eligiéramos — de ahí que 1.7 subiera a trece familias y la pantalla
     siguiera viéndose repetida.

     --tone-canvas es el fondo contra el que se mezclan los rellenos
     TEÑIDOS: neutro en los dos temas. En claro ya lo era. En oscuro es un
     gris apenas cálido calibrado a la MISMA luminancia relativa que el navy
     (.0277 vs .0267), así que la profundidad de la interfaz no cambia y sólo
     desaparece la deriva: máximo 14°, y la separación real entre las cuatro
     tarjetas pasa de 22° a 63°.

     NO sustituye a --surface. Sólo se usa donde un tono se diluye para hacer
     superficie; las superficies neutras siguen siendo --surface. */
  --tone-canvas:var(--surface);

  /* ------------------------------------- 1.14.2 · DOSIS DE LOS RELLENOS --
     Los porcentajes de mezcla estaban escritos a mano dentro de base.css, así
     que la única forma de que una paleta tuviera MÁS presencia era duplicar
     reglas. Ahora la dosis es un token y cada paleta la ajusta.

     POR QUÉ IMPORTA, con el número delante: al mezclar un tono contra blanco
     la saturación del resultado es EXACTAMENTE `porcentaje x saturación del
     tono`. Con 24% no existe tono capaz de dar un relleno vivo: aunque el
     tono esté a 90 de saturación, el relleno sale a 21. El techo de "esto se
     sigue viendo pastel" no estaba en los matices, estaba aquí.

     Estos son los valores de Pastel y son los MISMOS que base.css tenía
     escritos a mano, así que Pastel no se mueve. */
  --mix-card:24%;            /* relleno de las fichas de Hoy */
  --mix-card-hover:28%;
  /* 1.15.0 — Las filas suben de 8% a 12%, y NO es "para que se note más": es
     para que se note LO MISMO. La saturación de un relleno es dosis x croma
     del tono, y los tonos de la lámina pastel son más desaturados que los que
     había (croma OKLCH medio .086 frente a .134). Con el 8% de antes el relleno
     salía a croma .0069 y en pantalla era blanco: medido en el DOM, L 99 sobre
     papel L 98. Al 12% vuelve a .0103, que es exactamente donde estaba
     (.134 x 8% = .0107). Misma presencia, matices nuevos.
     Las fichas SÍ se quedan en 24%: son superficies grandes y ahí la lámina
     manda —"suave, luminoso, muy desaturado"—, así que se aceptan más pálidas
     que antes. Una fila de 40px y una ficha de 90px no piden lo mismo. */
  --mix-row:12%;             /* filas con área en Pendientes y Listas */
  --mix-row-hover:17%;
  --mix-row-border:22%;
  --mix-row-border-hover:38%;
  /* 1.15.0 — En pantalla estrecha la fila ocupa casi todo el ancho y la misma
     dosis pesa el doble, así que baja. Estaba escrita a mano dentro de un
     media query de base.css, con lo que Vivo se quedaba sin color justo en
     móvil. Ahora es un token y cada paleta pone el suyo. */
  --mix-row-narrow:10%;
  --rule-w:3px;              /* ancho del marcador de área de la fila */
}

/* 1.9 — Profundidad real: el fondo baja dos pasos de luminosidad y las
   tarjetas suben uno. Antes fondo (#18324A) y tarjeta (#203F59) estaban tan
   cerca en valor que todo se veía plano y "lechoso"; ahora la jerarquía
   fondo → hundido → superficie → hover se lee sin bordes gruesos. */
/* 1.15.0 — El navy se retira y la rampa oscura sale de PIZARRA (#5B6670), el
   único neutro oscuro de la lámina pastel. Es el mismo gesto de siempre —una
   base fría y templada, nunca negro puro— pero con la mitad de croma que el
   navy (.021 frente a .034 en OKLCH). Eso importa aquí más que la estética:
   cada punto de croma de la SUPERFICIE es deriva de matiz en cuanto algo se
   mezcla contra ella, y con el navy la deriva llegaba a 49° (ver 1.14.1).
   Medido: ink 12.83 sobre la superficie, --ink-muted 6.67, --ink-faint 3.75. */
[data-theme="dark"] {
  --paper:#14181C;
  --surface:#232930;
  --surface-sunken:#1A1F24;
  --surface-hover:#2D343C;
  --line:#333B43;
  --line-strong:#454E58;
  --ink:#EDF0F3;
  --ink-strong:#FFFFFF;
  --ink-muted:#A7B0B9;
  --ink-faint:#78828C;
  --action:#F7FAFC;
  --action-ink:#181C21;
  --action-hover:#FFFFFF;
  /* 1.15.0 — Con guardia de modo: sin ella este --focus-ring le ganaba por
     orden al del bloque sobrio (misma especificidad) y Sobrio oscuro sacaba un
     anillo cian que además cambiaba con la paleta. Sobrio no puede notar la
     paleta, y su foco es neutro por diseño. */
  --focus-ring:var(--ink-muted);
  --shadow-card: 0 1px 1px rgba(0,0,0,.25), 0 12px 32px -18px rgba(0,0,0,.6);
}

/* 1.14.1 — El tier `-ink` se INVIERTE en oscuro. "Ink" nombra un rol —"el
   extremo del matiz que se lee sobre la superficie de este tema"— no una
   luminosidad fija. Sobre navy el extremo legible es el claro, así que -ink
   resuelve al pastel. Gracias a esta inversión base.css escribe
   `color:var(--area-tasks-ink)` UNA vez y los dos temas quedan resueltos, sin
   una pareja de reglas por tema.
   Medido en 1.15.0 sobre la tarjeta oscura mix(tono 14%, #14181C): 7.4 a 9.9
   — AA holgado en las trece familias. */
/* data-theme y data-color-mode viven los dos en <html> (app.js 3528-3530 y
   themes.js 30), así que basta el selector simple. */
[data-theme="dark"] {
  /* ------------------- 1.15.0 · EL LIENZO Y LA DOSIS DE PASTEL EN OSCURO --
     AQUÍ ESTABA EL "VERDE OLIVA Y ROJO VINO" QUE FOTOGRAFIÓ RICARDO, y no era
     deriva de matiz: era MUD. Un tono pastel es CLARO y poco cromático por
     definición; diluido a media luz sobre un gris medio da un color de valor
     medio y saturación 9-16, y eso —da igual el matiz— el ojo lo lee como
     tierra. Medido con el amarillo sobre el lienzo #282828 al 24%: #5C5442,
     saturación 16, luminosidad 45. Eso es oliva, literalmente.

     La salida no es subir la dosis (más dosis = más claro = más mud) sino
     BAJAR EL LIENZO y bajar la dosis a la vez: el relleno se va a valor bajo,
     donde ya no compite con nada, y el color pasa a vivir en los elementos que
     sí pueden llevarlo a tono pleno sobre oscuro —el marcador de 3px, el punto
     y la etiqueta—, que es justo donde un pastel se ve bien sobre negro.
     Medido con la misma familia a #14181C y 20%: #434034, y las cuatro áreas
     bajan a luminosidad 33-37 con saturación 13-18. Deja de leerse como una
     mancha marrón y pasa a leerse como superficie.

     Sigue siendo NEUTRO, que es lo que --tone-canvas garantiza. */
  --tone-canvas:#14181C;
  /* 1.15.3 — Dosis SUBIDA. La de arriba (14%/10%/9%) se eligió para huir del
     efecto "terroso", y se pasó de prudente: Ricardo, con la app en oscuro,
     "porque casi no se ve el pastel en oscuro" y "se ve muy bajito hay que
     mejorarlo". Medido antes: saturación media de las fichas 4.8 sobre 100.

     El miedo al barro venía de mezclar con un lienzo de luminosidad MEDIA.
     Con este lienzo a #14181C (muy oscuro) subir la dosis mueve el relleno
     HACIA el tono pastel, que es claro y limpio, en vez de hacia un marrón.
     Se sube el doble y se comprueba en pantalla, no de memoria. */
  --mix-card:28%;
  --mix-card-hover:34%;
  --mix-row:20%;
  --mix-row-hover:26%;
  --mix-row-narrow:16%;

  --color-blue-ink:var(--color-blue-soft);
  --marcador-oscuro:6px;   /* lo consume el bloque con guardia de modo de abajo */
  --color-cyan-ink:var(--color-cyan-soft);
  --color-teal-ink:var(--color-teal-soft);
  --color-green-ink:var(--color-green-soft);
  --color-lime-ink:var(--color-lime-soft);
  --color-yellow-ink:var(--color-yellow-soft);
  --color-orange-ink:var(--color-orange-soft);
  --color-coral-ink:var(--color-coral-soft);
  --color-pink-ink:var(--color-pink-soft);
  --color-magenta-ink:var(--color-magenta-soft);
  --color-purple-ink:var(--color-purple-soft);
  --color-indigo-ink:var(--color-indigo-soft);
  --color-red-ink:var(--color-red-soft);
}
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) {
    /* Mismo lienzo y misma dosis que el bloque explícito de arriba. Si se
       tocan allí, hay que tocarlas aquí: este es el camino de quien nunca
       eligió tema y hereda el del sistema. */
    --tone-canvas:#14181C;
    --mix-card:28%;
    --mix-card-hover:34%;
    --mix-row:20%;
    --mix-row-hover:26%;
    --mix-row-narrow:16%;
    --color-blue-ink:var(--color-blue-soft);
    --color-cyan-ink:var(--color-cyan-soft);
    --color-teal-ink:var(--color-teal-soft);
    --color-green-ink:var(--color-green-soft);
    --color-lime-ink:var(--color-lime-soft);
    --color-yellow-ink:var(--color-yellow-soft);
    --color-orange-ink:var(--color-orange-soft);
    --color-coral-ink:var(--color-coral-soft);
    --color-pink-ink:var(--color-pink-soft);
    --color-magenta-ink:var(--color-magenta-soft);
    --color-purple-ink:var(--color-purple-soft);
    --color-indigo-ink:var(--color-indigo-soft);
    --color-red-ink:var(--color-red-soft);
  }
}

/* La paleta contextual de 1.1 se alinea con los tonos 1.7. */
/* 1.15.0 — La dosis de los tintes de Pastel en CLARO pasa de 15% a 22% por la
   misma aritmética que --mix-row: presencia = dosis x croma del tono, y los
   tonos de la lámina son un 36% menos cromáticos que los anteriores
   (croma OKLCH medio .086 frente a .134). 15% x .134 = .0201; 22% x .086 =
   .0189. Misma presencia que el build que Ricardo ya conocía, matices nuevos.
   No es "que se note más": es que no se note MENOS. */
[data-color-mode="color"] {
  --ctx-atencion:var(--color-red);
  /* 1.32.0 — CALENDARIO DEJA DE SER EL MISMO COLOR QUE PERSONAL.
     Medido en el DOM, no deducido: --ctx-calendario y --ctx-personal
     resolvían los dos a #C3B7F3. Dos significados, un color — justo lo que la
     cabecera de este archivo prohíbe ("cada uno tiene un significado asignado
     y no se usa fuera de él"). Y encima Calendario YA era magenta como área
     (--area-calendar, 289°), así que la misma pantalla se anunciaba de dos
     colores según por dónde se mirara: magenta en su título, morado en sus
     filas. Se alinea con su área — un calendario, un tono — y el morado queda
     para Personal, que es quien lo tenía asignado desde 1.1.
     Aplicado igual en Pastel y en Vivo: la colisión estaba en las dos. */
  --ctx-calendario:var(--color-magenta);
  --ctx-finanzas:var(--color-teal);
  --ctx-finanzas-soft:var(--color-teal-soft);
  --ctx-sillasmx:var(--color-yellow);
  --ctx-hoc:var(--color-coral);
  --ctx-kam:var(--color-teal);
  --ctx-personal:var(--color-purple);
  --ctx-lists:var(--color-pink);
  --ctx-tasks:var(--color-cyan);
  --ctx-expense:var(--color-coral);
  --ctx-income:var(--color-green);
  --ctx-azul:var(--color-blue);
  --ctx-cielo:var(--color-cyan);
  --ctx-menta:var(--color-teal);
  --ctx-verde:var(--color-green);
  --ctx-arena:var(--color-yellow);
  --ctx-naranja:var(--color-orange);
  --ctx-coral:var(--color-coral);
  --ctx-rojo:var(--color-red);
  --ctx-rosa:var(--color-pink);
  --ctx-magenta:var(--color-magenta);
  --ctx-morado:var(--color-purple);
  --ctx-oscuro:var(--color-indigo);

  --tint-atencion:color-mix(in srgb,var(--ctx-atencion) 22%,var(--tone-canvas));
  --tint-calendario:color-mix(in srgb,var(--ctx-calendario) 22%,var(--tone-canvas));
  --tint-finanzas:color-mix(in srgb,var(--ctx-finanzas) 22%,var(--tone-canvas));
  --tint-sillasmx:color-mix(in srgb,var(--ctx-sillasmx) 22%,var(--tone-canvas));
  --tint-hoc:color-mix(in srgb,var(--ctx-hoc) 22%,var(--tone-canvas));
  --tint-kam:color-mix(in srgb,var(--ctx-kam) 22%,var(--tone-canvas));
  --tint-personal:color-mix(in srgb,var(--ctx-personal) 22%,var(--tone-canvas));
  --tint-tasks:color-mix(in srgb,var(--ctx-tasks) 22%,var(--tone-canvas));
  --tint-lists:color-mix(in srgb,var(--ctx-lists) 22%,var(--tone-canvas));
  --tint-expense:color-mix(in srgb,var(--ctx-expense) 22%,var(--tone-canvas));
  --tint-income:color-mix(in srgb,var(--ctx-income) 22%,var(--tone-canvas));
  --tint-azul:color-mix(in srgb,var(--ctx-azul) 22%,var(--tone-canvas));
  --tint-cielo:color-mix(in srgb,var(--ctx-cielo) 22%,var(--tone-canvas));
  --tint-menta:color-mix(in srgb,var(--ctx-menta) 22%,var(--tone-canvas));
  --tint-verde:color-mix(in srgb,var(--ctx-verde) 22%,var(--tone-canvas));
  --tint-arena:color-mix(in srgb,var(--ctx-arena) 22%,var(--tone-canvas));
  --tint-naranja:color-mix(in srgb,var(--ctx-naranja) 22%,var(--tone-canvas));
  --tint-coral:color-mix(in srgb,var(--ctx-coral) 22%,var(--tone-canvas));
  --tint-rojo:color-mix(in srgb,var(--ctx-rojo) 22%,var(--tone-canvas));
  --tint-rosa:color-mix(in srgb,var(--ctx-rosa) 22%,var(--tone-canvas));
  --tint-magenta:color-mix(in srgb,var(--ctx-magenta) 22%,var(--tone-canvas));
  --tint-morado:color-mix(in srgb,var(--ctx-morado) 22%,var(--tone-canvas));
  --tint-oscuro:color-mix(in srgb,var(--ctx-oscuro) 22%,var(--tone-canvas));
}

/* ============================================================================
   1.14.1 · IDENTIDAD DE ÁREA EN MODO SOBRIO
   ----------------------------------------------------------------------------
   Va al FINAL del archivo a propósito. `:root` y `[data-color-mode="sober"]`
   tienen la misma especificidad (0,1,0), así que entre ellos decide el orden
   de aparición: el bloque `:root` que define --area-* está más arriba y
   ganaría. Neutralizar aquí es lo único que de verdad apaga el color.

   Se arregla de paso una fuga real de 1.7: las tarjetas de Hoy escribían
   `--mini-tone:var(--color-cyan)` sin guardia de modo, así que en Sobrio
   seguían saliendo cian, morada, teal y rosa. Sobrio prometía "ausencia de
   color decorativo" y cuatro fichas de colores es exactamente eso.
   ========================================================================== */
[data-color-mode="sober"],
:root:not([data-color-mode]) {
  --area-tasks:var(--ink-muted);
  --area-calendar:var(--ink-muted);
  --area-finance:var(--ink-muted);
  --area-lists:var(--ink-muted);

  /* La tinta sobria no es --ink-muted a secas: el gris secundario tiene que
     poder leerse como secundario y aun así cumplir AA a 11px sobre la
     superficie hundida. Con el #6B7280 de antes daba 4.43 y no llegaba; 1.15.0
     lo baja a #636973 (5.07) y esta mezcla al 30% de --ink lo lleva a 7.4. */
  --area-tasks-ink:color-mix(in srgb,var(--ink) 30%,var(--ink-muted));
  --area-calendar-ink:var(--area-tasks-ink);
  --area-finance-ink:var(--area-tasks-ink);
  --area-lists-ink:var(--area-tasks-ink);
}

/* ============================================================================
   SAMAPP 1.14.2 · PALETA VIVO — SEGUNDO EJE, INDEPENDIENTE DEL MODO
   ----------------------------------------------------------------------------
   POR QUÉ UN ATRIBUTO NUEVO Y NO UN TERCER VALOR DE data-color-mode.
   Contadas las reglas: 128 selectores del proyecto dependen literalmente de
   [data-color-mode="color"] (107 en base.css, 3 aquí, 17 en finanzas.css, 1 en
   captura.css). Un tercer valor —data-color-mode="vivo"— dejaría fuera esas
   128 reglas de golpe y la app perdería el aspecto entero. Así que
   data-color-mode conserva su semántica original y sólo dos valores
   ("¿se tiñe o no?") y la INTENSIDAD pasa a un eje aparte:

       data-theme      light | dark      -> luminosidad
       data-color-mode sober | color     -> ¿hay color?
       data-palette    pastel | vivo     -> ¿cuánto color?          (NUEVO)

   Sobrio ignora data-palette por construcción: con color-mode="sober" todos
   los --ctx-* y --area-* resuelven a neutros más abajo, así que da igual qué
   valga la familia --color-*. Pastel es el valor por defecto y NO redefine
   nada: quien no elija nada ve exactamente el 1.14.2 aprobado.

   ----------------------------------------------------------------------------
   1.15.0 · LOS TONOS SALEN DE "GRAFFITI POP", LA LÁMINA DE RICARDO

   La lámina trae 20 muestras en dos filas más una rampa de 10 grises. De las
   20, sólo 16 son ANCLAS DE MATIZ: las cuatro últimas de la fila 2 (#FF8C8C,
   #F8F2E8, #FFD6D2, #FFFEFF) son la cola clara —tintes y blancos—, y meterlas
   en la envolvente habría hundido el croma de toda la banda roja. Se
   reutilizan como neutros (ver el bloque de más abajo).

   MISMO MÉTODO QUE EN PASTEL, distinto material:

   1. LOS MATICES NO SE MUEVEN. Siguen siendo los trece de 1.14.1 y las cuatro
      áreas conservan su reparto exacto: azul 266°, magenta 321°, teal 182°,
      ámbar 88°. Cambiar los matices por los de la lámina habría metido a
      Pendientes y Calendario a 20° uno de otro.
   2. SE IMPORTA LA ENVOLVENTE. Leídas las 16 anclas en OKLCH, la lámina define
      una curva L(matiz) y otra C(matiz); se muestrean en los trece matices de
      la app interpolando entre vecinos. Eso trae lo que hace reconocible a
      Graffiti Pop: croma al borde del gamut en TODOS los matices (las 16
      anclas están a saturación 100) y una escalera de valor real —el violeta
      es el más oscuro (L .53), el lima el más claro (L .92)—, que es
      justamente el rango que a 1.14.1 le faltaba.
   3. LA L SE RECORTA EN BLANDO, no se trunca. Dentro de la banda utilizable
      [.640, .820] se respeta la de la lámina al pie de la letra; fuera se
      comprime (x0.20 por abajo, x0.32 por arriba) para que el ORDEN de valores
      sobreviva sin salirse de donde la tinta funciona. El suelo existe por un
      motivo medible: --ink-on-color es texto oscuro sobre relleno sólido, y
      por debajo de L .62 el morado cae de 4.5. El techo, porque un tono a
      L .92 diluido al 46% en blanco ya no se distingue del papel.

   QUÉ SE HACE CON LOS NEONES. #3DFF91 y #00F6FF a pantalla completa son
   insoportables y encima no se lee nada, así que van donde brillan sin dañar:
   el marcador de área de 6px, los puntos y los iconos —elementos SIN texto
   encima, sin ninguna restricción de contraste— y como base de rellenos ya
   diluidos por la dosis. La dosis NO se sube para "que se note más": está
   calibrada y subirla sólo se come el contraste de la etiqueta.

   ¿SE VE MÁS COLORIDO? Croma OKLCH del relleno de la ficha de Hoy (que es lo
   que se ve, no el hex del token): Pastel .021 de media, Vivo .110. Cinco
   veces. Y el 6px va a tono pleno, sin diluir.
   ========================================================================== */
[data-palette="vivo"] {
  --color-red-strong:#EE2B42;       --color-red:#FF4A55;      --color-red-soft:#E49390;
  --color-coral-strong:#ED2608;     --color-coral:#FF442B;    --color-coral-soft:#F38976;
  --color-orange-strong:#E78500;    --color-orange:#FF9401;   --color-orange-soft:#E4B388;
  --color-yellow-strong:#E0AF00;    --color-yellow:#F6C000;   --color-yellow-soft:#F5C74C;
  --color-lime-strong:#99D300;      --color-lime:#A7E600;     --color-lime-soft:#ACE736;
  --color-green-strong:#00DC7F;     --color-green:#00F08C;    --color-green-soft:#3CEE91;
  --color-teal-strong:#00D6C0;      --color-teal:#00EAD2;     --color-teal-soft:#3CE9D3;
  --color-cyan-strong:#00B2E7;      --color-cyan:#00C5FE;     --color-cyan-soft:#62CEFA;
  --color-blue-strong:#3766FF;      --color-blue:#507EFF;     --color-blue-soft:#86A8F9;
  --color-indigo-strong:#5D57FF;    --color-indigo:#6D72FF;   --color-indigo-soft:#97A3F9;
  --color-purple-strong:#8736FF;    --color-purple:#925CFF;   --color-purple-soft:#B099F9;
  --color-magenta-strong:#C300E0;   --color-magenta:#DB02FB;  --color-magenta-soft:#E477F9;
  --color-pink-strong:#EE47A6;      --color-pink:#FF5FB6;     --color-pink-soft:#E79ABE;

  /* Tinta de MODO CLARO, derivada igual que la de Pastel pero con el croma
     fijo al 70% del gamut en vez del 58%: el relleno de Vivo es cinco veces
     más cromático y una tinta contenida al 58% encima se leería apagada.
     Cada valor es la L más ALTA que a ese croma cumple los cinco umbrales.
     Comentario: sobre blanco · sobre su relleno al 46% (la ficha de Hoy) ·
     al 52% (esa ficha en hover, el peor caso real de toda la paleta). */
  --color-red-ink:#832C2F;        /* 8.87 · 4.98 · 4.61 */
  --color-coral-ink:#7F2E22;      /* 9.07 · 4.93 · 4.56 */
  --color-orange-ink:#79502A;     /* 7.01 · 4.83 · 4.58 */
  --color-yellow-ink:#705D2E;     /* 6.37 · 4.96 · 4.79 */
  --color-lime-ink:#50672D;       /* 6.33 · 5.18 · 5.03 */
  --color-green-ink:#326B48;      /* 6.30 · 4.91 · 4.78 */
  --color-teal-ink:#326960;       /* 6.32 · 4.91 · 4.79 */
  --color-cyan-ink:#2E6075;       /* 6.89 · 4.80 · 4.61 */
  --color-blue-ink:#1B3CBF;       /* 8.59 · 4.97 · 4.59 */
  --color-indigo-ink:#3D37B1;     /* 8.82 · 5.02 · 4.64 */
  --color-purple-ink:#55319B;     /* 9.13 · 5.03 · 4.61 */
  --color-magenta-ink:#5E2469;    /* 10.87 · 5.04 · 4.56 */
  --color-pink-ink:#892F60;       /* 7.96 · 4.89 · 4.61 */

  /* ---------------------------------- LA DOSIS, que es lo que se ve --------
     PRIMER INTENTO FALLIDO, y merece quedar escrito: la versión anterior de
     Vivo sólo subía el croma de los tonos y dejaba el relleno en 24%. El
     croma subía un 48% real y aun así NADIE distinguía Vivo de Pastel. La
     razón es la identidad de arriba: saturación del relleno = dosis x
     saturación del tono. Con 24% el resultado vivía entre 6 y 22 sobre 100 —
     pastel por definición, daba igual el tono de partida.

     46% en las fichas es el punto donde el relleno llega a 31 de saturación
     media (21 la familia más floja, el magenta) y TODAVÍA existe una tinta
     que cumple AA sobre él: el peor caso medido es 4.62. Por encima, la tinta
     tendría que oscurecerse tanto que dejaría de leerse como color.
     30% en las filas por lo mismo, con el meta corregido en base.css.

     La DOSIS no vive en este bloque sino en el de más abajo, junto a los
     tintes: tiene que ir condicionada a [data-color-mode="color"]. La primera
     versión la puso aquí y rompió Sobrio — `.row-rule` usa --rule-w sin
     guardia de modo, así que Sobrio+Vivo sacaba marcadores de área de 6px.
     Medido: 9 de 159 elementos cambiaban. Sobrio no puede notar la paleta. */

  /* Texto sobre RELLENOS SÓLIDOS del tono (chips activos, botón de añadir, día
     de hoy en el calendario: color-mix(tono ~92%, blanco)). Es el noveno paso
     de la rampa de grises de la propia lámina, #0C0C0C, y por ser NEUTRO no
     mete un matiz ajeno encima de un relleno saturado — el #22262B de Pastel
     tiene pizarra dentro y sobre el magenta #DB02FB se leía azulado.
     Medido sobre los rellenos sólidos reales: 5.37 Pendientes, 5.04
     Calendario, 12.76 Finanzas, 11.61 Listas; el peor chip es el morado con
     5.44. Los dos casos ajustados —Calendario y Pendientes— son los dos
     matices que la lámina pone más oscuros, y ahí el suelo de L .62 del
     recorte en blando es lo único que los mantiene por encima de 4.5. */
}

/* ============================================================================
   1.15.0 · LOS NEUTROS DE VIVO — LA RAMPA DE GRISES DE LA LÁMINA
   ----------------------------------------------------------------------------
   Graffiti Pop no trae sólo colores: trae una rampa de diez grises
   (#E3E3E3 #C4C4C4 #A6A6A6 #878787 #696969 #4A4A4A #2D2D2D #191919 #0C0C0C
   #000000) y tres tintes claros al final de la fila 2. Eso es medio sistema
   de interfaz regalado, y es lo que separa a Vivo de Pastel más allá del
   croma: Pastel se apoya en la pizarra templada de su lámina y Vivo en gris
   puro y crema. Dos personalidades, no dos intensidades del mismo gris.

   POR QUÉ HAY QUE ESCRIBIR EL SELECTOR CON data-theme Y ADEMÁS CON MEDIA QUERY.
   Un bloque [data-color-mode="color"][data-palette="vivo"] vale (0,2,0) y le
   ganaría al [data-theme="dark"] de (0,1,0) que fija los neutros oscuros: en
   modo oscuro saldrían los neutros claros. Así que el bloque explícito lleva
   [data-theme="light"] y el caso "sin atributo, sistema en claro" —que es como
   arranca quien no ha elegido tema— necesita su propio bloque dentro de la
   media query. El [data-color-mode="color"] es obligatorio en los dos: sin él
   estos neutros pisarían los de Sobrio, y Sobrio no puede notar la paleta.

   Medido con --ink-muted #5F5F5F (interpolado entre el 5º y el 6º gris de la
   rampa; el #696969 literal se quedaba en 4.16 sobre la superficie de hover):
   ink 15.79 sobre papel, muted 5.73, faint 3.23. */
[data-theme="light"][data-color-mode="color"][data-palette="vivo"] {
  --paper:#F8F2E8;           /* el crema de la fila 2, tal cual */
  --surface:#FFFFFF;
  --surface-sunken:#F3EBDD;
  --surface-hover:#EDE3D2;
  --line:#E3E3E3;            /* 1er gris de la rampa */
  --line-strong:#C4C4C4;     /* 2º gris */
  --ink:#191919;             /* 8º gris */
  --ink-strong:#0C0C0C;      /* 9º gris */
  --ink-muted:#5F5F5F;
  --ink-faint:#878787;       /* 4º gris */
}
@media (prefers-color-scheme:light) {
  :root:not([data-theme="dark"])[data-color-mode="color"][data-palette="vivo"] {
    --paper:#F8F2E8;
    --surface:#FFFFFF;
    --surface-sunken:#F3EBDD;
    --surface-hover:#EDE3D2;
    --line:#E3E3E3;
    --line-strong:#C4C4C4;
    --ink:#191919;
    --ink-strong:#0C0C0C;
    --ink-muted:#5F5F5F;
    --ink-faint:#878787;
  }
}

/* El tier -ink SE INVIERTE en oscuro: "ink" nombra un rol —el extremo del
   matiz legible sobre la superficie de este tema—, y sobre navy ese extremo es
   el claro. Hace falta repetirlo aquí por ARITMÉTICA DE ESPECIFICIDAD: el
   bloque [data-theme="dark"] que hace la inversión vale (0,1,0) igual que
   [data-palette="vivo"], y como el de Vivo aparece DESPUÉS en el archivo le
   ganaría por orden — el modo oscuro se quedaría con la tinta de modo claro.
   Con las dos condiciones juntas sube a (0,2,0) y gana siempre.
   El lienzo neutro es lo que impide que la superficie arrastre el matiz (ver
   1.14.1 arriba), y en Vivo importa MÁS, no menos: Vivo baja el suyo a #0C0C0C
   en el bloque de más abajo. Medido, soft sobre color-mix(tono 34%, #0C0C0C):
   5.10 (coral, peor caso) a 5.57. AA en las trece familias. */
/* Tintes contextuales de Vivo en CLARO. Son el fondo de las filas de Hoy, que
   en Pastel se mezclan al 15% y salen a 7 de saturación — invisibles. Al 30%
   suben a 20. Lleva [data-color-mode="color"] a la fuerza: sin esa condición
   este bloque (0,2,0) le ganaría al bloque sobrio (0,1,0) y Sobrio volvería a
   teñirse, que es exactamente lo que Sobrio promete que no pasa.
   Los bloques de oscuro de más abajo valen (0,3,0) y (0,4,0), así que
   sobrescriben estos valores donde corresponde. */
[data-color-mode="color"][data-palette="vivo"] {
  /* La dosis de Vivo. Va aquí y no en el bloque [data-palette="vivo"] porque
     --rule-w lo consume una regla SIN guardia de modo (.row-rule), y en
     Sobrio+Vivo eso sacaba marcadores de 6px donde Sobrio promete ausencia de
     color decorativo. */
  /* --ink-on-color vive AQUÍ y no en [data-palette="vivo"] por lo mismo que
     la dosis: ese bloque no lleva guardia de modo y .swipe-back button usa la
     tinta sin condicionar, así que Sobrio+Vivo salía con una tinta distinta a
     Sobrio+Pastel. Comprobado en el DOM: 10 elementos de 189 cambiaban. */
  --ink-on-color:#0C0C0C;

  --mix-card:46%;
  --mix-card-hover:52%;
  --mix-row:22%;
  --mix-row-hover:28%;
  --mix-row-border:48%;
  --mix-row-border-hover:64%;
  --mix-row-narrow:20%;

  /* El marcador de área va a TONO PLENO (saturación 46 a 92 según familia) y
     al doble de ancho. Es la palanca más rentable de todo el encargo: una
     barra no lleva texto encima, así que no tiene NINGUNA restricción de
     contraste y puede usar el tono a tope. Lo que se lee como "colorido" son
     los elementos que cantan, no un lavado de fondo menos pálido. */
  --rule-w:6px;

  --tint-atencion:color-mix(in srgb,var(--ctx-atencion) 30%,var(--tone-canvas));
  --tint-calendario:color-mix(in srgb,var(--ctx-calendario) 30%,var(--tone-canvas));
  --tint-finanzas:color-mix(in srgb,var(--ctx-finanzas) 30%,var(--tone-canvas));
  --tint-sillasmx:color-mix(in srgb,var(--ctx-sillasmx) 30%,var(--tone-canvas));
  --tint-hoc:color-mix(in srgb,var(--ctx-hoc) 30%,var(--tone-canvas));
  --tint-kam:color-mix(in srgb,var(--ctx-kam) 30%,var(--tone-canvas));
  --tint-personal:color-mix(in srgb,var(--ctx-personal) 30%,var(--tone-canvas));
  --tint-tasks:color-mix(in srgb,var(--ctx-tasks) 30%,var(--tone-canvas));
  --tint-lists:color-mix(in srgb,var(--ctx-lists) 30%,var(--tone-canvas));
  --tint-expense:color-mix(in srgb,var(--ctx-expense) 30%,var(--tone-canvas));
  --tint-income:color-mix(in srgb,var(--ctx-income) 30%,var(--tone-canvas));
  --tint-azul:color-mix(in srgb,var(--ctx-azul) 30%,var(--tone-canvas));
  --tint-cielo:color-mix(in srgb,var(--ctx-cielo) 30%,var(--tone-canvas));
  --tint-menta:color-mix(in srgb,var(--ctx-menta) 30%,var(--tone-canvas));
  --tint-verde:color-mix(in srgb,var(--ctx-verde) 30%,var(--tone-canvas));
  --tint-arena:color-mix(in srgb,var(--ctx-arena) 30%,var(--tone-canvas));
  --tint-naranja:color-mix(in srgb,var(--ctx-naranja) 30%,var(--tone-canvas));
  --tint-coral:color-mix(in srgb,var(--ctx-coral) 30%,var(--tone-canvas));
  --tint-rojo:color-mix(in srgb,var(--ctx-rojo) 30%,var(--tone-canvas));
  --tint-rosa:color-mix(in srgb,var(--ctx-rosa) 30%,var(--tone-canvas));
  --tint-magenta:color-mix(in srgb,var(--ctx-magenta) 30%,var(--tone-canvas));
  --tint-morado:color-mix(in srgb,var(--ctx-morado) 30%,var(--tone-canvas));
  --tint-oscuro:color-mix(in srgb,var(--ctx-oscuro) 30%,var(--tone-canvas));
}

[data-theme="dark"][data-palette="vivo"] {
  /* EL LIENZO DE VIVO EN OSCURO ES MUCHO MÁS OSCURO QUE EL DE PASTEL, y esto
     es el hallazgo que hizo funcionar el modo oscuro.

     En oscuro subir la dosis NO basta: acerca el relleno al tono, y los tonos
     son claros, así que el relleno se ACLARA mientras gana croma y la tinta
     clara (-soft) se queda sin contraste. Medido contra el lienzo #282828 de
     Pastel: al 46% el verde cae a 4.01 y al 52% a 3.41. Ilegible.

     Bajando el lienzo el relleno gana croma y PIERDE luminancia a la vez, que
     es lo que hace falta. 1.15.0 lo pone en #0C0C0C, que es literalmente el
     noveno gris de la rampa de Graffiti Pop y coincide con --paper: los tonos
     de la lámina son neón sobre negro, y ese es su sitio natural.

     Sigue siendo un lienzo NEUTRO, que era el punto de --tone-canvas en
     1.14.1: mezclar contra el navy arrastraba el matiz (el ámbar +77° hasta
     el verde). Sólo cambia la luminancia, no la neutralidad.
     Se declara en el bloque de más abajo, que lleva [data-color-mode="color"]:
     aquí, sin guardia de modo, Sobrio+Vivo habría heredado un lienzo distinto
     al de Sobrio+Pastel. */

  --color-blue-ink:var(--color-blue-soft);
  --color-cyan-ink:var(--color-cyan-soft);
  --color-teal-ink:var(--color-teal-soft);
  --color-green-ink:var(--color-green-soft);
  --color-lime-ink:var(--color-lime-soft);
  --color-yellow-ink:var(--color-yellow-soft);
  --color-orange-ink:var(--color-orange-soft);
  --color-coral-ink:var(--color-coral-soft);
  --color-pink-ink:var(--color-pink-soft);
  --color-magenta-ink:var(--color-magenta-soft);
  --color-purple-ink:var(--color-purple-soft);
  --color-indigo-ink:var(--color-indigo-soft);
  --color-red-ink:var(--color-red-soft);
}

/* Oscuro por preferencia del sistema, sin elección explícita. El bloque
   equivalente de 1.14.1 ya vale (0,2,0) y por sí solo le ganaría a Vivo, pero
   se repite explícito para que el día que alguien reordene el archivo la
   inversión no dependa de un empate afortunado. Aquí son (0,3,0). */
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"])[data-palette="vivo"] {
    --color-blue-ink:var(--color-blue-soft);
    --color-cyan-ink:var(--color-cyan-soft);
    --color-teal-ink:var(--color-teal-soft);
    --color-green-ink:var(--color-green-soft);
    --color-lime-ink:var(--color-lime-soft);
    --color-yellow-ink:var(--color-yellow-soft);
    --color-orange-ink:var(--color-orange-soft);
    --color-coral-ink:var(--color-coral-soft);
    --color-pink-ink:var(--color-pink-soft);
    --color-magenta-ink:var(--color-magenta-soft);
    --color-purple-ink:var(--color-purple-soft);
    --color-indigo-ink:var(--color-indigo-soft);
    --color-red-ink:var(--color-red-soft);
  }
}

/* ============================================================================
   1.14.2 · VIVO EN OSCURO — LOS --ctx-* TAMBIÉN
   ----------------------------------------------------------------------------
   HALLAZGO, medido en el DOM real durante la revisión de esta paleta.

   En oscuro, 20 tokens NO seguían a la paleta: los nueve --ctx-* de la era 1.1
   y sus nueve --tint-*, más --finance-positive/-negative que se derivan de
   ellos. Se quedaban congelados en los hex de 2019 (--ctx-personal #C08BF5,
   --ctx-income #78B58D...) en vez de resolver a la familia --color-* de 1.7.

   LA CAUSA es aritmética de especificidad, no un error de esta paleta:

     @media (prefers-color-scheme:dark) { :root:not([data-theme="light"]) }
       -> (0,2,0), fija --ctx-* y --tint-* a hex literales
     [data-color-mode="color"]
       -> (0,1,0), los remapea a var(--color-*)

   Gana el primero. Y `:not([data-theme="light"])` casa TAMBIÉN cuando el
   usuario ha elegido oscuro explícitamente, así que basta con que el SISTEMA
   operativo esté en oscuro —el caso de la mayoría de quienes usan el tema
   oscuro— para que la paleta contextual se quede en 2019. Comprobado: con el
   SO en claro y data-theme="dark" los 7 tokens de muestra sí siguen a Vivo;
   con el SO en oscuro, ninguno.

   ESTO ES ANTERIOR A VIVO Y LE PASA IGUAL A PASTEL. No se arregla para todos a
   propósito: hacerlo cambiaría el aspecto de Pastel en oscuro, que es
   justamente lo que no se puede tocar. Queda reportado.

   Aquí se corrige SÓLO para Vivo, porque si no la misma opción se vería
   distinta según cómo llegaste a oscuro (elección propia con el SO en claro vs
   SO en oscuro): eso sí sería un defecto de esta paleta y no heredado.

   El selector lleva las cuatro condiciones a propósito:
     · :root:not([data-theme="light"]) para ganarle al bloque de (0,2,0);
     · [data-color-mode="color"] para NO recolorear Sobrio — sin él este
       bloque (0,3,0) le ganaría al bloque sobrio (0,1,0) y las filas neutras
       volverían a teñirse;
     · [data-palette="vivo"] para no rozar Pastel.
   Total (0,4,0) en la variante del media query y (0,3,0) en la explícita.

   Los tintes se mezclan contra --tone-canvas, NO contra --surface: el navy
   arrastra el matiz (ámbar +77° hacia el verde, ver 1.14.1) y el lienzo de
   Vivo en oscuro (#0C0C0C, ver arriba) es neutro, así que no hay deriva.
   La dosis es 40% y no el 13% del bloque oscuro de Color: contra un lienzo
   tan oscuro el 13% seguía dando filas casi grises. Al 40% la saturación
   media de las filas sube de 11.9 (Pastel) a 27.
   ========================================================================== */
[data-theme="dark"][data-color-mode="color"] { --focus-ring:var(--color-cyan); }
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"])[data-color-mode="color"] { --focus-ring:var(--color-cyan); }
}

[data-theme="dark"][data-color-mode="color"][data-palette="vivo"] {
  /* --------------------------- 1.15.0 · NEUTROS Y DOSIS DE VIVO EN OSCURO --
     Los neutros son la rampa de la lámina de punta a punta: papel #0C0C0C,
     superficie #191919, líneas #2D2D2D y #4A4A4A, tinta #E3E3E3. Graffiti Pop
     ES neón sobre negro; con el navy de antes los tonos perdían la mitad de la
     fuerza y, peor, el navy tiene matiz propio y rotaba cualquier relleno que
     se mezclara contra él. Medido: ink 13.70 sobre la superficie, --ink-muted
     7.22, --ink-faint 4.89.

     LA DOSIS BAJA EN OSCURO, y no es una contradicción con "no subas la dosis":
     es que en oscuro la dosis va al revés. El tono es MÁS CLARO que el lienzo,
     así que subir el porcentaje ACLARA el relleno en vez de intensificarlo, y
     se lleva por delante el contraste de la tinta clara. Medido con el verde
     #00F08C contra #0C0C0C: al 46% el relleno sale #067547 y la tinta -soft se
     queda en 4.01; al 34% sale #085A38 —saturación 84, un verde joya, MÁS
     cromático que el de 46% contra blanco— y la tinta sube a 5.47.
     Menos porcentaje, más color. El peor caso de las trece familias en oscuro
     queda en 4.56 (rojo, ficha en hover). */
  --tone-canvas:#0C0C0C;
  --paper:#0C0C0C;
  --surface:#191919;
  --surface-sunken:#121212;
  --surface-hover:#2D2D2D;
  --line:#2D2D2D;
  --line-strong:#4A4A4A;
  --ink:#E3E3E3;
  --ink-strong:#FFFEFF;
  --ink-muted:#A6A6A6;
  --ink-faint:#878787;

  --mix-card:34%;
  --mix-card-hover:40%;
  --mix-row:26%;
  --mix-row-hover:32%;
  --mix-row-narrow:18%;

  --ctx-atencion:var(--color-red);
  --ctx-calendario:var(--color-magenta);
  --ctx-finanzas:var(--color-teal);
  --ctx-finanzas-soft:var(--color-teal-soft);
  --ctx-sillasmx:var(--color-yellow);
  --ctx-hoc:var(--color-coral);
  --ctx-kam:var(--color-teal);
  --ctx-personal:var(--color-purple);
  --ctx-lists:var(--color-pink);
  --ctx-tasks:var(--color-cyan);
  --ctx-expense:var(--color-coral);
  --ctx-income:var(--color-green);

  --tint-atencion:color-mix(in srgb,var(--ctx-atencion) 40%,var(--tone-canvas));
  --tint-calendario:color-mix(in srgb,var(--ctx-calendario) 40%,var(--tone-canvas));
  --tint-finanzas:color-mix(in srgb,var(--ctx-finanzas) 40%,var(--tone-canvas));
  --tint-sillasmx:color-mix(in srgb,var(--ctx-sillasmx) 40%,var(--tone-canvas));
  --tint-hoc:color-mix(in srgb,var(--ctx-hoc) 40%,var(--tone-canvas));
  --tint-kam:color-mix(in srgb,var(--ctx-kam) 40%,var(--tone-canvas));
  --tint-personal:color-mix(in srgb,var(--ctx-personal) 40%,var(--tone-canvas));
  --tint-tasks:color-mix(in srgb,var(--ctx-tasks) 40%,var(--tone-canvas));
  --tint-lists:color-mix(in srgb,var(--ctx-lists) 40%,var(--tone-canvas));
  --tint-expense:color-mix(in srgb,var(--ctx-expense) 40%,var(--tone-canvas));
  --tint-income:color-mix(in srgb,var(--ctx-income) 40%,var(--tone-canvas));
}
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"])[data-color-mode="color"][data-palette="vivo"] {
    /* Mismos neutros y misma dosis que el bloque explícito de arriba: quien
       tiene el sistema en oscuro y no ha elegido tema sólo ve este. */
    --tone-canvas:#0C0C0C;
    --paper:#0C0C0C;
    --surface:#191919;
    --surface-sunken:#121212;
    --surface-hover:#2D2D2D;
    --line:#2D2D2D;
    --line-strong:#4A4A4A;
    --ink:#E3E3E3;
    --ink-strong:#FFFEFF;
    --ink-muted:#A6A6A6;
    --ink-faint:#878787;

    --mix-card:34%;
    --mix-card-hover:40%;
    --mix-row:26%;
    --mix-row-hover:32%;
    --mix-row-narrow:18%;

    --ctx-atencion:var(--color-red);
    --ctx-calendario:var(--color-magenta);
    --ctx-finanzas:var(--color-teal);
    --ctx-finanzas-soft:var(--color-teal-soft);
    --ctx-sillasmx:var(--color-yellow);
    --ctx-hoc:var(--color-coral);
    --ctx-kam:var(--color-teal);
    --ctx-personal:var(--color-purple);
    --ctx-lists:var(--color-pink);
    --ctx-tasks:var(--color-cyan);
    --ctx-expense:var(--color-coral);
    --ctx-income:var(--color-green);

    --tint-atencion:color-mix(in srgb,var(--ctx-atencion) 40%,var(--tone-canvas));
    --tint-calendario:color-mix(in srgb,var(--ctx-calendario) 40%,var(--tone-canvas));
    --tint-finanzas:color-mix(in srgb,var(--ctx-finanzas) 40%,var(--tone-canvas));
    --tint-sillasmx:color-mix(in srgb,var(--ctx-sillasmx) 40%,var(--tone-canvas));
    --tint-hoc:color-mix(in srgb,var(--ctx-hoc) 40%,var(--tone-canvas));
    --tint-kam:color-mix(in srgb,var(--ctx-kam) 40%,var(--tone-canvas));
    --tint-personal:color-mix(in srgb,var(--ctx-personal) 40%,var(--tone-canvas));
    --tint-tasks:color-mix(in srgb,var(--ctx-tasks) 40%,var(--tone-canvas));
    --tint-lists:color-mix(in srgb,var(--ctx-lists) 40%,var(--tone-canvas));
    --tint-expense:color-mix(in srgb,var(--ctx-expense) 40%,var(--tone-canvas));
    --tint-income:color-mix(in srgb,var(--ctx-income) 40%,var(--tone-canvas));
  }
}

/* ============================================================================
   1.15.3 · MARCADOR MÁS ANCHO EN OSCURO
   ----------------------------------------------------------------------------
   En oscuro el relleno de las superficies no puede llevar el color (medido:
   el techo de contraste está en 34% de dosis y ahí la ficha apenas alcanza
   9.4 de saturación sobre 100). El color vive en el marcador, que no lleva
   texto encima y puede ir a tono pleno — así que se le da el doble de ancho.

   La guardia [data-color-mode="color"] NO es opcional: `.row-rule` consume
   --rule-w SIN condicionar el modo, y sin la guardia Sobrio sacaría
   marcadores de 6px, que es justo lo que Sobrio promete que no pasa.
   ========================================================================== */
[data-theme="dark"][data-color-mode="color"] { --rule-w:var(--marcador-oscuro,6px); }
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"])[data-color-mode="color"] { --rule-w:var(--marcador-oscuro,6px); }
}

/* ============================================================================
   2.1.2 · SOBRIO CON EL SISTEMA EN OSCURO
   ----------------------------------------------------------------------------
   Con el teléfono en oscuro, el bloque de preferencia del sistema de 1.15.0
   (:root:not([data-theme="light"]), (0,2,0)) le ganaba al apagado de Sobrio
   de 1.5.1, que pesa (0,1,0): en Oscuro + Sobrio se colaban el azul del
   calendario, el dorado del marcador de «Tu día» y el color de los gráficos.
   Con el sistema en claro todo salía gris. Aquí se repite el apagado con
   (0,3,0) sólo para los tokens que ese bloque pinta. No toca --ctx-atencion
   ni --tint-atencion (el rojo funcional) ni el modo Color.
   ========================================================================== */
@media (prefers-color-scheme:dark) {
  :root[data-color-mode="sober"]:not([data-theme="light"]),
  :root:not([data-color-mode]):not([data-theme="light"]) {
    --ctx-calendario: var(--ink-muted);
    --ctx-finanzas: var(--ink);
    --ctx-finanzas-soft: var(--ink-muted);
    --ctx-sillasmx: var(--ink-muted);
    --ctx-personal: var(--ink-muted);
    --ctx-tasks: var(--ink-muted);
    --ctx-lists: var(--ink-muted);
    --ctx-expense: var(--ink);
    --ctx-income: var(--ink);
    --tint-calendario: var(--surface-sunken);
    --tint-finanzas: var(--surface-sunken);
    --tint-sillasmx: var(--surface-sunken);
    --tint-personal: var(--surface-sunken);
    --tint-tasks: var(--surface-sunken);
    --tint-lists: var(--surface-sunken);
    --tint-expense: var(--surface-sunken);
    --tint-income: var(--surface-sunken);
  }
}
