/* ==========================================================================
   车镜 CarMirror · base.css
   设计令牌 / Reset / 排版 / 应用外壳

   冷黑青色业务界面 / 蓝紫极光账号入口 / 共享玻璃材质。
   状态色保留独立语义，动画仅作用于展示层。
   ========================================================================== */

:root {
  /* ==========================================================================
     调色板 —— 取自 shadcn 预设 b2D2i7uQC 的 .dark 组
     整体为带青蓝倾向的深色（色相 215–229），非中性 zinc。
     换配色时只需改本区块，其余淡底 / 描边 / 焦点环全部由下方 color-mix 派生。
     ========================================================================== */

  /* ---- 60% 主色：背景层 ---- */
  --bg:            #0b1216;
  --bg-subtle:     #101e24;

  /* ---- 30% 辅助色：卡片与面板层 ---- */
  --card:          #16242a;                  /* 下拉菜单与无模糊回退保持实色 */
  --card-hover:    #20353d;
  --muted-bg:      oklch(0.275 0.011 216.9);   /* preset --muted */
  --border:        rgb(223 247 255 / .14);
  --border-strong: oklch(1 0 0 / 20%);         /* 派生：预设 --input 为 15%，
                                                  此处提到 20% 以保证 hover 时
                                                  描边变化可被察觉 */

  /* ---- 前景 ---- */
  --fg:            oklch(0.987 0.002 197.1);   /* preset --foreground */
  --fg-muted:      #c3d3d9;
  --fg-subtle:     #a3b9c2;
  --fg-faint:      #90a9b3;

  /* ---- 10% 强调色 ----
     ⚠️ 此处刻意不用预设的 --primary: oklch(0.45 0.085 224.283)。
     shadcn 的 --primary 是给「实心按钮底色 + --primary-foreground 白字」用的，
     本身不需要在深色底上可读。而车镜的主按钮是透明底 + 强调色描边与文字，
     强调色必须直接作为文字色使用。

     实测对比度（相对 --bg）：
       预设 --primary          L=0.45  → 约 3.0:1   不满足 WCAG AA 正文 4.5:1
       预设 --sidebar-primary  L=0.715 → 约 7.3:1   通过 AA / AAA

     因此取同一预设、同色相族（215 对 224）的 --sidebar-primary 作为强调色 ——
     它在预设里本就是「需要被看见的品牌色」。 */
  --accent:        oklch(0.715 0.143 215.221); /* preset --sidebar-primary */

  /* 三档预警：视觉即语义。青柠与琥珀按要求保留，朱红取预设的 --destructive */
  --ok:            #7cf29b;                    /* 青柠 · 暂未发现异常（保留） */
  --warn:          #f59e0b;                    /* 琥珀 · 需要关注（保留） */
  --danger:        oklch(0.704 0.191 22.216);  /* preset --destructive */

  /* ---- 派生的透明变体 ----
     一律用 color-mix 从上面的基色算出，不再写死 rgb() 通道值。
     这样换配色时只需改上面那几个基色，淡底、描边、焦点环全部自动跟随。 */
  --accent-soft:   color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-line:   color-mix(in srgb, var(--accent) 30%, transparent);
  --ok-soft:       color-mix(in srgb, var(--ok) 12%, transparent);
  --warn-soft:     color-mix(in srgb, var(--warn) 12%, transparent);
  --warn-line:     color-mix(in srgb, var(--warn) 30%, transparent);
  --danger-soft:   color-mix(in srgb, var(--danger) 12%, transparent);
  --danger-line:   color-mix(in srgb, var(--danger) 35%, transparent);
  --ring:          color-mix(in srgb, var(--accent) 45%, transparent);

  /* 弹层遮罩：刻意的纯黑，与调色板无关，不随主题变 */
  --overlay:       rgb(0 0 0 / .7);

  /* ---- 圆角：Shadcn ---- */
  --radius:        0.5rem;
  --radius-sm:     0.375rem;
  --radius-lg:     0.5rem;
  --radius-full:   9999px;

  /* ---- 间距：Tailwind 4px 增量 ---- */
  --sp-1:  0.25rem;   /*  4px */
  --sp-2:  0.5rem;    /*  8px */
  --sp-3:  0.75rem;   /* 12px */
  --sp-4:  1rem;      /* 16px */
  --sp-5:  1.25rem;   /* 20px */
  --sp-6:  1.5rem;    /* 24px */
  --sp-8:  2rem;      /* 32px */
  --sp-10: 2.5rem;    /* 40px */
  --sp-12: 3rem;      /* 48px */

  /* ---- 阴影：仅两档 ---- */
  --shadow:    0 1px 2px 0 rgb(0 0 0 / .4);
  --shadow-lg: 0 8px 24px rgb(0 0 0 / .5);

  --glass-bg: rgb(22 38 42 / .66);
  --glass-strong: rgb(18 32 37 / .9);
  --glass-highlight: linear-gradient(135deg, rgb(222 250 255 / .065), transparent 58%);
  --glass-shadow: inset 0 1px 0 rgb(231 253 255 / .08), 0 8px 24px rgb(0 0 0 / .16);
  --glass-hover-shadow: inset 0 1px 0 rgb(231 253 255 / .15), 0 12px 30px rgb(0 0 0 / .32);
  --glass-blur: 16px;

  /* ---- 动效：仅两档时长 + 一条缓动曲线 ---- */
  --dur-fast: 0.15s;
  --dur:      0.18s;
  --dur-slow: 0.9s;                            /* 仅用于环形仪表入场 */
  --ease:     cubic-bezier(0.16, 1, 0.3, 1);   /* ease-out，收尾更稳 */

  /* ---- 字体 ---- */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* ---- 布局 ---- */
  --app-width:  480px;
  --appbar-h:   3.5rem;   /* 56px */
  --tabbar-h:   3.75rem; /* 60px */
}

