/* ══════════════════════════════════════════════════════════════════════
   DEVIA · hoja de estilo única — reconstrucción guiada por skills
   ══════════════════════════════════════════════════════════════════════

   Design read (design-taste-frontend §0.B): rediseño-preserva de una
   landing de servicios para dueños de pyme, lenguaje editorial oscuro
   minimalista fijado por la marca, CSS nativo con animación ligada al
   scroll. Diales: VARIANCE 6 · MOTION 6 · DENSITY 3.

   Reglas de las skills que gobiernan esta hoja:

   · Un antetítulo como máximo por página (taste §4.7): el del héroe de
     portada, que es el descriptor de marca. Los títulos cargan solos.
   · Sin flip de tema a mitad de página (taste §4.11): el crema aparece
     solo como DOCUMENTO acotado sobre la mesa, nunca como banda.
   · Curvas y duraciones de las tablas de `animate`, no inventadas.
   · Una entrada firmada por familia de sección, no la misma en todas
     (impeccable/craft-floor). El momento focal es la cuenta de horas.
   · Nada se retira animándose al salir del viewport: pelear con el
     lector no es dinamismo (Emil). El scroll solo TRAE contenido.
   · Movimiento reducido = menos y más suave, no cero: el color y la
     opacidad siguen; el desplazamiento muere (Emil §accesibilidad).
   · Hover con transform solo bajo (hover:hover) and (pointer:fine).
   · Sombras con offset y desenfoque suave, casi invisibles
     (craft-floor + minimalist-ui).
   · Las superficies del navegador también son diseño: selección,
     caret, scrollbar y foco van tematizados (craft-floor).

   Invariantes de la casa que ninguna skill toca:
   · Nada que tenga que verse depende de que corra nada. El estado por
     defecto es visible; la animación vive dentro de keyframes bajo
     doble guarda (@supports + prefers-reduced-motion).
   · Cero peticiones a terceros. Grano y motivos son data-URI o
     gradientes.
   · El ritmo vertical se aplica en UN sitio (.seccion). Los offsets
     de composición se documentan como excepción donde ocurren.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Tipografías, servidas desde aquí ────────────────────────────────
   Cormorant Garamond la nombra el kit de marca (serif justificada por
   brief, taste §4.1); Jost es el cuerpo; DM Mono existe porque los
   numerales de Cormorant son proporcionales y no alinean columnas.   */

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../tipos/cormorant-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../tipos/cormorant-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../tipos/jost-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../tipos/jost-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../tipos/jost-500.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../tipos/dmmono-300.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../tipos/dmmono-400.woff2') format('woff2');
}

/* ── Fichas ─────────────────────────────────────────────────────────── */

:root {
  /* Paleta del kit. No se inventa ninguna. */
  --tinta: #0b0b0c;
  --crema: #f6f3ed;
  --nieve: #fffefb;
  --oro: #a8873f;
  --oro-claro: #c6a76b;
  --gris: #5a6273;

  /* Superficies, no marca: los tres escalones de oscuridad de la casa.
     El carril es tinta, la mesa es carbón, y el documento es el mismo
     carbón con un velo de oro al 12 %: un paso hacia la luz, cálido y
     de la familia. Medido: 1,22:1 contra la mesa, que con el filete
     dorado y la sombra basta para leerlo como objeto apoyado. */
  --carbon: #16151b;
  --tabaco: #2b2725;

  /* Movimiento: las curvas oficiales de la skill `animate`, tal cual.
     Regla dura de la skill: no inventar cubic-beziers de memoria. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-llegada: cubic-bezier(0.16, 1, 0.3, 1); /* impeccable: llegadas con aplomo */

  /* Duraciones por las tablas: feedback 160, UI corta 200,
     transición de vista 300-500, entrada focal 500-800. */
  --t-feedback: 160ms;
  --t-ui: 200ms;
  /* El morfo del puntero, de círculo a dos semicírculos y de vuelta.
     Algo más largo que un cambio de estado corriente porque aquí hay
     que leer una forma abriéndose, no un color cambiando; sigue dentro
     del tramo de 150-300 ms que marcan las tablas. */
  --t-morfo: 280ms;
  --t-vista: 420ms;
  --t-focal: 650ms;

  /* Espaciado. DENSITY 3: galería, no cabina. */
  --e1: 0.5rem;
  --e2: 1rem;
  --e3: 1.5rem;
  --e4: 2.5rem;
  --e5: 4rem;
  --e6: 6rem;
  --ritmo: clamp(5rem, 10vw, 9.5rem);

  --carril: 15rem;
  --ancho-texto: 56rem;
  --margen: clamp(1.5rem, 4vw, 4rem);

  --letra-titular: 'Cormorant Garamond', Garamond, Georgia, serif;
  --letra-texto: 'Jost', 'Helvetica Neue', Arial, sans-serif;
  --letra-cifra: 'DM Mono', ui-monospace, 'SF Mono', Consolas, monospace;

  /* Superficie oscura, la de por defecto. Alfas medidos con auditar.js:
     crema al 86 % da ~12:1 sobre carbón; al 58 %, ~6:1. El gris azul
     nunca es texto aquí: filetes y marcas apagadas. */
  --texto: rgb(246 243 237 / 0.86);
  --texto-suave: rgb(246 243 237 / 0.58);
  --acento: var(--oro-claro);
  --acento-texto: var(--oro-claro);
  --fondo: var(--carbon);
  --filete: rgb(198 167 107 / 0.3);
  --filete-tenue: rgb(214 197 170 / 0.14);
  --apagado: rgb(90 98 115 / 0.55);
}

/* La superficie del documento: no invierte el tema, lo eleva. Antes era
   una hoja crema y encendía la página entera cada vez que aparecía; el
   panel de tabaco pertenece a la mesa y deja que el oro siga siendo el
   único claro de la casa. Medidos sobre lo pintado: texto 10,3:1,
   texto suave 5,5:1, acento 6,5:1 — el oro ya no necesita oscurecerse
   para leerse, que es lo que obligaba la hoja clara. */
.panel {
  --texto: rgb(246 243 237 / 0.86);
  --texto-suave: rgb(246 243 237 / 0.58);
  --acento: var(--oro-claro);
  --acento-texto: var(--oro-claro);
  --fondo: var(--tabaco);
  --filete: rgb(198 167 107 / 0.34);
  --filete-tenue: rgb(246 243 237 / 0.12);
  --apagado: rgb(246 243 237 / 0.22);

  background: var(--fondo);
  color: var(--texto);
}

/* ── Reinicio corto ─────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Superficie del navegador nº 1: la barra de scroll, del color de
     la casa (craft-floor: lo que no dibujaste también es diseño). */
  scrollbar-color: rgb(90 98 115 / 0.5) var(--carbon);
}

