/* ─── TOKENS ───────────────────────────────────────────── */
/* Tema CLARO (default) — papel cremoso, tinta oscura, terracota como acento
   primario + azul petróleo como acento secundario para dinamismo cromático
   sin perder elegancia. Diario de mercado, no panfleto. */
:root {
  --cream:        #f3ead9;
  --cream-deep:   #ede2cc;
  --cream-soft:   #f8f1e2;
  --paper:        #faf4e6;
  --ink:          #16140f;
  --ink-soft:     #2a2620;
  --ink-mute:     #6b6357;
  --line:         #d9cdb4;
  --line-soft:    #e6dbc3;

  /* Paleta cromática refinada — terracota saturada + azul petróleo
     como secundario. Ambos saturados pero con base cálida. */
  --accent:        #b8390a;        /* terracota más profundo, mejor contraste */
  --accent-soft:   #e8a087;
  --accent-bg:     rgba(184, 57, 10, 0.08);
  --accent-2:      #1d4e89;        /* azul petróleo — secundario */
  --accent-2-soft: #6b94c4;
  --accent-2-bg:   rgba(29, 78, 137, 0.07);
  --accent-3:      #3f7a4d;        /* verde moss — terciario, info positiva */
  --accent-3-bg:   rgba(63, 122, 77, 0.08);

  --font-display: 'Cormorant Garamond', 'Times New Roman', serif;
  --font-body:    'Inter Tight', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;

  --radius-xs:    2px;
  --radius:       4px;
  --radius-md:    6px;
  --radius-lg:    8px;
  --radius-xl:    12px;
  --radius-pill:  999px;
  --shadow-sm:    0 1px 2px rgba(22, 20, 15, 0.05);
  --shadow-md:    0 4px 24px rgba(22, 20, 15, 0.08);

  --tracking:     0.14em;
  --tracking-sm:  0.08em;

  /* ── ESCALA TIPOGRÁFICA ──────────────────────────────────────────────
     Antes havia 34 tamanhos distintos, com meios-pixels (9.5, 10.5, 12.5…)
     que renderizam desfocados e não davam hierarquia nenhuma. Esta escala
     tem 10 degraus e chega para tudo. Os degraus pequenos (micro→sm) são
     para as etiquetas mono em maiúsculas; base é o texto corrido. */
  --fs-micro:  9px;    /* etiquetas mono minúsculas, sempre com tracking */
  --fs-2xs:   10px;
  --fs-xs:    11px;
  --fs-sm:    12px;
  --fs-md:    13px;    /* texto secundário / tabelas */
  --fs-base:  14px;    /* componentes (etiquetas, tabelas densas) */
  --fs-body:  15px;    /* texto corrido do site — como no v1 */
  --fs-lg:    17px;
  --fs-xl:    20px;
  --fs-2xl:   24px;
  --fs-3xl:   28px;
  --fs-4xl:   32px;
  --fs-5xl:   42px;
  /* Degraus de display (títulos Cormorant e o preço herói). Separados da
     escala de texto porque respondem a breakpoints e são deliberadamente
     grandes. */
  --fs-display-sm: 30px;
  --fs-display:    36px;
  --fs-hero:       84px;   /* preço único */
  --fs-hero-range: 56px;   /* preço em intervalo: cabem dois números */

  /* ── ESCALA DE ESPAÇAMENTO (ritmo de 4px) ────────────────────────────
     Antes havia 32 valores soltos (7, 9, 11, 15, 26, 38, 46…). Sem um
     ritmo comum, nada alinha com nada e o olho lê isso como desleixo. */
  --sp-1:   4px;
  --sp-2:   8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  20px;
  --sp-6:  24px;
  --sp-8:  32px;
  --sp-10: 40px;
  --sp-12: 48px;
  --sp-16: 64px;

  /* Aviso (banner "sem leilão recente"). Antes eram 3 hex fixos, que no tema
     escuro davam 2.73:1 — abaixo do mínimo legível. */
  --warn:      #8a5a00;
  --warn-bg:   #fff4d6;
  --warn-line: #f0c45a;
}

/* ── NÚMEROS TABULARES ──────────────────────────────────────────────────
   Regra de precisão, não de decoração: os nossos preços mudam ao longo do
   dia. Com dígitos de largura variável, o número "salta" de posição a cada
   atualização e as colunas de preço não alinham entre linhas. `tabular-nums`
   dá a todos os dígitos a mesma largura — é o que qualquer serviço sério de
   cotações faz. Aplica-se a preços, tabelas, eixos e horas; nunca ao texto
   corrido, onde os dígitos proporcionais leem melhor. */
.price-value,
.price-currency,
.price-trend,
.data-table,
.table-compact,
.ms-num,
.ms-val,
.ms-sub,
.cr-price,
.cr-range,
.cr-hora,
.cr-axis,
.cross-axis,
.chart-wrap,
.ticker-px,
.ticker-prices,
.ls-stat-value,
.ls-stat-range,
.insight-detail,
.clock,
#clockTime,
.topbar-session,
.mono,
[class*="-price"],
[class*="-px"] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* Tema OSCURO — paleta inversa con calidez (no negro puro). Pensado para
   uso prolongado en horarios de leilón, alineado con TradingView/Bloomberg.
   Los acentos se aclaran para mantener contraste sobre fondo oscuro. */
body.dark-theme {
  --cream:        #1f1b16;
  --cream-deep:   #2a2520;
  --cream-soft:   #1a1611;
  --paper:        #25201a;        /* fondo principal */
  --ink:          #faf4e6;        /* texto principal — invertido */
  --ink-soft:     #ebe1cc;
  --ink-mute:     #8a8073;
  --line:         #3a342c;
  --line-soft:    #2e2922;

  --accent:        #e87b3f;        /* terracota más claro para contraste */
  --accent-soft:   #b8390a;
  --accent-bg:     rgba(232, 123, 63, 0.10);
  --accent-2:      #6b94c4;        /* azul más claro en oscuro */
  --accent-2-soft: #1d4e89;
  --accent-2-bg:   rgba(107, 148, 196, 0.10);
  --accent-3:      #6fa67c;        /* verde más claro */
  --accent-3-bg:   rgba(111, 166, 124, 0.10);

  --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md:    0 4px 24px rgba(0, 0, 0, 0.5);

  --warn:      #f0c45a;               /* invertido: texto claro sobre fundo escuro */
  --warn-bg:   rgba(240, 196, 90, 0.10);
  --warn-line: rgba(240, 196, 90, 0.35);
}

body { transition: background-color .25s, color .25s; }

/* Toggle de tema (sol/luna) en el header */
.theme-toggle {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--ink-mute);
  transition: color .15s, border-color .15s, background .15s;
  padding: 0;
}
.theme-toggle:hover {
  color: var(--ink);
  border-color: var(--ink-mute);
  background: rgba(60, 50, 35, 0.05);
}
.theme-toggle .theme-icon-light { display: none; }
.theme-toggle .theme-icon-dark  { display: inline; }
body.dark-theme .theme-toggle .theme-icon-light { display: inline; }
body.dark-theme .theme-toggle .theme-icon-dark  { display: none; }

/* ─── RESET ────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Atributo HTML "hidden" deve sempre ocultar — overrides locais com display:flex/grid/block. */
[hidden] { display: none !important; }

/* Mini-resumen de la lota — aparece al seleccionar lota, antes de Ver precios.
   Top especies del día con precios. Da contexto inmediato sin click extra. */
.lota-summary { padding: 40px 24px; }
.lota-summary-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 8px;
}
.lota-summary-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-5xl);
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  color: var(--ink);
}
.lota-summary-title em { font-style: italic; color: var(--accent); }
.lota-summary-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
  letter-spacing: var(--tracking-sm);
  margin: 0 0 28px;
}
/* Stats: mediana del día + variación + nº especies. Arriba de las cards. */
.lota-summary-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  padding: 20px 0 28px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line-soft);
}
.ls-stat { display: flex; flex-direction: column; gap: 4px; }
.ls-stat-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
}
.ls-stat-value {
  font-family: var(--font-display);
  font-size: var(--fs-4xl);
  line-height: 1;
  color: var(--ink);
}
/* Peixe mais ativo: nombre menor (cabe), color acento, italic para destacar */
.ls-stat-value.ls-stat-active {
  font-size: var(--fs-2xl);
  color: var(--accent);
  font-style: italic;
  line-height: 1.1;
}
.ls-stat-unit {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
}
.ls-stat-range {
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

.lota-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.lota-summary-card {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  transition: border-color .15s ease;
}
.lota-summary-card:hover { border-color: var(--ink-mute); }
.lota-summary-card .sp-name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: var(--ink);
  font-weight: 500;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lota-summary-card .sp-price {
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  color: var(--accent);
  font-weight: 500;
  white-space: nowrap;
}
.lota-summary-hint {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
  text-align: center;
  margin: 20px 0 0;
  letter-spacing: var(--tracking-sm);
  font-style: italic;
}

/* Linha de atribução da fonte, debaixo do bloco de resultados.
   Discreta, mono, em itálico. Só aparece se tiver conteúdo. */
.source-line {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
  letter-spacing: 0.04em;
  text-align: right;
  margin: 24px 0 0;
  font-style: italic;
}
.source-line:empty { display: none; }
.source-line a { color: var(--ink-mute); text-decoration: underline; text-underline-offset: 2px; }
.source-line a:hover { color: var(--accent); }
body {
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
a { color: inherit; text-decoration: none; }
input, select { font-family: inherit; font-size: inherit; color: inherit; }

/* ─── TOPBAR ───────────────────────────────────────────── */
.topbar {
  background: var(--ink);
  color: var(--cream-soft);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  /* O ticker é largo de propósito (a pista chega aos 2700px) e a faixa da
     sessão tem largura fixa de 420px. Sem isto, num telemóvel de 375px a
     PÁGINA INTEIRA deslizava na horizontal — não só a barra. */
  overflow: hidden;
}
.topbar-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 8px 32px;
  display: flex;
  align-items: center;
}
.topbar-text { opacity: 0.78; }

/* Etiqueta fija a la izquierda: "Última sessão · vie 15 mai" */
.topbar-inner { gap: 22px; }
.topbar-session {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  color: var(--cream-soft);
  opacity: 0.85;
  white-space: nowrap;
  flex-shrink: 0;
  padding-right: 16px;
  border-right: 1px solid rgba(243, 234, 217, 0.18);
}
.topbar-session:empty { display: none; }
.topbar-session {
  /* Width fijo: 420px alcanza para "ÚLTIMOS DATOS DISPONIBLES Vila Real
     de Santo António · 19:30" sin truncar. Centrado y estable. */
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  min-width: 420px;
  max-width: 420px;
  /* Separador más fuerte: línea vertical + espacio respira */
  border-right: 1px solid rgba(243, 234, 217, 0.32);
  padding-right: 22px;
  margin-right: 4px;
  /* Transición suave al actualizar contenido */
  transition: opacity 0.25s ease;
}
.topbar-session.fading { opacity: 0; }
.topbar-session .label {
  text-transform: uppercase;
  opacity: 0.55;
  margin-right: 8px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* Dot pulsante verde antes del label — indica "info viva" */
.topbar-session .label::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #6fa67c;
  box-shadow: 0 0 0 0 rgba(111, 166, 124, 0.7);
  animation: topbar-pulse 1.8s ease-in-out infinite;
}
@keyframes topbar-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(111, 166, 124, 0.7); opacity: 1; }
  50%      { box-shadow: 0 0 0 5px rgba(111, 166, 124, 0); opacity: 0.7; }
}
.topbar-lota-link {
  /* Que el link ocupe lo que necesite pero sin empujar más allá del max-width */
  display: inline-block;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-lota-link {
  color: var(--cream-soft);
  text-decoration: none;
  padding: 2px 4px;
  border-radius: var(--radius);
  transition: background 0.15s;
}
.topbar-lota-link:hover {
  background: rgba(243, 234, 217, 0.12);
  color: #ffd89a;
  cursor: pointer;
}

/* Reloj de Portugal continental — siempre visible, da contexto temporal */
.topbar-clock {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--cream-soft);
  white-space: nowrap;
  flex-shrink: 0;
  padding-right: 22px;
  border-right: 1px solid rgba(243, 234, 217, 0.32);
}
.topbar-clock .clock-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #6ad26a;
  box-shadow: 0 0 6px rgba(106, 210, 106, 0.6);
  animation: clock-pulse 2s ease-in-out infinite;
}
@keyframes clock-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
#clockTime {
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* Ticker em carrossel — uma espécie de cada vez, transição vertical suave.
   Altura fixa, uma única linha, overflow oculto: nunca desborda. */
