﻿/* ============================================================
   PKD.Work — 设计系统
   一套自研的精细化设计语言：柔和渐变、玻璃拟态、细腻阴影与微动效
   ============================================================ */

/* ---------- 设计令牌 ---------- */
:root {
    /* 主色：靛蓝 → 紫罗兰 */
    --brand-50: #eef2ff;
    --brand-100: #e0e7ff;
    --brand-200: #c7d2fe;
    --brand-300: #a5b4fc;
    --brand-400: #818cf8;
    --brand-500: #6366f1;
    --brand-600: #4f46e5;
    --brand-700: #4338ca;
    --brand-800: #3730a3;

    --accent-400: #a78bfa;
    --accent-500: #8b5cf6;
    --accent-600: #7c3aed;

    --cyan-400: #22d3ee;
    --cyan-500: #06b6d4;
    --emerald-400: #34d399;
    --emerald-500: #10b981;
    --amber-400: #fbbf24;
    --amber-500: #f59e0b;
    --rose-400: #fb7185;
    --rose-500: #f43f5e;

    /* 语义色 */
    --bg: #f6f7fb;
    --bg-elevated: #ffffff;
    --bg-subtle: #f1f3f9;
    --bg-inset: #fafbfd;
    --surface-glass: rgba(255, 255, 255, 0.72);

    /* 面板里的次级底色与次级文字。这两组之前被引用但没定义，
       导致表格工具条底色、Word 引用块文字色实际是静默失效的。 */
    --surface-1: #ffffff;
    --surface-2: rgba(20, 22, 31, 0.035);
    --surface-3: rgba(20, 22, 31, 0.06);
    --text-soft: #4a4f63;

    /* 透明区域的棋盘格底纹（画布与图层缩略图共用） */
    --checker-base: #ffffff;
    --checker-ink: rgba(20, 22, 31, 0.10);

    --text-strong: #14161f;
    --text: #33374a;
    --text-muted: #6b7189;
    --text-faint: #9aa0b4;

    --border: rgba(20, 22, 31, 0.08);
    --border-strong: rgba(20, 22, 31, 0.14);
    --border-subtle: rgba(20, 22, 31, 0.05);

    --brand-soft: rgba(99, 102, 241, 0.10);
    --brand-softer: rgba(99, 102, 241, 0.06);

    /* 阴影 —— 多层叠加，柔和自然 */
    --shadow-xs: 0 1px 2px rgba(20, 22, 31, 0.04);
    --shadow-sm: 0 1px 3px rgba(20, 22, 31, 0.05), 0 1px 2px rgba(20, 22, 31, 0.03);
    --shadow-md: 0 4px 12px -2px rgba(20, 22, 31, 0.07), 0 2px 4px -2px rgba(20, 22, 31, 0.04);
    --shadow-lg: 0 12px 32px -8px rgba(20, 22, 31, 0.12), 0 4px 10px -4px rgba(20, 22, 31, 0.06);
    --shadow-xl: 0 24px 56px -12px rgba(20, 22, 31, 0.18), 0 8px 20px -8px rgba(20, 22, 31, 0.08);
    --shadow-brand: 0 8px 24px -6px rgba(99, 102, 241, 0.45);
    --ring: 0 0 0 3px rgba(99, 102, 241, 0.18);

    /* 圆角 */
    --r-xs: 6px;
    --r-sm: 9px;
    --r-md: 12px;
    --r-lg: 16px;
    --r-xl: 22px;
    --r-full: 999px;

    /* 动效 */
    --ease: cubic-bezier(.4, 0, .2, 1);
    --ease-out: cubic-bezier(.16, 1, .3, 1);
    --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
    --t-fast: 120ms;
    --t: 200ms;
    --t-slow: 380ms;

    /* 布局 */
    --sidebar-w: 252px;
    --topbar-h: 60px;

    --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --font-mono: "JetBrains Mono", "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", "Cascadia Code", monospace;
}

/* ---------- 暗色主题 ---------- */
[data-theme="dark"] {
    --bg: #0a0d17;
    --bg-elevated: #121624;
    --bg-subtle: #0e1220;
    --bg-inset: #161b2c;
    --surface-glass: rgba(18, 22, 36, 0.72);

    --surface-1: #1a2033;
    --surface-2: rgba(255, 255, 255, 0.045);
    --surface-3: rgba(255, 255, 255, 0.075);
    --text-soft: #b9c0d4;

    --checker-base: #1c2333;
    --checker-ink: rgba(255, 255, 255, 0.075);

    --text-strong: #f2f4fb;
    --text: #d5dae9;
    --text-muted: #8b93ad;
    --text-faint: #626a85;

    --border: rgba(255, 255, 255, 0.09);
    --border-strong: rgba(255, 255, 255, 0.16);
    --border-subtle: rgba(255, 255, 255, 0.06);

    --brand-soft: rgba(129, 140, 248, 0.16);
    --brand-softer: rgba(129, 140, 248, 0.09);

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 4px 14px -2px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 14px 36px -8px rgba(0, 0, 0, 0.55);
    --shadow-xl: 0 26px 60px -12px rgba(0, 0, 0, 0.68);
    --shadow-brand: 0 8px 26px -6px rgba(99, 102, 241, 0.55);
    --ring: 0 0 0 3px rgba(129, 140, 248, 0.28);
}

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

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    font-family: var(--font-sans);
    font-size: 14px;
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

body { overflow: hidden; }

app { display: block; height: 100%; }

h1, h2, h3, h4, h5 { margin: 0; color: var(--text-strong); font-weight: 650; letter-spacing: -0.02em; }
p { margin: 0; }

a { color: var(--brand-600); text-decoration: none; transition: color var(--t) var(--ease); }
a:hover { color: var(--brand-500); }

::selection { background: var(--brand-200); color: var(--brand-800); }
[data-theme="dark"] ::selection { background: rgba(129, 140, 248, .32); color: #fff; }

/* 滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--border-strong);
    border-radius: var(--r-full);
    border: 3px solid transparent;
    background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }

/* ---------- 应用外壳 ---------- */
.app-shell {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    height: 100vh;
    overflow: hidden;
    position: relative;
}

.app-shell.sidebar-collapsed { grid-template-columns: 72px 1fr; }

/* 背景光晕 */
.app-shell::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    background:
        radial-gradient(760px 460px at 12% -6%, rgba(99, 102, 241, .10), transparent 62%),
        radial-gradient(680px 420px at 92% 4%, rgba(139, 92, 246, .09), transparent 60%),
        radial-gradient(620px 400px at 60% 104%, rgba(34, 211, 238, .06), transparent 62%);
    transition: opacity var(--t-slow) var(--ease);
}
[data-theme="dark"] .app-shell::before {
    background:
        radial-gradient(760px 460px at 12% -6%, rgba(99, 102, 241, .16), transparent 62%),
        radial-gradient(680px 420px at 92% 4%, rgba(139, 92, 246, .13), transparent 60%),
        radial-gradient(620px 400px at 60% 104%, rgba(34, 211, 238, .08), transparent 62%);
}

/* ---------- 侧边栏 ---------- */
.sidebar {
    position: relative;
    z-index: 3;
    display: flex;
    flex-direction: column;
    background: var(--surface-glass);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-right: 1px solid var(--border);
    height: 100vh;
    overflow: hidden;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    height: var(--topbar-h);
    padding: 0 18px;
    flex: 0 0 auto;
    border-bottom: 1px solid var(--border-subtle);
}

.brand-mark {
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    border-radius: 11px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    box-shadow: var(--shadow-brand);
    color: #fff;
    position: relative;
    overflow: hidden;
}
.brand-mark::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(255,255,255,.35), transparent 55%);
}
.brand-mark svg { position: relative; z-index: 1; }

.brand-text { display: flex; flex-direction: column; min-width: 0; }
.brand-title {
    font-size: 14.5px;
    font-weight: 700;
    color: var(--text-strong);
    letter-spacing: -0.015em;
    line-height: 1.25;
    white-space: nowrap;
}
.brand-sub {
    font-size: 10.5px;
    color: var(--text-faint);
    letter-spacing: .09em;
    text-transform: uppercase;
    line-height: 1.3;
    white-space: nowrap;
}

.sidebar-search {
    padding: 12px 14px 6px;
    flex: 0 0 auto;
}

.sidebar-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 6px 10px 18px;
    scrollbar-width: thin;
}

.nav-group-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 14px 10px 6px;
    white-space: nowrap;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 8px 11px;
    margin: 2px 0;
    border: none;
    border-radius: var(--r-md);
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    position: relative;
    transition: background var(--t) var(--ease), color var(--t) var(--ease), transform var(--t) var(--ease);
    white-space: nowrap;
}
.nav-item:hover { background: var(--brand-softer); color: var(--text-strong); }
.nav-item:active { transform: scale(.985); }

.nav-item .nav-icon {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    display: grid;
    place-items: center;
    color: var(--text-faint);
    transition: color var(--t) var(--ease);
}
.nav-item:hover .nav-icon { color: var(--brand-500); }

.nav-item.active {
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    color: #fff;
    box-shadow: var(--shadow-brand);
    font-weight: 600;
}
.nav-item.active .nav-icon { color: #fff; }
.nav-item.active::before {
    content: "";
    position: absolute;
    left: -10px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 18px;
    border-radius: var(--r-full);
    background: var(--brand-500);
}

.nav-badge {
    margin-left: auto;
    font-size: 10px;
    font-weight: 600;
    padding: 1px 7px;
    border-radius: var(--r-full);
    background: var(--emerald-500);
    color: #fff;
    letter-spacing: .02em;
}

.sidebar-footer {
    flex: 0 0 auto;
    border-top: 1px solid var(--border-subtle);
    padding: 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* 折叠态 */
.sidebar-collapsed .brand-text,
.sidebar-collapsed .nav-group-label span,
.sidebar-collapsed .nav-item span.nav-label,
.sidebar-collapsed .sidebar-search,
.sidebar-collapsed .nav-badge { display: none; }
.sidebar-collapsed .nav-item { justify-content: center; padding: 10px 0; }
.sidebar-collapsed .nav-item.active::before { left: 0; }
.sidebar-collapsed .nav-group-label { text-align: center; padding: 12px 0 4px; font-size: 9px; }

/* ---------- 主区域 ---------- */
.main-area {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    height: 100vh;
    min-width: 0;
    overflow: hidden;
}

.topbar {
    flex: 0 0 var(--topbar-h);
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 22px;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--surface-glass);
    backdrop-filter: saturate(180%) blur(16px);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
}

.topbar-title { font-size: 15px; font-weight: 650; color: var(--text-strong); }
.topbar-crumb { font-size: 12px; color: var(--text-faint); }
.topbar-spacer { flex: 1 1 auto; }

.content-scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 26px 30px 60px;
    scroll-behavior: smooth;
}