body {
  margin: 0;
  background-color: var(--carbon);
  color: var(--texto);
  font-family: var(--letra-texto);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg {
  max-width: 100%;
  display: block;
}

/* Superficies del navegador nº 2 y 3: selección y caret. */
::selection {
  background: var(--oro);
  color: var(--tinta);
}

input {
  caret-color: var(--acento);
}

/* ── Atmósfera: la luz de cada página ───────────────────────────────
   Lavados radiales a ≤5 % (minimalist-ui los llama «soft radial light
   spots» y los pide así de bajos), distintos por página para que la
   transición de vista cruce la luz al navegar. Sin fotografía: esta
   web presume de no pedir nada a terceros.                           */

.pagina-inicio {
  background-image:
    radial-gradient(56rem 38rem at 82% -6%, rgb(198 167 107 / 0.05), transparent 62%),
    radial-gradient(48rem 34rem at -12% 42%, rgb(90 98 115 / 0.045), transparent 60%);
}

.pagina-servicios {
  background-image:
    radial-gradient(52rem 36rem at 86% -8%, rgb(90 98 115 / 0.055), transparent 62%),
    radial-gradient(44rem 30rem at -10% 70%, rgb(198 167 107 / 0.03), transparent 58%);
}

.pagina-precios {
  background-image:
    radial-gradient(54rem 36rem at 18% -8%, rgb(198 167 107 / 0.045), transparent 60%),
    radial-gradient(40rem 30rem at 105% 55%, rgb(90 98 115 / 0.04), transparent 58%);
}

.pagina-contacto {
  background-image:
    radial-gradient(50rem 34rem at 70% -10%, rgb(198 167 107 / 0.045), transparent 60%),
    radial-gradient(46rem 32rem at -8% 80%, rgb(198 167 107 / 0.028), transparent 55%);
}

.pagina-legal {
  background-image:
    radial-gradient(48rem 30rem at 75% -10%, rgb(90 98 115 / 0.04), transparent 60%);
}

/* El grano: feTurbulence en un velo fijo sin eventos (taste §6.E exige
   exactamente esto: capa fixed + pointer-events none, jamás sobre
   contenedores con scroll). Convierte el carbón en material. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* ── Tipografía ─────────────────────────────────────────────────────── */

h1,
h2,
h3 {
  font-family: var(--letra-titular);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: 0.005em;
  margin: 0;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.75rem, 6.2vw, 5.25rem);
  font-weight: 300;
}

h2 {
  font-size: clamp(2.1rem, 4vw, 3.4rem);
}

h3 {
  font-size: 1.5rem;
}

/* Aterrizaje de las anclas. Un titular con id es el destino de algún
   enlace, y sin este margen el navegador lo deja pegado al borde de
   arriba: se lee como si la página hubiera cargado mal. En móvil hay
   además un carril fijo de unos 72 px que se lo comería entero. */
h1[id],
h2[id],
h3[id] {
  scroll-margin-top: var(--e4);
}

p {
  margin: 0;
  text-wrap: pretty;
}

/* Etiqueta de documento: las versalitas espaciadas del kit, reservadas
   a dos usos: el descriptor de marca en el héroe de portada y el
   membrete de los documentos crema. NUNCA sobre títulos de sección
   (taste §4.7: el título carga solo; craft-floor las veta). */
.antetitulo {
  font-family: var(--letra-texto);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--acento-texto);
  margin: 0;
}

.entradilla {
  font-size: clamp(1.125rem, 1.7vw, 1.3125rem);
  font-weight: 300;
  line-height: 1.65;
  color: var(--texto);
  max-width: 34rem;
}

.suave {
  color: var(--texto-suave);
}

.cifra {
  font-family: var(--letra-cifra);
  font-weight: 300;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* El filete dorado: el trazo que separa DEV de IA en el logo. Único
   adorno de la casa. */
.filete {
  border: 0;
  height: 1px;
  background: var(--acento);
  width: 4.5rem;
  margin: 0;
}

.filete-ancho {
  border: 0;
  height: 1px;
  background: var(--filete-tenue);
  width: 100%;
  margin: 0;
}

a {
  color: inherit;
}

/* ── Foco: visible siempre, en oro sobre los dos fondos ─────────────── */

:where(a, button, input, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 3px;
  border-radius: 1px;
}

.salto-contenido {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--oro-claro);
  color: var(--tinta);
  padding: var(--e2) var(--e3);
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}

.salto-contenido:focus {
  left: 0;
}

/* ── El puntero de la casa ──────────────────────────────────────────
   Un punto y dos circunferencias finas, en oro. Sobre algo accionable
   el trazo engorda y la circunferencia exterior vibra. Es el hermano
   con ratón de la regla de foco de aquí arriba: la misma respuesta,
   por la otra vía de entrada.

   Procedencia y conflicto declarado: taste-skill veta los punteros
   personalizados por «anticuados, hostiles a la accesibilidad y caros»,
   y ui-ux-pro-max marca como severidad alta depender del hover. El
   encargo los pide expresamente y la propia taste-skill dice que el
   brief manda sobre sus valores por defecto. Así que se construye
   desmontando sus tres objeciones una por una:

   · Accesibilidad. Solo existe con puntero fino, nunca en táctil. El
     cursor nativo vuelve sobre los campos de texto, porque la barra de
     escritura es información. Desaparece entero en contraste forzado.
     No sustituye a ningún estado: el foco de teclado sigue igual, y
     todo lo accionable conserva además su propio hover de color.
   · Coste. Una capa fija que solo mueve transform, escrita una vez por
     frame. Cero lecturas de layout, cero listeners de scroll.
   · Anticuado. Aquí no es un juguete de portfolio: el punto y las dos
     circunferencias son el trazo del logo, y el oro es el de la marca.
     Medido sobre lo pintado: 8,5:1 sobre carbón y 6,4:1 sobre tabaco,
     muy por encima del 3:1 que pide la norma para un componente no
     textual.

   Sin JavaScript no hay clase .con-puntero: ni pieza ni cursor oculto,
   el del sistema intacto. Como todo el movimiento de esta casa.        */

.puntero {
  display: none;
}

/* `any-hover` y `any-pointer`, no `hover` y `pointer`: los segundos
   describen el dispositivo PRIMARIO, y un portátil con pantalla táctil
   puede declararse táctil aunque tenga un ratón enchufado. Con la
   consulta primaria el puntero no llegaba a aparecer nunca en esas
   máquinas. Los `any-` miran todos los dispositivos disponibles, que es
   justo la pregunta que hay que hacer aquí: ¿existe un ratón?

   Los demás bloques de hover de esta hoja sí usan la consulta primaria,
   y hacen bien: allí la pregunta es otra, la de evitar hovers pegados
   en pantallas táctiles. */
