/* ---------------------------------------------------------------------------
   Utopie — hoja de estilos del sitio público renderizado por Django.

   La fuente de verdad del diseño es la landing del SPA, no este archivo. Los
   colores están copiados literalmente de src/assets/scss/colors.scss y hay un
   test (backend/tests/test_marketing_design.py) que falla si alguien cambia uno
   de los dos lados y no el otro.

   Por qué no importamos el SCSS del SPA directamente: la identidad de la
   landing no vive en una hoja propia, vive en componentes de bootstrap-vue
   (b-card, b-button pill) más un puñado de variables. Traerla entera
   significaría servir Bootstrap — unos 160 KB — para reusar dos componentes, en
   una página cuyo argumento entero es pesar poco. Lo que sí se comparte, y es
   lo único que puede desincronizarse, son los trece colores.
--------------------------------------------------------------------------- */

:root {
  /* Paleta — src/assets/scss/colors.scss */
  --dark: #393e46;
  --light: #dfe2e2;
  --ultralight: #f3f3f3;
  --omglight: #fafafa;
  --primary: #f8b500;
  --primary-dark: #c28e02;
  --secondary: #00adb5;
  --secondary-dark: #227580;
  --redpie: #e74a57;
  --tertiary: #2789ba;
  --purple: #c6588d;
  --brown: #b76629;
  --pie: #208ac6;

  /* Roles. El acento lo fija cada producto en su plantilla, tomándolo del
     btnVariant que ese mismo producto ya usa en la landing: Corrección de
     Tests es outline-brown, Eureka es outline-primary, y así. Es el color del
     producto, no el de la familia de URL. */
  --accent: var(--primary);
  --accent-ink: var(--primary-dark);
  --ink: var(--dark);
  --ink-soft: #5c636d;
  --ground: #ffffff;
  --rule: var(--light);

  --shell: 1180px;
  --radius: 14px;
  --radius-pill: 999px;

  /* Ubuntu es la tipografía del SPA: la declara el body de LandingPage.vue.
     La pila de reserva es la del sistema para que el texto se lea antes de que
     llegue la fuente. */
  --font: Ubuntu, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
}

/* --- base ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0 0 0.5em;
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

h1 {
  font-size: clamp(1.9rem, 4vw, 3.1rem);
}

h2 {
  font-size: clamp(1.45rem, 2.5vw, 2.05rem);
}

h3 {
  font-size: 1.15rem;
}

p {
  margin: 0 0 1em;
}

a {
  color: var(--accent-ink);
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--ink);
}

img {
  max-width: 100%;
  height: auto;
}

strong {
  font-weight: 700;
}

:focus-visible {
  outline: 3px solid var(--secondary);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--dark);
  color: #fff;
  border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
  left: 0;
  color: #fff;
}

/* --- rejilla ------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 22px;
}

.section {
  padding-block: clamp(2.5rem, 5vw, 4.25rem);
}

.section--tinted {
  background: var(--ultralight);
}

.section__head {
  max-width: 44rem;
  margin-bottom: 2rem;
}

.section__head--centered {
  max-width: none;
  text-align: center;
}

.section__head p {
  color: var(--ink-soft);
  margin-bottom: 0;
}

.eyebrow {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

/* --- cabecera y pie ------------------------------------------------------ */

.site-header {
  background: var(--dark);
  color: #fff;
}

.site-header__bar {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  min-height: 62px;
  flex-wrap: wrap;
}

.site-header__brand {
  font-size: 1.3rem;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  letter-spacing: -0.01em;
}

.site-header__brand:hover {
  color: var(--primary);
}

.site-nav {
  display: flex;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin-left: auto;
  align-items: center;
}

.site-nav a {
  color: var(--light);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--primary);
}

.site-nav .btn {
  font-size: 0.9rem;
  padding: 0.4em 1.2em;
}

.site-footer {
  background: var(--dark);
  color: var(--light);
  padding-block: 2.75rem 2rem;
  margin-top: 0;
  font-size: 0.95rem;
}

.site-footer a {
  color: var(--light);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--primary);
}

.site-footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1.75rem 2rem;
}