/* fill-mode 用 backwards 而不是 both：both 会在动画结束后把 to 帧永久挂在元素上，
   Edge 里表现为恒等 transform——任何非 none 的 transform 都会成为 position:fixed
   后代的包含块，把 .fs-css 全屏兜底关进内容列（页头/侧栏露出来、底部超出视口）。 */
.page-enter { animation: pageIn var(--t-slow) var(--ease-out) backwards; }
@keyframes pageIn {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

/* ---------- 通用卡片 / 面板 ---------- */
.panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.panel-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border-subtle);
    background: linear-gradient(180deg, var(--bg-inset), transparent);
}
.panel-title { font-size: 13px; font-weight: 650; color: var(--text-strong); }
.panel-body { padding: 16px; }
.panel-flush { padding: 0; }

/* ---------- 按钮 ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 8px 15px;
    border-radius: var(--r-sm);
    border: 1px solid var(--border-strong);
    background: var(--bg-elevated);
    color: var(--text);
    font-family: inherit;
    font-size: 13px;
    font-weight: 550;
    line-height: 1.4;
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--t) var(--ease);
    box-shadow: var(--shadow-xs);
    user-select: none;
}
.btn:hover { border-color: var(--brand-300); color: var(--brand-600); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(0) scale(.985); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }

.btn-primary {
    border-color: transparent;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    color: #fff;
    box-shadow: var(--shadow-brand);
}
.btn-primary:hover {
    color: #fff;
    filter: brightness(1.07);
    box-shadow: 0 10px 28px -6px rgba(99, 102, 241, .55);
}

.btn-ghost { border-color: transparent; background: transparent; box-shadow: none; }
.btn-ghost:hover { background: var(--brand-softer); box-shadow: none; }

.btn-danger { border-color: rgba(244, 63, 94, .3); color: var(--rose-500); background: rgba(244, 63, 94, .06); }
.btn-danger:hover { background: rgba(244, 63, 94, .12); border-color: var(--rose-400); color: var(--rose-500); }

.btn-sm { padding: 5px 11px; font-size: 12px; border-radius: var(--r-xs); gap: 5px; }
.btn-icon { padding: 7px; width: 32px; height: 32px; border-radius: var(--r-sm); }
.btn-icon.btn-sm { width: 26px; height: 26px; padding: 4px; }

/* ---------- 输入控件 ---------- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: .01em;
    display: flex;
    align-items: center;
    gap: 6px;
}
.field-hint { font-size: 11.5px; color: var(--text-faint); font-weight: 400; }

.input, .textarea, .select {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
    background: var(--bg-inset);
    color: var(--text-strong);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.55;
    transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease), background var(--t) var(--ease);
    outline: none;
}
.input:hover, .textarea:hover, .select:hover { border-color: var(--brand-300); }
.input:focus, .textarea:focus, .select:focus {
    border-color: var(--brand-400);
    box-shadow: var(--ring);
    background: var(--bg-elevated);
}
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }
.input:disabled, .textarea:disabled { opacity: .6; cursor: not-allowed; }

.textarea { resize: vertical; min-height: 96px; }
.textarea.mono, .input.mono { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: -0.005em; }

.input-group { display: flex; gap: 8px; align-items: center; }
.input-group .input { flex: 1 1 auto; }

/* 搜索输入带图标 */
.search-wrap { position: relative; display: flex; align-items: center; }
.search-wrap .search-icon {
    position: absolute;
    left: 11px;
    color: var(--text-faint);
    pointer-events: none;
    display: grid;
    place-items: center;
}
.search-wrap .input { padding-left: 34px; }
.search-wrap .search-clear {
    position: absolute;
    right: 8px;
    border: none;
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    display: grid;
    place-items: center;
    padding: 3px;
    border-radius: var(--r-xs);
}
.search-wrap .search-clear:hover { color: var(--text); background: var(--bg-subtle); }

/* ---------- 分段选择器（替代 RadioGroup） ---------- */
.segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 3px;
    padding: 3px;
    background: var(--bg-subtle);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-md);
}
.segmented-item {
    border: none;
    background: transparent;
    padding: 5px 13px;
    border-radius: calc(var(--r-md) - 4px);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 550;
    color: var(--text-muted);
    cursor: pointer;
    transition: all var(--t) var(--ease);
    line-height: 1.5;
}
.segmented-item:hover { color: var(--text-strong); }
.segmented-item.active {
    background: var(--bg-elevated);
    color: var(--brand-600);
    box-shadow: var(--shadow-xs);
}
[data-theme="dark"] .segmented-item.active { color: var(--brand-300); }
.segmented-item:focus-visible { outline: none; box-shadow: var(--ring); }

/* ---------- 开关 ---------- */
.switch {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    cursor: pointer;
    user-select: none;
    font-size: 13px;
    color: var(--text);
}
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
    width: 38px;
    height: 21px;
    border-radius: var(--r-full);
    background: var(--border-strong);
    position: relative;
    transition: background var(--t) var(--ease);
    flex: 0 0 38px;
}
.switch-track::after {
    content: "";
    position: absolute;
    top: 2.5px;
    left: 2.5px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: var(--shadow-sm);
    transition: transform var(--t) var(--ease-spring);
}
.switch input:checked + .switch-track { background: linear-gradient(135deg, var(--brand-500), var(--accent-500)); }
.switch input:checked + .switch-track::after { transform: translateX(17px); }
.switch input:focus-visible + .switch-track { box-shadow: var(--ring); }

/* ---------- 标签 ---------- */
.tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: var(--r-full);
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.6;
    background: var(--bg-subtle);
    color: var(--text-muted);
    border: 1px solid var(--border-subtle);
    white-space: nowrap;
}
.tag-brand { background: var(--brand-soft); color: var(--brand-600); border-color: transparent; }
.tag-emerald { background: rgba(16, 185, 129, .12); color: #059669; border-color: transparent; }
.tag-amber { background: rgba(245, 158, 11, .13); color: #b45309; border-color: transparent; }
.tag-rose { background: rgba(244, 63, 94, .12); color: #e11d48; border-color: transparent; }
.tag-cyan { background: rgba(6, 182, 212, .13); color: #0891b2; border-color: transparent; }
.tag-violet { background: rgba(139, 92, 246, .13); color: #7c3aed; border-color: transparent; }
[data-theme="dark"] .tag-emerald { color: var(--emerald-400); }
[data-theme="dark"] .tag-amber { color: var(--amber-400); }
[data-theme="dark"] .tag-rose { color: var(--rose-400); }
[data-theme="dark"] .tag-cyan { color: var(--cyan-400); }
[data-theme="dark"] .tag-violet { color: var(--accent-400); }
[data-theme="dark"] .tag-brand { color: var(--brand-300); }

/* ---------- 提示条 ---------- */
.alert {
    display: flex;
    gap: 10px;
    padding: 11px 13px;
    border-radius: var(--r-md);
    font-size: 12.5px;
    line-height: 1.6;
    border: 1px solid transparent;
}
.alert-error {
    background: rgba(244, 63, 94, .08);
    border-color: rgba(244, 63, 94, .22);
    color: #b91c50;
}
.alert-info {
    background: var(--brand-softer);
    border-color: rgba(99, 102, 241, .2);
    color: var(--brand-700);
}
.alert-success {
    background: rgba(16, 185, 129, .09);
    border-color: rgba(16, 185, 129, .22);
    color: #047857;
}
[data-theme="dark"] .alert-error { color: var(--rose-400); }
[data-theme="dark"] .alert-info { color: var(--brand-300); }
[data-theme="dark"] .alert-success { color: var(--emerald-400); }
.alert-icon { flex: 0 0 16px; padding-top: 1px; }
.alert-body { flex: 1 1 auto; min-width: 0; word-break: break-word; }

/* ---------- Toast ---------- */
.toast-host {
    position: fixed;
    top: 18px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 4000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 16px;
    border-radius: var(--r-full);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    font-size: 13px;
    font-weight: 550;
    color: var(--text-strong);
    animation: toastIn var(--t-slow) var(--ease-spring) both;
    max-width: 78vw;
}
.toast.leaving { animation: toastOut var(--t) var(--ease) both; }
@keyframes toastIn { from { opacity: 0; transform: translateY(-14px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-10px) scale(.96); } }
.toast-icon { display: grid; place-items: center; flex: 0 0 16px; }
.toast-success .toast-icon { color: var(--emerald-500); }
.toast-error .toast-icon { color: var(--rose-500); }
.toast-info .toast-icon { color: var(--brand-500); }

/* ---------- 模态框 ---------- */
.modal-mask {
    position: fixed;
    inset: 0;
    z-index: 3000;
    background: rgba(10, 12, 22, .45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: grid;
    place-items: center;
    padding: 24px;
    animation: fadeIn var(--t) var(--ease) both;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal {
    width: 100%;
    max-width: 520px;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-xl);
    animation: modalIn var(--t-slow) var(--ease-out) both;
    overflow: hidden;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }
.modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border-subtle);
}
.modal-title { font-size: 15px; font-weight: 650; color: var(--text-strong); }
.modal-body { padding: 20px; overflow-y: auto; flex: 1 1 auto; }
.modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 9px;
    padding: 13px 20px;
    border-top: 1px solid var(--border-subtle);
    background: var(--bg-inset);
}

/* ---------- 表格 ---------- */
.table-wrap { overflow: auto; border-radius: var(--r-md); border: 1px solid var(--border); }
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }
.table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--bg-subtle);
    padding: 9px 12px;
    text-align: left;
    font-weight: 650;
    font-size: 11.5px;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.table tbody td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text);
    vertical-align: middle;
}
.table tbody tr { transition: background var(--t-fast) var(--ease); }
.table tbody tr:hover { background: var(--brand-softer); }
.table tbody tr.selected { background: var(--brand-soft); }
.table tbody tr:last-child td { border-bottom: none; }
.table .num { font-variant-numeric: tabular-nums; text-align: right; }

/* ---------- 空状态 ---------- */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 52px 24px;
    text-align: center;
    color: var(--text-faint);
}
.empty-icon {
    width: 56px;
    height: 56px;
    border-radius: var(--r-lg);
    display: grid;
    place-items: center;
    background: var(--bg-subtle);
    color: var(--text-faint);
}
.empty-title { font-size: 13.5px; font-weight: 600; color: var(--text-muted); }
.empty-desc { font-size: 12.5px; max-width: 340px; line-height: 1.65; }

