/* Certropy AI — design system and layout.
   Panels are pinned over a fixed WebGL stage; each chapter section is only scroll
   distance. Without JS the sections fall back to a normal document flow. */

:root {
  --abyss: #040a18;
  --abyss-rgb: 4, 10, 24; /* the same colour, for the scrims */
  --ink: #070c18;
  --ice: #eaf1ff;
  --ice-2: #c3d0ec;
  --mist: #b0bdd8;
  --dim: #74819f;
  --line: rgba(168, 194, 255, 0.14);
  --line-2: rgba(168, 194, 255, 0.3);
  --indigo: #263bff;
  --blue: #136dff;
  --sky: #00a6ff;
  --cyan: #00d2d8;
  --ember: #e46a1a;
  --ember-hi: #ff8f45;
  --signal: #7fd4ff;
  /* callout leader lines and anchor marks, as RGB triplets for the HUD canvas */
  --callout-line: 190, 214, 255;
  --callout-mark: 226, 238, 255;

  --m: clamp(20px, 2.6vw, 44px);
  /* type scale: display, chapter heading, body, label */
  --fs-display: clamp(46px, min(6vw, 11vh), 112px);
  --fs-h2: clamp(28px, min(3.2vw, 6.2vh), 56px);
  --fs-body: clamp(14.5px, 1vw, 16px);
  --fs-label: 12px;
  --font-sans: "Geist", "Certropy SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  --font-mono: "Martian Mono", "Certropy SC", ui-monospace, "Cascadia Mono", Consolas, monospace;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);
}

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

html {
  background: var(--abyss);
  color: var(--ice);
  font-family: var(--font-sans);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
}
html.js { scroll-snap-type: y proximity; }
html.is-loading { overflow: hidden; }

body { margin: 0; min-height: 100%; overflow-x: hidden; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, p, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }

