/* ══════════════════════════════════════════════════════════════════════════
   工作助手 · 全站样式表
   ──────────────────────────────────────────────────────────────────────────
   这份档案分成三段，照顺序读：

     第一章 颜色积木     — 全站用到的每个颜色，都先在这里取名字（CSS 变量）
     第二章 背景装饰     — 深海 / 银河 / 北极冰川 三套背景各自的画法
     第三章 界面零件     — 侧边栏、卡片、按钮、表格、弹窗…（一律只用第一章的积木）

   想换主题只要动第一章：在 body.某主题 {...} 里把积木重新定义一次，
   第三章一行都不用改，整站就跟着变色。
   ══════════════════════════════════════════════════════════════════════════ */

* {
  box-sizing: border-box;
}

/* ══════════════════ 第一章 · 颜色积木 ══════════════════════════════════════
   预设 = 深海／银河（深色）。北极冰川的浅色版本在本章最后面覆盖。 */
:root {
  /* 底色与面板 */
  --bg: #020c18;                        /* 整页最底层 */
  --surface: rgba(3,18,40,0.75);        /* 卡片 */
  --surface-2: rgba(2,10,24,0.7);       /* 卡片里再沉一层：输入框、列表行、表头 */
  --surface-3: rgba(3,14,32,0.8);       /* 表格的标题列 */
  --surface-3-solid: rgb(3,14,32);      /* 同上，但不透明（横向卷动时不透光）*/
  --surface-4-solid: rgb(2,8,22);       /* 表格左上角那一格 */
  --surface-solid: #0b1c30;             /* 弹窗、悬浮窗（不能透明）*/
  --surface-float: rgba(3,18,40,0.92);  /* 浮在页面上的小钮（汉堡钮、架构图钮）*/
  --sidebar-bg: rgba(3,18,38,0.82);     /* 左边选单 */
  --scrim: rgba(0,0,0,0.5);             /* 手机版选单后面的黑纱 */
  --scrim-modal: rgba(2,10,24,0.65);    /* 弹窗后面的黑纱 */

  /* 线条 */
  --border: rgba(14,165,233,0.14);
  --border-soft: rgba(14,165,233,0.08);
  --border-mid: rgba(14,165,233,0.2);
  --border-strong: rgba(14,165,233,0.3);
  --neutral-soft: rgba(148,163,184,0.12);      /* 灰色淡底 */
  --neutral-soft-2: rgba(148,163,184,0.22);    /* 灰色淡底（滑过）*/
  --neutral-line-soft: rgba(148,163,184,0.15);
  --neutral-line: rgba(148,163,184,0.28);
  --neutral-line-2: rgba(148,163,184,0.35);
  --neutral-dim: rgba(148,163,184,0.4);
  --neutral-icon: rgba(148,163,184,0.75);

  /* 文字 */
  --text: #cce3f5;          /* 一般内文 */
  --text-strong: #e2e8f0;   /* 重点字 */
  --heading: #f8fafc;       /* 标题 */
  --muted: #5b8db8;         /* 次要说明 */
  --muted-2: #94a3b8;       /* 更淡的说明 */
  --label: #94c9e8;         /* 表单栏位名 */
  --dim: #7f8ea3;           /* 最不起眼的小字 */

  /* 主色（蓝）：查询、跳转、选中状态 */
  --accent: #38bdf8;
  --accent-text: #7dd3fc;
  --accent-alt: #93c5fd;
  --accent-soft: rgba(56,189,248,0.18);
  --accent-soft-2: rgba(56,189,248,0.28);
  --accent-line-soft: rgba(56,189,248,0.4);
  --accent-line: rgba(56,189,248,0.55);
  --accent-line-strong: rgba(56,189,248,0.75);
  --accent-glow: rgba(56,189,248,0.4);      /* 品牌字的光晕 */

  /* 成功（绿） */
  --ok: #34d399;
  --ok-text: #6ee7b7;
  --ok-soft: rgba(52,211,153,0.12);
  --ok-soft-2: rgba(52,211,153,0.22);
  --ok-line: rgba(52,211,153,0.35);
  --ok-bg: rgba(6,60,30,0.7);

  /* 危险（红） */
  --danger: #f87171;
  --danger-text: #fca5a5;
  --danger-strong: #ef4444;
  --danger-soft: rgba(248,113,113,0.18);
  --danger-soft-2: rgba(248,113,113,0.28);
  --danger-line: rgba(248,113,113,0.55);
  --danger-bg: rgba(80,10,10,0.7);

  /* 提醒（黄） */
  --warn: #fbbf24;
  --warn-text: #fcd34d;
  --warn-strong: #f59e0b;
  --warn-soft: rgba(251,191,36,0.12);
  --warn-soft-2: rgba(251,191,36,0.22);
  --warn-line: rgba(251,191,36,0.4);

  /* 紫 */
  --purple: #c084fc;
  --purple-2: #a78bfa;
  --purple-3: #e879f9;
  --purple-soft: rgba(192,132,252,0.14);
  --purple-soft-2: rgba(192,132,252,0.24);

  /* 班表格子：每种假别一个底色 */
  --sched-off-bg: #0d3a5c;
  --sched-leave-bg: #2d1a4a;
  --sched-spec-bg: #2a1f05;
  --sched-sick-bg: #0d3326;
  --sched-grief-bg: #1e1a3a;
  --sched-mat-bg: #06302c;
  --sched-mat-fg: #2dd4bf;
  --sched-period-bg: #3a0d1a;
  --sched-other-bg: #262b33;
  --sched-other-fg: #cbd5e1;

  /* 右下角🔔泡泡 / 私聊气泡（base.html 用） */
  --bell-bg: linear-gradient(145deg,#0e2c47,#0b1c30);
  --dm-bubble-bg: #14304a;      /* 对方讲的话，那颗气泡的底色 */
  --dm-mine-bg: #2563eb;        /* 自己讲的话，那颗气泡的底色（2026-08-24 补：以前写死在 base.html）*/
  --dm-mine-time: rgba(255,255,255,0.72);   /* 自己那颗气泡上的时间戳 */

  /* 阴影 */
  --shadow-color: rgba(0,0,0,0.5);   /* 只给「自己拼阴影」的地方用（base.html 的悬浮窗）*/
  --shadow: 0 4px 14px rgba(0,0,0,0.35);

  /* 登入页的大背景 */
  --login-bg:
    radial-gradient(ellipse 70% 50% at 50% 0%, rgba(6,40,80,0.6) 0%, transparent 70%),
    radial-gradient(ellipse 50% 60% at 20% 80%, rgba(2,20,50,0.5) 0%, transparent 65%),
    linear-gradient(180deg, #020c18 0%, #031422 40%, #04192d 100%);
}

/* ══════════════════ 北极冰川：把上面的积木换成浅色 ═══════════════════════
   规则：白底 + 浅蓝 + 浅灰。文字反过来变深，才看得清楚。
   （加 .login-body.arctic 是因为登入页没有套 base.html，class 长得不一样） */
body.arctic,
body.login-body.arctic {
  /* 底色与面板 —— 白 / 冰蓝 / 浅灰 */
  --bg: #eef4fa;
  --surface: rgba(255,255,255,0.9);    /* 白底给到 0.9，背景的冰山海豹才不会透进卡片影响阅读 */
  --surface-2: rgba(238,245,251,0.85);
  --surface-3: rgba(224,236,246,0.92);
  --surface-3-solid: rgb(226,238,247);
  --surface-4-solid: rgb(213,229,243);
  --surface-solid: #ffffff;
  --surface-float: rgba(255,255,255,0.94);
  --sidebar-bg: rgba(255,255,255,0.86);
  --scrim: rgba(30,58,84,0.35);
  --scrim-modal: rgba(30,58,84,0.3);

  /* 线条 —— 浅灰蓝，不刺眼但看得见边界 */
  --border: rgba(120,158,190,0.28);
  --border-soft: rgba(120,158,190,0.16);
  --border-mid: rgba(120,158,190,0.4);
  --border-strong: rgba(90,135,175,0.55);
  --neutral-soft: rgba(100,130,160,0.09);
  --neutral-soft-2: rgba(100,130,160,0.18);
  --neutral-line-soft: rgba(120,158,190,0.22);
  --neutral-line: rgba(120,158,190,0.42);
  --neutral-line-2: rgba(100,140,180,0.55);
  --neutral-dim: rgba(100,140,180,0.6);
  --neutral-icon: rgba(90,125,160,0.8);

  /* 文字 —— 深蓝灰，白底上够黑才好读
     ─────────────────────────────────────────────────────────────────────
     ★ 浅色主题的每个「会拿来当字」的颜色，都必须在 --surface-4-solid
       （#d5e5f3，本主题最深的那块浅色面板）上撑到 4.5:1 以上（WCAG 2.1 AA）。
       在最深的面板上过关，其他更白的地方一定过。
       要改这里，先跑专案根目录的 contrast_audit.py 量过再改，别凭肉眼调 ——
       浅色主题「看起来还好」跟「真的够对比」差很多，2026-08-15 就是这样被反映的。 */
  --text: #1f3b55;
  --text-strong: #12293e;
  --heading: #0d2136;
  --muted: #49647a;
  --muted-2: #546275;
  --label: #3d6485;
  --dim: #4f6575;

  /* 主色（蓝）—— 白底要用深一点的蓝，浅蓝在白底上会看不见 */
  --accent: #02628f;
  --accent-text: #03649a;
  --accent-alt: #1454dd;
  --accent-soft: rgba(2,132,199,0.10);
  --accent-soft-2: rgba(2,132,199,0.18);
  --accent-line-soft: rgba(2,132,199,0.35);
  --accent-line: rgba(2,132,199,0.5);
  --accent-line-strong: rgba(2,132,199,0.7);
  --accent-glow: rgba(2,132,199,0.18);

  /* 成功（绿） */
  --ok: #046e4d;
  --ok-text: #036348;
  --ok-soft: rgba(5,150,105,0.10);
  --ok-soft-2: rgba(5,150,105,0.18);
  --ok-line: rgba(5,150,105,0.38);
  --ok-bg: rgba(209,250,229,0.85);

  /* 危险（红） */
  --danger: #b61d1d;
  --danger-text: #b91c1c;
  --danger-strong: #b61d1d;
  --danger-soft: rgba(220,38,38,0.09);
  --danger-soft-2: rgba(220,38,38,0.17);
  --danger-line: rgba(220,38,38,0.4);
  --danger-bg: rgba(254,226,226,0.85);

  /* 提醒（黄） */
  --warn: #9f4908;
  --warn-text: #92400e;
  --warn-strong: #975304;
  --warn-soft: rgba(217,119,6,0.10);
  --warn-soft-2: rgba(217,119,6,0.18);
  --warn-line: rgba(217,119,6,0.4);

  /* 紫 */
  --purple: #7935ed;
  --purple-2: #6d28d9;
  --purple-3: #a21caf;
  --purple-soft: rgba(124,58,237,0.10);
  --purple-soft-2: rgba(124,58,237,0.18);

  /* 班表格子：改成浅色底 + 深色字（字的颜色在第三章里也走积木） */
  --sched-off-bg: #dbeafe;
  --sched-leave-bg: #ede9fe;
  --sched-spec-bg: #fef3c7;
  --sched-sick-bg: #d1fae5;
  --sched-grief-bg: #e0e7ff;
  --sched-mat-bg: #ccfbf1;
  --sched-mat-fg: #0f766e;
  --sched-period-bg: #ffe4e6;
  --sched-other-bg: #e2e8f0;
  --sched-other-fg: #334155;

  /* 右下角🔔泡泡 / 私聊气泡 */
  --bell-bg: linear-gradient(145deg,#ffffff,#e6f1fa);
  --dm-bubble-bg: #e8f1f8;
  --dm-mine-bg: #2563eb;        /* 自己讲的话，那颗气泡的底色（2026-08-24 补：以前写死在 base.html）*/
  --dm-mine-time: rgba(255,255,255,0.78);   /* 自己那颗气泡上的时间戳 */

  /* 阴影 —— 浅色主题下要很淡，太黑会脏 */
  --shadow-color: rgba(30,58,84,0.18);
  --shadow: 0 4px 14px rgba(30,58,84,0.10);

  /* 登入页背景：晴空 → 冰原 */
  --login-bg:
    radial-gradient(ellipse 80% 55% at 50% -5%, rgba(186,224,248,0.85) 0%, transparent 70%),
    radial-gradient(ellipse 60% 55% at 15% 85%, rgba(219,234,248,0.9) 0%, transparent 68%),
    linear-gradient(180deg, #eaf4fc 0%, #f3f9fd 45%, #ffffff 100%);
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* ══════════════════ 第二章 · 背景装饰 ═══════════════════════════════════ */

/* ── Deep sea background ── */
/* Static galaxy background theme */
body.galaxy-bg {
  background: #020c18;
}

body.galaxy-bg::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(rgba(2,12,24,0.5), rgba(2,12,24,0.66)),
    url('/static/img/nebula-bg.jpg') center center / cover no-repeat;
  /* JWST 星云本身就是红蓝色，保留原色、不做色相偏移 */
  filter: saturate(1.05);
}

.sea-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(ellipse 90% 55% at 50% -8%, rgba(20,90,140,0.45) 0%, rgba(8,45,80,0.18) 38%, transparent 68%),
    radial-gradient(circle at 82% 12%, rgba(45,160,200,0.14) 0%, transparent 42%),
    linear-gradient(180deg, #05203a 0%, #041a30 26%, #03121f 58%, #010a14 100%);
}

/* god rays — 柔和倾泻的水下丁达尔光束 */
.sea-bg::before {
  content: '';
  position: absolute;
  top: -20%;
  left: -12%;
  right: -12%;
  height: 150%;
  background:
    linear-gradient(103deg, transparent 17%, rgba(90,200,240,0.06) 22%, transparent 28%),
    linear-gradient(105deg, transparent 33%, rgba(120,215,250,0.05) 39%, transparent 46%),
    linear-gradient(101deg, transparent 52%, rgba(80,190,235,0.055) 57%, transparent 64%),
    linear-gradient(107deg, transparent 71%, rgba(110,205,245,0.045) 76%, transparent 83%);
  filter: blur(7px);
  mix-blend-mode: screen;
}

/* 海底幽光 — 底部渐暗，营造深邃感 */
.sea-bg::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 34%;
  background: linear-gradient(0deg, rgba(1,8,18,0.92) 0%, rgba(2,15,35,0.34) 46%, transparent 100%);
}

/* ══════════════════ 北极冰川背景 ═══════════════════════════════════════════
   一共四层，由远到近叠出来的（全都是 CSS 画的，没有图档、不吃流量）：
     .arctic-bg          天空 —— 上面淡蓝、下面接近白，像清晨的极地
     .arctic-bg::before  极光 —— 斜斜的几道淡青绿光带，很慢地飘
     .arctic-bg::after   远山 —— 地平线上一排半透明的冰峰剪影
     .arctic-ice         冰原 —— 页面底部的雪地，带几道裂纹的高光
   加上到处慢慢飘的 .snow 雪花。 */
.arctic-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(ellipse 100% 60% at 50% -10%, rgba(147,206,240,0.55) 0%, rgba(191,225,246,0.28) 42%, transparent 72%),
    radial-gradient(circle at 78% 16%, rgba(255,255,255,0.75) 0%, transparent 38%),
    linear-gradient(180deg, #d8ecfa 0%, #e8f4fc 30%, #f4fafd 58%, #ffffff 100%);
}

/* 极光：三条很淡的斜光带，横着来回飘 */
.arctic-bg::before {
  content: '';
  position: absolute;
  top: -15%;
  left: -20%;
  right: -20%;
  height: 70%;
  background:
    linear-gradient(98deg, transparent 12%, rgba(125,211,252,0.30) 20%, transparent 30%),
    linear-gradient(94deg, transparent 36%, rgba(167,243,208,0.24) 45%, transparent 55%),
    linear-gradient(101deg, transparent 62%, rgba(191,219,254,0.28) 71%, transparent 80%);
  filter: blur(26px);
  animation: aurora-drift 46s ease-in-out infinite;
}

@keyframes aurora-drift {
  0%, 100% { transform: translateX(-3%) translateY(0); opacity: 0.85; }
  50%      { transform: translateX(3%)  translateY(14px); opacity: 1; }
}

/* 远方的冰峰：用 clip-path 切出锯齿状的山棱线 */
.arctic-bg::after {
  content: '';
  position: absolute;
  left: -2%;
  right: -2%;
  bottom: 20%;
  height: 30%;
  background: linear-gradient(180deg, rgba(255,255,255,0.92) 0%, rgba(203,229,246,0.72) 55%, rgba(186,220,242,0.5) 100%);
  clip-path: polygon(
    0% 100%, 0% 62%, 6% 44%, 11% 58%, 17% 30%, 23% 52%, 29% 38%, 34% 55%,
    41% 22%, 47% 46%, 53% 33%, 58% 51%, 65% 26%, 71% 48%, 77% 36%, 83% 54%,
    89% 40%, 95% 57%, 100% 46%, 100% 100%
  );
  filter: blur(0.4px);
}

/* 脚下的冰原：雪白的地面 + 几道裂纹高光 */
.arctic-ice {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 22%;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(219,238,250,0.55) 0%, rgba(255,255,255,0.92) 45%, #ffffff 100%);
}

.arctic-ice::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(76deg,  transparent 18%, rgba(147,197,231,0.35) 19%, transparent 20%),
    linear-gradient(-64deg, transparent 44%, rgba(147,197,231,0.28) 45%, transparent 46%),
    linear-gradient(83deg,  transparent 70%, rgba(147,197,231,0.32) 71%, transparent 72%),
    linear-gradient(-71deg, transparent 88%, rgba(147,197,231,0.22) 89%, transparent 90%);
}

/* 雪花：小白点，从上面慢慢飘下来，边飘边左右晃 */
.snow {
  position: fixed;
  top: -12px;
  z-index: 1;
  pointer-events: none;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 6px rgba(255,255,255,0.95), 0 0 2px rgba(125,180,220,0.5);
  opacity: 0.9;
  animation: snow-fall linear infinite;
  will-change: transform, opacity;
}

@keyframes snow-fall {
  0%   { transform: translate(0, 0) rotate(0deg);        opacity: 0; }
  8%   { opacity: 0.95; }
  50%  { transform: translate(26px, 50vh) rotate(180deg); }
  92%  { opacity: 0.6; }
  100% { transform: translate(-14px, 106vh) rotate(360deg); opacity: 0; }
}

/* 北极的 emoji 装饰，沿用海洋主题那套 .creature 定位规则，
   只是把发光改成浅色主题下看得见的淡蓝影子 */
body.arctic .creature {
  filter: drop-shadow(0 3px 10px rgba(80,130,175,0.35));
}

/* 海豹：趴在冰上不动，就一只大海豹待在右下角（啤啤指定：放大、不要跑） */
.creature-seal {
  font-size: 296px;
  bottom: 4%;
  right: 6%;
  opacity: 0.85;
}

/* 冰山：远远地飘，很淡，当背景 */
.creature-iceberg {
  font-size: 130px;
  bottom: 20%;
  left: 3%;
  opacity: 0.2;
  animation: iceberg-bob 20s ease-in-out infinite;
}

.creature-iceberg2 {
  font-size: 92px;
  bottom: 24%;
  right: 30%;
  opacity: 0.16;
  animation: iceberg-bob 26s ease-in-out infinite;
  animation-delay: -9s;
}

/* 雪花 emoji：挂在天上慢慢转 */
.creature-flake {
  font-size: 38px;
  top: 12%;
  right: 14%;
  opacity: 0.4;
  animation: flake-spin 30s linear infinite;
}

.creature-flake2 {
  font-size: 26px;
  top: 26%;
  left: 12%;
  opacity: 0.34;
  animation: flake-spin 44s linear infinite reverse;
}

@keyframes iceberg-bob {
  0%, 100% { transform: translateY(0)    rotate(-0.6deg); }
  50%      { transform: translateY(-14px) rotate(0.6deg); }
}

@keyframes flake-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ── Creatures ── */
.creature {
  position: fixed;
  pointer-events: none;
  z-index: 1;
  user-select: none;
  will-change: transform;
  line-height: 1;
  display: flex;
}

.creature svg {
  display: block;
  height: 1em;
  width: auto;
}

.creature img {
  display: block;
  height: 1em;
  width: auto;
}

/* Whale – right→left, already faces left ✓ */
.creature-whale {
  font-size: 200px;
  bottom: 16%;
  right: -200px;
  opacity: 0.6;
  color: #7dd3fc;
  filter:
    drop-shadow(0 0 30px rgba(56,189,248,0.35))
    drop-shadow(0 6px 18px rgba(0,30,80,0.5))
    brightness(0.9) saturate(1.2);
  animation: drift-left 110s linear infinite;
  animation-delay: -22s;
}

/* Godzilla – huge, lurking in the background */
.creature-godzilla {
  font-size: 520px;
  bottom: -40px;
  right: 5%;
  opacity: 0.2;
  color: #0e3a5f;
  filter:
    drop-shadow(0 0 80px rgba(0,80,160,0.6));
  animation: godzilla-breathe 8s ease-in-out infinite;
  animation-delay: -3s;
  z-index: 0;
  line-height: 1;
}

/* Jellyfish 1 – large, purple glow, gentle bob */
.creature-jelly1 {
  font-size: 90px;
  top: 8%;
  left: 6%;
  opacity: 0.55;
  color: #c084fc;
  filter:
    drop-shadow(0 0 28px rgba(168,85,247,0.5))
    drop-shadow(0 0 60px rgba(139,92,246,0.2))
    brightness(1.1);
  animation: jelly-float 14s ease-in-out infinite, jelly-drift-right 90s linear infinite;
  animation-delay: 0s, -12s;
}

/* Jellyfish 2 – medium, drifts right→left, needs flip */
.creature-jelly2 {
  font-size: 65px;
  top: 28%;
  right: -100px;
  opacity: 0.45;
  color: #c084fc;
  filter:
    drop-shadow(0 0 20px rgba(192,132,252,0.45))
    brightness(1.05);
  animation: jelly-float 10s ease-in-out infinite, drift-left 95s linear infinite;
  animation-delay: -5s, -30s;
}

/* Jellyfish 3 – small, login page extra */
.creature-jelly3 {
  font-size: 50px;
  bottom: 10%;
  left: -80px;
  opacity: 0.4;
  color: #c084fc;
  filter: drop-shadow(0 0 16px rgba(168,85,247,0.4));
  animation: jelly-float 11s ease-in-out infinite, jelly-drift-right 110s linear infinite;
  animation-delay: -6s, -45s;
}


/* Fish school – right→left, already face left ✓ */
.creature-fish {
  font-size: 40px;
  bottom: 58%;
  right: -100px;
  opacity: 0.5;
  color: #38bdf8;
  letter-spacing: 6px;
  filter:
    drop-shadow(0 0 10px rgba(56,189,248,0.2))
    brightness(0.9);
  animation: drift-left 45s linear infinite;
  animation-delay: -8s;
  gap: 16px;
}

/* Fish school 2 – left→right, needs flip */
.creature-fish2 {
  font-size: 32px;
  bottom: 72%;
  left: -120px;
  opacity: 0.4;
  color: #38bdf8;
  letter-spacing: 4px;
  filter: drop-shadow(0 0 8px rgba(56,189,248,0.15));
  animation: drift-right 58s linear infinite;
  animation-delay: -20s;
  gap: 12px;
  transform: scaleX(-1);
}

/* ── 章鱼 & 虾米（2026-08-24 补齐）─────────────────────────────────────────
   这两只在 login.html 一直都写着，但 ① sea-creatures.svg 里没有它们的图案
   ② style.css 里连一条规则都没有 —— 所以深海主题的登入页上，
   一只章鱼加五只虾米一直是「画不出来的空白」，而且因为没有定位规则，
   它们全挤在 .creature 的预设起点上。图案与规则都是这次补的。
   （octo-wander 那组动画早就写好了，只是从来没有规则去用它。）        */
.creature-octo {
  font-size: 110px;
  top: 22%;
  right: -160px;
  opacity: 0.42;
  color: #c084fc;                       /* 给 sea-emoji 主题的 🐙 用 */
  filter:
    drop-shadow(0 0 26px rgba(168,85,247,0.4))
    drop-shadow(0 4px 14px rgba(0,30,80,0.4));
  animation: octo-wander 78s ease-in-out infinite;
  animation-delay: -12s;
}

.creature-shrimp {
  font-size: 34px;
  right: -140px;                        /* bottom 由 login.html 就地指定 */
  opacity: 0.45;
  color: #fb923c;                       /* 给 sea-emoji 主题的 🦐 用 */
  letter-spacing: 5px;
  filter: drop-shadow(0 0 9px rgba(251,146,60,0.18));
  animation: drift-left 52s linear infinite;
  animation-delay: -14s;
  gap: 14px;
}

/* 让鱼群上下错落、大小不一，像自然的一小群，而不是一条直挺挺的队伍 */
.creature-fish svg:nth-child(1) { transform: translateY(-11px) scale(1); }
.creature-fish svg:nth-child(2) { transform: translateY(13px) scale(0.82); margin-left: 3px; }
.creature-fish svg:nth-child(3) { transform: translateY(-4px) scale(1.14); margin-left: 7px; }
.creature-fish svg:nth-child(4) { transform: translateY(19px) scale(0.9); }
.creature-fish svg:nth-child(5) { transform: translateY(4px) scale(1.03); margin-left: 9px; }
.creature-fish2 svg:nth-child(1) { transform: translateY(8px) scale(0.9); }
.creature-fish2 svg:nth-child(2) { transform: translateY(-9px) scale(1.1); margin-left: 5px; }
.creature-fish2 svg:nth-child(3) { transform: translateY(15px) scale(0.8); margin-left: 4px; }

/* 虾米也散开，别排成一直线（照鱼群同一套做法）*/
.creature-shrimp svg:nth-child(1) { transform: translateY(6px) scale(0.95); }
.creature-shrimp svg:nth-child(2) { transform: translateY(-8px) scale(1.08); margin-left: 4px; }
.creature-shrimp svg:nth-child(3) { transform: translateY(11px) scale(0.86); margin-left: 8px; }
.creature-shrimp svg:nth-child(4) { transform: translateY(-3px) scale(1.02); margin-left: 2px; }
.creature-shrimp svg:nth-child(5) { transform: translateY(14px) scale(0.9);  margin-left: 7px; }

/* Bubbles */
.bubble {
  position: fixed;
  pointer-events: none;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, rgba(255,255,255,0.4), rgba(56,189,248,0.06));
  border: 1px solid rgba(56,189,248,0.22);
  animation: rise linear infinite;
  will-change: transform, opacity;
}

/* drift-left: emoji already face LEFT, just translate ✓ */
@keyframes drift-left {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100vw - 300px)); }
}

