/**
 * Caché Match — layout y componentes.
 * Mobile-first. Consume solo tokens de tokens.css.
 */

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

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

body {
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font);
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--bg-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
img { display: block; max-width: 100%; }

/* ---------------------------------------------------------------- fondo ---- */

/*  La textura, fija detras de todo. Antes eran tres degradados radiales que
 *  ademas se movian; ahora es la tela del diseño. Va en este elemento y no
 *  en el body porque `fixed` no depende del scroll y asi no se repinta. */
.bloom {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--bg-base) var(--bg-img) center / cover no-repeat;
}

/* ---------------------------------------------------------------- shell ---- */

.shell {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 0 var(--gutter);
  max-width: 1440px;
  margin: 0 auto;
}

/* ---------------------------------------------------------------- topbar --- */

.topbar {
  flex: none;
  display: grid;
  grid-template-columns: 2.5rem 1fr 2.5rem;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) 0;
  min-height: var(--topbar-h);
}

@media (min-width: 768px) {
  .topbar { grid-template-columns: 3rem 1fr 3rem; padding: var(--s-5) 0; }
}

/* Colocacion explicita: con display:none la auto-colocacion metia la barra
   de progreso en la columna 1 (2.5rem) y salia aplastada a 20px. */
#backBtn { grid-column: 1; }
.track   { grid-column: 2; }
.skip    { grid-column: 3; }