::selection { background: rgba(0, 166, 255, 0.35); color: #fff; }
:focus-visible { outline: 1px solid var(--signal); outline-offset: 4px; }

.mono {
  font-family: var(--font-mono);
  font-stretch: 87.5%;
  font-size: 10.5px;
  letter-spacing: 0.04em;
}

.skip {
  position: fixed; left: var(--m); top: 12px; z-index: 200;
  padding: 8px 12px; background: var(--ice); color: var(--abyss);
  transform: translateY(-160%); transition: transform 0.3s var(--ease-out);
}
.skip:focus { transform: none; }

/* ───────────── Stage layers ───────────── */

.gl, .hud-lines {
  position: fixed; left: 0; top: 0;
  width: 100vw; height: 100vh; height: 100lvh;
  display: block;
}
.gl { z-index: 0; }
.hud-lines { z-index: 3; pointer-events: none; }
.callouts { position: fixed; inset: 0; z-index: 4; pointer-events: none; }

.gl-fallback {
  position: fixed; inset: 0; z-index: 0; display: none;
  place-items: center;
  background:
    radial-gradient(60vmax 50vmax at 62% 46%, rgba(19, 109, 255, 0.22), transparent 60%),
    radial-gradient(30vmax 30vmax at 62% 46%, rgba(228, 106, 26, 0.12), transparent 60%),
    linear-gradient(180deg, #060a16, var(--abyss));
}
.gl-fallback img { width: min(58vmin, 560px); margin-left: 24vw; filter: drop-shadow(0 0 40px rgba(0, 166, 255, 0.35)); }
.no-webgl .gl-fallback { display: grid; }
.no-webgl .gl { display: none; }

/* ───────────── Loader ───────────── */

.loader {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-content: center; justify-items: center; gap: 28px;
  background: var(--abyss);
  transition: opacity 1.1s var(--ease-io), visibility 0s linear 1.1s;
}
.loader.is-done { opacity: 0; visibility: hidden; }
.loader-mark { width: 196px; height: 196px; overflow: visible; }
.loader-mark rect { opacity: 0.12; transition: opacity 0.5s var(--ease-out), filter 0.5s; }
.loader-mark rect.on { opacity: 1; }
.loader-mark path { opacity: 0; transition: opacity 0.6s var(--ease-out); }
.loader-mark.is-core path { opacity: 1; filter: drop-shadow(0 0 18px rgba(255, 120, 40, 0.9)); }
.loader-line {
  display: flex; gap: 40px; align-items: baseline;
  font-family: var(--font-mono); font-stretch: 87.5%; font-size: 10.5px; letter-spacing: 0.06em;
  color: var(--mist);
}
.loader-name { font-family: var(--font-sans); font-size: 12px; letter-spacing: 0.12em; }
.loader-pct { color: var(--ice); font-size: 11px; font-variant-numeric: tabular-nums; }
.loader-pct i { font-style: normal; color: var(--dim); margin-left: 2px; }
.loader-bar { width: 220px; height: 1px; background: var(--line); overflow: hidden; }
.loader-bar i { display: block; height: 100%; width: 100%; background: var(--ice); transform-origin: 0 50%; transform: scaleX(0); }

/* ───────────── HUD ───────────── */

.hud { position: fixed; z-index: 20; }
.js .hud { opacity: 0; transition: opacity 1.4s var(--ease-io) 0.3s; }
.js.is-ready .hud { opacity: 1; }

.hud-top {
  left: 0; right: 0; top: 0; z-index: 40;
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 24px var(--m) 0;
  pointer-events: none;
}
.hud-top > * { pointer-events: auto; }

.brand { display: flex; align-items: center; gap: 16px; }
.brand-mark { width: 52px; height: 52px; margin: -5px -3px -5px -8px; }
.brand-text { display: grid; gap: 5px; line-height: 1; }
.brand-text b { font-weight: 600; font-size: 19.5px; letter-spacing: 0.18em; }
.brand-text i {
  font-style: normal; font-size: 12.5px; font-weight: 400; letter-spacing: 0.12em; color: var(--mist);
}

.nav { display: flex; gap: clamp(18px, 2.2vw, 36px); margin-top: 6px; }
.nav a {
  position: relative; padding: 6px 0;
  font-size: 13px; letter-spacing: 0.14em; color: var(--mist);
  transition: color 0.4s var(--ease-out);
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0.14em; bottom: 0; height: 1px;
  background: var(--ice); transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 0.5s var(--ease-out);
}
.nav a:hover { color: var(--ice); }
.nav a:hover::after { transform: scaleX(1); }
.nav a.is-current { color: var(--ice); }
.nav a.is-current::after { transform: scaleX(1); background: var(--sky); }

.hud-tools { display: flex; gap: 14px; align-items: center; margin-top: 6px; }
.tool {
  font-size: var(--fs-label); letter-spacing: 0.08em;
  color: var(--mist); padding: 6px 2px; transition: color 0.3s;
}
.tool:hover { color: var(--ice); }
.lang { display: inline-flex; gap: 6px; }
.lang-on { color: var(--ice); }
.lang-sep { color: var(--dim); }
.menu-btn { display: none; }

.hud-rail { right: calc(var(--m) - 6px); top: 50%; transform: translateY(-50%); }
.hud-rail ol { display: grid; gap: 14px; justify-items: end; }
.hud-rail li {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  font-size: var(--fs-label); letter-spacing: 0.1em; color: var(--dim);
  transition: color 0.4s;
}
.hud-rail li span { order: -1; opacity: 0; transform: translateX(6px); transition: opacity 0.4s, transform 0.5s var(--ease-out); }
.hud-rail li i { display: block; width: 12px; height: 1px; background: currentColor; transition: width 0.6s var(--ease-out), background 0.4s; }
.hud-rail li:hover span { opacity: 1; transform: none; }
.hud-rail li:hover { color: var(--ice); }
.hud-rail li.is-current { color: var(--ice); }
.hud-rail li.is-current i { width: 28px; background: var(--sky); }

.hud-bottom {
  left: 0; right: 0; bottom: 0;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end;
  padding: 0 var(--m) 22px;
  pointer-events: none;
  font-size: var(--fs-label); letter-spacing: 0.06em; color: var(--mist);
}
.hud-bottom button { pointer-events: auto; }
.hud-chapter { display: flex; align-items: baseline; gap: 14px; }
.hud-index { font-family: var(--font-mono); font-stretch: 87.5%; font-size: 10.5px; color: var(--dim); font-variant-numeric: tabular-nums; }
.hud-index b { font-weight: 400; color: var(--ice); font-size: 12px; }
.hud-title { font-size: var(--fs-label); letter-spacing: 0.16em; color: var(--ice-2); }

.hud-scroll { display: grid; justify-items: center; gap: 10px; color: var(--dim); transition: opacity 0.6s; }
.hud-scroll i { position: relative; display: block; width: 1px; height: 34px; background: var(--line); overflow: hidden; }
.hud-scroll i::after {
  content: ""; position: absolute; left: 0; top: 0; width: 1px; height: 12px; background: var(--ice);
  animation: scrollcue 2.4s var(--ease-io) infinite;
}
@keyframes scrollcue { 0% { transform: translateY(-14px); } 60%, 100% { transform: translateY(36px); } }
.hud-scroll.is-hidden { opacity: 0; }

.hud-readout { display: flex; justify-content: flex-end; align-items: baseline; gap: 22px; }
.readout b { font-family: var(--font-mono); font-stretch: 87.5%; font-size: 11px; font-weight: 400; color: var(--ice); font-variant-numeric: tabular-nums; margin: 0 2px; }
.sound { display: inline-flex; align-items: center; gap: 8px; padding: 0; }
.sound-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 9px; }
.sound-bars i { display: block; width: 1px; height: 3px; background: currentColor; transition: height 0.3s; }
.sound.is-on { color: var(--ice); }
.sound.is-on .sound-bars i { animation: eq 1.1s var(--ease-io) infinite alternate; }
.sound.is-on .sound-bars i:nth-child(2) { animation-delay: -0.4s; }
.sound.is-on .sound-bars i:nth-child(3) { animation-delay: -0.8s; }
.sound.is-on .sound-bars i:nth-child(4) { animation-delay: -0.2s; }
@keyframes eq { from { height: 2px; } to { height: 9px; } }
/* the autoplay switch: a track, with one block of the logo for a thumb */
.auto { position: relative; display: inline-flex; align-items: center; gap: 8px; padding: 6px 0; margin: -6px 0; }
.auto-switch {
  position: relative; display: block; width: 24px; height: 12px;
  border: 1px solid var(--line-2); border-radius: 3px;
  transition: border-color 0.3s, background 0.3s;
}
.auto-switch i {
  position: absolute; left: 2px; top: 2px; width: 6px; height: 6px; border-radius: 1px;
  background: var(--mist);
  transition: transform 0.35s var(--ease-out), background 0.3s;
}
.auto[aria-checked="true"] { color: var(--ice); }
.auto[aria-checked="true"] .auto-switch { border-color: rgba(127, 212, 255, 0.7); background: rgba(19, 109, 255, 0.24); }
.auto[aria-checked="true"] .auto-switch i { transform: translateX(12px); background: var(--ice); }
/* the current wait: how long this chapter holds, or how long until it carries on */
.auto::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--signal); opacity: 0;
  transform: scaleX(var(--p, 0)); transform-origin: 0 50%;
  transition: opacity 0.3s;
}
.auto[data-state="dwell"]::after, .auto[data-state="hold"]::after { opacity: 0.85; }

