/* Fulana News — layout */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  transition: background-color var(--duration-standard) var(--ease-standard),
    color var(--duration-standard) var(--ease-standard);
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-3);
  font-weight: 700;
}

h1 { font-size: var(--text-title1); line-height: var(--lh-title1); letter-spacing: var(--tracking-tight); }
h2 { font-size: var(--text-title2); line-height: var(--lh-title2); letter-spacing: var(--tracking-tight); }
h3 { font-size: var(--text-title3); line-height: var(--lh-title3); }
h4 { font-size: var(--text-headline); line-height: var(--lh-headline); }

p { margin: 0 0 var(--space-4); }

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.container {
  max-width: 1320px;
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (max-width: 767px) {
  .container { padding-inline: var(--space-4); }
}

/* ---------- Accesible pero invisible ----------
   Para texto que Google y los lectores de pantalla necesitan (ej. el <h1> del home,
   bloque 10) pero que NO debe competir visualmente con las tarjetas — el criterio de
   diseño del sitio es compacto tipo Polymarket, sin grandes títulos editoriales. */
.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;
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--color-accent);
  color: #fff;
  padding: var(--space-2) var(--space-4);
  z-index: 200;
}
.skip-link:focus { left: var(--space-4); top: var(--space-4); }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* Barra de transparencia de IA (2026-09-10): declara que las notas se reescriben con IA.
   Va DENTRO del header sticky, así que su alto SUMA al del header: el de desktop mide
   133px + estos 28px = 161px, y hay medidas calibradas a mano que lo asumen —
     - tokens.css      --header-clearance: 118px (y 56px en el breakpoint mobile)
     - layout.css      .sidebar `top: 161px` + `max-height: calc(100vh - 161px ...)`
     - components.css  .weather-page-aside `top: 176px`, .fin-nav `top: 124px`
     - components.css  .fin-block `scroll-margin-top: 118px`
   Si cambia `height` acá, todas esas se mueven en la misma cantidad.
   Negro fijo en los dos temas a propósito: es una banda de aviso, no superficie de marca
   (en oscuro el papel es #0b0e11 y el header #14181c, así que el #000 se sigue leyendo). */
.header-ia-notice {
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  color: #fff;
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.header-top {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: 44px;
  border-bottom: 1px solid var(--color-border);
  overflow: hidden;
}

.header-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-3);
}

.brand-logo { display: inline-flex; color: var(--color-ink); flex-shrink: 0; }
.brand-logo svg { height: 30px; width: auto; display: block; }

/* Logo de sección (encabezado de landing de sección) */
.section-logo { display: inline-flex; color: var(--color-ink); }
.section-logo svg { height: 34px; width: auto; display: block; }
@media (max-width: 767px) { .section-logo svg { height: 28px; } }

/* Con 12 secciones (reestructuración 2026-08) el nav ya no entra en una fila
   sin romper el header: los links envolvían su texto a 2-3 líneas ("Actualidad
   Internacional", "Autos y Motos") y estiraban .header-main, empujando
   .header-actions (buscar/tema/hamburger) fuera del viewport.
   Se probó scroll horizontal primero y se descartó (feedback de Mateo: no
   queda bien, prefiere algo más intuitivo) — mega-menu.js ya había reemplazado
   un patrón de scroll horizontal antes por el mismo motivo (ver su comentario
   de cabecera), así que no es la primera vez que se rechaza acá. En su lugar,
   "priority navigation": nav-overflow.js mide en cada carga/resize cuántas
   secciones entran en el ancho real disponible y empuja las que no entran
   (de derecha a izquierda, nunca la sección activa) a un trigger "Más" con
   dropdown animado — mismo lenguaje visual que el mega menu de categoría.
   .brand-logo/.header-actions quedan fijos a los costados (flex-shrink:0)
   sin importar cuántas secciones se agreguen en el futuro. */
.main-nav {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-5);
  font-weight: 600;
  font-size: var(--text-subhead);
  min-width: 0;
  /* overflow:hidden corta el dropdown de "Más" (nav-more-panel es position:absolute
     adentro de .main-nav). El JS de nav-overflow.js ya oculta los items que no
     entran con display:none, así que el overflow visual se maneja por script y no
     hace falta clippear. Un flash breve antes del recálculo de JS es preferible
     a un dropdown que no abre. */
  overflow: visible;
}

.main-nav a {
  position: relative;
  padding-block: var(--space-1);
  white-space: nowrap;
}
.main-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 100%;
  bottom: -2px;
  height: 2px;
  background: var(--categoria-color, var(--color-accent));
  transition: right var(--duration-fast) var(--ease-standard);
}
.main-nav a[aria-current="page"] { color: var(--categoria-color, var(--color-accent)); }
.main-nav a:hover::after,
.main-nav a[aria-current="page"]::after { right: 0; }

