/*
  Kabelo UI v1.0 — the design system, as this project consumes it.
  Tagline: Tecnología que impulsa tu estilo.

  Source of truth for the VALUES is `assets/design/tokens.json`, shipped from
  the design package unchanged. This file is the CSS half of it, plus the two
  things a package cannot know: how this codebase serves fonts, and which of
  its conventions must not be broken.

  NOTHING CONSUMES THIS YET, and that is deliberate.

  Every surface still paints itself with its own palette. This file lands first
  so the screens still to be written — the two panel views left in the point of
  sale — are born in the system instead of being born pink and repainted later.
  Migrating an existing surface means pointing its own variables at these and
  checking the result, one surface at a time, never all four at once on a live
  product.

  The accent is copper and it is rationed. The package is explicit: it should
  normally occupy a small part of the interface. It is not the default action
  colour — that is the deep teal.
*/

/*
  Montserrat, self-hosted, same as the font the landing already serves.

  No CDN: this product opens on a phone with two bars of signal inside a salon,
  and a webfont from a third-party domain costs a DNS lookup and a TLS
  handshake before a single letter can be drawn. It is also a variable font, so
  one file covers 400 to 700 instead of four downloads.

  The latin-ext subset only downloads if a character needs it — a business name
  with a letter outside Spanish should not arrive broken, and should not cost
  anything to everyone else either.
*/
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/montserrat-v31-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/montserrat-v31-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/*
  Fraunces, para los títulos grandes. También propia, por lo mismo.

  Este archivo dice, unas líneas más arriba, que aquí hubo una serif inventada
  —Georgia— buscando "aire de salón", y que se quitó porque meter una segunda
  familia que nadie eligió es tan malo como inventarse los colores. Eso sigue
  siendo cierto: lo que cambió es que ahora la eligió Héctor y entra por la
  puerta, como token del sistema, con su archivo servido desde este dominio y
  disponible para la consola igual que para la página del negocio.

  Sólo pinta títulos: una serif en un botón, en un precio o en una tabla de
  horas se lee peor y más despacio, que es justo lo contrario de lo que hace
  falta en una pantalla que se usa con un cliente delante.

  Variable de 400 a 700 en un archivo: cuatro pesos sin cuatro descargas. Y el
  subconjunto extendido sólo baja si un nombre lo necesita.
*/
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/fraunces-v38-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/fraunces-v38-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --k-font-sans: 'Montserrat', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /*
    La de los títulos grandes.

    Georgia detrás y no una sans: si Fraunces no llega —red mala, o el archivo
    todavía bajando—, lo que se ve tiene que seguir siendo una serif. Cambiar de
    serif a sans a mitad de carga mueve todo el texto de sitio.
  */
  --k-font-display: 'Fraunces', Georgia, 'Times New Roman', serif;

  /* The brand itself. These two never change between themes. */
  --k-brand: #184A5A;
  --k-accent: #C89A4B;

  /*
    El color de marca cuando hace de TEXTO.

    `--k-brand` pinta fondos de botón, donde el color manda y encima va letra
    blanca. Pero el mismo color como letra sobre el fondo de la página es otra
    cosa: FMNavarro eligió un verde azulado oscuro que sobre blanco se lee
    perfecto y sobre el fondo oscuro da 1.59 de contraste — sus enlaces
    "Reservar →" desaparecían.

    Y el acento tiene el problema al revés: el dorado `#C89A4B` sobre el crema
    de la página da 2.40, así que los ojales de cada sección se leían a medias.

    Estas variantes las calcula `assets/color.js` a partir del color que el
    negocio ya dio: aclarándolo u oscureciéndolo lo justo para llegar a 4.5:1,
    y parando ahí — llevarlo al blanco sería legible y ya no sería su color.

    El valor de aquí es el de fábrica, para cuando no hay negocio que aplicar
    (la landing de la plataforma, la consola) o mientras carga.
  */
  --k-brand-texto: var(--k-brand-texto-claro, var(--k-brand));
  --k-accent-texto: var(--k-accent-texto-claro, #8A6524);

  /* Light. Ivory rather than white: a full-white ground under a whole day of
     use is harsher than it looks in a screenshot. */
  /*
    EL FONDO DE UNA OPCION ELEGIDA, y su borde.

    En claro basta con teñir la superficie con la marca. En OSCURO no: la
    marca es un verde oscuro, y mezclarla con una superficie oscura da
    practicamente el mismo color -- medido, rgb(20,39,46) contra rgb(21,45,53).
    Alli hay que ACLARAR, como ya hace el borde de los controles.

    Por eso es un token por tema y no un color en la regla: la mezcla correcta
    depende de sobre que se pinta.
  */
  --k-elegido: color-mix(in srgb, var(--k-brand) 16%, var(--k-surface));
  --k-elegido-borde: var(--k-brand);

  --k-bg: #F8F7F4;
  --k-surface: #FFFFFF;
  --k-surface-raised: #FFFFFF;
  --k-text: #1F2A36;
  --k-text-muted: #66747C;
  --k-border: #E3E5E4;
  /*
    El borde de un CONTROL, que no es el de separar dos cosas.

    `--k-border` está pensado para dividir: un filete casi invisible entre una
    tarjeta y el fondo. Sobre el fondo crema da 1.06 de contraste, y con eso un
    botón blanco de borde suave sobre fondo casi blanco no se ve como un botón
    — se ve como una palabra flotando. Es la mitad del "todo está muy plano".

    Un control se toca, así que su límite tiene que existir. 3.3:1 contra el
    fondo de página, que es lo que pide la norma para el límite de un control
    (WCAG 1.4.11) con un poco de margen. Se ve, y sigue sin gritar.
  */
  --k-border-control: #7F8A86;
  --k-success: #16865C;
  --k-warning: #B7791F;
  --k-danger: #C44242;
  --k-info: #287AA0;

  --k-space-1: 4px;
  --k-space-2: 8px;
  --k-space-3: 12px;
  --k-space-4: 16px;
  --k-space-5: 20px;
  --k-space-6: 24px;
  --k-space-8: 32px;
  --k-space-10: 40px;
  --k-space-12: 48px;
  --k-space-16: 64px;
  --k-space-20: 80px;

  --k-radius-sm: 6px;
  --k-radius-md: 10px;
  --k-radius-lg: 14px;
  --k-radius-xl: 20px;
  --k-radius-pill: 999px;

  --k-fast: 120ms;
  --k-base: 180ms;
  --k-slow: 240ms;

  /*
    La escala tipográfica, tal cual la lámina Foundations.

    Tamaño y altura de línea van juntos porque en la lámina van juntos: un
    título de 32 con interlineado de 22 no es el mismo título.
  */
  --k-display: 40px/48px;
  --k-h1: 32px/40px;
  --k-h2: 24px/32px;
  --k-h3: 20px/28px;
  --k-body-lg: 16px/24px;
  --k-body: 14px/22px;
  --k-small: 12px/18px;
  --k-label: 13px/18px;
  --k-button: 14px/20px;

  /* Las tres alturas de botón de la lámina. El control de formulario sigue en
     44, que es lo que dice COMPONENTS.md para los campos. */
  --k-btn-sm: 32px;
  --k-btn-md: 40px;
  --k-btn-lg: 48px;

  /*
    Elevación, con los valores exactos de la lámina.

    Son cuatro niveles y no tres: superficie, elevada, desplegable y modal. La
    nota al pie de la lámina dice que la profundidad se logra con superficies y
    bordes, no con sombras intensas — por eso los valores son tan bajos.
  */
  /*
    Las tres del paquete, con sus valores exactos.

    Estaban más planas y con otra base de color: `rgba(31, 42, 54, .06)` en vez
    de `rgba(13, 27, 32, .08)`, y la geometría a la mitad. Se escribieron a ojo
    antes de leer el paquete, que es justo lo que Héctor pidió que dejáramos de
    hacer. Una sombra más plana no se ve mal por sí sola: se ve mal al lado de
    una maqueta que sí las tiene.

    `--k-shadow-drop` no está en el paquete y se queda, con nota: la usa el menú
    de cuenta, y es una elevación entre `md` y `lg` que el sistema no nombra.
  */
  --k-shadow-sm: 0 1px 2px rgba(13, 27, 32, .05);
  --k-shadow-md: 0 8px 24px rgba(13, 27, 32, .08);
  --k-shadow-drop: 0 4px 16px rgba(13, 27, 32, .08);
  --k-shadow-lg: 0 18px 48px rgba(13, 27, 32, .12);

  --k-sidebar: 256px;
  --k-sidebar-collapsed: 72px;
  --k-header: 64px;
  /* 44px is the control height AND the minimum touch target. A barber taps
     this with wet hands between clients. */
  --k-control: 44px;

  /*
    El ancho del panel de IA, que el paquete declara y aquí faltaba.

    Todavía no lo usa nadie —el estudio vive fuera del panel— y se declara ahora
    para que nazca con la medida del sistema en vez de con una inventada el día
    que se escriba.

    La barra lateral NO se declara aquí: ya está arriba, con los valores del
    paquete. Estuve a punto de duplicarla con otro nombre.
  */
  --k-ai-panel: 380px;
}