/* Menu (small screens) */
.menu {
  position: fixed; inset: 0; z-index: 30;
  display: grid; align-content: center; padding: 0 var(--m);
  background: rgba(var(--abyss-rgb), 0.92); backdrop-filter: blur(14px);
}
.menu[hidden] { display: none; }
.menu ol { display: grid; gap: 4px; }
.menu a { display: flex; align-items: baseline; gap: 18px; padding: 10px 0; font-size: 28px; letter-spacing: 0.1em; border-bottom: 1px solid var(--line); }
.menu .mono { color: var(--dim); }

/* ───────────── Callouts (3D-anchored labels) ───────────── */

.callout {
  position: absolute; left: 0; top: 0;
  text-shadow: 0 0 10px rgba(var(--abyss-rgb), 0.95), 0 0 22px rgba(var(--abyss-rgb), 0.8);
  display: grid; gap: 3px;
  white-space: nowrap;
  opacity: 0; transition: opacity 0.5s var(--ease-out);
  will-change: transform;
}
.callout.is-on { opacity: 1; }
.callout b { font-weight: 500; font-size: 13.5px; letter-spacing: 0.1em; color: var(--ice); white-space: pre-line; }
.callout:lang(en) b { letter-spacing: 0.03em; line-height: 1.25; }
.callout i {
  font-style: normal; font-size: var(--fs-label); letter-spacing: 0.06em; color: var(--mist);
  font-variant-numeric: tabular-nums;
}
.callout.is-right { justify-items: end; text-align: right; }
.callout.is-hot b { color: #fff; }
.callout.is-hot i { color: var(--signal); }
.callout.is-core b { color: #fff; }
.callout.is-interactive { cursor: pointer; padding: 6px 8px; margin: -6px -8px; }
/* only a label that is on screen may catch the cursor */
.callout.is-interactive.is-on { pointer-events: auto; }

/* ───────────── Type ───────────── */

.t-hero {
  font-weight: 300;
  /* width sets the size; on short, wide screens the height caps it so the headline
     never crowds the stage */
  font-size: var(--fs-display);
  line-height: 1;
  letter-spacing: 0.02em;
  margin-left: -0.06em;
  white-space: nowrap;
}
/* one heading size for every chapter, capped by the viewport height so a chapter never
   runs under the header on short laptop screens */
.t-statement, .t-h2 {
  font-weight: 300;
  font-size: var(--fs-h2);
  line-height: 1.34;
  letter-spacing: 0.015em;
  white-space: pre-line;
}
.t-lead { font-size: clamp(15px, 1.1vw, 17.5px); line-height: 1.85; color: var(--ice-2); max-width: 31em; text-wrap: pretty; }
.t-body { font-size: var(--fs-body); line-height: 1.8; color: var(--mist); max-width: 32em; text-wrap: pretty; }
.cap-list p, .ver-list p, .assure p, .cov-items { text-wrap: pretty; }
h3 { font-weight: 500; font-size: 16px; letter-spacing: 0.08em; color: var(--ice); }

/* English type, by :lang() rather than the <html> attribute, so that the copy can be laid
   out in either language whatever the page shows (main.js measures both for the camera) */
.t-hero:lang(en) { font-weight: 300; letter-spacing: -0.035em; line-height: 0.98; font-size: clamp(42px, min(5.2vw, 9.6vh), 100px); white-space: pre-line; }
/* English runs wider: the hero headline breaks onto two lines before it reaches the logo */
.js .ch-hero .panel-in:lang(en) { width: min(46rem, 48vw); }
.t-statement:lang(en) { letter-spacing: -0.025em; line-height: 1.12; }
.t-h2:lang(en) { letter-spacing: -0.02em; line-height: 1.14; }
.t-lead:lang(en), .t-body:lang(en) { line-height: 1.65; }
.panel-in h3:lang(en) { letter-spacing: 0.01em; }
.nav a:lang(en), .brand-text b:lang(en) { letter-spacing: 0.04em; }

/* ───────────── Buttons ───────────── */

/* the primary action: solid ice with the ember block, the only orange outside the core */
.btn {
  position: relative; display: inline-flex; align-items: center; gap: 14px;
  padding: 15px 26px 15px 22px;
  font-size: 15px; font-weight: 500; letter-spacing: 0.12em; color: var(--abyss);
  background: var(--ice);
  border-radius: 2px;
  transition: background 0.4s var(--ease-out), gap 0.5s var(--ease-out);
}
.btn::before {
  content: ""; width: 7px; height: 7px; flex: none;
  background: var(--ember); transform: rotate(45deg);
}
.btn:hover { background: #fff; gap: 18px; }
.btn:focus-visible { outline-offset: 5px; }
.btn-lg { padding: 18px 32px 18px 26px; font-size: 16px; }

.btn-quiet {
  position: relative; font-size: 14.5px; letter-spacing: 0.12em; color: var(--ice-2);
  padding: 8px 0; transition: color 0.4s;
}
.btn-quiet::after {
  content: ""; position: absolute; left: 0; right: 0.12em; bottom: 2px; height: 1px;
  background: currentColor; transform-origin: 100% 50%; transition: transform 0.5s var(--ease-out);
}
.btn-quiet:hover { color: var(--ice); }
.btn-quiet:hover::after { transform: scaleX(0.3); }

.btn:lang(en), .btn-quiet:lang(en) { letter-spacing: 0.02em; }

/* ───────────── Chapters ───────────── */

.ch { position: relative; }
.panel { position: relative; }
.panel-in { position: relative; }

.js .ch { height: 140vh; scroll-snap-align: start; }
.js .ch:last-child { height: 100vh; }
/* Inactive panels are transparent rather than hidden, so screen readers still reach every
   chapter; focus moving into one scrolls the page to it (see main.js). */
.js .panel { position: fixed; inset: 0; z-index: 5; pointer-events: none; opacity: 0; }
.js .ch.is-active .panel, .js .ch.is-leaving .panel { opacity: 1; }
.js .panel-in { position: absolute; pointer-events: none; }
.js .ch.is-active .panel-in { pointer-events: auto; }

/* soft scrims keep copy legible over the stage */
.js .panel::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: 0; transition: opacity 0.9s var(--ease-out);
}
.js .ch.is-active .panel::before { opacity: 1; }
.ch-hero .panel::before { background: radial-gradient(64vw 74vh at 0% 82%, rgba(var(--abyss-rgb), 0.74), rgba(var(--abyss-rgb), 0.3) 52%, transparent 74%); }
.ch-thesis .panel::before { background: radial-gradient(44vw 30vh at 50% 50%, rgba(var(--abyss-rgb), 0.78), rgba(var(--abyss-rgb), 0.4) 55%, transparent 78%); }
.ch-cap .panel::before { background: linear-gradient(90deg, rgba(var(--abyss-rgb), 0.74), rgba(var(--abyss-rgb), 0.4) 34%, transparent 54%); }
.ch-ver .panel::before { background: linear-gradient(270deg, rgba(var(--abyss-rgb), 0.76), rgba(var(--abyss-rgb), 0.42) 36%, transparent 56%); }
.ch-cov .panel::before { background: linear-gradient(90deg, rgba(var(--abyss-rgb), 0.72), rgba(var(--abyss-rgb), 0.36) 30%, transparent 48%); }
.ch-team .panel::before { background: linear-gradient(90deg, rgba(var(--abyss-rgb), 0.7), transparent 52%); }
.ch-contact .panel::before { background: linear-gradient(0deg, rgba(var(--abyss-rgb), 0.88), rgba(var(--abyss-rgb), 0.45) 42%, transparent 62%); }

/* reveal: a left-to-right scan instead of fade-up. As a chapter comes in, main.js plays the
   scan itself (scan()), the same way, to keep it in step with the scene; these transitions
   play it otherwise, and play it out */
.js [data-reveal] {
  clip-path: inset(-20% 100% -20% 0);
  opacity: 0;
  transition: clip-path 1.1s var(--ease-out), opacity 0.6s var(--ease-out);
  transition-delay: calc(var(--d, 0) * 1ms);
}
.js .ch.is-active [data-reveal] { clip-path: inset(-20% -2% -20% 0); opacity: 1; }
.js .ch.is-leaving [data-reveal] { transition-duration: 0.4s, 0.35s; transition-delay: 0s; clip-path: inset(-20% -2% -20% 0); opacity: 0; }
.js .ch.is-leaving [data-decode] { opacity: 0; transition: opacity 0.35s; }
.js [data-decode] { transition: opacity 0.3s; }

/* hero: the copy has a box, from 42.6vh down to 16vh above the bottom, which the Chinese copy
   fills exactly at 1280x593 (the reference screen). Copy taller than the box (English on short
   screens) keeps its bottom and runs upward, as before; copy shorter than it takes a third of
   the spare room above and two thirds below, so the headline stays at much the same height on
   every screen instead of sinking towards the bottom on tall ones (a 16:10 laptop, a QHD
   monitor), where the type is a smaller part of the screen */
.js .ch-hero .panel-in {
  left: var(--m); top: 42.6vh; bottom: 16vh; width: min(52rem, 56vw);
  display: flex; flex-direction: column; justify-content: flex-end;
}
.js .ch-hero .panel-in::before, .js .ch-hero .panel-in::after { content: ""; flex: 1 1 0; }
.js .ch-hero .panel-in::after { flex-grow: 2; }
.ch-hero .t-lead { margin-top: 2rem; }
.hero-actions { display: flex; align-items: center; gap: 34px; margin-top: 2.6rem; }
/* and the gaps between headline, lead and buttons grow with the screen's height, as the same
   share of it as on the reference screen, within limits; phones keep their own gaps */
@media (min-width: 761px) and (orientation: landscape) {
  .ch-hero .t-lead { margin-top: clamp(2rem, 5.4vh, 3.5rem); }
  .hero-actions { margin-top: clamp(2.6rem, 7vh, 4.5rem); }
}

/* thesis */
.js .ch-thesis .panel-in { left: 50%; top: 50%; width: min(64rem, 88vw); transform: translate(-50%, -50%); text-align: center; }
.ch-thesis .t-body { margin: 2.2rem auto 0; max-width: 36em; white-space: pre-line; }

/* capabilities: four services as one ruled list, the heading beside its line */
.js .ch-cap .panel-in { left: var(--m); top: 50%; transform: translateY(-50%); width: min(38rem, 40vw); }
.cap-list { margin-top: min(2.4rem, 4vh); display: grid; border-bottom: 1px solid var(--line); }
.cap-list li {
  display: grid; grid-template-columns: minmax(8.5em, 11em) 1fr; column-gap: 1.6rem; align-items: baseline;
  padding: min(1.05rem, 1.9vh) 0; border-top: 1px solid var(--line);
}
.cap-list p { font-size: 14px; line-height: 1.7; color: var(--mist); }

/* coverage: the copy and its colour key in one compact column on the left; the carousel
   is framed in the space to its right (camera.fit) */
.js .ch-cov .panel-in { left: var(--m); top: 50%; transform: translateY(-50%); width: min(28rem, 29vw); }
.ch-cov .t-body { margin-top: min(1.4rem, 2.4vh); font-size: 14.5px; }
.cov-legend { display: grid; gap: 0.9rem; margin-top: min(2.4rem, 4vh); }
.cov-group { display: grid; row-gap: 0.35rem; padding-top: 0.9rem; border-top: 1px solid var(--line); }
.cov-name { display: flex; align-items: center; gap: 10px; font-size: 15px; letter-spacing: 0.1em; color: var(--ice); }
/* colour key: the hue of that group's clusters on the carousel */
.cov-name::before { content: ""; width: 7px; height: 7px; flex: none; transform: rotate(45deg); background: var(--key); box-shadow: 0 0 10px var(--key); }
.cov-group.is-workflow { --key: var(--cyan); }
.cov-group.is-domain { --key: var(--blue); }
.cov-items { font-size: 13px; letter-spacing: 0.06em; color: var(--mist); padding-left: 17px; }

/* verification: mirrored, the rings on the left and the copy on the right; the three
   layers, then the delivery guarantees in a quieter row */
.js .ch-ver .panel-in { right: calc(var(--m) + 40px); top: 50%; transform: translateY(-50%); width: min(44rem, 46vw); }
.ch-ver .t-body { margin-top: min(1.2rem, 2vh); }
.ver-list { margin-top: min(2rem, 3.4vh); display: grid; border-bottom: 1px solid var(--line); }
.ver-list li {
  display: grid; grid-template-columns: minmax(6.5em, 8em) 1fr; column-gap: 1.6rem; align-items: baseline;
  padding: min(0.95rem, 1.7vh) 0; border-top: 1px solid var(--line);
}
.ver-list p { font-size: 14px; line-height: 1.7; color: var(--mist); }
.assure {
  margin-top: min(1.8rem, 3vh);
  display: grid; grid-template-columns: repeat(3, 1fr); column-gap: clamp(16px, 1.6vw, 28px);
}
.assure li { display: grid; gap: 0.4rem; align-content: start; }
.assure h3 { font-size: 13.5px; letter-spacing: 0.08em; color: var(--ice-2); }
.assure p { font-size: 12.5px; line-height: 1.65; color: var(--mist); }

/* team: the copy alone on the left; the network is the picture */
.js .ch-team .panel-in { left: var(--m); top: 50%; transform: translateY(-50%); width: min(36rem, 40vw); }
.ch-team .t-body { margin-top: min(1.6rem, 2.6vh); }

/* contact: sizes and gaps follow the viewport height, so the copy leaves the logo room */
.js .ch-contact .panel-in { left: 50%; bottom: 0; width: min(70rem, 92vw); transform: translateX(-50%); text-align: center; padding-bottom: min(92px, 12vh); }
.ch-contact .t-body { margin: min(1.4rem, 2.4vh) auto 0; max-width: 34em; white-space: pre-line; }
.contact-actions { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 14px 28px; margin-top: min(2.4rem, 3.8vh); }
.contact-mail { position: relative; color: var(--ice-2); font-size: 14px; letter-spacing: 0.06em; }
/* "email us" (js/mail.js): a note stands in the address's place for a few seconds, and a
   line runs under it while the page waits for a mail app */
.mail-addr { transition: opacity 0.4s var(--ease-out); }
.mail-note {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  white-space: nowrap; color: var(--ice); opacity: 0; pointer-events: none;
  transition: opacity 0.4s var(--ease-out);
}
.contact-mail.is-noted .mail-addr { opacity: 0; }
.contact-mail.is-noted .mail-note { opacity: 1; }
.contact-mail::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -7px; height: 1px;
  background: var(--signal); opacity: 0; transform: scaleX(0); transform-origin: 0 50%;
  transition: opacity 0.3s, transform 0s 0.3s;
}
.contact-mail.is-waiting::after { opacity: 0.85; transform: scaleX(1); transition: opacity 0.3s, transform var(--wait, 2.5s) linear; }
.site-foot {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 8px 28px; margin-top: min(3.2rem, 5vh);
  font-size: 11.5px; letter-spacing: 0.06em; color: var(--dim);
}
.site-foot a:hover { color: var(--ice-2); }
/* on a wide screen the legal line sits in the bottom HUD's row, between its two corners */
@media (min-width: 1000px) and (orientation: landscape) {
  .js .ch-contact .site-foot { position: absolute; left: 0; right: 0; bottom: 22px; margin: 0; }
}
/* in a narrower landscape window the line would run into the readout at the right, so it
   takes the row above the HUD corners instead; the English line is the longer one, and the
   copy above keeps clear of it on a short screen */
@media (min-width: 1000px) and (max-width: 1279px) and (orientation: landscape) {
  .js .ch-contact .site-foot:lang(en) { bottom: 44px; }
  .js .ch-contact .panel-in:lang(en) { padding-bottom: max(min(92px, 12vh), 74px); }
}
@media (min-width: 1000px) and (max-width: 1139px) and (orientation: landscape) {
  .js .ch-contact .site-foot { bottom: 44px; }
  .js .ch-contact .panel-in { padding-bottom: max(min(92px, 12vh), 74px); }
}

/* ───────────── Web mail chooser (js/mail.js) ───────────── */

/* for screen readers only */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; font-style: normal; }

