/* ============================================================================
   SASPOL — DESIGN SYSTEM · Foundation Tokens (RFC-001)
   ----------------------------------------------------------------------------
   Fuente ÚNICA de verdad de la base visual. Para cambiar cualquier color,
   espaciado, radio, sombra, etc. en TODA la plataforma se edita SOLO este
   archivo (y se sube a Hostinger junto a los HTML).

   FASE 1 (este archivo): puramente ADITIVO. Define tokens nuevos y NO
   redefine ninguna variable existente (--azul, --dorado, --blanco…), por lo
   que enlazarlo no cambia el render. El mapa de equivalencia con las variables
   actuales va comentado al final, para guiar la migración de FASE 2.

   Convención de nombres:
     Escalas    : --primary-500, --gold-400, --neutral-300…
     Semánticos : --color-background, --color-text-primary…
     Espaciado  : --space-16  (el número = px)
     Radios     : --radius-8
     Sombras    : --shadow-m
     Transición : --transition-normal / --ease-standard
     Opacidad   : --opacity-60
     Breakpoints: --bp-tablet  (referencia; CSS no permite var() en @media)
   ============================================================================ */

:root {

  /* ---- COLOR · PRIMARY (azul corporativo, ancla 700 = #1b2e6e) ---------- */
  --primary-50:  #eef1fa;
  --primary-100: #d9e0f2;
  --primary-200: #b3c1e4;
  --primary-300: #8598cf;
  --primary-400: #5670b4;
  --primary-500: #34509a;
  --primary-600: #253f9a;   /* = --azul2 actual */
  --primary-700: #1b2e6e;   /* = --azul actual (marca) */
  --primary-800: #152451;
  --primary-900: #0e1836;

  /* ---- COLOR · GOLD (dorado, ancla 500 = #c9a227) ---------------------- */
  --gold-50:  #fbf7ea;
  --gold-100: #f5ecc7;
  --gold-200: #ecdb96;
  --gold-300: #e2c85c;
  --gold-400: #e8ba30;   /* = --dorado2 actual */
  --gold-500: #c9a227;   /* = --dorado actual */
  --gold-600: #a5851f;
  --gold-700: #806618;
  --gold-800: #5c4911;
  --gold-900: #3d300b;

  /* ---- COLOR · EMERALD (verde corporativo oscuro, AGNÓSTICO de marca) --
     Primitiva para el Theme de Guardia Civil (RFC-I-001). No es la marca:
     un Theme la enlaza (--brand-primary: var(--emerald-700)). Distinta de
     SUCCESS (#16a34a, verde de estado, más claro). */
  --emerald-50:  #e9f9f2;
  --emerald-600: #007a53;
  --emerald-700: #0c5138;
  --emerald-800: #06371f;
  /* grises con TINTE emerald (neutrales de marca GC; valores aprobados exactos).
     Los equivalentes navy-tinted son las propias --neutral-* (ancla PMM). */
  --emerald-gray-50:  #f2f6f4;
  --emerald-gray-200: #e2ebe7;
  --emerald-gray-300: #cde2da;

  /* ---- COLOR · SUCCESS (verde, ancla 500 = #16a34a) ------------------- */
  --success-50:  #e6f5ed;
  --success-100: #c3e9d3;
  --success-200: #90d6b0;
  --success-300: #57bd8a;
  --success-400: #2e9e5b;
  --success-500: #16a34a;
  --success-600: #158040;
  --success-700: #146637;
  --success-800: #0f4d2a;
  --success-900: #0a331c;

  /* ---- COLOR · WARNING (ámbar, ancla 500 = #f59e0b) ------------------- */
  --warning-50:  #fef6e7;
  --warning-100: #fde7b8;
  --warning-200: #fbd07f;
  --warning-300: #f8b846;
  --warning-400: #f7a91f;
  --warning-500: #f59e0b;
  --warning-600: #d17e06;
  --warning-700: #a5620a;
  --warning-800: #79470c;
  --warning-900: #4d2d09;

  /* ---- COLOR · DANGER (rojo, ancla 500 = #dc2626) --------------------- */
  --danger-50:  #fdecea;
  --danger-100: #f9d0cc;
  --danger-200: #f2a9a1;
  --danger-300: #e87d71;
  --danger-400: #e0543f;
  --danger-500: #dc2626;
  --danger-600: #c0392b;   /* rojo de énfasis (exp-key, errores) */
  --danger-700: #a01f18;
  --danger-800: #7a1712;
  --danger-900: #530f0c;

  /* ---- COLOR · NEUTRAL (grises + blanco/negro) ----------------------- */
  --neutral-0:   #ffffff;
  --neutral-50:  #f5f6f8;   /* = --gris-cl actual */
  --neutral-100: #eef1f6;
  --neutral-200: #e8eaef;   /* = --gris-md actual */
  --neutral-300: #d8dce8;   /* = --gris-borde actual */
  --neutral-400: #b0b6c3;
  --neutral-500: #6b7280;   /* = --gris-texto actual */
  --neutral-600: #4b5563;
  --neutral-700: #374151;
  --neutral-800: #1f2530;
  --neutral-900: #0f1117;   /* = --negro actual */

  /* ---- COLOR · ACCENT (morado de categorías psicotécnicos) ----------- */
  --accent-purple: #7c3aed;

  /* ---- COLOR · SEMÁNTICOS (lo que consumen los componentes) ---------- */
  --color-background:     var(--neutral-50);
  --color-surface:        var(--neutral-0);
  --color-surface-alt:    var(--neutral-100);
  --color-border:         var(--neutral-300);
  --color-border-strong:  var(--neutral-400);
  --color-text-primary:   var(--brand-primary);
  --color-text-secondary: var(--neutral-500);
  --color-text-disabled:  var(--neutral-400);
  --color-text-inverse:   var(--neutral-0);
  --color-brand:          var(--brand-primary);
  --color-brand-accent:   var(--brand-accent);

  /* ====================================================================
     THEME HOOKS (RFC-006 / RFC-I-001) — capa de MARCA
     --------------------------------------------------------------------
     La identidad de marca se expresa por estos hooks. El DEFAULT resuelve a
     PMM (navy + dorado) para que, sin ningún Theme enlazado, el render sea
     IDÉNTICO al actual. Un archivo de Theme (themes/theme-*.css) redefine
     SOLO estos hooks para dar otra identidad (GC=verde…). Los tokens de
     componente (--button-*, --card-*) consumen estos hooks, nunca Foundation
     de color directamente. Ningún componente conoce la marca. */
  --brand-primary:        var(--primary-700);   /* PMM navy (default) */
  --brand-primary-hover:  var(--primary-600);   /* hover de primary */
  --brand-primary-strong: var(--primary-800);   /* activo/énfasis */
  --brand-primary-soft:   var(--primary-50);    /* fondo suave de marca */
  --brand-accent:         var(--gold-500);       /* dorado */
  --brand-accent-hover:   var(--gold-400);
  --brand-on-primary:     var(--neutral-0);      /* texto sobre fondo primary */
  --brand-on-accent:      var(--primary-700);    /* texto sobre acento (gold) */
  --brand-focus-ring:     var(--primary-600);    /* anillo de foco de marca */
  /* superficies/bordes SUTILES tintados de marca (RFC-I-004). Default navy = --neutral-*. */
  --brand-surface-subtle:        var(--neutral-50);
  --brand-surface-subtle-strong: var(--neutral-200);
  --brand-border-subtle:         var(--neutral-300);

  /* ---- APP SHELL + Z-INDEX (RFC-P-002) — semánticos, apuntan a Foundation/Theme ---- */
  --app-bg:            var(--color-background);
  --shell-surface:     var(--surface-default);
  --shell-border:      var(--border-default);
  --shell-shadow:      var(--shadow-l);
  /* Profundidad visual opt-in por Theme. Los defaults son neutros para que un
     piloto de marca no altere las demás academias antes de ser validado. */
  --depth-canvas:             var(--app-bg);
  --depth-surface-shadow:     none;
  --depth-interactive-shadow: none;
  --depth-shell-shadow:       none;
  --depth-feature-surface:    var(--surface-brand-subtle);
  --depth-dash-hover-shadow:  var(--card-shadow);
  --content-max-read:  760px;
  --content-max-wide:  1120px;
  --content-gutter:    var(--space-24);
  --header-gap:        var(--space-24);
  --z-base:    0;
  --z-sticky:  100;
  --z-shell:   200;
  --z-overlay: 300;
  --z-drawer:  400;
  --z-modal:   1000;
  --z-toast:   1100;

  /* ---- ESPACIADO (escala oficial; el número = px) ------------------- */
  --space-4:   4px;
  --space-8:   8px;
  --space-12:  12px;
  --space-16:  16px;
  --space-20:  20px;
  --space-24:  24px;
  --space-32:  32px;
  --space-40:  40px;
  --space-48:  48px;
  --space-64:  64px;
  --space-80:  80px;
  --space-96:  96px;
  --space-128: 128px;

  /* ---- BORDER RADIUS ------------------------------------------------- */
  --radius-4:  4px;
  --radius-8:  8px;
  --radius-12: 12px;
  --radius-16: 16px;
  --radius-24: 24px;
  --radius-32: 32px;
  --radius-full: 9999px;

  /* ---- SOMBRAS (tintadas en azul de marca, como el resto de la UI) --- */
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-s:  0 2px 8px rgba(27, 46, 110, 0.08);
  --shadow-m:  0 8px 24px rgba(27, 46, 110, 0.12);
  --shadow-l:  0 18px 50px rgba(15, 25, 60, 0.18);
  --shadow-xl: 0 28px 70px rgba(6, 14, 44, 0.28);

  /* ---- TRANSICIONES ------------------------------------------------- */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --transition-fast:   120ms var(--ease-standard);
  --transition-normal: 200ms var(--ease-standard);
  --transition-slow:   350ms var(--ease-standard);

  /* ---- OPACIDADES --------------------------------------------------- */
  --opacity-5:   0.05;
  --opacity-10:  0.10;
  --opacity-15:  0.15;
  --opacity-20:  0.20;
  --opacity-30:  0.30;
  --opacity-40:  0.40;
  --opacity-60:  0.60;
  --opacity-80:  0.80;
  --opacity-100: 1;

  /* ---- BREAKPOINTS (referencia — CSS no admite var() en @media) ----- */
  --bp-mobile:  480px;
  --bp-tablet:  768px;
  --bp-laptop:  1024px;
  --bp-desktop: 1200px;
  --bp-wide:    1440px;
}