/* Mega menu de categoría: hover en desktop (con delay de cierre) sobre un solo
   panel compartido (.mega-menu-region) debajo de todo el header — el JS
   swapea el contenido según qué item se hovereó, así el cambio entre
   categorías es un crossfade en vez de cerrar+abrir. Ver mega-menu.js.
   En mobile/tablet este nav ni el panel se usan (sin mouse no hay hover) —
   el hamburger + drawer de más abajo cubre ese caso, reusando estas mismas
   clases (.mega-menu-panel/.mega-menu-grid/etc.) adentro del acordeón. */
.nav-item--mega { position: relative; display: flex; align-items: center; flex-shrink: 0; }

/* Trigger "Más" (nav-overflow.js) — oculto por default (display:none), JS lo
   muestra recién cuando hay secciones que no entraron. A propósito con
   display en vez de [hidden]: mezclar el atributo hidden con una regla de
   clase que también define display es el mismo bug ya documentado en este
   proyecto para el toggle de modo oscuro (el inline/atributo puede perder
   contra una regla de clase con igual especificidad según el orden de
   cascada) — más simple que nav-overflow.js controle todo por
   element.style.display y listo. */
.nav-item--more {
  display: none;
  position: relative;
  align-items: center;
  flex-shrink: 0;
}
.nav-more-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: none;
  border: none;
  font: inherit;
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  padding-block: var(--space-1);
}
.nav-more-chevron {
  width: 14px;
  height: 14px;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.nav-item--more.is-open .nav-more-chevron { transform: rotate(180deg); }

.nav-more-panel {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: var(--space-3);
  min-width: 200px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card-hover);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
  z-index: 20;
}
.nav-item--more.is-open .nav-more-panel {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.nav-more-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius-pill);
  font-weight: 600;
  font-size: var(--text-subhead);
  color: var(--color-ink);
  white-space: nowrap;
}
.nav-more-link:hover,
.nav-more-link[aria-current="page"] {
  background: color-mix(in srgb, var(--categoria-color, var(--color-accent)) 14%, transparent);
  color: var(--categoria-color, var(--color-accent));
}
/* Los links del desplegable "Más" son <a> dentro de .main-nav, así que heredaban la
   barrita ::after que el nav usa como subrayado de hover/activo. Acá el estado ya se
   marca con el fondo teñido, así que las dos cosas juntas se leían como dos indicadores
   distintos del mismo estado. Se saca solo la barrita; el fondo queda.
   El selector lleva dos clases a propósito: `.nav-more-link::after` (0,1,0) pierde en
   especificidad contra `.main-nav a::after` (0,1,1) y la barrita seguiría apareciendo. */
.main-nav .nav-more-link::after { content: none; }
.nav-more-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--categoria-color, var(--color-accent));
}

.mega-menu-region {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  pointer-events: none;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-card-hover);
  transition: max-height var(--duration-standard) ease-in,
    opacity var(--duration-standard) ease-in;
  z-index: 10;
}
.mega-menu-region.is-open {
  max-height: var(--mega-height, 600px);
  opacity: 1;
  pointer-events: auto;
  transition: max-height var(--duration-standard) ease-out,
    opacity var(--duration-standard) ease-out;
}

.mega-menu-inner { position: relative; padding-block: var(--space-6); }
.mega-menu-content { transition: opacity 120ms var(--ease-standard); }
.mega-menu-content.is-swapping { opacity: 0; }

.mega-menu-panel { display: flex; gap: var(--space-6); }
.mega-menu-main { flex: 1; min-width: 0; }

.mega-menu-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}
.mega-menu-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-title3);
  font-weight: 700;
}
.mega-menu-title::before {
  content: "";
  width: 4px;
  height: 1.1em;
  border-radius: var(--radius-pill);
  background: var(--categoria-color, var(--color-accent));
}
.mega-menu-viewall {
  font-size: var(--text-subhead);
  font-weight: 600;
  color: var(--categoria-color, var(--color-accent));
  white-space: nowrap;
}
.mega-menu-viewall:hover { text-decoration: underline; }

.mega-menu-subs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.mega-menu-subs a {
  padding: 0.25rem 0.75rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-2);
  font-size: var(--text-footnote);
  font-weight: 600;
}
.mega-menu-subs a:hover {
  background: color-mix(in srgb, var(--categoria-color, var(--color-accent)) 14%, var(--color-surface-2));
  color: var(--categoria-color, var(--color-accent));
}

.mega-menu-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }

