/* =========================================================================
   COMPONENTES — piezas reutilizables. Se carga el ÚLTIMO.
   =========================================================================
   Va el último para poder matizar lo de layout.css sin recurrir a
   !important ni a selectores kilométricos.

   Convención BEM: .bloque, .bloque__elemento, .bloque--modificador.
   Ventaja: la especificidad se mantiene plana (siempre una clase), así que
   nunca hay que pelear contra el propio CSS.
   ========================================================================= */

/* ---------------------------------------------------------------------
   ICONOS
   ---------------------------------------------------------------------
   currentColor hace que hereden el color del texto: funcionan solos en
   claro y en oscuro, y dentro de un botón burdeos se vuelven blancos. */
.icon {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------
   BOTONES
   ---------------------------------------------------------------------
   Son <a> cuando navegan y <button> cuando actúan. La clase solo define
   el aspecto: la etiqueta se elige por lo que HACE, no por cómo se ve. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  transition: background-color var(--transition), color var(--transition),
              border-color var(--transition), transform var(--transition);
}

/* Móvil: ancho completo, más fácil de acertar con el pulgar.
   Escritorio: ajustado al texto. */
.btn {
  width: 100%;
}

@media (min-width: 30em) {
  .btn {
    width: auto;
  }
}

.btn--primary {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
}

.btn--primary:hover {
  color: var(--color-accent-text);
  background-color: var(--color-accent-hover);
}

.btn--secondary {
  color: var(--color-accent-ink);
  background-color: transparent;
  border-color: currentColor;
}

.btn--secondary:hover {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-color: var(--color-accent-ink);
}

.btn:active {
  transform: translateY(1px);
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Enlace de texto con flecha, para los "Conóceme mejor →" */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  font-weight: 600;
  text-decoration: none;
}

.link-arrow::after {
  content: "→";
  transition: transform var(--transition);
}

.link-arrow:hover::after {
  transform: translateX(3px);
}

/* ---------------------------------------------------------------------
   TARJETAS
   --------------------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  height: 100%;
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: transform var(--transition), box-shadow var(--transition);
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.card__media {
  margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) 0;
  overflow: hidden;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.card__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Ilustraciones provisionales (SVG con su propio fondo crema y márgenes):
   en la tarjeta se ven enteras, sin recortar, sobre el mismo crema. */
.card__media .card__ilustracion {
  object-fit: contain;
  background-color: #f7f5f1;
}

.ilustracion {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
}

.ilustracion--servicio {
  max-width: 26rem;
  margin-bottom: var(--space-5);
}

.retrato {
  width: 100%;
  max-width: 30rem;
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}

.card__title {
  font-size: var(--text-xl);
}

/* Cuando el título es un enlace (tarjetas de artículos), hereda el color
   del título y solo se subraya al pasar por encima. */
.card__title a {
  color: inherit;
  text-decoration: none;
}

.card__title a:hover {
  color: var(--color-accent-ink);
  text-decoration: underline;
}

/* TARJETA CLICABLE ENTERA ("enlace estirado")
   Cada tarjeta tiene UN solo enlace, marcado con .card__link. Su ::after
   se estira sobre toda la tarjeta (position:absolute + inset:0, y la
   tarjeta es la referencia por su position:relative). Así se puede
   pulsar en cualquier parte, pero en el HTML sigue habiendo un único
   enlace: Google y el lector de pantalla leen solo su texto.
   Si una tarjeta tuviera dos enlaces, esto no sirve: el ::after de uno
   taparía al otro. */
.card {
  position: relative;
}

.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
}

/* Un transform convierte al botón en la nueva referencia del ::after:
   al pulsar (:active) la capa encogería al tamaño del botón a mitad de
   clic y el clic se perdería. En estos enlaces no se mueve el botón. */
.btn.card__link:hover,
.btn.card__link:active {
  transform: none;
}

/* Con teclado, el foco se marca en toda la tarjeta, que es lo que se
   va a abrir, y no solo en el botón. */
.card:has(.card__link:focus-visible) {
  outline: 2px solid var(--color-accent-ink);
  outline-offset: 3px;
}

.card__link:focus-visible {
  outline: none;
}

/* La etiqueta de categoría no debe estirarse al ancho de la tarjeta. */
.card .badge {
  align-self: flex-start;
}

.card__text {
  color: var(--color-text-muted);
}

/* El precio, con foco propio: etiqueta tintada de burdeos con el texto en
   color normal. El botón va con borde y sin relleno; así no se confunden. */
.card__price {
  align-self: flex-start;
  padding: var(--space-1) var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  background-color: color-mix(in srgb, var(--color-accent-ink) 14%, transparent);
  border-radius: var(--radius);
}

/* margin-top:auto empuja el CTA al fondo de la tarjeta. Así todos los
   botones de una fila quedan alineados aunque los textos midan distinto. */
