/* Lufran Solutions · sistema visual y movimiento (v3, «el plano»; 23-oct-2026, R-046, D-108).
   Marca: tinta #071C38 y cobalto #056BD8 sobre papel blanco. Voz: Recursive, la letra que va del diseño (Sans) al código
   (Mono) en una sola familia, como la frase de la marca. Firma: el plano del monograma, con sus líneas y sus cotas, que
   miden la marca de verdad, y el cajetín del pie y de las legales. Movimiento: un gesto (el encaje), una vez; solo
   transform/opacity/color, y quieto con «Reducir movimiento». Sin cápsulas, paneles de degradado ni marcas fantasma. */

/* ── Tipografía (autoalojada; sin servicios externos) ────────────────────────────────── */
/* Recursive (OFL 1.1, Arrow Type): el fichero lleva los ejes de grosor y MONO; «MONO» 0 es la Sans y 1, la Mono. */
@font-face {
  font-family: "Recursive";
  src: url("/assets/fonts/recursive-latin.bda8bb8f.woff2") format("woff2");
  font-style: normal; font-weight: 300 1000; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Recursive";
  src: url("/assets/fonts/recursive-latin-ext.bb6d1acf.woff2") format("woff2");
  font-style: normal; font-weight: 300 1000; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Reserva con las mismas medidas mientras llega la letra: sin saltos (CLS). */
@font-face { font-family: "Recursive reserva"; src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans"); font-weight: 100 549; size-adjust: 105%; ascent-override: 92%; descent-override: 24%; }
@font-face { font-family: "Recursive reserva"; src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold"); font-weight: 550 1000; size-adjust: 101%; ascent-override: 95%; descent-override: 25%; }

/* ── Tokens ─────────────────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light dark;
  /* Grosores con nombre (R-050, D-105; informe común `grosores-y-trazos`): los de la HIG en el texto y uno más, Bold, solo para
     el titular de la portada; trazos fino, grueso y más grueso (como Fluent y Primer); los iconos de línea, con el asta de
     Recursive del peso de su texto. Ningún número suelto. */
  --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700;
  --stroke-thin: 1px; --stroke-thick: 2px; --stroke-thicker: 3px;
  --icon-stroke-regular: .091em; --icon-stroke-semibold: .121em; --icon-stroke: var(--icon-stroke-semibold);
  --ink: #071C38;
  --cobalt: #056BD8;
  --sand: #F3F1EB;

  /* El papel: blanco, como el de un plano (canones-2026: el lienzo, el del sistema o uno igual de claro). */
  --bg: #FFFFFF;
  --bg-raised: #FFFFFF;
  --text: var(--ink);
  --text-2: #3E4C62;
  --text-3: #56637A;
  --line: rgb(7 28 56 / .12);
  --line-strong: rgb(7 28 56 / .24);
  --control-line: rgb(7 28 56 / .52);
  --accent: var(--cobalt);
  --accent-hover: #0459B5;
  --accent-tint: rgb(5 107 216 / .08);
  --accent-tint-hover: rgb(5 107 216 / .14);
  --on-accent: #FFFFFF;
  --mark-l: var(--ink);
  --mark-s: var(--cobalt);
  /* El plano: las líneas de construcción, finas, y las cotas, que son texto (4,5:1 o más). */
  --plano-line: rgb(7 28 56 / .14);
  --plano-cota: rgb(7 28 56 / .46);
  --plano-lit: var(--cobalt);
  --menu-shadow: 0 18px 48px rgb(7 28 56 / .14), 0 2px 6px rgb(7 28 56 / .08);
  --icon-tile-fylark: #EDF1F6;

  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.32, .72, 0, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --t-fast: 160ms;
  --t-base: 260ms;
  --t-slow: 420ms;

  --gutter: max(clamp(20px, 5vw, 72px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --maxw: 1240px;
  --header-h: 64px;

  --fs-hero: clamp(2.75rem, 1.15rem + 4.6vw, 5.5rem);
  --fs-l: clamp(2.125rem, 1.2rem + 3vw, 4rem);
  --fs-m: clamp(1.75rem, 1.2rem + 1.9vw, 2.75rem);
  --fs-s: clamp(1.375rem, 1.1rem + .9vw, 1.875rem);
  --fs-lead: clamp(1.1875rem, 1rem + .6vw, 1.5rem);
  --fs-lede: clamp(1.125rem, 1rem + .45vw, 1.375rem);
  --fs-intro: clamp(1.0625rem, 1rem + .3vw, 1.25rem);
  --fs-body: 1.0625rem;
  --fs-small: .9375rem;
  --fs-caption: .875rem;
  --fs-mono: .8125rem;
  --fs-mono-s: .75rem;
  --fs-email: clamp(1.5rem, .6rem + 3.4vw, 3.5rem);
  --font: "Recursive", "Recursive reserva", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #071C38;
    --bg-raised: #0D2749;
    --text: #F3F1EB;
    --text-2: #C6CEDA;
    --text-3: #9EABBE;
    --line: rgb(243 241 235 / .13);
    --line-strong: rgb(243 241 235 / .26);
    --control-line: rgb(243 241 235 / .5);
    --accent: #5AA5FF;
    --accent-hover: #83BCFF;
    --accent-tint: rgb(90 165 255 / .14);
    --accent-tint-hover: rgb(90 165 255 / .22);
    --on-accent: #071C38;
    --mark-l: #F3F1EB;
    --plano-line: rgb(243 241 235 / .15);
    --plano-cota: rgb(243 241 235 / .58);
    --plano-lit: #5AA5FF;
    --menu-shadow: 0 18px 48px rgb(0 0 0 / .45), 0 2px 6px rgb(0 0 0 / .3);
  }
}
/* Contraste alto (R-050, D-104; HIG «Color»): cada texto a 7:1 con su mismo tono; las cotas y las líneas, más firmes. */
@media (prefers-contrast: more) {
  :root { --text-2: var(--text); --text-3: var(--text); --line: var(--line-strong);
    --accent: #024fa3; --accent-hover: #054894; --accent-tint: rgb(2 79 163 / 0); --accent-tint-hover: rgb(2 79 163 / .06);
    --plano-line: rgb(7 28 56 / .3); --plano-cota: var(--text); }
}
@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
  :root { --accent: #79b5fe; --accent-hover: #83bcff; --accent-tint: rgb(121 181 254 / 0); --accent-tint-hover: rgb(121 181 254 / .06);
    --plano-line: rgb(243 241 235 / .32); }
}

/* ── Base ───────────────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 24px); background: var(--bg); }
/* El hueco de la barra de desplazamiento queda reservado: abrir el menú no ensancha la página (D-048). */
html { scrollbar-gutter: stable; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0; min-height: 100svh; background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: var(--fs-body); line-height: 1.6; font-variation-settings: "MONO" 0;
  font-kerning: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
p { margin: 0; text-wrap: pretty; }
h1, h2, h3 { margin: 0; font-weight: var(--weight-semibold); text-wrap: balance; }
ul, ol, dl, dd { margin: 0; }
::selection { background: var(--accent); color: var(--on-accent); }
:focus-visible { outline: var(--stroke-thicker) solid var(--accent); outline-offset: 3px; border-radius: 6px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.wrap { width: min(100% - 2 * var(--gutter), var(--maxw)); margin-inline: auto; }
/* La letra del código: la misma familia con el eje MONO. Para cotas, fechas, números y etiquetas; nunca en mayúsculas espaciadas. */
.mono { font-variation-settings: "MONO" 1; letter-spacing: 0; }
.skip {
  position: fixed; left: 16px; top: 12px; z-index: 100; transform: translateY(-160%);
  background: var(--text); color: var(--bg); padding: 12px 20px; border-radius: 999px; text-decoration: none; font-weight: var(--weight-semibold);
  transition: transform var(--t-base) var(--ease-out);
}
.skip:focus-visible { transform: none; }
.scroll-sentinel { position: absolute; top: 0; left: 0; width: 1px; height: 24px; pointer-events: none; }

/* ── Barra: plana y opaca, la misma en todas las páginas ────────────────────────────── */
.site-header { position: sticky; top: 0; z-index: 40; height: var(--header-h); display: flex; align-items: center; background: var(--bg); view-transition-name: site-header; }
/* El borde aparece al desplazar (el «scroll edge effect» de la HIG, en una web): una línea fina, no una sombra. */
.site-header::after { content: ""; position: absolute; inset: auto 0 0; height: var(--stroke-thin); background: var(--line); opacity: 0; transition: opacity var(--t-base) var(--ease-out); }
.site-header.is-scrolled::after { opacity: 1; }
.header-inner { display: flex; align-items: center; gap: 24px; width: min(100% - 2 * var(--gutter), var(--maxw)); min-height: 52px; margin-inline: auto; }
/* El logotipo bueno (D-035): el horizontal del maestro, con su letra; en oscuro, su versión clara. */
.brand { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; border-radius: 6px; flex: none; }
.brand picture { display: block; }
.brand img { display: block; height: 24px; width: auto; max-width: none; }
.nav { margin-inline-start: auto; }
.nav ul, .lang-pills { list-style: none; padding: 0; margin: 0; }
.nav ul { display: flex; gap: 4px; }
.nav a {
  position: relative; display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px;
  border-radius: 6px; text-decoration: none; color: var(--text-2); font-size: var(--fs-small);
  transition: color var(--t-fast);
}
.nav a:hover { color: var(--text); }
.nav a::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: 9px; height: var(--stroke-thick); background: currentColor; transform: scaleX(0); transform-origin: left center; transition: transform var(--t-base) var(--ease-out); }
.nav a:hover::after { transform: scaleX(1); }
.nav a[aria-current="true"] { color: var(--text); }
.nav a[aria-current="true"]::after { transform: scaleX(1); background: var(--accent); }
/* Selector de idioma (R-025, D-052; el de las landings): un botón con el globo y el idioma actual abre la lista de los cinco,
   cada uno por su nombre en su lengua, como popover nativo anclado al botón. Por debajo de 981 px vive en el menú. */
.lang { position: relative; display: flex; align-items: center; }
.lang svg { width: 16px; height: 16px; --icon-stroke: var(--icon-stroke-regular); }
/* Iconos de línea con el grosor de la letra que acompañan (R-050, tanda 2): su trazo, en em de su texto. */
svg[stroke] :is(path, line, polyline, polygon, circle, rect, ellipse) { vector-effect: non-scaling-stroke; stroke-width: var(--icon-stroke); }
.lang-toggle { display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 12px; border: 0; border-radius: 6px; background: none; color: var(--text); font: inherit; font-size: var(--fs-small); cursor: pointer; transition: background-color var(--t-fast); }
.lang-toggle:hover { background: var(--accent-tint); }
.lang-chevron { color: var(--text-2); transition: rotate .2s ease-out; }
.lang-toggle:has(+ .lang-pills:popover-open) .lang-chevron { rotate: 180deg; }
.lang-pills a {
  display: flex; align-items: center; min-height: 44px; padding: 0 14px; border-radius: 6px;
  text-decoration: none; font-size: var(--fs-small); color: var(--text-2); white-space: nowrap;
  transition: color var(--t-fast), background-color var(--t-fast);
}
.lang-pills a:hover { color: var(--text); background: var(--accent-tint); }
.lang-pills a[aria-current="page"] { color: var(--text); font-weight: var(--weight-semibold); box-shadow: inset var(--stroke-thick) 0 0 var(--accent); border-radius: 0 6px 6px 0; }
.lang-pills:popover-open { position: fixed; inset: auto; top: 72px; right: 24px; display: flex; flex-direction: column; gap: 2px; min-width: 12rem; padding: 6px; border: 0; border-radius: 10px; background: var(--bg-raised); color: var(--text); box-shadow: var(--menu-shadow), inset 0 0 0 var(--stroke-thin) var(--line); }
@supports (anchor-name: --lang-toggle) {
  .lang-toggle { anchor-name: --lang-toggle; }
  .lang-pills:popover-open { position-anchor: --lang-toggle; top: calc(anchor(bottom) + 6px); right: anchor(right); position-try-fallbacks: flip-inline; }
}
@media not (prefers-reduced-motion: reduce) {
  .lang-pills:popover-open { transition: opacity .18s ease-out, translate .18s ease-out; }
  @starting-style { .lang-pills:popover-open { opacity: 0; translate: 0 -4px; } }
}
/* Sin popover (navegadores anteriores a 2024): sin botón, los cinco nombres a la vista. */
@supports not selector(:popover-open) {
  .lang-toggle { display: none; }
  .lang-pills { display: flex; gap: 2px; }
  .lang-pills a { min-height: 36px; padding: 0 8px; font-size: .8125rem; }
}
/* Menú en el teléfono: botón de dos líneas y hoja a pantalla completa (Apple, Stripe, Linear). */
.menu-btn { display: none; place-items: center; width: 44px; height: 44px; margin-inline-start: auto; border: 0; border-radius: 6px; background: transparent; color: var(--text); cursor: pointer; transition: background-color var(--t-fast); }
.menu-btn:hover { background: var(--accent-tint); }
/* Con contraste alto, al pasar, un contorno en vez del velo (R-050). */
@media (prefers-contrast: more) { .lang-toggle:hover, .lang-pills a:not([aria-current="page"]):hover, .menu-btn:hover { background: none; box-shadow: inset 0 0 0 var(--stroke-thin) currentColor; } }
.menu-btn svg, .menu-close svg { width: 22px; height: 22px; }
.menu {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: var(--bg); color: var(--text); overflow-y: auto; overscroll-behavior: contain;
}
.menu::backdrop { background: transparent; }
.menu-inner { min-height: 100%; display: flex; flex-direction: column; gap: 32px; padding: 6px var(--gutter) max(28px, env(safe-area-inset-bottom)); }
.menu-top { display: flex; align-items: center; justify-content: space-between; min-height: 52px; }
.menu-close { display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 6px; background: var(--accent-tint); color: var(--text); cursor: pointer; }
.menu-nav { list-style: none; padding: 0; margin: 8px 0 0; display: grid; border-top: var(--stroke-thin) solid var(--line); }
.menu-nav a {
  display: flex; align-items: center; min-height: 64px; padding: 10px 2px; border-bottom: var(--stroke-thin) solid var(--line);
  font-size: clamp(1.75rem, 1.2rem + 3vw, 2.375rem); font-weight: var(--weight-semibold); letter-spacing: -.03em; line-height: 1.1; text-decoration: none;
}
.menu-langs { display: grid; gap: 10px; }
.menu-langs-title { font-size: var(--fs-mono); color: var(--text-3); }
.menu-lang-list { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 4px 6px; }
.menu-lang-list a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; border-radius: 6px; text-decoration: none; color: var(--text-2); }
.menu-lang-list a[aria-current="page"] { color: var(--text); font-weight: var(--weight-semibold); background: var(--accent-tint); }
.menu-cta { margin-top: auto; justify-content: center; }
.menu .menu-cta { padding-inline: 16px; white-space: normal; text-align: center; } /* R-014: la dirección entera a 320 px; si no cupiera, se parte detrás de la @ */
html.menu-open { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .menu[open] { animation: menu-in 280ms var(--ease-out); }
  .menu.is-closing { animation: menu-out 200ms var(--ease-in-out) forwards; }
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-8px); } }
@keyframes menu-out { to { opacity: 0; transform: translateY(-6px); } }

