/* iosAutoAgent 中枢门户 —— 设计系统
 *
 * 取 shadcn/ui 的**记号体系**与 Vercel 的**观感**:一层纸(card)、1px 边框、近黑的主按钮、
 * 不要投影去假装立体。**没有构建步骤** —— 这里是手写 CSS,不是 Tailwind;shadcn 那套
 * 变量名、半径、间距、focus ring 照搬,类名按它的组件名(.btn/.card/.pill/.tabs…)。
 *
 * ## 为什么颜色写成 HSL 三元组
 *
 * `--border: 240 6% 90%` 这种写法(不带 hsl())是 shadcn 的约定,好处是同一个变量能派生出
 * 半透明:`hsl(var(--border) / .4)`。一路写成 #rrggbb 的话,每需要一档透明就得再定义一个变量。
 *
 * ## 昼夜两档
 *
 * 默认跟随系统,人点过就以人选的为准(`<html data-theme>`)。**两档只换取值,不重写规则** ——
 * 布局一条都不分叉,否则改一处要记得改两处,而漏掉的那处只在另一档里看得见。
 */
:root{
  --background: 0 0% 100%;
  --foreground: 240 10% 3.9%;
  --card: 0 0% 100%;
  --muted: 240 5% 96%;
  --muted-foreground: 240 4% 46%;
  --border: 240 6% 90%;
  --input: 240 6% 90%;
  --primary: 240 6% 10%;
  --primary-foreground: 0 0% 98%;
  --accent-fg: 221 83% 45%;
  --success: 142 72% 29%;
  --warning: 38 92% 40%;
  --destructive: 0 72% 45%;
  --ring: 240 5% 65%;
  --radius: .5rem;
  color-scheme: light;
}
/* 夜间值班台:墨底暖纸,卡片从底上托起来;活着的状态用青绿,告警用黄铜。
   原先暗色卡和底几乎同色(4% vs 6%)、描边 16% 贴在 4% 底上看不见,整页糊成一块。 */
:root[data-theme="dark"]{
  --background: 222 28% 6%;
  --foreground: 38 18% 93%;
  --card: 222 22% 11%;
  --muted: 222 16% 16%;
  --muted-foreground: 215 10% 68%;
  --border: 215 12% 24%;
  --input: 215 12% 24%;
  --primary: 38 18% 93%;
  --primary-foreground: 222 28% 8%;
  --accent-fg: 168 52% 52%;
  --success: 152 42% 50%;
  --warning: 38 72% 56%;
  --destructive: 6 72% 62%;
  --ring: 168 40% 36%;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --background: 222 28% 6%;
    --foreground: 38 18% 93%;
    --card: 222 22% 11%;
    --muted: 222 16% 16%;
    --muted-foreground: 215 10% 68%;
    --border: 215 12% 24%;
    --input: 215 12% 24%;
    --primary: 38 18% 93%;
    --primary-foreground: 222 28% 8%;
    --accent-fg: 168 52% 52%;
    --success: 152 42% 50%;
    --warning: 38 72% 56%;
    --destructive: 6 72% 62%;
    --ring: 168 40% 36%;
    color-scheme: dark;
  }
}

*{box-sizing:border-box}
/* **带 hidden 属性的一律不显示。** 浏览器默认的 [hidden]{display:none} 优先级最低,
   任何写了 display 的类都会把它盖掉:发布对话框「按机器名筛」给 .canary-row 设 hidden,
   而 .canary-row 是 flex,于是一行都藏不掉;抽屉里的跳转矩阵同理(2026-09-14 审出)。 */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:hsl(var(--background));
  color:hsl(var(--foreground));
  font:14px/1.55 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,
       "PingFang SC","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
  font-feature-settings:"cv02","cv03","cv04","cv11";
}
a{color:inherit;text-decoration:none}
.mono{font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace}
.hide{display:none !important}

/* ---------- 顶栏 ---------- */
/* 公网存储告警横幅:四页同一份(中枢、授权、落地池、全量,见 updatekit/storagebudget)。平时不占位,有告警才出现。 */
.storage-banner{display:flex;gap:10px;align-items:baseline;padding:8px 20px;font-size:13px;line-height:1.5;
  background:hsl(var(--warning) / .12);border-bottom:1px solid hsl(var(--warning) / .35);color:hsl(var(--foreground))}