/* Altura: 24px, não 18px. Cada par (lota + preço) mede 17px de texto; com o
   selo de período das entradas espanholas ("agosto 2026") a caixa passava dos
   30px dentro de uma janela de 18px com overflow:hidden — e o preço aparecia
   cortado ao meio. Era isto que se via no topo do site. */
.ticker {
  position: relative;
  height: 24px;
  overflow: hidden;
  width: 100%;
}
.ticker-slide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  opacity: 0;
  transform: translateY(100%);
  transition: opacity .5s ease, transform .5s cubic-bezier(.22,.61,.36,1);
}
.ticker-slide.in   { opacity: 1; transform: translateY(0); }
.ticker-slide.out  { opacity: 0; transform: translateY(-100%); }
.ticker-sp {
  color: var(--cream-soft);
  font-weight: 700;
  text-transform: uppercase;
  margin-right: 18px;
  letter-spacing: 0.08em;
}
.ticker-sp::after { content: none; }
/* Separador grande entre bloques de especie distintos (◆) */
.ticker-sp-sep {
  display: inline-block;
  margin: 0 22px;
  opacity: 0.28;
  color: var(--cream-soft);
  font-size: var(--fs-micro);
  vertical-align: middle;
}

/* Ticker en 2 zonas: especie fija (izq) + precios scroll (der) */
.ticker {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;  /* importante: permite que el flex child se encoja */
  gap: 24px;     /* más aire entre nombre especie y zona de precios */
  overflow: hidden;
}
.ticker-especie-zone {
  position: relative;
  flex: 0 0 auto;
  /* width adaptable: usar el texto natural del slide visible. min 80px,
     max 230px para no romper nombres largos. */
  /* Largura FIXA. Era `min-width:80px` com o slide em position:absolute: um
     nome como "ROBALO-LEGÍTIMO" (130px) saía da sua zona e passava por cima
     do separador e dos primeiros preços. Fixa também evita que a linha
     inteira salte de sítio a cada troca de espécie. */
  width: 172px;
  min-width: 0;
  height: 24px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  color: var(--cream-soft);
  text-transform: uppercase;
  /* Para que el slide flotante ocupe todo el ancho disponible */
  display: inline-flex;
  align-items: center;
}
.ticker-sp-slide {
  position: absolute;
  inset: 0;
  white-space: nowrap;
  /* block + ellipsis: um nome comprido corta-se com "…" dentro da sua zona,
     em vez de sair por cima do que está ao lado. */
  display: block;
  line-height: 24px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateY(100%);
  transition: opacity .45s ease, transform .45s cubic-bezier(.22,.61,.36,1);
}
.ticker-sp-slide.in  { opacity: 1; transform: translateY(0); }
.ticker-sp-slide.out { opacity: 0; transform: translateY(-100%); }
.ticker-divider {
  flex: 0 0 auto;
  color: var(--cream-soft);
  opacity: 0.35;
}
.ticker-prices-zone {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

/* Marquee: scroll continuo horizontal lento.
   A máscara existe por um motivo concreto: sem ela o primeiro par ficava
   cortado a meio na borda esquerda e lia-se "09" solto, como se fosse um
   número do site. Um preço cortado é pior do que preço nenhum. Com o
   degradê, as entradas aparecem e desaparecem em vez de serem fatiadas. */
.ticker-marquee {
  width: 100%;
  overflow: hidden;
  position: relative;
  /* O degradê da esquerda tem de ser LARGO. Um par mede 170-200px e o preco
     esta no fim: cortado pela borda, o que sobra e um "€...09" sem lota
     nenhuma ao lado -- um numero solto que parece ser do site. Com 110px, o
     que resta de um par cortado ja vem esbatido ao ponto de se ler como
     "isto continua", que e o que de facto acontece. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 110px, #000 calc(100% - 56px), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 110px, #000 calc(100% - 56px), transparent 100%);
}
.ticker-marquee-track {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  /* Animación lenta para los precios. 60s para una vuelta del contenido
     duplicado (translateX -50%). Pausa al hover. */
  animation: marquee-scroll 60s linear infinite;
  will-change: transform;
}
.ticker-marquee:hover .ticker-marquee-track {
  animation-play-state: paused;  /* pausa al hover para poder leer/clickear */
}
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.ticker-pair {
  display: inline-flex;
  align-items: center;
  gap: 10px;            /* más aire entre lota y precio */
  text-decoration: none;
  color: inherit;
  /* Sem padding vertical: a caixa passa a medir os mesmos 24px da faixa e
     nada fica cortado em cima nem em baixo. */
  padding: 0 14px;
  height: 24px;
  line-height: 24px;
  margin: 0 4px;
  border-radius: var(--radius);
  transition: background 0.15s ease;
  white-space: nowrap;
}
.ticker-pair:hover {
  background: rgba(243, 234, 217, 0.12);
  cursor: pointer;
}
.ticker-lt {
  opacity: 0.78;
  letter-spacing: 0.03em;
}
.ticker-px {
  color: #f8c97a;
  font-weight: 600;
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  margin-left: 4px;
}
.ticker-pair:hover .ticker-px { color: #ffd89a; }

/* ─── NAV ──────────────────────────────────────────────── */
.nav {
  background: var(--paper);
  border-bottom: 1px solid var(--line-soft);
}
.nav-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 16px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--font-display);
  font-size: var(--fs-4xl);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.logo em {
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  margin: 0 -2px;
}
.logo.small { font-size: var(--fs-2xl); }
.logo-divider {
  font-size: var(--fs-2xl);
  color: var(--line);
  margin: 0 6px 0 10px;
  font-weight: 300;
}
.logo-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  align-self: center;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}
.lang-switch {
  display: inline-flex;
  background: var(--cream-deep);
  border-radius: var(--radius);
  padding: 4px;
  gap: 0;
}
.lang-btn {
  padding: 6px 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  border-radius: var(--radius);
  transition: all .18s ease;
}
.lang-btn.active {
  background: var(--ink);
  color: var(--cream-soft);
}
.alert-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--ink);
  transition: all .18s ease;
}
.alert-btn:hover {
  background: var(--ink);
  color: var(--cream-soft);
  border-color: var(--ink);
}
.alert-btn svg { transition: transform .2s ease; }
.alert-btn:hover svg { transform: rotate(-10deg); }

/* ─── MAIN ─────────────────────────────────────────────── */
.main {
  flex: 1;
  max-width: 1280px;
  width: 100%;
  margin: 0 auto;
  padding: 24px 32px 64px;
}

/* ─── FILTERS ──────────────────────────────────────────── */
.filters { margin-bottom: 28px; }
.filters-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
  margin-bottom: 16px;
}
.dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
  position: relative;
  display: inline-block;
}
.dot::after {
  content: '';
  position: absolute; inset: -4px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.25;
  animation: pulse 2s ease-out infinite;
}
@keyframes pulse {
  0%   { transform: scale(0.8); opacity: 0.4; }
  100% { transform: scale(2.2); opacity: 0; }
}

.filters-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  gap: 14px;
  align-items: end;
}
.field { display: flex; flex-direction: column; gap: 8px; }
.field label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
}
.select-wrap { position: relative; }
.select-wrap select {
  width: 100%;
  padding: 14px 40px 14px 16px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-base);
  color: var(--ink);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: border-color .15s ease;
}
.select-wrap select:hover:not(:disabled) { border-color: var(--ink-mute); }
.select-wrap select:focus { outline: none; border-color: var(--ink); }
.select-wrap select:disabled { opacity: 0.5; cursor: not-allowed; }
.caret {
  position: absolute;
  right: 14px; top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--ink-mute);
}

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  background: var(--ink);
  color: var(--cream-soft);
  border-radius: var(--radius);
  font-size: var(--fs-base);
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: all .18s ease;
  white-space: nowrap;
}
.cta:hover {
  background: var(--ink-soft);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}
.cta:active { transform: translateY(0); }

/* ─── RESULT ───────────────────────────────────────────── */
.result {
  min-height: 380px;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--cream-soft);
  position: relative;
  overflow: hidden;
}

.empty-state, .loading, .error-state {
  min-height: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px;
}
.empty-title {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: 400;
  color: var(--ink);
  margin: 0 0 14px;
  letter-spacing: 0.005em;
}
.empty-title em {
  font-style: italic;
  color: var(--accent);
}
.empty-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
  margin: 0;
}

.spinner {
  width: 28px; height: 28px;
  border: 2px solid var(--line);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin .8s linear infinite;
  margin-bottom: 14px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading p {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
}
.error-title {
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  color: var(--ink);
  margin: 0 0 8px;
}
.error-sub {
  font-size: var(--fs-md);
  color: var(--ink-mute);
  max-width: 480px;
}

/* ─── RESULT CONTENT ───────────────────────────────────── */
.result-content {
  background: var(--paper);
  border-radius: var(--radius-lg);
  padding: 36px 40px;
  animation: fadeUp .4s ease both;
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.result-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 32px;
}
.result-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
  margin: 0 0 6px;
}
.result-title {
  font-family: var(--font-display);
  font-size: var(--fs-5xl);
  font-weight: 400;
  margin: 0 0 6px;
  letter-spacing: 0.005em;
  line-height: 1.1;
}
.result-meta {
  font-size: var(--fs-md);
  color: var(--ink-mute);
  margin: 0;
}
.stale-warning {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 10px 0 0;
  padding: 8px 12px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  border-radius: var(--radius-md);
  letter-spacing: 0.01em;
}
.stale-warning::before {
  content: "⚠";
  font-size: var(--fs-base);
}

.ghost-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink);
  transition: all .15s ease;
}
.ghost-btn:hover { background: var(--cream-deep); }

/* ─── PRICE BLOCK ──────────────────────────────────────── */
.price-block {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 40px;
  margin-bottom: 40px;
  align-items: start;
}
.price-side {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.price-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
  margin: 0;
}
.price-value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-hero);
  line-height: 0.95;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 4px;
  transition: font-size .2s ease;
}
/* Cuando hay un rango (varios calibres con precios distintos), reducimos
   un poco el tamaño porque caben dos números y un guión. */
.price-value.range { font-size: var(--fs-hero-range); }
.price-value .price-dash {
  font-size: 0.55em;
  color: var(--ink-mute);
  padding: 0 0.18em;
  font-style: italic;
}
/* Modo "histórico solamente" (no se vendió hoy): precio en gris suave
   para indicar que no es el precio actual sino el último conocido. */
.price-value.historical-only { color: var(--ink-mute); opacity: 0.85; }
.price-value.historical-only .price-currency { color: var(--ink-mute); }
.price-currency {
  font-size: 34px;
  font-style: italic;
  color: var(--accent);
  align-self: flex-start;
  margin-top: 8px;
}
.price-unit {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--ink-mute);
  letter-spacing: var(--tracking-sm);
  margin-left: 6px;
  align-self: flex-end;
  margin-bottom: 12px;
}

.price-trend {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
  letter-spacing: var(--tracking-sm);
  margin: 0 0 6px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line-soft);
}
.price-trend.up   { color: var(--accent-3); }
.price-trend.down { color: var(--accent); }

/* Tabela compacta directo no bloco do preço (substitui o range min/máx) */
.table-compact { margin-top: 4px; }
.table-compact .table-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 8px;
}
.table-compact .table-title {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  font-weight: 500;
  margin: 0;
}
.table-compact .table-count {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  margin: 0;
}
.table-compact .data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-md);
}
.table-compact .data-table thead th {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
  font-weight: 500;
  text-align: left;
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
}
.table-compact .data-table thead th.num { text-align: right; }
.table-compact .data-table tbody td {
  padding: 8px 8px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-soft);
}
.table-compact .data-table tbody td.num {
  text-align: right;
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--ink);
}
.table-compact .data-table tbody tr:hover { background: var(--cream-deep); }
.table-compact .table-wrap {
  max-height: 280px;
  overflow-y: auto;
  overflow-x: hidden;  /* el subtexto puede ser largo, dejamos que wrappee */
}
.table-compact .data-table { table-layout: fixed; width: 100%; }
.table-compact .data-table th:nth-child(1) { width: 38%; }  /* calibre */
.table-compact .data-table th:nth-child(2) { width: 16%; }  /* frescura */
.table-compact .data-table th:nth-child(3) { width: 46%; }  /* precio + sub */