@media (max-width: 980px) {
  .nav, .lang { display: none; }
  .js .menu-btn { display: inline-grid; }
}

/* ── Botones y acciones de texto ────────────────────────────────────────────────────── */
/* Uno principal, relleno del acento y plano (canones-2026: sin sombra de color ni brillo); el secundario, una acción de
   texto en el acento y sin subrayar. La forma, la del sistema de Apple: la cápsula. */
.btn {
  display: inline-flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 26px; border-radius: 999px;
  font-weight: var(--weight-semibold); font-size: 1rem; text-decoration: none; white-space: nowrap;
  transition: background-color var(--t-base) var(--ease-out), color var(--t-base), transform var(--t-fast) var(--ease-out);
}
.btn svg { width: 18px; height: 18px; flex: none; transition: transform var(--t-base) var(--ease-out); }
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:hover svg { transform: translateY(2px); }
.btn-tinted { background: var(--accent-tint); color: var(--accent); }
.btn-tinted:hover { background: var(--accent-tint-hover); color: var(--accent-hover); }
.text-action { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 4px; color: var(--accent); font-weight: var(--weight-semibold); text-decoration: none; border-radius: 6px; }
.text-action svg { width: 18px; height: 18px; flex: none; transition: transform var(--t-base) var(--ease-out); }
.text-action:hover { color: var(--accent-hover); }
.text-action:hover svg { transform: translateX(3px); }