/* drift-right: flip to face RIGHT then move ✓ */
@keyframes drift-right {
  from { transform: scaleX(-1) translateX(0); }
  to   { transform: scaleX(-1) translateX(calc(-100vw - 300px)); }
}

/* jellyfish drifts slowly rightward */
@keyframes jelly-drift-right {
  from { transform: translateX(-120px); }
  to   { transform: translateX(110vw); }
}

@keyframes jelly-float {
  0%, 100% { margin-top: 0px;   filter: drop-shadow(0 0 28px rgba(168,85,247,0.5)) brightness(1.1); }
  50%       { margin-top: 36px; filter: drop-shadow(0 0 40px rgba(168,85,247,0.7)) brightness(1.2); }
}

/* Octopus erratic bouncing wander across screen */
@keyframes octo-wander {
  0%   { transform: translate(0, 0px)    rotate(0deg)   scale(1); }
  8%   { transform: translate(-6vw,  -90px)  rotate(-18deg) scale(1.08); }
  16%  { transform: translate(-15vw,  70px)  rotate(14deg)  scale(0.93); }
  24%  { transform: translate(-25vw, -110px) rotate(-22deg) scale(1.1); }
  32%  { transform: translate(-36vw,  55px)  rotate(16deg)  scale(0.96); }
  40%  { transform: translate(-46vw, -80px)  rotate(-10deg) scale(1.05); }
  48%  { transform: translate(-56vw,  95px)  rotate(20deg)  scale(0.91); }
  56%  { transform: translate(-65vw, -65px)  rotate(-16deg) scale(1.07); }
  64%  { transform: translate(-75vw,  45px)  rotate(12deg)  scale(0.95); }
  72%  { transform: translate(-84vw, -100px) rotate(-20deg) scale(1.09); }
  80%  { transform: translate(-93vw,  60px)  rotate(18deg)  scale(0.94); }
  90%  { transform: translate(-103vw,-40px)  rotate(-8deg)  scale(1.02); }
  100% { transform: translate(-115vw, 0px)   rotate(0deg)   scale(1); }
}