/* ---------- 加载 ---------- */
.spinner {
    width: 16px;
    height: 16px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin .7s linear infinite;
    display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

.skeleton {
    background: linear-gradient(90deg, var(--bg-subtle) 25%, var(--border-subtle) 37%, var(--bg-subtle) 63%);
    background-size: 400% 100%;
    animation: shimmer 1.4s ease infinite;
    border-radius: var(--r-sm);
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.busy-overlay {
    position: absolute;
    inset: 0;
    background: var(--surface-glass);
    backdrop-filter: blur(2px);
    display: grid;
    place-items: center;
    z-index: 5;
    color: var(--brand-500);
}

/* ---------- 首页 ---------- */
.hero {
    position: relative;
    border-radius: var(--r-xl);
    padding: 34px 36px;
    margin-bottom: 26px;
    overflow: hidden;
    background: linear-gradient(125deg, var(--brand-600) 0%, var(--accent-500) 52%, #a855f7 100%);
    box-shadow: var(--shadow-lg);
    color: #fff;
}
.hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(520px 260px at 88% 8%, rgba(255,255,255,.22), transparent 60%),
        radial-gradient(420px 240px at 4% 96%, rgba(34,211,238,.22), transparent 62%);
}
.hero::after {
    content: "";
    position: absolute;
    width: 420px;
    height: 420px;
    right: -110px;
    top: -170px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255,255,255,.16), transparent 66%);
}
.hero-inner { position: relative; z-index: 1; }
.hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 12px;
    border-radius: var(--r-full);
    background: rgba(255,255,255,.18);
    border: 1px solid rgba(255,255,255,.24);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .02em;
    margin-bottom: 14px;
    backdrop-filter: blur(6px);
}
.hero h1 {
    font-size: 27px;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: #fff;
    margin-bottom: 8px;
    line-height: 1.3;
}
.hero p { font-size: 14px; color: rgba(255,255,255,.85); max-width: 620px; line-height: 1.7; }
.hero-stats { display: flex; gap: 26px; margin-top: 22px; flex-wrap: wrap; }
.hero-stat { display: flex; flex-direction: column; }
.hero-stat b { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.hero-stat span { font-size: 11.5px; color: rgba(255,255,255,.72); letter-spacing: .04em; }

.tool-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
    gap: 14px;
}

.tool-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 17px;
    border-radius: var(--r-lg);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    overflow: hidden;
    text-align: left;
    font-family: inherit;
    transition: transform var(--t) var(--ease-out), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease);
    animation: cardIn var(--t-slow) var(--ease-out) both;
}
@keyframes cardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.tool-card::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: 0;
    background: radial-gradient(340px 160px at 100% 0%, var(--card-glow, rgba(99,102,241,.13)), transparent 65%);
    transition: opacity var(--t) var(--ease);
}
.tool-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
    border-color: var(--border-strong);
}
.tool-card:hover::before { opacity: 1; }
.tool-card:active { transform: translateY(-1px); }
.tool-card:focus-visible { outline: none; box-shadow: var(--ring); }

.tool-card-top { display: flex; align-items: center; gap: 11px; position: relative; z-index: 1; }
.tool-icon {
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    border-radius: 11px;
    display: grid;
    place-items: center;
    background: var(--card-soft, var(--brand-soft));
    color: var(--card-color, var(--brand-600));
    transition: transform var(--t) var(--ease-spring);
}
.tool-card:hover .tool-icon { transform: scale(1.07) rotate(-3deg); }
.tool-card h3 { font-size: 14px; font-weight: 650; color: var(--text-strong); }
.tool-card p {
    font-size: 12.2px;
    color: var(--text-muted);
    line-height: 1.6;
    position: relative;
    z-index: 1;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.tool-card-arrow {
    position: absolute;
    right: 15px;
    bottom: 15px;
    color: var(--text-faint);
    opacity: 0;
    transform: translateX(-4px);
    transition: all var(--t) var(--ease-out);
}
.tool-card:hover .tool-card-arrow { opacity: 1; transform: none; color: var(--brand-500); }

.section-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin: 26px 0 13px;
}
.section-head h2 { font-size: 15px; font-weight: 650; }
.section-head .count { font-size: 12px; color: var(--text-faint); }
.section-line { flex: 1 1 auto; height: 1px; background: var(--border); }

/* ---------- 工具页 ---------- */
.tool-page { max-width: 1180px; }
.tool-page-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 22px;
}
.tool-page-icon {
    width: 46px;
    height: 46px;
    flex: 0 0 46px;
    border-radius: 14px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    color: #fff;
    box-shadow: var(--shadow-brand);
}
.tool-page-head h1 { font-size: 21px; font-weight: 700; letter-spacing: -0.025em; line-height: 1.3; }
.tool-page-head p { font-size: 13px; color: var(--text-muted); margin-top: 3px; line-height: 1.65; max-width: 760px; }

.tool-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 16px;
}
@media (max-width: 980px) { .tool-split { grid-template-columns: minmax(0, 1fr); } }

.io-head {
    display: flex;
    align-items: center;
    gap: 8px;
}
.io-head .spacer { flex: 1 1 auto; }

.result-box {
    position: relative;
    background: var(--bg-inset);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 11px 12px;
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--text-strong);
    white-space: pre-wrap;
    word-break: break-all;
    min-height: 46px;
    max-height: 340px;
    overflow: auto;
}
.result-box.empty-result { color: var(--text-faint); font-family: var(--font-sans); }

.copy-btn {
    position: absolute;
    top: 7px;
    right: 7px;
    opacity: 0;
    transition: opacity var(--t) var(--ease);
}
.result-box:hover .copy-btn, .copy-btn:focus { opacity: 1; }

/* ---------- 标签页 ---------- */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 18px; overflow-x: auto; }
.tab {
    position: relative;
    border: none;
    background: transparent;
    padding: 9px 15px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 550;
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--t) var(--ease);
}
.tab:hover { color: var(--text-strong); }
.tab.active { color: var(--brand-600); font-weight: 650; }
[data-theme="dark"] .tab.active { color: var(--brand-300); }
.tab.active::after {
    content: "";
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: -1px;
    height: 2px;
    border-radius: var(--r-full);
    background: linear-gradient(90deg, var(--brand-500), var(--accent-500));
    animation: tabIn var(--t) var(--ease-out) both;
}
@keyframes tabIn { from { transform: scaleX(.4); opacity: 0; } to { transform: none; opacity: 1; } }
.tab:focus-visible { outline: none; color: var(--brand-600); }

/* ---------- Redis 管理 ---------- */
.redis-layout {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}
@media (max-width: 1180px) { .redis-layout { grid-template-columns: minmax(0, 1fr); } }

.conn-card {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--r-md);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: all var(--t) var(--ease);
    position: relative;
    overflow: hidden;
}
.conn-card:hover { border-color: var(--brand-300); box-shadow: var(--shadow-sm); }
.conn-card.active { border-color: var(--brand-400); background: var(--brand-softer); box-shadow: var(--ring); }
.conn-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 8px;
    background: var(--text-faint);
}
.conn-dot.live { background: var(--emerald-500); box-shadow: 0 0 0 4px rgba(16,185,129,.18); animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(16,185,129,.18); }
    50% { box-shadow: 0 0 0 6px rgba(16,185,129,.07); }
}
.conn-name { font-size: 13px; font-weight: 600; color: var(--text-strong); line-height: 1.35; }
.conn-meta { font-size: 11.5px; color: var(--text-faint); line-height: 1.4; }

.db-picker { display: flex; flex-wrap: wrap; gap: 5px; }
.db-chip {
    min-width: 34px;
    padding: 4px 8px;
    border-radius: var(--r-xs);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    transition: all var(--t) var(--ease);
}
.db-chip:hover { border-color: var(--brand-300); color: var(--brand-600); }
.db-chip.active {
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    border-color: transparent;
    color: #fff;
    box-shadow: var(--shadow-brand);
}

.key-list { max-height: 620px; overflow-y: auto; }
.key-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 12px;
    border: none;
    background: transparent;
    border-radius: var(--r-sm);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: background var(--t-fast) var(--ease);
    border-bottom: 1px solid var(--border-subtle);
}
.key-row:hover { background: var(--brand-softer); }
.key-row.active { background: var(--brand-soft); }
.key-name {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--font-mono);
    font-size: 12.2px;
    color: var(--text-strong);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cli {
    background: #0d1117;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    font-family: var(--font-mono);
}
[data-theme="dark"] .cli { background: #070a12; }
.cli-body {
    padding: 12px 14px;
    max-height: 260px;
    overflow-y: auto;
    font-size: 12.2px;
    line-height: 1.75;
}
.cli-line { white-space: pre-wrap; word-break: break-all; }
.cli-line.cmd { color: #7dd3fc; }
.cli-line.res { color: #d4d8e6; }
.cli-line.err { color: #fb7185; }
.cli-line.info { color: #6b7280; }
.cli-input-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 12px;
    border-top: 1px solid rgba(255,255,255,.08);
    background: rgba(255,255,255,.03);
}
.cli-prompt { color: var(--emerald-400); font-weight: 700; flex: 0 0 auto; }
.cli-input {
    flex: 1 1 auto;
    background: transparent;
    border: none;
    outline: none;
    color: #e8eaf2;
    font-family: var(--font-mono);
    font-size: 12.5px;
}
.cli-input::placeholder { color: #4b5563; }

.kv-grid { display: grid; grid-template-columns: 128px minmax(0,1fr); gap: 6px 14px; font-size: 12.5px; }
.kv-grid dt { color: var(--text-muted); font-weight: 550; }
.kv-grid dd { margin: 0; color: var(--text-strong); font-variant-numeric: tabular-nums; word-break: break-all; }

.entry-row {
    display: grid;
    grid-template-columns: 46px minmax(0, 1.2fr) minmax(0, 1.6fr) auto;
    gap: 10px;
    align-items: center;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-subtle);
}
.entry-row:last-of-type { border-bottom: none; }
.entry-idx { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-faint); text-align: right; }

.stat-strip { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.stat-card {
    flex: 1 1 132px;
    padding: 12px 14px;
    border-radius: var(--r-md);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-xs);
}
.stat-card .label { font-size: 11px; color: var(--text-faint); letter-spacing: .04em; text-transform: uppercase; font-weight: 600; }
.stat-card .value { font-size: 19px; font-weight: 700; color: var(--text-strong); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1.3; margin-top: 2px; }

/* ---------- 工具类 ---------- */
.row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.row-tight { gap: 6px; }
.col { display: flex; flex-direction: column; gap: 12px; }
.spacer { flex: 1 1 auto; }
.mono { font-family: var(--font-mono); }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-xs { font-size: 11.5px; }
.text-sm { font-size: 12.5px; }
.strong { color: var(--text-strong); font-weight: 600; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: 6px; } .mt-2 { margin-top: 12px; } .mt-3 { margin-top: 18px; } .mt-4 { margin-top: 24px; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: 6px; } .mb-2 { margin-bottom: 12px; } .mb-3 { margin-bottom: 18px; }

/* ---------- 错误 UI ---------- */
#blazor-error-ui {
    background: #fff4f4;
    color: #b91c50;
    bottom: 0;
    box-shadow: var(--shadow-lg);
    display: none;
    left: 0;
    padding: 12px 22px;
    position: fixed;
    width: 100%;
    z-index: 5000;
    font-size: 13px;
    border-top: 1px solid rgba(244,63,94,.25);
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 16px; top: 12px; }

/* ---------- 首屏加载 ---------- */
.boot-screen {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    background: var(--bg);
    z-index: 6000;
    transition: opacity var(--t-slow) var(--ease), visibility var(--t-slow);
}
.boot-screen.hidden { opacity: 0; visibility: hidden; }
.boot-logo {
    width: 56px;
    height: 56px;
    border-radius: 17px;
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    box-shadow: var(--shadow-brand);
    color: #fff;
    animation: bootPulse 1.6s var(--ease) infinite;
}
@keyframes bootPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.06); }
}
.boot-text { font-size: 13px; color: var(--text-muted); letter-spacing: .02em; }
.boot-bar { width: 168px; height: 3px; border-radius: var(--r-full); background: var(--border); overflow: hidden; }
.boot-bar i {
    display: block;
    height: 100%;
    width: 40%;
    border-radius: var(--r-full);
    background: linear-gradient(90deg, var(--brand-500), var(--accent-500));
    animation: bootSlide 1.15s var(--ease) infinite;
}
@keyframes bootSlide {
    0% { transform: translateX(-110%); }
    100% { transform: translateX(320%); }
}

