/* GENERADO por frontend/scripts/ds-tokens.mjs — no editar. Tokens --ds-* (idénticos a src/shared/ds/tokens.css) + el CSS del sistema
 * que usa la landing, concatenado tal cual desde src/shared/ds (primitives/primitives.css · Button/Button.css · brand/brand.css · pages/pages.css · Field/Field.css · Card/Card.css · Badge/Badge.css).
 * Se regenera con `node scripts/ds-tokens.mjs` (desde frontend/); `--check` falla en CI si diverge. */
/* GENERADO por scripts/ds-tokens.mjs — tokens del sistema nuevo (rebrand), namespace --ds-*. No editar a mano.
 * Conviven con los tokens viejos de globals.css hasta que cada sprint migre sus pantallas. `node scripts/ds-tokens.mjs --check` en CI. */
:root {
  /* stops fuente (D-039: familia naranja de producción) */
  --ds-source-cream: #FAF0E8; --ds-source-amber: #F3B463; --ds-source-orange: #E07C42; --ds-source-primary: #C2562A; --ds-source-ember: #9A3F1C;
  --ds-gradient-brand: linear-gradient(135deg in oklab, #FAF0E8 12.5%, #F3B463 37.5%, #E07C42 62.5%, #C2562A 87.5%);
  --ds-gradient-brand-fallback: linear-gradient(135deg, #FAF0E8 12.5%, #F3B463 37.5%, #E07C42 62.5%, #C2562A 87.5%);
  /* rampas de producción (warm 0–950 · familia naranja) */
  --ds-warm-0: #FFFFFF;
  --ds-warm-25: #FCFBF9;
  --ds-warm-50: #F7F5F1;
  --ds-warm-100: #F5F3EF;
  --ds-warm-200: #EDEAE4;
  --ds-warm-300: #E0DCD4;
  --ds-warm-400: #C8C2B8;
  --ds-warm-500: #9A9089;
  --ds-warm-600: #7C726A;
  --ds-warm-700: #6B625B;
  --ds-warm-800: #3D352F;
  --ds-warm-900: #211B17;
  --ds-warm-950: #17120E;
  --ds-orange-tint: #FAF0E8;
  --ds-orange-tint-border: #EBD7C7;
  --ds-orange-amber: #F3B463;
  --ds-orange-glow: #E8935A;
  --ds-orange-bright: #E07C42;
  --ds-orange-mid: #D86A3C;
  --ds-orange-primary: #C2562A;
  --ds-orange-deep: #9A3F1C;
  /* semánticos — light */
  --ds-bg: #FCFBF9; /* Fondo de página: warm-25 en light (como producción; sustituye al blanco puro de D-011), warm-950 en dark. */
  --ds-surface: #FFFFFF; /* Superficie de trabajo (tier 3): blanco sobre el fondo warm, separado además por hairline (D-010). */
  --ds-surface-raised: #FFFFFF; /* Card elevada, popovers, menús (tier 2 sin vidrio). */
  --ds-surface-sunken: #F7F5F1; /* Wells, pistas, pill activa (warm-50). */
  --ds-border: rgb(33 27 23 / 0.08); /* Hairline por defecto (line-hairline de producción). */
  --ds-border-strong: rgb(33 27 23 / 0.12); /* Separador con presencia, borde de inputs (line-strong). */
  --ds-text: #211B17; /* Texto principal: warm-900 en light, crema en dark (16:1). */
  --ds-text-muted: #5A524B; /* Texto secundario. ≥ 7:1 sobre bg en ambos temas (AAA en tablas y chat): light ajustado desde warm-700 (5,8:1) a 7,4:1. */
  --ds-text-subtle: #7C726A; /* Texto e icono de un control deshabilitado (botón, trigger e ítem de menú, pulgar del switch): se atenúa por color, nunca por opacidad (D-065 · D-071). warm-600 en ambos temas; ≥ 3:1 sobre bg, surface, surface-raised y surface-sunken, por debajo de muted para que se distinga de lo habilitado. */
  --ds-text-on-accent: #FFFFFF; /* Texto sobre el acento del tema (badges, focus). Nunca sobre el botón primario: ese lleva --ds-cta-fg. */
  --ds-accent: #BD5228; /* Acento del tema: focus, badges, links, selección. Como texto es AA también sobre surface y surface-raised (D-052: en dark, accent dark de producción +0,006 de luminosidad OKLab; el CTA sigue en ORANGE.mid). No es relleno de botón (D-014). */
  --ds-accent-strong: #9A3F1C; /* Hover del acento, texto acentuado (naranja profundo en light, accent-bright de producción en dark). */
  --ds-accent-tint: #FAF0E8; /* Fondo tinte de chips, filas seleccionadas (orange-tint). */
  --ds-glow: #F3B463; /* Luz / glow del sistema (ámbar). Solo tier 1–2. */
  --ds-cta: #C2562A; /* Botón primario en la app (D-014): sólido, orange-primary con texto blanco (4,5:1) en light; accent dark con texto warm-950 (5,4:1) en dark. */
  --ds-cta-hover: #9A3F1C; /* Hover del botón primario sólido. */
  --ds-cta-fg: #FFFFFF; /* Texto del botón primario. */
  --ds-cta-glass: rgb(154 63 28 / 0.86); /* Botón primario sobre el campo (tier 1): vidrio «naranja profundo + halo»; .86 para que su texto sea AA sobre el campo (D-041). */
  --ds-cta-glass-hover: rgb(154 63 28 / 0.94); /* Hover del botón de vidrio. */
  --ds-cta-glass-fg: #FFFFFF; /* Texto del botón de vidrio: blanco en ambos temas (D-041; --ds-cta-fg es warm-950 en dark y no se lee sobre el naranja profundo). */
  --ds-cta-halo: rgb(194 86 42 / 0.35); /* Halo naranja bajo el botón de vidrio. */
  --ds-cta-halo-hover: rgb(194 86 42 / 0.5); /* Halo al hover: crece y sube de opacidad. */
  --ds-success: #177B50; /* Éxito / pedido confirmado (green-won; light #1F8A5B → #1B7D52 → #177B50 y dark #3FB37D → #44B781: AA sobre su tinte). */
  --ds-success-tint: #E6F2EB; /* Fondo pill success. */
  --ds-warning: #976210; /* Aviso / espera respuesta (amber-warn; light #B7791F → #9A6414 → #976210: AA sobre su tinte). */
  --ds-warning-tint: #FBF1DD; /* Fondo pill warning. */
  --ds-danger: #C0392B; /* Error / baja (red-lost; dark #E8705F → #F87E6D: AA sobre su tinte en surface-raised). */
  --ds-danger-tint: #FAEBE8; /* Fondo pill danger. */
  --ds-info: #2267D3; /* Información (blue-info; light #2A6FDB → #2267D3 y dark #5B92EE → #69A1FF: AA sobre su tinte). */
  --ds-info-tint: #E9F0FC; /* Fondo pill info. */
  --ds-violet: #6E4AA8; /* Categoría (violet-cat de producción; sustituye al tono indigo de D-023). Texto de badge de categoría. */
  --ds-violet-tint: #F0EAF9; /* Fondo pill de categoría. */
  --ds-scrim: rgb(23 18 14 / 0.45); /* Velo bajo modales y sheets (D-020). */
  --ds-shadow-rgb: 33 27 23; /* Insumo de sombras tintadas warm (rgb(var(--ds-shadow-rgb) / a)). */
  --ds-glass-bg: rgb(255 255 255 / 0.5); /* Relleno del vidrio (D-041: .5 / .55, el texto pleno es AA sobre el campo vivo). */
  --ds-glass-bg-modal: rgb(255 255 255 / 0.6); /* Vidrio intermedio para modales y sheets (D-028): entre el vidrio del campo (.5 / .55) y uno denso (.78); el texto muted es AA sobre la app velada. */
  --ds-glass-border: linear-gradient(140deg, rgb(255 255 255 / 0.85), rgb(255 255 255 / 0.18) 38%, rgb(255 255 255 / 0.06) 70%, rgb(255 255 255 / 0.3)); /* Borde 1 px gradiente blanco→transparente (pseudo-elemento + mask). */
  --ds-glass-highlight: rgb(255 255 255 / 0.55); /* Highlight interior 1 px. */
  --ds-specular: rgb(255 255 255 / 0.22); /* Brillo especular que sigue al cursor (--ds-mx / --ds-my). */
  --ds-field-1: #FAF0E8; /* Stop 1 del campo (crema / ámbar en dark). */
  --ds-field-2: #F3B463; /* Stop 2 del campo (ámbar / naranja en dark). */
  --ds-field-3: #E07C42; /* Stop 3 del campo (naranja / naranja profundo en dark). */
  --ds-field-4: #9A3F1C; /* Stop 4 del campo (naranja profundo / fondo dark). */
  --ds-field-veil: rgb(252 251 249 / 0.86); /* Velo radial bajo el copy del hero para legibilidad (D-041: .86 / .9, radial 100 % × 120 %). */
  --ds-chat-in: #FFFFFF; /* Burbuja entrante (cliente): la superficie elevada; el hairline lo pone --ds-border. Texto --ds-text en AAA. */
  --ds-chat-out: #FAEEE9; /* Burbuja saliente (agente u operador): acento mezclado en OKLab sobre surface-raised, 10 % light · 16 % dark. Texto --ds-text en AAA. */
  --ds-chat-out-border: #F3D6CB; /* Hairline de la burbuja saliente: el mismo tinte, más hondo (24 % · 30 %). */
  --ds-chat-meta: #4F4741; /* Hora, «Editado» y ticks sin leer sobre las burbujas: muted un paso más hondo para quedar en AAA (≥ 7) también sobre el tinte de la saliente. */
  --ds-chat-tick-read: #2267D3; /* Visto (✓✓ azul): el tono info del sistema, AA sobre las dos burbujas (el #2BA5DE de antes medía 2,6 sobre blanco). */
  --ds-chat-on-media: #FFFFFF; /* Hora y ticks ENCIMA de una foto o un vídeo, y texto sobre el velo de carga: blanco en los dos temas (el medio no cambia con el tema). */
  --ds-chat-media-veil: rgb(23 18 14 / 0.72); /* Velo warm-950 sobre un medio (degradado bajo la hora, carga, error, QR caducado): con .72 el blanco es AA aunque el medio sea blanco. */
  --ds-receipt-paper: #FFFFFF; /* Papel del recibo: blanco en los dos temas (una térmica no vira). */
  --ds-receipt-ink: #211B17; /* Tinta del recibo sobre el papel (16:1). */
  --ds-receipt-muted: #5A524B; /* Rótulos del recibo (Pagado con, Fecha, N.º de operación): el muted light del sistema, AAA sobre el papel. */
  --ds-receipt-line: #EDEAE4; /* Líneas punteadas del recibo. */
  --ds-receipt-hero-bg: #17120E; /* La «impresora»: hero siempre oscuro (warm-950) en los dos temas. */
  --ds-receipt-hero-ink: #F5F1EC; /* Texto sobre el hero del recibo («Pago completado» y el total): la crema del texto dark. */
  --ds-receipt-hero-ok: #44B781; /* Disco del check del hero: el success dark del sistema; el check va en receipt-hero-bg encima. */
  --ds-receipt-tray: #E0DCD4; /* Bandeja tras el papel: la ÚNICA pieza del recibo que vira (warm-300 en light; más hondo que el hero en dark para que el papel no se funda con él). */
  --ds-chart-bar: #7C726A; /* Columna neutra (BarChart sin tono, /debug/billing): warm-600 en light, warm-500 en dark; ≥ 4,5 sobre la superficie. */
  --ds-chart-bar-hover: #211B17; /* Columna neutra activa (hover / foco): el texto. */
  --ds-chart-people: #2267D3; /* «Personas nuevas» (tone="people"): el info del sistema, el mismo azul del badge «Nuevo» (D-065). */
  --ds-chart-people-soft: #2267D3; /* Punta de esa barra (degradado vertical): con CHART_TIP 0 es el mismo tono, barra plana. */
  --ds-chart-money: #177B50; /* «Facturación» (tone="money"): el success del sistema, la venta ganada. */
  --ds-chart-money-soft: #177B50; /* Punta de esa barra (degradado vertical): con CHART_TIP 0 es el mismo tono, barra plana. */
  --ds-chart-appt: #6E4AA8; /* «Pulso de citas» (tone="appointments"): la categoría violet, sin carga de estado. */
  --ds-chart-appt-soft: #6E4AA8; /* Punta de esa barra (degradado vertical): con CHART_TIP 0 es el mismo tono, barra plana. */
  --ds-chart-outcome: #BD5228; /* La barra «Compraron» del embudo y su «+1»: el acento (AA como texto sobre surface-raised). */
  --ds-chart-outcome-soft: #BD5228; /* Punta de esa barra (degradado vertical): con CHART_TIP 0 es el mismo tono, barra plana. */
  --ds-chart-conv-1: #9A9089; /* Rampa ordinal del embudo, paso 1 de 7 (el capítulo 1): el neutro cálido warm-500; sube hacia el naranja de marca capítulo a capítulo. */
  --ds-chart-conv-2: #9C8378; /* Rampa ordinal del embudo, paso 2 de 7 (mezcla OKLab warm-500 → naranja). */
  --ds-chart-conv-3: #9D7767; /* Rampa ordinal del embudo, paso 3 de 7 (mezcla OKLab warm-500 → naranja). */
  --ds-chart-conv-4: #9D6A56; /* Rampa ordinal del embudo, paso 4 de 7 (mezcla OKLab warm-500 → naranja). */
  --ds-chart-conv-5: #9D5C44; /* Rampa ordinal del embudo, paso 5 de 7 (mezcla OKLab warm-500 → naranja). */
  --ds-chart-conv-6: #9C4E32; /* Rampa ordinal del embudo, paso 6 de 7 (mezcla OKLab warm-500 → naranja). */
  --ds-chart-conv-7: #9A3F1C; /* Rampa ordinal del embudo, paso 7 (el último capítulo): naranja profundo en light, ámbar en dark. */
  --ds-chart-flash: #F3B463; /* Destello de un evento en vivo sobre la barra (Inicio en vivo): la luz ámbar del sistema, que se apaga en 400 ms. */
  --ds-font-wa: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; /* Fuente del teléfono de «Probar»: la del sistema del teléfono, como en WhatsApp (paleta de tercero). */
  --ds-shadow-wa-bubble: 0 1px 0.5px rgb(11 20 26 / 0.13); /* Sombra mínima de burbujas, chips y campo del teléfono de «Probar» (WhatsApp). */
  --ds-wa-header-bg: #F0F2F5; /* Cabecera del teléfono de «Probar» (WhatsApp). */
  --ds-wa-header-text: #111B21; /* Nombre del agente en la cabecera. */
  --ds-wa-header-sub: #5D6D77; /* «en línea» / «escribiendo…»: un punto más oscuro que WhatsApp para pasar AA. */
  --ds-wa-header-icon: #54656F; /* Iconos y controles de la cabecera. */
  --ds-wa-header-line: rgb(17 27 33 / 0.10); /* Hairline bajo la cabecera. */
  --ds-wa-pill-bg: rgb(84 101 111 / 0.12); /* Píldora «Empezar en» y hover de los iconos de la cabecera. */
  --ds-wa-avatar-bg: #DFE5E7; /* Fondo del avatar del agente. */
  --ds-wa-avatar-fg: #54656F; /* Iniciales del avatar. */
  --ds-wa-thread-bg: #EFEAE2; /* Papel tapiz del hilo. */
  --ds-wa-doodle: rgb(94 76 51 / 0.10); /* Garabatos del papel tapiz: el beige lee primero. */
  --ds-wa-in-bg: #FFFFFF; /* Burbuja del cliente. */
  --ds-wa-out-bg: #D9FDD3; /* Burbuja del agente (verde de WhatsApp). */
  --ds-wa-text: #111B21; /* Texto de las burbujas. */
  --ds-wa-time: #667781; /* Hora sobre la burbuja del cliente; puntos de «escribiendo». */
  --ds-wa-time-out: #5B6B76; /* Hora sobre la burbuja verde. */
  --ds-wa-tick: #8696A0; /* Check de enviado / entregado. */
  --ds-wa-tick-read: #53BDEB; /* Doble check azul de leído (el de WhatsApp: 1,9 sobre la burbuja verde, asumido). */
  --ds-wa-chip-bg: #FFFFFF; /* Chips de sistema (fecha, capítulo, herramientas). */
  --ds-wa-chip-text: #54656F; /* Texto de los chips de sistema. */
  --ds-wa-notice-bg: #FFEECD; /* Chip de aviso (el amarillo del cifrado de extremo a extremo). */
  --ds-wa-notice-text: #54656F; /* Texto del chip de aviso. */
  --ds-wa-sender: #D6297F; /* Rótulo «Cliente de ejemplo», como el nombre del remitente en un grupo. */
  --ds-wa-error: #EA0038; /* Fallo de entrega y herramienta en error (el rojo de WhatsApp; 4,42 en dark sobre la entrante, asumido). */
  --ds-wa-composer-bg: #F0F2F5; /* Banda del compositor. */
  --ds-wa-input-bg: #FFFFFF; /* Campo redondeado del compositor. */
  --ds-wa-input-text: #111B21; /* Texto del campo. */
  --ds-wa-placeholder: #667781; /* Placeholder «Escribe como el cliente…» (AA sobre el campo). */
  --ds-wa-send-bg: #00A884; /* Botón redondo de enviar (verde de WhatsApp); también el caret del campo. */
  --ds-wa-send-fg: #FFFFFF; /* Avión del botón de enviar (icono: ≥ 3:1). */
  --ds-wa-action-bg: #008069; /* Píldora llena dentro de un chip (Guardar y probar) y puntos de progreso de la demo. */
  --ds-wa-action-fg: #FFFFFF; /* Texto de la píldora llena. */
  --ds-wa-action-text: #006B57; /* Botón de solo texto sobre el chip amarillo (Detener demo) y hover del chip de capítulo. */
  --ds-wa-focus: #008069; /* Anillo de foco sólido dentro del teléfono (≥ 3:1 sobre cabecera y compositor). */
  --ds-wa-scrollbar: rgb(17 27 33 / 0.22); /* Barra de scroll fina del hilo. */
  --ds-wa-selection: rgb(0 168 132 / 0.28); /* Selección de texto dentro del teléfono. */

  /* tipografía (D-008): Manrope única familia · JetBrains Mono para IDs, teléfonos, código y atajos. Escala «Editorial» (D-019): titular hasta 6,2 rem, cuerpo 16, UI 14, tabla 13,5. */
  --ds-font-sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --ds-font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
  --ds-weight-regular: 400; --ds-weight-medium: 500; --ds-weight-semibold: 600; --ds-weight-bold: 700; --ds-weight-heavy: 800;
  --ds-leading-display: .95; --ds-leading-tight: 1.1; --ds-leading-snug: 1.25; --ds-leading-normal: 1.5; --ds-leading-relaxed: 1.6;
  --ds-tracking-display: -.05em; --ds-tracking-h1: -.035em; --ds-tracking-tight: -.02em; --ds-tracking-normal: 0; --ds-tracking-wide: .06em; --ds-tracking-caps: .08em;
  --ds-text-display: clamp(3.3rem, 7vw, 6.2rem); --ds-text-h1: 30px; --ds-text-h2: 24px; --ds-text-h3: 18px; --ds-text-lede: 19px;
  --ds-text-base: 16px; --ds-text-ui: 14px; --ds-text-table: 13.5px; --ds-text-sm: 13px; --ds-text-xs: 12px; --ds-text-2xs: 11px;
  /* espaciado (8 pt) y densidad: comfortable por defecto; [data-density="compact"] en tablas y listas */
  --ds-space-0: 0; --ds-space-1: 4px; --ds-space-2: 8px; --ds-space-3: 12px; --ds-space-4: 16px; --ds-space-5: 20px; --ds-space-6: 24px; --ds-space-8: 32px; --ds-space-10: 40px; --ds-space-12: 48px; --ds-space-16: 64px; --ds-space-20: 80px; --ds-space-24: 96px; --ds-space-32: 128px;
  --ds-row-h: 44px; --ds-cell-x: var(--ds-space-3); --ds-control-h: 40px; --ds-control-h-sm: 32px; --ds-control-h-lg: 52px;
  /* radios (D-010 · Plano): 10 controles · 14 cards · 18 frames y paneles */
  --ds-radius-xs: 4px; --ds-radius-sm: 6px; --ds-radius-md: 10px; --ds-radius-lg: 14px; --ds-radius-xl: 18px; --ds-radius-2xl: 24px; --ds-radius-full: 999px;
  /* elevación «Capas» (D-020): dos capas tintadas warm por elevación (más lejos, más difusa) SOLO en lo que flota (tier 2:
   * menús, popovers, modales, sheets, toasts) y en el vidrio de tier 1 (sombra + halo ámbar). Las superficies de trabajo (tier 3)
   * siguen planas (D-010): nunca box-shadow en cards, filas ni paneles fijos. Excepción explícita a «sin sombras decorativas» (D-009). */
  --ds-shadow-none: none;
  --ds-shadow-float: 0 4px 10px rgb(var(--ds-shadow-rgb) / .08), 0 12px 32px rgb(var(--ds-shadow-rgb) / .10);
  --ds-shadow-modal: 0 8px 20px rgb(var(--ds-shadow-rgb) / .10), 0 32px 80px rgb(var(--ds-shadow-rgb) / .18);
  --ds-shadow-toast: 0 6px 16px rgb(var(--ds-shadow-rgb) / .10), 0 18px 40px rgb(var(--ds-shadow-rgb) / .12);
  --ds-shadow-glass: 0 30px 80px rgb(var(--ds-shadow-rgb) / .28), 0 0 60px rgb(243 180 99 / .25);
  --ds-shadow-halo: 0 8px 30px var(--ds-cta-halo); --ds-shadow-halo-hover: 0 12px 40px var(--ds-cta-halo-hover);
  --ds-shadow-focus: 0 0 0 2px var(--ds-bg), 0 0 0 4px var(--ds-accent);   /* anillo de foco por box-shadow cuando el outline no puede seguir el radio */
  --ds-shadow-ring: 0 0 0 3px var(--ds-accent-tint); --ds-shadow-ring-danger: 0 0 0 3px var(--ds-danger-tint);   /* anillo tinte de foco en campos */
  /* motion (D-016 · Calma): fundidos de 4 px, cúbica suave, sin spring ni magnetismo. Tier 2 ≤ 250 ms · tier 3 ≤ 150 ms. */
  --ds-dur-instant: 80ms; --ds-dur-fast: 150ms; --ds-dur-base: 240ms; --ds-dur-slow: 400ms; --ds-dur-cinematic: 1200ms; --ds-dur-theme: 600ms; --ds-dur-field: 26s;
  --ds-ease-enter: cubic-bezier(.33, 1, .68, 1); --ds-ease-exit: cubic-bezier(.4, 0, 1, 1); --ds-ease-live: var(--ds-ease-enter); --ds-ease-micro: var(--ds-ease-enter); --ds-ease-linear: linear;
  --ds-ease-spring: linear(0, .006, .025 2.8%, .101 6.1%, .539 18.9%, .721 25.3%, .849 31.5%, .937 38.1%, .968 41.8%, .991 45.7%, 1.006 50.1%, 1.012 55.3%, 1.007 63.5%, .998 78.9%, 1);
  --ds-stagger: 60ms; --ds-stagger-max: 12;
  --ds-dist-1: 4px; --ds-dist-2: 8px; --ds-dist-3: 16px; --ds-dist-4: 24px; --ds-dist-enter: var(--ds-dist-1);
  --ds-scale-press: .96; --ds-scale-hover: 1; --ds-scale-enter: .985;
  --ds-shimmer-dur: 1.8s; --ds-typing-dur: 1.6s; --ds-pulse-dur: 2.4s; --ds-spin-dur: .8s; --ds-specular-o: .5;
  /* grano (D-021): SOLO tier 1, sobre el campo, al 10 %; la app (tier 2/3) no lleva grano (D-010) · vidrio · campo */
  --ds-grain: .10;
  --ds-glass-blur: 20px; --ds-glass-saturate: 160%; --ds-glass-blur-cta: 18px;
  --ds-field-speed: 26;
  /* z-index: misma escala que el sistema viejo para convivir sin solapes */
  --ds-z-dropdown: 1000; --ds-z-sticky: 1020; --ds-z-fixed: 1030; --ds-z-modal-backdrop: 1040; --ds-z-modal: 1050; --ds-z-popover: 1060; --ds-z-tooltip: 1070;
  /* foco: anillo 2 px con el gradiente de marca (tier 1–2) o el acento (tier 3) */
  --ds-focus: var(--ds-accent); --ds-focus-offset: 2px;
  color-scheme: light;
}
[data-theme="dark"] {
  --ds-bg: #17120E;
  --ds-surface: #221C17;
  --ds-surface-raised: #2A231D;
  --ds-surface-sunken: #1C1712;
  --ds-border: rgb(255 255 255 / 0.08);
  --ds-border-strong: rgb(255 255 255 / 0.14);
  --ds-text: #F5F1EC;
  --ds-text-muted: #A89E95;
  --ds-text-subtle: #7C726A;
  --ds-text-on-accent: #17120E;
  --ds-accent: #DA6C3E;
  --ds-accent-strong: #E68A54;
  --ds-accent-tint: rgb(216 106 60 / 0.12);
  --ds-glow: #F3B463;
  --ds-cta: #D86A3C;
  --ds-cta-hover: #E07C42;
  --ds-cta-fg: #17120E;
  --ds-cta-glass: rgb(154 63 28 / 0.86);
  --ds-cta-glass-hover: rgb(154 63 28 / 0.94);
  --ds-cta-glass-fg: #FFFFFF;
  --ds-cta-halo: rgb(194 86 42 / 0.35);
  --ds-cta-halo-hover: rgb(194 86 42 / 0.5);
  --ds-success: #44B781;
  --ds-success-tint: rgb(63 179 125 / 0.18);
  --ds-warning: #D9A23E;
  --ds-warning-tint: rgb(217 162 62 / 0.18);
  --ds-danger: #F87E6D;
  --ds-danger-tint: rgb(232 112 95 / 0.18);
  --ds-info: #69A1FF;
  --ds-info-tint: rgb(91 146 238 / 0.18);
  --ds-violet: #B69BE8;
  --ds-violet-tint: rgb(182 155 232 / 0.18);
  --ds-scrim: rgb(23 18 14 / 0.6);
  --ds-shadow-rgb: 0 0 0;
  --ds-glass-bg: rgb(23 18 14 / 0.55);
  --ds-glass-bg-modal: rgb(23 18 14 / 0.6);
  --ds-glass-border: linear-gradient(140deg, rgb(255 255 255 / 0.38), rgb(255 255 255 / 0.08) 40%, rgb(255 255 255 / 0.03) 70%, rgb(255 255 255 / 0.16));
  --ds-glass-highlight: rgb(255 255 255 / 0.16);
  --ds-specular: rgb(255 255 255 / 0.12);
  --ds-field-1: #F3B463;
  --ds-field-2: #D86A3C;
  --ds-field-3: #9A3F1C;
  --ds-field-4: #17120E;
  --ds-field-veil: rgb(23 18 14 / 0.9);
  --ds-chat-in: #2A231D;
  --ds-chat-out: #432F23;
  --ds-chat-out-border: #5B3928;
  --ds-chat-meta: #CBC1B8;
  --ds-chat-tick-read: #69A1FF;
  --ds-chat-on-media: #FFFFFF;
  --ds-chat-media-veil: rgb(23 18 14 / 0.72);
  --ds-receipt-paper: #FFFFFF;
  --ds-receipt-ink: #211B17;
  --ds-receipt-muted: #5A524B;
  --ds-receipt-line: #EDEAE4;
  --ds-receipt-hero-bg: #17120E;
  --ds-receipt-hero-ink: #F5F1EC;
  --ds-receipt-hero-ok: #44B781;
  --ds-receipt-tray: #0F0B08;
  --ds-chart-bar: #9A9089;
  --ds-chart-bar-hover: #F5F1EC;
  --ds-chart-people: #69A1FF;
  --ds-chart-people-soft: #69A1FF;
  --ds-chart-money: #44B781;
  --ds-chart-money-soft: #44B781;
  --ds-chart-appt: #B69BE8;
  --ds-chart-appt-soft: #B69BE8;
  --ds-chart-outcome: #DA6C3E;
  --ds-chart-outcome-soft: #DA6C3E;
  --ds-chart-conv-1: #9A9089;
  --ds-chart-conv-2: #A99685;
  --ds-chart-conv-3: #B79C80;
  --ds-chart-conv-4: #C6A37A;
  --ds-chart-conv-5: #D5A874;
  --ds-chart-conv-6: #E4AE6C;
  --ds-chart-conv-7: #F3B463;
  --ds-chart-flash: #F3B463;
  --ds-font-wa: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --ds-shadow-wa-bubble: 0 1px 0.5px rgb(11 20 26 / 0.40);
  --ds-wa-header-bg: #202C33;
  --ds-wa-header-text: #E9EDEF;
  --ds-wa-header-sub: #8696A0;
  --ds-wa-header-icon: #AEBAC1;
  --ds-wa-header-line: rgb(233 237 239 / 0.10);
  --ds-wa-pill-bg: rgb(174 186 193 / 0.14);
  --ds-wa-avatar-bg: #3B4A54;
  --ds-wa-avatar-fg: #E9EDEF;
  --ds-wa-thread-bg: #0B141A;
  --ds-wa-doodle: rgb(233 237 239 / 0.05);
  --ds-wa-in-bg: #202C33;
  --ds-wa-out-bg: #005C4B;
  --ds-wa-text: #E9EDEF;
  --ds-wa-time: #8696A0;
  --ds-wa-time-out: rgb(233 237 239 / 0.82);
  --ds-wa-tick: #8696A0;
  --ds-wa-tick-read: #53BDEB;
  --ds-wa-chip-bg: #182229;
  --ds-wa-chip-text: #8696A0;
  --ds-wa-notice-bg: #182229;
  --ds-wa-notice-text: #FFD279;
  --ds-wa-sender: #F06292;
  --ds-wa-error: #F15C6D;
  --ds-wa-composer-bg: #202C33;
  --ds-wa-input-bg: #2A3942;
  --ds-wa-input-text: #D1D7DB;
  --ds-wa-placeholder: #9FADB5;
  --ds-wa-send-bg: #00A884;
  --ds-wa-send-fg: #111B21;
  --ds-wa-action-bg: #00A884;
  --ds-wa-action-fg: #111B21;
  --ds-wa-action-text: #06CF9C;
  --ds-wa-focus: #00A884;
  --ds-wa-scrollbar: rgb(233 237 239 / 0.18);
  --ds-wa-selection: rgb(0 168 132 / 0.35);
  color-scheme: dark;
}
[data-density="compact"] { --ds-row-h: 34px; --ds-cell-x: var(--ds-space-2); --ds-control-h: 32px; }
@media (prefers-reduced-motion: reduce) { :root { --ds-rm: 1; } }

/* ── src/shared/ds/primitives/primitives.css ── */
/* Primitivas del sistema nuevo (Gate 3 · bloque 2). Zona estricta: solo tokens --ds-*; solo transform / opacity animados. */

/* ── Field · MeshFlow (D-002) ─────────────────────────────────────────────── */
.ds-mesh { position: relative; overflow: hidden; isolation: isolate; }
.ds-mesh__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; image-rendering: auto; z-index: 0; }
.ds-mesh--veil::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(100% 120% at 22% 55%, var(--ds-field-veil), transparent 70%); }
.ds-mesh__content { position: relative; z-index: 2; height: 100%; }