.mail-pick {
  width: min(35rem, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px);
  margin: auto; padding: 24px 30px 22px;
  color: var(--ice);
  background: linear-gradient(180deg, #0c152c, #050a17);
  border: 1px solid rgba(168, 194, 255, 0.2); border-radius: 3px;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.55);
  overflow: auto; overscroll-behavior: contain;
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out);
}
.mail-pick.is-open { opacity: 1; transform: none; transition-duration: 0.5s; }
/* (the backdrop inherits no custom properties in older browsers: the abyss, spelled out) */
.mail-pick::backdrop { background: rgba(4, 10, 24, 0.66); opacity: 0; transition: opacity 0.24s; }
.mail-pick.is-open::backdrop { opacity: 1; transition-duration: 0.4s; }

.mail-pick-head { display: flex; justify-content: space-between; align-items: center; margin-right: -10px; }
/* the label leads with a tick, like the current chapter's in the nav and on the rail */
.mail-pick-label { display: flex; align-items: center; gap: 12px; font-size: var(--fs-label); letter-spacing: 0.16em; color: var(--mist); }
.mail-pick-label::before { content: ""; width: 20px; height: 1px; background: var(--sky); }
.mail-pick-close { position: relative; width: 32px; height: 32px; color: var(--mist); transition: color 0.3s; }
.mail-pick-close:hover { color: var(--ice); }
.mail-pick-close i, .mail-pick-close i::after { position: absolute; width: 14px; height: 1px; background: currentColor; }
.mail-pick-close i { left: 9px; top: 15.5px; transform: rotate(45deg); }
.mail-pick-close i::after { content: ""; left: 0; top: 0; transform: rotate(90deg); }