/* ---------- 响应式 ---------- */
@media (max-width: 900px) {
    .app-shell { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed;
        left: 0; top: 0; bottom: 0;
        width: var(--sidebar-w);
        z-index: 2000;
        transform: translateX(-100%);
        transition: transform var(--t-slow) var(--ease-out);
        box-shadow: var(--shadow-xl);
    }
    .app-shell.drawer-open .sidebar { transform: none; }
    .sidebar-backdrop {
        position: fixed;
        inset: 0;
        z-index: 1999;
        background: rgba(10, 12, 22, .42);
        backdrop-filter: blur(3px);
        animation: fadeIn var(--t) var(--ease) both;
        border: none;
        padding: 0;
    }
    .content-scroll { padding: 18px 16px 48px; }
    .hero { padding: 26px 22px; }
    .hero h1 { font-size: 22px; }
}

@media (min-width: 901px) {
    .sidebar-backdrop { display: none; }
    .menu-toggle { display: none; }
}

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

/* ==========================================================================
   自研富文本编辑器（在线 Word）
   - 工具栏三排：行内格式 / 段落与列表 / 插入
   - 弹出层（字体、字号、段落样式、颜色）自己实现，不用 <select>：
     <select> 会抢走 contenteditable 的焦点，而按钮只要 mousedown 阻止默认行为
     就能让编辑器一直保持选区。
   ========================================================================== */
.word-shell {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.word-toolbar {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    /* 在工具条上拖动鼠标不能把按钮文字选亮 —— 选区是编辑器的命根子 */
    user-select: none;
    -webkit-user-select: none;
}

.word-tb-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
}

/* 阻断了 mousedown 默认行为的工具栏分组：点按钮时编辑器不会失焦 */
.word-tb-row {
    user-select: none;
}

.word-tb-sep {
    width: 1px;
    height: 18px;
    background: var(--border-strong);
    margin: 0 6px;
    flex: 0 0 auto;
}

.word-tb-spacer {
    flex: 1 1 auto;
    min-width: 8px;
}

.word-tb-label {
    font-size: 11px;
    color: var(--text-faint);
    margin-right: 4px;
    flex: 0 0 auto;
}

.word-tb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 28px;
    min-width: 28px;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font-size: 12.5px;
    line-height: 1;
    cursor: pointer;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.word-tb-btn:hover:not(:disabled) {
    background: var(--surface-3);
    color: var(--text-strong);
}
.word-tb-btn:disabled {
    opacity: .38;
    cursor: not-allowed;
}
.word-tb-btn.on {
    background: var(--brand-soft);
    border-color: rgba(99, 102, 241, 0.28);
    color: var(--brand-600);
}
.word-tb-btn .word-ico {
    font-size: 13px;
    line-height: 1;
}
.word-tb-btn b, .word-tb-btn i, .word-tb-btn u, .word-tb-btn s {
    font-size: 13px;
    line-height: 1;
}
/* 颜色按钮下方那条色带就是当前色 */
.word-tb-btn.word-color {
    position: relative;
    padding-bottom: 3px;
}
.word-tb-btn.word-color::after {
    content: "";
    position: absolute;
    left: 6px;
    right: 6px;
    bottom: 3px;
    height: 3px;
    border-radius: 2px;
    background: var(--wc, transparent);
    border: 1px solid var(--border);
}

/* ---------- 自定义下拉 ---------- */
.word-picker {
    position: relative;
    flex: 0 0 auto;
    /* 抬到遮罩之上：否则点另一个下拉时第一下只会命中遮罩（先关旧的、得多点一次） */
    z-index: 35;
}
.word-picker.open { z-index: 45; }
.word-picker-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-elevated);
    color: var(--text);
    font-size: 12.5px;
    cursor: pointer;
    transition: border-color .12s ease, background .12s ease;
}
.word-picker-btn:hover { border-color: var(--border-strong); }
.word-picker-btn.open {
    border-color: var(--brand-500);
    background: var(--brand-soft);
    color: var(--brand-700);
}
.word-picker-name {
    min-width: 62px;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.word-picker-caret {
    font-size: 9px;
    color: var(--text-faint);
}

.word-backdrop {
    position: fixed;
    inset: 0;
    z-index: 30;
    background: transparent;
}

.word-pop {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 40;
    min-width: 168px;
    max-height: 288px;
    overflow-y: auto;
    padding: 5px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background: var(--bg-elevated);
    box-shadow: var(--shadow-lg);
    animation: word-pop-in .12s ease-out;
}
.word-pop.wide { min-width: 210px; }
@keyframes word-pop-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.word-pop-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 6px 8px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}
.word-pop-item:hover { background: var(--surface-3); }
.word-pop-item.on {
    background: var(--brand-soft);
    color: var(--brand-700);
    font-weight: 500;
}
.word-pop-item .word-pop-check {
    margin-left: auto;
    color: var(--brand-600);
    font-size: 11px;
}
.word-pop-hint {
    padding: 5px 8px 7px;
    font-size: 11px;
    color: var(--text-faint);
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 4px;
}

/* 段落样式预览的字号层级 */
.word-pop-item[data-block="h1"] { font-size: 17px; font-weight: 600; }
.word-pop-item[data-block="h2"] { font-size: 15.5px; font-weight: 600; }
.word-pop-item[data-block="h3"] { font-size: 14.5px; font-weight: 600; }
.word-pop-item[data-block="h4"],
.word-pop-item[data-block="h5"],
.word-pop-item[data-block="h6"] { font-weight: 500; }
.word-pop-item[data-block="blockquote"] { font-style: italic; color: var(--text-soft); }
.word-pop-item[data-block="pre"] { font-family: ui-monospace, Consolas, monospace; font-size: 12px; }

/* ---------- 调色盘 ---------- */
.word-palette {
    display: grid;
    grid-template-columns: repeat(9, 20px);
    gap: 4px;
    padding: 4px;
}
.word-swatch {
    width: 20px;
    height: 20px;
    border-radius: 4px;
    border: 1px solid var(--border-strong);
    cursor: pointer;
    padding: 0;
    transition: transform .1s ease;
}
.word-swatch:hover { transform: scale(1.14); }
.word-swatch.on { box-shadow: 0 0 0 2px var(--brand-500); }
.word-swatch.none {
    background:
        linear-gradient(to bottom right, transparent 45%, #e5484d 45%, #e5484d 55%, transparent 55%),
        var(--bg-elevated);
}
.word-palette-foot {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-top: 4px;
    border-top: 1px solid var(--border-subtle);
    margin-top: 4px;
}

/* ---------- 纸张 ---------- */
.word-canvas {
    padding: 20px;
    background: var(--bg-subtle);
    overflow-y: auto;
    min-height: 0;
    max-height: 620px;
    overscroll-behavior: contain;
}

.word-editor {
    position: relative;
    max-width: 820px;
    min-height: 520px;
    margin: 0 auto;
    padding: 30px 36px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-elevated);
    box-shadow: var(--shadow-sm);
    color: var(--text);
    font-size: 15px;
    line-height: 1.8;
    outline: none;
    word-wrap: break-word;
}
.word-editor:focus {
    border-color: var(--brand-400);
    box-shadow: var(--shadow-md), 0 0 0 3px var(--brand-softer);
}
.word-editor.is-empty::before {
    content: attr(data-placeholder);
    position: absolute;
    top: 30px;
    left: 36px;
    color: var(--text-faint);
    pointer-events: none;
}

.word-editor > *:first-child { margin-top: 0; }
.word-editor p { margin: 0 0 10px; }
.word-editor h1 { font-size: 26px; margin: 20px 0 10px; line-height: 1.35; font-weight: 600; }
.word-editor h2 { font-size: 21px; margin: 18px 0 8px; line-height: 1.35; font-weight: 600; }
.word-editor h3 { font-size: 18px; margin: 16px 0 8px; line-height: 1.4; font-weight: 600; }
.word-editor h4 { font-size: 16px; margin: 14px 0 6px; font-weight: 600; }
.word-editor h5 { font-size: 15px; margin: 12px 0 6px; font-weight: 600; }
.word-editor h6 { font-size: 14px; margin: 12px 0 6px; font-weight: 600; color: var(--text-soft); }

.word-editor ul, .word-editor ol { padding-left: 26px; margin: 8px 0; }
.word-editor li { margin: 2px 0; }
/* 嵌套列表：同级用 circle / lower-alpha，和浏览器默认保持一致 */
.word-editor ul ul { list-style-type: circle; }
.word-editor ul ul ul { list-style-type: square; }
.word-editor ol ol { list-style-type: lower-alpha; }
.word-editor ol ol ol { list-style-type: lower-roman; }

