@charset "UTF-8";
/* ============================================================================
   NovaMall Design System  ·  nm-design.css
   ----------------------------------------------------------------------------
   Layer 1  Material  —— 材质打底：毛玻璃 / 柔阴影 / 渐变网格 / 颗粒纹理
   Layer 4  Component —— 标准化组件：按钮 / 表单 / 卡片 / 表格 / 徽章 / 弹层 …
   设计基准：Apple HIG + Material 3 elevation + 8pt grid
   约束：只做视觉层，不改变任何 DOM 结构与业务逻辑
   ========================================================================== */

/* ==========================================================================
   0. DESIGN TOKENS
   ========================================================================== */
:root {
    /* ---- 字体 ---- */
    --nm-font: "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont,
               "Helvetica Neue", "Segoe UI Variable", "Segoe UI",
               "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
    --nm-font-mono: "SF Mono", ui-monospace, "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;

    /* ---- 字号阶梯（1.25 modular scale，对齐 iOS Dynamic Type）---- */
    --nm-fs-11: 11px;  --nm-fs-12: 12px;  --nm-fs-13: 13px;
    --nm-fs-15: 15px;  --nm-fs-17: 17px;  --nm-fs-20: 20px;
    --nm-fs-24: 24px;  --nm-fs-28: 28px;  --nm-fs-34: 34px;
    --nm-fs-44: 44px;

    --nm-lh-tight: 1.2;
    --nm-lh-snug: 1.35;
    --nm-lh-base: 1.55;

    --nm-track-tight: -0.022em;
    --nm-track-normal: -0.011em;
    --nm-track-wide: 0.02em;

    /* ---- 间距：8pt 网格 ---- */
    --nm-s1: 4px;   --nm-s2: 8px;   --nm-s3: 12px;  --nm-s4: 16px;
    --nm-s5: 20px;  --nm-s6: 24px;  --nm-s7: 32px;  --nm-s8: 40px;
    --nm-s9: 48px;  --nm-s10: 64px; --nm-s11: 80px;

    /* ---- 圆角：连续曲率（squircle 近似）---- */
    --nm-r-xs: 6px;   --nm-r-sm: 9px;   --nm-r-md: 12px;
    --nm-r-lg: 16px;  --nm-r-xl: 22px;  --nm-r-2xl: 28px;
    --nm-r-pill: 999px;

    /* ---- 中性色（iOS System Gray 阶梯）---- */
    --nm-bg: #f5f5f7;                 /* 页面底 */
    --nm-bg-2: #ffffff;               /* 卡片面 */
    --nm-bg-3: #fafafc;               /* 次级面 */
    --nm-fill: rgba(120, 120, 128, 0.085);
    --nm-fill-2: rgba(120, 120, 128, 0.13);
    --nm-fill-3: rgba(120, 120, 128, 0.19);
    --nm-sep: rgba(60, 60, 67, 0.09);         /* 细分割线（hairline）*/
    --nm-sep-opaque: rgba(60, 60, 67, 0.18);
    --nm-label: #1d1d1f;              /* 主文本 */
    --nm-label-2: #6e6e73;            /* 次要文本 */
    --nm-label-3: #8e8e93;            /* 三级文本 */

    /* ---- 系统语义色 ---- */
    --nm-blue: #0071e3;
    --nm-indigo: #5856d6;
    --nm-teal: #30b0c7;
    --nm-green: #34c759;
    --nm-mint: #00c7be;
    --nm-yellow: #ffcc00;
    --nm-orange: #ff9500;
    --nm-red: #ff3b30;
    --nm-pink: #ff2d55;
    --nm-purple: #af52de;
    --nm-gray: #8e8e93;

    /* 品牌交互色（运行时由主题变量覆盖，缺省 iOS 蓝）*/
    --nm-tint: var(--nm-blue);
    --nm-tint-strong: color-mix(in srgb, var(--nm-tint) 88%, #000);
    --nm-tint-soft: color-mix(in srgb, var(--nm-tint) 12%, transparent);
    --nm-tint-softer: color-mix(in srgb, var(--nm-tint) 7%, transparent);

    /* ---- 材质：毛玻璃 ---- */
    --nm-blur: saturate(180%) blur(22px);
    --nm-blur-sm: saturate(160%) blur(12px);
    --nm-blur-lg: saturate(190%) blur(40px);
    --nm-mat-light: rgba(255, 255, 255, 0.72);
    --nm-mat-light-strong: rgba(255, 255, 255, 0.86);
    --nm-mat-dark: rgba(28, 28, 30, 0.72);
    --nm-mat-overlay: rgba(250, 250, 252, 0.82);

    /* ---- 阴影：多级 elevation（柔和双层，避免脏灰）---- */
    --nm-shadow-1: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.03);
    --nm-shadow-2: 0 2px 4px rgba(16, 24, 40, 0.04), 0 8px 20px -6px rgba(16, 24, 40, 0.10);
    --nm-shadow-3: 0 4px 8px rgba(16, 24, 40, 0.05), 0 16px 40px -12px rgba(16, 24, 40, 0.16);
    --nm-shadow-4: 0 8px 16px rgba(16, 24, 40, 0.06), 0 32px 64px -16px rgba(16, 24, 40, 0.22);
    --nm-shadow-tint: 0 4px 14px -4px color-mix(in srgb, var(--nm-tint) 40%, transparent);
    --nm-ring: 0 0 0 4px color-mix(in srgb, var(--nm-tint) 22%, transparent);

    /* ---- 动效 ---- */
    --nm-ease-out: cubic-bezier(0.22, 1, 0.36, 1);       /* decelerate 出场 */
    --nm-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);      /* 标准 */
    --nm-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* 弹性 */
    --nm-dur-1: 120ms;
    --nm-dur-2: 200ms;
    --nm-dur-3: 320ms;
    --nm-dur-4: 480ms;

    /* ---- 层级 ---- */
    --nm-z-header: 90;
    --nm-z-drawer: 800;
    --nm-z-modal: 900;
    --nm-z-toast: 950;
    --nm-z-grain: 9999;

    /* ---- 布局 ---- */
    --nm-container: 1400px;
    --nm-safe-b: env(safe-area-inset-bottom, 0px);
    --nm-safe-t: env(safe-area-inset-top, 0px);

    color-scheme: light;
}