/* ==========================================================================
   Reset
   ========================================================================== */

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

* { margin: 0; padding: 0; }

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

html,
body { height: 100%; }

body {
  font-family: var(--font-sans);
  font-size: 0.875rem;   /* 14px */
  line-height: 1.6;
  color: var(--fg);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  letter-spacing: 0;
  background-image: linear-gradient(125deg, #0b1216 15%, #10252b 48%, #0b1216 80%);
  background-attachment: fixed;
}

body[data-theme="auth"] {
  --bg: #0b1024;
  --bg-subtle: #131d36;
  --card: #19243d;
  --card-hover: #24334f;
  --accent: #a0d9ff;
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 30%, transparent);
  --ring: color-mix(in srgb, var(--accent) 45%, transparent);
  --glass-bg: rgb(22 31 58 / .62);
  --glass-strong: rgb(16 24 46 / .9);
  --glass-highlight: linear-gradient(135deg, rgb(221 230 255 / .095), transparent 65%);
  background-image: linear-gradient(130deg, #0b1024 12%, #192e4c 48%, #201b39 80%, #0b1024);
}

img,
svg { display: block; max-width: 100%; }

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}

button { cursor: pointer; }

ul,
ol { list-style: none; }

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

[hidden] { display: none !important; }

/* 全局焦点环：键盘可达性 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* ==========================================================================
   应用外壳：480px 居中单列，两侧留白
   ========================================================================== */

.stage {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-6);
  padding: var(--sp-8) var(--sp-6) var(--sp-10);
}

.app-shell {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: var(--app-width);
  height: min(860px, calc(100vh - 9rem));
  min-height: 560px;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 24px 80px rgb(0 0 0 / .32), inset 0 1px 0 rgb(227 251 255 / .08);
}

/* The backdrop is behind every glass surface, outside the scrolling content. */
.app-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(150deg, #15313a 0%, #0c191f 34%, #183330 65%, #0c171e 100%);
}

@supports not (backdrop-filter: blur(1px)) {
  .app-shell::before { opacity: .45; }
}

body[data-theme="auth"] .app-shell::before {
  inset: -35%;
  background:
    linear-gradient(rgb(11 16 36 / .32), rgb(11 16 36 / .22)),
    linear-gradient(122deg, transparent 20%, rgb(75 115 177 / .7) 36%, transparent 54%),
    linear-gradient(38deg, transparent 24%, rgb(104 68 172 / .75) 47%, transparent 72%),
    linear-gradient(155deg, #0b1024 12%, #244a86 38%, #173b48 54%, #382c60 73%, #0b1024);
  background-size: 100% 100%, 180% 180%, 160% 160%, 100% 100%;
  /* Begin mid-cycle so the slow drift is visible as soon as the page opens. */
  animation: aurora-flow 28s ease-in-out -10s infinite alternate;
}

@keyframes aurora-flow {
  from {
    transform: translate(-10%, -6%) rotate(-5deg);
    background-position: 0 0, 100% 0%, 0% 100%, 50% 50%;
  }
  to {
    transform: translate(10%, 6%) rotate(5deg);
    background-position: 0 0, 0% 100%, 100% 0%, 50% 50%;
  }
}

.view {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-6);
  outline: none;
  overflow-x: hidden;
}

