/* ==========================================================================
   Fruites Jiménez — hoja de estilos
   Concepto: "el mercado a las 5 de la madrugada"
   Tokens y dirección: ver PLAN-IMPLEMENTACION.md
   ========================================================================== */

/* ---------- Tipografías ---------- */
/* Alojadas aquí desde el 2026-10-29: antes venían de Google Fonts, que recibía la IP de
   cada visitante en cada página y añadía dos conexiones a otro dominio antes de pintar.
   Ficheros en assets/fonts/, con su licencia (OFL.txt). Bricolage e Instrument Sans son
   variables: un solo fichero cubre todos los pesos. Cada familia va en dos subconjuntos;
   el navegador solo baja latin-ext si la página usa algún carácter de ese rango.
   Las dos primeras se precargan en el <head> de cada página: son las del héroe. */
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 500 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 500 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  --paper: #ffffff;
  --paper-tint: #f3f7eb;
  --ink: #1f2a16;
  --ink-soft: #46543a;
  --board: #212e17;
  --board-line: #38492a;
  --naranja: #f08a00;
  --naranja-deep: #b25f00;
  --verde: #85bb3a;
  --verde-deep: #4f7d1b;
  --linea: #dce5ce;

  --font-display: "Bricolage Grotesque", "Arial Black", sans-serif;
  --font-body: "Instrument Sans", "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", "Consolas", monospace;

  --wrap: 1120px;
  --radius: 10px;
  --sombra: 0 12px 32px rgba(31, 42, 22, 0.10);
}

/* ---------- Reset ligero ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
/* scroll-padding-top = altura de la cabecera sticky + holgura. Va por tramos porque la
   cabecera no mide lo mismo en todos: 68px a partir de 1121, 112px entre 861 y 1120
   —donde la navegación baja a una segunda fila— y 60px por debajo de 861. Con un solo
   valor de 80px, en el tramo de dos filas el borde de la sección quedaba 32px por
   debajo de la cabecera al pulsar un ancla.
   Los tres valores tienen que quedar POR ENCIMA del umbral del scroll-spy
   (altura de cabecera + 28 en capcalera.js), o al pulsar se marcaría la sección
   anterior. Ver CLAUDE.md §6.5. */
html { scroll-behavior: smooth; scroll-padding-top: 80px; overflow-x: clip; }
@media (max-width: 1120px) and (min-width: 861px) { html { scroll-padding-top: 124px; } }
@media (max-width: 860px) { html { scroll-padding-top: 72px; } }
body {
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
/* Las fotos llevan width/height en el HTML (reservan hueco y evitan saltos). Sin esto,
   max-width estrecha el ancho pero el alto del atributo se queda: la foto se estira en
   cuanto su regla de clase no llega (CSS antiguo en caché, fallo de carga). */
img { height: auto; }
input, button, select, textarea { font: inherit; color: inherit; }
/* sin el retardo del doble toque para hacer zoom en los controles */
a, button, summary, label { touch-action: manipulation; }
ul { padding: 0; }

/* ---------- Utilidades ---------- */
.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: clamp(1.1rem, 4vw, 2rem); }
.u-naranja { color: var(--naranja); }
/* naranja sobre claro: el único que pasa AA (GUIA-ESTETICA §2.2) */
.u-naranja-deep { color: var(--naranja-deep); }
/* Tramos horarios («08:30–14:00»): que la línea parta entre tramos, nunca a media hora.
   Solo se aplica a piezas cortas, así que no puede ensanchar nada ni con texto al 200 %. */
.u-nowrap { white-space: nowrap; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
.skip-link {
  /* se esconde con su propia altura, no con un `top` fijo: con el texto al 200 % el
     enlace mide más de 3.5rem y asomaba por encima de la barra de utilidades */
  position: absolute; left: 1rem; top: 0; z-index: 100;
  transform: translateY(-110%);
  background: var(--ink); color: var(--paper);
  padding: 0.6rem 1rem; border-radius: 0 0 var(--radius) var(--radius);
  text-decoration: none; transition: transform 0.15s ease;
}
.skip-link:focus { transform: none; }

:focus-visible {
  outline: 3px solid var(--naranja);
  outline-offset: 2px;
  border-radius: 2px;
}
/* Destinos del skip-link: reciben el foco por programa para que el siguiente Tab siga
   desde el contenido, pero no son controles. Un anillo naranja rodeando media pantalla
   sería ruido. Los elementos que sí se tabulan llevan tabindex="0" y no entran aquí. */
[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline: none; }

/* ---------- Tipografía ---------- */
/* Los titulares van en cuerpos grandes (el h2 llega a 3rem) y el catalán trae palabras
   largas: «Instal·lacions», «magatzem», «col·lectivitats». En una pantalla de 320px con
   el texto ampliado al 200% ninguna de esas cabe en una línea, y sin poder partirlas
   ensanchaban la maquetación. `break-word` solo rompe cuando no hay más remedio, así que
   al tamaño normal no cambia ni un salto de línea. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.05;
  letter-spacing: -0.01em;
  text-wrap: balance;
  overflow-wrap: break-word;
}
h2 { font-size: clamp(1.9rem, 4.2vw, 3rem); font-weight: 800; }
h3 { font-size: 1.25rem; font-weight: 700; line-height: 1.2; }

.eyebrow {
  font-family: var(--font-mono);
  overflow-wrap: break-word;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--verde-deep);
  margin-bottom: 0.9rem;
}
.eyebrow--board { color: var(--verde); }

.section-sub {
  max-width: 46ch;
  color: var(--ink-soft);
  margin-top: 0.9rem;
}

/* ---------- Botones ---------- */
.btn {
  display: inline-block;
  font-weight: 600;
  text-decoration: none;
  text-align: center;
  border: 2px solid transparent;
  border-radius: 999px;
  padding: 0.62rem 1.35rem;
  cursor: pointer;
  /* con el texto ampliado, «Contacta'ns per a col·lectivitats» no cabe en una línea de
     móvil: que parta la palabra antes que ensanchar la tarjeta y sacar la página de la
     pantalla. `break-word` solo rompe cuando no hay más remedio; `anywhere` partiría
     también donde sí cabe. */
  max-width: 100%;
  overflow-wrap: break-word;
  transition: transform 0.12s ease, background-color 0.15s ease,
              color 0.15s ease, border-color 0.15s ease;
}
.btn:active { transform: scale(0.97); }

.btn-primary {
  background: var(--naranja);
  color: var(--ink);
}
.btn-primary:hover { background: #ffa227; }

.btn-ghost {
  border-color: var(--ink);
  color: var(--ink);
  background: transparent;
}
.btn-ghost:hover { background: var(--ink); color: var(--paper); }

.btn-line {
  border-color: var(--verde-deep);
  color: var(--verde-deep);
  background: transparent;
}
.btn-line:hover { background: var(--verde-deep); color: var(--paper); }

.btn-big { padding: 0.85rem 1.8rem; font-size: 1.05rem; }

/* ---------- Barra de utilidades (nivel 1) ----------
   Servicio, no navegación: estado de la atención telefónica y teléfono. El conmutador
   de idioma que había aquí se retiró el 2026-09-09 (la web es solo en catalán, §5).
   No es sticky — se va con el scroll para que lo que se queda pegado sea solo la
   cabecera. Registro de albarán: monoespaciada sobre tinta. */
.topbar {
  background: var(--ink);
  color: #dfe8d1;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
}
.topbar-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  min-height: 34px;
}
.topbar a { color: inherit; text-decoration: none; }

/* estado de apertura: el punto es el único color de la barra */
.topbar-estat { display: flex; align-items: center; gap: 0.45rem; min-width: 0; }
.topbar-estat[hidden] { display: none; }
.estat-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.estat-punt {
  width: 7px; height: 7px; border-radius: 50%;
  background: #9dab88; flex-shrink: 0;
}
.es-obert  .estat-punt { background: var(--verde); box-shadow: 0 0 0 3px rgba(133, 187, 58, 0.22); }
.es-aviat  .estat-punt { background: var(--naranja); }
.es-tancat .estat-punt { background: #9dab88; }

.topbar-eines { display: flex; align-items: center; gap: 1rem; flex-shrink: 0; }

.topbar-tel {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-weight: 600;
  padding-block: 0.2rem;
  border-bottom: 1px solid transparent;
}
.topbar-tel svg { width: 14px; height: 14px; flex-shrink: 0; }
.topbar-tel:hover { color: var(--paper); border-bottom-color: var(--verde); }

/* ---------- Cabecera (nivel 2, sticky) ---------- */
.header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--linea);
}
.header.is-scrolled { box-shadow: 0 4px 18px rgba(31, 42, 22, 0.08); }