.card__cta {
  margin-top: auto;
  padding-top: var(--space-2);
}

/* Imagen todavía no disponible: hueco con la proporción correcta para que
   el diseño no se descoloque cuando llegue la foto real. */
.placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-align: center;
  background-color: var(--color-bg-alt);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius);
}

/* ---------------------------------------------------------------------
   ETIQUETAS
   --------------------------------------------------------------------- */
.badge {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-badge-text);
  background-color: color-mix(in srgb, var(--color-accent) 12%, transparent);
  border-radius: var(--radius-full);
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0;
  list-style: none;
}

.tag {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text);
  background-color: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

/* ---------------------------------------------------------------------
   PREGUNTAS FRECUENTES
   ---------------------------------------------------------------------
   <details>/<summary>: acordeón nativo, sin JavaScript. Se oculta el
   triángulo del navegador y se dibuja un "+" que gira a "×" al abrir. */
.faq {
  max-width: 48rem;
  border-top: 1px solid var(--color-border);
}

.faq__item {
  border-bottom: 1px solid var(--color-border);
}

.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--tap-target);
  padding-block: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  cursor: pointer;
  list-style: none;                 /* quita el triángulo (Firefox, Chrome) */
}

.faq__question::-webkit-details-marker {
  display: none;                    /* quita el triángulo (Safari) */
}

.faq__question::after {
  content: "+";
  flex-shrink: 0;
  font-family: var(--font-body);
  font-size: 1.5em;
  font-weight: 400;
  line-height: 1;
  color: var(--color-accent-ink);
  transition: transform var(--transition);
}

.faq__item[open] .faq__question::after {
  transform: rotate(45deg);
}

.faq__question:hover {
  color: var(--color-accent-ink);
}

.faq__item p {
  padding-bottom: var(--space-4);
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   NIVELES DE PRECIO
   ---------------------------------------------------------------------
   Apilados en móvil, fila de 3 en cuanto caben. No se usa .grid porque
   dentro de media columna sus 17rem mínimos los apilarían siempre. */
.tiers {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
}

@media (min-width: 30em) {
  .tiers {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Cada nivel es un <button>. Los botones traen fuente, color y fondo
   propios del navegador: se heredan los de la página. */
.tier {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  height: 100%;
  padding: var(--space-5) var(--space-3);
  font: inherit;
  color: inherit;
  text-align: center;
  cursor: pointer;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}

.tier:hover {
  border-color: var(--color-accent-ink);
  transform: translateY(-2px);
}

/* Seleccionado: el estado vive en aria-pressed, igual que la página activa
   de la nav vive en aria-current. El segundo píxel de borde se pinta con
   box-shadow: cambiar border-width movería el contenido al seleccionar. */
.tier[aria-pressed="true"] {
  border-color: var(--color-accent-ink);
  box-shadow: 0 0 0 1px var(--color-accent-ink);
}

.tier__name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
}

.tier__price {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-accent-ink);
}

/* Cuando en vez de una cifra va texto ("Consulta precio"), a tamaño de
   cifra ocuparía dos líneas enormes. */
.tier__price--text {
  font-size: var(--text-lg);
}

.tier__note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   LÍNEA DE TIEMPO (Sobre mí)
   ---------------------------------------------------------------------
   Es un <ol>: los hitos tienen orden. La línea y el punto se dibujan con
   pseudo-elementos, sin añadir un solo <div> extra al HTML. */
.timeline {
  position: relative;
  padding: 0;
  list-style: none;
}

.timeline__item {
  position: relative;
  padding-bottom: var(--space-6);
  padding-left: var(--space-6);
}

/* La línea vertical */
.timeline__item::before {
  content: "";
  position: absolute;
  top: 0.75rem;
  bottom: 0;
  left: 0.3125rem;
  width: 2px;
  background-color: var(--color-border);
}

/* El punto */
.timeline__item::after {
  content: "";
  position: absolute;
  top: 0.5rem;
  left: 0;
  width: 0.75rem;
  height: 0.75rem;
  background-color: var(--color-accent);
  border-radius: 50%;
}

/* El último hito no necesita línea hacia abajo: no hay nada después. */
.timeline__item:last-child {
  padding-bottom: 0;
}

.timeline__item:last-child::before {
  display: none;
}

.timeline__title {
  margin-bottom: var(--space-1);
  font-size: var(--text-lg);
}

.timeline__when {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-accent-ink);
}

/* ---------------------------------------------------------------------
   REDES SOCIALES
   --------------------------------------------------------------------- */
.social {
  display: flex;
  gap: var(--space-2);
  padding: 0;
  list-style: none;
}

.social a {
  display: grid;
  place-items: center;
  width: var(--tap-target);
  height: var(--tap-target);
  color: inherit;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  transition: color var(--transition), border-color var(--transition);
}

.social a:hover {
  color: var(--color-accent-ink);
  border-color: currentColor;
}

