/* jetbrains-mono-cyrillic-ext-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-cyrillic-ext-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-ext-400-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-cyrillic-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-400-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-greek-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-greek-400-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-vietnamese-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-vietnamese-400-normal.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-latin-ext-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-ext-400-normal.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-400-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/jetbrains-mono-latin-400-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-400-normal.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* jetbrains-mono-cyrillic-ext-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-cyrillic-ext-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-ext-500-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-cyrillic-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-500-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-greek-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-greek-500-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-vietnamese-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-vietnamese-500-normal.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-latin-ext-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-ext-500-normal.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-500-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(../fonts/jetbrains-mono-latin-500-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-500-normal.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* jetbrains-mono-cyrillic-ext-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-cyrillic-ext-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-ext-700-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-cyrillic-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-700-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-greek-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-greek-700-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-vietnamese-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-vietnamese-700-normal.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-latin-ext-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-ext-700-normal.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-700-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(../fonts/jetbrains-mono-latin-700-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-700-normal.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* jetbrains-mono-cyrillic-ext-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-cyrillic-ext-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-ext-800-normal.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* jetbrains-mono-cyrillic-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-cyrillic-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-cyrillic-800-normal.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* jetbrains-mono-greek-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-greek-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-greek-800-normal.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* jetbrains-mono-vietnamese-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-vietnamese-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-vietnamese-800-normal.woff) format('woff');
  unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

/* jetbrains-mono-latin-ext-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-latin-ext-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-ext-800-normal.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* jetbrains-mono-latin-800-normal */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 800;
  src: url(../fonts/jetbrains-mono-latin-800-normal.woff2) format('woff2'), url(../fonts/jetbrains-mono-latin-800-normal.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}/* silkscreen-latin-ext-400-normal */
@font-face {
  font-family: 'Silkscreen';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/silkscreen-latin-ext-400-normal.woff2) format('woff2'), url(../fonts/silkscreen-latin-ext-400-normal.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* silkscreen-latin-400-normal */
@font-face {
  font-family: 'Silkscreen';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(../fonts/silkscreen-latin-400-normal.woff2) format('woff2'), url(../fonts/silkscreen-latin-400-normal.woff) format('woff');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}:root {
  /* The landing page opens as a calm paper-and-ink interface. */
  --bg: #f5f7fb;
  --bg-2: #ffffff;
  --panel: rgba(255, 255, 255, 0.78);
  --line: rgba(41, 57, 82, 0.14);
  --line-2: rgba(41, 57, 82, 0.28);
  --text: #182235;
  --dim: #52617a;
  --faint: #8290a5;
  --c-main: #c88314;
  --c-support: #108d84;
  --c-backup: #cf5365;
  --ink: #182235;
  --on-accent: #182235;
  --shadow: rgba(37, 53, 79, 0.16);
  --scene-backdrop: #eef2f9;
  --scene-fog: #dfe6f2;
  --scene-haze-low: #cbd8ea;
  --scene-haze-high: #f5f8fd;
  --scene-cloud-base: #b8c9df;
  --scene-cloud-top: #f3f7fc;
  --mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  --pixel: 'Silkscreen', 'JetBrains Mono', monospace;
  --cn: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'HarmonyOS Sans SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
  --pad: clamp(16px, 3.4vw, 52px);
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
  color-scheme: light;
}

html[data-theme='dark'] {
  --bg: #07090e;
  --bg-2: #0b0f17;
  --panel: rgba(14, 19, 29, 0.72);
  --line: rgba(150, 170, 205, 0.13);
  --line-2: rgba(150, 170, 205, 0.24);
  --text: #e8ecf3;
  --dim: #939cb0;
  --faint: #5c6579;
  --c-main: #ffc24b;
  --c-support: #5ee6d0;
  --c-backup: #ff7d8c;
  --ink: #0a0d14;
  --on-accent: #0a0d14;
  --shadow: rgba(0, 0, 0, 0.42);
  --scene-backdrop: #07090e;
  --scene-fog: #0c1220;
  --scene-haze-low: #121c33;
  --scene-haze-high: #2c3b5e;
  --scene-cloud-base: #1b2233;
  --scene-cloud-top: #3a4560;
  color-scheme: dark;
}

html,
body,
.app,
.top,
.intro,
.nodes,
.node,
.statusbar,
.foot,
.chat,
.icon-btn,
.btn-ghost {
  transition:
    background-color 0.45s var(--ease),
    border-color 0.45s var(--ease),
    color 0.45s var(--ease),
    box-shadow 0.45s var(--ease);
}

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

html {
  background: var(--bg);
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100svh;
  background:
    radial-gradient(1200px 600px at 50% 30%, color-mix(in srgb, var(--c-support) 9%, transparent), transparent 70%),
    var(--bg);
  color: var(--text);
  font-family: var(--cn);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

[hidden] {
  display: none !important;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

kbd {
  display: inline-grid;
  place-items: center;
  min-width: 1.7em;
  height: 1.7em;
  padding: 0 0.4em;
  margin: 0 0.1em;
  font-family: var(--mono);
  font-size: 0.85em;
  color: var(--text);
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  border-radius: 3px;
  line-height: 1;
}

:focus-visible {
  outline: 2px solid var(--c-main);
  outline-offset: 3px;
}

.skip {
  position: fixed;
  left: 12px;
  top: -60px;
  z-index: 100;
  padding: 10px 14px;
  background: var(--c-main);
  color: var(--ink);
  font-family: var(--mono);
  font-weight: 700;
  transition: top 0.2s;
}
.skip:focus {
  top: 12px;
}


/* ───────────────────────── mark ───────────────────────── */
.mark {
  display: inline-block;
  width: 30px;
  height: 30px;
  background: url('../favicon.svg') center / contain no-repeat;
  image-rendering: pixelated;
  box-shadow: 0 0 24px rgba(255, 194, 75, 0.35);
  flex: none;
}
.mark--lg {
  width: 56px;
  height: 56px;
}

/* ───────────────────────── boot ───────────────────────── */
.boot {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  background: var(--bg);
  cursor: pointer;
  transition:
    opacity 0.7s var(--ease),
    visibility 0.7s;
}
.boot.is-done {
  opacity: 0;
  visibility: hidden;
}
.boot__inner {
  width: min(440px, 84vw);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
}
.boot__logo {
  margin-bottom: 22px;
  animation: bootPulse 1.2s steps(2) infinite;
}
@keyframes bootPulse {
  50% {
    filter: brightness(1.25);
  }
}
.boot__log {
  margin: 0 0 18px;
  min-height: 7.5em;
  font: inherit;
  line-height: 1.55;
  white-space: pre-wrap;
}
.boot__log b {
  color: var(--c-main);
  font-weight: 500;
}
.boot__bar {
  height: 6px;
  background: rgba(255, 255, 255, 0.06);
  position: relative;
  overflow: hidden;
}
.boot__bar i {
  position: absolute;
  inset: 0;
  transform-origin: left;
  transform: scaleX(0);
  background: repeating-linear-gradient(90deg, var(--c-main) 0 8px, transparent 8px 10px);
  transition: transform 0.25s steps(6);
}
.boot__hint {
  margin-top: 14px;
  font-family: var(--pixel);
  font-size: 9px;
  letter-spacing: 0.2em;
  color: var(--faint);
}

/* ───────────────────────── app shell ───────────────────────── */
.app {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding: 0 var(--pad);
}
.app > main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.top {
  position: relative;
  z-index: 5;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
  height: 76px;
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
.brand__name {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.02em;
}
.brand__name em {
  font-style: normal;
  color: var(--c-main);
  margin-right: 0.4em;
}
.brand__cn {
  font-size: 12px;
  color: var(--faint);
  padding-left: 12px;
  border-left: 1px solid var(--line-2);
  letter-spacing: 0.3em;
}
.top__ticker {
  min-width: 0;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ticker {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--faint);
  white-space: nowrap;
  display: flex;
  width: max-content;
  animation: ticker 48s linear infinite;
}
.ticker span {
  padding-right: 4em;
}
@keyframes ticker {
  to {
    transform: translateX(-50%);
  }
}
.top__meta {
  display: flex;
  align-items: center;
  gap: 22px;
}
.pill {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.pill--live {
  color: var(--c-main);
}
.pill--live i {
  width: 7px;
  height: 7px;
  background: currentColor;
  box-shadow: 0 0 10px currentColor;
  animation: blink 1.6s steps(1) infinite;
}
@keyframes blink {
  60% {
    opacity: 0.25;
  }
}
.meta {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  display: inline-flex;
  gap: 10px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.meta__k {
  color: var(--faint);
}
.meta--dim {
  color: var(--dim);
}
.icon-btn {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  color: var(--dim);
  transition:
    color 0.2s,
    border-color 0.2s,
    background 0.2s;
}
.icon-btn:hover {
  color: var(--text);
  border-color: var(--dim);
  background: color-mix(in srgb, var(--text) 6%, transparent);
}

.theme-btn,
#theme-toggle {
  position: relative;
  overflow: hidden;
}
.theme-btn svg,
#theme-toggle svg {
  width: 16px;
  height: 16px;
  transition: transform 0.45s var(--ease), opacity 0.3s;
}
.theme-btn .moon,
#theme-toggle .theme-icon--moon {
  display: none;
}
html[data-theme='dark'] .theme-btn .sun,
html[data-theme='dark'] #theme-toggle .theme-icon--sun {
  display: none;
}
html[data-theme='dark'] .theme-btn .moon,
html[data-theme='dark'] #theme-toggle .theme-icon--moon {
  display: block;
}
.theme-btn:hover svg,
#theme-toggle:hover svg {
  transform: rotate(18deg) scale(1.08);
}
.icon-btn svg {
  width: 16px;
  height: 16px;
}
#sound .wave {
  display: none;
}
#sound[aria-pressed='true'] {
  color: var(--c-main);
  border-color: color-mix(in srgb, var(--c-main) 50%, transparent);
}
#sound[aria-pressed='true'] .wave {
  display: block;
}
#sound[aria-pressed='true'] .mute {
  display: none;
}