.mega-item { position: relative; display: flex; gap: var(--space-3); }
.mega-item-thumb {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-surface-2);
  flex-shrink: 0;
}
.mega-item-thumb img { width: 100%; height: 100%; object-fit: cover; }
.mega-item-body { min-width: 0; }
.mega-item-title {
  font-size: var(--text-subhead);
  line-height: var(--lh-subhead);
  font-weight: 600;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mega-item-title a::after { content: ""; position: absolute; inset: 0; }
.mega-item-excerpt {
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  color: var(--color-ink-muted);
  margin-top: 0.25rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mega-item-skeleton .mega-item-thumb,
.mega-skel-line {
  background: var(--color-surface-2);
  border-radius: var(--radius-sm);
  animation: mega-skel-pulse 1.1s ease-in-out infinite;
}
.mega-skel-line { display: block; height: 0.75rem; margin-top: var(--space-2); }
.mega-skel-line:first-child { margin-top: 0.15rem; }
@keyframes mega-skel-pulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

.mega-menu-empty {
  color: var(--color-ink-muted);
  font-size: var(--text-subhead);
  padding-block: var(--space-4);
}

.mega-menu-aside { flex: 0 0 300px; }

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-shrink: 0;
}

@media (max-width: 1023px) {
  .header-top { display: none; }

  /* El nav horizontal con scroll queda solo para desktop — en mobile lo
     reemplaza el hamburger + drawer de abajo (pedido explícito del cliente:
     con scroll horizontal mucha gente no lo encuentra). */
  .main-nav { display: none; }

  /* El header sin ticker/nav mide ~61px acá (vs. 133px en desktop) — el
     mismo --header-clearance de 90px pensado para despejar el header grande
     dejaba ~150px de blanco antes del primer contenido. Suma 28px la barra de IA
     del header (ver .header-ia-notice). */
  :root { --header-clearance: 56px; }
}

/* Los touch targets (icon-btn, nav-hamburger, mobile-drawer-close,
   mobile-nav-expand) se llevan a 44×44 en components.css, no acá — sus
   reglas base viven repartidas entre este archivo y components.css, que
   carga después; un override en layout.css pierde el empate de
   especificidad contra cualquier base declarada más abajo en components.css.
   Ver el bloque final de components.css. */

/* Estas 4 reglas son las mismas que ya usa el panel de desktop
   (.mega-menu-panel/.mega-menu-grid/etc.) — el acordeón del drawer mobile
   inyecta el mismo HTML (ver panelHtml() en mega-menu.js) adentro de
   .mobile-nav-panel-inner, así que hereda este tratamiento en 1 columna
   sin necesitar reglas nuevas. */
@media (max-width: 1023px) {
  .mega-menu-panel { flex-direction: column; }
  .mega-menu-grid { grid-template-columns: 1fr; }
  .mega-menu-aside { flex: none; }
  .mega-menu-aside .ad-slot { margin-inline: auto; }
}

/* ---------- Nav mobile: hamburger + drawer con el mega menu como acordeón ----------
   Especificidad ".header-actions .nav-hamburger" a propósito: components.css se
   carga después de layout.css en el <head>, y ".icon-btn { display: inline-flex }"
   (misma especificidad que un ".nav-hamburger" solo) ganaría por orden de cascada
   y mostraría el botón también en desktop. */
.header-actions .nav-hamburger { display: none; }
.header-actions .header-search-mobile { display: none; }

@media (max-width: 1023px) {
  .header-actions .nav-hamburger { display: inline-flex; }
}

/* ≤767px: la bottom-tabbar de más abajo reemplaza al hamburger (su tab
   "Categorías" abre el mismo drawer) y a Buscar le toca el único ícono que
   queda arriba, al lado del logo — ver rediseño mobile v2. En 768-1023px
   (tablet) no cambia nada: sigue el hamburger + drawer lateral de siempre. */
@media (max-width: 767px) {
  .header-actions .nav-hamburger { display: none; }
  .header-actions .header-search-mobile { display: inline-flex; }
}

body.nav-drawer-open { overflow: hidden; }

.mobile-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-standard) var(--ease-standard),
    visibility 0s linear var(--duration-standard);
  z-index: 160;
}
.mobile-drawer-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--duration-standard) var(--ease-standard),
    visibility 0s linear 0s;
}

.mobile-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(88vw, 380px);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  box-shadow: var(--shadow-card-hover);
  transform: translateX(-100%);
  transition: transform var(--duration-standard) var(--ease-standard);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  z-index: 170;
}
.mobile-drawer.is-open { transform: translateX(0); }

@media (min-width: 1024px) {
  .mobile-drawer,
  .mobile-drawer-backdrop { display: none !important; }
}

/* ≤767px: el mismo drawer pasa de deslizar desde la izquierda a deslizar
   desde abajo (bottom sheet), acorde a la bottom-tabbar que lo dispara acá
   (tab "Categorías") — en 768-1023px sigue siendo el drawer lateral de
   siempre, sin tocar. El acordeón/auto-preview/barra de color de adentro no
   cambian, solo el eje del contenedor padre. */
@media (max-width: 767px) {
  .mobile-drawer {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: 85vh;
    border-top-left-radius: var(--radius-card);
    border-top-right-radius: var(--radius-card);
    transform: translateY(100%);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .mobile-drawer.is-open { transform: translateY(0); }
}

.mobile-drawer-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.mobile-drawer-title { font-weight: 700; font-size: var(--text-title3); }
.mobile-drawer-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-ink);
  cursor: pointer;
}
.mobile-drawer-close svg { width: 16px; height: 16px; }