/* ---------------------------------------------------------------------
   BLOQUE PROMOCIONAL (canal de Telegram en la Home)
   ---------------------------------------------------------------------
   Una caja con borde burdeos a la izquierda: destaca sin ser otra banda
   de color, que rompería la alternancia claro/gris de las secciones. */
.promo {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-5);
  /* Tinte burdeos sobre la superficie: destaca sobre el fondo de la sección
     sin perder el contraste del texto. */
  background-color: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface));
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent-ink);
  border-radius: var(--radius-lg);
}

/* Ocupa todo el ancho como el resto de secciones. En escritorio se parte
   en dos: la explicación a la izquierda, ventajas y botón a la derecha. */
@media (min-width: 56em) {          /* 896px, igual que .grid--split */
  .promo {
    grid-template-columns: 3fr 2fr;
    align-items: center;
    gap: var(--space-7);
    padding: var(--space-7);
  }
}

.promo .section__head {
  margin-bottom: 0;                 /* el hueco ya lo pone el gap */
}

.promo__cta {
  margin-top: var(--space-5);
}

/* Lista de ventajas con un check dibujado en CSS en vez de la viñeta.
   Es decorativo, así que va en ::before y el lector de pantalla no lo lee. */
.checklist {
  display: grid;
  gap: var(--space-2);
  padding: 0;
  list-style: none;
}

.checklist li {
  position: relative;
  padding-left: var(--space-5);
}

.checklist li::before {
  content: "";
  position: absolute;
  top: 0.35em;
  left: 0.2em;
  width: 0.4em;
  height: 0.7em;
  border: solid var(--color-accent-ink);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.contact-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 0;
  list-style: none;
}

.contact-list a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-target);
  font-weight: 500;
  text-decoration: none;
}

/* ---------------------------------------------------------------------
   FORMULARIOS
   --------------------------------------------------------------------- */
.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.form__grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

@media (min-width: 40em) {
  .form__grid--2 {
    grid-template-columns: 1fr 1fr;
  }
}

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

.field__label {
  font-size: var(--text-sm);
  font-weight: 600;
}

.field__hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--tap-target);
  padding: var(--space-3);
  color: var(--color-text);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.field textarea {
  min-height: 7rem;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--color-accent-ink);
  outline: none;                    /* se sustituye por el anillo de abajo */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-ink) 30%, transparent);
}

/* :invalid se dispara ANTES de que el usuario escriba nada, así que al
   cargar la página ya tendrías medio formulario en rojo.
   :user-invalid espera a que el campo se haya tocado de verdad. */
.field input:user-invalid,
.field textarea:user-invalid {
  border-color: #b3261e;
}

.form fieldset {
  /* Columna con hueco entre campos, igual que .form. Sin esto, los campos
     sueltos (el mensaje, bajo la rejilla) quedaban pegados. La <legend>
     no es un hijo flex normal: conserva su propio margin-bottom. */
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: 0;
  margin: 0;
  border: 0;
}

.form legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
}

.form__note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

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

@media (min-width: 30em) {
  .form__actions {
    flex-direction: row;
  }
}

/* Honeypot: campo trampa invisible para humanos. Los robots de spam
   rellenan todos los campos que encuentran; si este viene con contenido,
   el envío se descarta. Mejor que un captcha porque no molesta a nadie.
   No se usa .visually-hidden a propósito: aquí SÍ queremos ocultarlo
   también a los lectores de pantalla. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------------
   TEXTO LARGO (política de privacidad)
   --------------------------------------------------------------------- */
.prose {
  max-width: var(--max-width-prose);
}

.prose h2 {
  margin-top: var(--space-7);
  margin-bottom: var(--space-3);
  font-size: var(--text-xl);
}

.prose p,
.prose ul {
  margin-bottom: var(--space-4);
}

.prose ul,
.prose ol {
  padding-left: var(--space-5);
}

/* ---------------------------------------------------------------------
   ARTÍCULOS (sección Aprende)
   ---------------------------------------------------------------------
   El cuerpo del artículo es .prose: 65 caracteres de ancho, que es lo
   cómodo para leer. Estas piezas son lo que un artículo añade encima. */
.prose h3 {
  margin-top: var(--space-6);
  margin-bottom: var(--space-2);
  font-size: var(--text-lg);
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose ol {
  margin-bottom: var(--space-4);
}

/* Migas de pan visibles. Los separadores "/" los pone el CSS: así el
   lector de pantalla no los lee y el HTML queda como una lista limpia. */
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0;
  margin: 0 0 var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  list-style: none;
}

.breadcrumbs li + li {
  margin-top: 0;
}

.breadcrumbs li + li::before {
  content: "/";
  margin-right: var(--space-2);
}

.breadcrumbs a {
  color: inherit;
}

