/* Generado por `manage.py bundle_css`. NO editar a mano:
   se sobrescribe en cada build. Las fuentes son las de
   apps/core/css_bundles.py → BUNDLES['base'] */

/* ===== css/tokens.css ===== */
/* ============================================================================
   FUENTES — autoalojadas desde el 18-09-2026
   Antes venían de fonts.googleapis.com: una hoja externa bloqueante (~850 ms
   en móvil según Lighthouse) más dos orígenes nuevos a los que conectar.
   Ahora salen del mismo origen que el resto de estáticos.

   - Solo subconjuntos latin y latin-ext (la web está en ES/EN). El navegador
     descarga latin-ext solo si la página usa algún carácter de su
     unicode-range (ej. un nombre de marca con «ł» o «ő»).
   - Las tres son fuentes variables: un fichero cubre 400–700. JetBrains Mono
     también: Google servía el mismo fichero para 400, 500 y 700.
   - Space Grotesk e Instrument Sans (latin) van con <link rel="preload"> en
     base.html: están en todas las páginas. Si cambias sus ficheros, cambia
     también esos preload o el navegador descargará dos veces.
   - Para actualizar: pedir el CSS de Google con un User-Agent de Chrome
     moderno y copiar los woff2 de los bloques latin / latin-ext.
   ============================================================================ */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin.25ea4a783c12.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-latin-ext.dea099b7d5a5.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin.e35fad09c70b.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin-ext.e2385a017626.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-italic-latin.ba4ed4ed7590.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-italic-latin-ext.fd76d1df2b71.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.570751c5f8b4.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext.e6155c5cfacf.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Archivo: la familia del sistema nuevo (rediseño oct-2026, ver DESIGN-GUIDE.md).
   Variable en peso (400–800) y en anchura (62–125 %): una sola familia hace de
   display (≈104 %), de cuerpo (100 %) y de rótulo condensado (≈78 %). Solo la
   usan las páginas ya migradas; el navegador no la descarga en las demás. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("../fonts/archivo-latin.2f7ea45bad3a.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("../fonts/archivo-latin-ext.cde95d2797df.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================================
   SonidoenRed — TOKENS
   Único origen de verdad del sistema de diseño. Se carga ANTES que cualquier
   otra hoja. Ver DESIGN-GUIDE.md.

   Capas:
     L1  Primitivas    — no dependen del tema (tipografía, espacio, radios, motion)
     L2  Semánticas    — color y elevación, con override en [data-theme="dark"]
     L3  Compatibilidad— nombres antiguos que aún consumen las 22 hojas restantes

   El bloque claro se declara en :root y también en [data-theme="light"], para
   poder forzar una isla clara dentro de una página oscura (lo usa el styleguide
   para enseñar las dos paletas a la vez).

   BREAKPOINTS (no pueden ser variables: @media no acepta var()).
   El código nuevo usa SOLO estos cinco, siempre en min-width, móvil primero:
       480px   móvil grande
       640px   phablet / 2 columnas
       768px   tablet
      1024px   escritorio
      1280px   ancho
   El código antiguo conserva los suyos hasta que se migre su página.
   ============================================================================ */

:root,
[data-theme="light"] {

  /* ==========================================================================
     L1 — PRIMITIVAS
     ========================================================================== */

  /* --- Familias ----------------------------------------------------------- */
  --font-display: 'Space Grotesk', system-ui, -apple-system, sans-serif;
  --font-body: 'Instrument Sans', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* --- Escala tipográfica -------------------------------------------------
     Sustituye la improvisación de 14.5 / 13.5 / 12.5px por 15 / 14 / 13.
     Space Grotesk llega hasta 700: no existe un peso 800 en este sistema. */
  --fs-display-xl: clamp(40px, 6vw, 68px);
  --fs-display-lg: clamp(30px, 4vw, 44px);
  --fs-display-md: clamp(24px, 3vw, 32px);
  --fs-xl: 20px;
  --fs-lg: 18px;
  --fs-md: 16px;
  --fs-base: 15px;
  --fs-sm: 14px;
  --fs-xs: 13px;
  --fs-2xs: 11px;

  --lh-tight: 1.08;
  --lh-snug: 1.25;
  --lh-normal: 1.5;
  --lh-relaxed: 1.65;

  --ls-tighter: -.03em;
  --ls-tight: -.02em;
  --ls-normal: 0;
  --ls-wide: .09em;

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* --- Espaciado (base 4px) ----------------------------------------------- */
  --space-0: 0;
  --space-px: 1px;
  --space-05: 2px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 28px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-30: 120px;

  --section-y: clamp(70px, 9vw, 110px);
  --gutter: clamp(16px, 4vw, 24px);

  /* --- Radios -------------------------------------------------------------
     Absorben los 8/11/12/13/14/16/18/20/22/28 hardcodeados de hoy.
     --radius-btn y --radius-card van con nombre porque son los dos que
     definen el carácter del sistema y se repiten por todas partes. */
  --radius-xs: 8px;
  --radius-sm: 12px;
  --radius-md: 16px;
  --radius-lg: 20px;
  --radius-xl: 24px;
  --radius-2xl: 28px;
  --radius-pill: 999px;
  --radius-btn: 13px;
  --radius-card: 18px;

  /* --- Motion -------------------------------------------------------------
     --dur-slow debe quedarse por debajo de los 300ms que main.js:75 espera
     antes de poner hidden en el menú móvil. */
  --dur-instant: 90ms;
  --dur-fast: 150ms;
  --dur-base: 220ms;
  --dur-slow: 290ms;
  --dur-slower: 500ms;
  --dur-reveal: 700ms;

  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-standard: cubic-bezier(.4, 0, .2, 1);

  /* --- Layout -------------------------------------------------------------
     --header-h está CONGELADO en 68px: 26 reglas de 12 hojas lo usan para
     offsets sticky y scroll-margin-top. Cambiarlo descoloca barras de filtros
     y anclas en toda la web. */
  --container: 1200px;
  --container-narrow: 760px;
  --container-wide: 1360px;
  --header-h: 68px;

  /* --- Capas -------------------------------------------------------------- */
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-header: 300;
  --z-overlay: 400;
  --z-drawer: 500;
  --z-toast: 600;
  --z-progress: 700;

  /* ==========================================================================
     L2 — SEMÁNTICAS (modo claro)
     ========================================================================== */

  /* --- Marca --------------------------------------------------------------
     #7A0CFF es el ancla de identidad. 6.3:1 sobre blanco → AA.
     --accent-rgb existe para que las sombras de acento sigan al tema en vez
     de quedarse con el morado claro hardcodeado. */
  --accent: #7A0CFF;
  --accent-rgb: 122 12 255;
  --accent-strong: #6200E0;
  --accent-soft: #F3EBFF;
  --accent-border: #E2D1FF;
  --accent-contrast: #FFFFFF;
  --accent-cyan: #22B8D6;

  /* --- Superficies --------------------------------------------------------- */
  --bg: #FFFFFF;
  --bg-alt: #F7F5FC;
  --surface: #FFFFFF;
  --surface-2: #FBFAFE;
  --surface-3: #F3F0FA;
  --overlay: rgba(8, 5, 16, .55);
  /* Lienzo para fotos de catálogo. Blanco en los dos temas a propósito: las
     imágenes vienen recortadas con fondo blanco cocido, así que sobre
     cualquier otro color se ve un rectángulo dentro de otro. */
  --photo: #FFFFFF;

  /* --- Texto ---------------------------------------------------------------
     Contraste sobre --bg en claro:  ink 17.6:1 · ink-soft 7.7:1 · ink-faint 5.4:1.
     ink-faint era #8A8398 y daba 3.6:1, por debajo de AA para texto normal, y
     se usa para metadatos (fechas, contadores) en toda la web. Se oscurece. */
  --ink: #15101F;
  --ink-soft: #574F66;
  --ink-faint: #6E6780;
  --ink-inverse: #FFFFFF;

  /* --- Bordes -------------------------------------------------------------- */
  --border: #ECE8F4;
  --border-strong: #DDD6EC;
  --focus-ring: #7A0CFF;

  /* --- Estados -------------------------------------------------------------
     --success y --warning se oscurecieron el 18-09-2026: se usan como COLOR DE
     TEXTO (badges, «Sí», bajadas de precio, veredictos) y no llegaban a AA.
       success #1B9E4B → #157D3B: 3.5 → 5.2:1 sobre blanco, 4.7 sobre --success-soft
       warning #C98A00 → #916300: 2.9 → 5.3:1 sobre blanco, 4.8 sobre --warning-soft
     Mismo tono, solo más oscuros. */
  --success: #157D3B;
  --success-soft: #E7F6EC;
  --success-border: #BCE6CB;
  --danger: #C13737;
  --danger-soft: #FBEAEA;
  --danger-border: #F58F8F;
  /* Texto legible sobre --danger. En oscuro el rojo se aclara y el blanco
     baja a 2,5:1, así que ahí el contraste lo da la tinta oscura. */
  --danger-contrast: #FFFFFF;
  --warning: #916300;
  --warning-soft: #FBF3DF;
  --warning-border: #E8CE8A;
  --info: #0B84BA;
  --info-soft: #E6F4FA;
  --info-border: #A8D8EA;
  --star: #F5A524;

  /* --- Elevación ----------------------------------------------------------- */
  --shadow-xs: 0 1px 2px rgba(21, 16, 31, .05);
  --shadow-sm: 0 1px 2px rgba(21, 16, 31, .04), 0 2px 6px rgba(21, 16, 31, .04);
  --shadow-md: 0 4px 12px rgba(21, 16, 31, .06), 0 12px 32px rgba(21, 16, 31, .07);
  --shadow-lg: 0 12px 28px rgba(21, 16, 31, .10), 0 28px 60px rgba(21, 16, 31, .10);
  --shadow-xl: 0 24px 48px rgba(21, 16, 31, .14), 0 48px 96px rgba(21, 16, 31, .12);
  --shadow-accent-sm: 0 6px 18px rgb(var(--accent-rgb) / .28);
  --shadow-accent-md: 0 10px 26px rgb(var(--accent-rgb) / .38);

  /* --- Series de datos (gráficos del panel) --------------------------------
     Orden fijo: el color va con la entidad (macOS, Windows, Linux), nunca con
     su posición en el ranking. No son los colores de marca tal cual: están
     ajustados para que se distingan con daltonismo y contrasten 3:1 contra
     --surface. Si añades una serie, no inventes un color: agrupa en «Otros». */
  --chart-1: #7A0CFF;
  --chart-2: #0E8FA8;
  --chart-3: #B8730A;
  --chart-otros: #8A8398;
  --chart-grid: #EFECF6;

  /* ==========================================================================
     L3 — COMPATIBILIDAD CON NOMBRES ANTIGUOS

     Las otras 22 hojas (~10.800 líneas) consumen estos nombres. La sustitución
     de custom properties se resuelve contra el valor EN CASCADA del mismo
     elemento, así que un alias definido aquí sigue automáticamente al valor
     que [data-theme="dark"] ponga más abajo: no hace falta repetirlos en el
     bloque oscuro.

     TIER A — alias: el valor nuevo y el viejo ya coincidían.
     ========================================================================== */
  --text-color-accent-default: var(--accent);
  --icon-color-accent-default: var(--accent);
  --background-color-primary-default: var(--bg);
  --background-color-accent-default: var(--accent-soft);
  --background-color-error-default: var(--danger-soft);
  --text-color-success-default: var(--success);
  --icon-color-success-default: var(--success);
  --text-color-error-default: var(--danger);
  --icon-color-error-default: var(--danger);
  --text-color-link-default: var(--info);

  /* --- TIER B — CONGELADOS -------------------------------------------------
     Su valor antiguo NO coincide con el nuevo y aliasarlos repintaría cientos
     de reglas de páginas todavía sin migrar. Se quedan con su literal exacto
     (claro y oscuro) hasta que se migre la página que los consume.
     Descongelar es parte de la migración de cada página, no de este paso. */
  --color-accent-default: #7A0CFF;              /* FROZEN — 44 usos */
  --text-color-primary-default: #2D2D31;        /* FROZEN — 40 usos */
  --text-color-secondary-default: #71717A;      /* FROZEN — 48 usos */
  --border-color-primary-default: #71717A;      /* FROZEN */
  --border-color-secondary-default: #C6C6CA;    /* FROZEN — 56 usos */
  --border-color-accent-default: #CA9EFF;       /* FROZEN */
  --border-color-error-default: #F58F8F;        /* FROZEN */
  --icon-color-primary-default: #2D2D31;        /* FROZEN */
  --icon-color-secondary-default: #71717A;      /* FROZEN */
  --color-text-original: #22252F;               /* FROZEN — relleno de SVG de marca */
  --color-text-light: #E9E9EE;                  /* FROZEN — relleno de SVG de marca */
  --color-bg-default: #22252F;                  /* FROZEN — relleno de SVG de marca */
  --color-corner-outline: #2D2D31;              /* FROZEN */
  --color-label-default: #F1F1F2;               /* FROZEN */

  /* --- TIER C — estructurales, alias con valor idéntico --------------------- */
  --spacing-xxs: var(--space-1);
  --spacing-xs: var(--space-2);
  --spacing-sm: var(--space-3);
  --spacing-md: var(--space-4);
  --spacing-lg: var(--space-5);
  --spacing-xl: var(--space-6);
  --spacing-xxl: var(--space-7);

  --corner-radius-xs: var(--radius-xs);   /* 8  — 11 usos */
  --corner-radius-sm: var(--radius-sm);   /* 12 — 16 usos */
  --corner-radius-md: var(--radius-md);   /* 16 — 10 usos */
  --corner-radius-lg: var(--radius-lg);   /* 20 —  1 uso  */
  --corner-radius-xl: var(--radius-xl);   /* 24 — 15 usos */

  --header-height: var(--header-h);

  --content-max-horizontal-padding: 20px;
  --content-max-horizontal-padding-mb: 8px;
  --content-max-vertical-padding-16: 16px;
  --content-max-vertical-padding-32: 32px;
  --content-max-vertical-padding-64: 64px;

  /* --- Nombres huérfanos ---------------------------------------------------
     Se referencian en el CSS existente pero no estaban definidos en ninguna
     parte. Dos de ellos eran fallos reales sin fallback:
       comparator/comparator.css      background: var(--background-color-secondary-default) (regla ya borrada)
       training/index.css             color: var(--text-color-muted) (hoja ya borrada)
     Ambos resolvían a inválido. Definirlos aquí los arregla. */
  --color-border: var(--border);
  --color-surface: var(--surface);
  --color-surface-2: var(--surface-2);
  --color-text: var(--ink);
  --color-text-muted: var(--ink-faint);
  --text-color-muted: var(--ink-faint);
  --color-accent-hover: var(--accent-strong);
  --background-color-secondary-default: var(--surface-2);
}

/* ============================================================================
   MODO OSCURO

   Selector de atributo a secas (no html[data-theme]) a propósito: permite
   pintar una isla oscura dentro de una página clara (<div data-theme="dark">)
   para las muestras comparadas del styleguide.

   Solo se redefinen las semánticas. Los alias del Tier A y C las siguen solos.
   ============================================================================ */

[data-theme="dark"] {
  /* --- Marca ---------------------------------------------------------------
     El morado se aclara para mantener AA sobre fondo oscuro: #A66BFF da 5.8:1
     sobre --bg. Y el texto SOBRE el acento pasa a ser casi negro: blanco sobre
     #A66BFF solo daría 3.4:1, que no llega a AA para texto normal. */
  --accent: #A66BFF;
  --accent-rgb: 166 107 255;
  --accent-strong: #8A3CFF;
  --accent-soft: rgba(166, 107, 255, .13);
  --accent-border: rgba(166, 107, 255, .32);
  --accent-contrast: #100B1A;
  --accent-cyan: #3AD2EF;

  /* --- Superficies --------------------------------------------------------- */
  --bg: #0C0913;
  --bg-alt: #100B1A;
  --surface: #15101F;
  --surface-2: #1A1428;
  --surface-3: #211A32;
  --overlay: rgba(4, 2, 9, .68);

  /* --- Texto --------------------------------------------------------------- */
  --ink: #F5F2FB;
  --ink-soft: #B4ADC4;
  /* Era #7E7791: 4.4:1 sobre --surface y 4.2 sobre --surface-2, justo por
     debajo de AA. Es el color de metadatos, contadores y precios tachados de
     todo el comparador (160+ elementos por página en Lighthouse). #8A849B da
     4.98:1 en --surface-2, el peor caso, y sigue claramente por debajo de
     --ink-soft (8.3:1), así que la jerarquía se mantiene. */
  --ink-faint: #8A849B;
  --ink-inverse: #15101F;

  /* --- Bordes -------------------------------------------------------------- */
  --border: #251D38;
  --border-strong: #322749;
  --focus-ring: #A66BFF;

  /* --- Estados -------------------------------------------------------------
     danger-soft, warning, warning-soft y star no tenían valor oscuro: se
     quedaban con el fondo claro sobre #0C0913. */
  --success: #34D87A;
  --success-soft: rgba(52, 216, 122, .12);
  --success-border: rgba(52, 216, 122, .3);
  --danger: #FF8080;
  --danger-soft: rgba(255, 128, 128, .12);
  --danger-border: rgba(255, 128, 128, .32);
  --danger-contrast: #2A0E0E;
  --warning: #F0B429;
  --warning-soft: rgba(240, 180, 41, .12);
  --warning-border: rgba(240, 180, 41, .32);
  --info: #60B4E4;
  --info-soft: rgba(96, 180, 228, .12);
  --info-border: rgba(96, 180, 228, .32);
  --star: #FFB020;

  /* --- Elevación ----------------------------------------------------------- */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, .45);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, .55);
  --shadow-xl: 0 28px 64px rgba(0, 0, 0, .62);

  /* --- Series de datos en oscuro -------------------------------------------
     No es el claro aclarado: son sus propios pasos validados contra la
     superficie oscura. */
  --chart-1: #A66BFF;
  --chart-2: #1B96AF;
  --chart-3: #C07F14;
  --chart-otros: #7E7791;
  --chart-grid: #221B33;

  /* --- TIER B en oscuro — congelados igual que en claro --------------------- */
  --color-accent-default: #9333EA;              /* FROZEN */
  --text-color-primary-default: #EEEEF5;        /* FROZEN */
  --text-color-secondary-default: #8888A0;      /* FROZEN */
  --border-color-primary-default: #3A3A50;      /* FROZEN */
  --border-color-secondary-default: #252535;    /* FROZEN */
  --border-color-accent-default: #4A1E9E;       /* FROZEN */
  --border-color-error-default: #7A2020;        /* FROZEN */
  --icon-color-primary-default: #EEEEF5;        /* FROZEN */
  --icon-color-secondary-default: #8888A0;      /* FROZEN */
  --color-text-original: #EEEEF5;               /* FROZEN */
  --color-text-light: #EEEEF5;                  /* FROZEN */
  --color-bg-default: #06060D;                  /* FROZEN */
  --color-corner-outline: #1E1E2E;              /* FROZEN */
  --color-label-default: #F1F1F2;               /* FROZEN */
}

