/* ============================================================
   MarsBlog · Unified Design System
   Three themes (Ocean / Mono / Nebula) sharing one token layer
   ============================================================ */

/* --- 1.  Modern reset (lightweight, plays nice with Bootstrap) --- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; }
img, svg, video { max-width: 100%; height: auto; display: block; }
button { font-family: inherit; }

/* ============================================================
   2.  Design tokens (font, space, radius, motion)
   ============================================================ */
:root {
    /* -- nav height (Apple slim app bar) -- */
    --nav-h: 48px;

    /* -- editorial faces (landing + post list) --
       Archivo 是可变字重 + 可变字宽（100%–125%）的 grotesque，展宽后
       是机构标识/年报那种气派感；IBM Plex Mono 承载编号、日期、状态这类
       仪表信息。两者只在公共页面使用，中文自动回落到系统字体。 */
    --font-editorial: "Archivo", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", sans-serif;
    --font-data:      "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

    /* -- hairline rules：跟随当前主题的正文色，明暗两套都不用另写 -- */
    --rule:        color-mix(in srgb, var(--text-primary) 12%, transparent);
    --rule-strong: color-mix(in srgb, var(--text-primary) 26%, transparent);

    /* -- 8px spacing scale -- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;
    --space-9: 96px;

    /* -- motion -- */
    --ease-out:     cubic-bezier(0.16, 1, 0.3, 1);
    --ease-apple:   cubic-bezier(0.2, 0.8, 0.2, 1);
    --ease-spring:  cubic-bezier(0.34, 1.56, 0.64, 1);
    --dur-fast:     0.15s;
    --dur-base:     0.25s;
    --dur-slow:     0.4s;

    /* -- z-index scale -- */
    --z-nav:       100;
    --z-overlay: 1000;
    --z-modal:   1050;
    --z-toast:   1100;
    --z-popover: 9999;
}

/* ============================================================
   Mars unified design system + progressive app shell
   ============================================================ */
html[data-theme="mars"] {
    --font-display: "Inter", "Noto Sans SC", -apple-system, BlinkMacSystemFont, sans-serif;
    --font-sans: "Inter", "Noto Sans SC", -apple-system, BlinkMacSystemFont, sans-serif;
    --brand: #7c6cff;
    --brand-hover: #9286ff;
    --brand-soft: rgba(124, 108, 255, .14);
    --brand-contrast: #fff;
    --accent: #32d6c5;
    --accent-soft: rgba(50, 214, 197, .13);
    --radius-xs: 6px;
    --radius-s: 10px;
    --radius-m: 16px;
    --radius-l: 22px;
    --radius-xl: 30px;
    --radius-btn: 12px;
    --radius-pill: 999px;
    --focus-ring: 0 0 0 4px rgba(124, 108, 255, .22);
    color-scheme: dark;
}

html[data-theme="mars"][data-mode="dark"] {
    --bg-body: #0b0d12;
    --bg-card: #141720;
    --bg-subtle: #1a1e29;
    --bg-elevated: #11141b;
    --text-primary: #f6f7fb;
    --text-secondary: #a9b0c0;
    --text-tertiary: #747d90;
    --text-inverse: #0b0d12;
    --border-subtle: rgba(255, 255, 255, .08);
    --border-medium: rgba(255, 255, 255, .14);
    --border-strong: rgba(255, 255, 255, .24);
    --navbar-bg: rgba(11, 13, 18, .82);
    --navbar-text: #e9ebf2;
    --navbar-active: #fff;
    --dropdown-bg: #171a23;
    --dropdown-border: rgba(255, 255, 255, .1);
    --dropdown-hover: #202531;
    --footer-bg: #0e1117;
    --footer-text: #8f97a8;
    --shadow-card: 0 10px 30px rgba(0, 0, 0, .24);
    --shadow-hover: 0 18px 48px rgba(0, 0, 0, .34);
    --shadow-lift: 0 24px 60px rgba(0, 0, 0, .42);
    color-scheme: dark;
}

html[data-theme="mars"][data-mode="light"] {
    --bg-body: #f5f6fa;
    --bg-card: #fff;
    --bg-subtle: #eceef5;
    --bg-elevated: #fff;
    --text-primary: #171923;
    --text-secondary: #646b7a;
    --text-tertiary: #8b92a1;
    --text-inverse: #fff;
    --border-subtle: rgba(24, 28, 40, .08);
    --border-medium: rgba(24, 28, 40, .14);
    --border-strong: rgba(24, 28, 40, .24);
    --navbar-bg: rgba(255, 255, 255, .86);
    --navbar-text: #272a35;
    --navbar-active: #171923;
    --dropdown-bg: #fff;
    --dropdown-border: rgba(24, 28, 40, .1);
    --dropdown-hover: #f0f1f6;
    --footer-bg: #eceef5;
    --footer-text: #707786;
    --shadow-card: 0 8px 28px rgba(33, 39, 58, .08);
    --shadow-hover: 0 16px 42px rgba(33, 39, 58, .14);
    --shadow-lift: 0 22px 54px rgba(33, 39, 58, .18);
    color-scheme: light;
}

.app-navigation-progress {
    position: fixed;
    inset: 0 auto auto 0;
    z-index: 20000;
    width: 0;
    height: 3px;
    opacity: 0;
    pointer-events: none;
    background: linear-gradient(90deg, var(--brand), var(--accent));
    box-shadow: 0 0 16px var(--brand);
    transition: opacity .15s ease, width .25s ease;
}

.app-is-navigating .app-navigation-progress { width: 78%; opacity: 1; }
.app-is-navigating #app-main { opacity: .55; transition: opacity .15s ease; }
#app-main { min-height: calc(100vh - 180px); transition: opacity .2s ease; }
#app-main:focus { outline: none; }

.card, .post-card, .settings-card, .admin-stat-card, .auth-card {
    border-color: var(--border-subtle) !important;
    box-shadow: var(--shadow-card);
}

.btn { border-radius: var(--radius-btn); font-weight: 600; }
.form-control, .form-select { border-radius: var(--radius-s); }

@media (max-width: 768px) {
    #app-main.container { width: 100%; padding-inline: 16px; }
    .hero-title { font-size: clamp(2rem, 10vw, 3.25rem); }
    .post-grid { grid-template-columns: 1fr; }
    .auth-card { padding: 28px 20px; }
}