/* ───────────────────────── stage ───────────────────────── */
.stage {
  --shift: 0;
  --lift: 0.06;
  --fit: 1.1;
  position: relative;
  height: clamp(460px, calc(100svh - 76px - 300px), 820px);
  min-height: 460px;
  /* Keep projected station tags in the page stacking context. Expanded
     service cards rise into the stage, but must not paint over those tags. */
  isolation: auto;
}
/* Keep the 3D scene calm and focused. The former telemetry HUD and controls
   remain in the DOM for keyboard compatibility, but stay out of the visual
   presentation. */
.stage__bar,
.stage__title,
.side--r,
.statusbar,
.foot,
.top__ticker,
.pill--live {
  display: none !important;
}
.intro__lede:empty {
  display: none;
}
.stage__hint {
  display: none;
}
.top__meta {
  grid-column: 3;
}
.stage__canvas {
  position: absolute;
  top: 0;
  bottom: 0;
  /* bleed to the viewport edges, past the capped content column */
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  z-index: 0;
  mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 86%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 86%, transparent 100%);
  opacity: 0;
  transition: opacity 1.2s var(--ease);
}
.is-live .stage__canvas {
  opacity: 1;
}
.stage__canvas canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
}
.stage__canvas::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.022) 0 1px, transparent 1px 3px);
  mix-blend-mode: overlay;
}
.stage__notice {
  position: absolute;
  z-index: 4;
  left: 0;
  top: clamp(28px, 8%, 72px);
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: min(680px, 86vw);
  padding: 8px 12px 8px 0;
  color: var(--text);
  font-family: var(--mono);
  font-size: clamp(12px, 1.1vw, 16px);
  letter-spacing: 0.16em;
  line-height: 1.4;
  pointer-events: none;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease), color 0.35s;
}
.is-live .stage__notice {
  opacity: 1;
  transform: none;
}
.stage__notice-mark {
  flex: none;
  color: var(--c-main);
  font-family: var(--mono);
  font-size: inherit;
  font-weight: 700;
}
.stage__notice-caret {
  flex: none;
  width: auto;
  height: auto;
  color: var(--dim);
  font-family: var(--mono);
  font-style: normal;
  animation: blink 1s steps(1) infinite;
}
.stage__fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  color: var(--dim);
  font-size: 14px;
}
.stage__fallback p {
  margin: 4px;
}