/* ============================================================================
   Sistema nuevo «mostrador técnico» (oct-2026): tokens --x-*
   Globales: los usan el comparador (.cmpx), la barra de comparar, la cabecera,
   el menú móvil y el pie. El resto de la web sigue con los tokens de arriba
   hasta que se migre. Ver DESIGN-GUIDE.md.
   ============================================================================ */
:root {
  --x-paper: #FAFAF9;
  --x-surface: #FFFFFF;
  --x-tray: #EEEEEB;          /* pozo de foto: las fotos traen fondo blanco cocido */
  --x-ink: #141416;
  --x-ink-2: #55565C;
  --x-ink-3: #6F7076;         /* 4.9:1 sobre --x-paper */
  --x-line: #E3E3DF;
  --x-line-2: #CFCFCA;
  --x-accent: #7A0CFF;
  --x-accent-ink: #FFFFFF;
  --x-accent-soft: #F1E8FF;
  --x-low: #0A7A43;           /* precio cerca del mínimo / bajada */
  --x-low-soft: #E3F3EA;
  --x-mid: #D6D6D1;
  --x-high: #A85A06;          /* precio por encima de lo normal */
  --x-strip: #141416;
  --x-strip-ink: #FAFAF9;
  /* Series del gráfico de precios: una por tienda, en orden fijo. Sin verde
     ni ámbar (son los veredictos). Distinguibles con daltonismo y 3:1 sobre
     --x-surface. */
  --x-chart-1: #7A0CFF;
  --x-chart-2: #0B7285;
  --x-chart-3: #C2255C;
  --x-chart-4: #3B5BDB;
  --x-chart-5: #8C5A2B;
  --x-chart-6: #495057;
  --x-star: #B7791F;

  --x-font: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --x-r: 10px;
}