/* tres grupos separados por espacio, no por adorno: marca | navegación | acciones */
/* `flex-wrap` es un seguro, no una decisión de maquetación: con el texto al tamaño normal
   sobran 8px en el peor ancho (medido a 320, 360, 375 y 390), así que nunca llega a
   plegarse. Solo salta cuando el visitante amplía el texto —a 200% la etiqueta larga del
   CTA mide 292px— y sin él la barra desbordaba a lo ancho incluso a 1440px. Plegar es
   peor que caber, pero mucho mejor que sacar la página de la pantalla. */
.header-in {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: clamp(1.2rem, 3vw, 2.6rem);
  min-height: 68px;
}

/* Logo bicolor sin placa (2026-10-28). El verde lima del logo oficial sobre blanco da
   1,68:1 y no se lee; hasta hoy iba dentro de una placa de tinta, que se leía como una
   etiqueta pegada. En la cabecera va ahora una versión con los verdes pasados a
   --verde-deep (logo-germans-jimenez-bicolor-*.png) directamente sobre el blanco; el
   naranja del fruto se queda. El pie, que es de tinta, sigue con el logo original.
   PENDIENTE: el bicolor modifica el logo oficial; lo tiene que aprobar el cliente. */
.brand {
  display: flex; align-items: center; gap: 0.5rem;
  text-decoration: none; color: inherit;
  flex-shrink: 0;
}
/* Logo oficial (PNG, 2026-10-22): rótulo «Germans Jiménez» con el fruto. Sustituye al
   icono recreado + el nombre en texto; el nombre accesible lo da el aria-label del enlace.
   Se fija la altura y el ancho sale de la proporción del fichero (2,59:1). A 46px el rótulo
   medía ~8px y no se leía. Sin placa crece lo que ocupaba el marco: 56px en escritorio, 48
   por debajo de 560 y 46 por debajo de 390, con el mismo ancho que tenía la placa, así que
   los cortes medidos de la barra siguen valiendo. Los ficheros salen ya escalados del
   original (150/300/450w) para que el navegador no reduzca 3,5× uno grande. */
.brand-logo { height: 56px; width: auto; flex-shrink: 0; }

/* la navegación ocupa el centro y empuja las acciones al extremo */
.nav { margin-right: auto; }
.nav-links {
  display: flex; gap: clamp(0.9rem, 1.8vw, 1.6rem); list-style: none;
}
.nav-links a {
  position: relative;
  display: block;
  text-decoration: none; color: var(--ink-soft);
  font-weight: 500; font-size: 0.95rem;
  white-space: nowrap;
  padding-block: 0.35rem;
  transition: color 0.15s ease;
}
/* subrayado que crece desde el centro: sin salto de layout al pasar por encima */
.nav-links a::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--naranja);
  transform: scaleX(0);
  transition: transform 0.18s ease;
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after { transform: scaleX(1); }
/* sección en pantalla: el tic de marca — «lo de ahora, encendido» */
.nav-links a.is-actiu { color: var(--ink); font-weight: 600; }
.nav-links a.is-actiu::after { transform: scaleX(1); }

/* enlaces que solo existen dentro del menú desplegable */
.nav-nomes-mobil { display: none; }

.nav-toggle {
  display: none;
  align-items: center; gap: 0.5rem;
  background: none; border: 1px solid var(--linea);
  border-radius: 999px; padding: 0.4rem 0.9rem;
  font-weight: 600; font-size: 0.9rem; cursor: pointer;
}
.nav-toggle-bar {
  width: 16px; height: 2px; background: var(--ink);
  position: relative;
  transition: background-color 0.15s ease;
}
.nav-toggle-bar::before, .nav-toggle-bar::after {
  content: ""; position: absolute; left: 0;
  width: 16px; height: 2px; background: var(--ink);
  transition: transform 0.18s ease, top 0.18s ease;
}
.nav-toggle-bar::before { top: -5px; }
.nav-toggle-bar::after { top: 5px; }
/* abierto: las tres barras se convierten en una X */
.nav-toggle.is-open .nav-toggle-bar { background: transparent; }
.nav-toggle.is-open .nav-toggle-bar::before { top: 0; transform: rotate(45deg); }
.nav-toggle.is-open .nav-toggle-bar::after  { top: 0; transform: rotate(-45deg); }

/* acciones: secundaria de línea + primaria naranja, en ese orden de lectura */
.header-cta { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }
/* el CTA es el único trabajo de la web: más cuerpo y un anillo de su mismo naranja al
   18 % para que destaque sobre la barra blanca sin añadir otra superficie naranja */
.header-cta .btn {
  white-space: nowrap;
  padding: 0.7rem 1.55rem;
  font-weight: 700;
  box-shadow: 0 0 0 4px rgba(240, 138, 0, 0.18);
}
/* .btn-comandes / .nav-comandes: latentes. El área de comandes está oculta (CLAUDE.md §9);
   se conservan para cuando se vuelva a enlazar. */
.btn-comandes { padding-block: 0.5rem; font-size: 0.92rem; border-width: 1.5px; }

/* en anchos medios la navegación pasa a una segunda fila en vez de comprimirse */
@media (max-width: 1120px) and (min-width: 861px) {
  .header-in { flex-wrap: wrap; padding-block: 0.5rem; row-gap: 0; min-height: 0; }
  .nav { order: 3; width: 100%; margin-right: 0; }
  .nav-links { padding-bottom: 0.55rem; }
  .header-cta { margin-left: auto; }
}

/* ---------- Héroe ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3.5rem, 9vw, 7rem) clamp(3rem, 7vw, 5.5rem);
  background:
    radial-gradient(1200px 600px at 85% 0%, rgba(133, 187, 58, 0.07), transparent 60%),
    var(--paper);
}

/* Texto y foto (2026-10-27). Hasta entonces el hueco de la derecha lo ocupaba el logo
   oficial en placa, que repetía el de la cabecera; ahora es una foto del almacén con el
   albarán montado encima. En móvil, una columna: texto, foto y albarán. */
.hero-in {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2.4rem, 6vw, 3.5rem);
}
/* 1.2fr/0.8fr y no mitades: «Fruita i verdura» a 5.2rem mide ~550px, y a mitades la
   columna de texto se quedaba en 500 y el titular saltaba a cuatro líneas. */
@media (min-width: 961px) {
  .hero-in {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    align-items: center;
  }
}

.hero-media {
  position: relative;
  animation: sube 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.3s both;
}
/* El fichero ya es 4:5 (2026-10-28) y en escritorio se ve entero. En móvil, cuadrada y
   encuadrada desde arriba: el rótulo «Fruites G. Jiménez · des de 1958» está en el
   borde superior, y a 3:2 centrada se perdía. Sin filtros (GUIA-ESTETICA §5). */
.hero-foto {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: 50% 0;
  border-radius: var(--radius);
  background: var(--paper-tint);
}
@media (min-width: 961px) {
  .hero-foto { aspect-ratio: 4 / 5; max-height: 560px; }
}