.site-footer h2 {
  font-size: 0.8rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 0.75rem;
}

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer li + li {
  margin-top: 0.4rem;
}

.site-footer__legal {
  margin-top: 2.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  color: #9aa1aa;
  font-size: 0.85rem;
}

.site-footer__legal p {
  margin: 0;
}

/* --- botones ------------------------------------------------------------- */
/* Píldora, como en toda la landing (b-button pill). Sobre un campo de color el
   botón es blanco con el texto del acento — que es exactamente lo que hace
   InfoBanner. Sobre fondo claro se invierte, porque un botón blanco sobre
   blanco no se ve. */

.btn {
  display: inline-block;
  padding: 0.62em 1.7em;
  border: 2px solid transparent;
  border-radius: var(--radius-pill);
  font: inherit;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease,
    color 0.15s ease;
}

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

/* El fondo del botón sólido es el ink y no el color base: el base está elegido
   para rellenos y con texto blanco encima no llega a 4,5:1. Con el amarillo la
   diferencia es abismal — 1,81:1 contra 4,70:1. */
.btn--solid {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
  color: #fff;
}

.btn--solid:hover {
  background: var(--dark);
  border-color: var(--dark);
  color: #fff;
}

.btn--on-field {
  background: #fff;
  border-color: #fff;
  color: var(--accent-ink);
}

.btn--on-field:hover {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--dark);
}

.btn--quiet {
  background: transparent;
  border-color: currentColor;
  color: inherit;
}

.btn--quiet:hover {
  background: rgba(255, 255, 255, 0.14);
  color: inherit;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  align-items: center;
}

/* --- migas --------------------------------------------------------------- */

.breadcrumbs {
  padding-block: 0.9rem 0;
  font-size: 0.87rem;
  color: var(--ink-soft);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumbs li + li::before {
  content: "›";
  margin-right: 0.4rem;
  color: var(--light);
}

/* --- hero ---------------------------------------------------------------- */
/* El mismo gesto que InfoBanner: el banner ocupa todo el ancho y el texto va
   encima, en blanco, sobre el campo liso que la ilustración deja libre. Va como
   <img> y no como background para que la ilustración tenga alt y Google la
   pueda leer. */

/* La altura la manda el texto, no la imagen. Con la imagen mandando, un titular
   de tres líneas más el botón se salen por abajo del banner — que es justo lo
   que pasaba. El banner se recorta por la derecha, que es campo de color liso:
   no se pierde nada de la ilustración. */
/* La banda toma la proporción del banner, así que la ilustración entra entera:
   con `cover` a una altura menor el recorte se comía el avión de papel, que es
   justo el gesto que amarra la página a la identidad. Es además cómo se
   comporta InfoBanner en el SPA, donde la b-card lleva la imagen a width:100%
   y height:auto.

   aspect-ratio propone la altura, no la impone: si el texto es más alto —
   móvil, tipografía grande, un titular largo — la banda crece y no recorta. */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--accent);
  aspect-ratio: 1920 / 690;
}

@media (max-width: 767px) {
  .hero {
    aspect-ratio: 800 / 1339;
  }
}

/* La ilustración sale del flujo: la altura de la banda la fija el texto y la
   imagen rellena lo que haya. Al revés — con la imagen mandando — un titular de
   tres líneas empuja el botón fuera del campo de color, y como el botón es
   blanco sobre fondo blanco, desaparece sin dejar rastro. */
.hero__media {
  position: absolute;
  inset: 0;
}

.hero__media img {
  display: block;
  width: 100%;
  height: 100%;
  /* Recorta por la derecha, que es campo liso: la ilustración no se toca. */
  object-fit: cover;
  object-position: left center;
}

.hero__body {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: clamp(1.75rem, 4vw, 3rem);
}

/* Velo bajo el texto blanco. El campo cafe de Correccion de Tests da 4,25:1
   con blanco y el minimo AA para texto normal es 4,5: el titular pasa por
   texto grande y le bastaria 3:1, pero la bajada y la nota no.

   El degradado arranca en el 40% y ya esta al maximo en el 55%, que es donde
   empieza el bloque de texto: la ilustracion de la izquierda no se toca y la
   zona del texto queda a opacidad uniforme, que es lo que hace que el test
   pueda medirla. El valor sale de HERO_SCRIM en registry.py — un solo numero
   para el CSS y para el test. */