/* ============================================================================
   MAPA DE EQUIVALENCIA (para la migración de FASE 2 — sustituir el hex/var
   antiguo por el token). NO se activa aquí para no alterar el render actual.

     --azul         →  var(--primary-700)   (#1b2e6e)
     --azul2        →  var(--primary-600)   (#253f9a)
     --azul-cl      →  var(--primary-50)    (#eef1fa)
     --dorado       →  var(--gold-500)      (#c9a227)
     --dorado2      →  var(--gold-400)      (#e8ba30)
     --gris-cl      →  var(--neutral-50)    (#f5f6f8)
     --gris-md      →  var(--neutral-200)   (#e8eaef)
     --gris-borde   →  var(--neutral-300)   (#d8dce8)
     --gris-texto   →  var(--neutral-500)   (#6b7280)
     --negro        →  var(--neutral-900)   (#0f1117)
     --blanco       →  var(--neutral-0)     (#ffffff)
     --rojo         →  var(--danger-500)    (#dc2626)
     verde GC #0c5138 / #007a53  →  tema GC (se define aparte en recolor_gc)
   ============================================================================ */


/* ============================================================================
   RFC-002 · TYPOGRAPHY SYSTEM
   ----------------------------------------------------------------------------
   Infraestructura tipográfica. ADITIVA: nada consume aún estos tokens (la
   migración de clases será otro RFC). Valores ANCLADOS a los efectivos hoy,
   para que la migración futura sea sin cambio visual.

   Sistema de voces (ya vigente en la práctica):
     BRAND/HEADING (Outfit)          → cromo: navs, sidebars, topbars,
                                       eyebrows, encabezados de sección, wordmark
     DISPLAY (Barlow Condensed)      → titulares hero, títulos de tarjeta,
                                       cifras, botones de acción display
     BODY (Barlow)                   → párrafos, descripciones, formularios
     MONO                            → código/valores técnicos (reserva)
   ============================================================================ */

:root {

  /* ---- FAMILIAS ------------------------------------------------------- */
  --font-brand:   'Outfit', system-ui, -apple-system, sans-serif;
  --font-heading: 'Outfit', system-ui, -apple-system, sans-serif;
  --font-display: 'Barlow Condensed', sans-serif;
  --font-body:    'Barlow', sans-serif;
  --font-mono:    ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* ---- ESCALA (size / line-height / weight / letter-spacing) ----------
     Cada nivel indica su familia prevista y qué estilos actuales deberán
     consumirlo cuando se migre (RFC futuro).                              */

  /* DISPLAY XL · font-display · hero de landings (.sec-t, .hero-t) */
  --type-display-xl-size:     clamp(36px, 5vw, 56px);
  --type-display-xl-line:     0.95;
  --type-display-xl-weight:   900;
  --type-display-xl-tracking: -1px;

  /* DISPLAY L · font-display · títulos de modal (.modal-title), h1 de
     convocatorias, resultado de test (nota grande secundaria) */
  --type-display-l-size:     28px;
  --type-display-l-line:     1.1;
  --type-display-l-weight:   900;
  --type-display-l-tracking: -0.5px;

  /* DISPLAY M · font-display · títulos de tarjeta de módulo (.mm, .mc-name),
     títulos de bloque (BLOQUE 1 —…), .dash-section-title/.topbar-title
     ORIGINALES (los actuales ya migraron a heading) */
  --type-display-m-size:     22px;
  --type-display-m-line:     1.15;
  --type-display-m-weight:   900;
  --type-display-m-tracking: 0.5px;

  /* HEADING XL · font-heading · .topbar-title de las aulas (19px Outfit 800),
     .topbar-tit de personalidad */
  --type-heading-xl-size:     19px;
  --type-heading-xl-line:     1.2;
  --type-heading-xl-weight:   800;
  --type-heading-xl-tracking: 0.5px;

  /* HEADING L · font-heading · .dash-section-title (Acceso rápido / Módulos
     de Teoría / Exámenes Oficiales) */
  --type-heading-l-size:     18px;
  --type-heading-l-line:     1.25;
  --type-heading-l-weight:   800;
  --type-heading-l-tracking: 0.5px;

  /* HEADING M · font-heading · cabeceras de tarjeta de modo (.mc-top),
     .pben-t (beneficios de precios), .pwa-h (pasos de instalación) */
  --type-heading-m-size:     16px;
  --type-heading-m-line:     1.3;
  --type-heading-m-weight:   800;
  --type-heading-m-tracking: 0.4px;

  /* HEADING S · font-heading · títulos menores de panel, .mcc-top del modal */
  --type-heading-s-size:     14px;
  --type-heading-s-line:     1.35;
  --type-heading-s-weight:   700;
  --type-heading-s-tracking: 0.3px;

  /* BODY XL · font-body · base de la página (body 16px), enunciados de test */
  --type-body-xl-size:     16px;
  --type-body-xl-line:     1.6;
  --type-body-xl-weight:   400;
  --type-body-xl-tracking: 0;

  /* BODY L · font-body · .sec-s (subtítulos de sección), .faq-a, párrafos
     de landing */
  --type-body-l-size:     15px;
  --type-body-l-line:     1.7;
  --type-body-l-weight:   400;
  --type-body-l-tracking: 0;

  /* BODY M · font-body · descripciones de tarjeta (.md, .mex-body),
     opciones de test, listados */
  --type-body-m-size:     14px;
  --type-body-m-line:     1.55;
  --type-body-m-weight:   400;
  --type-body-m-tracking: 0;

  /* BODY S · font-body · .conf-sub, .mc-desc/.mcc-desc, explicaciones,
     notas al pie de tarjeta */
  --type-body-s-size:     13px;
  --type-body-s-line:     1.5;
  --type-body-s-weight:   400;
  --type-body-s-tracking: 0;

  /* CAPTION · font-body · metadatos (.mex-meta, fechas, "x preguntas · sin
     hacer", hints de teclado) */
  --type-caption-size:     11px;
  --type-caption-line:     1.4;
  --type-caption-weight:   500;
  --type-caption-tracking: 0.3px;

  /* LABEL · font-heading · etiquetas uppercase pequeñas: .hs-l (labels de
     stats), .sb-sub, chips de recuento ("401 ejercicios"), .mn (Bloque 01) */
  --type-label-size:     10px;
  --type-label-line:     1.3;
  --type-label-weight:   700;
  --type-label-tracking: 1.5px;

  /* EYEBROW · font-heading · .sec-ey (antetítulos numerados de landing),
     .ey de convocatorias, .sb-section del sidebar */
  --type-eyebrow-size:     10px;
  --type-eyebrow-line:     1.2;
  --type-eyebrow-weight:   700;
  --type-eyebrow-tracking: 2.5px;

  /* NAVIGATION · font-heading · .nav-links a, .nav-dd-btn, .sb-item-l
     (ítems del sidebar del aula, 14px → usa --type-nav-size-l) */
  --type-nav-size:       12px;
  --type-nav-size-l:     14px;
  --type-nav-line:       1.2;
  --type-nav-weight:     600;
  --type-nav-tracking:   0.5px;

  /* BUTTON · font-heading (cromo: .nav-cta 13px/800/.6px) y font-display
     (acción: .btn-start 13px/700/1px) — dos variantes documentadas.
     line = normal: ancla corregida en RFC-004 (los botones reales no fijan
     line-height; 1.2 provocaba derivas subpíxel de 1px en la migración) */
  --type-button-size:     13px;
  --type-button-line:     normal;
  --type-button-weight:   800;
  --type-button-tracking: 0.6px;
  --type-button-display-weight:   700;
  --type-button-display-tracking: 1px;

  /* STATISTIC · font-display · cifras del hero (.hs-n), KPIs del dashboard,
     nota del test (resultado) */
  --type-statistic-size:     36px;
  --type-statistic-line:     1;
  --type-statistic-weight:   900;
  --type-statistic-tracking: -1px;

  /* CODE · font-mono · reservado (artículos legales citados, IDs, valores
     técnicos). Sin uso actual. */
  --type-code-size:     13px;
  --type-code-line:     1.5;
  --type-code-weight:   400;
  --type-code-tracking: 0;
}

/* ============================================================================
   MAPA DE CONSUMO PREVISTO (RFC de migración futuro; NO activo)
   ----------------------------------------------------------------------------
   LANDINGS      .sec-t→display-xl · .sec-s→body-l · .sec-ey→eyebrow ·
                 .nav-links a→navigation · .nav-cta→button · .hs-n→statistic ·
                 .hs-l→label · .mm/.mc-name→display-m · .md→body-m ·
                 .faq-a→body-l · .pfeats li→body-m · .pben-t→heading-m
   PORTAL        h1→display-xl · .card h2→display-m · .card p→body-m ·
                 .b-sub→label · pmm-switch→navigation
   AULAS         .topbar-title→heading-xl · .dash-section-title→heading-l ·
                 .sb-item-l→navigation(-l) · .sb-section→eyebrow ·
                 .sb-sub→label · tarjetas dashboard→display-m/label ·
                 test: enunciado→body-xl, opciones→body-m, explicación→body-s ·
                 .modal-title→display-l · .btn-start→button(display)
   PSICOTÉCNICOS .topbar-title→heading-xl · .sb-sec→eyebrow · cat-count→label ·
                 enunciados→body-xl · .exp-body→body-s
   PERSONALIDAD  .topbar-tit→heading-xl · preguntas→body-xl · escalas→body-m
   CONVOCATORIAS h1→display-l · .ey→eyebrow · .back→navigation · fichas→body-m
   INSTALACIÓN   pasos .pwa-h→heading-m · .pwa-steps li→body-m
   ============================================================================ */


/* ============================================================================
   RFC-003 · SEMANTIC DESIGN TOKENS
   ----------------------------------------------------------------------------
   Capa semántica: los componentes NUNCA consumen Foundation directamente;
   consumen estos tokens, que a su vez apuntan a Foundation. ADITIVA: nada la
   consume aún (RFC-004). Ningún color propio: todo referencia Foundation.

   Nota: los --color-* de RFC-001 fueron un primer alias semántico; esta capa
   los EXTIENDE y es la oficial para componentes. Valores anclados al aspecto
   real actual de cada componente (para migrar sin cambio visual).

   Jerarquía:  componente → semantic → foundation
   ============================================================================ */