.hero-title {
  font-size: clamp(2.6rem, 7.2vw, 5.2rem);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.02em;
  max-width: 12ch;
  /* el titular es lo más grande de la página: con el texto ampliado, una palabra suya no
     cabe en una línea de 320px y ensanchaba la maquetación entera */
  overflow-wrap: break-word;
  animation: sube 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes sube {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}

.hero-sub {
  max-width: 44ch;
  margin-top: 1.4rem;
  font-size: 1.13rem;
  color: var(--ink-soft);
  animation: sube 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.12s both;
}

.hero-actions {
  display: flex; flex-wrap: wrap; gap: 0.9rem;
  margin-top: 2rem;
  animation: sube 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.22s both;
}

/* Ticket albarán. Montado sobre el pie de la foto: sube 3rem sobre ella y se mete hacia
   dentro, como el papel grapado a la caja. En escritorio sobresale además por la
   izquierda, hacia la columna de texto, que en esa altura ya está vacía. */
.ticket {
  position: relative;
  margin: -3rem 0.8rem 0;
  max-width: 420px;
  background: var(--paper);
  border: 1px solid var(--linea);
  border-radius: 6px;
  box-shadow: var(--sombra);
  font-family: var(--font-mono);
  animation: sube 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.34s both;
}
.ticket-head {
  padding: 0.7rem 1.1rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  border-bottom: 1px dashed var(--linea);
  color: var(--naranja-deep);
}
.ticket-body { padding: 0.9rem 1.1rem; display: grid; gap: 0.45rem; }
.ticket-body > div { display: flex; justify-content: space-between; gap: 1rem; }
.ticket-body dt { color: var(--ink-soft); font-size: 0.85rem; }
.ticket-body dd { font-weight: 600; font-size: 0.85rem; text-align: right; }
/* ≤420: la etiqueta encima del valor. En una fila, «Es demana» se partía en dos líneas y
   el valor se quedaba en un hueco de ~150px, partido a su vez y alineado a la derecha. */
@media (max-width: 420px) {
  .ticket-body { gap: 0.6rem; }
  .ticket-body > div { flex-direction: column; gap: 0.1rem; }
  .ticket-body dd { text-align: left; }
}
.ticket-foot {
  padding: 0.6rem 1.1rem;
  font-size: 0.75rem;
  color: var(--ink-soft);
  border-top: 1px dashed var(--linea);
}
@media (min-width: 961px) {
  .ticket { margin: -5rem 0 0; }
}
/* solo desde 1080 hay aire para que sobresalga hacia el texto: a 961 se quedaba a 15px
   del botón «Veure què és de temporada» */
@media (min-width: 1080px) {
  .ticket { margin-left: -3rem; }
}

/* ---------- Línea de pesaje (cifras) ---------- */
.scale-strip {
  background: var(--ink);
  color: var(--paper);
  border-block: 4px solid var(--naranja);
}
/* Cifras de báscula (2026-10-27): la cifra a cuerpo grande y la descripción debajo.
   Hasta entonces todo iba a 0.85rem en una línea y la franja se leía como un pie de
   página. Siguen en mono y en --verde (GUIA-ESTETICA §10.2). */
.scale-in {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1.2rem 2.2rem;
  padding-block: clamp(1.4rem, 3vw, 2rem);
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}
.scale-in p {
  display: grid;
  gap: 0.2rem;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.75);
}
.scale-in b {
  font-size: clamp(2rem, 4vw, 2.8rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--verde);
}

/* ---------- Secciones ---------- */
.section { padding-block: clamp(3.5rem, 8vw, 6rem); }
.section--tint { background: var(--paper-tint); }
.section--board { background: var(--board); color: #f2f5ea; }
.section--board h2 { color: #fff; }
.section--board .section-sub { color: #b9c6a6; }
.section-head { margin-bottom: clamp(2rem, 5vw, 3rem); }

/* ---------- Productos ---------- */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.2rem;
}
.cat-card {
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  padding: 1.5rem 1.4rem;
  background: var(--paper);
}

/* Mismo caso que en segmentos: la tarjeta lleva también .reveal y `.js .reveal` (0,2,0)
   le ganaba a `.cat-card` (0,1,0) —y a `.cat-card:hover` (0,2,0), por orden—, así que ni
   la transición ni el translateY del hover llegaban a verse nunca. La transición se
   declara aquí con el peso suficiente, conservando los tiempos de la entrada. */
#productos .reveal {
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1),
              scale 0.18s ease, filter 0.18s ease,
              border-color 0.15s ease, box-shadow 0.15s ease;
}

/* La familia apuntada se adelanta y las otras tres se van fuera de foco, igual que en
   la rejilla de segmentos (ver GUIA-ESTETICA §7). Aquí el borde es verde, no naranja:
   estas tarjetas informan, no son una acción. El desplazamiento de 3px se sustituye por
   la escala, que es la propiedad que no se pisa con la animación de entrada.
   Estas tarjetas no contienen nada enfocable, así que no hay pareja de teclado. */
@media (hover: hover) {
  .cat-card:hover {
    scale: 1.03;
    z-index: 1;
    box-shadow: var(--sombra);
    border-color: var(--verde);
  }
  .cat-grid:hover .cat-card:not(:hover) { filter: blur(1px) opacity(0.5); }
}
/* Foto real de la familia en cabeza de la tarjeta (2026-10-22, sustituye al icono).
   Sangra hasta el borde: anula el padding de la tarjeta con margen negativo y redondea
   solo arriba, 1px menos que la tarjeta porque va por dentro de su borde. */
.cat-foto {
  width: calc(100% + 2.8rem);
  max-width: none;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  margin: -1.5rem -1.4rem 1.1rem;
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
  background: var(--paper-tint);
}
/* ≤560 la rejilla es de una columna y la foto, a todo el ancho, es la mayor parte de cada
   tarjeta. A 3:2 —la proporción que ya usan las fotos de instalaciones— baja de ~265 a
   ~237px a 390px de viewport: unos 30px por tarjeta, y los chips suben hacia la foto. */
@media (max-width: 560px) {
  .cat-foto { aspect-ratio: 3 / 2; }
}
.cat-card h3 { margin-bottom: 0.8rem; }
.chip-list { list-style: none; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip-list li {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  padding: 0.22rem 0.6rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  color: var(--ink-soft);
  background: var(--paper-tint);
}

/* El ultimo chip de cada familia avisa de que la lista es una muestra, no el surtido
   entero. Linea discontinua y verde para que no se lea como un producto mas. El selector
   lleva el `li` porque `.chip-list li` ya es (0,1,1) y una clase sola no le ganaria. */
.chip-list li.chip-list-mes {
  border-style: dashed;
  border-color: var(--verde);
  background: transparent;
  color: var(--verde-deep);
  font-weight: 600;
}

/* Cierre de la seccion: misma pieza que .seg-particulars en segmentos, porque hace el
   mismo trabajo —matizar lo de arriba y mandar al telefono— y conviene que se reconozca. */
.cat-nota {
  margin-top: 1.6rem;
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--verde);
  background: var(--paper-tint);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}
.cat-nota a {
  color: var(--verde-deep);
  text-decoration-color: var(--verde);
  text-underline-offset: 2px;
  font-weight: 600;
}
.cat-nota a:hover { color: var(--ink); }

/* ---------- Pizarra de temporada ---------- */
.mes-actual-label {
  color: var(--naranja);
  font-weight: 600;
}

.cal-filtros {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-bottom: 1.4rem;
}
.chip {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 500;
  padding: 0.35rem 0.95rem;
  border-radius: 999px;
  border: 1px solid var(--board-line);
  background: transparent;
  color: #cdd8bc;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.chip:hover { border-color: var(--verde); color: #fff; }
.chip.is-active {
  background: var(--verde);
  border-color: var(--verde);
  color: var(--ink);
  font-weight: 600;
}

.cal-scroll {
  overflow-x: auto;
  border: 1px solid var(--board-line);
  border-radius: var(--radius);
  -webkit-overflow-scrolling: touch;
}
.cal-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 720px;
  font-family: var(--font-mono);
  font-size: 0.82rem;
}
.cal-table th, .cal-table td {
  padding: 0.55rem 0.5rem;
  border-bottom: 1px solid var(--board-line);
  text-align: center;
}
.cal-table thead th {
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: #aebb99;
  border-bottom: 2px solid var(--board-line);
}
/* La columna de producto se queda fija al desplazar la tabla. Sin esto, en móvil el
   visitante llega al mes de hoy —lo coloca main.js → calendarioAlMes()— y ve una rejilla
   de puntos sin saber de qué producto es cada fila. El fondo tiene que ser opaco (antes
   se veía --board por transparencia) y el hairline de la derecha es el mismo
   --board-line del resto de la tabla. */