.mail-pick-title { margin-top: 12px; font-weight: 300; font-size: 26px; line-height: 1.3; letter-spacing: 0.04em; white-space: pre-line; }
.mail-pick-title:lang(en) { letter-spacing: -0.01em; }
.mail-pick-body { margin-top: 10px; font-size: 14px; line-height: 1.75; color: var(--mist); white-space: pre-line; text-wrap: pretty; }
.mail-pick-body:lang(en) { line-height: 1.6; }

.mail-pick-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 22px; }
.mail-pick-item {
  position: relative; display: grid; gap: 6px; padding: 15px 30px 14px 16px;
  border: 1px solid var(--line); border-radius: 2px; background: rgba(168, 194, 255, 0.03);
  opacity: 0; transform: translateY(6px);
  transition: border-color 0.3s, background 0.3s,
    opacity 0.5s var(--ease-out) calc(140ms + var(--k, 0) * 45ms), transform 0.6s var(--ease-out) calc(140ms + var(--k, 0) * 45ms);
}
.mail-pick.is-open .mail-pick-item { opacity: 1; transform: none; }
/* line heights set, so a row of Chinese names and a row of Latin ones are the same height */
.mail-pick-item b { font-weight: 400; font-size: 15px; line-height: 22px; letter-spacing: 0.06em; color: var(--ice); white-space: nowrap; }
.mail-pick-item:lang(en) b { letter-spacing: 0.01em; }
.mail-pick-item span { font-size: 11px; line-height: 16px; letter-spacing: 0.04em; color: var(--dim); white-space: nowrap; }
.mail-pick-item svg {
  position: absolute; right: 13px; top: 17px; width: 10px; height: 10px;
  fill: none; stroke: currentColor; stroke-width: 1; color: var(--dim);
  transition: color 0.3s, transform 0.4s var(--ease-out);
}
.mail-pick-item:hover, .mail-pick-item:focus-visible { border-color: rgba(127, 212, 255, 0.5); background: rgba(19, 109, 255, 0.12); }
.mail-pick-item:hover svg, .mail-pick-item:focus-visible svg { color: var(--ice); transform: translate(2px, -2px); }
.mail-pick-item:focus-visible { outline-offset: 2px; }