:root[data-theme="dark"] {
  --x-paper: #0F0F11;
  --x-surface: #17171A;
  --x-tray: #E4E4E0;          /* se mantiene claro a propósito: mismo motivo */
  --x-ink: #EDEDEF;
  --x-ink-2: #A7A8AE;
  --x-ink-3: #8C8D93;
  --x-line: #26262B;
  --x-line-2: #36363C;
  --x-accent: #A66BFF;
  --x-accent-ink: #0F0F11;
  --x-accent-soft: #251A38;
  --x-low: #3FCB80;
  --x-low-soft: #123222;
  --x-mid: #3A3A40;
  --x-high: #E39A45;
  --x-strip: #A66BFF;
  --x-strip-ink: #0F0F11;
  --x-chart-1: #B48CFF;
  --x-chart-2: #3BC9DB;
  --x-chart-3: #F06595;
  --x-chart-4: #748FFC;
  --x-chart-5: #D9A066;
  --x-chart-6: #ADB5BD;
  --x-star: #F2B84B;
}

/* Controles nativos (casillas, radios, desplegables, barras de desplazamiento)
   en el tema elegido. Sin esto, en oscuro las casillas salían blancas. */
:root { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* ===== css/main.css ===== */
/* ============================================================================
   SonidoenRed — BASE + CHROME
   Los tokens viven en tokens.css, que se carga antes que esta hoja.
   ============================================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}
[hidden] {
  display: none !important;
}
html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-height);
  overflow-x: clip; /* Contiene overflow horizontal sin crear scroll container */
}