/* ── Navbar coin balance ─────────────────────────────────────────────────── */
.nav-coin {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    flex-shrink: 0;
    min-width: 72px;
    height: 30px;
    margin-left: var(--space-2);
    padding: 0 10px;
    border: 1px solid color-mix(in srgb, #f0b429 34%, transparent);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, #f0b429 12%, transparent);
    color: var(--navbar-text);
    text-decoration: none;
    font-size: 12px;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    transition: transform var(--dur-fast) var(--ease-apple),
                background var(--dur-fast), border-color var(--dur-fast);
}
.nav-coin i { color: #f0b429; font-size: 14px; }
.nav-coin:hover,
.nav-coin:focus-visible {
    color: var(--navbar-active);
    background: color-mix(in srgb, #f0b429 20%, transparent);
    border-color: color-mix(in srgb, #f0b429 58%, transparent);
    transform: translateY(-1px);
}
.nav-coin-value { min-width: 1ch; text-align: right; }
.nav-coin-label { opacity: .68; font-size: 10px; font-weight: 550; }
.nav-coin.is-gaining { animation: nav-coin-gain .65s var(--ease-spring); }
.nav-coin-float {
    position: absolute;
    left: 50%;
    top: 4px;
    z-index: 2;
    color: #f0b429;
    font-size: 12px;
    font-weight: 750;
    white-space: nowrap;
    pointer-events: none;
    text-shadow: 0 2px 10px rgba(0, 0, 0, .24);
    animation: nav-coin-float .9s var(--ease-out) forwards;
}
@keyframes nav-coin-gain {
    0%, 100% { transform: scale(1); }
    38% { transform: scale(1.13); box-shadow: 0 0 0 8px color-mix(in srgb, #f0b429 14%, transparent); }
}
@keyframes nav-coin-float {
    from { opacity: 0; transform: translate(-50%, 4px) scale(.8); }
    24% { opacity: 1; }
    to { opacity: 0; transform: translate(-50%, -28px) scale(1.08); }
}

@media (max-width: 768px) {
    .nav-coin          { order: 2; margin-left: auto; min-width: 58px; padding: 0 8px; }
    .nav-coin-label    { display: none; }
    .nav-notify        { order: 3; margin-left: var(--space-1); }
    .apple-nav-toggle  { order: 4; }
    .apple-nav-list    { order: 5; }
}

@media (prefers-reduced-motion: reduce) {
    .nav-coin.is-gaining,
    .nav-coin-float { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
    .app-navigation-progress, #app-main { transition: none !important; }
}

/* ============================================================
   3.  THEME · APPLE  (Human Interface Guidelines)   ── default light
   ============================================================ */
:root,
[data-theme="apple"] {
    /* — Typography — */
    --font-display: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", sans-serif;
    --font-sans:    "SF Pro Text", -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", sans-serif;
    --font-serif:   "New York", "Charter", Georgia, "Songti SC", serif;
    --font-mono:    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    /* — Colors — */
    --brand:           #0071e3;
    --brand-hover:     #0077ed;
    --brand-soft:      rgba(0, 113, 227, 0.10);
    --brand-contrast:  #ffffff;

    --accent:        #ff9500;
    --accent-soft:   rgba(255, 149, 0, 0.10);
    --purple:        #bf5af2;
    --purple-soft:   rgba(191, 90, 242, 0.10);
    --green:         #34c759;
    --green-soft:    rgba(52, 199, 89, 0.12);
    --red:           #ff3b30;
    --red-soft:      rgba(255, 59, 48, 0.10);
    --orange:        #ff9500;
    --orange-soft:   rgba(255, 149, 0, 0.10);

    --bg-body:       #fbfbfd;
    --bg-card:       #ffffff;
    --bg-subtle:     #f5f5f7;
    --bg-elevated:   #ffffff;

    --text-primary:   #1d1d1f;
    --text-secondary: #86868b;
    --text-tertiary:  #a1a1a6;
    --text-inverse:   #ffffff;

    --border-subtle:  rgba(0, 0, 0, 0.06);
    --border-medium:  rgba(0, 0, 0, 0.10);
    --border-strong:  rgba(0, 0, 0, 0.18);

    /* — Apple-style soft shadows — */
    --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-card:  0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 24px rgba(0, 0, 0, 0.05);
    --shadow-hover: 0 6px 20px rgba(0, 0, 0, 0.06), 0 16px 48px rgba(0, 0, 0, 0.10);
    --shadow-lift:  0 12px 40px rgba(0, 0, 0, 0.12);

    /* — Generous Apple radii — */
    --radius-xs: 6px;
    --radius-s:  10px;
    --radius-m:  14px;
    --radius-l:  20px;
    --radius-xl: 28px;
    --radius-pill: 980px;
    --radius-btn:  980px;

    --navbar-bg:     rgba(22, 22, 23, 0.80);
    --navbar-text:   #f5f5f7;
    --navbar-active: #ffffff;

    --dropdown-bg:     #ffffff;
    --dropdown-border: rgba(0, 0, 0, 0.06);
    --dropdown-hover:  #f5f5f7;

    --footer-bg:   #f5f5f7;
    --footer-text: #86868b;

    --gradient-hero:   linear-gradient(135deg, #1d1d1f 0%, #86868b 100%);
    --gradient-accent: linear-gradient(135deg, #0071e3 0%, #bf5af2 100%);

    --focus-ring: 0 0 0 4px rgba(0, 113, 227, 0.18);

    --blue: var(--brand);
    --blue-hover: var(--brand-hover);
    --gray: var(--text-secondary);
    --gray-light: var(--bg-subtle);
}

/* ============================================================
   4.  THEME · GOOGLE  (Material Design 3)  ── light
   ============================================================ */
[data-theme="google"] {
    /* — Typography (Roboto + Google Sans) — */
    --font-display: "Google Sans", "Product Sans", "Roboto", "Inter", -apple-system, BlinkMacSystemFont, "Noto Sans SC", sans-serif;
    --font-sans:    "Roboto", "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Noto Sans SC", sans-serif;
    --font-serif:   "Roboto Slab", "Charter", Georgia, serif;
    --font-mono:    "Roboto Mono", ui-monospace, "Courier New", monospace;

    /* — Google four-color palette — */
    --brand:           #1a73e8;
    --brand-hover:     #1967d2;
    --brand-soft:      rgba(26, 115, 232, 0.10);
    --brand-contrast:  #ffffff;

    --accent:        #34a853;   /* Google green */
    --accent-soft:   rgba(52, 168, 83, 0.12);
    --purple:        #a142f4;
    --purple-soft:   rgba(161, 66, 244, 0.10);
    --green:         #34a853;
    --green-soft:    rgba(52, 168, 83, 0.12);
    --red:           #ea4335;   /* Google red */
    --red-soft:      rgba(234, 67, 53, 0.10);
    --orange:        #fbbc04;   /* Google yellow */
    --orange-soft:   rgba(251, 188, 4, 0.16);

    --bg-body:       #ffffff;
    --bg-card:       #ffffff;
    --bg-subtle:     #f8f9fa;
    --bg-elevated:   #ffffff;

    --text-primary:   #202124;
    --text-secondary: #5f6368;
    --text-tertiary:  #80868b;
    --text-inverse:   #ffffff;

    --border-subtle:  rgba(32, 33, 36, 0.08);
    --border-medium:  #dadce0;
    --border-strong:  #80868b;

    /* — Material elevation shadows — */
    --shadow-xs:    0 1px 2px 0 rgba(60, 64, 67, 0.30), 0 1px 3px 1px rgba(60, 64, 67, 0.15);
    --shadow-card:  0 1px 2px 0 rgba(60, 64, 67, 0.30), 0 2px 6px 2px rgba(60, 64, 67, 0.15);
    --shadow-hover: 0 1px 3px 0 rgba(60, 64, 67, 0.30), 0 4px 8px 3px rgba(60, 64, 67, 0.15);
    --shadow-lift:  0 4px 8px 3px rgba(60, 64, 67, 0.15), 0 1px 3px rgba(60, 64, 67, 0.30);

    /* — Material rounded but not pill — */
    --radius-xs: 4px;
    --radius-s:  8px;
    --radius-m:  12px;
    --radius-l:  16px;
    --radius-xl: 24px;
    --radius-pill: 999px;
    --radius-btn:  24px;

    --navbar-bg:     rgba(255, 255, 255, 0.92);
    --navbar-text:   #202124;
    --navbar-active: #1a73e8;

    --dropdown-bg:     #ffffff;
    --dropdown-border: rgba(32, 33, 36, 0.10);
    --dropdown-hover:  #f1f3f4;

    --footer-bg:   #f8f9fa;
    --footer-text: #5f6368;

    --gradient-hero:   linear-gradient(135deg, #1a73e8 0%, #34a853 50%, #fbbc04 100%);
    --gradient-accent: linear-gradient(90deg, #4285f4 0%, #34a853 33%, #fbbc04 66%, #ea4335 100%);

    --focus-ring: 0 0 0 3px rgba(26, 115, 232, 0.24);

    --blue: var(--brand);
    --blue-hover: var(--brand-hover);
    --gray: var(--text-secondary);
    --gray-light: var(--bg-subtle);
}

/* ============================================================
   5.  THEME · MICROSOFT  (Fluent 2 Design)  ── light
   ============================================================ */
[data-theme="microsoft"] {
    /* — Typography (Segoe UI Variable) — */
    --font-display: "Segoe UI Variable Display", "Segoe UI", "Inter", -apple-system, BlinkMacSystemFont, "Microsoft YaHei UI", "Microsoft YaHei", sans-serif;
    --font-sans:    "Segoe UI Variable Text", "Segoe UI", "Inter", -apple-system, BlinkMacSystemFont, "Microsoft YaHei UI", "Microsoft YaHei", sans-serif;
    --font-serif:   "Cambria", "Georgia", "Songti SC", serif;
    --font-mono:    "Cascadia Code", "Consolas", "Courier New", monospace;

    /* — Fluent colors — */
    --brand:           #0078d4;
    --brand-hover:     #106ebe;
    --brand-soft:      rgba(0, 120, 212, 0.10);
    --brand-contrast:  #ffffff;

    --accent:        #5c2d91;   /* Office purple */
    --accent-soft:   rgba(92, 45, 145, 0.10);
    --purple:        #5c2d91;
    --purple-soft:   rgba(92, 45, 145, 0.10);
    --green:         #107c10;
    --green-soft:    rgba(16, 124, 16, 0.12);
    --red:           #d83b01;
    --red-soft:      rgba(216, 59, 1, 0.10);
    --orange:        #ca5010;
    --orange-soft:   rgba(202, 80, 16, 0.10);

    --bg-body:       #faf9f8;
    --bg-card:       #ffffff;
    --bg-subtle:     #f3f2f1;
    --bg-elevated:   #ffffff;

    --text-primary:   #201f1e;
    --text-secondary: #605e5c;
    --text-tertiary:  #8a8886;
    --text-inverse:   #ffffff;

    --border-subtle:  #edebe9;
    --border-medium:  #d2d0ce;
    --border-strong:  #a19f9d;

    /* — Fluent crisp small shadows — */
    --shadow-xs:    0 0.3px 0.9px rgba(0, 0, 0, 0.07), 0 0.8px 1.8px rgba(0, 0, 0, 0.07);
    --shadow-card:  0 0.3px 0.9px rgba(0, 0, 0, 0.07), 0 1.6px 3.6px rgba(0, 0, 0, 0.11);
    --shadow-hover: 0 0.6px 1.8px rgba(0, 0, 0, 0.10), 0 3.2px 7.2px rgba(0, 0, 0, 0.13);
    --shadow-lift:  0 6.4px 14.4px rgba(0, 0, 0, 0.14), 0 1.2px 3.6px rgba(0, 0, 0, 0.10);

    /* — Fluent sharper corners — */
    --radius-xs: 2px;
    --radius-s:  4px;
    --radius-m:  6px;
    --radius-l:  8px;
    --radius-xl: 12px;
    --radius-pill: 9999px;
    --radius-btn:  4px;

    --navbar-bg:     rgba(243, 242, 241, 0.85);
    --navbar-text:   #201f1e;
    --navbar-active: #0078d4;

    --dropdown-bg:     #ffffff;
    --dropdown-border: #d2d0ce;
    --dropdown-hover:  #f3f2f1;

    --footer-bg:   #f3f2f1;
    --footer-text: #605e5c;

    --gradient-hero:   linear-gradient(135deg, #0078d4 0%, #5c2d91 100%);
    --gradient-accent: linear-gradient(135deg, #0078d4 0%, #00b7c3 100%);

    --focus-ring: 0 0 0 2px #ffffff, 0 0 0 4px #0078d4;

    --blue: var(--brand);
    --blue-hover: var(--brand-hover);
    --gray: var(--text-secondary);
    --gray-light: var(--bg-subtle);
}

/* ============================================================
   5.1 Dark theme tokens per brand
   ============================================================ */
html[data-theme="apple"][data-mode="dark"] {
    --brand:           #5ea0ff;
    --brand-hover:     #7ab0ff;
    --brand-soft:      rgba(94, 160, 255, 0.16);
    --brand-contrast:  #08111f;

    --accent:        #ffb340;
    --accent-soft:   rgba(255, 179, 64, 0.14);
    --purple:        #c792ff;
    --purple-soft:   rgba(199, 146, 255, 0.14);
    --green:         #5ad17d;
    --green-soft:    rgba(90, 209, 125, 0.14);
    --red:           #ff7b72;
    --red-soft:      rgba(255, 123, 114, 0.14);
    --orange:        #ffb340;
    --orange-soft:   rgba(255, 179, 64, 0.14);

    --bg-body:       #0b0c10;
    --bg-card:       #15171c;
    --bg-subtle:     #1b1e24;
    --bg-elevated:   #111318;

    --text-primary:   #f5f7fa;
    --text-secondary: #aab2bf;
    --text-tertiary:  #7d8694;
    --text-inverse:   #0b0c10;

    --border-subtle:  rgba(255, 255, 255, 0.08);
    --border-medium:  rgba(255, 255, 255, 0.14);
    --border-strong:  rgba(255, 255, 255, 0.24);

    --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-card:  0 8px 24px rgba(0, 0, 0, 0.28);
    --shadow-hover: 0 14px 40px rgba(0, 0, 0, 0.34);
    --shadow-lift:  0 18px 56px rgba(0, 0, 0, 0.42);

    --navbar-bg:     rgba(11, 12, 16, 0.78);
    --navbar-text:   #f5f7fa;
    --navbar-active: #ffffff;
    --dropdown-bg:   #17191f;
    --dropdown-border: rgba(255, 255, 255, 0.08);
    --dropdown-hover:  #20242c;
    --footer-bg:     #101217;
    --footer-text:   #9ba3af;
    --gradient-hero: linear-gradient(135deg, #ffffff 0%, #8ab4ff 100%);
    --gradient-accent: linear-gradient(135deg, #5ea0ff 0%, #c792ff 100%);
    --focus-ring: 0 0 0 4px rgba(94, 160, 255, 0.18);
}

html[data-theme="google"][data-mode="dark"] {
    --brand:           #8ab4f8;
    --brand-hover:     #a8c7fa;
    --brand-soft:      rgba(138, 180, 248, 0.16);
    --brand-contrast:  #0f1724;

    --accent:        #81c995;
    --accent-soft:   rgba(129, 201, 149, 0.14);
    --purple:        #c58af9;
    --purple-soft:   rgba(197, 138, 249, 0.14);
    --green:         #81c995;
    --green-soft:    rgba(129, 201, 149, 0.14);
    --red:           #f28b82;
    --red-soft:      rgba(242, 139, 130, 0.14);
    --orange:        #fdd663;
    --orange-soft:   rgba(253, 214, 99, 0.16);

    --bg-body:       #0f1115;
    --bg-card:       #171a1f;
    --bg-subtle:     #20242b;
    --bg-elevated:   #13161b;

    --text-primary:   #e8eaed;
    --text-secondary: #9aa0a6;
    --text-tertiary:  #80868b;
    --text-inverse:   #0f1115;

    --border-subtle:  rgba(255, 255, 255, 0.08);
    --border-medium:  rgba(255, 255, 255, 0.14);
    --border-strong:  rgba(255, 255, 255, 0.22);

    --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.36);
    --shadow-card:  0 8px 24px rgba(0, 0, 0, 0.30);
    --shadow-hover: 0 14px 40px rgba(0, 0, 0, 0.36);
    --shadow-lift:  0 18px 56px rgba(0, 0, 0, 0.42);

    --navbar-bg:     rgba(15, 17, 21, 0.82);
    --navbar-text:   #e8eaed;
    --navbar-active: #8ab4f8;
    --dropdown-bg:   #171a1f;
    --dropdown-border: rgba(255, 255, 255, 0.08);
    --dropdown-hover:  #20242b;
    --footer-bg:     #13161b;
    --footer-text:   #9aa0a6;
    --gradient-hero: linear-gradient(135deg, #8ab4f8 0%, #81c995 50%, #fdd663 100%);
    --gradient-accent: linear-gradient(90deg, #8ab4f8 0%, #81c995 33%, #fdd663 66%, #f28b82 100%);
    --focus-ring: 0 0 0 3px rgba(138, 180, 248, 0.24);
}

html[data-theme="microsoft"][data-mode="dark"] {
    --brand:           #6cb8ff;
    --brand-hover:     #8cc9ff;
    --brand-soft:      rgba(108, 184, 255, 0.16);
    --brand-contrast:  #091521;

    --accent:        #b692f6;
    --accent-soft:   rgba(182, 146, 246, 0.14);
    --purple:        #b692f6;
    --purple-soft:   rgba(182, 146, 246, 0.14);
    --green:         #6dd47e;
    --green-soft:    rgba(109, 212, 126, 0.14);
    --red:           #ff8c69;
    --red-soft:      rgba(255, 140, 105, 0.14);
    --orange:        #ffb86b;
    --orange-soft:   rgba(255, 184, 107, 0.14);

    --bg-body:       #0e1116;
    --bg-card:       #171b22;
    --bg-subtle:     #202631;
    --bg-elevated:   #131820;

    --text-primary:   #f3f6fb;
    --text-secondary: #a7b0bd;
    --text-tertiary:  #7f8896;
    --text-inverse:   #0e1116;

    --border-subtle:  rgba(255, 255, 255, 0.08);
    --border-medium:  rgba(255, 255, 255, 0.14);
    --border-strong:  rgba(255, 255, 255, 0.22);

    --shadow-xs:    0 1px 2px rgba(0, 0, 0, 0.36);
    --shadow-card:  0 8px 24px rgba(0, 0, 0, 0.30);
    --shadow-hover: 0 14px 40px rgba(0, 0, 0, 0.36);
    --shadow-lift:  0 18px 56px rgba(0, 0, 0, 0.42);

    --navbar-bg:     rgba(14, 17, 22, 0.82);
    --navbar-text:   #f3f6fb;
    --navbar-active: #6cb8ff;
    --dropdown-bg:   #171b22;
    --dropdown-border: rgba(255, 255, 255, 0.08);
    --dropdown-hover:  #202631;
    --footer-bg:     #11161d;
    --footer-text:   #a7b0bd;
    --gradient-hero: linear-gradient(135deg, #6cb8ff 0%, #b692f6 100%);
    --gradient-accent: linear-gradient(135deg, #6cb8ff 0%, #54d2d2 100%);
    --focus-ring: 0 0 0 2px rgba(14, 17, 22, 0.9), 0 0 0 4px rgba(108, 184, 255, 0.26);
}

/* ============================================================
   6.  Base layout & typography
   ============================================================ */
body {
    font-family: var(--font-sans);
    background-color: var(--bg-body);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    line-height: 1.6;
    font-size: 16px;
    letter-spacing: -0.005em;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    transition: background-color var(--dur-base) ease, color var(--dur-base) ease;
}

main {
    flex: 1;
    width: 100%;
    padding-top: calc(var(--nav-h) + var(--space-4));
}

a {
    text-decoration: none;
    color: inherit;
    transition: color var(--dur-fast) ease;
}
a:hover { color: var(--brand); }

::selection {
    background: var(--brand-soft);
    color: var(--text-primary);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    color: var(--text-primary);
    line-height: 1.25;
    letter-spacing: -0.02em;
    font-weight: 700;
    margin: 0;
}

p { margin: 0; }

/* Container */
.container {
    max-width: 1024px;
    margin: 0 auto;
    padding: 0 var(--space-5);
}

/* 导航栏与正文之间的留白。刻意**不画背景**：画布底色已经是 --bg-body，
   而任何页面级的固定背景层（积分页 .pts-ambient、mars 主题的 body::before，
   都是 z-index:-1）会被这块不透明色挡住，在导航栏下方切出一条纯色横带。 */
.top-spacer {
    height: var(--space-5);
    width: 100%;
}

/* ============================================================
   7.  Navbar (apple-style frosted)
   ============================================================ */
.apple-navbar {
    background-color: var(--navbar-bg);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    height: var(--nav-h);
    width: 100%;
    position: sticky;
    top: 0;
    z-index: var(--z-popover);
    font-size: 13px;
    color: var(--navbar-text);
    border-bottom: 1px solid transparent;
    transition: background-color var(--dur-base) ease, border-color var(--dur-base) ease, box-shadow var(--dur-base) ease;
}

[data-theme="nebula"] .apple-navbar {
    border-bottom-color: rgba(167, 139, 250, 0.08);
}

.apple-nav-content {
    max-width: 1024px;
    margin: 0 auto;
    height: 100%;
    padding: 0 var(--space-5);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.apple-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

.apple-nav-item { display: inline-block; }

.apple-nav-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    color: var(--navbar-text);
    opacity: 0.78;
    text-decoration: none;
    transition: opacity var(--dur-base) var(--ease-apple),
                color var(--dur-base) ease,
                background-color var(--dur-fast) ease;
    font-family: var(--font-sans);
    font-weight: 500;
    letter-spacing: -0.01em;
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
}

.apple-nav-link:hover,
.apple-nav-link:focus {
    opacity: 1;
    color: var(--navbar-active);
    background-color: var(--dropdown-hover);
    text-decoration: none;
}

.apple-nav-link.active {
    opacity: 1;
    color: var(--navbar-active);
}

/* 当前页指示：链接下方一颗小圆点，比整段高亮克制 */
.apple-nav-link.active::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -5px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--brand);
    transform: translateX(-50%);
}

.apple-nav-icon { font-size: 14px; }

.apple-nav-brand-link {
    display: none;
    color: var(--navbar-text);
    width: 32px;
    height: 32px;
    border-radius: var(--radius-s);
    align-items: center;
    justify-content: center;
}

.apple-nav-brand-link:hover,
.apple-nav-brand-link:focus {
    background: var(--dropdown-hover);
    color: var(--navbar-active);
}

.apple-nav-toggle {
    display: none;
    margin-left: auto;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: var(--radius-s);
    background: transparent;
    color: var(--navbar-text);
    align-items: center;
    justify-content: center;
    font-size: 18px;
    line-height: 1;
}

.apple-nav-toggle:hover,
.apple-nav-toggle:focus {
    background: var(--dropdown-hover);
    color: var(--navbar-active);
}

.apple-navbar.scrolled {
    border-bottom-color: var(--border-subtle);
    box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.18);
}

/* ── Unified dropdown system (data-dropdown / -toggle / -menu) ──
   Menus stay in the DOM ([hidden] when closed); JS removes hidden,
   then adds .dd-open on the next frame so open AND close both animate. */
[data-dropdown] { position: relative; }

[data-dropdown] > [data-dropdown-menu] {
    position: absolute;
    top: calc(100% + 10px);
    z-index: var(--z-popover);
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
    transform-origin: top;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-apple),
                transform var(--dur-base) var(--ease-apple);
}
/* Beat Bootstrap's .dropdown-menu { display: none } once un-hidden */
[data-dropdown] > [data-dropdown-menu]:not([hidden]) { display: block; }
[data-dropdown] > [data-dropdown-menu].dd-open {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}

/* User dropdown */
.nav-user-dropdown { position: relative; }

.nav-user-toggle {
    background: transparent;
    border: none;
    cursor: pointer;
    font: inherit;
    display: inline-flex;
    align-items: center;
}

.nav-user-dropdown .dropdown-menu {
    right: -10px;
    left: auto;
    margin: 0;
    background: var(--dropdown-bg);
    border: 1px solid var(--dropdown-border);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-lift);
    padding: var(--space-2);
    min-width: 240px;
    list-style: none;
    transform-origin: top right;
}

.nav-user-dropdown .dropdown-header {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: var(--space-2);
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
}

.nav-user-dropdown .dropdown-item {
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-s);
    font-size: 14px;
    color: var(--text-primary);
    transition: background var(--dur-fast) ease, color var(--dur-fast) ease;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.nav-user-dropdown .dropdown-item:hover {
    background: var(--dropdown-hover);
    color: var(--brand);
}

.nav-user-dropdown .dropdown-item i {
    width: 20px;
    color: var(--text-secondary);
    flex-shrink: 0;
}

/* ============================================================
   8.  Theme switcher (3-way)
   ============================================================ */
.theme-switcher {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.theme-switcher-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--navbar-text);
    opacity: 0.78;
    cursor: pointer;
    transition: opacity var(--dur-fast) ease, transform var(--dur-fast) ease, background var(--dur-fast) ease;
    padding: 0;
    font-size: 14px;
}

.theme-switcher-toggle:hover {
    opacity: 1;
    background: var(--dropdown-hover);
    transform: scale(1.05);
}

.theme-switcher-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--dropdown-bg);
    border: 1px solid var(--dropdown-border);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-lift);
    padding: var(--space-2);
    min-width: 220px;
    display: block;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-8px) scale(0.98);
    transform-origin: top right;
    z-index: var(--z-popover);
    transition: opacity var(--dur-base) var(--ease-apple),
                transform var(--dur-base) var(--ease-apple),
                visibility var(--dur-base);
}

.theme-switcher-menu.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0) scale(1);
}

.theme-switcher-title {
    padding: var(--space-2) var(--space-3) var(--space-1);
    font-size: 11px;
    font-weight: 700;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.theme-option {
    width: 100%;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: none;
    background: transparent;
    border-radius: var(--radius-s);
    text-align: left;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 14px;
    transition: background var(--dur-fast) ease;
}

.theme-option:hover { background: var(--dropdown-hover); }

.theme-option-swatch {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.theme-option-swatch.apple     { background: linear-gradient(135deg, #1d1d1f 0%, #f5f5f7 50%, #0071e3 100%); }
.theme-option-swatch.google    { background: conic-gradient(from 180deg, #4285f4 0% 25%, #34a853 25% 50%, #fbbc04 50% 75%, #ea4335 75% 100%); }
.theme-option-swatch.microsoft { background: conic-gradient(from 0deg, #f25022 0% 25%, #7fba00 25% 50%, #00a4ef 50% 75%, #ffb900 75% 100%); }

.theme-option-meta {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1;
}
.theme-option-name {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.2;
}
.theme-option-desc {
    font-size: 11px;
    color: var(--text-secondary);
    line-height: 1.3;
}
.theme-option-check {
    color: var(--brand);
    font-size: 16px;
    opacity: 0;
    transition: opacity var(--dur-fast) ease;
}
.theme-option.active .theme-option-check { opacity: 1; }
.theme-option.active { background: var(--brand-soft); }

/* ============================================================
   9.  Hero & headlines
   ============================================================ */
.hero-section {
    padding: var(--space-8) 0 var(--space-7);
}

.hero-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(40px, 6vw, 64px);
    letter-spacing: -0.025em;
    line-height: 1.05;
    margin-bottom: var(--space-3);
    background: var(--gradient-hero);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.gradient-text {
    background: var(--gradient-accent);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.hero-subtitle {
    font-size: clamp(18px, 2.4vw, 22px);
    font-weight: 400;
    color: var(--text-secondary);
    max-width: 60ch;
}

.section-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 28px;
    letter-spacing: -0.015em;
    color: var(--text-primary);
}

.section-header-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
}

/* ============================================================
   10.  Cards
   ============================================================ */
/* .widget-card / .settings-card 是卡片时代的两个通用面板，
   全站还有 34 处引用。视觉上它们现在等同于 §54 的 .sheet：
   透明底 + 一条 hairline，没有阴影和悬停位移。 */
.widget-card {
    background: transparent;
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    box-shadow: none;
    transition: border-color var(--dur-base) ease;
}

.widget-card:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--rule-strong);
}

.widget-icon {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-m);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
}

.bg-blue-light   { background: var(--brand-soft);  }
.text-blue       { color: var(--brand);            }
.bg-purple-light { background: var(--purple-soft); }
.text-purple     { color: var(--purple);           }
.bg-orange-light { background: var(--orange-soft); }
.text-orange     { color: var(--orange);           }
.bg-green-light  { background: var(--green-soft);  }
.text-green      { color: var(--green);            }
.bg-red-light    { background: var(--red-soft);    }
.text-red        { color: var(--red);              }

/* Post grid + post card */
.post-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: var(--space-6);
    padding-bottom: var(--space-8);
}

.post-card {
    background: var(--bg-card);
    border-radius: var(--radius-l);
    border: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    transition: transform var(--dur-slow) var(--ease-apple),
                box-shadow var(--dur-slow) var(--ease-apple),
                border-color var(--dur-base) ease;
    height: 100%;
    display: flex;
    flex-direction: column;
    color: var(--text-primary);
}

.post-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow-hover);
    border-color: var(--border-medium);
    z-index: 10;
}

.card-img-wrapper {
    height: 220px;
    overflow: hidden;
    position: relative;
    background-color: var(--bg-subtle);
}

.card-img-wrapper img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s var(--ease-apple);
}

.post-card:hover .card-img-wrapper img { transform: scale(1.05); }

.card-body {
    padding: var(--space-5);
    flex-grow: 1;
    display: flex;
    flex-direction: column;
}

.post-date {
    font-size: 11px;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: var(--text-tertiary);
    text-transform: uppercase;
}

.card-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    line-height: 1.25;
    margin-bottom: var(--space-3);
    color: var(--text-primary);
    letter-spacing: -0.015em;
}

.card-text {
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-secondary);
    margin-bottom: auto;
}

/* ============================================================
   11.  Pagination
   ============================================================ */
.pagination { gap: var(--space-2); }

.page-link {
    border: 1px solid var(--border-subtle);
    background: var(--bg-card);
    color: var(--text-secondary);
    border-radius: 50%;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 500;
    font-size: 14px;
    transition: all var(--dur-fast) ease;
}

.page-link:hover {
    background: var(--bg-subtle);
    color: var(--text-primary);
    border-color: var(--border-medium);
}

.page-item.active .page-link {
    background: var(--text-primary);
    color: var(--text-inverse);
    border-color: var(--text-primary);
}

/* ============================================================
   12.  Blog detail
   ============================================================ */
.blog-content {
    font-size: 18px;
    line-height: 1.75;
    font-family: var(--font-serif);
    color: var(--text-primary);
    max-width: 70ch;
    margin: 0 auto;
}

.blog-content h2,
.blog-content h3,
.blog-content h4 {
    font-family: var(--font-display);
    margin-top: 2em;
    margin-bottom: 0.7em;
    font-weight: 700;
    color: var(--text-primary);
}

.blog-content p { margin: 0 0 1.2em; }

.blog-content a {
    color: var(--brand);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}
.blog-content a:hover { color: var(--brand-hover); }

.blog-content blockquote {
    margin: 1.5em 0;
    padding: var(--space-2) var(--space-5);
    border-left: 3px solid var(--brand);
    color: var(--text-secondary);
    font-style: italic;
    background: var(--bg-subtle);
    border-radius: 0 var(--radius-m) var(--radius-m) 0;
}

/* — 页头：左对齐，和 /blog 的 .page-head 同一套记法。
     路径标签的每一段都是链接，原先那条 .breadcrumb-nav 因此撤掉了。 — */
.post-head { padding-top: clamp(26px, 4.6vw, 60px); }
.post-head-crumb a {
    color: inherit;
    text-decoration: none;
    transition: color var(--dur-fast) ease;
}
.post-head-crumb a:hover { color: var(--brand); }

.post-head-title {
    margin: 0;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 112%;
    font-size: clamp(29px, 4.3vw, 58px);
    line-height: 1.05;
    letter-spacing: -0.032em;
    color: var(--text-primary);
}
.post-head-lede {
    margin: clamp(15px, 2vw, 24px) 0 0;
    max-width: 56ch;
    font-size: clamp(15px, 1.25vw, 17px);
    line-height: 1.75;
    color: var(--text-secondary);
}

/* 元信息条：mono，上下各一条 hairline，把页头和正文隔开 */
.post-head-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin-top: clamp(20px, 2.6vw, 32px);
    padding: var(--space-4) 0;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.05em;
    color: var(--text-tertiary);
}
.post-head-meta .sep { opacity: .35; }
.post-head-author {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--role, var(--text-primary));
    font-weight: 500;
    text-decoration: none;
}
.post-head-avatar {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--role, var(--brand)) 15%, transparent);
    color: var(--role, var(--brand));
    font-size: 11px;
    font-weight: 600;
}
.post-head-tags {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-left: auto;
}

.post-media {
    margin-top: clamp(26px, 3.6vw, 48px);
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    overflow: hidden;
}