@media (any-hover: hover) and (any-pointer: fine) {
  /* El `!important` aquí es deliberado y es el único de la hoja.
     `cursor` se hereda, pero una declaración propia del elemento gana a
     lo heredado, y esta hoja pone `cursor: pointer` en cinco sitios
     (.boton, .tarea-nombre, la casilla, .paso-boton, .carril-boton),
     alguno con más peso que cualquier selector razonable que se ponga
     aquí. El resultado era el dedo del sistema asomando encima de cada
     botón mientras el puntero dorado intentaba hacer su trabajo.

     Sustituir el cursor del sistema es una decisión categórica y global,
     que es exactamente para lo que existe `!important`. El radio de
     acción está acotado: la clase .con-puntero solo existe cuando hay
     ratón de verdad y el guion ha construido la pieza. */
  html.con-puntero,
  html.con-puntero * {
    cursor: none !important;
  }

  /* La única excepción, y no es negociable: sin barra vertical nadie
     sabe que en ese hueco se puede teclear. Lleva `!important` porque
     tiene que ganarle a la regla de arriba, que ya lo lleva. */
  html.con-puntero input[type='number'],
  html.con-puntero input[type='text'],
  html.con-puntero input[type='email'],
  html.con-puntero textarea {
    cursor: auto !important;
  }

  html.con-puntero .puntero {
    display: block;
    position: fixed;
    left: 0;
    top: 0;
    /* Por encima del grano (90), que si no el puntero se ensucia. Por
       debajo del salto al contenido (100), que es lo único con más
       derecho a estar delante de todo. */
    z-index: 95;
    width: 40px;
    height: 40px;
    /* El centro de la pieza cae sobre la punta real del ratón. */
    margin: -20px 0 0 -20px;
    pointer-events: none;
    transition: opacity var(--t-ui) ease;
    will-change: transform;
  }

  /* Los dos estados van como hermanos, con el mismo peso de selector y
     el mismo prefijo. La versión anterior ponía `opacity: 0` en la regla
     de arriba y lo intentaba anular con `.puntero[data-visible="si"]`,
     que pesa menos: la pieza se creaba, se colocaba y se marcaba como
     visible, pero se quedaba transparente para siempre. Un puntero
     perfecto que no se veía. Con los dos estados al mismo nivel no hay
     pelea que perder. */
  html.con-puntero .puntero[data-visible='no'] {
    opacity: 0;
  }

  html.con-puntero .puntero[data-visible='si'] {
    opacity: 1;
  }

  /* Las dos transiciones van juntas en la MISMA declaración, y eso no es
     cosmética: `transition` es una abreviada, así que una regla más
     específica no la completa, la sustituye entera. Estuvieron separadas
     —el trazo aquí y el transform en `.puntero-arco`— y como este
     selector pesa más (una clase y un elemento contra una clase), se
     quedaba solo el trazo: el círculo saltaba a semicírculos en seco.
     Con ambas en el mismo sitio no hay nada que pisar. */
  .puntero circle,
  .puntero path {
    fill: none;
    stroke: var(--oro-claro);
    stroke-width: 1;
    transition:
      stroke-width var(--t-feedback) var(--ease-out),
      transform var(--t-morfo) var(--ease-out);
  }

  /* La circunferencia exterior son dos arcos que en reposo se tocan por
     sus extremos y se leen como un círculo. El grupo es lo que escala en
     el estado de acción; los arcos por separado son lo que se abre en el
     estado de texto. Cada transformación en su capa, sin pisarse. */
  .puntero-fuera,
  .puntero-arco {
    transform-box: view-box;
    transform-origin: 20px 20px;
  }

  /* Ojo con el peso del selector: la regla de arriba es «.puntero circle»,
     una clase y un elemento, y le gana a «.puntero-punto» a secas. Con
     ese empate perdido el punto salía sin relleno, es decir, como un
     anillo diminuto en vez de un punto. Dos clases lo resuelven. */
  .puntero .puntero-punto {
    fill: var(--oro-claro);
    stroke: none;
  }

  /* Sobre algo accionable: el trazo engorda. Es transición y no
     keyframes a propósito, porque entrar y salir de un botón es de lo
     que más rápido se dispara en una web y una transición retoma desde
     donde está en vez de reiniciar. */
  .puntero[data-modo='accion'] circle,
  .puntero[data-modo='accion'] path {
    stroke-width: 2;
  }

  /* ── Sobre un texto: la exterior se abre en dos semicírculos ────────
     Cada mitad viaja hacia dentro exactamente su propio radio, así que
     las dos cúspides acaban en el centro del puntero y los semicírculos
     quedan lindando ahí, uno contra otro. El resultado abraza al círculo
     interior, que no se mueve: es la única pieza que se queda quieta en
     los tres estados, y por eso el conjunto no se desarma. */
  .puntero[data-modo='texto'] .puntero-arco-izq {
    transform: translateX(15.5px);
  }

  .puntero[data-modo='texto'] .puntero-arco-der {
    transform: translateX(-15.5px);
  }
}

/* Y sobre algo accionable, la circunferencia exterior converge: aparece
   fuera, se acerca al círculo interior hasta fundirse con él, y vuelve a
   empezar. Es un latido hacia dentro, y dice lo que tiene que decir sin
   gritar: aquí hay algo, y ese algo está en el centro, donde apuntas.

   Antes hubo una vibración de un píxel. Se cambió porque decía menos:
   temblar es una alarma, converger es señalar. La escala final es 0,42,
   que no es un número bonito sino el cociente exacto entre los dos
   radios (6,5 / 15,5): la exterior se funde con la interior, no cerca.

   El ciclo dura 800 ms. Empezó en 1,3 s y se acortó porque a ese ritmo
   el latido se leía como calma y aquí lo que se quiere transmitir es que
   hay algo esperando: a 800 ms el pulso insiste sin llegar a parpadear.
   Las tablas de `animate` piden menos de 300 ms, pero esas son para
   transiciones de estado; esto es un latido continuo, y a 300 ms el
   recorrido de fuera adentro no daría tiempo ni a verse. Va en bucle,
   que es lo que ui-ux-pro-max desaconseja como decoración; se acepta por
   lo mismo que antes: no es ambiente, es un estado pasajero atado a la
   intención del visitante, que empieza al posarse sobre un botón y muere
   al apartarse. */
@media (any-hover: hover) and (any-pointer: fine) and (prefers-reduced-motion: no-preference) {
  .puntero[data-modo='accion'] .puntero-fuera {
    animation: puntero-converger 800ms linear infinite;
  }
}

@keyframes puntero-converger {
  /* Nace fuera y transparente, y se enciende enseguida. */
  0% {
    transform: scale(1);
    opacity: 0;
  }
  10% {
    transform: scale(0.96);
    opacity: 1;
  }
  /* Viaja hacia dentro hasta el radio de la interior. */
  74% {
    transform: scale(0.42);
    opacity: 1;
  }
  /* Se funde con ella: al llegar, se apaga sin moverse. */
  88% {
    transform: scale(0.42);
    opacity: 0;
  }
  /* Y vuelve a su sitio ya invisible, para no verse el salto de vuelta. */
  100% {
    transform: scale(1);
    opacity: 0;
  }
}