:root {

  /* ---- SURFACE -------------------------------------------------------- */
  --surface-default:  var(--neutral-0);
  --surface-elevated: var(--neutral-0);     /* blanca + sombra (la sombra la da card-shadow) */
  --surface-overlay:  color-mix(in srgb, var(--neutral-900) 60%, transparent);
  --surface-disabled: var(--neutral-50);
  /* superficies de MARCA (fondos/gradientes de héroes y banners de marca).
     Consumen los hooks --brand-* → el Theme resuelve la identidad (RFC-I-003). */
  --surface-brand:        var(--brand-primary);
  --surface-brand-strong: var(--brand-primary-strong);  /* superficie de marca oscura */
  --surface-brand-hover:  var(--brand-primary-hover);
  --surface-accent:       var(--brand-accent);
  --surface-accent-hover: var(--brand-accent-hover);
  --surface-brand-soft:          var(--brand-primary-soft);          /* fondo suave de marca (highlight) */
  --surface-brand-subtle:        var(--brand-surface-subtle);        /* fondo sutil tintado */
  --surface-brand-subtle-strong: var(--brand-surface-subtle-strong); /* 2º nivel */
  --border-brand-subtle:         var(--brand-border-subtle);         /* borde sutil tintado */

  /* ---- TEXT ----------------------------------------------------------- */
  --text-primary:   var(--brand-primary);   /* cuerpo navy = marca */
  --text-secondary: var(--neutral-500);
  --text-muted:     var(--neutral-400);
  --text-disabled:  var(--neutral-300);
  --text-inverse:   var(--neutral-0);

  /* ---- BORDER --------------------------------------------------------- */
  --border-default: var(--neutral-300);
  --border-strong:  var(--neutral-400);
  --border-focus:   var(--brand-focus-ring);
  --border-success: var(--success-500);
  --border-warning: var(--warning-500);
  --border-danger:  var(--danger-500);

  /* ---- BUTTONS --------------------------------------------------------
     primary   = CTA navy ("Ver planes y precios", CTAs de modal)
     secondary = blanco con borde navy (opción alternativa de modal)
     danger    = acciones destructivas                                     */
  --button-primary-bg:      var(--brand-primary);
  --button-primary-hover:   var(--brand-primary-hover);
  --button-primary-text:    var(--brand-on-primary);
  --button-secondary-bg:    var(--neutral-0);
  --button-secondary-hover: var(--brand-primary-soft);
  --button-secondary-text:  var(--brand-primary);
  --button-danger-bg:       var(--danger-500);
  --button-danger-hover:    var(--danger-700);
  --button-danger-text:     var(--neutral-0);

  /* ---- INPUTS --------------------------------------------------------- */
  --input-bg:          var(--neutral-0);
  --input-border:      var(--neutral-300);
  --input-focus:       var(--brand-focus-ring);
  --input-placeholder: var(--neutral-400);
  --input-disabled:    var(--neutral-50);

  /* ---- CARDS ---------------------------------------------------------- */
  --card-bg:           var(--neutral-0);
  --card-border:       var(--neutral-300);
  --card-shadow:       var(--shadow-s);
  --card-hover-shadow: var(--shadow-m);
  --card-radius:       var(--radius-12);
  --card-border-width: 1px;
  --card-focus-ring:   var(--button-focus-ring);

  /* ---- BADGES --------------------------------------------------------- */
  --badge-success: var(--success-500);
  --badge-warning: var(--warning-500);
  --badge-danger:  var(--danger-500);
  --badge-info:    var(--primary-500);

  /* ---- NAVIGATION (nav superior de landings; el tema oscuro PN/GC la
          redefine a nivel de tema, no aquí) ----------------------------- */
  --nav-bg:          var(--neutral-0);
  --nav-border:      var(--neutral-300);
  --nav-item:        var(--neutral-500);
  --nav-item-hover:  var(--brand-primary);
  --nav-item-active: var(--brand-primary);

  /* ---- SIDEBAR (aulas y psicotécnicos) -------------------------------- */
  --sidebar-bg:          var(--neutral-0);
  --sidebar-border:      var(--neutral-200);
  --sidebar-item:        var(--neutral-500);
  --sidebar-item-hover:  var(--brand-primary);
  --sidebar-item-active: var(--brand-primary);

  /* ---- TOPBAR --------------------------------------------------------- */
  --topbar-bg:     var(--neutral-0);
  --topbar-border: var(--neutral-200);
  --topbar-title:  var(--brand-primary);

  /* ---- MODAL ---------------------------------------------------------- */
  --modal-bg:      var(--neutral-0);
  --modal-overlay: color-mix(in srgb, var(--neutral-900) 60%, transparent);
  --modal-border:  var(--neutral-300);
}


/* ============================================================================
   RFC-004 · 04 · COMPONENTS — BUTTON  (Button System v1)
   ----------------------------------------------------------------------------
   Componente oficial de botón. ADITIVO hasta que los HTML adopten .ds-button
   (migración por tandas). Jerarquía: .ds-button → semantic → foundation.
   Cero hexadecimales propios.

   USO
     <button class="ds-button ds-button--primary ds-button--md">Guardar</button>
     <button class="btn-start ds-button ds-button--success ds-button--lg">…</button>
       (convivencia con clase legacy: la legacy conserva selectores JS y
        overrides puntuales; al confirmar cada tanda se retiran de la legacy
        las propiedades visuales ya gobernadas por .ds-button)

   VARIANTES  --primary (CTA navy) · --secondary (blanco borde navy) ·
              --gold (CTA dorado tipo nav-cta) · --success (acción verde,
              empezar test) · --danger (destructiva/entregar) ·
              --ghost (translúcido sobre fondo oscuro, tipo btn-volver) ·
              --text (enlace-botón, tipo ing-selall)
   TAMAÑOS    --sm (28px) · --md (36px) · --lg (44px de alto mínimo)
   MODIF.     --full (ancho completo) · --icon (texto+icono) ·
              --icon-only (cuadrado, requiere aria-label)
   ESTADOS    :hover · :active · :focus-visible (anillo, nunca outline:none
              sin sustituto) · :disabled y [aria-disabled=true] ·
              [aria-busy=true] (carga)

   NO USAR .ds-button EN: tabs (.cuenta-tab, .auth-tab, .ing-tab-btn),
   selectores de modo (.ing-modo-btn, .ex-modo-btn, .modo-card, .pmm-switch),
   opciones de respuesta (.bopt, .ing-opt, .gp-opt, .opt), navegador de
   preguntas (rejillas ex-nav), acordeones y tarjetas clicables. Son otros
   componentes (RFCs posteriores).
   ============================================================================ */

:root {
  /* tokens de componente que faltaban (→ semantic/foundation) */
  --button-gold-bg:       var(--brand-accent);
  --button-gold-hover:    var(--brand-accent-hover);
  --button-gold-text:     var(--brand-on-accent);
  --button-success-bg:    var(--success-500);
  --button-success-hover: var(--success-600);
  --button-success-text:  var(--neutral-0);
  --button-border:        var(--neutral-300);
  --button-focus-ring:    var(--brand-focus-ring);
  --button-disabled-bg:   var(--neutral-200);
  --button-disabled-text: var(--neutral-400);
  --button-disabled-border: var(--neutral-300);
}

.ds-button{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--space-8);
  font-family:var(--font-heading);
  font-size:var(--type-button-size);
  font-weight:var(--type-button-weight);
  /* v1 parity: los botones legacy HEREDAN el line-height del contexto (1.6 en
     landings, normal en psico…); un valor fijo rompería alguno. El token
     --type-button-line queda para la normalización opt-in de v2. */
  line-height:inherit;
  letter-spacing:var(--type-button-tracking);
  text-transform:uppercase;
  text-decoration:none;
  border:none; /* paridad v1: variantes con borde lo declaran completo */
  border-radius:var(--radius-8);
  padding:0 var(--space-16);
  min-height:36px;
  cursor:pointer;
  transition:background-color var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast);
  user-select:none;
  white-space:nowrap;
  -webkit-tap-highlight-color:transparent;
}
.ds-button:focus-visible{
  outline:2px solid var(--button-focus-ring);
  outline-offset:2px;
}
.ds-button:disabled,
.ds-button[aria-disabled="true"]{
  background:var(--button-disabled-bg);
  color:var(--button-disabled-text);
  border-color:var(--button-disabled-border); /* aplica en variantes con borde */
  cursor:not-allowed;
  box-shadow:none;
}
.ds-button[aria-busy="true"]{
  cursor:progress;
  opacity:var(--opacity-60);
  pointer-events:none;
}

/* ---- variantes ---- */
.ds-button--primary{background:var(--button-primary-bg);color:var(--button-primary-text);}
.ds-button--primary:hover{background:var(--button-primary-hover);}
.ds-button--primary:active{background:var(--primary-800);}

.ds-button--secondary{background:var(--button-secondary-bg);color:var(--button-secondary-text);border:1px solid var(--button-secondary-text);}
.ds-button--secondary:hover{background:var(--button-secondary-hover);}
.ds-button--secondary:active{background:var(--primary-100);}

.ds-button--gold{background:var(--button-gold-bg);color:var(--button-gold-text);}
.ds-button--gold:hover{background:var(--button-gold-hover);}
.ds-button--gold:active{background:var(--gold-600);color:var(--neutral-0);}

.ds-button--success{background:var(--button-success-bg);color:var(--button-success-text);}
.ds-button--success:hover{background:var(--button-success-hover);}
.ds-button--success:active{background:var(--success-700);}

.ds-button--danger{background:var(--button-danger-bg);color:var(--button-danger-text);}
.ds-button--danger:hover{background:var(--button-danger-hover);}
.ds-button--danger:active{background:var(--danger-800);}

.ds-button--ghost{background:color-mix(in srgb,var(--neutral-0) 12%,transparent);color:var(--text-inverse);border:1px solid color-mix(in srgb,var(--neutral-0) 22%,transparent);}
.ds-button--ghost:hover{background:color-mix(in srgb,var(--neutral-0) 20%,transparent);}

.ds-button--text{background:transparent;color:var(--text-primary);text-decoration:underline;padding:0 var(--space-4);min-height:0;}
.ds-button--text:hover{color:var(--primary-600);}

/* ---- tamaños ---- */
.ds-button--sm{min-height:28px;padding:0 var(--space-12);font-size:11px;}
.ds-button--md{min-height:36px;}
.ds-button--lg{min-height:44px;padding:0 var(--space-24);}

/* ---- modificadores ---- */
.ds-button--full{width:100%;}
.ds-button--icon svg,.ds-button--icon i{flex:none;}
.ds-button--icon-only{width:36px;min-width:36px;padding:0;}
.ds-button--icon-only.ds-button--sm{width:28px;min-width:28px;}
.ds-button--icon-only.ds-button--lg{width:44px;min-width:44px;}

/* ---- accesibilidad / motion ---- */
@media (prefers-reduced-motion: reduce){
  .ds-button{transition:none;}
}