.word-editor blockquote {
    margin: 10px 0;
    padding: 6px 16px;
    border-left: 3px solid var(--brand-400);
    background: var(--brand-softer);
    border-radius: 0 6px 6px 0;
    color: var(--text-soft);
}
.word-editor pre {
    margin: 10px 0;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-inset);
    font-family: ui-monospace, Consolas, "Courier New", monospace;
    font-size: 13px;
    line-height: 1.6;
    overflow-x: auto;
    white-space: pre-wrap;
}
.word-editor code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--surface-3);
    font-family: ui-monospace, Consolas, monospace;
    font-size: .92em;
}
.word-editor a {
    color: var(--brand-600);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.word-editor img {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
    vertical-align: bottom;
}
.word-editor hr {
    border: none;
    border-top: 1px solid var(--border-strong);
    margin: 18px 0;
}
/* 分页符：虚线强调，并标出「分页符」三个字（导出成 docx 是真正的分页符） */
.word-editor hr.page-break {
    position: relative;
    border-top: 2px dashed var(--brand-400);
    margin: 22px 0;
    height: 0;
}
.word-editor hr.page-break::after {
    content: "分页符";
    position: absolute;
    right: 0;
    top: -9px;
    padding: 0 6px;
    border-radius: 4px;
    background: var(--bg-elevated);
    color: var(--brand-500);
    font-size: 10px;
    line-height: 15px;
}

.word-editor table {
    width: 100%;
    margin: 12px 0;
    border-collapse: collapse;
    font-size: 14px;
}
.word-editor td, .word-editor th {
    border: 1px solid var(--border-strong);
    padding: 4px 8px;
    vertical-align: top;
}
.word-editor th {
    background: var(--surface-3);
    font-weight: 600;
    text-align: center;
}
/* 表格里放段落时去掉段间距，否则单元格会显得很空 */
.word-editor td > p:last-child, .word-editor th > p:last-child { margin-bottom: 0; }

.word-editor sub, .word-editor sup { font-size: .75em; }

/* ---------- 状态栏 ---------- */
.word-status {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
    padding: 6px 12px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 12px;
    color: var(--text-muted);
}
.word-status .ws-sep {
    width: 1px;
    height: 12px;
    background: var(--border-strong);
}
.word-status .ws-hint {
    margin-left: auto;
    color: var(--text-faint);
}
.word-status kbd {
    padding: 1px 4px;
    border: 1px solid var(--border-strong);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: var(--bg-elevated);
    font-family: inherit;
    font-size: 11px;
}

/* ---------- 页眉页脚 ---------- */
.word-hf {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}
.word-hf input {
    flex: 1 1 auto;
    min-width: 0;
    height: 28px;
    padding: 0 9px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-elevated);
    color: var(--text);
    font-size: 12.5px;
}
.word-hf input:focus {
    outline: none;
    border-color: var(--brand-400);
    box-shadow: 0 0 0 3px var(--brand-softer);
}
.word-hf-label {
    font-size: 12px;
    color: var(--text-muted);
    flex: 0 0 auto;
}

/* ==========================================================================
   多工作表电子表格编辑器
   - 表头（列头 / 筛选行）、行头、冻结行都靠 sticky 定位。sticky 与
     border-collapse: collapse 一起用时边框会随滚动丢帧，所以这里用
     separate + border-spacing: 0，边框画在单元格的右下两侧
   - 行高固定 26px，这是行虚拟化的前提（与 ExcelEditor.RowHeight 常量对应）；
     --head-h 是表头总高，筛选行与冻结行的 sticky top 都由它推导
   ========================================================================== */

.sheet-panel .panel-head { flex-wrap: wrap; row-gap: 6px; }
.sheet-panel .panel-body { display: flex; flex-direction: column; }

/* ---------- 工作表标签条 ---------- */
.sheet-tabs {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    padding: 6px 10px 0;
    overflow-x: auto;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    scrollbar-width: thin;
}
.sheet-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 12px;
    flex: 0 0 auto;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--r-sm) var(--r-sm) 0 0;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.sheet-tab:hover { color: var(--text-strong); background: var(--surface-3); }
.sheet-tab.active {
    color: var(--brand-600);
    background: var(--surface-1);
    border-color: var(--border);
    box-shadow: inset 0 2px 0 0 var(--brand-500);
}
.sheet-tab-add {
    padding: 0 10px;
    color: var(--text-faint);
    font-size: 15px;
    font-weight: 700;
}
.sheet-tab-add:hover { color: var(--brand-600); }
.sheet-rename {
    width: 108px;
    height: 24px;
    padding: 0 7px;
    border-radius: var(--r-xs);
    font-size: 12.5px;
}

/* ---------- 工具条 ---------- */
.sheet-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
    padding: 7px 10px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.sheet-toolbar-2 { background: var(--bg-inset); }
.sheet-sep {
    flex: 0 0 auto;
    width: 1px;
    height: 20px;
    margin: 0 4px;
    background: var(--border-strong);
}
.sheet-namebox {
    flex: 0 0 auto;
    width: 92px;
    padding: 5px 8px;
    border-color: transparent;
    background: var(--brand-soft);
    color: var(--brand-600);
    font-family: var(--font-mono);
    font-size: 12.5px;
    font-weight: 700;
    text-align: center;
}
.sheet-namebox:focus { border-color: var(--brand-400); background: var(--bg-elevated); }
.sheet-fx {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border-radius: var(--r-xs);
    background: var(--brand-soft);
    color: var(--brand-600);
}
.sheet-formula {
    flex: 1 1 260px;
    min-width: 180px;
    padding: 5px 9px;
    font-family: var(--font-mono);
    font-size: 12.5px;
}
.sheet-ico {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    padding: 0;
    border-radius: var(--r-xs);
}
.sheet-ico.on {
    color: var(--brand-600);
    background: var(--brand-soft);
    box-shadow: inset 0 0 0 1px var(--brand-300);
}
.sheet-size {
    flex: 0 0 auto;
    width: 64px;
    padding: 4px 6px;
    font-size: 12.5px;
}
.sheet-numfmt {
    flex: 0 0 auto;
    width: 116px;
    padding: 4px 6px;
    font-size: 12.5px;
}

/* 取色器：原生 color 输入压在图标上方，底部一条色带显示当前颜色 */
.sheet-picker {
    position: relative;
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 30px;
    height: 28px;
    border: 1px solid var(--border);
    border-radius: var(--r-xs);
    background: var(--bg-inset);
    color: var(--text-soft);
    cursor: pointer;
}
.sheet-picker:hover { border-color: var(--brand-300); color: var(--text-strong); }
.sheet-picker input[type="color"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: none;
    opacity: 0;
    cursor: pointer;
}
.sheet-picker i {
    position: absolute;
    left: 3px;
    right: 3px;
    bottom: 2px;
    height: 3px;
    border-radius: 2px;
}

/* ---------- 弹出工具（查找替换 / 条件格式） ---------- */
.sheet-pop {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-1);
    box-shadow: var(--shadow-sm);
    animation: sheet-pop-in var(--t) var(--ease-out);
}
@keyframes sheet-pop-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}
.sheet-pop-input {
    flex: 0 0 auto;
    width: 148px;
    padding: 5px 9px;
    font-size: 12.5px;
}
.sheet-pop-narrow { width: 98px; }
.sheet-check {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12.5px;
    color: var(--text-muted);
    user-select: none;
    cursor: pointer;
}
.sheet-check input { accent-color: var(--brand-500); }
.sheet-hint { font-size: 11.5px; color: var(--text-faint); }
.sheet-danger { color: var(--rose-500); }
.sheet-danger:hover { color: var(--rose-500); background: rgba(244, 63, 94, .10); }
.sheet-danger:disabled { color: var(--rose-500); }

/* ---------- 网格 ---------- */
.sheet-scroll {
    position: relative;
    overflow: auto;
    /* 面板体是纵向 flex，显式写 0 才能让 max-height 真正生效 */
    min-height: 0;
    max-height: 560px;
    outline: none;
    background: var(--bg-inset);
    overscroll-behavior: contain;
}
.sheet-grid {
    --row-h: 26px;
    --head-h: 26px;

    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 12.5px;
    color: var(--text);
}
.sheet-grid.filtered { --head-h: 52px; }

.sheet-grid th,
.sheet-grid td {
    box-sizing: border-box;
    height: var(--row-h);
    padding: 0 7px;
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    vertical-align: middle;
}
/* 合并单元格要跟着 rowspan 长高，不能被单行的 26px 卡住 */
.sheet-grid td.sheet-merged {
    height: auto;
}

/* 列头 / 左上角 */
.sheet-grid .sheet-col-head,
.sheet-grid .sheet-corner {
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--bg-subtle);
    color: var(--text-faint);
    font-size: 11.5px;
    font-weight: 700;
    text-align: center;
    user-select: none;
}
.sheet-grid .sheet-col-head { cursor: pointer; }
.sheet-grid .sheet-col-head:hover { color: var(--brand-600); background: var(--brand-softer); }
.sheet-grid .sheet-corner { left: 0; z-index: 6; cursor: pointer; }
.sheet-grid .sheet-corner:hover { background: var(--brand-softer); }

/* 行号 */
.sheet-grid .sheet-row-head {
    position: sticky;
    left: 0;
    z-index: 3;
    background: var(--bg-subtle);
    color: var(--text-faint);
    font-size: 11.5px;
    font-weight: 700;
    text-align: center;
    user-select: none;
    cursor: pointer;
}
.sheet-grid .sheet-row-head:hover { color: var(--brand-600); background: var(--brand-softer); }

/* 整列 / 整行选中 */
.sheet-grid .sheet-col-head.sel,
.sheet-grid .sheet-row-head.sel {
    color: var(--brand-600);
    background: var(--brand-soft);
    box-shadow: inset 0 0 0 1px var(--brand-300);
}

/* 列宽拖拽把手：默认隐身在列头右边缘，悬停才亮出来 */
.sheet-col-grip {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 6px;
    border-right: 2px solid transparent;
    cursor: col-resize;
}
.sheet-col-grip:hover,
.sheet-col-grip.dragging { border-right-color: var(--brand-400); }

/* 筛选行 */
.sheet-grid .sheet-filter-row > th {
    position: sticky;
    top: var(--row-h);
    z-index: 4;
    height: var(--row-h);
    padding: 2px 3px;
    background: var(--bg-inset);
}
.sheet-grid .sheet-filter-row > .sheet-row-head { left: 0; z-index: 6; }
.sheet-filter-select {
    width: 100%;
    height: 21px;
    padding: 0 2px;
    border: 1px solid var(--border);
    border-radius: var(--r-xs);
    background: var(--surface-1);
    color: var(--text);
    font-family: inherit;
    font-size: 11px;
    cursor: pointer;
}
.sheet-filter-select:focus { border-color: var(--brand-400); outline: none; }

/* 冻结首行：必须始终渲染，靠 sticky 钉在表头下面。
   这里刻意写成「两级类名 + 子元素」把优先级提到 (0,3,0)：
   .sheet-grid .sheet-cell 也是 (0,2,0) 且更靠后，否则它的 position: relative
   会把 sticky 覆盖掉，冻结行就变成一个普通行了。 */
.sheet-grid .sheet-frozen-row > .sheet-cell,
.sheet-grid .sheet-frozen-row > .sheet-row-head {
    position: sticky;
    top: var(--head-h);
    z-index: 5;
    background: var(--bg-elevated);
}
.sheet-grid .sheet-frozen-row > .sheet-row-head { left: 0; z-index: 7; }

/* 单元格 */
.sheet-grid .sheet-cell {
    position: relative;
    color: var(--text);
    cursor: cell;
    /* 单元格文字一律不允许被浏览器「原生选中」。三个理由：
       ① 在格子上拖动鼠标会顺带拉出一片原生文字选区，它的颜色是 --brand-200
          （实色蓝，比选区的 .sel 底纹更深），看起来就像「多选上了一列」；
       ② Shift+点击在非可选中区域上会按浏览器默认行为，把已有的原生文字选区
          **延伸过去** —— 用户报的「用 shift 总是把后边一列选上」就是这么来的；
       ③ 一旦页面里存在原生文字选区，Ctrl+C 会触发浏览器自己的 copy，
          把「选中的文字」（实测还会退化成页面 URL）写进剪贴板，
          盖掉我们写进去的单元格 TSV —— 粘贴内容就错乱了。
       Excel 的网格同样不允许选文字：要选单元格里的文字，先双击 / F2 进编辑态。 */
    user-select: none;
    -webkit-user-select: none;
}
.sheet-grid .sheet-cell:hover { background: var(--brand-softer); }
/* 选区底纹与活动单元格的边框都用伪元素画：
   单元格自身的 background-color / box-shadow 被行内样式占用（用户填充色与自定义边框） */