body {
  margin: 0;
  font-family: var(--font-body);
  background-color: var(--background-color-primary-default);
  color: var(--text-color-primary-default);
  overflow-x: clip; /* clip no rompe position:sticky (hidden sí lo haría) */
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6,
.H3-Heading {
  font-family: var(--font-display);
}
h1, h2, h3, h4, h5, h6,
p,
ul,
ol {
  margin: 0;
}
img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.H3-Heading {
  font-size: 28px;
  font-weight: 600;
  line-height: 42px;
}

/* ============================================================================
   CHROME — cabecera, navegación, menú móvil, dropdowns y pie.

   CONTRATO CON EL JS (no renombrar nada de esto sin tocar static/js/):
     main.js        .navbar-toggle · .mobile-menu · .mobile-menu-close · .is-open
                    .navbar-avatar · .navbar-avatar-wrap · .navbar-dropdown
                    .navbar-notifications(-wrap|-dropdown|-badge)
                    .notif-list · .notif-dropdown-empty · .notif-mark-all-read
                    .notif-item · .notif-dot · .is-unread · .notif-content
                    .notif-title · .notif-message · .notif-time   (los crea el JS)
                    #themeToggle · #mobileThemeToggle · #mobileThemeLabel
                    .theme-icon-sun · .theme-icon-moon · .srn-nav-progress
     onboarding.js  #nav-* y #mnav-*
     cookie_consent.js  [data-cookie-preferences] (vive en el pie)

   Tres detalles de comportamiento que condicionan el CSS:
     · .mobile-menu es el OVERLAY, no el panel: main.js cierra comparando
       e.target === menu. El panel es .mobile-menu-panel.
     · main.js pone hidden en el menú tras 300ms, así que la transición de
       salida no puede pasar de ahí (--dur-slow son 290ms).
     · El trampeo de foco filtra por [hidden] y display:none. Nada de ocultar
       con visibility u opacity, o el tabulador entra en controles invisibles.
   ============================================================================ */

/* ============================================================================
   Sistema «mostrador técnico» (migrado el 29-10-2026). Tokens --x-* de
   tokens.css, una sola familia (Archivo), sin desenfoques ni animaciones de
   entrada. El morado queda para el foco, el contador de notificaciones y el
   idioma elegido; el estado activo va en tinta. Mismo ancho y márgenes que
   .cmpx-wrap para que la marca quede alineada con el contenido.
   ============================================================================ */

.site-header,
.mobile-menu,
.site-footer {
  font-family: var(--x-font);
  color: var(--x-ink);
}

.site-header :focus-visible,
.mobile-menu :focus-visible,
.site-footer :focus-visible {
  outline: 2px solid var(--x-accent);
  outline-offset: 2px;
  /* Sin border-radius aquí: cambiaría la forma del elemento al enfocarlo (el
     avatar redondo pasaba a cuadrado). El contorno ya sigue el radio propio. */
}

/* ============================================================================
   CABECERA
   ============================================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  block-size: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--x-line);
  background: var(--x-surface);
}

.site-header nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  inline-size: 100%;
  block-size: 100%;
  max-inline-size: 1200px;
  padding-inline: max(16px, env(safe-area-inset-left, 0px)) max(16px, env(safe-area-inset-right, 0px));
}

/* Barra de progreso de navegación (feedback al pulsar un enlace).
   El JS le escribe transform y opacity en línea: no usar !important aquí. */
.srn-nav-progress {
  position: fixed;
  inset-inline: 0;
  top: var(--header-h);
  block-size: 2px;
  z-index: var(--z-progress);
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--x-accent);
  pointer-events: none;
  will-change: transform, opacity;
}

/* --- Marca ---------------------------------------------------------------- */
.navbar-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--x-ink);
  text-decoration: none;
  flex: none;
}

.navbar-isotipo img { display: block; inline-size: 28px; block-size: 28px; }

.navbar-logotipo {
  font-family: var(--x-font);
  font-stretch: 104%;
  font-size: 18px;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -.015em;
}

/* --- Navegación principal -------------------------------------------------- */
.navbar-menu,
.navbar-auth { display: none; }

.navbar-menu {
  align-items: stretch;
  align-self: stretch;
  gap: 28px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.navbar-item { display: flex; }

/* El activo se marca con un filete de tinta pegado al borde inferior de la
   cabecera, sin animación. */
.navbar-link {
  display: flex;
  align-items: center;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--x-ink-2);
  text-decoration: none;
  transition: border-color 150ms ease;
}

.navbar-link:hover { color: var(--x-ink); border-bottom-color: var(--x-line-2); }
.navbar-link.is-active { color: var(--x-ink); font-weight: 600; border-bottom-color: var(--x-ink); }

/* --- Zona de acciones ------------------------------------------------------ */
.navbar-auth {
  align-items: center;
  gap: 6px;
  flex: none;
}

.navbar-user-controls {
  display: none;
  align-items: center;
  gap: 6px;
}

.navbar-theme-toggle,
.navbar-notifications {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 38px;
  block-size: 38px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--x-r);
  color: var(--x-ink-2);
  background: none;
  cursor: pointer;
  flex: none;
  transition: background-color 150ms ease, border-color 150ms ease;
}

.navbar-theme-toggle:hover,
.navbar-notifications:hover { color: var(--x-ink); background: var(--x-paper); border-color: var(--x-line); }

.navbar-theme-toggle svg,
.navbar-notifications svg { inline-size: 19px; block-size: 19px; }

.navbar-notifications-wrap { position: relative; }

.navbar-notifications[aria-expanded="true"] { color: var(--x-ink); background: var(--x-paper); border-color: var(--x-line-2); }

.navbar-notifications-badge {
  position: absolute;
  top: 3px;
  right: 3px;
  min-inline-size: 17px;
  block-size: 17px;
  padding-inline: 4px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 2px solid var(--x-surface);
  background: var(--x-accent);
  color: var(--x-accent-ink);
  font-size: 10.5px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Iniciar sesión: botón secundario. El morado se reserva para la acción
   principal de cada página (buscar, ver en tienda…). */
.navbar-login {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-inline-start: 6px;
  padding: 8px 14px;
  border: 1px solid var(--x-line-2);
  border-radius: var(--x-r);
  background: var(--x-surface);
  color: var(--x-ink);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 150ms ease;
}

.navbar-login:hover { border-color: var(--x-ink); }
.navbar-login svg { inline-size: 17px; block-size: 17px; }

/* --- Avatar ---------------------------------------------------------------- */
.navbar-avatar-wrap { position: relative; }

.navbar-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 34px;
  block-size: 34px;
  margin-inline-start: 4px;
  padding: 0;
  border: 1px solid var(--x-line-2);
  border-radius: 50%;
  background: none;
  cursor: pointer;
  overflow: hidden;
  flex: none;
  transition: border-color 150ms ease;
}

.navbar-avatar:hover,
.navbar-avatar[aria-expanded="true"] { border-color: var(--x-ink); }

.navbar-avatar-img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.navbar-avatar-initials,
.mobile-menu-avatar-initials {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 100%;
  block-size: 100%;
  background: var(--x-paper);
  color: var(--x-ink-2);
  font-size: 12.5px;
  font-weight: 650;
  line-height: 1;
  user-select: none;
}

/* --- Botón de menú móvil ---------------------------------------------------- */
.navbar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  padding: 0;
  border: 1px solid var(--x-line-2);
  border-radius: var(--x-r);
  color: var(--x-ink);
  background: var(--x-surface);
  cursor: pointer;
  flex: none;
  transition: border-color 150ms ease;
}

.navbar-toggle:hover { border-color: var(--x-ink); }
.navbar-toggle svg { inline-size: 21px; block-size: 21px; }

/* ============================================================================
   DROPDOWNS (notificaciones y perfil)
   ============================================================================ */

.navbar-notifications-dropdown,
.navbar-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: var(--z-dropdown);
  border: 1px solid var(--x-line-2);
  border-radius: 12px;
  background: var(--x-surface);
  box-shadow: 0 10px 30px rgb(20 20 22 / .10);
  overflow: hidden;
}

.navbar-notifications-dropdown { inline-size: min(340px, calc(100vw - 32px)); }
.navbar-dropdown { min-inline-size: 236px; }

/* --- Cabecera de dropdown --------------------------------------------------- */
.notif-dropdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--x-line);
}

.notif-dropdown-title { font-size: 15px; font-weight: 650; color: var(--x-ink); }

.notif-mark-all-read {
  padding: 0;
  border: 0;
  background: none;
  color: var(--x-ink-2);
  font: inherit;
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--x-line-2);
  cursor: pointer;
}

.notif-mark-all-read:hover { color: var(--x-ink); text-decoration-color: currentColor; }

/* --- Lista de notificaciones (el JS crea estos nodos) ------------------------ */
.notif-list {
  margin: 0;
  padding: 0;
  list-style: none;
  max-block-size: 340px;
  overflow-y: auto;
}

.notif-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 16px;
  text-decoration: none;
  transition: background-color 150ms ease;
}

.notif-list li + li .notif-item { border-top: 1px solid var(--x-line); }
.notif-item:hover { background: var(--x-paper); }

.notif-dot {
  flex: none;
  inline-size: 7px;
  block-size: 7px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--x-accent);
}