.mail-pick-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 8px 16px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line);
}
.mail-pick-addr { font-size: 14px; letter-spacing: 0.06em; color: var(--ice-2); user-select: all; }
.mail-pick-copy { font-size: 13.5px; }

@media (max-width: 560px) {
  .mail-pick { padding: 20px 20px 18px; }
  .mail-pick-title { font-size: 22px; }
  .mail-pick-list { grid-template-columns: repeat(2, 1fr); margin-top: 18px; }
}

/* ───────────── No-JS flow ───────────── */

html:not(.js) .ch { min-height: 100vh; padding: 18vh var(--m) 12vh; border-top: 1px solid var(--line); }
html:not(.js) .gl-fallback { display: grid; opacity: 0.35; }
html:not(.js) .loader, html:not(.js) .hud-bottom, html:not(.js) .hud-rail { display: none; }
html:not(.js) .panel-in { max-width: 48rem; }


/* ───────────── Responsive ───────────── */

@media (max-width: 1100px) {
  .nav { display: none; }
  .menu-btn { display: inline-block; }
  .js .ch-cap .panel-in, .js .ch-ver .panel-in, .js .ch-team .panel-in { width: min(36rem, 48vw); }
  .js .ch-cov .panel-in { width: min(28rem, 38vw); }
}