/* Godzilla subtle breathing */
@keyframes godzilla-breathe {
  0%, 100% { transform: scale(1)    translateY(0px); opacity: 0.07; }
  50%       { transform: scale(1.015) translateY(-12px); opacity: 0.09; }
}

@keyframes sink-down {
  from { transform: translateY(-140px); }
  to   { transform: translateY(115vh); }
}

@keyframes rise {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  8%   { opacity: 0.9; }
  92%  { opacity: 0.5; }
  100% { transform: translateY(-100vh) translateX(15px); opacity: 0; }
}

a {
  text-decoration: none;
}

button,
.btn-link {
  background: var(--accent-soft);
  color: var(--accent-text);
  border: 1.5px solid var(--accent-line);
  border-radius: 6px;
  padding: 9px 16px;
  font-weight: 600;
  cursor: pointer;
  display: inline-block;
  box-shadow: none;
  transition: background 0.15s, border-color 0.15s;
}

/* 「条件还没满足，整块先停用」的区块（例：SSO 一颗产品都没勾时的批次操作列）。
   淡化程度不写死在各页面：深色底淡到 0.4 还看得见，浅色底淡到 0.4 就整块糊进白色，
   所以浅色主题在本章最后另外覆盖成比较高的值。 */
.block-off {
  opacity: 0.4;
  pointer-events: none;
}