.nav-btn {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  transition: background var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.nav-btn:hover { background: rgba(255,255,255,.5); }
.nav-btn svg { width: 1.375rem; height: 1.375rem; }
.nav-btn[hidden] { display: none; }

.skip {
  justify-self: end;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  padding: .5rem .25rem;
  white-space: nowrap;
  transition: opacity var(--t-fast) var(--ease);
}
.skip:hover { opacity: .6; }
.skip[hidden] { display: none; }

/* Progreso: pista fina centrada, del ancho del referente. */
.track[hidden] { display: none; }

.track {
  justify-self: center;
  width: min(58%, 14rem);
  height: 4px;
  border-radius: var(--r-pill);
  background: rgba(23,24,26,.14);
  overflow: hidden;
}
.track-fill {
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: var(--ink);
  transition: width .52s var(--ease-out);
}

/* ------------------------------------------------------------------ vista -- */

.view {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-bottom: var(--s-6);
}
.view[hidden] { display: none; }

/* =========================================================== movimiento ===
   Todo se anima con transform / opacity / filter para que el compositor
   haga el trabajo. La direccion importa: avanzar y volver no se sienten
   igual, y eso es lo que da la sensacion de estar recorriendo algo.
   ======================================================================= */

/* Entrada generica, con cascada opcional via --i. */
@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 20px, 0); }
  to   { opacity: 1; transform: none; }
}
.rise {
  animation: rise .58s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

/* --- transicion entre preguntas --- */

@keyframes headIn {
  from { opacity: 0; transform: translate3d(0, 16px, 0); filter: blur(10px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes headInBack {
  from { opacity: 0; transform: translate3d(0, -14px, 0); filter: blur(10px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes colOut {
  from { opacity: 1; transform: none; filter: blur(0); }
  to   { opacity: 0; transform: translate3d(0, -16px, 0); filter: blur(7px); }
}
@keyframes colOutBack {
  from { opacity: 1; transform: none; filter: blur(0); }
  to   { opacity: 0; transform: translate3d(0, 16px, 0); filter: blur(7px); }
}
@keyframes optIn {
  from { opacity: 0; transform: translate3d(0, 16px, 0) scale(.95); }
  to   { opacity: 1; transform: none; }
}

/* La salida se anima sobre la columna entera: una sola capa compuesta. */
.q-col[data-phase="out-fwd"]  { animation: colOut     .19s var(--ease-in) both; }
.q-col[data-phase="out-back"] { animation: colOutBack .19s var(--ease-in) both; }

.q-col[data-phase="in-fwd"]  .q-head { animation: headIn     .56s var(--ease-out) both; }
.q-col[data-phase="in-back"] .q-head { animation: headInBack .56s var(--ease-out) both; }

/* Las opciones caen en cascada, despues del encabezado. */
.q-col[data-phase^="in"] .opt {
  animation: optIn .5s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger) + 110ms);
}
.q-col[data-phase^="in"] .confirm {
  animation: optIn .5s var(--ease-out) both;
  animation-delay: calc(var(--n, 4) * var(--stagger) + 150ms);
}

/* --- feedback al elegir --- */

/* La elegida da un golpe corto; las demas se apagan y ceden protagonismo. */
@keyframes chosen {
  0%   { transform: scale(1); }
  42%  { transform: scale(1.045); }
  100% { transform: scale(1); }
}
.pill.is-chosen { animation: chosen .34s var(--ease-spring); }

.pill.is-dimmed {
  opacity: .32;
  transform: scale(.97);
}

/* --- resultado --- */

/* Revelado por mascara. El padding negativo evita cortar los descendentes. */
.mask {
  overflow: hidden;
  padding-bottom: .12em;
  margin-bottom: -.12em;
}
.mask > span {
  display: block;
  animation: maskUp .74s var(--ease-out) both;
  animation-delay: .06s;
}
@keyframes maskUp {
  from { transform: translate3d(0, 105%, 0); }
  to   { transform: none; }
}

/* La firma se asienta con un acercamiento minimo. */
@keyframes sigSettle {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}
/* La foto se asienta al entrar. Va sobre el LIENZO, no sobre la imagen: el
   lienzo recorta con radio, asi que escalar la imagen dentro le comia el
   frasco por abajo. Escalando el conjunto no se recorta nada. */
.sig { animation: sigSettle 1.5s var(--ease-out) both; }


/* --- deriva del fondo --- */

/* Movimiento muy lento: el degradado nunca queda del todo quieto, pero
   tampoco llama la atencion. */
@keyframes drift {
  0%, 100% { transform: scale(1)    translate3d(0, 0, 0); }
  50%      { transform: scale(1.09) translate3d(-1.6%, -1.2%, 0); }
}

/* --- accesibilidad --- */

@media (prefers-reduced-motion: reduce) {
  .rise, .sig, .mask > span,
  .pill.is-chosen,
  .q-col[data-phase] .q-head,
  .q-col[data-phase] .pill,
  .q-col[data-phase] .confirm,
  .q-col[data-phase] { animation: none !important; }
  .pill.is-dimmed { opacity: .5; transform: none; }
  .track-fill { transition: none; }
}

/* ----------------------------------------------------------------- texto --- */

.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: var(--s-4);
}

/*  48: interlineado 1.2 y -.02 de tracking, como `.side-title`. */
.qtitle {
  font-size: var(--fs-title);
  font-weight: 800;
  line-height: var(--lh-title);
  letter-spacing: var(--tr-tight);
  max-width: 17ch;
  text-wrap: balance;
}

.helper {
  margin-top: var(--s-4);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  max-width: 38ch;          /* los 554 del export, medidos en caracteres */
}

/* --------------------------------------------------------------- pildoras -- */

/* Clave del referente: abrazan su contenido, no ocupan el ancho completo.
   align-items:flex-start es lo que produce el escalonado natural. */
.pills {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-2);
  margin-top: var(--s-5);
}

.pill {
  position: relative;
  padding: var(--s-4) var(--s-6);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-size: var(--fs-pill);
  font-weight: 500;
  letter-spacing: -.01em;
  text-align: left;
  transition:
    transform var(--t-mid) var(--ease-out),
    opacity var(--t-mid) var(--ease-out),
    background var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease);
}

@media (hover: hover) {
  .pill:hover { transform: translateY(-2px); }
}
.pill:active { transform: translateY(0) scale(.985); }

.pill[aria-pressed="true"] {
  background: var(--ink);
  color: var(--surface);
}

.pill:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* La pregunta 10 es multi-seleccion: en fila, no en columna. */
.pills.wrap {
  flex-direction: row;
  flex-wrap: wrap;
  max-width: 34rem;
}

/* Confirmar la multi-seleccion. */
.confirm {
  margin-top: var(--s-5);
  align-self: flex-start;
  padding: var(--s-4) var(--s-7);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--surface);
  font-size: var(--fs-pill);
  font-weight: 600;
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.confirm:hover { transform: translateY(-2px); }
.confirm[hidden] { display: none; }

/* ------------------------------------------------------------------ hero --- */

.hero {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: var(--s-7);
}

/*  72: interlineado .99 y sin tracking, como `.match-name`. */
.hero h1 {
  font-size: var(--fs-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: 0;
  max-width: 15ch;
}

.hero .lede {
  margin-top: var(--s-4);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  max-width: 38ch;
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin-bottom: var(--s-5);
}
.wordmark b {
  font-size: var(--fs-eyebrow);
  font-weight: 800;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
}
.wordmark span {
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
}

.meta-line {
  margin-top: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  font-size: var(--fs-micro);
  color: var(--ink-faint);
}

/* --------------------------------------------------------------- perfil ---- */

/*  Resumen de respuestas acumuladas, discreto al pie de cada pregunta.
 *  Va fuera del flujo a proposito: con `margin-top:auto` se comia todo el
 *  espacio libre de la columna, y entonces la primera pregunta salia
 *  centrada (aun no hay chips) y las demas pegadas al techo. El salto se
 *  veia al pasar de la una a la dos. */
.profile {
  margin-top: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
}
@media (min-width: 900px) {
  .profile { position: absolute; left: 0; right: 0; bottom: var(--s-6); margin-top: 0; }
}
.profile:empty { display: none; }

.chip {
  padding: var(--s-1) var(--s-2);
  border-radius: var(--r-chip);
  border: 1px solid var(--hairline-mid);
  font-size: var(--fs-micro);
  font-weight: 500;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* -------------------------------------------------------------- resultado -- */

.result-head { margin-bottom: var(--s-5); }

/* Tarjeta principal, ya sin tarjeta.
   REGLA DE FORMA, una sola para toda la pantalla:
     - lo que se pulsa (botones) va en capsula completa
     - las superficies con imagen llevan 12px
     - el resto no lleva radio: se agrupa con lineas de 1px y con aire
   Antes convivian ocho radios distintos y cada bloque iba metido en su propia
   caja con sombra. Eso es lo que hacia que la pantalla se leyera como un
   tablero de widgets en lugar de como una pagina. */
.match {
  background: none;
  border-radius: 0;
  box-shadow: none;
}

.sig {
  position: relative;
  /* Apaisada y con techo en vh: el match tiene que entrar en pantalla
     entero. Una foto que obliga a bajar deja de ser un veredicto y pasa a
     ser el principio de un scroll. */
  aspect-ratio: 4 / 3;
  max-height: 34vh;
  display: grid;
  place-items: center;
  border-radius: 12px;
  overflow: hidden;
  background: var(--sig-bg, linear-gradient(135deg, #dfe4c8, #a9ccd6));
}

.match-brand {
  margin: var(--s-4) 0 0;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink-faint);
}
.match-name {
  margin: .375rem 0 0;
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -.03em;
}
.match-score {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem .625rem;
  margin: var(--s-2) 0 0;
  font-size: .875rem;
  color: var(--ink-soft);
}
.match-score b {
  font-size: 3.25rem;
  font-weight: 600;
  line-height: .9;
  color: var(--ink);
  letter-spacing: -.04em;
}
.score-k { color: var(--ink-soft); }
.score-price {
  padding-left: .625rem;
  border-left: 1px solid var(--hairline-mid);
  color: var(--ink-faint);
}

/* El match ocupa la banda superior entera y el resto de la pantalla baja a
   un segundo plano declarado. Antes el protagonismo se repartia entre ocho
   bloques del mismo peso y no ganaba ninguno: se leia como un panel de
   control, no como un veredicto. Densidad abajo, jerarquia arriba. */
.match-id { min-width: 0; }
.advice { max-width: 42ch; }
.result-grid { margin-top: var(--s-7); }

/* Las notas eran seis pildoras. En texto ocupan menos, se leen antes y no
   piden ser pulsadas, que es lo que una pildora promete sin cumplir. */
.notes-line {
  margin: var(--s-3) 0 0;
  padding-top: var(--s-3);
  border-top: 1px solid var(--hairline);
  font-size: .875rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 46ch;
}
.notes-k {
  display: block;
  margin-bottom: .125rem;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Aviso cuando el catalogo no cubre del todo lo que se pidio. Discreto:
   informa sin parecer un error. */
.heads-up {
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-left: 2px solid var(--hairline-mid);
  font-size: .875rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.heads-up b {
  color: var(--ink);
  font-weight: 600;
}

/* Alternativas: mismo lenguaje, jerarquia menor. */
/* Las filas ya se separan con su propia linea: el gap sobra. */
.alts { margin-top: 0; }
.alt {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  padding: .75rem 0;
  border: 0;
  border-top: 1px solid var(--hairline);
  border-radius: 0;
  background: none;
  text-align: left;
  transition: opacity var(--t-fast) var(--ease);
}
.alt:hover { background: var(--surface); transform: translateY(-1px); }
.alt-sig {
  width: 3rem; height: 3rem;
  border-radius: 12px;
  background: var(--sig-bg, #dfe4c8);
  background-size: contain;
}
/* Igual en la miniatura, con el fondo de su propia fila. */
.alt-sig.has-photo {
  background-color: var(--surface);
  background-blend-mode: multiply;
  background-clip: padding-box;
  background-origin: content-box;
  border: 1px solid var(--hairline);
  padding: .3125rem;
}
/* Son <span> dentro de un <span>: sin display:block no se apilan. */
.alt-name, .alt-brand { display: block; }
.alt-name { font-size: .9375rem; font-weight: 600; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alt-brand { font-size: .75rem; color: var(--ink-faint); margin-top: .125rem; }
.alt-score { font-size: .8125rem; font-weight: 600; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

.result-actions {
  margin-top: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
}

/* .confirm nace como boton solitario (margin-top + align-self). Dentro de
   la fila de acciones esas dos propiedades lo desalineaban del ghost. */
.result-actions .confirm {
  margin-top: 0;
  align-self: auto;
}

.ghost {
  padding: 1.0625rem 1.75rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline-mid);
  font-size: var(--fs-pill);
  font-weight: 500;
  transition: background var(--t-fast) var(--ease);
}
.ghost:hover { background: rgba(255,255,255,.6); }

.empty {
  padding: var(--s-6) 0;
  max-width: 34ch;
}
.empty p { margin-top: var(--s-3); color: var(--ink-soft); line-height: var(--lh-body); }

/* ------------------------------------------------------------- desktop ----- */

/* En pantallas grandes el contenido vive en una columna editorial a la
   izquierda y el degradado respira a la derecha. Nada de mobile estirado. */
@media (min-width: 900px) {
  .view, .hero { justify-content: center; }
  /*  Centrar aqui centraba en el hueco que deja la barra, no en la pantalla:
   *  el bloque caia 28px por debajo del centro real y con la barra encima se
   *  leia todavia mas bajo. Compensar la barra con relleno abajo lo sube a su
   *  sitio, y los --s-4 de propina son el centrado optico, que pide unos
   *  pixeles por encima del centro geometrico. Va en las dos vistas para que
   *  el bloque no de un salto al pasar de la portada a la primera pregunta. */
  .view, .hero { padding-bottom: calc(var(--topbar-h) + var(--s-4)); }
  .q-col { max-width: 46rem; }
  /* Dos columnas con peso real. Antes la izquierda solo llevaba la tarjeta y
     la derecha acumulaba siete bloques, asi que una quedaba vacia y la otra
     desbordada. El desglose del porque pertenece al perfume, asi que baja a
     la columna principal y equilibra la pagina. */
  .result-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
    gap: var(--s-7);
    align-items: start;
  }
  .qtitle { max-width: 20ch; }

  /* Visual y ficha a la par. Antes el visual iba en media columna con seis
     bloques compitiendo al lado. */
  /* La columna de la foto mide lo que mide la foto, no la mitad de la
     pantalla. Con `1fr` la caja se estiraba y la ficha quedaba empujada al
     borde derecho con un vacio enorme en medio. */
  .match {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--s-6);
    align-items: center;
  }
  .sig {
    height: min(46vh, 25rem);
    width: auto;
    aspect-ratio: 1 / 1;
    max-height: none;
  }
  .match-name { font-size: 3.25rem; }
  .match-score b { font-size: 4.5rem; }
}

/* --- opcion + su badge de ayuda --- */

/* El badge es hermano de la pildora, no hijo: asi la pildora se queda limpia
   y el signo no compite con la etiqueta por la atencion. */
.opt {
  display: flex;
  align-items: center;
  gap: .5rem;
  max-width: 100%;
}

.hint-badge {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--hairline-mid);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-faint);
  font: 400 .8125rem/1 var(--font);
  cursor: help;
  opacity: .75;
  transition:
    border-color var(--t-fast) var(--ease),
    background    var(--t-fast) var(--ease),
    color         var(--t-fast) var(--ease),
    opacity       var(--t-fast) var(--ease),
    transform     var(--t-fast) var(--ease-out);
}
@media (hover: hover) {
  .hint-badge:hover { opacity: 1; border-color: var(--ink); color: var(--ink); transform: scale(1.08); }
}
.hint-badge[aria-expanded="true"] {
  opacity: 1;
  border-color: var(--ink);
  background: var(--ink);
  color: var(--surface);
}

.hint-bubble {
  max-width: 38ch;
  margin: var(--s-1) 0 var(--s-1) var(--s-4);
  padding-left: var(--s-3);
  border-left: 1px solid var(--hairline-mid);
  color: var(--ink-soft);
  font-size: .875rem;
  line-height: 1.5;
  animation: hintIn .28s var(--ease) both;
}
@keyframes hintIn {
  from { opacity: 0; transform: translateY(-.25rem); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .hint-bubble { animation: none; } }

/* Una opcion sin catalogo detras. No se esconde: se apaga y se explica,
   porque desaparecer una opcion que estaba hace un momento se lee como un
   fallo de la pagina. */
.opt.is-agotada .pill {
  opacity: .42;
  cursor: not-allowed;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--hairline-mid);
}
@media (hover: hover) {
  .opt.is-agotada .pill:hover { transform: none; }
}
.agotada-nota {
  max-width: 38ch;
  margin: calc(var(--s-1) * -1) 0 var(--s-1) var(--s-4);
  padding-left: var(--s-3);
  border-left: 1px solid var(--hairline-mid);
  color: var(--ink-soft);
  font-size: .875rem;
  line-height: 1.5;
}

/* --- breadcrumb de respuestas --- */
/* Sin cajas: filas separadas por una linea de 1px, que es lo que aguanta
   ocho elementos sin que el bloque parezca un enjambre de botones. */

.crumbs-wrap { margin-top: var(--s-5); }
.crumbs-title,
.crumbs-foot {
  margin: 0;
  color: var(--ink-faint);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
}
.crumbs-foot {
  display: inline;
  margin-left: .5rem;
  font-weight: 400;
  letter-spacing: .04em;
  text-transform: none;
}

/* Una sola columna. En la columna lateral del resultado, dos columnas dejan
   menos de 9rem por celda y los valores se truncaban ("Noche y ev...",
   "No tengo p..."), que es justo lo que el breadcrumb tiene que evitar. */
.crumbs { margin-top: var(--s-2); }

/* Rejilla de tres: icono, pregunta, respuesta. La columna de la pregunta con
   ancho fijo para que las respuestas queden alineadas y el bloque se lea como
   una tabla y no como una lista suelta. */
.crumb {
  display: grid;
  grid-template-columns: 1rem 5.25rem minmax(0, 1fr);
  align-items: center;
  gap: .625rem;
  padding: .6875rem .125rem;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  border-radius: 0;
  background: none;
  font-size: .875rem;
  text-align: left;
  color: var(--ink);
  transition: color var(--t-fast) var(--ease);
}
.crumb .ico { color: var(--ink-faint); transition: color var(--t-fast) var(--ease); }
@media (hover: hover) {
  .crumb:hover { color: var(--ink); }
  .crumb:hover .ico { color: var(--ink); }
  .crumb:hover .crumb-v { text-decoration: underline; text-underline-offset: 3px; }
}
.crumb-k {
  color: var(--ink-faint);
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: var(--tr-key);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
}
.crumb-v { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Icono compartido por breadcrumb y desglose. */
.ico {
  flex: none;
  width: 1rem;
  height: 1rem;
}

/* --- desglose del porque --- */

.breakdown {
  margin-top: var(--s-5);
  border-top: 1px solid var(--hairline);
  padding-top: var(--s-3);
}
.breakdown > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  list-style: none;
  color: var(--ink);
  font-size: .9375rem;
  font-weight: 500;
}
.breakdown > summary::-webkit-details-marker { display: none; }
/* Un + que se convierte en −, sin flechas ni chevrones. */
.breakdown > summary::after {
  content: '';
  width: .75rem;
  height: .75rem;
  background:
    linear-gradient(var(--ink-soft), var(--ink-soft)) center/100% 1px no-repeat,
    linear-gradient(var(--ink-soft), var(--ink-soft)) center/1px 100% no-repeat;
  transition: transform .3s var(--ease-out);
}
.breakdown[open] > summary::after {
  background: linear-gradient(var(--ink-soft), var(--ink-soft)) center/100% 1px no-repeat;
  transform: rotate(180deg);
}

.bd-body { padding-top: var(--s-3); }
.bd-intro, .bd-note {
  margin: 0 0 var(--s-3);
  color: var(--ink-soft);
  font-size: .8125rem;
  line-height: 1.55;
}
.bd-note { margin: var(--s-3) 0 0; }
.bd-note b { color: var(--ink); font-weight: 600; }

.bd-list { list-style: none; margin: 0; padding: 0; }
/* Sin linea separadora: la barra ya separa las filas. Con las dos, cada fila
   tenia dos rayas horizontales a pocos pixeles y el bloque se veia sucio. */
/* Dos lineas por fila: la pregunta arriba y la respuesta debajo. En una sola
   linea la respuesta se truncaba ("Arriesgado, que ..."), porque esta columna
   del resultado es estrecha en pantalla ancha tambien. */
.bd-row {
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr) 2.75rem;
  gap: .125rem .75rem;
  padding: .4375rem 0 .875rem;
  font-size: .875rem;
}
.bd-row .ico {
  grid-row: 1 / 3; grid-column: 1;
  align-self: center;
  color: var(--ink-faint);
}
.bd-k {
  grid-row: 1; grid-column: 2 / -1;
  color: var(--ink-faint);
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: var(--tr-key);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bd-v { grid-row: 2; grid-column: 2; color: var(--ink); }
.bd-n {
  grid-row: 2; grid-column: 3;
  color: var(--ink); text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
.bd-n i { color: var(--ink-faint); font-style: normal; font-size: .6875rem; }

/* De borde a borde y despegada del texto: pegada bajo la etiqueta se leia
   como un subrayado, no como una medida. */
.bd-bar {
  grid-row: 3; grid-column: 1 / -1;
  margin-top: .375rem;
  height: 3px;
  background: var(--hairline);
  border-radius: 2px;
  overflow: hidden;
}
.bd-bar i {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: var(--ink);
  transform-origin: left;
  animation: barIn .7s var(--ease-out) both;
}
@keyframes barIn { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) { .bd-bar i { animation: none; } }

/* Lo que el perfume NO cumplio: se apaga, no se tacha. */
.bd-zero .bd-v, .bd-zero .bd-n { color: var(--ink-faint); }
.bd-zero .ico { opacity: .4; }

@media (max-width: 560px) {
  .crumbs { grid-template-columns: 1fr; }
  .crumb  { grid-template-columns: 1rem 4.75rem minmax(0, 1fr); }
  .bd-row { gap: .125rem .5rem; }
}

/* --- el consejo, en lugar de la lista de vinetas --- */
.advice {
  margin: var(--s-3) 0 0;
  max-width: 34em;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* --- cambio de una respuesta desde el resultado --- */

/* Al cambiar de tarjeta -- corrigiendo una respuesta o subiendo una de las
   alternativas -- solo se reanima el match. El resto de la pantalla ya
   estaba ahi: relanzar la cascada entera, titulo incluido, se siente como si
   la pagina se recargara.
   El :not(.swap-in) importa: la tarjeta lleva las dos clases, y sin excluirla
   este reset le ganaba por especificidad y la dejaba tambien sin animar. */
.result-body.is-swap .rise:not(.swap-in) { animation: none; }
.result-body.is-swap .mask > span { animation: none; }

.swap-in { animation: swapIn .42s var(--ease-out) both; }
@keyframes swapIn {
  from { opacity: 0; transform: translateY(6px) scale(.995); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .swap-in { animation: none; } }

/* --- lo que el perfil pide y no tenemos --- */

/* Sin caja. Se separa del resto con una linea y aire, no con un contenedor
   de color: encerrar cada bloque en su propia tarjeta era lo que hacia que
   la pantalla pareciera un tablero y no una pagina. */
.gap { margin-top: var(--s-5); padding-top: var(--s-4); border-top: 1px solid var(--hairline); }
.gap-list { list-style: none; margin: 0; padding: 0; }
.gap-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s-2);
  padding: .5rem 0;
}
.gap-row + .gap-row { border-top: 1px solid var(--hairline); }
.gap-name, .gap-meta { display: block; }
.gap-name {
  font-size: .9375rem;
  font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gap-meta { margin-top: .0625rem; font-size: .75rem; color: var(--ink-faint); }
.gap-score { font-size: .8125rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.gap-foot {
  margin: var(--s-3) 0 0;
  font-size: .75rem;
  line-height: 1.55;
  color: var(--ink-faint);
  max-width: 44ch;
}


/* --- columnas del resultado --- */

/* Los titulillos de la columna lateral. Uno por bloque, en el mismo registro
   que el resto de la pagina: no son etiquetas decorativas, dicen que hay
   debajo. */

/* Al apilarse en movil las dos columnas se tocaban: el desglose terminaba
   y las alternativas empezaban sin aire de por medio. */
.col-side { margin-top: var(--s-6); }
.col-side > * + * { margin-top: var(--s-5); }
@media (min-width: 768px) { .col-side { margin-top: 0; } }
.col-side .crumbs-wrap { margin-top: var(--s-5); }

/* El desglose cuelga del perfume, no de la columna lateral. */
.col-main .breakdown { margin-top: var(--s-5); }


/* ========================================================================== */
/*  PANTALLA FINAL                                                            */
/*                                                                            */
/*  Un solo bloque. Sustituye por completo las capas anteriores, que se       */
/*  pisaban por cascada y provocaron varios fallos reales.                    */
/* ========================================================================== */

/* Paleta propia de esta pantalla: crema y vino. */
/*  Esta pantalla ya no tiene paleta propia: sus nombres apuntan a los
 *  tokens. Se quedan porque medio bloque los usa, pero el valor es uno. */
#resultView {
  --crema:   transparent;
  --vino:    var(--accent);
  --tinta:   var(--ink);
  --suave:   var(--ink-soft);
  --linea:   var(--hairline);
  --panel:   #fffdf9;
  --display: var(--font);
}
/*  El resultado ya no se pinta sobre un crema plano ni cambia de familia:
 *  mismo fondo y misma letra que el test, que es lo que hacia que las dos
 *  mitades del producto parecieran de dos sitios distintos. */
body.on-result { background: transparent; }
/* La barra de navegacion del test no pinta en el resultado: aqui manda la
   barra de la tienda. */
body.on-result .topbar { display: none; }

/*  Esa barra que se quita era lo unico que separaba el contenido del borde de
 *  arriba, asi que al llegar al resultado la tarjeta quedaba en top:0. En
 *  escritorio no se nota porque la vista centra; en un telefono queda debajo
 *  de la barra del navegador y del notch, y la cabecera de la publicacion se
 *  lee cortada.
 *
 *  No se devuelven los 5rem enteros de la barra —en un telefono eso es
 *  pantalla desperdiciada—, sino el MISMO margen que ya tiene a los lados:
 *  asi la tarjeta queda dentro de un marco parejo y el espacio se lee como
 *  decidido y no como un numero suelto. Si algun dia cambia --gutter, esto
 *  cambia con el.
 *
 *  El env() se apoya en el viewport-fit=cover que ya trae index.html; donde
 *  no haya notch, el 0px de reserva lo deja igual. */
@media (max-width: 959px) {
  body.on-result #resultView {
    padding-top: calc(var(--gutter) + env(safe-area-inset-top, 0px));
  }
}

/* --- barra de la tienda --- */

.site-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-4) 0 var(--s-5);
}
.nav-brand { display: flex; align-items: center; gap: var(--s-3); }
.nav-word {
  font-family: var(--display);
  font-size: 2.25rem;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--tinta);
}
.nav-claim {
  padding-left: var(--s-3);
  border-left: 1px solid var(--linea);
  font-size: .5625rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
}
.nav-links { display: flex; align-items: center; gap: var(--s-4); }
.nav-links a {
  font-size: .9375rem;
  color: var(--tinta);
  text-decoration: none;
  transition: opacity var(--t-fast) var(--ease);
}
.nav-links a:hover { opacity: .6; }

/* --- reticula --- */

.final { display: grid; gap: var(--s-5); }
@media (min-width: 960px) {
  .final {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s-6);
    align-items: center;
  }
}

/* --- la publicacion --- */

.post {
  position: relative;
  border-radius: 1.25rem;
  background: var(--panel);
  box-shadow: 0 2px 6px rgba(28, 26, 24, .05), 0 24px 60px rgba(28, 26, 24, .10);
}
.post-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
}
.post-ava {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--vino);
  color: #fff;
  font-family: var(--display);
  font-size: 1.125rem;
}

