/* ===========================================================================
   Chatmoe 运营台 · 样式
   ---------------------------------------------------------------------------
   设计取向（与 app 的取舍对齐，但按控制台的需求重排）：
   - 只有一个强调色（品牌蓝），其余靠层级表面与细线表达结构，不用投影堆叠；
   - 数字用等宽表格数字并右对齐，方便纵向比大小；ID 用等宽字体，避免 o/0、l/1 认错；
   - 深浅色全部由 light-dark() 驱动，不留主题类，不写第二套深色样式；
   - 密度优先：11px 微标签 + 46px 行高，一屏尽量多放行，但不牺牲点击目标尺寸。

   组件用 Lit 但走 Light DOM（见 js/app.js 的说明），因此这里是一份全局样式表，
   而不是每个组件内联一份 Shadow DOM 样式 —— 控制台的表格/表单/按钮是共享基元，
   复制到 12 个组件里就再也改不齐了。
   =========================================================================== */

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

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

body {
   margin: 0;
   min-height: 100dvh;
   font-family: var(--font-text);
   font-size: var(--text-body-sm);
   line-height: var(--leading-body-sm);
   letter-spacing: var(--tracking-body-sm);
   color: var(--color-charcoal-ink);
   background: var(--surface-canvas);
   -webkit-tap-highlight-color: transparent;
}

h1,
h2,
h3,
h4,
p,
figure {
   margin: 0;
}

button {
   font: inherit;
   color: inherit;
}

a {
   color: var(--color-chatmoe-blue);
   text-decoration: none;
}

a:hover {
   text-decoration: underline;
}

:focus-visible {
   outline: 2px solid var(--color-chatmoe-blue);
   outline-offset: 2px;
   border-radius: var(--radius-md);
}

::selection {
   background: color-mix(in srgb, var(--color-chatmoe-blue) 26%, transparent);
}

.material-symbols-rounded {
   font-size: 20px;
   line-height: 1;
   user-select: none;
}

/* --- 排版基元 ------------------------------------------------------------ */

.eyebrow {
   font-size: var(--text-micro);
   line-height: var(--leading-micro);
   letter-spacing: var(--tracking-micro);
   color: var(--color-slate);
   font-weight: var(--font-weight-medium);
}

.muted {
   color: var(--color-slate);
}

.strong {
   font-weight: var(--font-weight-medium);
}

.num {
   font-variant-numeric: tabular-nums;
   font-feature-settings: 'tnum' 1;
}

.mono {
   font-family: var(--font-mono);
   font-size: 0.92em;
   font-variant-numeric: tabular-nums;
}

.truncate {
   display: inline-block;
   max-width: 100%;
   overflow: hidden;
   text-overflow: ellipsis;
   vertical-align: bottom;
   white-space: nowrap;
}

.nowrap {
   white-space: nowrap;
}

.right {
   text-align: right;
}

/* --- 外壳 ---------------------------------------------------------------- */

.shell {
   display: grid;
   grid-template-columns: var(--rail-width) minmax(0, 1fr);
   height: 100dvh;
   overflow: hidden;
}

.rail {
   display: flex;
   flex-direction: column;
   gap: var(--spacing-16);
   height: 100dvh;
   padding: 18px 14px;
   background: var(--surface-sunken);
   border-right: 1px solid var(--border-subtle);
}

.rail-brand {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 6px 8px 14px;
   border-bottom: 1px solid var(--border-subtle);
}

.rail-mark {
   display: grid;
   place-items: center;
   width: 30px;
   height: 30px;
   flex: none;
   border-radius: 9px;
   background: var(--color-chatmoe-blue);
   color: light-dark(oklch(1 0 0), oklch(0.16 0.02 255));
   font-family: var(--font-display);
   font-size: 15px;
   font-weight: var(--font-weight-bold);
   letter-spacing: -0.4px;
}

.rail-wordmark {
   min-width: 0;
}

.rail-wordmark b {
   display: block;
   font-family: var(--font-display);
   font-size: var(--text-body);
   font-weight: var(--font-weight-medium);
   letter-spacing: -0.2px;
   line-height: 1.2;
}

.rail-wordmark span {
   display: block;
   font-size: var(--text-micro);
   letter-spacing: var(--tracking-micro);
   color: var(--color-slate);
}

.rail-nav {
   display: flex;
   flex-direction: column;
   gap: 2px;
   min-height: 0;
   overflow-y: auto;
   scrollbar-width: thin;
}

.rail-group {
   margin: 14px 8px 4px;
}