/* ---- 暗色模式 ---- */
[data-nm-theme="dark"] {
    --nm-bg: #000000;
    --nm-bg-2: #1c1c1e;
    --nm-bg-3: #2c2c2e;
    --nm-fill: rgba(120, 120, 128, 0.20);
    --nm-fill-2: rgba(120, 120, 128, 0.28);
    --nm-fill-3: rgba(120, 120, 128, 0.36);
    --nm-sep: rgba(255, 255, 255, 0.10);
    --nm-sep-opaque: rgba(255, 255, 255, 0.20);
    --nm-label: #f5f5f7;
    --nm-label-2: #a1a1a6;
    --nm-label-3: #8e8e93;
    --nm-mat-light: rgba(28, 28, 30, 0.72);
    --nm-mat-light-strong: rgba(28, 28, 30, 0.88);
    --nm-mat-overlay: rgba(18, 18, 20, 0.84);
    --nm-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5);
    --nm-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.5), 0 12px 28px -8px rgba(0, 0, 0, 0.6);
    --nm-shadow-3: 0 8px 32px -8px rgba(0, 0, 0, 0.7);
    --nm-shadow-4: 0 24px 64px -16px rgba(0, 0, 0, 0.8);
    color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
    [data-nm-theme="auto"] {
        --nm-bg: #000000;
        --nm-bg-2: #1c1c1e;
        --nm-bg-3: #2c2c2e;
        --nm-fill: rgba(120, 120, 128, 0.20);
        --nm-fill-2: rgba(120, 120, 128, 0.28);
        --nm-sep: rgba(255, 255, 255, 0.10);
        --nm-sep-opaque: rgba(255, 255, 255, 0.20);
        --nm-label: #f5f5f7;
        --nm-label-2: #a1a1a6;
        --nm-label-3: #8e8e93;
        --nm-mat-light: rgba(28, 28, 30, 0.72);
        --nm-mat-overlay: rgba(18, 18, 20, 0.84);
        color-scheme: dark;
    }
}