.sheet-grid .sheet-cell.sel::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: var(--brand-soft);
    pointer-events: none;
}
.sheet-grid .sheet-cell.anchor::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    box-shadow: inset 0 0 0 2px var(--brand-500);
    pointer-events: none;
}
.sheet-cell-text {
    position: relative;
    z-index: 1;
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* 自动换行会把行撑高，此时页面会关掉行虚拟化 */
.sheet-grid .sheet-cell.wrap {
    height: auto;
    min-height: var(--row-h);
    padding-top: 3px;
    padding-bottom: 3px;
    line-height: 1.35;
    white-space: normal;
    word-break: break-word;
}
.sheet-grid .sheet-cell.wrap .sheet-cell-text {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    white-space: normal;
}

/* 条件格式的数据条 */
.sheet-grid .sheet-cell.bar { position: relative; }

/* 填充柄：钉在选区右下角单元格的右下角，mousedown 后由 PKDSheet 接管拖动。
   刻意完全放在单元格内部（right/bottom 都是正值）：
   骑跨在边界外的部分在真实指针命中测试里会输给相邻/下侧单元格，
   表现为「柄看得见点不到」；合成事件发现不了这个差别（合成 mousedown 直接指定 target）。 */
.sheet-fill-handle {
    position: absolute;
    right: 1px;
    bottom: 1px;
    z-index: 8;
    width: 8px;
    height: 8px;
    border: 1px solid var(--surface-1);
    border-radius: 2px;
    background: var(--brand-500);
    cursor: crosshair;
}
/* 拖动过程中的目标高亮（JS 给目标单元格加 .fill-target） */
.sheet-grid .sheet-cell.fill-target {
    outline: 1px dashed var(--brand-400);
    outline-offset: -1px;
}
.sheet-grid .sheet-cell.fill-target::before {
    background: var(--brand-softer);
}

.sheet-bar {
    position: absolute;
    left: 0;
    top: 1px;
    bottom: 1px;
    z-index: 0;
    border-radius: 2px;
    opacity: .6;
    pointer-events: none;
}

/* 单元格内联编辑器 */
.sheet-inline {
    position: absolute;
    inset: 0;
    z-index: 4;
    width: 100%;
    height: 100%;
    padding: 0 6px;
    border: 2px solid var(--brand-500);
    border-radius: 0;
    background: var(--surface-1);
    color: var(--text-strong);
    font: inherit;
    outline: none;
    box-shadow: var(--shadow-md);
    /* 编辑态必须能把文字选亮（上面 .sheet-cell 把整格设成了 user-select: none，
       输入框会继承，不显式放行的话鼠标就选不中编辑框里的字）。 */
    user-select: text;
    -webkit-user-select: text;
}

/* 虚拟化的占位行 */
.sheet-grid .sheet-spacer > td {
    padding: 0;
    border: none;
    background: transparent;
    height: auto;
}

/* ---------- 状态栏 ---------- */
.sheet-status {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    padding: 7px 12px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 11.5px;
    color: var(--text-muted);
}
.sheet-selinfo {
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 700;
    color: var(--brand-600);
}

/* ==========================================================================
   在线 PS（自研图像编辑器）
   - 画布区由 JS 托管（.ps-stage 内的一切都是运行时建立的）
   - 其余部分走 Blazor 渲染，与站点其余面板保持同一套视觉语言
   ========================================================================== */

.ps-topbar { margin-bottom: 14px; }
.ps-topbar .panel-body { padding: 0; }

.ps-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 14px;
}

.ps-bar + .ps-bar { border-top: 1px solid var(--border); }

.ps-sep {
    width: 1px;
    height: 20px;
    margin: 0 2px;
    background: var(--border);
}

.ps-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-muted);
    cursor: pointer;
    user-select: none;
}

.ps-check input { accent-color: var(--brand-500); cursor: pointer; }

.ps-label { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }
.ps-strong { font-weight: 650; color: var(--text-strong); }
.ps-times { color: var(--text-faint); }

.ps-num { width: 84px; }

.input-sm { padding: 5px 9px; font-size: 12.5px; border-radius: var(--r-xs); }
.select-sm { padding: 5px 9px; font-size: 12.5px; border-radius: var(--r-xs); }

/* ---------- 三栏布局 ---------- */

.ps-body {
    display: grid;
    grid-template-columns: 108px minmax(0, 1fr) 320px;
    gap: 14px;
    align-items: start;
}

@media (max-width: 1180px) {
    .ps-body { grid-template-columns: 100px minmax(0, 1fr); }
    .ps-side { grid-column: 1 / -1; }
}

/* ---------- 工具箱 ---------- */

.ps-rail {
    position: sticky;
    top: 12px;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 10px;
}

.ps-tool {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 4px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-muted);
    font-size: 11px;
    font-family: inherit;
    cursor: pointer;
    transition: all var(--t-fast) var(--ease);
}

.ps-tool:hover { background: var(--brand-softer); color: var(--text-strong); }

.ps-tool.active {
    background: var(--brand-soft);
    border-color: var(--brand-300);
    color: var(--brand-600);
    font-weight: 650;
    box-shadow: var(--shadow-xs);
}

.ps-rail-sep { height: 1px; margin: 4px 2px; background: var(--border); }

.ps-colors {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 0 2px;
}

/* 色块 + 右下角的「透明」小开关叠在一起，所以要在同一个定位上下文里 */
.ps-swatch-wrap { position: relative; display: inline-flex; }

.ps-swatch {
    position: relative;
    width: 26px;
    height: 26px;
    border-radius: var(--r-xs);
    border: 1px solid var(--border-strong);
    box-shadow: var(--shadow-xs);
    cursor: pointer;
    overflow: hidden;
}