.storage-banner[hidden]{display:none}
.storage-banner b{color:hsl(var(--warning));white-space:nowrap}
.storage-banner .sb-text{flex:1;min-width:0}
.storage-banner .sb-sum{color:hsl(var(--muted-foreground));white-space:nowrap}
@media (max-width:900px){.storage-banner{padding:8px 12px;flex-wrap:wrap}}
header{
  position:sticky;top:0;z-index:30;
  display:flex;gap:14px;align-items:center;
  height:56px;padding:0 20px;
  background:hsl(var(--background) / .8);
  backdrop-filter:saturate(180%) blur(8px);
  border-bottom:1px solid hsl(var(--border));
}
header h1{font-size:14px;font-weight:600;margin:0;letter-spacing:-.01em;white-space:nowrap}
header .sp{flex:1}
/* 顶栏永远一行。窄屏下标题和导航会各自折成两行,把 56px 的条撑破、
   底下那条分隔线歪在半空。**先让最不吃劲的两件退场** —— 版本号和用户名;
   连接状态和导航留着,它们是这条栏存在的理由。 */
@media (max-width:900px){
  header{gap:10px;padding:0 12px}
  header #ver,header #who{display:none}
}

/* ---------- 版心 ---------- */
main{max-width:1080px;margin:0 auto;padding:24px 20px 64px;display:grid;gap:20px}
main.wide{max-width:1520px}
.stack{display:grid;gap:20px}

/* ---------- 卡片 ---------- */
.card,.panel{
  background:hsl(var(--card));
  border:1px solid hsl(var(--border));
  border-radius:calc(var(--radius) + 2px);
  overflow:hidden;
}
.card-hd{display:flex;align-items:center;gap:10px;padding:16px 20px 0}
.card-hd .sp{flex:1}
.card-title,.panel h2{
  font-size:15px;font-weight:600;letter-spacing:-.01em;margin:0;padding:0;border:0;
}
.panel h2{padding:16px 20px 0}
.card-desc{margin:6px 0 0;font-size:13px;color:hsl(var(--muted-foreground))}
.card-bd,.body{padding:16px 20px 20px}

/* ---------- 按钮 ---------- */
button,.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:36px;padding:0 14px;
  font:inherit;font-size:13px;font-weight:500;line-height:1;
  border-radius:calc(var(--radius) - 2px);
  border:1px solid hsl(var(--border));
  background:hsl(var(--card));
  color:hsl(var(--foreground));
  cursor:pointer;white-space:nowrap;
  transition:background-color .12s,border-color .12s,color .12s,opacity .12s;
}
button:hover,.btn:hover{background:hsl(var(--muted))}
button:focus-visible,.btn:focus-visible,
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:none;
  box-shadow:0 0 0 2px hsl(var(--background)),0 0 0 4px hsl(var(--ring));
}
button.primary{
  background:hsl(var(--primary));border-color:hsl(var(--primary));
  color:hsl(var(--primary-foreground));
}
button.primary:hover{background:hsl(var(--primary) / .9)}
button.ghost{background:transparent;border-color:transparent}
button.ghost:hover{background:hsl(var(--muted))}
button.danger{background:transparent;border-color:hsl(var(--destructive) / .35);
              color:hsl(var(--destructive))}
button.danger:hover{background:hsl(var(--destructive) / .1)}
button.small,.btn.small{height:30px;padding:0 10px;font-size:12px}
button:disabled{opacity:.5;cursor:not-allowed}
button:disabled:hover{background:hsl(var(--card))}

/* ---------- 输入 ---------- */
input,select,textarea{
  height:36px;padding:0 10px;font:inherit;font-size:13px;
  color:hsl(var(--foreground));background:transparent;
  border:1px solid hsl(var(--input));border-radius:calc(var(--radius) - 2px);
}
textarea{height:auto;padding:8px 10px}
input::placeholder,textarea::placeholder{color:hsl(var(--muted-foreground))}
input[type=checkbox],input[type=radio]{height:15px;width:15px;padding:0;accent-color:hsl(var(--primary))}
select{padding-right:26px}
.field{display:flex;flex-direction:column;gap:6px;min-width:150px}
.field label,.label{font-size:12px;font-weight:500;color:hsl(var(--foreground))}
.hint,.card-desc{font-size:13px;color:hsl(var(--muted-foreground))}

/* ---------- 排版小件 ---------- */
.muted{color:hsl(var(--muted-foreground))}
.small{font-size:12px}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.sp{flex:1}
code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
     font-size:12px;color:hsl(var(--muted-foreground));
     background:hsl(var(--muted));padding:1px 5px;border-radius:4px}
.err{color:hsl(var(--destructive));font-size:13px}
.note{margin:0;padding:10px 12px;font-size:13px;border-radius:calc(var(--radius) - 2px);
      color:hsl(var(--warning));background:hsl(var(--warning) / .1);
      border:1px solid hsl(var(--warning) / .25)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:760px){.grid2{grid-template-columns:1fr}}