.mobile-drawer-nav {
  display: flex;
  flex-direction: column;
  padding: var(--space-2) var(--space-5) var(--space-6);
}

.mobile-nav-link {
  display: block;
  padding: var(--space-3) 0;
  font-weight: 600;
  font-size: var(--text-body);
}
.mobile-nav-link[aria-current="page"] { color: var(--categoria-color, var(--color-accent)); }

.mobile-nav-item {
  position: relative;
  border-bottom: 1px solid var(--color-border);
}
.mobile-nav-item .mobile-nav-link { flex: 1; min-width: 0; }
.mobile-nav-row {
  display: flex;
  align-items: center;
  padding-left: var(--space-3);
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.mobile-nav-row:active {
  background: color-mix(in srgb, var(--categoria-color, var(--color-accent)) 10%, transparent);
}

/* Barra de color por categoría — mismo patrón que .section-title::before /
   .mega-menu-title::before, para que el drawer cerrado ya insinúe que cada
   fila tiene su propia identidad en vez de ser un menú de texto plano. */
.mobile-nav-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 1.4em;
  border-radius: var(--radius-pill);
  background: var(--categoria-color, var(--color-accent));
}

.mobile-nav-expand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  margin-inline: var(--space-2);
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--categoria-color, var(--color-accent)) 14%, transparent);
  color: var(--categoria-color, var(--color-accent));
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-standard);
}
.mobile-nav-expand:active {
  background: color-mix(in srgb, var(--categoria-color, var(--color-accent)) 24%, transparent);
}
.mobile-nav-expand svg {
  width: 18px;
  height: 18px;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.mobile-nav-expand[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Acordeón sin medir alto por JS: el truco grid-template-rows 0fr→1fr anima
   a "auto" con solo CSS (necesita el wrapper interno con overflow:hidden). */
.mobile-nav-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-standard) var(--ease-standard);
}
.mobile-nav-panel.is-open { grid-template-rows: 1fr; }
.mobile-nav-panel-inner { overflow: hidden; min-height: 0; }
.mobile-nav-panel-inner .mega-menu-panel { padding-block: 0 var(--space-5); }
.mobile-nav-panel-inner .mega-menu-header { margin-bottom: var(--space-3); }

/* ---------- Bottom tab bar (rediseño mobile v2) ----------
   Solo ≤767px — en tablet/desktop no existe, ahí sigue el hamburger de
   siempre. 4 accesos reales: Inicio, Categorías (abre el drawer de arriba
   como bottom sheet), Radio (el mini-player de siempre, reposicionado acá —
   override en components.css, después de sus reglas base) y Buscar. */
.bottom-tabbar { display: none; }

@media (max-width: 767px) {
  .bottom-tabbar {
    display: flex;
    align-items: stretch;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* safe-area-inset-bottom se suma mediante padding interno, no margen:
       así la barra llega hasta el borde físico del dispositivo y el contenido
       interno se mantiene legible en iPhone con home indicator. */
    padding: var(--space-2) var(--space-4) calc(var(--space-2) + env(safe-area-inset-bottom));
    z-index: 150;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 12px rgb(0 0 0 / 0.06);
    border-radius: 0;
    transition: transform var(--duration-standard) var(--ease-standard);
  }
  /* Auto-hide: se oculta al scrollear hacia abajo, vuelve al scrollear hacia arriba.
     La clase la agrega/quitá bottom-tabbar.js observando el scroll de window. */
  .bottom-tabbar.is-hidden {
    transform: translateY(100%);
  }
  body.nav-drawer-open .bottom-tabbar {
    transform: translateY(100%);
  }
}

.bottom-tab,
.bottom-tab-radio-slot {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: var(--space-1) var(--space-2);
  border: none;
  background: none;
  color: var(--color-ink-muted);
  border-radius: 0;
  cursor: pointer;
  outline: none;
  transition: color var(--duration-fast) var(--ease-standard);
}
.bottom-tab-radio-slot { position: relative; }
.bottom-tab svg { width: 22px; height: 22px; flex-shrink: 0; }
.bottom-tab span {
  display: block;
  font-size: 10px;
  font-weight: 700;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard);
}
.bottom-tab[aria-current="page"],
.bottom-tab[aria-expanded="true"] {
  color: var(--tab-color, var(--color-accent));
}
.bottom-tab[aria-current="page"] span,
.bottom-tab[aria-expanded="true"] span {
  max-height: 14px;
  opacity: 1;
}
.bottom-tab:active { transform: scale(0.94); }


/* ---------- Desktop/tablet: el mini-player de radio vuelve a ser flotante ----------
   El rediseño mobile v2 movió el reproductor a la bottom-tabbar (≤767px), pero
   como esa barra estaba display:none en el resto de los anchos, en desktop/tablet
   el reproductor quedó sin aparecer. El markup sigue siendo el mismo (única
   instancia, dentro de .bottom-tabbar): acá no lo duplicamos — convertimos la
   barra en un wrapper invisible (nav de altura 0, tabs ocultas) y dejamos que
   .mini-player use su regla base de components.css (position:fixed, pastilla
   flotante abajo a la derecha). En ≤767px sigue mandando la media query de
   arriba, que restaura display:flex. */