/*  El avatar lleva la marca, no una letra suelta.
 *
 *  Va como MASCARA y no como <img>: asi hereda el `color` del circulo en vez
 *  de traer el tono quemado dentro del archivo. app.css no escribe colores
 *  literales, y un SVG con el hex dentro es exactamente eso, solo que
 *  escondido donde nadie lo busca al cambiar la direccion de arte.
 *
 *  El SVG es assets/img/marca.svg, recortado del logo original a solo
 *  "CACHE": la linea "PERFUME" del logotipo completo mide, dentro de este
 *  circulo, unos 4 px de alto. Ni se lee ni deja leer la de arriba.
 *
 *  El span va VACIO en el HTML. Antes llevaba una "C" de respaldo y no
 *  funciono: el `font-size: 0` que la ocultaba lo pisaba el .post-ava de mas
 *  abajo, asi que se veian las dos cosas a la vez. Con la letra fuera no hay
 *  cascada que pelear.
 */
.post-ava::before {
  content: '';
  display: block;
  width: 74%;
  aspect-ratio: 466.1 / 111.8;
  background: currentColor;
  -webkit-mask: url('../img/marca.svg') no-repeat center / contain;
          mask: url('../img/marca.svg') no-repeat center / contain;
}
.post-id b { display: block; font-size: .875rem; font-weight: 600; }
.post-id small { display: block; font-size: .75rem; color: var(--suave); }
.post-more { color: var(--suave); letter-spacing: var(--tr-wide); }

.post-shot {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--sig-bg, var(--crema));
  isolation: isolate;
}
.post-shot.has-photo { background: var(--crema); }
.shot-frasco img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: var(--s-5);
  object-fit: contain;
  object-position: center center;
  mix-blend-mode: multiply;
}
.post-shot .sig-mark { position: absolute; inset: 0; display: grid; place-items: center; }

.post-bar {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
}
.post-ico { display: block; width: 1.5rem; height: 1.5rem; color: var(--tinta); }
.post-ico svg { width: 100%; height: 100%; }
.post-like { color: var(--vino); fill: currentColor; }
.post-like svg { fill: currentColor; }
.post-save { margin-left: auto; }

@media (max-width: 719px) {
}

/* --- la ficha --- */

.flip { perspective: 1600px; position: relative; }
.flip-in {
  position: relative;
  transform-style: preserve-3d;
  transition: transform .72s var(--ease-out);
}
.flip.is-flipped .flip-in { transform: rotateY(180deg); }
.face { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.face-b {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  border-radius: 1.25rem;
  background: var(--panel);
  overflow: hidden;
}
.face-scroll {
  position: absolute;
  inset: var(--s-4);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--linea) transparent;
  padding-right: var(--s-3);
}
.face-scroll::-webkit-scrollbar { width: 5px; }
.face-scroll::-webkit-scrollbar-track { background: transparent; }
.face-scroll::-webkit-scrollbar-thumb { background: var(--linea); border-radius: var(--r-pill); }

/*  En movil el resultado usaba otra escala que el escritorio: 11px de
 *  antetitulo, un serif de 36 para el titular y el nombre en vino. Ahora
 *  son los mismos tokens, solo que en su tramo pequeño. */
