/* The home page's look, ported from prototipos/base/base.css (commit 1df18c1) without the prototype-only parts (the
   prototype tag and switcher). Neutral interface: the image carries the colour; on the cover, the logo's own colour
   copies. */
:root {
  --negro: #050507; --blanco: #FAFAF4;
  --cian: #00E7FF; --azul: #2247FF; --rojo: #FF3038; --magenta: #FF2BC2; --violeta: #7B4DFF;
  --verde: #59C94F; --amarillo: #FFD84C;
  --ui: rgba(250, 250, 244, .78); --ui-dim: rgba(250, 250, 244, .5); --filo: rgba(250, 250, 244, .22);
  --vidrio: rgba(5, 5, 7, .55);
  --f-marca: "Comfortaa", "Varela Round", system-ui, sans-serif;
  --f-ui: "Manrope", "Segoe UI", system-ui, sans-serif;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body {
  margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none;
  background: var(--negro); color: var(--blanco); font: 400 15px/1.5 var(--f-ui);
  -webkit-tap-highlight-color: transparent;
}
a { color: inherit; }
:focus-visible { outline: 2px solid var(--blanco); outline-offset: 3px; }

canvas#scene {
  position: fixed; inset: 0; width: 100vw; height: 100vh; height: 100dvh; display: block;
  opacity: 0; transition: opacity .45s ease; touch-action: none;
}
body.show-canvas canvas#scene { opacity: 1; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- 01 · Inicio ---------- */
#intro {
  position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 24px 16px; text-align: center; z-index: 5;
}
#intro .logo-wrap {
  width: clamp(200px, 48vmin, 420px); aspect-ratio: 2.5 / 1.9; margin-bottom: 6px;
  transition: transform .75s cubic-bezier(.45, 0, .2, 1);
}
#intro .logo-move { width: 100%; height: 100%; transition: transform .5s cubic-bezier(.2, .7, .2, 1); }
.logo-svg { width: 100%; height: 100%; display: block; overflow: visible; }
/* the psychedelic colour copies (logo.js, COPIES): fixed offsets in the SVG's own units (1px = 1 logo unit here), plus
   a small parallax main.js sets with --lx/--ly while the pointer moves; none with reduced motion */
.logo-copy {
  transform: translate(calc(var(--dx) + var(--k) * var(--lx, 0px)), calc(var(--dy) + var(--k) * var(--ly, 0px)));
  transition: transform .6s cubic-bezier(.2, .7, .2, 1);
}
/* The cover's psychedelic life (owner 2026-11-04: «la animación del ojo debe ser más psicodélica, el ojo debe seguir el
   mouse y al hacer click debe cambiar fluidamente»): echoes of the outline grow out of the pupil, the logo breathes,
   main.js turns the pupil (.logo-pupil) towards the pointer and drifts the copies a little after it (--lx/--ly), and a
   click on the eye enters. The colour copies stay at their own offsets, in their own colours (the ones the journey's eye
   draws): circling round their places, even all together, they moved against the white and the black shapes, so every
   rim changed colour on each lap (cyan to blue on the right, the lights' red and cyan crescents swapping sides; owner
   2026-11-05 «un titilar lento ... un efecto que cambia de colores», 2026-11-09 «El ojo del landing se sigue bugueando
   cuando titila»). The Studio teaser keeps its logo still. Nothing here moves with reduced motion (the end of this file). */
@property --aluc-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
/* the breath: its phase (--aluc-bp, the animation) and its depth (--aluc-bk), which fades to 0 on the way in */
@property --aluc-bp { syntax: '<number>'; inherits: false; initial-value: 0; }
@property --aluc-bk { syntax: '<number>'; inherits: false; initial-value: 0; }
#intro .logo-wrap { cursor: pointer; }
#intro .logo-move { position: relative; }
#intro .logo-svg {
  position: relative; --aluc-bk: .03; scale: calc(1 + var(--aluc-bk) * var(--aluc-bp));
  animation: aluc-breathe 7s ease-in-out infinite;
  transition: --aluc-bk .8s cubic-bezier(.2, .7, .2, 1);
}
/* on the way in the copies come to rest at their own offsets, without the pointer's parallax: where the journey's
   first eye draws them at its stop (scene-pineal.js, the cover's logo), so the two eyes cross-fade like for like */
body.entering #intro .logo-svg { --aluc-bk: 0; transition-duration: .75s; }
body.entering #intro .logo-copy { transform: translate(var(--dx), var(--dy)); transition-duration: .75s; }
#intro .logo-echo { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
/* the echoes grow past the logo: the words and buttons stay above them */
#intro .wordmark, #intro .tagline, #intro .ctas { position: relative; z-index: 1; }
#intro .logo-echo .echo {
  fill: none; stroke: var(--magenta); stroke-width: .009px; opacity: 0;   /* logo units: about 1.5 px on a 420 px logo */
  transform-origin: .1549px -.0396px;   /* the disc's centre (logo.discSvg()) */
  animation: aluc-echo 8s cubic-bezier(.3, .5, .5, 1) infinite;
  animation-delay: calc(var(--i) * -1.3333s);
}
@keyframes aluc-turn { to { --aluc-a: 360deg; } }
@keyframes aluc-echo { 0% { scale: 1; opacity: 0; } 12% { opacity: .6; } 100% { scale: 3.2; opacity: 0; } }
@keyframes aluc-breathe { 0%, 100% { --aluc-bp: 0; } 50% { --aluc-bp: 1; } }