/* En contraste forzado manda el sistema: su cursor y sus colores.
   El `!important` no es de adorno: la regla que oculta el cursor lo
   lleva, y sin él aquí este bloque perdía y el visitante se quedaba en
   alto contraste sin ningún puntero. */
@media (forced-colors: active) {
  html.con-puntero,
  html.con-puntero * {
    cursor: auto !important;
  }

  html.con-puntero .puntero {
    display: none;
  }
}

/* ── Maqueta: el margen carga peso ──────────────────────────────────── */

.lienzo {
  display: grid;
  grid-template-columns: var(--carril) minmax(0, 1fr);
  min-height: 100vh;
}

.carril {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: var(--e4);
  padding: var(--e4) var(--e3);
  border-right: 1px solid var(--filete-tenue);
  /* Tinta pura: el carril es marca y su escalón de oscuridad da
     profundidad a la mesa de carbón. */
  background: var(--tinta);
  z-index: 20;
  /* En las transiciones de página, el carril es lo que no se mueve. */
  view-transition-name: carril;
}

.carril-marca {
  display: block;
  text-decoration: none;
}

.carril-marca svg {
  width: 100%;
  height: auto;
}

/* El logo va incrustado: un SVG externo no ve el @font-face y saldría
   en Georgia. Medidas del kit, sin tocar. La portada usa el mismo
   lockup, así que comparte letra. */
.carril-marca text,
.portada text {
  font-family: var(--letra-titular);
  font-weight: 400;
  font-size: 118px;
  letter-spacing: 11.8px;
}

.marca-dev {
  fill: var(--crema);
}

.marca-ia {
  fill: var(--oro-claro);
}

.carril-nav {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  margin-top: auto;
}

.carril-enlace {
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--texto-suave);
  text-decoration: none;
  transition: color var(--t-ui) ease;
}

.carril-enlace:hover,
.carril-enlace[aria-current='page'] {
  color: var(--oro-claro);
}

.carril-pie {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  padding-top: var(--e3);
  border-top: 1px solid var(--filete-tenue);
  font-size: 0.75rem;
  color: var(--texto-suave);
}

.carril-pie a {
  text-decoration: none;
  color: inherit;
  transition: color var(--t-ui) ease;
}

.carril-pie a:hover {
  color: var(--oro-claro);
}

.carril-boton {
  display: none;
}

/* ── Secciones: el único sitio con ritmo vertical ───────────────────── */

.seccion {
  padding: var(--ritmo) var(--margen);
}

.seccion-compacta {
  padding-block: calc(var(--ritmo) * 0.55);
}

.envoltura {
  max-width: var(--ancho-texto);
  display: flex;
  flex-direction: column;
  gap: var(--e4);
}

.cabecera-seccion {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  max-width: 40ch;
}

/* ── Botones ────────────────────────────────────────────────────────
   Minimalist-ui: sólido, sin sombra, radio 0 (Shape Lock: todo
   afilado). El color transiciona siempre; el transform solo con
   puntero fino y sin movimiento reducido (Emil).                     */

.boton {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.95rem 1.6rem;
  background: var(--oro-claro);
  color: var(--tinta);
  font-family: var(--letra-texto);
  font-size: 0.78125rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--oro-claro);
  cursor: pointer;
  transition:
    background var(--t-ui) ease,
    color var(--t-ui) ease;
}

@media (hover: hover) and (pointer: fine) {
  .boton:hover {
    background: transparent;
    color: var(--oro-claro);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .boton {
    transition:
      background var(--t-ui) ease,
      color var(--t-ui) ease,
      transform var(--t-feedback) var(--ease-out);
  }

  /* Feedback de pulsación (Emil: scale 0.95-0.98, 100-160 ms). */
  .boton:active {
    transform: scale(0.97);
  }
}

.boton-linea {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.78125rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--acento-texto);
  text-decoration: none;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--filete);
  transition: border-color var(--t-ui) ease;
  align-self: flex-start;
}

.boton-linea:hover {
  border-bottom-color: var(--acento);
}

/* ── Héroe: partido asimétrico ──────────────────────────────────────
   taste §10: Asymmetric Split Hero. El texto a la izquierda; el
   documento vivo (la cuenta de horas, que es una vista previa REAL
   del producto, el único tipo de «captura» que la skill permite) a la
   derecha. En páginas sin documento, el vacío a la derecha es
   composición, no descuido (VARIANCE 6).                             */

.heroe {
  padding: clamp(2.5rem, 5vw, 4.5rem) var(--margen) var(--ritmo);
  display: flex;
  flex-direction: column;
  gap: var(--e5);
}

.heroe-texto {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  max-width: 42rem;
}

.heroe-texto .entradilla {
  max-width: 34rem;
}

.heroe h1 {
  max-width: 33rem;
}

/* El corte del partido sale de la aritmética, no del catálogo de
   breakpoints: carril (15rem) + márgenes + documento (44rem) + hueco
   dejan columna de texto digna (~30rem) solo a partir de ~100rem. Por
   debajo, apilado, que a esos anchos es la composición correcta. */
@media (min-width: 100rem) {
  .heroe {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 44rem);
    gap: var(--e5);
    align-items: center;
  }

  .heroe-texto {
    padding-block: var(--e5);
  }

  .heroe h1 {
    font-size: clamp(2.75rem, 3.5vw, 4.5rem);
  }
}

/* ══ LA CUENTA DE HORAS ══════════════════════════════════════════════
   El momento focal de toda la web (impeccable: una secuencia con
   autoría, nacida de este producto). Una semana de cuarenta horas
   dibujada con el trazo del logo; el visitante enciende las suyas.
   Las horas las pone él: la página no afirma ahorros que no puede
   demostrar.                                                          */

.cuenta {
  max-width: 46rem;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  display: flex;
  flex-direction: column;
  gap: var(--e4);
  /* Sobre fondo oscuro el objeto ya no lo recorta la sombra sino el
     filo: hairline dorado arriba, que es donde daría la luz, y un
     borde apenas insinuado en el resto. La sombra se queda para
     asentarlo (craft-floor pide offset+blur, minimalist-ui opacidad
     mínima): el documento se apoya, no flota. */
  border: 1px solid rgb(198 167 107 / 0.16);
  border-top-color: rgb(198 167 107 / 0.34);
  box-shadow:
    0 20px 44px -28px rgb(0 0 0 / 0.55),
    0 2px 10px -6px rgb(0 0 0 / 0.35);
}

/* Los documentos de sección (método, facturación, contacto) comparten
   material con la cuenta: panel acotado sobre la mesa, jamás banda a
   todo lo ancho (taste §4.11: la página tiene UN tema). */