#resultView .eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink);
}
.side-title {
  margin: var(--s-4) 0 var(--s-4);
  font-size: var(--fs-title);
  font-weight: 800;
  line-height: var(--lh-title);
  letter-spacing: var(--tr-tight);
  color: var(--tinta);
}
.match-brand {
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--ink);
}
.match-name {
  margin: var(--s-4) 0 0;
  font-size: var(--fs-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--ink);          /* el nombre NO es rojo, ni aqui ni alli */
}
.match-score {
  display: flex;
  align-items: baseline;
  gap: var(--s-5);
  margin: 0;
}
.match-score b {
  font-size: var(--fs-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: 0;
  color: var(--ink);
}
.score-k { font-size: var(--fs-lead); color: var(--ink); }
.advice {
  margin: var(--s-2) 0 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
  max-width: 38ch;
}

/* --- acordes --- */

/* Marcador: aqui va la foto del acorde cuando lleguen los 32 archivos. */

/* --- banner y acciones --- */


/*  Los tres botones del pie de la columna miden igual: el de compartir manda
 *  y los dos secundarios lo copian. Solo cambia el relleno —macizo uno,
 *  contorno los otros dos— porque no compiten por lo mismo. */
.cta, .cta-sec {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  width: 100%;
  margin-top: var(--s-4);
  padding: 1.125rem 1.5rem;
  border-radius: var(--r-pill);
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}
.cta {
  border: 0;
  background: var(--vino);
  color: #fff;
}
/*  El contorno va de `box-shadow` y no de `border` a proposito: con
 *  `border-box`, si el contenido ya llena el `min-height`, el borde suma sus
 *  2px por fuera y el secundario salia de 73 contra los 71 del macizo. La
 *  sombra interior no ocupa caja, asi que los tres miden exactamente igual. */
.cta-sec {
  border: 0;
  box-shadow: inset 0 0 0 1px var(--linea);
  background: transparent;
  color: var(--tinta);
}
.cta:hover { transform: translateY(-1px); opacity: .93; }
.cta-sec:hover { background: rgba(255, 255, 255, .55); }

.flip-btn {
  cursor: pointer;
}
/*  El icono va en `em`: con el cuerpo del lienzo a 29px, 1rem se quedaba en
 *  un garabato al lado del texto. */
.cta-sec .ico { width: 1.1em; height: 1.1em; flex: none; }
.flip-btn .ico { transition: transform var(--t-mid) var(--ease); }
.flip-btn:hover .ico { transform: rotate(-180deg); }
.flip.is-peek:not(.is-flipped) .flip-in { transform: rotateY(-11deg); }

@keyframes hintIcono { from { transform: rotate(0); } to { transform: rotate(-360deg); } }
@keyframes nudgePeek {
  0%, 100% { transform: none; }
  25%      { transform: rotateY(-11deg); }
  55%      { transform: rotateY(-4deg); }
}
.flip-btn.nudge .ico { animation: hintIcono 1.15s cubic-bezier(.65, 0, .35, 1) 2; }
.flip.is-nudging:not(.is-flipped) .flip-in { animation: nudgePeek 1.15s var(--ease) 2; }

/* --- alternativas y pie --- */

.final-foot {
  display: grid;
  gap: var(--s-4);
  margin-top: var(--s-5);
  align-items: center;
}
@media (min-width: 960px) {
  .final-foot { grid-template-columns: minmax(0, 1fr) auto; }
}
.others { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); }
.other {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: .75rem;
  align-items: center;
  padding: 0; border: 0; background: none; text-align: left; cursor: pointer;
  transition: opacity var(--t-fast) var(--ease);
}
.other:hover { opacity: .7; }
.other-shot {
  position: relative;
  width: 3.5rem; height: 3.5rem;
  border-radius: 1rem;
  overflow: hidden;
  background: var(--sig-bg, var(--panel));
  isolation: isolate;
}
.other-shot.has-photo { background: var(--panel); }
.other-shot img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  padding: .3125rem; object-fit: contain; mix-blend-mode: multiply;
}
.other-name {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: .8125rem; font-weight: 600; line-height: 1.2;
}
.other-score { display: block; font-size: .75rem; color: var(--suave); }

.shop-badge {
  display: inline-flex; align-items: center; gap: .5rem;
  justify-self: start;
  padding: .875rem 1.5rem;
  border: 1px solid var(--vino);
  border-radius: var(--r-pill);
  color: var(--vino);
  font-size: .9375rem; font-weight: 600; text-decoration: none;
  transition: background var(--t-fast) var(--ease);
}
.shop-badge::after { content: "↗"; font-size: .8125rem; }
.shop-badge:hover { background: rgba(109, 26, 38, .07); }

.final-extra { margin-top: var(--s-5); }
.linkish {
  padding: 0; border: 0; background: none;
  font: inherit; color: var(--suave);
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}

/* --- el paso del nombre --- */

.name-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); width: 100%; }
.name-input {
  flex: 1 1 14rem; min-width: 0;
  padding: 1.0625rem 1.5rem;
  border: 1px solid var(--hairline-mid);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit; font-size: var(--fs-pill);
}
.name-input:focus { outline: none; border-color: var(--ink); }
.name-form .confirm { margin-top: 0; align-self: auto; }
.name-form .confirm:disabled { background: var(--ink-soft); cursor: not-allowed; }
.name-form .confirm:disabled:hover { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .flip-in, .flip-btn .ico { transition: none; }
  .flip-btn.nudge .ico, .flip.is-nudging:not(.is-flipped) .flip-in { animation: none; }
}

/* ===================== que entre en pantallas reales ===================== */

/* La tarjeta era cuadrada: a 1366x768 medía 714px de alto ella sola y el
   boton quedaba fuera. Ahora el alto lo manda la ventana y la foto ocupa lo
   que sobra entre la cabecera y la barra de acciones. `contain` se encarga
   de que el frasco se vea entero sea cual sea la proporcion resultante. */
/* La foto se queda CUADRADA, como en la referencia. Lo que se limita es el
   ANCHO de la tarjeta, calculado desde el alto libre de la ventana: asi la
   composicion mantiene su proporcion en vez de estirarse.
   El descuento cubre la barra de navegacion, la cabecera y la barra de
   acciones de la tarjeta, y el pie de enlaces. */
@media (min-width: 960px) {
  .post {
    width: min(100%, 68vh);
    margin: 0 auto;
  }
  .flip, .flip-in, .face-a { height: 100%; }
  .face-a {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 0;
  }
}

/* Pantallas bajas: se recorta lo prescindible antes que dejar el boton
   fuera de vista. */
@media (min-width: 960px) and (max-height: 860px) {
  .site-nav { padding: var(--s-3) 0 var(--s-4); }
  .side-title { margin-bottom: var(--s-3); }
  .cta, .cta-sec { margin-top: var(--s-3); padding: .9375rem 1.5rem; }
  .cta-sec { margin-top: .5rem; padding: .5625rem 1rem; }
  .advice { margin-top: var(--s-2); }
  .final-foot { margin-top: var(--s-3); }
  .other-shot { width: 3rem; height: 3rem; }
}

@media (min-width: 960px) and (max-height: 780px) {
  .post { width: min(100%, 62vh); }
  .advice { display: none; }   /* lo primero que sobra cuando falta alto */
}

/*  Los dos secundarios miden lo mismo que el principal: solo cambia el
    relleno. Del ancho de su texto competian mal con un boton de 685. */

/* Pie de enlaces discretos: lo que el mockup no tiene pero la tienda
   necesita (comprar) y las pruebas de oficina tambien (empezar de nuevo). */
.final-extra {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  margin-top: var(--s-4);
}
.mini-link {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: .875rem;
  color: var(--suave);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.mini-link:hover { color: var(--vino); }

/* ================== la tarjeta, con las medidas del SVG ================== */

/*  Del archivo de Illustrator, lienzo 1920x1080:
 *    tarjeta   679 x 849   radio 9.92        -> proporcion 4:5, radio 1.46%
 *    cabecera   85 de alto (10.01% del alto)
 *    foto      651 x 679, 14 de margen lateral (2.06%)
 *    barra      85 de alto
 *    avatar    ⌀56 (8.25% del ancho)   puntos ⌀9.16
 *    textos    Raleway 18.95 y Light 16.29  (2.79% y 2.40% del ancho)
 *
 *  Todo va en porcentaje del ancho de la tarjeta (`cqw`), no en px: asi la
 *  composicion se mantiene identica al diseño en cualquier pantalla, que es
 *  justo lo que a ojo no me salia.
 */
.post {
  container-type: inline-size;
  display: grid;
  grid-template-rows: 10.01% 79.98% 10.01%;
  aspect-ratio: 679 / 849;
  border-radius: 1.46cqw;
  overflow: hidden;
}

.post-head {
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 2.4cqw;
  padding: 0 4.8cqw;
  align-items: center;
}
.post-ava {
  width: 8.25cqw;
  height: 8.25cqw;
  font-size: 3.4cqw;
}
.post-id b     { font-size: 2.79cqw; font-weight: 400; }
.post-id small { font-size: 2.40cqw; font-weight: 400; margin-top: .2cqw; }

/* Los tres puntos: en el diseño son circulos de 9.16, no un caracter. */
.post-more {
  display: flex;
  gap: .58cqw;
  letter-spacing: 0;
  font-size: 0;
}
.post-more::before,
.post-more::after,
.post-more span { content: ""; }
.post-more::before,
.post-more::after {
  width: 1.35cqw;
  height: 1.35cqw;
  border-radius: 50%;
  background: var(--tinta);
}

.post-shot {
  margin: 0 2.06%;
  border-radius: 1.46cqw;
  background: #f2f2f2;
  aspect-ratio: auto;
  height: 100%;
  min-height: 0;
}
.shot-frasco img { padding: 6cqw; }

/* Barra de acciones: like en el 8% del ancho, comentario en el 21.6%,
   compartir en el 29.3% y guardar pegado al borde derecho. */
.post-bar {
  align-items: center;
  gap: 8.8cqw;
  padding: 0 7.9cqw;
}
.post-ico { width: 4.9cqw; height: 4.9cqw; }
.post-like svg { fill: currentColor; }

/* El ancho lo marca el alto libre, manteniendo la proporcion 4:5. */
@media (min-width: 960px) {
  .post {
    width: min(100%, calc((100vh - 12rem) * 0.8));
    margin: 0 auto;
  }
}

/* ============= la tarjeta, con las medidas de Figma (1920x1080) ========== */

/*  tarjeta        681 x 860   en (281,121)   #E8E8E8   radio 16
 *  foto           651 x 683   en (296,213)   #E8E8E8   radio 16
 *  avatar          63 x 63    en (309,141)   #FFFFFF   circulo
 *  nombre                     en (391,146)   Inter 600 24/120%  -0.02em  #1E1E1E
 *  "Tu match"                 en (391,174)   Inter 400 20/120%          #757575
 *  tres puntos   35.3 x 9.15  en (895,166)   #000
 *  barra       613.56 x 35.51 en (314,924)   iconos #3C3C3B
 *
 *  Todo en cqw (% del ancho de la tarjeta) para que la proporcion no
 *  dependa de la resolucion. Las divisiones estan hechas sobre 681 y 860.
 */
#resultView { --crema: transparent; }

/*  La tarjeta es blanca calida sobre la textura, no gris. El gris #e8e8e8
 *  del export de Figma era de prueba. */
.post {
  background: var(--panel);
  border-radius: 2.35cqw;                 /* 16 / 681 */
  grid-template-rows: 10.70% 79.42% 9.88%;  /* 92 · 683 · resto de 860 */
  aspect-ratio: 681 / 860;
  box-shadow: var(--lift-card);
}

.post-head { padding: 0 4.11cqw; gap: 2.79cqw; }   /* 28 y 19 de 681 */
.post-ava {
  width: 9.25cqw;                          /* 63 / 681 */
  height: 9.25cqw;
  background: var(--panel);
  color: var(--vino);
  font-size: 4cqw;
  /*  La elipse tiene que verse. El diseño la puso blanca sobre una tarjeta
   *  gris, pero la tarjeta paso a blanco calido y el circulo quedo del mismo
   *  #fffdf9 que su fondo: invisible. El filo la devuelve sin inventar un
   *  tono nuevo, que es lo que haria falta para distinguir dos blancos. */
  box-shadow: inset 0 0 0 .15cqw var(--hairline);
}
.post-id b {
  font-family: 'Inter', var(--font);
  font-size: 3.52cqw;                      /* 24 / 681 */
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -.02em;
  color: var(--tinta);
}
.post-id small {
  font-family: 'Inter', var(--font);
  font-size: 2.94cqw;                      /* 20 / 681 */
  font-weight: 400;
  line-height: 1.2;
  color: var(--suave);
  margin-top: 0;
}

.post-more { gap: .58cqw; }                /* 3.92 / 681 */
.post-more::before,
.post-more::after {
  width: 1.34cqw;                          /* 9.15 / 681 */
  height: 1.34cqw;
  background: var(--tinta);
}

.post-shot {
  margin: 0 2.20cqw;                       /* 15 / 681 */
  width: 95.6%;                            /* 651 / 681 */
  border-radius: 2.35cqw;
  background: var(--surface-warm);
}
.shot-frasco img { padding: 3cqw; mix-blend-mode: multiply; }

/* La barra arranca a 33 del borde y mide 613.56 de ancho. Los iconos caen
   en el 0%, 13.5%, 24.87% y 94.84% de ese ancho. */
.post-bar {
  padding: 0 4.85cqw;
  gap: 4.1cqw;
  align-items: center;
}
.post-ico { width: 5.5cqw; height: 5.5cqw; color: var(--tinta); }
/* El corazon va marcado: es la unica accion de la barra que ya esta dada. */
.post-like { color: var(--vino); }

/* Los tres puntos son TRES elementos. Con ::before y ::after solo salian
   dos, y parecia que el tercero estaba recortado por la esquina. */
.post-more { display: flex; align-items: center; gap: .58cqw; font-size: 0; }
.post-more::before, .post-more::after { content: none; }
.post-more i {
  width: 1.34cqw;      /* 9.15 / 681 */
  height: 1.34cqw;
  border-radius: 50%;
  background: var(--tinta);
}

/* Los radios son 16px del diseño, no una fraccion del ancho: en cqw se
   encogian junto con la tarjeta y quedaban mas secos que en Figma. */
.post,
.post-shot { border-radius: 1rem; }

/* El area de la foto se separa de la tarjeta por un punto de calidez, no
   por un gris. */
.post-shot,
.post-shot.has-photo { background: var(--surface-warm); }

/* El hueco de la foto se distingue de la tarjeta. Va mas CLARO y no mas
   oscuro por una razon tecnica: la foto se funde con `multiply`, asi que el
   fondo tiñe el frasco. Sobre un gris oscuro el envase saldria sucio; sobre
   uno mas claro que la tarjeta se separa igual y la foto queda limpia. */
.post-shot,
.post-shot.has-photo { background: var(--surface-warm); }

.post { position: relative; overflow: visible; }
.post-shot { overflow: hidden; }

/*  Sin soporte de cristal se vuelve al panel solido: media transparencia sin
 *  desenfoque deja el texto ilegible sobre la foto. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
}

/*  La de arriba se ancla por la izquierda y crece hacia dentro de la
 *  tarjeta. La de abajo se ancla por la DERECHA y crece tambien hacia
 *  dentro: si creciera hacia fuera se comeria el hueco que la separa de la
 *  columna de texto, que en 1920 es de cinco pixeles. */
/*  Las dos flotan sobre el FRASCO, no sobre la tira de notas.
 *
 *  La de arriba estaba anclada a la izquierda y tapaba la primera ficha
 *  entera. Ahora las dos salen por el lado derecho, a alturas distintas para
 *  que no se lean como una columna, y el lado izquierdo queda limpio. */

/* ============== la tarjeta anclada al lienzo de 1920x1080 =============== */

/*  En Figma la tarjeta esta en (281,121) y mide 681x860 sobre 1920x1080.
 *  Traducido a la ventana:
 *      izquierda  281/1920 = 14.64vw
 *      ancho      681/1920 = 35.47vw
 *      arriba     121/1080 = 11.20vh
 *      alto       860/1080 = 79.63vh   (lo da la proporcion 681/860)
 *
 *  Antes la tarjeta heredaba el ancho del contenedor del test (1440
 *  centrado, con 6rem de margen), asi que arrancaba en 345 y medía 590.
 *  Los tamaños de dentro estaban bien; lo que fallaba era el marco. */
@media (min-width: 960px) {
  #resultView {
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: 100vw;
    padding: 0;
  }

  .site-nav { padding: 2vh 5vw 0 14.64vw; }

  .final {
    grid-template-columns: 35.47vw minmax(0, 1fr);
    gap: 2vw;
    margin: 0 5vw 0 14.64vw;
    grid-auto-rows: auto;
    align-items: start;
  }

  .post {
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .final-foot,
  .final-extra { margin-left: 14.64vw; margin-right: 5vw; }
}

/* ========================= responsive ==================================== */

/*  El diseño es un lienzo fijo de 1920x1080. Para llevarlo a pantallas
 *  reales hay tres tramos, y en los tres la tarjeta manda: todo lo de
 *  dentro va en `cqw`, asi que basta con darle el ancho correcto y la
 *  composicion se mantiene sola. */

/* --- pantallas anchas: la proporcion del lienzo, con techo de alto ------- */
@media (min-width: 960px) {
  .post {
    /* 35.47vw es el ancho del diseño. El segundo termino evita que en una
       pantalla ancha y baja la tarjeta (proporcion 681/860) se salga por
       abajo: se limita por el alto libre y se recalcula el ancho. */
    width: min(35.47vw, calc((100vh - 11rem) * 681 / 860));
  }
  /* Si el alto manda, la columna se queda ancha y la tarjeta bailaria:
     se ancla a la izquierda, que es donde esta en el diseño. */
  .final { justify-items: start; }
}

/* --- tableta: una sola columna, tarjeta centrada ------------------------- */
@media (max-width: 959px) {
  #resultView { margin: 0; width: auto; padding: 0; }

  .site-nav { padding: var(--s-3) 0 var(--s-4); }
  .nav-links { gap: var(--s-3); font-size: .8125rem; }

  .final {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-5);
    margin: 0;
  }
  .post {
    width: min(100%, calc((100vh - 22rem) * 681 / 860));
    min-width: 17rem;
    margin: 0 auto;
  }

  .flip, .flip-in, .face-a { height: auto; }
  .face-a { justify-content: flex-start; }
  .face-b { position: relative; inset: auto; min-height: 24rem; }
}