/* ── Portada: el titular, de un color ───────────────────────────────────────────────── */
.hero { padding-block: clamp(40px, 9vh, 112px) clamp(32px, 6vh, 72px); }
.display { font-size: var(--fs-hero); line-height: 1; letter-spacing: -.042em; font-weight: var(--weight-bold); }
/* En pantallas anchas, dos líneas: quién y qué respeta. En las estrechas, se parte solo. */
@media (min-width: 761px) { .display > span { display: block; } }
.hero-foot { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 24px 56px; margin-top: clamp(28px, 4.4vw, 56px); }
.lede { font-size: var(--fs-lede); line-height: 1.5; color: var(--text-2); max-width: 42ch; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }

/* ── El plano: la L y la S encajan, medidas (la firma; D-108) ───────────────────────── */
/* Las líneas de construcción salen de las aristas reales del maestro (build.py, GRID_X y GRID_Y) y cruzan la página; las
   cotas miden la marca en su rejilla de 1024: la junta entre la L y la S (34,5), el ancho y el alto. Nada de rejilla de
   fondo ni de panel: el dibujo va sobre el papel. Al entrar, una sola vez, la S encaja en la L y la cota de la junta baja
   hasta su medida; con «Reducir movimiento», sin JavaScript o al imprimir, ya encajada. */