.notif-item:not(.is-unread) .notif-dot { background: transparent; }

.notif-content { min-inline-size: 0; display: flex; flex-direction: column; gap: 2px; }

.notif-title { font-size: 14px; font-weight: 600; color: var(--x-ink); line-height: 1.35; }
.notif-item:not(.is-unread) .notif-title { font-weight: 500; color: var(--x-ink-2); }

.notif-message {
  font-size: 13px;
  color: var(--x-ink-2);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.notif-time { font-size: 12px; color: var(--x-ink-3); font-variant-numeric: tabular-nums; }

.notif-dropdown-empty {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 36px 16px;
  text-align: center;
  color: var(--x-ink-3);
  font-size: 14px;
}

.notif-dropdown-empty p { margin: 0; }

.notif-dropdown-footer { border-top: 1px solid var(--x-line); }

.notif-dropdown-footer a {
  display: block;
  padding: 11px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--x-ink);
  text-decoration: none;
  transition: background-color 150ms ease;
}

.notif-dropdown-footer a:hover { background: var(--x-paper); }

/* --- Dropdown de perfil ------------------------------------------------------ */
.navbar-dropdown-header {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--x-line);
}

.navbar-dropdown-name {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 14.5px;
  font-weight: 650;
  color: var(--x-ink);
}

.navbar-dropdown-email { font-size: 13px; color: var(--x-ink-3); }

.navbar-dropdown-list { margin: 0; padding: 6px; list-style: none; }

.navbar-dropdown-list a,
.navbar-dropdown-logout {
  display: block;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--x-ink-2);
  text-decoration: none;
  transition: background-color 150ms ease;
}

.navbar-dropdown-list a:hover { background: var(--x-paper); color: var(--x-ink); }

.navbar-dropdown-footer { padding: 6px; border-top: 1px solid var(--x-line); }

.navbar-dropdown-logout:hover { background: var(--x-paper); color: var(--x-ink); }

/* Bloqueo de scroll del fondo mientras hay un panel abierto.
   Vivía solo en la hoja antigua de formación, que la mayoría de páginas no cargaba, así que
   el menú móvil global no lo tenía. */
.no-scroll { overflow: hidden; }

/* ============================================================================
   MENÚ MÓVIL
   .mobile-menu es el overlay. El panel es .mobile-menu-panel.
   ============================================================================ */

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: rgb(15 15 17 / .45);
}

.mobile-menu-panel {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  display: flex;
  flex-direction: column;
  inline-size: 88%;
  max-inline-size: 380px;
  background: var(--x-surface);
  border-inline-start: 1px solid var(--x-line);
  transform: translateX(102%);
  transition: transform var(--dur-slow) var(--ease-standard);
}

.mobile-menu.is-open .mobile-menu-panel { transform: translateX(0); }

.mobile-menu-panel a:focus-visible,
.mobile-menu-panel button:focus-visible { outline-offset: -2px; }

/* --- Cabecera del panel ------------------------------------------------------ */
.mobile-menu-user {
  display: flex;
  align-items: center;
  gap: 12px;
  min-block-size: var(--header-h);
  padding: 12px 16px;
  border-bottom: 1px solid var(--x-line);
  flex: none;
}

.mobile-menu-user--guest p {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--x-ink-2);
  line-height: 1.4;
}

.mobile-menu-avatar {
  flex: none;
  inline-size: 40px;
  block-size: 40px;
  border-radius: 50%;
  border: 1px solid var(--x-line-2);
  overflow: hidden;
}

.mobile-menu-avatar img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.mobile-menu-user-info { display: flex; flex-direction: column; gap: 1px; min-inline-size: 0; }

.mobile-menu-user-name {
  font-stretch: 104%;
  font-size: 16px;
  font-weight: 650;
  color: var(--x-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mobile-menu-user-email {
  font-size: 13px;
  color: var(--x-ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mobile-menu-close {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  flex: none;
  padding: 0;
  border: 1px solid var(--x-line-2);
  border-radius: var(--x-r);
  background: none;
  color: var(--x-ink);
  cursor: pointer;
  transition: border-color 150ms ease;
}

.mobile-menu-close:hover { border-color: var(--x-ink); }
.mobile-menu-close svg { inline-size: 20px; block-size: 20px; }

/* --- Zona con scroll ---------------------------------------------------------- */
.mobile-menu-scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.mobile-menu-scroll-sections {
  display: flex;
  flex-direction: column;
  padding-block: 4px;
}

.mobile-menu-section + .mobile-menu-section { border-top: 1px solid var(--x-line); }

/* Rótulo de grupo: el mismo que las cabeceras de tabla (condensado, versales). */
.mobile-menu-section-label {
  padding: 14px 16px 4px;
  font-stretch: 78%;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--x-ink-3);
}

.mobile-menu-group { display: flex; flex-direction: column; padding-bottom: 6px; }

/* --- Filas -------------------------------------------------------------------- */
.mobile-menu-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  min-block-size: 46px;
  color: var(--x-ink);
  text-decoration: none;
  font-size: 15.5px;
  transition: background-color 150ms ease;
}

.mobile-menu-row:hover { background: var(--x-paper); }

/* Icono de la fila (no la flecha). No vale :first-child: en la fila del tema
   el primero es la luna, que va oculta en modo oscuro, y el sol quedaba sin
   tamaño ni color. */
.mobile-menu-row > svg:not(.mobile-menu-row-arrow) {
  flex: none;
  inline-size: 20px;
  block-size: 20px;
  color: var(--x-ink-3);
}

.mobile-menu-row span { flex: 1; min-inline-size: 0; }

/* Activo: filete de tinta a la izquierda, mismo gesto que la cabecera. */
.mobile-menu-row.is-active { font-weight: 650; }

.mobile-menu-row.is-active::before {
  content: "";
  position: absolute;
  inset-block: 8px;
  inset-inline-start: 0;
  inline-size: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--x-ink);
}

.mobile-menu-row.is-active > svg:not(.mobile-menu-row-arrow) { color: var(--x-ink); }

.mobile-menu-row-arrow { flex: none; inline-size: 14px; block-size: 14px; color: var(--x-ink-3); }

/* --- Variantes de fila --------------------------------------------------------- */
.mobile-menu-row--danger { color: var(--x-ink-2); }
.mobile-menu-row--signup { font-weight: 650; }

/* Filas que no navegan (tema, idioma): sin cursor de enlace ni flecha. */
.mobile-menu-row--lang { inline-size: 100%; text-align: start; font-family: inherit; }
button.mobile-menu-row--lang { border: 0; background: none; cursor: pointer; }

/* --- Selector de idioma --------------------------------------------------------- */
.mobile-menu-lang-pills { display: flex; gap: 6px; margin-inline-start: auto; }

.mobile-menu-lang-pill {
  padding: 5px 11px;
  border: 1px solid var(--x-line-2);
  border-radius: 999px;
  background: var(--x-surface);
  color: var(--x-ink);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}

.mobile-menu-lang-pill:hover { border-color: var(--x-ink); }

.mobile-menu-lang-pill.is-active {
  background: var(--x-ink);
  border-color: var(--x-ink);
  color: var(--x-paper);
}

/* --- Pie del panel, siempre visible ---------------------------------------------- */
.mobile-menu-footer {
  flex: none;
  padding-block: 4px calc(4px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--x-line);
}

/* ============================================================================
   PIE
   ============================================================================ */

.site-footer {
  border-top: 1px solid var(--x-line);
  background: var(--x-surface);
  font-size: 14.5px;
}

.footer-container {
  inline-size: 100%;
  max-inline-size: 1200px;
  margin-inline: auto;
  padding-inline: max(16px, env(safe-area-inset-left, 0px)) max(16px, env(safe-area-inset-right, 0px));
}

.footer-top { padding-block: 48px 40px; }

.footer-top .footer-container {
  display: grid;
  gap: 32px;
}

.footer-brand-link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--x-ink);
  text-decoration: none;
}

.footer-isotipo-svg { inline-size: 26px; block-size: 26px; }