.documento {
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  display: flex;
  flex-direction: column;
  gap: var(--e4);
  border: 1px solid rgb(198 167 107 / 0.16);
  border-top-color: rgb(198 167 107 / 0.34);
  box-shadow:
    0 20px 44px -28px rgb(0 0 0 / 0.55),
    0 2px 10px -6px rgb(0 0 0 / 0.35);
}

.cuenta-cabecera {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: baseline;
  justify-content: space-between;
}

/* La semana: 5 grupos de 8 trazos. Cada trazo, una hora. */
.semana {
  display: flex;
  gap: clamp(0.75rem, 2.5vw, 1.5rem);
}

.dia {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  flex: 1;
  min-width: 0;
}

.dia-horas {
  display: flex;
  gap: clamp(0.25rem, 0.9vw, 0.5rem);
  height: clamp(3rem, 7vw, 4.25rem);
}

.hora {
  flex: 1;
  min-width: 2px;
  background: var(--apagado);
  transition: background 0.35s ease;
  transform-origin: bottom;
}

.hora[data-gastada='si'] {
  background: var(--acento);
}

.dia-letra {
  font-family: var(--letra-cifra);
  font-size: 0.6875rem;
  font-weight: 300;
  letter-spacing: 0.1em;
  color: var(--texto-suave);
  text-align: center;
}

.tareas {
  display: flex;
  flex-direction: column;
}

.tarea {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--e2);
  padding: 0.875rem 0;
  border-bottom: 1px solid var(--filete-tenue);
}

.tarea:first-child {
  border-top: 1px solid var(--filete-tenue);
}

.tarea-nombre {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  cursor: pointer;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--texto-suave);
  transition: color var(--t-ui) ease;
}

.tarea-nombre:hover {
  color: var(--texto);
}

.tarea input[type='checkbox'] {
  appearance: none;
  flex: none;
  width: 1.0625rem;
  height: 1.0625rem;
  margin: 0;
  border: 1px solid var(--apagado);
  background: transparent;
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: border-color var(--t-ui) ease;
}

/* El punto que confirma la marca: feedback de estado, se conserva
   también bajo movimiento reducido (Emil: el feedback que aporta
   comprensión se queda). */
.tarea input[type='checkbox']::after {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  background: var(--acento);
  transform: scale(0);
  transition: transform 150ms var(--ease-out);
}

.tarea input[type='checkbox']:checked {
  border-color: var(--acento);
}

.tarea input[type='checkbox']:checked::after {
  transform: scale(1);
}

.tarea:has(input:checked) .tarea-nombre {
  color: var(--texto);
}

.paso {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  opacity: 0.35;
  transition: opacity var(--t-ui) ease;
}

.tarea:has(input:checked) .paso {
  opacity: 1;
}

.paso-boton {
  width: 1.75rem;
  height: 1.75rem;
  display: grid;
  place-content: center;
  border: 1px solid var(--filete-tenue);
  background: transparent;
  color: var(--texto-suave);
  font-family: var(--letra-cifra);
  font-size: 0.875rem;
  line-height: 1;
  cursor: pointer;
  transition:
    border-color var(--t-ui) ease,
    color var(--t-ui) ease;
}

@media (hover: hover) and (pointer: fine) {
  .paso-boton:hover:not(:disabled) {
    border-color: var(--acento);
    color: var(--acento-texto);
  }
}

.paso-boton:disabled {
  opacity: 0.3;
  cursor: default;
}

.paso input[type='number'] {
  width: 3.25rem;
  padding: 0.3rem 0;
  border: 0;
  background: transparent;
  color: var(--texto);
  font-family: var(--letra-cifra);
  font-size: 0.9375rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  text-align: center;
  -moz-appearance: textfield;
}

.paso input[type='number']::-webkit-outer-spin-button,
.paso input[type='number']::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

.paso-unidad {
  font-family: var(--letra-cifra);
  font-size: 0.8125rem;
  color: var(--texto-suave);
}

.cuenta-total {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--e3);
}

.total-cifras {
  display: flex;
  align-items: baseline;
  gap: var(--e3);
}

.total-dato {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.total-numero {
  font-family: var(--letra-cifra);
  font-size: clamp(2rem, 4.5vw, 2.75rem);
  font-weight: 300;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--texto);
}

.total-numero small {
  font-size: 0.4em;
  color: var(--texto-suave);
  margin-left: 0.15em;
}

.total-etiqueta {
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--texto-suave);
}

.cuenta-nota {
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--texto-suave);
  max-width: 52ch;
}

/* ── Servicios: bento asimétrico ────────────────────────────────────
   taste §4.7: celda-por-contenido exacta, ritmo y diversidad de
   fondos. Celdas desiguales: la destacada lleva el material del panel
   (el documento se cuela en la rejilla), una el motivo de horas de la
   casa, el resto en carbón. Nada de tarjetas gemelas.                */

.rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--filete-tenue);
  border: 1px solid var(--filete-tenue);
}

@media (min-width: 60rem) {
  .rejilla {
    grid-template-columns: 1.2fr 1fr;
    grid-template-areas:
      'ia ulises'
      'ia medida'
      'web web';
  }

  .celda-ia {
    grid-area: ia;
  }

  .celda-ulises {
    grid-area: ulises;
  }

  .celda-medida {
    grid-area: medida;
  }

  .celda-web {
    grid-area: web;
  }
}

.servicio {
  background: var(--carbon);
  padding: var(--e4) var(--e3);
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  transition: background var(--t-ui) ease;
}

/* La celda destacada lleva el material del documento: el panel entra en
   la rejilla y rompe la monotonía (Bento Background Diversity) sin
   encender un rectángulo claro en mitad de la mesa. */
.servicio-destacado {
  background: var(--tabaco);
  --texto: rgb(246 243 237 / 0.86);
  --texto-suave: rgb(246 243 237 / 0.58);
  --acento: var(--oro-claro);
  --acento-texto: var(--oro-claro);
  color: var(--texto);
  justify-content: flex-end;
  padding: var(--e4) var(--e3);
}

.servicio-destacado h3 {
  font-size: clamp(1.75rem, 2.6vw, 2.4rem);
}

/* La celda ancha lleva el motivo de la casa: los trazos de hora,
   tenues, como marca de agua propia (patrón, no decoración ajena). */
.servicio-motivo {
  background-image: repeating-linear-gradient(
    90deg,
    rgb(198 167 107 / 0.06) 0 2px,
    transparent 2px 26px
  );
}

@media (hover: hover) and (pointer: fine) {
  .servicio:not(.servicio-destacado):hover {
    background-color: #1c1b22;
  }
}

.servicio h3 {
  color: var(--texto);
}

.servicio p {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--texto-suave);
  max-width: 52ch;
}