button:hover,
.btn-link:hover {
  opacity: 1;
  background: var(--accent-soft-2);
  box-shadow: none;
}

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator {
  filter: invert(92%) sepia(8%) saturate(142%) hue-rotate(184deg) brightness(108%) contrast(92%);
  opacity: 0.9;
  cursor: pointer;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="month"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* ══════════════════ 第三章 · 界面零件 ═════════════════════════════════════ */

/* ── 右下角那颗悬浮泡泡（🔔通知／私聊）占掉的地盘 ────────────────────────────
   泡泡是 position:fixed 浮在最上层的，画面右下角那一块永远被它盖住。
   页面内容会滚动，滚过去就好；但「钉在画面底部、滚不开」的东西（例如聊天页
   那排输入框）会被它压死 —— 2026-08-18 就是这样：手机上「送出」整颗看不到。

   所以泡泡的尺寸只在这里写一次，base.html 的泡泡本体、聊天页要让出来的宽度
   都读这三个积木，改一处两边同步，不会再各写各的对不上。
     --fab-size  泡泡直径
     --fab-gap   泡泡离画面右／下缘多远
     --fab-safe  底部横条要往右让出多少（泡泡本体＋一点空隙；横条右缘本来就比
                 泡泡右缘再靠左一点，所以不必加满 gap）
     --fab-step  🔧扳手泡泡叠在🔔上面，两颗之间的空隙（1023 加）
     --fab-stack 两颗叠起来多高：每页底部要留的空白照它算，不然最后一排右边的按钮会被扳手盖住*/
:root {
  --fab-size: 54px;
  --fab-gap: 24px;
  --fab-safe: calc(var(--fab-size) + 26px);
  --fab-step: 12px;
  --fab-stack: calc(var(--fab-size) * 2 + var(--fab-step));
}

.layout {
  display: flex;
  min-height: 100vh;
  position: relative;
  z-index: 2;
}

.sidebar {
  width: 250px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 20px;
  border-right: 1px solid var(--border);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  font-size: 24px;
  font-weight: 700;
  margin-bottom: 18px;
  color: var(--accent);
  text-shadow: 0 0 18px var(--accent-glow);
  letter-spacing: 0.5px;
}

.nav-main {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.nav-group {
  display: block;
}

.nav-summary {
  list-style: none;
  cursor: pointer;
}

.nav-summary::-webkit-details-marker {
  display: none;
}

.nav-summary::after {
  content: '▾';
  float: right;
  color: var(--text-strong);
  font-size: 12px;
  margin-top: 2px;
}

.nav-group:not([open]) .nav-summary::after {
  content: '▸';
}

.nav-children {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0 6px 12px;
  padding-left: 12px;
  border-left: 2px solid var(--border-mid);
}

.childlink {
  display: block;
  padding: 10px 12px;
  border-radius: 10px;
  background: transparent;
  color: var(--label);
  font-size: 14px;
  font-weight: 700;
  border: 1px solid transparent;
}

.childlink.active {
  background: var(--accent-soft);
  color: var(--accent-text);
  border-color: var(--accent-line-soft);
}

.navlink {
  display: block;
  color: var(--label);
  padding: 12px 14px;
  border-radius: 10px;
  transition: background 0.2s, color 0.2s;
}

.navlink.active,
.navlink:hover {
  background: var(--accent-soft);
  color: var(--accent-text);
}

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

.settings-link {
  background: var(--surface-2);
  border: 1px solid var(--border-mid);
}

.logout {
  color: var(--danger);
  /* display:block + 12px 上下内距 = 约 45px 高。原本 8px 只有 37px，
     低于手指按得准的门槛（Apple 建议 44）。 */
  display: block;
  padding: 12px 4px;
  transition: color 0.2s;
}

.logout:hover {
  color: var(--danger-text);
}

.userbox {
  padding: 14px;
  border-radius: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
}

.user-name {
  font-size: 18px;
  font-weight: 700;
  margin: 6px 0;
}

.main {
  flex: 1;
  min-width: 0;
  padding: 28px;
  /* 底下多留一截空白：右下角那两颗泡泡（🔧＋🔔）会盖住画面右下角，留了这段空白，
     每一页的最后一行内容都还能往上滚出泡泡底下（不然最后一颗按钮点不到）*/
  padding-bottom: calc(var(--fab-stack) + var(--fab-gap) + 20px);
  background: transparent;
  overflow-x: hidden;
}

.pagehead {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
  margin-bottom: 20px;
}

/* ── 右上角浮动钮：代码架构地图（每页可见，固定在视窗右上角）── */
.arch-fab {
  position: fixed;
  top: 14px;
  right: 20px;
  z-index: 120;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: 20px;
  background: var(--surface-float);
  border: 1px solid var(--accent-line-soft);
  color: var(--accent-text);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow);
  transition: background 0.15s, border-color 0.15s;
}
.arch-fab:hover { background: var(--accent-soft); border-color: var(--accent-line-strong); }
.arch-fab .ic { font-size: 15px; line-height: 1; }

/* 更新日志页那颗放两倍大（更显眼，导去架构地图）。只出现在更新日志页，那页右上角本来是空的，不会撞到东西 */
.arch-fab.big {
  top: 18px;
  right: 24px;
  gap: 10px;
  padding: 14px 26px;
  font-size: 22px;
  border-radius: 30px;
  border-width: 2px;
}
.arch-fab.big .ic { font-size: 26px; }

@media (max-width: 700px) {
  .arch-fab { top: 10px; right: 12px; padding: 6px 9px; }
  .arch-fab .t { display: none; }   /* 手机版只留地图图示，省空间 */
  .arch-fab.big { top: 10px; right: 12px; padding: 8px 11px; font-size: 15px; }
  .arch-fab.big .ic { font-size: 20px; }
}

.card {
  background: var(--surface);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 18px;
}

.toolbar {
  display: flex;
  gap: 16px;
  align-items: end;
  flex-wrap: wrap;
}

.archive-toolbar-inline {
  margin: 14px 0 18px;
}

.toolbar input,
.toolbar select,
input,
select,
textarea {
  width: 100%;
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border-mid);
  border-radius: 10px;
  padding: 10px 12px;
  transition: border-color 0.2s, box-shadow 0.2s;
}

input[type="radio"],
input[type="checkbox"] {
  width: auto;
  padding: 0;
  border: none;
  background: none;
  border-radius: 0;
}

/* 用手指点的机子（手机、平板）：勾选框放大。
   浏览器给的原始大小是 13×13，用滑鼠点没问题，用手指点常常点不中 ——
   /sso 一次列 39 个产品、发通知一次列 20 几个收件人，全是这种小方格。
   (pointer: coarse) = 「主要输入装置是手指」，桌机滑鼠不受影响、维持原样。*/
