/* ═══════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM · Planificador de Oposiciones
   ───────────────────────────────────────────────────────────────────────
   UNA sola paleta y UNA sola tipografía para escritorio y móvil. Lo único
   que cambia entre aparatos es la DENSIDAD (tamaños y aire).

   ═══ La identidad · «terracota» (septiembre 2026) ═══

   La guía completa, con el porqué de cada decisión, está en
   GUIA_DE_DISENO.md. Lo esencial:

   La marca era rojo #C8392C sobre crema. El rojo es el color de la
   alarma y del error, y un opositor mira esta pantalla cuatro o cinco
   horas al día: cada botón principal le hablaba en el tono de un aviso.
   Y era el mismo rojo de los simulacros y del botón de borrar.

   La terracota conserva la calidez y la energía de aquel rojo, pero es
   un color de tierra, no de alarma. Y se separa de todo lo demás:

     · TERRACOTA (#B04A2A) — la marca y lo que se pulsa. Nada más.
       Como mucho un 10 % de la pantalla.
     · SALVIA (#3F7A6E) — lo conseguido: avance, rachas, «hecho».
     · ARENA (#FCD9A8) — el tramo que cierra la P del logotipo.
     · PAPEL cálido de fondo y TINTA marrón oscura para el texto. El
       papel es el fondo natural de quien estudia y cansa menos que un
       blanco puro.
     · El PELIGRO es carmesí (#B4233C), más frío que la marca, y los
       SIMULACROS frambuesa: ninguno de los dos se confunde con un
       botón normal.

   Bricolage Grotesque para titulares e Inter para el texto: Inter es de
   las letras que mejor se leen a 12 px, que es el tamaño de las sesiones
   del calendario.

   Todos los colores de texto están medidos: 4,5:1 o más sobre tarjeta,
   sobre papel y sobre el gris suave. `herramientas/construir_marca.py`
   genera el logotipo con estos mismos valores.

   Este archivo se carga DESPUÉS del <style> de cada base.html, así que
   sus valores ganan a los que hubiera antes sin tener que tocar las
   miles de reglas que ya dependen de estos nombres de variable.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* ─── Fondos y superficies · papel cálido ────────────────────────── */
  --c-bg:#F8F5F0;
  --c-bg-card:#FFFFFF;
  --c-bg-soft:#F0EBE3;
  --c-bg-hover:#EAE3D8;
  --c-bg-sunken:#E3DBCE;
  --c-border:#E8E1D6;
  --c-border-soft:#F0EAE1;
  --c-border-strong:#D6CCBE;

  /* ─── Texto · tinta marrón ─────────────────────────────────────────
     No negro puro: sobre papel cálido, un marrón muy oscuro cansa menos
     y casa con la terracota.
     muted 5,8:1 sobre tarjeta · 5,3:1 sobre papel · 4,9:1 sobre soft  */
  --c-text:#241C18;
  --c-text-soft:#4E4540;
  --c-text-muted:#6E645D;
  --c-text-faint:#A39A92;          /* SOLO decorativo, nunca texto que haya que leer */
  --c-text-inverse:#FFFFFF;

  /* ─── Marca · terracota ────────────────────────────────────────────
     5,4:1 con texto blanco encima · 5,0:1 como texto sobre papel.
     Solo para lo que se pulsa, lo seleccionado y la propia marca.     */
  --c-brand:#B04A2A;
  --c-brand-rgb:176,74,42;         /* para rgba(var(--c-brand-rgb), .x) */
  --c-brand-hover:#963C20;
  --c-brand-deep:#7A2E17;
  --c-brand-soft:#F7E6DE;
  --c-brand-tint:#FBF3EE;
  --c-brand-on-soft:#7A2E17;       /* texto sobre --c-brand-soft · 7,8:1 */
  --c-brand-ring:rgba(176,74,42,.28);

  /* ─── Acento · salvia ──────────────────────────────────────────────
     Para lo CONSEGUIDO: barras de avance, rachas, sesiones hechas.
     `--c-accent` es de relleno (con texto blanco encima, 5,0:1);
     para texto sobre claro, `--c-accent-strong`.                      */
  --c-accent:#3F7A6E;
  --c-accent-soft:#E3EFEC;
  --c-accent-strong:#2E5E54;
  --c-arena:#FCD9A8;               /* el tramo que cierra la P del logo */

  /* ─── Semánticos ───────────────────────────────────────────────────
     `danger` NO es la marca: si borrar y continuar tienen el mismo
     color, el botón destructivo parece el camino normal. Por eso el
     peligro es carmesí, más frío que la terracota.                    */
  --c-success:#2E7553;
  --c-success-soft:#E4F2EA;
  --c-success-on-soft:#1F5C42;

  --c-warning:#9A5A0C;
  --c-warning-soft:#FCF0DC;
  --c-warning-on-soft:#74420A;

  --c-danger:#B4233C;
  --c-danger-soft:#FBE8EB;
  --c-danger-on-soft:#85192B;

  --c-info:#2B6A8F;
  --c-info-soft:#E5EFF5;
  --c-info-on-soft:#1E4E6B;

  /* ─── Colores por tipo de sesión ───────────────────────────────────
     Cada tipo de sesión tiene SIEMPRE el mismo color en todas las
     pantallas: calendario, hoy, progreso, temario y correos. Ninguno
     coincide con la marca, para que «esto es un botón» y «esto es un
     test» no se confundan. Lectura y repaso son primos (azul y verde
     azulado): repasar es volver a leer.                               */
  --s-lectura:#2563A8;    --s-lectura-soft:#E6EFF9;    --s-lectura-text:#1E4E82;
  --s-repaso:#0E7C86;     --s-repaso-soft:#E2F2F3;     --s-repaso-text:#0B5A61;
  --s-test:#7B3FA0;       --s-test-soft:#F2E9F7;       --s-test-text:#5E2D7B;
  --s-flashcards:#2F855A; --s-flashcards-soft:#E5F3EB; --s-flashcards-text:#22613F;
  --s-simulacro:#B03A6F;  --s-simulacro-soft:#FAE8F0;  --s-simulacro-text:#842A52;
  --s-caso:#A0660C;       --s-caso-soft:#FAF0DC;       --s-caso-text:#6E4A08;

  /* ─── Subrayadores del PDF (idénticos en ambas vistas) ─────────── */
  --hl-amarillo:#FFF4C2;--hl-amarillo-strong:#D4A017;--hl-amarillo-text:#5E4400;
  --hl-rosa:#FFD6E8;--hl-rosa-strong:#D4568A;--hl-rosa-text:#6E1A3E;
  --hl-azul:#D0E4FF;--hl-azul-strong:#3B6DB5;--hl-azul-text:#1A3461;
  --hl-verde:#C8EECA;--hl-verde-strong:#3D8A50;--hl-verde-text:#1A4428;
  --hl-naranja:#FFDCAD;--hl-naranja-strong:#C47520;--hl-naranja-text:#5C3000;
  --hl-violeta:#E2D4FF;--hl-violeta-strong:#7548A0;--hl-violeta-text:#3A1D5A;

  /* ─── Tipografía ───────────────────────────────────────────────────
     Bricolage Grotesque para titulares: tiene carácter sin dejar de ser
     seria. Inter para el texto y los datos: se lee muy bien pequeña y
     sus cifras tabulares alinean horas y porcentajes.

     Antes los titulares iban en Space Grotesk, cuyo «1» con bandera
     hacía que la cuenta atrás («189 días») pareciera otra letra.      */
  --font-display:"Bricolage Grotesque","Inter",system-ui,sans-serif;
  --font-body:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;

  --t-display:30px;--t-title:20px;--t-subtitle:16px;
  --t-body:14px;--t-small:13px;--t-micro:11.5px;

  /* ─── Forma ─── un poco más redonda: más amable, igual de ordenada */
  --r-sm:6px;--r:10px;--r-lg:14px;--r-xl:18px;--r-2xl:24px;--r-pill:999px;

  /* ─── Sombras ─── teñidas de la tinta marrón, no de negro */
  --shadow-sm:0 1px 0 rgba(36,28,24,.04);
  --shadow:0 1px 2px rgba(36,28,24,.05),0 4px 14px -4px rgba(36,28,24,.08);
  --shadow-lg:0 6px 20px -4px rgba(36,28,24,.10),0 28px 56px -16px rgba(36,28,24,.22);
  --shadow-brand:0 6px 18px -4px rgba(176,74,42,.40);

  /* ─── Espaciado ─── */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;
  --sp-5:24px;--sp-6:32px;--sp-7:48px;--sp-8:64px;

  /* ─── Movimiento ─── */
  --ease:cubic-bezier(.22,1,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-fast:.14s;--dur:.22s;--dur-slow:.4s;

  /* ─── Alto de la cabecera ────────────────────────────────────────
     Lo necesitan las pantallas que ocupan el alto entero (el
     planificador) para restarlo del 100vh. Estaba escrito a mano como
     56px en el calc y la cabecera medía 57: un píxel de más, y la
     página entera hacía scroll por él. */
  --alto-cabecera:57px;

  /* ─── Áreas seguras (notch de iOS) y barra inferior de móvil ─── */
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --bottom-bar:64px;

  /* ─── Degradado de marca ───────────────────────────────────────────
     El mismo de la baldosa del logotipo. Solo para piezas de marca
     (símbolo, cabecera del modal Premium); los botones van lisos.     */
  --grad-brand:linear-gradient(135deg,#C25A36,#9A3E21);
}

/* ─── Densidad en pantalla pequeña ───────────────────────────────────
   Lo ÚNICO que cambia en móvil. Mismos colores, misma letra, menos
   aire y titulares algo menores, que es lo que pide una pantalla de
   375 px de ancho.                                                    */
@media (max-width:767px){
  :root{
    --t-display:26px;--t-title:18px;--t-subtitle:15px;
    --sp-5:20px;--sp-6:28px;--sp-7:40px;--sp-8:56px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   BASE
   ═══════════════════════════════════════════════════════════════════ */

body{
  font-family:var(--font-body);
  background:var(--c-bg);
  color:var(--c-text);
}

/* Foco visible en todo lo que se pueda enfocar con teclado.
   No se toca :focus a secas para no pintar un anillo a quien navega
   con el ratón, que es ruido visual sin ninguna utilidad. */
:where(a,button,input,textarea,select,summary,[tabindex]):focus-visible{
  outline:2px solid var(--c-brand);
  outline-offset:2px;
  border-radius:var(--r-sm);
}

/* Quien pide menos movimiento en su sistema no debería ver nada
   desplazarse ni rebotar. Las transiciones se acortan, no se quitan:
   a cero, algunos cambios de estado se vuelven imperceptibles. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   COMPONENTES COMPARTIDOS
   Todo lo que aparece en más de una pantalla vive aquí, para que no
   haya dos maneras distintas de pintar un aviso o un botón.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Avisos (ds-alert) ──────────────────────────────────────────── */
.ds-alert{
  display:flex;gap:var(--sp-3);align-items:flex-start;
  padding:var(--sp-4);border-radius:var(--r-lg);
  border:1px solid var(--c-border);border-left:4px solid var(--c-border-strong);
  background:var(--c-bg-card);font-size:var(--t-small);line-height:1.55;
}
.ds-alert-icon{flex-shrink:0;font-size:18px;line-height:1.35}
.ds-alert-body{flex:1;min-width:0}
.ds-alert-title{font-weight:700;font-size:var(--t-body);margin-bottom:2px}
.ds-alert-actions{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-3)}

.ds-alert--info{background:var(--c-info-soft);border-left-color:var(--c-info);color:var(--c-info-on-soft)}
.ds-alert--info .ds-alert-title{color:var(--c-info-on-soft)}
.ds-alert--warning{background:var(--c-warning-soft);border-left-color:var(--c-warning);color:var(--c-warning-on-soft)}
.ds-alert--warning .ds-alert-title{color:var(--c-warning-on-soft)}
.ds-alert--success{background:var(--c-success-soft);border-left-color:var(--c-success);color:var(--c-success-on-soft)}
.ds-alert--success .ds-alert-title{color:var(--c-success-on-soft)}
.ds-alert--danger{background:var(--c-danger-soft);border-left-color:var(--c-danger);color:var(--c-danger-on-soft)}
.ds-alert--danger .ds-alert-title{color:var(--c-danger-on-soft)}

/* ─── Etiquetas de estado (ds-badge) ─────────────────────────────── */
.ds-badge{
  display:inline-flex;align-items:center;gap:5px;
  padding:3px 9px;border-radius:var(--r-pill);
  font-size:var(--t-micro);font-weight:700;letter-spacing:.02em;
  border:1px solid transparent;white-space:nowrap;
}
.ds-badge--neutral{background:var(--c-bg-soft);color:var(--c-text-soft);border-color:var(--c-border)}
.ds-badge--brand{background:var(--c-brand-soft);color:var(--c-brand-on-soft);border-color:rgba(var(--c-brand-rgb),.22)}
.ds-badge--success{background:var(--c-success-soft);color:var(--c-success-on-soft);border-color:rgba(46,117,83,.22)}
.ds-badge--warning{background:var(--c-warning-soft);color:var(--c-warning-on-soft);border-color:rgba(154,90,12,.24)}
.ds-badge--danger{background:var(--c-danger-soft);color:var(--c-danger-on-soft);border-color:rgba(180,35,60,.22)}
.ds-badge--info{background:var(--c-info-soft);color:var(--c-info-on-soft);border-color:rgba(43,106,143,.22)}

/* ─── Puntos de color por tipo de sesión ─────────────────────────── */
.ds-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.ds-dot--lectura{background:var(--s-lectura)}
.ds-dot--test{background:var(--s-test)}
.ds-dot--flashcards{background:var(--s-flashcards)}
.ds-dot--simulacro{background:var(--s-simulacro)}
.ds-dot--repaso{background:var(--s-repaso)}
.ds-dot--caso{background:var(--s-caso)}

/* ─── Estado vacío (ds-empty) ────────────────────────────────────── */
.ds-empty{
  text-align:center;padding:var(--sp-7) var(--sp-4);
  color:var(--c-text-soft);max-width:420px;margin:0 auto;
}
.ds-empty-icon{
  width:56px;height:56px;margin:0 auto var(--sp-4);
  border-radius:var(--r-xl);display:grid;place-items:center;
  background:var(--c-bg-soft);color:var(--c-text-muted);font-size:26px;
}
.ds-empty-title{font-family:var(--font-display);font-size:var(--t-subtitle);font-weight:700;color:var(--c-text);margin:0 0 var(--sp-2)}
.ds-empty-text{font-size:var(--t-small);line-height:1.6;margin:0 0 var(--sp-4)}

/* ─── Esqueleto de carga (ds-skeleton) ───────────────────────────── */
.ds-skeleton{
  background:linear-gradient(90deg,var(--c-bg-soft) 25%,var(--c-bg-hover) 50%,var(--c-bg-soft) 75%);
  background-size:200% 100%;
  animation:dsShimmer 1.4s infinite;
  border-radius:var(--r);
}
@keyframes dsShimmer{to{background-position:-200% 0}}

/* ─── Zona táctil mínima ─────────────────────────────────────────────
   44×44 px es el mínimo de las guías de Apple y de la WCAG 2.2. Se
   aplica en pantallas con dedo, no en escritorio, donde un botón de
   44 px de alto en una barra de herramientas es desproporcionado.    */
@media (pointer:coarse){
  .ds-tap,button.ds-tap,a.ds-tap{min-height:44px;min-width:44px}
}

/* ─── Solo para lectores de pantalla ─────────────────────────────── */
.ds-sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ─── Salto al contenido (primer tabulador de la página) ─────────── */
.ds-skip-link{
  position:absolute;left:var(--sp-3);top:-60px;z-index:9999;
  padding:10px 18px;border-radius:var(--r);
  background:var(--c-brand);color:#fff;font-weight:700;font-size:var(--t-small);
  transition:top var(--dur-fast) var(--ease-out);
}
.ds-skip-link:focus{top:calc(var(--sat) + var(--sp-3));color:#fff}

/* ═══════════════════════════════════════════════════════════════════
   SALUD DE UN TEMA
   ───────────────────────────────────────────────────────────────────
   La tira que se pinta bajo cada tema del temario. Contesta de un
   vistazo a «¿cuáles llevo flojos?» y «¿cuáles hace que no toco?», que
   es lo que decide dónde poner las horas de esta semana.

   Antes el temario solo decía si el tema tenía PDF y si la IA ya le
   había generado preguntas: el estado del MATERIAL, no el del alumno.
   ═══════════════════════════════════════════════════════════════════ */

.sl{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin-top:6px}

/* ─── Las tres vueltas ────────────────────────────────────────────
   Un segmento por vuelta del plan, en una barra de ancho fijo: mide
   lo mismo con tres vueltas que con diez. Una barra de porcentaje daría
   un número falso: las vueltas no son intercambiables, y saber que va
   por la segunda dice más que un «66%». */
.sl-vueltas{display:flex;gap:3px;align-items:center}
.sl-vueltas-barra{display:flex;gap:2px;width:54px}
.sl-v{
  flex:1;min-width:3px;height:5px;border-radius:99px;background:var(--c-bg-sunken);
  transition:background var(--dur) var(--ease)
}
.sl-v.hecha{background:var(--c-success)}
.sl-vueltas-txt{font-size:var(--t-micro);color:var(--c-text-muted);margin-left:2px}

/* ─── Datos sueltos ───────────────────────────────────────────── */
.sl-dato{
  display:inline-flex;align-items:center;gap:4px;
  font-size:var(--t-micro);color:var(--c-text-muted);white-space:nowrap
}
.sl-dato strong{color:var(--c-text-soft);font-weight:700}

/* ─── El titular ──────────────────────────────────────────────────
   Uno solo por tema, el más urgente. Dos avisos sobre la misma fila
   no se leen: compiten entre ellos. */
.sl-estado{
  display:inline-flex;align-items:center;gap:5px;
  padding:2px 9px;border-radius:var(--r-pill);
  font-size:var(--t-micro);font-weight:700;white-space:nowrap
}
.sl-estado::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor}
.sl-estado[data-e="sin_empezar"]{background:var(--c-bg-soft);color:var(--c-text-muted)}
.sl-estado[data-e="en_marcha"]{background:var(--c-info-soft);color:var(--c-info-on-soft)}
.sl-estado[data-e="solido"]{background:var(--c-success-soft);color:var(--c-success-on-soft)}
.sl-estado[data-e="frio"]{background:var(--c-warning-soft);color:var(--c-warning-on-soft)}
.sl-estado[data-e="flojo"]{background:var(--c-danger-soft);color:var(--c-danger-on-soft)}

/* ─── Cuándo vuelve a caer ───────────────────────────────────────
   Es la respuesta a «¿tengo que hacer algo YA?». Si el plan ya lo tiene
   puesto para mañana, no hay nada que decidir. */
.sl-proxima{
  display:inline-flex;align-items:center;gap:4px;
  font-size:var(--t-micro);color:var(--c-text-muted)
}
/* En tinta, no en terracota: en un temario de treinta temas eran treinta
   «hoy» del color de los botones, y ninguno se podía pulsar. */
.sl-proxima strong{color:var(--c-text-soft);font-weight:700}

/* ─── Resumen de un bloque ───────────────────────────────────────── */
.sl-bloque{display:flex;align-items:center;gap:var(--sp-3);margin-top:6px}
.sl-barra{
  flex:1;min-width:60px;max-width:180px;height:6px;border-radius:99px;
  background:var(--c-bg-sunken);overflow:hidden
}
.sl-barra-relleno{height:100%;border-radius:99px;background:var(--c-success);
  transition:width var(--dur-slow) var(--ease-out)}
.sl-bloque-txt{font-size:var(--t-micro);color:var(--c-text-muted);white-space:nowrap}
.sl-bloque-aviso{
  font-size:var(--t-micro);font-weight:700;color:var(--c-warning-on-soft);
  background:var(--c-warning-soft);padding:2px 8px;border-radius:var(--r-pill)
}

@media (max-width:620px){
  /* En móvil sobra el detalle: se deja el titular y cuándo vuelve a
     caer, que es lo accionable. Los contadores caben en la ficha. */
  .sl-dato,.sl-vueltas-txt{display:none}
  .sl{gap:var(--sp-2)}
}

/* ═══════════════════════════════════════════════════════════════════
   ICONOS
   ───────────────────────────────────────────────────────────────────
   Un solo juego, incrustado en la página (components/iconos.html).
   Sustituye a tres sistemas que convivían: 274 iconos de Tabler desde
   un CDN, 917 emojis y 1.345 glifos sueltos de texto. El mismo
   concepto se dibujaba de tres formas, cada una con su tamaño, su
   grosor y su alineación.

   El icono NO lleva color propio: hereda el del texto. Así un icono
   dentro de un aviso de atención sale ámbar y dentro de uno de error
   sale rojo, sin una sola regla extra.
   ═══════════════════════════════════════════════════════════════════ */

.ico{
  display:inline-block;vertical-align:-.15em;flex-shrink:0;
  fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;
}
/* Un icono que va solo dentro de un botón no necesita bajar la línea
   base: no acompaña a ningún texto con el que alinearse. */
button > .ico:only-child,a > .ico:only-child{vertical-align:middle}


/* ═══════════════════════════════════════════════════════════════════
   JERARQUÍA DE ATENCIÓN
   ───────────────────────────────────────────────────────────────────
   Este es el corazón del sistema, y lo que arregla «hay muchos avisos».
   El problema nunca fue cuántos avisos había: era que TODOS pedían lo
   mismo. Cuarenta y siete elementos compitiendo a la vez en el temario,
   ninguno con más derecho que otro a mirarse primero.

   Cinco niveles. Cada elemento pertenece a uno, y el nivel decide
   cuánto peso visual se le da:

     1 · DATO         Está ahí por si lo buscas. Gris, pequeño, sin caja.
                      .ds-meta              (sin límite en pantalla)

     2 · ESTADO       Cómo va algo. Teñido, pero no pide nada.
                      .ds-badge             (sin límite)

     3 · SUGERENCIA   Algo que podrías hacer. Caja suave, una acción.
                      .ds-nota              (máximo 2 por región)

     4 · DECISIÓN     Algo que te está esperando. Color, borde, botones.
                      .ds-alert             (MÁXIMO 1 EN PANTALLA)

     5 · BLOQUEO      Detiene todo. Solo para lo irreversible.
                      modal                 (máximo 1, y casi nunca)

   LA REGLA: solo puede haber UN elemento de nivel 4 o 5 visible. Si hay
   dos cosas que decidir, se enseña la más urgente y la otra baja a
   nivel 3. Dos avisos de nivel 4 se anulan entre ellos: el opositor
   deja de leer los dos.

   Cómo se decide cuál sube: lo que caduca antes. Un cobro fallido
   caduca en días y deja a alguien fuera; un tema sin PDF no caduca
   nunca. El cobro sube; el PDF se queda en nivel 3.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Nivel 1 · dato ─────────────────────────────────────────────── */
.ds-meta{
  display:inline-flex;align-items:center;gap:4px;
  font-size:var(--t-micro);color:var(--c-text-muted);white-space:nowrap
}
.ds-meta strong{color:var(--c-text-soft);font-weight:700}
.ds-meta + .ds-meta::before{
  content:'\00b7';margin-right:4px;color:var(--c-border-strong)
}

/* ─── Nivel 3 · sugerencia ───────────────────────────────────────────
   UNA LÍNEA, no una tarjeta.

   Eran cajas de dos líneas con 16 px de relleno: 76 px cada una. Tres
   sugerencias se comían 230 px de la parte de arriba del plan, que es
   donde debería estar el calendario. Y ninguna de las tres pedía nada
   urgente: eran cosas que el opositor puede hacer cuando quiera.

   Ahora es una fila de 44 px: icono, de qué va, y el enlace a la
   derecha. El detalle largo pasa al `title`, que es donde se mira
   cuando hace falta y no ocupa mientras tanto.

   Sin fondo teñido: el color es lo que hace que algo parezca urgente, y
   una sugerencia no lo es. Se distingue por la caja y el icono. */
.ds-nota{
  display:flex;gap:var(--sp-3);align-items:center;
  padding:10px var(--sp-4);min-height:44px;
  border:1px solid var(--c-border);border-radius:var(--r-lg);
  background:var(--c-bg-card);
  font-size:var(--t-small);line-height:1.4;color:var(--c-text-soft)
}
.ds-nota .ico{color:var(--c-text-muted)}
.ds-nota-cuerpo{
  flex:1;min-width:0;display:flex;align-items:baseline;gap:8px;
  overflow:hidden;white-space:nowrap
}
.ds-nota-titulo{font-weight:600;color:var(--c-text);flex-shrink:0}
/* La explicación acompaña al título en la misma línea y se recorta. Si
   no cabe, es que no era imprescindible: para eso está el `title`. */
.ds-nota-texto{
  color:var(--c-text-muted);overflow:hidden;text-overflow:ellipsis;
  min-width:0;font-size:var(--t-micro)
}
.ds-nota-accion{
  flex-shrink:0;font-weight:700;color:var(--c-brand);
  font-size:var(--t-small);white-space:nowrap
}
.ds-nota-accion:hover{color:var(--c-brand-hover);text-decoration:underline}
/* Para lo que solo informa y ni siquiera sugiere actuar */
.ds-nota--tenue{border-style:dashed;background:transparent}

@media (max-width:620px){
  /* En una pantalla estrecha la explicación no cabe con el título en la
     misma línea, así que se retira: el título ya dice de qué va. */
  .ds-nota-texto{display:none}
}


/* ═══════════════════════════════════════════════════════════════════
   BOTONES
   ───────────────────────────────────────────────────────────────────
   Había 127 clases de botón distintas, con DOS convenciones para el
   principal (.btn-brand con 123 usos y .btn-primary con 30) y un
   centenar de botones de un solo uso (.evt-dia-btn, .cv-btn,
   .pdf-tb-btn, .fc-card-btn...).

   Aquí hay cuatro, y cada uno dice una cosa distinta:

     primario    Lo que quieres que pulse. UNO por región.
     secundario  Lo demás que puede hacer ahí.
     fantasma    Lo accesorio: cerrar, cancelar, «ahora no».
     peligro     Lo que destruye algo. Nunca es el primario.

   Un botón de peligro con el aspecto del primario es una trampa: la
   mano va al botón grande y de color, y ahí estaba «borrar».
   ═══════════════════════════════════════════════════════════════════ */

.ds-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:10px 18px;border-radius:var(--r);
  border:1px solid transparent;background:transparent;
  font-family:inherit;font-size:var(--t-body);font-weight:600;
  line-height:1.2;white-space:nowrap;cursor:pointer;user-select:none;
  transition:background var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease),
             transform var(--dur-fast) var(--ease);
}
.ds-btn:disabled,.ds-btn[aria-disabled="true"]{opacity:.45;pointer-events:none}