/* 正文左对齐到和标题同一条竖线上，不再居中——页头是左对齐的，
   正文再居中会在两者之间留出一道说不通的缝。 */
.post-layout .blog-content {
    margin-inline: 0;
    padding-block: clamp(30px, 4.2vw, 54px);
}

/* — 操作条：左标签右按钮，上下 hairline — */
.post-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4) 0;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}
.post-actions-tags,
.post-actions-btns {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.post-actions .btn {
    font-size: 13px;
    padding: 7px var(--space-4);
}

.post-like-btn,
.post-coin-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.post-like-btn.is-liked {
    color: var(--red);
    border-color: var(--red);
    background: transparent;
}
.post-like-btn.is-liked i { animation: post-heart-pop .42s var(--ease-spring); }
.post-coin-btn i { color: #f0b429; }
.post-coin-btn.is-success { animation: post-coin-success .55s var(--ease-spring); }
@keyframes post-heart-pop {
    0% { transform: scale(.65); }
    55% { transform: scale(1.3); }
    100% { transform: scale(1); }
}
@keyframes post-coin-success {
    0%, 100% { transform: scale(1); }
    45% { transform: scale(1.08); box-shadow: 0 0 0 7px color-mix(in srgb, #f0b429 14%, transparent); }
}

/* ── 12b. 评论区 ────────────────────────────────────────────
   一条评论一行 hairline，没有卡片。回复缩进后靠一条竖 hairline
   挂在父评论上，比原先那条 2px 实线轻，也和全站的分隔线同宽。
   注意：新评论 / 新回复由 main/post.html 里的 fetch 直接拼 HTML
   插进来，改这里的结构时那两段模板字符串要一起改。
   ────────────────────────────────────────────────────────── */
.comments-section { padding-block: clamp(34px, 4.6vw, 60px) clamp(52px, 7vw, 92px); }
.comment-form-wrap { margin-bottom: clamp(26px, 3.6vw, 44px); }
.comment-form-wrap .field { margin-bottom: var(--space-3); }

.comment-item {
    padding: clamp(16px, 2.2vw, 24px) 0;
    border-bottom: 1px solid var(--rule);
}
.comment-item:first-child { padding-top: 0; }

.comment-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}
.comment-avatar {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--role, var(--brand)) 15%, transparent);
    color: var(--role, var(--brand));
    font-size: 12.5px;
    font-weight: 600;
}
.comment-author {
    font-size: 14px;
    font-weight: 600;
    color: var(--role, var(--text-primary));
}
.comment-date {
    margin-left: auto;
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--text-tertiary);
    white-space: nowrap;
}
.comment-body {
    font-size: 15px;
    line-height: 1.75;
    color: var(--text-secondary);
}
.comment-body > :last-child { margin-bottom: 0; }

.comment-foot { margin-top: var(--space-3); }
.comment-reply-btn {
    padding: 0;
    background: none;
    border: 0;
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    cursor: pointer;
    transition: color var(--dur-fast) ease;
}
.comment-reply-btn:hover { color: var(--brand); }

.reply-form { margin-top: var(--space-3); }
.reply-form .field { margin-bottom: var(--space-2); }

.comment-replies {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-4);
    padding-left: clamp(14px, 2vw, 22px);
    border-left: 1px solid var(--rule);
}
.comment-replies:empty { display: none; }
.comment-reply-head {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-bottom: 5px;
}
.comment-reply-author { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.comment-reply-body { font-size: 14px; line-height: 1.7; color: var(--text-secondary); }
.comment-reply-body > :last-child { margin-bottom: 0; }

.table-responsive { -webkit-overflow-scrolling: touch; }

/* ============================================================
   13.  Animations / utilities
   ============================================================ */
/* .fade-in 在模板中大量硬编码：置为无动画，刷新即刻呈现。
   入场动画只保留给滚动显现的 .reveal-in（由 main.js 添加）。 */
.fade-in { opacity: 1; }

.reveal-in {
    animation: fadeIn 0.35s var(--ease-apple) forwards;
}
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0);   }
}

.line-clamp-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ============================================================
   14.  Footer
   ============================================================ */
.footer {
    background: var(--footer-bg);
    border-top: 1px solid var(--border-subtle);
    padding: var(--space-7) 0;
    margin-top: auto;
    transition: background-color var(--dur-base) ease;
}

.footer .text-muted { color: var(--footer-text) !important; }

/* ============================================================
   15.  Buttons
        形状跟着主题走（--radius-btn：apple 是胶囊、google 24px、
        microsoft 4px），但质感统一成 §54 那套：只有 hairline 和填色，
        不再有悬停上浮和彩色投影——那是卡片时代留下的动作。
   ============================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    border-radius: var(--radius-btn);
    padding: var(--space-2) var(--space-5);
    font-weight: 500;
    font-size: 14px;
    line-height: 1.5;
    transition: background var(--dur-fast) ease,
                border-color var(--dur-fast) ease,
                color var(--dur-fast) ease;
    font-family: var(--font-sans);
    border: 1px solid transparent;
}

.btn-primary {
    background-color: var(--brand);
    border-color: var(--brand);
    color: var(--brand-contrast);
}
.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--brand-hover);
    border-color: var(--brand-hover);
    color: var(--brand-contrast);
}

.btn-outline-primary {
    color: var(--brand);
    border-color: var(--brand);
    background: transparent;
}
.btn-outline-primary:hover {
    background: var(--brand);
    color: var(--brand-contrast);
    border-color: var(--brand);
}

/* 次级按钮：透明底 + hairline，悬停只换描边和字色 */
.btn-light {
    background: transparent;
    border-color: var(--rule-strong);
    color: var(--text-primary);
}
.btn-light:hover {
    background: transparent;
    color: var(--brand);
    border-color: var(--brand);
}

.account-summary-card {
    background: linear-gradient(180deg, color-mix(in srgb, var(--bg-card) 92%, transparent), var(--bg-card));
}

.account-panel-header {
    background: var(--bg-subtle);
    color: var(--text-primary);
}

.account-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-primary);
    --bs-table-border-color: var(--border-subtle);
    margin-bottom: 0;
}

.account-table thead th {
    color: var(--text-secondary);
}

.account-table-row {
    border-color: var(--border-subtle) !important;
}

.account-inline-code {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    padding: 2px 9px;
    border-radius: var(--radius-pill);
    background: transparent;
    border: 1px solid var(--rule);
    color: var(--text-primary);
    font-family: var(--font-data);
    font-size: 12px;
    white-space: nowrap;
}

/* /account/keys：新 key 的明文只出现一次，用绿色 hairline 圈住 */
.key-reveal { border-color: color-mix(in srgb, var(--green, #34c759) 45%, transparent); }
.key-reveal-row {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
}
.key-reveal-row .field-input { font-family: var(--font-data); font-size: 13.5px; }
.key-snippet {
    margin: var(--space-4) 0 0;
    padding: var(--space-3) 0 0;
    border-top: 1px solid var(--rule);
    background: transparent;
    font-family: var(--font-data);
    font-size: 12px;
    line-height: 1.9;
    color: var(--text-secondary);
    overflow-x: auto;
}
.key-snippet code { background: none; padding: 0; font-size: inherit; color: inherit; }

.account-count-badge {
    background: var(--bg-elevated);
    color: var(--text-secondary);
}

.usage-status-badge-success {
    background: rgba(52, 199, 89, 0.16) !important;
    color: #34c759 !important;
}

.usage-status-badge-running {
    background: rgba(255, 159, 10, 0.16) !important;
    color: #ff9f0a !important;
}

.usage-status-badge-failed {
    background: rgba(255, 59, 48, 0.14) !important;
    color: #ff3b30 !important;
}

.status-dot {
    display: inline-block;
    width: 0.95rem;
    height: 0.95rem;
    border-radius: 50%;
    vertical-align: middle;
}

.status-dot-success {
    background: #34c759;
    box-shadow: 0 0 0 6px rgba(52, 199, 89, 0.14);
}

.status-dot-running {
    background: #ff9f0a;
    box-shadow: 0 0 0 6px rgba(255, 159, 10, 0.12);
}

.status-dot-failed {
    background: #ff3b30;
    box-shadow: 0 0 0 6px rgba(255, 59, 48, 0.12);
}

/* ============================================================
   16.  Auth (login / register / 找回密码)
        改成编辑式：不再是居中的白卡片，而是一列左对齐的排版——
        mono 路径标签 → 展宽大标题 → 一句说明 → 下划线输入框。
        Bootstrap 的 .form-floating 换成 §54 的 .field，
        浮动标签那一套（label 缩放、placeholder 透明）随之整段删掉。
   ============================================================ */
.auth-wrapper {
    min-height: calc(100svh - var(--nav-h) - 120px);
    display: flex;
    align-items: center;
    padding: clamp(32px, 6vw, 72px) 0;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
    text-align: left;
}

/* 路径标签，后面拖一条 hairline —— 和 .page-eyebrow 是同一个记法 */
.auth-eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0 0 clamp(16px, 2.4vw, 24px);
    font-family: var(--font-data);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.auth-eyebrow::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--rule);
}

.auth-title {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 116%;
    font-size: clamp(34px, 5.4vw, 58px);
    line-height: 0.96;
    letter-spacing: -0.035em;
    margin: 0;
    color: var(--text-primary);
}

.auth-subtitle {
    margin: clamp(12px, 1.8vw, 18px) 0 clamp(28px, 4vw, 44px);
    max-width: 40ch;
    font-size: 15px;
    line-height: 1.75;
    color: var(--text-secondary);
}

/* 主提交按钮：整宽墨色实心，悬停转品牌色 */
.btn-auth {
    width: 100%;
    height: 50px;
    border-radius: var(--radius-btn);
    background: var(--text-primary);
    border: 1px solid var(--text-primary);
    color: var(--bg-body);
    font-family: var(--font-sans);
    font-size: 15px;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    margin-top: clamp(24px, 3.2vw, 36px);
    box-shadow: none;
    transition: background var(--dur-fast) ease,
                border-color var(--dur-fast) ease,
                color var(--dur-fast) ease;
}

.btn-auth:hover {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--brand-contrast);
}

.btn-auth i { font-size: 1.05em; }

.auth-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: clamp(24px, 3.2vw, 36px);
    padding-top: var(--space-4);
    border-top: 1px solid var(--rule);
}

.auth-links {
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 2;
    color: var(--text-tertiary);
}

.auth-links a {
    color: var(--text-primary);
    text-decoration: none;
    transition: color var(--dur-fast) ease;
}

.auth-links a:hover { color: var(--brand); }

/* 记住我这类勾选行 */
.auth-check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-4);
    font-size: 13px;
    color: var(--text-secondary);
}
.auth-check .form-check-input { margin: 0; }

/* ============================================================
   17.  Scroll-to-top
   ============================================================ */
.scroll-to-top {
    position: fixed;
    bottom: 30px;
    right: 30px;
    width: 48px;
    height: 48px;
    background: var(--bg-card);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border: 1px solid var(--border-subtle);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: var(--shadow-card);
    opacity: 0;
    visibility: hidden;
    transform: translateY(20px) scale(0.9);
    transition: all var(--dur-slow) var(--ease-apple);
    z-index: 9990;
    color: var(--text-primary);
    font-size: 20px;
}

.scroll-to-top.visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}

.scroll-to-top:hover {
    transform: translateY(-2px) scale(1.05);
    box-shadow: var(--shadow-hover);
    color: var(--brand);
    border-color: var(--border-medium);
}

.scroll-to-top:active { transform: scale(0.95); }

/* ============================================================
   18.  Flash messages
   ============================================================ */
.flash-container {
    position: fixed;
    top: 60px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-toast);
    width: 90%;
    max-width: 440px;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    pointer-events: none;
}

.apple-alert {
    background: var(--bg-card);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-radius: var(--radius-pill);
    padding: var(--space-3) var(--space-5);
    box-shadow: var(--shadow-hover);
    border: 1px solid var(--border-subtle);
    display: flex;
    align-items: center;
    justify-content: space-between;
    animation: slideDown 0.5s var(--ease-apple);
    pointer-events: auto;
    color: var(--text-primary);
    font-size: 14px;
    font-weight: 500;
}

.apple-alert-success { border-left: 4px solid var(--green); }
.apple-alert-danger  { border-left: 4px solid var(--red);   }
.apple-alert-warning { border-left: 4px solid var(--orange);}
.apple-alert-info    { border-left: 4px solid var(--brand); }

.apple-alert .btn-close {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-size: 18px;
    cursor: pointer;
    padding: 0;
    margin-left: var(--space-3);
    opacity: 0.5;
    transition: opacity var(--dur-fast) ease;
}

.apple-alert .btn-close:hover { opacity: 1; }

@keyframes slideDown {
    from { opacity: 0; transform: translateY(-20px); }
    to   { opacity: 1; transform: translateY(0);    }
}

/* ============================================================
   19.  Profile / settings cards
   ============================================================ */
.profile-header {
    margin-bottom: var(--space-7);
    text-align: center;
    padding: var(--space-7) var(--space-5);
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-card);
}

.profile-avatar-wrapper {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto var(--space-4);
    border: 4px solid var(--bg-card);
    box-shadow: var(--shadow-card);
}

.profile-avatar-wrapper img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-title {
    font-family: var(--font-display);
    font-size: 32px;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: var(--space-1);
    letter-spacing: -0.02em;
}

.profile-email {
    color: var(--text-secondary);
    font-size: 16px;
}

.settings-card {
    background: transparent;
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    padding: clamp(20px, 2.6vw, 32px);
    box-shadow: none;
    margin-bottom: var(--space-5);
}

.settings-title {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 108%;
    font-size: clamp(17px, 1.6vw, 21px);
    line-height: 1.2;
    letter-spacing: -0.02em;
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--rule);
    color: var(--text-primary);
}

.profile-form .form-control {
    background-color: var(--bg-subtle);
    border: 1px solid transparent;
    color: var(--text-primary);
}

.profile-form .form-control:focus {
    background-color: var(--bg-card);
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

/* ============================================================
   20.  Search overlay (blog search)
   模板：app/templates/includes/search_overlay.html
   .search-overlay 是遮罩本体（base.html 的 toggleSearch() 直接改它的
   display，所以这里保持 display:none / flex 这套约定）；面板内部一律用
   .blog-search-* 前缀，避免和 profile / vocab 页的 .search-* 撞名。
   ============================================================ */
.search-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(30px) saturate(180%);
    -webkit-backdrop-filter: blur(30px) saturate(180%);
    z-index: 10000;
    display: none;
    align-items: flex-start;
    justify-content: center;
    animation: fadeIn var(--dur-base) var(--ease-apple);
}

[data-mode="dark"] .search-overlay { background: rgba(8, 10, 16, 0.74); }

/* 面板不吃满高：搜索是「输入 + 一小段结果」，撑满屏只会让空态显得很空。
   顶部留白让面板落在视觉黄金位，而不是垂直居中后被键盘顶走（移动端）。 */
.blog-search-panel {
    width: min(680px, calc(100% - 2 * var(--space-4)));
    margin-top: clamp(var(--space-6), 12vh, 140px);
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-l);
    box-shadow: var(--shadow-lift);
    overflow: hidden;
    animation: searchPanelIn var(--dur-base) var(--ease-apple);
}

@keyframes searchPanelIn {
    from { opacity: 0; transform: translateY(-12px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── 输入条 ────────────────────────────────────────────── */
.blog-search-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
}

.blog-search-bar-icon {
    font-size: 18px;
    color: var(--text-tertiary);
    flex: none;
}

.blog-search-input {
    flex: 1;
    min-width: 0;
    height: 58px;
    border: none;
    outline: none;
    background: transparent;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 17px;
}

.blog-search-input::placeholder { color: var(--text-tertiary); }

/* type=search 在 WebKit 下自带一个清除按钮，和自定义的 .blog-search-clear
   重复，隐掉原生的那个。 */
.blog-search-input::-webkit-search-cancel-button,
.blog-search-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.blog-search-input:focus-visible { outline: none; }

.blog-search-clear {
    flex: none;
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: none;
    background: none;
    color: var(--text-tertiary);
    font-size: 16px;
    cursor: pointer;
    transition: color var(--dur-fast) ease;
}

.blog-search-clear:hover { color: var(--text-secondary); }

.blog-search-close {
    flex: none;
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
}

.blog-search-close kbd,
.blog-search-hint kbd {
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    padding: 4px 6px;
    color: var(--text-tertiary);
    background: var(--bg-subtle);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-xs);
}

.blog-search-close:hover kbd {
    color: var(--text-primary);
    border-color: var(--border-medium);
}

/* ── 结果区 ────────────────────────────────────────────── */
.blog-search-results {
    max-height: min(52vh, 460px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}

.blog-search-results:empty { display: none; }

.blog-search-results::-webkit-scrollbar { width: 8px; }
.blog-search-results::-webkit-scrollbar-thumb {
    background: var(--border-medium);
    border-radius: 4px;
}

.blog-search-group { padding: var(--space-3) var(--space-2) 0; }
.blog-search-group:last-child { padding-bottom: var(--space-3); }

.blog-search-group-label {
    padding: 0 var(--space-3) var(--space-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.blog-search-option {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-s);
    color: var(--text-primary);
    text-decoration: none;
}

/* 键盘选中与 hover 共用一个类：JS 在 mousemove 时同步 activeIndex，
   避免键盘高亮和鼠标高亮同时落在两个不同项上。 */
.blog-search-option.is-active { background: var(--brand-soft); }

.blog-search-option-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-s);
    background: var(--bg-subtle);
    color: var(--text-secondary);
    font-size: 15px;
}

.blog-search-option.is-active .blog-search-option-icon {
    background: var(--brand);
    color: var(--brand-contrast);
}

.blog-search-option-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.blog-search-option-title,
.blog-search-option-sub {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.blog-search-option-title { font-size: 15px; font-weight: 550; }

.blog-search-option-sub {
    font-size: 13px;
    color: var(--text-tertiary);
}

/* 回车图标只在选中项上出现，提示「按 ↵ 打开这一条」。 */
.blog-search-option-enter {
    flex: none;
    font-size: 12px;
    color: var(--brand);
    opacity: 0;
}

.blog-search-option.is-active .blog-search-option-enter { opacity: 1; }

/* ── 标签组（横排 chip，不占满行） ──────────────────────── */
.blog-search-tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: 0 var(--space-3) var(--space-1);
}

.blog-search-tag {
    padding: 5px var(--space-3);
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
    text-decoration: none;
    background: var(--bg-subtle);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    transition: color var(--dur-fast) ease, background var(--dur-fast) ease,
                border-color var(--dur-fast) ease;
}

.blog-search-tag.is-active {
    color: var(--brand-contrast);
    background: var(--brand);
    border-color: var(--brand);
}

/* ── 空态 ──────────────────────────────────────────────── */
.blog-search-empty {
    padding: var(--space-6) var(--space-5);
    text-align: center;
}

.blog-search-empty-icon {
    font-size: 24px;
    color: var(--text-tertiary);
}

.blog-search-empty-title {
    margin: var(--space-3) 0 var(--space-1);
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.blog-search-empty-text {
    margin: 0;
    font-size: 13px;
    color: var(--text-tertiary);
}

/* ── 底栏提示 ──────────────────────────────────────────── */
.blog-search-hint {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--border-subtle);
    background: var(--bg-subtle);
    font-size: 12px;
    color: var(--text-tertiary);
}

.blog-search-hint-count {
    font-weight: 600;
    color: var(--brand);
    text-decoration: none;
}

.blog-search-hint-count:hover { text-decoration: underline; }

.blog-search-hint-keys {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
}

/* vocab 页（app/templates/vocab/index.html）借用这个类做搜索框外壳，
   浮层本身已不再使用，但不能删。 */
.search-bar-wrapper {
    background: var(--bg-card);
    border-radius: 28px;
    padding: 6px;
    box-shadow: var(--shadow-card);
    border: 1px solid var(--border-subtle);
    margin-bottom: var(--space-6);
    transition: box-shadow var(--dur-base) var(--ease-apple), border-color var(--dur-base) ease;
}

.search-bar-wrapper:focus-within {
    box-shadow: var(--shadow-hover);
    border-color: var(--brand);
}

/* ============================================================
   21.  Admin workspace
        2026-08-28：原先是 macOS 系统设置的观感（浮起的侧栏卡片 +
        彩色圆角瓷砖图标 + 整块高亮的选中项）。全站推平到编辑式排版后，
        这里改成 hairline：侧栏是一条竖线隔开的导航轨，选中项靠左侧
        品牌竖线和字色表示，图标退成单色。

        页头 / 表格已经不在这一节了 —— 模板统一改用 §54 的
        .page-head 与 .data-table。
   ============================================================ */
.admin-sidebar {
    background: transparent;
    border: 0;
    border-right: 1px solid var(--rule);
    border-radius: 0;
    padding: clamp(18px, 2.6vw, 28px) var(--space-5) var(--space-6) 0;
    box-shadow: none;
    position: sticky;
    top: calc(var(--nav-h) + var(--space-4));
    max-height: calc(100vh - var(--nav-h) - var(--space-6));
    overflow-y: auto;
    scrollbar-width: thin;
}

.admin-side-head {
    padding: 0 0 var(--space-4);
    margin-bottom: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    border-bottom: 1px solid var(--rule);
}

.admin-side-title {
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--text-tertiary);
}