.rail-link {
   position: relative;
   display: flex;
   align-items: center;
   gap: 10px;
   height: 38px;
   padding: 0 10px;
   border: 0;
   border-radius: var(--radius-lg);
   background: transparent;
   color: var(--color-graphite);
   font-size: var(--text-body-sm);
   text-align: left;
   cursor: pointer;
   transition: background var(--duration-fast) var(--ease-out),
      color var(--duration-fast) var(--ease-out);
}

.rail-link:hover {
   background: var(--surface-hover);
   color: var(--color-charcoal-ink);
}

.rail-link[aria-current='page'] {
   background: color-mix(in srgb, var(--color-chatmoe-blue) 13%, transparent);
   color: var(--color-charcoal-ink);
   font-weight: var(--font-weight-medium);
}

/* 选中态用左侧 2px 竖条而不是投影：竖条在深色下依然清晰，也不增加视觉重量 */
.rail-link[aria-current='page']::before {
   content: '';
   position: absolute;
   left: -14px;
   top: 9px;
   bottom: 9px;
   width: 2px;
   border-radius: 0 2px 2px 0;
   background: var(--color-chatmoe-blue);
}

.rail-link .material-symbols-rounded {
   font-size: 19px;
   color: var(--color-slate);
}

.rail-link[aria-current='page'] .material-symbols-rounded {
   color: var(--color-chatmoe-blue);
}

.rail-link-key {
   margin-left: auto;
   font-size: var(--text-micro);
   color: var(--color-cloud-shadow);
}

.rail-foot {
   margin-top: auto;
   padding-top: 14px;
   border-top: 1px solid var(--border-subtle);
   display: flex;
   flex-direction: column;
   gap: 8px;
}

.rail-account {
   display: flex;
   align-items: center;
   gap: 8px;
   min-width: 0;
   font-size: var(--text-caption);
   color: var(--color-slate);
}

.rail-account .material-symbols-rounded {
   font-size: 18px;
}

.main {
   display: flex;
   flex-direction: column;
   min-width: 0;
   height: 100dvh;
}

.topbar {
   display: flex;
   align-items: center;
   gap: 12px;
   height: var(--topbar-height);
   flex: none;
   padding: 0 24px;
   background: color-mix(in srgb, var(--surface-canvas) 86%, transparent);
   backdrop-filter: saturate(160%) blur(10px);
   border-bottom: 1px solid var(--border-subtle);
   z-index: 20;
}

.topbar-title {
   display: flex;
   align-items: baseline;
   gap: 10px;
   min-width: 0;
}

.topbar-title h1 {
   font-family: var(--font-display);
   font-size: var(--text-subheading);
   font-weight: var(--font-weight-medium);
   letter-spacing: -0.1px;
   white-space: nowrap;
}

.topbar-title span {
   font-size: var(--text-caption);
   color: var(--color-slate);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}

.topbar-spacer {
   flex: 1;
}

.content {
   flex: 1;
   min-height: 0;
   display: flex;
   flex-direction: column;
   gap: 16px;
   padding: 20px 24px 24px;
   overflow: hidden;
}

/*
 * .content 里只放着一个页面元素（<page-users> 这类自定义元素）。自定义元素默认是
 * inline，不会自动成为 flex 容器，于是它内部的 .table-wrap（flex: 1; min-height: 0）
 * 找不到有约束高度的父级，只会按内容一路撑高到「行数 × 行高」，再被 .content 的
 * overflow: hidden 整块裁掉 —— 表现就是列表完全滚不动，页面上也看不到滚动条。
 * 所以这里必须让页面元素自己成为列向 flex 容器，把高度约束传下去。
 */
.content > * {
   display: flex;
   flex-direction: column;
   gap: 16px;
   flex: 1;
   min-height: 0;
}

/*
 * 整页滚动的页面（概览、用户详情）反过来：让页面按内容自然高度撑开，由 .content--scroll
 * 负责滚动。这里必须显式 flex: none —— 默认 flex-shrink: 1 会把页面压缩到容器高度，
 * 内容依旧被裁在内部，外层永远滚不动。
 */
.content--scroll > * {
   flex: none;
}

.content--scroll {
   overflow-y: auto;
   scrollbar-width: thin;
}

.page-head {
   display: flex;
   align-items: flex-end;
   gap: 16px;
   flex-wrap: wrap;
   /* 列表页里 .content 的剩余高度全部让给表格，标题与筛选条不能被压扁 */
   flex: none;
}

.page-head h2 {
   font-family: var(--font-display);
   font-size: var(--text-heading-sm);
   font-weight: var(--font-weight-medium);
   letter-spacing: var(--tracking-heading-sm);
}