/* Punto de color para identificar calibre (mismo color en grafico y tabla). */
.cal-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
}
/* Pequeno texto al lado del calibre con su peso. */
.cal-weight {
  display: inline-block;
  margin-left: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  opacity: 0.85;
}

/* Sub-info dentro de la celda de precio: hora última obs, n obs, variación.
   Permite wrap natural si el texto es largo, así el precio principal no se corta. */
.cell-sub {
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  opacity: 0.75;
  letter-spacing: 0.02em;
  font-weight: 400;
  white-space: normal;
  line-height: 1.4;
}

/* Indicador de disponibilidad: 3 barritas tipo "señal". Discreto, junto al
   precio. Más barras llenas = más cambios de precio hoy = más rotación real.
   alta=3 (verde) · media=2 (azul) · baja=1 (gris). Tooltip explica el detalle. */
.avail {
  display: inline-flex;
  align-items: flex-end;
  gap: 1.5px;
  height: 9px;
  margin-left: 8px;
  vertical-align: middle;
  cursor: help;
}
.avail i {
  width: 2.5px;
  background: var(--line);
  border-radius: var(--radius-xs);
}
.avail i:nth-child(1) { height: 4px; }
.avail i:nth-child(2) { height: 6.5px; }
.avail i:nth-child(3) { height: 9px; }
.avail-baja  i:nth-child(1) { background: var(--ink-mute); }
.avail-media i:nth-child(1),
.avail-media i:nth-child(2) { background: var(--accent-2); }
.avail-alta  i { background: var(--accent-3); }
/* La celda numérica del precio: precio grande arriba, subtexto bajo, alineado
   a la derecha. Sin overflow forzado. */
.table-compact .data-table td.num {
  white-space: normal;
  text-align: right;
  min-width: 105px;
}

/* Nota explicativa debajo de la tabla (ej: "no se diferencia por calibre"). */
.table-note {
  margin: 10px 4px 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  font-style: italic;
  line-height: 1.5;
}

/* ─── CHART ────────────────────────────────────────────── */
.chart-wrap {
  background: var(--cream-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 22px 24px;
  display: flex;
  flex-direction: column;
  min-height: 280px;
}
.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}
.chart-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  margin: 0;
  color: var(--ink);
  font-style: italic;
  font-weight: 400;
}
.chart-range {
  display: inline-flex;
  gap: 0;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 2px;
}
.range-btn {
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  border-radius: var(--radius);
  text-transform: uppercase;
  transition: all .15s ease;
}
.range-btn:hover { color: var(--ink); }
.range-btn.active {
  background: var(--ink);
  color: var(--cream-soft);
}
/* Botón HOY destacado con punto rojo (live) */
.range-btn[data-range="today"] {
  position: relative;
  padding-left: 18px;
}
.range-btn[data-range="today"]::before {
  content: "";
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #c2410c;
  box-shadow: 0 0 6px rgba(194, 65, 12, 0.6);
  animation: clock-pulse 2s ease-in-out infinite;
}
.range-btn[data-range="today"].active::before {
  background: #ffd89a;
  box-shadow: 0 0 6px rgba(255, 216, 154, 0.7);
}

/* Herramientas del gráfico: rango + botón ampliar */
.chart-tools {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.chart-expand-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 28px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  color: var(--ink-mute);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.chart-expand-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* ─── Modal de zoom del gráfico ─────────────────────────── */
.chart-zoom-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(30, 24, 16, 0.62);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3vh 3vw;
}
.chart-zoom-backdrop[hidden] { display: none; }
.chart-zoom-box {
  background: var(--cream-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  width: 94vw;
  height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(0,0,0,0.35);
  overflow: hidden;
}
.chart-zoom-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.chart-zoom-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-style: italic;
  color: var(--ink);
  margin: 0;
}
.chart-zoom-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chart-zoom-zoombtn,
.chart-zoom-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  font-size: var(--fs-xl);
  line-height: 1;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.chart-zoom-zoombtn:hover { border-color: var(--accent); color: var(--accent); }
.chart-zoom-close { font-size: var(--fs-2xl); }
.chart-zoom-close:hover { background: var(--ink); color: var(--cream); }
.chart-zoom-body {
  flex: 1;
  overflow: auto;
  padding: 18px 20px;
  display: block;
}
.chart-zoom-svg { display: block; }
.chart-zoom-hint {
  flex-shrink: 0;
  margin: 0;
  padding: 8px 20px 14px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.03em;
  color: var(--ink-mute);
  opacity: 0.75;
  text-align: center;
}

/* Leyenda interactiva: click toggle por serie */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  padding: 0 4px;
  justify-content: center;
}
.chart-legend[hidden] { display: none; }
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  background: transparent;
  border-radius: var(--radius-xl);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--ink);
  transition: opacity .15s, background .15s, border-color .15s;
}
.legend-item:hover { background: rgba(60, 50, 35, 0.05); }
.legend-item.off {
  opacity: 0.35;
}
.legend-item.off:hover { opacity: 0.55; }
.legend-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.legend-item.off .legend-swatch {
  background: transparent !important;
  border: 1.5px solid currentColor;
}
.legend-label { line-height: 1; }

/* Indicador "cache" para series sin venta hoy (precio = día anterior).
   Se muestra atenuada con etiqueta "cache" en italic. Click la activa
   por si el usuario quiere verla igual. */
.legend-item.cache {
  border-style: dashed;
  opacity: 0.5;
}
.legend-item.cache em {
  font-style: italic;
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.75;
  margin-left: 4px;
  color: var(--ink-mute);
}

/* ============================================================
   Ficha de especie — UNA SOLA LÍNEA compacta
   Nombre científico + familia + sostenibilidad + link PDF.
   Objetivo: que TODO el detalle (ficha + tabla + gráfico) entre
   en una pantalla sin scroll.
   ============================================================ */

.species-card {
  padding: 6px 0;
  background: transparent;
  border: none;
  margin: 0 0 8px;
}
.species-card[hidden] { display: none; }

.species-info {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  min-width: 0;
}

.species-scientific {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--ink);
  margin: 0;
  line-height: 1.1;
  letter-spacing: -0.005em;
}

/* Meta row: datasheet con labels mono pequeño + valores.
   Cada celda separada por gap, cada valor linkeable a fuente externa (SEO). */
.species-meta-line {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 24px;
  margin: 6px 0 4px;
  padding: 0;
  align-items: flex-start;
}
.species-meta-line .meta-cell {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.species-meta-line .meta-cell-label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.7;
}
.species-meta-line .meta-cell-val {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink);
  text-decoration: none;
  letter-spacing: 0.01em;
  line-height: 1.2;
}
.species-meta-line .meta-cell-val.sci {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-base);
}
/* span normal — sin underline. Tooltip explica la fuente. */
.species-meta-line .meta-cell-val[title] {
  cursor: help;
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
}

/* Descripción del producto — OCULTADA por default. La descripción del PDF
   queda accesible en el link "Ficha PDF oficial". El usuario quiere ver
   TODO en una pantalla sin scroll, así que sacamos esto. */
.species-desc { display: none; }

/* IUCN status con código de color — solo la pill, sin badge grande */
.meta-iucn {
  font-weight: 600;
  letter-spacing: 0.06em;
}
.meta-iucn-lc { color: #3f7a4d; }
.meta-iucn-nt { color: #8a6d1a; }
.meta-iucn-vu { color: #b8721a; }
.meta-iucn-en { color: #a83b3b; }
.meta-iucn-cr { color: #6e1f1f; font-weight: 700; }
.meta-iucn-dd { color: var(--ink-mute); opacity: 0.7; }

.species-footer {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
}

/* Etiqueta de sostenibilidad — pill discreta */
.species-sustainability {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--radius-xl);
  font-weight: 600;
}
.species-sustainability::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}
.species-sustainability.ok {
  background: rgba(63, 122, 77, 0.10);
  color: #2d5c39;
}
.species-sustainability.ok::before { background: #3f7a4d; }
.species-sustainability.caution {
  background: rgba(184, 114, 26, 0.10);
  color: #8a5410;
}
.species-sustainability.caution::before { background: #b8721a; }
.species-sustainability.avoid {
  background: rgba(168, 59, 59, 0.10);
  color: #7a2e2e;
}
.species-sustainability.avoid::before { background: #a83b3b; }

.species-source-link {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-decoration: none;
  opacity: 0.7;
  transition: opacity .15s, color .15s;
}
.species-source-link:hover {
  color: var(--accent);
  opacity: 1;
}

/* Mobile: stack vertical compacto */
@media (max-width: 600px) {
  .species-card {
    gap: 12px;
    padding: 10px 12px;
  }
  .species-img-wrap {
    width: 60px;
    height: 60px;
  }
  .species-scientific { font-size: var(--fs-lg); }
  .species-meta-line { font-size: var(--fs-2xs); }
}

/* Dark theme: ajustar bordes y fondos */
body.dark-theme .species-img-wrap {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--line);
}
body.dark-theme .meta-iucn-lc { color: #6fa67c; }
body.dark-theme .meta-iucn-nt { color: #d4a44c; }
body.dark-theme .meta-iucn-vu { color: #e09a3a; }
body.dark-theme .meta-iucn-en { color: #e87b6e; }
body.dark-theme .species-sustainability.ok {
  background: rgba(111, 166, 124, 0.15);
  color: #9ec9a8;
}
body.dark-theme .species-sustainability.caution {
  background: rgba(224, 154, 58, 0.15);
  color: #e0b870;
}
body.dark-theme .species-sustainability.avoid {
  background: rgba(232, 123, 110, 0.15);
  color: #e8a59b;
}

/* Fila de tabla atenuada cuando su serie está oculta en la leyenda.
   No la escondemos del todo: el usuario ve que existe pero está "apagada". */
#tableBody tr {
  transition: opacity .2s, background .15s;
}
#tableBody tr:hover {
  background: rgba(60, 50, 35, 0.04);
}
#tableBody tr.row-dimmed {
  opacity: 0.32;
}
#tableBody tr.row-dimmed .cal-dot {
  background: transparent !important;
  border: 1.5px solid currentColor;
  box-sizing: border-box;
}
#tableBody tr.row-focused {
  background: rgba(194, 65, 12, 0.07);
  box-shadow: inset 3px 0 0 var(--accent, #c2410c);
}

/* Chip "A visualizar T1/A · ✕ ver todos" — modo focus activo */
.focus-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: var(--accent, #c2410c);
  color: #faf4e6;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono, monospace);
  font-size: var(--fs-xs);
  letter-spacing: 0.05em;
  margin: 0 0 16px;
  cursor: pointer;
  user-select: none;
  transition: background .15s, transform .15s;
  width: fit-content;
}
.focus-chip:hover {
  background: #a83209;
  transform: translateY(-1px);
}
.focus-chip[hidden] { display: none; }
.focus-chip-label {
  opacity: 0.7;
  text-transform: uppercase;
}
.focus-chip strong {
  font-weight: 700;
  letter-spacing: 0.08em;
}
.focus-chip-clear {
  margin-left: 4px;
  padding-left: 10px;
  border-left: 1px solid rgba(250, 244, 230, 0.3);
  opacity: 0.85;
  font-size: var(--fs-2xs);
}

#chart { width: 100% !important; height: 220px !important; flex: 1; }

/* Tooltip hover sobre el gráfico — flotante, semitransparente */
.chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 10px 6px;
  box-shadow: var(--shadow-md, 0 4px 24px rgba(22,20,15,0.12));
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink);
  z-index: 50;
  min-width: 140px;
  max-width: 200px;
}
.chart-tooltip[hidden] { display: none; }
.chart-tooltip .ct-header {
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  text-transform: uppercase;
  margin-bottom: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line-soft);
}
.chart-tooltip .ct-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 1px 0;
  line-height: 1.3;
}
.chart-tooltip .ct-swatch {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.chart-tooltip .ct-label {
  flex: 1;
  color: var(--ink-soft);
  font-size: var(--fs-2xs);
}
.chart-tooltip .ct-val {
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.chart-empty {
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  margin: auto;
}

/* ─── TABLE ────────────────────────────────────────────── */
.table-block { margin-top: 24px; }
.table-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 14px;
}
.table-title {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 500;
  margin: 0;
  color: var(--ink);
}
.table-count {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  margin: 0;
}
.table-wrap {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--cream-soft);
}
.data-table {
  width: 100%;
  border-collapse: collapse;
}
.data-table th, .data-table td {
  padding: 12px 16px;
  text-align: left;
  font-size: var(--fs-md);
}
.data-table th {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  font-weight: 500;
  background: var(--cream-deep);
  border-bottom: 1px solid var(--line-soft);
}
.data-table td {
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-soft);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--cream-deep); }
.data-table .num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.data-table td.nome {
  font-family: var(--font-display);
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--ink);
}