/* 过滤框：和 §54 的 .field-input 一样，只有一条下边框 */
.admin-nav-filter {
    width: 100%;
    padding: 6px 2px;
    font-size: 13px;
    color: var(--text-primary);
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule);
    border-radius: 0;
    outline: none;
    transition: border-color var(--dur-fast) ease;
}
.admin-nav-filter::placeholder { color: var(--text-tertiary); }
.admin-nav-filter:focus { border-bottom-color: var(--brand); }

.admin-nav-group { margin-bottom: var(--space-5); }
.admin-nav-group-title {
    padding: 0 0 var(--space-2);
    font-family: var(--font-data);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--text-tertiary);
}

.admin-nav-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 6px 0 6px var(--space-3);
    margin-left: -1px;                       /* 压在侧栏的竖 hairline 上 */
    border-left: 1px solid transparent;
    border-radius: 0;
    color: var(--text-secondary);
    font-size: 13.5px;
    font-weight: 450;
    transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
    text-decoration: none;
    line-height: 1.35;
}

/* 彩色瓷砖去掉：新语言里唯一的颜色重音是 --brand，
   --tile 变量还留在模板的 style 属性里，这里不再读它。 */
.admin-nav-ico {
    width: 18px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border-radius: 0;
    color: inherit;
    font-size: 13px;
    box-shadow: none;
}
.admin-nav-ico i { line-height: 1; }

.admin-nav-item:hover { color: var(--text-primary); }

/* 选中项：左侧一条品牌竖线 + 品牌字色，不刷整块底色 */
.admin-nav-item.active {
    background: none;
    color: var(--brand);
    border-left-color: var(--brand);
    font-weight: 500;
}

/* — 宽屏：侧栏收成 240px 的固定导轨，内容占满余下宽度 — */
@media (min-width: 992px) {
    #app-main:has(.admin-sidebar) {
        max-width: 1360px;
    }
    #app-main [class*="col-"]:has(> .admin-sidebar) {
        flex: 0 0 240px;
        width: 240px;
        max-width: 240px;
        padding-right: 0;
    }
    #app-main [class*="col-"]:has(> .admin-sidebar) + [class*="col-"] {
        flex: 1 1 0;
        width: auto;
        max-width: none;
        min-width: 0;
        padding-left: var(--space-6);
    }
}

/* — 窄屏：压平成一条横向滚动的 chip 轨 — */
@media (max-width: 991.98px) {
    .admin-sidebar {
        position: static;
        max-height: none;
        overflow: visible;
        padding: var(--space-4) 0;
        border-right: 0;
        border-bottom: 1px solid var(--rule);
    }
    .admin-side-head { display: none; }
    .admin-nav-list {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: var(--space-2);
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .admin-nav-list::-webkit-scrollbar { display: none; }
    .admin-nav-group { display: contents; }
    .admin-nav-group-title { display: none; }
    .admin-nav-list hr { display: none; }
    .admin-nav-item {
        flex: 0 0 auto;
        white-space: nowrap;
        border: 1px solid var(--rule);
        border-radius: var(--radius-pill);
        padding: 5px var(--space-3);
        margin: 0;
    }
    .admin-nav-item.active {
        background: var(--text-primary);
        border-color: var(--text-primary);
        color: var(--bg-body);
    }
    .admin-sidebar .admin-side-actions { display: none; }
}

/* — 统计卡：hairline 格，数字走 §54 的 .stat-v 字形 — */
.admin-stat-card {
    background: transparent;
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    padding: clamp(18px, 2.2vw, 26px);
    box-shadow: none;
    transition: border-color var(--dur-base) ease;
    text-align: left;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.admin-stat-card:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--rule-strong);
}

.admin-stat-value {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 116%;
    font-size: clamp(28px, 3vw, 42px);
    line-height: 1;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
    margin-bottom: var(--space-2);
}

.admin-stat-label {
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    color: var(--text-tertiary);
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

/* 图标退成轮廓字符，不再是彩色圆角方块 */
.admin-stat-icon {
    font-size: 18px;
    margin-bottom: var(--space-4);
    width: auto;
    height: auto;
    border-radius: 0;
    background: none !important;
    color: color-mix(in srgb, var(--text-primary) 30%, transparent) !important;
    display: block;
}

/* 后台页头：栏宽比公开页窄，展示级标题跟着降一档 */
.admin-page .page-title,
#app-main:has(.admin-sidebar) .page-title {
    font-size: clamp(28px, 3.4vw, 44px);
}

/* 后台是工作台，不需要公共页那种大留白页头：
   上下内边距收窄，eyebrow / subtitle 的间距同步收紧 */
#app-main:has(.admin-sidebar) .page-head {
    padding: clamp(18px, 2.6vw, 28px) 0 clamp(14px, 2vw, 20px);
}
#app-main:has(.admin-sidebar) .page-eyebrow {
    margin-bottom: clamp(8px, 1.2vw, 12px);
}
#app-main:has(.admin-sidebar) .page-subtitle {
    margin-top: clamp(6px, 1vw, 10px);
}

/* 后台表格已统一改用 §54 的 .data-table（模板里的 .apple-table
   全部改名了），这一节不再单独写一份表格样式。 */

/* ============================================================
   22.  Code & pre formatting
   ============================================================ */
pre {
    max-width: 100%;
    overflow-x: auto;
    position: relative;
    border-radius: var(--radius-m);
    padding: var(--space-5);
    margin: 1.5rem 0;
    background-color: var(--bg-subtle);
    font-size: 14px;
    line-height: 1.55;
    border: 1px solid var(--border-subtle);
}

code {
    font-family: var(--font-mono);
    padding: 0.15em 0.4em;
    background-color: var(--bg-subtle);
    border-radius: var(--radius-xs);
    font-size: 0.92em;
    color: var(--text-primary);
}

pre code {
    padding: 0;
    background-color: transparent;
    font-size: inherit;
    white-space: pre;
    word-break: normal;
}

/* ============================================================
   23.  Images
   ============================================================ */
img { max-width: 100%; height: auto; }

.blog-content img {
    max-height: 75vh;
    object-fit: contain;
    display: block;
    margin: 2rem auto;
    border-radius: var(--radius-l);
    box-shadow: var(--shadow-card);
    transition: transform var(--dur-base) var(--ease-apple);
}

.blog-content img:hover { transform: scale(1.01); }

.post-detail-featured-image {
    width: 100%;
    max-height: 500px;
    object-fit: cover;
}

.avatar-sm { width: 32px;  height: 32px;  }
.avatar-md { width: 64px;  height: 64px;  }
.avatar-lg { width: 128px; height: 128px; }

.rounded-circle {
    border-radius: 50% !important;
    object-fit: cover;
}

/* ============================================================
   24.  Responsive breakpoints
   ============================================================ */
@media (max-width: 992px) {
    :root { --nav-h: 48px; }
    main { padding-top: calc(var(--nav-h) + var(--space-2)); }
    .container { padding: 0 var(--space-4); }
    .hero-section { padding: var(--space-7) 0 var(--space-5); }
    .hero-title    { font-size: clamp(32px, 8vw, 44px); }
    .hero-subtitle { font-size: 19px; }
    .section-title { font-size: 24px; }
    .post-grid {
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
        gap: var(--space-4);
        padding-bottom: var(--space-7);
    }
    .card-img-wrapper { height: 200px; }
    .card-body { padding: var(--space-4); }
    .blog-content { font-size: 17px; }
    .profile-header { padding: var(--space-6) var(--space-5); margin-bottom: var(--space-6); }
    .admin-stat-value { font-size: 28px; }
}

@media (max-width: 768px) {
    .top-spacer { height: 0; }

    .apple-nav-content {
        padding: 0 var(--space-3);
        position: relative;
        justify-content: space-between;
    }

    .apple-nav-brand-link { display: inline-flex; }
    .apple-nav-toggle     { display: inline-flex; }

    .apple-nav-list {
        position: absolute;
        top: var(--nav-h);
        left: 0; right: 0;
        width: 100%;
        /* 不透明：本元素的 backdrop-filter 是空转的 —— .apple-navbar 自带
           backdrop-filter，已经给子树建立了新的 backdrop root，子元素再滤
           也采不到页面内容。只写半透明的 --navbar-bg 会让正文原样透上来。
           这里在不透明底色上再叠一层导航条色，观感与顶栏一致。 */
        background-color: var(--bg-body);
        background-image: linear-gradient(var(--navbar-bg), var(--navbar-bg));
        border-bottom: 1px solid var(--border-subtle);
        padding: var(--space-3) var(--space-2) var(--space-4);
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        max-height: calc(100vh - var(--nav-h));
        overflow-y: auto;
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        pointer-events: none;
        transition: opacity var(--dur-base) ease, transform var(--dur-base) ease, visibility var(--dur-base) ease;
    }

    .apple-navbar.menu-open .apple-nav-list {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        pointer-events: auto;
    }

    .apple-nav-item { width: 100%; }
    .apple-nav-spacer { display: none; }

    .apple-nav-link {
        display: flex;
        align-items: center;
        width: 100%;
        min-height: 44px;
        font-size: 15px;
        padding: 0 var(--space-3);
        border-radius: var(--radius-s);
    }

    .nav-user-dropdown .dropdown-menu {
        position: static;
        top: auto;
        right: auto;
        width: 100%;
        min-width: 0;
        margin-top: var(--space-2);
    }

    .theme-switcher-menu {
        right: 0;
        left: 0;
        width: 100%;
    }

    .hero-section { padding: var(--space-6) 0 var(--space-4); }
    .hero-subtitle { font-size: 16px; }

    .widget-icon { width: 44px; height: 44px; font-size: 18px; }

    .widget-split-row { flex-wrap: wrap; gap: var(--space-3); }

    .section-header-row {
        align-items: flex-start;
        flex-direction: column;
    }

    .card-title { font-size: 20px; }
    .post-grid { grid-template-columns: 1fr; }

    .blog-content { font-size: 17px; line-height: 1.7; }
    .blog-content img { margin: 1.6rem auto; border-radius: var(--radius-m); }

    /* 窄屏评论：回复缩进收窄，元信息行允许换行 */
    .comment-replies {
        padding-left: var(--space-3);
        margin-top: var(--space-3);
    }
    .comment-date { margin-left: 0; }

    .auth-wrapper {
        min-height: calc(100vh - 140px);
        padding: var(--space-5) var(--space-3);
    }

    .auth-card {
        border-radius: var(--radius-l);
        padding: var(--space-6) var(--space-5);
    }

    .profile-title { font-size: 26px; }
    .profile-email { font-size: 15px; }
    .settings-card { padding: var(--space-4); }

    /* 搜索浮层：面板贴近顶部、输入条压低，给移动端键盘留出空间 */
    .blog-search-panel { margin-top: var(--space-4); border-radius: var(--radius-m); }
    .blog-search-bar { padding: 0 var(--space-3); }
    /* 输入字号保持 16px：低于 16px 时 iOS Safari 会自动放大页面 */
    .blog-search-input { height: 50px; font-size: 16px; }
    .blog-search-results { max-height: 56vh; }
    .blog-search-hint { padding: var(--space-2) var(--space-3); }
    .blog-search-hint-keys { display: none; }

    .flash-container { width: calc(100% - 24px); }
    .apple-alert {
        border-radius: var(--radius-m);
        padding: var(--space-3) var(--space-4);
        font-size: 14px;
    }

    .pagination { flex-wrap: wrap; row-gap: var(--space-2); }

    .scroll-to-top {
        right: 16px;
        bottom: 16px;
        width: 44px;
        height: 44px;
        font-size: 18px;
    }
}

@media (max-width: 576px) {
    .container { padding: 0 var(--space-3); }
    .hero-title { font-size: clamp(28px, 10vw, 36px); }
    .section-title { font-size: 22px; }
    .card-img-wrapper { height: 180px; }
    .card-body { padding: var(--space-4); }
    .card-title { font-size: 18px; }
    .post-date { font-size: 10px; }
    .blog-content { font-size: 16px; }
    .footer { padding: var(--space-5) 0; }
}

/* ============================================================
   25.  Dark-mode adjustments (applies to nebula)
        Targeted via data-mode="dark" so any future dark themes
        inherit these without further work.
   ============================================================ */

[data-mode="dark"] body {
    color-scheme: dark;
}

/* Bootstrap utility overrides */
[data-mode="dark"] .bg-light  { background-color: var(--bg-subtle) !important; }
[data-mode="dark"] .bg-white  { background-color: var(--bg-card) !important; }
[data-mode="dark"] .text-dark { color: var(--text-primary) !important; }
[data-mode="dark"] .text-muted{ color: var(--text-secondary) !important; }
[data-mode="dark"] .border    { border-color: var(--border-subtle) !important; }

[data-mode="dark"] .btn-dark {
    background-color: var(--bg-elevated);
    border-color: var(--border-medium);
    color: var(--text-primary);
}
[data-mode="dark"] .btn-dark:hover {
    background-color: var(--bg-subtle);
    border-color: var(--border-strong);
}

[data-mode="dark"] .card,
[data-mode="dark"] .modal-content,
[data-mode="dark"] .list-group-item {
    background: var(--bg-card);
    border-color: var(--border-subtle);
    color: var(--text-primary);
}

[data-mode="dark"] .table {
    color: var(--text-primary);
    border-color: var(--border-subtle);
}
[data-mode="dark"] .table-striped > tbody > tr:nth-of-type(odd) {
    background-color: rgba(255, 255, 255, 0.03);
    color: var(--text-primary);
}

[data-mode="dark"] .modal-header,
[data-mode="dark"] .modal-footer { border-color: var(--border-subtle); }

[data-mode="dark"] .alert { border-color: var(--border-subtle); }

[data-mode="dark"] hr,
[data-mode="dark"] .dropdown-divider { border-color: var(--border-subtle); }

/* Forms */
[data-mode="dark"] .form-control,
[data-mode="dark"] .form-select {
    background-color: var(--bg-elevated);
    color: var(--text-primary);
    border-color: var(--border-medium);
}

[data-mode="dark"] .form-control:focus,
[data-mode="dark"] .form-select:focus {
    background-color: var(--bg-subtle);
    color: var(--text-primary);
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

[data-mode="dark"] .form-control.bg-transparent,
[data-mode="dark"] .input-group-text.bg-transparent {
    background-color: transparent !important;
}

[data-mode="dark"] input::placeholder,
[data-mode="dark"] textarea::placeholder {
    color: var(--text-tertiary) !important;
    opacity: 1;
}

/* Tags */
[data-mode="dark"] .badge,
[data-mode="dark"] .tag-badge {
    background: var(--brand-soft);
    color: var(--brand);
}

/* Game center / empty states */
[data-mode="dark"] .game-empty {
    background: var(--bg-card);
    border-color: var(--border-subtle);
    color: var(--text-primary);
}
[data-mode="dark"] .game-empty h4,
[data-mode="dark"] .game-empty p { color: var(--text-primary); }

/* Vocab pages */
[data-mode="dark"] .vocab-filter-card,
[data-mode="dark"] .vocab-card {
    background: var(--bg-card) !important;
    border-color: var(--border-subtle) !important;
}
[data-mode="dark"] .vocab-filter-card input,
[data-mode="dark"] .vocab-filter-card select {
    background: var(--bg-elevated) !important;
    color: var(--text-primary) !important;
    border-color: var(--border-medium) !important;
}
[data-mode="dark"] .vocab-filter-card label { color: var(--text-secondary) !important; }

[data-mode="dark"] .flashcard,
[data-mode="dark"] .card-face,
[data-mode="dark"] .quiz-card {
    background: var(--bg-card) !important;
    color: var(--text-primary) !important;
    box-shadow: var(--shadow-hover) !important;
}

[data-mode="dark"] .card-face h2,
[data-mode="dark"] .card-face .word-title {
    background: var(--gradient-hero) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
}

[data-mode="dark"] .mode-tab {
    background: var(--bg-card) !important;
    border-color: var(--border-subtle) !important;
    color: var(--text-primary) !important;
}
[data-mode="dark"] .mode-tab.active {
    background: var(--brand) !important;
    color: var(--brand-contrast) !important;
}

[data-mode="dark"] .choice-btn {
    background: var(--bg-elevated) !important;
    border-color: var(--border-subtle) !important;
    color: var(--text-primary) !important;
}
[data-mode="dark"] .choice-btn:hover { background: var(--bg-subtle) !important; }
[data-mode="dark"] .choice-index {
    background: var(--brand-soft) !important;
    color: var(--text-secondary) !important;
}

[data-mode="dark"] .spelling-input {
    background: var(--bg-card) !important;
    border-color: var(--border-medium) !important;
    color: var(--text-primary) !important;
}

[data-mode="dark"] .ai-settings-box,
[data-mode="dark"] .batch-progress-panel,
[data-mode="dark"] .batch-result-item {
    background: var(--bg-card) !important;
    border-color: var(--border-subtle) !important;
    color: var(--text-primary) !important;
}

/* Inline-styled inputs (legacy) */
[data-mode="dark"] input[style*="border: 1px solid #d2d2d7"],
[data-mode="dark"] textarea[style*="border: 1px solid #d2d2d7"],
[data-mode="dark"] select[style*="border: 1px solid #d2d2d7"] {
    background: var(--bg-elevated) !important;
    color: var(--text-primary) !important;
    border-color: var(--border-medium) !important;
}

/* Admin pages */
[data-mode="dark"] .admin-content { background: var(--bg-body); }

/* Vditor (markdown editor) */
[data-mode="dark"] .vditor-wrapper,
[data-mode="dark"] .vditor {
    background: var(--bg-card) !important;
    border-color: var(--border-subtle) !important;
}
[data-mode="dark"] .vditor-toolbar {
    background-color: var(--bg-elevated) !important;
    border-bottom-color: var(--border-subtle) !important;
}
[data-mode="dark"] .vditor-toolbar button { color: var(--text-primary) !important; }
[data-mode="dark"] .vditor-toolbar button:hover { background: var(--bg-subtle) !important; }
[data-mode="dark"] .vditor-content,
[data-mode="dark"] .vditor-ir .vditor-reset,
[data-mode="dark"] .vditor-sv,
[data-mode="dark"] .vditor-wysiwyg {
    background: var(--bg-card) !important;
    color: var(--text-primary) !important;
}
[data-mode="dark"] .vditor-reset { color: var(--text-primary) !important; }

[data-mode="dark"] .post-title-input,
[data-mode="dark"] input[placeholder="Enter post title..."],
[data-mode="dark"] input[placeholder*="post title"] {
    background: transparent !important;
    color: var(--text-primary) !important;
    border-color: var(--border-medium) !important;
}
[data-mode="dark"] .post-title-input::placeholder { color: var(--text-tertiary) !important; }

/* 文章详情与评论的暗色覆盖已随 §12 / §12b 改版移除：
   那两块现在只吃 --text-* / --rule，明暗两模自动跟随。 */

/* Auth */
/* 卡片底和 Bootstrap 浮动标签的暗色补丁已随 §16 改版删除
   （现在是透明底 + 下划线输入框，没有需要遮的东西）。
   只留下浏览器自动填充这一条：Chrome 会给自动填充的输入框刷一层
   系统浅黄底，必须用 inset box-shadow 顶掉，否则暗色模式下是白框。 */
[data-mode="dark"] .field .form-control:-webkit-autofill,
[data-mode="dark"] .field-input:-webkit-autofill {
    -webkit-text-fill-color: var(--text-primary);
    caret-color: var(--text-primary);
    -webkit-box-shadow: 0 0 0 1000px var(--bg-body) inset;
}

[data-mode="dark"] .form-check-label { color: var(--text-primary); }

[data-mode="dark"] .about-section,
[data-mode="dark"] .contact-section { color: var(--text-primary); }

/* Cards & post items in dark */
[data-mode="dark"] .post-card,
[data-mode="dark"] .widget-card {
    background: var(--bg-card);
    border-color: var(--border-subtle);
}

[data-mode="dark"] .card-title,
[data-mode="dark"] .card-body { color: var(--text-primary); }

[data-mode="dark"] .card-text,
[data-mode="dark"] .post-excerpt { color: var(--text-secondary); }

/* Blog content in dark */
[data-mode="dark"] .blog-content { color: var(--text-primary); }
[data-mode="dark"] .blog-content pre,
[data-mode="dark"] .blog-content code {
    background: var(--bg-subtle);
    border-color: var(--border-subtle);
}

[data-mode="dark"] .blog-content code:not(.hljs),
[data-mode="dark"] .blog-content pre {
    color: var(--text-primary);
}

[data-mode="dark"] .blog-content pre {
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-m);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
}