.page-head-actions {
   margin-left: auto;
   display: flex;
   align-items: center;
   gap: 8px;
}

/* --- 按钮 ---------------------------------------------------------------- */

.btn {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   height: 34px;
   padding: 0 14px;
   border: 1px solid transparent;
   border-radius: var(--radius-lg);
   background: transparent;
   font-size: var(--text-body-sm);
   font-weight: var(--font-weight-medium);
   white-space: nowrap;
   cursor: pointer;
   transition: background var(--duration-fast) var(--ease-out),
      border-color var(--duration-fast) var(--ease-out), filter var(--duration-fast) var(--ease-out);
}

.btn .material-symbols-rounded {
   font-size: 18px;
}

.btn:disabled,
.btn[aria-disabled='true'] {
   opacity: 0.42;
   pointer-events: none;
}

.btn--primary {
   background: var(--color-chatmoe-blue);
   color: light-dark(oklch(1 0 0), oklch(0.16 0.02 255));
}

.btn--primary:hover {
   filter: brightness(0.94);
}

.btn--outline {
   border-color: var(--border-strong);
   background: var(--surface-raised);
   color: var(--color-charcoal-ink);
}

.btn--outline:hover {
   background: var(--surface-hover);
}

.btn--ghost {
   color: var(--color-graphite);
}

.btn--ghost:hover {
   background: var(--surface-hover);
   color: var(--color-charcoal-ink);
}

.btn--danger {
   border-color: color-mix(in srgb, var(--color-critical) 45%, transparent);
   color: var(--color-critical);
}

.btn--danger:hover {
   background: color-mix(in srgb, var(--color-critical) 12%, transparent);
}

.btn--sm {
   height: 28px;
   padding: 0 10px;
   font-size: var(--text-caption);
}

.btn--sm .material-symbols-rounded {
   font-size: 16px;
}

.icon-btn {
   display: grid;
   place-items: center;
   width: 34px;
   height: 34px;
   flex: none;
   border: 1px solid transparent;
   border-radius: var(--radius-lg);
   background: transparent;
   color: var(--color-graphite);
   cursor: pointer;
   transition: background var(--duration-fast) var(--ease-out);
}

.icon-btn:hover {
   background: var(--surface-hover);
   color: var(--color-charcoal-ink);
}

/* --- 表单 ---------------------------------------------------------------- */

.field {
   display: flex;
   flex-direction: column;
   gap: 6px;
}

.field > label,
.field-label {
   font-size: var(--text-caption);
   color: var(--color-slate);
}

.input,
.select,
.textarea {
   height: 34px;
   padding: 0 10px;
   border: 1px solid var(--border-strong);
   border-radius: var(--radius-lg);
   background: var(--surface-raised);
   color: var(--color-charcoal-ink);
   font-size: var(--text-body-sm);
   transition: border-color var(--duration-fast) var(--ease-out);
}

.textarea {
   height: auto;
   min-height: 72px;
   padding: 8px 10px;
   resize: vertical;
   line-height: var(--leading-body-sm);
   font-family: inherit;
}

.input:hover,
.select:hover,
.textarea:hover {
   border-color: var(--color-cloud-shadow);
}

.input:focus,
.select:focus,
.textarea:focus {
   outline: none;
   border-color: var(--color-chatmoe-blue);
   box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-chatmoe-blue) 18%, transparent);
}

.input::placeholder,
.textarea::placeholder {
   color: var(--color-cloud-shadow);
}

.input--search {
   padding-left: 32px;
   min-width: 220px;
}

.search {
   position: relative;
   display: inline-flex;
   align-items: center;
}

.search .material-symbols-rounded {
   position: absolute;
   left: 8px;
   font-size: 18px;
   color: var(--color-slate);
   pointer-events: none;
}

.search-clear {
   position: absolute;
   right: 4px;
   width: 24px;
   height: 24px;
   display: grid;
   place-items: center;
   border: 0;
   border-radius: var(--radius-md);
   background: transparent;
   color: var(--color-slate);
   cursor: pointer;
}

.search-clear .material-symbols-rounded {
   position: static;
   font-size: 16px;
}

.search-clear:hover {
   background: var(--surface-hover);
   color: var(--color-charcoal-ink);
}

.filter-bar {
   display: flex;
   align-items: center;
   gap: 8px;
   flex-wrap: wrap;
   flex: none;
   padding: 10px 12px;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-2xl);
   background: var(--surface-raised);
}

.filter-bar .filter-bar-spacer {
   flex: 1;
}

.segmented {
   display: inline-flex;
   padding: 2px;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-lg);
   background: var(--surface-sunken);
}