@media (pointer: coarse) {
  input[type="radio"],
  input[type="checkbox"] {
    width: 21px;
    height: 21px;
    min-width: 21px;
    accent-color: var(--accent);
  }

  /* ★ 手机上碰输入框不要把整页放大。
     iPhone 的 Safari 有一条写死的行为：点进字级**小於 16px** 的输入框，
     它会自动把整页放大到看得清楚为止，而且**不会自己缩回去**——
     从那一刻起整个网站看起来就变得又大又歪。
     浏览器给输入框的预设字级是 13.33px，我们从来没设过，所以全站每一页都会中；
     啤啤 0902 反映「网页整体比例太大就很难看」就是这个。
     这里只指定「元素」层级（input/select/textarea），
     所以有自己 class 的密集元件（班表下拉、质检的小方框…）维持原本的小字不受影响。 */
  input:not([type="radio"]):not([type="checkbox"]):not([type="file"]),
  select,
  textarea {
    font-size: 16px;
  }
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.toolbar > div {
  min-width: 180px;
}

.toolbar-actions {
  display: flex;
  gap: 10px;
  /* 手机上一定要能换行。不换行的话 flex 会把每个东西压扁去挤同一列 ——
     离席页量到的就是这个：查询钮被推到画面外 99px，「只看某人」的下拉
     被挤成 26px 宽，手指根本点不到。 */
  flex-wrap: wrap;
}

.archive-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.archive-item {
  display: grid;
  grid-template-columns: 120px 1fr 1fr 170px;
  gap: 12px;
  padding: 14px;
  border-radius: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  align-items: center;
}

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

.small-actions button {
  padding: 8px 12px;
}

.empty {
  padding: 20px;
  color: var(--muted-2);
  text-align: center;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

/* 四栏并排（开始日期／开始时间／结束日期／结束时间这种）。
   以前是直接写在 HTML 的 style 里，手机版的规则管不到它，日期框就被切掉一截；
   改成挂这个 class，窄画面时下面的媒体查询会自动折成两栏、再窄折成一栏。 */
.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}

/* 四栏後面再挂一颗按钮的版本（补爬对话那排）。窄画面时下面的媒体查询照样把它折成两栏／一栏 */
.grid-4-act {
  grid-template-columns: repeat(4, 1fr) auto;
  gap: 10px;
  align-items: end;
}

/* 放不下就左右滑的表格外框。
   .main 是 overflow-x:hidden（挡住整页乱跑），表格太宽会直接被裁掉、右边永远看不到；
   包一层这个，表格就在自己的框里左右滑，整页还是不动。 */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.big-text {
  min-height: 380px;
}

.medium-text {
  min-height: 160px;
}

.meta-list {
  padding-left: 18px;
}

.section-head,
.list-head,
.stat-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.stat-row {
  flex-wrap: wrap;
}

.warning-banner {
  background: var(--danger-soft);
  border-left: 4px solid var(--danger-strong);
  border-radius: 0 6px 6px 0;
  color: var(--danger-text);
  font-size: 1rem;
  font-weight: 600;
  padding: 10px 14px;
  margin-bottom: 12px;
  line-height: 1.6;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.warning-banner::before {
  content: "⚠️";
  flex-shrink: 0;
  margin-top: 1px;
}
.monthly-stats {
  display: flex;
  gap: 20px;
  align-items: center;
  flex-wrap: wrap;
  margin-left: auto;
  font-size: 0.88rem;
  color: var(--muted-2);
  padding: 4px 0;
}
.monthly-stats strong {
  color: var(--text);
}

.table-like {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}

.table-like .row {
  display: grid;
  grid-template-columns: 140px 1fr 120px 120px;
  gap: 10px;
  padding: 12px 14px;
  border-top: 1px solid var(--border);
  align-items: center;
}

.table-like .row.head {
  background: var(--surface-2);
  font-weight: 700;
  border-top: none;
}

.inline-form {
  display: inline;
}

.success {
  background: var(--ok-bg);
  color: var(--ok-text);
  border: 1px solid var(--ok-line);
  padding: 12px 16px;
  border-radius: 12px;
  margin-bottom: 16px;
}

.error {
  background: var(--danger-bg);
  color: var(--danger-text);
  border: 1px solid var(--danger-line);
  padding: 12px 16px;
  border-radius: 12px;
  margin-bottom: 16px;
}

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

.compact {
  gap: 8px;
}

.login-body {
  min-height: 100vh;
  background: var(--login-bg);
  position: relative;
  overflow: hidden;
}

.login-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  position: relative;
  z-index: 2;
}

.login-card {
  width: min(460px, 100%);
  background: var(--surface);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  padding: 30px;
  border-radius: 22px;
  border: 1px solid var(--border-mid);
  box-shadow: 0 20px 60px var(--scrim), 0 0 40px var(--border-soft);
}

.simple-login-card {
  padding-top: 34px;
}

.simple-login-title {
  margin: 0 0 18px;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--accent);
  text-shadow: 0 0 24px var(--accent-glow);
}

.simple-login-copy {
  margin-bottom: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.simple-login-copy p {
  margin: 0;
  color: var(--text-strong);
  font-size: 22px;
  line-height: 1.35;
}

.login-form {
  gap: 14px;
}

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

.field-block label {
  font-size: 14px;
  color: var(--label);
}

.login-submit {
  margin-top: 6px;
  width: 100%;
  padding: 12px 16px;
  font-size: 16px;
  font-weight: 700;
}

.login-footnote {
  margin: 16px 0 0;
  color: var(--dim);
  font-size: 18px;
  line-height: 1.4;
}

.col-actions {
  justify-content: flex-start;
}

.col-date,
.col-name,
.col-status {
  word-break: break-word;
}

.team-issue-item {
  background: var(--danger-strong);
  color: #ffffff;
  border-radius: 10px;
  padding: 12px 14px;
  border-top: none;
}

.subtab {
  padding: 7px 14px;
  border-radius: 6px;
  background: transparent;
  color: var(--muted-2);
  border: 1px solid var(--neutral-line);
  font-weight: 500;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.subtab:hover { background: var(--neutral-soft); }

.subtab.active {
  background: var(--accent-soft);
  color: var(--accent-text);
  border-color: var(--accent-line);
  font-weight: 600;
}

.schedule-table {
  width: max-content;
  border-collapse: collapse;
  margin-bottom: 18px;
}

.schedule-table th,
.schedule-table td {
  border: 1px solid var(--border);
  padding: 6px;
  min-width: 78px;
  background: var(--surface-2);
  vertical-align: middle;
}

.schedule-table th {
  background: var(--surface-3);
  font-size: 12px;
  color: var(--heading);
}

.schedule-table th:first-child,
.schedule-table td:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface-3-solid) !important; /* fully opaque so scrolled content doesn't bleed through */
}

.schedule-table thead th:first-child {
  z-index: 4;
  background: var(--surface-4-solid) !important;
}

.sticky-name {
  min-width: 140px;
  background: var(--surface-3) !important;
  font-size: 12px;
  font-weight: 700;
}

.schedule-readonly {
  display: inline-block;
  min-width: 56px;
  font-size: 12px;
}

/* Schedule cell status colors */
td.sched-off      { background: var(--sched-off-bg) !important; color: var(--accent-text) !important; }
td.sched-leave    { background: var(--sched-leave-bg) !important; color: var(--purple) !important; }
td.sched-spec     { background: var(--sched-spec-bg) !important; color: var(--warn-text) !important; }
td.sched-sick     { background: var(--sched-sick-bg) !important; color: var(--ok) !important; }
td.sched-grief    { background: var(--sched-grief-bg) !important; color: var(--purple-2) !important; }
td.sched-mat      { background: var(--sched-mat-bg) !important; color: var(--sched-mat-fg) !important; }
td.sched-period   { background: var(--sched-period-bg) !important; color: var(--danger) !important; }
td.sched-late     { color: var(--warn) !important; }
td.sched-other    { background: var(--sched-other-bg) !important; color: var(--sched-other-fg) !important; }

/* 「不是普通休假」的那些（特休／事假／病假／丧假／产假育婴／生理假／迟到／其它）：
   2026-09-02 啤啤反映「普通休假以外的假别很不明显」。各假别本来就有自己的底色，
   但它们跟「休」的蓝一样淡，扫过去看不出差别。这里再补两个跟底色无关的记号——
   加粗＋左边一条实心色条——所以就算某个假别的底色偏淡，也一眼看得出「这天不是单纯休假」。
   色条用 inset box-shadow 而不是 border，才不会把表格的格线挤歪。 */
td.sched-flag {
  font-weight: 700 !important;
  box-shadow: inset 3px 0 0 0 currentColor;
}

.note-edit-form {
  flex: 1;
}

.btn-sm {
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 6px;
}

.btn-danger {
  background: var(--danger-soft);
  color: var(--danger);
  border-color: var(--danger-line);
  box-shadow: none;
}
.btn-danger:hover { background: var(--danger-soft-2); }

.readonly-note {
  flex: 1;
  white-space: pre-wrap;
  line-height: 1.6;
  font-size: 13px;
  padding-top: 2px;
}

.note-display-row {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.note-display-row .readonly-note {
  flex: 1;
}

.note-edit-toggle {
  flex-shrink: 0;
  align-self: center;
}

.note-edit-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.note-actions-col {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
}

.image-card {
  padding: 12px;
}

.wide-image-card {
  overflow: hidden;
}

.attendance-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 10px;
  position: relative;
}

.attendance-scroll table {
  position: relative;
}

.attendance-image {
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  display: block;
}

.month-image {
  width: auto;
  max-width: none;
  min-width: 900px;
}

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

/* Unsaved change indicator */
.is-dirty {
  border-color: var(--warn-strong) !important;
  box-shadow: 0 0 0 3px var(--warn-soft-2), 0 0 8px var(--warn-soft) !important;
}

.small {
  font-size: 12px;
}

/* Desktop/mobile conditional display */
.view-mobile-only { display: none; }
.view-desktop-only { display: block; }

/* ── Hamburger button (mobile only) ── */
.hamburger {
  display: none;
  position: fixed;
  top: 14px;
  left: 14px;
  z-index: 200;
  background: var(--surface-float);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  padding: 8px 11px;
  cursor: pointer;
  color: var(--accent);
  font-size: 20px;
  line-height: 1;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 0 14px var(--border);
}

/* Overlay behind open sidebar on mobile */
.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 98;
  background: var(--scrim);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