.article__meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.article__lead {
  font-size: var(--text-lg);
  color: var(--color-text-muted);
}

/* Las tablas no se encogen bien: en móvil se desplazan en horizontal
   dentro de su envoltorio en vez de romper el ancho de la página. */
.table-wrap {
  margin-bottom: var(--space-4);
  overflow-x: auto;
}

.prose table {
  width: 100%;
  min-width: 32rem;
  font-size: var(--text-sm);
  border-collapse: collapse;
}

.prose th,
.prose td {
  padding: var(--space-3);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}

.prose thead th {
  font-weight: 600;
  border-bottom-width: 2px;
}

.prose tbody th {
  font-weight: 600;
  color: var(--color-text-muted);
}

/* Llamada a la acción dentro del texto: misma familia visual que .promo
   (borde burdeos a la izquierda), pero siempre en una columna. */
.cta-box {
  padding: var(--space-5);
  margin-block: var(--space-6);
  background-color: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent-ink);
  border-radius: var(--radius-lg);
}

.prose .cta-box h2 {
  margin-top: 0;
}

.cta-box .form__actions {
  margin-top: var(--space-4);
  margin-bottom: 0;
}

/* ---------------------------------------------------------------------
   PÁGINA 404
   --------------------------------------------------------------------- */
.error-page {
  display: grid;
  place-items: center;
  gap: var(--space-4);
  min-height: 50vh;
  padding-block: var(--section-gap);
  text-align: center;
}

.error-page p {
  margin-inline: auto;
}

/* =========================================================================
   OFERTAS (páginas generadas por scripts/generar-ofertas.mjs)
   ========================================================================= */

/* Tarjetas más estrechas que las de servicios: caben 4 por fila. */
.grid--ofertas {
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
}

/* La foto de la tienda: botella sobre blanco, también en modo oscuro
   (las fotos de producto vienen con fondo blanco y un recuadro oscuro
   alrededor se vería sucio). contain: la botella entera, sin recortar. */
.oferta__media {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 3 / 4;
  margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) 0;
  overflow: hidden;
  background-color: var(--color-product-bg);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

/* La foto se ajusta AL RECUADRO (position:absolute + inset:0), no a su
   tamaño propio. Antes una foto alta desbordaba el recuadro y se cortaba
   por abajo: parecía "muy cerca". Las fotos ya vienen normalizadas del
   build (botella centrada con el mismo margen), así que no llevan padding. */
