/* @layer ui — 基础重置与通用控件。
 * 控件的层级表达统一为：平色材质 + 发丝线描边 + 清晰聚焦环。 */

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

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.5;
  letter-spacing: var(--tracking-body);   /* 苹果式的微紧字距 */
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

h1, h2, h3, p, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
h1, h2, h3 { letter-spacing: var(--tracking-title); }

button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; background: none; border: none; padding: 0; }
button:disabled { cursor: not-allowed; opacity: 0.38; }
/* 上面那条对**描边键**成立，对**实心键**不成立：opacity 同时冲淡底与字，
   比值几乎不变而两者一起消失，结果是一枚"看不清但确实在那儿"的主按钮。
   UI_PATTERNS §1 早就写下了这一条，chat.css 的 .chat-send 与 widget.css 的
   .wg__send 也各自修过一遍——唯独基准 .btn--primary / .btn--danger 自己漏了，
   因为冲淡它们的不是自己那条规则，而是上面这条 button:disabled，
   连 tests/css-contract.test.js 那条"禁用态的实心按钮不靠 opacity 冲淡"也扫不到。
   实测浅色下 .btn--primary:disabled 是 rgb(214,217,238) 底压 rgb(249,249,250) 字，
   **2.02:1**——保存/确认这类按钮在表单填完之前一直是这个样子。
   换成中性键：禁用不等于看不见，禁用是"现在按不了"。 */
.btn--primary:disabled,
.btn--danger:disabled {
  opacity: 1;
  background: color-mix(in srgb, var(--text) 10%, transparent);
  color: var(--text-muted);
  box-shadow: none;
}

/* 一道纯色硬环压在近白的纸上太"锐"。外面再垫一层同色柔光，把环化进纸里——
   这正是 .input:focus 一直在做的事，现在提到全局：整个产品只有一种聚焦的长相。
   柔光是叠加的：组件仍可把 outline-offset 收成负值、把硬环画在自己身上
   （见 calendar-shell 的视图切换条），那条写法不受影响。

   这里**不再**声明 border-radius。原来有一条 `border-radius: var(--radius-xs)`，
   它改的是元素自己的圆角，不是环的圆角——outline 与 box-shadow 本来就跟着元素的
   圆角走，不需要谁去设。它当前之所以没闯祸，只是因为 base.css 排在 components.css
   之前、同特异度下输给了组件自己的圆角；一旦哪个胶囊控件（.calpick__item、
   .onb__cal、.chat-suggestions button、.task-follow-chip 都是 --radius-pill）
   的圆角声明落到它后面，那枚胶囊会在聚焦的一瞬间被削成 5px 的方角。
   把这条埋着的雷拆掉，聚焦只做聚焦该做的事。 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 3.5px var(--accent-soft);
}

kbd {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  padding: 2px 6px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  color: var(--text-muted);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: var(--fs-body);
  font-weight: 560;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              transform var(--dur-press) var(--ease);
}
.btn:active:not(:disabled) { transform: scale(0.975); }

.btn--primary {
  background: var(--accent);
  color: var(--accent-text);
  box-shadow: var(--accent-glow);
}
.btn--primary:hover:not(:disabled) { background: var(--accent-hover); }

.btn--ghost {
  border-color: var(--border-strong);
  background: var(--raised-grad);
  color: var(--text);
}
.btn--ghost:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--border-strong); }

.btn--danger-ghost { color: var(--danger); }
.btn--danger-ghost:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 10%, transparent); }
/* 深色下 --danger 是 #ff7a6b，压白字只有 2.6:1。深色改压一层近黑的红，6.8:1。 */
.btn--danger { background: var(--danger); color: light-dark(#fff, hsl(8 45% 12%)); box-shadow: 0 1px 3px color-mix(in srgb, var(--danger) 28%, transparent); }
.btn--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 88%, #000); }

.btn--block { width: 100%; }
.btn--sm { min-height: 29px; font-size: var(--fs-tiny); padding: 0 11px; align-self: flex-start; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-xs);
  color: var(--text-muted);
  font-size: var(--fs-lead);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-press) var(--ease);
}
.icon-btn:hover:not(:disabled) { background: var(--surface-hover); color: var(--text); }
.icon-btn:active:not(:disabled) { transform: scale(0.92); }
.icon-btn--sm { width: 26px; height: 26px; font-size: var(--fs-small); }