@media (max-width: 700px) {
  .hamburger { display: flex; align-items: center; justify-content: center; }

  .layout {
    flex-direction: row;
  }

  /* Sidebar slides in from left as a drawer */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 260px;
    z-index: 100;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    padding: 20px 16px;
  }

  .sidebar.open {
    transform: translateX(0);
  }

  .sidebar-overlay.open {
    display: block;
    left: 260px; /* only cover the area beside the sidebar, not on top of it */
  }

  .main {
    width: 100%;
    padding: 14px;
    padding-top: 58px; /* leave room for hamburger */
    /* 手机上一样要给右下角泡泡留位置（上面那行 padding 简写会把它洗掉，所以重写一次）*/
    padding-bottom: calc(var(--fab-stack) + var(--fab-gap) + 20px);
  }

  .pagehead {
    flex-direction: column;
    align-items: stretch;
  }

  .grid-2,
  .archive-item {
    grid-template-columns: 1fr;
  }.table-like .row{
    grid-template-columns: 1fr 1fr;
  }

  .card {
    padding: 14px;
  }

  .toolbar {
    gap: 10px;
  }

  .toolbar > div {
    min-width: 100%;
  }

  .horizontal-actions {
    gap: 6px;
  }

  .userbox {
    padding: 12px;
  }

  .schedule-table th,
  .schedule-table td {
    min-width: 44px;
    padding: 3px 2px;
    font-size: 10px;
  }

  .sticky-name {
    min-width: 72px;
    max-width: 90px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 10px;
  }

  .schedule-readonly,
  .muted.small {
    font-size: 11px;
  }

  .big-text {
    min-height: 280px;
  }.medium-text{
    min-height: 88px;
  }

  .nav-main {
    gap: 6px;
  }

  /* Show mobile view, hide desktop view */
  .view-mobile-only { display: block; }
  .view-desktop-only { display: none; }

  /* Touch-friendly buttons */
  button,
  .btn-link {
    min-height: 44px;
  }

  .btn-sm {
    min-height: 36px;
  }

  /* Stack note edit row vertically */
  .note-edit-row {
    flex-direction: column;
  }

  .note-actions-col {
    flex-direction: row;
    flex-wrap: wrap;
  }

  /* Allow section-head to wrap */
  .section-head,
  .list-head {
    flex-wrap: wrap;
    gap: 8px;
  }

  /* Stack pagehead buttons below title */
  .pagehead {
    gap: 10px;
  }

  /* Wider toolbar items */
  .toolbar > div,
  .toolbar input,
  .toolbar select {
    min-width: 0;
    width: 100%;
  }

  /* Note display rows: stack on very narrow */
  .note-display-row {
    flex-wrap: wrap;
  }

  /* 上面那条只挡到 <button>，用 <a> 做的钮（例如巡检页「看这轮」）漏掉了，补上 */
  a.btn-chip,
  a.btn-link {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
  }

  /* 写死四栏的日期／时间表单（质检、评论反查）：手机上挤成两栏才放得下 */
  .grid-4 {
    grid-template-columns: 1fr 1fr;
  }

  /* 查询结果卡：三栏在手机上每格只剩一百出头，改成两栏 */
  .lookup-grid-3 {
    grid-template-columns: 1fr 1fr;
  }

  /* SSO 产品名手机上折行：桌机一格够宽，名字太长截成「…」还看得出是哪支；
     手机一格只剩一百多 px，截完剩前四个字就分不出来了，宁可折成两行也要看得完整。
     （行内 style 写了 nowrap／ellipsis，这里得用 !important 才盖得过去）*/
  .sso-pname {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    line-height: 1.35;
    word-break: break-word;
  }
}

@media (max-width: 480px) {
  .hamburger { display: flex; align-items: center; justify-content: center; }
  .sidebar {
    width: 100vw;
  }

  /* 更窄的机子：日期／时间表单一行一格，日期框才不会被切掉 */
  .grid-4 {
    grid-template-columns: 1fr;
  }

  .sidebar-overlay.open {
    display: none; /* sidebar is full-screen, no area to cover */
  }

  .brand {
    font-size: 22px;
  }

  .navlink,
  .childlink,
  .settings-link,
  button,
  .btn-link {
    font-size: 14px;
  }

  .pagehead h1 {
    font-size: 22px;
    margin: 0;
  }

  .schedule-table th,
  .schedule-table td {
    min-width: 38px;
    font-size: 10px;
    padding: 2px 1px;
  }

  .sticky-name {
    min-width: 60px;
    max-width: 72px;
    font-size: 10px;
  }

  .attendance-scroll {
    padding-bottom: 10px;
  }

  /* Cards less padding to save space */
  .card {
    padding: 12px;
    border-radius: 12px;
  }

  /* Stack note-display-row items fully */
  .note-display-row {
    flex-direction: column;
    align-items: stretch;
  }

  .note-edit-toggle {
    align-self: flex-start;
  }

  /* Full-width buttons in forms */
  .note-actions-col button,
  .note-actions-col .btn-link {
    width: 100%;
  }
}

/* ── 输入框叉叉清除按钮 ─────────────────────────────────────── */
.input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.input-wrap > input {
  width: 100%;
  padding-right: 28px;
}
.btn-clear-input {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: var(--neutral-line-soft);
  border: none;
  border-radius: 50%;
  color: var(--neutral-icon);
  cursor: pointer;
  padding: 0;
  width: 18px;
  height: 18px;
  font-size: 11px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s;
  flex-shrink: 0;
}
.btn-clear-input:hover {
  background: var(--neutral-line-2);
  color: var(--text-strong);
}
.input-wrap input:not(:placeholder-shown) ~ .btn-clear-input {
  opacity: 1;
}
.input-wrap:focus-within .btn-clear-input {
  opacity: 0.6;
}
.input-wrap input:not(:placeholder-shown):focus ~ .btn-clear-input {
  opacity: 1;
}

/* ── User Lookup ── */
.lookup-layout { display: flex; flex-direction: column; gap: 18px; }
.lookup-top { display: flex; gap: 18px; align-items: flex-start; }
.lookup-form-card { flex-shrink: 0; width: 340px; display: flex; flex-direction: column; gap: 14px; }
.group-tabs { display: flex; gap: 8px; flex-wrap: wrap; }
.radio-row { display: flex; gap: 20px; align-items: center; }
.radio-label { display: flex; align-items: center; gap: 6px; color: var(--label); cursor: pointer; font-size: 14px; white-space: nowrap; }
.radio-label input { accent-color: var(--accent); }
.lookup-card-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; flex-wrap: wrap; gap: 8px; }
.lookup-badge { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 8px; margin-left: 8px; }
.lookup-badge.banned { background: var(--danger-soft); color: var(--danger-text); border: 1px solid var(--danger-line); }
.lookup-badge.vip { background: var(--warn-soft); color: var(--warn-text); border: 1px solid var(--warn-soft-2); }
.lookup-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.lookup-grid-3 { grid-template-columns: 1fr 1fr 1fr; }
.lookup-field { display: flex; flex-direction: column; gap: 3px; }
.lookup-label { font-size: 11px; color: var(--muted); }
.lookup-value { font-size: 14px; color: var(--text); word-break: break-all; }
.lookup-value.copyable { cursor: pointer; border-bottom: 1px dashed var(--accent-line-soft); }
.lookup-value.copyable:hover { color: var(--accent); }
button.secondary { background: var(--border); border: 1px solid var(--border-strong); color: var(--accent); box-shadow: none; }
button.secondary:hover { background: var(--border-mid); }

/* ── 统一 chip 按钮：半透明底 + 细边框 + 圆角，按功能分色 ──────────────────
   蓝 blue=查询/操作/跳转 · 红 red=危险(封禁/删除) · 绿 green=确认/成功 · 黄 amber=提醒 · 不带色=次要/取消 */
/* 折叠区块右边那个箭头（收起 ▶ / 点开 ▽）。翻转的 JS 在 base.html。
   本来六个地方各写一份一模一样的 inline 样式，收成这一条。 */
.toggle-arrow { color: var(--muted-2); font-size: 13px; margin-left: auto; }