/* --- teléfono ----------------------------------------------------------- */
@media (max-width: 719px) {
  /* Los enlaces del nav no caben: queda la marca. */
  .nav-links { display: none; }

  .post { width: 100%; }
   /* 100 - 44.35: pegada al borde derecho */

  .match-score b { font-size: 1.75rem; }
  .cta, .cta-sec { font-size: 1rem; padding: 1rem; }
  .final-extra { gap: var(--s-3); }
}

@media (max-width: 719px) {
  body.on-result { overflow-x: hidden; }
  .final, .post, .final-foot, .final-extra { max-width: 100%; }
}

/* ============ la columna derecha, medidas de Figma (1920x1080) =========== */

/*  Todo arranca en x=1123 (58.49vw) con 685 de ancho util (35.68vw).
 *  Las verticales salen de restar posiciones consecutivas del export, asi
 *  que los huecos son los del diseño y no una interpretacion mia.
 *
 *  Dos cosas que yo tenia mal y este export corrige:
 *    - NO hay serif. El titular es Inter 800 de 48, no Playfair.
 *    - El nombre del perfume es #1E1E1E, no vino. El rojo (#C92D2D) es de
 *      los circulos de acorde y del boton, no del texto.
 */
@media (min-width: 960px) {
  .final {
    grid-template-columns: 35.47vw minmax(0, 35.68vw);
    gap: 8.38vw;                      /* 1123 - (281+681) */
    margin: 0 0 0 14.64vw;
  }
  .face-a { padding: 0; display: block; }

  /* --- textos --- */
  #resultView .eyebrow {
    font-family: 'Inter', var(--font);
    font-size: .9375vw;               /* 18 */
    font-weight: 400;
    letter-spacing: var(--tr-wide);
    text-transform: uppercase;
    color: var(--tinta);
    margin: 0;
  }
  .side-title {
    font-family: 'Inter', var(--font);
    font-size: 2.5vw;                 /* 48 */
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: 0;
    color: var(--tinta);
    margin: 1.94vh 0 0;               /* 175-132-22 = 21 */
  }
  .match-brand {
    font-family: 'Inter', var(--font);
    font-size: .9375vw;
    font-weight: 400;
    letter-spacing: var(--tr-wide);
    color: var(--tinta);
    margin-top: 1.85vh;               /* 20 */
  }
  .match-name {
    font-family: 'Inter', var(--font);
    font-size: 3.75vw;                /* 72 */
    font-weight: 800;
    line-height: .99;
    letter-spacing: 0;
    color: var(--vino);               /* el nombre SI es vino */
    margin-top: 1.94vh;               /* 21 */
    min-height: 0;
  }
  .match-score { margin-top: 0; align-items: baseline; gap: 1.5vw; }
  .match-score b {
    font-family: 'Inter', var(--font);
    font-size: 3.75vw;                /* 72 */
    font-weight: 800;
    line-height: .99;
    letter-spacing: 0;
    color: var(--tinta);
  }
  .score-k {
    font-family: 'Inter', var(--font);
    font-size: 1.51vw;                /* 29 */
    font-weight: 400;
    color: var(--tinta);
  }
  .advice {
    font-family: 'Inter', var(--font);
    font-size: 1.25vw;                /* 24 */
    font-weight: 400;
    line-height: 1.2;
    color: var(--tinta);
    max-width: 28.85vw;               /* 554 */
    margin-top: 0;
  }

  /* --- acordes: circulos rojos de 109, separados 241 --- */

  /* --- los tres botones: mismo ancho y mismo alto --- */
  .cta, .cta-sec {
    width: 35.68vw;                   /* 685 */
    min-height: 6.57vh;               /* 71 */
    border-radius: 9999px;
  }
  .cta {
    border: 0;
    background: var(--vino);
    color: #fff;
    margin-top: .65vh;                /* 965 - 958 */
  }
}

/* ================== escala normalizada del resultado ==================== */

/*  UNA sola unidad para toda la pantalla.
 *
 *  `--u` vale 1 pixel del lienzo de Figma, que ahora es 1920x950: el alto
 *  real que deja el navegador en una pantalla de 1080. La unidad se queda
 *  con el menor de los dos factores, el de ancho y el de alto, asi que la
 *  composicion SIEMPRE cabe y nunca se deforma.
 *
 *  Al alto disponible se le descuenta antes lo que NO esta en el export y
 *  sin embargo ocupa sitio: el boton de girar y la fila de enlaces de
 *  abajo. Sin ese descuento el lienzo mide 950 pero la pagina pide 950 mas
 *  esos dos bloques, y se vuelve a salir por abajo, que es justo lo que
 *  veniamos arreglando.
 *
 *  A partir de aqui, cada medida del diseño se escribe con su numero real:
 *      font-size: calc(48 * var(--u))   ->  los 48px del export
 *
 *  Los cuerpos son los seis del diseño. Los espacios, en cambio, venian
 *  sueltos (21, 20, 21, 35, 28, 25, 7...): se redondean a multiplos de 4,
 *  que es lo que les da coherencia sin separarse del original.
 */
#resultView {
  --fuera: 8rem;                   /* boton de girar + enlaces, fuera del export */
  /*  Alto de la composicion. 24 de margen + 960 de tarjeta serian 984, pero
   *  se reservan 1060: el aviso de lo que el perfume no cumple aparece en la
   *  mayoria de los resultados y ocupa hasta tres lineas. Sin esa reserva el
   *  boton de girar se salia de la ventana justo cuando hay algo que leer. */
  --alto: 1060;
  --u: min(0.0520833vw, calc((100vh - var(--fuera)) / var(--alto)));

  --t-eyebrow: calc(18 * var(--u));
  --t-label:   calc(22 * var(--u));
  --t-body:    calc(24 * var(--u));
  --t-lead:    calc(29 * var(--u));
  --t-title:   calc(48 * var(--u));
  --t-display: calc(72 * var(--u));
  --t-name:    calc(88 * var(--u));   /* el nombre manda: es el resultado */

  --s1: calc( 8 * var(--u));
  --s2: calc(12 * var(--u));
  --s3: calc(16 * var(--u));
  --s4: calc(20 * var(--u));
  --s5: calc(24 * var(--u));
  --s6: calc(32 * var(--u));
  --s7: calc(40 * var(--u));
}

