:root {
    --neblux-motion-feedback: 120ms;
    --neblux-motion-arrival: 180ms;
    --neblux-motion-panel: 220ms;
    --neblux-accent: #c7a66b;
    /* Deep field surfaces; gold remains the navigation and brand accent. */
    --neblux-bg: #02040a;
    --neblux-surface: #080c14;
    --neblux-surface-raised: #0d121c;
    --neblux-ink: #eeeae2;
    --neblux-muted: #a1a8b5;
    --neblux-radius-sm: 6px;
    --neblux-radius-md: 12px;
    --neblux-radius-lg: 20px;
    --neblux-radius-control: 999px;   /* 互動控件統一圓角（膠囊）：搜尋框 / 按鈕 / 標籤 */
    --neblux-radius-panel: 16px;      /* 浮層面板統一圓角：下拉結果 / tooltip */
    --neblux-shadow-soft: 0 10px 30px rgba(0, 0, 0, 0.38);
    --neblux-shadow-strong: 0 24px 56px rgba(0, 0, 0, 0.58);
    --neblux-ease-ui: cubic-bezier(0.16, 1, 0.3, 1);
    --neblux-glass-border: rgba(255, 255, 255, 0.08);
    --neblux-glass-shadow: 0 0 20px rgba(199, 166, 107, 0.04);

    /* ── Button system (B segmented rail + C ghost) — shared by Main ──
       One container holds the glass/blur; inner buttons are borderless segments.
       active text = --neblux-accent. Dark = graph chrome, light = detail panel. */
    --rail-bg:            rgba(5, 8, 15, 0.78);
    --rail-border:        rgba(255, 255, 255, 0.09);
    --rail-divider:       rgba(255, 255, 255, 0.06);
    --seg-hover:          rgba(255, 255, 255, 0.05);
    --seg-active:         rgba(199, 166, 107, 0.18);
    --rail-bg-light:      rgba(148, 163, 184, 0.08);
    --rail-border-light:  rgba(148, 163, 184, 0.22);
    --rail-divider-light: rgba(148, 163, 184, 0.22);
    --seg-hover-light:    rgba(148, 163, 184, 0.14);
    --seg-active-light:   rgba(199, 166, 107, 0.22);

    /* ── Type families ─────────────────────────────────────────────────────
       Oxanium now drives display + headlines (was Sora); Sora stays for body.
       Space Grotesk dropped — node/tooltip titles use Oxanium. */
    /* None of the Latin faces above ship CJK glyphs, so every Chinese and
       Japanese page was falling through to whatever `system-ui` happens to be
       on that machine — a different face per OS, and per family. Name the CJK
       fallback explicitly instead, in the site's own order of preference. No
       extra payload: these are all system faces. */
    --font-cjk: 'PingFang TC', 'Hiragino Sans', 'Noto Sans CJK TC', 'Noto Sans TC',
                'Microsoft JhengHei', 'Yu Gothic', sans-serif;
    --font-display:       'Oxanium', var(--font-cjk);                /* display + UI headlines */
    --font-body:          'Sora', var(--font-cjk);                   /* body text, paragraphs */
    --font-graph-body:    'IBM Plex Sans', var(--font-cjk);          /* graph-view prose */
    /* Mono readouts carry CJK too (kickers, domain lines, counts). Without a
       named face those glyphs fell to whatever generic monospace the OS has —
       a third CJK face beside the body's. Latin stays mono; CJK joins the body. */
    --font-cjk-mono:      'PingFang TC', 'Hiragino Sans', 'Noto Sans CJK TC', 'Noto Sans TC',
                          'Microsoft JhengHei', 'Yu Gothic', monospace;
    --font-label:         'JetBrains Mono', ui-monospace, var(--font-cjk-mono); /* chrome labels, wordmark */
    --font-mono:          'IBM Plex Mono', ui-monospace, var(--font-cjk-mono);  /* graph data, code */
    --font-tooltip-title: 'Oxanium', var(--font-cjk);                /* tooltip / node titles */

    /* ── Fluid text scale  (375px → 1440px) ────────────────────────────────
       T-shirt steps: 2xs · xs · sm · base · md · lg · xl · 2xl · 3xl · 4xl */
    --text-2xs:  clamp(10px, calc(0.094vw +  9.65px), 11px);
    --text-xs:   clamp(11px, calc(0.094vw + 10.65px), 12px);
    --text-sm:   clamp(13px, calc(0.094vw + 12.65px), 14px);
    --text-base: clamp(15px, calc(0.188vw + 14.30px), 17px);
    --text-md:   clamp(17px, calc(0.282vw + 15.94px), 20px);
    --text-lg:   clamp(20px, calc(0.751vw + 17.18px), 28px);
    --text-xl:   clamp(26px, calc(1.315vw + 21.07px), 40px);
    --text-2xl:  clamp(34px, calc(2.066vw + 26.25px), 56px);
    --text-3xl:  clamp(44px, calc(2.629vw + 34.14px), 72px);
    --text-4xl:  clamp(56px, calc(3.756vw + 41.92px), 96px);

    /* ── Leading (line-height) ─────────────────────────────────────────────── */
    --leading-none:    1;
    --leading-tight:   1.1;
    --leading-snug:    1.25;
    --leading-normal:  1.5;
    --leading-relaxed: 1.6;
    --leading-loose:   1.75;

    /* ── Tracking (letter-spacing) ─────────────────────────────────────────── */
    --tracking-tight:   -0.025em;
    --tracking-snug:    -0.01em;
    --tracking-normal:  0em;
    --tracking-wide:     0.06em;
    --tracking-wider:    0.1em;
    --tracking-widest:   0.14em;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SEMANTIC TYPE RAMP  —  .type-* classes
   Prefer these going forward. Legacy .display-lg / .body-base aliases below.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Display — Oxanium, futuristic character ───────────────────────────── */
.type-display {
    font-family: var(--font-display);
    font-size: var(--text-4xl); line-height: var(--leading-none);
    letter-spacing: var(--tracking-tight); font-weight: 700;
}
.type-display-sm {
    font-family: var(--font-display);
    font-size: var(--text-3xl); line-height: var(--leading-tight);
    letter-spacing: -0.02em; font-weight: 700;
}

/* ── Headline — Oxanium ────────────────────────────────────────────────── */
.type-headline-lg {
    font-family: var(--font-display);
    font-size: var(--text-2xl); line-height: var(--leading-tight);
    letter-spacing: -0.015em; font-weight: 700;
}
.type-headline {
    font-family: var(--font-display);
    font-size: var(--text-xl); line-height: var(--leading-snug);
    letter-spacing: var(--tracking-snug); font-weight: 600;
}
.type-headline-sm {
    font-family: var(--font-display);
    font-size: var(--text-lg); line-height: 1.3;
    font-weight: 600;
}

/* ── Body — Sora ───────────────────────────────────────────────────────── */
.type-body-lg {
    font-family: var(--font-body);
    font-size: var(--text-md); line-height: var(--leading-relaxed);
    font-weight: 400;
}
.type-body {
    font-family: var(--font-body);
    font-size: var(--text-base); line-height: var(--leading-relaxed);
    font-weight: 400;
}
.type-body-sm {
    font-family: var(--font-body);
    font-size: var(--text-sm); line-height: var(--leading-normal);
    font-weight: 400;
}

/* ── Label — JetBrains Mono ────────────────────────────────────────────── */
.type-label {
    font-family: var(--font-label);
    font-size: var(--text-sm); line-height: 1.4;
    font-weight: 400;
}
.type-label-caps {
    font-family: var(--font-label);
    font-size: var(--text-xs); line-height: 1;
    letter-spacing: var(--tracking-wider); font-weight: 500;
    text-transform: uppercase;
}
.type-micro {
    font-family: var(--font-label);
    font-size: var(--text-2xs); line-height: 1;
    letter-spacing: var(--tracking-wide);
}

/* ── Code / Graph — IBM Plex Mono ──────────────────────────────────────── */
.type-code {
    font-family: var(--font-mono);
    font-size: var(--text-sm); line-height: var(--leading-normal);
    font-weight: 400;
}
.type-graph-label {
    font-family: var(--font-mono);
    font-size: var(--text-xs); letter-spacing: 0.04em;
    font-weight: 400;
}

/* ── Legacy aliases — deprecated; prefer .type-* above ─────────────────── */
.display-lg        { font-family: var(--font-display); font-size: var(--text-4xl); line-height: var(--leading-none); letter-spacing: var(--tracking-tight); font-weight: 700; }
.display-lg-mobile { font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); font-weight: 700; }
.headline-md       { font-family: var(--font-display); font-size: var(--text-lg); line-height: 1.25; font-weight: 600; }
.body-base         { font-family: var(--font-body); font-size: var(--text-base); line-height: var(--leading-relaxed); }
.body-sm           { font-family: var(--font-body); font-size: var(--text-sm); line-height: var(--leading-normal); }
.label-code        { font-family: var(--font-label); font-size: var(--text-sm); line-height: 1.4; }
.label-caps        { font-family: var(--font-label); font-size: var(--text-xs); letter-spacing: var(--tracking-wider); font-weight: 500; text-transform: uppercase; }
.graph-data-label  { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.05em; }
/* ═══════════════════════════════════════════════════════════════════════════
   CJK TEXT  —  the ramp above is tuned for Latin
   Full-width punctuation already carries half a glyph of side bearing, and CJK
   glyphs sit on a fixed body box, so Latin-tuned tracking and leading read as
   airy: 「的學科 ， 為」 opens a hole after every comma and 1.75 leading turns a
   paragraph into rivers. Trim the punctuation, drop the extra tracking, and cap
   prose leading. `:where()` keeps specificity at 0 so any page can still opt out.
   ═══════════════════════════════════════════════════════════════════════════ */
:where(:lang(zh), :lang(zh-Hant), :lang(ja)) {
    text-spacing-trim: trim-start;
}
:where(:lang(zh), :lang(zh-Hant), :lang(ja)) :where(p, li, dd, dt, blockquote, figcaption, summary) {
    letter-spacing: normal;
}
:where(:lang(zh), :lang(zh-Hant), :lang(ja)) :where(p, li, blockquote) {
    line-height: min(var(--leading-relaxed), 1.7);
}