/* 存储策略卡：控制端/手机两组，输入框等宽、窄屏两列或一列 */
.policy-group + .policy-group{margin-top:16px;padding-top:16px;border-top:1px solid hsl(var(--border))}
.policy-group-title{display:flex;align-items:baseline;gap:8px;margin:0 0 10px;font-size:13px;font-weight:600}
.policy-group-title .muted{font-weight:400}
.policy-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 14px}
.policy-grid.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.policy-grid .field{min-width:0}
.input-unit{display:flex;align-items:center;gap:6px}
.input-unit input{flex:1;min-width:0;width:100%}
.input-unit span{font-size:12px;color:hsl(var(--muted-foreground));white-space:nowrap}
.policy-actions{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:16px}
@media (max-width:900px){.policy-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:520px){.policy-grid,.policy-grid.two{grid-template-columns:1fr}}

/* ---------- 徽标 ---------- */
.pill{
  display:inline-flex;align-items:center;gap:4px;
  padding:2px 8px;border-radius:999px;
  font-size:11px;font-weight:500;line-height:1.5;
  border:1px solid transparent;white-space:nowrap;
}
.pill{background:hsl(var(--muted));color:hsl(var(--muted-foreground))}
.s-ok{background:hsl(var(--success) / .12);color:hsl(var(--success));
      border-color:hsl(var(--success) / .25)}
.s-run{background:hsl(var(--accent-fg) / .12);color:hsl(var(--accent-fg));
       border-color:hsl(var(--accent-fg) / .25)}
.s-busy{background:hsl(var(--warning) / .12);color:hsl(var(--warning));
        border-color:hsl(var(--warning) / .25)}
.s-err{background:hsl(var(--destructive) / .12);color:hsl(var(--destructive));
       border-color:hsl(var(--destructive) / .25)}

/* ---------- 分段控件(shadcn 的 Tabs) ---------- */
.tabs{display:inline-flex;gap:2px;padding:3px;border-radius:calc(var(--radius));
      background:hsl(var(--muted));flex-wrap:wrap}
.tabs button{
  height:30px;padding:0 12px;font-size:13px;font-weight:500;
  border:1px solid transparent;background:transparent;
  color:hsl(var(--muted-foreground));border-radius:calc(var(--radius) - 3px);
}
.tabs button:hover{background:transparent;color:hsl(var(--foreground))}
.tabs button.on{background:hsl(var(--card));color:hsl(var(--foreground));
                border-color:hsl(var(--border))}
.tabs .n{margin-left:6px;font-size:11px;color:hsl(var(--muted-foreground))}

/* 顶栏导航:同一套分段控件,尺寸小一档 */
nav.views{display:inline-flex;gap:2px;padding:3px;border-radius:var(--radius);
          background:hsl(var(--muted));flex-wrap:nowrap;flex-shrink:1;min-width:0;overflow-x:auto}
nav.views button,nav.views .viewlink{
  height:28px;padding:0 12px;font-size:13px;font-weight:500;line-height:28px;
  border:1px solid transparent;background:transparent;
  color:hsl(var(--muted-foreground));border-radius:calc(var(--radius) - 3px);
  display:inline-flex;align-items:center;flex:none;
}
nav.views button:hover,nav.views .viewlink:hover{color:hsl(var(--foreground));background:transparent}
nav.views button.on,nav.views .viewlink.on{
  background:hsl(var(--card));color:hsl(var(--foreground));
  border-color:hsl(var(--border));
}

/* ---------- 表格 ----------
   表头与格子一律居中(2026-09-18 用户定:门户里凡是表格都对着列中线)。 */
table{width:100%;border-collapse:separate;border-spacing:0}
th,td{text-align:center;vertical-align:middle;padding:10px 12px;font-size:13px;
      border-bottom:1px solid hsl(var(--border))}
th{font-size:12px;font-weight:500;color:hsl(var(--muted-foreground));
   background:hsl(var(--muted) / .4)}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover td{background:hsl(var(--muted) / .35)}

/* ---------- 对话框 ---------- */
.modal{position:fixed;inset:0;z-index:60;display:flex;align-items:center;
       justify-content:center;padding:24px;background:hsl(240 10% 4% / .6);
       backdrop-filter:blur(2px)}