/* ============================================================================
   RFC-004.5 · BUTTON SYSTEM v1 — CONGELADO (2026-07-18)
   ----------------------------------------------------------------------------
   API ESTABLE. 359 botones migrados en las 20 páginas. Superficie cerrada:
     VARIANTES   --primary · --secondary · --gold · --success · --danger ·
                 --ghost · --text                (7)
     TAMAÑOS     --sm (28) · --md (36) · --lg (44)                 (3)
     MODIF.      --full · --icon · --icon-only                     (3)
     ESTADOS     :hover · :active · :focus-visible · :disabled ·
                 [aria-disabled=true] · [aria-busy=true] · reduced-motion

   POLÍTICA OFICIAL (obligatoria para todo RFC futuro):
     1. Ningún botón nuevo podrá implementarse fuera de .ds-button.
        Prohibido crear clases de botón nuevas o estilar <button>/<a role=button>
        con background/padding/border propios. Se compone con variante+tamaño.
     2. Prohibidas las variantes específicas de página. Si un botón no encaja
        en la API, se amplía ESTE componente (variante/modificador genérico),
        nunca se parchea en el <style> de una página.
     3. La clase legacy sólo puede conservar responsabilidades FUNCIONALES
        (layout: margin/flex/width, hooks JS, posicionamiento). Toda propiedad
        visual (color, borde, radio, tipografía, cursor, transform-text) la
        gobierna .ds-button. No re-duplicar en legacy lo que el DS ya define.

   EXCEPCIONES DOCUMENTADAS (no son Button v1 — componentes futuros):
     · Block-CTA a ancho completo que envuelve a 2 líneas (personalidad .cta/
       .cta.gold/.cta.ghost): el nowrap de .ds-button no aplica → componente
       "Block CTA" propio. NO migrar a .ds-button.
     · Botones con disabled por opacidad (psico .btn-start, aula .onb-btn):
       afordancia dim distinta del disabled sólido del DS → legacy hasta que
       v2 ofrezca un modificador de estilo de disabled. NO variante de página.
     · Enlaces de navegación con aspecto de botón (.back, .test-back, .ent-back,
       .ing-back-btn): navegación, no acción → fuera de Button.
     · Tabs, option-cards (.bopt/.opt/.cat-card), navegador de preguntas
       (rejillas ex-nav, .btn-next), toggles, tarjetas-CTA (.modal-cta-card):
       cada uno es su propio componente en RFCs posteriores.
   ============================================================================ */

/* ============================================================================
   RFC-005 · 05 · COMPONENTS — CARD (Card System v1)
   ----------------------------------------------------------------------------
   Primitivo de SUPERFICIE genérica. Gobierna SOLO: fondo, borde, radio, y
   —opcional— sombra (elevación), transición de interacción y padding. NO
   impone tipografía, headings, layouts internos, iconos ni badges. Jerarquía:
   Foundation → Semantic (--card-*) → .ds-card → Domain/Patterns.

   USO (aditivo; la clase legacy conserva radio/sombra/padding propios y hooks
   JS, y gana por cascada al ir su <style> después de este archivo):
     <div class="req-card ds-card ds-card--elevated">…</div>          (estática)
     <div class="prog-kpi ds-card">…</div>                            (métrica)
     <a  class="card ds-card ds-card--elevated ds-card--interactive">…</a>

   API v1 (mínima):
     BASE        .ds-card                 borde + sin sombra
     VARIANTES   --elevated (sombra) · --interactive (solo tratamiento visual
                 de interacción: transición + hover + focus-visible)
     MODIF.      --padding-none/-sm/-md/-lg · --full · --overflow-visible

   REGLAS DE SEMÁNTICA (la superficie NUNCA define comportamiento):
     · .ds-card NO añade cursor:pointer, role, tabindex ni teclado.
     · --interactive es SOLO visual; la semántica (enlace/acción/teclado) la
       aporta el HTML (<a href>, o control real dentro de la card).
     · El anillo de foco aparece únicamente si la PROPIA card es el elemento
       interactivo real (:focus-visible sobre <a>/elemento con teclado). No se
       usa :focus-within (evita un segundo anillo al enfocar controles internos).

   Card v1 NO incluye: selected · disabled · correct/incorrect · focus-within ·
   colores por oposición · tamaños de una sola página. Esos estados pertenecen
   a componentes específicos (ds-option-card, ds-answer, QuestionCard…).
   ============================================================================ */

.ds-card{
  background:var(--card-bg);
  border:var(--card-border-width) solid var(--card-border);
  border-radius:var(--card-radius);
  box-sizing:border-box;
}
.ds-card--elevated{ box-shadow:var(--card-shadow); }

.ds-card--interactive{
  transition:transform var(--transition-normal),box-shadow var(--transition-normal);
}
.ds-card--interactive:hover{ box-shadow:var(--card-hover-shadow); }
.ds-card--interactive:focus-visible{
  outline:2px solid var(--card-focus-ring);
  outline-offset:2px;
}

/* ---- padding (opcional) ---- */
.ds-card--padding-none{ padding:0; }
.ds-card--padding-sm{ padding:var(--space-12); }
.ds-card--padding-md{ padding:var(--space-16); }
.ds-card--padding-lg{ padding:var(--space-24); }

/* ---- layout transversal ---- */
.ds-card--full{ width:100%; }
.ds-card--overflow-visible{ overflow:visible; }

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

/* ============================================================================
   RFC-P-002 · 06 · COMPONENTS — PAGE HEADER (v1)
   Encabezado de vista: eyebrow → título → descripción → acciones. Consume DS
   (tipografía/spacing/color vía Semantic). 0 hex, 0 --brand-* directo. Las
   acciones son .ds-button; los chips .ds-badge/.ds-chip. Variantes por modificador.
   ============================================================================ */
.page-header{
  display:flex; flex-direction:column; gap:var(--space-8);
  padding-bottom:var(--space-16);
  margin-bottom:var(--header-gap);
  border-bottom:1px solid var(--shell-border);
}
.page-header__eyebrow{
  font-family:var(--font-brand); font-weight:700; text-transform:uppercase;
  letter-spacing:2.5px; font-size:11px; color:var(--text-secondary);
}
.page-header__row{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-16); flex-wrap:wrap; }
.page-header__title{
  font-family:var(--font-display); font-weight:900; text-transform:uppercase;
  font-size:28px; line-height:1.1; letter-spacing:.3px; color:var(--text-primary); margin:0;
}
.page-header__desc{ font-size:14px; line-height:1.5; color:var(--text-secondary); max-width:60ch; margin:0; }
.page-header__actions{ display:flex; gap:var(--space-8); flex-wrap:wrap; }
.page-header__meta{ display:flex; gap:var(--space-8); flex-wrap:wrap; align-items:center; }
/* variantes */
.page-header--dashboard .page-header__title{ font-size:34px; }
.page-header--compact{ gap:var(--space-4); padding-bottom:var(--space-8); margin-bottom:var(--space-16); }
.page-header--compact .page-header__title{ font-size:20px; }
.page-header.page-header--immersive{ border-bottom:none; margin-bottom:var(--space-12); }
.page-header--results{ text-align:center; align-items:center; border-bottom:none; margin-bottom:var(--space-16); }
.page-header--results .page-header__row{ justify-content:center; }
.page-header--results .page-header__title{ font-size:22px; }
.page-header--results .page-header__desc{ margin-left:auto; margin-right:auto; }
.page-header--sticky{ position:sticky; top:var(--sticky-offset,0); z-index:var(--z-sticky); background:var(--shell-surface); }
@media (max-width:767px){
  .page-header__title{ font-size:22px; }
  .page-header__row{ flex-direction:column; }
  .page-header__actions{ width:100%; }
  .page-header--dashboard .page-header__title{ font-size:26px; }
}

/* ============================================================================
   RFC-P-003 · STATUS SYSTEM v1 — TOKENS DE ESTADO (Fase 4)
   ----------------------------------------------------------------------------
   Estado por EJES (availability · interaction · evaluation · disclosure).
   Cada estado expone fg/bg/border (+emphasis). ADITIVO: nada lo consume aún
   salvo el piloto GC vía data-attributes. Reglas duras (ver STATUS_SYSTEM_SPEC):
     · correct/incorrect/blank NO dependen del Theme (verde/rojo/gris en las 4).
     · selected SÍ consume Theme (--brand-*).
     · doubtful = acento estable (--warning-*, dorado), no de marca.
     · locked ≠ disabled ; annulled ≠ blank.
     · 0 hex en componentes: sólo Foundation/Semantic/Theme.
   ============================================================================ */
:root{
  /* neutral (defecto; no se pinta salvo chips explícitos) */
  --status-neutral-fg:      var(--text-secondary);
  --status-neutral-bg:      var(--neutral-50);
  --status-neutral-border:  var(--neutral-300);
  /* selected — CONSUME THEME */
  --status-selected-fg:     var(--brand-primary);
  --status-selected-bg:     var(--brand-primary-soft);
  --status-selected-border: var(--brand-primary);
  --status-selected-ring:   var(--brand-focus-ring);
  /* correct — Foundation (independiente de marca) */
  --status-correct-fg:      var(--success-600);
  --status-correct-bg:      var(--success-50);
  --status-correct-border:  var(--success-500);
  /* incorrect — Foundation */
  --status-incorrect-fg:    var(--danger-600);
  --status-incorrect-bg:    var(--danger-50);
  --status-incorrect-border:var(--danger-500);
  /* blank — Foundation */
  --status-blank-fg:        var(--text-secondary);
  --status-blank-bg:        var(--neutral-100);
  --status-blank-border:    var(--neutral-300);
  /* doubtful — acento SEMÁNTICO estable = SÓLO tokens Warning (RFC-P-003B).
     Prohibido consumir --brand-accent/--gold-*/colores locales/hex: doubtful
     significa lo mismo en las 4 aulas, no depende del Theme. */
  --status-doubtful-fg:     var(--warning-800);   /* 7.2:1 sobre bg (AAA); AA aún en nº pequeño de nav */
  --status-doubtful-bg:     var(--warning-50);
  --status-doubtful-border: var(--warning-500);
  --status-doubtful-icon:   var(--warning-600);
  /* disabled — atenuado sólido */
  --status-disabled-fg:     var(--text-disabled);
  --status-disabled-bg:     var(--surface-disabled);
  --status-disabled-border: var(--neutral-300);
  /* locked — contenido de pago (borde discontinuo, candado) */
  --status-locked-fg:       var(--text-muted);
  --status-locked-bg:       var(--neutral-50);
  --status-locked-border:   var(--neutral-400);
  /* annulled — tachado/gris (≠ blank) */
  --status-annulled-fg:     var(--text-muted);
  --status-annulled-bg:     var(--neutral-100);
  --status-annulled-border: var(--neutral-400);
  /* reviewed — ya revisado */
  --status-reviewed-fg:     var(--text-secondary);
  --status-reviewed-bg:     var(--surface-default);
  --status-reviewed-border: var(--brand-primary-soft);
}

/* ============================================================================
   RFC-P-003 · STATUS SYSTEM v1 — PRIMITIVAS VISUALES (Fase 6)
   ----------------------------------------------------------------------------
   Definen SIGNIFICADO, no layout. Se componen sobre badges/dots/chips/tarjetas/
   opciones/filas. LEEN los data-attributes y exponen --_st-fg/bg/border del
   estado activo (precedencia: availability > evaluation > interaction).
   Evaluation SÓLO se resuelve con data-disclosure revealed|reviewed.
   ============================================================================ */