/* ==========================================================================
   1. RESET / BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
    font-family: var(--nm-font);
    font-size: var(--nm-fs-15);
    line-height: var(--nm-lb, var(--nm-lh-base));
    letter-spacing: var(--nm-track-normal);
    color: var(--nm-label);
    background: var(--nm-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    font-kerning: normal;
    font-variant-numeric: tabular-nums;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--nm-font);
    letter-spacing: var(--nm-track-tight);
    line-height: var(--nm-lh-tight);
    font-weight: 700;
    color: var(--nm-label);
    margin: 0;
}

a { color: var(--nm-tint); text-decoration: none; }
a:hover { color: var(--nm-tint-strong); }

::selection { background: color-mix(in srgb, var(--nm-tint) 24%, transparent); }

:focus-visible {
    outline: 2px solid var(--nm-tint);
    outline-offset: 2px;
    border-radius: var(--nm-r-xs);
}

/* 统一滚动条 */
* { scrollbar-width: thin; scrollbar-color: var(--nm-fill-3) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--nm-fill-3);
    border: 3px solid transparent;
    background-clip: content-box;
    border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--nm-sep-opaque); background-clip: content-box; }

/* ==========================================================================
   2. LAYER 1 —— 材质打底（Mesh Gradient + Grain + Glass）
   ========================================================================== */

/* 2.1 渐变网格背景：多层 radial-gradient 形成柔光氛围，比纯色底高级 */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -3;
    pointer-events: none;
    background:
        radial-gradient(60% 55% at 12% 0%,   color-mix(in srgb, var(--nm-tint) 9%, transparent) 0%, transparent 60%),
        radial-gradient(50% 45% at 92% 4%,   color-mix(in srgb, var(--nm-indigo) 7%, transparent) 0%, transparent 62%),
        radial-gradient(55% 50% at 78% 92%,  color-mix(in srgb, var(--nm-teal) 6%, transparent) 0%, transparent 65%),
        radial-gradient(45% 40% at 30% 100%, color-mix(in srgb, var(--nm-pink) 4%, transparent) 0%, transparent 60%);
    opacity: 1;
    transition: opacity var(--nm-dur-4) var(--nm-ease-out);
}
[data-nm-theme="dark"] body::before { opacity: 0.55; }

/* 2.2 颗粒纹理：feTurbulence 生成的胶片颗粒，消除数字扁平感 */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: var(--nm-z-grain);
    pointer-events: none;
    opacity: 0.028;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
    background-repeat: repeat;
}
@media (prefers-reduced-motion: no-preference) {
    /* 颗粒极缓慢漂移，产生"活"的质感（性能友好：仅位移背景） */
    body::after { animation: nm-grain-drift 8s steps(6) infinite; }
}
@keyframes nm-grain-drift {
    0%   { transform: translate3d(0, 0, 0); }
    17%  { transform: translate3d(-2%, 1%, 0); }
    33%  { transform: translate3d(1%, -2%, 0); }
    50%  { transform: translate3d(-1%, 2%, 0); }
    67%  { transform: translate3d(2%, 1%, 0); }
    83%  { transform: translate3d(-2%, -1%, 0); }
    100% { transform: translate3d(0, 0, 0); }
}

/* 2.3 Three.js 画布容器（Layer 3 挂载点）*/
.nm-scene {
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    opacity: 0;
    transition: opacity 1200ms var(--nm-ease-out);
}
.nm-scene.is-ready { opacity: 1; }
.nm-scene canvas { display: block; width: 100% !important; height: 100% !important; }

/* 2.4 玻璃材质工具类 */
.nm-glass {
    background: var(--nm-mat-light);
    -webkit-backdrop-filter: var(--nm-blur);
    backdrop-filter: var(--nm-blur);
    border: 0.5px solid var(--nm-sep);
    box-shadow: var(--nm-shadow-2);
}
.nm-glass-strong {
    background: var(--nm-mat-light-strong);
    -webkit-backdrop-filter: var(--nm-blur-lg);
    backdrop-filter: var(--nm-blur-lg);
    border: 0.5px solid var(--nm-sep);
    box-shadow: var(--nm-shadow-3);
}

/* 2.5 描边高光：顶部 1px 内高光，模拟真实玻璃边缘 */
.nm-sheen { position: relative; }
.nm-sheen::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 42%);
    opacity: 0.85;
}
[data-nm-theme="dark"] .nm-sheen::before {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.10) 0%, transparent 42%);
}