/*
  Dark is a separate palette, not an inversion.

  The dark ground is #0D1B20 and never pure black: black kills the sense of
  depth that separates a raised surface from the one behind it, and the status
  colours are re-picked rather than reused, because #16865C on ivory and on
  near-black are not the same green to a human eye.

  Both selectors, because this codebase sets `data-theme` on the root element
  and the package documents `.dark` as an alternative. Supporting one and not
  the other is how a theme toggle ends up half working.
*/
:root[data-theme="dark"],
.dark {
  /* Las mismas variantes, calculadas contra el fondo oscuro. El interruptor de
     tema no vuelve a pedir nada: las dos existen desde que carga la página. */
  --k-brand-texto: var(--k-brand-texto-oscuro, #7FB3C4);
  --k-accent-texto: var(--k-accent-texto-oscuro, #E0BE7E);

  /* Aclarando, no tiñendo: mezclar la marca aqui no cambia nada. Blanco al 12%
     da 1.45 de contraste contra la superficie -- se ve y no ensucia el tono. */
  --k-elegido: color-mix(in srgb, #FFFFFF 12%, var(--k-surface));
  /* Y el borde en el acento: el verde de marca sobre fondo oscuro se pierde. */
  --k-elegido-borde: var(--k-accent);

  --k-bg: #0D1B20;
  --k-surface: #14272E;
  --k-surface-raised: #19323A;
  --k-text: #F8F7F4;
  --k-text-muted: #AAB8BD;
  --k-border: #29434B;
  /* En oscuro el control se separa aclarando, no oscureciendo: por debajo del
     fondo no queda sitio. 4.3:1 contra el fondo de página. */
  --k-border-control: #6E8189;
  --k-success: #3BB98A;
  --k-warning: #E5A93D;
  --k-danger: #EF6B6B;
  --k-info: #55A8CB;

  /* En oscuro la lámina dice que la profundidad se logra con superficies y
     bordes, no con sombras intensas: sobre casi negro una sombra no se ve, y
     subirla sólo ensucia. */
  --k-shadow-sm: 0 1px 2px rgba(0, 0, 0, .12);
  --k-shadow-md: 0 8px 24px rgba(0, 0, 0, .18);
  --k-shadow-drop: 0 4px 16px rgba(0, 0, 0, .2);
  --k-shadow-lg: 0 18px 48px rgba(0, 0, 0, .22);
}

/*
  Three primitives, and only three.

  The package lists two dozen components. They are not written here because a
  component nobody has used yet is a guess: these three are what every screen
  in the mockups is actually built from, and the rest earn their place when a
  real screen needs them.
*/

/* The focus ring. Written once because it is the accessibility guarantee that
   is easiest to forget per-component and most obvious when missing. */
.k-focus:focus-visible,
.k-focusable:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--k-brand) 24%, transparent);
}

.k-surface {
  background: var(--k-surface);
  border: 1px solid var(--k-border);
  border-radius: var(--k-radius-lg);
}