@media (min-width: 768px) {
  .bottom-tabbar { display: block; }
  .bottom-tab { display: none; }
  .bottom-tab-radio-slot { display: contents; }
}

/* ---------- Hero principal: 2 columnas grandes + tercera compacta ----------
   Nombres internos (usar estos nombres para referenciar las cards del hero en
   conversaciones/notas):
   - "Hero Grande"  → las 2 cards grandes (clases `.card-hero-grande`), dentro de `.hero-main`.
   - "Hero Compactas" → la 3ª columna con las noticias chiquitas (clase `.card-hero-chica`), dentro de `.hero-aside`.
   - "Hero Grid" → el contenedor completo (`.hero-grid`).
   Desktop: el hero es un grid de 2 zonas — .hero-main (destacada + segunda,
   lado a lado, imagen arriba en ambas) y .hero-aside (las noticias chiquitas
   en columna compacta, con separación propia y chica). En tablet el aside pasa
   a 2 columnas; en mobile el hero sigue siendo el carrusel de siempre y los
   wrappers se vuelven display:contents para que las cards sigan siendo slides. */
.hero-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
  padding-block: var(--space-6);
}

.hero-main {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
}

.hero-aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

@media (max-width: 1023px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-main { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-aside { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
  /* "Breaking News": el hero pasa de grid apilado a carrusel horizontal —
     destacada + secundarias son ahora slides del mismo carrusel (estilo de
     tarjeta unificado en components.css), no un hero grande + una lista
     debajo. Mismo patrón scroll-snap que ya usa .carousel-track (ver "Seguir
     leyendo" más abajo en este archivo) — sin JS para el swipe en sí; los
     puntos de paginación sí llevan JS (hero-carousel.js). */
  .hero-grid {
    display: flex;
    grid-template-columns: none;
    gap: var(--space-3);
    padding-block: var(--space-4) 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .hero-grid::-webkit-scrollbar { display: none; }
  /* Los wrappers de desktop desaparecen del layout: sus cards pasan a ser
     los ítems directos del carrusel. */
  .hero-main,
  .hero-aside { display: contents; }
  .hero-grid .card {
    flex: 0 0 86%;
    scroll-snap-align: start;
    /* .card trae will-change:transform para el hover-lift de escritorio —
       acá, dentro de un contenedor con scroll horizontal, esa capa de
       composición de más es justo el disparador típico de un bug conocido
       de WebKit/iOS: la imagen de fondo (position:absolute) de la card
       siguiente queda invisible al hacer swipe hacia ella y solo reaparece
       si se repinta la capa (por eso "se arregla" al volver). Sin
       will-change acá, mobile no tiene hover real de todos modos. */
    will-change: auto;
  }
  .hero-grid .card-featured { grid-column: unset; grid-row: unset; }
  /* Las slides del carrusel (grandes y compactas) mantienen el mismo tamaño 3/4:
     el stretch del flex las iguala y el carrusel queda parejo. */
}


/* Puntos de paginación del carrusel hero — armados por hero-carousel.js
   contando los hijos de .hero-grid, ningún dato nuevo por PHP. Solo tienen
   sentido con .hero-grid en modo carrusel — hero-carousel.js ya evita
   insertarlos fuera de ≤767px, pero el display:none acá es un resguardo
   extra por si algo queda en el DOM al cruzar el breakpoint sin recargar. */
.hero-carousel-dots { display: none; }

@media (max-width: 767px) {
  .hero-carousel-dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding-top: 5px;
    padding-bottom: var(--space-4);
  }
  .hero-carousel-dot {
    box-sizing: content-box;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-border);
    padding: 4px;
    margin: 0;
    border: none;
    cursor: pointer;
    background-clip: content-box;
    transition: width var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard);
  }
  .hero-carousel-dot.is-active {
    width: 16px;
    border-radius: var(--radius-pill);
    background: var(--color-accent);
  }
}

.empty-state {
  padding-block: var(--space-8);
  text-align: center;
  color: var(--color-ink-muted);
}

/* ---------- Markets strip (teaser de finanzas en el home) ---------- */
.markets-strip {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.markets-strip-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: 700;
  font-size: var(--text-subhead);
  white-space: nowrap;
  color: var(--color-finances);
}
.markets-strip-title svg { width: 14px; height: 14px; }
.markets-strip-items {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  font-variant-numeric: tabular-nums;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none; /* el scrollbar nativo flotante tapa la fila, es angosta */
}
.markets-strip-items::-webkit-scrollbar { display: none; }
.market-mini {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
  font-size: var(--text-footnote);
}
.market-mini-name { color: var(--color-ink-muted); }
.market-mini-value { font-weight: 600; }

@media (max-width: 767px) {
  .markets-strip { flex-direction: column; align-items: stretch; gap: var(--space-2); }
}