/* ==========================================================================
   3. LAYER 2 —— 动效（滚动渐入 / 微交互 / 呼吸感）
   ========================================================================== */

/* 3.1 滚动渐入（由 nm-motion.js 添加 .is-in）
   ★ 修复：不用 scale 缩放，避免区块在动画未完成时与主列错位 */
[data-reveal] {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
    transition:
        opacity 620ms var(--nm-ease-out),
        transform 620ms var(--nm-ease-out);
    will-change: opacity, transform;
}
[data-reveal].is-in { opacity: 1; transform: none; }
[data-reveal="left"]  { transform: translate3d(-22px, 0, 0); }
[data-reveal="right"] { transform: translate3d(22px, 0, 0); }
[data-reveal="zoom"]  { transform: translate3d(0, 22px, 0); }
[data-reveal][data-delay="1"] { transition-delay: 60ms; }
[data-reveal][data-delay="2"] { transition-delay: 120ms; }
[data-reveal][data-delay="3"] { transition-delay: 180ms; }
[data-reveal][data-delay="4"] { transition-delay: 240ms; }
[data-reveal][data-delay="5"] { transition-delay: 300ms; }
[data-reveal][data-delay="6"] { transition-delay: 360ms; }

/* 3.2 通用微交互：可点击元素按下回弹 */
.nm-press { transition: transform var(--nm-dur-1) var(--nm-ease-out); }
.nm-press:active { transform: scale(0.965); }

/* 3.3 浮动呼吸动画（用于装饰元素）*/
@keyframes nm-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-8px); }
}
@keyframes nm-pulse-ring {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--nm-tint) 40%, transparent); }
    70%  { box-shadow: 0 0 0 12px color-mix(in srgb, var(--nm-tint) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--nm-tint) 0%, transparent); }
}
@keyframes nm-shimmer {
    0%   { background-position: -420px 0; }
    100% { background-position: 420px 0; }
}
@keyframes nm-spin { to { transform: rotate(360deg); } }
@keyframes nm-fade-up {
    from { opacity: 0; transform: translate3d(0, 12px, 0); }
    to   { opacity: 1; transform: none; }
}
@keyframes nm-toast-in {
    from { opacity: 0; transform: translate3d(0, -14px, 0) scale(0.96); }
    to   { opacity: 1; transform: none; }
}

/* 3.4 光标跟随光晕（前台 hero 用）*/
.nm-spotlight {
    position: relative;
    isolation: isolate;
}
.nm-spotlight::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: -1;
    background: radial-gradient(
        340px circle at var(--mx, 50%) var(--my, 50%),
        color-mix(in srgb, var(--nm-tint) 14%, transparent),
        transparent 65%
    );
    opacity: 0;
    transition: opacity var(--nm-dur-3) var(--nm-ease-out);
}
.nm-spotlight:hover::after { opacity: 1; }

/* ==========================================================================
   4. LAYER 4 —— 组件系统
   ========================================================================== */

/* ---------- 4.1 按钮 ---------- */
.nm-btn {
    --btn-h: 38px;
    --btn-px: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: var(--btn-h);
    padding: 0 var(--btn-px);
    border: 1px solid transparent;
    border-radius: var(--nm-r-pill);
    font-family: inherit;
    font-size: var(--nm-fs-15);
    font-weight: 590;
    letter-spacing: var(--nm-track-normal);
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    background: var(--nm-fill);
    color: var(--nm-label);
    transition:
        background-color var(--nm-dur-2) var(--nm-ease-out),
        color var(--nm-dur-2) var(--nm-ease-out),
        transform var(--nm-dur-1) var(--nm-ease-out),
        box-shadow var(--nm-dur-2) var(--nm-ease-out),
        border-color var(--nm-dur-2) var(--nm-ease-out);
}
.nm-btn:hover { background: var(--nm-fill-2); }
.nm-btn:active { transform: scale(0.968); }

.nm-btn--primary {
    background: var(--nm-tint);
    color: #fff;
    box-shadow: var(--nm-shadow-tint);
}
.nm-btn--primary:hover {
    background: var(--nm-tint-strong);
    box-shadow: 0 6px 20px -6px color-mix(in srgb, var(--nm-tint) 55%, transparent);
}