.stage__bar {
  position: relative;
  z-index: 3;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 22px;
  pointer-events: none;
}
.stage__bar > * {
  pointer-events: auto;
}
.crumb {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  color: var(--dim);
}
.crumb b {
  color: var(--c-main);
  font-weight: 500;
  margin-right: 0.6em;
}
.caret {
  animation: blink 1s steps(1) infinite;
}
.stage__ctrl {
  display: flex;
  align-items: center;
  gap: 10px;
}
.stage__ctrl .meta {
  margin-right: 10px;
}
.btn-ghost {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 8px 13px;
  border: 1px solid var(--line-2);
  color: var(--dim);
  background: color-mix(in srgb, var(--bg-2) 72%, transparent);
  backdrop-filter: blur(6px);
  transition:
    color 0.2s,
    border-color 0.2s,
    background 0.2s;
}
.btn-ghost:hover {
  color: var(--text);
  border-color: var(--dim);
}
.btn-ghost[aria-pressed='true'] {
  color: var(--c-main);
  border-color: color-mix(in srgb, var(--c-main) 50%, transparent);
}

.stage__title {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  top: 7%;
  display: flex;
  justify-content: space-between;
  pointer-events: none;
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(56px, 10.5vw, 188px);
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--text) 16%, transparent);
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 1.6s var(--ease) 0.4s,
    transform 1.6s var(--ease) 0.4s;
}
.is-live .stage__title {
  opacity: 1;
  transform: none;
}
.stage__title span:last-child {
  margin-top: 0.62em;
}

/* labels */
.labels {
  position: absolute;
  inset: 0;
  /* Expanded cards use z-index: 2; keep the station tags above them when a
     card opens upward into the stage. */
  z-index: 5;
  pointer-events: none;
  overflow: visible;
}
.label {
  --c: var(--c-main);
  position: absolute;
  left: 0;
  top: 0;
  will-change: transform;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.is-ready .label {
  opacity: 1;
}
.label__dot {
  position: absolute;
  left: -4px;
  top: -4px;
  width: 8px;
  height: 8px;
  background: var(--c);
  box-shadow: 0 0 12px var(--c);
}
.label__dot::after {
  content: '';
  position: absolute;
  inset: -6px;
  border: 1px solid var(--c);
  animation: ping 2.4s var(--ease) infinite;
}
@keyframes ping {
  0% {
    transform: scale(0.4);
    opacity: 1;
  }
  80%,
  100% {
    transform: scale(1.8);
    opacity: 0;
  }
}
.label__stem {
  position: absolute;
  left: 0;
  bottom: 8px;
  width: 1px;
  height: 46px;
  background: linear-gradient(to top, var(--c), transparent);
  transform-origin: bottom;
  transition: height 0.4s var(--ease);
}
.label__tag {
  position: absolute;
  left: 0;
  bottom: 54px;
  padding: 8px 12px 8px 12px;
  border-left: 2px solid var(--c);
  background: color-mix(in srgb, var(--bg-2) 86%, transparent);
  backdrop-filter: blur(8px);
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  line-height: 1.5;
  pointer-events: auto;
  cursor: pointer;
  transition:
    background 0.3s,
    box-shadow 0.3s;
}
.label__title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--text);
  font-family: var(--cn);
  font-size: 14px;
  letter-spacing: 0.02em;
}
.label__title b {
  color: var(--c);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
}
.label__code {
  margin-top: 2px;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.13em;
}
.label__more {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.label__more > div {
  overflow: hidden;
  font-family: var(--cn);
  letter-spacing: 0.02em;
  font-size: 14px;
  color: var(--text);
}
.label__more span {
  display: block;
  padding-top: 6px;
}
.label.is-active .label__more {
  grid-template-rows: 1fr;
}
.label.is-active .label__more > div {
  min-width: max-content;
}
.label.is-active .label__stem {
  height: 64px;
}
.label.is-active .label__tag {
  /* Keep the hit target anchored while its details unfold upward. Moving the
     whole tag on hover makes the pointer leave/re-enter in a tight loop. */
  bottom: 54px;
  background: color-mix(in srgb, var(--c) 14%, var(--bg-2));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--c) 30%, transparent), 0 10px 40px -10px color-mix(in srgb, var(--c) 50%, transparent);
}
.label.is-flip .label__tag {
  left: auto;
  right: 0;
  border-left: 0;
  border-right: 2px solid var(--c);
  text-align: right;
}
.label.is-flip .label__title { justify-content: flex-end; }

/* speech bubble */
.bubble {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  pointer-events: none;
  will-change: transform;
}
.bubble > span {
  position: absolute;
  bottom: 14px;
  left: 0;
  transform: translateX(-50%) scale(0.6);
  transform-origin: 50% 100%;
  opacity: 0;
  /* Give short station replies a real line box. Without an explicit width,
     an intrinsic CJK box can collapse to a narrow vertical strip. */
  width: min(300px, calc(100vw - 40px));
  max-width: calc(100vw - 40px);
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: center;
  line-height: 1.55;
  padding: 9px 12px;
  background: #f4efe2;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  box-shadow:
    0 -3px 0 0 #f4efe2,
    0 3px 0 0 #f4efe2,
    3px 0 0 0 #f4efe2,
    -3px 0 0 0 #f4efe2,
    6px 6px 0 0 rgba(0, 0, 0, 0.35);
  transition:
    transform 0.35s var(--ease-back),
    opacity 0.2s;
}
.bubble > span::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -10px;
  width: 8px;
  height: 7px;
  margin-left: -4px;
  background: #f4efe2;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.bubble.is-on > span {
  opacity: 1;
  transform: translateX(-50%) scale(1);
}