/* ─── MODAL ────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(22, 20, 15, 0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  padding: 20px;
  animation: fadeIn .2s ease;
}
/* Respeitar o atributo HTML hidden — sem isto, display:flex acima sobrepõe-se. */
.modal-backdrop[hidden] { display: none !important; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.modal {
  background: var(--paper);
  border-radius: var(--radius-lg);
  padding: 40px 36px 32px;
  max-width: 460px;
  width: 100%;
  position: relative;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
  animation: fadeUp .3s ease;
}
.modal-close {
  position: absolute;
  top: 14px; right: 18px;
  width: 32px; height: 32px;
  font-size: var(--fs-2xl);
  color: var(--ink-mute);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: all .15s ease;
}
.modal-close:hover { background: var(--cream-deep); color: var(--ink); }

.modal-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  color: var(--accent);
  margin: 0 0 6px;
  text-transform: uppercase;
}
.modal-title {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  font-weight: 400;
  margin: 0 0 10px;
  letter-spacing: 0.005em;
}
.modal-title em { font-style: italic; color: var(--accent); }
.modal-sub {
  font-size: var(--fs-md);
  color: var(--ink-mute);
  margin: 0 0 22px;
  line-height: 1.5;
}

.modal-form { display: flex; flex-direction: column; gap: 14px; }
.modal-form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  color: var(--ink-mute);
  text-transform: uppercase;
}
.modal-form input, .modal-form select {
  padding: 12px 14px;
  background: var(--cream-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}
.modal-form input:focus, .modal-form select:focus {
  outline: none;
  border-color: var(--ink);
}
.modal-row {
  display: grid;
  grid-template-columns: 1fr 120px;
  gap: 12px;
}
.modal-note {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-align: center;
  margin: 4px 0 0;
}

/* ─── FOOTER ───────────────────────────────────────────── */
.footer {
  margin-top: auto;
  background: var(--paper);
  border-top: 1px solid var(--line-soft);
  /* Encima del sidebar sticky (que tiene z-index implícito por position:sticky) */
  position: relative;
  z-index: 10;
}
/* Footer centrado en columna: marca → newsletter → nav → fuente/copy.
   Todo alineado al centro, jerarquía vertical clara. */
.footer-inner {
  max-width: 640px;
  margin: 0 auto;
  padding: 48px 32px 34px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 28px;
}
.footer-top {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
}
.footer-bottom {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding-top: 24px;
  border-top: 1px solid var(--line-soft);
}
.footer-source {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: var(--ink-mute);
  margin: 0;
  line-height: 1.6;
  max-width: 520px;
}
.footer-source a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px dotted var(--line);
}
.footer-source a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.footer-tag {
  font-size: var(--fs-sm);
  color: var(--ink-mute);
  margin: 0;
  max-width: 360px;
  line-height: 1.5;
}

/* Newsletter signup en el footer */
.footer-newsletter {
  margin-top: 10px;
  width: 100%;
  max-width: 380px;
}
.nl-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 8px;
}
.nl-row {
  display: flex;
  gap: 6px;
  justify-content: center;
}
.nl-input {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-md);
}
.nl-input:focus {
  outline: none;
  border-color: var(--accent);
}
.nl-btn {
  padding: 8px 14px;
  background: var(--ink);
  color: var(--cream);
  border: none;
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s;
}
.nl-btn:hover { background: var(--accent); }
.nl-msg {
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  line-height: 1.4;
  text-align: center;
}
.nl-msg.ok { color: var(--accent-3); }
.nl-msg.err { color: var(--accent); }
.footer-nav {
  display: flex;
  gap: 16px 24px;
  flex-wrap: wrap;
  justify-content: center;
}
.footer-nav a {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-transform: uppercase;
  transition: color .15s ease;
}
.footer-nav a:hover { color: var(--ink); }
.footer-copy {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-align: center;
  margin: 0;
}
.footer-sources {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: var(--ink-mute);
  margin: 0;
  line-height: 1.6;
  max-width: 520px;
  text-align: center;
}

/* Botões de idioma nas páginas estáticas (sobre/contacto/termos/privacidade):
   marcação simples sem a classe .lang-btn, mesmo estilo visual do site principal. */
.lang-switch button {
  padding: 6px 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  background: none;
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  transition: all .18s ease;
}
.lang-switch button.active {
  background: var(--ink);
  color: var(--cream-soft);
}

/* ─── PÁGINAS ESTÁTICAS (sobre/contacto/termos/privacidade) ───────────── */
.static-page {
  max-width: 720px;
}
.static-page .eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 10px;
}
.static-page h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(30px, 5vw, 42px);
  line-height: 1.15;
  margin: 0 0 22px;
  color: var(--ink);
}
.static-page h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-2xl);
  margin: 40px 0 12px;
  color: var(--ink);
}
.static-page p {
  font-size: var(--fs-base);
  line-height: 1.7;
  color: var(--ink-soft);
  margin: 0 0 14px;
}
.static-page p a {
  color: var(--ink);
  border-bottom: 1px dotted var(--line);
  text-decoration: none;
}
.static-page p a:hover { border-bottom-color: var(--ink); }
.static-page .dim { color: var(--ink-mute); font-size: var(--fs-md); }
.static-list {
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
}
.static-list li {
  font-size: var(--fs-base);
  line-height: 1.7;
  color: var(--ink-soft);
  padding: 10px 0 10px 18px;
  border-top: 1px solid var(--line-soft);
  position: relative;
}
.static-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 19px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-2);
}
.static-list li:last-child { border-bottom: 1px solid var(--line-soft); }

.info-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin: 22px 0 8px;
}
.info-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  background: var(--cream-soft);
}
.info-card .cadence {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--accent-2);
  background: var(--accent-2-bg);
  padding: 4px 8px;
  border-radius: var(--radius);
  margin-bottom: 8px;
}
.info-card .title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 6px;
}
.info-card .text {
  font-size: var(--fs-md);
  line-height: 1.55;
  color: var(--ink-mute);
}
@media (max-width: 640px) {
  .info-cards { grid-template-columns: 1fr; }
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 420px;
  margin-top: 24px;
}
.contact-form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
}
.contact-form input,
.contact-form textarea {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  color: var(--ink);
  background: var(--cream-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.contact-form textarea { min-height: 110px; resize: vertical; }
.contact-form input:focus,
.contact-form textarea:focus { outline: none; border-color: var(--accent-2); }
.contact-form button {
  align-self: flex-start;
  padding: 10px 22px;
  border: none;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--cream-soft);
  font-size: var(--fs-base);
  font-weight: 500;
  cursor: pointer;
  transition: background .15s ease;
}
.contact-form button:hover { background: var(--accent); }

/* ─── EXPLORER LAYOUT (sidebar + panel) ───────────────── */
.main-explorer {
  display: grid;
  grid-template-columns: 232px 1fr;
  gap: 28px;
  align-items: start;
}
.sidebar {
  position: sticky;
  top: 16px;
  /* align-self start: la sidebar arranca arriba en la columna, y como es
     hija de main grid, NO sobrepasa el final del main (que termina antes
     del footer) — eso evita la superposición con el footer. */
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  max-height: calc(100vh - 100px);
}
.sidebar-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;       /* clave para que flex-children no fuercen overflow */
  flex: 0 0 auto;
}
.sidebar-section[hidden] { display: none; }
/* Lista interna con scroll propio cuando hay muchos items. */
.sidebar-section .sidebar-list {
  overflow-y: auto;
  /* Padding-right pequeño para que el scrollbar no tape texto */
  padding-right: 4px;

  /* Scrollbar Firefox — fino, color terroso integrado con la paleta */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

/* Scrollbar WebKit (Chrome, Safari, Edge) — disimulado, acorde a la paleta */
.sidebar-section .sidebar-list::-webkit-scrollbar {
  width: 6px;
}
.sidebar-section .sidebar-list::-webkit-scrollbar-track {
  background: transparent;
}
.sidebar-section .sidebar-list::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: var(--radius);
  transition: background .2s;
}
.sidebar-section .sidebar-list::-webkit-scrollbar-thumb:hover {
  background: var(--ink-mute);
}

/* Misma estética para otros scrollables del sidebar y dropdown selects */
.sidebar::-webkit-scrollbar,
.sidebar-search::-webkit-scrollbar {
  width: 6px;
}
.sidebar::-webkit-scrollbar-track,
.sidebar-search::-webkit-scrollbar-track {
  background: transparent;
}
.sidebar::-webkit-scrollbar-thumb,
.sidebar-search::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: var(--radius);
}

/* Dark theme: subir un toque la opacidad para que sea visible */
body.dark-theme .sidebar-section .sidebar-list::-webkit-scrollbar-thumb {
  background: rgba(250, 244, 230, 0.12);
}
body.dark-theme .sidebar-section .sidebar-list::-webkit-scrollbar-thumb:hover {
  background: rgba(250, 244, 230, 0.25);
}
body.dark-theme .sidebar-section .sidebar-list {
  scrollbar-color: rgba(250, 244, 230, 0.12) transparent;
}
/* Alturas máximas por sección — calibradas para que las 3 entren en ~700-800px
   sin scrollear la página: LOTAS arriba, ESPECIES en el medio, CALIBRES abajo. */
#sidebarLotas      { max-height: 320px; }
/* "sem resultados" do buscador do sidebar */
.sidebar-empty {
  margin: var(--sp-2) 0 var(--sp-1);
  padding: 0 var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  opacity: .8;
}
#sidebarEspecies   { max-height: 280px; }
#sidebarCalibres   { max-height: 90px; }
/* Quando NÃO há espécie selecionada, a lista de lonjas pode ocupar mais.
   A regra antiga era `.sidebar-section[hidden] + .sidebar-section #sidebarLotas`,
   que dependia da secção escondida vir ANTES da das lonjas. Deixou de
   coincidir quando se acrescentou a secção PAÍS por cima, e ficou sem
   efeito sem que se notasse. `:has()` olha para a secção certa venha ela
   antes ou depois.
   O limite é relativo à janela porque a Galicia tem 56 lonxas (contra 17
   lotas em Portugal): num ecrã alto vê-se bastante mais sem scroll. */
.sidebar:has(#sidebarEspeciesWrap[hidden]) #sidebarLotas { max-height: min(520px, 52vh); }
.sidebar-section[hidden] + .sidebar-section #sidebarLotas { max-height: min(520px, 52vh); }
.sidebar-title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.sidebar-group {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sidebar-group-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--ink-mute);
  opacity: 0.7;
  text-transform: uppercase;
  padding: 6px 0 4px;
}
.sidebar-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.sidebar-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: var(--fs-md);
  color: var(--ink);
  background: transparent;
  border: 1px solid transparent;
  transition: background .12s ease, color .12s ease;
  text-align: left;
  font-family: inherit;
}
.sidebar-item {
  position: relative;
  transition: background .12s, color .12s, padding .12s;
}
.sidebar-item:hover {
  background: var(--accent-2-bg);
  color: var(--ink);
}
.sidebar-item:hover::before {
  /* Pequeña barra azul petróleo a la izquierda al hacer hover — sutil */
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--accent-2);
  border-radius: 0 2px 2px 0;
}
.sidebar-item.active {
  background: var(--ink);
  color: var(--cream);
  font-weight: 500;
}
.sidebar-item.active:hover {
  background: var(--ink);
}
.sidebar-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  background: var(--accent);
  border-radius: 0 2px 2px 0;
}
.sidebar-item .count {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  opacity: 0.55;
}
.sidebar-item.active .count {
  opacity: 0.75;
}
.sidebar-item.dim {
  opacity: 0.45;
  font-style: italic;
}
/* Data de uma lonja que a fonte deixou de publicar (ex.: MÁLAGA, parada em
   2024-12). Fica listada mas assinalada — nunca se esconde dado real, nem
   se mostra um preço antigo como se fosse actual. */