.footer-logotipo {
  font-family: var(--x-font);
  font-stretch: 104%;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.015em;
}

.footer-brand p {
  margin-top: 12px;
  max-inline-size: 44ch;
  line-height: 1.55;
  color: var(--x-ink-2);
}

.footer-column { display: flex; flex-direction: column; gap: 12px; }

.footer-column h3,
.footer-social-title {
  font-family: var(--x-font);
  font-stretch: 78%;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--x-ink-3);
}

.footer-nav ul {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.footer-nav a {
  line-height: 1.4;
  color: var(--x-ink-2);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
}

.footer-nav a:hover { color: var(--x-ink); text-decoration-color: currentColor; }

/* --- Callout de Google Preferred Sources ---------------------------------------- */
.foot-pref { margin-top: 24px; }

.foot-pref__label {
  display: block;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--x-ink-2);
}

/* --- Barra inferior --------------------------------------------------------------- */
.footer-bottom { border-top: 1px solid var(--x-line); }

.footer-bottom-inner {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-block: 20px calc(20px + env(safe-area-inset-bottom, 0px));
}

.footer-legal {
  font-style: normal;
  font-size: 13px;
  line-height: 1.5;
  color: var(--x-ink-3);
  max-inline-size: 60ch;
}

.footer-social { display: flex; align-items: center; gap: 12px; }

.footer-social-list { display: flex; gap: 4px; margin: 0; padding: 0; list-style: none; }

.footer-social-list a {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 36px;
  block-size: 36px;
  border: 1px solid transparent;
  border-radius: var(--x-r);
  color: var(--x-ink-2);
  transition: border-color 150ms ease;
}

.footer-social-list a:hover { color: var(--x-ink); border-color: var(--x-line-2); }

.footer-social-list svg { inline-size: 19px; block-size: 19px; }

/* ============================================================================
   PUNTOS DE RUPTURA DEL CHROME
   ============================================================================ */

@media (min-width: 768px) {
  /* La marca ocupa el espacio sobrante y las dos columnas de enlaces se
     agrupan a la derecha ajustadas a su contenido. */
  .footer-top .footer-container {
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 64px;
  }
  .footer-nav { min-inline-size: 150px; }
  .footer-bottom-inner { flex-direction: row; align-items: center; justify-content: space-between; }
}

@media (min-width: 1024px) {
  .navbar-menu,
  .navbar-auth,
  .navbar-user-controls { display: flex; }
  .navbar-toggle { display: none; }
}

/* ============================================================================
   MOTION REDUCIDO
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  .navbar-link,
  .mobile-menu-panel,
  .navbar-avatar,
  .navbar-theme-toggle,
  .navbar-notifications,
  .navbar-login,
  .navbar-toggle,
  .mobile-menu-row,
  .mobile-menu-close,
  .mobile-menu-lang-pill,
  .footer-social-list a { transition: none; }
}
.ad-container {
  width: 100%;
  overflow: hidden;
  margin: 2rem 0;
  min-height: 100px;
}
.ad-container--inarticle {
  margin: 2.5rem 0;
}
.ad-container--end {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--color-border, #e5e7eb);
}

/* ── Avisos (Django contrib.messages) — sistema nuevo, 29-10-2026 ──────────
   Flotan bajo la cabecera (position: fixed, no desplazan el contenido).
   Blanco con borde y un filete de color a la izquierda según el tipo:
   verde si salió bien, ámbar si es un aviso o un error, gris si es
   información. main.js los cierra a los 4 s o al pulsar, y espera al
   animationend de .flash-hiding para quitarlos: por eso la salida es una
   animación (un fundido corto) y no una transición, también con movimiento
   reducido. */
.flash-messages {
  position: fixed;
  top: calc(var(--header-h) + 12px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: max-content;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}
@media (min-width: 640px) { .flash-messages { max-width: 480px; } }

.flash-messages__item {
  padding: 11px 16px 11px 14px;
  border: 1px solid var(--x-line-2);
  border-left: 3px solid var(--x-ink-3);
  border-radius: var(--x-r);
  background: var(--x-surface);
  box-shadow: 0 10px 30px rgb(20 20 22 / .12);
  font-family: var(--x-font);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--x-ink);
  pointer-events: auto;
  cursor: pointer;
  animation: flash-in 150ms ease both;
}
.flash-messages__item.flash-hiding { animation: flash-out 150ms ease both; }
@keyframes flash-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes flash-out { from { opacity: 1; } to { opacity: 0; } }

.flash-messages__item--success { border-left-color: var(--x-low); }
.flash-messages__item--warning,
.flash-messages__item--error { border-left-color: var(--x-high); }

/* Toggle de tema */
/* ========================
   REVEAL al hacer scroll (mejora progresiva)
   El contenido es visible por defecto; si el JS añade .js-reveal al <html>,
   los elementos .reveal entran con opacidad + desplazamiento.
   ======================== */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s cubic-bezier(.22, 1, .36, 1), transform .7s cubic-bezier(.22, 1, .36, 1);
}
.js-reveal .reveal.in {
  opacity: 1;
  transform: none;
}
.js-reveal .reveal.d1 { transition-delay: .07s; }
.js-reveal .reveal.d2 { transition-delay: .14s; }
.js-reveal .reveal.d3 { transition-delay: .21s; }
.js-reveal .reveal.d4 { transition-delay: .28s; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   Google Preferred Sources — callout (pie de artículo) + variante footer
   El botón es .pref-gbtn (aspecto de badge de Google); el flujo lo activa el
   JS de base.html (modo manual) para permitir varios botones por página.
   ========================================================================== */
.pref {
  margin: 34px 0;
  display: flex;
  gap: 18px;
  align-items: center;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 18px;
  padding: 20px 22px;
}
.pref__ic {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-sm);
}
.pref__ic svg { display: block; }
.pref__main { flex: 1; min-width: 0; }
.pref__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  color: var(--ink);
  line-height: 1.25;
}
.pref__text {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.55;
  margin-top: 4px;
}
.pref__cta { flex-shrink: 0; }

/* Botón "Fuente preferida" (aspecto de badge de Google; adapta claro/oscuro) */
.pref-gbtn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  border-radius: 20px;
  padding: 9px 16px 9px 12px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid #dadce0;
  background: #fff;
  color: #3c4043;
  transition: box-shadow .15s ease;
}
[data-theme="dark"] .pref-gbtn {
  background: #202124;
  color: #e8eaed;
  border-color: #5f6368;
}
.pref-gbtn:hover { box-shadow: 0 1px 3px rgba(60, 64, 67, .3); }
.pref-gbtn__g { width: 18px; height: 18px; flex-shrink: 0; }


@media (max-width: 640px) {
  .pref {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding: 18px;
  }
  .pref__cta { width: 100%; }
}

/* ===== css/components.css ===== */
/* ============================================================================
   SonidoenRed — COMPONENTES GLOBALES
   Se carga después de tokens.css y main.css, y antes del CSS de cada página.
   Todo lo de aquí es reutilizable en cualquier plantilla del sitio.
   ============================================================================ */

/* ============================================================================
   LAYOUT
   ============================================================================ */

/* Visible solo para lectores de pantalla. */
.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: var(--container-narrow); }
.container--wide { max-width: var(--container-wide); }

.section { padding-block: var(--section-y); }
.section--alt { background: var(--bg-alt); }
.section--tight { padding-block: calc(var(--section-y) * .6); }

/* Cabecera de sección: titular y entradilla apilados.
   Nada de "titular grande a la izquierda + párrafo pequeño flotando a la
   derecha": esa composición es puro relleno y descoloca la lectura. */
.section-head {
  max-width: 62ch;
  margin-bottom: var(--space-12);
}

.section-head__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-lg);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
}

.section-head__lead {
  margin-top: var(--space-4);
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  color: var(--ink-soft);
  max-width: 58ch;
}

/* ============================================================================
   EYEBROW
   Etiqueta de sección. Monoespaciada con un filete de acento delante: lenguaje
   de consola, no la píldora morada con puntito latiendo de antes.
   Presupuesto: como mucho una por cada tres secciones.
   ============================================================================ */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--space-4);
}