.stage { --pl: 1; --pg: 1; position: relative; overflow: hidden; padding-block: clamp(24px, 5vh, 56px) clamp(56px, 9vh, 104px); }
@media print { .stage { --pl: 1 !important; --pg: 1 !important; } .stage-caption .w-b { color: var(--text) !important; }
  *, *::before, *::after { transition: none !important; animation: none !important; } }
/* El plano cabe entero en la pantalla: como mucho el 62 % de su alto (84svh de ancho, por la proporción 1600:1180), y el 80 % en
   las pantallas bajas (menos de 500 px), para que el encaje se vea entero y con aire. */
.plano { position: relative; width: min(100% - 2 * var(--gutter), 640px, 84svh); margin-inline: auto; aspect-ratio: 1600 / 1180; }
@media (height < 500px) { .plano { width: min(100% - 2 * var(--gutter), 640px, 108svh); } }
.plano svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.plano-grid line { stroke: var(--plano-line); stroke-width: var(--stroke-thin); vector-effect: non-scaling-stroke; transform-box: view-box; transform-origin: 512px 512px; transform: scale(var(--pg)); }
.plano-cotas line, .plano-cotas path { stroke: var(--plano-cota); stroke-width: var(--stroke-thin); vector-effect: non-scaling-stroke; fill: none; }
.plano-cotas { opacity: var(--pg); }
.stage-mark path { transform-box: fill-box; transform-origin: 50% 50%; }
/* La L, quieta (el diseño); la S (el código) llega y encaja en ella. */
.stage-mark .mark-l { fill: var(--mark-l); }
.stage-mark .mark-s { fill: var(--mark-s); transform: translate3d(calc((1 - var(--pl)) * 340px), calc((1 - var(--pl)) * -60px), 0) rotate(calc((1 - var(--pl)) * 12deg)); }
.plano .joint { transform: translate3d(calc((1 - var(--pl)) * 340px), 0, 0); }
/* Las cifras de las cotas son texto en la letra del código, a 4,5:1 o más; van en HTML para no encogerse con el dibujo. */
/* Aparecen con sus líneas (--pg): antes del encaje no flotan solas sobre la S que espera (captura del 24-oct). */
.cota { position: absolute; z-index: 1; translate: -50% -50%; font-variation-settings: "MONO" 1; font-size: var(--fs-mono-s); line-height: 1; color: var(--text-2); background: var(--bg); padding: 2px 5px; white-space: nowrap; font-variant-numeric: tabular-nums; opacity: var(--pg); }
/* Su sitio, en la caja del plano (build.py, PLANO_BOX = -288 -40 1600 1180): el ancho, bajo la marca; el alto, a su derecha;
   la junta, encima, entre la L y la S. */
.cota-w { left: 49.98%; top: 82.16%; }
.cota-h { left: 79.41%; top: 46.69%; }
.cota-j { left: 38.61%; top: 7.33%; color: var(--accent); }
.stage-caption { position: relative; margin: clamp(20px, 3vh, 36px) auto 0; width: min(100% - 2 * var(--gutter), 760px); text-align: center; font-size: var(--fs-m); line-height: 1.15; letter-spacing: -.03em; font-weight: var(--weight-medium); color: var(--text-2); text-wrap: balance; }
.stage-caption .w-l { color: var(--text); }
.stage-caption .w-s { color: var(--accent); font-variation-settings: "MONO" 1; letter-spacing: -.02em; }
.stage-caption .w-b { color: var(--text); font-weight: var(--weight-semibold); transition: color 600ms var(--ease-out); }
.stage.is-playing:not(.is-locked) .stage-caption .w-b { color: var(--text-3); }
.stage.is-locked .stage-mark { animation: lock 420ms var(--ease-soft); }
.stage-grid-lit line { stroke: var(--plano-lit); opacity: 0; }
.stage.is-locked .stage-grid-lit line { animation: line-lit 1000ms var(--ease-out) calc(var(--i, 0) * 50ms) both; }
.stage-grid-lit .i1 { --i: 1; } .stage-grid-lit .i2 { --i: 2; } .stage-grid-lit .i3 { --i: 3; }
.stage-grid-lit .i4 { --i: 4; } .stage-grid-lit .i5 { --i: 5; } .stage-grid-lit .i6 { --i: 6; }

/* ── Secciones ──────────────────────────────────────────────────────────────────────── */
.section { padding-block: clamp(64px, 9vh, 112px); }
.section-head { display: grid; gap: 16px; max-width: 760px; margin-bottom: clamp(32px, 4.4vw, 56px); }
.section-title { font-size: var(--fs-l); line-height: 1.04; letter-spacing: -.036em; }
.section-intro { font-size: var(--fs-intro); color: var(--text-2); max-width: 54ch; }