.segmented button {
   height: 28px;
   padding: 0 12px;
   border: 0;
   border-radius: 6px;
   background: transparent;
   color: var(--color-slate);
   font-size: var(--text-caption);
   cursor: pointer;
   transition: background var(--duration-fast) var(--ease-out),
      color var(--duration-fast) var(--ease-out);
}

.segmented button:hover {
   color: var(--color-charcoal-ink);
}

.segmented button[aria-pressed='true'] {
   background: var(--surface-raised);
   color: var(--color-charcoal-ink);
   font-weight: var(--font-weight-medium);
   box-shadow: 0 1px 2px light-dark(oklch(0.21 0.006 264 / 0.08), oklch(0 0 0 / 0.4));
}

/* --- 面板与卡片 ---------------------------------------------------------- */

.panel {
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-2xl);
   background: var(--surface-raised);
}

.panel-head {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 14px 18px;
   border-bottom: 1px solid var(--border-subtle);
}

.panel-head h3 {
   font-size: var(--text-body);
   font-weight: var(--font-weight-medium);
}

.panel-head .panel-head-actions {
   margin-left: auto;
   display: flex;
   align-items: center;
   gap: 6px;
}

.panel-body {
   padding: 16px 18px;
}

/* 概览页的「今日简报」：先给一句话结论，再给数字带。
   运营打开后台的第一眼应该是「今天怎么样」，而不是自己从 8 个数字里推 */
.brief {
   display: flex;
   gap: 14px;
   padding: 16px 18px;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-2xl);
   background:
      linear-gradient(
         180deg,
         color-mix(in srgb, var(--color-chatmoe-blue) 7%, transparent),
         transparent 92%
      ),
      var(--surface-raised);
}

.brief-mark {
   flex: none;
   display: grid;
   place-items: center;
   width: 34px;
   height: 34px;
   border-radius: var(--radius-lg);
   background: color-mix(in srgb, var(--color-chatmoe-blue) 14%, transparent);
   color: var(--color-chatmoe-blue);
}

.brief p {
   font-size: var(--text-body);
   line-height: 1.6;
   max-width: 82ch;
}

.brief p b {
   font-weight: var(--font-weight-medium);
   font-variant-numeric: tabular-nums;
}

.brief-meta {
   margin-top: 6px;
}

/* --- 指标带 -------------------------------------------------------------- */

/* 一个被内部分隔的表带，而不是四张各自带阴影的卡片：
   数字之间可比才是一排指标的意义，卡片化会把它们拆成四个独立对象 */
.stat-band {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-2xl);
   background: var(--surface-raised);
   overflow: hidden;
}

.stat {
   padding: 14px 18px 16px;
   border-left: 1px solid var(--border-subtle);
   border-top: 1px solid var(--border-subtle);
}

.stat:first-child {
   border-left: 0;
}

.stat-value {
   display: flex;
   align-items: baseline;
   gap: 6px;
   margin-top: 6px;
   font-family: var(--font-display);
   font-size: var(--text-heading-sm);
   line-height: 1.15;
   font-weight: var(--font-weight-medium);
   letter-spacing: var(--tracking-heading-sm);
   font-variant-numeric: tabular-nums;
}

.stat-unit {
   font-size: var(--text-caption);
   font-weight: var(--font-weight-regular);
   color: var(--color-slate);
}

.stat-note {
   margin-top: 4px;
   font-size: var(--text-caption);
   color: var(--color-slate);
}

.stat-note.is-warn {
   color: var(--color-warning);
}

.grid-2 {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
   gap: 16px;
}

/*
 * 栅格项默认 min-width: auto，即「不许窄于内容的最小宽度」。趋势图里的 <svg> 是替换元素，
 * 它的内在宽度来自 width 属性（首帧由组件给值），于是这个内在宽度会顶到栅格轨道上：
 * 卡片被撑到比轨道宽，整个 .grid-2 溢出内容区；等 ResizeObserver 量到新宽度再重排，
 * 又变成一次可见的跳动。把下限交给 minmax() 里的 340px 管，内容不许反过来定尺寸。
 */
.grid-2 > * {
   min-width: 0;
}

/* --- 图表 ---------------------------------------------------------------- */

/*
 * 自定义元素默认是 inline —— 与 .content > * 里那个坑同源，但 <trend-chart> 不是
 * .content 的直接子元素，拿不到那条规则。
 *
 * 这里的后果比「撑不开列表」更隐蔽：inline 的宿主里塞一个块级 .chart，宿主会被拆成
 * 前后两个空片段，ResizeObserver 量到的宽度是 0，组件就退回默认宽度，SVG 于是按
 * 720px 的真实像素坐标画进一个只有几百 px 宽的卡片里，折线直接溢出卡片。
 * 所以必须显式声明成块级，让宿主自己就是被观测的那个盒子。
 */