.btn-chip {
  background: var(--neutral-soft);
  border: 1px solid var(--neutral-line);
  color: var(--muted-2);
  border-radius: 6px;
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
  box-shadow: none;
  transition: background 0.15s, border-color 0.15s;
}
.btn-chip:hover { opacity: 1; box-shadow: none; background: var(--neutral-soft-2); }
.btn-chip.blue   { background: var(--accent-soft);  border-color: var(--accent-line-soft); color: var(--accent-text); }
.btn-chip.blue:hover   { background: var(--accent-soft-2); }
.btn-chip.red    { background: var(--danger-soft); border-color: var(--danger-line); color: var(--danger); }
.btn-chip.red:hover    { background: var(--danger-soft-2); }
.btn-chip.green  { background: var(--ok-soft);  border-color: var(--ok-line); color: var(--ok-text); }
.btn-chip.green:hover  { background: var(--ok-soft-2); }
.btn-chip.amber  { background: var(--warn-soft);  border-color: var(--warn-line);  color: var(--warn-text); }
.btn-chip.amber:hover  { background: var(--warn-soft-2); }
.tx-table-wrap { overflow-x: auto; }
.tx-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.tx-table th { background: var(--surface-2); color: var(--muted); padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
/* ⚠️ 这里刻意不用 word-break: break-all。它准许在**任何字元中间**断行，
   窄栏位时会把「2026-08-30」拆成「2026-08-3 / 0」、「06:26」拆成「06: / 26」、
   「已完成」拆成「已完 / 成」—— 手机上整张表看起来像被绞碎。
   overflow-wrap: anywhere 只在真的塞不下时才断，长订单号照样断得掉。 */
.tx-table td { padding: 9px 10px; border-bottom: 1px solid var(--border-soft); color: var(--text); overflow-wrap: anywhere; }
.tx-table tr:hover td { background: var(--border-soft); }
.tx-status-3 { color: var(--ok); font-weight: 700; }
.tx-status-1, .tx-status-2 { color: var(--warn); }
.tx-status-4, .tx-status-5 { color: var(--danger); }
.tx-id { font-family: monospace; font-size: 11px; color: var(--muted); }
.flow-coin-in { color: var(--ok); font-weight: 700; }
.flow-coin-out { color: var(--danger); font-weight: 700; }
.flow-desc { max-width: 200px; word-break: break-all; font-size: 12px; color: var(--label); }
.recovery-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 12px; }
.recovery-row:last-of-type { margin-bottom: 0; }
.recovery-field-product { flex: 0 1 280px; min-width: 240px; }
.recovery-field-product select { width: 100%; }
.recovery-field-image { flex: 1 1 380px; min-width: 280px; }
.recovery-field-time { flex: 0 1 280px; min-width: 260px; }
.recovery-field-time input { width: 100%; min-width: 260px; }
.recovery-field-narrow { flex: 0 0 100px; }
.recovery-field-narrow input { width: 100%; }
.recovery-field-btn { flex: 0 0 auto; }
#recoveryImagePaste {
  min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center;
  border: 1px dashed var(--accent-line-soft); border-radius: 8px; padding: 0 10px;
  color: var(--label); font-size: 13px; cursor: text; outline: none; overflow: hidden; white-space: nowrap;
}
#recoveryImagePaste:empty:before { content: attr(data-placeholder); color: var(--muted); }
#recoveryImagePaste.recognized { border-color: var(--ok-line); background: var(--ok-soft); color: var(--ok-text); white-space: normal; height: auto; min-height: 38px; word-break: break-all; }
#qrInvitePaste {
  min-height: 38px; height: 38px; box-sizing: border-box; display: flex; align-items: center;
  border: 1px dashed var(--accent-line-soft); border-radius: 8px; padding: 0 10px;
  color: var(--label); font-size: 13px; cursor: text; outline: none; overflow: hidden; white-space: nowrap;
}
#qrInvitePaste:empty:before { content: attr(data-placeholder); color: var(--muted); }
#qrInvitePaste.recognized { border-color: var(--ok-line); background: var(--ok-soft); color: var(--ok-text); white-space: normal; height: auto; min-height: 38px; word-break: break-all; }
input[type="datetime-local"]::-webkit-calendar-picker-indicator { filter: invert(0.8); cursor: pointer; }
#recoveryHead th, #recoveryBody td { white-space: nowrap; word-break: normal; }
#recoveryBody .flow-desc { max-width: none; }