.k-raised {
  background: var(--k-surface-raised);
  border: 1px solid var(--k-border);
  border-radius: var(--k-radius-xl);
  box-shadow: var(--k-shadow-md);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --k-fast: 0ms;
    --k-base: 0ms;
    --k-slow: 0ms;
  }
}

/* --- La foto en grande -------------------------------------------------------

   Vive en el sistema de diseño y no en la hoja de una página porque lo usan
   tres: la página del salón, Mi cuenta y la ficha del cliente en el panel. El
   comportamiento está en `assets/lupa.js`, que también las tres cargan.

   Un `<dialog>` de verdad: el navegador le da la capa de encima, el cierre con
   Escape, el foco atrapado dentro y el fondo inerte. Todo eso a mano son
   cincuenta líneas que se rompen la primera vez que alguien navega con teclado.
*/
.lupa {
  /* `inset: 0` con los cuatro lados fijados: un `<dialog>` se centra solo con
     los márgenes automáticos del navegador, y eso lo encoge al tamaño de su
     contenido. Aquí tiene que ocupar la pantalla entera. */
  position: fixed;
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
}

/*
  El centrado va en `[open]`, y ése era el error.

  La hoja del navegador trae `dialog:not([open]) { display: none }`. Un
  `display: grid` en `.lupa` a secas la pisa y el visor se queda visible siempre
  — pero puesto sólo en `[open]` no pisa nada y el diálogo cerrado sigue
  cerrado. Sin esta regla los hijos eran posicionados absolutos sobre un bloque
  sin centrar, y la foto salía pegada arriba y a un lado, que es justo lo que se
  vio en la captura.
*/
.lupa[open] {
  display: grid;
  place-items: center;
}

.lupa::backdrop { background: rgba(6, 12, 14, .92); }

.lupa img {
  display: block;
  /* Cabe entera SIEMPRE: una foto vertical de tres mil píxeles recortada por
     arriba y por abajo es justo lo que el visor viene a evitar. */
  max-width: min(92vw, 1100px);
  max-height: 78dvh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--k-radius-md);
}

.lupa-pie {
  position: absolute;
  z-index: 1;
  left: 0; right: 0; bottom: var(--k-space-8);
  margin: 0;
  padding: 0 var(--k-space-6);
  text-align: center;
  color: #f8f7f4;
  font: var(--k-body) var(--k-font-sans);
}
.lupa-pie:empty { display: none; }

/* Los tres controles, con área táctil de verdad: esto se toca con el pulgar en
   una pantalla llena de foto. */