/* ── Grain (D-021: solo tier 1, .10) ──────────────────────────────────────── */
.ds-grain { position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: overlay; background-image: var(--ds-grain-url); background-repeat: repeat; background-size: 256px 256px; image-rendering: pixelated; }
.ds-grain { opacity: var(--ds-grain); }

/* ── Glass ────────────────────────────────────────────────────────────────── */
.ds-glass { position: relative; isolation: isolate; background: var(--ds-glass-bg); -webkit-backdrop-filter: blur(var(--ds-glass-blur)) saturate(var(--ds-glass-saturate)); backdrop-filter: blur(var(--ds-glass-blur)) saturate(var(--ds-glass-saturate)); box-shadow: inset 0 1px 0 var(--ds-glass-highlight), var(--ds-shadow-glass); transition: box-shadow var(--ds-dur-base) var(--ds-ease-enter); }
.ds-glass--flat { box-shadow: inset 0 1px 0 var(--ds-glass-highlight); }
.ds-glass--r-md { border-radius: var(--ds-radius-md); }
.ds-glass--r-lg { border-radius: var(--ds-radius-lg); }
.ds-glass--r-xl { border-radius: var(--ds-radius-xl); }
.ds-glass--r-2xl { border-radius: var(--ds-radius-2xl); }
.ds-glass--r-full { border-radius: var(--ds-radius-full); }
/* borde gradiente 1 px (mask) */
.ds-glass::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; background: var(--ds-glass-border); -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none; z-index: 2; }
/* especular: sigue al cursor (--ds-mx / --ds-my desde useSpecular); el hover responde en borde y highlight, no en blur */
.ds-glass::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: radial-gradient(360px circle at var(--ds-mx, 50%) var(--ds-my, 0%), var(--ds-specular), transparent 60%); opacity: var(--ds-specular-o); pointer-events: none; z-index: 1; transition: opacity var(--ds-dur-base) var(--ds-ease-enter); }
.ds-glass:hover::after { opacity: 1; }
.ds-glass > * { position: relative; z-index: 3; }