/* Un enlace dentro de una tarjeta: sin esto heredaría el color del
   párrafo y sería indistinguible del texto, es decir, invisible como
   enlace. Mismo tratamiento que en la prosa de las páginas legales:
   oro y filete debajo, que es como enlaza esta casa. */
.servicio p a {
  color: var(--acento-texto);
  text-decoration: none;
  border-bottom: 1px solid var(--filete);
  transition: border-color var(--t-ui) ease;
}

.servicio p a:hover {
  border-bottom-color: var(--acento);
}

/* El selector lleva `.servicio` delante a propósito: sin él, la regla
   genérica `.servicio p` es más específica y se come el oro, que es
   justo el dato que la celda tiene que destacar. */
.servicio .servicio-desde {
  margin-top: auto;
  padding-top: var(--e2);
  font-family: var(--letra-cifra);
  font-size: 0.8125rem;
  color: var(--acento-texto);
  font-variant-numeric: tabular-nums;
}

.servicio-destacado .servicio-desde {
  margin-top: var(--e2);
}

/* La celda de Ulises lleva el motivo de trazos, y sobre él la línea de
   precio necesita separarse del patrón para no confundirse con él. */
.celda-ulises .servicio-desde {
  border-top: 1px solid var(--filete-tenue);
}

/* ── Método: el eje del tiempo ──────────────────────────────────────
   Vive dentro de un documento crema. La única secuencia real de la
   web se numera con su duración, y una línea de tiempo se dibuja al
   ritmo del scroll: aquí el scroll ES el significado (impeccable:
   scroll-driven solo cuando la relación con el scroll aporta).       */

.metodo {
  position: relative;
  display: flex;
  flex-direction: column;
  padding-left: var(--e3);
}

.metodo::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 2px;
  background: var(--filete);
  transform-origin: top;
}

/* Cuando el método viaja dentro de un documento, el eje se separa del
   borde del panel y las fases pegan sus hairlines sin el gap del
   contenedor. */
.metodo.documento {
  gap: 0;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  padding-left: calc(clamp(1.75rem, 3.5vw, 2.75rem) + 1.25rem);
}

.metodo.documento::before {
  left: clamp(1.75rem, 3.5vw, 2.75rem);
  top: clamp(1.75rem, 3.5vw, 2.75rem);
  bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}

.fase {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr);
  gap: var(--e3);
  padding: var(--e3) 0;
  border-top: 1px solid var(--filete-tenue);
  align-items: start;
}

.fase:first-child {
  border-top: 0;
}

.fase-plazo {
  font-family: var(--letra-cifra);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--acento-texto);
  padding-top: 0.35rem;
}

.fase-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.fase h3 {
  font-size: 1.375rem;
}

.fase p {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--texto-suave);
  max-width: 52ch;
}

/* ── Tarifas ────────────────────────────────────────────────────────── */

.tarifa {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--e3);
  align-items: baseline;
  padding: var(--e3) 0;
  border-top: 1px solid var(--filete-tenue);
}

.tarifa:first-child {
  border-top: 0;
}

.tarifa-nombre {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.tarifa-nombre strong {
  font-family: var(--letra-titular);
  font-size: 1.4375rem;
  font-weight: 400;
  letter-spacing: 0.01em;
}

.tarifa-nombre span {
  font-size: 0.875rem;
  color: var(--texto-suave);
  line-height: 1.6;
}

.tarifa-precio {
  font-family: var(--letra-cifra);
  font-size: 1.125rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--acento-texto);
  white-space: nowrap;
}

/* Los datos de contacto son enlaces vivos dentro de la columna de
   precio. Dos cuidados: el subrayado de fábrica se cambia por el filete
   de la casa, y se levanta el `nowrap` heredado, porque un correo largo
   en una celda que no parte desborda la tarjeta en móvil. */
.tarifa-precio a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--filete);
  transition: border-color var(--t-ui) ease;
  white-space: normal;
  overflow-wrap: anywhere;
}

.tarifa-precio a:hover {
  border-bottom-color: var(--acento);
}

.tarifa-precio small {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--texto-suave);
  text-align: right;
  margin-bottom: 0.2rem;
}

/* La cuota anual va DEBAJO del precio, no encima como el «Desde»: son
   dos cifras del mismo trato, y el orden de lectura es el orden en que
   se pagan. En minúscula y sin espaciar, para que no compita con el
   precio ni se lea como otra etiqueta. */
.tarifa-precio .tarifa-cuota {
  margin-bottom: 0;
  margin-top: 0.25rem;
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
  text-transform: none;
}

/* ── Garantías: aire y desnivel ─────────────────────────────────────
   Familia distinta de la rejilla: sin cajas, hairline dorado arriba y
   columnas desiguales con la segunda descolgada (VARIANCE 6: offset).
   El margen de composición de nth-child(even) es la excepción
   documentada a la regla de ritmo.                                   */

.garantias {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--e4) var(--e5);
}

@media (min-width: 60rem) {
  .garantias {
    grid-template-columns: 1.15fr 1fr;
  }

  .garantia:nth-child(even) {
    margin-top: var(--e4);
  }
}

.garantia {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-top: var(--e2);
  border-top: 1px solid var(--filete);
  transition: border-top-color var(--t-ui) ease;
}

@media (hover: hover) and (pointer: fine) {
  .garantia:hover {
    border-top-color: var(--acento);
  }
}

.garantia h3 {
  font-size: 1.375rem;
}

.garantia p {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--texto-suave);
}

/* ── Listas de detalle ──────────────────────────────────────────────── */

.lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.lista li {
  position: relative;
  padding-left: 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--texto-suave);
}

.lista li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 0.6rem;
  height: 1px;
  background: var(--acento);
}

.lista-no li::before {
  background: var(--apagado);
}

/* ── Pie ────────────────────────────────────────────────────────────── */

.pie {
  padding: var(--e5) var(--margen) var(--e4);
  border-top: 1px solid var(--filete-tenue);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e4);
  justify-content: space-between;
  align-items: flex-end;
  font-size: 0.8125rem;
  color: var(--texto-suave);
}

.pie-enlaces {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e3);
}

.pie a {
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition:
    border-color var(--t-ui) ease,
    color var(--t-ui) ease;
}

.pie a:hover {
  color: var(--oro-claro);
  border-bottom-color: var(--filete);
}

/* Marcador de dato pendiente: chilla a propósito. */
.pendiente {
  background: #ffe5e5;
  color: #8b0000;
  font-family: var(--letra-cifra);
  font-size: 0.85em;
  padding: 0.1em 0.4em;
  font-weight: 400;
}

/* ── Contenido largo (legales): modo Lectura, sin coreografía ───────── */

.prosa {
  max-width: 42rem;
  display: flex;
  flex-direction: column;
  gap: var(--e3);
}

.prosa h2 {
  font-size: 1.75rem;
  margin-top: var(--e3);
}