.nm-btn--tinted {
    background: var(--nm-tint-soft);
    color: var(--nm-tint);
}
.nm-btn--tinted:hover { background: color-mix(in srgb, var(--nm-tint) 18%, transparent); }

.nm-btn--ghost {
    background: transparent;
    color: var(--nm-label-2);
}
.nm-btn--ghost:hover { background: var(--nm-fill); color: var(--nm-label); }

.nm-btn--outline {
    background: var(--nm-bg-2);
    border-color: var(--nm-sep-opaque);
    color: var(--nm-label);
}
.nm-btn--outline:hover { border-color: var(--nm-tint); color: var(--nm-tint); }

.nm-btn--danger { background: var(--nm-red); color: #fff; }
.nm-btn--danger:hover { background: color-mix(in srgb, var(--nm-red) 88%, #000); }

.nm-btn--sm { --btn-h: 30px; --btn-px: 13px; font-size: var(--nm-fs-13); }
.nm-btn--lg { --btn-h: 48px; --btn-px: 26px; font-size: var(--nm-fs-17); }
.nm-btn--block { width: 100%; }
.nm-btn--icon { --btn-px: 0; width: var(--btn-h); }
.nm-btn[disabled], .nm-btn.is-disabled {
    opacity: 0.42;
    pointer-events: none;
    box-shadow: none;
}
.nm-btn .nm-ic, .nm-btn svg { width: 1.06em; height: 1.06em; flex: none; }
.nm-btn.is-loading { color: transparent !important; position: relative; }
.nm-btn.is-loading::after {
    content: "";
    position: absolute;
    width: 15px; height: 15px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    color: #fff;
    animation: nm-spin 640ms linear infinite;
}

/* ---------- 4.2 表单 ---------- */
.nm-field { display: flex; flex-direction: column; gap: 6px; }
.nm-label {
    font-size: var(--nm-fs-13);
    font-weight: 560;
    color: var(--nm-label-2);
    letter-spacing: 0;
}
.nm-input, .nm-select, .nm-textarea {
    width: 100%;
    min-height: 40px;
    padding: 9px 13px;
    font-family: inherit;
    font-size: var(--nm-fs-15);
    color: var(--nm-label);
    background: var(--nm-bg-2);
    border: 1px solid var(--nm-sep-opaque);
    border-radius: var(--nm-r-md);
    transition:
        border-color var(--nm-dur-2) var(--nm-ease-out),
        box-shadow var(--nm-dur-2) var(--nm-ease-out),
        background-color var(--nm-dur-2) var(--nm-ease-out);
    -webkit-appearance: none;
    appearance: none;
}
.nm-input::placeholder, .nm-textarea::placeholder { color: var(--nm-label-3); }
.nm-input:hover, .nm-select:hover, .nm-textarea:hover { border-color: color-mix(in srgb, var(--nm-label-3) 50%, transparent); }
.nm-input:focus, .nm-select:focus, .nm-textarea:focus {
    outline: none;
    border-color: var(--nm-tint);
    box-shadow: var(--nm-ring);
}
.nm-select {
    padding-right: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    cursor: pointer;
}
.nm-textarea { min-height: 92px; resize: vertical; line-height: var(--nm-lh-base); }
.nm-hint { font-size: var(--nm-fs-12); color: var(--nm-label-3); }

/* 开关 */
.nm-switch {
    -webkit-appearance: none; appearance: none;
    position: relative;
    width: 51px; height: 31px;
    border-radius: 99px;
    background: var(--nm-fill-3);
    cursor: pointer;
    transition: background-color var(--nm-dur-3) var(--nm-ease-out);
    flex: none;
}
.nm-switch::after {
    content: "";
    position: absolute;
    top: 2px; left: 2px;
    width: 27px; height: 27px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), 0 1px 1px rgba(0, 0, 0, 0.16);
    transition: transform var(--nm-dur-3) var(--nm-ease-spring);
}
.nm-switch:checked { background: var(--nm-green); }
.nm-switch:checked::after { transform: translateX(20px); }

/* 复选框 / 单选框 */
.nm-check, .nm-radio {
    -webkit-appearance: none; appearance: none;
    position: relative;
    width: 19px; height: 19px;
    flex: none;
    border: 1.5px solid var(--nm-sep-opaque);
    border-radius: 5.5px;
    background: var(--nm-bg-2);
    cursor: pointer;
    vertical-align: -3px;
    transition: background-color var(--nm-dur-2) var(--nm-ease-out),
                border-color var(--nm-dur-2) var(--nm-ease-out);
}
.nm-radio { border-radius: 50%; }
.nm-check:checked, .nm-radio:checked {
    background: var(--nm-tint);
    border-color: var(--nm-tint);
}
.nm-check:checked::after {
    content: "";
    position: absolute;
    left: 5.5px; top: 2px;
    width: 5px; height: 9.5px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
    border-radius: 1px;
}
.nm-radio:checked::after {
    content: "";
    position: absolute;
    inset: 4px;
    border-radius: 50%;
    background: #fff;
}

/* ---------- 4.3 卡片 ---------- */
.nm-card {
    position: relative;
    background: var(--nm-bg-2);
    border: 0.5px solid var(--nm-sep);
    border-radius: var(--nm-r-lg);
    box-shadow: var(--nm-shadow-1);
    transition:
        box-shadow var(--nm-dur-3) var(--nm-ease-out),
        transform var(--nm-dur-3) var(--nm-ease-out),
        border-color var(--nm-dur-3) var(--nm-ease-out);
}
.nm-card--hover:hover {
    transform: translateY(-3px);
    box-shadow: var(--nm-shadow-3);
    border-color: color-mix(in srgb, var(--nm-tint) 22%, var(--nm-sep));
}
.nm-card--flush { border-radius: var(--nm-r-lg); overflow: hidden; }
.nm-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--nm-s3);
    padding: 16px 20px;
    border-bottom: 0.5px solid var(--nm-sep);
}
.nm-card-title {
    font-size: var(--nm-fs-15);
    font-weight: 650;
    letter-spacing: var(--nm-track-normal);
    color: var(--nm-label);
}
.nm-card-body { padding: 20px; }
.nm-card-foot {
    padding: 14px 20px;
    border-top: 0.5px solid var(--nm-sep);
    background: var(--nm-bg-3);
    border-radius: 0 0 var(--nm-r-lg) var(--nm-r-lg);
}