.eyebrow::before {
  content: "";
  inline-size: 24px;
  block-size: 2px;
  background: var(--accent);
  flex: none;
}

/* ============================================================================
   CIFRAS
   El dato es el producto en esta web: siempre monoespaciado y tabular para que
   las columnas de precios y contadores cuadren verticalmente.
   ============================================================================ */

.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -.01em;
}

/* ============================================================================
   BOTONES
   .btn-primary / .btn-secondary se mantienen como alias porque los usan 8
   sitios en 5 plantillas, tres de las cuales no cargaban ninguna hoja que los
   definiera (estaban sin estilo). Al vivir aquí, quedan arreglados solos.
   ============================================================================ */

.btn,
.btn-primary,
.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  letter-spacing: var(--ls-tight);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.btn svg,
.btn-primary svg,
.btn-secondary svg {
  inline-size: 18px;
  block-size: 18px;
  flex: none;
}

/* --- Primario -------------------------------------------------------------
   En oscuro el texto pasa a casi negro (--accent-contrast): blanco sobre el
   morado claro solo daría 3.4:1 y no llegaría a AA. */
.btn--primary,
.btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: var(--shadow-accent-sm);
}

.btn--primary:hover,
.btn-primary:hover {
  background: var(--accent-strong);
  transform: translateY(-2px);
  box-shadow: var(--shadow-accent-md);
}

/* --- Secundario ------------------------------------------------------------ */
.btn--secondary,
.btn-secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}

.btn--secondary:hover,
.btn-secondary:hover {
  border-color: var(--accent-border);
  color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

/* --- Ghost ----------------------------------------------------------------- */
.btn--ghost {
  background: transparent;
  color: var(--ink-soft);
}

.btn--ghost:hover {
  background: var(--surface-2);
  color: var(--ink);
}

/* --- Peligro --------------------------------------------------------------- */
.btn--danger {
  background: var(--danger-soft);
  color: var(--danger);
  border-color: var(--danger-border);
}

.btn--danger:hover {
  background: var(--danger);
  color: var(--danger-contrast);
  border-color: var(--danger);
}

/* --- Tamaños --------------------------------------------------------------- */
.btn--sm { padding: 9px 16px; font-size: var(--fs-sm); }
.btn--lg { padding: 16px 28px; font-size: var(--fs-md); }
.btn--block { display: flex; inline-size: 100%; }

/* --- Estados --------------------------------------------------------------- */
.btn:active,
.btn-primary:active,
.btn-secondary:active { transform: translateY(0) scale(.98); }

.btn:disabled,
.btn[aria-disabled="true"],
.btn-primary:disabled,
.btn-secondary:disabled {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ============================================================================
   TARJETA
   ============================================================================ */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  transition:
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

.card--pad { padding: var(--space-6); }

.card--link:hover {
  transform: translateY(-4px);
  border-color: var(--accent-border);
  box-shadow: var(--shadow-lg);
}

.card--link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

/* ============================================================================
   BADGE / CHIP
   ============================================================================ */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: .06em;
  text-transform: uppercase;
  background: var(--surface-3);
  color: var(--ink-soft);
  border: 1px solid var(--border);
}

.badge--accent {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-border);
}

.badge--success {
  background: var(--success-soft);
  color: var(--success);
  border-color: var(--success-border);
}

/* ============================================================================
   FORMULARIOS
   Etiqueta ARRIBA del campo, ayuda opcional, error DEBAJO. Nunca placeholder
   como etiqueta.
   ============================================================================ */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.field__label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
}

.input,
.textarea,
.select {
  inline-size: 100%;
  padding: 12px 14px;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

/* --ink-soft, no --ink-faint: el placeholder tiene que pasar AA (7.7:1). */
.input::placeholder,
.textarea::placeholder { color: var(--ink-soft); opacity: 1; }

.input:focus-visible,
.textarea:focus-visible,
.select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / .18);
}

.input[aria-invalid="true"],
.textarea[aria-invalid="true"] { border-color: var(--danger); }

.field__help { font-size: var(--fs-xs); color: var(--ink-soft); }
.field__error { font-size: var(--fs-xs); color: var(--danger); font-weight: var(--fw-medium); }

/* --- Checkbox --------------------------------------------------------------- */
.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--ink-soft);
  cursor: pointer;
}

.checkbox input[type="checkbox"] {
  appearance: none;
  flex: none;
  inline-size: 18px;
  block-size: 18px;
  margin-top: 1px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  background: var(--surface);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

.checkbox input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: var(--accent);
  /* Tick dibujado con mask para que herede el color del acento en ambos temas */
  -webkit-mask: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 5'/%3E%3C/svg%3E");
  background-size: 14px;
  background-position: center;
  background-repeat: no-repeat;
}

.checkbox input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.checkbox a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }

/* --- Honeypot ---------------------------------------------------------------
   clip a propósito en vez de display:none: los bots ignoran los campos ocultos
   con display:none, pero rellenan este. */
.honeypot {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================================
   NEWSLETTER
   Componente global: lo usan la home y el índice de formación. Antes vivía en
   la hoja de la landing, lo que obligaba a formación a importarla entera.
   ============================================================================ */

.newsletter {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  padding: clamp(28px, 5vw, 56px);
  box-shadow: var(--shadow-sm);
}

.newsletter__head { max-width: 52ch; }

.newsletter__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
}

.newsletter__lead {
  margin-top: var(--space-3);
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  color: var(--ink-soft);
}

.newsletter__form { margin-top: var(--space-8); }

.newsletter__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 520px;
}

.newsletter__msg {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}

/* El color lo ponen los tokens, no el JS: antes venía hardcodeado en el
   handler AJAX con los verdes y rojos del modo claro. */
.newsletter__msg.is-ok { color: var(--success); }
.newsletter__msg.is-error { color: var(--danger); }

.newsletter__consent { margin-top: var(--space-4); max-width: 52ch; }

@media (min-width: 640px) {
  .newsletter__row { flex-direction: row; align-items: center; }
  .newsletter__row .input { flex: 1; }
}

/* ============================================================================
   ESTADO VACÍO
   ============================================================================ */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-16) var(--space-6);
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-card);
  color: var(--ink-soft);
}

.empty-state__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

/* ============================================================================
   MOTION REDUCIDO
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn-primary,
  .btn-secondary,
  .card,
  .input,
  .textarea,
  .select,
  .checkbox input[type="checkbox"] {
    transition: none !important;
  }
  .btn:hover,
  .btn-primary:hover,
  .btn-secondary:hover,
  .btn:active,
  .btn-primary:active,
  .btn-secondary:active,
  .card--link:hover {
    transform: none !important;
  }
}

/* ============================================================================
   DIÁLOGO DE CONFIRMACIÓN
   Sustituye a window.confirm(). Es un overlay real, así que aquí sí procede
   --shadow-md; el resto de la web no lleva sombras.
   ============================================================================ */
.cdlg {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: min(420px, calc(100vw - 32px));
}
.cdlg::backdrop { background: rgba(12, 9, 19, .55); }

.cdlg__box {
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-md);
}

.cdlg__title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.cdlg__text { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }
.cdlg__actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }

/* La apertura es una acción del usuario, así que puede animarse. */
@media (prefers-reduced-motion: no-preference) {
  .cdlg[open] { animation: cdlg-in 160ms cubic-bezier(.22, 1, .36, 1); }
  @keyframes cdlg-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ===== css/cookie_banner.css ===== */
/* ============================================================================
   AVISO Y PREFERENCIAS DE COOKIES — sistema «mostrador técnico» (29-10-2026)
   Mantiene los IDs y clases que usa static/js/cookie_consent.js.

   - Barra fija abajo a todo el ancho, mismo ancho de contenido que la cabecera.
   - «Rechazar todo» y «Aceptar todo» con el mismo peso visual (guía de cookies
     de la AEPD: rechazar debe ser tan fácil y visible como aceptar). Por eso
     ninguno es morado; «Configurar» va como enlace.
   - Sin animación de entrada, sin desenfoque ni sombras de color.
   - Móvil primero; min-width 640 y 1024.
   ============================================================================ */

.srn-cookie-banner[hidden],
.srn-cookie-prefs[hidden] {
  display: none !important;
}

.srn-cookie-banner,
.srn-cookie-prefs {
  font-family: var(--x-font);
  color: var(--x-ink);
}

.srn-cookie-banner :focus-visible,
.srn-cookie-prefs :focus-visible {
  outline: 2px solid var(--x-accent);
  outline-offset: 2px;
}

/* ── Barra ─────────────────────────────────────────────────────────────── */
.srn-cookie-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 300;
  background: var(--x-surface);
  border-top: 1px solid var(--x-line-2);
  box-shadow: 0 -6px 24px rgb(20 20 22 / .08);
}

.srn-cookie-banner__inner {
  display: grid;
  gap: 14px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px max(16px, env(safe-area-inset-right, 0px)) calc(16px + env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px));
}

.srn-cookie-banner__content { min-width: 0; }

.srn-cookie-banner__title {
  margin: 0 0 4px;
  font-family: var(--x-font);
  font-stretch: 104%;
  font-size: 16px;
  font-weight: 650;
  line-height: 1.3;
  color: var(--x-ink);
}

.srn-cookie-banner__text {
  margin: 0;
  max-width: 78ch;
  font-size: 14px;
  line-height: 1.5;
  color: var(--x-ink-2);
}

.srn-cookie-banner__text a,
.srn-cookie-prefs a {
  color: var(--x-ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Móvil: Rechazar y Aceptar en dos columnas iguales; Configurar debajo. */
.srn-cookie-banner__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.srn-cookie-banner__actions .srn-cookie-btn--link {
  grid-column: 1 / -1;
  grid-row: 2;
}

/* ── Botones ───────────────────────────────────────────────────────────── */
.srn-cookie-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px;
  border: 1px solid transparent;
  border-radius: var(--x-r);
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease;
}

/* Sólido en tinta. --primary se mantiene como alias: lo usa la política de
   cookies (templates/core/cookie_policy.html). */
.srn-cookie-btn--solid,
.srn-cookie-btn--primary {
  background: var(--x-ink);
  color: var(--x-paper);
}

.srn-cookie-btn--solid:hover,
.srn-cookie-btn--primary:hover { background: color-mix(in srgb, var(--x-ink) 85%, var(--x-paper)); }

.srn-cookie-btn--ghost,
.srn-cookie-btn--secondary {
  background: var(--x-surface);
  color: var(--x-ink);
  border-color: var(--x-line-2);
}

.srn-cookie-btn--ghost:hover,
.srn-cookie-btn--secondary:hover { border-color: var(--x-ink); }

.srn-cookie-btn--link {
  padding-block: 6px;
  background: none;
  color: var(--x-ink-2);
  text-decoration: underline;
  text-decoration-color: var(--x-line-2);
  text-underline-offset: 3px;
}

.srn-cookie-btn--link:hover { color: var(--x-ink); text-decoration-color: currentColor; }

/* ── Preferencias (diálogo) ────────────────────────────────────────────── */
.srn-cookie-prefs {
  position: fixed;
  inset: 0;
  z-index: 350;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.srn-cookie-prefs__backdrop {
  position: absolute;
  inset: 0;
  background: rgb(15 15 17 / .45);
}

/* Móvil: hoja que sube desde abajo, a todo el ancho. */
.srn-cookie-prefs__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: 92vh;
  background: var(--x-surface);
  border: 1px solid var(--x-line-2);
  border-bottom: 0;
  border-radius: 14px 14px 0 0;
}

.srn-cookie-prefs__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  border-bottom: 1px solid var(--x-line);
}

.srn-cookie-prefs__header h2 {
  margin: 0;
  font-family: var(--x-font);
  font-stretch: 104%;
  font-size: 18px;
  font-weight: 650;
  color: var(--x-ink);
}

.srn-cookie-prefs__close {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--x-line-2);
  border-radius: var(--x-r);
  background: none;
  color: var(--x-ink);
  cursor: pointer;
  transition: border-color 150ms ease;
}

.srn-cookie-prefs__close:hover { border-color: var(--x-ink); }

.srn-cookie-prefs__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px;
}

.srn-cookie-prefs__intro {
  margin: 0 0 4px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--x-ink-2);
}

/* Categorías como filas separadas por línea, no como tarjetas. */
.srn-cookie-cat {
  padding-block: 16px;
  border-bottom: 1px solid var(--x-line);
}

.srn-cookie-cat:last-child { border-bottom: 0; padding-bottom: 0; }

.srn-cookie-cat__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.srn-cookie-cat__title {
  margin: 0;
  font-family: var(--x-font);
  font-size: 15px;
  font-weight: 650;
  color: var(--x-ink);
}

.srn-cookie-cat__title label { cursor: pointer; }

.srn-cookie-cat__pill {
  font-size: 13px;
  color: var(--x-ink-3);
  white-space: nowrap;
}

.srn-cookie-cat__desc {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--x-ink-2);
}

/* ── Interruptor ───────────────────────────────────────────────────────── */
.srn-cookie-switch { position: relative; display: inline-flex; align-items: center; gap: 9px; cursor: pointer; }
.srn-cookie-switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.srn-cookie-switch__slider {
  position: relative;
  flex: none;
  width: 40px;
  height: 24px;
  border-radius: 999px;
  background: var(--x-line-2);
  transition: background-color 150ms ease;
}

.srn-cookie-switch__slider::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--x-surface);
  transition: transform 150ms ease;
}

.srn-cookie-switch input:checked + .srn-cookie-switch__slider { background: var(--x-accent); }
.srn-cookie-switch input:checked + .srn-cookie-switch__slider::before { transform: translateX(16px); }
.srn-cookie-switch input:focus-visible + .srn-cookie-switch__slider { outline: 2px solid var(--x-accent); outline-offset: 2px; }

.srn-cookie-switch__text { font-size: 13px; font-weight: 600; color: var(--x-ink-2); }
.srn-cookie-switch__text--on { display: none; }
.srn-cookie-switch__text--off { display: inline; }
.srn-cookie-switch input:checked ~ .srn-cookie-switch__text--on { display: inline; }
.srn-cookie-switch input:checked ~ .srn-cookie-switch__text--off { display: none; }

/* Pie del diálogo: en móvil, Rechazar y Aceptar en dos columnas y Guardar
   (la acción de este diálogo) a todo el ancho encima. */
.srn-cookie-prefs__footer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--x-line);
}

.srn-cookie-prefs__footer .srn-cookie-btn--solid { grid-column: 1 / -1; grid-row: 1; }

/* ── Breakpoints ───────────────────────────────────────────────────────── */
@media (min-width: 640px) {
  .srn-cookie-prefs { align-items: center; padding: 24px; }
  .srn-cookie-prefs__panel {
    max-width: 560px;
    max-height: 88vh;
    border-bottom: 1px solid var(--x-line-2);
    border-radius: 12px;
    box-shadow: 0 10px 30px rgb(20 20 22 / .12);
  }
  .srn-cookie-prefs__header,
  .srn-cookie-prefs__body { padding-inline: 24px; }
  .srn-cookie-prefs__footer {
    display: flex;
    justify-content: flex-end;
    padding: 14px 24px;
  }
  .srn-cookie-prefs__footer .srn-cookie-btn--solid { order: 3; }
}

@media (min-width: 1024px) {
  /* Texto a la izquierda y botones a la derecha, en una sola franja. */
  .srn-cookie-banner__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 32px;
  }
  .srn-cookie-banner__actions {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .srn-cookie-banner__actions .srn-cookie-btn--link { order: -1; margin-right: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .srn-cookie-btn,
  .srn-cookie-prefs__close,
  .srn-cookie-switch__slider,
  .srn-cookie-switch__slider::before { transition: none; }
}