/* 透明态：内联 style 会留空（见 SwatchStyle），由这条规则画棋盘格底纹 */
.ps-swatch.is-transparent {
    background-color: #ffffff;
    background-image:
        linear-gradient(45deg, #cbd2dc 25%, transparent 25%),
        linear-gradient(-45deg, #cbd2dc 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #cbd2dc 75%),
        linear-gradient(-45deg, transparent 75%, #cbd2dc 75%);
    background-size: 8px 8px;
    background-position: 0 0, 0 4px, 4px -4px, -4px 0;
}

.ps-swatch input {
    position: absolute;
    inset: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
    border: 0;
    padding: 0;
}

/* 右下角的透明开关：压在 <input> 之上，点它不会命中取色器（z-index 决定命中谁） */
.ps-swatch-alpha {
    position: absolute;
    right: -3px;
    bottom: -3px;
    width: 12px;
    height: 12px;
    padding: 0;
    border: 1px solid var(--border-strong);
    border-radius: 3px;
    background-color: #ffffff;
    background-image:
        linear-gradient(45deg, #cbd2dc 25%, transparent 25%),
        linear-gradient(-45deg, #cbd2dc 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #cbd2dc 75%),
        linear-gradient(-45deg, transparent 75%, #cbd2dc 75%);
    background-size: 4px 4px;
    background-position: 0 0, 0 2px, 2px -2px, -2px 0;
    cursor: pointer;
    z-index: 2;
    box-shadow: var(--shadow-xs);
}

.ps-swatch-alpha:hover { border-color: var(--brand-500); }

/* 当前颜色槽就是透明：描一圈品牌色，一眼能看出开关处于打开状态 */
.ps-swatch-alpha.on {
    border-color: var(--brand-500);
    box-shadow: 0 0 0 1.5px var(--brand-300);
}

/* ---------- 画布区 ---------- */

.ps-center { display: flex; flex-direction: column; min-width: 0; }

.ps-zoom-chip {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 700;
    color: var(--brand-600);
    background: var(--brand-soft);
    border-radius: var(--r-xs);
    padding: 2px 8px;
}

.ps-zoom-range { width: 108px; accent-color: var(--brand-500); cursor: pointer; }

.ps-stage {
    position: relative;
    height: clamp(420px, 62vh, 760px);
    background: var(--surface-2);
    overflow: hidden;
}

.ps-scroll {
    position: absolute;
    inset: 0;
    overflow: auto;
    background:
        linear-gradient(var(--border-subtle) 1px, transparent 1px) 0 0 / 100% 100%,
        var(--surface-2);
}

.ps-scroll.ps-can-pan { cursor: grab; }
.ps-scroll.ps-panning { cursor: grabbing; }

.ps-board {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 100%;
    min-height: 100%;
    padding: 36px;
}

.ps-frame {
    position: relative;
    flex: 0 0 auto;
    box-shadow: var(--shadow-lg);
    /* 透明区域的棋盘格 */
    background-color: var(--checker-base);
    background-image:
        linear-gradient(45deg, var(--checker-ink) 25%, transparent 25%, transparent 75%, var(--checker-ink) 75%),
        linear-gradient(45deg, var(--checker-ink) 25%, transparent 25%, transparent 75%, var(--checker-ink) 75%);
    background-size: 16px 16px;
    background-position: 0 0, 8px 8px;
}

.ps-frame.ps-flat { background-image: none; }

/* 文字就地编辑浮层：双击画布上的字就出现，可直接打字改字。
   宽度/字体由 JS 按 renderText 的同一套度量设置，保证光标位置与提交后栅格化的字重合。 */
.ps-textedit {
    position: absolute;
    left: 0;
    top: 0;
    display: none;
    margin: 0;
    background: transparent;
    border: 0;
    outline: none;
    white-space: pre;
    overflow: visible;
    transform-origin: 0 0;
    caret-color: transparent;   /* 自绘光标，避免与自绘竖线重影 */
    cursor: text;
    user-select: text;
    -webkit-user-select: text;
    touch-action: none;
    z-index: 6;
}
.ps-textedit.ps-text-dragging {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}
.ps-textedit:focus { outline: none; }

/* 浮层底衬：让深色画布上的字也看得见（提交后这层衬底不会进像素） */
.ps-textedit::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .06);
    box-shadow: 0 0 0 1px rgba(20, 22, 31, .35);
    pointer-events: none;
}

/* 自绘光标竖线 */
.ps-textedit-caret {
    position: absolute;
    display: none;
    width: 1px;
    background: var(--brand-500, #3b82f6);
    animation: psCaretBlink 1.06s steps(1, end) infinite;
    pointer-events: none;
}
@keyframes psCaretBlink {
    0%, 55% { opacity: 1; }
    56%, 100% { opacity: 0; }
}

.ps-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    touch-action: none;
}

/* 拖动中的选框 */
.ps-marquee {
    position: absolute;
    display: none;
    border: 1px dashed rgba(255, 255, 255, 0.9);
    outline: 1px dashed rgba(20, 22, 31, 0.55);
    pointer-events: none;
}

/* 已生效的选区：黑白双色虚线，深浅底色上都看得见 */
.ps-selection {
    position: absolute;
    display: none;
    border: 1px dashed rgba(255, 255, 255, 0.95);
    outline: 1px dashed rgba(20, 22, 31, 0.6);
    box-shadow: 0 0 0 1px rgba(20, 22, 31, 0.15);
    pointer-events: none;
}

/* 画笔光标：一个跟随鼠标的空心圆，尺寸与笔头一致 */
.ps-brush {
    position: absolute;
    display: none;
    left: 0;
    top: 0;
    width: 24px;
    height: 24px;
    margin-left: 0;
    transform: translate(-50%, -50%);
    border: 1px solid rgba(255, 255, 255, 0.95);
    outline: 1px solid rgba(20, 22, 31, 0.6);
    border-radius: 50%;
    pointer-events: none;
    z-index: 3;
}

/* ================= 自由变换的变换框 ================= */

/*
 * 框本身 pointer-events:none，只有手柄和内部拖动层接收指针 ——
 * 否则框内没放东西的空白会把点击吃掉，画布静默点不动。
 * 框挂 .ps-frame 内，所以位置用「文档坐标 × zoom」算，跟着画布缩放平移。
 */
.ps-tfbox {
    position: absolute;
    display: none;
    box-sizing: border-box;
    border: 1px solid rgba(255, 255, 255, 0.95);
    outline: 1px solid rgba(20, 22, 31, 0.65);
    transform-origin: 50% 50%;
    pointer-events: none;
    z-index: 5;
}

/* 内部拖动 = 平移变换结果 */
.ps-tfmover {
    position: absolute;
    inset: 0;
    cursor: move;
    pointer-events: auto;
}

/* 缩放手柄：固定 9px 屏幕尺寸，不随 zoom 变大变小 */
.ps-tfhandle {
    position: absolute;
    width: 9px;
    height: 9px;
    margin: -5px 0 0 -5px;
    box-sizing: border-box;
    background: #fff;
    border: 1px solid rgba(20, 22, 31, 0.75);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
    pointer-events: auto;
    z-index: 2;
}

.ps-tf-nw { left: 0;    top: 0;    cursor: nwse-resize; }
.ps-tf-n  { left: 50%;  top: 0;    cursor: ns-resize; }
.ps-tf-ne { left: 100%; top: 0;    cursor: nesw-resize; }
.ps-tf-e  { left: 100%; top: 50%;  cursor: ew-resize; }
.ps-tf-se { left: 100%; top: 100%; cursor: nwse-resize; }
.ps-tf-s  { left: 50%;  top: 100%; cursor: ns-resize; }
.ps-tf-sw { left: 0;    top: 100%; cursor: nesw-resize; }
.ps-tf-w  { left: 0;    top: 50%;  cursor: ew-resize; }

/* 旋转手柄：顶边中点上方一个小圆，拖它绕区域中心转 */
.ps-tfrotate {
    position: absolute;
    left: 50%;
    top: -26px;
    width: 13px;
    height: 13px;
    margin-left: -7px;
    box-sizing: border-box;
    border-radius: 50%;
    background: #fff;
    border: 1px solid rgba(20, 22, 31, 0.75);
    cursor: grab;
    pointer-events: auto;
    z-index: 2;
}
.ps-tfrotate::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 100%;
    width: 1px;
    height: 12px;
    margin-left: -0.5px;
    background: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 0 0.5px rgba(20, 22, 31, 0.6);
}

.ps-foot {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding: 8px 14px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 12px;
    color: var(--text-muted);
}

.ps-foot-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    white-space: nowrap;
}

/* ---------- 右侧面板 ---------- */

.ps-side { display: flex; flex-direction: column; }

.ps-tabs { margin: 10px 10px 0; }

.ps-side-body { padding: 12px; max-height: calc(62vh + 120px); overflow: auto; }

.ps-group { margin-bottom: 14px; }
.ps-group:last-child { margin-bottom: 0; }

.ps-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

.ps-row:last-child { margin-bottom: 0; }
.ps-grow { flex: 1 1 auto; min-width: 0; }

.ps-value {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
    min-width: 48px;
    text-align: right;
}

.ps-range { flex: 1 1 auto; min-width: 0; accent-color: var(--brand-500); cursor: pointer; }

.ps-actions { display: flex; flex-wrap: wrap; gap: 5px; }

.ps-desc { margin: 4px 0 0; font-size: 12px; color: var(--text-muted); line-height: 1.5; }
.ps-warn { color: #b45309; }
.ps-hint { margin: 0 0 8px; font-size: 12px; color: var(--text-faint); line-height: 1.55; }

.ps-preview-head {
    padding: 10px;
    border: 1px solid var(--brand-300);
    border-radius: var(--r-sm);
    background: var(--brand-softer);
}

/* ---------- 图层列表 ---------- */

.ps-layers { display: flex; flex-direction: column; gap: 5px; }

.ps-layer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface-1);
    cursor: pointer;
    transition: all var(--t-fast) var(--ease);
}

.ps-layer:hover { border-color: var(--brand-300); }

.ps-layer.active {
    border-color: var(--brand-400);
    background: var(--brand-soft);
    box-shadow: var(--shadow-xs);
}

.ps-eye {
    border: 0;
    background: transparent;
    color: var(--text-muted);
    padding: 3px;
    border-radius: var(--r-xs);
    cursor: pointer;
    display: flex;
    flex: 0 0 auto;
}

.ps-eye:hover { background: var(--surface-3); color: var(--text-strong); }
.ps-eye.off { color: var(--text-faint); opacity: 0.55; }

.ps-thumb {
    width: 44px;
    height: 33px;
    flex: 0 0 auto;
    border-radius: 5px;
    border: 1px solid var(--border);
    background-color: var(--checker-base);
    background-image:
        linear-gradient(45deg, var(--checker-ink) 25%, transparent 25%, transparent 75%, var(--checker-ink) 75%),
        linear-gradient(45deg, var(--checker-ink) 25%, transparent 25%, transparent 75%, var(--checker-ink) 75%);
    background-size: 10px 10px;
    background-position: 0 0, 5px 5px;
    image-rendering: pixelated;
}

.ps-layer-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.ps-layer-name {
    width: 100%;
    border: 1px solid transparent;
    background: transparent;
    padding: 1px 4px;
    margin: 0;
    border-radius: var(--r-xs);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-strong);
    outline: none;
}

.ps-layer-name:hover { border-color: var(--border); }
.ps-layer-name:focus { border-color: var(--brand-400); background: var(--surface-1); box-shadow: var(--ring); }

.ps-layer-sub { font-size: 11px; color: var(--text-faint); padding-left: 5px; }

/* ---------- 滤镜 / 调整选择器 ---------- */

.ps-filter-group {
    margin: 10px 0 6px;
    font-size: 11.5px;
    font-weight: 650;
    color: var(--text-faint);
    letter-spacing: 0.02em;
}

.ps-chips { display: flex; flex-wrap: wrap; gap: 5px; }

.ps-chip {
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-full);
    background: var(--surface-1);
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
    cursor: pointer;
    transition: all var(--t-fast) var(--ease);
}

.ps-chip:hover { border-color: var(--brand-300); color: var(--brand-600); transform: translateY(-1px); }

.ps-chip.active {
    background: var(--brand-600);
    border-color: var(--brand-600);
    color: #fff;
    font-weight: 600;
}

/* ---------- 历史 ---------- */

.ps-history { display: flex; flex-direction: column; gap: 2px; }

.ps-history-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 5px 8px;
    border: 0;
    border-radius: var(--r-xs);
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 12.5px;
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease);
}

.ps-history-item:hover { background: var(--brand-softer); }
.ps-history-item.future { color: var(--text-faint); }

.ps-history-item.active {
    background: var(--brand-soft);
    color: var(--brand-600);
    font-weight: 650;
}

.ps-history-dot {
    width: 6px;
    height: 6px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--border-strong);
}

.ps-history-item.active .ps-history-dot { background: var(--brand-500); }

/* 当前工具的选项条（对应 Photoshop 的选项栏位置） */
.ps-options {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    min-height: 42px;
}

.ps-opt-range { flex: 0 0 96px; width: 96px; }
.ps-text-input { flex: 0 1 200px; min-width: 120px; }
.ps-options .ps-font { flex: 0 0 132px; width: 132px; }

.ps-hint-inline {
    font-size: 12px;
    color: var(--text-faint);
    line-height: 1.5;
}

/* =====================================================================
   编辑器全屏（Word / Excel / PS 共用，配合 js 里的 PKDWorkFS）
   ---------------------------------------------------------------------
   .fs-shell 登记为全屏根；标准 Fullscreen API 生效时浏览器自动接管，
   只需补背景色避免透明露底；拿不到全屏权限时退化为 .fs-css 铺满视口。
   z-index 取 500：高于页内一切面板/工具条（最高 7），低于 Toast（4000）。
   ===================================================================== */
.fs-shell:fullscreen {
    background: var(--bg);
    overflow: auto;
}

.fs-shell.fs-css {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: var(--bg);
    overflow: auto;
}
/* 兜底防御：fs-css 依赖 fixed 铺满视口，任何祖先的 transform（哪怕恒等）都会破坏它。
   只要页面上有壳进入 CSS 兜底态，就停掉入场动画（动画早已结束，停掉无视觉变化）。 */
body:has(.fs-shell.fs-css) .page-enter { animation: none; }
/* 壳处于 .main-area(z-index:1) 的层叠上下文里，而侧栏 z-index:3 —— 壳自身的 z-index
   只在上下文内部生效，压不过侧栏。壳进入兜底态时把主区临时抬到侧栏之上。 */
body:has(.fs-shell.fs-css) .main-area { z-index: 600; }

/* 全屏态：按页面定制高度（不要写成 .fs-shell .panel 通配 —— PS 全屏态里有多个并列 panel）
   Word 用 flex 让纸张区吃掉全部剩余高度——不要用 calc(100vh - 固定值) 估算工具栏高度，
   工具栏换行/查找行显隐都会让估算失准，失准的部分就是状态栏下方的空带（2026-10-11 用户反馈）。 */
.word-shell:fullscreen,
.word-shell.fs-css {
    height: 100vh;
    display: flex;
    flex-direction: column;
}
.word-shell:fullscreen .panel-body,
.word-shell.fs-css .panel-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.word-shell:fullscreen .word-canvas,
.word-shell.fs-css .word-canvas {
    flex: 1;
    min-height: 0;
    max-height: none;   /* 放开普通态的 620px 上限 */
}
.word-shell:fullscreen .word-editor,
.word-shell.fs-css .word-editor {
    min-height: 100%;   /* 内容少时纸张也铺满画布可视区 */
}