.prosa p,
.prosa li {
  font-size: 0.9375rem;
  line-height: 1.75;
  color: var(--texto-suave);
}

.prosa ul {
  margin: 0;
  padding-left: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.prosa a {
  color: var(--acento-texto);
  text-decoration: none;
  border-bottom: 1px solid var(--filete);
}

.prosa dl {
  margin: 0;
  display: grid;
  grid-template-columns: 11rem minmax(0, 1fr);
  gap: 0.65rem var(--e3);
  font-size: 0.9375rem;
}

.prosa dt {
  font-family: var(--letra-cifra);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--acento-texto);
  padding-top: 0.25rem;
}

.prosa dd {
  margin: 0;
  color: var(--texto-suave);
}

/* ── Móvil ──────────────────────────────────────────────────────────── */

@media (max-width: 60rem) {
  .lienzo {
    grid-template-columns: minmax(0, 1fr);
  }

  .carril {
    position: sticky;
    top: 0;
    height: auto;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--e2);
    padding: var(--e2) var(--margen);
    border-right: 0;
    border-bottom: 1px solid var(--filete-tenue);
  }

  .carril-marca {
    width: 7.5rem;
  }

  /* El carril pasa a barra fija arriba, así que el destino de un ancla
     tiene que caer por debajo de ella y no detrás. */
  h1[id],
  h2[id],
  h3[id] {
    scroll-margin-top: calc(4.5rem + var(--e3));
  }

  .carril-boton {
    display: grid;
    place-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid var(--filete-tenue);
    background: transparent;
    color: var(--texto);
    cursor: pointer;
  }

  .carril-nav {
    display: none;
    flex-basis: 100%;
    margin-top: 0;
    padding-top: var(--e2);
    border-top: 1px solid var(--filete-tenue);
    gap: var(--e2);
  }

  .carril[data-abierto='si'] .carril-nav {
    display: flex;
  }

  .carril-pie {
    display: none;
  }

  .carril[data-abierto='si'] .carril-pie {
    display: flex;
    flex-basis: 100%;
  }

  .fase {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }

  .fase-plazo {
    padding-top: 0;
  }

  .metodo {
    padding-left: var(--e2);
  }

  .metodo.documento {
    padding: var(--e3);
    padding-left: calc(var(--e3) + 1rem);
  }

  .metodo.documento::before {
    left: var(--e3);
    top: var(--e3);
    bottom: var(--e3);
  }

  .prosa dl {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.2rem;
  }

  .prosa dd {
    margin-bottom: var(--e2);
  }

  .cuenta-total {
    flex-direction: column;
    align-items: stretch;
  }

  .cuenta-total .boton {
    justify-content: center;
  }

  .tarea {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }

  .paso {
    justify-content: flex-end;
  }
}

@media (max-width: 30rem) {
  .semana {
    gap: 0.5rem;
  }

  .dia-horas {
    gap: 0.1875rem;
  }

  .total-cifras {
    gap: var(--e2);
  }
}

/* ══════════════════════════════════════════════════════════════════
   MOVIMIENTO
   ══════════════════════════════════════════════════════════════════

   La tesis (impeccable exige escribirla): el producto vende tiempo
   recuperado, así que el movimiento de la casa es EL TIEMPO. El
   momento focal es la cuenta de horas encendiéndose; el eje del
   método se dibuja al ritmo del scroll; el resto del contenido llega
   con un gesto corto y propio de su familia, y NADA se anima al salir
   del viewport: pelear con el lector no es dinamismo.

   Historia que hay que conocer: hubo IntersectionObserver y escondía
   contenido; hubo salidas hacia los lados y ensuciaban la lectura.
   Aquí el estado oculto vive solo DENTRO de keyframes bajo doble
   guarda. Sin soporte o con movimiento reducido: página completa,
   visible y quieta. No añadir fallbacks con observers.               */

/* ── 1 · Transiciones entre páginas (continuidad, CSS puro) ────────── */

@view-transition {
  navigation: auto;
}

/* Asimetría deliberada: la que sale solo se apaga, rápida; la que
   entra sube por encima, más lenta (impeccable: exit más rápido que
   entrance; Emil: una sola capa en movimiento). */
::view-transition-old(root) {
  animation: vt-salir 240ms var(--ease-out) both;
}

::view-transition-new(root) {
  animation: vt-entrar var(--t-vista) var(--ease-llegada) both;
}

@keyframes vt-salir {
  to {
    opacity: 0;
  }
}

@keyframes vt-entrar {
  from {
    opacity: 0;
    transform: translateY(0.55rem);
  }
}

/* ── 2 · La portada (solo Inicio, una vez por visita) ───────────────
   La cubierta de tinta del libro de cuentas: el filete se traza, DEV
   e IA acuden desde los lados a ocupar su sitio junto al eje, y la
   cubierta se abre hacia arriba descubriendo la mesa. Sin contador de
   porcentaje: aquí no hay carga que medir y esta web no enseña cifras
   que no son.

   Existe solo si el script de cabecera puso .con-portada (sin JS no
   hay cubierta que retirar), bajo la doble guarda de siempre. El
   héroe espera a que la cubierta pase: la espera se publica en
   --espera-heroe y también la lee horas.js para el encendido.

   Compás: filete 120-640 ms · DEV 260-910 · IA 340-990 · apertura
   1260-1880. El héroe arranca en 1700, cuando la cubierta ya ha
   despejado el tercio superior.                                      */

.portada {
  display: none;
}

@supports (transform-box: fill-box) {
  @media (prefers-reduced-motion: no-preference) {
    html.con-portada {
      --espera-heroe: 1700ms;
    }

    html.con-portada .portada {
      display: grid;
      place-items: center;
      position: fixed;
      inset: 0;
      /* Bajo el grano (90): la cubierta también es material. */
      z-index: 80;
      background: var(--tinta);
      animation: portada-abrirse 620ms var(--ease-in-out) 1260ms both;
    }

    html.con-portada .portada svg {
      width: min(64vw, 26rem);
      height: auto;
    }

    /* Los px de un transform CSS dentro de SVG son unidades del
       viewBox (900 de ancho): 30 equivalen a ~14 px pintados. */
    html.con-portada .portada .marca-dev {
      animation: portada-acudir-izquierda var(--t-focal) var(--ease-llegada) 260ms backwards;
    }

    html.con-portada .portada .marca-ia {
      animation: portada-acudir-derecha var(--t-focal) var(--ease-llegada) 340ms backwards;
    }

    html.con-portada .portada rect {
      transform-box: fill-box;
      transform-origin: center;
      animation: portada-trazarse 520ms var(--ease-in-out) 120ms backwards;
    }
  }
}

@keyframes portada-trazarse {
  from {
    transform: scaleY(0);
  }
}