.ds-status{
  /* defecto = neutral; los data-* de abajo sobreescriben las 3 vars */
  --_st-fg:var(--status-neutral-fg);
  --_st-bg:var(--status-neutral-bg);
  --_st-border:var(--status-neutral-border);
}
/* interaction (menor precedencia) */
.ds-status[data-interaction="selected"]{ --_st-fg:var(--status-selected-fg); --_st-bg:var(--status-selected-bg); --_st-border:var(--status-selected-border); }
.ds-status[data-interaction="doubtful"]{ --_st-fg:var(--status-doubtful-fg); --_st-bg:var(--status-doubtful-bg); --_st-border:var(--status-doubtful-border); }
/* evaluation — sólo si está revelada (modo test ciego: hidden no pinta juicio) */
.ds-status[data-disclosure="revealed"][data-evaluation="correct"],
.ds-status[data-disclosure="reviewed"][data-evaluation="correct"]{ --_st-fg:var(--status-correct-fg); --_st-bg:var(--status-correct-bg); --_st-border:var(--status-correct-border); }
.ds-status[data-disclosure="revealed"][data-evaluation="incorrect"],
.ds-status[data-disclosure="reviewed"][data-evaluation="incorrect"]{ --_st-fg:var(--status-incorrect-fg); --_st-bg:var(--status-incorrect-bg); --_st-border:var(--status-incorrect-border); }
.ds-status[data-disclosure="revealed"][data-evaluation="blank"],
.ds-status[data-disclosure="reviewed"][data-evaluation="blank"]{ --_st-fg:var(--status-blank-fg); --_st-bg:var(--status-blank-bg); --_st-border:var(--status-blank-border); }
.ds-status[data-evaluation="annulled"]{ --_st-fg:var(--status-annulled-fg); --_st-bg:var(--status-annulled-bg); --_st-border:var(--status-annulled-border); }
/* availability (MAYOR precedencia: manda sobre evaluation/interaction).
   El atributo se repite para elevar la especificidad a (0,3,0) = la de las
   reglas de evaluation con guard de disclosure, y al ir DESPUÉS en el código
   gana la cascada. Así locked/disabled dominan aunque haya evaluation revelada. */
.ds-status[data-availability="disabled"][data-availability]{ --_st-fg:var(--status-disabled-fg); --_st-bg:var(--status-disabled-bg); --_st-border:var(--status-disabled-border); }
.ds-status[data-availability="locked"][data-availability]{ --_st-fg:var(--status-locked-fg); --_st-bg:var(--status-locked-bg); --_st-border:var(--status-locked-border); }

/* indicator: punto/marca del estado (nav-dot, chip-dot). Toma color del estado */
.ds-status-indicator{
  display:inline-block; width:.5em; height:.5em; border-radius:50%;
  background:var(--_st-fg,var(--status-neutral-fg)); flex:none;
}
/* label: señal textual redundante (visible o sr-only). Nunca sólo color */
.ds-status-label{
  font-family:var(--font-heading); font-size:11px; font-weight:700;
  letter-spacing:.4px; text-transform:uppercase; color:var(--_st-fg,var(--status-neutral-fg));
}
.ds-status-label--sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
/* iconografía redundante: ✓ / ✕ / ○ / ◆ vía ::before opcional del contexto */
.ds-status-indicator--correct::before{ content:"✓"; }
.ds-status-indicator--incorrect::before{ content:"✕"; }
.ds-status-indicator--blank::before{ content:"○"; }
.ds-status-indicator--doubtful::before{ content:"◆"; }
.ds-status-indicator[class*="ds-status-indicator--"]{ width:auto; height:auto; border-radius:0; background:none; font-size:.85em; line-height:1; color:var(--_st-fg); }

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

/* ============================================================================
   RFC-P-004/005 · PRODUCT COMPONENT — ds-answer v0.3 (COMPLETE STATE)
   ----------------------------------------------------------------------------
   Alcance acumulado: v0.1 selección · v0.2 evaluación revelada · v0.3 estados
   completos (doubtful, locked, disabled, reviewed, annulled).

   ESTRATEGIA DE PRECEDENCIA (explícita, NO por especificidad CSS accidental):
   los 4 ejes del Status System viajan como atributos SEMÁNTICOS separados
   (data-availability / data-interaction / data-evaluation / data-disclosure y
   los flags data-doubtful / data-reviewed) y NUNCA se fusionan. El componente
   resuelve en JS una ÚNICA capa de pintado derivada, `data-paint`, con este
   orden fijo:
        disabled  >  evaluation (si disclosure la permite)  >  locked
                  >  selected  >  doubtful  >  idle
   El CSS pinta sólo `data-paint` (una regla por valor, sin guerras de
   especificidad). Los MARCADORES aditivos (◆ dudosa, ↺ revisada, borde
   discontinuo de locked, tachado de anulada) son independientes de la capa de
   pintado: por eso doubtful/reviewed nunca tapan correct/incorrect, y locked
   deja legible la evaluación.
   correct/incorrect/blank/doubtful/annulled NO consumen Theme; selected sí.
   Sin reflow: borde 1px constante, ring por box-shadow, marcadores absolutos.
   ============================================================================ */
ds-answer{ display:block; }
.ds-answer{ display:flex; flex-direction:column; gap:var(--space-16); }
.ds-answer__prompt{
  font-family:var(--font-body); font-size:var(--type-body-xl-size,17px);
  line-height:1.5; color:var(--text-primary); font-weight:600; margin:0;
}
.ds-answer__options{ display:flex; flex-direction:column; gap:var(--space-8); list-style:none; margin:0; padding:0; }
.ds-answer__option{
  position:relative;
  display:flex; align-items:center; gap:var(--space-12); width:100%;
  text-align:left; padding:var(--space-12) var(--space-16);
  background:var(--surface-default); color:var(--text-primary);
  border:1px solid var(--border-default); border-radius:var(--radius-8);
  font-family:var(--font-body); font-size:var(--type-body-m-size,15px); line-height:1.4;
  cursor:pointer; -webkit-tap-highlight-color:transparent; appearance:none;
  transition:border-color var(--transition-fast),background-color var(--transition-fast),box-shadow var(--transition-fast);
}
/* marcador (radio) — señal de forma, no sólo color */
.ds-answer__marker{
  flex:none; width:20px; height:20px; border-radius:50%;
  border:2px solid var(--border-strong); background:var(--surface-default);
  display:inline-flex; align-items:center; justify-content:center;
  transition:border-color var(--transition-fast),background-color var(--transition-fast);
}
.ds-answer__marker::after{ content:""; width:8px; height:8px; border-radius:50%; background:transparent; transition:background-color var(--transition-fast); }
.ds-answer__label{ flex:1 1 auto; }

/* hover (solo puntero): indicio de pulsable; NUNCA imita a selected.
   Se desactiva si el grupo está revelado o si la opción no es interactuable. */
@media (hover:hover){
  .ds-answer:not([data-disclosure="revealed"]):not([data-disclosure="reviewed"])
    .ds-answer__option:not([data-paint="disabled"]):not([data-paint="locked"]):hover{
      border-color:var(--border-strong); background:var(--surface-brand-subtle);
  }
}
.ds-answer__option:focus-visible{ outline:2px solid var(--border-focus); outline-offset:2px; }

/* ---- CAPA DE PINTADO (data-paint, resuelta en JS) ------------------------ */
/* selected — único que consume THEME */
.ds-answer__option[data-paint="selected"]{
  border-color:var(--status-selected-border); background:var(--status-selected-bg);
  color:var(--status-selected-fg); box-shadow:inset 0 0 0 1px var(--status-selected-border);
}
.ds-answer__option[data-paint="selected"] .ds-answer__marker{ border-color:var(--status-selected-border); }
.ds-answer__option[data-paint="selected"] .ds-answer__marker::after{ background:var(--status-selected-border); }
/* evaluación (Foundation, sin Theme) */
.ds-answer__option[data-paint="correct"]{ border-color:var(--status-correct-border); background:var(--status-correct-bg); color:var(--status-correct-fg); box-shadow:inset 0 0 0 1px var(--status-correct-border); }
.ds-answer__option[data-paint="incorrect"]{ border-color:var(--status-incorrect-border); background:var(--status-incorrect-bg); color:var(--status-incorrect-fg); box-shadow:inset 0 0 0 1px var(--status-incorrect-border); }
.ds-answer__option[data-paint="correct"] .ds-answer__marker,
.ds-answer__option[data-paint="incorrect"] .ds-answer__marker{ background:var(--surface-default); }
.ds-answer__option[data-paint="correct"] .ds-answer__marker{ border-color:var(--status-correct-border); }
.ds-answer__option[data-paint="incorrect"] .ds-answer__marker{ border-color:var(--status-incorrect-border); }
.ds-answer__option[data-paint="correct"] .ds-answer__marker::after{ content:"\2713"; width:auto; height:auto; border-radius:0; background:none; color:var(--status-correct-fg); font-size:13px; font-weight:900; line-height:1; }
.ds-answer__option[data-paint="incorrect"] .ds-answer__marker::after{ content:"\2715"; width:auto; height:auto; border-radius:0; background:none; color:var(--status-incorrect-fg); font-size:12px; font-weight:900; line-height:1; }
/* annulled — tokens propios (ni success ni danger, ni blank ni neutral).
   Señal redundante: glifo ⊘ + tachado del texto. */
.ds-answer__option[data-paint="annulled"]{ border-color:var(--status-annulled-border); background:var(--status-annulled-bg); color:var(--status-annulled-fg); box-shadow:none; }
.ds-answer__option[data-paint="annulled"] .ds-answer__marker{ border-color:var(--status-annulled-border); background:var(--surface-default); }
.ds-answer__option[data-paint="annulled"] .ds-answer__marker::after{ content:"\2298"; width:auto; height:auto; border-radius:0; background:none; color:var(--status-annulled-fg); font-size:13px; font-weight:700; line-height:1; }
.ds-answer__option[data-paint="annulled"] .ds-answer__label{ text-decoration:line-through; }
/* doubtful — SÓLO tokens Warning (RFC-P-003B); nunca Theme ni dorado de marca */
.ds-answer__option[data-paint="doubtful"]{ border-color:var(--status-doubtful-border); background:var(--status-doubtful-bg); color:var(--status-doubtful-fg); box-shadow:inset 0 0 0 1px var(--status-doubtful-border); }
.ds-answer__option[data-paint="doubtful"] .ds-answer__marker{ border-color:var(--status-doubtful-border); }
/* locked — interacción cerrada. Distinto de disabled SIN depender del color:
   borde DISCONTINUO (forma) + texto accesible. Mantiene contraste de lectura. */