/* ── Signature ────────────────────────────────────────────────────────────── */
.ds-signature { display: block; pointer-events: none; background: var(--ds-gradient-brand-fallback); background: var(--ds-gradient-brand); }
.ds-signature--hairline { height: 2px; width: var(--ds-sig-w, 120px); border-radius: var(--ds-radius-xs); transform-origin: left; animation: ds-draw-x var(--ds-dur-slow) var(--ds-ease-enter) both; }
.ds-signature--bar { position: absolute; left: 0; top: var(--ds-space-2); bottom: var(--ds-space-2); width: 3px; border-radius: var(--ds-radius-xs); transform-origin: top; animation: ds-draw-y var(--ds-dur-fast) var(--ds-ease-enter) both; }
.ds-signature--ring { position: absolute; inset: -3px; border-radius: inherit; padding: 2px; -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: ds-fade-in var(--ds-dur-fast) var(--ds-ease-enter) both; }
@keyframes ds-draw-x { from { transform: scaleX(0); } }
@keyframes ds-draw-y { from { transform: scaleY(0); } }
@keyframes ds-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ── Reveal · Stagger (D-016: fundido + 4 px, stagger 60, tope 12) ───────── */
.ds-reveal { opacity: 0; }
.ds-reveal.is-in { animation: ds-reveal var(--ds-dur-slow) var(--ds-ease-enter) both; animation-delay: calc(var(--ds-i, 0) * var(--ds-stagger)); }
.ds-reveal--cinematic.is-in { animation-duration: var(--ds-dur-cinematic); }
@keyframes ds-reveal { from { opacity: 0; transform: translateY(var(--ds-dist-enter)); } to { opacity: 1; transform: none; } }