/* ---------- Section headings de marca ---------- */
.home-section { margin-bottom: var(--space-7); }
.section-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.section-title::before {
  content: "";
  width: 4px;
  height: 1.1em;
  border-radius: var(--radius-pill);
  background: var(--categoria-color, var(--color-accent));
}
/* El título de la sección linkea a la categoría (además del "Ver todo" de la derecha):
   hereda el color del heading en vez de tomar el color de link global, y el subrayado
   aparece recién en hover para que no parezca un link suelto. */
.section-title a { color: inherit; text-decoration: none; }
.section-title a:hover { text-decoration: underline; }
.section-link {
  font-size: var(--text-subhead);
  font-weight: 600;
  color: var(--categoria-color, var(--color-accent));
}
.section-link:hover { text-decoration: underline; }

/* ---------- Page layout: contenido + sidebar sticky ---------- */
.page-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--space-7);
  align-items: start;
  padding-block: var(--space-6);
}
.page-layout--single { grid-template-columns: minmax(0, 760px); justify-content: center; }

/* Página propia de Fórmula 1 (/formula-1/): es una landing de datos, no una nota,
   así que usa el ancho completo del sitio en vez de la columna de lectura de
   760 px. Las piezas se reparten adentro con la grilla de 12 columnas .f1-grid
   (ver el bloque ANCLA-F1-PAGINA en components.css). */
.page-layout--wide { grid-template-columns: minmax(0, 1280px); justify-content: center; }

.sidebar {
  position: sticky;
  top: 161px; /* header real: 44px (ticker) + 72px (nav) + 28px (barra IA) + margen — ver .header-ia-notice */
  /* Sin esto, una sidebar más alta que el viewport (desde que sumamos el
     ad de 300×600, ver ad_slot('...', 'skyscraper')) queda "pegada" arriba
     y el contenido que no entra en pantalla (clima, más leídas) no se ve
     hasta scrollear TODA la nota principal — position:sticky no scrollea
     internamente por sí solo, si el elemento sticky mide más que el
     viewport el sobrante queda tapado por el borde de la ventana. Con
     max-height + overflow-y, la sidebar se vuelve su propia columna con
     scroll independiente, visible completa sin depender del scroll de la
     columna principal.
  */
  max-height: calc(100vh - 161px - var(--space-6));
  overflow-y: auto;
  scrollbar-width: thin;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

@media (max-width: 1023px) {
  /* minmax(0, 1fr), no 1fr solo: un 1fr "pelado" todavía respeta el
     min-content de lo que tenga adentro (ej. el carrusel de "seguir
     leyendo"), así que si algo interno pide más ancho del disponible,
     la columna entera se agranda y descentra todo lo que tiene
     max-width + margin:auto (título, cuerpo de la nota, etc). */
  .page-layout { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: static; }
}

/* ---------- Section grid (categorías) ---------- */
.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-5);
}
.section-heading h1,
.section-heading h2 { margin-bottom: 0; }
.section-subheading {
  font-size: var(--text-subhead);
  font-weight: 600;
  color: var(--categoria-color, var(--color-ink-muted));
  margin-bottom: 0;
}

/* Aire mínimo entre el header sticky y el logo/título de una landing de
   categoría — solo cuando el heading es lo primero de la página (acá, no
   en los section-heading que aparecen más abajo dentro del home). */
#page-content > .section-heading:first-child { padding-top: var(--header-clearance); }

.article-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
}

/* Segunda tanda de una categoría: mismo contenido, tratamiento visual
   distinto (filas horizontales anchas) para que la página no sea el mismo
   grid repetido hasta el final. */
.article-list-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
  margin-top: var(--space-6);
}
@media (max-width: 767px) {
  .article-list-grid { grid-template-columns: 1fr; }
}

@media (max-width: 1023px) {
  .article-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 639px) {
  .article-grid { grid-template-columns: 1fr; }
}