.ds-answer__option[data-paint="locked"]{ border-color:var(--status-locked-border); border-style:dashed; background:var(--status-locked-bg); color:var(--status-locked-fg); cursor:default; }
.ds-answer__option[data-paint="locked"] .ds-answer__marker{ border-color:var(--status-locked-border); border-style:dashed; }
/* disabled — no disponible. Sólido y atenuado (≠ locked, que es discontinuo). */
.ds-answer__option[data-paint="disabled"]{ border-color:var(--status-disabled-border); background:var(--status-disabled-bg); color:var(--status-disabled-fg); cursor:not-allowed; box-shadow:none; }
.ds-answer__option[data-paint="disabled"] .ds-answer__marker{ border-color:var(--status-disabled-border); }
/* disabled + selección previa: se muestra como dato HISTÓRICO (atenuado), sin
   aparentar interacción posible (degradación segura documentada). */
.ds-answer__option[data-paint="disabled"][data-interaction="selected"] .ds-answer__marker::after{ background:var(--status-disabled-fg); }
/* la opción bloqueada conserva el borde discontinuo aunque pinte evaluación */
.ds-answer__option[data-availability="locked"]{ border-style:dashed; cursor:default; }

/* ---- MARCADORES ADITIVOS (independientes de data-paint) ------------------ */
/* dudosa: ◆ en esquina — nunca tapa correct/incorrect */
.ds-answer__option[data-doubtful="true"]::after{
  content:"\25C6"; position:absolute; top:3px; right:5px; font-size:9px; line-height:1;
  color:var(--status-doubtful-icon);
}
/* revisada: indicador discreto, jamás compite con la evaluación */
.ds-answer__option[data-reviewed="true"]::before{
  content:"\21BA"; position:absolute; top:3px; left:5px; font-size:10px; line-height:1;
  color:var(--text-muted);
}
/* grupo revelado: no editable (no se reutiliza disabled para expresar disclosure) */
.ds-answer[data-disclosure="revealed"] .ds-answer__option,
.ds-answer[data-disclosure="reviewed"] .ds-answer__option{ cursor:default; }
/* ---- FEEDBACK v0.4 ------------------------------------------------------
   Línea de estado del grupo = ÚNICO lugar del feedback. Está RESERVADA desde
   que hay disclosure ⇒ aparecer no provoca reflow. Es un mensaje brevísimo
   ("¿he acertado?"); el PORQUÉ lo sigue dando la explicación existente del
   modo Repaso, que ds-answer no duplica, mueve ni oculta. */
.ds-answer__status{
  min-height:20px; display:flex; align-items:center; gap:var(--space-12);
  font-family:var(--font-heading); font-size:12px; font-weight:700;
  letter-spacing:.3px; color:var(--text-secondary);
}
/* el mensaje de feedback es lo ÚNICO dentro de la live region */
.ds-answer__fb{ display:inline-flex; align-items:center; gap:var(--space-8); opacity:0; transition:opacity 180ms var(--ease-standard,ease); }
.ds-answer__status[data-feedback] .ds-answer__fb{ opacity:1; }
.ds-answer__status[data-feedback] .ds-answer__fb::before{ font-weight:900; font-size:13px; line-height:1; }
.ds-answer__status[data-feedback="correct"]{ color:var(--status-correct-fg); }
.ds-answer__status[data-feedback="correct"] .ds-answer__fb::before{ content:"\2713"; }
.ds-answer__status[data-feedback="incorrect"]{ color:var(--status-incorrect-fg); }
.ds-answer__status[data-feedback="incorrect"] .ds-answer__fb::before{ content:"\2715"; }
.ds-answer__status[data-feedback="blank"]{ color:var(--status-blank-fg); }
.ds-answer__status[data-feedback="blank"] .ds-answer__fb::before{ content:"\25CB"; }
.ds-answer__status[data-feedback="annulled"]{ color:var(--status-annulled-fg); }
.ds-answer__status[data-feedback="annulled"] .ds-answer__fb::before{ content:"\2298"; }
/* marcador de pregunta DUDOSA (nivel pregunta, v0.5). Fuera de la live region
   ⇒ marcar/desmarcar NO se anuncia. Tokens Warning, nunca marca. */
.ds-answer__flag{ display:inline-flex; align-items:center; gap:var(--space-4); color:var(--status-doubtful-fg); }
.ds-answer__flag:empty{ display:none; }
.ds-answer__flag::before{ content:"\25C6"; color:var(--status-doubtful-icon); font-size:9px; line-height:1; }
@media (prefers-reduced-motion:reduce){ .ds-answer__fb{ transition:none; } }

@media (prefers-reduced-motion:reduce){
  .ds-answer__option,.ds-answer__marker,.ds-answer__marker::after{ transition:none; }
}
/* ============================================================================
   RFC-P-006B/C · PATTERNS DEL RECORRIDO (lenguaje visual SASPOL)
   ----------------------------------------------------------------------------
   Patrones de composición del recorrido de entrenamiento. INERTES sin la clase
   raíz `.visual-pilot`. Son SEMÁNTICOS y reutilizables por cualquier oposición:
   no hay tokens ni clases por cuerpo ni por página. Componen sobre el DS
   existente: 0 hex, 0 --brand-* directo, sin variantes de ds-answer ni
   componentes nuevos. Desactivar la clase devuelve el aspecto legacy.

   006C = ronda de refinamiento (producto, no arquitectura):
   P1 runner inmersivo real · P2 jerarquía del resultado · P3 metadata en su
   punto · P4 ritmo de la explicación y rojo sólo para error · P5 móvil y App
   Shell · uniformidad entre módulos.
   ============================================================================ */

/* 1 · ANCHOS DE LECTURA ------------------------------------------------------
   El rol lo expresa el token: wide para paneles y listados, read para leer. */
.visual-pilot .content{
  max-width:var(--content-max-wide); margin-left:auto; margin-right:auto;
  padding-left:var(--content-gutter); padding-right:var(--content-gutter);
}
.visual-pilot .ing-activo-body,
.visual-pilot .ing-activo-btns{
  max-width:var(--content-max-read); margin-left:auto; margin-right:auto; width:100%;
}
/* el resultado se lee, no se explora */
.visual-pilot #view-pro-teo-resultado > *,
.visual-pilot #view-pro-ingles-resultado > *,
.visual-pilot #view-eteo-resultado > *,
.visual-pilot #view-eing-resultado > *,
.visual-pilot #view-examenes-resultado > *,
.visual-pilot #view-lengua-resultado > *{
  max-width:var(--content-max-read); margin-left:auto; margin-right:auto;
}

/* ============================================================================
   2 · RUNNER INMERSIVO (P1)
   Mientras se responde existe UN solo nivel de navegación: el propio runner.
   La topbar global se retira entera (menú, correo, sesión, ayuda) y su función
   la asume la cabecera del runner, que conserva lo único necesario: salir,
   progreso, cronómetro y marcador.
   CLAVE: la inmersión NO depende del ancho. Un móvil en apaisado o un tablet
   no recuperan la sidebar por tener más pixeles.
   ============================================================================ */
.visual-pilot.runner-immersive .sidebar{
  transform:translateX(-100%); visibility:hidden; pointer-events:none;
}
.visual-pilot.runner-immersive .main{ margin-left:0; }
.visual-pilot.runner-immersive .topbar{ display:none; }
.visual-pilot .sidebar{ transition:transform var(--transition-normal); }
@media (prefers-reduced-motion:reduce){ .visual-pilot .sidebar{ transition:none; } }

/* Cabecera del runner = única barra. Se alinea con la columna de lectura sin
   añadir marcado: el padding lateral centra el contenido y el fondo sigue
   ocupando todo el ancho. */
.visual-pilot .ing-activo-header{
  position:sticky; top:0; z-index:30;
  background:var(--card-bg); border-bottom:1px solid var(--card-border);
  display:grid; grid-template-columns:auto 1fr; align-items:center;
  column-gap:var(--space-16); row-gap:var(--space-12);
  padding-top:var(--space-12); padding-bottom:var(--space-12);
  padding-left:max(var(--content-gutter), calc((100% - var(--content-max-read)) / 2));
  padding-right:max(var(--content-gutter), calc((100% - var(--content-max-read)) / 2));
  padding-top:calc(var(--space-12) + env(safe-area-inset-top,0px));
}
.visual-pilot .ing-activo-info{
  justify-self:end; display:flex; align-items:center; gap:var(--space-8);
  flex-wrap:wrap; justify-content:flex-end; min-width:0;
}
.visual-pilot .ing-activo-prog-wrap{ grid-column:1 / -1; }
.visual-pilot .ing-back-btn{ font-weight:600; }
/* el contador es dato de orientación, no titular */
.visual-pilot #teo-contador,.visual-pilot #ing-contador,
.visual-pilot #eteo-contador,.visual-pilot #eing-contador,
.visual-pilot #ex-contador{
  font-family:var(--font-heading); font-weight:700; font-size:13px;
  color:var(--text-secondary); letter-spacing:.04em;
}
/* el cronómetro sí manda cuando existe */
.visual-pilot .ing-crono{
  font-family:var(--font-heading); font-weight:800; font-size:14px;
  color:var(--text-primary); letter-spacing:.04em;
}

/* ============================================================================
   3 · CONTEXTO DE PREGUNTA (P3)
   Punto intermedio: la metadata informa con claridad pero no compite con el
   enunciado. Ni titular en mayúsculas (legacy) ni letra pequeña desvaída.
   No se trunca ni se altera el texto del banco.
   ============================================================================ */
body.visual-pilot .ing-tema-pill{
  display:block; background:none; border-radius:0; text-transform:none;
  border-left:2px solid var(--card-border);
  padding:2px 0 2px var(--space-12);
  color:var(--text-secondary); font-family:var(--font-body); font-weight:500;
  font-size:13px; letter-spacing:0; line-height:1.5;
  margin-bottom:var(--space-20);
}
.visual-pilot .ing-pregunta{
  font-size:20px; line-height:1.45; font-weight:600;
  color:var(--text-primary); margin-bottom:var(--space-24);
}

/* ============================================================================
   4 · EXPLICACIÓN (P4)
   Mismo contenido y mismo lugar (continuidad y memoria espacial): sólo ritmo,
   jerarquía y color. No se toca expHL ni el HTML del banco.
   REGLA DE COLOR: el rojo significa ERROR. La referencia jurídica destacada
   deja de ser roja y pasa a énfasis tipográfico sobre subrayado de marca.
   ============================================================================ */
.visual-pilot .ing-explicacion{
  background:var(--card-bg); border:1px solid var(--card-border);
  border-left:3px solid var(--surface-brand);
  border-radius:0 var(--radius-8) var(--radius-8) 0;
  padding:var(--space-20);
  font-size:15px; line-height:1.7; color:var(--text-primary);
  margin-top:var(--space-20); margin-bottom:var(--space-20);
}
.visual-pilot .exp-key{
  color:var(--text-primary); font-weight:700;
  box-shadow:inset 0 -0.34em var(--surface-brand-subtle);
}
/* la línea de feedback conserva TODO el peso semántico del acierto/error */
.visual-pilot .ds-answer__status{ margin-top:var(--space-16); }