trend-chart {
   display: block;
   width: 100%;
}

.chart {
   position: relative;
   width: 100%;
}

/*
 * 这里刻意不写 overflow: visible。折线用的是量出来的真实像素坐标，本就不该越界；
 * 而量宽一旦失效，visible 会把「坐标算错」放大成「图形溢出卡片、盖住旁边的面板」，
 * 默认的裁剪至少把影响圈在卡片内。
 */
.chart svg {
   display: block;
   width: 100%;
}

.chart-line {
   fill: none;
   stroke: var(--color-chatmoe-blue);
   stroke-width: 2;
   stroke-linecap: round;
   stroke-linejoin: round;
}

.chart-area {
   fill: url(#chart-gradient);
   stroke: none;
}

.chart-grid {
   stroke: var(--border-subtle);
   stroke-width: 1;
}

.chart-axis {
   fill: var(--color-cloud-shadow);
   font-size: 10px;
   font-variant-numeric: tabular-nums;
}

.chart-crosshair {
   stroke: var(--border-strong);
   stroke-width: 1;
   stroke-dasharray: 3 3;
}

.chart-dot {
   fill: var(--surface-raised);
   stroke: var(--color-chatmoe-blue);
   stroke-width: 2;
}

.chart-hit {
   fill: transparent;
   cursor: crosshair;
}

.chart-tip {
   position: absolute;
   z-index: 3;
   min-width: 132px;
   padding: 8px 10px;
   border: 1px solid var(--border-strong);
   border-radius: var(--radius-lg);
   background: var(--surface-raised);
   box-shadow: var(--shadow-pop);
   pointer-events: none;
   font-size: var(--text-caption);
   font-variant-numeric: tabular-nums;
}

.chart-tip b {
   display: block;
   font-size: var(--text-body-sm);
   font-weight: var(--font-weight-medium);
}

.chart-tip span {
   display: block;
   color: var(--color-slate);
}

.chart-empty {
   display: grid;
   place-items: center;
   height: 220px;
   color: var(--color-slate);
   font-size: var(--text-caption);
}

/* --- 表格 ---------------------------------------------------------------- */

.table-wrap {
   flex: 1;
   min-height: 0;
   overflow: auto;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-2xl);
   background: var(--surface-raised);
   scrollbar-width: thin;
}

table.data {
   width: 100%;
   border-collapse: separate;
   border-spacing: 0;
}

.data thead th {
   position: sticky;
   top: 0;
   z-index: 2;
   height: 36px;
   padding: 0 14px;
   background: var(--surface-sunken);
   border-bottom: 1px solid var(--border-subtle);
   font-size: var(--text-micro);
   font-weight: var(--font-weight-medium);
   letter-spacing: var(--tracking-micro);
   color: var(--color-slate);
   text-align: left;
   white-space: nowrap;
}

.data thead th.is-sortable {
   cursor: pointer;
   user-select: none;
}

.data thead th.is-sortable:hover {
   color: var(--color-charcoal-ink);
}

.sort-caret {
   margin-left: 4px;
   font-size: 13px;
   opacity: 0.85;
}

.data tbody td {
   height: var(--row-height);
   padding: 0 14px;
   border-bottom: 1px solid var(--border-subtle);
   white-space: nowrap;
   vertical-align: middle;
}

.data tbody tr:last-child td {
   border-bottom: 0;
}

.data tbody tr.is-clickable {
   cursor: pointer;
}

.data tbody tr.is-clickable:hover {
   background: var(--surface-hover);
}

.data tbody tr.is-clickable:active {
   background: var(--surface-active);
}

.data tbody tr.is-selected {
   background: color-mix(in srgb, var(--color-chatmoe-blue) 9%, transparent);
}

.data td.right,
.data th.right {
   text-align: right;
}

.cell-id {
   font-family: var(--font-mono);
   font-size: var(--text-caption);
   color: var(--color-slate);
   cursor: copy;
}

.cell-id:hover {
   color: var(--color-charcoal-ink);
}

/*
 * 外链（用户站点等「点开就离开操作台」的地址）。
 * 尾部的小图标是唯一的提示：表格里的蓝色文字常常被读成「页内跳转」，
 * 有了 open_in_new，点之前就知道会另开一个标签页。
 */