/* Apps: una fila por app, entre filetes; su icono de verdad, su promesa, su estado y su web (D-108). */
.app-list { list-style: none; padding: 0; border-top: var(--stroke-thin) solid var(--line); }
.app { display: grid; grid-template-columns: 76px minmax(0, .9fr) minmax(0, 1.3fr) minmax(0, auto); grid-template-areas: "icon name what go"; align-items: center; gap: 20px clamp(20px, 3vw, 44px); padding-block: clamp(24px, 3vw, 36px); border-bottom: var(--stroke-thin) solid var(--line); }
.app-icon { grid-area: icon; width: 76px; height: 76px; border-radius: 22.5%; overflow: hidden; flex: none; }
.app-icon img { width: 100%; height: 100%; }
.app-icon--fylark { background: var(--icon-tile-fylark); box-shadow: inset 0 0 0 var(--stroke-thin) rgb(7 28 56 / .08); }
.app-icon--fylark img { width: 74%; height: 74%; margin: 13%; }
.app-name { grid-area: name; display: grid; gap: 4px; }
.app-name h3 { font-size: var(--fs-m); line-height: 1; letter-spacing: -.035em; }
.app-kicker { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
/* Los sistemas de cada app (R-046, D-112; ley global del 20-oct-2026), bajo su tipo y en su letra, separados por un punto que el
   lector de pantalla no lee (lee la lista, con su nombre: «Compatibilidad», el de la App Store); si no caben, bajan de línea
   entre sistemas, nunca dentro de «Apple Watch». El punto va delante de cada sistema, en el hueco entre dos, y el del primero de
   cada renglón queda fuera de la lista, recortado: al partirse la fila, ningún punto cuelga al principio ni al final de un renglón. */
.app-systems { --sep: 1.6em; list-style: none; padding: 0; margin: 2px 0 0; display: flex; flex-wrap: wrap; gap: 0 var(--sep); overflow-x: clip; font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
.app-systems li { white-space: nowrap; margin-inline-start: calc(-1 * var(--sep)); }
.app-systems li::before { content: "·"; content: "·" / ""; display: inline-block; inline-size: var(--sep); text-align: center; }
.app-what { grid-area: what; display: grid; gap: 6px; }
.app-claim { font-size: var(--fs-lead); line-height: 1.25; letter-spacing: -.02em; font-weight: var(--weight-medium); }
.app-desc { color: var(--text-2); }
.app-go { grid-area: go; display: grid; justify-items: end; gap: 6px; }
.app-state { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-2); }
/* El estado, con su cuadrado del color de la app: abierto (lleno). */
.app-state::before { content: ""; width: 8px; height: 8px; background: var(--state, var(--accent)); flex: none; }
.app--fylark { --state: #0B4DA2; }
.app--cestly { --state: #2FBF73; }
@media (prefers-color-scheme: dark) { .app--fylark { --state: #5AA5FF; } }
.app-link { position: relative; }
.app-link::after { content: ""; position: absolute; inset: -8px -12px; }

/* Principios: cuatro promesas en un registro, cada una con su prueba (D-108): en esta visita, tus ajustes, tus idiomas y la
   última revisión. Las pruebas en vivo las hace site.js en tu navegador, sin guardar ni enviar nada; sin JavaScript, el texto
   de servidor dice lo mismo. */
.principles-list { list-style: none; padding: 0; border-top: var(--stroke-thin) solid var(--line); counter-reset: none; }
.principle { display: grid; grid-template-columns: 48px minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "num body proof"; gap: 14px clamp(20px, 3vw, 44px); padding-block: clamp(24px, 3vw, 36px); border-bottom: var(--stroke-thin) solid var(--line); align-items: start; }
.principle .num { grid-area: num; font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--accent); padding-top: .55em; }
.principle-body { grid-area: body; display: grid; gap: 8px; }
.principle h3 { font-size: var(--fs-s); line-height: 1.15; letter-spacing: -.025em; }
.principle-body p { color: var(--text-2); max-width: 46ch; }
.proof { grid-area: proof; display: grid; gap: 6px; padding-top: .35em; font-size: var(--fs-small); }
.proof-k { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
.proof-v { display: grid; gap: 2px; font-variation-settings: "MONO" 1; color: var(--text); line-height: 1.5; }
.proof-v > span:not(.sr-only) { display: block; }
.proof-langs { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 0 4px; font-variation-settings: "MONO" 0; }
.proof-langs a { display: inline-flex; align-items: center; min-height: 32px; padding: 0 6px; margin-inline-start: -6px; color: var(--accent); text-decoration: none; border-radius: 6px; }
.proof-langs a:hover { text-decoration: underline; text-underline-offset: 4px; }
.proof-langs a[aria-current="page"] { color: var(--text); font-weight: var(--weight-semibold); }

/* Sobre Lufran: una persona, con nombre y lugar. */
.about-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(28px, 6vw, 96px); align-items: start; }
.about-text { font-size: var(--fs-lead); line-height: 1.45; letter-spacing: -.012em; max-width: 34ch; }
.byline { display: grid; gap: 2px; margin-top: 28px; padding-top: 16px; border-top: var(--stroke-thin) solid var(--line); max-width: 34ch; }
.byline-name { font-weight: var(--weight-semibold); }
.byline-role { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }

/* Contacto: la dirección es el objeto; sin panel. */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px clamp(28px, 6vw, 96px); align-items: start; }
.contact-text { font-size: var(--fs-intro); color: var(--text-2); max-width: 46ch; }
.email-row { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-top: clamp(16px, 3vw, 40px); padding-top: clamp(20px, 3vw, 32px); border-top: var(--stroke-thin) solid var(--line); container-type: inline-size; }
.email {
  /* R-014: el tamaño baja con el ancho para que la dirección quepa entera; por debajo de 20 px no baja más y se parte detrás de la @. */
  font-size: var(--fs-email); font-size: max(1.25rem, min(var(--fs-email), 6.6cqi)); font-weight: var(--weight-semibold); letter-spacing: -.035em; line-height: 1.15;
  color: var(--text); text-decoration: none; overflow-wrap: anywhere;
  background: linear-gradient(var(--accent), var(--accent)) 0 100% / 0 var(--stroke-thick) no-repeat; padding-bottom: 6px;
  transition: background-size var(--t-slow) var(--ease-out);
}
.email:hover, .email:focus-visible { background-size: 100% var(--stroke-thick); }
.copy {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--accent-tint); color: var(--accent); font: var(--weight-semibold) var(--fs-small)/1 var(--font);
  transition: background-color var(--t-base) var(--ease-out);
}
.copy:hover { background: var(--accent-tint-hover); color: var(--accent-hover); }
/* Con contraste alto, lo teñido pierde el velo (el acento no llegaría a 7:1 sobre él) y gana su contorno. */
@media (prefers-contrast: more) { .copy, .btn-tinted, .menu-close { box-shadow: inset 0 0 0 var(--stroke-thin) currentColor; } }
.copy svg { width: 16px; height: 16px; }
.copy .ico-check { display: none; }
.copy.is-done .ico-copy { display: none; }
.copy.is-done .ico-check { display: block; animation: pop 420ms var(--ease-soft); }

/* ── El cajetín: el pie como el de un plano (D-108) ─────────────────────────────────── */
/* Lo que se busca al final de una web, en celdas con su nombre: quién la hace y dónde, las apps, las páginas legales, los
   idiomas y la fecha de la última revisión. Las líneas del cajetín son las del plano. */
.site-footer { padding-block: clamp(48px, 7vw, 88px) clamp(28px, 4vw, 48px); }
/* Las líneas del cajetín son el fondo que asoma entre sus celdas (1 px de hueco): siempre enteras, se coloquen como se coloquen. */
.cajetin { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr)); gap: var(--stroke-thin); background: var(--line-strong); border: var(--stroke-thin) solid var(--line-strong); }
.cj { padding: 18px 20px 20px; background: var(--bg); min-width: 0; }
.cj-row { display: contents; }
.cj-row .cj { padding-block: 12px; }
.cj-row .cj:nth-child(2), .cj-row .cj:nth-child(3) { grid-column: span 2; }
.cj h2 { font-size: var(--fs-mono); font-weight: var(--weight-regular); font-variation-settings: "MONO" 1; color: var(--text-3); margin-bottom: 8px; }
.cj ul { list-style: none; padding: 0; display: grid; gap: 0; }
.cj a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; text-decoration: none; color: var(--text-2); font-size: var(--fs-small); } /* 44 px, como el resto de la web (HIG; referentes del 24-oct) */
.cj a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 4px; }
.cj a svg { width: 12px; height: 12px; }
.cj-brand .brand img { height: 22px; }
.cj-brand p { margin-top: 10px; font-size: var(--fs-small); color: var(--text-2); }
.cj-foot { font-size: var(--fs-caption); color: var(--text-2); }
.cj-foot.mono { font-variation-settings: "MONO" 1; }
.footer-lang-list a[aria-current="page"] { color: var(--text); font-weight: var(--weight-semibold); }