/* Between the cover and the Studio teaser: where the browser can (cross-document view transitions), the eye flies from
   one page to its place on the other and the rest dissolves; elsewhere main.js fades the cover out, then the page loads. */
@view-transition { navigation: auto; }
#intro .logo-wrap, .teaser-logo { view-transition-name: aluc-eye; }
::view-transition-group(aluc-eye) { animation-duration: .95s; animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
::view-transition-old(aluc-eye), ::view-transition-new(aluc-eye) { animation-duration: .95s; }
::view-transition-old(root) { animation: aluc-vt-out .55s cubic-bezier(.4, 0, 1, 1) both; }
::view-transition-new(root) { animation: aluc-vt-in .8s cubic-bezier(0, 0, .2, 1) .25s both; }
@keyframes aluc-vt-out { to { opacity: 0; scale: 1.05; filter: blur(8px); } }
@keyframes aluc-vt-in { from { opacity: 0; scale: .97; filter: blur(8px); } }
.wordmark { font: 700 clamp(36px, 7.4vmin, 66px)/1 var(--f-marca); letter-spacing: -.01em; margin: 0; }
.tagline { margin: 0; color: var(--ui); font-size: clamp(15px, 2.2vmin, 19px); }
.ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 14px; }
.btn {
  appearance: none; border: 1px solid var(--filo); background: var(--vidrio); color: var(--blanco);
  font: 600 15px/1 var(--f-ui); padding: 14px 22px; border-radius: 999px; cursor: pointer; text-decoration: none;
  min-height: 46px; display: inline-flex; align-items: center; gap: 8px;
}
.btn:hover { border-color: var(--ui); }
.btn.primary { background: var(--blanco); color: var(--negro); border-color: var(--blanco); }
.btn.primary:hover { background: #fff; }
/* the ES · EN switch (also used by the Studio page): the current language is plain text, the other one is the link */
.lang-switch { display: flex; align-items: center; gap: 6px; color: var(--ui-dim); font: 600 13px/1 var(--f-ui); }
.lang-switch [aria-current] { color: var(--blanco); padding: 12px 2px; }
.lang-switch a { color: var(--ui); text-decoration: none; padding: 12px 8px; }
.lang-switch a:hover { color: var(--blanco); }
#intro .lang-switch { position: absolute; top: max(8px, env(safe-area-inset-top)); right: 8px; }
/* credits: the project's Instagram and its author, quiet at the foot of the cover */
.credits { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0 10px; font-size: 13px; color: var(--ui-dim); }
.credits a { color: var(--ui); text-underline-offset: 3px; padding: 8px 2px; }
.credits a:hover { color: var(--blanco); }
#intro .credits { position: absolute; left: 16px; right: 16px; bottom: max(6px, env(safe-area-inset-bottom)); z-index: 1; }
#intro .wordmark, #intro .tagline, #intro .ctas, #intro .lang-switch, #intro .credits { transition: opacity .35s ease; }
body.entering #intro .wordmark, body.entering #intro .tagline, body.entering #intro .ctas,
body.entering #intro .lang-switch, body.entering #intro .credits { opacity: 0; }
/* the logo grows into the journey's first eye (main.js sets --to: its place and size there) */
body.entering #intro .logo-wrap { transform: var(--to, scale(2.5)); }
body.entering #intro .logo-echo { opacity: 0; transition: opacity .45s ease; }
body.in-exp #intro { display: none; }
/* the stills journey (no zoom): the cover just fades out first */
body.leaving-cover #intro { opacity: 0; pointer-events: none; transition: opacity .4s ease; }

/* ---------- the loading screen (owner 2026-11-05: «una pantalla de carga para la experiencia que permita hacer una
   transición más suave», then «mejora la pantalla de carga»). In the dark the zoom ends in, the logo's eye draws itself
   in light while the scenes compile and the láminas arrive (logo.loaderSvg; main.js writes the progress as --p, 0..1),
   its colour copies trailing behind the white line; stars fly out of the pupil (loader.js); no words (owner 2026-11-08:
   «Quita eso de abriendo la mirada»). The eye is drawn exactly where and as large as the journey's first frame draws the logo (the
   scene's unit is half the screen's shorter side, --m / 2), so when everything is in, the journey fades in under the
   line art and the drawing becomes that eye. ---------- */
#loader {
  --m: min(100vw, 100vh); --m: min(100vw, 100dvh); --p: 0; --px: .0059;
  position: fixed; inset: 0; z-index: 6; overflow: hidden; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .9s ease .15s, visibility 0s linear 1.05s;
}
body.loading #loader { opacity: 1; visibility: visible; transition: opacity .5s ease; }
/* a faint violet aura round the eye, where the journey's cosmos will be */
#loader::before {
  content: ''; position: absolute; left: 50%; top: 50%; width: calc(1.7 * var(--m)); height: calc(1.3 * var(--m));
  translate: -50% -50%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(123, 77, 255, .16), rgba(255, 43, 194, .07) 45%, rgba(34, 71, 255, .04) 70%, transparent);
}
.loader-eye {
  position: absolute; left: 50%; top: 50%; width: calc(1.25 * var(--m)); height: calc(.95 * var(--m));
  translate: -50% -50%; overflow: visible;
}
/* widths in the eye's own units: --px is one screen pixel in them (main.js), so a line is the same on every screen */
.ld-line, .ld-glow { fill: none; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; }
.ld-line { stroke: var(--blanco); stroke-width: calc(1.6 * var(--px)); transition: stroke-dashoffset .6s ease; }
/* each line has its own stretch of the progress: the outline first, then its inner edge, then the disc */
.ld-outer { stroke-dashoffset: calc(1 - clamp(0, var(--p) / .72, 1)); }
.ld-inner { stroke-dashoffset: calc(1 - clamp(0, (var(--p) - .1) / .7, 1)); stroke-opacity: .55; stroke-width: calc(1 * var(--px)); }
.ld-disc { stroke-dashoffset: calc(1 - clamp(0, (var(--p) - .22) / .66, 1)); stroke-opacity: .8; }
.ld-glow {
  stroke: var(--violeta); stroke-width: calc(9 * var(--px)); stroke-opacity: .22; stroke-dashoffset: calc(1 - clamp(0, var(--p) / .72, 1));
  transition: stroke-dashoffset 1s ease;
}
/* the colour copies of the outline (the logo's own offsets) trail the white line */
.ld-copy .ld-line { stroke-width: calc(1.3 * var(--px)); mix-blend-mode: screen; }
.ld-copy.c-magenta .ld-line { stroke: var(--magenta); stroke-opacity: .75; transition-duration: 1.1s; }
.ld-copy.c-azul .ld-line { stroke: var(--cian); stroke-opacity: .65; transition-duration: 1.6s; }
/* the three lights come one after another at the end */
.ld-light {
  fill: var(--blanco); transform-box: fill-box; transform-origin: center;
  opacity: clamp(0, calc((var(--p) - .8 - var(--i) * .05) / .06), 1); scale: calc(.4 + .6 * clamp(0, calc((var(--p) - .8 - var(--i) * .05) / .06), 1));
  transition: opacity .5s ease, scale .6s cubic-bezier(.2, .7, .2, 1.3);
}
/* the stars fly out of the pupil and fade */
.ld-stars { position: absolute; inset: 0; }
.ld-star {
  position: absolute; left: calc(50% + .0775 * var(--m)); top: calc(50% - .0198 * var(--m));
  width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2); border-radius: 50%;
  background: var(--c); opacity: 0; animation: ld-fly var(--d) linear var(--dl) infinite;
}
@keyframes ld-fly {
  0% { translate: calc(var(--x) * var(--a) * var(--m)) calc(var(--y) * var(--a) * var(--m)); opacity: 0; scale: .6; }
  25% { opacity: var(--o); }
  100% { translate: calc(var(--x) * var(--b) * var(--m)) calc(var(--y) * var(--b) * var(--m)); opacity: 0; scale: 1.6; }
}
/* reduced motion: no stars, the lines drawn without transitions */
body.reduced .ld-stars { display: none; }
body.reduced .ld-line, body.reduced .ld-glow, body.reduced .ld-light { transition: none; }
/* the zoomed cover leaves the logo's colour copies at 26 times their size, flickering at the screen's edge (owner
   2026-11-05: «¿qué es eso que titila? En la pantalla de carga»): from showAfter on it fades out, into the journey or
   into the dark round the loading screen (before, it stayed until it was cut away at once) */