/* ============================================================================
   5 · RESULTADO (P2)
   Jerarquía: veredicto → puntuación y escala → desglose → acciones.
   La lógica y el scoring NO se tocan: el atributo data-verdict sólo traduce a
   representación el veredicto que ya calculó el motor.
   ============================================================================ */
.visual-pilot .page-header--results{
  text-align:center; border:0; background:none;
  padding-bottom:0; margin-bottom:var(--space-16);
}
.visual-pilot .page-header--results .page-header__eyebrow{
  color:var(--text-muted); letter-spacing:.16em;
}
.visual-pilot .page-header--results .page-header__row{ justify-content:center; }
/* veredicto como distintivo, no como titular suelto */
.visual-pilot [data-verdict] .page-header__title{
  display:inline-flex; align-items:center; gap:var(--space-8);
  font-family:var(--font-display); font-size:15px; line-height:1;
  letter-spacing:.14em; text-transform:uppercase;
  padding:var(--space-8) var(--space-16); border-radius:var(--radius-32);
  border:1px solid transparent;
}
.visual-pilot [data-verdict="aprobado"] .page-header__title{
  color:var(--status-correct-fg); background:var(--status-correct-bg);
  border-color:var(--status-correct-border);
}
.visual-pilot [data-verdict="no_aprobado"] .page-header__title{
  color:var(--status-incorrect-fg); background:var(--status-incorrect-bg);
  border-color:var(--status-incorrect-border);
}
.visual-pilot .page-header--results .page-header__desc{
  color:var(--text-secondary); margin-top:var(--space-8);
}
/* la puntuación deja de ser un disco saturado y pasa a ser una cifra seria */
.visual-pilot [data-verdict] .ing-res-circle-wrap{ margin:var(--space-24) 0 var(--space-8); }
.visual-pilot [data-verdict] .ing-res-circle{
  width:auto; height:auto; min-width:min(280px, 100%);
  border-radius:var(--radius-16); background:var(--card-bg);
  border:1px solid var(--card-border); box-shadow:var(--shadow-s);
  padding:var(--space-24) var(--space-32); gap:var(--space-4);
}
.visual-pilot [data-verdict] .ing-res-pct{
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(38px, 9vw, 52px); line-height:1; letter-spacing:-.01em;
}
.visual-pilot [data-verdict="aprobado"] .ing-res-pct{ color:var(--status-correct-fg); }
.visual-pilot [data-verdict="no_aprobado"] .ing-res-pct{ color:var(--status-incorrect-fg); }
.visual-pilot [data-verdict] .ing-res-lbl{
  color:var(--text-muted); font-family:var(--font-heading); font-weight:700;
  font-size:11px; letter-spacing:.16em; text-transform:uppercase;
}
.visual-pilot .pattern-scale{
  text-align:center; font-size:13px; line-height:1.65; color:var(--text-secondary);
  margin:0 auto var(--space-24); max-width:62ch;
  padding:var(--space-12) var(--space-16);
  background:var(--card-bg); border:1px solid var(--card-border);
  border-radius:var(--radius-12);
}
.visual-pilot .pattern-scale b{ color:var(--text-primary); }
/* desglose: tres medidas comparables, no tres avisos de colores */
.visual-pilot .ing-res-stats{ gap:var(--space-12); margin-bottom:var(--space-24); }
.visual-pilot .ing-res-stat{
  border-radius:var(--card-radius); padding:var(--space-16) var(--space-12);
  border-top-width:1px; position:relative; overflow:hidden;
}
.visual-pilot .ing-res-stat::before{
  content:""; position:absolute; inset:0 0 auto 0; height:3px;
}
.visual-pilot .ing-res-stat.verde::before{ background:var(--status-correct-fg); }
.visual-pilot .ing-res-stat.rojo::before{ background:var(--status-incorrect-fg); }
.visual-pilot .ing-res-stat.dorado::before{ background:var(--status-doubtful-icon); }
.visual-pilot .ing-res-stat-n{
  font-family:var(--font-display); font-size:32px; color:var(--text-primary);
}
.visual-pilot .ing-res-stat-l{
  font-size:11px; color:var(--text-muted); letter-spacing:.12em;
}
/* acciones posteriores: una primaria clara, una salida secundaria */
.visual-pilot .pattern-result-actions{
  display:flex; gap:var(--space-12); margin:0 0 var(--space-32);
}
.visual-pilot .pattern-result-actions > .ds-button{ flex:1 1 0; min-width:0; }
/* las clases legacy (.btn-start, .btn-auth) traían su propio color; dentro del
   patrón manda la jerarquía: una acción primaria y una salida secundaria. */
.visual-pilot .pattern-result-actions > .ds-button--primary{
  background:var(--button-primary-bg); color:var(--button-primary-text); border:1px solid transparent;
}
.visual-pilot .pattern-result-actions > .ds-button--primary:hover{ background:var(--button-primary-hover); }
.visual-pilot .pattern-result-actions > .ds-button--secondary{
  background:var(--button-secondary-bg); color:var(--button-secondary-text);
  border:1px solid var(--button-secondary-text);
}
.visual-pilot .pattern-result-actions > .ds-button--secondary:hover{ background:var(--button-secondary-hover); }
.visual-pilot .ing-res-repaso{ margin-top:var(--space-8); }

/* ============================================================================
   6 · PANEL: jerarquía por LAYOUT (sin tocar el DOM)
   ============================================================================ */
/* Nota: la jerarquía NO se resuelve con flex/order — goProView fija
   `style.display` inline en la vista y un estilo inline gana a cualquier
   selector. El orden se establece por posición en el DOM (pilotNextAction). */
body.visual-pilot .dash-acc-card{
  background:var(--card-bg); border:1px solid var(--card-border); color:var(--text-primary);
  box-shadow:none; border-radius:var(--card-radius);
}
body.visual-pilot .dash-acc-card::before,
body.visual-pilot .dash-acc-card::after{ background:none; opacity:0; }
body.visual-pilot .dash-acc-card:hover{ border-color:var(--surface-brand); box-shadow:var(--card-shadow); }
body.visual-pilot .dash-acc-icon{ color:var(--surface-brand); }
body.visual-pilot .dash-acc-name{ color:var(--text-primary); }
body.visual-pilot .dash-acc-sub{ color:var(--text-secondary); }

/* 7 · ACCIÓN PRINCIPAL (pattern reutilizable) --------------------------------
   Sólo acciones REALES y disponibles; nunca métricas inventadas. */
.pattern-next{ display:none; }
.visual-pilot .pattern-next{
  display:flex; gap:var(--space-24); align-items:center; flex-wrap:wrap;
  border:1px solid var(--surface-brand); border-left:4px solid var(--surface-brand);
  border-radius:var(--card-radius); background:var(--surface-brand-subtle);
  padding:var(--space-24); margin-bottom:var(--space-24);
}
.visual-pilot .pattern-next__body{ flex:1 1 260px; min-width:0; }
.visual-pilot .pattern-next__eyebrow{
  font-family:var(--font-heading); font-weight:700; font-size:11px; letter-spacing:1.6px;
  text-transform:uppercase; color:var(--text-secondary); margin-bottom:var(--space-4);
}
.visual-pilot .pattern-next__title{
  font-family:var(--font-display); font-weight:900; font-size:26px; line-height:1.15;
  text-transform:uppercase; margin:0 0 var(--space-4); color:var(--text-primary);
}
.visual-pilot .pattern-next__desc{ margin:0; font-size:14px; color:var(--text-secondary); max-width:56ch; }
.visual-pilot .pattern-next__actions{ display:flex; gap:var(--space-8); flex-wrap:wrap; }

/* ============================================================================
   8 · UNIFORMIDAD ENTRE MÓDULOS
   Teoría, Inglés, Exámenes, Simulacros y Lengua comparten encabezado, ritmo y
   botonera. El alumno no debe notar que cambia de aplicación al cambiar de
   módulo. Se estiliza el marcado que YA existe (`conf-header`), sin migrarlo.
   ============================================================================ */
.visual-pilot .conf-header{
  border-bottom:1px solid var(--card-border);
  padding-bottom:var(--space-16); margin-bottom:var(--space-24);
}
.visual-pilot .conf-title{
  font-family:var(--font-display); font-weight:900;
  font-size:clamp(22px, 4vw, 28px); line-height:1.1;
  text-transform:uppercase; letter-spacing:.01em; color:var(--text-primary);
}
.visual-pilot .conf-sub{
  font-size:14px; line-height:1.6; color:var(--text-secondary); margin-top:var(--space-8);
}
/* REGLA DE COLOR DE ACCIÓN (uniformidad entre módulos):
   el verde claro de "éxito" comunica ACIERTO, no acción. Todos los botones de
   acción principal —empezar, lanzar, repetir, entregar— hablan con la voz
   primaria de la marca, en cualquier módulo. Así el alumno no aprende un código
   de color distinto en cada pantalla. No se toca la variante en el DS: sólo se
   iguala su apariencia dentro del recorrido. */
.visual-pilot .ds-button--success{
  background:var(--button-primary-bg); color:var(--button-primary-text);
}
.visual-pilot .ds-button--success:hover{ background:var(--button-primary-hover); }
.visual-pilot .ds-button--success:active{ background:var(--primary-800); }

/* listados y tarjetas: mismo radio y mismo borde en todos los módulos */
.visual-pilot .tema-card,.visual-pilot .bloque-card,.visual-pilot .ex-card,
.visual-pilot .teo-test-card,.visual-pilot .modulo-card{
  border-radius:var(--card-radius);
}

/* ============================================================================
   9 · MÓVIL (P5)
   ============================================================================ */
@media (max-width:640px){
  .visual-pilot .pattern-next{ padding:var(--space-16); }
  .visual-pilot .pattern-next__title{ font-size:21px; }
  .visual-pilot .pattern-next__actions .ds-button{ width:100%; }
  .visual-pilot .ing-pregunta{ font-size:18px; margin-bottom:var(--space-20); }
  body.visual-pilot .ing-tema-pill{ font-size:12.5px; margin-bottom:var(--space-16); }
  .visual-pilot .ing-explicacion{ padding:var(--space-16); }
  body.visual-pilot .ing-tema-pill{
    display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
  }
  .visual-pilot .ing-activo-header{ row-gap:var(--space-8); }
  .visual-pilot .ing-activo-info{ gap:var(--space-4); }
  .visual-pilot [data-verdict] .ing-res-circle{ padding:var(--space-20); min-width:0; width:100%; }
  .visual-pilot .ing-res-stats{ gap:var(--space-8); }
  .visual-pilot .ing-res-stat{ padding:var(--space-12) var(--space-8); }
  .visual-pilot .ing-res-stat-n{ font-size:26px; }
  .visual-pilot .ing-res-stat-l{ font-size:10px; letter-spacing:.08em; }
  .visual-pilot .pattern-result-actions{ flex-direction:column; }
}
/* apaisado de móvil: alto escaso, la cabecera del runner no puede comerse la
   pantalla — pero la inmersión se mantiene igual que en vertical. */