.lupa-cerrar, .lupa-ir {
  position: absolute;
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  border: 0;
  border-radius: var(--k-radius-pill);
  background: rgba(0, 0, 0, .45);
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
/* Los tres van sobre la foto, no en el flujo de la retícula: así el centrado
   de la imagen no cuenta con ellos. */
.lupa-cerrar { top: var(--k-space-4); right: var(--k-space-4); font-size: 1.8rem; }
.lupa-ir[data-lupa-ir="-1"] { left: var(--k-space-3); top: 50%; transform: translateY(-50%); }
.lupa-ir[data-lupa-ir="1"] { right: var(--k-space-3); top: 50%; transform: translateY(-50%); }
.lupa-cerrar:hover, .lupa-ir:hover { background: rgba(0, 0, 0, .7); }
.lupa-cerrar:focus-visible, .lupa-ir:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/*
  El botón que envuelve una foto de prueba.

  Es un `<button>` y no un `<img>` con un `onclick` para que se llegue con
  tabulador y el lector de pantalla diga que se puede pulsar. Pero no se puede
  VER como un botón: lo que se ve es la foto, y un marco gris alrededor de cada
  miniatura convertiría una rejilla de fotos en una barra de herramientas.

  El `zoom-in` es la única pista, y es la correcta: dice exactamente lo que va a
  pasar al pulsar.
*/
.prueba-lupa {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  /* Sin esto, el botón hereda el `line-height` del texto y deja una franja
     bajo la foto que desalinea las dos columnas del antes y el después. */
  line-height: 0;
}
.prueba-lupa:focus-visible {
  outline: 2px solid var(--k-brand);
  outline-offset: 2px;
  border-radius: var(--k-radius-md);
}

/*
  La lámina del análisis facial, con CSS propio.

  Vive en la hoja COMPARTIDA porque la enseñan las dos pantallas: el probador
  público y el simulador del panel. En la del estudio, el panel no la carga y
  la lámina saldría sin una sola regla.

  Y con CSS PROPIO a propósito. Esta página no lleva Tailwind: lo que hay en
  `estudio.css` es un puñado de clases escritas a mano que imitan las que el
  marcado ya usaba. La primera versión de esta hoja se apoyó en utilidades
  que no existen aquí —`aspect-[3/4]`, `bg-no-repeat`— y el resultado fue una
  lámina con los textos bien y las seis fotos de alto cero: invisible. No lo
  vio ninguna prueba; lo vio el navegador.

  Una pieza con identidad propia no puede colgar de utilidades ajenas.
*/
.lamina-hoja {
  max-width: 60rem; margin: 0 auto; background: #fff; color: #0f172a;
  border-radius: 1rem; overflow: hidden; box-shadow: 0 20px 45px rgb(2 6 23 / .35);
}
/*
  La cabecera trae el color del negocio DESDE AQUÍ.

  Lo ponía sólo el probador, en el estilo del elemento. El panel no, y como el
  texto de dentro es blanco, la lámina del mostrador salía con el nombre del
  salón en blanco sobre blanco: invisible. Con el color por omisión aquí, las
  dos pantallas lo tienen y el probador sigue pudiendo pisarlo cuando conoce el
  color exacto del negocio que está sirviendo.
*/
.lamina-cabecera {
  display: flex; align-items: center; gap: .9rem; padding: 1.1rem 1.5rem;
  background: var(--k-brand);
}
/*
  La forma del rostro, dentro de la franja de color y al otro extremo.

  `margin-left: auto` la empuja a la derecha sin añadir un contenedor: la
  cabecera ya es una fila, y con dos bloques en los extremos se lee como una
  ficha —de quién es, y de qué habla— en vez de como una lista.

  En un teléfono la fila se parte y cae debajo del nombre, que es donde tiene
  que estar cuando no cabe al lado.
*/
.lamina-rostro {
  margin: 0 0 0 auto;
  text-align: right;
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.1;
  color: #fff;
  letter-spacing: -.01em;
}
.lamina-rostro span {
  display: block;
  font-size: .58rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgb(255 255 255 / .7);
  margin-bottom: .1rem;
}
.lamina-cabecera img { width: 2.75rem; height: 2.75rem; border-radius: .6rem; object-fit: cover; }
.lamina-negocio { color: #fff; font-weight: 700; font-size: 1.1rem; line-height: 1.2; }
.lamina-que-es { color: rgb(255 255 255 / .78); font-size: .78rem; margin-top: .15rem; }

/* La conclusión del análisis, en grande y antes que los rasgos sueltos. */
.lamina-sujeto {
  display: grid; gap: 1.25rem; padding: .9rem 1.5rem 1.25rem;
  border-bottom: 1px solid #e2e8f0;
}
/* La foto del cliente en vertical y CONTENIDA. A lo ancho de la hoja se
   comía media lámina y empujaba los rasgos fuera de la primera pantalla. */
.lamina-retrato {
  position: relative;
  width: 8.5rem; height: 11rem;
  margin: 0;
  border-radius: .75rem; border: 1px solid #e2e8f0;
  overflow: hidden;
}
.lamina-retrato img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  /* Encuadrada por ARRIBA. La foto la sube quien sea, muchas veces de medio
 cuerpo; centrada, el retrato del análisis facial acaba enseñando una
 camiseta. La cara está arriba. */
  object-position: center top;
}

/*
  Las marcas sobre la cara.

  Un número, no una línea larga hasta el margen. Cuatro líneas cruzando un
  retrato de ocho centímetros se enredan entre ellas y tapan justo lo que
  vienen a señalar; el mismo número repetido en la lista de al lado une las
  dos cosas sin dibujar nada encima.

  La posición viene del modelo, que miró ESTA foto: ver `leerDonde`.
*/
.lamina-marca {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  width: 1.05rem; height: 1.05rem;
  border-radius: 50%;
  /* Blanco sobre un aro oscuro: encima de una foto cualquiera —clara, oscura,
     con el pelo negro detrás— tiene que leerse igual, y una marca del color de
     la marca del negocio desaparecería sobre las fotos de ese color. */
  background: rgba(15, 23, 42, 0.88);
  border: 1.5px solid #ffffff;
  color: #ffffff;
  font-size: .6rem; font-weight: 700; line-height: 1;
}

/* El mismo número, delante del rasgo en la lista. */
.lamina-numero {
  display: inline-flex; align-items: center; justify-content: center;
  width: .92rem; height: .92rem; margin-right: .3rem;
  border-radius: 50%;
  background: #0f172a; color: #ffffff;
  font-size: .58rem; font-weight: 700; line-height: 1;
  vertical-align: middle;
}
.lamina-lectura { font-size: .875rem; color: #334155; line-height: 1.55; margin: 0 0 .75rem; }
.lamina-rasgos { display: grid; gap: .35rem 1.5rem; margin: 0; }
.lamina-rasgos dt { display: inline; font-weight: 600; color: #0f172a; font-size: .84rem; }
.lamina-rasgos dd { display: inline; margin: 0; color: #475569; font-size: .84rem; }

/*
  Los cortes. `auto-fit` y no un número de columnas: la misma regla sirve
  para una lámina de tres, de cuatro o de seis sin escribir tres reglas —y
  es el negocio quien elige cuántos, no nosotros.
*/
/*
  Las tarjetas siguen la forma de la REJILLA, no el ancho disponible.

  Con `auto-fit` a secas, seis tarjetas caían de cuatro en cuatro y la segunda
  fila quedaba con dos y un hueco. Peor todavía: la lámina dejaba de leerse como
  la imagen que tiene detrás —tres arriba y tres abajo— y las tarjetas no
  cuadraban con las caras.

  `--lamina-cols` lo pone quien pinta, desde la rejilla. Por debajo del ancho de
  una tableta manda el espacio: tres columnas de nueve centímetros no se leen en
  un teléfono.
*/
.lamina-cortes {
  display: grid; gap: 1rem; padding: 1.25rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
@media (min-width: 900px) {
  .lamina-cortes {
    grid-template-columns: repeat(var(--lamina-cols, 3), minmax(0, 1fr));
  }
}
.lamina-carta {
  border: 1px solid #e2e8f0; border-radius: .75rem; overflow: hidden;
  display: flex; flex-direction: column; background: #fff;
}
/*
  La celda: un trozo de la rejilla. El encuadre lo pone React en el estilo
  del elemento, porque depende de cuántas caras hay. Aquí sólo va lo que no
  cambia — y `aspect-ratio`, que es lo que le da altura: sin él la caja mide
  cero y la foto no se ve aunque esté puesta.
*/
/*
  La celda toma la proporción REAL de una celda de la rejilla, no una inventada.

  Aquí había `aspect-ratio: 3/4` a secas, y las seis caras salían estiradas: el
  modelo devuelve la rejilla en 2528x1696, así que con 3 columnas por 2 filas
  cada celda mide 843x848 —casi cuadrada— y meterla en un hueco 3:4 la alarga.

  Quien pinta mide la imagen al cargarla y pone `--lamina-celda` con
  (ancho/columnas)/(alto/filas). Así da igual el tamaño que devuelva el modelo.
  El 1 de respaldo es para el instante entre que la tarjeta se dibuja y la
  imagen carga: cuadrado no deforma a nadie.
*/
.lamina-celda {
  aspect-ratio: var(--lamina-celda, 1);
  background-color: #f1f5f9; background-repeat: no-repeat;
}
.lamina-texto { padding: .85rem .9rem; display: flex; flex-direction: column; gap: .35rem; flex: 1; }
.lamina-titulo { font-size: .95rem; font-weight: 700; line-height: 1.3; margin: 0; }
.lamina-porque { font-size: .8rem; color: #475569; line-height: 1.45; margin: 0; }
.lamina-ficha { font-size: .74rem; color: #64748b; margin: auto 0 0; padding-top: .4rem; }
.lamina-ficha dt { display: inline; font-weight: 600; color: #334155; }
/* El color propuesto se marca: es un servicio de más, no un dato de más. */
.lamina-color dt, .lamina-color dd { color: #92400e; }
.lamina-ficha dd { display: inline; margin: 0; }
.lamina-precio {
  font-size: .82rem; font-weight: 700; margin: .4rem 0 0;
  padding-top: .45rem; border-top: 1px solid #f1f5f9;
}
.lamina-precio span { font-weight: 500; color: #64748b; }
/*
  Bajo qué línea del catálogo se cobra este peinado.

  Va encima del precio y en pequeño porque contesta una pregunta que el cliente
  no hace pero el mostrador sí: seis peinados distintos pueden cobrarse todos
  como "Corte Caballero", y sin decirlo el precio repetido parece un error.
*/
.lamina-servicio {
  display: block; font-size: .68rem; font-weight: 600; color: #94a3b8;
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: .1rem;
}

.lamina-acciones {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
  justify-content: space-between; padding: .9rem 1.5rem;
  background: #f8fafc; border-top: 1px solid #e2e8f0;
}
.lamina-aviso { font-size: .7rem; color: #64748b; margin: 0; max-width: 32rem; }
/* La firma. Separada del aviso por un punto medio, y más apagada que él: es
   una procedencia, no una advertencia. */
.lamina-firma { display: block; margin-top: .15rem; color: #94a3b8; font-weight: 600; }
.lamina-acciones button {
  padding: .5rem .9rem; font-size: .76rem; font-weight: 600;
  border-radius: .5rem; cursor: pointer; border: 1px solid transparent;
}
.lamina-secundario { background: #fff; border-color: #cbd5e1; color: #334155; }
.lamina-principal { color: #fff; }

@media (min-width: 640px) {
  .lamina-sujeto { grid-template-columns: auto 1fr; align-items: start; }
  .lamina-rasgos { grid-template-columns: 1fr 1fr; }
}

/*
  LA HOJA EN UN TELEFONO.

  Esto se diseño en una pantalla ancha y se leia bien ahi. En 390px se rompia:
  la hoja se quedaba en 287px porque su propio margen de 1.5rem se sumaba al
  del visor, al de la tarjeta y al del area de contenido — cuatro marcos, uno
  dentro de otro, para enseñar una hoja. Y con ese ancho la cabecera media
  194px y el pie 188px: casi cuatrocientos pixeles, la mitad de la pantalla,
  gastados en el membrete y en el aviso legal antes de que se viera una sola
  recomendacion.

  Es la pantalla donde MAS se usa: el mostrador se la enseña al cliente en el
  telefono, con la persona mirando desde el otro lado de la silla.
*/
@media (max-width: 30rem) {
  /* Los margenes laterales bajan de 1.5rem a 1rem. Parece poco y son 16px de
     ancho util por lado sobre una columna de 239: un 13% mas de texto por
     linea, que en un parrafo de tres lineas es una linea menos. */
  .lamina-cabecera { flex-wrap: wrap; padding: .85rem 1rem; gap: .7rem; }
  .lamina-cabecera img { width: 2.25rem; height: 2.25rem; }
  .lamina-negocio { font-size: 1rem; }
  .lamina-que-es { font-size: .72rem; }

  /* El rostro, EN UNA LINEA. Con la etiqueta en bloque encima del valor se
     comia una fila entera de la cabecera para decir dos palabras. Sigue siendo
     el dato principal del analisis; no necesita sesenta pixeles propios. */
  .lamina-rostro {
    margin-left: 0;
    text-align: left;
    width: 100%;
    display: flex;
    align-items: baseline;
    gap: .4rem;
    font-size: 1rem;
  }
  .lamina-rostro span { display: inline; margin: 0; }

  /* El retrato AL LADO de la lectura, no encima.

     Apilados, el retrato dejaba 200px vacios a su derecha y empujaba los
     rasgos 176px hacia abajo: media pantalla de telefono gastada en un hueco.
     La fila cabe de sobra —112px de foto y 200 de texto— y sube la lectura del
     rostro a la primera pantalla, que es lo que el cliente lee primero.

     El breakpoint de dos columnas de mas abajo empieza en 640px y esto no lo
     pisa: son dos reparticiones distintas para dos anchos distintos. */
  .lamina-sujeto {
    padding: .85rem 1rem 1rem;
    gap: .85rem;
    grid-template-columns: auto 1fr;
    align-items: start;
  }
  .lamina-retrato { width: 7rem; height: 9rem; }
  /* DOS COLUMNAS, no una.

     Apiladas de una en una, seis cortes con foto cuadrada median 2937px: diez
     pantallas de telefono para enseñar seis peinados, con la persona sentada
     delante esperando. Y peor que largo: se perdia lo que hace util un
     analisis facial, que es ver los seis JUNTOS y compararlos de un vistazo.

     `minmax(11rem, 1fr)` de la regla base pedia 176px por columna y por eso
     caia a una sola. Aqui se fija en dos y se deja que se estrechen: 142px de
     foto se ven de sobra en la mano, y el nombre y el precio caben debajo.

     Dos y no tres: a 96px por columna el nombre de un corte se parte en cuatro
     lineas y la foto deja de decir nada. */
  .lamina-cortes {
    padding: 1rem;
    gap: .75rem;
    grid-template-columns: 1fr 1fr;
  }
  .lamina-texto { padding: .6rem .65rem; gap: .25rem; }
  .lamina-titulo { font-size: .82rem; }
  .lamina-porque { font-size: .72rem; line-height: 1.35; }
  .lamina-ficha { font-size: .68rem; }
  .lamina-precio { font-size: .74rem; }
  .lamina-servicio { font-size: .6rem; letter-spacing: .04em; }

  /* El pie: el aviso mas pequeño y los botones a lo ancho. Dos botones de
     texto corto centrados en una fila de 240px dejan el pulgar buscando; a
     ancho completo se tocan sin mirar. */
  .lamina-acciones { padding: .85rem 1rem; gap: .5rem; }
  .lamina-aviso { font-size: .66rem; }
  .lamina-acciones > div { width: 100%; }
  .lamina-acciones button { flex: 1; padding: .6rem .5rem; }
}


/*
  Al imprimir, sólo la lámina.

  En la hoja COMPARTIDA porque el botón "Guardar o imprimir" está en las dos
  pantallas. Vivía dentro de index.html, así que desde el panel el mismo botón
  mandaba a la impresora la consola entera —barra lateral, menú y todo— en vez
  de la hoja.

  "Guardar o imprimir" es cómo se saca la hoja del análisis facial: es lo
  que ya sabe hacer cualquier navegador —incluido "Guardar como PDF" en el
  teléfono— y no cuesta ni un kilobyte de JavaScript. Sin esto saldría
  también la barra, las pestañas y los dos botones de la propia hoja, que en
  papel no son nada.

  `visibility` y no `display:none`: escondiendo los padres con `display` se
  esconde también la lámina que está dentro de ellos.
*/
@media print {
  /*
    Todo lo que no lleva a la lámina se QUITA, no se esconde.

    `visibility: hidden` deja el hueco: la barra lateral del panel y lo que hay
    debajo del visor seguían midiendo dos mil píxeles, así que la hoja salía en
    dos páginas y la segunda era un rectángulo del color de fondo. Comprobado
    generando el PDF con la lámina anidada como está en el panel.

    `:has()` deja conservar el camino: los ancestros de la lámina siguen ahí
    —si no, se llevaría por delante a la propia lámina— y todo lo demás
    desaparece de verdad. Y a los ancestros se les quita el aire y el color,
    que es de donde salía la franja crema.
  */
  /*
    ACOTADO A `.printing-lamina`, y esto no es orden: es el arreglo de un fallo
    que llegó a producción.

    Sin la clase, estas dos reglas se aplicaban a CUALQUIER impresión desde
    cualquiera de las diez páginas que cargan esta hoja. Y como esconden todo
    lo que no lleva a la lámina, escondían también lo que sí se estaba
    imprimiendo: el ticket de venta salía en blanco, el corte de caja también,
    y el "Exportar a PDF" del reporte igual. El `#ticket` sobrevivía —lo rescata
    `console.css`— pero sus renglones no, así que salía un papel con nada.

    `console.css` ya había aprendido esto y lo dice en su propio comentario:
    "sin acotar a esta clase, cualquier otra impresión saldría en blanco". Esta
    hoja lo repitió sin la clase.

    La clase la pone quien imprime una lámina, y sólo él.
  */
  body { background: #fff; margin: 0; padding: 0; }
  .printing-lamina body *:not(:has(.lamina-hoja)):not(.lamina-hoja):not(.lamina-hoja *) {
    display: none !important;
  }
  .printing-lamina body :has(.lamina-hoja) {
    display: block !important;
    margin: 0 !important; padding: 0 !important;
    background: none !important; border: 0 !important;
    width: auto !important; max-width: none !important;
    min-height: 0 !important; height: auto !important;
    overflow: visible !important; box-shadow: none !important;
  }
  .lamina-hoja {
    position: static;
    width: 100%; max-width: none;
    border-radius: 0; box-shadow: none;
  }
  /* Los botones de la propia hoja: en papel no hacen nada. */
  .lamina-acciones button { display: none; }
  /* Los fondos de color son la marca del negocio; sin esto el navegador
     los quita para ahorrar tinta y la hoja sale sin identidad. */
  .lamina-hoja * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  /*
    Y LA LÁMINA CABE EN UNA HOJA.

    Es lo que arruinó la primera impresión de verdad: el salto de página caía en
    medio de las tarjetas, así que en una hoja quedaban las tres fotos, en la
    siguiente los tres títulos, y al final unos "Mantenimiento:" sueltos sin
    foto ni nombre encima.

    `break-inside: avoid` no lo arregla —con una rejilla, Chromium lo ignora, y
    está comprobado: el PDF sale igual con y sin la regla—. Así que se ataca la
    causa: si todo cabe en una página no hay salto que parta nada. La lámina de
    referencia que trajo Héctor es exactamente eso, una sola hoja.

    Se aprieta lo que no cuesta legibilidad —aire, sombras, esquinas— y se
    reduce el cuerpo del texto un punto. Lo que NO se toca es el tamaño de las
    caras: son lo que se mira.
  */
  /*
    Márgenes finos, y no por gusto.

    La hoja se pasaba de la página por unos veinticinco píxeles. Se puede
    apretar el texto o ensanchar la página, y ensancharla no cuesta legibilidad:
    4 mm sigue estando dentro de lo que imprime cualquier impresora doméstica
    —el mínimo suele ser 3— y devuelve casi cincuenta píxeles de alto.
  */
  @page { size: A4 portrait; margin: 4mm; }

  /*
    Un pelo más apretada, con colchón.

    Con la ficha de rasgos de un rostro y el texto de seis cortes, la hoja se
    pasaba de la página por unos cuarenta píxeles — y eso depende de lo largo
    que escriba el modelo, así que no basta con que quepa por poco: hace falta
    margen. Lo que no se toca sigue siendo el tamaño de las caras.
  */
  /*
    El alto lo mandan las CELDAS, no el texto.

    Bajar el cuerpo de letra no movía la aguja: cada celda es cuadrada, así que
    su alto sale de su ancho, y el ancho sale de la página. Estrechando la
    rejilla un dedo por cada lado bajan las dos filas de golpe y la hoja entra
    con holgura — que es lo que hace falta, porque el texto que escribe el
    modelo cambia de un cliente a otro y empatar con el borde no es caber.
  */
  .lamina-hoja { font-size: 11px; }
  .lamina-cabecera { padding: .25rem .7rem; gap: .4rem; }
  .lamina-cabecera img { width: 1.5rem; height: 1.5rem; }
  .lamina-negocio { font-size: .8rem; line-height: 1.15; }
  .lamina-que-es { font-size: .55rem; margin-top: 0; line-height: 1.2; }

  .lamina-rostro { font-size: .95rem; }
  .lamina-rostro span { font-size: .5rem; margin-bottom: 0; }
  .lamina-sujeto { padding: .2rem .7rem .35rem; gap: .55rem; }
  .lamina-retrato { width: 4.4rem; height: 5.5rem; }
  .lamina-lectura { font-size: .62rem; line-height: 1.3; margin-bottom: .25rem; }
  .lamina-rasgos { gap: .05rem .7rem; }
  .lamina-rasgos dt, .lamina-rasgos dd { font-size: .59rem; line-height: 1.25; }
  .lamina-marca { width: .78rem; height: .78rem; font-size: .45rem; border-width: 1px; }
  .lamina-numero { width: .68rem; height: .68rem; font-size: .44rem; margin-right: .2rem; }

  /*
    Y en papel manda la REJILLA, no el ancho.

    La regla que sigue las columnas de la rejilla vive tras un `min-width: 900px`
    —para que en un teléfono no salgan tres columnas de nueve centímetros—, y
    una hoja A4 mide 750px de ancho: no llegaba. Resultado: seis tarjetas
    acomodadas de cuatro en cuatro, con la segunda fila coja y sin cuadrar con
    las caras de la imagen que tienen detrás.
  */
  .lamina-cortes {
    padding: .45rem .7rem; gap: .4rem;
    grid-template-columns: repeat(var(--lamina-cols, 3), minmax(0, 1fr));
  }
  .lamina-carta { box-shadow: none; border-radius: .3rem; }
  .lamina-texto { padding: .25rem .4rem; gap: .1rem; }
  .lamina-titulo { font-size: .68rem; line-height: 1.2; }
  /*
    El porqué, a dos renglones como mucho.

    Es lo único que se puede recortar sin perder información que decida algo: el
    nombre, el largo y el precio se quedan enteros. Y con seis tarjetas, dos
    renglones de más en cada una son los que empujaban la lámina a una segunda
    hoja donde llegaba partida.
  */
  .lamina-porque {
    font-size: .58rem; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .lamina-ficha { font-size: .55rem; padding-top: .18rem; line-height: 1.3; }
  .lamina-ficha div { display: block; }
  .lamina-servicio { font-size: .5rem; letter-spacing: .04em; }
  .lamina-precio { font-size: .62rem; padding-top: .18rem; margin-top: .18rem; }

  .lamina-acciones { padding: .2rem .7rem; }
  .lamina-aviso { font-size: .5rem; }
  .lamina-firma { margin-top: .05rem; }

  /* Y por si aun así hiciera falta un salto: que caiga entre tarjetas y no
     dentro de una. No basta solo, pero no estorba. */
  .lamina-carta, .lamina-sujeto { break-inside: avoid; page-break-inside: avoid; }
}


/*
  El comparador de cortina: una foto encima de la otra, y una línea que se
  arrastra.

  Sustituye al "mantén presionado para ver el original", que en un teléfono no
  funciona: el dedo selecciona el botón, aparece el menú de copiar, y hay que
  acertar y sostener a la vez. Aquí se arrastra, que es el gesto que ya se hace
  para todo lo demás.

  El tirador es un `input[type=range]` de verdad, invisible por encima. Eso da
  gratis lo que costaría escribir: el arrastre con el dedo, las flechas del
  teclado, el foco y el anuncio para lectores de pantalla. Un `div` con
  `mousedown` no da nada de eso.
*/
.comparador {
  position: relative;
  overflow: hidden;
  border-radius: var(--k-radius-lg, .75rem);
  /* Sin selección de texto: arrastrando sobre una imagen, el navegador intenta
     seleccionar y el gesto se pelea con el del comparador. */
  user-select: none;
  -webkit-user-select: none;
  touch-action: pan-y;
}
.comparador img {
  display: block;
  width: 100%;
  height: auto;
}
/* La de ANTES va encima, recortada por la derecha. Se recorta la de arriba y no
   la de abajo para que el borde de la cortina caiga sobre una imagen completa y
   no sobre el fondo. */
.comparador-antes {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc(100% - var(--cortina, 50%)) 0 0);
}
.comparador-antes img { height: 100%; object-fit: cover; }
.comparador-linea {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--cortina, 50%);
  width: 2px;
  margin-left: -1px;
  background: #fff;
  box-shadow: 0 0 0 1px rgb(0 0 0 / .35);
  pointer-events: none;
}
/* El agarradero, para que se vea que eso se mueve. */
.comparador-linea::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2rem;
  height: 2rem;
  margin: -1rem 0 0 -1rem;
  border-radius: 9999px;
  background: #fff;
  box-shadow: 0 1px 6px rgb(0 0 0 / .4);
}
/*
  El tirador cubre la FOTO ENTERA, y eso hay que pelearlo.

  Un `input[type=range]` trae altura propia —cuarenta y cuatro píxeles— y
  `height: 100%` a secas no la cambia: quedaba una franja arrastrable arriba y
  el resto de la foto no respondía al dedo. Se ve en la prueba: quien recibía el
  toque en el centro era la imagen, no el control.

  Hay que estirar también la PISTA y el AGARRE, que son las piezas de dentro y
  las que de verdad ocupan el alto. El agarre va ancho a propósito: con dos
  píxeles habría que acertarle, y de eso justamente veníamos huyendo.
*/
/*
  El selector lleva el CONTENEDOR delante, y hace falta.

  El probador carga `estudio.css` después de esta hoja, y allí hay un
  `input[type=range] { height: 24px }` para los deslizadores de largo y volumen.
  `input.comparador-tirador` pesa exactamente lo mismo —un elemento y una
  clase—, así que ganaba la hoja que se carga última y el tirador se quedaba en
  una franja: la foto entera no respondía al dedo, que es justo lo que la
  cortina venía a arreglar.

  Con `.comparador` delante pesa una clase más y gana sin `!important`, sin
  tocar la regla de al lado y sin que el próximo deslizador que alguien añada
  tenga que enterarse de nada.
*/
.comparador input.comparador-tirador {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: ew-resize;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  /* Por encima de todo lo demás del comparador, que es lo que lo hace
     arrastrable en cualquier punto de la foto y no sólo sobre la línea. */
  z-index: 2;
}
.comparador input.comparador-tirador::-webkit-slider-runnable-track { height: 100%; background: transparent; }
.comparador input.comparador-tirador::-moz-range-track { height: 100%; background: transparent; }
.comparador input.comparador-tirador::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 2.75rem;
  height: 100%;
  background: transparent;
  border: 0;
}
.comparador input.comparador-tirador::-moz-range-thumb {
  width: 2.75rem;
  height: 100%;
  background: transparent;
  border: 0;
}
/* El foco sí se ve: es invisible al ratón, no a quien navega con teclado. */
.comparador input.comparador-tirador:focus-visible + .comparador-linea {
  box-shadow: 0 0 0 3px var(--k-brand, #184A5A);
}
/* Las etiquetas, una en cada lado. */
.comparador-etiqueta {
  position: absolute;
  top: .6rem;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #fff;
  background: rgb(0 0 0 / .55);
  padding: .2rem .5rem;
  border-radius: .3rem;
  pointer-events: none;
}
.comparador-etiqueta.antes { left: .6rem; }
.comparador-etiqueta.despues { right: .6rem; }

/*
  El interruptor de la propuesta de color, bajo el botón del análisis.

  En la hoja compartida porque lo llevan las dos pantallas. Discreto y en una
  línea: es un matiz de lo que ya se pidió, no una segunda decisión — quien no
  lo toca recibe lo de siempre.
*/
.analisis-color {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  margin-top: .3rem;
  font-size: .72rem;
  color: #94a3b8;
  cursor: pointer;
}
.analisis-color input { width: .9rem; height: .9rem; margin: 0; cursor: pointer; }

/* ============================================================
   FICHAS DE REFERENCIA
   ============================================================

   Un cliente no sabe qué es un "Buzz Cut". Leerlo en una lista no se lo dice;
   verlo, sí.

   Empezó siendo una miniatura de 44 píxeles al lado del desplegable y no
   servía: a ese tamaño un fade y un taper son la misma mancha, así que decía
   "aquí hay algo" en vez de decir qué. Y lo que había que ver estaba detrás de
   un clic, o sea detrás de saber que se podía hacer clic.

   Ahora la ilustración se ve sola, debajo de lo que se acaba de elegir. El
   desplegable se queda porque con veinte cortes hace falta una forma de saltar
   al que se busca, pero ya no hay que abrir nada para saber qué se eligió.

   Vive aquí y no en estudio.css porque la ven las dos pantallas —el probador,
   que es oscuro, y el simulador del panel, que es claro—. Por eso los colores
   son translúcidos en vez de fijos: se apoyan en el fondo que les toque en vez
   de imponer uno. */

.referencia-fila {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.referencia-fila > select { width: 100%; }

/*
  La ilustración, en su proporción.

  Se limita por ANCHO y no por alto, y eso no es lo mismo. Con `max-height` la
  caja quedaba apaisada en cuanto la columna era ancha —434 por 190 en
  escritorio— y de una ilustración vertical se recortaba casi todo: quedaba una
  banda con media cabeza. Topando el ancho, el `aspect-ratio` manda y la
  ilustración se ve entera a cualquier tamaño de pantalla.

  Centrada porque a 190 píxeles dentro de una columna de 434 pegada a la
  izquierda parece un error de maquetación.
*/
.referencia-vista {
  display: block;
  width: 100%;
  max-width: 190px;
  margin: 0 auto;
  aspect-ratio: 3 / 4;
  padding: 0;
  border: 1px solid currentColor;
  border-radius: var(--k-radius-md);
  overflow: hidden;
  cursor: zoom-in;
  background: transparent;
  opacity: 0.9;
  transition: opacity var(--k-fast) ease;
  position: relative;
}

.referencia-vista:hover,
.referencia-vista:focus-visible { opacity: 1; }

.referencia-vista img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Se recorta por abajo si hace falta: lo que hay que ver en un catálogo de
     cortes está en la cabeza, no en los hombros. */
  object-position: top;
}

/*
  "Toca para ampliar", encima de la ilustración y no debajo.

  Debajo empujaba el resto de los controles una línea más por cada selector con
  ficha —tres en la pantalla del probador— y eso es media pantalla de móvil
  gastada en repetir tres veces la misma frase. Encima no ocupa nada, y sobre
  un degradado se lee igual en una ilustración clara que en una oscura.
*/
.referencia-vista span {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 14px 8px 5px;
  background: linear-gradient(to top, rgba(15, 23, 42, 0.75), transparent);
  color: #FFFFFF;
  font-family: var(--k-font-sans);
  font-size: 11px;
  text-align: center;
  letter-spacing: .02em;
}

/* La ilustración grande se abre encima de todo, y se cierra tocando donde sea:
   quien la abrió para salir de dudas no debería tener que buscar una equis. */
.referencia-lupa {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  border: 0;
  background: rgba(15, 23, 42, 0.82);
  cursor: zoom-out;
}

.referencia-grande {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 380px;
  /* La ilustración es más alta que ancha. Sin tope de alto cabía por ancho y
     se salía por abajo: media cara fuera de la pantalla, en un móvil todavía
     más. El alto manda, y el ancho se ajusta a él. */
  max-height: 100%;
  min-height: 0;
  width: 100%;
}

.referencia-grande img {
  display: block;
  min-height: 0;
  max-width: 100%;
  max-height: 100%;
  margin: 0 auto;
  border-radius: var(--k-radius-lg);
  object-fit: contain;
}

.referencia-grande span {
  color: #FFFFFF;
  font-family: var(--k-font-sans);
  font-size: 15px;
  font-weight: 600;
  text-align: center;
}