/* min-height 24 是命中区，不是视觉尺寸：这枚文字键实测 45×21，
   高度掉在 WCAG 2.5.8「目标尺寸（最小）24×24」之下。inline-flex + 居中
   让字保持原位，只把可点的盒子撑到 24。（UI_PATTERNS §9 要的 44×44 是更严的
   一档，那一档要连顶栏的图标键一起在骨架层解决，见交接报告。） */
.link-btn {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--accent-ink);
  font-size: var(--fs-tiny);
  padding: 2px 0;
  border-radius: var(--radius-xs);
  transition: opacity var(--dur-fast) var(--ease);
}
.link-btn:hover { opacity: 0.72; }

/* ---------------- 分段控件（胶囊式，不是 Material 的 Tab） ---------------- */

.seg {
  display: inline-flex;
  padding: 2px;
  gap: 1px;
  background: var(--surface-sunken);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
.seg__item {
  white-space: nowrap;
  padding: 0 11px;
  height: 28px;
  border-radius: calc(var(--radius) - 3px);
  font-size: var(--fs-small);
  font-weight: 450;
  color: var(--text-muted);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.seg__item:hover { color: var(--text); }
.seg__item.is-active {
  background: var(--surface);
  color: var(--text);
  font-weight: 550;
  /* 顶边内高光走令牌：写死的白在深色下会在激活项顶上留一道亮边。 */
  box-shadow: var(--shadow-sm), var(--shadow-inset);
}
.seg--sm .seg__item { height: 26px; font-size: var(--fs-tiny); padding: 0 9px; }

/* ---------------- 输入 ---------------- */

/* 表单域是**凹进纸面的槽**，不是一圈描边。
   弹层的内容面是 --surface，域若也用 --surface，就只剩描边在证明它存在——
   于是一张编辑器看上去是"一堆框"。这里让域落到明度梯的最低一级，
   聚焦时再一路抬到最高一级：sunken -> bg -> surface，三步都在梯子上，
   深浅两套方向一致（深色下 sunken 5.8% < bg 8.2% < surface 12.4%）。
   用 background-color 而不是 background 简写：简写会把 select 的箭头
   （靠 background-image 画的两个三角）一并抹掉——旧写法在 hover 时正是如此。 */
.input {
  width: 100%;
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--surface-sunken);
  color: var(--text);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.input::placeholder { color: var(--text-faint); }
.input:hover:not(:focus) { background-color: var(--bg); }
.input:focus {
  outline: none;
  border-color: var(--accent);
  background-color: var(--surface);
  box-shadow: 0 0 0 3.5px var(--accent-soft);
}
.input--title { height: 44px; font-size: var(--fs-title); font-weight: 600; letter-spacing: var(--tracking-title); }
.input--num { width: 78px; }
.input--time { width: 132px; min-width: 132px; }
.input--area { height: auto; padding: 8px 10px; resize: vertical; line-height: 1.6; }

/* ---------------- 原生日期/时间控件的内脏 ----------------
   这是整套设计语言里唯一一处"设计管不到"的地方，而它偏偏长在一个**日历产品**
   最常用的两个控件上（编辑器的开始/结束、待办的截止日）。不写这一段的后果是：
     · 右端那枚日历/时钟图标由浏览器画，是 OS 深灰的实心块，尺寸也不归我们管；
       它压在 --surface-sunken 的浅槽上，比同一行里 13.5px 的正文还重；
     · 分段（月/日/年、上午/下午）用系统色高亮——macOS 上是系统蓝，
       在一套群青（#2743BE）的界面里当场露出第二种蓝；
     · 未填写的分段用 OS 自己的占位灰，和 --text-faint 对不上。
   下面只做一件事：把这三处收进令牌。不改结构、不改交互、不隐藏图标。
   注：::-webkit-calendar-picker-indicator 是一张位图，只能用 opacity 调；
   深浅两套由 :root 的 color-scheme 驱动浏览器自己换图，这里不需要 filter。 */
.input::-webkit-calendar-picker-indicator,
.task-chip-input::-webkit-calendar-picker-indicator {
  padding: 0;
  margin-left: 4px;
  opacity: 0.4;                 /* 目测与 --text-faint 同量级；它是提示不是主角 */
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease);
}
.input:hover::-webkit-calendar-picker-indicator,
.task-chip-input:hover::-webkit-calendar-picker-indicator { opacity: 0.62; }
.input:focus::-webkit-calendar-picker-indicator,
.task-chip-input:focus::-webkit-calendar-picker-indicator { opacity: 0.85; }

.input::-webkit-datetime-edit,
.task-chip-input::-webkit-datetime-edit { padding: 0; }
/* 分隔符（/ : 空格）与空分段退到 faint，填好的分段才是正文 */
.input::-webkit-datetime-edit-text,
.task-chip-input::-webkit-datetime-edit-text { color: var(--text-faint); padding: 0 1px; }
.input::-webkit-datetime-edit-year-field,
.input::-webkit-datetime-edit-month-field,
.input::-webkit-datetime-edit-day-field,
.input::-webkit-datetime-edit-hour-field,
.input::-webkit-datetime-edit-minute-field,
.input::-webkit-datetime-edit-ampm-field,
.task-chip-input::-webkit-datetime-edit-year-field,
.task-chip-input::-webkit-datetime-edit-month-field,
.task-chip-input::-webkit-datetime-edit-day-field { color: inherit; }
/* 选中的分段：系统蓝 → --accent-soft + --accent，与全产品的选中/聚焦同一支笔 */
.input::-webkit-datetime-edit-year-field:focus,
.input::-webkit-datetime-edit-month-field:focus,
.input::-webkit-datetime-edit-day-field:focus,
.input::-webkit-datetime-edit-hour-field:focus,
.input::-webkit-datetime-edit-minute-field:focus,
.input::-webkit-datetime-edit-ampm-field:focus,
.task-chip-input::-webkit-datetime-edit-year-field:focus,
.task-chip-input::-webkit-datetime-edit-month-field:focus,
.task-chip-input::-webkit-datetime-edit-day-field:focus {
  background: var(--accent-soft);
  /* 这一段字正压在 --accent-soft 上——深色下 --accent 压在自己的淡色底上
     只有 3.13:1，必须走 --accent-ink（见 themes.css）。 */
  color: var(--accent-ink);
  border-radius: var(--radius-xs);
  outline: none;
}

select.input {
  appearance: none;
  padding-right: 28px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 14px, calc(100% - 10px) 14px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--fs-body); }