/* ---------- 4.4 徽章 ---------- */
.nm-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 9px;
    border-radius: var(--nm-r-pill);
    font-size: var(--nm-fs-12);
    font-weight: 600;
    letter-spacing: 0;
    line-height: 1;
    white-space: nowrap;
    background: var(--nm-fill);
    color: var(--nm-label-2);
}
.nm-badge--blue   { background: color-mix(in srgb, var(--nm-blue) 13%, transparent);   color: var(--nm-blue); }
.nm-badge--green  { background: color-mix(in srgb, var(--nm-green) 15%, transparent);  color: #1f8f42; }
.nm-badge--orange { background: color-mix(in srgb, var(--nm-orange) 16%, transparent); color: #b26a00; }
.nm-badge--red    { background: color-mix(in srgb, var(--nm-red) 13%, transparent);    color: var(--nm-red); }
.nm-badge--purple { background: color-mix(in srgb, var(--nm-purple) 13%, transparent); color: var(--nm-purple); }
.nm-badge--teal   { background: color-mix(in srgb, var(--nm-teal) 14%, transparent);   color: #1a7f91; }
.nm-badge--outline {
    background: transparent;
    border: 0.5px solid var(--nm-sep-opaque);
    color: var(--nm-label-2);
}
[data-nm-theme="dark"] .nm-badge--green  { color: #4ade80; }
[data-nm-theme="dark"] .nm-badge--orange { color: #fbbf24; }
[data-nm-theme="dark"] .nm-badge--teal   { color: #5eead4; }

/* ---------- 4.5 表格 ---------- */
.nm-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--nm-fs-13);
}
.nm-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    padding: 11px 14px;
    text-align: left;
    font-size: var(--nm-fs-12);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--nm-label-3);
    background: var(--nm-bg-3);
    border-bottom: 0.5px solid var(--nm-sep);
    white-space: nowrap;
}
.nm-table tbody td {
    padding: 13px 14px;
    border-bottom: 0.5px solid var(--nm-sep);
    color: var(--nm-label);
    vertical-align: middle;
}
.nm-table tbody tr:last-child td { border-bottom: none; }
.nm-table tbody tr { transition: background-color var(--nm-dur-1) var(--nm-ease-out); }
.nm-table tbody tr:hover td { background: var(--nm-tint-softer); }
.nm-table tbody tr.is-selected td { background: var(--nm-tint-soft); }

/* ---------- 4.6 分段控件 / 标签页 ---------- */
.nm-segmented {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    background: var(--nm-fill);
    border-radius: var(--nm-r-sm);
}
.nm-segmented > * {
    padding: 6px 14px;
    border-radius: 7px;
    font-size: var(--nm-fs-13);
    font-weight: 560;
    color: var(--nm-label-2);
    cursor: pointer;
    transition: all var(--nm-dur-2) var(--nm-ease-out);
    white-space: nowrap;
}
.nm-segmented > .is-active {
    background: var(--nm-bg-2);
    color: var(--nm-label);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 0 0 0.5px var(--nm-sep);
}

/* ---------- 4.7 弹层 / 抽屉 ---------- */
.nm-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--nm-z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--nm-s4);
    background: color-mix(in srgb, #000 34%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    animation: nm-fade-up var(--nm-dur-3) var(--nm-ease-out);
}
.nm-dialog {
    width: min(92vw, 480px);
    max-height: 86vh;
    overflow: auto;
    background: var(--nm-bg-2);
    border: 0.5px solid var(--nm-sep);
    border-radius: var(--nm-r-xl);
    box-shadow: var(--nm-shadow-4);
    animation: nm-fade-up var(--nm-dur-3) var(--nm-ease-spring);
}

/* ---------- 4.8 Toast ---------- */
.nm-toast-host {
    position: fixed;
    top: calc(16px + var(--nm-safe-t));
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--nm-z-toast);
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
    width: max-content;
    max-width: min(92vw, 420px);
}
.nm-toast {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 16px;
    border-radius: var(--nm-r-pill);
    font-size: var(--nm-fs-13);
    font-weight: 560;
    color: var(--nm-label);
    background: var(--nm-mat-light-strong);
    -webkit-backdrop-filter: var(--nm-blur);
    backdrop-filter: var(--nm-blur);
    border: 0.5px solid var(--nm-sep);
    box-shadow: var(--nm-shadow-3);
    animation: nm-toast-in var(--nm-dur-3) var(--nm-ease-spring);
}
.nm-toast--success { color: #1f8f42; }
.nm-toast--error   { color: var(--nm-red); }
.nm-toast--info    { color: var(--nm-tint); }

/* ---------- 4.9 骨架屏 ---------- */
.nm-skeleton {
    background: linear-gradient(
        90deg,
        var(--nm-fill) 0%,
        var(--nm-fill-2) 40%,
        var(--nm-fill) 80%
    );
    background-size: 420px 100%;
    border-radius: var(--nm-r-sm);
    animation: nm-shimmer 1.4s linear infinite;
}
.nm-skeleton--text { height: 12px; margin: 7px 0; }
.nm-skeleton--title { height: 20px; width: 42%; margin-bottom: 12px; }
.nm-skeleton--circle { border-radius: 50%; }

/* ---------- 4.10 空状态 ---------- */
.nm-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--nm-s3);
    padding: var(--nm-s10) var(--nm-s6);
    text-align: center;
    color: var(--nm-label-3);
}
.nm-empty-icon {
    display: grid;
    place-items: center;
    width: 64px; height: 64px;
    border-radius: var(--nm-r-xl);
    background: var(--nm-fill);
    color: var(--nm-label-3);
}
.nm-empty-icon svg, .nm-empty-icon .nm-ic { width: 28px; height: 28px; stroke-width: 1.5; }
.nm-empty-title { font-size: var(--nm-fs-15); font-weight: 600; color: var(--nm-label-2); }
.nm-empty-desc { font-size: var(--nm-fs-13); color: var(--nm-label-3); max-width: 34ch; }