[data-mode="dark"] .blog-content pre code.hljs,
[data-mode="dark"] .blog-content .hljs {
    background: transparent;
    color: #e6edf3;
}

[data-mode="dark"] .blog-content .hljs-comment,
[data-mode="dark"] .blog-content .hljs-quote {
    color: #8b949e;
}

[data-mode="dark"] .blog-content .hljs-keyword,
[data-mode="dark"] .blog-content .hljs-doctag,
[data-mode="dark"] .blog-content .hljs-meta .hljs-keyword,
[data-mode="dark"] .blog-content .hljs-template-tag,
[data-mode="dark"] .blog-content .hljs-type {
    color: #ff7b72;
}

[data-mode="dark"] .blog-content .hljs-title,
[data-mode="dark"] .blog-content .hljs-section,
[data-mode="dark"] .blog-content .hljs-title.function_,
[data-mode="dark"] .blog-content .hljs-title.class_,
[data-mode="dark"] .blog-content .hljs-class .hljs-title {
    color: #d2a8ff;
}

[data-mode="dark"] .blog-content .hljs-string,
[data-mode="dark"] .blog-content .hljs-attribute,
[data-mode="dark"] .blog-content .hljs-addition,
[data-mode="dark"] .blog-content .hljs-built_in,
[data-mode="dark"] .blog-content .hljs-literal,
[data-mode="dark"] .blog-content .hljs-number,
[data-mode="dark"] .blog-content .hljs-symbol {
    color: #79c0ff;
}

[data-mode="dark"] .blog-content .hljs-variable,
[data-mode="dark"] .blog-content .hljs-template-variable,
[data-mode="dark"] .blog-content .hljs-name,
[data-mode="dark"] .blog-content .hljs-selector-tag,
[data-mode="dark"] .blog-content .hljs-bullet,
[data-mode="dark"] .blog-content .hljs-deletion {
    color: #ffa657;
}

[data-mode="dark"] .blog-content .hljs-meta,
[data-mode="dark"] .blog-content .hljs-operator,
[data-mode="dark"] .blog-content .hljs-punctuation,
[data-mode="dark"] .blog-content .hljs-subst {
    color: #c9d1d9;
}

/* 表格的深浅两套配色统一由第 52 节的设计令牌驱动，这里不再单独覆写 */

[data-mode="dark"] .blog-content blockquote {
    background: color-mix(in srgb, var(--bg-subtle) 88%, transparent);
    color: var(--text-secondary);
}

/* vocab 页搜索框外壳的暗色适配（.search-bar-wrapper 见 §20 末尾的说明） */
[data-mode="dark"] .search-bar-wrapper {
    background: var(--bg-card);
    border-color: var(--border-subtle);
    box-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
}
[data-mode="dark"] .search-bar-wrapper:focus-within {
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
    border-color: var(--brand);
}

/* ============================================================
   26.  Mother's day banner & petals (preserved)
   ============================================================ */
.mothers-day-banner {
    background: linear-gradient(135deg, #ff8fb1 0%, #ffb3c6 50%, #ffd6e0 100%);
    color: #fff;
    text-align: center;
    padding: 9px 20px;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.4px;
    position: relative;
    z-index: 10;
    box-shadow: 0 2px 14px rgba(255, 105, 150, 0.22);
    text-shadow: 0 1px 3px rgba(180, 40, 80, 0.18);
}

.mothers-day-banner .md-heart {
    display: inline-block;
    animation: mdHeartbeat 1.6s ease-in-out infinite;
    transform-origin: center;
}

@keyframes mdHeartbeat {
    0%, 100% { transform: scale(1);    }
    40%      { transform: scale(1.25); }
    60%      { transform: scale(1.12); }
}

[data-mode="dark"] .mothers-day-banner {
    background: linear-gradient(135deg, #7a1535 0%, #a8204a 50%, #c0335f 100%);
    box-shadow: 0 2px 14px rgba(180, 40, 80, 0.35);
}

.petals-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 9998;
    overflow: hidden;
}

.petal {
    position: absolute;
    top: -24px;
    border-radius: 150% 0 150% 0;
    opacity: 0;
    animation: petalFall linear infinite;
}

@keyframes petalFall {
    0%   { transform: translateY(0)    rotate(0deg)   translateX(0px);  opacity: 0;    }
    5%   {                                                              opacity: 0.75; }
    50%  { transform: translateY(52vh) rotate(200deg) translateX(28px); opacity: 0.6;  }
    95%  {                                                              opacity: 0.3;  }
    100% { transform: translateY(108vh) rotate(400deg) translateX(-18px); opacity: 0;  }
}

/* ============================================================
   27.  Scrollbar styling (matches theme)
   ============================================================ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--border-medium);
    border-radius: var(--radius-pill);
    border: 2px solid transparent;
    background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--border-strong); background-clip: padding-box; }

/* ============================================================
   28.  Focus visible (accessibility)
   ============================================================ */
:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--radius-xs);
}

button:focus-visible,
a:focus-visible {
    outline-offset: 3px;
}

/* ============================================================
   29.  Breadcrumb
   ============================================================ */
.breadcrumb-nav {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: 13px;
    color: var(--text-secondary);
    margin-bottom: var(--space-5);
    flex-wrap: wrap;
}
.breadcrumb-nav a {
    color: var(--text-secondary);
    transition: color var(--dur-fast) ease;
}
.breadcrumb-nav a:hover { color: var(--brand); }
.breadcrumb-nav .crumb-sep {
    color: var(--text-tertiary);
    font-size: 11px;
}
.breadcrumb-nav .crumb-current {
    color: var(--text-primary);
    font-weight: 500;
    max-width: 30ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================
   30.  Reading-progress bar (top of viewport, on post pages)
   ============================================================ */
.reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0%;
    background: var(--gradient-accent);
    z-index: calc(var(--z-popover) + 1);
    transition: width 0.08s linear;
    pointer-events: none;
}

/* ============================================================
   31.  Post list pages (/blog, /tag/<slug>, /search)
        标记见 templates/macros/post_list.html —— 三个页面共用一套，
        首页 landing 的「最新信号」复用同一份 .entry-row。

        形态是编辑式而非卡片式：一条 hairline 分隔一篇，日期占左侧固定
        栏，标题用展宽的 Archivo 放到很大。密度低、字大，整页是一面字墙。
   ============================================================ */
.post-list-page #app-main.container { max-width: 1240px; }

/* 页头本体已提到 §54 的 .page-head / .page-eyebrow / .page-title /
   .page-subtitle；这里只剩 /blog 与 /tag 专属的搜索入口。 */
.page-search-trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 200px;
    height: 42px;
    padding: 0 var(--space-2) 0 var(--space-4);
    flex: 0 0 auto;
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-tertiary);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
    transition: color var(--dur-fast) ease,
                border-color var(--dur-fast) ease,
                background var(--dur-fast) ease;
}
.page-search-trigger span { flex: 1; }
.page-search-trigger kbd {
    min-width: 32px;
    padding: 3px 7px;
    border: 1px solid var(--rule);
    border-radius: 6px;
    background: transparent;
    box-shadow: none;
    color: var(--text-tertiary);
    font-family: var(--font-data);
    font-size: 10.5px;
    line-height: 1.2;
    text-align: center;
}
.page-search-trigger:hover {
    color: var(--text-primary);
    border-color: var(--rule-strong);
}
.page-search-trigger:active { transform: scale(.99); }
.page-search-trigger:focus-visible {
    outline: none;
    border-color: var(--brand);
    box-shadow: var(--focus-ring);
}


/* — 标签行：横向可滚动，窄屏不换行堆高 — */
.tag-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: clamp(18px, 2.6vw, 26px) 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* 滚动时首尾不贴边，滚到端点能停在 chip 边界上 */
    scroll-snap-type: x proximity;
}
.tag-row::-webkit-scrollbar { display: none; }
.tag-row .tag-chip { scroll-snap-align: start; }

.tag-chip {
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    background: transparent;
    border: 1px solid var(--rule);
    color: var(--text-secondary);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color var(--dur-fast) ease, color var(--dur-fast) ease;
}
.tag-chip:hover {
    border-color: var(--brand);
    color: var(--brand);
}
.tag-chip:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}
.tag-chip.active {
    background: var(--text-primary);
    border-color: var(--text-primary);
    color: var(--bg-body);
}


/* — 搜索命中的用户 — */
.user-hits {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding-bottom: var(--space-5);
}
.user-hit {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4) var(--space-2) var(--space-2);
    border-radius: var(--radius-pill);
    background: transparent;
    border: 1px solid var(--rule);
    text-decoration: none;
    transition: border-color var(--dur-fast) ease;
}
.user-hit:hover { border-color: var(--rule-strong); }
.user-hit:focus-visible {
    outline: none;
    border-color: var(--brand);
    box-shadow: var(--focus-ring);
}
.user-hit-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 13px;
    background: var(--brand-soft);
    background: color-mix(in srgb, var(--user-accent) 12%, transparent);
    color: var(--user-accent);
}
.user-hit-text { display: flex; flex-direction: column; line-height: 1.25; }
.user-hit-name { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.user-hit-handle { font-size: 11px; color: var(--text-secondary); }

/* — 计数行：兼作行列表的表头，右侧给出页码位置 — */
.rows-count {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--rule-strong);
}

/* ============================================================
   31b. Entry lead（首篇特写）+ entry rows（行列表）
        独立类名，不复用 .post-card：后者被 profile / game 页占用，
        且带 §2 的 border-color !important、apple 主题的 hover 位移、
        §42 的光斑伪元素和 main.js 的 scroll-reveal（opacity:0 起步）。

        行没有卡片外框，只有一条 hairline。悬停时底线由左向右扫成品牌色，
        桌面端另有封面跟随光标浮出（post-list.js）。
   ============================================================ */

/* — 首篇特写 — */
.entry-lead {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(24px, 4vw, 64px);
    padding: clamp(26px, 3.6vw, 48px) 0;
    border-bottom: 1px solid var(--rule);
    text-decoration: none;
    color: inherit;
}
.entry-lead-media {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: var(--radius-l);
    background: var(--bg-subtle);
}
.entry-lead-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .8s var(--ease-apple);
}
.entry-lead:hover .entry-lead-media img { transform: scale(1.035); }

/* 无封面时的色板：写的是这篇文章的主标签（没有标签就写年份），
   色相由 post.id 决定，同一篇永远同色 */
.entry-lead-plate {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: var(--space-5);
    text-align: center;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 118%;
    font-size: clamp(30px, 5vw, 62px);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: color-mix(in srgb, var(--text-primary) 34%, transparent);
    background:
        radial-gradient(120% 92% at 16% 0%, hsl(var(--lead-hue, 260) 72% 56% / .28), transparent 68%),
        var(--bg-subtle);
}

.entry-lead-body { min-width: 0; }
.entry-lead-label {
    display: inline-block;
    margin-bottom: clamp(12px, 1.6vw, 18px);
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--brand);
}
.entry-lead-title {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 112%;
    font-size: clamp(27px, 3.4vw, 52px);
    line-height: 1.06;
    letter-spacing: -0.032em;
    color: var(--text-primary);
    margin: 0;
    transition: color var(--dur-base) ease;
}
.entry-lead:hover .entry-lead-title { color: var(--brand); }
.entry-lead-summary {
    margin: clamp(14px, 1.8vw, 20px) 0 0;
    max-width: 46ch;
    font-size: 15px;
    line-height: 1.75;
    color: var(--text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.entry-lead-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-top: clamp(18px, 2.4vw, 28px);
    padding-top: var(--space-4);
    border-top: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.06em;
    color: var(--text-tertiary);
}
.entry-lead-author { font-weight: 500; }
.entry-lead-go {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-left: auto;
    font-family: var(--font-sans);
    font-size: 13px;
    letter-spacing: 0;
    color: var(--brand);
}
.entry-lead-go i { transition: transform var(--dur-base) var(--ease-apple); }
.entry-lead:hover .entry-lead-go i { transform: translateX(5px); }

.entry-lead:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 6px;
    border-radius: var(--radius-s);
}

/* — 行列表 — */
.entry-rows { --date-col: clamp(84px, 9vw, 116px); }

.entry-row {
    position: relative;
    display: grid;
    grid-template-columns: var(--date-col) minmax(0, 1fr) auto 40px;
    align-items: start;
    gap: clamp(14px, 2.2vw, 32px);
    padding: clamp(22px, 2.6vw, 34px) 0;
    border-bottom: 1px solid var(--rule);
    text-decoration: none;
    color: inherit;
}
/* 悬停时底线由左向右扫成品牌色——「这一条被选中」的读法，不越出行宽 */
.entry-row::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--brand);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform .5s var(--ease-apple);
}
.entry-row:hover::after,
.entry-row:focus-visible::after { transform: scaleX(1); }
.entry-row:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 4px;
    border-radius: var(--radius-xs);
}

.entry-row-date {
    padding-top: 0.4em;
    font-family: var(--font-data);
    font-size: 12px;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
    white-space: nowrap;
    transition: color var(--dur-base) ease;
}
.entry-row:hover .entry-row-date { color: var(--brand); }

.entry-row-main { min-width: 0; }
.entry-row-title {
    font-family: var(--font-editorial);
    font-weight: 650;
    font-stretch: 108%;
    font-size: clamp(19px, 2vw, 29px);
    line-height: 1.22;
    letter-spacing: -0.022em;
    color: var(--text-primary);
    margin: 0;
    transition: color var(--dur-base) ease;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.entry-row:hover .entry-row-title { color: var(--brand); }
.entry-row-summary {
    margin: 10px 0 0;
    max-width: 62ch;
    font-size: 14px;
    line-height: 1.7;
    color: var(--text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.entry-row-meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding-top: 0.35em;
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.06em;
    color: var(--text-tertiary);
    white-space: nowrap;
}
.entry-row-tag {
    padding: 3px 9px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    text-transform: uppercase;
    font-size: 10.5px;
}
.entry-row-views { font-variant-numeric: tabular-nums; }

.entry-row-go {
    justify-self: end;
    align-self: start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--rule);
    color: var(--text-tertiary);
    font-size: 13px;
    transition: color var(--dur-base) ease,
                border-color var(--dur-base) ease,
                transform var(--dur-base) var(--ease-apple);
}
.entry-row:hover .entry-row-go {
    color: var(--brand);
    border-color: var(--brand);
    transform: translateX(4px);
}

/* — 封面跟随光标（post-list.js 注入，仅桌面端） — */
.entry-peek {
    position: fixed;
    top: 0;
    left: 0;
    z-index: var(--z-overlay);
    width: 232px;
    height: 154px;
    border-radius: var(--radius-m);
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    box-shadow: var(--shadow-lift);
    transition: opacity .22s var(--ease-out);
    will-change: transform;
}
.entry-peek.is-on { opacity: 1; }
.entry-peek img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.entry-peek-plate {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: var(--space-3);
    text-align: center;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 118%;
    font-size: 26px;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: color-mix(in srgb, var(--text-primary) 44%, transparent);
    background:
        radial-gradient(120% 92% at 20% 0%, hsl(var(--peek-hue, 260) 72% 56% / .38), transparent 70%),
        var(--bg-subtle);
}


/* ============================================================
   31c. Pager (windowed pagination)
        页数多时由 iter_pages() 折成省略号，只占一行。
   ============================================================ */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    margin-top: clamp(36px, 5vw, 64px);
    padding: var(--space-5) 0 clamp(56px, 8vw, 104px);
    border-top: 1px solid var(--rule-strong);
}
.pager-step,
.pager-page {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 34px;
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    color: var(--text-secondary);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.pager-step { border: 1px solid var(--rule); }
.pager-step:hover { color: var(--brand); border-color: var(--brand); }
.pager-page:hover { color: var(--brand); }
.pager-step.is-disabled { opacity: 0.3; pointer-events: none; }

.pager-pages { display: flex; align-items: center; gap: var(--space-1); }
.pager-page { min-width: 34px; justify-content: center; padding: 0 var(--space-2); }
.pager-page.active {
    color: var(--text-primary);
    box-shadow: inset 0 -1px 0 0 var(--text-primary);
    border-radius: 0;
}
.pager-gap { color: var(--text-tertiary); padding: 0 var(--space-1); font-family: var(--font-data); font-size: 11px; }

@media (max-width: 576px) {
    .pager-step span { display: none; }
    .pager-step { padding: 0 var(--space-3); }
}

/* — 列表页窄屏：日期升到标题上方，元信息落到最底，标签行左右出血 — */
@media (max-width: 900px) {
    .entry-lead {
        grid-template-columns: 1fr;
        gap: var(--space-5);
    }
    .entry-lead-media { aspect-ratio: 16 / 9; }
}
@media (max-width: 768px) {
    .page-search-trigger { display: none; }
    .entry-row {
        grid-template-columns: minmax(0, 1fr) 34px;
        gap: var(--space-2) var(--space-4);
        align-items: center;
    }
    .entry-row-date {
        grid-column: 1 / -1;
        grid-row: 1;
        padding-top: 0;
    }
    .entry-row-main { grid-column: 1; grid-row: 2; }
    .entry-row-go   { grid-column: 2; grid-row: 2; }
    .entry-row-meta {
        grid-column: 1 / -1;
        grid-row: 3;
        padding-top: var(--space-1);
        flex-wrap: wrap;
        white-space: normal;
    }
    .entry-row-summary { display: none; }
    .tag-row {
        margin-inline: calc(-1 * var(--space-4));
        padding-inline: var(--space-4);
    }
    .pager { justify-content: center; }
}
@media (max-width: 576px) {
    .tag-row {
        margin-inline: calc(-1 * var(--space-3));
        padding-inline: var(--space-3);
    }
}

@media (prefers-reduced-motion: reduce) {
    .entry-row::after,
    .entry-lead-media img,
    .entry-row-go,
    .entry-peek { transition: none; }
}



/* ============================================================
   32.  Floating TOC (post page, desktop ≥1280px)
   ============================================================ */
/* Wider container dedicated to article pages */
.post-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 var(--space-5);
}
@media (min-width: 1440px) {
    .post-container { max-width: 1320px; }
}
@media (max-width: 768px) {
    .post-container { padding: 0 var(--space-4); }
}
@media (max-width: 480px) {
    .post-container { padding: 0 var(--space-3); }
}