@media (max-width: 767px) {
  /* Mismo tratamiento de fila compacta que ya lleva el hero — ahora también acá,
     para que las secciones por categoría del home y las páginas de categoría no
     "se sigan viendo como antes" (quedaron afuera de la pasada anterior a
     propósito, para no ensanchar el alcance; ahora sí se pide explícitamente
     una experiencia pareja en todo el feed mobile). Fuerza 1 columna en todo
  el rango ≤767 (no solo ≤639 como antes): una fila horizontal apretada en
  2 columnas se ve mal. */
  .article-grid {
    grid-template-columns: 1fr;
  }
  .article-grid > .card {
    flex-direction: row;
    align-items: stretch;
    gap: var(--space-3);
    position: relative;
  }
  .article-grid > .card .card-media {
    width: 120px;
    aspect-ratio: 4 / 3;
    flex-shrink: 0;
    overflow: hidden;
    border-radius: var(--radius-sm);
  }
  .article-grid > .card .card-body {
    padding: var(--space-2) var(--space-3);
    justify-content: center;
    gap: 2px;
    min-width: 0;
  }
  .article-grid > .card .card-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .article-grid > .card .card-excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: var(--text-footnote);
    line-height: var(--lh-footnote);
    color: var(--color-ink-muted);
  }
  .article-grid > .card .card-meta {
    display: none;
  }
  .article-grid > .card .categoria-pill {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    padding: 2px 6px;
    border-radius: 0 0 var(--radius-sm) 0;
    background: var(--categoria-color, var(--color-accent));
    color: #fff;
    line-height: 1.2;
  }
  .article-grid > .card .dot,
  .article-grid > .card .card-meta time {
    display: none;
  }

  /* Cada 2da sección del home (ver index.php, .article-grid--carousel) rompe
     el ritmo de filas compactas con un carrusel horizontal — mismo
     tratamiento que .hero-grid arriba (scroll-snap + cards con imagen de
     fondo), para que el home no se sienta "un listado" a medida que se
     scrollea. Tiene que ir DESPUÉS del bloque de fila compacta de arriba
     (misma especificidad) para ganarle en la cascada. */
  .article-grid--carousel {
    display: flex;
    grid-template-columns: none;
    gap: var(--space-3);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .article-grid--carousel::-webkit-scrollbar { display: none; }
  .article-grid--carousel > .card {
    flex: 0 0 72%;
    scroll-snap-align: start;
    flex-direction: column;
    align-items: stretch;
    will-change: auto;
  }
  .article-grid--carousel > .card .card-media {
    width: auto;
    aspect-ratio: auto;
  }
}

/* ---------- Article page ---------- */
.article-header { max-width: 700px; margin-inline: auto; padding-block: var(--space-6) var(--space-4); }
.article-header h1 { text-wrap: balance; }
.article-body { max-width: 700px; margin-inline: auto; font-size: var(--text-body); line-height: var(--leading-relaxed); }
.article-body p { margin-bottom: var(--space-5); }
.article-body h2 { margin-top: var(--space-7); }
.article-body strong { font-weight: 700; }

/* Formatos que solo puede generar el editor del CMS: Groq escribe únicamente
   subtítulos y negritas. Si se pueden escribir, tienen que verse bien publicados. */
.article-body em { font-style: italic; }
.article-body u { text-decoration: underline; text-underline-offset: 2px; }
.article-body a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.article-body a:hover { text-decoration-thickness: 2px; }

.article-body ul,
.article-body ol { margin: 0 0 var(--space-5); padding-left: var(--space-5); }
.article-body li { margin-bottom: var(--space-2); }

.article-body blockquote {
  margin: var(--space-6) 0;
  padding: var(--space-2) 0 var(--space-2) var(--space-4);
  border-left: 3px solid var(--color-accent);
  font-size: var(--text-title3);
  line-height: 1.4;
  font-weight: 500;
}

.article-meta { color: var(--color-ink-muted); font-size: var(--text-subhead); line-height: var(--lh-subhead); }

/* ---------- Article byline ---------- */
.article-byline {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: 700px;
  margin: var(--space-6) auto 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.byline-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-surface-2);
  color: var(--color-accent);
  font-weight: 700;
  font-size: var(--text-title3);
  flex-shrink: 0;
}
.article-byline strong { display: block; }
.article-byline span { color: var(--color-ink-muted); font-size: var(--text-footnote); }

/* ---------- Imagen destacada y atribución ---------- */
/* La <figure> reemplaza al <img> suelto con estilos inline que había antes, para poder
   colgarle el crédito de la foto debajo (ver bloque 1 del plan de desarrollo). */
.article-figure {
  position: relative;
  margin: 0 0 var(--space-6);
}
.article-figure img {
  display: block;
  width: 100%;
  /* Bug real en producción (2026-07-26, bloque 14): sin este `height: auto` la
     imagen salía estirada verticalmente en cada nota. El atributo HTML `height`
     (agregado en el bloque 14 contra el CLS) se traduce en un `height` de baja
     prioridad en la cascada — alcanza con que el `width` de acá lo pise y el
     `height` quede SIN ningún valor de autor para que el navegador use el número
     crudo del atributo (ej. 1333px) como alto fijo, ignorando el ancho real del
     contenedor. Las tarjetas (.card-media img) no tenían este problema porque ya
     declaraban `height: 100%` explícito. Cualquier <img> nuevo que reciba
     width/height por HTML necesita este mismo `height: auto` si su ancho se define
     por CSS y no por el atributo. */
  height: auto;
  border-radius: var(--radius-image);
}
.foto-credito {
  margin-top: var(--space-2);
  color: var(--color-ink-muted);
  font-size: var(--text-caption);
  text-align: right;
}
/* Badge "Noticia resumida por Fulana IA" — barra de UNA línea debajo de la imagen
   destacada (no superpuesta). Fondo "IA" translúcido (gradiente teal/violeta) que se
   nota sin tapar la foto; hover con elevación. Título a la izquierda y link a la
   fuente original a la derecha (rel=nofollow noopener, ver .article-fuente). */