/* side panels */
.side {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--dim);
  pointer-events: none;
  opacity: 0;
  transition: opacity 1s var(--ease) 0.6s;
}
.is-live .side {
  opacity: 1;
}
.side--l {
  left: 0;
}
.side--r {
  right: 0;
  text-align: right;
}
.side__k {
  color: var(--faint);
  margin-bottom: 14px;
}
.side__v {
  color: var(--text);
  line-height: 1.9;
}
.side__v span {
  color: var(--dim);
}
.side__rule {
  width: 1px;
  height: 56px;
  margin: 20px 0;
  background: linear-gradient(var(--c-main), transparent);
}
.telemetry {
  margin: 0;
  display: grid;
  gap: 6px;
}
.side--r .telemetry {
  margin: 0 0 26px;
}
.telemetry div {
  display: flex;
  justify-content: flex-end;
  gap: 14px;
}
.telemetry dt {
  color: var(--faint);
}
.telemetry dd {
  min-width: 4.5em;
}
.telemetry dd {
  margin: 0;
  color: var(--c-main);
  font-variant-numeric: tabular-nums;
}
.side__coords {
  margin: 26px 0;
  color: var(--faint);
  line-height: 1.9;
}
.side__slogan {
  color: var(--dim);
  line-height: 1.9;
}

.cross {
  position: absolute;
  z-index: 2;
  width: 13px;
  height: 13px;
  pointer-events: none;
}
.cross::before,
.cross::after {
  content: '';
  position: absolute;
  background: var(--faint);
}
.cross::before {
  left: 6px;
  top: 0;
  width: 1px;
  height: 13px;
}
.cross::after {
  top: 6px;
  left: 0;
  height: 1px;
  width: 13px;
}
.cross--tl {
  left: -6px;
  /* Keep the marker clear of the route notice (01 / Welcome...). */
  top: 104px;
}
.cross--tr {
  right: -6px;
  top: 72px;
}
.cross--bl {
  left: -6px;
  bottom: 62px;
  /* The lower-left marker adds visual noise beside the copy. */
  display: none;
}
.cross--br {
  right: -6px;
  bottom: 62px;
}

.stage__foot {
  /* The terminal output has moved into the lede. Keep this form in the DOM
     as a keyboard target without reserving space or drawing a second line. */
  position: fixed;
  left: -10000px;
  top: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}
.term {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex: 1;
  max-width: 720px;
  cursor: text;
}
.term__prompt {
  color: var(--c-main);
  cursor: text;
}
.term__line {
  min-width: 0;
  max-width: min(330px, 72vw);
  white-space: pre-line;
  text-align: left;
  line-height: 1.55;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
  font-family: var(--cn);
  letter-spacing: 0.02em;
}
.term__line #term-out {
  font-family: var(--mono), var(--cn);
}
.term__cursor {
  display: inline-block;
  width: 8px;
  height: 15px;
  margin-left: 4px;
  vertical-align: -2px;
  background: var(--c-main);
  animation: blink 1s steps(1) infinite;
}
.term__input {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 100%;
  font: inherit;
  border: 0;
  background: transparent;
  color: transparent;
  cursor: text;
}
.term.is-typing .term__line {
  color: var(--c-main);
}
.stage__hint {
  color: var(--faint);
  font-size: 11px;
  letter-spacing: 0.12em;
  white-space: nowrap;
}
.stage__hint kbd {
  font-size: 10px;
  color: var(--dim);
}

/* ───────────────────────── intro ───────────────────────── */
.intro {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  padding: 26px 0 30px;
  border-bottom: 1px solid var(--line);
  /* Keep the copy/CTA anchor stable while an entrance card reveals its
     secondary actions. The card may grow in its own grid row, but must not
     make this section re-measure on every pointer move. */
  contain: layout;
}
.intro__title {
  margin: 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 14px;
  font-size: clamp(48px, 6vw, 88px);
  line-height: 1;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.intro__head {
  display: contents;
}
.intro__cn {
  background: linear-gradient(180deg, var(--text) 30%, var(--dim));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.intro__title em {
  font-style: normal;
  font-family: var(--mono);
  font-weight: 700;
  color: var(--c-main);
  text-shadow: 0 0 40px rgba(255, 194, 75, 0.35);
}
.intro__title .intro__head {
  white-space: nowrap;
}
.intro__tag {
  font-size: clamp(18px, 1.7vw, 24px);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text);
  margin-left: 8px;
}
.intro__lede {
  margin: 14px 0 0;
  color: var(--dim);
  font-size: 15px;
  letter-spacing: 0.03em;
  /* Hover status messages have different lengths. Reserve one line so the
     left copy and the CTA never reflow when the pointer changes station. */
  min-height: 1.6em;
  height: 1.6em;
  overflow: hidden;
  white-space: nowrap;
}
.intro__lede .term__prompt {
  display: inline-block;
  margin-right: 10px;
  color: var(--c-main);
  font-family: var(--mono);
}
.intro__lede .term__line {
  display: inline;
  max-width: none;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  color: inherit;
  font-family: inherit;
  line-height: inherit;
}
.intro__lede .term__line #term-out {
  font-family: inherit;
}
.intro__lede .term__cursor {
  height: 1em;
  margin-left: 5px;
  vertical-align: -0.14em;
}
.intro__copy > * {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.9s var(--ease),
    transform 0.9s var(--ease);
}
.is-live .intro__copy > * {
  opacity: 1;
  transform: none;
}
.is-live .intro__copy > :nth-child(2) {
  transition-delay: 0.12s;
}