.modalbox{
  width:100%;max-width:560px;max-height:86vh;overflow:auto;
  background:hsl(var(--card));color:hsl(var(--foreground));
  border:1px solid hsl(var(--border));border-radius:calc(var(--radius) + 4px);
  box-shadow:0 16px 48px -12px hsl(240 10% 4% / .3);
  padding:24px;
}
.modalbox.wide{max-width:720px}
.modalbox h3{margin:0;font-size:17px;font-weight:600;letter-spacing:-.01em}
.modalbox .dlg-desc{margin:6px 0 18px;font-size:13px;color:hsl(var(--muted-foreground))}
.modalbox .dlg-ft{display:flex;gap:8px;justify-content:flex-end;align-items:center;
                  margin-top:22px;padding-top:18px;border-top:1px solid hsl(var(--border))}
.modalbox .dlg-ft .sp{flex:1}

/* ---------- 选项块(单选 + 它的附属输入) ---------- */
.optbox{border:1px solid hsl(var(--border));border-radius:calc(var(--radius));
        padding:12px 14px;margin:8px 0}
.optbox:has(input:checked){border-color:hsl(var(--foreground) / .35);
                           background:hsl(var(--muted) / .35)}
label.opt{display:flex;gap:10px;align-items:flex-start;margin:0;cursor:pointer}
label.opt b{font-size:13px;font-weight:600}
label.opt i{display:block;font-style:normal;margin-top:3px;font-size:12px;
            color:hsl(var(--muted-foreground))}
.optsub{margin:12px 0 0 25px}

/* ---------- 勾选清单 ---------- */
.canary-box{max-height:240px;overflow:auto;border:1px solid hsl(var(--border));
            border-radius:calc(var(--radius));background:hsl(var(--background))}
.canary-row{display:flex;align-items:center;gap:10px;padding:8px 12px;cursor:pointer;
            border-bottom:1px solid hsl(var(--border) / .6);font-size:13px}
.canary-row:last-child{border-bottom:0}
.canary-row:hover{background:hsl(var(--muted) / .4)}
.canary-row.off{cursor:default;opacity:.55}
.canary-row b{font-weight:500}
.canary-row .mono{font-size:11px}

/* ---------- 数字摘要 ---------- */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:12px}
.stat{border:1px solid hsl(var(--border));border-radius:calc(var(--radius));
      padding:14px 16px;background:hsl(var(--card))}
.stat b{display:block;font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1.2}
.stat span{font-size:12px;color:hsl(var(--muted-foreground))}

/* ---------- 登录页 ---------- */
.login{max-width:400px;margin:14vh auto;padding:28px}
.login h1{margin:0 0 6px;font-size:20px;letter-spacing:-.02em}

/* ---------- 空态 ---------- */
.empty{padding:36px 20px;text-align:center;font-size:13px;
       color:hsl(var(--muted-foreground))}

/* ---------- 连接状态(是状态不是按钮,所以不给边框底色) ---------- */
.conn-state{display:inline-flex;align-items:center;gap:6px;font-size:12px;
            color:hsl(var(--muted-foreground))}
.conn-state::before{content:'';width:6px;height:6px;border-radius:50%;
                    background:hsl(var(--muted-foreground))}
.conn-state.ok::before{background:hsl(var(--success))}
.conn-state.err::before{background:hsl(var(--destructive))}
#themeToggle{height:28px;width:28px;padding:0;border-color:transparent;background:transparent}
#themeToggle:hover{background:hsl(var(--muted))}

/* 夜间值班台的气氛:顶上一抹冷光、输入格有底、卡片沿上沿提亮。只动观感,布局不分叉。 */
html[data-theme="dark"] body{
  background-color:hsl(var(--background));
  background-image:
    radial-gradient(900px 420px at 8% -8%, hsl(222 50% 18% / .55), transparent 58%),
    radial-gradient(720px 380px at 100% 0%, hsl(168 40% 14% / .22), transparent 52%);
}
html[data-theme="dark"] header{
  background:hsl(222 28% 6% / .9);
  border-bottom-color:hsl(var(--border));
}
html[data-theme="dark"] .card,
html[data-theme="dark"] .panel,
html[data-theme="dark"] .stat,
html[data-theme="dark"] .modalbox{
  box-shadow:inset 0 1px 0 hsl(38 30% 96% / .07);
}
html[data-theme="dark"] input,
html[data-theme="dark"] select,
html[data-theme="dark"] textarea{
  background:hsl(var(--muted) / .55);
}
html[data-theme="dark"] th{
  background:hsl(var(--muted) / .7);
}
html[data-theme="dark"] tbody tr:hover td{
  background:hsl(var(--muted) / .85);
}
html[data-theme="dark"] nav.views{
  background:hsl(var(--muted) / .9);
}
html[data-theme="dark"] .conn-state.ok{color:hsl(var(--success))}
html[data-theme="dark"] .conn-state.err{color:hsl(var(--destructive))}