.ext-link {
   display: inline-flex;
   align-items: center;
   gap: 4px;
   max-width: 100%;
   min-width: 0;
}

.ext-link .material-symbols-rounded {
   flex: none;
   font-size: 15px;
   color: var(--color-cloud-shadow);
}

.ext-link:hover .material-symbols-rounded {
   color: var(--color-chatmoe-blue);
}

.cell-stack {
   display: flex;
   flex-direction: column;
   gap: 2px;
   min-width: 0;
}

.cell-stack small {
   font-size: var(--text-micro);
   color: var(--color-slate);
}

.cell-email {
   font-weight: var(--font-weight-medium);
}

/* --- 状态点 / 标签 ------------------------------------------------------- */

.pill {
   display: inline-flex;
   align-items: center;
   gap: 6px;
   height: 22px;
   padding: 0 9px 0 8px;
   border-radius: var(--radius-full);
   border: 1px solid var(--border-subtle);
   background: var(--surface-sunken);
   font-size: var(--text-micro);
   letter-spacing: var(--tracking-micro);
   color: var(--color-graphite);
   white-space: nowrap;
}

.pill::before {
   content: '';
   width: 6px;
   height: 6px;
   flex: none;
   border-radius: 50%;
   background: var(--color-neutral);
}

.pill--ok {
   color: var(--color-success);
   border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
}

.pill--ok::before {
   background: var(--color-success);
}

.pill--warn {
   color: var(--color-warning);
   border-color: color-mix(in srgb, var(--color-warning) 32%, transparent);
}

.pill--warn::before {
   background: var(--color-warning);
}

.pill--danger {
   color: var(--color-critical);
   border-color: color-mix(in srgb, var(--color-critical) 30%, transparent);
}

.pill--danger::before {
   background: var(--color-critical);
}

.pill--brand {
   color: var(--color-chatmoe-blue);
   border-color: color-mix(in srgb, var(--color-chatmoe-blue) 32%, transparent);
}

.pill--brand::before {
   background: var(--color-chatmoe-blue);
}

.pill--plain::before {
   display: none;
}

/* --- 分页 ---------------------------------------------------------------- */

.pager {
   display: flex;
   align-items: center;
   gap: 8px;
   flex: none;
   font-size: var(--text-caption);
   color: var(--color-slate);
}

.pager .pager-spacer {
   flex: 1;
}

.pager-page {
   font-variant-numeric: tabular-nums;
   color: var(--color-charcoal-ink);
}

/* --- 抽屉 / 弹层 --------------------------------------------------------- */

dialog {
   padding: 0;
   border: 0;
   background: transparent;
   color: inherit;
   max-width: none;
   max-height: none;
}

dialog::backdrop {
   background: color-mix(in srgb, oklch(0.15 0.01 264) 42%, transparent);
   backdrop-filter: blur(1px);
}

.drawer {
   margin: 0 0 0 auto;
   width: min(100%, var(--drawer-width));
   height: 100dvh;
   border-left: 1px solid var(--border-subtle);
   background: var(--surface-canvas);
   box-shadow: var(--shadow-pop);
}

.drawer[open] {
   animation: drawer-in var(--duration-base) var(--ease-out);
}

@keyframes drawer-in {
   from {
      transform: translateX(16px);
      opacity: 0;
   }
}

.drawer-head {
   position: sticky;
   top: 0;
   z-index: 2;
   display: flex;
   align-items: flex-start;
   gap: 12px;
   padding: 16px 18px;
   background: color-mix(in srgb, var(--surface-canvas) 88%, transparent);
   backdrop-filter: blur(8px);
   border-bottom: 1px solid var(--border-subtle);
}

.drawer-head h3 {
   font-family: var(--font-display);
   font-size: var(--text-subheading);
   font-weight: var(--font-weight-medium);
}

.drawer-body {
   padding: 18px;
   display: flex;
   flex-direction: column;
   gap: 18px;
   overflow-y: auto;
   height: calc(100dvh - 61px);
   scrollbar-width: thin;
}

.drawer-actions {
   display: flex;
   gap: 8px;
   flex-wrap: wrap;
}

.modal {
   width: min(100% - 32px, 460px);
   margin: auto;
   border: 1px solid var(--border-strong);
   border-radius: var(--radius-2xl);
   background: var(--surface-canvas);
   box-shadow: var(--shadow-pop);
}

.modal[open] {
   animation: modal-in var(--duration-base) var(--ease-out);
}

@keyframes modal-in {
   from {
      transform: translateY(6px) scale(0.99);
      opacity: 0;
   }
}

.modal-head {
   padding: 18px 20px 0;
}