.switch input {
  width: 38px; height: 22px; appearance: none; border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  border: 1px solid var(--border-strong);
  position: relative; cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.switch input::after {
  content: '';
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  /* 旋钮是"物件"，两种主题下都该是暖白，从纸的色相推出来。
     侧栏那枚开关（components.css 的 .deskrow__knob）早就是这个写法，
     只有这里还写着纯白——纯白是这套系统里"谁都不占"的那个值。 */
  background: hsl(var(--paper-h) 26% 98.5%);
  /* 0.2 的黑影曾是全产品最重的一道投影（--shadow-sm 才 0.055）。
     滑块只需要"接触"+顶边高光，不需要"高度"。
     但只留这两道，滑块在浅色下会消失：白滑块压在 --surface-sunken 的轨道上
     只有 1.18:1，而 --shadow-inset 的白内高光画在白滑块上等于没画，
     --shadow-sm 的 0.055 也托不住一个圆的边（实测轨道 234,236,241 / 滑块 255）。
     补一道发丝线——白色系统里让边缘存在的手段本来就是线，不是影。
     用轨道自己那条 --border-strong，滑块和轨道于是是同一支笔画的。 */
  box-shadow: var(--shadow-sm), var(--shadow-inset), 0 0 0 1px var(--border-strong);
  transition: transform var(--dur) var(--ease-spring);
}
.switch input:checked { background: var(--accent); border-color: transparent; }
.switch input:checked::after { transform: translateX(16px); }

/* ---------------- 滚动条 ---------------- */

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--radius-pill);
  border: 3.5px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }

/* ---------------- 无障碍与打印 ---------------- */

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

/* 深色分支不能挂在 [data-theme='dark'] 上：主题为 auto 时跟随系统进深色的用户
   命中不到它，只会命中上面那条近黑的边框——在深色里等于没有边框。
   与 themes.css 同一种做法：一处 light-dark()，两套永远同步；线仍然长在纸的色相上。 */