@media (min-width: 960px) {
  /*  El lienzo escalado se centra. Sus margenes no son simetricos (281 a la
   *  izquierda, 110 a la derecha), asi que no vale con `auto`: se reparte a
   *  los lados lo que sobra de los 1920, y dentro cada pieza conserva su
   *  posicion exacta del diseño. */
  #resultView {
    padding-left: calc((100vw - 1920 * var(--u)) / 2);
    padding-right: calc((100vw - 1920 * var(--u)) / 2);
    /*  Las migas son el ultimo bloque y terminaban justo en el borde de la
     *  pagina: el scroll se acababa en la misma linea del texto y parecia
     *  cortado. El aire va aqui como relleno y no como margen del ultimo
     *  hijo, porque un margen inferior al final del documento se colapsa y
     *  no llega a crear zona desplazable. */
    padding-bottom: calc(120 * var(--u));
  }

  /*  La tarjeta crece de 681x860 a 760x960 para llegar al pie de la columna
   *  de texto. No se estira: mantiene la proporcion 681/860, asi que crecer
   *  a lo alto la ensancha.
   *
   *  El reparto a lo ancho de los 1920:
   *      165  tarjeta 760  hueco 145  columna 685  165
   *  Los margenes son IGUALES a los dos lados. En el export no lo eran (281
   *  a la izquierda y 110 a la derecha) y la composicion se veia escorada;
   *  ahora lo que sobra se parte por la mitad. El hueco central se lleva lo
   *  que sale de esa cuenta: 145, veinte mas que antes.
   *
   *  Y el lienzo mide 984 de alto: 24 de margen mas los 960 de la tarjeta.
   *  Es el numero que consume `--alto` ahi arriba. */
  .final {
    grid-template-columns: calc(760 * var(--u)) calc(685 * var(--u));
    gap: calc(145 * var(--u));
    margin-left: calc(165 * var(--u));
    margin-top: calc(24 * var(--u));    /* la tarjeta arranca en y=24 */
    justify-content: start;
  }
  /* La columna de texto empieza en y=34 y la tarjeta en y=24: diez abajo. */
  .col-right { padding-top: calc(10 * var(--u)); }
  .post { width: 100%; max-width: none; }

  /*  La tarjeta mide 960 y la columna de texto 1032, asi que la izquierda
   *  terminaba 92px antes y los dos botones quedaban sueltos debajo de todo,
   *  con un hueco muerto encima. Ahora la columna se estira hasta el alto de
   *  la fila y los botones se anclan a su pie con `margin-top: auto`: caen
   *  solos a la altura del pie de la columna de texto, sin numeros magicos,
   *  y siguen ahi aunque el consejo cambie de largo.
   *
   *  Los margenes laterales se anulan porque ya los pone la rejilla. Los dos
   *  botones miden 655 de los 760 de la columna, asi que no envuelven. */
  /*  `justify-self: stretch` + `width: 100%` por lo mismo que en .col-right:
   *  la rejilla lleva `justify-items: start`, que dimensiona la celda por su
   *  CONTENIDO en vez de por su pista, y sin esto la columna salia de 675 en
   *  vez de 760 y la tarjeta encogia con ella. */
  .col-left {
    align-self: stretch; justify-self: stretch; width: 100%;
    display: flex; flex-direction: column; min-width: 0;
  }
  /*  La tarjeta absorbe el alto que le sobra a la columna, en vez de dejar
   *  un hueco entre ella y el boton de comprar.
   *
   *  La columna de texto no mide siempre igual: medida sobre ocho
   *  resultados va de 1055 a 1203. Lo que mas la mueve no es el nombre a dos
   *  lineas (34px) sino el aviso de lo que el perfume no cumple, que sale en
   *  la mayoria y ocupa 49 o 73. Con la tarjeta fija, el boton se separaba
   *  hasta 172px de ella.
   *
   *  Crece, pero con tope: la tarjeta es una publicacion y estirarla los 148
   *  del peor caso la dejaba en 760x1108, una proporcion que ya no parece un
   *  post. El tope son 1056, un 10% mas de alto, y de ahi para arriba vuelve
   *  a haber hueco. `flex-shrink: 0` porque encoger no debe pasar nunca: si
   *  la columna de texto fuera mas corta, manda la tarjeta. */
  .col-left .post { flex: 1 0 auto; max-height: calc(1056 * var(--u)); margin-bottom: var(--s5); }
  .col-left .final-extra { margin: auto 0 0; }

  /*  El pie de la columna de texto se ancla igual, para que las dos columnas
   *  terminen en la misma linea. Sin esto la fila la marcaba la derecha (1032)
   *  y en la izquierda solo sobraban 72px: los botones salian pegados a la
   *  tarjeta, a 5px. Anclando los dos pies manda la columna mas alta y el
   *  hueco bajo la tarjeta es el que se le pida. */
  .col-right { align-self: stretch; }

  /* --- tipografia: los seis cuerpos del diseño --- */
  #resultView .eyebrow { font-size: var(--t-eyebrow); }
  .match-brand         { font-size: var(--t-eyebrow); }
  .side-title          { font-size: var(--t-title); }
  .match-name          { font-size: var(--t-name); }
  .match-score b       { font-size: var(--t-display); }
  .score-k             { font-size: var(--t-lead); }
  .advice              { font-size: var(--t-body); max-width: calc(554 * var(--u)); }
  .cta, .cta-sec                 { font-size: var(--t-lead); }

  /* --- espacios: la escala de 4 --- */
  /*  El nombre pasa de 72 a 88 y eso son 32 de alto mas. Se recuperan
   *  arriba: los tres bloques que lo anteceden —TU MATCH, el titular y la
   *  marca— se aprietan de 20 a 12 de separacion, y el titular baja de 1.2
   *  a 1.05 de interlineado. Entre las cuatro cosas, 34. */
  .side-title   { margin-top: var(--s2); line-height: 1.05; }
  .match-brand  { margin-top: var(--s2); }
  .match-name   { margin-top: var(--s2); }
  /* El porcentaje y el consejo van pegados al nombre: en el export el 72
     arranca en 338 y el nombre acaba en 340. No hay hueco, se encabalgan. */
  .match-score  { margin-top: 0; gap: var(--s5); }
  .advice       { margin-top: 0; }
  .acordes      { margin-top: var(--s6); }
  .notas        { margin-left: 0; gap: calc(56 * var(--u)); }
  .nota-k       { margin-top: var(--s1); font-size: var(--t-label); }
  .nota + .nota::before { left: calc(-28 * var(--u)); }
  .rate         { margin-top: var(--s6); }   /* 671 - 643 = 28 -> 32 */
  .stars        { margin-top: calc(4 * var(--u)); gap: var(--s5); }
   /* 789 - 764 = 25 -> 24 */
  .cta          { margin-top: var(--s1); }
  .cta-sec      { margin-top: var(--s3); }

  /* --- las piezas con medida propia del export --- */
  .nota-img   { width: calc(109 * var(--u)); height: calc(109 * var(--u)); }
  .nota       { min-width: calc(109 * var(--u)); }
  .rate-k     { font-size: var(--t-lead); }
  .star-btn   { width: calc(54 * var(--u)); height: calc(54 * var(--u)); }
  .cta, .cta-sec { width: calc(685 * var(--u)); min-height: calc(71 * var(--u)); }
  .final-foot,
  .final-extra { margin-left: calc(165 * var(--u)); margin-right: calc(165 * var(--u)); }
}

/* El boton de girar vivia DENTRO de la cara frontal, asi que al voltear la
   tarjeta se iba con ella y no habia forma de volver. Ahora es hermano del
   giro: se queda quieto y sirve para ir y para volver. */
.col-right { display: flex; flex-direction: column; min-width: 0; }

/*  Un contenedor con scroll solo hace scroll si alguien le pone un techo, y
 *  aqui no lo tenia: la rejilla lleva `justify-items: start`, que dimensiona
 *  cada celda por su CONTENIDO en vez de por su pista. Mientras el contenido
 *  cabia daba igual; la tira de notas mide mas que la columna y estiraba la
 *  celda entera hasta 1784px, con la pista en 572. Estirando esta celda a su
 *  pista, el ancho pasa a ser un numero fijo y todo lo de dentro lo hereda. */
.col-right { justify-self: stretch; width: 100%; }
.col-right .flip { flex: none; width: 100%; min-width: 0; }
.flip-in, .face-a, .face-b { min-width: 0; }
.notas { min-width: 0; max-width: 100%; }
.flip, .flip-in, .face-a { height: auto; }
.face-b { position: absolute; inset: 0; }


/* ==================== la fila de valoracion ============================== */

/*  Del export: etiqueta de 29 en y=671 y cinco estrellas de 54 en y=710,
 *  con paso de 78 (o sea 24 de hueco), trazo de 2.5 sobre #2C2C2C.
 *  Las estrellas registran la nota: cinco botones que no hicieran nada
 *  serian un adorno, y el dato de si el match gusta es justo el que falta. */
.rate-k {
  font-family: 'Inter', var(--font);
  font-weight: 400;
  color: var(--tinta);
  margin: 0;
}
.stars { display: flex; }
.star-btn {
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--vino);
  cursor: pointer;
  transition: transform .18s ease, color .18s ease;
}
.star-btn .star { width: 100%; height: 100%; fill: none; }
.star-btn:hover { transform: scale(1.08); }
.star-btn.is-on .star { fill: var(--vino); }
.star-btn.is-on { color: var(--vino); }
.star-btn:focus-visible { outline: 2px solid var(--vino); outline-offset: 2px; border-radius: 4px; }

/*  Votado = bloqueado. `disabled` normalmente apaga el color de un boton, y
 *  aqui no puede: la nota que la persona acaba de poner tiene que seguir
 *  viendose igual de encendida. Solo se quita el gesto de que aun se puede
 *  tocar. */
.stars.is-rated .star-btn { cursor: default; opacity: 1; }
.star-btn:disabled:hover { transform: none; }

/*  "Modificar" va pegado al texto, no debajo: es la salida de un estado, no
 *  una accion de la pantalla. Pequeño y en tinta suave para que no compita
 *  con las estrellas, que es lo que se mira. */
.rate-k { display: flex; align-items: baseline; gap: .5em; flex-wrap: wrap; }
.rate-edit {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: .72em;
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: .2em;
  cursor: pointer;
}
.rate-edit:hover { color: var(--vino); }
.rate-edit:focus-visible { outline: 2px solid var(--vino); outline-offset: 2px; border-radius: 3px; }
.rate-edit[hidden] { display: none; }

/* En movil no hay lienzo que respetar: las estrellas se miden en rem. */
@media (max-width: 959px) {
  .rate { margin-top: var(--s-5); }
  .stars { margin-top: .5rem; gap: .75rem; }
  .star-btn { width: 2.5rem; height: 2.5rem; }
  .rate-k { font-size: 1.125rem; }
}

/* ================== el reverso de la tarjeta ============================= */

/*  `.face-k` y `.face-notes` existian en el marcado pero NO tenian ni una
 *  regla: se quedaron sin ellas en la purga de capas muertas. El resultado
 *  era que los dos rotulos del reverso —"Huele a" y "Por que este y no
 *  otro"— salian con el mismo cuerpo que la lista de notas y sin separacion
 *  entre bloques, asi que los tres parrafos se leian como uno corrido.
 *
 *  El rotulo es la misma etiqueta que se usa en el resto del producto:
 *  versalita menuda con aire.
 *
 *  La lista de notas ya no esta en el reverso: los acordes van delante y
 *  repetirlos detras no aportaba nada. */
.face-k {
  margin: 0;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
}