.sidebar-item .count.count-stale {
  color: var(--warn);
  opacity: 1;
  font-weight: 500;
}
/* Buscador rápido (especies) */
.sidebar-search {
  width: 100%;
  padding: 8px 10px;
  margin-bottom: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--ink);
  background: rgba(60, 50, 35, 0.04);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  letter-spacing: 0.03em;
  outline: none;
  transition: border-color .15s, background .15s;
}
.sidebar-search:focus {
  border-color: var(--ink);
  background: var(--cream);
}
.sidebar-search::placeholder {
  color: var(--ink-mute);
  opacity: 0.6;
}

/* Toggle "vendidas hoy / todas" */
.sidebar-toggle {
  width: 100%;
  padding: 6px 10px;
  margin-bottom: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  background: transparent;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  text-align: left;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: color .15s, border-color .15s, background .15s;
}
.sidebar-toggle:hover {
  color: var(--ink);
  border-color: var(--ink);
  background: rgba(60, 50, 35, 0.04);
}

/* Calibres en línea (compactos) */
.sidebar-list-inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 6px;
}
.sidebar-list-inline .sidebar-item {
  padding: 4px 10px;
  font-size: var(--fs-sm);
  border-radius: var(--radius-xl);
  border: 1px solid var(--line);
  flex: 0 0 auto;
}

/* Cuando hay sidebar visible (desktop), los dropdowns viejos quedan ocultos */
.main-explorer .filters { display: none; }

/* ─── MARKET BAR (franja superior con stats globales) ─── */
.market-bar {
  display: grid;
  /* 5 columnas FIJAS e iguales — no se reordenan al cambiar contenido,
     no varían según el ancho del texto. Layout estable. */
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  padding: 14px 28px;
  margin-bottom: 14px;
  background: rgba(60, 50, 35, 0.04);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  /* Transición suave cuando se actualiza el contenido al cambiar selección */
  transition: opacity 0.2s ease;
}
/* Cada stat con min-width 0 para que no estire la columna por contenido largo */
.market-bar .market-stat { min-width: 0; }
/* El número (valor) sí queda en una línea; el label (título arriba) puede
   envolver porque ahora es el encabezado y debe leerse completo. */
.market-bar .ms-num {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.market-stat {
  display: flex;
  flex-direction: column;
  /* Título (label) arriba, valor abajo. El label se separa del valor con
     algo de aire para jerarquía clara. */
  gap: 2px;
  padding: 4px 18px;
  border-right: 1px solid var(--line);
}
.market-stat:last-child { border-right: none; }
.market-stat .ms-num {
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-3xl);
  font-weight: 400;
  color: var(--ink);
  line-height: 1.05;
  letter-spacing: -0.01em;
}
.market-stat .ms-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.8;
  line-height: 1.25;
  margin-bottom: 4px;
  /* Título completo, sin recortar. Reserva 2 líneas para que los valores
     grandes queden alineados horizontalmente entre las 5 celdas. */
  white-space: normal;
  min-height: 2.4em;
  display: flex;
  align-items: flex-start;
}
.market-stat-soft .ms-num { color: var(--ink-mute); opacity: 0.5; }
.market-stat-soft .ms-label { opacity: 0.6; }

/* Sub-info bajo el valor (ej: lota donde ocurrió la mayor alza intra-día).
   Tipografía mono pequeña, color acento secundario para destacar discreto. */
.market-stat .ms-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.04em;
  color: var(--accent);
  margin-top: 4px;
  /* Nombre de lota completo — puede envolver a 2 líneas si es largo
     (ej. "Vila Real de Santo António") en vez de cortarse con "…". */
  white-space: normal;
  line-height: 1.25;
}

/* Cards 4 e 5 (peixe mais valorizado / preço mais em alta) — AMBOS em
   terracota. Antes o 5º era azul petróleo: duas células vizinhas, do mesmo
   nível hierárquico, em cores diferentes. O olho não sabia qual pesa mais e
   a barra lia-se como dois componentes colados. Um só acento de marca; a cor
   passa a marcar o que É a métrica destacada, não a dar variedade. */
.market-stat#msClima .ms-num { color: var(--accent); font-weight: 500; font-size: var(--fs-2xl); }
.market-stat#msBarcos .ms-num { color: var(--accent); font-weight: 500; opacity: 1; font-size: var(--fs-2xl); }
.market-stat#msClima.market-stat-soft .ms-num,
.market-stat#msBarcos.market-stat-soft .ms-num { color: var(--ink-mute); opacity: 0.4; font-weight: 400; font-size: var(--fs-3xl); }

/* Cards 4 y 5 con texto más largo: permitir wrap controlado en lugar de elipsis,
   y reducir font-size del valor para que entre cómodo */
.market-stat#msClima .ms-num,
.market-stat#msBarcos .ms-num {
  white-space: normal;
  line-height: 1.05;
  word-break: keep-all;
}

/* ─── BREADCRUMB ──────────────────────────────────────── */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  color: var(--ink-mute);
}
.breadcrumb[hidden] { display: none; }
.breadcrumb-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  background: var(--cream);
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--ink);
  transition: background .15s ease, transform .15s ease;
}
.breadcrumb-back:hover {
  background: var(--ink);
  color: var(--cream);
  transform: translateX(-2px);
}
.breadcrumb-trail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-transform: uppercase;
}
.breadcrumb-trail .crumb {
  cursor: pointer;
  transition: color .15s;
}
.breadcrumb-trail .crumb:hover { color: var(--ink); }
.breadcrumb-trail .crumb.current { color: var(--ink); font-weight: 500; }
.breadcrumb-trail .sep { opacity: 0.4; }

@media (max-width: 920px) {
  .market-bar {
    grid-template-columns: 1fr 1fr;
    padding: 12px 16px;
  }
  .market-stat { border-right: none; padding: 6px 10px; }
  .market-stat .ms-num { font-size: var(--fs-2xl); }
  .market-stat-soft { display: none; } /* ocultar las "próximamente" en mobile */
}

/* ─── PANORAMA (estado inicial) ──────────────────────── */
.panorama {
  padding: 22px 28px;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
}
.panorama[hidden] { display: none; }
.panorama-eyebrow {
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-transform: uppercase;
}
.panorama-title {
  margin: 0 0 8px;
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-display);
  font-weight: 400;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.panorama-meta {
  margin: 0 0 14px;
  font-size: var(--fs-md);
  color: var(--ink-mute);
}
/* ─── Mapa de Portugal con las 17 lotas ─── */
.panorama-meta-sub {
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.03em;
  color: var(--ink-mute);
  opacity: 0.7;
  font-style: italic;
}

/* Hero del panorama: propuesta de valor clara arriba */
.panorama-hero { margin-bottom: 12px; }
.panorama-pitch {
  margin: 6px 0 4px;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-style: italic;
  color: var(--ink-soft);
  line-height: 1.35;
  letter-spacing: -0.005em;
  max-width: 640px;
}

/* Buscador de la home: entrar directo a una especie o lota escribiendo. */
.home-search {
  position: relative;
  margin-top: 16px;
  max-width: 460px;
}
.home-search-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-mute);
  pointer-events: none;
}
#homeSearch {
  width: 100%;
  padding: 12px 14px 12px 40px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
}
#homeSearch:focus {
  outline: none;
  border-color: var(--accent);
}
.home-search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 32px rgba(0,0,0,0.16);
  overflow: hidden;
  max-height: 340px;
  overflow-y: auto;
}
.home-search-results[hidden] { display: none; }
.hs-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 10px 14px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
  text-align: left;
  transition: background .12s;
}
.hs-row:last-child { border-bottom: none; }
.hs-row:hover { background: var(--accent-2-bg); }
.hs-label {
  font-size: var(--fs-base);
  color: var(--ink);
}
.hs-type {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.7;
  flex-shrink: 0;
}

/* Insights da semana — sección "Bloomberg" con narrativas calculadas */
.panorama-insights {
  margin: 20px 0 24px;
  padding: 18px 20px;
  background: linear-gradient(180deg, var(--cream-soft) 0%, transparent 100%);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
}
.panorama-insights[hidden] { display: none; }
.insights-title {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.insights-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.insight-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--ink);
  cursor: pointer;
  transition: transform .15s, border-color .15s, box-shadow .15s;
  border-left: 3px solid var(--ink-mute);
}
.insight-card:hover {
  transform: translateY(-2px);
  border-color: var(--ink-mute);
  box-shadow: 0 4px 16px rgba(22, 20, 15, 0.08);
}
/* Colores por tipo de narrativa */
.insight-card.kind-busy    { border-left-color: var(--accent); }
.insight-card.kind-low     { border-left-color: #3f7a4d; }
.insight-card.kind-high    { border-left-color: #b8721a; }
.insight-card.kind-dormant { border-left-color: var(--ink-mute); opacity: 0.85; }
.insight-card.kind-luxury  { border-left-color: #8a5410; }
.insight-card.kind-spread  { border-left-color: var(--accent-2); }

.insight-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.85;
}
.insight-headline {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
  margin-top: 2px;
}
.insight-detail {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
  line-height: 1.45;
  margin-top: 4px;
}

@media (max-width: 800px) {
  .insights-grid { grid-template-columns: 1fr; }
}

/* Insights por lota: contexto distinto. Grid se adapta al número de cards (2-4),
   sin gradiente de fondo para diferenciarlo del panorama global. */
.lota-insights {
  margin: 16px 0 20px;
  padding: 14px 16px;
  background: transparent;
  border: 1px dashed var(--line);
}
.lota-insights .insights-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

/* Grid de regiones: 4 columnas con cards clickeables por lota.
   Reemplaza al mapa SVG (era visualmente confuso). */
.panorama-regions {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin: 16px 0 12px;
}
.region-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.region-head {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--ink-mute);
  margin: 0 0 4px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line-soft);
  letter-spacing: 0.01em;
}
.region-list { display: flex; flex-direction: column; gap: 2px; }
.region-item {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: transparent;
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-body);
  color: var(--ink);
  width: 100%;
  transition: background .12s;
}
.region-item:hover { background: var(--accent-2-bg); }
.region-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}
.region-dot.dot-active {
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(184, 57, 10, 0.18);
  animation: region-pulse 2.4s ease-in-out infinite;
}
@keyframes region-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(184, 57, 10, 0.18); }
  50%      { box-shadow: 0 0 0 5px rgba(184, 57, 10, 0.28); }
}
.region-dot.dot-quiet { background: var(--accent-2); opacity: 0.7; }
.region-dot.dot-stale { background: #ca8a04; opacity: 0.7; }
.region-dot.dot-cold  { background: var(--ink-mute); opacity: 0.4; }

.region-name {
  font-size: var(--fs-md);
  font-weight: 400;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.region-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.panorama-map-legend {
  margin: 12px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.04em;
  color: var(--ink-mute);
  text-align: right;
  opacity: 0.75;
}

@media (max-width: 900px) {
  .panorama-regions { grid-template-columns: 1fr 1fr; gap: 14px; }
}
@media (max-width: 520px) {
  .panorama-regions { grid-template-columns: 1fr; gap: 10px; }
}

.panorama-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}
.panorama-block { display: flex; flex-direction: column; gap: 10px; }
.panorama-section {
  margin: 0 0 4px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
}
.panorama-list { display: flex; flex-direction: column; gap: 4px; }
.panorama-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 14px;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--fs-md);
  transition: background .12s ease;
  border: 1px solid transparent;
}
.panorama-item:hover {
  background: rgba(60, 50, 35, 0.05);
  border-color: var(--line);
}
.panorama-item .pi-name {
  font-weight: 500;
  color: var(--ink);
}
.panorama-item .pi-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-mute);
}
.panorama-item .pi-price {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: #b87333;
  margin-left: 12px;
}
@media (max-width: 920px) {
  .panorama-grid { grid-template-columns: 1fr; gap: 24px; }
  .panorama { padding: 22px 20px; }
  .panorama-title { font-size: var(--fs-2xl); }
}