.cta {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  width: 360px;
  max-width: 100%;
  height: 88px;
  min-height: 88px;
  max-height: 88px;
  padding: 20px 24px;
  /* The anchor remains the stable pointer target. Its visual plate lives in
     ::after so the plate can float on hover without making the hit area
     chase the pointer at its edges. */
  background: transparent;
  color: var(--on-accent);
  box-shadow: none;
  isolation: isolate;
  transition:
    filter 0.18s var(--ease),
    box-shadow 0.18s var(--ease);
  overflow: visible;
  opacity: 0;
  translate: 0 16px;
}
.is-live .cta {
  opacity: 1;
  translate: 0 0;
  transition:
    filter 0.18s var(--ease),
    box-shadow 0.18s var(--ease),
    opacity 0.9s var(--ease) 0.2s,
    translate 0.9s var(--ease) 0.2s;
}
.cta::before {
  content: '';
  position: absolute;
  /* Lower plate: it sits a few pixels down and to the right at rest. Keep
     it separate from the upper plate so the two layers can travel at
     different speeds on hover, like the reference button. */
  inset: 8px -8px -8px 8px;
  z-index: 0;
  pointer-events: none;
  background: color-mix(in srgb, var(--c-main) 65%, #725012);
  transform: translate3d(0, 0, 0);
  transition: transform 0.36s var(--ease-back);
}

.cta::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.55) 48%, transparent 66%) -110% 0 / 220% 100% no-repeat,
    var(--c-main);
  box-shadow:
    0 0 60px -10px rgba(255, 194, 75, 0.5);
  transition:
    transform 0.36s var(--ease-back),
    background-position 0.7s var(--ease),
    box-shadow 0.36s var(--ease-back),
    filter 0.18s var(--ease);
}
.cta:hover::before,
.cta:focus-visible::before {
  /* The lower plate only lifts, while the upper plate also moves right. */
  transform: translate3d(0, -4px, 0);
}
.cta:hover::after,
.cta:focus-visible::after {
  transform: translate3d(5px, -8px, 0);
  background-position: 110% 0, 0 0;
  box-shadow:
    0 0 68px -8px rgba(255, 194, 75, 0.58);
}
.cta:hover {
  /* Keep the hit box fixed while the visual plate above gives the control
     the lively lift it had before. */
  filter: brightness(1.06);
}
.cta:not([href]) {
  cursor: pointer;
}
.cta:active {
  filter: brightness(0.96);
}
.cta:active::after {
  transform: translate3d(1px, 1px, 0);
}
.cta:active::before {
  transform: translate3d(0, 0, 0);
}
.cta__label {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  transition: transform 0.36s var(--ease-back);
}
.cta:hover .cta__label,
.cta:focus-visible .cta__label {
  transform: translate3d(5px, -8px, 0);
}
.cta__en {
  font-family: var(--mono);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: 0.08em;
}
.cta__cn {
  font-size: 13px;
  font-weight: 600;
  opacity: 0.72;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.cta__arrow {
  position: relative;
  z-index: 2;
  width: 28px;
  height: 28px;
  transition: transform 0.36s var(--ease-back);
}
.cta:hover .cta__arrow,
.cta:focus-visible .cta__arrow {
  transform: translate3d(10px, -6px, 0);
}

/* ───────────────────────── node cards ───────────────────────── */
.nodes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: stretch;
  margin-top: 22px;
  border: 1px solid var(--line);
  background: var(--line);
  gap: 1px;
}
.node-slot {
  position: relative;
  /* Keep the slot as the stable drawer track. The card itself grows upward
     when its secondary row opens, so the lower edge never moves. */
  display: block;
  min-width: 0;
  min-height: 100%;
}
.node {
  --c: var(--c-main);
  --node-lift: 0px;
  --drawer-rise: 60px;
  position: relative;
  margin-top: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  gap: 4px 18px;
  align-items: start;
  padding: 22px 24px 22px 24px;
  background: var(--bg);
  text-align: left;
  overflow: hidden;
  isolation: isolate;
  transition:
    background 0.35s var(--ease),
    translate 0.32s var(--ease),
    margin-top 0.34s var(--ease),
    box-shadow 0.32s var(--ease);
  opacity: 0;
  transform: translateY(20px);
  translate: 0 var(--node-lift);
  width: 100%;
}
.is-live .node {
  opacity: 1;
  transform: none;
  transition:
    background 0.35s var(--ease),
    translate 0.32s var(--ease),
    margin-top 0.34s var(--ease),
    box-shadow 0.32s var(--ease),
    opacity 0.8s var(--ease) calc(0.3s + var(--i) * 0.08s),
    transform 0.8s var(--ease) calc(0.3s + var(--i) * 0.08s);
}
.node::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--c);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s var(--ease);
}
.node::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(420px 160px at 0% 0%, color-mix(in srgb, var(--c) 16%, transparent), transparent 70%),
    repeating-linear-gradient(180deg, color-mix(in srgb, var(--c) 5%, transparent) 0 1px, transparent 1px 4px);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
.node:hover::before,
.node.is-active::before,
.node.is-selected::before,
.node:focus-visible::before {
  transform: scaleX(1);
}
.node:hover::after,
.node.is-active::after,
.node.is-selected::after,
.node:focus-visible::after {
  opacity: 1;
}
.node:hover,
.node.is-active,
.node.is-selected {
  /* Open like a drawer: the extra row is paid for with a negative top
     margin, keeping the bottom edge anchored to the slot. */
  --node-lift: 0px;
  margin-top: calc(-1 * var(--drawer-rise));
  background: var(--bg-2);
  z-index: 2;
  box-shadow: 0 16px 30px -24px color-mix(in srgb, var(--c) 72%, transparent);
}
.node:focus-visible {
  outline-offset: -2px;
  outline-color: var(--c);
}
.node__idx {
  grid-row: span 2;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--faint);
  padding-top: 3px;
  transition: color 0.3s;
}
.node:hover .node__idx,
.node.is-active .node__idx {
  color: var(--c);
}
.node__head {
  display: flex;
  align-items: center;
  gap: 0;
  grid-column: 2;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text);
}
.node__head i {
  width: 6px;
  height: 6px;
  flex: 0 0 6px;
  /* The status light belongs beside the title, as in the reference card,
     instead of being pushed to the far side of the heading column. */
  margin-left: 18px;
  background: var(--c);
  box-shadow: 0 0 10px var(--c);
}
.node__body {
  grid-column: 2;
  grid-row: 2;
}
.node__title {
  display: block;
  margin: 0;
}
.node__code {
  display: block;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--dim);
  line-height: 1.4;
}
.node__desc {
  display: block;
  margin-top: 5px;
  max-width: 32em;
  color: var(--faint);
  font-size: 11px;
  line-height: 1.55;
  letter-spacing: 0.01em;
}
/* Secondary entrances live in a real grid row so the card can grow without
   covering its copy or stealing the hit area from a neighbouring card. */