.post-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
    max-width: 100%;
}
/* Medium screens: article + author rail */
@media (min-width: 1024px) and (max-width: 1279.98px) {
    .post-layout {
        grid-template-columns: minmax(0, 1fr) 220px;
    }
    .post-layout > main { grid-column: 1; }
    .post-layout > .post-side { grid-column: 2; }
}
/* Wide screens: TOC + article + author rail */
@media (min-width: 1280px) {
    .post-layout {
        grid-template-columns: 200px minmax(0, 1fr) 240px;
        gap: var(--space-7);
    }
}
/* Wide screens, no TOC: drop the left column and center article */
@media (min-width: 1280px) {
    .post-layout.post-layout--no-toc {
        grid-template-columns: minmax(0, 1fr) 240px;
        max-width: 1080px;
        margin: 0 auto;
    }
    .post-layout.post-layout--no-toc > main { grid-column: 1; }
    .post-layout.post-layout--no-toc > .post-side { grid-column: 2; }
}

.post-toc {
    display: none;
}
@media (min-width: 1280px) {
    .post-toc {
        display: block;
        position: sticky;
        top: 80px;
        align-self: start;
        max-height: calc(100vh - 100px);
        overflow-y: auto;
        padding-left: var(--space-4);
        border-left: 1px solid var(--rule);
        font-size: 13px;
    }
}

.post-toc-title {
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--text-tertiary);
    margin-bottom: var(--space-3);
}

.post-toc ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.post-toc li.level-3 { padding-left: var(--space-3); }
.post-toc li.level-4 { padding-left: var(--space-5); }

.post-toc a {
    display: block;
    padding: var(--space-1) var(--space-2);
    color: var(--text-tertiary);
    text-decoration: none;
    transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
    line-height: 1.45;
    border-left: 1px solid transparent;
    margin-left: calc(-1 * var(--space-4) - 1px);
    padding-left: var(--space-4);
}
.post-toc a:hover { color: var(--text-primary); }
.post-toc a.active {
    color: var(--brand);
    border-left-color: var(--brand);
    font-weight: 500;
}

.post-side {
    display: none;
}
@media (min-width: 1024px) {
    .post-side {
        display: flex;
        flex-direction: column;
        gap: var(--space-4);
        position: sticky;
        top: 80px;
        align-self: start;
    }
}

.post-side-author {
    background: transparent;
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    padding: var(--space-5);
    box-shadow: none;
}
.post-side-label {
    display: block;
    margin-bottom: var(--space-4);
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.post-side-name { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.post-side-handle { font-family: var(--font-data); font-size: 11px; color: var(--text-tertiary); }
.post-side-bio {
    margin: var(--space-4) 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--text-secondary);
}

/* ============================================================
   33.  （原 blog-hero：已随列表页改版移除，页头样式见 §54 .page-head）
   ============================================================ */

/* ============================================================
   34.  Loading skeleton (used on async actions)
   ============================================================ */
.skeleton {
    background: linear-gradient(
        90deg,
        var(--bg-subtle) 0%,
        var(--bg-card) 50%,
        var(--bg-subtle) 100%
    );
    background-size: 200% 100%;
    animation: skeletonShimmer 1.5s ease-in-out infinite;
    border-radius: var(--radius-s);
}
@keyframes skeletonShimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ============================================================
   37.  Button :disabled / loading state
   ============================================================ */
.btn:disabled,
.btn[aria-busy="true"] {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none !important;
}
.btn[aria-busy="true"]::after {
    content: '';
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: var(--space-2);
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: btnSpin 0.8s linear infinite;
    vertical-align: middle;
}
@keyframes btnSpin { to { transform: rotate(360deg); } }

/* ============================================================
   38.  Empty state
        左对齐、hairline 收边，和 §54 的分区表头是同一个记法：
        图标退成一个轮廓字符，标题走展宽 Archivo，不再是居中的
        灰圆 + 灰字那种「出错了」读法。
   ============================================================ */
.empty-state {
    padding: clamp(40px, 6vw, 76px) 0;
    border-bottom: 1px solid var(--rule);
    color: var(--text-secondary);
}
.empty-state-icon {
    display: block;
    margin: 0 0 var(--space-4);
    background: none;
    border-radius: 0;
    width: auto;
    height: auto;
    color: color-mix(in srgb, var(--text-primary) 22%, transparent);
    font-size: 34px;
    line-height: 1;
}
.empty-state-title {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 110%;
    font-size: clamp(22px, 2.6vw, 34px);
    line-height: 1.12;
    letter-spacing: -0.028em;
    color: var(--text-primary);
    margin: 0 0 var(--space-3);
}
.empty-state-text {
    color: var(--text-secondary);
    font-size: 14.5px;
    line-height: 1.75;
    margin: 0 0 var(--space-5);
    max-width: 44ch;
}

/* ============================================================
   39.  Ambient background (mars theme, both modes)
   ============================================================ */
html[data-theme="mars"] body::before {
    content: '';
    position: fixed;
    inset: -10%;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(46% 38% at 12% 6%, var(--brand-soft), transparent 72%),
        radial-gradient(40% 34% at 90% 82%, var(--accent-soft), transparent 72%);
    opacity: .55;
    transition: opacity var(--dur-slow) ease;
}

/* ============================================================
   40.  Button press feedback (Apple-style scale, no ripple)
   ============================================================ */
.btn:active { transform: scale(0.97); }

/* ============================================================
   41.  Copy-code button (injected by main.js on pre > code)
   ============================================================ */
.copy-code-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-s);
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transform: translateY(-2px);
    transition: opacity var(--dur-fast) ease,
                transform var(--dur-fast) var(--ease-apple),
                color var(--dur-fast) ease,
                border-color var(--dur-fast) ease;
    box-shadow: var(--shadow-xs);
    z-index: 2;
}
pre:hover .copy-code-btn,
.copy-code-btn:focus-visible {
    opacity: 1;
    transform: translateY(0);
}
.copy-code-btn:hover {
    color: var(--brand);
    border-color: var(--border-medium);
}
.copy-code-btn.copied {
    opacity: 1;
    color: var(--green);
    border-color: var(--green);
}
@media (hover: none) {
    .copy-code-btn { opacity: 1; transform: none; }
}

/* ============================================================
   42.  Card cursor spotlight (position set by main.js)
   ============================================================ */
/* 光斑跟随已随卡片一起退场：面板改成透明底之后，这道径向渐变会直接
   糊在正文上，而不是「照亮卡面」。main.js 仍在写 --mx/--my，无副作用。 */
.post-card,
.widget-card,
.admin-stat-card,
.settings-card {
    position: relative;
}

/* ============================================================
   43.  View transition timing (SPA in-app navigation only)
   ============================================================ */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.18s;
    animation-timing-function: var(--ease-apple);
}

/* ============================================================
   44.  Reduced motion: kill all animation globally
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============================================================
   45.  APPLE · HIG polish layer (active theme)
        Frosted chrome, generous whitespace, fluid motion
   ============================================================ */

/* — Brand wordmark (navbar) — */
.a-wordmark {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: inherit;
    line-height: 1;
    white-space: nowrap;
}
.a-wordmark i { font-size: 17px; line-height: 1; }

/* — Navbar: pure frosted chrome, links brighten softly — */
[data-theme="apple"] .apple-navbar.scrolled {
    box-shadow: 0 1px 0 var(--border-subtle), 0 8px 24px rgba(0, 0, 0, 0.12);
}
[data-theme="apple"] .apple-nav-link {
    transition: opacity var(--dur-base) var(--ease-apple),
                color var(--dur-base) ease,
                transform var(--dur-base) var(--ease-apple);
}
[data-theme="apple"] .apple-nav-link:active { transform: scale(0.96); }

/* — Cards: deep radius, soft diffuse shadow, gentle lift — */
[data-theme="apple"] .post-card,
[data-theme="apple"] .widget-card {
    border-radius: var(--radius-l);
}
[data-theme="apple"] .post-card:hover {
    transform: translateY(-6px) scale(1.005);
}

/* — Section titles slightly larger, tighter — */
[data-theme="apple"] .section-title { letter-spacing: -0.02em; }

/* — Dropdown & menus: heavier frost — */
[data-theme="apple"] .nav-user-dropdown .dropdown-menu,
[data-theme="apple"] .theme-switcher-menu {
    background: color-mix(in srgb, var(--dropdown-bg) 86%, transparent);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
}

/* — Footer: quiet, small, centered — */
[data-theme="apple"] .footer { font-size: 13px; }

/* — Smooth link color transitions everywhere — */
[data-theme="apple"] a { transition: color var(--dur-base) var(--ease-apple), opacity var(--dur-base) var(--ease-apple); }

/* ============================================================
   46.  Admin dashboard widgets
   ============================================================ */
/* 页头已并入 §54 的 .page-head 一族（模板同步改了类名），
   这里只剩后台特有的仪表盘构件。 */

.admin-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}

a.admin-stat-card { text-decoration: none; color: inherit; }

.admin-stat-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-4);
}
.admin-stat-arrow {
    color: var(--text-tertiary);
    font-size: 14px;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.admin-stat-card:hover .admin-stat-arrow {
    opacity: 1;
    transform: translateX(0);
}

.admin-quick-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-3);
}
.admin-quick-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--bg-subtle);
    border: 1px solid transparent;
    border-radius: var(--radius-m);
    color: var(--text-primary);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-apple);
}
.admin-quick-item:hover {
    background: var(--bg-card);
    border-color: var(--border-medium);
    transform: translateY(-1px);
    color: var(--brand);
}
.admin-quick-item i { color: var(--brand); font-size: 16px; }

.admin-status-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) 0;
}
.admin-status-row + .admin-status-row { border-top: 1px solid var(--border-subtle); }
.admin-status-meta { flex: 1; min-width: 0; }
.admin-status-name { font-weight: 500; font-size: 14px; }
.admin-status-desc { color: var(--text-secondary); font-size: 12.5px; }

/* ============================================================
   47.  Forum
        列表走 §54 的 .data-row（标记在 forum/index.html），这里只留
        论坛自己的件：角色头像、置顶/锁定标记、楼层、回复框。
        全部 hairline，没有卡片底和阴影。
   ============================================================ */
.forum-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 14px;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--role, var(--brand)) 15%, transparent);
    color: var(--role, var(--brand));
}
.forum-avatar--sm { width: 30px; height: 30px; font-size: 12.5px; }

/* 置顶 / 锁定：用 §54 的 .pill 打底，这里只给颜色。
   置顶行左侧再补一条橙色竖线，扫列表时不用读文字也能看出来。 */
.data-row--pinned { box-shadow: inset 3px 0 0 -1px var(--orange); padding-left: var(--space-3); }

.forum-reply-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-data);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
    white-space: nowrap;
}

/* — Thread page — */
.forum-thread-body {
    padding: clamp(24px, 3.4vw, 44px) 0;
    border-bottom: 1px solid var(--rule);
}
.forum-thread-body.blog-content { margin-inline: 0; }

.forum-admin-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-4) 0;
    border-bottom: 1px solid var(--rule);
}

/* 楼层：一条 hairline 一楼，和文章页评论是同一个记法 */
.forum-reply {
    display: flex;
    gap: var(--space-3);
    padding: clamp(16px, 2.2vw, 24px) 0;
    border-bottom: 1px solid var(--rule);
}
.forum-reply-main { flex: 1; min-width: 0; }
.forum-reply-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}
.forum-reply-name {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: 600;
    font-size: 14px;
    color: var(--role, var(--text-primary));
}
.forum-reply-time {
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--text-tertiary);
    white-space: nowrap;
}
.forum-reply-body {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text-secondary);
    overflow-wrap: break-word;
}
.forum-reply-body > :last-child { margin-bottom: 0; }
.forum-reply-body.blog-content { margin-inline: 0; font-size: 15px; }

.forum-del-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-tertiary);
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    transition: color var(--dur-fast) ease;
}
.forum-del-btn:hover { color: var(--red); }

/* — Composer：只有一条下边框的输入区，聚焦时变品牌色 — */
.forum-composer { padding-top: clamp(24px, 3.4vw, 40px); }
.forum-composer-label {
    display: block;
    margin-bottom: var(--space-2);
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.forum-composer textarea {
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--rule-strong);
    border-radius: 0;
    background: transparent;
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.7;
    padding: 10px 2px;
    resize: none;
    overflow: hidden;
    min-height: 96px;
    color: var(--text-primary);
    outline: none;
    transition: border-color var(--dur-base) ease;
}
.forum-composer textarea:focus { border-bottom-color: var(--brand); }
.forum-composer-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-4);
    flex-wrap: wrap;
}
.forum-hint {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.forum-hint kbd {
    font-family: var(--font-data);
    font-size: 10px;
    background: transparent;
    border: 1px solid var(--rule);
    border-radius: 5px;
    padding: 1px 6px;
    color: var(--text-tertiary);
    box-shadow: none;
}

/* 实时更新指示灯 */
.live-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--green);
    display: inline-block;
    animation: pulse-green 2s infinite;
}
@keyframes pulse-green {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.28; }
}
@media (prefers-reduced-motion: reduce) {
    .live-dot { animation: none; }
}

/* ============================================================
   48.  Navbar dropdown menus (Read / Play / AI / Tools) + write CTA
        每个分类是一个顶栏入口，点击展开挂在按钮正下方的下拉列表，
        展开/收起动画复用第 7 节的统一下拉系统（opacity + translateY + scale）。
   ============================================================ */
.nav-write-cta {
    color: var(--brand) !important;
    font-weight: 600 !important;
    opacity: 1 !important;
    background: var(--brand-soft);
}

.nav-write-cta:hover,
.nav-write-cta:focus {
    background: color-mix(in srgb, var(--brand) 22%, transparent);
}

/* 分类按钮旁的小三角：展开时翻转，给用户明确的展开态反馈 */
.nav-mega-caret {
    font-size: 9px;
    opacity: 0.55;
    transition: transform var(--dur-base) var(--ease-apple), opacity var(--dur-fast) ease;
}

.nav-mega-toggle:hover .nav-mega-caret { opacity: 1; }
.nav-mega.dd-open .nav-mega-caret { transform: rotate(180deg); opacity: 1; }

.nav-mega-toggle {
    background: transparent;
    border: none;
    cursor: pointer;
    font: inherit;
    display: inline-flex;
    align-items: center;
}
/* 展开中的那一项按当前项处理 */
.nav-mega.dd-open > .nav-mega-toggle {
    opacity: 1;
    color: var(--navbar-active);
}

/* 下拉面板锚定在按钮上：[data-dropdown] 已给 .nav-mega position:relative，
   面板（position:absolute, top:calc(100%+10px)）自然落在按钮正下方。 */
.mega-menu {
    background: var(--dropdown-bg);
    box-shadow: var(--shadow-lift);
}

.nav-mega > .mega-menu {
    min-width: 264px;
    border: 1px solid var(--dropdown-border);
    border-radius: var(--radius-m);
    padding: var(--space-2);
    transform-origin: top left;
}

.mega-panel {
    max-width: none;
    margin: 0;
    padding: 0;
}

.mega-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-tertiary);
    padding: var(--space-2) var(--space-3) var(--space-1);
}

/* 纵向列表：每行 = 图标 tile + 名称 + 一句话说明 */
.mega-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
}

.mega-link {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    max-width: 100%;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-s);
    text-decoration: none;
    color: var(--text-primary);
    transition: background-color var(--dur-fast) ease;
}
.mega-link:hover { text-decoration: none; background: var(--dropdown-hover); }
.mega-link.active { background: var(--brand-soft); }

.mega-link-icon {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    background: var(--brand-soft);
    color: var(--brand);
    font-size: 15px;
    transition: background-color var(--dur-fast) ease,
                color var(--dur-fast) ease,
                transform var(--dur-fast) var(--ease-spring);
}
.mega-link:hover .mega-link-icon,
.mega-link:focus-visible .mega-link-icon {
    background: var(--brand);
    color: var(--brand-contrast);
    transform: scale(1.06);
}

.mega-link-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.mega-link-name {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.25;
    transition: color var(--dur-fast) ease;
}
.mega-link:hover .mega-link-name,
.mega-link:focus-visible .mega-link-name,
.mega-link.active .mega-link-name { color: var(--brand); }
.mega-link-desc {
    font-size: 12.5px;
    color: var(--text-tertiary);
    line-height: 1.4;
}

/* Mobile: dropdowns become inline panels inside the hamburger list */
@media (max-width: 768px) {
    .nav-mega > [data-dropdown-menu],
    .nav-user-dropdown > [data-dropdown-menu] {
        position: static;
        width: 100%;
        min-width: 0;
        transform: none;
        box-shadow: none;
        margin-top: var(--space-1);
    }
    .nav-mega > .mega-menu {
        border: none;
        background: transparent;
        padding: 0 0 var(--space-2) var(--space-3);
    }
    .mega-panel { max-width: none; padding: 0; }
    /* 顶栏按钮本身就写着分类名，面板里再来一遍 "Explore Play" 是废话 */
    .mega-label { display: none; }
    /* 桌面端是带图标的下拉列表，移动端进一步精简成纯文字列表 */
    .mega-links {
        display: flex;
        flex-direction: column;
        gap: 0;
        align-items: stretch;
    }
    .mega-link-icon { display: none; }
    .mega-link {
        gap: 0;
        min-height: 40px;
        justify-content: center;
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-s);
        /* 面板此时长在导航条底色上（apple 主题浅色模式下也是深色），
           正文色 --text-primary 叠上去几乎看不清，改用导航条自己的字色。 */
        color: var(--navbar-text);
    }
    /* 列表态不再需要指示点，active 直接靠底色区分 */
    .apple-nav-link.active::after { display: none; }
    .mega-link-name { font-size: 15px; font-weight: 500; letter-spacing: -0.01em; }
    .mega-link-desc { display: none; }
    .mega-link:hover {
        background: color-mix(in srgb, var(--navbar-text) 12%, transparent);
    }
    .mega-link.active {
        background: color-mix(in srgb, var(--brand) 26%, transparent);
    }
    .mega-link:hover .mega-link-name,
    .mega-link.active .mega-link-name { color: var(--navbar-active); }
}

/* ============================================================
   49.  Notification center (navbar bell)
        Single node: rightmost on desktop, next to the hamburger
        on mobile (flex order), so it never hides inside the menu.
   ============================================================ */
.nav-notify {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    margin-left: var(--space-2);
}

.notify-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--navbar-text);
    opacity: 0.78;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition: opacity var(--dur-fast) ease,
                background var(--dur-fast) ease,
                color var(--dur-fast) ease,
                transform var(--dur-fast) var(--ease-apple);
}
.notify-toggle:hover,
.notify-toggle:focus-visible { opacity: 1; background: var(--dropdown-hover); transform: scale(1.06); }
.notify-toggle:active { transform: scale(0.94); }
.nav-notify.dd-open .notify-toggle { opacity: 1; background: var(--dropdown-hover); }