.cal-prod-th, .cal-prod {
  text-align: left !important;
  white-space: nowrap;
  padding-left: 1rem !important;
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--board);
  border-right: 1px solid var(--board-line);
}
.cal-prod { color: #f2f5ea; font-weight: 500; }
/* En móvil el `nowrap` deja la columna de producto en 251px de los 283 que mide la caja:
   con la columna fija, eso significaba no ver ni un mes entero. Se le pone anchura y se
   le permite partir —«Préssec i nectarina» pasa a dos líneas— en vez de recortar con
   puntos suspensivos: el nombre del producto es el dato que da sentido a la fila.
   El corte de 620 ya existe en este fichero. */
@media (max-width: 620px) {
  .cal-prod-th, .cal-prod { white-space: normal; width: 7.5rem; }
}
.cal-table tbody tr:last-child th,
.cal-table tbody tr:last-child td { border-bottom: none; }
.cal-table tbody tr:hover { background: rgba(133, 187, 58, 0.07); }
/* la celda fija es opaca: el hover de la fila se le pinta encima en dos capas para no
   inventar un color nuevo —es el mismo rgba de siempre sobre --board */
.cal-table tbody tr:hover .cal-prod {
  background: linear-gradient(rgba(133, 187, 58, 0.07), rgba(133, 187, 58, 0.07)), var(--board);
}

.cal-table .is-hoy {
  background: rgba(240, 138, 0, 0.14);
}
.cal-table thead .is-hoy {
  color: var(--naranja);
  border-bottom-color: var(--naranja);
}

.dot {
  display: inline-block;
  width: 11px; height: 11px;
  border-radius: 50%;
}
.dot--alta { background: var(--naranja); }
.dot--disp { border: 2px solid var(--verde); background: transparent; }

.cal-leyenda {
  margin-top: 1.1rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: #b9c6a6;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.7rem;
}
.cal-leyenda-sep { opacity: 0.5; }
/* ≤620 la nota final baja de línea sola y el punto separador se quedaba colgando al
   final de la anterior */
@media (max-width: 620px) {
  .cal-leyenda-sep { display: none; }
}

.cal-row-hidden { display: none; }

.cal-noscript {
  padding: 1rem 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: #dfe8d1;
}
.cal-noscript a { color: var(--verde); }

/* ---------- Por qué nosotros ---------- */
/* Cabecera con el retrato del abuelo (2026-10-30): debajo del texto en móvil, a la
   derecha desde 900. El margen inferior pasa de .section-head al contenedor. El dibujo
   va entero: el `aspect-ratio` anula el 3:2 de .foto-img con la proporción exacta del
   fichero (640×1180), así que nada se recorta. No vale `auto`: con `loading="lazy"` la
   caja mide 0 de alto hasta que llega la imagen y la página salta. */
.empresa-cap {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  margin-bottom: clamp(2rem, 5vw, 3rem);
}
.empresa-cap .section-head { margin-bottom: 0; }
.empresa-retrat { margin: 0; max-width: 220px; }
.empresa-retrat .foto-img { aspect-ratio: 640 / 1180; }
@media (min-width: 900px) {
  .empresa-cap {
    grid-template-columns: minmax(0, 1fr) 260px;
    align-items: center;
    gap: 3rem;
  }
  .empresa-retrat { max-width: none; }
}
.why-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.2rem;
}
/* `minmax(0, 1fr)` y no `1fr`: con `1fr` el mínimo de la columna es su min-content, así
   que una palabra larga del h3 ensancha la rejilla y saca la página de la pantalla. Se ve
   con el texto ampliado al 200%, donde «intermediaris» mide 286px en un hueco de 285.
   Mismo motivo en .seg-grid, .contacto-grid, .faq-grid, .form-row--2col y .footer-in. */
@media (max-width: 620px) {
  .why-grid { grid-template-columns: minmax(0, 1fr); }
}
/* El filete verde de arriba ya no es el color del borde, sino una capa de fondo que
   ocupa exactamente los 4px que el borde transparente reserva. Se hace así para poder
   dibujarlo al entrar animando `background-size`: el fondo lo recorta el border-radius
   de la propia tarjeta, con lo que el filete conserva las esquinas redondeadas que tenía
   como borde. Un ::before no valía: al vivir en la zona del borde (top:-4px) lo recorta
   el overflow, y sin overflow sus esquinas rectas asomaban por fuera de la curva. */
.why-card {
  background-color: var(--paper);
  background-image: linear-gradient(var(--verde), var(--verde));
  background-repeat: no-repeat;
  background-position: left top;
  background-size: 100% 4px;
  border-radius: var(--radius);
  padding: 1.5rem 1.4rem;
  border-top: 4px solid transparent;
}
.why-card h3 { margin-bottom: 0.6rem; }
.why-card p { color: var(--ink-soft); font-size: 0.98rem; }

/* Entrada escalonada (GUIA-ESTETICA §7: una sola entrada orquestada, retardos de ~0.1s).
   Las cinco piezas llevan .reveal, y `.js .reveal` (0,2,0) declara `transition` en atajo
   —lo que pone `transition-delay` a 0 y se comería el escalonado—. Es el mismo choque ya
   documentado para #productos y #segmentos, así que se redeclara con peso de sección
   conservando los tiempos de la entrada. */
#empresa .reveal {
  transition: opacity 0.55s ease var(--retard, 0s),
              transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) var(--retard, 0s);
}
.why-card:nth-child(2) { --retard: 0.1s; }
.why-card:nth-child(3) { --retard: 0.2s; }
.why-card:nth-child(4) { --retard: 0.3s; }

/* La tarjeta sube y, cuando ya ha llegado, se traza el filete: primero la caja, luego la
   línea. El retardo propio del filete va en la lista, no en `transition-delay`, porque
   ese es único para todas las propiedades. */
#empresa .why-card.reveal {
  transition: opacity 0.55s ease var(--retard, 0s),
              transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) var(--retard, 0s),
              background-size 0.6s cubic-bezier(0.2, 0.7, 0.2, 1)
                calc(var(--retard, 0s) + 0.22s);
}
.js .why-card.reveal { background-size: 0 4px; }
.js .why-card.reveal.is-visible { background-size: 100% 4px; }
/* Con JS pero sin IntersectionObserver o con movimiento reducido: ya dibujado. */
.js.no-observer .why-card.reveal { background-size: 100% 4px; }

/* En una columna (≤620) las tarjetas ya no entran juntas: cada una aparece cuando le
   toca al hacer scroll, y un retardo acumulado se leería como lentitud, no como ritmo. */
@media (max-width: 620px) {
  /* Mismo peso que las reglas de arriba (0,2,0): con un simple `.why-card` (0,1,0) el
     reset no llegaba a aplicarse nunca. */
  .why-card:nth-child(2),
  .why-card:nth-child(3),
  .why-card:nth-child(4) { --retard: 0s; }
}

/* ---------- Calidad ----------
   Foto + lista (2026-10-27). Era la tercera rejilla de tarjetas con contorno seguida
   (productos, «Com treballem», calidad); ahora la foto de las cámaras hace de prueba y
   los tres puntos van sin caja, separados por espacio. ≥900 a dos columnas. */
.cert-cos {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .cert-cos { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.cert-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.8rem;
}
.cert-card { padding-left: 1.1rem; border-left: 3px solid var(--verde); }
.cert-card h3 { margin-bottom: 0.6rem; }
.cert-card p { color: var(--ink-soft); font-size: 0.98rem; }
.cert-num {
  margin-top: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.74rem !important;
  letter-spacing: 0.04em;
  color: var(--verde-deep) !important;
  border: 1px dashed var(--verde);
  border-radius: 4px;
  padding: 0.3rem 0.6rem;
  display: inline-block;
}

/* Entrada escalonada, misma gramática que «Com treballem» (GUIA-ESTETICA §7): primero
   aterriza la tarjeta y después llega el detalle, con el mismo desfase de 0.22s. Aquí el
   detalle no es un filete —estas tarjetas no lo llevan— sino el chip: es la prueba de lo
   que afirma el titular, así que es lo último que se posa, como un sello.
   Se redeclara la transición con peso de sección porque `.js .reveal` (0,2,0) la declara
   en atajo y pondría los retardos a 0. */
#calidad .reveal {
  transition: opacity 0.55s ease var(--retard, 0s),
              transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) var(--retard, 0s);
}
.cert-card:nth-child(2) { --retard: 0.1s; }
.cert-card:nth-child(3) { --retard: 0.2s; }

/* El chip hereda el --retard de su tarjeta y le suma su propio desfase. Se mueve con
   opacity/transform y no con márgenes, para que la altura de la tarjeta no cambie ni un
   píxel mientras entra. */
.js .cert-card.reveal .cert-num {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s ease calc(var(--retard, 0s) + 0.22s),
              transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1)
                calc(var(--retard, 0s) + 0.22s);
}
.js .cert-card.reveal.is-visible .cert-num { opacity: 1; transform: none; }
/* Con JS pero sin IntersectionObserver o con movimiento reducido: el chip ya puesto. */
.js.no-observer .cert-card.reveal .cert-num { opacity: 1; transform: none; }

/* La lista es de una columna a cualquier ancho, pero por encima de 900 entra entera a la
   vez junto a la foto y el escalonado tiene sentido; por debajo, apilada bajo la foto,
   cada punto entra cuando le toca. El corte de 900 ya existe en el fichero.
   Mismo peso que las reglas de arriba (0,2,0): con `.cert-card` a secas no se aplicaría. */