.hero--light .hero__body::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0) 40%,
    rgba(0, 0, 0, var(--hero-scrim)) 55%
  );
}

.hero--light.hero--left .hero__body::before {
  background: linear-gradient(
    to left,
    rgba(0, 0, 0, 0) 40%,
    rgba(0, 0, 0, var(--hero-scrim)) 55%
  );
}

.hero--light .hero__body > * {
  position: relative;
}

@media (max-width: 767px) {
  /* En vertical el texto va arriba, asi que el velo tambien. */
  .hero--light .hero__body::before {
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, var(--hero-scrim)) 55%,
      rgba(0, 0, 0, 0) 72%
    );
  }
}

.hero h1 {
  font-size: clamp(1.75rem, 3.1vw, 2.65rem);
}

/* De que lado cae el texto. Es el `orientation` de InfoBanner: cada banner
   deja libre un lado distinto y el texto va donde el campo es liso. */
.hero__text {
  width: min(50%, 34rem);
}

.hero--right .hero__text {
  margin-left: auto;
  padding-right: 22px;
}

.hero--left .hero__text {
  margin-right: auto;
  padding-left: 0;
}

/* Dos variantes, igual que el txtColor de InfoBanner en la landing. El campo
   de color del banner de producto es saturado y pide texto blanco; el del
   banner principal es crema y pide texto oscuro. Con la variante equivocada el
   titular no se lee, y es un error que no salta al mirar el codigo: hay que
   mirar la imagen. Por eso lo mide un test. */
.hero--light .hero__text,
.hero--light .hero__text h1 {
  color: #fff;
}

.hero--light .hero__note {
  color: rgba(255, 255, 255, 0.93);
}

.hero--dark .hero__text,
.hero--dark .hero__text h1 {
  color: var(--ink);
}

.hero--dark .hero__note {
  color: var(--ink-soft);
}

.hero__lede {
  font-size: clamp(1rem, 1.35vw, 1.28rem);
  margin-bottom: 1.4rem;
  max-width: 30rem;
}

.hero__note {
  margin: 0.9rem 0 0;
  font-size: 0.92rem;
}

/* En móvil el banner vertical deja el campo de color arriba, así que el texto
   se apila sobre esa mitad en vez de flotar al centro. */
/* En móvil el banner vertical deja el campo de color arriba, así que el texto
   se apila sobre esa mitad en vez de centrarse. El campo ocupa el 61% superior
   de la imagen y el bloque tiene que caber ahí: pasado ese punto el texto se
   monta sobre la taza de la ilustración y no se lee. De ahí que todo el ritmo
   se apriete en este tramo. */
@media (max-width: 767px) {
  .hero__body {
    align-items: flex-start;
    padding-block: 1rem 0;
  }

  /* En vertical el campo de color siempre queda arriba, asi que el lado deja
     de importar y el texto ocupa el ancho completo. */
  .hero--left .hero__text,
  .hero--right .hero__text {
    width: 100%;
    margin: 0;
    padding: 3vw 22px 0;
  }

  .hero h1 {
    font-size: clamp(1.55rem, 6.4vw, 2rem);
  }

  .hero__lede {
    max-width: none;
    margin-bottom: 1rem;
  }

  .hero__note {
    margin-top: 0.6rem;
    font-size: 0.85rem;
  }
}

/* Por debajo de 384 px el bloque de texto ya no cabe en el campo de color del
   banner vertical, y el titular se monta sobre la taza de la ilustración. Ahí
   el hero deja de ser una superposición y se desapila: primero el texto sobre
   el color, después la ilustración recortada a su parte útil.

   El recorte importa. La imagen de móvil es campo de color arriba e ilustración
   abajo; puesta entera debajo del texto, se ve el campo vacío dos veces. Con
   `object-position: bottom` y la proporción de la mitad inferior, se muestra
   solo la ilustración.

   OJO: .hero__media es position:absolute en el modo superpuesto y hay que
   devolverla al flujo, no solo reordenarla. Un elemento posicionado se pinta
   por encima de uno que no lo está: dejarla absolute con el texto en static
   borra el hero entero. Ya pasó. */