.oferta__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.oferta__media--grande {
  width: 100%;
  max-width: 28rem;
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.oferta__sin-foto {
  font-size: var(--text-sm);
  color: var(--color-product-muted);
}

.oferta__etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.badge--descuento {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
}

.oferta__nombre {
  font-size: var(--text-lg);
}

.oferta__detalle,
.oferta__tienda,
.ofertas__meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.oferta__precio {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

.oferta__precio-actual {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-accent-ink);
}

.oferta__precio--grande .oferta__precio-actual {
  font-size: var(--text-3xl);
}

.oferta__precio-antes {
  color: var(--color-text-muted);
}

/* El botón de compra va POR ENCIMA de la capa del enlace estirado
   (.card__link::after): así la tarjeta lleva a la ficha y el botón, a la
   tienda. */
.card__accion {
  position: relative;
  z-index: 1;
}

/* Filtros como "píldoras". Son enlaces a páginas estáticas, no JS: cada
   filtro es una URL que Google puede indexar. */
.filtros + .filtros {
  margin-top: var(--space-3);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chip {
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  text-decoration: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.chip:hover {
  border-color: var(--color-accent-ink);
}

.chip[aria-current="page"] {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-color: var(--color-accent-ink);
}

.chip__n {
  font-size: var(--text-xs);
  opacity: 0.75;
}

.paginacion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
}

.paginacion .btn {
  width: auto;
}

/* Obligatorio en todas las páginas de ofertas: visible, no letra pequeña
   escondida. */
.aviso-alcohol {
  font-size: var(--text-sm);
  font-weight: 600;
}

.aviso-ejemplo {
  padding: var(--space-3) var(--space-4);
  font-weight: 600;
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-radius: var(--radius);
}

.ofertas__vacio {
  padding: var(--space-6);
  text-align: center;
  color: var(--color-text-muted);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

/* Ficha: lista de datos en dos columnas (etiqueta | valor). */
.ficha-datos {
  display: grid;
  gap: var(--space-2);
}

.ficha-datos > div {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: var(--space-3);
  padding-block: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.ficha-datos dt {
  font-weight: 600;
}

.ficha-datos dd {
  margin: 0;
  color: var(--color-text-muted);
}

.ficha-datos--cata {
  max-width: var(--max-width-prose);
}

.oferta__subtitulo {
  font-size: var(--text-xl);
}

/* En móvil los filtros van en UNA fila que se desliza en horizontal, en
   vez de apilarse en seis líneas antes de llegar a las ofertas. */
@media (max-width: 40em) {
  .chips {
    flex-wrap: nowrap;
    padding-bottom: var(--space-2);
    overflow-x: auto;
    scrollbar-width: thin;
  }

  .chip {
    flex-shrink: 0;
  }
}

/* ---------------------------------------------------------------------
   EXPLORADOR DE OFERTAS (buscador, filtros y orden — assets/js/ofertas.js)
   ---------------------------------------------------------------------
   .solo-js: solo tiene sentido con JavaScript (la búsqueda se hace en el
   navegador). .sin-js: la alternativa para quien no lo tiene. Si los datos
   no cargan (.explorador--error), se vuelve a la versión sin JavaScript. */
html:not(.js) .solo-js,
.explorador--error .solo-js {
  display: none;
}

.js .explorador:not(.explorador--error) .sin-js {
  display: none;
}

.badge--nota {
  color: var(--color-text);
  background-color: var(--color-bg-alt);
  border: 1px solid var(--color-border);
}

/* Buscador */
.buscador {
  display: flex;
  gap: var(--space-2);
}

.buscador input {
  flex: 1;
  min-width: 0;
  min-height: var(--tap-target);
  padding: var(--space-3) var(--space-4);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.buscador input:focus {
  border-color: var(--color-accent-ink);
  outline: 2px solid var(--color-accent-ink);
  outline-offset: 1px;
}

.buscador .btn {
  width: auto;
}

/* Rejilla: filtros a la izquierda y resultados a la derecha en escritorio;
   en móvil los filtros se abren con un botón, encima de los resultados. */
.explorador {
  display: grid;
  gap: var(--space-6);
  margin-top: var(--space-6);
}

/* Barra (total y orden), filtros activos, rejilla y paginador: sin esto
   iban pegados unos a otros. El paginador se separa algo más: cierra la
   lista, no es parte de ella. */
.explorador__resultados {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.explorador__resultados > [data-paginacion] {
  margin-top: var(--space-3);
}

/* Vacíos no deben ocupar sitio: el gap de arriba los contaría igual. */
.explorador__activos:empty,
.explorador__resultados > [data-paginacion]:empty {
  display: none;
}

/* Páginas estáticas (por tipo y por tienda): mismo aire que el explorador. */
.filtros + .grid--ofertas {
  margin-top: var(--space-5);
}

.grid--ofertas + .paginacion {
  margin-top: var(--space-6);
}

/* Tras la lista, el bloque de Telegram con más aire que el paginador: si
   no, el paginador queda a medio camino y parece de ninguno de los dos. */
.explorador + .cta-box,
.paginacion + .cta-box {
  margin-top: var(--space-8);
}

@media (max-width: 63.99em) {
  .explorador__filtros {
    display: none;
  }

  .explorador--abierto .explorador__filtros {
    display: block;
    padding: var(--space-4);
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
  }
}

@media (min-width: 64em) {
  .explorador {
    grid-template-columns: 16rem 1fr;
    align-items: start;
  }

  /* El panel acompaña al hacer scroll, con su propio scroll si es largo. */
  .explorador__filtros {
    position: sticky;
    top: var(--space-4);
    max-height: calc(100vh - var(--space-6));
    padding-right: var(--space-2);
    overflow-y: auto;
  }

  .explorador__abrir,
  .explorador__cerrar {
    display: none;
  }
}

.explorador__filtros-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.explorador__titulo {
  font-size: var(--text-lg);
}

.explorador__cerrar {
  min-height: var(--tap-target);
  padding: 0 var(--space-4);
  font: inherit;
  font-weight: 600;
  color: var(--color-accent-text);
  cursor: pointer;
  background-color: var(--color-accent);
  border: 0;
  border-radius: var(--radius-full);
}

/* Barra de resultados: total, botón de filtros (móvil) y orden. */
.explorador__barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.explorador__total {
  font-weight: 600;
  scroll-margin-top: 6rem;
}

.explorador__abrir {
  width: auto;
}

.explorador__orden {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.explorador__orden select {
  min-height: var(--tap-target);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

/* Filtros activos, cada uno con su × para quitarlo. */
.explorador__activos:not(:empty) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.chip--quitar {
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  background-color: var(--color-bg-alt);
}

.explorador__limpiar {
  min-height: var(--tap-target);
  padding: 0 var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--color-accent-ink);
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: 0;
}

/* Grupos de filtros: <details> nativo, se pliega sin JS propio. */
.faceta {
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.faceta__titulo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target);
  font-weight: 600;
  cursor: pointer;
}

.faceta__marcadas {
  font-weight: 400;
  color: var(--color-accent-ink);
}

.faceta__opciones {
  display: grid;
  gap: var(--space-1);
  margin-top: var(--space-2);
}

.faceta__opcion {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.25rem;
  font-size: var(--text-sm);
  cursor: pointer;
}

.faceta__opcion input {
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
  accent-color: var(--color-accent);
}

.faceta__cuenta {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.faceta__mas {
  min-height: var(--tap-target);
  padding: 0;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-accent-ink);
  cursor: pointer;
  background: none;
  border: 0;
}

/* Paginación del explorador: números de página además de anterior/siguiente. */
.paginacion__num {
  min-width: var(--tap-target);
  min-height: var(--tap-target);
  font: inherit;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.paginacion__num[aria-current="page"] {
  color: var(--color-accent-text);
  cursor: default;
  background-color: var(--color-accent);
  border-color: var(--color-accent-ink);
}

.paginacion .btn:disabled {
  visibility: hidden;
}

.ofertas__vacio .btn {
  width: auto;
  margin-top: var(--space-3);
}

/* =========================================================================
   FICHA DE CATA (/ficha-de-cata) — formulario que genera el PDF
   =========================================================================
   Sigue el orden de la ficha impresa: un bloque por sección (La cata, El
   vino, Aspecto…). Las opciones de una sola respuesta son "píldoras":
   un radio real dentro de cada etiqueta, así funciona con teclado y con
   lector de pantalla, y el estilo sale de :has(input:checked). */
.ficha-enlaces {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.ficha-form {
  display: grid;
  gap: var(--space-6);
}

.ficha-form__bloque {
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

/* Cabecera burdeos como las bandas de la ficha impresa ("EL VINO", "NARIZ"…). */
.ficha-form__titulo {
  margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) var(--space-5);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.ficha-form__intro {
  margin-bottom: var(--space-4);
  color: var(--color-text-muted);
}

/* Rejilla de 6 columnas: cada campo ocupa lo que necesita. En móvil, todo
   a una columna. */
.ficha-form__campos {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

/* 12 columnas: cada fila tiene que sumar 12 para llegar al borde.
   entero 12 · ancho 8 (+ corto 4) · medio 6 + 6 · cuarto 3 × 4. */
@media (min-width: 40em) {
  .ficha-form__campos {
    grid-template-columns: repeat(12, 1fr);
  }

  .ficha-form__campos > * {
    grid-column: span 12;
  }

  .ficha-form__campos > .campo--ancho {
    grid-column: span 8;
  }

  .ficha-form__campos > .campo--medio {
    grid-column: span 6;
  }

  .ficha-form__campos > .campo--corto {
    grid-column: span 4;
  }

  .ficha-form__campos > .campo--cuarto {
    grid-column: span 3;
  }
}

.campo {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-width: none;                  /* es un <p>: sin el límite de lectura de los párrafos */
}

.campo label,
.opciones legend,
.epic legend {
  font-size: var(--text-sm);
  font-weight: 600;
}

.campo__ayuda {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.campo input,
.campo textarea {
  width: 100%;
  min-height: var(--tap-target);
  padding: var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.campo textarea {
  resize: vertical;
}

/* Obligatorios: asterisco en el rótulo y, si falta al enviar, borde de
   error (en campos) o marco de error (en grupos de opciones y EPIC). */
.obligatorio {
  color: var(--color-accent-ink);
  font-weight: 700;
}

.ficha-form__nota {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.campo.es-invalido input,
.campo.es-invalido textarea {
  border-color: var(--color-error);
  box-shadow: 0 0 0 1px var(--color-error);
}

fieldset.es-invalido {
  padding: var(--space-3);
  border: 2px solid var(--color-error);
  border-radius: var(--radius);
}

.campo input:focus,
.campo textarea:focus {
  border-color: var(--color-accent-ink);
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-ink) 30%, transparent);
}

/* Grupos de opciones */
.opciones,
.epic {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
  padding: 0;
  margin: 0;
  border: 0;
}

.opciones__lista {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.opcion {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-target);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  cursor: pointer;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  transition: background-color var(--transition), border-color var(--transition);
}

/* El radio/checkbox sigue ahí (accesible), pero invisible: se ve la píldora. */
.opcion input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.opcion:hover {
  border-color: var(--color-accent-ink);
}

.opcion:has(input:checked) {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-color: var(--color-accent-ink);
}

.opcion:has(input:focus-visible) {
  outline: 2px solid var(--color-accent-ink);
  outline-offset: 2px;
}

/* Las familias aromáticas (varias a la vez) llevan un check delante. */
.opciones--multiple .opcion:has(input:checked)::before {
  content: "✓";
  margin-right: var(--space-1);
}

.opcion--numero {
  justify-content: center;
  min-width: var(--tap-target);
  padding-inline: 0;
}

/* Casillas "sueltas" (defectuoso, consentimientos): casilla visible. */
.opcion--suelta {
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border: 0;
  border-radius: 0;
}

.opcion--suelta input {
  position: static;
  width: 1.2rem;
  height: 1.2rem;
  flex-shrink: 0;
  opacity: 1;
  pointer-events: auto;
  accent-color: var(--color-accent);
}

.opcion--suelta:has(input:checked) {
  color: inherit;
  background: none;
}

/* EPIC: cuatro casillas numéricas + total, como en la ficha. */
/* Arriba y no abajo: debajo de cada casilla va "/ 25" y el total no lo
   tiene, así que alineando por abajo el total quedaba descolgado. */
.epic__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-3);
}

.epic__campo {
  display: grid;
  gap: var(--space-1);
  font-size: var(--text-sm);
}

.epic__campo input {
  width: 5rem;
  min-height: var(--tap-target);
  padding: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  text-align: center;
  color: var(--color-text);
  background-color: var(--color-bg);
  border: 1px solid var(--color-accent-ink);
  border-radius: var(--radius);
}

.epic__campo input:disabled {
  opacity: 0.45;
}

.epic__campo small,
.epic__total small {
  color: var(--color-text-muted);
}

/* Misma estructura que una casilla (rótulo arriba, caja debajo) para que
   la caja del total quede a la altura de las otras cuatro. */
.epic__total {
  display: grid;
  gap: var(--space-1);
  font-size: var(--text-sm);
  font-weight: 600;
}

.epic__caja {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-bg-alt);
  border: 1px solid var(--color-accent-ink);
  border-radius: var(--radius);
}

.epic__total output {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.4;
  color: var(--color-accent-ink);
}

.epic__calidad output {
  font-weight: 600;
}

/* Foto: vista previa con la misma proporción que el hueco de la ficha. */
.foto {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 40em) {
  .foto {
    grid-template-columns: minmax(12rem, 16rem) 1fr;
    align-items: start;
  }

  .foto .campo__ayuda {
    grid-column: 2;
  }
}

.foto__vista {
  display: grid;
  place-items: center;
  aspect-ratio: 211 / 224;
  overflow: hidden;
  background-color: var(--color-bg);
  border: 2px dashed var(--color-accent-ink);
  border-radius: var(--radius-lg);
}

.foto__vista img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.foto__vacia {
  padding: var(--space-4);
  font-size: var(--text-sm);
  text-align: center;
  color: var(--color-text-muted);
}

.foto__vacia span {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-lg);
  color: var(--color-text);
}

.foto__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.foto__acciones .btn {
  cursor: pointer;
}

.foto__acciones .btn:has(input:focus-visible) {
  outline: 2px solid var(--color-accent-ink);
  outline-offset: 2px;
}

/* Acciones y publicación */
.ficha-form__estado:not(:empty) {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-weight: 600;
  background-color: var(--color-bg-alt);
  border-left: 4px solid var(--color-accent-ink);
  border-radius: var(--radius);
}

.ficha-form__estado[data-tipo="error"] {
  border-left-color: var(--color-error);
}

.publicar {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-5);
  background-color: var(--color-bg-alt);
  border-radius: var(--radius-lg);
}

.publicar h3 {
  font-size: var(--text-lg);
}

/* ---------------------------------------------------------------------
   GALERÍA DE CATAS (/catas) y detalle (/catas/ficha)
   --------------------------------------------------------------------- */
.cata__media {
  display: grid;
  place-items: center;
  aspect-ratio: 211 / 224;          /* la proporción del hueco de la ficha */
  margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) 0;
  overflow: hidden;
  background-color: var(--color-bg-alt);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.cata__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cata__media--grande {
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

/* Sin foto: la inicial del vino en grande, en Fraunces. */
.cata__sin-foto {
  font-family: var(--font-display);
  font-size: 4rem;
  font-style: italic;
  color: var(--color-accent-ink);
}

.cata__autor {
  margin-top: auto;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* Fichas oficiales (de Víctor): borde burdeos, sello "Verificada" y el
   autor en el color de la marca. El valor añadido se ve a primera vista. */
.badge--oficial {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-accent-ink);
  background-color: var(--color-surface);
  border: 1.5px solid var(--color-accent-ink);
}

.badge--oficial .icon {
  width: 1.1em;
  height: 1.1em;
}

.cata--oficial {
  border: 2px solid var(--color-accent-ink);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent-ink) 12%, transparent);
}

.cata--oficial .cata__autor {
  font-weight: 600;
  color: var(--color-accent-ink);
}

/* Tarjeta para crear tu ficha: primera de la lista, con borde discontinuo
   como el hueco de la foto de la ficha. */
.cata--crear {
  justify-content: center;
  gap: var(--space-3);
  min-height: 18rem;
  text-align: center;
  background-color: var(--color-bg-alt);
  border: 2px dashed var(--color-accent-ink);
}

.cata--crear .cata__autor {
  margin-top: var(--space-2);
}

/* Detalle de una ficha oficial: aviso con el sello, bajo el título. */
.cata-oficial {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  max-width: var(--max-width-prose);
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-bg-alt);
  border-left: 4px solid var(--color-accent-ink);
  border-radius: var(--radius);
}

.cata-oficial .icon {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  color: var(--color-accent-ink);
}

/* Página de un vino: una sección por añada. */
.vino__anada {
  margin-top: var(--space-7);
}

.vino__anada-titulo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.vino__anada-meta {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text-muted);
}

.campo small.campo__ayuda {
  display: block;
  margin-top: var(--space-1);
}

.revision__recordar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.cata-detalle__bloque + .cata-detalle__bloque,
.cata-detalle + .cata-detalle__bloque {
  margin-top: var(--space-6);
}

.cata-detalle__bloque .ficha-datos {
  max-width: var(--max-width-prose);
}

.revision {
  display: grid;
  gap: var(--space-5);
}

.revision__foto {
  width: 12rem;
  height: auto;
  border-radius: var(--radius);
}

/* Puntuaciones de la crítica en tarjeta y ficha de oferta: bien visibles. */
.oferta__puntos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.oferta__punto {
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text);
  background-color: var(--color-bg-alt);
  border: 1px solid var(--color-accent-ink);
  border-radius: var(--radius-full);
}

.oferta__punto strong {
  font-family: var(--font-display);
  color: var(--color-accent-ink);
}

/* ---------------------------------------------------------------------
   PANEL PRIVADO (/panel)
   Gráficas de una sola serie en el burdeos de la marca; los números y
   rótulos van siempre en colores de texto, nunca en el de la barra.
   --------------------------------------------------------------------- */
.panel {
  margin-top: var(--space-6);
}

.panel__nav {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) 0;
  background-color: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
}

.panel__nav a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--tap-target);
  font-weight: 600;
  text-decoration: none;
}