/* ── Presence (entra lento, sale rápido; origen espacial) ─────────────────── */
.ds-presence[data-state="entering"] { animation: ds-enter var(--ds-dur-base) var(--ds-ease-enter) both; }
.ds-presence[data-state="exiting"] { animation: ds-exit var(--ds-dur-fast) var(--ds-ease-exit) both; pointer-events: none; }
.ds-presence[data-origin="center"] { --ds-from: scale(var(--ds-scale-enter)); }
.ds-presence[data-origin="top"] { --ds-from: translateY(calc(-1 * var(--ds-dist-2))); }
.ds-presence[data-origin="bottom"] { --ds-from: translateY(var(--ds-dist-2)); }
.ds-presence[data-origin="left"] { --ds-from: translateX(calc(-1 * var(--ds-dist-3))); }
.ds-presence[data-origin="right"] { --ds-from: translateX(var(--ds-dist-3)); }
.ds-presence[data-origin="top-left"] { --ds-from: scale(var(--ds-scale-enter)); transform-origin: top left; }
.ds-presence[data-origin="top-right"] { --ds-from: scale(var(--ds-scale-enter)); transform-origin: top right; }
@keyframes ds-enter { from { opacity: 0; transform: var(--ds-from, none); } to { opacity: 1; transform: none; } }
@keyframes ds-exit { from { opacity: 1; transform: none; } to { opacity: 0; transform: var(--ds-from, none); } }