/* ---------- 4.11 头像 ---------- */
.nm-avatar {
    display: grid;
    place-items: center;
    width: 36px; height: 36px;
    border-radius: 50%;
    overflow: hidden;
    flex: none;
    font-size: var(--nm-fs-13);
    font-weight: 650;
    color: #fff;
    background: linear-gradient(140deg, var(--nm-tint), var(--nm-indigo));
    box-shadow: 0 0 0 1.5px var(--nm-bg-2), 0 0 0 2.5px var(--nm-sep);
}
.nm-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- 4.12 进度 ---------- */
.nm-progress {
    height: 6px;
    border-radius: 99px;
    background: var(--nm-fill);
    overflow: hidden;
}
.nm-progress > i {
    display: block;
    height: 100%;
    border-radius: 99px;
    background: linear-gradient(90deg, var(--nm-tint), var(--nm-indigo));
    transition: width var(--nm-dur-4) var(--nm-ease-out);
}

/* ---------- 4.13 工具提示 ---------- */
.nm-tip { position: relative; }
.nm-tip::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    padding: 6px 10px;
    border-radius: var(--nm-r-xs);
    font-size: var(--nm-fs-12);
    font-weight: 500;
    white-space: nowrap;
    color: #fff;
    background: rgba(29, 29, 31, 0.92);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--nm-dur-2) var(--nm-ease-out),
                transform var(--nm-dur-2) var(--nm-ease-out);
    z-index: 100;
}
.nm-tip:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- 4.14 分隔 / 工具 ---------- */
.nm-hr { height: 0.5px; border: 0; background: var(--nm-sep); margin: var(--nm-s5) 0; }
.nm-stack  { display: flex; flex-direction: column; gap: var(--nm-s4); }
.nm-row    { display: flex; align-items: center; gap: var(--nm-s3); }
.nm-spacer { flex: 1; }
.nm-num    { font-variant-numeric: tabular-nums; letter-spacing: var(--nm-track-tight); }
.nm-muted  { color: var(--nm-label-2); }
.nm-dim    { color: var(--nm-label-3); }
.nm-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nm-clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 图标统一：线性 SVG，继承字色，视觉重量一致 */
.nm-ic, .icon {
    display: inline-block;
    vertical-align: -0.14em;
    flex: none;
    stroke-width: 1.7;
}