@media (max-width: 383px) {
  .hero {
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
  }

  .hero__body {
    order: 1;
    padding-block: 1.5rem;
  }

  .hero__media {
    order: 2;
    position: relative;
    inset: auto;
    aspect-ratio: 800 / 645;
  }

  /* La imagen va absolute dentro del recorte y no con height:100% a secas: un
     porcentaje contra una altura que sale de aspect-ratio no resuelve, la
     imagen se desborda y lo que se ve es el campo de color vacío de arriba en
     vez de la ilustración. */
  .hero__media img {
    position: absolute;
    inset: 0;
    object-position: center bottom;
  }

  .hero__text {
    padding-top: 0;
  }
}

/* Aquí vivía una regla que ponía .hero__body en position:static por debajo de
   430 px. Borraba el texto del hero entero: .hero__media es absolute, y un
   elemento posicionado se pinta por encima de uno que no lo está, así que la
   ilustración tapaba el titular, la bajada y el botón. El body se queda
   relative siempre. El banner vertical deja el campo de color arriba y ahí cabe
   todo, que es justo para lo que existe la variante de móvil. */

/* --- la lista de tests --------------------------------------------------- */
/* Es el contenido que rankea: nombres propios, no adjetivos. Se lee como una
   ficha técnica — un renglón por test, con su área y lo que se ingresa. La
   regla punteada es el eco de la trayectoria del avión de papel de los
   banners. */

.tests-group + .tests-group {
  margin-top: 2.25rem;
}

.tests-group__head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}

.tests-group__head h3 {
  margin: 0;
  font-size: 1.05rem;
}