/* 视图内默认纵向节奏：用 gap，不堆 margin */
.view > .view-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}

.view::-webkit-scrollbar { width: 6px; }
.view::-webkit-scrollbar-thumb {
  background-color: var(--border-strong);
  border-radius: var(--radius-full);
}
.view::-webkit-scrollbar-track { background: transparent; }

.stage-foot {
  width: 100%;
  max-width: var(--app-width);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  text-align: center;
  font-size: 0.75rem;
  line-height: 1.7;
  color: var(--fg-faint);
}

.stage-foot .stage-title {
  font-size: 0.75rem;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--fg-subtle);
}

/* 移动端：全屏，去掉外框与两侧留白 */
@media (max-width: 520px) {
  :root { --glass-blur: 10px; }
  .stage { padding: 0; gap: 0; }
  .app-shell {
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    max-width: none;
    border: none;
    border-radius: 0;
  }
  .view { padding: var(--sp-5) var(--sp-4) var(--sp-8); }
  .stage-foot { display: none; }
}

/* ==========================================================================
   排版
   ========================================================================== */

h1, h2, h3, h4 {
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
}

h1 { font-size: 1.5rem; }    /* 24px */
h2 { font-size: 1.125rem; }  /* 18px */
h3 { font-size: 0.9375rem; } /* 15px */
h4 { font-size: 0.875rem; }  /* 14px */

.text-lg   { font-size: 1rem; }
.text-sm   { font-size: 0.8125rem; line-height: 1.6; }
.text-xs   { font-size: 0.75rem;   line-height: 1.6; }

.text-muted  { color: var(--fg-muted); }
.text-subtle { color: var(--fg-subtle); }
.text-faint  { color: var(--fg-faint); }

.text-accent { color: var(--accent); }
.text-ok     { color: var(--ok); }
.text-warn   { color: var(--warn); }
.text-danger { color: var(--danger); }

.font-medium { font-weight: 500; }
.font-semi   { font-weight: 600; }

/* 等宽数字：里程 / 分数 / 置信度 / 熵值，强化仪表读数感 */
.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.center { text-align: center; }

/* ==========================================================================
   布局助手：一律 flex/grid + gap
   ========================================================================== */

.row     { display: flex; align-items: center; gap: var(--sp-2); }
.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}
.col     { display: flex; flex-direction: column; }
.grow    { flex: 1; min-width: 0; }
.shrink-0 { flex: none; }
.wrap    { flex-wrap: wrap; }

.gap-1 { gap: var(--sp-1); }
.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); }
.gap-6 { gap: var(--sp-6); }

.stack   { display: flex; flex-direction: column; gap: var(--sp-4); }
.stack-2 { display: flex; flex-direction: column; gap: var(--sp-2); }
.stack-3 { display: flex; flex-direction: column; gap: var(--sp-3); }
.stack-6 { display: flex; flex-direction: column; gap: var(--sp-6); }

/* ==========================================================================
   图表配色钩子
   SVG 图元一律 stroke/fill="currentColor"，由这些类注入 base.css 令牌，
   禁止在 JS 中硬编码色值。
   ========================================================================== */

.chart-accent { color: var(--accent); }
.chart-ok     { color: var(--ok); }
.chart-warn   { color: var(--warn); }
.chart-danger { color: var(--danger); }
.chart-grid   { color: var(--border); }
.chart-muted  { color: var(--fg-subtle); }

/* ==========================================================================
   动效：克制，且尊重系统偏好

   全站只有两档时长，与既有 modal-in（.15s）/ toast-in（.18s）同一套语言，
   不为页面切换另造词汇。
   ========================================================================== */

@keyframes reveal-in {
  from { opacity: 0; translate: 0 8px; }
  to { opacity: 1; translate: 0 0; }
}

.reveal-pending { opacity: 0; translate: 0 8px; }
.reveal-running { animation: reveal-in 380ms var(--ease) both; }
.reveal-pending:focus-within { opacity: 1; translate: none; }

@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;
  }
  body[data-theme="auth"] .app-shell::before { animation: none; transform: none; }
  .reveal-pending, .reveal-running { opacity: 1; translate: none; animation: none; }
}