/* ==========================================================================
   5. 无障碍 / 降级
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    [data-reveal] { opacity: 1 !important; transform: none !important; }
    body::after { animation: none; }
}

/* 弱机型/低端设备：关闭毛玻璃重效果，保证流畅 */
@media (max-width: 480px) {
    :root { --nm-blur: saturate(170%) blur(16px); }
}

@media print {
    body::before, body::after, .nm-scene { display: none !important; }
}

/* ==========================================================================
   6. WebGL 降级：漂浮光斑（无 WebGL 环境的空间氛围）
   ========================================================================== */
.nm-fallback { overflow: hidden; }
.nm-fallback .nm-orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(70px);
    opacity: 0.35;
    will-change: transform;
}
.nm-orb-1 {
    width: 560px; height: 560px;
    top: -12%; left: -6%;
    background: radial-gradient(circle at 32% 32%, color-mix(in srgb, var(--nm-blue) 34%, transparent), transparent 68%);
    animation: nm-orb-a 26s var(--nm-ease-in-out) infinite;
}
.nm-orb-2 {
    width: 480px; height: 480px;
    top: 28%; right: -10%;
    background: radial-gradient(circle at 60% 40%, color-mix(in srgb, var(--nm-indigo) 30%, transparent), transparent 68%);
    animation: nm-orb-b 32s var(--nm-ease-in-out) infinite;
}
.nm-orb-3 {
    width: 420px; height: 420px;
    bottom: -14%; left: 34%;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--nm-teal) 26%, transparent), transparent 68%);
    animation: nm-orb-c 38s var(--nm-ease-in-out) infinite;
}
[data-nm-theme="dark"] .nm-fallback .nm-orb { opacity: 0.5; }
@keyframes nm-orb-a {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50%      { transform: translate3d(6vw, 5vh, 0) scale(1.12); }
}
@keyframes nm-orb-b {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50%      { transform: translate3d(-5vw, -6vh, 0) scale(0.92); }
}
@keyframes nm-orb-c {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50%      { transform: translate3d(4vw, -4vh, 0) scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
    .nm-fallback .nm-orb { animation: none; }
}