.tests-group__count {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.tests-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Rejilla y no flex: con flex, "Perfil sensorial · Padres" desborda su columna
   y arrastra la descripción, que deja de alinearse con las de arriba. La ficha
   se lee escaneando la segunda columna, así que esa alineación es el punto. */
.tests-list li {
  display: grid;
  grid-template-columns: minmax(11rem, 15rem) 1fr;
  align-items: baseline;
  gap: 0.25rem 1.2rem;
  padding: 0.72rem 0;
  border-bottom: 1px dotted var(--light);
}

.tests-list b {
  font-size: 1.02rem;
}

.tests-list span {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

@media (max-width: 559px) {
  .tests-list li {
    grid-template-columns: 1fr;
  }
}

/* --- precio -------------------------------------------------------------- */
/* Solo, y con la unidad clara. Un precio escondido entre párrafos es un precio
   que no se cree. */

.price {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1.5rem;
  text-align: center;
}

.price__amount {
  font-size: clamp(2.6rem, 6vw, 4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--accent-ink);
}

.price__unit {
  font-size: 1.05rem;
  color: var(--ink-soft);
  text-align: left;
}

.price__unit strong {
  display: block;
  color: var(--ink);
}

/* --- preguntas ----------------------------------------------------------- */
/* <details> nativo: el desplegable funciona sin JavaScript. */

.faq {
  max-width: 46rem;
}

.faq details {
  border-bottom: 1px solid var(--rule);
}

.faq summary {
  padding: 1rem 2rem 1rem 0;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
  position: relative;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "+";
  position: absolute;
  right: 0.25rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--accent-ink);
}

.faq details[open] summary::after {
  content: "–";
}

.faq details > div {
  padding-bottom: 1rem;
  color: var(--ink-soft);
}

.faq details > div > :last-child {
  margin-bottom: 0;
}

/* --- llamada de cierre --------------------------------------------------- */

.cta {
  background: var(--dark);
  color: #fff;
  border-radius: var(--radius);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  text-align: center;
}

.cta h2 {
  color: #fff;
  max-width: 30rem;
  margin-inline: auto;
}

.cta p {
  color: var(--light);
  max-width: 34rem;
  margin-inline: auto 1.5rem;
  margin-inline: auto;
  margin-bottom: 1.5rem;
}

.cta .btn-row {
  justify-content: center;
}

/* --- hueco del teaser ---------------------------------------------------- */
/* El póster está en el HTML servido desde el primer byte; el componente real
   lo reemplaza después de la primera pintura. Si el JavaScript no llega, el
   póster se queda y sigue llevando a la demo. */

.teaser-slot {
  position: relative;
}

.teaser-poster {
  background: var(--ultralight);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
}

.teaser-poster__actions {
  margin-top: 1.6rem;
  justify-content: center;
}

/* Los tres pasos del flujo. La trayectoria punteada entre ellos es el gesto
   que repiten los banners de la landing — el avión de papel y su estela — y
   acá gana su sitio porque de verdad codifica una secuencia: los puntajes
   entran, el test se corrige, sale el informe. Es el único sitio de la página
   donde aparece. */
.flow {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.flow__step {
  position: relative;
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
}

.flow__step + .flow__step::before {
  content: "";
  position: absolute;
  top: 1.05rem;
  right: calc(100% + 0.35rem);
  width: 1.5rem;
  border-top: 3px dotted var(--accent);
}

.flow__n {
  flex: none;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-ink);
  color: #fff;
  font-weight: 700;
  font-size: 0.95rem;
}

.flow__label b {
  display: block;
  line-height: 1.3;
}

.flow__label em {
  display: block;
  margin-top: 0.2rem;
  font-style: normal;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

@media (max-width: 719px) {
  .flow {
    grid-template-columns: 1fr;
    gap: 1.1rem;
  }

  /* En columna la estela va vertical, del círculo de un paso al del siguiente. */
  .flow__step + .flow__step::before {
    top: -1.05rem;
    right: auto;
    left: 1.05rem;
    width: 0;
    height: 0.95rem;
    border-top: 0;
    border-left: 3px dotted var(--accent);
  }
}

/* Cuando el componente monta, se anuncia con este atributo y el póster se
   retira. Un solo interruptor, para que no puedan verse los dos a la vez. */
.teaser-slot[data-teaser="live"] .teaser-poster {
  display: none;
}

.teaser-mount:empty {
  display: none;
}

/* --- movimiento ---------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .btn:hover {
    transform: none;
  }
}

/* --- impresión ----------------------------------------------------------- */

@media print {
  .site-header,
  .site-footer,
  .cta,
  .teaser-slot,
  .btn {
    display: none !important;
  }

  body {
    font-size: 11pt;
  }

  .faq details {
    /* En papel no hay dónde hacer clic: todo abierto. */
    display: block;
  }

  .faq details > div {
    display: block !important;
  }
}

/* --- informes de muestra -------------------------------------------------- */
/* Estas páginas no llevan banner ilustrado. Lo característico del tema es el
   documento, no un escritorio con una tableta, así que la portada es tipográfica
   y el peso visual se gasta entero en la hoja del informe (.informe-hoja). */

.hero-plano {
  padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 3vw, 2.25rem);
  background: var(--ultralight);
  border-bottom: 1px solid var(--rule);
}

.hero-plano h1 {
  max-width: 20ch;
}

.hero-plano__lede {
  max-width: 46ch;
  margin: 0 0 1.5rem;
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--ink-soft);
}

.hero-plano .btn-row {
  margin-bottom: 0;
}

/* --- índice de muestras --------------------------------------------------- */

.muestras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Columna y no bloque suelto: el botón se ancla abajo con margin-top:auto, así
   las tres fichas terminan a la misma altura aunque sus índices tengan distinto
   número de secciones. Sin eso, la ficha con el informe más corto deja el botón
   flotando a media altura y las tres dejan de leerse como una fila. */