/* ─── CROSS-LOTA (especie en múltiples lotas) ─────────── */
.cross-lota {
  padding: 32px 36px;
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
}
.cross-lota[hidden] { display: none; }
.cross-eyebrow {
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-transform: uppercase;
}
.cross-title {
  margin: 0 0 8px;
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-display);
  font-weight: 400;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.cross-meta {
  margin: 0 0 24px;
  font-size: var(--fs-md);
  color: var(--ink-mute);
}
/* Lista vertical (no grid de cards). Comparar precios = escanear de
   arriba a abajo. Ancho completo, una fila por lota. */
.cross-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 720px;
}
/* Fila del comparador: nombre (ancho fijo, no se parte) · barra · precio · hora.
   Layout limpio de tabla, una fila por lota. */
.cross-row {
  display: grid;
  grid-template-columns: 190px 1fr 96px 52px;
  gap: 16px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid transparent;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
  transition: background .12s;
}
.cross-row:hover { background: var(--accent-2-bg); }
/* Fila más barata: fondo verde sutil + borde izquierdo */
.cross-row.is-cheapest {
  background: var(--accent-3-bg);
  border-left: 3px solid var(--accent-3);
  padding-left: 12px;
}
.cross-row .cr-lota {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.cross-row .cr-name {
  font-weight: 500;
  font-size: var(--fs-base);
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.cross-row .cr-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.cross-row .cr-region {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.6;
  white-space: nowrap;
}
/* Badge "+ barato" / "+ caro" */
.cr-badge {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 1px 4px;
  border-radius: var(--radius-md);
  font-weight: 600;
  flex-shrink: 0;
}
.cr-badge.cheap  { background: var(--accent-3-bg); color: var(--accent-3); }
.cr-badge.pricey { background: rgba(184,57,10,0.12); color: var(--accent); }
/* Barra de RANGO flotante: posicionada del piso al techo en el eje global.
   El carril (wrap) es el rango completo de todas las lonjas; cada barra ocupa
   sólo el tramo piso→techo de SU lota, por eso es absolute con left+width. */
.cr-bar-wrap {
  position: relative;
  height: 7px;
  background: var(--line-soft);
  border-radius: var(--radius);
}
.cr-bar {
  position: absolute;
  top: 0;
  height: 100%;
  min-width: 3px;
  background: linear-gradient(90deg, var(--accent-3) 0%, #b8721a 65%, var(--accent) 100%);
  border-radius: var(--radius);
  transition: left .3s, width .3s;
}
.cross-row.is-cheapest .cr-bar {
  box-shadow: 0 0 0 1px rgba(63,122,77,0.35);
}
/* Eje de referencia: piso y techo globales bajo la lista */
.cross-axis {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-soft);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--ink-mute);
}
.cross-axis .cr-axis-label {
  font-weight: 400;
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.6;
  text-align: center;
}

/* ─── Gráfico comparativo entre lotas (vista cross-lota) ─────────────── */
.cross-compare {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid var(--line-soft);
}
.cross-compare-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-style: italic;
  color: var(--ink);
  margin: 0 0 14px;
}
.cmp-selectors {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}
.cmp-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.cmp-row[hidden] { display: none; }
.cmp-row-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  opacity: 0.7;
  margin-right: 4px;
  min-width: 48px;
}
.cmp-chip {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  padding: 4px 10px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-mute);
  cursor: pointer;
  transition: all .12s ease;
  white-space: nowrap;
}
.cmp-chip:hover { color: var(--ink); border-color: var(--ink-mute); }
/* Chip de lota activo: borde + punto del color asignado a esa lota */
.cmp-chip.lota.on {
  color: var(--ink);
  border-color: var(--chip, var(--accent));
  box-shadow: inset 0 0 0 1px var(--chip, var(--accent));
  padding-left: 22px;
  position: relative;
}
.cmp-chip.lota.on::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--chip, var(--accent));
}
/* Chip de calibre activo */
.cmp-chip.cal.on {
  color: var(--cream-soft);
  background: var(--ink);
  border-color: var(--ink);
}
.cross-chart-wrap {
  background: var(--cream-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 18px 20px;
}
#crossChart { width: 100%; display: block; }
.cross-chart-wrap .chart-legend { margin-top: 12px; }
/* Leyenda estática (no toggle) del comparador: muestra la línea + etiqueta */
.legend-item.static { cursor: default; }
.legend-line {
  display: inline-block;
  width: 18px;
  height: 0;
  margin-right: 6px;
  vertical-align: middle;
}
.cross-row .cr-price {
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--ink);
  text-align: right;
  white-space: nowrap;
}
.cross-row.is-stale { opacity: 0.6; }
.cr-stale {
  display: inline-block;
  margin-right: 4px;
  font-size: var(--fs-xs);
  vertical-align: middle;
  cursor: help;
}
.cross-row .cr-hora {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-mute);
  opacity: 0.6;
  white-space: nowrap;
  text-align: right;
}
@media (max-width: 720px) {
  .cross-lota { padding: 22px 18px; }
  .cross-title { font-size: var(--fs-2xl); }
  /* En mobile: nombre + precio + hora (sin barra) */
  .cross-row { grid-template-columns: 1fr auto auto; gap: 12px; }
  .cross-row .cr-bar-wrap { display: none; }
}