/* El intro del desglose cuelga de su rotulo, no flota suelto. */
.face-b .bd-body { padding-top: var(--s-3); }

/* ==================== la tira de notas =================================== */

/*  Antes eran tres acordes fijos. Ahora salen TODAS las notas del perfume
 *  —entre 3 y 22, nueve de media— en una tira que se desliza a lo ancho.
 *
 *  Cada circulo lleva su imagen cuando la hay. Mientras no la haya se tiñe
 *  con el color de su familia olfativa, que se deduce del nombre de la nota
 *  (ver notas.js): ambar para la vainilla, verde para la menta. Doce
 *  circulos grises iguales no dirian nada.
 *
 *  Las medidas son las del acorde del export —circulo de 109, rotulo de 22,
 *  bloque de 142 de alto— para que la fila siga cuadrando con la tarjeta.
 *  Lo unico que cambia es el hueco: 120 entre tres piezas era aire de sobra,
 *  pero con veinte notas obligaba a arrastrar media pantalla por nota.
 */
/* ---- el rotulo de los acordes -------------------------------------------
 *
 *  Los circulos salian sin nombrar, y "acorde" no es una palabra que la
 *  gente traiga puesta: la pregunta que llego fue justo esa, en que se
 *  diferencian de las notas de la tarjeta. El rotulo lo dice y el `?` lo
 *  explica al pasar por encima.
 *
 *  El globo aparece con `:hover` sobre el rotulo entero —es un blanco mas
 *  facil que un circulo de 24px— y tambien con `:focus` del boton, que es
 *  lo que hace que funcione al tocarlo en el movil, donde no hay hover.
 */
.acordes-k {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0 0 var(--s-3);
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
}

.acordes-ayuda {
  flex: none;
  width: 1.4em;
  height: 1.4em;
  padding: 0;
  border: 1px solid var(--hairline-mid);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-faint);
  font: 400 .8em/1 var(--font);
  letter-spacing: 0;
  cursor: help;
  opacity: .75;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
              opacity var(--t-fast) var(--ease);
}
.acordes-k:hover .acordes-ayuda,
.acordes-ayuda:focus { opacity: 1; border-color: var(--ink); color: var(--ink); }
.acordes-ayuda:focus-visible { outline: 2px solid var(--vino); outline-offset: 3px; }

/*  Va ENCIMA del rotulo: debajo taparia los circulos, que es justo lo que
 *  se esta explicando. Flota, asi que no empuja nada al aparecer. */
.acordes-tip {
  position: absolute;
  bottom: calc(100% + var(--s-1));
  left: 0;
  z-index: 3;
  width: max-content;
  max-width: min(34ch, 100%);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--hairline-mid);
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--lift);
  color: var(--ink-soft);
  font-size: .875rem;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(.25rem);
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease),
              visibility var(--t-fast);
}
@media (hover: hover) {
  .acordes-k:hover .acordes-tip { opacity: 1; visibility: visible; transform: none; }
}
.acordes-ayuda:focus ~ .acordes-tip { opacity: 1; visibility: visible; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .acordes-tip { transition: none; transform: none; }
}

/*  Las medidas del lienzo van aqui y no en el bloque de arriba: las reglas
 *  base de `.acordes-k` estan mas abajo en el archivo y, como una media query
 *  no suma especificidad, decide el orden de fuente y se las comia. */
@media (min-width: 960px) {
  .acordes-k { font-size: var(--t-eyebrow); margin: 0 0 var(--s3); }
}

.notas {
  display: flex;
  align-items: flex-start;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* El desbordamiento se sale por la derecha hasta el borde del lienzo: asi
     la nota cortada se ve y se entiende que hay mas. */
  overscroll-behavior-x: contain;
}
.notas::-webkit-scrollbar { display: none; }
.notas:focus-visible { outline: 2px solid var(--vino); outline-offset: 4px; border-radius: 4px; }

.nota {
  flex: none;
  position: relative;
  display: grid;
  justify-items: center;
  scroll-snap-align: start;
}
.nota-img {
  display: block;
  border-radius: 50%;
  background: var(--nota-bg, var(--surface-sunk));
  overflow: hidden;
}
.nota-img img { width: 100%; height: 100%; object-fit: cover; }
.nota-k {
  display: block;
  font-weight: 400;
  color: var(--ink);
  text-align: center;
  text-transform: capitalize;
  white-space: nowrap;
}

/* La linea va centrada en el hueco, no pegada al borde del acorde. */
.nota + .nota::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--linea);
}

/* --- la tira en pantallas pequeñas: misma ley, medida en rem --- */
@media (max-width: 959px) {
  .acordes { margin-top: var(--s-5); }
  .notas   { gap: 1.25rem; }
  .nota    { min-width: 3.75rem; }
  .nota-img { width: 3.75rem; height: 3.75rem; }
  .nota-k  { margin-top: var(--s-1); font-size: var(--fs-micro); }
  .nota + .nota::before { left: -.625rem; }
}

/* Imagen ya recortada: se pinta tal cual. Lo detecta ui.ajustarMezcla()
   mirando el alfa de las esquinas, no la extension del archivo. */
.shot-frasco img.recorte { mix-blend-mode: normal; }


/* ================== las otras tres propuestas ============================ */

/*  Van DEBAJO del pliegue, no al lado ni en el reverso de la tarjeta.
 *
 *  Al lado le quitarian el momento al ganador, que es lo unico que dice la
 *  primera pantalla. Y en el reverso no las encontraria nadie: ese boton
 *  dice "¿Por que este?", o sea una justificacion, no un catalogo.
 *
 *  Mismo lenguaje que la tarjeta grande —panel blanco calido, radio de 16,
 *  hueco de la foto en crema, la misma sombra abierta— pero a un tercio del
 *  ancho. La rejilla arranca y acaba donde la composicion de arriba, asi que
 *  los margenes laterales siguen siendo los mismos.
 */
.otras {
  /* El margen de abajo no es decorativo: sin el, la ultima fila de tarjetas
     acaba pegada al borde de la ventana y parece cortada. */
  margin: calc(96 * var(--u)) calc(165 * var(--u)) calc(80 * var(--u));
}
.otras-nota {
  margin: var(--s2) 0 var(--s6);
  font-size: var(--t-body);
  line-height: 1.35;
  color: var(--suave);
  max-width: 38ch;
}
.otras-fila {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: calc(40 * var(--u));
}

.otra {
  display: grid;
  gap: var(--s2);
  padding: calc(17 * var(--u));
  text-align: left;
  background: var(--panel);
  border: 0;
  border-radius: 1rem;
  box-shadow: var(--lift-card);
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
@media (hover: hover) {
  .otra:hover { transform: translateY(-3px); box-shadow: var(--lift-hover); }
}
.otra:focus-visible { outline: 2px solid var(--vino); outline-offset: 3px; }

/* Misma proporcion que el hueco de la tarjeta grande: 726 x 762. */
.otra-foto {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 726 / 762;
  border-radius: 1rem;
  background: var(--surface-warm);
  overflow: hidden;
}
/*  La foto se ancla a los cuatro lados en vez de pedir `height: 100%`.
 *
 *  Un porcentaje de alto no resuelve contra una altura que sale de
 *  `aspect-ratio`: el navegador se cae al tamaño intrinseco de la imagen y
 *  la dibujaba cuadrada dentro de un hueco apaisado, o sea recortada por
 *  arriba y por abajo. En escritorio no se veia porque el hueco es casi
 *  cuadrado; en movil, con el hueco 16:9, saltaba a la vista. */
.otra-foto img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6%;
  mix-blend-mode: multiply;
}
.otra-sin {
  font-family: 'Inter', var(--font);
  font-size: calc(72 * var(--u));
  font-weight: 800;
  color: var(--ink-faint);
}