/* Stacked layout for phones and portrait tablets: the subject sits in the upper half,
   the copy below it on a scrim. */
@media (max-width: 760px), (orientation: portrait) and (max-width: 1100px) {
  .hud-rail { display: none; }
  .js .ch { height: 135vh; }
  .js .ch:last-child { height: 100vh; }
  .js .panel-in {
    left: var(--m) !important; right: var(--m) !important; top: auto !important; bottom: 76px !important;
    width: auto !important; transform: none !important; text-align: left !important;
  }
  .js .panel::before {
    top: auto; height: 72vh;
    background: linear-gradient(180deg, rgba(var(--abyss-rgb), 0), rgba(var(--abyss-rgb), 0.78) 45%, rgba(var(--abyss-rgb), 0.92)) !important;
  }
  .ch-thesis .t-body, .ch-contact .t-body { margin-left: 0; }
  .cov-legend { margin-top: 1.4rem; }
  .contact-actions { justify-content: flex-start; }
  .site-foot { justify-content: flex-start; gap: 6px 18px; margin-top: 2rem; }
  .js .ch-contact .panel-in { padding-bottom: 0; }
}

@media (max-width: 760px) {
  :root { --m: 20px; }
  .brand { gap: 12px; }
  .brand-mark { width: 44px; height: 44px; }
  .brand-text b { font-size: 18px; }
  .brand-text i { font-size: 11px; }
  .hud-bottom { grid-template-columns: 1fr auto; padding-bottom: 16px; }
  .hud-scroll { display: none; }
  .hud-readout .readout { display: none; }

  .t-hero { font-size: clamp(44px, 13.5vw, 72px); }
  .t-statement, .t-h2 { font-size: clamp(26px, 7.2vw, 36px); }
  .ch-hero .t-lead { margin-top: 1.4rem; }
  .hero-actions { margin-top: 1.6rem; gap: 24px; }
  .ch-cap .t-h2, .ch-ver .t-h2 { font-size: clamp(24px, 6.6vw, 32px); }
  .cap-list { margin-top: 1.4rem; }
  .cap-list li { padding: 0.7rem 0; }
  .cap-list p, .ver-list p { font-size: 13px; line-height: 1.6; }
  .ch-cap .cap-list p { display: none; }
  .ver-list { margin-top: 1.4rem; }
  .ver-list li { padding: 0.75rem 0; }
  .ch-ver .t-body, .ch-ver .ver-list p { display: none; }
  .assure { grid-template-columns: 1fr; row-gap: 0.5rem; margin-top: 1rem; }
  .assure li { grid-template-columns: 8.4rem 1fr; }
  .assure p { font-size: 12.5px; line-height: 1.6; }
  /* the English descriptions run three lines each here, and would push the copy up into the rings */
  .ch-ver .assure p:lang(en) { display: none; }
  .callout b { font-size: 12px; }
  .callout i { display: none; }
}