@media (max-height:480px) and (orientation:landscape){
  .visual-pilot .ing-activo-header{
    padding-top:var(--space-8); padding-bottom:var(--space-8); row-gap:var(--space-8);
  }
  .visual-pilot .ing-pregunta{ font-size:17px; margin-bottom:var(--space-16); }
  /* Con poca altura la metadata NO puede empujar al enunciado fuera de pantalla.
     Se acota a 2 líneas: sigue informando y el enunciado recupera el primer
     plano. (La causa de fondo es de CONTENIDO: los títulos del banco GC son
     listas completas de legislación.) */
  body.visual-pilot .ing-tema-pill{
    margin-bottom:var(--space-12);
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  }
}

/* ============================================================================
   AR-047 · RUNNER DESKTOP COMFORT
   Escala de lectura para monitores amplios. El contrato móvil/tablet permanece
   intacto; no altera estructura, eventos, scoring ni estados de ds-answer.
   ROLLBACK: retirar este bloque completo.
   ============================================================================ */
@media (min-width:1200px){
  .visual-pilot.runner-immersive .ing-activo-body,
  .visual-pilot.runner-immersive .ing-activo-btns{
    max-width:min(1120px, calc(100vw - 96px));
  }
  .visual-pilot.runner-immersive .ing-activo-header{
    padding-left:max(48px, calc((100% - 1120px) / 2));
    padding-right:max(48px, calc((100% - 1120px) / 2));
  }
  .visual-pilot.runner-immersive .ing-activo-body{
    padding-top:var(--space-24);
  }
  body.visual-pilot.runner-immersive .ing-tema-pill{
    font-size:15px;
    line-height:1.55;
  }
  .visual-pilot.runner-immersive .ing-pregunta{
    font-size:clamp(24px, 1.65vw, 28px);
    line-height:1.4;
    margin-bottom:var(--space-32);
  }
  .visual-pilot.runner-immersive .ds-answer__options,
  .visual-pilot.runner-immersive .ing-opciones{
    gap:var(--space-12);
  }
  .visual-pilot.runner-immersive .ds-answer__option,
  .visual-pilot.runner-immersive .ing-opcion{
    padding:var(--space-16) var(--space-20);
    font-size:18px;
    line-height:1.5;
  }
  .visual-pilot.runner-immersive .ds-answer__marker,
  .visual-pilot.runner-immersive .ing-opcion-letra{
    width:24px;
    height:24px;
    min-width:24px;
  }
  .visual-pilot.runner-immersive .ds-answer__status{
    min-height:28px;
    font-size:15px;
  }
  .visual-pilot.runner-immersive .ing-explicacion{
    padding:var(--space-24);
    font-size:17px;
    line-height:1.7;
  }
  .visual-pilot.runner-immersive .qstat{
    padding:var(--space-16) var(--space-20);
  }
  .visual-pilot.runner-immersive .qstat-h{ font-size:12px; }
  .visual-pilot.runner-immersive .qstat-legend{ font-size:15px; }
  .visual-pilot.runner-immersive .ing-activo-btns{
    padding-top:var(--space-16);
    padding-bottom:var(--space-16);
  }
  .visual-pilot.runner-immersive .ing-btn-dudosa,
  .visual-pilot.runner-immersive .ing-btn-sig{
    min-height:52px;
    font-size:15px;
  }
}

/* ============================================================================
   AR-048 · VISUAL DEPTH PILOT
   Tres niveles: lienzo → superficie → superficie interactiva. Los valores son
   hooks de Theme; por defecto no cambian el render. GC los activa como piloto.
   Sólo presentación: no altera layout estructural, estado ni comportamiento.
   ============================================================================ */
body.visual-pilot{
  background:var(--depth-canvas);
}
body.visual-pilot .main{ background:transparent; }
body.visual-pilot .sidebar,
body.visual-pilot .topbar,
body.visual-pilot .ing-activo-header{
  box-shadow:var(--depth-shell-shadow);
}
body.visual-pilot .dash-acc-card,
body.visual-pilot .mc-card,
body.visual-pilot .ing-card,
body.visual-pilot .tema-card,
body.visual-pilot .bloque-card,
body.visual-pilot .ex-card,
body.visual-pilot .teo-test-card,
body.visual-pilot .modulo-card,
body.visual-pilot .pro-conf-wrap,
body.visual-pilot .res-detail,
body.visual-pilot .qstat,
body.visual-pilot .ing-explicacion,
body.visual-pilot .ds-answer__option{
  box-shadow:var(--depth-surface-shadow);
}
body.visual-pilot .pattern-next{
  background:var(--depth-feature-surface);
  box-shadow:var(--depth-surface-shadow);
}
@media (hover:hover){
  body.visual-pilot .dash-acc-card:hover{ box-shadow:var(--depth-dash-hover-shadow); }
  body.visual-pilot .ds-answer:not([data-disclosure="revealed"]):not([data-disclosure="reviewed"])
    .ds-answer__option:not([data-paint="disabled"]):not([data-paint="locked"]):hover{
      box-shadow:var(--depth-interactive-shadow);
  }
}

/* ============================================================================
   AR-014 · APP SHELL · robustez de la topbar en pantallas estrechas — INICIO
   ----------------------------------------------------------------------------
   Corrección TRANSVERSAL del desbordamiento horizontal medido en las cuatro
   aulas (24/54/94 px a 390/360/320 px con sesión iniciada). NO depende de
   ninguna bandera de piloto: vive en la hoja común, que las cuatro aulas
   enlazan, de modo que alcanza también al front generado sin regenerarlo.

   Principio: el TÍTULO es la zona degradable (tiene elipsis y su truncado es
   intencional); la ZONA DE USUARIO nunca encoge por debajo de sus controles,
   de forma que ni el avatar ni «Salir» pueden quedar recortados. El problema
   NO se resuelve ocultando controles.

   Especificidad: el <style> de cada aula se carga DESPUÉS de esta hoja, así que
   los selectores usan el hijo directo (0,2,0) para ganar por especificidad a las
   reglas de una sola clase (0,1,0). Sin !important.
   ============================================================================ */

/* El título cede espacio y trunca con elipsis en lugar de empujar el layout.
   `min-width:0` es la corrección de fondo: sin él, un ítem flex no puede
   encoger por debajo de su contenido (min-width:auto es el valor inicial).
   No se altera `flex-grow`/`flex-shrink`, para no redistribuir el reparto
   `space-between` existente en escritorio. */
.topbar > .topbar-title{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

/* La zona de usuario conserva SIEMPRE el ancho de sus controles. */
.topbar > .topbar-right{ flex-shrink:0; }

/* En anchos intermedios el correo se acota con elipsis para que una dirección
   larga no pueda desbordar. Sigue siendo legible y completo para el lector. */
@media (max-width:767px){
  .topbar > .topbar-right .user-pill{ min-width:0; }
  .topbar > .topbar-right .user-pill > span{
    max-width:26vw;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
  }
}

/* Hasta 480 px el correo cede el sitio al TÍTULO, que comunica dónde está el
   usuario y tiene prioridad sobre repetir visualmente la identidad: el avatar
   ya la conserva y el correo sigue disponible en «Mi cuenta». El umbral de
   480 px da holgura para correos, tipografías y títulos distintos, en lugar de
   ajustarse a un caso concreto.
   Se oculta VISUALMENTE con la técnica visually-hidden: sigue en el árbol de
   accesibilidad (el lector lo anuncia), no ocupa ancho, y no se usa
   `display:none` ni `visibility:hidden`, que lo eliminarían de ese árbol.
   Avatar y «Salir» permanecen completos y activables. */
@media (max-width:480px){
  .topbar > .topbar-right .user-pill > span{
    position:absolute;
    width:1px;
    height:1px;
    max-width:none;
    margin:-1px;
    padding:0;
    border:0;
    overflow:hidden;
    clip-path:inset(50%);
    white-space:nowrap;
  }
}
/* AR-014 — FIN ============================================================= */

/* ===========================================================================
   AR-012 · MODULE SHELL V1 (Psicotécnicos + Personalidad)
   Capa estrictamente visual y opt-in. No define navegación, eventos, estado,
   auth ni motores. ROLLBACK: retirar `module-shell-v1` del <body>.
   ========================================================================== */
body.module-shell-v1{
  background:var(--app-bg);
  color:var(--text-primary);
  font-family:var(--font-body);
}
body.module-shell-v1 .topbar{
  min-height:60px;
  padding:0 var(--space-24);
  background:var(--shell-surface);
  color:var(--text-primary);
  border-bottom:1px solid var(--shell-border);
  box-shadow:none;
  z-index:var(--z-sticky);
}
body.module-shell-v1 .topbar-title,
body.module-shell-v1 .topbar-tit{
  color:var(--text-primary);
  font-family:var(--font-brand);
  font-size:16px;
  font-weight:800;
  letter-spacing:.02em;
  text-transform:none;
}
body.module-shell-v1 .topbar-l svg{ fill:var(--surface-brand); }
body.module-shell-v1 .btn-volver{
  min-height:44px;
  padding:0 var(--space-16);
  background:var(--button-secondary-bg);
  color:var(--button-secondary-text);
  border:1px solid var(--button-secondary-text);
  border-radius:var(--radius-8);
  font-family:var(--font-brand);
  font-size:13px;
  font-weight:700;
}
body.module-shell-v1 .btn-volver:hover{ background:var(--button-secondary-hover); }
body.module-shell-v1 .wrap{ background:var(--app-bg); }

/* Psicotécnicos ya tiene la anatomía Sidebar/Main/Topbar del aula. */
body.module-shell-v1 .sidebar{
  background:var(--shell-surface);
  border-right:1px solid var(--shell-border);
  z-index:var(--z-shell);
}
body.module-shell-v1 .sb-logo{
  min-height:60px;
  border-bottom:1px solid var(--shell-border);
}
body.module-shell-v1 .sb-brand{ color:var(--text-primary); }
body.module-shell-v1 .sb-sub,
body.module-shell-v1 .sb-sec{ color:var(--text-secondary); }
body.module-shell-v1 .sb-item{
  min-height:44px;
  color:var(--nav-item);
  font-family:var(--font-brand);
}
body.module-shell-v1 .sb-item:hover{
  background:var(--surface-brand-soft);
  color:var(--nav-item-hover);
}
body.module-shell-v1 .sb-item.on{
  background:var(--surface-brand-soft);
  color:var(--nav-item-active);
  border-left-color:var(--surface-brand);
}
@media (max-width:768px){
  body.module-shell-v1 .topbar{ padding:0 var(--space-16); }
}
@media (prefers-reduced-motion:reduce){
  body.module-shell-v1 .sidebar,
  body.module-shell-v1 .sb-item,
  body.module-shell-v1 .btn-volver{ transition:none; }
}
