/*
  El sitio público.

  UNA IDEA, REPETIDA: la ventana. Todo lo que se enseña del producto es luz
  cálida vista desde un sitio oscuro y frío — que es literalmente lo que hace un
  visor. La interfaz se queda en el lado frío: negro azulado, un solo acento
  cian, y ni una gota del oro que hay dentro de las imágenes. Si ese calor se
  escapara a los botones y a los títulos, el hueco dejaría de leerse como un
  hueco y quedaría una página naranja más.

  Las cabeceras van a sangre y sin marco. No llevan clase propia para eso: están
  fuera de `.wrap`, que es lo único que limita el ancho en todo el sitio.

  La tipografía es la del sistema, que en un Mac y en un iPhone es San
  Francisco. Sin descarga, sin bloquear el primer pintado y sin una licencia que
  revisar.

  Las capturas del editor son del producto de verdad, así que se enmarcan como
  lo que son —una pantalla— y no se recortan en formas decorativas: una captura
  con las esquinas comidas por un ángulo bonito es una captura en la que ya no
  se puede leer nada.
*/

/*
  Sora, variable, servida desde aquí. El CSP del ápice es `font-src 'self'`, así
  que no hay Google Fonts que valga: el archivo vive en el bucket como cualquier
  otra cosa del sitio. Es el subconjunto latino —34 kB— porque el castellano y
  el inglés caben enteros en Latin-1; el latino extendido añadiría peso para
  glifos que este sitio no escribe.

  Va SÓLO en los titulares. En el cuerpo sigue la tipografía del sistema, que en
  un Mac es San Francisco: no se descarga, no parpadea y a 17 px se lee mejor
  que cualquier geométrica. Dos familias con trabajos distintos, no dos familias
  compitiendo.

  Sora es de Julieta Ulanovsky y colaboradores, bajo SIL Open Font License 1.1.
  La licencia viaja al lado del archivo, en fonts/OFL.txt, porque la OFL lo pide.
*/
@font-face {
  font-family: "Sora";
  src: url("/fonts/sora-latin.woff2") format("woff2");
  font-weight: 200 700;
  font-style: normal;
  /* `swap`: el titular se pinta con la del sistema y cambia cuando llega. Con
     `block` la portada se queda muda hasta que el archivo baja. */
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;

  /* La pared. Negro azulado, no gris: al lado de una imagen al atardecer
     cualquier neutro cálido se ve sucio. */
  --void: #06080b;
  --panel: #0d1117;
  --raise: #131a24;

  --rule: rgba(255, 255, 255, .10);
  --rule-soft: rgba(255, 255, 255, .055);

  --text: #eef1f5;
  --muted: #98a1ae;
  --dim: #6b7482;

  /* El mismo cian pálido con el que la sala se dibuja a sí misma en las
     imágenes: el único color de la interfaz sale de dentro de ellas. */
  --horizon: #9fc3dd;

  /* El dorado de las fotografías. No es `--horizon`, que es el azul pálido de
     los enlaces: la interfaz de este sitio es fría y sus imágenes son cálidas,
     y un icono que acompaña a la imaginería tiene que estar del lado cálido. */
  --glow: #e6b45c;

  --go: #f2f5f8;
  --go-ink: #06080b;
  --warn: #e8b4a4;

  --page: 1220px;
  --gutter: clamp(20px, 5vw, 40px);
  --section: clamp(72px, 10vw, 140px);
  --bar-h: 60px;

  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
          "Segoe UI Variable Display", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --display: "Sora", var(--sans);

  --r-window: 18px;
  --r-field: 12px;
  --r-chip: 8px;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--bar-h) + 16px); }