/* ── SharedElement (View Transitions): crossfade de raíz con el tempo del tema ─ */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--ds-dur-slow); animation-timing-function: var(--ds-ease-enter); }

/* ── LiveIndicator ────────────────────────────────────────────────────────── */
.ds-live { display: inline-flex; align-items: center; gap: var(--ds-space-2); font-size: var(--ds-text-xs); color: var(--ds-text-muted); }
.ds-live__dot { position: relative; width: 8px; height: 8px; border-radius: var(--ds-radius-full); background: var(--ds-text-muted); flex: none; }
/* pulso: un anillo ::after que escala y se desvanece (solo transform / opacity) */
.ds-live--online .ds-live__dot, .ds-live--live .ds-live__dot { background: var(--ds-pulse); }
.ds-live--online .ds-live__dot { --ds-pulse: var(--ds-success); }
.ds-live--live .ds-live__dot { --ds-pulse: var(--ds-glow); }
.ds-live--online .ds-live__dot::after, .ds-live--live .ds-live__dot::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: var(--ds-pulse); animation: ds-pulse var(--ds-pulse-dur) var(--ds-ease-enter) infinite; }
.ds-live__typing { display: inline-flex; gap: 3px; align-items: center; height: 8px; }
.ds-live__typing i { width: 6px; height: 6px; border-radius: var(--ds-radius-full); background: var(--ds-text-muted); animation: ds-typing var(--ds-typing-dur) var(--ds-ease-enter) infinite; }
.ds-live__typing i:nth-child(2) { animation-delay: calc(var(--ds-typing-dur) / 8); }
.ds-live__typing i:nth-child(3) { animation-delay: calc(var(--ds-typing-dur) / 4); }
.ds-live--typing { color: var(--ds-warning); }
@keyframes ds-pulse { 0% { transform: scale(1); opacity: .6; } 70%, 100% { transform: scale(3); opacity: 0; } }
@keyframes ds-typing { 0%, 60%, 100% { opacity: .35; } 30% { opacity: 1; } }

/* ── Reduced motion: se diseña, no se apaga ───────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ds-reveal.is-in { animation-name: ds-fade-in; animation-delay: 0s; }
  .ds-presence[data-state="entering"] { animation-name: ds-fade-in; }
  .ds-presence[data-state="exiting"] { animation-name: ds-fade-out; }
  .ds-signature--hairline, .ds-signature--bar { animation-name: ds-fade-in; }
  .ds-live--online .ds-live__dot::after, .ds-live--live .ds-live__dot::after { animation: none; opacity: 0; }
  .ds-live__typing i { animation: none; opacity: 1; }
  .ds-glass::after { opacity: var(--ds-specular-o); }
}
@keyframes ds-fade-out { from { opacity: 1; } to { opacity: 0; } }

/* ── src/shared/ds/components/Button/Button.css ── */
/* Button · sistema nuevo (D-022 · «Caja»). Zona estricta: solo tokens --ds-*.
 * Plano puro: secundario en caja con hairline fuerte, ghost transparente que se rellena con el well, danger en caja con texto danger.
 * Descartadas (historial hasta 865af653): Tinta (rellenos de tinte, ghost subrayado, loading por hairline) y Firma (hairline de gradiente al hover, danger sólido). */

/* ── base (común a las tres): geometría Plano (D-010), primario Río (D-014), motion Calma (D-016) ─────────────── */
.ds-button { --ds-btn-h: var(--ds-control-h); --ds-btn-px: var(--ds-space-4); --ds-btn-fs: var(--ds-text-ui);
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--ds-space-2);
  height: var(--ds-btn-h); padding: 0 var(--ds-btn-px); border-radius: var(--ds-radius-md); border: 1px solid transparent;
  font-family: var(--ds-font-sans); font-size: var(--ds-btn-fs); font-weight: var(--ds-weight-semibold); line-height: 1; letter-spacing: var(--ds-tracking-normal);
  color: var(--ds-text); background: transparent; cursor: pointer; white-space: nowrap; user-select: none; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--ds-dur-fast) var(--ds-ease-enter), border-color var(--ds-dur-fast) var(--ds-ease-enter), color var(--ds-dur-fast) var(--ds-ease-enter), box-shadow var(--ds-dur-fast) var(--ds-ease-enter), transform var(--ds-dur-fast) var(--ds-ease-enter); }
.ds-button:active:not(:disabled) { transform: scale(var(--ds-scale-press)); transition-duration: var(--ds-dur-instant); }
.ds-button:focus-visible { outline: 2px solid var(--ds-focus); outline-offset: var(--ds-focus-offset); }
.ds-button:disabled { cursor: not-allowed; }
.ds-button--sm { --ds-btn-h: var(--ds-control-h-sm); --ds-btn-px: var(--ds-space-3); --ds-btn-fs: var(--ds-text-sm); }
.ds-button--lg { --ds-btn-h: var(--ds-control-h-lg); --ds-btn-px: var(--ds-space-6); --ds-btn-fs: var(--ds-text-base); }
.ds-button--icon { width: var(--ds-btn-h); padding: 0; }
.ds-button--full { width: 100%; }
.ds-button__icon { display: inline-flex; width: 1.15em; height: 1.15em; }
.ds-button__icon > * { width: 100%; height: 100%; }
.ds-button__label { display: inline-flex; align-items: center; }
.ds-button--icon .ds-button__label > * { width: 1.15em; height: 1.15em; }