/* ─── TABLET / DESKTOP MEDIO: sidebar oculto pero price-block sigue 2 col ─── */
@media (max-width: 920px) {
  /* En tablet/desktop estrecho, ocultar sidebar y volver a los dropdowns */
  .main-explorer {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .sidebar { display: none; }
  .main-explorer .filters { display: block; }
}

/* ─── MOBILE PURO: el price-block se apila vertical ─── */
@media (max-width: 720px) {
  .price-block { grid-template-columns: 1fr; gap: 28px; }
  .price-value { font-size: 68px; }
  .price-side { gap: 10px; }
  .filters-row { grid-template-columns: 1fr 1fr; }
  .filters-row .cta { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
  .topbar-inner, .nav-inner, .main, .footer-inner { padding-left: 20px; padding-right: 20px; }
  .main { padding-top: 36px; padding-bottom: 48px; }
  .nav-inner { flex-wrap: wrap; gap: 14px; }
  .logo { font-size: var(--fs-2xl); }
  .logo-divider, .logo-sub { display: none; }
  .filters-row { grid-template-columns: 1fr; }
  .empty-title { font-size: var(--fs-3xl); }
  .result-content { padding: 24px 20px; }
  .result-header { flex-direction: column; gap: 12px; }
  .result-title { font-size: var(--fs-4xl); }
  .price-value { font-size: 64px; }
  .footer-inner { padding: 36px 20px 28px; }
  .footer-tag { max-width: none; }
  .modal-row { grid-template-columns: 1fr; }
  .data-table th:nth-child(3), .data-table td:nth-child(3) { display: none; }
}


/* ── BUSCA PRINCIPAL ─────────────────────────────────────────────────────
   Passou do meio do panorama para o topo do painel: quem chega ao site vem
   procurar o preço de uma espécie concreta, não ler um panorama. Fica com
   mais presença do que tinha lá dentro, sem virar um banner. */
.home-search-primary {
  margin: 0 0 var(--sp-3);
  max-width: none;
}
.home-search-primary input {
  font-size: var(--fs-lg);
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
}
.home-search-primary .home-search-icon { opacity: .8; }
/* Região de cada resultado ("Lonja · Galicia"): sem isto, "Vigo" e "Peniche"
   apareciam lado a lado sem se perceber de que mercado eram. */
.hs-row .hs-type { white-space: nowrap; }


/* ── ACORDEÃO DE MERCADOS ────────────────────────────────────────────────
   As lotas do mercado escolhido abrem por baixo dele, dentro da mesma lista,
   em vez de viverem numa secção separada. Muda-se de mercado sem recarregar
   página e sem perder de vista onde se está. */
.mercado-item {
  font-weight: 500;
}
.mercado-item[aria-expanded="true"] {
  background: var(--accent-bg);
  color: var(--accent);
}
/* Seta que roda ao abrir — sinal de que o item tem conteúdo por baixo. */
.mercado-item::after {
  content: "";
  width: 0; height: 0;
  margin-left: auto;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: .45;
  transform: rotate(-90deg);
  transition: transform .18s ease, opacity .18s ease;
  flex: none;
}
.mercado-item[aria-expanded="true"]::after {
  transform: rotate(0deg);
  opacity: .9;
}

.mercado-gaveta {
  /* A gaveta cresce/encolhe conforme o mercado: Portugal tem 17 lotas,
     a Galicia 56 (com buscador), a Comunitat Valenciana 3. */
  overflow: hidden;
  animation: gavetaAbre .22s ease;
  margin: var(--sp-1) 0 var(--sp-2);
  padding-left: var(--sp-2);
  border-left: 1px solid var(--line-soft);
}
@keyframes gavetaAbre {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Dentro da gaveta a lista já não precisa do limite da secção antiga. */
.mercado-gaveta #sidebarLotas {
  max-height: min(420px, 46vh);
}
@media (prefers-reduced-motion: reduce) {
  .mercado-gaveta { animation: none; }
  .mercado-item::after { transition: none; }
  /* Havia sete animações infinitas a correr sempre (ticker, pulsos do
     relógio, do ponto "ao vivo", das regiões). Quem pede menos movimento
     está a pedir isso mesmo — e num site de números, movimento perpétuo
     cansa a quem passa lá o dia. */
  .ticker-marquee-track { animation: none !important; transform: none !important; }
  /* Sem animação, a faixa passa a arrastar-se à mão. Faltavam duas coisas:
     a barra de deslocamento ficava à vista por baixo dos preços (feio, e a
     dizer "isto está avariado"), e a máscara continuava a esbater o primeiro
     preço — o que fazia sentido enquanto as entradas passavam a correr, mas
     aqui só apaga a primeira lota, que está parada e completa.
     Fica sem barra, sem degradê à esquerda, e com o degradê da direita, que
     é o que diz "há mais, continua". */
  .ticker-marquee {
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent 100%);
  }
  .ticker-marquee::-webkit-scrollbar { display: none; }
  .dot::after,
  .topbar-dot,
  .clock-dot,
  .region-dot { animation: none !important; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── TICKER: parar debaixo do rato e do teclado ─────────────────────────
   Os pares lota+preço são links. A correr, são um alvo em movimento: nem o
   rato acerta bem, e num telemóvel (21px de altura, a deslizar) é
   impossível. Pára quando alguém se aproxima. */
.ticker-marquee:hover .ticker-marquee-track,
.ticker-marquee:focus-within .ticker-marquee-track {
  animation-play-state: paused;
}
/* O alvo de toque de 32px fazia-se aqui com `padding-block: 7px`, e era isso
   que cortava os preços: a caixa do par passava a medir 31px dentro de uma
   faixa de 24px com overflow:hidden. O alvo continua a existir — mas cresce
   a FAIXA INTEIRA nos ecrãs de toque (regra mais abaixo), em vez de crescer
   só a caixa dentro de uma janela que não a acompanha. */
.ticker-pair {
  padding-block: 0;
}
.ticker-pair:focus-visible {
  outline: 2px solid var(--cream-soft);
  outline-offset: 2px;
}

/* Em ecrãs de toque o ticker deixa de correr e passa a deslizar-se com o
   dedo: estático é utilizável, em movimento não é. */
@media (hover: none), (max-width: 720px) {
  /* `scrollbar-width` além do `::-webkit-scrollbar`: o segundo trata o
     Chrome e o Safari, o primeiro o Firefox. Só com um deles, metade dos
     visitantes via uma barra cinzenta por baixo dos preços. */
  .ticker-marquee { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .ticker-marquee::-webkit-scrollbar { display: none; }
  .ticker-marquee-track { animation: none !important; transform: none !important; }
  /* Já não corre, por isso não há nada a esconder nas bordas — e a máscara
     em cima de uma zona que se arrasta com o dedo só apagava o primeiro
     preço. */
  .ticker-marquee { -webkit-mask-image: none; mask-image: none; }
  /* A faixa toda cresce para 32px: é o alvo de toque, agora sem cortar nada. */
  .topbar-inner { padding-top: 6px; padding-bottom: 6px; }
  .ticker, .ticker-especie-zone { height: 32px; }
  .ticker-pair { height: 32px; line-height: 32px; }
  .ticker-sp-slide { line-height: 32px; }
}

/* Num telemóvel estreito o relógio comia 124px dos 390 disponíveis e deixava
   a zona de preços com 86px — larga demais para ser decorativa, estreita
   demais para se ler nela um preço. Entre saber a hora e ver um preço, num
   site de preços ganha o preço. */
@media (max-width: 560px) {
  .topbar-clock { display: none; }
  .ticker-especie-zone { width: 128px; }
}

/* ── FOCO VISÍVEL ───────────────────────────────────────────────────────
   Havia sete `outline: none` e zero `:focus-visible`: quem navega com
   teclado perdia o rasto de onde estava. O anel só aparece a quem navega
   por teclado, não a quem clica. */
:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
.select-wrap select:focus-visible,
.contact-form input:focus-visible,
.contact-form textarea:focus-visible,
.sidebar-search:focus-visible,
#homeSearch:focus-visible,
.nl-input:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 1px;
}

/* ── SALTAR PARA O CONTEÚDO ─────────────────────────────────────────────
   Primeiro tab da página: salta o cabeçalho e o ticker. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  background: var(--ink);
  color: var(--cream-soft);
  padding: 10px 16px;
  border-radius: 0 0 var(--radius) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}
.skip-link:focus {
  left: 0;
}

/* Título da página para leitores de ecrã e motores de busca: o site não
   tinha nenhum <h1>. Não se mostra porque o desenho já tem a marca. */
.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;
}


/* ── TOPBAR EM ECRÃS ESTREITOS ───────────────────────────────────────────
   A faixa "últimos dados disponíveis" tem 420px fixos, pensados para
   desktop. Num telemóvel não cabe: encolhe e trunca em vez de empurrar a
   página para o lado. */
@media (max-width: 720px) {
  .topbar-inner { padding-left: var(--sp-4); padding-right: var(--sp-4); gap: var(--sp-3); }
  .topbar-session {
    min-width: 0;
    max-width: 60vw;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}


/* ── DIRETÓRIO IBÉRICO ───────────────────────────────────────────────────
   Todas as lotas e lonjas cobertas, agrupadas por mercado, com clique
   directo. Substituiu a grelha só-Portugal e as listas de rankings: quem
   chega quer ver onde pode ir. São ~102 entradas, por isso é denso de
   propósito — cabe numa vista de olhos e não obriga a rolar à procura. */
.diretorio {
  display: block;
  margin: var(--sp-4) 0 var(--sp-3);
}
.diretorio-bloco { margin-bottom: var(--sp-6); }
.diretorio-bloco:last-child { margin-bottom: 0; }

.diretorio-mercado {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
  padding-bottom: var(--sp-1);
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-xl);
  color: var(--ink);
}
.diretorio-mercado .dm-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
}
.diretorio-cols {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-4);
  align-items: start;
}
@media (max-width: 1100px) { .diretorio-cols { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .diretorio-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px)  { .diretorio-cols { grid-template-columns: 1fr; } }


/* Selo de período no ticker: só aparece nas entradas espanholas, onde o
   preço NÃO é de hoje (mensal/semanal). Em Portugal é sempre o dia corrente. */
.ticker-per {
  margin-left: 5px;
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
  opacity: .6;
  text-transform: none;
}

/* ─── FORMULÁRIOS (contacto + subscrição) ──────────────────
   Estado do envio à vista: enquanto o endpoint não estiver configurado
   (js/forms.js), o botão fica desativado e aparece o aviso .form-msg.warn —
   nunca se anuncia um "obrigado" que não corresponde a nada enviado.
   Só usa tokens, por isso segue o tema escuro sem regras próprias. */
.form-msg {
  margin: 4px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.5;
  max-width: 420px;
}
.form-msg.ok   { color: var(--accent-3); }
.form-msg.err  { color: var(--accent); }
.form-msg.warn {
  color: var(--ink-mute);
  background: var(--accent-2-bg);
  border-left: 2px solid var(--accent-2);
  padding: 8px 12px;
  border-radius: var(--radius-xs);
}
.form-msg a { color: inherit; }
.contact-form button[disabled] {
  opacity: .45;
  cursor: not-allowed;
}
.contact-form button[disabled]:hover { background: var(--ink); }

.form-privacy {
  margin-top: 14px;
  font-size: var(--fs-sm);
  color: var(--ink-mute);
  max-width: 420px;
}

.subscribe-block {
  margin-top: 48px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.subscribe-block h2 {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  margin: 0 0 8px;
}
.subscribe-block p {
  max-width: 60ch;
  color: var(--ink-mute);
  margin: 0;
}
.subscribe-form { margin-top: 18px; }

/* ── O QUE AINDA NÃO É PÚBLICO ─────────────────────────────
   Uma linha, por baixo da fonte, a dizer o que existe e ainda não está
   aberto. Não é um muro: nada do que já se publica fica escondido atrás
   disto. Serve para medir procura — quem clica está a dizer-nos o que
   lhe faz falta, que é a pergunta que ainda não sabemos responder. */
.pro-note {
  margin: 6px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
  text-align: right;
  line-height: 1.6;
}
.pro-note a {
  color: var(--accent-2);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.modal-form .form-msg { margin-top: 10px; }

/* O painel é uma coluna de uma grelha. Sem `min-width: 0`, qualquer filho
   com um conteúdo mínimo largo (uma tabela, uma linha que não quebra) alarga
   a coluna, alarga a página e obriga o telemóvel a scroll horizontal — com o
   conteúdo cortado à direita, que é como isto se manifesta. Já aconteceu
   duas vezes; fica travado aqui de uma vez. */
.panel { min-width: 0; }

/* ─── PREÇOS DE HOJE (topo da página inicial) ─────────────────────────────
   Porque é que isto existe.

   A página inicial mostrava um DIRETÓRIO: 46 lotas e lonjas com a hora da
   última sessão, e nem um único preço em 3.100px de altura num telemóvel.
   Num site cujo produto é o preço da primeira venda, quem chegava tinha de
   escolher mercado, lota, espécie e calibre — quatro decisões — antes de ver
   o primeiro número. É o equivalente a uma tabacaria que esconde os jornais.

   Não se mostram preços de mercados diferentes lado a lado: é a regra que já
   tinha tirado os preços daqui, e mantém-se. A saída não é mostrar nada, é
   mostrar UM mercado de cada vez com o seu período à vista no cabeçalho —
   "Portugal · 2 setembro" ou "Andalucía · agosto 2026". Assim nunca se soma
   um diário português a uma média mensal andaluza. */
.hoje {
  margin: 0 0 30px;
}
.hoje-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.hoje-eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
}
/* O período é a peça honesta deste bloco: diz de QUANDO são os números.
   Nunca fica vazio — se não houver período, o bloco não se mostra. */
.hoje-per {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink);
}
.hoje-per b { font-weight: 600; }
.hoje-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(184px, 1fr));
  gap: 10px;
}
.hoje-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.hoje-card:hover {
  border-color: var(--ink-mute);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.hoje-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.hoje-esp {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
  /* Nomes como "Areeiro-de-4-manchas" não podem empurrar o preço para baixo
     e desalinhar a grelha inteira. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hoje-px {
  font-family: var(--font-display);
  /* 20px e nao 24px: a €12,62-€21,98 (o intervalo mais largo do dia) o
     numero de 24px partia-se em duas linhas e o cartao ficava mais alto do
     que os vizinhos. Uma grelha que salta le-se pior do que uma grelha com
     numeros um degrau mais pequenos. */
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: 1.15;
  color: var(--ink);
  letter-spacing: -0.01em;
  white-space: nowrap;
}
/* Os dois numeros do intervalo tem o MESMO tamanho, de proposito.
   A primeira versao punha o minimo grande e o maximo pequeno, e ficava
   "€0,51" enorme ao lado de "PESCADA-BRANCA" -- quem passasse o olho levava
   dali que a pescada esta a 51 centimos, quando o intervalo do dia vai ate
   €31,00. O minimo costuma ser um lote de calibre baixo; sozinho, mente. Um
   intervalo e a unica coisa que estes dados sustentam, e e assim que se
   mostra. */
.hoje-px small {
  font-size: inherit;
  color: var(--ink);
}
.hoje-px .hoje-sep {
  font-size: var(--fs-md);
  color: var(--ink-mute);
  padding: 0 3px;
}
.hoje-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
}
.hoje-foot {
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-mute);
}
@media (max-width: 560px) {
  .hoje-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .hoje-card { padding: 12px 12px; }
  /* Dois numeros de 6 caracteres cada num cartao de 170px: o intervalo passa
     a duas linhas em vez de encolher ate nao se ler. */
  .hoje-px   { font-size: var(--fs-lg); line-height: 1.25; }
  .hoje-px .hoje-sep { font-size: var(--fs-sm); }
}

/* ─── DIRETÓRIO DE LOTAS: recolhido por omissão ───────────────────────────
   As 46 lotas continuam a uma abertura de distância, mas deixam de ser a
   primeira coisa da página. No computador já estão todas na barra lateral,
   por isso aqui eram uma segunda lista da mesma coisa. */
.diretorio {
  margin-top: 26px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
}
.diretorio > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  padding: 6px 0;
}
.diretorio > summary::-webkit-details-marker { display: none; }
.diretorio > summary:hover { color: var(--ink); }
.diretorio > summary::before {
  content: "+";
  font-size: var(--fs-md);
  line-height: 1;
  color: var(--ink-mute);
}
.diretorio[open] > summary::before { content: "–"; }
.diretorio > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.diretorio-corpo { padding-top: 16px; }

/* ─── FILTROS RECOLHIDOS NO TELEMÓVEL ─────────────────────────────────────
   Os quatro selects (mercado, lota, espécie, calibre) mais o botão ocupavam
   445px — mais de metade do primeiro ecrã de um telemóvel — antes de existir
   um único preço na página. Passam a estar atrás de um botão. A caixa de
   busca, essa, fica sempre visível: é o caminho mais curto para quem já sabe
   o que procura. */
.filters-toggle { display: none; }
@media (max-width: 900px) {
  .filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    justify-content: center;
    padding: 12px 16px;
    margin-bottom: 4px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    letter-spacing: var(--tracking-sm);
    text-transform: uppercase;
    color: var(--ink-soft);
  }
  .filters-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .filters-toggle .ft-caret { transition: transform .15s ease; }
  .filters-toggle[aria-expanded="true"] .ft-caret { transform: rotate(180deg); }
  .filters-toggle[aria-expanded="true"] { margin-bottom: 14px; }
  /* A etiqueta "DADOS EM TEMPO REAL · DOCAPESCA" era um rótulo do bloco de
     filtros; sem o bloco aberto ficava a pairar sozinha. */
  .filters-label { display: none; }
  .filters { margin-bottom: 22px; }
}

/* ─── BARRA DE CONTEXTO NO TELEMÓVEL ──────────────────────────────────────
   Ao abrir a ficha de uma espécie, esta barra media 228px de altura num
   telemóvel: cinco caixas em duas colunas, cada uma com um número de 24px e
   um rótulo que dava a volta em três linhas. Somada ao cabeçalho e à busca,
   empurrava o preço — a razão pela qual a pessoa entrou — para 559px abaixo
   do topo, e o site tinha de saltar sozinho para lá. Era isto que se sentia
   como "a página abre a meio".

   Em vertical passa a ser uma lista de "rótulo … valor", uma linha por
   facto: 5 linhas de 26px em vez de 228px, e continua a dizer exactamente o
   mesmo. Um número de 24px não vale 100px de altura roubados ao preço. */