@media (max-width: 899px) {
  .cert-card:nth-child(2),
  .cert-card:nth-child(3) { --retard: 0s; }
}

/* ---------- Instalaciones ---------- */
.fotos-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.2rem;
}
/* Mismo papel que tenían los huecos de foto: rejilla de figuras con pie. Una columna en
   móvil, dos desde 620 y las cuatro en fila desde 1080, para no dejar una huérfana. */
.foto-img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--linea);
  background: var(--paper);
}
.foto figcaption {
  margin-top: 0.7rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  overflow-wrap: break-word;
}
@media (min-width: 620px) {
  .fotos-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* ≥1080: zigzag sobre doce columnas, 7/5 y 5/7 (2026-10-27). Antes iban las cuatro en
   fila a ~250px cada una, demasiado pequeñas para las mejores fotos de la web.
   La foto ANCHA de cada fila se ve entera (2026-10-28): es contenido, no fondo, y a
   ~2:1 la de la botiga perdía el rótulo «Fruiteria» por arriba. Así que la fila toma la
   altura de la ancha a su 3:2 real, y la que se recorta es la estrecha (~1,1:1).
   La altura sale del ancho de la rejilla en unidades de contenedor —7 de 12 columnas más
   sus 6 huecos, por 2/3—, que coincide al píxel con la celda; con `vw` se colaba la barra
   de scroll. Sin soporte de `cqw` se queda en los 320px de antes. */
@media (min-width: 1080px) {
  .fotos-grid {
    grid-template-columns: repeat(12, minmax(0, 1fr)); row-gap: 2rem;
    container-type: inline-size;
  }
  .fotos-grid .foto:nth-child(4n+1), .fotos-grid .foto:nth-child(4n) { grid-column: span 7; }
  .fotos-grid .foto:nth-child(4n+2), .fotos-grid .foto:nth-child(4n+3) { grid-column: span 5; }
  .fotos-grid .foto-img {
    aspect-ratio: auto;
    height: 320px;
    height: calc(((100cqw - 11 * 1.2rem) / 12 * 7 + 6 * 1.2rem) * 2 / 3);
  }
}

/* Pase de fotos por hueco (2026-10-30, main.js → passiFotos). La primera foto va en
   flujo y da el tamaño —también la altura fija del mosaico—; las demás se apilan encima
   a su misma caja. Sin JS solo se ve la primera. Con el pase montado (`.is-pase`) se ve
   la activa, que entra con fundido por encima de la anterior; la anterior (`.is-sortint`)
   se queda opaca debajo hasta que el fundido termina, para que en medio no asome la
   primera. Sin transición al apagarse: para entonces ya está tapada. */
.foto-pase { position: relative; }
.foto-pase > .foto-img { position: relative; }
.foto-pase > .foto-img + .foto-img {
  position: absolute; inset: 0;
  height: 100%;
  opacity: 0;
}
.foto-pase.is-pase > .foto-img { opacity: 0; }
.foto-pase.is-pase > .foto-img.is-sortint { opacity: 1; z-index: 1; }
.foto-pase.is-pase > .foto-img.is-active {
  opacity: 1; z-index: 2;
  transition: opacity 0.9s ease;
}
/* Pausa (WCAG 2.2.2: lo que se mueve solo más de 5 s se tiene que poder parar). Tinta con
   aro de papel: así llega a 3:1 tanto sobre zona clara de la foto como oscura. */
.foto-pausa {
  position: absolute; right: 0.6rem; bottom: 0.6rem; z-index: 3;
  width: 2.25rem; height: 2.25rem; padding: 0;
  display: grid; place-items: center;
  border: 2px solid var(--paper); border-radius: 50%;
  background: var(--ink); color: var(--paper);
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.foto-pausa:hover { background: var(--verde-deep); }
.foto-pausa svg { width: 14px; height: 14px; }
.foto-pausa .ico-reprendre,
.foto-pausa[aria-pressed="true"] .ico-pausa { display: none; }
.foto-pausa[aria-pressed="true"] .ico-reprendre { display: block; }

/* ---------- Segmentos ---------- */
/* cuatro perfiles: 2×2 como .why-grid, para no dejar una tarjeta huérfana */
.seg-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.2rem;
}
@media (max-width: 620px) {
  .seg-grid { grid-template-columns: minmax(0, 1fr); }
}
.seg-card {
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  padding: 1.7rem 1.5rem;
  display: flex; flex-direction: column; gap: 0.8rem;
}

/* Las tres piezas de esta sección llevan también .reveal, y `.js .reveal` (0,2,0) le
   ganaba en especificidad a `.seg-card` (0,1,0): la transición de la tarjeta no llegaba
   a aplicarse nunca y el hover cambiaba de golpe. Se declara aquí una sola vez, con los
   tiempos del reveal para la entrada (opacity/transform) y los de micro-hover para lo
   demás. */
#segmentos .reveal {
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1),
              scale 0.18s ease, filter 0.18s ease,
              border-color 0.15s ease, box-shadow 0.15s ease;
}

/* La tarjeta apuntada se adelanta —crece un punto, borde naranja y sombra— y las otras
   tres se van fuera de foco. El resto de la sección (titular y nota del particular) no
   se toca: es texto que se lee, no una opción que se elige.
   Dos detalles que no son capricho: el atenuado va en `filter: opacity()` y la escala
   en `scale`, no en `opacity` ni en `transform`, porque esas dos las usa el reveal de
   entrada y se pisarían entre ellas.
   Todo el bloque vive dentro de `hover: hover`: en táctil el navegador mantiene el
   :hover después de tocar y las tarjetas se quedaban desenfocadas. */
@media (hover: hover) {
  .seg-card:hover {
    border-color: var(--naranja);
    box-shadow: var(--sombra);
    scale: 1.03;
    z-index: 1;
  }
  .seg-grid:hover .seg-card:not(:hover) { filter: blur(1px) opacity(0.5); }
}

/* Con teclado manda la tarjeta enfocada, con el mismo trato. Es `:focus-visible` y no
   `:focus-within`: al tocar el botón con el dedo, el foco se queda en él y las tarjetas
   habrían permanecido desenfocadas después del toque. */
.seg-card:has(:focus-visible) {
  border-color: var(--naranja);
  box-shadow: var(--sombra);
  scale: 1.03;
  z-index: 1;
}
.seg-grid:has(.seg-card :focus-visible) .seg-card:not(:has(:focus-visible)) {
  filter: blur(1px) opacity(0.5);
}
.seg-card p { color: var(--ink-soft); flex-grow: 1; }
.seg-card .btn { align-self: flex-start; }

/* nota para el particular: no es una tarjeta más, es una salida lateral */
.seg-particulars {
  margin-top: 1.6rem;
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--verde);
  background: var(--paper-tint);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}
/* sobre fondo claro el enlace va en verde profundo, que es el que cumple AA */
.seg-particulars a {
  color: var(--verde-deep);
  text-decoration-color: var(--verde);
  text-underline-offset: 2px;
  font-weight: 600;
}
.seg-particulars a:hover { color: var(--ink); }

/* ---------- Contacto ----------
   La clase .section--tarifa y el id #tarifa son identificadores históricos: la sección
   se titula «Contacte» desde 2026-09-15 (ver BRIEFING-CLIENTE.md §8). */
.section--tarifa {
  background:
    radial-gradient(900px 500px at 10% 0%, rgba(240, 138, 0, 0.08), transparent 55%),
    var(--board);
}

/* Banda de contenido: cada trabajo —pedir, resolver dudas, encontrarnos— va en la
   suya, separada por hairline. Los colores se escriben para fondo CLARO, que es el
   caso general; sobre pizarra se corrigen con .section--board. */
.bloc + .bloc {
  margin-top: clamp(2.6rem, 6vw, 4rem);
  padding-top: clamp(2.6rem, 6vw, 4rem);
  border-top: 1px solid var(--linea);
}
.section--board .bloc + .bloc { border-top-color: var(--board-line); }
/* título de banda: por debajo del h2 de la sección y por encima del cuerpo */
.bloc-titol {
  font-size: 1.25rem;
  color: var(--ink);
  margin-bottom: 1.2rem;
}
.section--board .bloc-titol { color: #fff; }

.contacto-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

/* el formulario es el objeto principal de la sección: va en panel para que el naranja
   del CTA se apoye en una superficie y no flote sobre el fondo de pizarra */
.contacto-form {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--board-line);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 3.5vw, 2rem);
}