/* primario: Río sólido (D-014) en la app */
.ds-button--primary { background: var(--ds-cta); color: var(--ds-cta-fg); }
.ds-button--primary:hover:not(:disabled) { background: var(--ds-cta-hover); }
/* primario de vidrio (tier 1, sobre el campo): «Río profundo + halo» */
.ds-button--glass { isolation: isolate; overflow: hidden; background: var(--ds-cta-glass); color: var(--ds-cta-glass-fg); -webkit-backdrop-filter: blur(var(--ds-glass-blur-cta)) saturate(var(--ds-glass-saturate)); backdrop-filter: blur(var(--ds-glass-blur-cta)) saturate(var(--ds-glass-saturate)); box-shadow: inset 0 1px 0 var(--ds-glass-highlight), var(--ds-shadow-halo); }
.ds-button--glass:hover:not(:disabled) { background: var(--ds-cta-glass-hover); box-shadow: inset 0 1px 0 var(--ds-glass-highlight), var(--ds-shadow-halo-hover); }
.ds-button--glass::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; background: var(--ds-glass-border); -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none; z-index: 2; }
.ds-button--glass::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: radial-gradient(140px circle at var(--ds-mx, 50%) var(--ds-my, 0%), var(--ds-specular), transparent 65%); opacity: 0; pointer-events: none; z-index: 1; transition: opacity var(--ds-dur-fast) var(--ds-ease-enter); }
.ds-button--glass:hover::after { opacity: 1; }
.ds-button--glass > * { position: relative; z-index: 3; }

/* loading: el ancho no cambia; el spinner sustituye al icono izquierdo o se antepone; el texto baja de peso */
.ds-button__spinner { width: 1em; height: 1em; border-radius: var(--ds-radius-full); border: 2px solid transparent; border-top-color: currentColor; border-right-color: currentColor; opacity: .9; animation: ds-spin var(--ds-spin-dur) var(--ds-ease-linear) infinite; }
.ds-button.is-loading .ds-button__icon--left { display: none; }
.ds-button.is-loading { opacity: .85; }
@keyframes ds-spin { to { transform: rotate(360deg); } }

/* ── secundario · ghost · danger (Caja, D-022) ─────────────────────────────── */
.ds-button--secondary { background: var(--ds-surface-raised); border-color: var(--ds-border-strong); color: var(--ds-text); }
.ds-button--secondary:hover:not(:disabled) { background: var(--ds-surface-sunken); }
.ds-button--ghost { color: var(--ds-text-muted); }
.ds-button--ghost:hover:not(:disabled) { background: var(--ds-surface-sunken); color: var(--ds-text); }
.ds-button--danger { background: var(--ds-surface-raised); border-color: var(--ds-border-strong); color: var(--ds-danger); }
.ds-button--danger:hover:not(:disabled) { background: var(--ds-danger-tint); border-color: var(--ds-danger); }

/* deshabilitado por color, nunca por opacidad (D-065 · D-071): texto subtle; las variantes con caja pasan al well con hairline
   y el ghost sigue sin caja. El loading no entra: conserva su variante y se lee por el spinner y aria-busy. */
.ds-button:disabled:not(.is-loading) { color: var(--ds-text-subtle); }
.ds-button--primary:disabled:not(.is-loading), .ds-button--secondary:disabled:not(.is-loading), .ds-button--danger:disabled:not(.is-loading) { background: var(--ds-surface-sunken); border-color: var(--ds-border); }

/* reduced motion: sin spinner giratorio ni barra; el estado loading se lee por opacidad y aria-busy */
@media (prefers-reduced-motion: reduce) {
  .ds-button__spinner { animation: none; }
  .ds-button:active:not(:disabled) { transform: none; }
}

/* ── src/shared/ds/brand/brand.css ── */
/* Marca · sistema nuevo (D-033 · «Bandas»). Zona estricta: solo tokens --ds-*.
 * Símbolo: embudo de tres bandas del gradiente con radio completo; wordmark «DarkFunnels» en Manrope 800, −.035em, tinta.
 * Regla de color: cada tema usa la mitad del gradiente que contrasta con su fondo —
 *   light: naranja → naranja profundo (--ds-brand-g1 → g3, g2 = mezcla oklab) · dark: crema → naranja → naranja. Stops de D-039 (paleta de producción), sin derivar; sobre tile ember, la mitad clara.
 * Nada aquí toca public/: los archivos de ./assets se copian a public/ en S1 / S3.
 * Descartadas (historial hasta dbc44997): A «Espiral» (isotipo trazado con gradiente, Manrope 700) y C «Monograma» (wordmark de dos tonos + tile «df»). */

/* ── stops del gradiente de marca por tema ─────────────────────────────────────────────────────────────────────────── */
.ds-brand-svg, .ds-brand, .ds-fav, .ds-og {
  --ds-brand-g1: var(--ds-source-primary);
  --ds-brand-g2: color-mix(in oklab, var(--ds-source-primary), var(--ds-source-ember));
  --ds-brand-g3: var(--ds-source-ember);
  --ds-brand-ink: var(--ds-text);
}
[data-theme="dark"] .ds-brand-svg, [data-theme="dark"] .ds-brand, [data-theme="dark"] .ds-fav, [data-theme="dark"] .ds-og, .ds-og, .ds-og .ds-brand-svg, .ds-brand-svg--tile {
  --ds-brand-g1: var(--ds-source-cream);
  --ds-brand-g2: var(--ds-source-orange);
  --ds-brand-g3: var(--ds-source-primary);
}
.ds-brand-svg__f1 { fill: var(--ds-brand-g1); }
.ds-brand-svg__f2 { fill: var(--ds-brand-g2); }
.ds-brand-svg__f3 { fill: var(--ds-brand-g3); }
.ds-brand-svg__tile { fill: var(--ds-source-ember); }

/* ── lockup (HTML: símbolo SVG + wordmark compuesto en Manrope, D-008). El wordmark escala con el símbolo (--ds-brand-h),
   no con la escala tipográfica: por eso sus tamaños son variables locales y no --ds-text-*. Lo mismo el OG: pieza fija de 1200 × 630 ── */
.ds-brand { --ds-brand-h: 40px; display: inline-flex; align-items: center; gap: calc(var(--ds-brand-h) * .28); color: var(--ds-brand-ink); font-family: var(--ds-font-sans); line-height: 1; white-space: nowrap; vertical-align: middle; }
.ds-brand__mark { display: block; width: var(--ds-brand-h); height: var(--ds-brand-h); flex: none; }
.ds-brand__word { --ds-brand-word: calc(var(--ds-brand-h) * .9); font-size: var(--ds-brand-word); font-weight: var(--ds-weight-heavy); letter-spacing: var(--ds-tracking-h1); }
.ds-brand--stacked { flex-direction: column; gap: calc(var(--ds-brand-h) * .2); }
.ds-brand--stacked .ds-brand__word { --ds-brand-word: calc(var(--ds-brand-h) * .6); }
.ds-brand__by { --ds-brand-by: calc(var(--ds-brand-h) * .42); font-size: var(--ds-brand-by); font-weight: var(--ds-weight-semibold); color: var(--ds-text-muted); letter-spacing: var(--ds-tracking-normal); align-self: center; margin-left: calc(var(--ds-brand-h) * .08); }

/* ── favicon: pestaña simulada (16), suelto (32) y tile de 180 (apple-touch / PWA) ─────────────────────────────────── */
.ds-fav { display: flex; align-items: center; gap: var(--ds-space-4); flex-wrap: wrap; }
.ds-fav__tab { display: inline-flex; align-items: center; gap: var(--ds-space-2); height: 32px; padding: 0 var(--ds-space-3); border-radius: var(--ds-radius-md) var(--ds-radius-md) 0 0; background: var(--ds-surface-raised); border: 1px solid var(--ds-border-strong); border-bottom: 0; font-family: var(--ds-font-sans); font-size: var(--ds-text-xs); color: var(--ds-text); max-width: 220px; }
.ds-fav__tab span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-fav__px { display: inline-grid; place-items: center; gap: var(--ds-space-1); font-family: var(--ds-font-mono); font-size: var(--ds-text-2xs); color: var(--ds-text-muted); }
.ds-fav__px svg { display: block; }

/* ── OG 1200 × 630, siempre dark (la landing arranca en dark, D-013). Todo se mide en --ds-og-u = 1/1200 del ancho del contenedor
   (unidades de contenedor): a 1200 px de ancho, 1 unidad = 1 px, que es como se exporta assets/og-image.png ─────────────────── */