body {
  margin: 0;
  background: var(--void);
  color: var(--text);
  font: 400 17px/1.6 var(--sans);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

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

.skip {
  position: fixed; top: 8px; left: 8px; z-index: 100;
  padding: 10px 16px; border-radius: 999px;
  background: var(--go); color: var(--go-ink); font-size: 15px; font-weight: 500;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

[hidden] { display: none !important; }

/* ── El texto ───────────────────────────────────────────────────────────────
   Una sola familia. La jerarquía la hacen el tamaño, el peso y el interletrado:
   cuanto más grande el tipo, más apretado, que es la corrección óptica que hace
   que un titular enorme no parezca desarmado. */

/* Los titulares en Sora y en peso ligero: es una geométrica y a tamaño grande
   el trazo fino es lo que la hace parecer de ahora en vez de gruesa y genérica.
   El interletrado es MENOS negativo que con la del sistema — una geométrica ya
   viene apretada de fábrica y seguir cerrándola le come los contrapunzones. */
h1, h2, h3 { margin: 0; font-family: var(--display); font-weight: 500; }

.display {
  font-family: var(--display);
  font-size: clamp(2.5rem, 6.2vw, 4.5rem);
  font-weight: 300;
  line-height: 1.06;
  letter-spacing: -.022em;
  max-width: 15ch;
}
.display span { display: block; }

.h1 { font-size: clamp(1.9rem, 4.4vw, 3.125rem); font-weight: 300; line-height: 1.1; letter-spacing: -.018em; max-width: 20ch; }
.h2 { font-size: clamp(1.75rem, 3.7vw, 2.625rem); font-weight: 400; line-height: 1.14; letter-spacing: -.016em; }
.h3 { font-size: clamp(1.125rem, 1.8vw, 1.375rem); font-weight: 500; line-height: 1.28; letter-spacing: -.01em; }

.lede {
  margin: 0;
  font-size: clamp(1.0625rem, 1.45vw, 1.25rem);
  line-height: 1.5;
  letter-spacing: -.011em;
  color: var(--muted);
  max-width: 36em;
}

.body { margin: 0; color: var(--muted); max-width: 34em; }
.small { font-size: .8125rem; line-height: 1.5; color: var(--dim); margin: 0; }
.note { color: var(--dim); }
.warn { color: var(--warn); font-size: .9375rem; margin: 0; }

.wrap { max-width: var(--page); margin: 0 auto; padding-inline: var(--gutter); }

/* ── Botones ─────────────────────────────────────────────────────────────── */

.go, .ghost {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 0 22px;
  border: 0; border-radius: 999px;
  font-size: 1rem; font-weight: 500; letter-spacing: -.01em;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.go { background: var(--go); color: var(--go-ink); }
.go:hover { background: #fff; }
.go:disabled { background: var(--raise); color: var(--dim); cursor: progress; }

.ghost { background: transparent; color: var(--text); border: 1px solid var(--rule); }
.ghost:hover { border-color: rgba(255, 255, 255, .28); }

.go.wide, .ghost.wide { width: 100%; }

.link {
  background: none; border: 0; padding: 6px 2px;
  color: var(--muted); font-size: .9375rem; cursor: pointer;
}
.link:hover { color: var(--text); }

.quiet { color: var(--horizon); }
.quiet:hover { text-decoration: underline; text-underline-offset: 4px; }

/* ── La barra ────────────────────────────────────────────────────────────── */

.bar {
  position: sticky; top: 0; z-index: 50;
  height: var(--bar-h);
  display: flex; align-items: center; gap: 20px;
  padding: 0 var(--gutter);
  background: color-mix(in srgb, var(--void) 72%, transparent);
  backdrop-filter: saturate(160%) blur(18px);
  -webkit-backdrop-filter: saturate(160%) blur(18px);
  border-bottom: 1px solid var(--rule-soft);
}
.bar .mark { display: flex; align-items: center; }
/* El logotipo es un lockup apilado —marca arriba, palabra abajo— y necesita el
   doble de alto que un logotipo en línea para que la palabra siga legible. */
.bar .mark img { height: 30px; width: auto; }
.bar nav { display: flex; gap: 24px; margin-left: 8px; }
.bar nav a { font-size: .9375rem; color: var(--muted); }
.bar nav a:hover { color: var(--text); }
.bar .end { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.bar .end .ghost { min-height: 34px; padding: 0 15px; font-size: .875rem; }

/* Quién ha entrado, en la barra. El nombre se recorta en vez de empujar la
   navegación: hay direcciones de correo más largas que la propia barra. */
.whoami { display: flex; align-items: center; gap: 8px; min-width: 0; }
.whoami .who {
  font-size: .875rem; color: var(--muted);
  max-width: 14ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 700px) { .whoami .who { display: none; } }

/* Lo que ya se compró no lleva precio: lleva esto. */
.ownedtag {
  margin: 2px 0 0; font-size: .8125rem; font-weight: 500;
  color: var(--horizon);
}

/* La sección de lo propio va antes que la tienda y se separa de ella con la
   misma línea que el resto de secciones. */
.shop.mine { padding-block: clamp(48px, 7vw, 88px) 0; }

.lang {
  min-height: 34px; padding: 0 12px;
  background: transparent; border: 1px solid var(--rule); border-radius: 999px;
  font-size: .8125rem; font-weight: 500; letter-spacing: .02em;
  color: var(--muted); cursor: pointer;
}
.lang:hover { color: var(--text); border-color: rgba(255, 255, 255, .28); }

@media (max-width: 700px) { .bar nav { display: none; } }

/* ── Cabeceras a sangre ────────────────────────────────────────────────────
   Sólo la primera ocupa la pantalla entera; las demás, media. Todas van de
   borde a borde y llevan el texto encima — no hay clase que lo consiga: están
   fuera de `.wrap`, que es lo único que limita el ancho en todo el sitio. */

.hero {
  position: relative;
  width: 100%;
  overflow: hidden;
  display: flex; align-items: flex-end;
  background: var(--void);
}
/* svh y no vh: en un móvil, `100vh` mide la ventana SIN la barra del navegador,
   así que la primera pantalla sale siempre un poco más alta de lo que se ve y
   la leyenda queda cortada por debajo. */
/* La línea en vh va primero como red: si un navegador no conoce `svh` —los hay,
   y en uno de ellos la declaración entera se descarta— la cabecera se quedaría
   con la altura de su contenido, que es casi el doble, y la imagen se saldría
   por debajo del pliegue. */
.hero.full { height: 100vh; height: 100svh; min-height: 560px; }
.hero.half { height: 52vh; height: 52svh; min-height: 340px; }

/* Un velo arriba y otro abajo, y el centro limpio: es exactamente donde estas
   imágenes tienen su asunto, y donde la página tiene su logotipo y su leyenda.
   El velo lateral de antes oscurecía justo el objeto. */
/* PANTALONES DE ELEFANTE. Un velo horizontal fuerte deja una banda oscura con
   un borde reconocible, y la imagen parece cortada y pegada encima del texto.
   Lo que hay aquí en su lugar son dos cosas suaves: una caída larguísima hacia
   el negro de la página —de más de la mitad de la altura, sin ningún punto en
   el que se vea empezar— y una elipse tenue justo detrás de donde cae el texto.
   El texto se apoya en la elipse; la imagen se disuelve en la página. Ni una
   arista entre las dos. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background:
    radial-gradient(80% 46% at 50% 92%, rgba(6, 8, 11, .74), rgba(6, 8, 11, 0) 72%),
    linear-gradient(to bottom,
      rgba(6, 8, 11, .58) 0%, rgba(6, 8, 11, .12) 18%,
      rgba(6, 8, 11, 0) 34%, rgba(6, 8, 11, .34) 66%,
      rgba(6, 8, 11, .78) 86%, var(--void) 100%);
}

.hero .back {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  will-change: transform;
}
/* La única cosa que se mueve sola en el sitio: un acercamiento lentísimo que
   respira. No un barrido lateral — estas composiciones tienen el foco en el
   centro y desplazarlas lo sacaría de ahí, que es lo único que no se puede
   hacer con ellas. */
.hero .back { animation: breathe 46s ease-in-out infinite alternate; }
@keyframes breathe { from { transform: scale(1); } to { transform: scale(1.055); } }

.hero .copy {
  position: relative; z-index: 2;
  width: 100%;
  padding-bottom: clamp(36px, 6vw, 72px);
  display: grid; gap: 20px; justify-items: start;
}
.hero .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.hero .back-link { color: var(--muted); font-size: .9375rem; }
.hero .back-link:hover { color: var(--text); }

/* La portada: logotipo arriba, leyenda abajo, todo centrado sobre el objeto.

   La imagen NO llena la pantalla: se contiene dentro de una franja que deja un
   8% arriba y un 12% abajo. Es lo que hace que el logotipo y la leyenda tengan
   dónde ponerse. Con `cover` la pantalla se llena, sí, pero un cuadrado en una
   ventana apaisada se recorta por arriba y por abajo — justo el aire que esta
   composición necesita— y el titular acaba encima del visor. Las franjas no se
   ven porque el fondo de la imagen es el mismo negro que el de la página. */
.hero.full .back {
  /* Llena la pantalla entera, ancho y alto. Un cuadrado en una ventana apaisada
     se recorta por arriba y por abajo — es el precio de que no queden bandas — y
     lo que devuelve el aire al logotipo y a la leyenda son los velos de abajo,
     no un hueco vacío. */
  inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
/* Más oscuros que en las demás cabeceras, y por eso: aquí el texto cae sobre el
   asunto, no sobre un fondo. */
.hero.full::after {
  background:
    radial-gradient(72% 42% at 50% 88%, rgba(6, 8, 11, .80), rgba(6, 8, 11, 0) 74%),
    linear-gradient(to bottom,
      rgba(6, 8, 11, .62) 0%, rgba(6, 8, 11, .16) 15%,
      rgba(6, 8, 11, 0) 36%, rgba(6, 8, 11, .30) 64%,
      rgba(6, 8, 11, .72) 84%, rgba(6, 8, 11, .94) 95%, var(--void) 100%);
}
/* Columna flexible y no rejilla. Con `grid-template-rows` + `justify-items` el
   ancho de la columna lo decidía el contenido y ni el logotipo quedaba centrado
   ni la entradilla se acotaba: se iba en una línea hasta el borde. Con flex,
   `align-items: center` centra de verdad y `space-between` reparte el hueco
   entre el logotipo arriba y la leyenda abajo. */
.hero.full .copy {
  height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between;
  text-align: center; gap: 0;
  padding-block: clamp(18px, 3.5svh, 44px) clamp(34px, 7svh, 80px);
}
.hero.full .crest { height: clamp(34px, 4.4vw, 56px); width: auto; opacity: .92; flex: none; }
.hero.full .caption {
  display: flex; flex-direction: column; align-items: center; gap: 18px;
  width: min(100%, 660px);
}
.hero.full .display, .hero.full .lede { max-width: none; width: 100%; }
.hero.full .lede { font-size: clamp(1.0625rem, 1.25vw, 1.1875rem); }

/* ── La ventana ──────────────────────────────────────────────────────────── */

.window {
  position: relative; overflow: hidden;
  border-radius: var(--r-window);
  background: var(--panel);
  /* El filo claro de arriba es el canto de la pared donde el hueco está
     cortado; el resto del borde apenas se insinúa. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10), inset 0 0 0 1px var(--rule-soft);
}
.window img { width: 100%; height: 100%; object-fit: cover; }
.screen { border-radius: 12px; }
.screen img { object-fit: contain; background: #0b0e14; }

/* ── La tienda: la galería es lo primero y lo más importante ─────────────── */

.shop { padding-block: clamp(56px, 8vw, 104px) var(--section); }
.shop .head { display: grid; gap: 14px; margin-bottom: clamp(30px, 4.5vw, 52px); }

.grid {
  display: grid;
  gap: clamp(24px, 3vw, 36px);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
  align-items: start;
}

/* Tarjetas de verdad: la imagen a sangre contra el borde superior, el texto en
   su propio panel debajo, y el botón siempre a la misma altura en toda la fila
   —de ahí el `1fr` y el `margin-top:auto`—, porque tres tarjetas con el botón
   a tres alturas distintas se leen como tres cosas distintas. */
.card {
  display: grid;
  grid-template-rows: auto 1fr;
  border-radius: var(--r-window);
  overflow: hidden;
  background: linear-gradient(170deg, var(--raise), var(--panel) 72%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), inset 0 0 0 1px var(--rule-soft);
  transition: transform .25s ease, box-shadow .25s ease;
}
.card:hover, .card:focus-within {
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), inset 0 0 0 1px var(--rule),
              0 24px 48px -28px rgba(0, 0, 0, .9);
}
/* Dentro de la tarjeta el hueco pierde su propio marco: el marco es la tarjeta,
   y dos bordes redondeados concéntricos se ven como un error de medio píxel. */
.card .shot { aspect-ratio: 16 / 10; border-radius: 0; box-shadow: none; }
.card .shot img { transition: transform 1.2s cubic-bezier(.2, .7, .2, 1); }
.card:hover .shot img, .card:focus-within .shot img { transform: scale(1.03); }
.card .said {
  padding: clamp(18px, 2vw, 24px);
  display: grid; gap: 10px; justify-items: start; align-content: start;
}
.card .body { font-size: .9375rem; }
.card .price { margin-top: 4px; }
.card .ghost { margin-top: auto; align-self: stretch; }

/* Quién publica el curso. Encima de los datos y debajo del resumen, en el mismo
   gris que el resto de lo secundario: es una atribución, no un reclamo. */
.byline { font-size: .8125rem; color: var(--dim); margin: 0; }

.facts { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 0; padding: 0; list-style: none; }
.facts li {
  padding: 5px 11px; border: 1px solid var(--rule-soft); border-radius: var(--r-chip);
  font-size: .8125rem; color: var(--muted); background: var(--panel);
}

.price { display: flex; align-items: baseline; gap: 10px; }
.amount { font-size: 1.375rem; font-weight: 600; letter-spacing: -.02em; }
.per { font-size: .8125rem; color: var(--dim); }

/* Gratis se dice en el color del acento y no en el del importe. Un «Gratis» con
   el gris de un precio se lee como un precio pendiente de poner; en el azul del
   horizonte se lee como lo que es, que es la razón para pulsar. */
.price.free .amount { color: var(--horizon); }

/* ── Autoría: las capturas del editor de verdad ─────────────────────────── */

.make { padding-block: var(--section); border-top: 1px solid var(--rule-soft); }
.make .head { display: grid; gap: 16px; margin-bottom: clamp(32px, 5vw, 56px); max-width: 46em; }
.shots { display: grid; gap: clamp(20px, 3vw, 32px); grid-template-columns: 1fr; }
@media (min-width: 900px) { .shots { grid-template-columns: repeat(3, 1fr); } }
.shots figure { margin: 0; display: grid; gap: 12px; }
.shots.wide { grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .shots.wide { grid-template-columns: 1fr 1fr; }
  .shots.wide figure:first-child { grid-column: 1 / -1; }
}

/* ── Las tres afirmaciones ───────────────────────────────────────────────── */

.claims { padding-block: var(--section); border-top: 1px solid var(--rule-soft); display: grid; gap: clamp(52px, 7vw, 96px); }
.claim { display: grid; gap: clamp(24px, 4vw, 56px); align-items: center; }
@media (min-width: 900px) {
  .claim { grid-template-columns: 1.1fr .9fr; }
  .claim.flip .shot { order: 2; }
}
.claim .shot { aspect-ratio: 3 / 2; }
.claim .said { display: grid; gap: 16px; }

/* ── Tres columnas de texto (la página de autoría) ──────────────────────── */

.three { padding-block: var(--section); display: grid; gap: clamp(28px, 4vw, 44px); }
@media (min-width: 860px) { .three { grid-template-columns: repeat(3, 1fr); } }
.three article { display: grid; gap: 12px; align-content: start; }

/* ── La invitación a publicar ───────────────────────────────────────────── */

.invite { padding-block: var(--section); border-top: 1px solid var(--rule-soft); }
.invite .inner {
  display: grid; gap: 26px; justify-items: start;
  padding: clamp(30px, 4.5vw, 54px);
  border-radius: var(--r-window);
  background: linear-gradient(160deg, var(--raise), var(--panel) 62%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
.invite .said { display: grid; gap: 14px; }

/* ── Campos ─────────────────────────────────────────────────────────────── */

.fields { display: grid; gap: 16px; width: 100%; max-width: 460px; }
.field { display: grid; gap: 6px; }
.field span { font-size: .875rem; font-weight: 500; color: var(--muted); }
.field input {
  width: 100%;
  min-height: 46px; padding: 12px 14px;
  border-radius: var(--r-field);
  border: 1px solid var(--rule);
  background: rgba(255, 255, 255, .03);
  color: var(--text);
  font: inherit; font-size: 1rem;
}
.field input::placeholder { color: var(--dim); }
.field input:focus { outline: 0; border-color: var(--horizon); }
.fields .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

/* ── La página del curso ─────────────────────────────────────────────────── */

.course-body { display: grid; gap: clamp(36px, 5vw, 64px); padding-block: clamp(40px, 6vw, 72px) var(--section); align-items: start; }
@media (min-width: 940px) { .course-body { grid-template-columns: minmax(0, 1fr) 400px; } }

.prose { display: grid; gap: 20px; }
.prose p { margin: 0; color: var(--muted); max-width: 36em; }
.prose h2 { margin-top: clamp(18px, 3vw, 30px); }

.modules { margin: 0; padding: 0; list-style: none; display: grid; }
.modules li {
  display: flex; justify-content: space-between; gap: 20px;
  padding: 15px 2px; border-top: 1px solid var(--rule-soft);
  color: var(--muted);
}
.modules li:last-child { border-bottom: 1px solid var(--rule-soft); }
.modules b { font-weight: 500; color: var(--text); }

.buy {
  display: grid; gap: 16px;
  padding: 26px;
  border-radius: var(--r-window);
  background: linear-gradient(160deg, var(--raise), var(--panel) 70%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), inset 0 0 0 1px var(--rule-soft);
}
@media (min-width: 940px) { .buy { position: sticky; top: calc(var(--bar-h) + 20px); } }
.buy .amount { font-size: 2.25rem; letter-spacing: -.03em; line-height: 1; }
.buy .rule { height: 1px; background: var(--rule-soft); }
.buy .pitch { margin: 0; font-size: .9375rem; line-height: 1.55; color: var(--muted); }

/* Los datos de prueba. Se parecen a los campos de al lado a propósito: es la
   misma caja de pago, no un aviso pegado encima. */
.testcard {
  display: grid; gap: 10px;
  padding: 14px 16px;
  border-radius: var(--r-field);
  border: 1px dashed rgba(159, 195, 221, .28);
  background: rgba(159, 195, 221, .05);
}
.testcard .tt { margin: 0; font-size: .8125rem; color: var(--muted); }
.testcard .tt b { color: var(--horizon); font-weight: 600; }
.testcard dl { margin: 0; display: grid; gap: 7px; }
.testcard dl > div { display: flex; align-items: center; gap: 10px; }
.testcard dt { flex: 0 0 6.5em; font-size: .8125rem; color: var(--dim); }
.testcard dd { margin: 0; flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.testcard code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .875rem; letter-spacing: .02em; color: var(--text);
}
/* `.clip` y no `.copy`: `.copy` es el bloque de texto de las cabeceras desde el
   principio, y darle el mismo nombre al botón le colaba `white-space: nowrap`
   —entre otras cosas— a la entradilla de la portada, que salía en una sola
   línea hasta salirse de la pantalla. */
.clip {
  margin-left: auto;
  padding: 4px 10px; min-height: 26px;
  border: 1px solid var(--rule); border-radius: 999px;
  background: transparent; color: var(--muted);
  font-size: .75rem; cursor: pointer; white-space: nowrap;
}
.clip:hover { color: var(--text); border-color: rgba(255, 255, 255, .3); }
.clip[data-done="1"] { color: var(--horizon); border-color: var(--horizon); }
.buy #start { display: grid; gap: 10px; }
.buy .fields { max-width: none; }
/* Lo que hay dentro de este hueco lo dibuja Stripe en un iframe suyo. Aquí sólo
   se le reserva el sitio; el color se le pasa por la Appearance API. */
#element { min-height: 44px; }

/* ── Gracias ─────────────────────────────────────────────────────────────── */

.done { min-height: 62vh; display: grid; align-content: center; gap: 22px; justify-items: start; padding-block: var(--section); }
.done .lede { max-width: 32em; }

.spin {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--rule); border-top-color: var(--horizon);
  animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── El diagrama de pasos ────────────────────────────────────────────────── */
/*
  UN DIAGRAMA HECHO DE HTML, NO UNA IMAGEN DE UN DIAGRAMA. Un SVG único con los
  cuatro pasos dentro se lee de maravilla a 900 px y es ilegible a 360: el texto
  se encoge con el dibujo y no hay nada que hacer al respecto. Aquí los pasos
  son elementos de una lista, el texto es texto —se selecciona, se traduce, lo
  lee un lector de pantalla— y la fila se convierte en columna cuando no cabe.

  EL CONECTOR ES UN PSEUDOELEMENTO Y GIRA CON LA MAQUETA. En fila sale del
  icono hacia la derecha; en columna, del icono hacia abajo. Se desvanece hacia
  el paso siguiente en vez de terminar en punta: una flecha por paso son cuatro
  puntas de flecha compitiendo con cuatro iconos, y gana el ruido.

  `<ol>` y no `<div>`: el orden de estos cuatro pasos es la mitad de lo que el
  diagrama dice, y en un lector de pantalla el conector no existe — la única
  cosa que queda diciendo «primero esto, luego esto» es la etiqueta de lista.
*/

.flowsec { padding-block: var(--section); border-top: 1px solid var(--rule-soft); }
.flowsec .head { display: grid; gap: 14px; margin-bottom: clamp(30px, 4.5vw, 52px); max-width: 46em; }

.flow { list-style: none; margin: 0; padding: 0; display: grid; gap: 30px; grid-template-columns: 1fr; }
.flow .h3 { font-size: 1.0625rem; }
.flow .small { color: var(--muted); max-width: 30em; }
.flow li::after { content: ""; position: absolute; pointer-events: none; }

/* En columna es una línea de tiempo: el icono se sale del flujo y se queda en
   un canalón a la izquierda, y el hilo baja por ese canalón. Sin el canalón el
   hilo pasaba POR ENCIMA de los titulares —tachándolos a la altura de la
   primera letra—, que es exactamente el aspecto de un fallo de maqueta. */
.flow li { position: relative; display: grid; gap: 9px; align-content: start;
           padding-inline-start: 48px; min-block-size: 34px; }
.flow li > .ico { position: absolute; inset-block-start: 0; inset-inline-start: 0; }

/* `100%` es sólo el alto de este paso, así que se le suma el hueco para que el
   hilo llegue al icono siguiente en vez de morir antes. */
.flow li:not(:last-child)::after {
  inset-block-start: 42px;
  inset-inline-start: 16.5px;
  inline-size: 1px;
  block-size: calc(100% - 42px + 30px);
  background: linear-gradient(180deg, rgba(230, 180, 92, .45), rgba(230, 180, 92, .08));
}

/* En fila el icono vuelve al flujo, encima de su rótulo, y el hilo sale de él
   hacia la derecha. Es el mismo diagrama girado, no un segundo diagrama. */
@media (min-width: 900px) {
  .flow { grid-template-columns: repeat(4, 1fr); gap: 30px; }
  .flow li { padding-inline-start: 0; }
  .flow li > .ico { position: static; }
  .flow li:not(:last-child)::after {
    inset-block-start: 16.5px;
    inset-inline-start: 44px;
    inline-size: calc(100% - 44px + 30px);
    block-size: 1px;
    background: linear-gradient(90deg, rgba(230, 180, 92, .45), rgba(230, 180, 92, .08));
  }
}

/* ── Los iconos de las tarjetas de texto ─────────────────────────────────── */
/*
  DIBUJADOS, NO GENERADOS, y contra las fotografías del sitio: línea dorada de
  un solo peso sobre negro, un núcleo encendido, geometría radial. Un difusor
  habría dado diecisiete ilustraciones parecidas entre sí y esto necesitaba
  diecisiete marcas IGUALES entre sí — mismo trazo, misma rejilla de 32, mismo
  halo—, que es una propiedad que se consigue con una mano y no con un modelo.

  El halo es un `drop-shadow` y no una segunda copia de cada trazo: una regla de
  CSS en vez de diecisiete rutas duplicadas, y el brillo sigue al color.

  Los atributos de dibujo van en el propio <svg> y NO aquí. Puestos en CSS, un
  `fill: none` ganaría a los `fill="currentColor"` de los círculos encendidos
  —el CSS pesa más que un atributo de presentación— y los núcleos se apagarían.
  Aquí sólo hay tamaño, color y halo.
*/

.ico { width: 34px; height: 34px; display: block; color: var(--glow);
       filter: drop-shadow(0 0 7px rgba(230, 180, 92, .32)); }
.mode .ico { width: 40px; height: 40px; }

/* ── Las dos clases de cuenta ────────────────────────────────────────────── */
/* Dos tarjetas del mismo tamaño, el mismo peso y la misma altura, y ninguna
   marcada como recomendada. Son dos opciones, no un plan y su versión gratis:
   destacar una con un borde de color sería elegir por quien está eligiendo. */

.modes { padding-block: var(--section); border-top: 1px solid var(--rule-soft); }
.modes .head { display: grid; gap: 14px; margin-bottom: clamp(30px, 4.5vw, 52px); max-width: 46em; }
.pair { display: grid; gap: clamp(20px, 3vw, 28px); grid-template-columns: 1fr; }
@media (min-width: 860px) { .pair { grid-template-columns: 1fr 1fr; } }

.mode {
  display: grid; gap: 16px; align-content: start;
  padding: clamp(26px, 3.5vw, 40px);
  border-radius: var(--r-window);
  background: linear-gradient(160deg, var(--raise), var(--panel) 62%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
/* El precio se pega al fondo de la tarjeta y el botón debajo, para que las dos
   cifras queden a la misma altura aunque una lista tenga una línea más. Un
   precio que baila entre las dos columnas se compara peor. */
.mode .price { margin-top: auto; padding-top: 6px; }
.mode .go { justify-self: start; }

.ticks { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.ticks li { position: relative; padding-inline-start: 24px; color: var(--muted); font-size: .9375rem; line-height: 1.5; }
.ticks li::before {
  content: ""; position: absolute; inset-inline-start: 2px; inset-block-start: .55em;
  width: 9px; height: 5px; border-inline-start: 1.5px solid var(--horizon);
  border-block-end: 1.5px solid var(--horizon); transform: rotate(-45deg);
}

/* ── La aritmética ───────────────────────────────────────────────────────── */
/* Un reparto explicado con palabras admite tres lecturas; con renglones y una
   cifra por renglón, una. Números tabulares y alineados a la derecha, que es
   como se lee una cuenta. */

.sums { padding-block: var(--section); border-top: 1px solid var(--rule-soft); }
.sums .head { display: grid; gap: 14px; margin-bottom: clamp(24px, 3.5vw, 40px); max-width: 46em; }
.sum {
  margin: 0 0 16px; padding: 0; list-style: none;
  display: grid; max-width: 30em;
}
.sum li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  padding: 13px 2px; border-top: 1px solid var(--rule-soft); color: var(--muted);
}
.sum li b { font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums; }
.sum li.minus b { color: var(--muted); }
.sum li.rule { border-top-color: var(--rule); }
.sum li.you { border-top-color: var(--rule); }
.sum li.you span, .sum li.you b { color: var(--text); }
.sum li.you b { font-size: 1.25rem; letter-spacing: -.02em; }
.sum li:last-child { border-bottom: 1px solid var(--rule-soft); }

/* ── Elegir clase de cuenta ──────────────────────────────────────────────── */
/* Dos botones grandes con lo que implica cada uno escrito dentro. Un desplegable
   habría cabido en menos sitio y habría escondido la única diferencia que
   importa, que es cuánto cuesta cada camino. */

.picks { display: grid; gap: 14px; grid-template-columns: 1fr; width: 100%; }
@media (min-width: 700px) { .picks { grid-template-columns: 1fr 1fr; max-width: 720px; } }
.pick {
  display: grid; gap: 7px; align-content: start; text-align: start;
  padding: 20px 22px;
  border-radius: var(--r-field);
  border: 1px solid var(--rule);
  background: rgba(255, 255, 255, .03);
  color: var(--text); font: inherit; cursor: pointer;
}
.pick:hover { border-color: rgba(255, 255, 255, .3); background: rgba(255, 255, 255, .05); }
.pick:focus-visible { outline: 2px solid var(--horizon); outline-offset: 2px; }
.pick:disabled { cursor: progress; opacity: .6; }
/* El que ya está elegido se marca, para que cambiar de clase de cuenta no
   parezca elegir por primera vez. */
.pick[aria-pressed="true"] { border-color: var(--horizon); }
.pick-name { font-size: 1.0625rem; font-weight: 600; letter-spacing: -.01em; }
.pick-what { font-size: .9375rem; color: var(--muted); line-height: 1.45; }
.pick-cost { font-size: .8125rem; color: var(--horizon); }

/* ── Los términos ────────────────────────────────────────────────────────── */
/* Una columna estrecha y cláusulas separadas por una línea. Un texto legal a
   ancho completo no se lee: se hojea, y hojear unos términos es no leerlos. */

.legal { padding-block: clamp(40px, 6vw, 72px) var(--section); max-width: 46em; }
.legal .head { display: grid; gap: 14px; margin-bottom: clamp(30px, 4.5vw, 48px); }
.clause { display: grid; gap: 10px; padding-block: clamp(22px, 3vw, 30px); border-top: 1px solid var(--rule-soft); }
.clause .body { max-width: none; }
.legal .note { margin-top: clamp(24px, 3.5vw, 36px); }

/* ── El pie ──────────────────────────────────────────────────────────────── */

.foot { border-top: 1px solid var(--rule-soft); padding-block: 40px 48px; }
.foot .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 20px 32px; }
.foot img { height: 40px; width: auto; opacity: .8; }
.footnav { display: flex; flex-wrap: wrap; gap: 12px 24px; margin-inline-start: auto; }
.footnav a { font-size: .875rem; color: var(--muted); }
.footnav a:hover { color: var(--text); }
@media (max-width: 700px) { .footnav { margin-inline-start: 0; } }

/* Una sola cosa se mueve sola en todo el sitio — la sala, desplazándose muy
   despacio detrás del titular — y quien pida que nada se mueva se queda mirando
   la misma sala, quieta. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero .back { animation: none; }
  .card .shot img { transition: none; }
  .spin { animation-duration: 3s; }
}