@keyframes portada-acudir-izquierda {
  from {
    opacity: 0;
    transform: translateX(-30px);
  }
}

@keyframes portada-acudir-derecha {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
}

@keyframes portada-abrirse {
  to {
    transform: translateY(-100%);
    visibility: hidden;
  }
}

/* ── 3 · La entrada del héroe (el momento focal, 500-800 ms) ────────
   Solo en llegadas directas: cuando la página entra por transición de
   vista, pagereveal marca <html class="llega-con-transicion"> y la
   entrada se salta para que el fundido aterrice sobre página completa.
   Si hay portada, todo el compás se desplaza --espera-heroe. */

@media (prefers-reduced-motion: no-preference) {
  html:not(.llega-con-transicion) .heroe .antetitulo {
    animation: alzar var(--t-focal) var(--ease-llegada) var(--espera-heroe, 0ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe h1 {
    animation: alzar var(--t-focal) var(--ease-llegada) calc(var(--espera-heroe, 0ms) + 90ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .filete {
    transform-origin: left;
    animation: trazar var(--t-focal) var(--ease-in-out) calc(var(--espera-heroe, 0ms) + 200ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .entradilla {
    animation: alzar var(--t-focal) var(--ease-llegada) calc(var(--espera-heroe, 0ms) + 280ms) backwards;
  }

  html:not(.llega-con-transicion) .heroe .panel {
    animation: aterrizar 700ms var(--ease-llegada) calc(var(--espera-heroe, 0ms) + 360ms) backwards;
  }
}

@keyframes alzar {
  from {
    opacity: 0;
    transform: translateY(0.8rem);
  }
}

@keyframes trazar {
  from {
    transform: scaleX(0);
  }
}

@keyframes aterrizar {
  from {
    opacity: 0;
    transform: translateY(1.4rem) scale(0.97);
  }
}

/* ── 4 · El scroll trae contenido (un verbo por familia) ───────────── */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Los elementos esperan desplazados; sin esta guarda ensancharían
       la página. clip, no hidden: no crea contenedor de scroll. */
    main {
      overflow-x: clip;
    }

    /* Cabeceras y documentos: suben y asientan. Gesto corto que
       completa pronto (entry 0-45 %) para no hacer esperar. */
    .seccion .cabecera-seccion,
    .seccion .envoltura > .documento,
    .seccion .envoltura > .boton {
      animation: surgir linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 45%;
    }

    /* La rejilla de servicios: espejo. La columna izquierda llega de
       la izquierda, la derecha de la derecha, cogiendo cuerpo. */
    .servicio:nth-child(odd) {
      animation: llegar-izquierda linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }

    .servicio:nth-child(even) {
      animation: llegar-derecha linear both;
      animation-timeline: view();
      animation-range: entry 8% entry 68%;
    }

    /* Las fases: entran siguiendo el eje, con compás escalonado. */
    .fase {
      animation: llegar-izquierda linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }

    .fase:nth-child(2) {
      animation-range: entry 8% entry 63%;
    }

    .fase:nth-child(3) {
      animation-range: entry 16% entry 71%;
    }

    .fase:nth-child(4) {
      animation-range: entry 24% entry 79%;
    }

    /* Y la línea de tiempo se dibuja al ritmo del lector: el único
       sitio donde el scroll ES el significado. */
    .metodo::before {
      animation: dibujar-eje linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 55%;
    }

    /* Garantías: aparecen quietas, son promesas y no espectáculo. */
    .garantia {
      animation: surgir linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 50%;
    }

    .garantia:nth-child(even) {
      animation-range: entry 10% entry 60%;
    }

    /* Filetes anchos: se trazan de izquierda a derecha. */
    .seccion .filete-ancho {
      transform-origin: left;
      animation: trazar linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }

    /* El héroe se recoge escena arriba al dejarlo atrás: continuidad
       espacial, y el único movimiento de salida de toda la web. */
    .heroe {
      animation: recogerse linear both;
      animation-timeline: view();
      animation-range: exit 15% exit 85%;
    }
  }
}

@keyframes surgir {
  from {
    opacity: 0;
    transform: translateY(1.1rem);
  }
}

@keyframes llegar-izquierda {
  from {
    opacity: 0;
    transform: translateX(-3.25rem) scale(0.96);
  }
}

@keyframes llegar-derecha {
  from {
    opacity: 0;
    transform: translateX(3.25rem) scale(0.96);
  }
}

@keyframes dibujar-eje {
  from {
    transform: scaleY(0);
  }
}

@keyframes recogerse {
  to {
    opacity: 0;
    transform: translateY(-1.75rem) scale(0.985);
  }
}

/* ── 5 · La marca de agua de las cuarenta horas ─────────────────────
   La retícula del héroe, enorme y casi invisible, derivando al límite
   de lo perceptible tras el titular de la portada.                   */

.pagina-inicio .heroe {
  position: relative;
  isolation: isolate;
  overflow: clip;
}

.pagina-inicio .heroe::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: clamp(1rem, 4vw, 3rem);
  right: -3rem;
  width: min(46rem, 72%);
  height: 24rem;
  pointer-events: none;
  opacity: 0.05;
  background-image: repeating-linear-gradient(
    90deg,
    var(--oro-claro) 0 2px,
    transparent 2px 24px
  );
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 190px, transparent 190px 238px);
  mask-image: repeating-linear-gradient(90deg, #000 0 190px, transparent 190px 238px);
  animation: derivar 90s ease-in-out infinite alternate;
}

@keyframes derivar {
  to {
    transform: translateX(2.5rem);
  }
}

/* ── Movimiento reducido: menos y más suave, no cero ────────────────
   Emil: se conservan las transiciones de color y opacidad que aportan
   comprensión (marcar una casilla, un hover que cambia de color); se
   elimina el desplazamiento. Todas las animaciones espaciales de esta
   hoja ya viven detrás de la guarda no-preference; aquí se apagan las
   transiciones de página, el deslizamiento del scroll y la deriva.   */

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }

  html {
    scroll-behavior: auto;
  }

  .pagina-inicio .heroe::before {
    animation: none;
  }

  /* El puntero conserva sus tres estados, que son información sobre lo
     que hay debajo, pero llega a ellos sin recorrido: los semicírculos
     se abren de golpe en vez de viajar. El trazo sí sigue engordando con
     transición, que es un cambio de grosor y no un desplazamiento. El
     latido de convergencia no existe aquí, porque su regla vive tras
     `no-preference`. */
  .puntero circle,
  .puntero path {
    transition: stroke-width var(--t-feedback) var(--ease-out);
  }
}

/* ── Impresión ──────────────────────────────────────────────────────── */

@media print {
  .carril,
  .boton,
  .paso,
  .portada,
  body::after,
  .pagina-inicio .heroe::before {
    display: none;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  .lienzo {
    grid-template-columns: 1fr;
  }
}