/* short landscape screens, in English: its headings take two lines and its descriptions run
   longer, so the capabilities and verification lists close up to keep clear of the header */
@media (min-width: 761px) and (max-height: 700px) {
  .ch-cap .cap-list:lang(en) { margin-top: 14px; }
  .ch-cap .cap-list li:lang(en) { padding: 6px 0; }
  .ch-cap .cap-list p:lang(en) { line-height: 1.5; }
  .ch-ver .t-body:lang(en) { margin-top: 8px; }
  .ch-ver .ver-list:lang(en) { margin-top: 12px; }
  .ch-ver .ver-list li:lang(en) { padding: 5px 0; }
  .ch-ver .ver-list p:lang(en) { line-height: 1.5; }
  .ch-ver .assure:lang(en) { margin-top: 12px; }
  .ch-ver .assure p:lang(en) { line-height: 1.45; }
  /* and both sit in the middle of the band between the header and the bottom HUD, which is
     a little lower than the middle of the screen, as the header is the taller */
  .js .ch-cap .panel-in:lang(en), .js .ch-ver .panel-in:lang(en) { transform: translateY(calc(-50% + 16px)); }
}

/* very short landscape screens: the verification copy drops its descriptions to stay on screen */
@media (min-width: 761px) and (max-height: 500px) and (orientation: landscape) {
  .ch-ver .ver-list p, .ch-ver .assure p { display: none; }
  .ch-ver .ver-list li { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html.js { scroll-snap-type: none; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; }
  .js [data-reveal] { transition-duration: 0.2s !important; transition-delay: 0s !important; }
  .mail-pick, .mail-pick::backdrop, .mail-pick-item, .contact-mail::after { transition-duration: 0.01ms !important; transition-delay: 0s !important; }
}

/* decode effect: characters still resolving */
.dc { white-space: pre-wrap; transition: opacity 0.4s; }

/* social card capture (?og) */
.is-og .hud-bottom, .is-og .hud-rail, .is-og .nav, .is-og .hud-tools, .is-og .hero-actions { display: none !important; }