/* 有未读：品牌色实心铃铛 + 扩散光环，静态也能一眼看到 */
.nav-notify.has-unread .notify-toggle {
    opacity: 1;
    color: var(--brand);
    background: var(--brand-soft);
}
.nav-notify.has-unread .notify-toggle::before {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: 50%;
    border: 1.5px solid var(--brand);
    animation: notify-ring 2.6s var(--ease-out) infinite;
    pointer-events: none;
}
@keyframes notify-ring {
    0%        { transform: scale(0.78); opacity: 0.6; }
    70%, 100% { transform: scale(1.35); opacity: 0; }
}

.notify-badge {
    position: absolute;
    top: -2px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: var(--radius-pill, 999px);
    background: var(--red);
    color: #fff;
    font-family: var(--font-sans);
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--navbar-bg), 0 2px 6px rgba(255, 59, 48, 0.45);
    animation: notify-pop var(--dur-base) var(--ease-spring);
}
@keyframes notify-pop {
    from { transform: scale(0.2); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
}

/* ── Panel ── */
.notify-menu {
    right: -6px;
    left: auto;
    width: 360px;
    max-width: calc(100vw - 24px);
    background: var(--dropdown-bg);
    border: 1px solid var(--dropdown-border);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-lift);
    overflow: hidden;
    transform-origin: top right;
}

.notify-head,
.notify-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}
.notify-head {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-subtle);
}
.notify-foot {
    padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
    border-top: 1px solid var(--border-subtle);
    font-size: 11px;
    color: var(--text-tertiary);
}
.notify-heading {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}
.notify-action {
    background: none;
    border: none;
    padding: 3px 8px;
    border-radius: var(--radius-xs);
    color: var(--brand);
    font-family: var(--font-sans);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--dur-fast) ease;
}
.notify-action:hover { background: var(--brand-soft); }

.notify-body {
    max-height: min(58vh, 420px);
    overflow-y: auto;
    padding: var(--space-2);
    overscroll-behavior: contain;
}

.notify-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3);
    border-radius: var(--radius-s);
    color: var(--text-primary);
    text-decoration: none;
    transition: background var(--dur-fast) ease;
}
.notify-item + .notify-item { margin-top: 2px; }
.notify-item:hover { background: var(--dropdown-hover); color: var(--text-primary); }
.notify-item.is-unread { background: var(--brand-soft); }
.notify-item.is-unread:hover { background: var(--dropdown-hover); }
.notify-item.is-priority { box-shadow: inset 2px 0 0 var(--red); }

.notify-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    font-size: 14px;
    flex-shrink: 0;
    background: var(--brand-soft);
    color: var(--brand);
}
.notify-accent-purple .notify-icon { background: var(--purple-soft); color: var(--purple); }
.notify-accent-green  .notify-icon { background: var(--green-soft);  color: var(--green); }
.notify-accent-orange .notify-icon { background: var(--orange-soft); color: var(--orange); }
.notify-accent-red    .notify-icon { background: var(--red-soft);    color: var(--red); }

.notify-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.notify-row  { display: flex; align-items: center; gap: var(--space-2); }
.notify-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    letter-spacing: 0.01em;
}
.notify-accent-purple .notify-label { color: var(--purple); }
.notify-accent-green  .notify-label { color: var(--green); }
.notify-accent-orange .notify-label { color: var(--orange); }
.notify-accent-red    .notify-label { color: var(--red); }
.notify-time { margin-left: auto; font-size: 11px; color: var(--text-tertiary); flex-shrink: 0; }
.notify-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand);
    flex-shrink: 0;
}
.notify-item-title {
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--text-primary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.notify-desc {
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.notify-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-7) var(--space-4);
    color: var(--text-tertiary);
    font-size: 12.5px;
}
.notify-placeholder i { font-size: 22px; }
.notify-spin { animation: notify-spin 1s linear infinite; }
@keyframes notify-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .nav-notify.has-unread .notify-toggle::before,
    .notify-badge,
    .notify-spin { animation: none; }
}

/* Mobile: bell moves into the top bar, panel becomes a full-width sheet */
@media (max-width: 768px) {
    .apple-nav-brand-link { order: 1; }
    .nav-coin             { order: 2; margin-left: auto; }
    .nav-notify           { order: 3; margin-left: var(--space-1); }
    .apple-nav-toggle     { order: 4; margin-left: var(--space-1); }
    .apple-nav-list       { order: 5; }

    .nav-notify > .notify-menu {
        position: fixed;
        top: calc(var(--nav-h) + 6px);
        left: var(--space-3);
        right: var(--space-3);
        width: auto;
        max-width: none;
    }
    .notify-body { max-height: min(64vh, 460px); }
}

/* ============================================================
   50.  Unread pill (navbar Messages entry + DM conversation list)
        Defined globally because the navbar renders on every page,
        while messages.css only loads on /messages and /feedback.
   ============================================================ */