.muestra-ficha {
  display: flex;
  flex-direction: column;
  padding: 1.6rem;
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.muestra-ficha__profesion {
  margin: 0 0 0.4rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.muestra-ficha__caso {
  margin: 0 0 0.5rem;
  font-size: 1.1rem;
  line-height: 1.35;
}

.muestra-ficha__caso a {
  color: inherit;
  text-decoration: none;
}

.muestra-ficha__caso a:hover,
.muestra-ficha__caso a:focus-visible {
  text-decoration: underline;
}

.muestra-ficha__instrumentos {
  margin: 0 0 1.25rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.muestra-ficha__rotulo {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* El índice real del informe, leído del documento generado. Va numerado porque
   el orden es información: es el orden en que la profesional lee el informe. */
.muestra-indice {
  margin: 0 0 1.5rem;
  padding-left: 1.4rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.muestra-indice li {
  padding: 0.15rem 0;
}

.muestra-ficha .btn-row {
  margin-top: auto;
  margin-bottom: 0;
}

/* --- caso e instrumentos -------------------------------------------------- */

.prosa {
  max-width: 62ch;
}

.prosa p {
  margin: 0 0 1rem;
}

.prosa p:last-child {
  margin-bottom: 0;
}

.caso {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

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

.caso__ficha {
  margin: 0;
  padding: 1.25rem 1.4rem;
  background: var(--ultralight);
  border-radius: var(--radius);
}

.caso__dato + .caso__dato {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px dotted var(--light);
}

.caso__dato dt {
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.caso__dato dd {
  margin: 0.15rem 0 0;
  font-weight: 500;
}

.instrumentos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* La regla de acento arriba y no un recuadro: son tres apuntes cortos, y
   encerrarlos les daría más peso del que tienen frente a la hoja de abajo. */
.instrumento {
  padding-top: 0.9rem;
  border-top: 3px solid var(--accent);
}

.instrumento__nombre {
  margin: 0 0 0.35rem;
  font-weight: 700;
  font-size: 1.05rem;
}

.instrumento__aporte {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

/* --- la hoja del informe -------------------------------------------------- */
/* El elemento con el que se recuerda la página. Es el documento convertido del
   .docx, puesto como una hoja sobre el fondo tramado de la sección.

   No imita a Word tipografía por tipografía —el documento fiel es el .docx que
   se descarga al lado—; lo que hace es leerse como documento y no como página
   web: medida de lectura corta, interlínea de texto impreso, tablas regladas y
   márgenes de hoja. */

.documento__nota {
  max-width: 60ch;
  margin: 0 0 1.5rem;
  color: var(--ink-soft);
}

.informe-hoja {
  padding: clamp(1.5rem, 4vw, 3.25rem);
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(57, 62, 70, 0.05),
              0 12px 32px rgba(57, 62, 70, 0.07);
  font-size: 0.97rem;
  line-height: 1.6;
}

.informe-hoja > :first-child {
  margin-top: 0;
}

.informe-hoja > :last-child {
  margin-bottom: 0;
}

/* Los títulos del informe, no los de la página: por eso no heredan la escala de
   h2 del sitio, que los dejaría del porte del titular de la sección. */
.informe-hoja h3 {
  margin: 2rem 0 0.6rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--rule);
  font-size: 1.02rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--accent-ink);
}

.informe-hoja h3:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  font-size: 1.25rem;
  color: var(--ink);
}

.informe-hoja p {
  max-width: 68ch;
  margin: 0 0 0.85rem;
}

/* Las tablas del informe pueden ser anchas —el desglose del TEPROSIF-R trae una
   columna por familia de proceso—. Se desplazan dentro de su caja para que la
   página nunca lo haga: un sitio que se mueve de lado en el teléfono se siente
   roto aunque el contenido esté bien. */
.doc-tabla-scroll {
  overflow-x: auto;
  margin: 0 0 1.25rem;
  -webkit-overflow-scrolling: touch;
}

.doc-tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.doc-tabla th,
.doc-tabla td {
  padding: 0.42rem 0.7rem;
  border: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}

.doc-tabla thead th {
  background: var(--ultralight);
  font-weight: 700;
  white-space: nowrap;
}

.doc-tabla tbody th {
  font-weight: 500;
}

.btn-row--centrada {
  justify-content: center;
}

.documento__pie {
  margin: 0.75rem 0 0;
  font-size: 0.9rem;
  text-align: center;
  color: var(--ink-soft);
}

.muestra-ficha__resto {
  margin: -1rem 0 1.5rem;
  padding-left: 1.4rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}