/* ── Páginas legales ────────────────────────────────────────────────────────────────── */
.doc-page { padding-block: clamp(32px, 6vw, 80px) clamp(56px, 9vw, 112px); }
.doc-nav { display: flex; flex-wrap: wrap; gap: 4px 20px; list-style: none; padding: 0; margin-bottom: clamp(28px, 4vw, 48px); border-bottom: var(--stroke-thin) solid var(--line); }
.doc-nav a { position: relative; display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; font-size: var(--fs-small); color: var(--text-2); }
.doc-nav a:hover { color: var(--text); }
.doc-nav a[aria-current="page"] { color: var(--text); font-weight: var(--weight-semibold); }
.doc-nav a[aria-current="page"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: var(--stroke-thick); background: var(--accent); }
.doc-page h1 { font-size: var(--fs-l); line-height: 1.02; letter-spacing: -.036em; max-width: 18ch; }
/* La revisión, en su cajetín (R-107 de las landings, aquí D-108): la fecha y qué ha cambiado, a la vista arriba. */
.doc-rev { display: grid; grid-template-columns: auto minmax(0, 1fr); margin-top: 22px; max-width: 68ch; border: var(--stroke-thin) solid var(--line-strong); }
.doc-rev > * { padding: 12px 16px; }
.doc-rev .updated { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-2); border-inline-end: var(--stroke-thin) solid var(--line-strong); white-space: nowrap; }
.doc-changed { font-size: var(--fs-small); color: var(--text-2); }
.doc-changed-k { display: block; font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); margin-bottom: 2px; }
.doc-page .intro { margin-top: 28px; font-size: var(--fs-lede); color: var(--text-2); max-width: 62ch; }
.doc-layout { display: grid; grid-template-columns: minmax(0, 68ch) minmax(200px, 260px); justify-content: space-between; gap: clamp(40px, 6vw, 96px); align-items: start; margin-top: clamp(36px, 5vw, 64px); }
.doc-body { max-width: 68ch; }
.toc { position: sticky; top: calc(var(--header-h) + 32px); display: grid; gap: 12px; }
.toc-title { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
.toc ol, .toc-fold ol { list-style: none; padding: 0; margin: 0; display: grid; gap: 2px; border-inline-start: var(--stroke-thin) solid var(--line); }
.toc a, .toc-fold a { display: block; padding: 6px 0 6px 16px; margin-inline-start: -1px; border-inline-start: var(--stroke-thick) solid transparent; font-size: var(--fs-small); color: var(--text-2); text-decoration: none; transition: color var(--t-fast), border-color var(--t-fast); }
.toc a:hover { color: var(--text); }
.toc a[aria-current="true"] { color: var(--text); border-inline-start-color: var(--accent); }
/* R-015: por debajo de 1100 px el índice lateral no cabe; va arriba, plegado, con el mismo trazo. */
.toc-fold { display: none; }
.toc-fold details { max-width: 68ch; margin-top: 24px; border-block: var(--stroke-thin) solid var(--line-strong); }
.toc-fold summary { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 0 4px; cursor: pointer; list-style: none; }
.toc-fold summary::-webkit-details-marker { display: none; }
.toc-fold-title { font-size: var(--fs-small); font-weight: var(--weight-semibold); }
.toc-fold-count { font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
.toc-fold summary svg { width: 18px; height: 18px; flex: none; margin-inline-start: auto; color: var(--text-2); transition: transform var(--t-base) var(--ease-out); }
.toc-fold summary:hover svg { color: var(--text); }
.toc-fold details[open] summary svg { transform: rotate(180deg); }
.toc-fold ol { margin: 0 4px 14px; padding-block: 6px; } /* 6 px: el anillo de foco (3 + 3) no se recorta */
.toc-fold a { display: flex; align-items: center; min-height: 44px; }
.toc-fold a:hover { color: var(--text); border-inline-start-color: var(--accent); }
@media (max-width: 1100px) { .doc-layout { grid-template-columns: minmax(0, 1fr); } .toc { display: none; } .toc-fold { display: block; } }
.doc-body section { padding-block: 28px; border-top: var(--stroke-thin) solid var(--line); }
.doc-body h2 { font-size: 1.375rem; line-height: 1.25; letter-spacing: -.015em; margin-bottom: 12px; }
.doc-body p + p { margin-top: 12px; }
.doc-body ul { padding-inline-start: 1.2em; display: grid; gap: 8px; }
.doc-body a, .doc-page .intro a { color: var(--accent); text-decoration-thickness: var(--stroke-thin); text-underline-offset: 3px; overflow-wrap: anywhere; }
.doc-body a:hover { text-decoration-thickness: var(--stroke-thick); }
/* R-014: en el texto corrido la dirección y su puntuación bajan juntas al renglón siguiente; solo si la dirección no
   cabe sola se parte, y entonces detrás de la @ (el <wbr> vuelve a valer dentro de la caja). */
.mail-unit { white-space: nowrap; }
.mail-unit > a { display: inline-block; max-width: calc(100% - .5em); white-space: normal; }
.doc-body strong { font-weight: var(--weight-semibold); color: var(--text); }
.back { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; margin-top: 40px; text-decoration: none; color: var(--accent); font-weight: var(--weight-semibold); }
.back svg { width: 18px; height: 18px; transition: transform var(--t-base) var(--ease-out); }
.back:hover { color: var(--accent-hover); }
.back:hover svg { transform: translateX(-3px); }

/* ── 404: la marca no encaja ────────────────────────────────────────────────────────── */
.nf { min-height: calc(100svh - var(--header-h)); display: grid; place-items: center; padding: 48px var(--gutter) 96px; text-align: center; }
.nf-inner { display: grid; justify-items: center; max-width: 660px; }
.nf .mark { width: clamp(120px, 18vw, 176px); height: auto; overflow: visible; }
.nf .mark-l { fill: var(--mark-l); transform: translate(-16%, 12%) rotate(-10deg); transition: transform 760ms var(--ease-soft); transform-box: fill-box; transform-origin: 50% 50%; }
.nf .mark-s { fill: var(--mark-s); transform: translate(16%, -12%) rotate(10deg); transition: transform 760ms var(--ease-soft); transform-box: fill-box; transform-origin: 50% 50%; }
.nf:has(.nf-home:hover, .nf-home:focus-visible) .mark-l, .nf:has(.nf-home:hover, .nf-home:focus-visible) .mark-s { transform: none; }
.nf-code { margin-top: 32px; font-size: var(--fs-mono); font-variation-settings: "MONO" 1; color: var(--text-3); }
/* La dirección que no existe, en la letra del código (R-108 de las landings: como Panic y Cestly). */
.nf-path { margin-top: 6px; max-width: 100%; font-size: var(--fs-small); font-variation-settings: "MONO" 1; color: var(--text-2); overflow-wrap: anywhere; }
.nf h1 { font-size: var(--fs-m); letter-spacing: -.035em; line-height: 1.05; margin-top: 18px; }
.nf-text { margin-top: 12px; color: var(--text-2); }
/* La página más parecida (R-062, D-113): una frase bajo el texto, con su enlace. El enlace es texto de la frase (no un bloque
   en línea: antes de un bloque se parte aunque haya un espacio que no se parte, y la comilla francesa se quedaba sola al final
   del renglón), y las líneas se equilibran. Como enlace dentro de una frase en la web, subrayado de 1 px, como los de las
   legales: el acento solo queda a 1,7:1 del texto de alrededor (canon de 2026, 8.9; WCAG 1.4.1). */
.nf-near { margin-top: 12px; color: var(--text-2); text-wrap: balance; }
.nf-near a { color: var(--accent); font-weight: var(--weight-semibold); text-decoration-thickness: var(--stroke-thin); text-underline-offset: 3px; }
.nf-near a:hover { text-decoration-thickness: var(--stroke-thick); }
.nf-home { margin-top: 28px; }
.nf-others { list-style: none; padding: 0; margin-top: 40px; display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 18px; font-size: var(--fs-small); }
/* Cada idioma, una acción de texto suelta: 44 px de alto para el dedo (canon de 2026, 8.8; HIG), como el resto de la web. */
.nf-others a { display: inline-flex; min-height: 44px; align-items: center; color: var(--accent); text-decoration: none; }
.nf-others a:hover { text-decoration: underline; text-underline-offset: 4px; }
.mark .mark-l { fill: var(--mark-l); }
.mark .mark-s { fill: var(--mark-s); }
.mark path { transform-box: fill-box; transform-origin: 50% 50%; }

/* ── Adaptación a pantallas ─────────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .hero-foot { grid-template-columns: 1fr; }
  .app { grid-template-columns: 64px minmax(0, 1fr); grid-template-areas: "icon name" "what what" "go go"; align-items: start; }
  .app-icon { width: 64px; height: 64px; }
  .app-go { justify-items: start; }
  .principle { grid-template-columns: 40px minmax(0, 1fr); grid-template-areas: "num body" ". proof"; }
  .about-grid, .contact-grid { grid-template-columns: minmax(0, 1fr); }
  /* Las celdas, en filas que se llenan solas: cada una cabe con su palabra más larga («Confidentialité», 113 px a 15 px) y la
     última de una fila se estira, así que nunca queda un hueco del color de las líneas (R-047, D-108). */
  .cajetin { display: flex; flex-wrap: wrap; }
  .cj { flex: 1 1 9.5rem; }
  .cj-brand, .cj-row .cj { flex-basis: 100%; }
}
@media (max-width: 599px) {
  .cj { padding-inline: 16px; }
  .plano { width: min(100% - 2 * var(--gutter) + 24px, 640px, 84svh); }
  .cota { font-size: .6875rem; padding: 1px 3px; }
  .doc-rev { grid-template-columns: minmax(0, 1fr); }
  .doc-rev .updated { border-inline-end: 0; border-bottom: var(--stroke-thin) solid var(--line-strong); white-space: normal; }
}
@media (max-width: 420px) {
  .brand img { height: 22px; }
  .actions { width: 100%; }
  .actions .btn { flex: 1 1 100%; justify-content: center; }
}
/* La cabecera fija solo donde cabe (2-oct-2026, R-027, D-054): de 500 a 639 px de alto, más baja (como mucho el 12 % del alto);
   por debajo de 500, se va con la página (WCAG, Understanding 1.4.10, técnica C43). */
@media (500px <= height < 640px) {
  :root { --header-h: 56px; }
  .header-inner { min-height: 48px; }
}
@media (height < 500px) {
  .site-header { position: relative; }
  html { scroll-padding-top: 16px; }
  .toc { top: 24px; }
}
/* La acción principal a la vista en las pantallas bajas (R-047, D-089): se recorta aire, nunca texto, y el titular se mide
   también por el alto; en el libro del iPhone Duo (de 721 a 980 px de ancho y bajo), la entradilla a un lado y la acción al
   otro, fuera del pliegue del centro; y donde ni así cabe (menos de 500 px de alto, con la cabecera que se va con la página),
   la acción va en la cabecera, como «Avisarme» en fylark.app y cestly.app. */
.header-cta { display: none; }
@media (height < 640px) {
  :root { --fs-hero: min(clamp(2.75rem, 1.15rem + 4.6vw, 5.5rem), 13.5svh); }
  .hero { padding-top: 16px; }
  .hero-foot { margin-top: 18px; row-gap: 14px; }
}
@media (721px <= width <= 980px) and (height < 640px) {
  .hero-foot { grid-template-columns: minmax(0, 1fr) auto; }
}
@media (width <= 980px) and (height < 500px) {
  .header-cta { display: inline-flex; min-height: 44px; padding: 0 18px; margin-inline-start: auto; font-size: var(--fs-small); }
  .header-cta + .menu-btn { margin-inline-start: 8px; }
}
/* Pantallas estrechas y bajas (R-047, D-091): por debajo de 520 px de ancho la marca se queda en su símbolo (el enlace sigue
   diciendo «Lufran Solutions, inicio»); por debajo de 380, la acción más justa y sin la flecha; y por debajo de 320, la acción
   baja a su propia fila, entera. */
@media (width <= 520px) and (height < 500px), (width < 320px) {
  .header-inner > .brand { width: 40px; overflow: hidden; }
}
@media (width <= 380px) and (height < 500px) {
  .header-inner { gap: 10px; }
  .header-cta { padding: 0 12px; }
  .header-cta svg { display: none; }
}
/* Con el texto grande (el zoom de Safari divide el hueco de la página: al 200 % con el Duo cerrado, 191 px de ancho), por
   debajo de 320 px: los títulos con un tope por el ancho, márgenes de 12 px, nada partido con guion y las cápsulas que se
   parten, en rectángulo redondeado (R-047, D-091 y D-093). */
@media (width < 320px) {
  :root { --fs-hero: min(2.75rem, 13vw, 13.5svh); --gutter: max(12px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)); }
  body, .email, .doc-body a, .doc-page .intro a { overflow-wrap: break-word; }
  /* La dirección del texto corrido, con su dominio entero: con Recursive, «lufransolutions.com» mide 168 px a 17 px y a 191 px
     su hueco es de 159; un tope por el ancho, como los títulos (D-091), y se parte solo detrás de la @ (R-014). */
  .mail-unit > a, .dominio { font-size: min(1em, 8.3vw); }
  .actions .btn { min-width: 0; padding-inline: 20px; white-space: normal; text-align: center; }
  .section-title { font-size: min(var(--fs-l), 10vw); }
  .stage-caption { font-size: min(var(--fs-m), 9vw); }
  .app { grid-template-columns: minmax(0, 1fr); grid-template-areas: "icon" "name" "what" "go"; }
  .app-name h3 { font-size: min(var(--fs-m), 11vw); }
  .principle { grid-template-columns: minmax(0, 1fr); grid-template-areas: "num" "body" "proof"; row-gap: 8px; }
  .principle .num { padding-top: 0; }
  .principle h3 { font-size: min(var(--fs-s), 10vw); }
  .email { font-size: max(.9375rem, min(var(--fs-email), 11cqi)); }
  .cj { padding-inline: 12px; }
  .toc-fold summary { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; padding: 10px 4px; }
  .toc-fold-title, .toc-fold-count { grid-column: 1; }
  .toc-fold summary svg { grid-column: 2; grid-row: 1 / span 2; margin: 0; }
  .toc-fold ol { margin-inline: 4px; }
  .toc-fold a { padding-inline-start: 12px; }
  .doc-page h1 { font-size: min(var(--fs-l), 11vw); }
  .doc-body h2 { font-size: min(1.375rem, 10vw); }
  .btn, .skip, .copy { border-radius: 16px; }
  .copy { white-space: normal; text-align: center; }
  .nf-inner { max-width: 100%; min-width: 0; }
  .nf-home { min-width: 0; white-space: normal; text-align: center; border-radius: 16px; padding-inline: 20px; }
}
@media (width < 320px) and (height < 500px) {
  .site-header { height: auto; }
  .header-inner { flex-wrap: wrap; row-gap: 6px; padding-block: 6px; }
  .header-cta { order: 1; flex: 1 1 100%; min-width: 0; justify-content: center; white-space: normal; text-align: center; border-radius: 16px; }
  .header-cta + .menu-btn { margin-inline-start: auto; }
}