.dm-unread {
    flex-shrink: 0;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--red);
    color: #fff;
    font-family: var(--font-sans);
    font-size: 10px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* ============================================================
   51.  Mermaid 渲染
       服务端把 ```mermaid 围栏渲染成 .mermaid-pre，前端替换为 .mermaid-rendered。
   ============================================================ */
.mermaid-pre {
    margin: 1.25rem 0;
    padding: 1rem;
    border-radius: 12px;
    background: var(--bg-body);
    border: 1px solid var(--border-subtle);
    overflow-x: auto;
}
.mermaid-rendered {
    margin: 1.25rem 0;
    padding: 1rem;
    border-radius: 12px;
    background: var(--bg-body);
    border: 1px solid var(--border-subtle);
    overflow-x: auto;
    text-align: center;
    line-height: 0;
}
.mermaid-rendered svg {
    max-width: 100%;
    height: auto;
}

/* ============================================================
   52.  Markdown 表格与行内语义标签（全站统一）

   作用域是所有 Markdown 正文容器：
     .md-table      服务端 TablePolishExtension / 前端 MarsMD.enhanceTables 包出来的滚动容器
     .blog-content  文章正文 + 论坛主题/回复
     .comment-body  文章评论
     .ai-msg-bubble AI 对话气泡（marked 渲染）
     .oi-md         洛谷题面（marked 渲染）

   历史文章的 body_html 里没有 .md-table 包裹，所以规则对裸 <table> 同样生效；
   深浅两套配色全部由设计令牌驱动，不要再写 [data-mode="dark"] 覆盖。
   ============================================================ */

/* 容器只负责外边距与横向滚动，边框/圆角画在 table 自身上，避免双层描边 */
.md-table {
    max-width: 100%;
    margin: 1.75em 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}
.md-table > table { margin: 0; }

:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) table {
    width: 100%;
    max-width: 100%;
    margin: 1.75em 0;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-m);
    /* separate + 0 间距：collapse 下单元格圆角会被忽略，表头就切不出圆角 */
    border-collapse: separate;
    border-spacing: 0;
    background: var(--bg-card);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.9em;
    line-height: 1.6;
}

:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) {
    padding: 0.68em 1.05em;
    /* 列多时宁可横向滚动，也不要把中文压成一列一个字 */
    min-width: 5.5em;
    border-right: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    text-align: left;
    vertical-align: top;
    /* 长 URL / 长代码不撑破版面 */
    overflow-wrap: anywhere;
    transition: background var(--dur-fast) ease;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td):last-child {
    border-right: 0;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) tbody tr:last-child :is(th, td) {
    border-bottom: 0;
}

:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) thead th {
    background: var(--bg-subtle);
    color: var(--text-secondary);
    font-weight: 650;
    font-size: 0.94em;
    letter-spacing: 0.02em;
    vertical-align: middle;
    /* 表头断行会把「输入价格」拆成两行，很难看；宁可让容器横向滚动 */
    white-space: nowrap;
    border-bottom-color: var(--border-medium);
}

/* 四角：圆角必须同时给 table 和角上的单元格，否则表头底色会溢出圆角 */
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) thead tr:first-child th:first-child {
    border-top-left-radius: calc(var(--radius-m) - 1px);
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) thead tr:first-child th:last-child {
    border-top-right-radius: calc(var(--radius-m) - 1px);
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) tbody tr:last-child :is(th, td):first-child {
    border-bottom-left-radius: calc(var(--radius-m) - 1px);
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) tbody tr:last-child :is(th, td):last-child {
    border-bottom-right-radius: calc(var(--radius-m) - 1px);
}

/* 斑马纹与悬停都画在单元格上：画在 tr 上会被单元格底色盖住，且吃不到圆角 */
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) tbody tr:nth-child(even) :is(th, td) {
    background: color-mix(in srgb, var(--text-primary) 3.5%, transparent);
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) tbody tr:hover :is(th, td) {
    background: color-mix(in srgb, var(--brand) 8%, transparent);
}

:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) caption {
    caption-side: top;
    padding: 0 0 0.6em;
    color: var(--text-tertiary);
    font-size: 0.9em;
    text-align: left;
}

/* 列对齐：md-ta-* 来自服务端（bleach 不放行 style，只能转成 class），
   align 属性来自前端 marked 的输出 */
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td):is(.md-ta-l, [align="left"]) {
    text-align: left;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td):is(.md-ta-c, [align="center"]) {
    text-align: center;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td):is(.md-ta-r, [align="right"]) {
    text-align: right;
}

/* ── 单元格里的 Markdown ────────────────────────────────────────────────
   正文级别的样式（大图、代码块外框、引用块背景……）落到单元格里会把表格挤炸，
   这里逐个收敛成行内尺度。 */
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) p {
    margin: 0 0 0.4em;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) :is(ul, ol) {
    margin: 0.2em 0;
    padding-left: 1.25em;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) :is(h1, h2, h3, h4, h5, h6) {
    margin: 0;
    font-family: inherit;
    font-size: 1em;
    font-weight: 600;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) > *:last-child {
    margin-bottom: 0;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) img {
    display: inline-block;
    max-width: 12em;
    max-height: 4.5em;
    margin: 0;
    border-radius: var(--radius-s);
    box-shadow: none;
    vertical-align: middle;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) img:hover {
    transform: none;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) code {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: 0.92em;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) :is(pre, .codehilite) {
    margin: 0.3em 0;
    padding: 0.5em 0.7em;
    max-width: 100%;
    overflow-x: auto;
    border-radius: var(--radius-s);
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) blockquote {
    margin: 0.3em 0;
    padding: 0.1em 0.7em;
    background: transparent;
    border-radius: 0;
    font-style: normal;
}

/* ── 行内语义标签 ─────────────────────────────────────────────────────── */
/* ~~删除线~~：服务端 StrikethroughExtension → <del>，前端 marked → <del> */
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(del, s) {
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
    text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
    opacity: 0.62;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) ins {
    text-decoration: underline;
    text-decoration-style: dotted;
    text-underline-offset: 3px;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) mark {
    padding: 0.05em 0.3em;
    border-radius: 4px;
    background: color-mix(in srgb, var(--brand) 22%, transparent);
    color: inherit;
}
:is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) kbd {
    padding: 0.15em 0.45em;
    border: 1px solid var(--border-medium);
    border-bottom-width: 2px;
    border-radius: 5px;
    background: var(--bg-subtle);
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: 0.85em;
    line-height: 1;
}

@media (max-width: 640px) {
    :is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) table {
        font-size: 0.85em;
    }
    :is(.md-table, .blog-content, .comment-body, .ai-msg-bubble, .oi-md) :is(th, td) {
        padding: 0.55em 0.75em;
        min-width: 4.5em;
    }
}

/* ============================================================
   53.  Game Center · Tank 置顶卡片
        坦克走独立路由、不在 games 表里，所以列表页给它一张单独的
        置顶卡。配色刻意沿用游戏本体的战场深色（#06080c 系），
        深浅两个模式下都保持深色 —— 它在列表里就是要显得"不一样"。
   ============================================================ */
.tank-feature {
    display: grid;
    grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
    gap: var(--space-5);
    align-items: center;
    padding: var(--space-5);
    border-radius: var(--radius-l);
    border: 1px solid rgba(122, 36, 52, .45);
    background:
        radial-gradient(120% 140% at 6% 0%, rgba(60, 120, 200, .20) 0%, transparent 56%),
        radial-gradient(90% 120% at 100% 100%, rgba(211, 58, 82, .18) 0%, transparent 58%),
        linear-gradient(150deg, #0c111a 0%, #06080c 100%);
    color: #cfe3ff;
    text-decoration: none;
    overflow: hidden;
    transition: border-color var(--dur-base) ease;
}
.tank-feature:hover,
.tank-feature:focus-visible {
    border-color: rgba(211, 58, 82, .68);
    color: #cfe3ff;
    text-decoration: none;
}

/* 战术图：迷宫墙 + 网格底 + 雷达扫掠 + 双方光点。纯 CSS，不引入新素材。 */
.tank-feature-art {
    position: relative;
    display: block;
    aspect-ratio: 1000 / 680;
    border-radius: var(--radius-m);
    border: 1px solid rgba(90, 150, 220, .22);
    background:
        linear-gradient(rgba(96, 156, 226, .34) 0 0) 16% 26% / 28% 4px no-repeat,
        linear-gradient(rgba(96, 156, 226, .34) 0 0) 64% 20% / 4px 36% no-repeat,
        linear-gradient(rgba(96, 156, 226, .34) 0 0) 36% 74% / 32% 4px no-repeat,
        linear-gradient(rgba(96, 156, 226, .34) 0 0) 13% 58% / 4px 26% no-repeat,
        linear-gradient(rgba(96, 156, 226, .34) 0 0) 86% 62% / 4px 24% no-repeat,
        repeating-linear-gradient(0deg,  rgba(90, 150, 220, .11) 0 1px, transparent 1px 30px),
        repeating-linear-gradient(90deg, rgba(90, 150, 220, .11) 0 1px, transparent 1px 30px),
        #0a0e14;
    overflow: hidden;
}
.tank-feature-scan {
    position: absolute;
    inset: 0;
    display: block;
    background: linear-gradient(100deg, transparent 42%, rgba(120, 190, 255, .17) 50%, transparent 58%);
    transform: translateX(-70%);
    animation: tankScan 4.6s var(--ease-out) infinite;
}
.tank-blip {
    position: absolute;
    display: block;
    width: 11px;
    height: 11px;
    border-radius: 2px;
}
.tank-blip.is-player {
    left: 21%;
    top: 61%;
    background: #4fd8a0;
    box-shadow: 0 0 12px #2fbd84;
}
.tank-blip.is-enemy {
    right: 23%;
    top: 24%;
    background: #ff5b6e;
    box-shadow: 0 0 12px #d8394c;
    animation: tankBlip 1.9s ease-in-out infinite;
}
@keyframes tankScan { 0% { transform: translateX(-70%); } 65%, 100% { transform: translateX(70%); } }
@keyframes tankBlip { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.tank-feature-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
    min-width: 0;
}
.tank-feature-kicker {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: #ff9aa8;
}
.tank-feature-title {
    font-family: var(--font-mono);
    font-size: clamp(19px, 2.4vw, 27px);
    font-weight: 700;
    letter-spacing: .13em;
    line-height: 1.25;
    color: #eaf3ff;
    text-shadow: 0 0 24px rgba(90, 160, 255, .45);
}
.tank-feature-title b {
    color: #ff5b6e;
    font-weight: 700;
    text-shadow: 0 0 24px rgba(255, 60, 90, .5);
}
.tank-feature-desc {
    font-size: 13.5px;
    line-height: 1.8;
    color: rgba(207, 227, 255, .66);
    max-width: 58ch;
}
.tank-feature-bounty {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 7px 14px;
    border-radius: 999px;
    border: 1px solid rgba(255, 120, 140, .32);
    background: rgba(40, 10, 18, .5);
    font-size: 12.5px;
    color: rgba(255, 214, 220, .85);
}
.tank-feature-bounty b { color: #ffb3be; }
.tank-feature-bounty .tank-diff { text-transform: uppercase; letter-spacing: .06em; }
.tank-feature-bounty .bi { color: #ffb3be; }

/* CTA 用卡片自己的深色系画一个 hairline 胶囊，
   不再借站点的 .btn-primary —— 那个是亮底配色，落在战场底上会打架。 */
.tank-feature-cta {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    align-self: flex-start;
    margin-top: var(--space-2);
    height: 40px;
    padding: 0 22px;
    border-radius: 999px;
    border: 1px solid rgba(255, 120, 140, .45);
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #ffd6dc;
    transition: border-color var(--dur-base) ease, background var(--dur-base) ease;
}
.tank-feature-cta i { transition: transform var(--dur-base) var(--ease-apple); }
.tank-feature:hover .tank-feature-cta {
    border-color: #ff5b6e;
    background: rgba(255, 60, 90, .14);
}
.tank-feature:hover .tank-feature-cta i { transform: translateX(4px); }

@media (max-width: 768px) {
    .tank-feature {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-4);
        padding: var(--space-4);
    }
    .tank-feature-art { aspect-ratio: 16 / 6; }
}

@media (prefers-reduced-motion: reduce) {
    .tank-feature,
    .tank-feature-cta,
    .tank-feature-cta i { transition: none; }
}

/* ============================================================
   54.  Editorial shell —— 全站通用的编辑式构图层

        landing 和 /blog 确立的那套语言在这里被抽成不带页面前缀的
        通用类，供其余页面复用。原本写在 §31（.list-*）和
        landing.html 行内 <style>（.lp-head / .lp-band / .lp-matrix）
        里的三份实现已经合并进来，那两处只保留各自独有的件。

        规则：
        · 分隔只用 hairline（--rule / --rule-strong），不用卡片边框 + 阴影
        · 唯一的颜色重音是 --brand，其余全交给灰阶
        · 展示级标题走展宽 Archivo（--font-editorial），
          编号 / 日期 / 状态 / 路径走 IBM Plex Mono（--font-data）
        · 数字一律 tabular-nums，换值时不跳动

        本节只吃既有 token，四套主题与明暗两模自动跟随，
        因此没有任何 [data-mode="dark"] 分支。
   ============================================================ */

/* ── 54a. 页头 ──────────────────────────────────────────────
   mono 路径标签（后面拖一条 hairline 到栏宽尽头）→ 超大展宽标题 →
   一句中文说明 → 一条 hairline 收底。右侧 auto 列放操作区；
   只有一个子元素时该列宽度为 0，不需要额外的修饰类。
   ────────────────────────────────────────────────────────── */
.page-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--space-5);
    padding: clamp(32px, 5.5vw, 76px) 0 clamp(22px, 3vw, 34px);
    border-bottom: 1px solid var(--rule);
}
.page-head-copy { min-width: 0; }

.page-eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: 0 0 clamp(16px, 2.4vw, 26px);
    font-family: var(--font-data);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.page-eyebrow::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--rule);
}

.page-title {
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 118%;
    font-size: clamp(36px, 6.2vw, 78px);
    line-height: 0.94;
    letter-spacing: -0.035em;
    color: var(--text-primary);
    margin: 0;
}
/* /blog 与 /tag 是全站的字墙起点，标题比其余二级页再大一档 */
.page-title--display { font-size: clamp(42px, 8vw, 100px); line-height: 0.92; }

.page-subtitle {
    margin: clamp(14px, 2vw, 22px) 0 0;
    max-width: 46ch;
    font-size: clamp(14px, 1.3vw, 16px);
    line-height: 1.75;
    color: var(--text-secondary);
}
.page-subtitle strong { color: var(--text-primary); font-weight: 600; }
.page-subtitle-clear {
    margin-left: var(--space-2);
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--brand);
    text-decoration: none;
    white-space: nowrap;
}
.page-subtitle-clear:hover { text-decoration: underline; }

.page-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

/* 页内分区：相邻两节之间只留一次上边距 */
.page-section { padding-block: clamp(40px, 6vw, 88px) 0; }
.page-section:last-child { padding-bottom: clamp(48px, 7vw, 96px); }

/* 说明型页面（关于 / 联系 / 反馈 …）：栏宽比列表页窄一档，
   一行不超过阅读舒适区，但页头仍然是满栏的。 */
.doc-page #app-main.container { max-width: 1080px; }


/* ── 54b. 分区表头 ─────────────────────────────────────────
   内页不再放展示级大标题：一个 mono 标签配一句中文说明，
   展示级字号全留给页头，一页因此只有一个重音。
   第三列是可选的操作区，缺席时宽度为 0。
   ────────────────────────────────────────────────────────── */
.rule-head {
    display: grid;
    grid-template-columns: clamp(110px, 14vw, 180px) minmax(0, 1fr) auto;
    align-items: baseline;
    gap: clamp(12px, 2vw, 32px);
    padding-bottom: clamp(16px, 2.2vw, 26px);
    margin-bottom: clamp(20px, 3vw, 38px);
    border-bottom: 1px solid var(--rule-strong);
}
.rule-head-label {
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.rule-head-note {
    margin: 0;
    max-width: 52ch;
    font-size: clamp(13.5px, 1.2vw, 15.5px);
    line-height: 1.75;
    color: var(--text-secondary);
}
.rule-head-actions {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: var(--space-3);
}


/* ── 54c. 遥测条 ───────────────────────────────────────────
   一排数字，格与格之间用竖 hairline 分开，首尾两格贴齐栏宽。
   列数由 --stat-cols 决定（默认 4）。
   ────────────────────────────────────────────────────────── */
.stat-band {
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}
.stat-band-grid {
    display: grid;
    grid-template-columns: repeat(var(--stat-cols, 4), minmax(0, 1fr));
}
.stat-cell {
    padding: clamp(20px, 2.6vw, 38px) clamp(12px, 2vw, 28px);
    border-left: 1px solid var(--rule);
    min-width: 0;
}
.stat-cell:first-child { border-left: 0; padding-left: 0; }
.stat-cell:last-child { padding-right: 0; }
.stat-k {
    display: block;
    margin-bottom: clamp(8px, 1.2vw, 14px);
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.stat-v {
    display: block;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 116%;
    font-size: clamp(26px, 3.8vw, 54px);
    line-height: 1;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}
.stat-v small { font-size: 0.42em; letter-spacing: 0; color: var(--text-tertiary); }
.stat-sub {
    display: block;
    margin-top: var(--space-2);
    font-family: var(--font-data);
    font-size: 11px;
    color: var(--text-tertiary);
}


/* ── 54d. 模块矩阵 ─────────────────────────────────────────
   1px 的网格间隙由容器底色透出来，比给每个格子写边框更准，
   交界处也不会叠成 2px。两种用法：
   · .matrix           —— 12 栏定宽，格子用 .matrix-cell--N 占栏
   · .matrix--auto     —— 按 --matrix-min 自动折行，格子不写占栏
   ────────────────────────────────────────────────────────── */
.matrix {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    overflow: hidden;
}
.matrix--auto {
    grid-template-columns: repeat(auto-fit, minmax(min(var(--matrix-min, 260px), 100%), 1fr));
}

.matrix-cell {
    display: flex;
    flex-direction: column;
    min-height: var(--matrix-h, clamp(150px, 17vw, 206px));
    padding: clamp(18px, 2.2vw, 30px);
    background: var(--matrix-bg, var(--bg-body));
    color: inherit;
    text-decoration: none;
    transition: background var(--dur-base) ease;
}
.matrix-cell--2  { grid-column: span 2; }
.matrix-cell--3  { grid-column: span 3; }
.matrix-cell--4  { grid-column: span 4; }
.matrix-cell--6  { grid-column: span 6; }
.matrix-cell--12 { grid-column: span 12; }

a.matrix-cell:hover { background: color-mix(in srgb, var(--brand) 7%, var(--matrix-bg, var(--bg-body))); }
a.matrix-cell:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
}

.matrix-path {
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.12em;
    color: var(--text-tertiary);
    overflow-wrap: anywhere;
}
.matrix-name {
    margin: clamp(10px, 1.4vw, 16px) 0 0;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 112%;
    font-size: clamp(20px, 2.1vw, 29px);
    line-height: 1.08;
    letter-spacing: -0.03em;
    color: var(--text-primary);
    transition: color var(--dur-base) ease;
}
a.matrix-cell:hover .matrix-name { color: var(--brand); }
.matrix-desc {
    margin: 8px 0 0;
    max-width: 44ch;
    font-size: 13.5px;
    line-height: 1.7;
    color: var(--text-secondary);
}
.matrix-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: clamp(14px, 2vw, 22px);
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.matrix-foot i {
    font-size: 13px;
    transition: transform var(--dur-base) var(--ease-apple), color var(--dur-base) ease;
}
a.matrix-cell:hover .matrix-foot i { transform: translateX(5px); color: var(--brand); }

/* 带封面的格子（游戏 / 商品）：图钉在正文之上，出血到格子边缘 */
.matrix-media {
    margin: calc(-1 * clamp(18px, 2.2vw, 30px)) calc(-1 * clamp(18px, 2.2vw, 30px)) clamp(16px, 2vw, 22px);
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--bg-subtle);
}
.matrix-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .8s var(--ease-apple);
}
a.matrix-cell:hover .matrix-media img { transform: scale(1.035); }
.matrix-media-fallback {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    font-size: 40px;
    color: color-mix(in srgb, var(--text-primary) 14%, transparent);
}


/* ── 54e. 数据行 ───────────────────────────────────────────
   §31b .entry-row 的通用版：那一份是为「日期 + 文章」定死的四栏，
   这一份用 flex，子元素个数随页面而变（论坛帖 / 单词 / 私信 / 日志）。
   悬停时底线由左向右扫成品牌色——只有可点的行（<a>）才有这个反馈。
   ────────────────────────────────────────────────────────── */
.data-rows { display: block; }
.data-rows--ruled { border-top: 1px solid var(--rule-strong); }

.data-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: clamp(12px, 2vw, 24px);
    padding: clamp(16px, 2vw, 24px) 0;
    border-bottom: 1px solid var(--rule);
    color: inherit;
    text-decoration: none;
}
a.data-row::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--brand);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform .5s var(--ease-apple);
}
a.data-row:hover::after,
a.data-row:focus-visible::after { transform: scaleX(1); }
a.data-row:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 4px;
    border-radius: var(--radius-xs);
}

.data-row-lead {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--rule);
    font-family: var(--font-data);
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    overflow: hidden;
}
.data-row-lead img { width: 100%; height: 100%; object-fit: cover; }
/* 序号列：给排行 / 楼层用，比头像窄 */
.data-row-index {
    flex: 0 0 auto;
    align-self: flex-start;
    min-width: 34px;
    padding-top: 2px;
    font-family: var(--font-data);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
}

.data-row-main { flex: 1 1 auto; min-width: 0; }
.data-row-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0;
    font-family: var(--font-editorial);
    font-weight: 650;
    font-stretch: 106%;
    font-size: clamp(16px, 1.5vw, 21px);
    line-height: 1.25;
    letter-spacing: -0.018em;
    color: var(--text-primary);
    transition: color var(--dur-base) ease;
}
.data-row-title > span { min-width: 0; overflow-wrap: anywhere; }
a.data-row:hover .data-row-title { color: var(--brand); }
.data-row-sub {
    margin: 7px 0 0;
    max-width: 68ch;
    font-size: 13.5px;
    line-height: 1.65;
    color: var(--text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.data-row-byline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: 7px;
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--text-tertiary);
}
.data-row-byline .sep { opacity: .45; }

.data-row-meta {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-data);
    font-size: 11px;
    letter-spacing: 0.06em;
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
    white-space: nowrap;
}

.data-row-go {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--rule);
    color: var(--text-tertiary);
    font-size: 13px;
    transition: color var(--dur-base) ease,
                border-color var(--dur-base) ease,
                transform var(--dur-base) var(--ease-apple);
}
a.data-row:hover .data-row-go {
    color: var(--brand);
    border-color: var(--brand);
    transform: translateX(4px);
}


/* ── 54f. 面板 ─────────────────────────────────────────────
   取代 .card / .widget-card / .settings-card：只有一条 hairline 外框，
   没有阴影和填充色，因此嵌在任何底色上都成立。
   ────────────────────────────────────────────────────────── */
.sheet {
    border: 1px solid var(--rule);
    border-radius: var(--radius-l);
    background: transparent;
    padding: clamp(20px, 2.6vw, 32px);
}
.sheet--flush { padding: 0; overflow: hidden; }
.sheet-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-4);
    border-bottom: 1px solid var(--rule);
}
.sheet--flush > .sheet-head {
    padding: clamp(16px, 2vw, 22px) clamp(18px, 2.4vw, 28px);
    margin-bottom: 0;
}
.sheet-title {
    margin: 0;
    font-family: var(--font-editorial);
    font-weight: 700;
    font-stretch: 108%;
    font-size: clamp(17px, 1.6vw, 22px);
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}
.sheet-label {
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.sheet-body { min-width: 0; }
.sheet--flush > .sheet-body { padding: clamp(18px, 2.4vw, 28px); }
.sheet-foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding-top: var(--space-4);
    margin-top: var(--space-4);
    border-top: 1px solid var(--rule);
}
.sheet--flush > .sheet-foot {
    padding: clamp(16px, 2vw, 22px) clamp(18px, 2.4vw, 28px);
    margin-top: 0;
}


/* ── 54g. 数据表 ───────────────────────────────────────────
   §21 原 .apple-table 的编辑式版本：mono 大写表头、hairline 行、
   表头不再刷 --bg-subtle 的底。首尾列贴齐栏宽。
   ────────────────────────────────────────────────────────── */
.data-table-wrap {
    overflow-x: auto;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}
.data-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
}
.data-table th {
    padding: var(--space-3) var(--space-4);
    background: transparent;
    border-bottom: 1px solid var(--rule-strong);
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    text-align: left;
    white-space: nowrap;
}
.data-table td {
    padding: var(--space-4);
    border-bottom: 1px solid var(--rule);
    font-size: 14px;
    line-height: 1.6;
    color: var(--text-primary);
    vertical-align: middle;
}
.data-table th:first-child,
.data-table td:first-child { padding-left: 0; }
.data-table th:last-child,
.data-table td:last-child { padding-right: 0; }
/* 上面的「首尾列贴齐栏宽」只对裸放在页面栏宽里的表成立。
   嵌进带 hairline 外框的面板（.settings-card / .sheet / .ai-data-card）时，
   首尾列得留出和面板头同一档的内边距，否则单元格直接贴着圆角边框。 */
.settings-card .data-table th:first-child,
.settings-card .data-table td:first-child,
.sheet .data-table th:first-child,
.sheet .data-table td:first-child,
.ai-data-card .data-table th:first-child,
.ai-data-card .data-table td:first-child { padding-left: clamp(18px, 2.4vw, 28px); }
.settings-card .data-table th:last-child,
.settings-card .data-table td:last-child,
.sheet .data-table th:last-child,
.sheet .data-table td:last-child,
.ai-data-card .data-table th:last-child,
.ai-data-card .data-table td:last-child { padding-right: clamp(18px, 2.4vw, 28px); }
.data-table tbody tr { transition: background var(--dur-fast) ease; }
.data-table tbody tr:hover { background: color-mix(in srgb, var(--text-primary) 3.5%, transparent); }
.data-table tbody tr:last-child td { border-bottom: 0; }
/* 数字列：等宽 + 右对齐，扫一眼就能比大小 */
.data-table .num {
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    text-align: right;
}


/* ── 54h. 表单 ─────────────────────────────────────────────
   mono 大写标签 + 只有下边框的输入框。.field 内部同时命中
   Bootstrap 的 .form-control / .form-select，这样 WTForms
   渲染出来的控件不用改一行 Python 就能套上新外观。
   ────────────────────────────────────────────────────────── */
.field { display: block; margin-bottom: clamp(20px, 2.4vw, 28px); }
.field-label {
    display: block;
    margin-bottom: var(--space-2);
    font-family: var(--font-data);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}
.field-input,
.field .form-control,
.field .form-select {
    display: block;
    width: 100%;
    padding: 10px 2px;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule-strong);
    border-radius: 0;
    box-shadow: none;
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.5;
    transition: border-color var(--dur-base) ease;
}
.field-input::placeholder,
.field .form-control::placeholder { color: var(--text-tertiary); }
.field-input:focus,
.field .form-control:focus,
.field .form-select:focus {
    outline: none;
    background: transparent;
    box-shadow: none;
    border-bottom-color: var(--brand);
}
.field textarea.field-input,
.field textarea.form-control {
    min-height: 132px;
    resize: vertical;
}
.field-hint,
.field-error {
    display: block;
    margin-top: var(--space-2);
    font-size: 12.5px;
    line-height: 1.6;
}
.field-hint { color: var(--text-tertiary); }
.field-error { color: var(--red, #ff3b30); }

/* 两栏表单行；窄屏自动落成一栏 */
.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: 0 clamp(20px, 3vw, 40px);
}

/* 表单本体的舒适栏宽 + 按钮行。--form-max 可以按页覆盖。 */
.form-body { max-width: var(--form-max, 620px); }
.form-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-5);
}
.form-actions--end { justify-content: flex-end; }


/* ── 54i. 标记 ─────────────────────────────────────────────
   mono 小胶囊，承载状态 / 角色 / 计数这类补充信息。
   ────────────────────────────────────────────────────────── */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    font-family: var(--font-data);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.5;
    color: var(--text-tertiary);
    text-decoration: none;
    white-space: nowrap;
}
.pill--brand { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 42%, transparent); }
.pill--solid { background: var(--text-primary); border-color: var(--text-primary); color: var(--bg-body); }
.pill--good  { color: var(--green,  #34c759); border-color: color-mix(in srgb, var(--green,  #34c759) 42%, transparent); }
.pill--warn  { color: var(--orange, #ff9500); border-color: color-mix(in srgb, var(--orange, #ff9500) 42%, transparent); }
.pill--bad   { color: var(--red,    #ff3b30); border-color: color-mix(in srgb, var(--red,    #ff3b30) 42%, transparent); }


/* ── 54j. 文字链 ───────────────────────────────────────────
   「全部文章 →」这一类的收尾链接。
   ────────────────────────────────────────────────────────── */
.more-link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-data);
    font-size: 11.5px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-primary);
    text-decoration: none;
}
.more-link i { transition: transform var(--dur-base) var(--ease-apple); }
.more-link:hover { color: var(--brand); }
.more-link:hover i { transform: translateX(5px); }


/* ── 54k. 窄屏 ─────────────────────────────────────────── */
@media (max-width: 1024px) {
    .matrix { grid-template-columns: repeat(6, minmax(0, 1fr)); }
    .matrix-cell--12 { grid-column: span 6; }
    .matrix-cell--6  { grid-column: span 6; }
    .matrix-cell--4  { grid-column: span 3; }
    .matrix-cell--3  { grid-column: span 3; }
    .matrix-cell--2  { grid-column: span 2; }
}
@media (max-width: 860px) {
    .stat-band-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .stat-cell { border-left: 1px solid var(--rule); }
    .stat-cell:nth-child(odd)  { border-left: 0; padding-left: 0; }
    .stat-cell:nth-child(even) { padding-right: 0; }
    .stat-cell:nth-child(n + 3) { border-top: 1px solid var(--rule); }
    .rule-head {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-3);
    }
    .rule-head-actions { justify-self: start; }
}
@media (max-width: 768px) {
    .page-head {
        grid-template-columns: minmax(0, 1fr);
        padding-top: clamp(26px, 6vw, 44px);
    }
    /* 行内的元信息掉到第二排，标题和箭头留在第一排 */
    .data-row { flex-wrap: wrap; }
    .data-row-main { flex: 1 1 100%; order: 1; }
    .data-row-lead,
    .data-row-index { order: 0; }
    .data-row-go { order: 2; margin-left: auto; }
    .data-row-meta {
        order: 3;
        flex: 1 1 100%;
        flex-wrap: wrap;
        white-space: normal;
    }
    .data-row-sub { -webkit-line-clamp: 1; line-clamp: 1; }
}
@media (max-width: 640px) {
    .matrix { grid-template-columns: minmax(0, 1fr); }
    .matrix-cell--2,
    .matrix-cell--3,
    .matrix-cell--4,
    .matrix-cell--6,
    .matrix-cell--12 { grid-column: span 1; }
}

@media (prefers-reduced-motion: reduce) {
    a.data-row::after,
    .data-row-go,
    .matrix-cell,
    .matrix-media img,
    .matrix-foot i,
    .more-link i { transition: none; }
}


/* ============================================================
   55.  Vocab（单词本）
        列表走 §54 的 .data-table，这里只留这一页自己的件：
        筛选条、词条排版、复习阶段进度。
   ============================================================ */
.vocab-filter {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    align-items: end;
    gap: 0 clamp(20px, 3vw, 36px);
}
.vocab-filter .field { margin-bottom: var(--space-4); }

.vocab-filter-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    padding-bottom: 14px;
    margin-bottom: var(--space-4);
}
.vocab-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: 13px;
    color: var(--text-secondary);
    cursor: pointer;
    white-space: nowrap;
}
.vocab-toggle .form-check-input { margin: 0; flex-shrink: 0; }

.vocab-filter-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding-bottom: 10px;
    margin-bottom: var(--space-4);
}

.vocab-term {
    font-family: var(--font-editorial);
    font-weight: 650;
    font-stretch: 106%;
    font-size: 17px;
    line-height: 1.25;
    letter-spacing: -0.018em;
    color: var(--text-primary);
}
.vocab-sub {
    margin-top: 4px;
    max-width: 34ch;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--text-secondary);
}

/* 复习阶段：一条细进度轨 + mono 编号，不用 Bootstrap 的 .progress */
.vocab-stage {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-family: var(--font-data);
    font-size: 11px;
    color: var(--text-tertiary);
    white-space: nowrap;
}
.vocab-stage-bar {
    display: inline-block;
    width: 56px;
    height: 3px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--text-primary) 12%, transparent);
    overflow: hidden;
}
.vocab-stage-bar i {
    display: block;
    height: 100%;
    background: var(--brand);
    transition: width var(--dur-slow) var(--ease-out);
}

.vocab-menu-btn {
    padding: 4px 6px;
    border: 0;
    background: none;
    color: var(--text-tertiary);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: color var(--dur-fast) ease;
}
.vocab-menu-btn:hover { color: var(--text-primary); }

/* 翻卡（vocab/review）：卡面去掉阴影，只留 hairline */
.card-face {
    background: transparent;
    border: 1px solid var(--rule);
    box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
    .vocab-stage-bar i { transition: none; }
}

/* 词条表单：输入框和「AI 填充」并排，AI 设置折在下面一格 hairline 里 */
.vocab-term-row {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
}
.vocab-term-row .field-input { flex: 1; min-width: 0; }

.vocab-ai-box {
    margin-top: var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--rule);
    border-radius: var(--radius-m);
}
.vocab-ai-box .sheet-label { display: block; margin-bottom: var(--space-3); }
.vocab-ai-box .field-hint { margin-top: var(--space-3); }

/* 批量添加：右栏进度面板 */
.batch-progress-panel {
    padding: var(--space-4);
    border: 1px solid var(--rule);
    border-radius: var(--radius-m);
    min-height: 400px;
}
.batch-progress-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.batch-progress-count {
    font-family: var(--font-data);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
}
.batch-progress-bar { display: block; width: 100%; margin-bottom: var(--space-4); }

.batch-result-list {
    display: flex;
    flex-direction: column;
    max-height: 500px;
    overflow-y: auto;
}
.batch-result {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--rule);
}
.batch-result-main { flex: 1; min-width: 0; }
.batch-result-term {
    font-family: var(--font-editorial);
    font-weight: 650;
    font-size: 15px;
    letter-spacing: -0.015em;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.batch-result-msg {
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.55;
    color: var(--text-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 复习页：单栏居中，宽度按翻卡的舒适阅读区来 */
.review-shell { max-width: 780px; margin: 0 auto; }
