/* 全站唯一的 token 与基础重置。每个页面第一个加载。 */
:root {
  color-scheme: light;
  font-family: "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  --serif: "Songti SC", "STSong", "Noto Serif SC", "Source Han Serif SC", "SimSun", Georgia, "Times New Roman", serif;
  --ink: #232120;
  --ink-soft: #504c4a;
  --ink-fill: #2f2c2a;
  --muted: #857f7c;
  /* 分隔线整体调暖并调淡一档。原来的 #dbdad9 是中性灰，压在暖白纸面上会显出
     一点冷调，一条一条加起来就是「硬」。现在的线跟纸同一个色相，只差明度。 */
  --line: #e7e2df;
  --line-strong: #d5cfcc;
  /* 这一版的纸是「暖白」，不是「奶油」。
     两者的差别只有一条：红蓝两个通道差多少。奶油纸的黄味来自蓝通道被压掉
     一大截（纸面上 R−B 是 5，线上是 14、17），黄味越往深处走越明显，于是
     整套界面越看越像一叠泛黄的纸。这一版把每一级的 R−B 砍掉一半左右——
     明度一格没动，暖的方向也没变，只是不再往黄里偏。 */
  --paper: #fbfaf8;
  --canvas: #f2efec;
  /* 侧栏用的第二层纸。比 paper 深一档，不靠边框跟中栏分开——一条通天的竖线
     是这一版之前最重的一笔「硬」，而两块纸的明度差已经足够说清哪边是哪边。 */
  --sand: #f4f1ee;
  --crimson: #b82934;
  --crimson-deep: #8f2029;
  --night: #252423;
  --r-xs: 4px;
  --r-sm: 8px;
  --r-md: 12px;
  /* 大圆角只给两样东西：输入框和首屏那排胶囊。它们是这一屏上唯一被直接摸的
     两处，圆角在这里说的是「可以按」，不是装饰——所以别的地方不用。 */
  --r-lg: 18px;
  --r-xl: 26px;
  --r-pill: 999px;
  /* 阴影两档，都很浅。深阴影会把一张卡片从纸上抬起来，这一屏要的是「铺开」
     不是「叠起来」，所以只用它画一圈极淡的落地感。 */
  --shadow-soft: 0 1px 2px rgb(58 52 48 / 4%), 0 8px 24px rgb(58 52 48 / 5%);
  --shadow-lift: 0 2px 6px rgb(58 52 48 / 6%), 0 18px 44px rgb(58 52 48 / 8%);
  /* 中栏里所有东西共用的一条内容列：首屏标题、胶囊、输入框、每一条消息，
     全部按它定宽并居中。原先各块各自定宽（760 / 833 / 无上限），窗口一宽
     就散成一片；现在无论多宽，读者的视线只在这一列里上下走。 */
  --column: 768px;
  --gutter: clamp(16px, 4vw, 56px);
  /* 一张字阶表，两条车道共用。
     下限是 12px。中文没有 x-height 可以借，笔画密度又比拉丁字母高得多：
     同样 10px，`code` 还认得出，「授课记录」先糊掉的是字的内部结构。
     这张表立起来之前，两个界面之间一共有 8 / 8.5 / 9 / 9.5 / 10 / 10.5 /
     11 / 11.5 / 12 / 12.5 / 13 / 13.5 / 14 十三个字号，相邻两级差半个像素。
     半个像素读不出层级，只读得出没对齐——「不够精致」就是从这儿来的。 */
  --t-display: clamp(28px, 2.6vw, 40px); /* 一页只出现一次的那句话 */
  --t-head: 21px;   /* 面板标题 */
  --t-title: 17px;  /* 卡片标题 */
  --t-body: 15px;   /* 正文、输入框——读和写用同一个字号 */
  --t-ui: 14px;     /* 控件文字、卡片正文 */
  --t-label: 13px;  /* 次级标签、按钮 */
  --t-meta: 12px;   /* 时间、编号、出处。下限 */
  /* 字重只有三档，因为字体里只有三档。
     实测（canvas 栅格化后比较墨量）：PingFang SC 落地 300 / 400 / 500 / 600，
     560 到 900 全部渲染成同一枚 Semibold；Songti SC 落地 300 / 400 / 600 / 800。
     :root 上有 font-synthesis: none，浏览器不会替我们补一档出来。
     所以 450、560、620、640、650、680、720、760、780、800 这十种写法，
     屏幕上只有两种结果——差别全在源码里，一点没到读者眼前。 */
  --w-normal: 400;
  --w-medium: 500;
  --w-strong: 600;
  /* 页面左右留白与 .app-header 的内边距同值，页面内容因此与页头对齐。 */
  --page-inline: clamp(20px, 3vw, 48px);
  color: var(--ink);
  background: var(--paper);
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

* { box-sizing: border-box; }
html, body { min-width: 320px; min-height: 100%; margin: 0; }
body { background: var(--paper); letter-spacing: 0; }
button, input, textarea, select { font: inherit; letter-spacing: 0; }
button, a { -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid rgba(184, 41, 52, 0.45);
  outline-offset: 2px;
}

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

.loading-screen {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 13px;
  color: #8c867e;
  font-size: 13px;
}
.loading-screen span {
  width: 28px;
  height: 28px;
  border: 2px solid #e0dfdd;
  border-top-color: var(--crimson);
  border-radius: 50%;
  animation: spin 800ms linear infinite;
}
.loading-screen p { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .loading-screen span { animation: none; }
}

@keyframes spin { to { transform: rotate(360deg); } }