.form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.1rem; }
/* `minmax(0, 1fr)` también aquí: la columna implícita se dimensiona a min-content, y el
   min-content de un <select> es su opción más larga («Col·lectivitats i escoles»), que
   con el texto ampliado desbordaba el panel entero. */
.form-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.4rem; }
.form-row--2col {
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.form-row--2col > div { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.4rem; }
.form label {
  font-size: 0.88rem;
  font-weight: 600;
  color: #dfe8d1;
}
.form .opt { font-weight: 400; color: #9dab88; }
.form input, .form select, .form textarea {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--board-line);
  border-radius: 8px;
  /* 0.78rem deja el campo en ~46px: por encima del objetivo táctil mínimo */
  padding: 0.78rem 0.9rem;
  color: #fff;
  width: 100%;
}
.form input::placeholder, .form textarea::placeholder { color: #8a9878; }
.form select { appearance: auto; }
.form select option { color: var(--ink); background: var(--paper); }
.form input:focus-visible, .form select:focus-visible, .form textarea:focus-visible {
  outline: 3px solid var(--naranja);
  outline-offset: 1px;
  border-color: var(--naranja);
}
/* la nota va al lado del botón, no debajo: responde al «¿y ahora qué pasa?» justo
   en el momento de decidir enviarlo */
.form-accio {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1.1rem;
  margin-top: 0.3rem;
}
.form-accio .btn { flex-shrink: 0; }
.form-nota {
  font-size: 0.85rem;
  line-height: 1.45;
  color: #b9c6a6;
  max-width: 24ch;
}
.form-ok {
  background: rgba(133, 187, 58, 0.15);
  border: 1px solid var(--verde);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  color: #f2f5ea;
  font-size: 0.95rem;
}
.form-ok a { color: var(--verde); font-weight: 600; }

/* ---------- Fichas de canal ----------
   Mientras el área de comandes esté oculta, teléfono, WhatsApp y email SON la vía de
   pedido (CLAUDE.md §9): dejan de ser una tabla etiqueta/valor de 0.95rem y pasan a
   fichas pulsables. Borde neutro y acento verde: la única superficie naranja de la
   sección sigue siendo el botón del formulario. */
.canals-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.9rem;
  margin-bottom: 1.1rem;
}
.canals-head .bloc-titol { margin-bottom: 0; }
/* mismo estado que la barra de utilidades, pero aquí el usuario ya está decidiendo:
   comparte los modificadores .es-* y el punto de color con .topbar-estat */
.canal-estat {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: #dfe8d1;
  border: 1px solid var(--board-line);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
}
.canal-estat[hidden] { display: none; }
/* el recorte con puntos suspensivos es de la barra de utilidades, que mide 34px de alto;
   esta píldora vive en una columna y puede crecer, así que el texto se parte en vez de
   desbordar cuando el visitante amplía la letra */
.canal-estat .estat-text { white-space: normal; overflow: visible; }

.canals { list-style: none; display: grid; gap: 0.7rem; }
.canal {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.9rem;
  align-items: center;
  padding: 0.85rem 1rem;
  border: 1px solid var(--board-line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  color: inherit;
  transition: transform 0.12s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.canal:hover {
  transform: translateY(-2px);
  border-color: var(--verde);
  background: rgba(133, 187, 58, 0.10);
}
.canal-icona {
  width: 40px; height: 40px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(133, 187, 58, 0.14);
  color: var(--verde);
  flex-shrink: 0;
}
.canal-icona svg { width: 21px; height: 21px; }
.canal-tipus {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #9dab88;
}
/* el email es largo: que parta antes que desbordar a 360px */
.canal-valor {
  display: block;
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.25;
  color: #fff;
  overflow-wrap: anywhere;
}
.canal-nota {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.82rem;
  line-height: 1.4;
  color: #b9c6a6;
}

/* resumen de servicio bajo las fichas: mismo lenguaje etiqueta/valor que el pie */
.canal-servei {
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--board-line);
}
.canal-servei h4 { font-size: 0.98rem; color: #fff; margin-bottom: 0.85rem; }
.canal-servei ul { list-style: none; display: grid; gap: 0.8rem; font-size: 0.92rem; }
.canal-servei li { display: grid; gap: 0.1rem; }
.canal-servei li span:not(.contacto-label) { color: #dfe8d1; line-height: 1.45; }

.contacto-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #9dab88;
}

/* ---------- Preguntas frecuentes ----------
   A dos columnas y a todo ancho: antes vivían en el raíl estrecho, que es el peor
   ancho de la página para el contenido que resuelve objeciones. */
.faq-grid { display: grid; gap: 0 clamp(2rem, 5vw, 4rem); }
.faq details {
  border-bottom: 1px solid var(--linea);
}
/* el marcador por defecto queda pegado al margen izquierdo y no dice si abre o cierra:
   se sustituye por +/− a la derecha, alineado con el borde de la banda */
.faq summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
  list-style: none;
  padding-block: 0.85rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  font-family: var(--font-mono);
  font-size: 1.15rem;
  line-height: 1;
  color: var(--verde-deep);
  flex-shrink: 0;
}
.faq details[open] summary::after { content: "–"; }
.faq summary:hover { color: var(--verde-deep); }
.faq details p {
  padding-top: 0.2rem;
  padding-bottom: 0.9rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
  max-width: 52ch;
}
/* los enlaces del FAQ van en verde de marca, no en el azul del navegador */
.faq details p a {
  color: var(--verde-deep);
  /* el email de la respuesta no tiene dónde partir y desbordaba a 320px con el texto
     ampliado; `anywhere` además sí reduce el min-content, que es lo que aquí hace falta */
  overflow-wrap: anywhere;
  text-decoration-color: var(--verde);
  text-underline-offset: 2px;
}
.faq details p a:hover { color: var(--ink); }

/* sobre pizarra, los mismos componentes con los neutros de la barra oscura */
.section--board .faq details { border-bottom-color: var(--board-line); }
.section--board .faq summary { color: #f2f5ea; }
.section--board .faq summary:hover,
.section--board .faq summary::after { color: var(--verde); }
.section--board .faq details p { color: #b9c6a6; }
.section--board .faq details p a { color: var(--verde); }
.section--board .faq details p a:hover { color: var(--paper); }

@media (min-width: 760px) {
  .faq-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ---------- Mapa de emplazamientos ---------- */
.mapa-cos {
  display: grid;
  gap: 1.2rem;
  align-items: start;
}
/* altura fija, no aspect-ratio: una proporcion crece con el ancho sin techo y a 1120px
   dejaba el marco en ~590px de alto para tres lineas de informacion. Aqui el mapa es
   un dato de contacto mas, asi que va en banda corta. */
.mapa-marc {
  height: 240px;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--linea);
}
.mapa-frame, .mapa-ph { width: 100%; height: 100%; display: block; border: 0; }
/* hueco mientras el cliente no envie su mapa: rayado discreto y etiqueta mono */
.mapa-ph {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.6rem;
  padding: 1rem;
  text-align: center;
  /* tintado sobre la sección blanca: el hueco tiene que leerse como una superficie
     esperando contenido, no como un agujero del mismo color que la página */
  background: var(--paper-tint);
}
.mapa-ph span {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  border: 1px dashed var(--verde-deep);
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
}
/* el mismo hueco, ya como boton: es la pantalla previa al iframe de Google. No lleva
   naranja a proposito, que la unica accion naranja de la pagina es el CTA de contacto. */
.mapa-ph--accio {
  font: inherit;
  color: inherit;
  cursor: pointer;
}
/* vale para el aviso del boton y para el <noscript> del hueco */
.mapa-ph small {
  font-size: 0.78rem;
  line-height: 1.4;
  max-width: 34ch;
  color: var(--ink-soft);
}
.mapa-ph a { color: var(--verde-deep); text-decoration-color: var(--verde); text-underline-offset: 2px; }
.mapa-ph a:hover { color: var(--ink); }
.mapa-ph--accio:hover span { color: var(--ink); border-color: var(--ink); }
.mapa-ph--accio:focus-visible { outline: 3px solid var(--naranja); outline-offset: -3px; }
.mapa-punts {
  list-style: none;
  display: grid;
  gap: 1rem;
  font-size: 0.95rem;
}
/* etiqueta encima del dato, tambien en movil: cada punto lleva ya direccion y horario,
   y en la columna de 92px la etiqueta de las tiendas se partia en dos lineas */
.mapa-punts li { display: grid; gap: 0.15rem; }
/* .contacto-label nacio para la pizarra (fichas de canal y pie); aqui vive sobre claro */
.mapa-punts .contacto-label { color: var(--ink-soft); }
.mapa-punts span:not(.contacto-label) { color: var(--ink-soft); }
.mapa-punts a { color: var(--verde-deep); text-decoration-color: var(--verde); text-underline-offset: 2px; }
.mapa-punts a:hover { color: var(--ink); }

@media (min-width: 760px) {
  /* mapa a la izquierda, las tres ubicaciones al lado: el bloque deja de sumar alturas */
  .mapa-cos { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: 2rem; }
  .mapa-marc { height: 320px; }
}

/* ---------- Páginas legales ----------
   Aviso legal, privacidad y galetes: son texto largo, así que van en una sola columna
   estrecha (~68 caracteres) dentro del .wrap de siempre. Comparten cabecera secundaria
   y pie con comandes.html; lo único propio es el ancho de lectura y la ficha de datos. */
.legal-hero {
  background: var(--paper-tint);
  border-bottom: 1px solid var(--linea);
  padding-block: clamp(2.2rem, 6vw, 3.6rem) clamp(1.6rem, 4vw, 2.4rem);
}
/* la cabecera de hoja se estrecha al mismo ancho que el cuerpo: si no, el título
   arranca en el borde del wrap y el texto empieza 130px más adentro */
.legal-hero .wrap { max-width: 68ch; }
/* y el aire de sección completa sobra entre dos bloques del mismo documento */
.legal-hero + .section { padding-top: clamp(1.8rem, 4vw, 2.6rem); }
.legal-titol { font-size: clamp(2rem, 5vw, 3rem); font-weight: 800; }
.legal-meta {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin-top: 0.9rem;
}
/* estas páginas todavía no han pasado por un abogado: el aviso lo dice en la propia
   página, no solo en un comentario del código */
.legal-avis {
  max-width: 62ch;
  margin-top: 1.2rem;
  padding: 0.8rem 1rem;
  background: var(--paper);
  border: 1px solid var(--linea);
  border-left: 3px solid var(--naranja);
  border-radius: var(--radius);
  font-size: 0.92rem;
  color: var(--ink-soft);
}

/* `overflow-wrap` en el cuerpo: el email y algún término largo del índice («Responsabilitat»)
   no caben en una línea de 320px con el texto ampliado. */
.legal-cos { max-width: 68ch; overflow-wrap: break-word; }
.legal-cos h2 {
  font-size: clamp(1.3rem, 2.6vw, 1.7rem);
  font-weight: 700;
  line-height: 1.15;
  margin-top: 2.6rem;
  scroll-margin-top: 90px;
}
.legal-cos h3 { margin-top: 1.7rem; }
.legal-cos p,
.legal-cos ul,
.legal-cos ol { margin-top: 0.9rem; color: var(--ink-soft); }
.legal-cos ul,
.legal-cos ol { padding-left: 1.2rem; }
.legal-cos li + li { margin-top: 0.35rem; }
.legal-cos li::marker { color: var(--verde-deep); }
.legal-cos a { color: var(--verde-deep); text-decoration-color: var(--verde); text-underline-offset: 2px; }
.legal-cos a:hover { color: var(--ink); }
.legal-cos strong { color: var(--ink); }

/* índice de la página: la ley obliga a que se encuentre la información, no a que se
   lea entera de arriba abajo */
.legal-index {
  margin-top: 1.4rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--linea);
  border-radius: var(--radius);
}
.legal-index ol { margin-top: 0.6rem; font-size: 0.95rem; }

/* ficha etiqueta/valor: datos del titular, del responsable o de cada tercero */
.legal-dades {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.4rem 1.1rem;
  margin-top: 1rem;
}
.legal-dades dt {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--verde-deep);
  padding-top: 0.22rem;
}
.legal-dades dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }

.legal-fitxa {
  margin-top: 1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--linea);
  border-radius: var(--radius);
}
.legal-fitxa h3 { font-size: 1.05rem; }
.legal-fitxa .legal-dades { margin-top: 0.7rem; }