.node__reveal {
  grid-column: 2 / 4;
  grid-row: 3;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  width: 100%;
  max-height: 0;
  margin-top: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition:
    max-height 0.34s var(--ease),
    margin-top 0.34s var(--ease),
    opacity 0.22s ease,
    transform 0.34s var(--ease);
}
.node__reveal-btn {
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: 46px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--c) 68%, var(--line-2));
  color: color-mix(in srgb, var(--c) 82%, var(--text));
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.3;
  letter-spacing: 0.08em;
  white-space: nowrap;
  transition:
    background 0.25s var(--ease),
    border-color 0.25s var(--ease),
    color 0.25s var(--ease),
    transform 0.25s var(--ease);
}
.node__reveal-btn::after {
  content: '↗';
  margin-left: auto;
  padding-left: 8px;
  font-size: 15px;
  line-height: 1;
}
.node__reveal-btn:hover {
  background: color-mix(in srgb, var(--c) 11%, transparent);
  border-color: var(--c);
  color: var(--c);
}
.node:hover .node__reveal,
.node.is-active .node__reveal,
.node.is-selected .node__reveal,
.node:focus-visible .node__reveal {
  /* Match the 46px entrance row exactly. Together with the 14px gap this
     lets the -60px drawer rise cancel the added height throughout the
     transition, so the bottom edge stays still instead of dipping first. */
  max-height: 46px;
  margin-top: 14px;
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.node__arrow {
  grid-column: 3;
  /* Park the action control in the upper-right corner. The copy below it
     can now breathe while KEY remains independently anchored at the bottom. */
  grid-row: 1;
  align-self: start;
  width: 42px;
  height: 42px;
  margin-top: -2px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  color: var(--c);
  transition:
    background 0.3s var(--ease),
    color 0.3s,
    border-color 0.3s,
    transform 0.3s var(--ease);
}
.node__arrow svg {
  width: 16px;
  height: 16px;
  transition: transform 0.35s var(--ease);
}
.node:hover .node__arrow,
.node.is-active .node__arrow {
  background: var(--c);
  border-color: var(--c);
  color: var(--on-accent);
}
.node:hover .node__arrow svg,
.node.is-active .node__arrow svg {
  transform: translate(2px, -2px);
}
.node__key {
  position: absolute;
  right: 10px;
  bottom: 8px;
  font-family: var(--pixel);
  font-size: 9px;
  letter-spacing: 0.1em;
  color: var(--faint);
  opacity: 0.8;
}

/* ───────────────────────── statusbar & footer ───────────────────────── */
.statusbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  padding: 16px 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--dim);
}
.statusbar__items {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 26px;
}
.statusbar__items span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.statusbar__items i {
  width: 5px;
  height: 5px;
  background: var(--c);
}
.foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding: 20px 0 26px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--faint);
}
.foot__keys kbd {
  font-size: 10px;
}
.foot__motto {
  color: var(--dim);
}