.modal-head h3 {
   font-family: var(--font-display);
   font-size: var(--text-subheading);
   font-weight: var(--font-weight-medium);
}

.modal-body {
   padding: 12px 20px 0;
   display: flex;
   flex-direction: column;
   gap: 12px;
}

.modal-foot {
   display: flex;
   justify-content: flex-end;
   gap: 8px;
   padding: 18px 20px;
}

.section {
   display: flex;
   flex-direction: column;
   gap: 10px;
}

.section-title {
   display: flex;
   align-items: center;
   gap: 8px;
   font-size: var(--text-caption);
   color: var(--color-slate);
   letter-spacing: var(--tracking-micro);
}

.section-title::after {
   content: '';
   flex: 1;
   height: 1px;
   background: var(--border-subtle);
}

.kv {
   display: grid;
   grid-template-columns: minmax(88px, auto) 1fr;
   gap: 8px 14px;
   font-size: var(--text-body-sm);
}

.kv dt {
   color: var(--color-slate);
}

.kv dd {
   margin: 0;
   min-width: 0;
   word-break: break-word;
}

.list {
   display: flex;
   flex-direction: column;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-lg);
   overflow: hidden;
}

.list-row {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 10px 12px;
   border-bottom: 1px solid var(--border-subtle);
   font-size: var(--text-caption);
}

.list-row:last-child {
   border-bottom: 0;
}

.list-row-main {
   min-width: 0;
   flex: 1;
}

.list-row-main b {
   display: block;
   font-size: var(--text-body-sm);
   font-weight: var(--font-weight-medium);
}

.list-row-main span {
   display: block;
   color: var(--color-slate);
}

.list-row-side {
   text-align: right;
   white-space: nowrap;
}

/* --- 空态 / 骨架 / 错误 -------------------------------------------------- */

.empty {
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
   gap: 8px;
   padding: 56px 24px;
   text-align: center;
   color: var(--color-slate);
}

.empty .material-symbols-rounded {
   font-size: 30px;
   color: var(--color-cloud-shadow);
}

.empty b {
   font-size: var(--text-body);
   font-weight: var(--font-weight-medium);
   color: var(--color-charcoal-ink);
}

.skeleton-row {
   height: var(--row-height);
   border-bottom: 1px solid var(--border-subtle);
   background: linear-gradient(
      90deg,
      var(--surface-sunken) 0%,
      var(--surface-hover) 40%,
      var(--surface-sunken) 80%
   );
   background-size: 300% 100%;
   animation: skeleton 1.4s ease-in-out infinite;
}

@keyframes skeleton {
   from {
      background-position: 120% 0;
   }
   to {
      background-position: -20% 0;
   }
}

.banner {
   display: flex;
   align-items: flex-start;
   gap: 10px;
   padding: 12px 14px;
   border: 1px solid color-mix(in srgb, var(--color-critical) 34%, transparent);
   border-radius: var(--radius-lg);
   background: color-mix(in srgb, var(--color-critical) 8%, transparent);
   font-size: var(--text-body-sm);
}

.banner--warn {
   border-color: color-mix(in srgb, var(--color-warning) 36%, transparent);
   background: color-mix(in srgb, var(--color-warning) 10%, transparent);
}

.banner .material-symbols-rounded {
   color: var(--color-critical);
   font-size: 18px;
}

.banner--warn .material-symbols-rounded {
   color: var(--color-warning);
}

.banner code {
   font-family: var(--font-mono);
   font-size: var(--text-caption);
}

/* --- 吐司 ---------------------------------------------------------------- */

.toasts {
   position: fixed;
   right: 20px;
   bottom: 20px;
   z-index: 60;
   display: flex;
   flex-direction: column;
   gap: 8px;
   pointer-events: none;
}

.toast {
   display: flex;
   align-items: center;
   gap: 8px;
   min-width: 200px;
   max-width: 380px;
   padding: 10px 14px;
   border: 1px solid var(--border-strong);
   border-radius: var(--radius-lg);
   background: var(--surface-raised);
   box-shadow: var(--shadow-pop);
   font-size: var(--text-body-sm);
   animation: toast-in var(--duration-base) var(--ease-out);
   pointer-events: auto;
}

.toast .material-symbols-rounded {
   font-size: 18px;
   color: var(--color-slate);
}

.toast--ok .material-symbols-rounded {
   color: var(--color-success);
}

.toast--error .material-symbols-rounded {
   color: var(--color-critical);
}

@keyframes toast-in {
   from {
      transform: translateY(8px);
      opacity: 0;
   }
}

/* --- 命令面板 ------------------------------------------------------------ */