.panel__aviso:not(:empty) {
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-radius: 999px;
}

.panel__periodo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.panel__periodo .chip {
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  background-color: transparent;
}

.panel__periodo .chip[aria-pressed="true"] {
  color: var(--color-accent-text);
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}

.panel__seccion {
  margin-top: var(--space-7);
  scroll-margin-top: 5rem;
}

.panel__seccion > h2 {
  margin-bottom: var(--space-3);
}

.panel__nota,
.panel__vacio,
.panel__meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.panel__kpis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(13rem, 100%), 1fr));
  gap: var(--space-3);
}

.panel__kpi {
  padding: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.panel__kpi-valor {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  line-height: 1.1;
}

.panel__kpi-texto {
  font-weight: 600;
}

.panel__kpi-detalle {
  margin-top: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.panel__rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.panel__bloque {
  padding: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.panel__bloque + .panel__rejilla,
.panel__nota + .panel__bloque {
  margin-top: var(--space-4);
}

.panel__bloque h3 {
  margin-bottom: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-muted);
}

.panel__lista {
  display: grid;
  gap: var(--space-2);
  padding: 0;
  list-style: none;
}

.panel__lista li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

/* Columnas: 4px redondeadas arriba, apoyadas en la base, 2px entre ellas. */
.grafica__max {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.grafica__cols {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 10rem;
  border-bottom: 1px solid var(--color-border);
}

.grafica__col {
  position: relative;
  display: flex;
  flex: 1;
  align-items: flex-end;
  height: 100%;
}

.grafica__barra {
  width: 100%;
  background-color: var(--color-accent-ink);
  border-radius: 4px 4px 0 0;
}

.grafica__col:hover .grafica__barra {
  opacity: 0.75;
}

/* El valor, al pasar por encima (title lo da también a lectores). */
.grafica__col:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + var(--space-1));
  left: 50%;
  z-index: 2;
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
  white-space: nowrap;
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transform: translateX(-50%);
  pointer-events: none;
}

/* Los <p> tienen ancho de lectura; el eje ocupa todo el ancho de la gráfica. */
.grafica__eje,
.grafica__max {
  max-width: none;
}

.grafica__eje {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.grafica__tabla {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
}

.grafica__tabla summary {
  cursor: pointer;
  color: var(--color-text-muted);
}

.grafica__tabla table {
  margin-top: var(--space-2);
  border-collapse: collapse;
}

.grafica__tabla th,
.grafica__tabla td {
  padding: var(--space-1) var(--space-4) var(--space-1) 0;
  text-align: left;
}

/* Listas con barra horizontal proporcional al primero. */
.top {
  display: grid;
  gap: var(--space-3);
  padding: 0;
  list-style: none;
}

.top__fila {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}

.top__nombre {
  overflow-wrap: anywhere;
}

.top__valor {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.top__barra {
  grid-column: 1 / -1;
  height: 6px;
  background-color: var(--color-bg-alt);
  border-radius: 999px;
}

.top__barra > span {
  display: block;
  height: 100%;
  background-color: var(--color-accent-ink);
  border-radius: 999px;
}