.sheet-panel:fullscreen,
.sheet-panel.fs-css {
    height: 100vh;
}
.sheet-panel:fullscreen .sheet-scroll,
.sheet-panel.fs-css .sheet-scroll {
    /* 560px 是给普通页面留的视口余量；全屏时直接吃满（C# 侧切换后会重测虚拟化窗口） */
    max-height: none;
    height: calc(100vh - 150px);
}

.ps-fsroot {
    min-width: 0;
    min-height: 0;
}
.ps-fsroot:fullscreen,
.ps-fsroot.fs-css {
    height: 100vh;
    display: flex;
    flex-direction: column;
}
.ps-fsroot:fullscreen .ps-body,
.ps-fsroot.fs-css .ps-body {
    flex: 1;
    min-height: 0;
    align-items: stretch;
}
/* 全屏时画布要吃掉 ps-center 的全部剩余高度。
   普通态的 .ps-stage 是 clamp(420px, 62vh, 760px) —— 那是给「嵌在页面里」用的；
   1440 高的屏幕上 62vh=892 会被 760px 上限卡住，而外层面板已被拉伸到整屏，
   底部就空出 ~480px 的面板白底（2026-10-13 用户反馈的「全屏下边空白区域」）。
   注意 .ps-center / .ps-side 要配 min-height:0，否则 flex 子项不肯收缩。 */
.ps-fsroot:fullscreen .ps-center,
.ps-fsroot.fs-css .ps-center { min-height: 0; }
.ps-fsroot:fullscreen .ps-stage,
.ps-fsroot.fs-css .ps-stage {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
}
/* 右侧属性栏同理：内容再长也在整屏高度内滚动，不再留一截空白 */
.ps-fsroot:fullscreen .ps-side,
.ps-fsroot.fs-css .ps-side { min-height: 0; }
.ps-fsroot:fullscreen .ps-side-body,
.ps-fsroot.fs-css .ps-side-body {
    max-height: none;
    flex: 1 1 auto;
    min-height: 0;
}

/* ---------- Word 查找替换行 ---------- */
.word-find-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px 10px;
    background: var(--bg-inset);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}

.word-find-input {
    width: 200px;
    height: 30px;
}

.word-find-check {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12.5px;
    color: var(--text-muted);
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}

.word-find-count {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-muted);
    min-width: 56px;
}

.word-tb-btn.on {
    color: var(--brand-500);
    background: var(--brand-50);
}

/* =====================================================================
   屏幕时钟（/tools/clock）
   ---------------------------------------------------------------------
   三种模式共用一块「大数字」舞台：时钟态只有数字，计时态外面套一个随
   剩余时间收缩的圆环。字号一律用 vmin clamp——手机竖屏到 4K 屏都不溢出，
   也就不必给每个断点单独调一套字号。
   数字必须 tabular-nums：等宽数字才不会每秒跳一下字形宽度（时钟抖动）。
   ===================================================================== */
.clock-shell { display: flex; flex-direction: column; min-height: 0; }
.clock-head { flex-wrap: wrap; gap: 8px 10px; }
.clock-head .segmented { flex: 0 0 auto; }

.clock-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(18px, 3.4vmin, 34px);
    padding: clamp(20px, 4vmin, 44px) 18px;
    background: radial-gradient(560px 320px at 50% 16%, var(--brand-softer), transparent 72%);
}

/* ---------- 时钟态 ---------- */
.clock-face { display: flex; flex-direction: column; align-items: center; gap: clamp(8px, 1.6vmin, 18px); }

.clock-time {
    display: flex;
    align-items: baseline;
    gap: clamp(6px, 1.2vmin, 14px);
    line-height: 1;
}
.clock-hm {
    font-size: clamp(58px, 17vmin, 208px);
    font-weight: 750;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    background: linear-gradient(135deg, var(--brand-600), var(--accent-600));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
}
[data-theme="dark"] .clock-hm { background: linear-gradient(135deg, var(--brand-300), var(--accent-400)); -webkit-background-clip: text; background-clip: text; }

.clock-s {
    font-size: clamp(20px, 5vmin, 60px);
    font-weight: 650;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}
.clock-ampm {
    font-size: clamp(14px, 3vmin, 30px);
    font-weight: 700;
    color: var(--brand-500);
    letter-spacing: .06em;
    padding: 2px 8px;
    border: 1px solid var(--brand-soft);
    border-radius: var(--r-full);
    background: var(--brand-softer);
}
.clock-date {
    font-size: clamp(13px, 2.4vmin, 24px);
    color: var(--text-muted);
    letter-spacing: .04em;
    font-variant-numeric: tabular-nums;
}

/* ---------- 计时态：圆环 ---------- */
.clock-ring-wrap {
    position: relative;
    width: clamp(230px, 44vmin, 400px);
    aspect-ratio: 1 / 1;
    display: grid;
    place-items: center;
}
.clock-ring { width: 100%; height: 100%; display: block; }
.clock-ring-track { fill: none; stroke: var(--border); stroke-width: 9; }
.clock-ring-bar {
    fill: none;
    stroke-width: 11;
    stroke-linecap: round;
    /* 从 12 点方向起笔，剩余越多圆越满 */
    transform: rotate(-90deg);
    transform-origin: 110px 110px;
    transition: stroke-dashoffset 200ms linear;
}
.clock-ring-bar.done { stroke: var(--emerald-500); animation: clockPulse 1.5s var(--ease) infinite; }
@keyframes clockPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}

.clock-ring-center {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    align-content: center;
    gap: 4px;
    pointer-events: none;
}
.clock-timer {
    font-size: clamp(36px, 9.5vmin, 96px);
    font-weight: 750;
    letter-spacing: -0.03em;
    color: var(--text-strong);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    line-height: 1.05;
}
.clock-phase { font-size: clamp(11px, 1.9vmin, 15px); color: var(--text-faint); letter-spacing: .12em; }

/* ---------- 操作区 ---------- */
.clock-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; }

.clock-chips { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 7px; }
.clock-chips .chip {
    padding: 5px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-full);
    background: var(--bg-elevated);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: all var(--t-fast) var(--ease);
}
.clock-chips .chip:hover { border-color: var(--brand-300); color: var(--brand-600); transform: translateY(-1px); }
.clock-chips .chip.on {
    border-color: transparent;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    color: #fff;
    box-shadow: var(--shadow-brand);
}
.clock-chips .chip:focus-visible { outline: none; box-shadow: var(--ring); }

.clock-custom { display: inline-flex; align-items: center; gap: 6px; }
.clock-custom-label { font-size: 12px; color: var(--text-faint); }
.clock-num { width: 76px; text-align: center; padding: 6px 8px; font-variant-numeric: tabular-nums; }

/* ---------- 专注态 ---------- */
.clock-dots { display: flex; align-items: center; justify-content: center; gap: 8px; }
.clock-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1.5px solid var(--border-strong);
    background: transparent;
    transition: all var(--t) var(--ease);
}
.clock-dot.on {
    border-color: transparent;
    background: linear-gradient(135deg, var(--brand-500), var(--accent-500));
    box-shadow: 0 0 0 3px var(--brand-softer);
}
.clock-dots-text { font-size: 12px; color: var(--text-faint); margin-left: 6px; }

.clock-opts { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 22px; }
.clock-opt { display: inline-flex; align-items: center; gap: 7px; }
.clock-opt label { font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.clock-opt .clock-num { width: 68px; }
.clock-opt-unit { font-size: 12px; color: var(--text-faint); }
.clock-opt-hint { font-size: 11.5px; color: var(--text-faint); }

/* ---------- 全屏态（配合 PKDWorkFS） ---------- */
.clock-shell:fullscreen,
.clock-shell.fs-css {
    height: 100vh;
    display: flex;
    flex-direction: column;
}
.clock-shell:fullscreen .clock-body,
.clock-shell.fs-css .clock-body { padding: clamp(24px, 5vmin, 56px) 24px; }
/* 全屏时面板自身就是舞台：去掉卡片边框与内圆角，避免大屏上「屏中屏」的割裂感 */
.clock-shell:fullscreen,
.clock-shell.fs-css { border: none; border-radius: 0; box-shadow: none; background: var(--bg); }

/* ---------- 小屏（手机竖屏当台钟的主要场景） ---------- */
@media (max-width: 640px) {
    .clock-head { padding: 10px 12px; gap: 6px 8px; }
    .clock-head .panel-title { display: none; }
    .clock-switch-label { display: none; }
    .clock-switch { gap: 0; }
    .clock-body { padding: 22px 12px; gap: 20px; }
    .clock-chips { gap: 6px; }
    .clock-chips .chip { padding: 4px 10px; font-size: 12px; }
    .clock-num { width: 64px; }
    .clock-opt .clock-num { width: 60px; }
    .clock-opt-hint { flex-basis: 100%; text-align: center; }
}

/* 全屏空闲自动收起：控制条与全部操作控件整体淡出，只留时间 / 圆环（和专注进度点）。
   只用 opacity 不动布局——display:none 折叠会让时钟纵向跳一下。
   任何鼠标 / 触摸 / 按键活动立即唤回（JS 侧 PKDClock.barAutoHide）。
   注意 idle class 放在 head / body 上而不是 shell：shell 的 class 必须静态，
   否则 Blazor 重渲染会抹掉 JS 写入的 fs-css 兜底类（见 Clock.razor 内注释）。 */
.clock-shell:fullscreen .clock-head,
.clock-shell.fs-css .clock-head,
.clock-shell:fullscreen .clock-body,
.clock-shell.fs-css .clock-body { transition: opacity var(--t-slow) var(--ease); }
.clock-shell:fullscreen .clock-head.clock-idle-bar,
.clock-shell.fs-css .clock-head.clock-idle-bar,
.clock-shell:fullscreen .clock-body.clock-idle-bar .clock-actions,
.clock-shell.fs-css .clock-body.clock-idle-bar .clock-actions,
.clock-shell:fullscreen .clock-body.clock-idle-bar .clock-chips,
.clock-shell.fs-css .clock-body.clock-idle-bar .clock-chips,
.clock-shell:fullscreen .clock-body.clock-idle-bar .clock-opts,
.clock-shell.fs-css .clock-body.clock-idle-bar .clock-opts { opacity: 0; pointer-events: none; }

/* ---------- 全站页脚（备案信息） ---------- */
.app-footer {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 9px 16px;
    border-top: 1px solid var(--border-subtle);
    background: var(--surface-glass);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-faint);
}
.app-footer a {
    color: var(--text-faint);
    transition: color var(--t) var(--ease);
}
.app-footer a:hover { color: var(--brand-600); }
[data-theme="dark"] .app-footer a:hover { color: var(--brand-300); }

@media (max-width: 640px) {
    .app-footer { padding: 7px 12px; font-size: 11px; }
}