/* ───────────────────────── chat drawer ───────────────────────── */
.chat {
  --c: var(--c-support);
  position: fixed;
  z-index: 60;
  right: 24px;
  bottom: 24px;
  width: min(390px, calc(100vw - 32px));
  height: min(580px, calc(100svh - 48px));
  display: flex;
  flex-direction: column;
  background: color-mix(in srgb, var(--bg-2) 91%, transparent);
  backdrop-filter: blur(18px) saturate(1.2);
  border: 1px solid color-mix(in srgb, var(--c) 30%, transparent);
  box-shadow:
    8px 8px 0 0 rgba(94, 230, 208, 0.12),
    0 30px 80px -20px var(--shadow);
  transform: translateY(24px) scale(0.97);
  transform-origin: bottom right;
  opacity: 0;
  visibility: hidden;
  transition:
    transform 0.4s var(--ease),
    opacity 0.3s var(--ease),
    visibility 0.4s;
}
.chat.is-open {
  transform: none;
  opacity: 1;
  visibility: visible;
}
.chat__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 14px 14px 16px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, color-mix(in srgb, var(--c) 10%, transparent), transparent);
}
.chat__who {
  display: flex;
  gap: 12px;
  align-items: center;
}
.chat__avatar {
  position: relative;
  width: 38px;
  height: 34px;
  background: #e9e5da;
  box-shadow: inset 0 -4px 0 #c9c4b6;
}
.chat__avatar::before {
  content: '';
  position: absolute;
  left: 5px;
  right: 5px;
  top: 7px;
  height: 15px;
  background: #1b2029;
}
.chat__avatar i {
  position: absolute;
  top: 11px;
  width: 6px;
  height: 7px;
  background: var(--c-main);
  box-shadow: 0 0 6px var(--c-main);
  animation: eyeBlink 4s steps(1) infinite;
}
.chat__avatar i:first-child {
  left: 10px;
}
.chat__avatar i:last-child {
  right: 10px;
}
@keyframes eyeBlink {
  96% {
    height: 1px;
    top: 14px;
  }
}
.chat__name {
  font-weight: 700;
  font-size: 14px;
}
.chat__status {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--c);
  display: flex;
  align-items: center;
  gap: 6px;
}
.chat__status i {
  width: 5px;
  height: 5px;
  background: currentColor;
  animation: blink 1.4s steps(1) infinite;
}
.chat__log {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
.msg {
  max-width: 84%;
  padding: 9px 12px;
  font-size: 14px;
  line-height: 1.55;
  animation: msgIn 0.35s var(--ease-back);
}
@keyframes msgIn {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.96);
  }
}
.msg--bot {
  align-self: flex-start;
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border-left: 2px solid var(--c);
}
.msg--me {
  align-self: flex-end;
  background: var(--c);
  color: var(--on-accent);
  font-weight: 500;
}
.msg__action {
  margin-top: 8px;
  padding: 5px 10px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  background: var(--c);
  color: var(--ink);
  box-shadow: 3px 3px 0 color-mix(in srgb, var(--c) 35%, #000);
  transition: transform 0.15s, box-shadow 0.15s;
}
.msg__action:hover {
  transform: translate(-1px, -1px);
  box-shadow: 4px 4px 0 color-mix(in srgb, var(--c) 35%, #000);
}
.msg__action:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 color-mix(in srgb, var(--c) 35%, #000);
}
.msg--sys {
  align-self: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--faint);
  padding: 2px;
}
.msg--typing {
  display: inline-flex;
  gap: 4px;
}
.msg--typing i {
  width: 5px;
  height: 5px;
  background: var(--c);
  animation: dots 1s infinite;
}
.msg--typing i:nth-child(2) {
  animation-delay: 0.15s;
}
.msg--typing i:nth-child(3) {
  animation-delay: 0.3s;
}
@keyframes dots {
  50% {
    opacity: 0.2;
    transform: translateY(-3px);
  }
}
.chat__quick {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 16px 12px;
}
.chat__quick button {
  font-size: 12px;
  padding: 6px 10px;
  border: 1px solid color-mix(in srgb, var(--c) 35%, transparent);
  color: var(--c);
  transition: background 0.2s;
}
.chat__quick button:hover {
  background: color-mix(in srgb, var(--c) 14%, transparent);
}
.chat__form {
  display: flex;
  border-top: 1px solid var(--line);
}
.chat__form input {
  flex: 1;
  min-width: 0;
  padding: 14px 16px;
  background: transparent;
  border: 0;
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.chat__form input:focus {
  outline: none;
}
.chat__form button {
  width: 52px;
  display: grid;
  place-items: center;
  color: var(--c);
  border-left: 1px solid var(--line);
}
.chat__form button svg {
  width: 18px;
  height: 18px;
}

/* ───────────────────────── fx overlays ───────────────────────── */
.warp {
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at 50% 50%, #fff6df 0%, var(--wc, var(--c-main)) 30%, color-mix(in srgb, var(--bg) 0%, transparent) 70%);
  mix-blend-mode: screen;
}
.warp.is-on {
  animation: warp 1.5s var(--ease) forwards;
}
@keyframes warp {
  0% {
    opacity: 0;
    transform: scale(0.2);
  }
  55% {
    opacity: 1;
    transform: scale(1.6);
  }
  100% {
    opacity: 0;
    transform: scale(2.4);
  }
}
.toast {
  position: fixed;
  z-index: 85;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 20px);
  padding: 10px 16px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  background: color-mix(in srgb, var(--bg-2) 94%, transparent);
  border: 1px solid var(--line-2);
  color: var(--text);
  opacity: 0;
  transition:
    opacity 0.3s,
    transform 0.3s var(--ease);
  pointer-events: none;
}
.toast.is-on {
  opacity: 1;
  transform: translate(-50%, 0);
}
.grain {
  position: fixed;
  inset: -50%;
  z-index: 70;
  pointer-events: none;
  opacity: 0.05;
  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%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 1.2s steps(4) infinite;
}
@keyframes grain {
  25% {
    transform: translate(-3%, 2%);
  }
  50% {
    transform: translate(2%, -3%);
  }
  75% {
    transform: translate(-1%, 3%);
  }
}
.noscript {
  position: fixed;
  inset: 0;
  z-index: 99;
  display: grid;
  place-content: center;
  text-align: center;
  background: var(--bg);
  font-size: 16px;
}
.noscript a {
  color: var(--c-main);
}

/* ───────────────────────── desktop hero: copy over the scene ───────────────────────── */
@media (min-width: 1181px) {
  .app > main {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    /* Expanded cards must not redistribute free space into the stage row. */
    align-content: start;
  }
  .stage {
    /* Give the scene more breathing room beside the left copy. */
    /* Preview baseline: --shift 0.17, --fit 1. */
    --shift: 0.13;
    --lift: 0;
    --fit: 0.96;
    grid-area: 1 / 1;
    height: clamp(560px, calc(100svh - 76px - 176px), 900px);
  }
  .stage::before {
    content: '';
    position: absolute;
    z-index: 1;
    left: calc(50% - 50vw);
    top: 0;
    bottom: 0;
    width: calc(50vw - 4%);
    pointer-events: none;
    background: radial-gradient(90% 70% at 0% 78%, color-mix(in srgb, var(--bg) 82%, transparent), color-mix(in srgb, var(--bg) 40%, transparent) 50%, transparent 78%);
  }
  .intro {
    grid-area: 1 / 1;
    align-self: end;
    justify-self: start;
    flex-direction: column;
    align-items: flex-start;
    gap: 30px;
    width: min(560px, 42%);
    max-width: none;
    margin-bottom: 148px;
    padding: 0;
    border: 0;
    z-index: 4;
  }
  .intro__title {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  .intro__copy {
    width: 100%;
    min-width: 0;
  }
  .intro__head {
    display: flex;
    align-items: baseline;
    gap: 16px;
  }
  .intro__tag {
    margin-left: 0;
  }
  .intro__lede {
    max-width: 30em;
  }
  .stage__title {
    display: none;
  }
  .nodes {
    margin-top: 16px;
  }
}

@media (max-width: 1180px) {
  .stage__notice {
    left: 0;
    top: 9%;
    max-width: calc(100% - 24px);
    font-size: 14px;
  }
}

/* ───────────────────────── responsive ───────────────────────── */
@media (max-width: 1180px) {
  .side {
    display: none;
  }
  .top__ticker {
    visibility: hidden;
  }
  .node {
    padding: 20px 18px;
    gap: 4px 12px;
  }
  .node__desc {
    display: block;
  }
}

@media (max-width: 860px) {
  .intro {
    flex-direction: column;
    align-items: stretch;
  }
  .cta {
    width: 100%;
  }
  .nodes {
    grid-template-columns: 1fr;
  }
  .node__desc {
    display: block;
  }
  .foot__keys {
    display: none;
  }
}

@media (max-width: 640px) {
  body {
    font-size: 14px;
  }
  .hide-sm {
    display: none !important;
  }
  .top {
    height: 64px;
    gap: 12px;
    grid-template-columns: auto 1fr auto;
  }
  .top__ticker {
    display: none;
  }
  .top__meta {
    grid-column: 3;
    gap: 10px;
  }
  .top__meta .meta__k {
    display: none;
  }
  .pill--live {
    display: none;
  }
  .brand__cn {
    display: none;
  }
  .brand__name {
    font-size: 16px;
  }
  .mark {
    width: 26px;
    height: 26px;
  }
  .stage {
    --shift: 0.05;
    --lift: 0.03;
    --fit: 1;
    height: min(118vw, 520px);
    min-height: 400px;
  }
  .stage__bar {
    padding-top: 14px;
  }
  .crumb {
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  .btn-ghost {
    padding: 6px 9px;
    font-size: 10px;
  }
  .stage__title {
    top: 12%;
    font-size: 19vw;
  }
  .stage__notice {
    top: 7%;
    gap: 9px;
    padding-right: 8px;
    font-size: 12px;
  }
  .stage__notice-mark {
    font-size: inherit;
  }
  .stage__notice-caret {
    width: auto;
    height: auto;
    background: none;
  }
  .cross--tl,
  .cross--tr {
    top: 52px;
  }
  .cross--tl {
    /* Leave a little extra breathing room below the route notice on phones. */
    top: 82px;
  }
  .label__tag {
    padding: 4px 8px;
    font-size: 10px;
    bottom: 34px;
  }
  /* compact tags: index only, the name unfolds when active */
  .label__name,
  .label__code {
    display: none;
  }
  .label__title b {
    margin-right: 0;
  }
  .label__stem {
    height: 28px;
  }
  .label.is-active .label__stem {
    height: 36px;
  }
  .label.is-active .label__tag {
    /* Keep the compact tag's pointer target anchored while details unfold. */
    bottom: 34px;
  }
  .label__more > div {
    font-size: 12px;
  }
  .stage__foot {
    /* Keep the off-canvas command form hidden on narrow screens too. */
    display: none;
  }
  .intro {
    padding: 14px 0 22px;
  }
  .intro__title {
    font-size: 52px;
  }
  .intro__tag {
    flex-basis: 100%;
    margin: 10px 0 0;
    font-size: 18px;
  }
  .intro__lede {
    font-size: 13px;
    max-width: 100%;
  }
  .cta {
    padding: 16px 20px;
  }
  .node {
    padding: 18px 16px;
  }
  .node__title {
    font-size: 17px;
  }
  .node__key {
    display: none;
  }
  .statusbar {
    flex-direction: column;
    align-items: flex-start;
  }
  .foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .chat {
    right: 8px;
    left: 8px;
    bottom: 8px;
    width: auto;
    height: min(72svh, 560px);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .ticker {
    animation: none;
  }
}

/* Connector map revealed by the SET SAIL tour. It is a viewport layer so the
   routes stay aligned when the orthographic camera or page layout changes. */
.route-overlay {
  position: fixed;
  inset: 0;
  z-index: 2;
  /* The guided tour now uses the island lights and robot gaze as the cue.
     Keep the bridge mounted for layout compatibility, but don't draw route
     lines over the scene/cards. */
  display: none !important;
  width: 100vw;
  height: 100vh;
  overflow: visible;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s ease, visibility 0s linear 0.45s;
}
.route-overlay.is-on {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
.route-overlay__route {
  color: var(--route-color);
  opacity: 0.32;
  transition: opacity 0.35s ease, filter 0.35s ease;
}
.route-overlay__route.is-active {
  opacity: 1;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--route-color) 75%, transparent));
}
.route-overlay__route.is-hidden {
  opacity: 0;
}
.route-overlay__line {
  stroke: var(--route-color);
  stroke-width: 1.35;
  stroke-linecap: square;
  stroke-dasharray: none;
  stroke-dashoffset: 0;
  opacity: 0.76;
}
.route-overlay__route.is-active .route-overlay__line {
  stroke-width: 2;
  opacity: 1;
}
.route-overlay__route.is-drawing .route-overlay__line {
  stroke-dasharray: 1;
  animation: route-draw 0.95s cubic-bezier(0.22, 0.8, 0.2, 1) both;
}
@keyframes route-draw {
  from {
    stroke-dashoffset: 1;
    opacity: 0;
  }
  to {
    stroke-dashoffset: 0;
    opacity: 1;
  }
}
.route-overlay__dot {
  fill: var(--route-color);
  opacity: 0.78;
  vector-effect: non-scaling-stroke;
}
.route-overlay__route.is-active .route-overlay__dot {
  opacity: 1;
  filter: drop-shadow(0 0 4px var(--route-color));
}
.route-overlay__dot--target {
  fill: var(--bg-2, #f5f7fb);
  stroke: var(--route-color);
  stroke-width: 1.25;
}
@media (prefers-reduced-motion: reduce) {
  .route-overlay__route.is-drawing .route-overlay__line {
    animation: none;
  }
}
@media (max-width: 640px) {
  .route-overlay__line {
    stroke-width: 1;
  }
  .route-overlay__route.is-active .route-overlay__line {
    stroke-width: 1.5;
  }
}
