/* RE-Lab site v12. One full-screen scene that never scrolls: a binary, shown as a crystal, across five chapters.
   Almost everything visual is the WebGL scene; the DOM is the small type around it and the title drum below.
   The scene publishes --ox / --oy (crystal centre) and --drum-y (drum centre), in CSS pixels. */
:root {
  --black: #050505;
  --t92: rgba(244, 242, 238, .92);
  --t62: rgba(244, 242, 238, .62);
  --t42: rgba(244, 242, 238, .42);
  --t24: rgba(244, 242, 238, .24);
  --mint: #5eead4;
  --expo: cubic-bezier(.22, 1, .36, 1);
  --in: cubic-bezier(.55, 0, .75, .2);
  --wipe: cubic-bezier(.65, 0, .35, 1);
  --edge: max(30px, env(safe-area-inset-left, 0px));
  --edge-r: max(30px, env(safe-area-inset-right, 0px));
  --edge-b: max(26px, env(safe-area-inset-bottom, 0px));
  --ox: 50vw; --oy: 42vh; --drum-y: 85.5vh;            /* fallbacks until the scene reports its layout */
  --DT: clamp(40px, min(7.4vw, 10.6vh), 132px);        /* drum title size */
  --R: 46vw;                                            /* drum radius */
  color-scheme: dark;
}
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; background: var(--black); }
body { color: var(--t92); font-family: var(--font-sans); font-size: 14px; line-height: 1.5; letter-spacing: .01em; touch-action: none; -webkit-font-smoothing: antialiased; cursor: grab; }
.over-crystal body, .over-crystal { cursor: crosshair; }
.is-dragging, .is-dragging body { cursor: grabbing; }
a { color: inherit; text-decoration: none; cursor: pointer; }
:focus-visible { outline: 1px solid rgba(244, 242, 238, .7); outline-offset: 4px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* scene */
.scene { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; }
.scene-still { position: fixed; left: var(--ox); top: var(--oy); width: min(30vh, 46vw); height: auto; transform: translate(-50%, -50%); opacity: .85; }
.js .scene-still { display: none; }                   /* only without the scene: no script, or no WebGL2 */
.no-gl .scene-still { display: block; }
.no-gl .loader, .no-gl .loading, .no-gl .windows { display: none; }
/* without WebGL: the scene's palette as a painted backdrop (night sky, a low moon, the glow of the horizon) */
.no-gl body, html:not(.js) body {
  background:
    radial-gradient(circle at 63% 52%, rgba(236, 234, 230, .5) 0 5.5vh, rgba(236, 234, 230, .07) 5.6vh, transparent 20vh),
    linear-gradient(180deg, #030303 0%, #060707 45%, #121314 62%, #050505 63%, #020202 100%);
}
/* without WebGL the grain comes from CSS (the scene draws its own) */
.no-gl body::after, html:not(.js) body::after {
  content: ""; position: fixed; inset: -60%; z-index: 40; pointer-events: none; opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- intro ---------- */
.loader { position: fixed; z-index: 30; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; transition: opacity .5s ease-out; }
.loader__line { fill: none; stroke: rgba(236, 234, 230, .72); stroke-width: 1.5; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: calc(1 - var(--boot, 0)); }
.loader__tip { fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-dasharray: .018 1; stroke-dashoffset: calc(1.009 - var(--boot, 0)); filter: drop-shadow(0 0 5px rgba(255, 255, 255, .9)); }
.is-wired .loader { opacity: 0; }
.no-intro .loader, .no-intro .windows { display: none; }

/* analysis windows: frames only; the scene draws each one's contents (the crystal in that pass) */
.windows { position: fixed; inset: 0; z-index: 31; pointer-events: none; }
/* window labels only: the scene draws each window's frame, title bar and contents */
.win { position: absolute; left: 0; top: 0; width: var(--w, 0); transform: translate(var(--x, 0), var(--y, 0)); opacity: var(--o, 0); }
.win p { display: flex; align-items: center; gap: 5px; height: 22px; margin: 0; padding: 0 9px; font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em; color: var(--t62); }
.win p i { width: 6px; height: 6px; border-radius: 50%; background: rgba(244, 242, 238, .22); }
.win p b { margin-left: 6px; font-weight: 500; color: var(--t92); }
.win--ok p b { color: var(--mint); }

/* corner UI fades in near the end of the reveal */
.ui { opacity: 0; }
.is-ui .ui { animation: ui-in .9s ease-out forwards; }
@keyframes ui-in { to { opacity: 1; } }

/* ---------- header ---------- */
.top { position: fixed; z-index: 20; top: 0; left: 0; right: 0; display: flex; justify-content: space-between; align-items: center; padding: max(24px, env(safe-area-inset-top, 0px)) var(--edge-r) 24px var(--edge); pointer-events: none; }
.top a { pointer-events: auto; position: relative; }
.top a::after { content: ""; position: absolute; inset: -14px -10px; }
/* the logo: its node is the brand's light; it brightens and sends out a ring on hover, once as the page arrives */
.brand__logo { display: block; width: 112px; height: auto; overflow: visible; }
.brand__node { fill: #14b8a6; transition: fill .4s; }
.brand__ping { fill: none; stroke: var(--mint); stroke-width: 4; opacity: 0; transform-box: fill-box; transform-origin: center; }
.is-ui .brand__ping { animation: ping 1.6s var(--expo) .9s 1; }
.brand:hover .brand__node, .brand:focus-visible .brand__node { fill: var(--mint); }
.brand:hover .brand__ping, .brand:focus-visible .brand__ping { animation: ping 1.4s var(--expo) infinite; }
@keyframes ping { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(2.7); } }
.top__r { display: flex; align-items: center; gap: 24px; }
/* a live status: founding pilots are open (it opens that chapter) */
.status {
  display: inline-flex; align-items: center; gap: 9px; height: 30px; padding: 0 14px 0 12px; border-radius: 999px;
  border: 1px solid rgba(244, 242, 238, .16); background: rgba(8, 9, 10, .45); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--t62);
  transition: border-color .35s, color .35s, background .35s;
}
.status:hover, .status:focus-visible { border-color: rgba(244, 242, 238, .42); color: var(--t92); background: rgba(244, 242, 238, .06); }
.status i { width: 6px; height: 6px; border-radius: 50%; background: var(--mint); animation: live 2.4s ease-out infinite; }
@keyframes live { 0% { box-shadow: 0 0 0 0 rgba(94, 234, 212, .6); } 70%, 100% { box-shadow: 0 0 0 7px rgba(94, 234, 212, 0); } }
::selection { background: rgba(94, 234, 212, .32); color: #fff; }

/* ---------- the probe: a small label that follows the cursor over the crystal ---------- */
.probe {
  position: fixed; z-index: 25; left: 0; top: 0; display: grid; gap: 3px; padding: 8px 11px 7px; pointer-events: none;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; color: var(--t62); white-space: nowrap;
  background: rgba(6, 9, 11, .62); border: 1px solid rgba(244, 242, 238, .16); border-radius: 6px;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  opacity: 0; transform: translate3d(-999px, -999px, 0); transition: opacity .25s ease-out;
}
.probe b { display: flex; align-items: center; gap: 7px; font-weight: 500; color: var(--t92); }
.probe b::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--mint); box-shadow: 0 0 8px var(--mint); }
.probe span { padding-left: 13px; }
.is-probing .probe { opacity: 1; }

/* ---------- title drum: a ring of titles under the crystal, turned by --stage; the front one fills letter by letter ---------- */
.drum {
  position: fixed; z-index: 10; left: 0; right: 0; top: calc(var(--drum-y) - var(--DT) * 1.05); height: calc(var(--DT) * 2.1);
  perspective: 1600px; pointer-events: none;
  /* at rest only the front title shows; the others appear as they turn through the middle */
  -webkit-mask-image: linear-gradient(90deg, transparent 20%, #000 33%, #000 67%, transparent 80%);
  mask-image: linear-gradient(90deg, transparent 20%, #000 33%, #000 67%, transparent 80%);
}
.drum__ring { position: absolute; inset: 0; transform-style: preserve-3d; transform: translateZ(calc(var(--R) * -1)) rotateY(calc(var(--stage, 0) * -50deg + var(--spin, 0deg))); }
.face {
  --f: 0;
  position: absolute; left: 50%; top: 50%; display: grid; justify-items: center;
  font-family: var(--font-mono); font-size: var(--DT); font-weight: 800; font-stretch: 112.5%;
  text-transform: uppercase; letter-spacing: -.05em; line-height: .9; white-space: nowrap;
  transform: translate(-50%, -50%) rotateY(calc(var(--fi) * 50deg)) translateZ(var(--R));
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  opacity: clamp(0, calc(var(--f) * 1.7), 1);          /* the others show only while they turn through the front */
}
.face:nth-child(1) { --fi: 0; } .face:nth-child(2) { --fi: 1; } .face:nth-child(3) { --fi: 2; } .face:nth-child(4) { --fi: 3; } .face:nth-child(5) { --fi: 4; }
.face .l { display: block; }
/* each letter fills from outline to solid in turn; the letter filling carries a white-hot glow */
.face .c {
  --a: clamp(0, calc((var(--f) * 1.45 - var(--ci, 0) / var(--n, 1)) * 5), 1);
  color: rgb(244 242 238 / var(--a));
  -webkit-text-stroke: 1px rgb(244 242 238 / calc(.55 - var(--a) * .55));
  text-shadow: 0 0 .3em rgb(255 255 255 / calc(var(--a) * (1 - var(--a)) * 2.2));
}

/* ---------- chapter copy: small text, bottom left, level with the title; its lines rise out of a mask on each change ---------- */
.sheets { position: fixed; z-index: 20; left: var(--edge); bottom: var(--edge-b); width: min(350px, calc(50vw - var(--edge) - 24px - var(--DT) * 2.9)); }
.sheets::before { content: ""; position: absolute; left: -60px; right: -80px; bottom: -40px; height: 260px; z-index: -1; pointer-events: none; background: radial-gradient(closest-side, rgba(3, 5, 6, .55), transparent); }
.sheet { position: absolute; left: 0; bottom: 0; width: 100%; visibility: hidden; transition: visibility 0s linear .5s; }
.sheet.is-on { visibility: visible; transition: none; }
.sheet > * { overflow: clip; }
.sheet > * > .ln { display: block; transform: translateY(110%); transition: transform .45s var(--in); }
.sheet.is-on > * > .ln { transform: none; transition: transform .9s var(--expo); transition-delay: calc(.08s * var(--k, 0) + .2s); }
.sheet .rollwrap { padding-top: 4px; }
.sheet .roll.ln { display: inline-flex; }
.sheet p { text-wrap: pretty; }
.sheet__k { margin: 0 0 12px; font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--t62); }
.sheet__k .ln::before { content: ""; display: inline-block; width: 16px; height: 1px; margin-right: 10px; vertical-align: .32em; background: currentColor; opacity: .8; }
.sheet p { margin: 0 0 10px; font-size: 14px; line-height: 1.55; color: var(--t62); }
.sheet__price { color: var(--t92) !important; font-size: 15px !important; font-weight: 500; }
.sheet__price .ln > span { display: block; font-family: var(--font-mono); font-size: 10px; font-weight: 400; letter-spacing: .12em; text-transform: uppercase; color: var(--t42); margin-top: 3px; }
.sheet__mailrow .ln { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.sheet__mail { display: inline-block; font-size: clamp(20px, 1.1rem + .6vw, 26px); font-weight: 500; letter-spacing: -.02em; color: var(--t92); transition: color .3s; }
.sheet__mail:hover { color: #fff; }
.copy {
  height: 26px; padding: 0 12px; border-radius: 999px; border: 1px solid rgba(244, 242, 238, .2); background: rgba(244, 242, 238, .04);
  color: var(--t62); font: 500 10px/1 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
  transition: border-color .3s, color .3s, background .3s;
}
.copy:hover, .copy:focus-visible { border-color: rgba(244, 242, 238, .5); color: var(--t92); }
.copy.is-done { border-color: var(--mint); color: var(--mint); background: rgba(20, 184, 166, .1); }
.sheet__links .ln { display: flex; gap: 18px; }
.sheet__links a[target="_blank"]::after { content: "↗"; margin-left: 4px; font-size: .9em; color: var(--t42); }
.sheet__links a { background: linear-gradient(currentColor, currentColor) left bottom / 100% 1px no-repeat; padding-bottom: 2px; transition: color .3s; }
.sheet__links a:hover { color: var(--t92); animation: wipe .8s var(--wipe); }
.sheet__legal { font-size: 11px !important; color: var(--t42) !important; margin-top: 14px !important; }
@keyframes wipe { 0% { background-size: 100% 1px; background-position: right bottom; } 50% { background-size: 0% 1px; background-position: right bottom; } 50.01% { background-position: left bottom; } 100% { background-size: 100% 1px; background-position: left bottom; } }

/* char-roll links (header and copy): letters roll up to a bright copy, the rule wipes, the arrow swaps */
.roll { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; color: var(--t92); }
.roll__t { position: relative; display: inline-flex; background: linear-gradient(currentColor, currentColor) left bottom / 100% 1px no-repeat; padding-bottom: 3px; }
.roll--nav .roll__t { background-size: 0% 1px; }
.roll__t .c { position: relative; display: inline-block; overflow: hidden; vertical-align: top; }
.roll__t .c > span { display: inline-block; transition: transform .55s var(--expo); transition-delay: calc(var(--i, 0) * 16ms); }
.roll__t .c > span::after { content: attr(data-c); position: absolute; left: 0; top: 100%; color: #fff; }
.roll:hover .roll__t .c > span, .roll:focus-visible .roll__t .c > span { transform: translateY(-100%); }
.roll:not(.roll--nav):hover .roll__t { animation: wipe .8s var(--wipe); }
.roll__a { position: relative; width: 14px; height: 14px; overflow: hidden; display: inline-block; }
.roll__a i { position: absolute; inset: 0; font-style: normal; line-height: 14px; text-align: center; transition: transform .32s var(--in); }
.roll__a i:last-child { transform: translate(-120%, 120%); color: #fff; transition: transform .45s var(--expo) .2s; }
.roll:hover .roll__a i:first-child { transform: translate(120%, -120%); }
.roll:hover .roll__a i:last-child { transform: none; }
/* the call to action: a dark glass pill whose arrow is the one teal mark on the page (the logo's node), brighter on hover */
.roll.cta {
  gap: 12px; height: 44px; padding: 0 7px 0 20px; border-radius: 999px; border: 1px solid rgba(244, 242, 238, .22);
  background: linear-gradient(180deg, rgba(244, 242, 238, .09), rgba(244, 242, 238, .02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 14px 34px -18px rgba(0, 0, 0, .9);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  transition: border-color .4s var(--expo), background .4s, box-shadow .4s;
}
.roll.cta:hover, .roll.cta:focus-visible {
  border-color: rgba(244, 242, 238, .55); background: linear-gradient(180deg, rgba(244, 242, 238, .15), rgba(244, 242, 238, .04));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 16px 40px -14px rgba(94, 234, 212, .35);
}
.roll.cta .roll__t { background: none; padding-bottom: 0; }
.roll.cta:not(.roll--nav):hover .roll__t { animation: none; }
.roll.cta .roll__a { width: 30px; height: 30px; border-radius: 50%; background: var(--mint); color: #04211d; }
.roll.cta .roll__a i { line-height: 30px; font-weight: 600; }
.roll.cta .roll__a i:last-child { color: #04211d; }

/* ---------- counter, bottom right ---------- */
.meta { position: fixed; z-index: 20; right: var(--edge-r); bottom: var(--edge-b); display: grid; justify-items: end; gap: 10px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em; color: var(--t42); text-transform: uppercase; }
.meta__count b { color: var(--t92); font-weight: 500; }
/* the counter's digits roll like an odometer */
.odo { display: inline-flex; vertical-align: top; }
.odo__d { display: inline-block; height: 1.25em; line-height: 1.25em; overflow: hidden; }
.odo__d > span { display: block; white-space: pre-line; transform: translateY(calc(var(--d, 0) * -1.25em)); transition: transform .7s var(--expo); }
.odo__d:last-child > span { transition-delay: .05s; }
/* five segments, the current chapter's long and lit */
.meta__bar { display: flex; gap: 5px; }
.meta__bar i { width: 10px; height: 2px; border-radius: 1px; background: var(--t24); transition: width .6s var(--expo), background .6s, box-shadow .6s; }
[data-chapter="0"] .meta__bar i:nth-child(1), [data-chapter="1"] .meta__bar i:nth-child(2), [data-chapter="2"] .meta__bar i:nth-child(3),
[data-chapter="3"] .meta__bar i:nth-child(4), [data-chapter="4"] .meta__bar i:nth-child(5) { width: 24px; background: var(--t92); box-shadow: 0 0 8px rgba(244, 242, 238, .35); }
.meta__probe { color: var(--t42); }
.meta__probe::before { content: ""; width: 10px; height: 10px; border: 1px solid currentColor; border-radius: 50%; background: radial-gradient(circle, var(--t92) 0 1.5px, transparent 2px); }
@media (hover: none) { .meta__probe { display: none; } }
/* loading: a boot log inside the crystal's outline, a large percentage and a bar where the title will stand */
.boot { position: fixed; inset: 0; z-index: 29; pointer-events: none; transition: opacity .45s ease-out; }
.boot__log {
  position: absolute; left: var(--ox); top: var(--oy); transform: translate(-50%, -50%); width: max-content; margin: 0; padding: 0; list-style: none;
  font-family: var(--font-mono); font-size: 10.5px; line-height: 2; letter-spacing: .04em; color: var(--t62);
}
.boot__log li { opacity: 0; clip-path: inset(0 100% 0 0); white-space: nowrap; transition: clip-path .45s steps(16), opacity .15s; }
.boot__log li::before { content: "› "; color: var(--t42); }
.boot__log li.is-on { opacity: 1; clip-path: inset(0 0 0 0); }
.boot__log li.is-on:not(:has(+ li.is-on))::after { content: ""; display: inline-block; width: 6px; height: 11px; margin-left: 4px; vertical-align: -1px; background: var(--t92); animation: caret .8s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
.boot__pct { position: absolute; left: 0; right: 0; top: calc(var(--drum-y, 85vh) - 30px); margin: 0; text-align: center; font-family: var(--font-mono); font-size: 34px; font-weight: 500; letter-spacing: -.02em; color: var(--t92); font-variant-numeric: tabular-nums; }
.boot__pct small { margin-left: 3px; font-size: 14px; color: var(--t42); }
.boot__bar { position: absolute; left: 50%; top: calc(var(--drum-y, 85vh) + 22px); width: 180px; height: 1px; margin-left: -90px; background: rgba(244, 242, 238, .14); overflow: hidden; }
.boot__bar i { position: absolute; inset: 0; background: var(--t92); transform-origin: left; transform: scaleX(0); box-shadow: 0 0 8px rgba(244, 242, 238, .55); }
.is-flash .boot { opacity: 0; }
.is-flash .loader__line { stroke: #fff; stroke-width: 2.2; filter: drop-shadow(0 0 7px rgba(255, 255, 255, .9)); transition: stroke .15s, stroke-width .15s, filter .15s; }
.is-wired .boot, .no-gl .boot, html:not(.js) .boot { display: none; }
.meta__hint { display: inline-flex; align-items: center; gap: 8px; }
.meta__wheel { width: 10px; height: 16px; border: 1px solid var(--t42); border-radius: 6px; position: relative; }
.meta__wheel::after { content: ""; position: absolute; left: 50%; top: 3px; width: 2px; height: 3px; margin-left: -1px; border-radius: 1px; background: var(--t92); animation: wheel 1.8s var(--expo) infinite; }
@keyframes wheel { 0% { transform: translateY(0); opacity: 1; } 70% { transform: translateY(5px); opacity: 0; } 100% { transform: translateY(0); opacity: 0; } }
[data-chapter="4"] .meta__hint { visibility: hidden; }
/* "hover to inspect" where there is something to inspect: the crystal (0) and the two samples (3) */
[data-chapter="1"] .meta__probe, [data-chapter="2"] .meta__probe, [data-chapter="4"] .meta__probe { opacity: 0; }
.meta__probe { transition: opacity .3s; }
.is-probing .meta__probe { opacity: 0; }

/* ---------- phones and portrait ---------- */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  :root { --DT: clamp(30px, 9.6vw, 74px); --R: 104vw; --edge: max(20px, env(safe-area-inset-left, 0px)); --edge-r: max(20px, env(safe-area-inset-right, 0px)); }
  /* the copy sits right under the title; a scrim from there down keeps the floor's reflections behind the text */
  .sheets { width: calc(100vw - var(--edge) - var(--edge-r)); top: calc(var(--drum-y) + var(--DT) * 1.15); bottom: auto; }
  .sheet { top: 0; bottom: auto; }
  .sheets::before { position: fixed; left: 0; right: 0; top: calc(var(--drum-y) + var(--DT) * .95); bottom: 0; height: auto; background: linear-gradient(180deg, transparent, rgba(3, 4, 5, .62) 20%, rgba(3, 4, 5, .8)); }
  .sheet p { font-size: 13.5px; }
  .sheet__k { margin-bottom: 8px; }
  .meta { left: var(--edge); right: var(--edge-r); bottom: var(--edge-b); grid-auto-flow: column; justify-content: space-between; }
  .meta__hint, .status { display: none; }
  .drum { -webkit-mask-image: linear-gradient(90deg, transparent 2%, #000 14%, #000 86%, transparent 98%); mask-image: linear-gradient(90deg, transparent 2%, #000 14%, #000 86%, transparent 98%); }
}

@media (prefers-reduced-motion: reduce) {
  .boot, .loader { display: none; }
  .meta__wheel::after, .status i, .brand__ping { animation: none !important; }
  .sheet > * > .ln, .roll *, .odo__d > span { transition: none !important; }
}