/* 浅色一侧的明度取 12%（= --text 的明度），不是常规线的 30%。
   30% 的纸色墨在 0.50 alpha 下压到近白的纸上只有 2.63:1，比它换掉的那条
   rgba(28,25,23,0.5)（3.34:1）还弱——用户按下"提高对比度"反而更糊，
   而且掉到 WCAG 1.4.11 给控件边界的 3:1 线以下。
   12% 让它回到 1.94 / 3.31（旧值是 1.93 / 3.34），同时仍然长在纸的色相上：
   高对比度下的线用的就是正文那支墨。 */
@media (prefers-contrast: more) {
  :root {
    --border:        light-dark(hsl(var(--paper-h) 18% 12% / 0.30), hsl(var(--paper-h) 22% 84% / 0.34));
    --border-strong: light-dark(hsl(var(--paper-h) 20% 12% / 0.50), hsl(var(--paper-h) 20% 86% / 0.55));
    /* 三级线的倍差要一起抬，只抬两级会把 1:2:4 压成 1:5.5:9 —— 那不是"更清楚"，
       是把最细的一级抛下。0.15 / 0.30 / 0.50 大致仍是 1:2:3.3。
       （layout.css 另有一条把侧栏那道竖线从 hairline 抬到 border 的规则，
        那是**局部**决定，与这里不冲突：竖线在高对比下要更重一档。） */
    --hairline:         light-dark(hsl(var(--paper-h) 18% 12% / 0.15), hsl(var(--paper-h) 25% 84% / 0.22));
    --decorative-faint: light-dark(hsl(var(--paper-h) 18% 12% / 0.09), hsl(var(--paper-h) 25% 84% / 0.13));
    /* 墨也要跟上。默认那三级已经全部过 AA（见 themes.css 的墨梯注释），
       但"我要更高对比"是用户明确说出来的诉求，不该只兑现在线上不兑现在字上。
       每一级都往 AAA（7:1）以上推一步，级差仍然保持 ~10 个 L*：
       实测最差组合 muted 8.76 / faint 6.05（浅色），muted 9.02 / faint 6.68（深色）。 */
    --text-muted: light-dark(hsl(var(--paper-h) 12% 24%), hsl(var(--paper-h) 8% 86%));
    --text-faint: light-dark(hsl(var(--paper-h) 10% 33%), hsl(var(--paper-h) 7% 74%));
  }
}

/* ---------------- 打印 ----------------
   这是一个日历，"打出来贴墙上"是真实用法，所以这一段不是走过场。
   原来只有四行，有两个硬伤：

   1. **深色主题原样上纸。** --text 在深色下是近白的，白纸上等于什么都没印。
      修法只需要一行：color-scheme 是 light-dark() 的总开关，
      用 !important 压过 :root[data-theme='dark'] 那条 color-scheme: dark，
      所有颜色型令牌当场翻回浅色一侧。数值型令牌（--accent-l）进不了
      light-dark()，所以 themes.css / brand.css 把那几条深色覆盖关进了 @media screen。

   2. **只印得出第一屏。** 主区与三个工作面全是"在一屏之内自己滚"的容器
      （.app__main / .chat-messages / .tasks-main 都是 overflow-y: auto + 100% 高）。
      打印时必须把高度和滚动一起放开，内容才会顺着纸往下流。
      这些容器长在别人的文件里（layout / chat / tasks），而 base.css 在它们之前加载，
      所以只能用 !important —— 打印块里这是正当用法，它不会影响屏幕上的任何一条规则。 */
@media print {
  :root { color-scheme: light !important; }

  /* 外壳、浮层、输入区不上纸：纸上没有"点一下"这回事。 */
  .app__header, .app__sidebar, .app__toast, .app__overlay,
  .calbar, .workspace-switch,
  .chat-composer-wrap, .chat-topbar__actions, .chat-suggestions,
  .task-compose { display: none !important; }

  .app { display: block; height: auto; }
  .app__main, .calshell, .calshell__body,
  .chat-workspace, .chat-stage, .chat-messages,
  .tasks-workspace, .tasks-main {
    display: block !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }
  /* 纸就是白的——这是全仓唯一一处 #fff 名正言顺的地方（见 themes.css 原则 1：
     纯白在屏幕上永远留空，因为屏幕上没有"纸"这个实体；打印时有）。 */
  body { overflow: visible; background: #fff; }

  /* 一件事不该被分页切成两半。 */
  .month__cell, .tg__col, .agenda__day,
  .chat-message, .chat-plan, .task-card { break-inside: avoid; }
}