.ds-og-wrap { container-type: inline-size; aspect-ratio: 1200 / 630; overflow: hidden; border-radius: var(--ds-radius-lg); border: 1px solid var(--ds-border); }
.ds-og-wrap--export { border: 0; border-radius: 0; width: 1200px; }
.ds-og { --ds-og-u: calc(100cqw / 1200); --ds-og-kicker: calc(22 * var(--ds-og-u)); --ds-og-title: calc(98 * var(--ds-og-u)); --ds-og-sub: calc(27 * var(--ds-og-u)); --ds-og-foot: calc(22 * var(--ds-og-u)); --ds-og-foot-2: calc(18 * var(--ds-og-u)); position: relative; width: 100%; height: 100%; box-sizing: border-box; padding: calc(52 * var(--ds-og-u)) calc(72 * var(--ds-og-u)) calc(44 * var(--ds-og-u)); display: grid; grid-template-rows: auto 1fr auto; font-family: var(--ds-font-sans); color: var(--ds-text); background: var(--ds-bg); overflow: hidden; isolation: isolate; }
.ds-og::before { content: ''; position: absolute; inset: 0; z-index: -1; background: radial-gradient(60% 80% at 100% 0%, color-mix(in oklab, var(--ds-source-primary) 35%, transparent), transparent 70%), radial-gradient(50% 60% at 0% 100%, color-mix(in oklab, var(--ds-source-ember) 55%, transparent), transparent 70%); }
.ds-og::after { content: ''; position: absolute; left: 0; top: 0; right: 0; height: calc(8 * var(--ds-og-u)); background: var(--ds-gradient-brand); }
.ds-og .ds-brand { --ds-brand-h: calc(34 * var(--ds-og-u)); align-self: start; }
.ds-og__ghost { position: absolute; right: calc(-40 * var(--ds-og-u)); top: calc(40 * var(--ds-og-u)); width: calc(560 * var(--ds-og-u)); height: calc(560 * var(--ds-og-u)); opacity: .07; z-index: -1; }
.ds-og__kicker { margin: 0 0 calc(22 * var(--ds-og-u)); font-family: var(--ds-font-mono); font-size: var(--ds-og-kicker); font-weight: var(--ds-weight-bold); letter-spacing: var(--ds-tracking-caps); color: var(--ds-accent); align-self: end; }
.ds-og__title { margin: 0; font-size: var(--ds-og-title); font-weight: var(--ds-weight-heavy); letter-spacing: var(--ds-tracking-display); line-height: 1; }
.ds-og__title em { font-style: normal; color: var(--ds-accent); }
.ds-og__sub { margin: calc(26 * var(--ds-og-u)) 0 0; font-size: var(--ds-og-sub); font-weight: var(--ds-weight-medium); color: var(--ds-text-muted); }
.ds-og__foot { display: flex; justify-content: space-between; align-items: baseline; font-size: var(--ds-og-foot); font-weight: var(--ds-weight-heavy); }
.ds-og__foot span { font-size: var(--ds-og-foot-2); font-weight: var(--ds-weight-semibold); color: var(--ds-text-muted); }

/* ── src/shared/ds/pages/pages.css ── */
/* Páginas de estado y boot · sistema nuevo (D-035 · «Campo»). Zona estricta: solo tokens --ds-*. Tier 1.
 * El campo vivo a pantalla completa (parado en los frames del DS: un frame) con grano; el mensaje en una tarjeta de vidrio intermedio
 * (--ds-glass-bg-modal, D-028) con el lockup. El boot es plano: lockup apilado y barra indeterminada sobre el fondo del tema, sin campo.
 * Solo transform / opacity en movimiento.
 * Descartadas (historial hasta cb776562): «Editorial» (plano, cabecera + número enorme) y «Símbolo» (las bandas cuentan el estado). */

.ds-status, .ds-boot { position: relative; width: 100%; height: 100%; min-height: 100%; box-sizing: border-box; overflow: hidden; background: var(--ds-bg); color: var(--ds-text); font-family: var(--ds-font-sans); }
.ds-status__field { position: absolute; inset: 0; }
.ds-status__center, .ds-boot__center { position: relative; display: grid; place-items: center; align-content: center; gap: var(--ds-space-6); min-height: 100%; padding: var(--ds-space-8); box-sizing: border-box; }

/* tarjeta: vidrio intermedio de 520 px con el lockup arriba; sombra de vidrio (D-020) */
.ds-status__card { width: min(100%, 520px); padding: var(--ds-space-8); background: var(--ds-glass-bg-modal); box-shadow: inset 0 1px 0 var(--ds-glass-highlight), var(--ds-shadow-glass); }
.ds-status__lockup { margin-bottom: var(--ds-space-6); }
/* D-041 «Texto pleno» (S1): la tarjeta flota sobre el campo vivo, así que el texto secundario va en --ds-text como en el hero.
   Peor instante (240 del campo real, sin blur): texto pleno ≥ 6,33 dark · 8,75 light; el muted se quedaba en 2,71 · 3,94. */
.ds-status__eyebrow { margin: 0 0 var(--ds-space-2); font-size: var(--ds-text-sm); font-weight: var(--ds-weight-semibold); letter-spacing: var(--ds-tracking-caps); text-transform: uppercase; color: var(--ds-text); }
.ds-status__title { margin: 0; font-size: var(--ds-text-h1); font-weight: var(--ds-weight-bold); letter-spacing: var(--ds-tracking-h1); line-height: var(--ds-leading-tight); }
.ds-status__desc { margin: var(--ds-space-3) 0 0; max-width: 46ch; font-size: var(--ds-text-base); line-height: var(--ds-leading-normal); color: var(--ds-text); }
.ds-status__actions { display: flex; flex-wrap: wrap; gap: var(--ds-space-2); margin-top: var(--ds-space-6); }
.ds-status__actions a { text-decoration: none; }
/* D-041 también en las acciones y en el eyebrow del 500 (S3a, campo vivo real, peor de 3 instantes): el ghost en muted se quedaba
   en 3,06 dark y el eyebrow en --ds-danger en 3,35 dark · 3,52 light sobre la tarjeta. Los dos van en texto pleno; el 500 se
   distingue por el título y role=alert. */
.ds-status__actions .ds-button--ghost { color: var(--ds-text); }

/* boot plano: lockup apilado + barra indeterminada (segmento del 40 % que recorre la pista hairline por transform) + caption, sobre --ds-bg */
.ds-boot__center { gap: var(--ds-space-8); }
.ds-boot__caption { margin: 0; font-size: var(--ds-text-ui); color: var(--ds-text); } /* texto pleno, como en el arranque real (D-049) */
.ds-boot__bar { position: relative; display: block; width: 160px; height: 3px; overflow: hidden; border-radius: var(--ds-radius-full); background: var(--ds-border); }
.ds-boot__fill { position: absolute; inset: 0; width: 40%; border-radius: inherit; background: var(--ds-accent); transform: translateX(-100%); animation: ds-boot-slide calc(var(--ds-dur-cinematic) * 1.5) var(--ds-ease-linear) infinite; }
@keyframes ds-boot-slide { to { transform: translateX(250%); } }

@media (max-width: 768px) {
  .ds-status__card { padding: var(--ds-space-6); }
}

@media (prefers-reduced-motion: reduce) {
  .ds-boot__fill { animation: none; transform: none; width: 100%; opacity: .6; }
}

/* ── src/shared/ds/components/Field/Field.css ── */
/* Field · Input / Select / Textarea · sistema nuevo (D-023 · «Caja»). Zona estricta: solo tokens --ds-*.
 * Etiqueta arriba, caja de 40 px con hairline fuerte sobre surface-raised, foco = borde del acento + anillo tinte, error por color.
 * Descartadas (historial hasta a5ae9d64): Well (etiqueta flotante dentro de un well de 52 px) y Firma (versalitas + anillo de gradiente al foco). */

/* ── caja de 40 px radio 10 (D-010), tipografía UI, foco y error por color en 150 ms (D-016) ─────────── */
.ds-field { display: grid; gap: var(--ds-space-1); min-width: 0; }
.ds-field__label { font-size: var(--ds-text-sm); font-weight: var(--ds-weight-medium); color: var(--ds-text); line-height: var(--ds-leading-snug); }
.ds-field__req { color: var(--ds-danger); }
.ds-field__hint { margin: 0; font-size: var(--ds-text-xs); color: var(--ds-text-muted); }
.ds-field__error { margin: 0; font-size: var(--ds-text-xs); color: var(--ds-danger); display: flex; align-items: center; gap: var(--ds-space-1); }
.ds-field__error::before { content: ''; width: 6px; height: 6px; border-radius: var(--ds-radius-full); background: currentColor; flex: none; }