/* dato del cliente aún sin confirmar. Fondo naranja muy diluido pero texto en tinta:
   el naranja aquí marca, no escribe (ver GUIA-ESTETICA §2). */
.legal-pendent {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  background: rgba(240, 138, 0, 0.16);
  color: var(--ink);
  padding: 0.05rem 0.4rem;
  border-radius: 4px;
}

.legal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem 1.4rem;
  margin-top: 2.8rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--linea);
  font-size: 0.95rem;
}

@media (max-width: 480px) {
  /* a esta anchura la columna de etiquetas se come el valor: se apilan */
  .legal-dades { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; }
  .legal-dades dd { margin-bottom: 0.7rem; }
  .legal-dades dt { padding-top: 0; }
}

/* ---------- Pie ---------- */
.footer {
  background: var(--ink);
  color: rgba(255, 255, 255, 0.82);
}
.footer-in {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem 3rem;
  padding-block: 2.6rem 2rem;
}
.footer-logo { display: block; width: 186px; max-width: 100%; height: auto; margin-bottom: 0.7rem; }
.footer-claim { font-size: 0.92rem; color: rgba(255, 255, 255, 0.6); margin-top: 0.4rem; }
.footer-tel {
  margin-top: 0.9rem;
  font-family: var(--font-mono);
  font-size: 1.02rem;
  font-weight: 600;
  /* la mono abre mucho los dígitos a este cuerpo: el número se leía como seis bloques
     sueltos en vez de como un teléfono. Medido contra tres ajustes: este es el único
     que agrupa 93 · 886 · 10 · 65 sin salir de la mono (GUIA-ESTETICA §3). */
  letter-spacing: -0.07em;
  word-spacing: -0.14em;
}
/* en el pie de la home el enlace lleva el icono del teléfono, como en la barra de
   utilidades. El subrayado va en el <span>: si va en el enlace, cruza también el icono. */
.footer-tel a { color: var(--verde); text-decoration-color: var(--verde); text-underline-offset: 3px; }
.footer-tel a:hover { color: var(--paper); }
.footer-brand .footer-tel a { display: inline-flex; align-items: center; gap: 0.45rem; text-decoration: none; }
.footer-brand .footer-tel svg { width: 16px; height: 16px; flex-shrink: 0; }
.footer-brand .footer-tel a span { text-decoration: underline; text-decoration-color: var(--verde); text-underline-offset: 3px; }

/* datos de administracion: presentes, pero sin competir con el telefono */
.footer-mini {
  list-style: none;
  margin-top: 1rem;
  display: grid;
  gap: 0.3rem;
  font-size: 0.85rem;
}
.footer-mini li { display: grid; gap: 0.1rem; }
.footer-mini a { color: rgba(255, 255, 255, 0.82); text-decoration-color: rgba(133, 187, 58, 0.6); overflow-wrap: anywhere; }
.footer-mini a:hover { color: var(--verde); }

/* h2 y no h4: el pie es un landmark propio, no una subsección de «On som», que es el
   último h3 de la página. El tamaño lo fija esta regla, no la global de h2. */
.footer-col h2 {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--verde);
  margin-bottom: 0.9rem;
}
.footer-col ul { list-style: none; display: grid; gap: 0.45rem; font-size: 0.95rem; }
.footer-col a { color: rgba(255, 255, 255, 0.82); text-decoration-color: rgba(133, 187, 58, 0.6); overflow-wrap: anywhere; }
.footer-col a:hover { color: var(--verde); }
.footer-legal {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.6rem;
  /* el email es la cadena más larga del pie y no tiene dónde partir: sin esto desborda
     en cuanto el visitante amplía el texto */
  overflow-wrap: anywhere;
  padding-block: 1.1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.55);
}
.footer-legal a { color: rgba(255, 255, 255, 0.72); text-decoration-color: rgba(133, 187, 58, 0.6); }
.footer-legal a:hover { color: var(--verde); }
/* pie de las páginas legales: sin la rejilla de arriba, la línea no necesita borde */
.footer--curt .footer-legal { border-top: none; padding-block: 1.8rem; }

/* ---------- WhatsApp flotante ---------- */
.wa-float {
  position: fixed;
  right: 1.1rem; bottom: 1.1rem;
  z-index: 60;
  width: 60px; height: 60px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--verde);
  color: var(--ink);
  box-shadow: 0 8px 22px rgba(31, 42, 22, 0.28);
  transition: transform 0.15s ease, background-color 0.15s ease;
}
/* hover #96cc4b: el --verde un punto más claro, igual que #ffa227 lo es del naranja.
   Documentado en GUIA-ESTETICA.md §3. */