.otra-marca {
  margin-top: var(--s2);
  font-size: var(--t-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
}
.otra-nombre {
  font-size: var(--t-lead);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: var(--tr-tight);
  color: var(--tinta);
}
.otra-pie {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-top: var(--s1);
}
.otra-pie b {
  font-size: var(--t-title);
  font-weight: 800;
  line-height: 1;
  color: var(--tinta);
}
/* Lo que lo diferencia del ganador. Es la decision real: un tercio de las
   veces el porcentaje es el mismo y el acorde es lo unico que cambia. */
.otra-pie em {
  font-style: normal;
  font-size: var(--t-label);
  color: var(--suave);
  text-transform: capitalize;
}

/* Una foto ya recortada se pinta tal cual, aqui tambien. */
.otra-foto img.recorte { mix-blend-mode: normal; }

/*  --- en pantallas pequeñas: en fila, no en columna ---
 *
 *  Tres tarjetas con la foto arriba eran tres pantallas de scroll. Y
 *  apaisando el hueco para acortarlas, el frasco salia diminuto: es
 *  vertical, asi que al meterlo en un 16:9 sobra aire a los lados y no
 *  queda alto. Con la foto a la izquierda el frasco recupera su formato y
 *  las tres tarjetas caben en media pantalla.
 */
@media (max-width: 959px) {
  .otras { margin: var(--s-7) 0 var(--s-6); }
  .otras-nota { font-size: 1rem; margin-bottom: var(--s-5); }
  .otras-fila { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }

  .otra {
    grid-template-columns: 6.5rem minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    align-items: center;
    column-gap: var(--s-3);
    row-gap: 0;
    padding: .75rem;
  }
  .otra-foto { grid-column: 1; grid-row: 1 / -1; }
  .otra-marca { grid-column: 2; align-self: end; margin-top: 0; font-size: var(--fs-micro); }
  .otra-nombre { grid-column: 2; font-size: 1.125rem; margin: .125rem 0; }
  .otra-pie { grid-column: 2; align-self: start; margin-top: 0; gap: var(--s-2); }
  .otra-pie b { font-size: 1.5rem; }
  .otra-pie em { font-size: var(--fs-micro); }
  .otra-sin { font-size: 1.75rem; }
}

/* ============ la foto que se sale del cuadro (prueba) ==================== */

/*  El hueco deja de recortar y la foto crece por encima de su caja, asi que
 *  la fruta se escapa por los lados. No vale para cualquier imagen: hace
 *  falta una composicion con algo en el borde que merezca salirse.
 *
 *  Entra creciendo desde un poco menos de su tamaño final. La animacion se
 *  repite sola cuando la tarjeta se repinta —al aparecer y al subir una
 *  propuesta desde abajo— porque el repintado crea nodos nuevos.
 */
.post-shot.desborda { overflow: visible; }
.post-shot.desborda img {
  padding: 0;
  transform: scale(1.18);
  animation: escapa .95s var(--ease-out) both;
}
@keyframes escapa {
  from { transform: scale(.94); }
  to   { transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .post-shot.desborda img { animation: none; }
}

/* ============ segunda capa: lo que no tenemos en tienda ================== */

/*  Los 7.541 de Fragrantica son el universo de referencia, no el catalogo.
 *  Por eso este bloque va DESPUES de las tres propuestas y con un peso
 *  visual menor: lo de arriba se puede comprar, esto no. Filas, no tarjetas.
 *
 *  Las fotos vienen del CDN de Fragrantica. Si alguna no carga, la fila se
 *  queda con las iniciales y no se rompe nada.
 */
.gap {
  margin: calc(80 * var(--u)) calc(165 * var(--u)) calc(96 * var(--u));
  padding-top: calc(40 * var(--u));
  border-top: 1px solid var(--linea);
}
.gap-title {
  font-family: 'Inter', var(--font);
  font-size: var(--t-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
  margin: 0 0 var(--s5);
}
.gap-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }

.gap-row {
  display: grid;
  grid-template-columns: calc(96 * var(--u)) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s5);
  padding: var(--s2) var(--s4) var(--s2) var(--s2);
  border-radius: 1rem;
  background: var(--panel);
  color: inherit;
  text-decoration: none;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
@media (hover: hover) {
  .gap-row:hover { transform: translateX(3px); box-shadow: var(--lift); }
}
.gap-row:focus-visible { outline: 2px solid var(--vino); outline-offset: 3px; }

.gap-shot {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: .75rem;
  background: var(--surface-warm);
  overflow: hidden;
}
.gap-shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 8%; }
.gap-ini {
  font-family: 'Inter', var(--font);
  font-size: var(--t-label);
  font-weight: 800;
  color: var(--ink-faint);
  opacity: 0;                     /* solo asoma si la foto no llego */
}
.gap-shot.sin-foto .gap-ini { opacity: 1; }

.gap-txt { display: grid; gap: 2px; min-width: 0; }
.gap-name {
  font-family: 'Inter', var(--font);
  font-size: var(--t-body);
  font-weight: 600;
  line-height: 1.2;
  color: var(--tinta);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gap-brand {
  font-family: 'Inter', var(--font);
  font-size: var(--t-eyebrow);
  font-weight: 400;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--suave);
}
.gap-score {
  font-family: 'Inter', var(--font);
  font-size: var(--t-lead);
  font-weight: 800;
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
}
.gap-foot {
  margin: var(--s5) 0 0;
  font-family: 'Inter', var(--font);
  font-size: var(--t-body);
  line-height: 1.35;
  color: var(--suave);
  max-width: 62ch;
}

@media (max-width: 959px) {
  .gap { margin: var(--s-6) 0 var(--s-6); padding-top: var(--s-5); }
  .gap-title { font-size: var(--fs-micro); margin-bottom: var(--s-3); }
  .gap-row { grid-template-columns: 3.5rem minmax(0,1fr) auto; gap: var(--s-3); padding: var(--s-2); }
  .gap-name { font-size: 1rem; }
  .gap-brand { font-size: var(--fs-micro); }
  .gap-score { font-size: 1.125rem; }
  .gap-foot { font-size: .9375rem; margin-top: var(--s-4); }
}

/* El aviso de lo que el perfume no cumple. Va en la cara de delante, debajo
   del consejo: es la informacion que hacia falta y estaba escondida. */
.ojo {
  margin: var(--s2) 0 0;
  font-family: 'Inter', var(--font);
  font-size: var(--t-eyebrow);
  line-height: 1.35;
  color: var(--suave);
  max-width: 38ch;
}
.ojo b { color: var(--tinta); font-weight: 600; }
@media (max-width: 959px) {
  .ojo { font-size: 1rem; margin-top: var(--s-2); }
}

/*  El motivo, debajo del aviso. Va mas apagado y con una linea al lado: es
    la letra pequeña de lo de arriba, no otra noticia. */
.ojo-por {
  margin: var(--s-1) 0 0;
  padding-left: var(--s-3);
  border-left: 1px solid var(--hairline-mid);
  font-family: 'Inter', var(--font);
  font-size: var(--t-eyebrow);
  line-height: 1.45;
  color: var(--ink-faint, var(--suave));
  max-width: 38ch;
  opacity: .9;
}
.ojo-por b { color: var(--suave); font-weight: 600; }
@media (max-width: 959px) {
  .ojo-por { font-size: .9375rem; }
}

/* ============ la imagen central, armada por piezas ====================== */

/*  Componer una foto por producto —el frasco entre peras, entre manzanas—
 *  no escala: son miles de imagenes, una por referencia. Esta se arma sola
 *  con dos cosas que ya tenemos: la foto plana del frasco y las fotos de sus
 *  notas, que se reutilizan en decenas de perfumes.
 *
 *  Si el perfume no llega a tres notas con foto, la tira no se pinta y el
 *  frasco ocupa el hueco entero, como hasta ahora.
 */
/*  La tira baja del 26% al 21% para dejarle sitio al frasco, que con el 26
 *  se pintaba a 473 en una celda de 538: lo apretaba el ancho, no el alto.
 *  Con el 21 el frasco pasa a 557, un 18% mas que al empezar.
 *
 *  El limite lo pone la etiqueta mas larga que puede salir del catalogo,
 *  "notas de frutos secos". Medida al 21%: cuatro lineas y 63px dentro de
 *  una teja de 168, o sea que sobra sitio. Envuelve, no se corta. */
.post-shot { display: grid; grid-template-columns: 21% minmax(0, 1fr); }
.post-shot:not(:has(.shot-notas)) { grid-template-columns: minmax(0, 1fr); }

.shot-notas {
  display: grid;
  grid-auto-rows: 1fr;
  gap: 3.4%;
  padding: 5% 0 5% 5%;
  min-height: 0;
}
.shot-nota {
  position: relative;
  display: grid;
  align-content: end;
  border-radius: .5rem;
  overflow: hidden;
  background: var(--surface-sunk);
  min-height: 0;
}
.shot-nota img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Velo solo bajo el nombre: sobre una foto clara el blanco desaparece. */
.shot-nota::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 60%;
  background: linear-gradient(transparent, rgba(0, 0, 0, .6));
}
.shot-nota b {
  position: relative;
  z-index: 1;
  padding: 0 8% 7%;
  font-family: 'Inter', var(--font);
  font-size: 2.1cqw;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: .02em;
  color: #fff;
  text-transform: uppercase;
  text-wrap: balance;
}

.shot-frasco { position: relative; display: grid; place-items: center; min-height: 0; }
/*  El 6% de relleno costaba caro. La celda mide 538x762 y la foto es
 *  cuadrada, asi que con `contain` manda el ANCHO: el frasco se pintaba a
 *  473 y sobraban 225px de alto sin usar. Quitando relleno hasta el 1,5% el
 *  frasco crece un 12% sin tocar nada mas. Para que crezca de verdad habria
 *  que estrechar la tira de notas, que es lo que se lleva el 26%. */
.shot-frasco img { width: 100%; height: 100%; object-fit: contain; padding: 1.5%; }

/* ============ las migas, en el lienzo grande ============================= */

/*  Este bloque venia del diseño anterior, donde vivia en una columna lateral
 *  estrecha: una sola fila por respuesta y tipografia en rem. Colgado del
 *  resultado nuevo se quedaba pegado al borde izquierdo mientras el resto de
 *  la composicion empieza en 165, y ademas ocho filas en una columna dejaban
 *  medio ancho vacio.
 *
 *  Aqui se le dan los mismos margenes que a las otras bandas y se reparte en
 *  cuatro columnas: dos filas de cuatro, que es justo lo que cabe sin que se
 *  trunque ningun valor.
 */
@media (min-width: 960px) {
  .crumbs-wrap {
    margin: calc(72 * var(--u)) calc(165 * var(--u)) 0;
  }
  .crumbs-title, .crumbs-foot {
    font-size: var(--t-eyebrow);
    font-weight: 400;
    letter-spacing: var(--tr-wide);
    color: var(--suave);
  }
  .crumbs-foot {
    letter-spacing: .04em;
    text-transform: none;
    margin-left: var(--s4);
  }
  .crumbs {
    margin-top: var(--s5);
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: calc(40 * var(--u));
    row-gap: 0;
  }
  .crumb {
    grid-template-columns: calc(26 * var(--u)) minmax(0, 1fr);
    align-items: baseline;
    gap: 0 var(--s3);
    padding: var(--s3) 0;
    border-bottom: 1px solid var(--linea);
  }
  .crumb .ico { grid-row: 1 / 3; align-self: center; }
  .crumb-k { grid-column: 2; font-size: calc(16 * var(--u)); letter-spacing: var(--tr-key); color: var(--suave); }
  .crumb-v { grid-column: 2; font-size: calc(22 * var(--u)); font-weight: 600; color: var(--tinta); }
}

/* Tableta: dos columnas. Con cuatro, los valores largos se truncan. */
@media (min-width: 600px) and (max-width: 959px) {
  .crumbs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-5); }
}

/* ============ las dos acciones del resultado ============================= */

/*  Eran dos enlaces subrayados del tamaño de una nota al pie. Uno de los dos
 *  es el de COMPRAR, que es lo unico que el negocio le pide a esta pantalla,
 *  asi que ahora son botones y se ven. El de comprar va macizo; el de repetir
 *  el test, con borde, porque no compiten por lo mismo.
 */
.final-extra { display: flex; flex-wrap: wrap; align-items: center; }

/*  Los tamaños base NO pueden salir del lienzo. `--u` vale
 *  min(0.0520833vw, ...), o sea 0,20px en un movil de 390: los dos botones
 *  salian de 15px de alto y 5px de letra, ilegibles, justo el de comprar.
 *  Las unidades del lienzo entran abajo, en su media query. */
.accion {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  font-size: var(--fs-body);
  /*  Contorno de `box-shadow` y no de `border`, por lo mismo que en
   *  `.cta-sec`: con `border-box`, si el contenido ya llena el `min-height`,
   *  el borde suma sus 2px por fuera y este salia de 73 contra los 71 de los
   *  de la derecha. */
  border: 0;
  box-shadow: inset 0 0 0 1px var(--linea);
  border-radius: 9999px;
  background: var(--panel);
  color: var(--tinta);
  font-family: 'Inter', var(--font);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}
@media (min-width: 960px) {
  /*  Mismo alto y mismo cuerpo que los tres de la derecha, y el ancho de la
   *  tarjeta: es el unico boton de su columna y el que le importa al
   *  negocio, asi que no tiene con quien compartir la linea. */
  .accion {
    width: 100%;
    min-height: calc(71 * var(--u));
    justify-content: center;
    gap: var(--s2);
    padding: calc(18 * var(--u)) calc(32 * var(--u));
    font-size: var(--t-lead);
  }
}
.accion .ico { width: 1.1em; height: 1.1em; flex: none; }
.accion-fuerte {
  background: var(--vino);
  box-shadow: none;
  color: #fff;
}
@media (hover: hover) {
  /*  El contorno viaja dentro de la sombra: si el hover solo pusiera
   *  `var(--lift)` se llevaria por delante el `inset` y el boton perderia el
   *  borde justo al pasar por encima. */
  .accion:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--linea), var(--lift); }
  .accion-fuerte:hover { box-shadow: var(--lift-hover); }
}
.accion:focus-visible { outline: 2px solid var(--vino); outline-offset: 3px; }

/* ============ el aviso de que la pagina sigue =========================== */

/*  Va fijo al pie de la ventana, no al final del documento: la composicion
 *  acaba justo en el borde y cualquier cosa puesta "abajo" ya estaria fuera
 *  de vista, que es precisamente el problema que resuelve. Desaparece en
 *  cuanto se baja, para no estorbar el resto del recorrido.
 */
.hay-mas {
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: calc(14 * var(--u)) calc(26 * var(--u));
  border: 1px solid var(--linea);
  border-radius: 9999px;
  background: rgba(255, 253, 249, .82);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: var(--lift);
  color: var(--tinta);
  font-family: 'Inter', var(--font);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  cursor: pointer;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.hay-mas .ico { width: 1.2em; height: 1.2em; }
.hay-mas .ico { animation: asoma 2.4s var(--ease) infinite; }
@keyframes asoma {
  0%, 70%, 100% { transform: translateY(0); }
  82%           { transform: translateY(3px); }
}
body.ya-bajo .hay-mas {
  opacity: 0;
  transform: translate(-50%, 10px);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .hay-mas .ico { animation: none; }
}
@media (max-width: 719px) {
  .hay-mas { font-size: .8125rem; padding: .5rem 1rem; }
}