.ds-control { --ds-ctl-h: var(--ds-control-h); position: relative; display: flex; align-items: center; min-width: 0; height: var(--ds-ctl-h); border-radius: var(--ds-radius-md); background: var(--ds-surface-raised); border: 1px solid var(--ds-border-strong); color: var(--ds-text); transition: border-color var(--ds-dur-fast) var(--ds-ease-enter), background-color var(--ds-dur-fast) var(--ds-ease-enter), box-shadow var(--ds-dur-fast) var(--ds-ease-enter); }
.ds-control--sm { --ds-ctl-h: var(--ds-control-h-sm); }
.ds-control--textarea { height: auto; min-height: calc(var(--ds-ctl-h) * 2.4); align-items: stretch; }
.ds-control__input { flex: 1; min-width: 0; height: 100%; padding: 0 var(--ds-space-3); border: 0; background: transparent; color: inherit; font-family: var(--ds-font-sans); font-size: var(--ds-text-ui); line-height: var(--ds-leading-normal); outline: none; border-radius: inherit; appearance: none; }
.ds-control--textarea .ds-control__input { padding: var(--ds-space-2) var(--ds-space-3); resize: vertical; min-height: inherit; }
.ds-control__input::placeholder { color: var(--ds-text-muted); opacity: .8; }
.ds-control__affix { display: inline-flex; align-items: center; justify-content: center; width: 1.1em; height: 1.1em; margin-left: var(--ds-space-3); color: var(--ds-text-muted); flex: none; font-size: var(--ds-text-ui); }
.ds-control__affix > * { width: 100%; height: 100%; }
.ds-control__affix--end { margin-left: 0; margin-right: var(--ds-space-3); }
.ds-control.has-prefix .ds-control__input { padding-left: var(--ds-space-2); }
.ds-control.has-suffix .ds-control__input, .ds-control--select .ds-control__input { padding-right: var(--ds-space-2); }
.ds-control--select .ds-control__chevron { position: absolute; right: 0; pointer-events: none; }
.ds-control--select .ds-control__input { padding-right: calc(var(--ds-space-3) + 1.1em + var(--ds-space-2)); cursor: pointer; }
.ds-control--select.is-placeholder .ds-control__input { color: var(--ds-text-muted); }
.ds-control:hover { border-color: var(--ds-text-muted); }
.ds-control:focus-within { border-color: var(--ds-accent); box-shadow: var(--ds-shadow-ring); }
.ds-control.is-invalid { border-color: var(--ds-danger); }
.ds-control.is-invalid:focus-within { box-shadow: var(--ds-shadow-ring-danger); }
.ds-control:has(.ds-control__input:disabled) { background: var(--ds-surface-sunken); color: var(--ds-text-muted); cursor: not-allowed; }
.ds-control:has(.ds-control__input:disabled) .ds-control__input { cursor: not-allowed; }
.ds-control:has(.ds-control__input:read-only:not(:disabled):not(select)) { background: var(--ds-surface); border-style: dashed; }

/* ── src/shared/ds/components/Card/Card.css ── */
/* Card · sistema nuevo (D-025 · «Caja»). Zona estricta: solo tokens --ds-*.
 * Surface + hairline, radio 14, sin sombra; partes separadas por hairline; elevated = raised + sombra float; accent = borde del acento.
 * Descartadas (historial hasta 88e3a1fd): Bandeja (well sin borde, pie como franja) y Firma (radio 18, filete de gradiente). */

/* ── base: relleno por --ds-card-pad, partes (header · body · footer) a sangre con el relleno, tipografía de cabecera ── */
.ds-card { --ds-card-pad: var(--ds-space-5); position: relative; display: flex; flex-direction: column; min-width: 0; padding: var(--ds-card-pad); color: var(--ds-text);
  transition: background-color var(--ds-dur-fast) var(--ds-ease-enter), border-color var(--ds-dur-fast) var(--ds-ease-enter), box-shadow var(--ds-dur-fast) var(--ds-ease-enter), transform var(--ds-dur-fast) var(--ds-ease-enter); }
.ds-card--interactive { cursor: pointer; }
.ds-card--interactive:focus-visible { outline: 2px solid var(--ds-focus); outline-offset: var(--ds-focus-offset); }
.ds-card__header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ds-space-3); }
.ds-card__heading { display: grid; gap: var(--ds-space-1); min-width: 0; }
.ds-card__eyebrow { font-size: var(--ds-text-2xs); font-weight: var(--ds-weight-semibold); letter-spacing: var(--ds-tracking-caps); text-transform: uppercase; color: var(--ds-text-muted); }
.ds-card__title { margin: 0; font-size: var(--ds-text-base); font-weight: var(--ds-weight-semibold); line-height: var(--ds-leading-snug); letter-spacing: var(--ds-tracking-tight); }
.ds-card__desc { margin: 0; font-size: var(--ds-text-sm); color: var(--ds-text-muted); line-height: var(--ds-leading-normal); }
.ds-card__actions { display: inline-flex; gap: var(--ds-space-2); flex: none; }
.ds-card__body { min-width: 0; }
.ds-card__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--ds-space-2); }
.ds-card__header + .ds-card__body, .ds-card__body + .ds-card__footer, .ds-card__header + .ds-card__footer { margin-top: var(--ds-space-4); }

/* ── caja: surface + hairline, radio 14, sin sombra; partes separadas por hairline; elevated = raised + sombra float ─────── */
.ds-card { border-radius: var(--ds-radius-lg); background: var(--ds-surface); border: 1px solid var(--ds-border); }
.ds-card__header + .ds-card__body, .ds-card__body + .ds-card__footer, .ds-card__header + .ds-card__footer { padding-top: var(--ds-space-4); border-top: 1px solid var(--ds-border); }
.ds-card--interactive:hover { border-color: var(--ds-border-strong); background: var(--ds-surface-raised); }
.ds-card--elevated { background: var(--ds-surface-raised); border-color: var(--ds-border-strong); box-shadow: var(--ds-shadow-float); }
.ds-card--elevated.ds-card--interactive:hover { box-shadow: var(--ds-shadow-modal); }
.ds-card--accent { border-color: var(--ds-accent); }

@media (prefers-reduced-motion: reduce) { .ds-card { transition: none; } }

/* ── src/shared/ds/components/Badge/Badge.css ── */
/* Badge · sistema nuevo (D-024 · «Caja»). Zona estricta: solo tokens --ds-*.
 * Radio 6 con tinte + hairline del tono; texto xs semibold; punto opcional. Descartadas (historial hasta 32ee742f):
 * Píldora (tinte sin borde, radio completo) y Trazo (solo contorno, versalitas 2xs). */

/* ── base: píldora pequeña, texto semibold, punto opcional; el tono da --ds-tone / --ds-tone-tint ─────────────────── */
.ds-badge { --ds-tone: var(--ds-text-muted); --ds-tone-tint: var(--ds-surface-sunken);
  display: inline-flex; align-items: center; gap: var(--ds-space-1); height: 20px; padding: 0 var(--ds-space-2);
  font-family: var(--ds-font-sans); font-size: var(--ds-text-xs); font-weight: var(--ds-weight-semibold); line-height: 1; letter-spacing: var(--ds-tracking-normal);
  white-space: nowrap; vertical-align: middle; color: var(--ds-tone); }
.ds-badge--md { height: 24px; padding: 0 var(--ds-space-3); font-size: var(--ds-text-sm); font-weight: var(--ds-weight-medium); }
.ds-badge__dot { width: 6px; height: 6px; border-radius: var(--ds-radius-full); background: var(--ds-tone); flex: none; }
.ds-badge--md .ds-badge__dot { width: 7px; height: 7px; }
.ds-badge--accent { --ds-tone: var(--ds-accent-strong); --ds-tone-tint: var(--ds-accent-tint); }
.ds-badge--success { --ds-tone: var(--ds-success); --ds-tone-tint: var(--ds-success-tint); }
.ds-badge--warning { --ds-tone: var(--ds-warning); --ds-tone-tint: var(--ds-warning-tint); }
.ds-badge--danger { --ds-tone: var(--ds-danger); --ds-tone-tint: var(--ds-danger-tint); }
.ds-badge--info { --ds-tone: var(--ds-info); --ds-tone-tint: var(--ds-info-tint); }
.ds-badge--violet { --ds-tone: var(--ds-violet); --ds-tone-tint: var(--ds-violet-tint); }

/* ── caja: radio 6 con hairline del tono sobre tinte (coherente con Button/Field Caja) ─────────────────────────────── */
.ds-badge { border-radius: var(--ds-radius-sm); background: var(--ds-tone-tint); border: 1px solid var(--ds-tone-tint); }
.ds-badge--neutral { border-color: var(--ds-border-strong); background: var(--ds-surface-raised); }