.wa-float:hover { transform: translateY(-3px); background: #96cc4b; }
.wa-float svg { width: 32px; height: 32px; }
/* halo que late tres veces al cargar y se apaga: avisa de que el botón está ahí sin
   quedarse moviendo mientras se lee. Su estado base es invisible, así que con movimiento
   reducido (la duración cae a 0,01 ms) no llega a verse. */
.wa-float::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--verde);
  opacity: 0;
  pointer-events: none;
  animation: wa-halo 1.8s ease-out 1.2s 3;
}
@keyframes wa-halo {
  0%   { transform: scale(1);   opacity: 0.7; }
  100% { transform: scale(1.6); opacity: 0; }
}

/* ---------- Reveal por scroll ----------
   Quién pone estas dos clases, y por qué importa:
     .js           la pone el <script> en línea del <head>. Es la que OCULTA, así que sin
                   JavaScript no se oculta nada y la página se lee entera.
     .no-observer  la pone ese mismo script cuando ya sabe que no habrá animación:
                   movimiento reducido, navegador sin IntersectionObserver o ?qa=flat.
                   Decidirlo en el <head> —y no al final del <body>, como se hacía— evita
                   que el CSS y el JS opinen distinto durante el primer pintado.
   Y el seguro: como .js oculta y quien destapa es main.js, si main.js no llegara a
   cargarse la página se quedaría medio en blanco. El script del <head> programa retirar
   .js a los 3 s y main.js lo desarma al arrancar. Por eso aquí no hace falta nada más. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.js .reveal.is-visible { opacity: 1; transform: none; }
.js.no-observer .reveal { opacity: 1; transform: none; }

/* ---------- Movimiento reducido ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  /* el filete de las tarjetas de «Com treballem» ya dibujado, sin trazo */
  .why-card { background-size: 100% 4px; }
  /* el chip de «Qualitat» ya puesto, sin entrada propia */
  .cert-num { opacity: 1; transform: none; }
  /* la tarjeta de segmento deja de crecer; el desenfoque del resto se queda, porque
     marca dónde está el puntero y no es movimiento */
  .seg-card:hover, .seg-card:has(:focus-visible), .cat-card:hover { scale: 1; }
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .contacto-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ≤860: la navegación se pliega en un desplegable y las acciones secundarias
   (comandas, teléfono) bajan dentro de él. En la barra solo queda el CTA. */
@media (max-width: 860px) {
  .header-in { padding-block: 0.55rem; gap: 0.7rem; min-height: 60px; }
  .brand { margin-right: auto; }
  .nav { margin-right: 0; }
  .nav-toggle { display: inline-flex; }
  /* panel desplegable bajo la barra: el sticky se queda en una sola fila */
  /* El panel cuelga de la cabecera, que es sticky: lo que sobresalga por debajo del
     viewport NO se alcanza haciendo scroll, porque el panel baja pegado a la cabecera.
     Medido en apaisado: a 568×320 se perdían 42px —el enlace del teléfono entero— y a
     740×360, 2px. Con techo propio y scroll interno el panel siempre se recorre entero.
     El `100vh` va primero como reserva para los navegadores sin `dvh`. Se descuentan
     101px: el panel cuelga de la cabecera (67px medidos, no los 60 de `min-height`) y
     ARRIBA del todo la barra de utilidades (34px) todavía está en pantalla,
     porque no es sticky y solo se va al hacer scroll. Con 94px el panel se salía 8px en
     apaisado justo al abrirse, que es cuando la página está sin desplazar (corregido el
     2026-10-28). Descontando los dos, el techo vale para el caso peor y sobra holgura una
     vez se ha bajado.
     `overscroll-behavior` evita que al llegar al final del panel el gesto siga
     arrastrando la página por debajo. */
  .nav-links {
    display: none;
    position: absolute;
    left: 0; right: 0; top: 100%;
    flex-direction: column;
    gap: 0;
    background: var(--paper);
    border-block: 1px solid var(--linea);
    box-shadow: var(--sombra);
    padding: 0.2rem clamp(1.1rem, 4vw, 2rem) 0.7rem;
    max-height: calc(100vh - 101px);
    max-height: calc(100dvh - 101px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav-links.is-open { display: flex; }
  .nav-links li + li { border-top: 1px solid var(--linea); }
  .nav-links a { padding: 0.75rem 0.2rem; font-size: 1rem; }
  /* el subrayado animado no tiene sentido en una lista vertical */
  .nav-links a::after { display: none; }
  .nav-links a.is-actiu { color: var(--naranja-deep); }
  .nav-nomes-mobil { display: block; }
  .nav-links a.nav-comandes { color: var(--verde-deep); font-weight: 600; }
  .nav-links a.nav-tel { font-family: var(--font-mono); font-weight: 600; }

  .btn-comandes { display: none; }
  .brand { gap: 0.4rem; margin-right: auto; }
  .brand-logo { height: 48px; }
  .header-cta { gap: 0.5rem; }
  .header-cta .btn { padding: 0.55rem 1.05rem; font-size: 0.92rem; white-space: nowrap; }

  .form-row--2col { grid-template-columns: minmax(0, 1fr); }
  .footer-in { grid-template-columns: minmax(0, 1fr); gap: 1.6rem; }
}

/* ≤620: el botón de envío ocupa el ancho del panel —es el objetivo principal— y la
   nota baja debajo en lugar de partirse en dos palabras por línea */
@media (max-width: 620px) {
  /* `minmax(0, 1fr)`, igual que en .form y .form-row: la columna implícita se dimensiona
     al min-content del botón y de la nota. */
  .form-accio { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }
  .form-accio .btn { width: 100%; }
  .form-nota { max-width: none; }
}

/* CTA de cabecera: versión corta solo en pantallas muy estrechas */
.cta-short { display: none; }
@media (max-width: 560px) {
  .cta-full { display: none; }
  .cta-short { display: inline; }
  /* En la home la barra se queda solo con el estado: el teléfono ya está dentro del menú
     desplegable (.nav-tel) y en el botón flotante, así que repetirlo aquí solo aprieta
     una barra de 34px.
     Las demás páginas no tienen ni menú ni flotante —cabecera secundaria, ver
     comandes.html y las tres legales—, así que allí esta es la ÚNICA vía rápida al
     teléfono y se queda. */
  .topbar-tel { display: none; }
  .pagina-comandes .topbar-tel,
  .pagina-legal .topbar-tel { display: inline-flex; }
  /* el botón de menú pasa a icono. El texto se oculta VISUALMENTE, no con
     display:none, o el botón se quedaría sin nombre accesible.
     Al quedarse sin texto el contenido del botón es una barra de 2px, así que el objetivo
     táctil caía a 39×20 —por debajo del mínimo de 24×24 y justo en los anchos de móvil—.
     El mínimo de 40px lo devuelve a la medida del CTA de al lado (39px de alto) y cabe de
     sobra en la cabecera de este tramo: 60px menos 0.55rem de padding arriba y abajo. */
  .nav-toggle {
    padding: 0.5rem 0.65rem;
    min-width: 40px; min-height: 40px;
    justify-content: center;
  }
  .header-in { gap: 0.5rem; }
  .nav-toggle-txt {
    position: absolute; width: 1px; height: 1px;
    clip-path: inset(50%); overflow: hidden; white-space: nowrap;
  }
}

/* ≤389. Hasta el 2026-10-22 aquí se ocultaba el nombre en texto de la marca; con el
   logo oficial ya no hay nombre aparte y el logo (119px a esta anchura) cabe entero. */
@media (max-width: 389px) {
  .brand-logo { height: 46px; }
  /* a 320 logo + menú + «Contacta'ns» a 0.92rem no caben en una fila y la cabecera se
     partía en dos (118px). Un punto menos de letra y de relleno, medido (2026-10-30). */
  .header-cta .btn { padding-inline: 0.75rem; font-size: 0.88rem; }
  /* En comandes y en las legales la barra lleva estado Y teléfono (ver el corte de 560),
     y por debajo de 390px no caben en una fila: «Atenem a partir de les 17:00» perdía
     justo la hora. Se parte en dos líneas en vez de recortarse. La barra no es sticky,
     así que crecer 18px solo afecta a lo primero que se ve y se va con el scroll.
     En la home no cambia nada: allí el teléfono ya está oculto desde los 560. */
  .topbar-in { flex-wrap: wrap; justify-content: flex-start; row-gap: 0.1rem; }
  .topbar-estat { flex-basis: 100%; }
  .estat-text { white-space: normal; overflow: visible; }
}