@media (max-width: 620px) {
  .market-bar {
    display: block;
    padding: 6px 14px;
  }
  .market-stat {
    flex-direction: row;
    flex-wrap: wrap;   /* sem isto, a sub-linha de baixo alargava a página */
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0;
    border-right: none;
    border-bottom: 1px solid var(--line-soft);
    min-width: 0;
  }
  .market-stat:last-child { border-bottom: none; }
  .market-stat .ms-label {
    /* O min-height de 2.4em existia para alinhar cinco números lado a lado.
       Numa lista vertical não há nada para alinhar, e só fazia altura. */
    min-height: 0;
    margin-bottom: 0;
    font-size: var(--fs-2xs);
    flex: 1 1 auto;
  }
  .market-stat .ms-num {
    font-size: var(--fs-lg);
    flex: 0 0 auto;
    text-align: right;
  }
  /* `flex: 0 0 100%` numa linha que não quebra é um pedido impossível: o
     item não pode encolher e exige 100% da largura do pai, e o pai passa a
     medir-se pelo item. Resultado: a página inteira ficava 449px de largura
     num ecrã de 390 e o utilizador via os valores cortados à direita, com
     scroll horizontal. Com `1 1 100%` e a linha a quebrar, ocupa a linha
     seguinte, que é o que se queria. */
  .market-stat .ms-sub { flex: 1 1 100%; min-width: 0; text-align: right; }
  /* Duas das cinco linhas apareciam a terracota — herança das células que
     em tempos eram "clima" e "barcos no mar" e ganhavam cor ao ter dado.
     Numa lista vertical isso lê-se como aviso: "MAIS BARATO T5 €1,84" a
     vermelho parece um alerta, e é só mais um facto. Todas iguais. */
  .market-stat#msClima .ms-num,
  .market-stat#msBarcos .ms-num {
    color: var(--ink);
    font-weight: 400;
    font-size: var(--fs-lg);
  }
}

/* ─── ESTADO DA LOTA NA BARRA LATERAL ─────────────────────────────────────
   Ponto de cor + duas palavras, no sítio onde antes estava uma hora que não
   dizia nada. O nome da lota tem prioridade sobre o estado: quando não cabem
   os dois, é o estado que encolhe. */
.estado-lota {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  min-width: 0;
}
.estado-lota .estado-txt {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.estado-lota .region-dot { width: 6px; height: 6px; }

/* Amarelo-âmbar para "ainda não": não é um problema, é uma espera. Não podia
   reutilizar o dot-stale (a fonte parada, que é um problema) nem o dot-cold
   (não há nada hoje), porque são três coisas diferentes. */
.region-dot.dot-wait {
  background: #ca8a04;
  opacity: 0.55;
  box-shadow: 0 0 0 2px rgba(202, 138, 4, 0.14);
}

/* ─── CABEÇALHO NUMA LINHA NO TELEMÓVEL ───────────────────────────────────
   Era `flex-wrap: wrap` com o logótipo em cima e os botões em baixo: 197px
   de cabeçalho antes de qualquer conteúdo, num ecrã de 844. Passa a uma
   linha só, com o botão de alerta reduzido ao sino — a chamada com texto
   mudou-se para junto dos preços (.cta-alerta), que é onde faz sentido. */
@media (max-width: 640px) {
  .nav-inner {
    flex-wrap: nowrap;
    gap: 10px;
    padding-top: 12px;
    padding-bottom: 12px;
  }
  .logo { font-size: var(--fs-2xl); flex: 0 1 auto; min-width: 0; white-space: nowrap; }
  .nav-actions { gap: 8px; flex: 0 0 auto; }
  .lang-btn { padding: 6px 9px; }
  /* Sino sem texto: alvo de 36px, que é acima do mínimo confortável. */
  .alert-btn { padding: 0; width: 36px; height: 36px; justify-content: center; }
  .alert-btn-txt { display: none; }
}
/* Ecrãs muito estreitos (≤360px): o seletor de idioma é o que menos falta
   faz numa primeira visita — o site já arranca no idioma do browser. */
@media (max-width: 360px) {
  .lang-switch { display: none; }
}

/* ─── CHAMADA PARA CRIAR ALERTA ───────────────────────────────────────────
   Estava só no cabeçalho, como botão permanente: presente em todo o lado e
   pertinente em lado nenhum. Passa a aparecer duas vezes, sempre a seguir a
   preços — na página inicial depois da grelha, e na ficha depois do preço da
   espécie, aí com o nome da espécie e da lota lá dentro. É o momento em que
   a pessoa acabou de ver um número e pensa "e amanhã?". */
.cta-alerta {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin: 18px 0 0;
  padding: 14px 18px;
  text-align: left;
  background: var(--accent-bg);
  border: 1px solid rgba(184, 57, 10, 0.22);
  border-radius: var(--radius-lg);
  color: var(--ink);
  font-size: var(--fs-body);
  transition: background .15s ease, border-color .15s ease, transform .12s ease;
}
.cta-alerta:hover {
  background: rgba(184, 57, 10, 0.13);
  border-color: rgba(184, 57, 10, 0.42);
}
.cta-alerta:active { transform: translateY(1px); }
.cta-alerta:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cta-alerta-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
}
.cta-alerta-txt { flex: 1 1 auto; min-width: 0; line-height: 1.35; }
.cta-alerta-txt b { font-weight: 600; }
.cta-alerta-seta {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  color: var(--accent);
  opacity: .8;
}
@media (max-width: 560px) {
  .cta-alerta { padding: 12px 14px; gap: 10px; font-size: var(--fs-md); }
  .cta-alerta-seta { display: none; }
}


/* ─── O NOME DA LOTA NUNCA PARTE EM DUAS LINHAS ───────────────────────────
   Com o estado ao lado ("A DECORRER"), "Póvoa de Varzim" deixava de caber e
   partia-se, e essa linha da lista ficava com o dobro da altura das outras.
   Numa lista, uma linha mais alta lê-se como se fosse outra coisa. O nome
   encolhe com reticências; o estado, que é curto e fixo, não encolhe. */
.sidebar-item > span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── SEM BARRA LATERAL: UMA COLUNA SÓ ────────────────────────────────────
   A barra lateral tinha três listas — mercado, lotas, espécies — e as três
   já existiam na coluna principal. Duas listas da mesma coisa não ajudam:
   obrigam a pessoa a decidir em qual olhar. Fica uma coluna, igual no
   telemóvel e no computador, e menos uma coisa para manter em sincronia.

   O <aside> deixou de existir no HTML; estas regras existem para o caso de
   alguma página antiga ainda o trazer. */
.main-explorer { display: block; }
.sidebar { display: none; }

/* Os filtros (lota · espécie · calibre) eram só do telemóvel porque no
   computador a barra lateral fazia esse trabalho. Sem ela, o botão e o painel
   passam a existir em todos os tamanhos. */
.filters-toggle { display: inline-flex; }

/* ─── PASSO 1: ESCOLHER MERCADO ───────────────────────────────────────────
   Três fichas, não um menu fechado: vê-se de uma vez o que existe, e cada
   uma diz a cadência da fonte antes de se clicar. Um preço diário e uma
   média mensal não são a mesma coisa, e isso tem de estar à vista antes da
   escolha, não depois. */
.mercados {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.mercado-ficha {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 18px;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color .14s ease, background .14s ease;
}
.mercado-ficha:hover { border-color: var(--ink-mute); }
.mercado-ficha:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* O mercado activo distingue-se por fundo e borda, não só por uma cor de
   texto: num ecrã ao sol, ou para quem não distingue bem cores, a cor
   sozinha não chega. */
.mercado-ficha.ativo {
  background: var(--ink);
  border-color: var(--ink);
}
.mercado-ficha.ativo .mercado-nome { color: var(--cream-soft); }
.mercado-ficha.ativo .mercado-cad  { color: var(--cream-soft); opacity: .7; }
.mercado-nome {
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
}
.mercado-cad {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-mute);
}
@media (max-width: 560px) {
  .mercados { grid-template-columns: 1fr; gap: 8px; }
  .mercado-ficha { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 14px; }
  .mercado-nome { font-size: var(--fs-body); }
}

/* Os filtros existiam só no telemóvel (`.main-explorer .filters {display:none}`
   mais acima) porque no computador a barra lateral fazia esse trabalho. Sem
   barra lateral, existem em todos os tamanhos — e recolhidos por omissão em
   todos, que é o que já se fazia no telemóvel e funcionava. */
.main-explorer .filters { display: block; }
.filters-label { display: none; }
.filters-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  justify-content: center;
  padding: 12px 16px;
  margin-bottom: 4px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.filters-toggle:hover { border-color: var(--ink-mute); }
.filters-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.filters-toggle .ft-caret { transition: transform .15s ease; }
.filters-toggle[aria-expanded="true"] .ft-caret { transform: rotate(180deg); }
.filters-toggle[aria-expanded="true"] { margin-bottom: 14px; }
.filters { margin-bottom: 22px; }
/* Três campos e o botão: o mercado saiu para as fichas do topo. */
.filters-row { grid-template-columns: 1fr 1fr 1fr auto; }
@media (max-width: 900px) { .filters-row { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .filters-row { grid-template-columns: 1fr; } }

/* O diretório deixou de ser uma gaveta: é a lista de lotas da página. */
.diretorio-aberto {
  margin-top: 20px;
  border-top: 1px solid var(--line);
  padding-top: 6px;
}

/* Nas páginas de texto, um link tem de parecer um link. O reset global tira
   o sublinhado a todos os <a> (faz sentido nos botões e nas listas), mas no
   meio de um parágrafo isso deixa "aviso legal" com exactamente o mesmo
   aspecto do texto à volta — ninguém adivinha que se pode clicar. */
.static-page p a,
.static-page li a {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--line);
  transition: text-decoration-color .15s ease;
}
.static-page p a:hover,
.static-page li a:hover { text-decoration-color: var(--accent); }

/* ─── FORMULÁRIO DE PEDIDO ────────────────────────────────────────────────
   Linha de contexto: diz de que ecrã veio o pedido. Sem ela, quem abre o
   formulário a partir da ficha do carapau em Portimão tem a sensação de
   estar a escrever para o vazio — e do nosso lado chegaria um email sem
   pista nenhuma sobre o que a pessoa andava a ver. */
.modal-contexto {
  margin: 0 0 16px;
  padding: 8px 12px;
  background: var(--accent-bg);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-sm);
  color: var(--ink-soft);
}
.modal-contexto b { font-weight: 600; color: var(--ink); }
.modal-contexto span { opacity: .7; text-transform: uppercase; }

/* As opções são caixas de verificação a sério, disfarçadas de etiquetas:
   funcionam com teclado e com leitor de ecrã, ao contrário de uma <div>
   com um onclick. */
.modal-chips {
  border: 0;
  padding: 0;
  margin: 0 0 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.modal-chips legend {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 10px;
  padding: 0;
}
.modal-chips .chip {
  /* `.modal-form label` põe `flex-direction: column` — é o que faz sentido
     para "Email" em cima do campo. Aqui a caixa e o texto vão lado a lado,
     e é preciso dizê-lo: sem isto o quadradinho ficava por cima do texto e
     cada opção ocupava uma linha inteira. */
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  width: auto;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-body);
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: var(--fs-md);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.modal-chips .chip:hover { border-color: var(--ink-mute); }
.modal-chips .chip input { accent-color: var(--accent); margin: 0; }
.modal-chips .chip:has(input:checked) {
  background: var(--accent-bg);
  border-color: var(--accent);
  color: var(--ink);
}
.modal-chips .chip:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

.modal-form textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-family: inherit;
  font-size: var(--fs-base);
  color: var(--ink);
  resize: vertical;
  min-height: 76px;
}
.modal-form textarea:focus { outline: none; border-color: var(--ink); }

/* ─── O FORMULÁRIO CRESCEU: TEM DE CABER ──────────────────────────────────
   Com as opções e a caixa de texto, a janela passou a medir 941px. Num
   telemóvel de 844 ficava centrada e cortada nas duas pontas: o botão de
   fechar caía 34px ACIMA do ecrã, sem forma de lá chegar. Uma janela que não
   se consegue fechar é uma armadilha.

   `align-items: center` com `overflow: auto` não resolve — é um defeito
   antigo do flexbox: o que passa do topo fica inalcançável. A forma correta
   é alinhar ao topo e centrar com `margin: auto`, que centra quando há
   espaço e não corta quando não há. */
.modal-backdrop {
  align-items: flex-start;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal-backdrop .modal { margin: auto; }

@media (max-width: 560px) {
  .modal-backdrop { padding: 12px; }
  .modal { padding: 28px 20px 24px; }
  .modal-chips .chip { font-size: var(--fs-base); padding: 7px 11px; }
}