.palette {
   width: min(100% - 32px, 560px);
   margin: 12vh auto auto;
   border: 1px solid var(--border-strong);
   border-radius: var(--radius-2xl);
   background: var(--surface-canvas);
   box-shadow: var(--shadow-pop);
   overflow: hidden;
}

.palette-input {
   width: 100%;
   height: 52px;
   padding: 0 18px;
   border: 0;
   border-bottom: 1px solid var(--border-subtle);
   background: transparent;
   color: inherit;
   font-size: var(--text-body);
}

.palette-input:focus {
   outline: none;
}

.palette-list {
   max-height: 320px;
   overflow-y: auto;
   padding: 6px;
   scrollbar-width: thin;
}

.palette-item {
   display: flex;
   align-items: center;
   gap: 10px;
   width: 100%;
   height: 40px;
   padding: 0 12px;
   border: 0;
   border-radius: var(--radius-lg);
   background: transparent;
   font-size: var(--text-body-sm);
   text-align: left;
   cursor: pointer;
}

.palette-item .material-symbols-rounded {
   font-size: 18px;
   color: var(--color-slate);
}

.palette-item[aria-selected='true'] {
   background: color-mix(in srgb, var(--color-chatmoe-blue) 12%, transparent);
}

.palette-hint {
   margin-left: auto;
   font-size: var(--text-micro);
   color: var(--color-cloud-shadow);
}

.palette-foot {
   padding: 8px 14px;
   border-top: 1px solid var(--border-subtle);
   font-size: var(--text-micro);
   color: var(--color-slate);
}

/* --- 登录页 -------------------------------------------------------------- */

.login {
   display: grid;
   place-items: center;
   min-height: 100dvh;
   padding: 24px;
   background:
      radial-gradient(
         1100px 520px at 50% -10%,
         color-mix(in srgb, var(--color-chatmoe-blue) 16%, transparent),
         transparent 70%
      ),
      var(--surface-canvas);
}

.login-card {
   width: min(100%, 392px);
   padding: 28px;
   border: 1px solid var(--border-subtle);
   border-radius: var(--radius-3xl);
   background: var(--surface-raised);
   box-shadow: var(--shadow-pop);
}

.login-brand {
   display: flex;
   align-items: center;
   gap: 10px;
   margin-bottom: 20px;
}

.login-card h1 {
   font-family: var(--font-display);
   font-size: var(--text-heading-sm);
   font-weight: var(--font-weight-medium);
   letter-spacing: var(--tracking-heading-sm);
}

.login-card form {
   display: flex;
   flex-direction: column;
   gap: 14px;
   margin-top: 18px;
}

.login-card .btn--primary {
   height: 38px;
   justify-content: center;
}

.login-foot {
   margin-top: 16px;
   font-size: var(--text-caption);
   color: var(--color-slate);
}

.login-lang {
   position: fixed;
   top: 20px;
   right: 20px;
}

/* --- 工具类 -------------------------------------------------------------- */

.stack {
   display: flex;
   flex-direction: column;
   gap: 16px;
}

.row {
   display: flex;
   align-items: center;
   gap: 8px;
   flex-wrap: wrap;
}

.hidden {
   display: none !important;
}

.sr-only {
   position: absolute;
   width: 1px;
   height: 1px;
   padding: 0;
   margin: -1px;
   overflow: hidden;
   clip: rect(0 0 0 0);
   white-space: nowrap;
   border: 0;
}

/* --- 响应式 -------------------------------------------------------------- */

@media (max-width: 1180px) {
   .shell {
      grid-template-columns: var(--rail-width-compact) minmax(0, 1fr);
   }

   .rail {
      padding: 14px 10px;
   }

   .rail-wordmark,
   .rail-link-label,
   .rail-link-key,
   .rail-account span {
      display: none;
   }

   .rail-brand {
      justify-content: center;
      padding: 6px 0 12px;
   }

   .rail-link {
      justify-content: center;
      padding: 0;
   }

   .rail-link[aria-current='page']::before {
      left: -10px;
   }

   .rail-foot .btn--ghost .material-symbols-rounded + * {
      display: none;
   }
}

@media (max-width: 820px) {
   .topbar {
      padding: 0 14px;
   }

   .content {
      padding: 14px 14px 18px;
   }

   .stat {
      border-left: 0;
   }

   .drawer {
      width: 100%;
   }

   .filter-bar {
      gap: 6px;
   }
}

@media (prefers-reduced-motion: reduce) {
   *,
   *::before,
   *::after {
      animation-duration: 0.001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important;
   }
}