.ai-badge {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  min-width: 0;
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--color-brand-teal) 55%, transparent), color-mix(in srgb, #7c3aed 45%, transparent)),
    rgb(15 23 42 / 0.72);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 4px 16px rgb(0 0 0 / 0.25);
  transition: transform var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}
.ai-badge:hover,
.ai-badge:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.35);
}
/* Tipografía del portal (Inter, pesos normales): el título y el link comparten la
   misma línea de base (alineación por baseline) y el título cede espacio (trunca con
   …) en pantallas chicas — el link nunca se corta ni se sale de la barra. */
.ai-badge-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--text-footnote);
  font-weight: 400;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-badge-link {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  flex-shrink: 0;
  font-size: var(--text-footnote);
  font-weight: 500;
  line-height: 1.3;
  text-decoration: underline;
  text-underline-offset: 2px;
  opacity: 0.94;
  white-space: nowrap;
}
.ai-badge-link svg { width: 14px; height: 14px; align-self: center; }

@media (max-width: 767px) {
  .ai-badge { gap: var(--space-2); padding: var(--space-2) var(--space-3); }
  .ai-badge-title { font-size: var(--text-caption); }
  .ai-badge-link { font-size: var(--text-caption); }
}
/* Pie de fuente: deliberadamente discreto — informa sin competir con la firma del autor.
   Mismo ancho que el byline para que queden alineados. */
.article-fuente {
  max-width: 700px;
  margin: var(--space-3) auto 0;
  color: var(--color-ink-muted);
  font-size: var(--text-footnote);
}
.article-fuente a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.article-fuente a:hover { color: var(--color-accent); }

/* ---------- Compartir ---------- */
.action-row { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4); }
/* 44px y no 34px: es el mínimo de superficie táctil de la guía de Apple y de WCAG,
   y estos cuatro botones son lo más tocado de una nota en un portal (compartir por
   WhatsApp es la vía principal de difusión acá). A 34px con 8px de separación se
   fallaba el toque seguido, sobre todo el de copiar, que está último y pegado al
   borde. El ícono queda en 18px para que el círculo no se vea vacío. */
.action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: #fff;
  flex-shrink: 0;
  border: none;
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-standard);
}
.action-btn:hover { transform: scale(1.08); }
.action-btn svg { width: 18px; height: 18px; }
.action-wa { background: #25d366; }
.action-tw { background: #000; }
.action-fb { background: #1877f2; }
.action-copy { background: var(--color-surface-2); color: var(--color-ink-muted); border: 1px solid var(--color-border); }

/* ---------- Seguir leyendo (cierre de nota): carrusel de 3 ---------- */
.next-section { margin-top: var(--space-7); }
.next-article-label {
  display: block;
  font-size: var(--text-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-ink-muted);
  margin-bottom: var(--space-3);
}
.carousel { display: flex; align-items: center; gap: var(--space-3); }
.carousel-track {
  flex: 1;
  min-width: 0;
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-item { flex: 0 0 calc((100% - 2 * var(--space-4)) / 3); min-width: 0; scroll-snap-align: start; }
.carousel-arrow {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-ink);
}
.carousel-arrow svg { width: 18px; height: 18px; }
.carousel-arrow:hover { border-color: var(--color-accent); color: var(--color-accent); }

@media (max-width: 900px) {
  .carousel-item { flex-basis: calc((100% - var(--space-4)) / 2); }
}
@media (max-width: 639px) {
  .carousel-item { flex-basis: 78%; }
  .carousel-arrow { display: none; }
}

/* Lista de cards compactas (thumb + título) apiladas en un widget de sidebar */
.compact-list { display: flex; flex-direction: column; gap: var(--space-3); }

/* ---------- Prose (institucional) ---------- */
.prose { max-width: 700px; }
.prose h1 { margin-bottom: var(--space-3); }
.prose .lead { font-size: var(--text-title3); line-height: var(--lh-title3); color: var(--color-ink-muted); margin-bottom: var(--space-6); }
.prose h2 { margin-top: var(--space-6); }
.prose a:not(.btn) { color: var(--color-link); text-decoration: underline; }

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-9);
  padding-block: var(--space-7) var(--space-5);
  color: var(--color-ink-muted);
  font-size: var(--text-footnote);
  background: var(--color-surface);
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--space-6);
  padding-bottom: var(--space-6);
}
.footer-brand p { margin-top: var(--space-3); max-width: 34ch; }
.footer-logo { display: inline-flex; color: var(--color-ink); }
.footer-logo svg { height: 26px; width: auto; display: block; }
.footer-col { display: flex; flex-direction: column; gap: var(--space-2); }
.footer-col h4 { font-size: var(--text-subhead); color: var(--color-ink); margin-bottom: var(--space-1); }
.footer-col a { transition: color var(--duration-fast) var(--ease-standard); }
.footer-col a:hover { color: var(--color-accent); }
.footer-legal {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

@media (max-width: 767px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}