/* ── Movimiento ─────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  /* Cambio de página (D-048): la nueva está entera desde el primer fotograma y la vieja se desvanece encima, sin destellos. */
  @view-transition { navigation: auto; }
  ::view-transition-new(*) { animation: none; mix-blend-mode: normal; }
  ::view-transition-old(*) { animation: vt-out 220ms var(--ease-out) both; mix-blend-mode: normal; z-index: 1; }
  .toc-fold details { interpolate-size: allow-keywords; }
  .toc-fold details::details-content { block-size: 0; overflow-y: clip; transition: block-size var(--t-base) var(--ease-out), content-visibility var(--t-base) allow-discrete; }
  .toc-fold details[open]::details-content { block-size: auto; }
}
@keyframes lock { 40% { transform: scale(1.025); } }
@keyframes line-lit { 0% { opacity: 0; } 22% { opacity: .9; } 100% { opacity: 0; } }
@keyframes pop { 0% { transform: scale(.4); } 60% { transform: scale(1.15); } 100% { transform: none; } }
@keyframes vt-out { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; animation-delay: 0ms !important; }
}

/* ── Colores forzados (alto contraste de Windows) ───────────────────────────────────── */
@media (forced-colors: active) {
  .btn, .copy, .lang-toggle, .doc-nav a[aria-current="page"] { border: var(--stroke-thin) solid ButtonText; }
  .mark .mark-l, .mark .mark-s, .stage-mark .mark-l, .stage-mark .mark-s { fill: CanvasText; }
  .plano-grid line, .plano-cotas line, .plano-cotas path { stroke: CanvasText; }
  .stage-grid-lit, .site-header::after { display: none; }
  .app-state::before { forced-color-adjust: none; background: CanvasText; }
}