/* ── Modal ── */
.modal-overlay { position: fixed; inset: 0; background: var(--scrim-modal); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.modal-box { background: var(--surface-solid); border: 1px solid var(--accent-soft-2); border-radius: 12px; width: 420px; max-width: 92vw; max-height: 85vh; overflow-y: auto; padding: 16px 18px; box-shadow: 0 10px 40px var(--scrim); }
.modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.modal-head strong { color: var(--accent); font-size: 16px; }
.modal-close { cursor: pointer; color: var(--muted); font-size: 16px; }
.modal-close:hover { color: var(--danger); }
.modal-body .field-block { margin-bottom: 10px; }
.modal-body label { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.modal-body input, .modal-body select, .modal-body textarea {
  width: 100%; box-sizing: border-box; background: var(--surface-2); border: 1px solid var(--border-mid);
  border-radius: 6px; color: var(--text); padding: 6px 8px; font-size: 13px;
}
.modal-body textarea { resize: vertical; min-height: 50px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.modal-hint { font-size: 11px; color: var(--muted); margin-top: 2px; }
.modal-hint-warn { font-size: 13px; color: var(--danger); margin-top: 8px; }

/* ── Weekly Report ── */
/* min-width:0 ——grid／flex 的子元素预设不肯缩到比内容还窄，
   日期框这种有原生宽度的东西就会把整列撑爆、被 .main 裁掉。 */
.field-row { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

/* ── Recharge Dashboard ── */
.recharge-wrap { max-width: 1200px; margin: 0 auto; padding: 20px 16px 40px; }
.recharge-title { font-size: 1.25rem; font-weight: 700; color: var(--text); margin-bottom: 18px; }
.token-box {
  background: var(--surface-2); border: 1px solid var(--neutral-line-soft);
  border-radius: 10px; padding: 14px 16px; margin-bottom: 20px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.token-save-btn {
  background: var(--ok-soft); border: 1px solid var(--ok-line);
  border-radius: 6px; color: var(--ok-text); padding: 5px 14px; font-size: 0.8rem; cursor: pointer;
}
.token-save-btn:hover { background: var(--ok-soft-2); }
.recharge-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.recharge-controls select, .recharge-controls input[type=date] {
  background: var(--surface-2); border: 1px solid var(--neutral-line);
  border-radius: 6px; color: var(--text); padding: 5px 10px; font-size: 0.83rem;
}
.btn-fetch {
  background: var(--accent-soft); border: 1px solid var(--accent-line-soft);
  border-radius: 6px; color: var(--accent-alt); padding: 5px 14px; font-size: 0.83rem; cursor: pointer;
}
.btn-fetch:hover { background: var(--accent-soft-2); }
.btn-fetch:disabled { opacity: 0.5; cursor: not-allowed; }
.chart-section {
  margin-top: 6px;
  background: var(--surface-2);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 18px;
}
.metric-toggle {
  display: flex; gap: 12px; margin: 8px 0 18px;
  background: var(--surface-2); border: 1px solid var(--neutral-soft);
  border-radius: 12px; padding: 14px 16px;
}
.metric-btn {
  background: transparent; border: 1px solid var(--neutral-line);
  border-radius: 6px; color: var(--muted-2); padding: 8px 20px; font-size: 0.88rem;
  cursor: pointer; min-width: 80px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.metric-btn:hover { background: var(--neutral-soft); color: var(--muted-2); }
.metric-btn.active {
  background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--accent-text); font-weight: 600;
}
.summary-bar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.summary-card {
  background: var(--surface-2); border: 1px solid var(--neutral-line-soft);
  border-radius: 8px; padding: 10px 14px; min-width: 140px;
}
.summary-card .sc-label { font-size: 0.72rem; color: var(--muted); margin-bottom: 3px; }
.summary-card .sc-val { font-size: 1.05rem; font-weight: 700; color: var(--text); }
.summary-card .sc-sub { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }
.zero-alert {
  background: var(--danger-soft); border: 1px solid var(--danger-line);
  border-radius: 8px; padding: 10px 14px; color: var(--danger-text); font-size: 0.82rem;
  margin-bottom: 12px; display: none;
}
.zero-alert.show { display: block; }
.monitor-status {
  border-radius: 8px; padding: 10px 14px; font-size: 0.82rem; margin-bottom: 14px; line-height: 1.6;
}
.monitor-status.ok {
  background: var(--ok-soft); border: 1px solid var(--ok-line); color: var(--ok-text);
}
.monitor-status.bad {
  background: var(--danger-soft); border: 1px solid var(--danger-line); color: var(--danger-text);
}
.legend-row { display: flex; align-items: center; gap: 16px; font-size: 0.78rem; color: var(--muted); margin-bottom: 10px; flex-wrap: wrap; }
.legend-swatch-item { display: inline-flex; align-items: center; gap: 6px; }
.legend-swatch-item span { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.recharge-loading { padding: 40px; text-align: center; color: var(--muted); font-size: 0.85rem; }

/* ══════════════════ 北极冰川 · 零件微调 ═══════════════════════════════════
   有几个地方光靠换颜色积木还不够，得单独交代一下。 */

/* 1. 日期选择器右边那颗小日历图示：深色主题把它「反白」才看得见，
      浅色主题不用反白，反白反而会消失在白底里 */
body.arctic input[type="date"]::-webkit-calendar-picker-indicator,
body.arctic input[type="month"]::-webkit-calendar-picker-indicator,
body.arctic input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  filter: none;
  opacity: 0.65;
}
body.arctic input[type="date"]::-webkit-calendar-picker-indicator:hover,
body.arctic input[type="month"]::-webkit-calendar-picker-indicator:hover,
body.arctic input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* 1b. 「淡化」在浅色底上要收敛
   ─────────────────────────────────────────────────────────────────────────
   同样叫「淡一点」，两种底的代价差很多：
     深色底：白字淡到 40%，还是浮在深蓝上，读得出来。
     浅色底：深字淡到 40%，等於往白色靠 60%，直接糊进背景里。
   所以凡是用 opacity 表示「停用／已处理／不能按」的地方，浅色主题都要往上调。
   已停用的区块本来就不该看起来能按，所以不调到满，只调到「读得出写什么」。 */
/* 停用中的区块：浅色主题不靠「整块调淡」表示停用（淡到读得出字就已经不像停用了），
   改成把里面的钮换成灰底灰框灰字 —— 一看就知道不能按，字却还是读得清楚。 */
body.arctic .block-off {
  opacity: 1;
}
body.arctic .block-off button,
body.arctic .block-off .btn-link {
  background: var(--neutral-soft);
  border-color: var(--border);
  color: var(--muted);
}
body.arctic .feat-item.off {
  opacity: 0.7;
}

/* 2. 卡片、侧边栏在白底上要有一点点浮起来的阴影，否则整片白会分不出层次 */
body.arctic .card,
body.arctic .chart-section {
  box-shadow: 0 2px 10px rgba(30,58,84,0.06);
}
body.arctic .sidebar {
  box-shadow: 2px 0 16px rgba(30,58,84,0.06);
}

/* 3. 「工作助手」品牌字：深色主题靠发光，浅色主题改成实心深蓝，干净一点 */
body.arctic .brand,
body.arctic .simple-login-title {
  text-shadow: none;
}

/* 4. 表格左边固定不动的那一栏：横向卷动时下面的字会透上来，
      所以浅色主题也要一个「不透明的白」压着 */
body.arctic .schedule-table th:first-child,
body.arctic .schedule-table td:first-child {
  background: var(--surface-3-solid) !important;
}
body.arctic .schedule-table thead th:first-child {
  background: var(--surface-4-solid) !important;
}

/* 5. 手机版汉堡钮的光晕，在白底上会糊掉，改成淡阴影 */
body.arctic .hamburger {
  box-shadow: 0 2px 10px rgba(30,58,84,0.12);
}

/* 6. 输入框在白底上给一层实底，比半透明清楚 */
body.arctic input,
body.arctic select,
body.arctic textarea {
  background: rgba(255,255,255,0.9);
}

/* 7. 卷动条也跟着变浅，不然白页面配一条深色卷动条很突兀 */
body.arctic {
  scrollbar-color: rgba(120,158,190,0.5) rgba(255,255,255,0.4);
}
body.arctic ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
body.arctic ::-webkit-scrollbar-track {
  background: rgba(226,238,247,0.6);
}
body.arctic ::-webkit-scrollbar-thumb {
  background: rgba(150,186,214,0.6);
  border-radius: 6px;
}
body.arctic ::-webkit-scrollbar-thumb:hover {
  background: rgba(120,160,195,0.8);
}


/* ── 更新日志两页共用（2026-08-24 从模板搬进来）──────────────────────────────
   changelog.html 与 changelog_detailed.html 本来各自内嵌一份 <style>，
   20 条规则里有 18 条逐字相同、0 条冲突——改一次样式要记得改两个地方。
   搬进这里之後两边都不必再带 <style>。
   .cl-points 只有主日志在用（日志规范第 12 条：一条主说明底下附 3~5 个短点），
   放这里不影响详细版。 */
  .cl-item { color:var(--text); font-size:13px; line-height:1.9; margin-top:6px; }
  .cl-type { display:inline-block; font-size:11px; color:var(--accent-text);
           background:var(--accent-soft); border:1px solid var(--accent-soft-2);
           border-radius:4px; padding:0 6px; }
  .cl-name { color:var(--text-strong); font-weight:600; }
  /* 名称本来就已经是半粗体了，里面再写 <b> 会看不出差别，
   所以标题里的重点改用「主色 + 全粗」来突显；说明那段是灰字，单纯加粗就够明显。 */
  .cl-name b { color:var(--accent); font-weight:700; }
  .cl-desc { color:var(--muted); font-size:12px; }
  .cl-desc b { color:var(--text); font-weight:700; }
  .cl-path { color:var(--muted); font-size:12px; padding-left:16px; margin-top:1px; }
  .cl-ba   { color:var(--muted); font-size:12px; padding-left:16px; }
  .cl-ba.after { color:var(--label); }
  /* 子重点：一条主说明底下附 3~5 个短点，日志规范第 12 条合并多条时用 */
  .cl-points { color:var(--muted); font-size:12px; padding-left:22px; margin-top:2px; }
  .cl-points li { line-height:1.7; list-style:disc; margin-left:8px; }

  /* 月份内容区：固定高度自己滚，别让单一月份把整页吃光 */
  .cl-scroll {
  max-height: 460px;
  overflow-y: auto;
  padding: 4px 10px 10px 0;
  /* 卷轴细一点，配合整站质感 */
  scrollbar-width: thin;
  scrollbar-color: var(--border-mid) transparent;
  }
  .cl-scroll::-webkit-scrollbar { width: 8px; }
  .cl-scroll::-webkit-scrollbar-thumb { background: var(--border-mid); border-radius: 999px; }
  .cl-scroll::-webkit-scrollbar-track { background: transparent; }

  /* 日期分隔线。⚠️ 别把它改成 position:sticky 钉在框顶——试过，不行：
   卡片底色（--surface）是半透明叠在背景图上的，钉住就得给个不透明底色去挡住
   卷过去的条目，而任何纯色都跟卡片对不上，会在页面上拉出一条突兀的深色带。
   工作讯息那份也没有钉住，照它来就好。 */
  .cl-day {
  display:flex; align-items:center; gap:10px;
  margin: 14px 0 10px;
  }
  .cl-day:first-child { margin-top: 4px; }
  .cl-sect { margin-bottom: 12px; }
  .cl-sect-title { font-size:13px; font-weight:500; margin-bottom:6px; }

  @media (max-width: 640px) { .cl-scroll { max-height: 380px; } }

/* ── 跟着滑鼠的小生物 ────────────────────────────────────────────────────────
   设置 → 背景主题里自己挑一只（预设没有）。位置由 base.html 那段 JS 每帧改
   transform，这里只管长相；width 与 margin 写在 base.html 那个 div 上
   （每只宽度不同；margin 让牠待在游标右下方，不挡视线）。
   ★ 显示时是完全不透明的（.on 的 opacity 是 1）：原本 0.92，加上图案格子交界
     漏色，整只看起来半透明（2026-10-05 啤啤回报）。漏色的部分见 sea-creatures.svg 档头。
   ★ pointer-events:none 不可拿掉——拿掉的话它会挡住底下的按钮，
     使用者会以为「点了没反应」。                                            */
#cursor-pet {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1200;               /* 游标上的装饰，盖在最上层；反正点不到 */
  pointer-events: none;
  opacity: 0;                  /* 滑鼠动过一次才淡入，免得开页面时定在左上角 */
  transition: opacity .35s ease;
  will-change: transform;
  filter: drop-shadow(0 2px 6px rgba(0, 20, 50, 0.45));
}

#cursor-pet.on { opacity: 1; }

#cursor-pet svg {
  display: block;
  width: 100%;
  height: auto;
}


/* ══ 手机版：靠 mobilecheck.py 量出来的修正 ═══════════════════════════════════
   为什么单独放一区：这些不是「美感调整」，是量得出来的客观毛病 ——
   手指按不到、表格被绞碎、内容压在浮动钮底下。
   改动前後都跑 mobilecheck.py，拿两次数字对照，不靠感觉。
   （量测工具本身也踩过坑：背景那些海洋生物是 pointer-events:none 的装饰，
     一开始被误报成「盖住按钮」103 笔，全是假的。）              */
@media (max-width: 700px) {

  /* ── 点击区：手指按得准的门槛是 44px，量到 99 个元件不到 ──────────────
     排除 checkbox / radio —— 它们在 (pointer:coarse) 那区已经调过 21px，
     这里再拉高会变成两个规则打架，方框被撑成长方形。 */
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
  select,
  textarea,
  button,
  .btn-chip {
    min-height: 44px;
  }

  /* ── 表格：可以横向卷的那种，就别让格子里的字断行 ────────────────────
     只对「已经包在卷动容器里」的表格生效。没包的表格照旧换行，
     不然它会撑破版面变成整页可以左右滑 —— 那比断行更难看。
     站上有两种写法：.table-scroll / .tx-table-wrap 这两个 class，
     以及直接写 style="overflow-x:auto" 的 inline 版（9 支模板混着用）。
     用属性选择器把 inline 那种也收进来，就不必去改 9 支模板 ——
     以後谁再写一个 inline 的也会自动吃到这条规则。 */
  .table-scroll .tx-table,
  .tx-table-wrap .tx-table,
  [style*="overflow-x"] .tx-table {
    min-width: max-content;
  }

  .table-scroll .tx-table th,
  .table-scroll .tx-table td,
  .tx-table-wrap .tx-table th,
  .tx-table-wrap .tx-table td,
  [style*="overflow-x"] .tx-table th,
  [style*="overflow-x"] .tx-table td {
    white-space: nowrap;
  }

  /* 底部留白不用再写：.main 那两处已经用 --fab-stack + --fab-gap 留过了
     （1023 加了🔧扳手泡泡後是 164px），这里再写一份反而会盖成比较小的值。查过才没写。 */
}

/* ══════════════════════════════════════════════════════════════════
   小只的手机（≤420px）—— 密度调整
   啤啤 0902：「我拿的工作机比较小只，网页整体比例太大就很难看」。
   这里不动字的可读性（内文维持 16px），只把「白白浪费掉的空间」收掉：
   卡片的内距与间隔、标题字级、栏位标签。实测 360×640 下，
   首页从只看得到 1.5 笔纪录变成 2.5 笔。
   ⚠️ 不要在这里用 padding 简写洗掉 .main 的 padding-bottom
   ——那是留给右下角🔔泡泡的位置（见 --fab-size）。
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 420px) {
  .main {
    padding-left: 10px;
    padding-right: 10px;
    padding-top: 54px;
  }

  .card {
    padding: 11px;
    margin-bottom: 12px;
    border-radius: 12px;
  }

  .card h3 {
    font-size: 16px;
    margin-top: 0;
    margin-bottom: 10px;
  }

  .pagehead h1 {
    font-size: 20px;
  }

  .pagehead {
    margin-bottom: 10px;
  }

  .toolbar label,
  .card label {
    font-size: 14px;
  }

  .toolbar {
    gap: 8px;
  }

  .archive-toolbar-inline {
    margin: 10px 0 12px;
  }

  /* 输入框的字级在手机上被拉到 16px（不然 iPhone 会放大整页），
     字变大格子就变高——这里把上下内距收回来补偿，高度维持得住，字还是看得清楚。 */
  input:not([type="radio"]):not([type="checkbox"]):not([type="file"]),
  select,
  textarea {
    padding: 7px 10px;
  }

  .stack {
    gap: 8px;
  }
}