body.deep #intro { opacity: 0; transition: opacity .3s ease .25s; }   /* (the scene is in under the logo by then) */

/* ---------- the first screen (owner 2026-11-08: «Crea una pantalla de carga inicial para el landing, que ayude a
   minimizar ese momento de carga de la primera animación»). The page opens on the loading screen's eye in the dark
   (index.html has it from the first paint), the cover hidden under it, while the journey's start gets ready unseen
   (main.js, loader.js BOOT). Until the script runs the eye draws itself by time (boot-draw; then main.js writes --p).
   Then it lands (body.landing): the cover logo, waiting under the eye as the entry's first eye (main.js sets --to),
   fills in as the eye's lines fade; body.booting goes, and it flies to its place while the screen fades and the words
   come in. Arrivals that go straight into the journey (#entrar, #studio: :target) never see it. Should the script not
   run, the screen goes by itself after BOOT.failsafe (10 s), and with scripts off a <noscript> style shows the cover. */
@property --p { syntax: '<number>'; inherits: true; initial-value: 0; }
body.booting:not(:has(:target)) #loader { opacity: 1; visibility: visible; transition: none; animation: boot-off .6s ease 10s forwards; }
body.booting:not(:has(:target)):not(.landing) #intro { visibility: hidden; animation: boot-on .6s ease 10s forwards; }
body.booting:not(:has(:target)) #intro .logo-wrap { opacity: 0; transform: var(--to, none); transition: none; animation: boot-on .6s ease 10s forwards; }
body.booting:not(:has(:target)) .loader-eye { animation: boot-draw 1.2s cubic-bezier(.3, .6, .4, 1) forwards; }
@keyframes boot-off { to { opacity: 0; visibility: hidden; } }
@keyframes boot-on { to { visibility: visible; opacity: 1; transform: none; } }
@keyframes boot-draw { from { --p: 0; } to { --p: .62; } }
/* one screen pixel in the eye's units (2 / the shorter side) before main.js measures it: in steps, within a tenth */
@media (min-width: 360px) and (min-height: 360px) { #loader { --px: .0051; } }
@media (min-width: 430px) and (min-height: 430px) { #loader { --px: .00423; } }
@media (min-width: 520px) and (min-height: 520px) { #loader { --px: .00352; } }
@media (min-width: 620px) and (min-height: 620px) { #loader { --px: .00295; } }
@media (min-width: 740px) and (min-height: 740px) { #loader { --px: .00248; } }
@media (min-width: 880px) and (min-height: 880px) { #loader { --px: .00208; } }
@media (min-width: 1050px) and (min-height: 1050px) { #loader { --px: .00175; } }
@media (min-width: 1250px) and (min-height: 1250px) { #loader { --px: .00148; } }
@media (min-width: 1480px) and (min-height: 1480px) { #loader { --px: .00124; } }
@media (min-width: 1750px) and (min-height: 1750px) { #loader { --px: .00105; } }
@media (min-width: 2070px) and (min-height: 2070px) { #loader { --px: .00089; } }
/* the cover logo waits as the journey's eye: its copies at rest at their own offsets, no breath, no echoes */
body.booting:not(:has(:target)) #intro .logo-svg { --aluc-bk: 0; }
body.booting:not(:has(:target)) #intro .logo-copy { transform: translate(var(--dx), var(--dy)); }
body.booting:not(:has(:target)) #intro .logo-echo { opacity: 0; }
/* landing: the logo fills in under the eye's lines as they fade (the same place and size), the words wait */
body.booting.landing #intro .logo-wrap { opacity: 1; transition: opacity .45s ease .1s; }
body.landing .loader-eye { opacity: 0; transition: opacity .45s ease .1s; }
body.booting.landing #intro .wordmark, body.booting.landing #intro .tagline, body.booting.landing #intro .ctas, body.booting.landing #intro .lang-switch, body.booting.landing #intro .credits { opacity: 0; transition: none; }
body.landing #intro .wordmark, body.landing #intro .tagline, body.landing #intro .ctas, body.landing #intro .lang-switch, body.landing #intro .credits { transition-delay: .35s; }
body.landing #intro .logo-echo { transition: opacity .5s ease .5s; }
/* while the eye stands in for the journey's and flies to its place, the cover takes no press: a click on the eye would
   send it to its place and straight back into the zoom */
body.landing #intro, body.returning #intro { pointer-events: none; }
/* cut without its transitions (main.js cutBoot: a late script, a tab nobody looked at) */
body.boot-cut #loader, body.boot-cut #loader *, body.boot-cut #intro, body.boot-cut #intro * { transition: none !important; }

/* ---------- back to the cover (owner 2026-11-08: «Si le doy a logo de alucinación desde la experiencia para volver al
   landing principal, la transición también debe ser fluida»; main.js toCover): the entry backwards. The cover logo
   comes in over the zoom journey as its first eye (the same place and size: main.js sets --to), its copies at rest like
   the scene's, while the journey fades out under it; then it flies back to its place and the words come in
   (body.landing, above). The journey's buttons fade out with it. From the stills: they fade out, the cover fades in. */
body.returning #intro .logo-wrap { opacity: 0; transform: var(--to, none); transition: none; }
body.returning.filling #intro .logo-wrap { opacity: 1; transition: opacity .45s ease; }
body.returning #intro .logo-svg { --aluc-bk: 0; }
body.returning #intro .logo-copy { transform: translate(var(--dx), var(--dy)); }
body.returning #intro .logo-echo, body.returning #intro .wordmark, body.returning #intro .tagline, body.returning #intro .ctas, body.returning #intro .lang-switch, body.returning #intro .credits { opacity: 0; transition: none; }
body.returning .hud { display: flex; }
body.returning #hint { display: block; }
body.returning .hud, body.leaving-stills .hud { opacity: 0; pointer-events: none; transition-duration: .35s; }
body.leaving-stills #stills { opacity: 0; transition: opacity .4s ease; }
body.cover-back #intro { animation: cover-back .4s ease both; }
@keyframes cover-back { from { opacity: 0; } }

/* ---------- HUD during the journey ---------- */
.hud { position: fixed; z-index: 4; display: none; align-items: center; gap: 8px; font-size: 13px; }
body.in-exp .hud, body.in-stills .hud { display: flex; }
body.no-hud .hud, body.no-hud #hint { display: none !important; }
body:not(.debug) #chapter { display: none !important; } /* one continuous world: no chapter numbers outside debug */
.hud-tl { top: max(14px, env(safe-area-inset-top)); left: 16px; }
.hud-tr { top: max(12px, env(safe-area-inset-top)); right: calc(24px + var(--mark-w)); flex-wrap: wrap; justify-content: flex-end; gap: 10px 14px; }
/* the brand's eye in the top right corner for the whole journey and the stills (owner 2026-11-05: «agregar el logo de
   alucinación durante toda la experiencia, en la esquina superior derecha»): outside the HUD, so it stays when the
   buttons go away or are hidden; the buttons sit to its left. It is the cover's logo (logo.svg, its own ids). */
:root { --mark-w: 58px; }
.corner-logo {
  position: fixed; z-index: 4; top: max(10px, env(safe-area-inset-top)); right: 14px; width: var(--mark-w); aspect-ratio: 2.5 / 1.9;
  pointer-events: none; opacity: 0; visibility: hidden; transition: opacity .7s ease, visibility 0s linear .7s;
}
body.in-exp .corner-logo, body.in-stills .corner-logo { opacity: 1; visibility: visible; transition: opacity .7s ease, visibility 0s; }
/* like the brand's name (top left), it takes the visitor back to the cover (main.js toCover) */
body.in-exp a.corner-logo, body.in-stills a.corner-logo { pointer-events: auto; cursor: pointer; }
/* and it lives like the cover's eye (owner 2026-11-08: «El logo de la esquina le falta alguna animación o efecto de luz
   ... Debería seguir el mouse o hacer algo, está demasiado plano, se ve como una imagen puesta»): its pupil follows the
   pointer and looks around when nobody points (main.js), its colour copies stand further out (at this size the cover's
   offsets are under a pixel) and circle round their places, it breathes, and a soft light breathes behind its pupil.
   Only while it shows; nothing moves with reduced motion (the end of this file). */
.corner-logo::before {
  content: ''; position: absolute; left: 56.2%; top: 47.92%; width: 150%; height: 170%; translate: -50% -50%; z-index: -1;
  border-radius: 50%; opacity: .6;
  background: radial-gradient(closest-side, rgba(123, 77, 255, .42), rgba(255, 43, 194, .15) 55%, transparent);
}
.corner-logo .logo-svg { transform-origin: 56.2% 47.92%; }
.corner-logo .logo-copy { transform: translate(calc(2.4 * var(--dx)), calc(2.4 * var(--dy))); translate: calc(cos(var(--aluc-a)) * .02px) calc(sin(var(--aluc-a)) * .02px); }
body:is(.in-exp, .in-stills) .corner-logo::before { animation: mark-glow 6s ease-in-out infinite; }
body:is(.in-exp, .in-stills) .corner-logo .logo-svg { animation: mark-breathe 6s ease-in-out infinite; }
body:is(.in-exp, .in-stills) .corner-logo .logo-copy { animation: aluc-turn 9s linear infinite; }
@keyframes mark-glow { 0%, 100% { opacity: .45; scale: .9; } 50% { opacity: 1; scale: 1.06; } }
@keyframes mark-breathe { 50% { scale: 1.04; } }
.hud-bl { bottom: max(14px, env(safe-area-inset-bottom)); left: 16px; color: var(--ui-dim); font-variant-numeric: tabular-nums; }
.hud .mini-mark { font: 700 18px/1 var(--f-marca); text-decoration: none; }
.chip {
  appearance: none; border: 1px solid var(--filo); background: var(--vidrio); color: var(--ui);
  font: 600 12.5px/1 var(--f-ui); padding: 9px 12px; border-radius: 999px; cursor: pointer; text-decoration: none;
  min-height: 34px; display: inline-flex; align-items: center;
}
.chip:hover, .chip[aria-pressed="true"] { color: var(--blanco); border-color: var(--ui); }
/* ---------- the journey's buttons (owner 2026-11-08: «Los botones de la experiencia están muy feos, mejóralos») ----------
   The Studio button is a piece of the logo: the logo's black (its white for the Studio call at the end), with the
   cover's five colour copies peeking out behind it at the cover's offsets (logo.js COPIES; box-shadow paints front to
   back: cyan, red, magenta, blue, yellow; --cs is the size of a logo unit). Under the pointer they spread a little, as
   the cover's eye does, and close in on a press. The journey's own controls (pause, hide the buttons, reduced motion
   and the language) share one quiet glass bar, each with its icon; a pressed control shows its other icon. */
@property --cs { syntax: '<length>'; inherits: false; initial-value: 80px; }
.chip.studio, .chip.cta {
  --cs: 80px; min-height: 36px; padding: 0 17px; border: 0; font: 700 13px/1 var(--f-marca);
  box-shadow: calc(var(--cs) * 0.017) calc(var(--cs) * 0.004) 0 var(--cian), calc(var(--cs) * -0.014) calc(var(--cs) * -0.016) 0 var(--rojo),
    calc(var(--cs) * -0.032) calc(var(--cs) * 0.012) 0 var(--magenta), calc(var(--cs) * 0.034) calc(var(--cs) * 0.009) 0 var(--azul),
    calc(var(--cs) * -0.024) calc(var(--cs) * -0.026) 0 var(--amarillo);
  transition: --cs .45s cubic-bezier(.2, .7, .2, 1);
}
.chip.studio { background: var(--negro); color: var(--blanco); }
.chip.studio:hover, .chip.cta:hover, .chip.studio:focus-visible, .chip.cta:focus-visible { --cs: 130px; }
.chip.studio:active, .chip.cta:active { --cs: 40px; transition-duration: .12s; }
.chip.studio:focus-visible, .chip.cta:focus-visible { outline-offset: 6px; }
.hud-ctrl {
  display: flex; align-items: center; gap: 2px; height: 36px; padding: 3px; border-radius: 999px;
  background: rgba(5, 5, 7, .5); border: 1px solid rgba(250, 250, 244, .14);
  backdrop-filter: blur(12px) saturate(1.4); -webkit-backdrop-filter: blur(12px) saturate(1.4);
}
.ctrl {
  appearance: none; position: relative; display: inline-flex; align-items: center; gap: 7px; height: 100%; padding: 0 12px 0 10px;
  border: 0; border-radius: 999px; background: transparent; color: var(--ui); font: 600 12.5px/1 var(--f-ui); cursor: pointer;
  transition: color .2s ease, background-color .2s ease;
}
.ctrl:hover { color: var(--blanco); background: rgba(250, 250, 244, .08); }
.ctrl[aria-pressed="true"] { color: var(--blanco); background: rgba(250, 250, 244, .16); }
.ctrl:focus-visible { outline-offset: -2px; }
.ico { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.ico .i-on { display: none; }
.ctrl[aria-pressed="true"] .i-off { display: none; }
.ctrl[aria-pressed="true"] .i-on { display: inline; }
#btn-pause .i-on { fill: currentColor; stroke-width: 1.2; }
/* the language: the current one lit, the other one the link (the « · » between them stays in the markup, unseen) */
.hud .lang-switch { gap: 2px; height: 100%; margin-left: 2px; font-size: 0; }
.hud .lang-switch [aria-current], .hud .lang-switch a {
  display: inline-flex; align-items: center; height: 100%; padding: 0 9px; border-radius: 999px; font: 700 11.5px/1 var(--f-ui); letter-spacing: .04em;
}
.hud .lang-switch [aria-current] { color: var(--blanco); background: rgba(250, 250, 244, .16); }
.hud .lang-switch a { color: var(--ui-dim); transition: color .2s ease, background-color .2s ease; }
.hud .lang-switch a:hover { color: var(--blanco); background: rgba(250, 250, 244, .08); }
/* the HUD rests out of sight after the pointer is still a while, after a long scroll, or always in «Ocultar botones»
   mode (then the band at the top brings it back); it fades back in as the pointer moves (main.js) */
.hud { transition: opacity .7s ease, translate .7s cubic-bezier(.2, .7, .2, 1); }
body.hud-away .hud { opacity: 0; pointer-events: none; }
body.hud-away .hud-tl, body.hud-away .hud-tr { translate: 0 -8px; }
body.hud-away .hud-bl { translate: 0 8px; }
body.hud-away .hud:focus-within { opacity: 1; pointer-events: auto; translate: none; }
.chip.cta { background: var(--blanco); color: var(--negro); display: none; }
body.returned .chip.cta { display: inline-flex; }
/* the Studio opens later: once its call is up, the plain Studio chip would only say the same thing twice */
body.returned .hud-tr a.chip:not(.cta) { display: none; }

#hint {
  position: fixed; left: 0; right: 0; bottom: 64px; z-index: 3; text-align: center; color: var(--ui);
  font-size: 13px; pointer-events: none; display: none; transition: opacity .6s ease;
}
body.in-exp #hint { display: block; }

/* ---------- Narrative lines (few, quiet) ---------- */
#story { position: fixed; inset: 0; z-index: 3; pointer-events: none; }
.line {
  position: absolute; left: 16px; right: 16px; bottom: 18vh; text-align: center; margin: 0; opacity: 0;
  font: 600 clamp(20px, 3.4vmin, 30px)/1.25 var(--f-marca); text-wrap: balance;
  text-shadow: 0 2px 18px rgba(5, 5, 7, .9), 0 0 2px rgba(5, 5, 7, .9);
}
/* The card at the end of every lap and the Studio card (main.js, openStudio) are one card (owner 2026-11-09: «Cuando
   finalice el loop debe aparecer el mismo texto que cuando se da click en crea el mundo de tu marca»): the offer of
   studio.html (creative web experiences, the owner's contacts) over the living scene, with a soft shade behind its words
   so they read over any stop; the Studio card adds its button back to the journey */
.return-card, .studio-card {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: min(100% - 32px, 620px); opacity: 0; visibility: hidden;
  display: flex; flex-direction: column; align-items: center; text-align: center; text-shadow: 0 2px 22px rgba(5, 5, 7, .95), 0 0 3px rgba(5, 5, 7, .9);
}
.return-card::before, .studio-card::before {
  content: ""; position: absolute; inset: -22% -18%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(5, 5, 7, .84), rgba(5, 5, 7, .56) 58%, rgba(5, 5, 7, 0));
}
/* STORY_FADE: the lines and the card are switched on and off by the journey (main.js) and fade by time, never by
   position, so none stays half see-through while the camera goes slowly; the card is hidden once faded out */
#story .line { transition: opacity .7s ease; }
#story .line.on { opacity: 1; }
#story .return-card { transition: opacity .7s ease, visibility 0s linear .7s; }
#story .return-card.on { opacity: 1; visibility: visible; transition: opacity .7s ease, visibility 0s; }
#story .studio-card { transition: opacity .7s ease, visibility 0s linear .7s; }
#story .studio-card.on { opacity: 1; visibility: visible; transition: opacity .7s ease, visibility 0s; }
.return-card .opening, .studio-card .opening {
  display: flex; align-items: center; gap: 14px; margin: 0; color: var(--ui);
  font: 600 12.5px/1 var(--f-ui); letter-spacing: .2em; text-transform: uppercase;
}
:is(.return-card, .studio-card) .opening::before, :is(.return-card, .studio-card) .opening::after { content: ""; width: clamp(24px, 6vw, 44px); height: 1px; background: var(--filo); }
.return-card .title, .studio-card h2 { margin: 18px 0 0; font: 700 clamp(30px, 5.6vmin, 56px)/1.08 var(--f-marca); letter-spacing: -.015em; }
.return-card .lead, .studio-card .lead { margin: 18px 0 0; max-width: 31em; color: var(--blanco); font-size: clamp(16px, 2.3vmin, 19px); line-height: 1.5; text-wrap: balance; }
.return-card .note, .studio-card .note { margin: 10px 0 0; color: var(--ui); font-size: clamp(14px, 1.9vmin, 15.5px); line-height: 1.5; text-wrap: balance; }
.return-card .call, .studio-card .call { margin: 24px 0 12px; font: 600 clamp(17px, 2.6vmin, 22px)/1.25 var(--f-marca); text-wrap: balance; }
.return-card .contact, .studio-card .contact { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.return-card .btn, .studio-card .btn { pointer-events: auto; text-shadow: none; }
.studio-card #studio-go { margin-top: 14px; }
/* while it is open the Studio chips would only open it again */
body.studio-open .hud-tr a.chip { display: none; }

/* ---------- Stills journey ---------- */
/* stills.js fills #stills. The scroller is the whole screen; a sticky stage keeps the stills in place while the visitor
   scrolls. Each step is one screen of scroll (--vh, set by the script) with a snap point at its top. A still fades in
   over the one before it (which stays whole beneath until the fade ends) over --fade, set by the script from FADE_MS.
   Only opacity changes. A still that is missing keeps the gradient of its stop and its story line. */
body.in-stills #intro { display: none; }
/* the WebGL journey's own lines, card and chapter label freeze when it hands over: they must not stay over the stills */
body.in-stills #story, body.in-stills #chapter { display: none; }
body.in-stills #btn-pause, body.stills-only #btn-reduced { display: none; }
.stills {
  position: fixed; inset: 0; z-index: 2; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  scroll-snap-type: y mandatory; touch-action: pan-y; background: var(--negro); outline: none;
}
.stills-track { position: relative; height: calc(var(--vh) * var(--steps)); }
.stills-snap { position: absolute; left: 0; width: 1px; height: var(--vh); top: calc(var(--vh) * var(--i)); scroll-snap-align: start; scroll-snap-stop: always; pointer-events: none; }
.stills-stage { position: sticky; top: 0; height: var(--vh); overflow: hidden; }
.stills-layers { list-style: none; margin: 0; padding: 0; position: absolute; inset: 0; }
.still {
  position: absolute; inset: 0; z-index: 0; background: var(--bg); opacity: 0; visibility: hidden;
  transition: opacity var(--fade) ease, visibility 0s linear var(--fade);
}
.still.on { z-index: 2; opacity: 1; visibility: visible; transition: opacity var(--fade) ease, visibility 0s; }
.still.prev { z-index: 1; opacity: 1; visibility: visible; transition: none; }
.still picture, .still img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.still img { object-fit: cover; opacity: 0; transition: opacity var(--fade) ease; }
.still.loaded img { opacity: 1; }
.still::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: linear-gradient(to top, rgba(5, 5, 7, .6), rgba(5, 5, 7, 0) 45%); }
.still.is-return::after { background: rgba(5, 5, 7, .5); }
.stills .line, .stills .return-card { z-index: 1; opacity: 1; }
.stills .return-card { visibility: inherit; }
.stills-nav { position: absolute; left: 0; right: 0; bottom: max(14px, env(safe-area-inset-bottom)); z-index: 3; display: flex; align-items: center; justify-content: center; gap: 12px; pointer-events: none; }
.stills-nav .chip { pointer-events: auto; min-width: 44px; justify-content: center; font-size: 18px; }
.stills-nav .chip[aria-disabled="true"] { opacity: .35; cursor: default; }
.stills-progress { width: min(160px, 30vw); height: 2px; background: var(--filo); border-radius: 2px; overflow: hidden; }
.stills-progress i { display: block; height: 100%; width: 0; background: var(--ui); }

/* ---------- Panels ---------- */
.panel {
  position: fixed; inset: auto 16px 16px 16px; max-width: 460px; margin: 0 auto; z-index: 8;
  background: rgba(18, 18, 24, .94); border: 1px solid var(--filo); border-radius: 16px; padding: 18px 18px 16px;
  display: none; flex-direction: column; gap: 10px;
}
.panel.open { display: flex; }
.panel h2 { margin: 0; font: 700 19px/1.2 var(--f-marca); }
.panel p { margin: 0; color: var(--ui); }
.panel .btn { align-self: flex-start; }
#errors {
  position: fixed; left: 8px; right: 8px; bottom: 8px; z-index: 9; max-height: 40vh; overflow: auto; display: none;
  background: #2a0b0e; color: #ffd4d4; font: 12px/1.4 ui-monospace, Consolas, monospace; white-space: pre-wrap;
  padding: 10px; border-radius: 8px; border: 1px solid #ff6b6b;
}

@media (max-width: 820px) {
  /* narrower screens: the bar keeps its icons; each word comes up under its icon on hover or keyboard focus, and stays
     the button's name for screen readers */
  .ctrl { padding: 0 10px; }
  .ctrl .lbl {
    position: absolute; top: calc(100% + 10px); left: 50%; translate: -50% -4px; padding: 6px 9px; border-radius: 8px;
    background: rgba(5, 5, 7, .85); color: var(--blanco); font-size: 12px; white-space: nowrap; pointer-events: none;
    opacity: 0; transition: opacity .2s ease, translate .2s ease;
  }
  .ctrl:focus-visible .lbl { opacity: 1; translate: -50% 0; }
}
@media (max-width: 820px) and (hover: hover) {
  .ctrl:hover .lbl { opacity: 1; translate: -50% 0; }
}
@media (max-width: 600px) {
  :root { --mark-w: 46px; }
  .line { bottom: 22vh; }
}
@media (max-width: 560px) {
  /* a phone: the buttons get a row of their own under the wordmark and the eye */
  .hud-tr { top: calc(max(12px, env(safe-area-inset-top)) + 46px); left: 16px; right: 14px; justify-content: flex-start; pointer-events: none; }
  .hud-tr > * { pointer-events: auto; }
  .chip.studio, .chip.cta { padding: 0 14px; font-size: 12px; }
  .ctrl { padding: 0 9px; }
  .hud .lang-switch [aria-current], .hud .lang-switch a { padding: 0 8px; }
}
/* reduced motion is the HUD button's (main.js sets body.reduced), never the system preference: motion is on by default */
body.reduced #intro .logo-wrap, body.reduced #intro .logo-move, body.reduced .logo-copy, body.reduced .chip.studio, body.reduced .chip.cta { transition: none; }
body.reduced #intro .logo-svg { animation: none; }
body.reduced .corner-logo .logo-svg, body.reduced .corner-logo .logo-copy, body.reduced .corner-logo::before { animation: none; }
body.reduced .corner-logo .logo-copy { translate: none; }
body.reduced #intro .logo-echo { display: none; }
body.reduced #intro .logo-wrap { view-transition-name: none; }
body.reduced.entering #intro .logo-wrap { transform: none; opacity: 0; transition: opacity .3s ease; }