.ds-btn--primario{
  background:var(--c-brand);color:#fff;
  box-shadow:0 1px 0 var(--c-brand-deep),0 4px 12px -4px rgba(var(--c-brand-rgb),.45)
}
.ds-btn--primario:hover{background:var(--c-brand-hover);color:#fff;transform:translateY(-1px)}
.ds-btn--primario:active{transform:none}

.ds-btn--secundario{
  background:var(--c-bg-card);color:var(--c-text);
  border-color:var(--c-border-strong)
}
.ds-btn--secundario:hover{background:var(--c-bg-soft);color:var(--c-text)}

.ds-btn--fantasma{color:var(--c-text-soft)}
.ds-btn--fantasma:hover{background:var(--c-bg-soft);color:var(--c-text)}

/* Peligro: contorno, no relleno. Que haya que buscarlo, no esquivarlo. */
.ds-btn--peligro{
  background:var(--c-bg-card);color:var(--c-danger);
  border-color:rgba(180,35,60,.35)
}
.ds-btn--peligro:hover{background:var(--c-danger);color:#fff;border-color:var(--c-danger)}

.ds-btn--sm{padding:6px 12px;font-size:var(--t-small);gap:5px}
.ds-btn--lg{padding:13px 26px;font-size:15px}
.ds-btn--bloque{width:100%}
/* Solo icono: cuadrado, y el nombre va en aria-label */
.ds-btn--icono{padding:0;width:36px;height:36px;border-radius:var(--r)}

@media (pointer:coarse){
  /* 44 px es el mínimo de las guías de Apple y de la WCAG 2.2 para algo
     que se pulsa con el dedo. Por debajo, se falla el botón. */
  .ds-btn{min-height:44px}
  .ds-btn--sm{min-height:38px}
  .ds-btn--icono{width:44px;height:44px}
}


/* ═══════════════════════════════════════════════════════════════════
   AYUDA QUE SE APAGA SOLA
   ───────────────────────────────────────────────────────────────────
   El temario enseñaba un tutorial de cuatro pasos a todo el mundo, para
   siempre. Quien llevaba seis meses estudiando seguía leyendo «pulsa la
   estrella de los temas que más caen». Ocupaba el primer pantallazo
   entero, que es el sitio más caro de la pantalla.

   Ahora cada paso desaparece cuando el opositor ya ha hecho esa cosa.
   Quien llega nuevo la ve entera; quien tiene rodaje no ve nada. Y la
   guía sigue accesible desde el «?» de la cabecera para quien la busque.
   ═══════════════════════════════════════════════════════════════════ */

.ds-guia{
  display:flex;gap:var(--sp-3);align-items:flex-start;
  padding:var(--sp-4);margin-bottom:var(--sp-4);
  border:1px solid var(--c-border);border-radius:var(--r-lg);
  background:var(--c-bg-card)
}
.ds-guia .ico{color:var(--c-brand);margin-top:1px}
.ds-guia-cuerpo{flex:1;min-width:0}
.ds-guia-titulo{font-weight:700;font-size:var(--t-body);margin-bottom:2px}
.ds-guia-texto{font-size:var(--t-small);color:var(--c-text-soft);line-height:1.55}
.ds-guia-pasos{display:flex;gap:var(--sp-2);margin-top:var(--sp-3);flex-wrap:wrap}
/* El paso pendiente destaca; los ya hechos quedan de contexto, para que
   se vea que se avanza y cuánto queda. */
.ds-guia-paso{
  display:inline-flex;align-items:center;gap:5px;
  padding:4px 10px;border-radius:var(--r-pill);
  font-size:var(--t-micro);font-weight:600;
  background:var(--c-bg-soft);color:var(--c-text-muted)
}
.ds-guia-paso[data-hecho="1"]{background:var(--c-success-soft);color:var(--c-success-on-soft)}
.ds-guia-paso[data-ahora="1"]{
  background:var(--c-brand-soft);color:var(--c-brand-on-soft);
  box-shadow:0 0 0 1px rgba(var(--c-brand-rgb),.22)
}
.ds-guia-cerrar{
  flex-shrink:0;border:none;background:transparent;cursor:pointer;
  color:var(--c-text-muted);padding:2px;border-radius:var(--r-sm)
}
.ds-guia-cerrar:hover{color:var(--c-text);background:var(--c-bg-soft)}

@media (max-width:620px){
  .ds-guia{padding:var(--sp-3)}
  .ds-guia-pasos{gap:5px}
}

/* ─── La pila de avisos ──────────────────────────────────────────────
   Un solo sitio por pantalla donde aparecen. Antes estaban repartidos:
   uno en la barra lateral, otro sobre el calendario, otro flotando
   encima. El opositor tenia que barrer la pantalla para saber si habia
   algo que atender. */
.ds-avisos{display:flex;flex-direction:column;gap:var(--sp-2);margin-bottom:var(--sp-4)}
/* Las sugerencias seguidas se pegan y comparten borde: se leen como una
   lista, no como tres sucesos distintos. */
.ds-avisos > .ds-nota + .ds-nota{margin-top:-9px;border-top-left-radius:0;border-top-right-radius:0}
.ds-avisos > .ds-nota:has(+ .ds-nota){border-bottom-left-radius:0;border-bottom-right-radius:0}
.ds-avisos:empty{display:none}
/* Los datos sueltos (nivel 1) se juntan en una linea en vez de ocupar
   una fila cada uno: son informacion de fondo, no sucesos. */
.ds-avisos > .ds-meta{padding:2px 0}
.ds-avisos > .ds-meta + .ds-meta{margin-top:-4px}

/* La caja del icono de la guia, para que no baile con el texto */
.ico-caja{display:inline-grid;place-items:center;width:20px;height:20px;flex-shrink:0}

/* ═══════════════════════════════════════════════════════════════════
   ENCABEZADO DEL TEMARIO
   ───────────────────────────────────────────────────────────────────
   Eran 144 px para un titulo, una frase y un contador, mas 78 de
   estadisticas y 39 de leyenda: 261 px de cabecera antes de ver el
   primer tema. En una pantalla de portatil, eso es un tercio.

   Se aprieta el aire, no el contenido: sigue estando todo.
   ═══════════════════════════════════════════════════════════════════ */
.tm-hero{padding-top:var(--sp-4)!important;padding-bottom:var(--sp-3)!important}
.tm-hero .h-display{font-size:26px;margin-bottom:2px}
.tm-hero > div > p.text-soft{font-size:13px;margin-top:2px!important}
.tm-stats{margin-bottom:var(--sp-3)!important}
.estado-leyenda{
  margin-bottom:var(--sp-3)!important;padding:7px 12px!important;
  font-size:var(--t-micro)
}

/* ── Esperar · el logo girando, en TODAS las cargas ────────────────────
   Habia once animaciones de carga distintas repartidas por la plataforma:
   aros de dos colores, puntos que laten, barras que brillan, textos
   «Cargando…» sueltos. Cada espera se veia de una manera y ninguna decia
   de quien era la aplicacion. Ahora todas son el logo girando, centrado:
     · .ds-esperando-marca  (img) las esperas largas: un BOE, un plan, un PDF;
     · .ds-cargando         «Cargando…» dentro de una lista o un panel;
     · .ds-girando          en linea: dentro de un boton o una pastilla.  */
.ds-esperando{display:grid;place-items:center;gap:14px;text-align:center}
.ds-esperando-marca{width:56px;height:56px;display:block;margin-left:auto;margin-right:auto;
  animation:dsGirar 1.15s cubic-bezier(.45,0,.55,1) infinite}
.ds-esperando-titulo{font-family:var(--font-display);font-size:var(--t-subtitle);
  font-weight:700;color:var(--c-text)}
.ds-esperando-texto{font-size:var(--t-small);color:var(--c-text-soft);max-width:34ch;line-height:1.55}
/*  Doble clase: gana a la de la pagina («.prs-loading», «.mm-empty»…)
    venga antes o despues.  */
.ds-cargando.ds-cargando{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:12px;padding:28px 16px;text-align:center;font-style:normal;color:var(--c-text-muted)}
.ds-cargando.ds-cargando::before{content:'';display:block;flex-shrink:0;width:40px;height:40px;
  background:url(../favicon.svg) center/contain no-repeat;
  animation:dsGirar 1.15s cubic-bezier(.45,0,.55,1) infinite}
.ds-cargando.compacto{gap:8px;padding:14px 12px}
.ds-cargando.compacto::before{width:26px;height:26px}
.ds-girando{display:inline-block;flex-shrink:0;width:1.2em;height:1.2em;vertical-align:-.25em;
  border-radius:24%;background:url(../favicon.svg) center/contain no-repeat;
  animation:dsGirar 1.15s cubic-bezier(.45,0,.55,1) infinite}
/*  Sobre un boton de color, con un filo blanco para que no se funda.  */
.btn-brand .ds-girando,.btn-primary .ds-girando{box-shadow:0 0 0 1.5px rgba(255,255,255,.85)}
@keyframes dsGirar{to{transform:rotate(360deg)}}
/*  El paso «en marcha» de una lista de pasos late; no gira (giraba el
    numero, y no se entendia).  */
@keyframes dsLatir{0%,100%{box-shadow:0 0 0 0 rgba(176,74,42,.38)}50%{box-shadow:0 0 0 7px rgba(176,74,42,0)}}
@media (prefers-reduced-motion:reduce){
  .ds-esperando-marca,.ds-cargando.ds-cargando::before,.ds-girando{animation-duration:3s}
}

/* ── Preguntar y confirmar ─────────────────────────────────────────────
   Sustituye a los `confirm()` y `prompt()` del navegador: una ventana
   gris del sistema, con el dominio arriba y los botones en el idioma del
   navegador, que aparecía justo al borrar algo. Lo usa `dialogos.js`. */
.ds-dialogo-velo{position:fixed;inset:0;z-index:9990;display:flex;
  align-items:center;justify-content:center;padding:20px;
  background:rgba(26,24,18,.45);backdrop-filter:blur(3px)}
.ds-dialogo{width:min(420px,100%);background:var(--c-bg-card);
  border:1px solid var(--c-border);border-radius:16px;box-shadow:var(--shadow-lg);
  overflow:hidden;transform:scale(.97);opacity:0;
  transition:transform .13s var(--ease-out),opacity .13s}
.ds-dialogo.entra{transform:scale(1);opacity:1}
.ds-dialogo-cuerpo{padding:22px 22px 4px}
.ds-dialogo-titulo{font-family:var(--font-display);font-size:var(--t-subtitle);
  font-weight:700;color:var(--c-text);line-height:1.3}
.ds-dialogo-texto{margin:8px 0 0;font-size:var(--t-small);line-height:1.55;
  color:var(--c-text-soft);white-space:pre-line}
.ds-dialogo-label{display:block;margin:16px 0 5px;font-size:var(--t-micro);
  font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--c-text-muted)}
.ds-dialogo-campo{width:100%;padding:10px 12px;border-radius:9px;
  border:1.5px solid var(--c-border-strong);background:var(--c-bg);
  font-family:inherit;font-size:var(--t-body);color:var(--c-text)}
.ds-dialogo-campo:focus{outline:none;border-color:var(--c-brand);
  box-shadow:0 0 0 3px var(--c-brand-ring)}
.ds-dialogo-pie{display:flex;justify-content:flex-end;gap:8px;padding:18px 22px 20px}
.ds-dialogo-btn{padding:9px 18px;border-radius:9px;cursor:pointer;
  font-family:inherit;font-size:var(--t-small);font-weight:600;
  border:1px solid var(--c-border-strong);background:var(--c-bg-card);color:var(--c-text-soft)}
.ds-dialogo-btn:hover{background:var(--c-bg-soft);color:var(--c-text)}
.ds-dialogo-ok{background:var(--c-brand);border-color:var(--c-brand);color:#fff}
.ds-dialogo-ok:hover{background:var(--c-brand-hover);color:#fff}
.ds-dialogo-ok.peligro{background:var(--c-danger);border-color:var(--c-danger)}
.ds-dialogo-ok.peligro:hover{background:var(--c-danger-on-soft)}
@media (prefers-reduced-motion:reduce){.ds-dialogo{transition:none}}
