/* ==========================================================================
   微迹 Weetrack — 日迹页
   --------------------------------------------------------------------------
   布局：页头横跨整页、贴在最上面（`.page-head` 复用 layout.css 那套），
   它**下面是**两栏：左侧固定宽度日历（下面接情绪），右侧自适应。

     ┌──────────────────────────────────────────────────────────┐
     │  ▥ 日迹  说明…                          [ 日程│行程│日记 ] │  ← .page-head
     ├───────────────┬──────────────────────────────────────────┤     （整页宽、贴最上面）
     │   日历        │  日期标题 + 四个快捷信息                  │
     │  （含今天按钮）├──────────────────────────────────────────┤
     │               │  日程（日 / 周 / 月 可切）                │
     │   情绪        │  投入 · 待办 · 提醒，高度按内容走         │
     └───────────────┴──────────────────────────────────────────┘

   【页头为什么不在这个网格里（2026-10-02）】
   上一版页头是右栏 .fl-main 的第一个孩子 —— 于是它只横跨右栏，
   日历栏和它并排、日历顶着整页最上面。用户要求「日历往下挪，
   标题和其他模块一致往左上角」，所以 .page-head 提到了 .fl-wrap 外面。
   这个文件里**没有**任何一条 .fl-* 规则依赖页头在网格内，
   所以那次改动只动了 daymark.js 的组装顺序，CSS 一行没改。
   ========================================================================== */

/* ==========================================================================
   【2026-10-03：两栏高度从此只有一个来源】
   --------------------------------------------------------------------------
   用户的原话：「日历的底部有一些空白，可以往上调一点……我希望能够
   **刚好铺满屏幕**，并且**随着屏幕自适应**」。

   症状（改前实测）：1600×1000 下左栏底边 691.8，右栏底边 987.2 ——
   左栏下面空着 **295px**。那个洞是这么来的：
     · 右栏 .fl-main 有一条 `min-height: calc(100vh - 96px)`，
       于是它被抬到接近一屏高（1000 视口 → 904px）；
     · 左栏 .fl-side 写着 `align-self: start` —— 网格的默认拉伸被这一条
       取消掉，它就只长到"内容多高"（608.6px），
       剩下的高度**没有任何东西去接**，就露成了底部的空白。

   【为什么不再写 `calc(100vh - 数字)`】
   那个 96 是**页头还在 .fl-main 里面**的时候凑出来的（页头 + 上下留白）。
   上一轮把页头提到 .fl-wrap 外面之后它就不准了 —— 只是恰好还接近，
   没红而已（实测 1600×1000：96 仍然"对"，因为 904 = 1000-96；
   可 1280×720 时右栏内容 754.4 > 624，说明两栏早就不靠这个数对齐了）。
   再拍一个数字只会重复同一个错误：**只要页头的字换行、内边距改一次，
   它立刻失效，而且失效时没有任何东西会报错**。

   现在改成让高度**沿着 DOM 自己往下传**：
     .main（滚动容器，高度由视口定死）
       └ .view-host.fl-fit { min-height: 100% }   ← 取 .main 内容盒的高度
           └ .fl-wrap      { flex: 1 }            ← 吃掉页头和 gap 剩下的
               └ 两栏       { align-items: stretch } ← 同一行，同高
   这条链子上**一个像素常数都没有**：页头多高、gap 多大、内边距多少，
   全都由 CSS 自己算，改文字/改间距会自动跟上。
   `.fl-fit` 是新加的一个标记类（由 daymark.js 挂在 .view-host 上），
   而不是把 `min-height: 100%` 写进全局的 .view-host ——
   其它板块的 .view-host 没有"必须铺满一屏"这个要求，
   给它们加上会把页面底部撑出一块空高。
   ========================================================================== */
.fl-fit {
  /* 百分比高度解析的是 .main 的**内容盒**（已扣掉它自己的上下内边距），
     所以这里不需要知道 --page-pad 和底部那 40px 是多少。 */
  min-height: 100%;
}

.fl-wrap {
  display: grid;
  /* 日历列要放得下 7 个日期格：
     每格（.fc-cell）现在高 36px、宽由这一列均分得到 ≈ 40px，
     7 个 ≈ 290px + 6 个 2px 间距 + 卡片左右各 14px 内边距 ≈ 320。
     给 320 才不会把日期数字挤成一团。
     （2026-10-03 之前格子是 aspect-ratio:1 的正方形、39.7px，
     列宽这个数本身没变 —— 变的只是高度不再由它推出来。） */
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 18px;
  align-items: stretch;
  padding: 4px 0 32px;
  /* 【吃掉页头下面剩下的所有高度】
     .fl-fit 是列 flex 容器，页头和本行是它的两个 flex 子项；
     flex: 1 让本行把"一屏 − 页头 − gap"全部拿走 —— 这就是左栏能铺满的来源。
     min-height: 0 是必须的：grid 项默认 min-height:auto，
     不压住的话内容比可用高度高时（矮屏）它会顶破而不肯缩。 */
  flex: 1 1 auto;
  min-height: 0;
}

/* 左栏：日历 + 图例 + 情绪，纵向排；整列跟着右栏一起撑满。
   【原来的 align-self: start 删掉了】它正是"内容多高就多高"的来源 ——
   网格默认的 stretch 才会让这一列等于整行的高度。
   删掉之后左栏底边 == 右栏底边 == 内容区底边，是同一个网格行给出来的，
   不是两处各算一遍凑出来的。
   【sticky 也删掉了（2026-10-03 用户这一轮追问的那个问题）】
   改前它是 `position: sticky; top: 12px`。左栏现在**自己就是一屏高**，
   sticky 的语义是"在滚动容器里贴住顶端直到父容器用完" ——
   父容器（.fl-wrap 这一行）已经和它一样高、没有可滚动的余量，
   于是这条声明是**死代码**：实测滚动时它一动不动。
   留着它反而有害：sticky 会建立一个新的包含块，且一旦将来有人把
   .fl-wrap 的高度改得比左栏高，左栏就会开始"粘住"，
   表现为日历跟着页面往上飘、底部露出一截背景 —— 那是坏的、不是好的。
   所以改成 static（默认值，这里显式写出来是为了让下一个人看见这个决定）。 */
.fl-side {
  position: static;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* 不用再写 align-self：父级 .fl-wrap 的 align-items: stretch 就是想要的效果。
     min-height: 0 让它在矮屏时肯缩（grid/flex 项默认不肯缩到内容以下）。 */
  min-height: 0;
}

/* ==========================================================================
   【2026-10-03：日历卡改成"自己多高就多高"的卡片（不再被拉伸）】
   --------------------------------------------------------------------------
   用户这一轮：「日历的底部有一些空白，可以往上调一点；日历这边也减少点高度。
   我希望能够**刚好铺满屏幕**，并且**随着屏幕自适应**」。

   改前：日历卡是**内容高度** 341.5px，靠 `.fc-cell { aspect-ratio: 1 }`
   撑出来（格子宽度被 320px 的列宽定死，高度跟着宽度走）。

   现在左栏等于整行高度（见上面 .fl-wrap / .fl-side），比内容高，
   多出来的高度必须有人接。**试过让日历卡接，结论是错的**：
   卡片一旦 `flex: 1` 被拉高，格子即使封了顶，多出来的空间也会
   空在网格下方 —— 日历卡自己变成一个 578px 的大盒子、里面
   上下都是空白，这正是用户抱怨的那种"空白"，只是换了个地方。
   而且它还违背"日历这边也减少点高度"。

   所以这一版把职责分清楚：
     · **日历卡**：flex: 0 0 auto —— 高度只由格子（max-height 36px）决定，
       实测约 289px，比改前的 341.5px **矮约 50px**；
     · **情绪卡 .fl-mood**：flex: 1 1 auto —— 由它来接左栏剩下的高度。
       情绪卡内部本来就是一个"上面是按钮行 / 中间是备注框 / 下面是趋势图"
       的纵向布局，多出来的高度给它最自然（图表区域变大），
       不会在卡片中间凭空多出一块空白。
   这样"左栏底边 == 右栏底边"（铺满）和"日历变矮"两个要求同时成立。 */
.fc-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
  display: flex;
  flex-direction: column;
  /* 不伸不长：高度完全由里面的格子决定（见 .fc-cell 的 max-height）。
     矮屏时也不缩（内容就是内容），左栏装不下由 .main 滚动。 */
  flex: 0 0 auto;
}

.fc-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.fc-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .3px;
  white-space: nowrap;
}

.fc-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.fc-nav button {
  font: inherit;
  font-size: 12px;
  min-width: 26px;
  height: 26px;
  padding: 0 7px;
  border-radius: 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}

.fc-nav button:hover {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text);
}

/* 「今天」按钮稍微突出一点，让人一眼看到 */
.fc-nav button.fc-today {
  border-color: var(--line);
  color: var(--brand, #48ab93);
  font-weight: 500;
}

.fc-nav button.fc-today:hover {
  background: var(--brand-soft, rgba(107,122,90,.14));
  border-color: var(--brand, #48ab93);
}

/* ---------- 左上角日历的「年月」按钮 ---------- */

/* 原来 .fc-title 是纯文字，现在是按钮。
   样式上保持原来的字号和位置，只是多了可点击的样子。 */
.fc-title {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  padding: 3px 8px;
  margin-left: -8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background .15s;
}
.fc-title:hover { background: var(--surface-2); }

.fc-caret { font-size: 9px; opacity: .5; }

/* 年月快速选择面板 */
.fc-picker {
  margin-top: 8px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  display: grid;
  gap: 8px;
}
.fc-picker[hidden] { display: none; }

.fc-pk-year {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.fc-pk-yin {
  width: 62px;
  height: 26px;
  text-align: center;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
}
.fc-pk-yin:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.fc-pk-unit { font-size: 12px; color: var(--text-3); }

.fc-pk-nav {
  font: inherit;
  font-size: 13px;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
}
.fc-pk-nav:hover { background: var(--surface); color: var(--text); }

.fc-pk-months {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
}

.fc-pk-m {
  font: inherit;
  font-size: 11.5px;
  height: 28px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
}
.fc-pk-m:hover { border-color: var(--accent); color: var(--text); }
.fc-pk-m.on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

.fc-pk-ops { display: flex; justify-content: flex-end; }

.fc-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  margin-bottom: 4px;
}

.fc-week span {
  text-align: center;
  font-size: 11px;
  color: var(--text-3);
  padding: 2px 0;
}

/* ==========================================================================
   【2026-10-03：网格不再靠格子自身的长宽比撑高度】
   --------------------------------------------------------------------------
   改前这里只有 `grid-template-columns: repeat(7, 1fr)`，行高由**内容**
   决定：每格 `aspect-ratio: 1`，格子宽 ≈ 39.7px，于是六行 + 五个 gap
   = 248.3px。日历多高完全由**列宽**决定，跟屏幕高度一点关系都没有。

   现在格子自己声明高度（见 .fc-cell 的 max-height: 36px），
   行高跟着格子走 —— 网格只剩"七列 + 定宽行"这一件事。

   【行高为什么显式写 36px，而不是留给格子自己撑】
   格子上写的 max-height 只约束**格子自己**，不参与"自动行高"的计算 ——
   实测：行高会按内容定到一个比 36 更小的值（30px），
   格子被自己的 min-height 顶住，六个 30px + 间距 = 190px 的网格。
   那样"格子到底多高"就由内容碰运气决定，不是我们要的 36px。
   所以行高在这里**显式定死**：repeat(6, 36px)，和格子的
   --fc-cell-h 用同一个变量，改一处两处一起变。
   注意这里**不能**写 1fr：卡片是 flex: 0 0 auto（不拉伸），
   没有"剩余高度"可平分，1fr 会让行为变得依赖父级的偶发高度。 */
.fc-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-template-rows: repeat(6, var(--fc-cell-h, 36px));
  gap: 2px;
}

/* --------------------------------------------------------------------------
   【关键】.fc-cell 必须显式写 padding: 0 和 box-sizing。
   base.css 里有一个**全局的 .empty**（空状态占位样式，带 padding: 26px 16px）。
   日历空格子如果也带 .empty 类，就会吃到那 26px 内边距 ——
   54px 的格子被吃掉 52px，日期数字被挤出方块（这就是之前那个显示 bug）。
   现在空格子改叫 .fc-blank 避开它，这里再显式压住 padding，双保险。
   -------------------------------------------------------------------------- */
.fc-cell {
  position: relative;
  box-sizing: border-box;
  /* 【这两行不能删】见上面那段说明：base.css 的全局 .empty 带 padding，
     不显式压住的话，54px 的格子会被吃掉 52px，日期数字挤出方块。
     ⚠️ tools/daymark-redesign-selftest.mjs 会**临时**把这两行改掉来复现原 bug，
     所以它们被改过之后一定要还原 —— 那个脚本原来没有 try/finally，
     中途崩掉就把这里留成了坏的状态（真发生过）。 */
  padding: 0;
  margin: 0;
  /* 【2026-10-03：aspect-ratio: 1 删掉了】
     它是"日历高度由列宽决定、跟屏幕高度无关"的根源（见 .fc-grid 那段）：
     格子宽度被 320px 的列宽定死，高度跟着宽度走 —— 于是日历永远
     248.3px 的网格、341.5px 的卡片，在高屏上就是"矮矮一截、下面一片空"。
     现在格子不再声明长宽比，高度由网格行给（.fc-grid 的
     repeat(6, var(--fc-cell-h))），这里只把同一个变量再写一遍，
     让"格子自己"和"网格行"用的是**同一个数**（改一处两处一起变）。

     【36px 这个数是怎么来的】
     改前格子是**方形**的，高度由 320px 的列宽算出来 39.7px，
     六行 + 五个 2px 间距 = 248.3px，日历卡合计 **341.5px**（实测冻结值）。
     36px 之后：6 × 36 + 5 × 2 = 226px 的网格 + 标题栏 + 星期行 + 内边距
     = 日历卡 **283.2px** —— 比改前的 341.5px 矮 **58.3px**。
     为什么是 36 而不是更小：格子还要放日期数字（12.5px）、
     今天那条小横线（bottom: 3px + 2px）和打点（.marks，4px），
     再小就挤到一起了（30px 是实测"还没挤"的下限）。 */
  --fc-cell-h: 36px;
  height: var(--fc-cell-h);
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}

/* 空格子：上/下月的位置，占位但不可见 */
.fc-cell.fc-blank {
  cursor: default;
  visibility: hidden;
}

.fc-cell:not(.fc-blank):hover {
  background: var(--surface-2);
  color: var(--text);
}

.fc-cell .num {
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.fc-cell.today .num {
  font-weight: 700;
  color: var(--brand, #48ab93);
}

.fc-cell.today::after {
  content: '';
  position: absolute;
  bottom: 3px;
  width: 10px;
  height: 2px;
  border-radius: 2px;
  background: var(--brand, #48ab93);
}

.fc-cell.on {
  background: var(--brand, #48ab93);
  color: var(--on-brand);
  border-color: var(--brand, #48ab93);
}

/* 【这个 .num 的白字在**单独的规则**里，没有 background ——
   上一趟那种"同一个块里既看 background 又看 color"的扫法看不见它，
   所以漏到了最后。教训：白字不一定和它的底写在同一个块里，
   父级设了底、子级再单独设白字，是很常见的写法。 */
.fc-cell.on .num {
  color: var(--on-brand);
  font-weight: 600;
}

.fc-cell.on::after {
  background: color-mix(in srgb, var(--surface) 80%, transparent);
}

/* 打点：最多三个小点，排一行 */
.fc-cell .marks {
  display: flex;
  gap: 2px;
  height: 4px;
  align-items: center;
  justify-content: center;
}

.fc-cell .marks .dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  display: block;
  flex: none;
}

.dot.diary { background: #d59a2e; }
.dot.mood  { background: #c8553d; }
.dot.task  { background: #4a8f6a; }

.fc-cell.on .dot { box-shadow: 0 0 0 1px rgba(255,255,255,.55); }

.fc-legend {
  display: flex;
  gap: 12px;
  padding: 0 4px;
  font-size: 11px;
  color: var(--text-3);
}

.fc-legend .lg {
  display: flex;
  align-items: center;
  gap: 4px;
}

.fc-legend i.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: block;
}

/* ============================ 右侧主区 ============================ */

/* 右栏：日期标题 + 四个快捷信息 + 日程。
   【高度从哪来（2026-10-03 改）】
   原来这里是一条 `min-height: calc(100vh - 96px)` —— 那个 96 是页头还在
   .fl-main 里面的时候凑出来的（页头高 + 上下留白）。页头搬到 .fl-wrap
   外面之后它就不准了，只是恰好还接近，所以没人发现。
   **现在整条 min-height 删掉了**：右栏的高度由 .fl-wrap 那一行给
   （grid 的 align-items: stretch → 而 .fl-wrap 又由 .fl-fit / .main 给），
   和左栏**是同一个来源**。两栏不再各算一遍、也就不会各算错一遍。

   【"让日程卡片往下铺满"这个说法已经过期（2026-09-30 用户确认收掉）】
   原来这里写的是"撑满一屏，让日程卡片能往下铺满（用户要求）"，
   对应 tools/daymark-day-check.mjs 里那条"卡片底边贴到视口底部"的断言 ——
   实测 1600×1000 差了 166px，**从来没达标过**（那条断言参数写反了、
   恒为真，所以没人发现）。用户已经确认不要再追这个目标，
   断言改成"下方不留一整屏空白"。删掉 min-height 也不影响那一条：
   它守的是"下方别空出一整屏"，而现在的下方是**内容本身的自然收尾**。 */
.fl-main {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  /* 【这两条是"内容比可用高度还高"（矮屏）时的保命线】
     align-self: stretch 让它和左栏同一个网格行一起被拉伸；
     min-height: 0 压掉 grid 项默认的 min-height:auto ——
     不然矮屏下它会顶破网格行，把左栏一起顶出去。
     内容真的装不下时由 .main（外层滚动容器）滚动，这是既有行为。 */
  align-self: stretch;
  min-height: 0;
}

.fl-dayhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.fl-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.fl-title h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: .3px;
}

.fl-week { font-size: 12.5px; color: var(--text-3); }

.badge.fl-rel {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--surface-2);
  color: var(--text-3);
}

.badge.fl-rel.is-today {
  background: var(--brand-soft, rgba(107,122,90,.14));
  color: var(--brand, #48ab93);
  font-weight: 500;
}

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

/* ---------- 四个快捷信息 ---------- */

.fl-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.fl-stat {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 10px);
  padding: 10px 12px 10px 14px;
  overflow: hidden;
}

/* 左侧一条分类色带，四块之间好区分 */
.fl-stat::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
}

.fl-stat.done::before   { background: #4a8f6a; }
.fl-stat.remind::before { background: #d59a2e; }
.fl-stat.focus::before  { background: #4a7fa8; }
.fl-stat.diary::before  { background: #a86fa8; }

.fs-label {
  font-size: 11.5px;
  color: var(--text-3);
  margin-bottom: 3px;
}

.fs-value {
  display: flex;
  align-items: baseline;
  gap: 3px;
}

.fs-value b {
  font-size: 19px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.fs-sub { font-size: 12px; color: var(--text-3); }
.fs-unit { font-size: 11px; color: var(--text-3); }

/* ---------- 甘特图的容器 ----------
   情绪已经挪到左栏（日历下方），所以这里不再需要两列布局。
   甘特图**独占右栏**，宽度铺满；高度按内容自然生长 ——
   不再用 flex:1 把三条轨道拉成胖子（那是"行高有点高"的来源）。
   （原来的 .fl-body / .fl-right 两列布局已删除） */

/* ============================ 甘特图 ============================ */

/* ==========================================================================
   日程：日 / 周 / 月
   --------------------------------------------------------------------------
   【统一尺寸是这次改动的核心】
   用户的问题：「日、周、月的长宽完全不协调，日甚至高度高了一倍」。

   原因：日视图是「24 小时 × 46px = 1104px」的时间轴，
   而周/月只有三条 34px 的轨道 —— 差了二十多倍。

   现在三个视图**共用 --sched-h 这一个高度**，内部各自处理溢出：
     · 日   在固定高度里滚动
     · 周   列内滚动
     · 月   格内滚动（5 行，多了滚）
   所以切换视图时卡片高度纹丝不动。
   ========================================================================== */

.fl-gantt {
  --sched-h: 560px;
  --sched-gap: 8px;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
  min-width: 0;
}

/* 三个视图的外框高度都锁在 --sched-h。
   注意用 height 而不是 min-height —— 后者会让"内容多"的视图把卡片撑高，
   那样切视图时高度还是会变。 */
/* ==========================================================================
   【三个视图的第一行必须一样高】
   --------------------------------------------------------------------------
   用户的要求：「日程组件 周的第一行 高度和日 月不一致，需修复一下」。

   实测（1440×900）：日的第一行（全天那一条）68px、
   周的第一行（七个日期）57px、月的第一行（星期几）29px —— 三个都不一样。
   于是切 日/周/月 的时候，下面那条时间轴的起点会上下跳一段，
   看着就是"三个视图没对齐"。

   现在统一用这个变量。**改一个数，三个视图一起变** ——
   以前是三处各写各的高度，改一处另外两处不会跟着动，
   这正是"不一致"的来源。
   ========================================================================== */
.sched-day,
.sched-week,
.sched-month {
  --sched-head-h: 46px;
  height: var(--sched-h);
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ---------- 标题栏 ---------- */

.gl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.gl-head-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.gl-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 600;
}

.gl-title > span { font-size: 13px; opacity: .65; }

/* 日 / 周 / 月 切换：分段控件（三个按钮拼成一条，当前那个是实心底） */
.gl-seg {
  display: inline-flex;
  padding: 2px;
  border-radius: 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
}

.gl-seg-btn {
  font: inherit;
  font-size: 11.5px;
  min-width: 30px;
  height: 22px;
  padding: 0 9px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  transition: background .15s, color .15s;
}
.gl-seg-btn:hover { color: var(--text); }
.gl-seg-btn.on {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0,0,0,.08);
}

.gl-nav { display: flex; gap: 4px; align-items: center; }

.gl-range {
  font-size: 11.5px;
  color: var(--text-3);
  margin-right: 4px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gl-nav button {
  font: inherit;
  font-size: 11.5px;
  min-width: 26px;
  height: 24px;
  padding: 0 8px;
  border-radius: 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.gl-nav button:hover { background: var(--surface-2); color: var(--text); }

/* 「今天」按钮：紧挨在「创建日程」左边，用户要求的位置 */
.gl-today-btn { border-color: var(--line) !important; }

/* 「＋ 创建日程」是这一栏里最重的操作，给它实心样式 */
.gl-create {
  margin-left: 6px;
  height: 28px !important;
  padding: 0 12px !important;
  border-radius: 8px !important;
  background: var(--accent) !important;
  color: var(--on-accent) !important;
  font-weight: 500;
}
.gl-create:hover { filter: brightness(1.08); }

/* ============================== 日视图 ============================== */

.sched-day { gap: var(--sched-gap); }

/* 顶部「全天」那一条 */
.sched-allday {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  flex: 0 0 auto;
  /* 和另外两个视图的第一行齐平（见 --sched-head-h 那段说明）。
     条目多了在这一条里自己滚。 */
  height: var(--sched-head-h);
  max-height: var(--sched-head-h);
  overflow-y: auto;
}

.sched-allday-label {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--text-3);
  padding-top: 2px;
}

.sched-allday-body {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  min-width: 0;
}

.sched-chip {
  font: inherit;
  font-size: 11.5px;
  padding: 2px 8px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sched-chip:hover { border-color: var(--accent); }
.sched-chip.done { text-decoration: line-through; color: var(--text-3); }
.sched-chip.rem { border-style: dashed; }

.sched-add-all {
  font: inherit;
  font-size: 11.5px;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
}
.sched-add-all:hover { color: var(--accent); border-color: var(--accent); }

/* 时间轴区：**24 小时整屏放下，不滚动**
 *
 * 【2026-09-26 第二轮改的】
 * 用户的原话：「日程组件的日 内容时间高度太长了，减少一点，
 * 最好都不需要滑块条」。
 * 原来是固定 52px/小时 → 内容 1248px，而这块只有 400 多像素高，
 * 所以必然挂着一条滑块条（周视图更夸张：七列各一条，同时五条）。
 *
 * 现在刻度行（.sched-hour / .sched-line）用 flex 均分高度，
 * 条目位置用百分比（见 daymark.js 的 minToPct）——
 * 容器多高，24 小时就均分多高，永远不会溢出。
 * 所以这里把 overflow 收成 hidden：不是"藏起来",
 * 而是**真的没有东西要滚**（万一哪天真溢出了，宁可裁掉也不该冒出滚动条）。
 */
.sched-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
}

/* 让刻度列和轨道**铺满** .sched-scroll 的高度 ——
   这是"均分"这件事的前提：两个子元素自己是撑不高的。 */
.sched-tl {
  display: flex;
  height: 100%;
}

.sched-scale {
  flex: 0 0 54px;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--surface-2);
}

/* 【flex: 1 1 0 —— 24 行平分高度】
   basis 给 0（不是 auto）：auto 的话每行先按内容高度站住，
   再分配剩下的空间，24 行就分不匀了（最后一行会偏高）。 */
.sched-hour {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 2px 8px 0 0;
  font-size: 10.5px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}
/* 奇数点只留刻度线不写字，免得挤 */
.sched-hour:not(.major) span { visibility: hidden; }

.sched-track {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  cursor: crosshair;
  /* 24 条横线也均分轨道高度（和左边的刻度一一对应） */
  display: flex;
  flex-direction: column;
}

.sched-line {
  flex: 1 1 0;
  min-height: 0;
  border-bottom: 1px solid var(--line);
  box-sizing: border-box;
}
.sched-line:last-child { border-bottom: 0; }

/* 时间轴上的条目块 */
.sched-block {
  position: absolute;
  left: 6px;
  right: 6px;
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 11.5px;
  overflow: hidden;
  cursor: pointer;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 1px;
  border-left: 3px solid rgba(0,0,0,.18);
  /* 【高度是百分比，所以要给一个最小高度兜底】
     24 小时均分下来每小时才十几像素，一个 30 分钟的块只有 8px ——
     不给下限就完全看不见了。 */
  min-height: 17px;
}

.sched-block-time {
  font-size: 10px;
  opacity: .85;
  font-variant-numeric: tabular-nums;
}
.sched-block-title {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 待办：实心 */
.sched-block.task {
  background: color-mix(in srgb, #4a8f6a 20%, var(--surface));
  color: var(--text);
  border-left-color: #4a8f6a;
}
.sched-block.task.done {
  opacity: .55;
  text-decoration: line-through;
}

/* 时间切片：虚线边，和待办区分开 */
.sched-block.slice {
  border: 1px dashed var(--line-strong);
  border-left: 3px solid currentColor;
  background: var(--surface-2);
}

.sched-block.slice.k-work  { color: var(--green); }
.sched-block.slice.k-study { color: #4a7fa8; }
.sched-block.slice.k-rest  { color: #d59a2e; }
.sched-block.slice.k-life  { color: #a86fa8; }
.sched-block.slice.k-other { color: #9a958e; }

/* 拖动时的草稿框 */
.sched-draft {
  position: absolute;
  left: 6px;
  right: 6px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border: 1px dashed var(--accent);
  font-size: 11px;
  color: var(--text);
  padding: 3px 8px;
  pointer-events: none;
  box-sizing: border-box;
  font-variant-numeric: tabular-nums;
  /* 和 .sched-block 同理：高度是百分比，太短要给个下限才看得见 */
  min-height: 18px;
}

/* 提醒：时间轴上一条细线 */
.sched-rem {
  position: absolute;
  left: 6px;
  right: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-2);
  cursor: pointer;
  transform: translateY(-50%);
}
.sched-rem-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #d59a2e;
}
.sched-rem-txt {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sched-rem.done { opacity: .5; }
.sched-rem.done .sched-rem-txt { text-decoration: line-through; }

/* ============================== 周视图 ============================== */

.sched-week { gap: var(--sched-gap); }

.sched-week-grid {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.sched-wdates {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--surface-2);
  /* 【2026-10-02：flex 从 0 0 auto 改成 1 1 auto】
     它原来是一整行（父元素 .sched-week-grid 直接是纵向 flex），
     `0 0 auto` = 按内容宽。现在它被挪进 .sched-whead、和左边的占位格并排，
     而它的内容只是 7 个"周几 + 数字"的小方块 ——
     实测父行 888px，它只占 **142px**（7×20.25px），
     下面的 7 列轨道却有 834px（7×119px），**日期和列完全对不上**。
     改成 flex: 1 1 auto 之后它吃掉剩余宽度，和下面的轨道一样宽。 */
  flex: 1 1 auto;
  min-width: 0;
  /* 和日 / 月 的第一行齐平（见 --sched-head-h 那段说明） */
  height: var(--sched-head-h);
  /* 【分隔线从 .sched-wdates 挪到 .sched-whead】
     否则左边那块占位格下面没有线，日期行看着像从中间才开始。 */
}

.sched-wdate {
  font: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: 6px 2px;
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  /* 拖选时不要选中文字 */
  user-select: none;
}
.sched-wdate:last-child { border-right: 0; }
.sched-wdate:hover { background: var(--surface); }
.sched-wdate.today .sched-wn { color: var(--accent); font-weight: 700; }
.sched-wdate.on { background: var(--accent-soft); }

/* 拖选中的那几天 */
.sched-wdate.picked {
  background: color-mix(in srgb, var(--accent) 24%, transparent);
  box-shadow: inset 0 -2px 0 var(--accent);
}

.sched-wd { font-size: 10px; }
.sched-wn {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.sched-wc {
  font-size: 9.5px;
  color: var(--text-3);
  height: 12px;
}

/* 【2026-10-02 加左侧时间刻度】
   用户报的：「日迹模块：日程组件 周 左侧没有时间，日是有时间的」。
   日视图一直有 .sched-scale（54px，00:00/02:00…），周视图漏了。

   结构（见 daymark.js 里那段注释）：
     .sched-week-grid（纵向）
       ├─ .sched-whead（横向）→ [.sched-wgutter 占位] + [.sched-wdates 7 个日期]
       └─ .sched-wbody（横向）→ [.sched-scale 刻度] + [.sched-wbody-cols 7 列]
   关键：**占位格和刻度列的宽度来自同一个变量**，
   所以日期行和下面的轨道一定对齐，不会因为哪边内容变宽而错位。 */
.sched-week-grid {
  --sched-gutter-w: 54px;   /* 和日视图 .sched-scale 的 flex-basis 保持一致 */
}

/* 日期行：左边留出和刻度列一样宽的空格 */
.sched-whead {
  display: flex;
  flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  height: var(--sched-head-h);
}
/* 占位格：只有宽度和一条右边的分隔线，和下面的刻度列对得上 */
.sched-wgutter {
  flex: 0 0 var(--sched-gutter-w);
  border-right: 1px solid var(--line);
}

.sched-wbody {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

/* 刻度列：复用日视图的 .sched-scale 外观（字号/颜色/数字右对齐都一样），
   只是这里要显式占宽（日视图那份是 flex: 0 0 54px，这里跟着变量走）。 */
.sched-wscale {
  flex: 0 0 var(--sched-gutter-w);
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* 【刻度列顶部要空出列顶那一条的高度】
   每一列的最上面是 .sched-wtop（"没有具体时间"的条目，固定 34px），
   轨道从它下面才开始。刻度列如果从最顶上就排 00:00，
   那 24 行就会**比轨道多占 34px**，越往下错得越多
   （实测：刻度 310~794、轨道 344~794 —— 顶部整整差 34px，
    也就是 22:00 那行的标签会跑到轨道的 21:00 附近）。
   所以这里垫一块同高的空条，两边 24 行才一一对应。 */
.sched-wscale-pad {
  flex: 0 0 auto;
  height: 34px;                 /* == .sched-wtop 的 height */
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

/* 7 列轨道：原来 .sched-wbody 自己就是 7 列栅格，现在退到这一层 */
.sched-wbody-cols {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.sched-wcol {
  border-right: 1px solid var(--line);
  padding: 0;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* 【列本身不再滚动】
     2026-09-26 周视图改成时间轴之后，滚动交给里面的 .sched-wscroll ——
     列自己还留着 overflow 的话会出现"两条滚动条"，
     而且同步滚动也没法做了（它需要精确控制每个滚动容器的 scrollTop）。 */
  overflow: hidden;
}
.sched-wcol:last-child { border-right: 0; }

/* 列顶：没有具体时间的条目 + 加一条的按钮
 *
 * 【为什么高度要**写死**成一行】
 * 七列的时间刻度必须横着对齐（周三 14:00 和周五 14:00 在同一条线上），
 * 那就要求每一列的时间轴**起点一样高**。
 * 原来这里是 flex: 0 0 auto —— 谁多一条没时间的待办，谁就高一点，
 * 那一列的刻度整体往下挪，七列就对不齐了。
 * 现在固定一行的高度，条目多了就在这一行里自己滚
 * （宁可偶尔出现一条小滑块，也不能让刻度错位）。 */
.sched-wtop {
  flex: 0 0 auto;
  height: 34px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 5px 5px 3px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

/* 列主体：24 小时时间轴，**不滚动**（和日视图同一套做法）
 *
 * 【"同时有 5 条滑块条"就是这么来的】
 * 原来是每列 overflow-y:auto + 七列同步 scrollTop：
 * 内容 1248px、可视 400 多px，于是七列一起挂上滚动条。
 * 现在 24 小时均分列高，一列也不滚，同步滚动那套逻辑也一起删了。 */
.sched-wscroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  position: relative;
}
.sched-wtrack {
  position: relative;
  height: 100%;
  /* 和日视图一样：24 条横线均分高度 */
  display: flex;
  flex-direction: column;
}
/* 周视图里的块比日视图窄得多（一列大约 1/7 宽），
   字号和内边距都收紧一点，否则一行只放得下两三个字。 */
.sched-wtrack .sched-block {
  left: 3px;
  right: 3px;
  font-size: 10.5px;
  padding: 2px 5px;
}
.sched-wtrack .sched-block-time { font-size: 9.5px; }

.sched-item {
  font: inherit;
  font-size: 11px;
  display: flex;
  align-items: baseline;
  gap: 4px;
  width: 100%;
  text-align: left;
  padding: 3px 6px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  overflow: hidden;
}
.sched-item:hover { border-color: var(--accent); }
.sched-item-t {
  flex: 0 0 auto;
  font-size: 9.5px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.sched-item-x {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sched-item.task { border-left: 3px solid #4a8f6a; }
.sched-item.task.done { opacity: .55; text-decoration: line-through; }
.sched-item.slice { border-style: dashed; border-left: 3px solid currentColor; }
.sched-item.slice.k-work  { color: var(--green); }
.sched-item.slice.k-study { color: #4a7fa8; }
.sched-item.slice.k-rest  { color: #d59a2e; }
.sched-item.slice.k-life  { color: #a86fa8; }
.sched-item.rem { border-style: dashed; }

.sched-wadd {
  font: inherit;
  font-size: 11px;
  padding: 3px;
  border-radius: 6px;
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s;
}
.sched-wcol:hover .sched-wadd { opacity: 1; }
.sched-wadd:hover { color: var(--accent); border-color: var(--accent); }

/* ============================== 月视图 ============================== */

.sched-month { gap: var(--sched-gap); }

.sched-mhead {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
  background: var(--surface-2);
  overflow: hidden;
  /* 和日 / 周 的第一行齐平（见 --sched-head-h 那段说明）。
     星期几本来只要 29px，垫高到 46px 是为了三块对齐 ——
     不对齐的话每切一次视图，下面的格子就往下挪一段。 */
  height: var(--sched-head-h);
  align-items: center;
}

.sched-mhd {
  padding: 5px 0;
  text-align: center;
  font-size: 11px;
  color: var(--text-3);
}
.sched-mhd.wk { color: var(--red); opacity: .8; }

.sched-mgrid {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  /* 行数由 JS 按实际周数给（5 或 6），固定下来翻月时不跳 */
  grid-template-rows: repeat(var(--sched-rows, 6), minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  overflow: hidden;
}

.sched-mcell {
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 3px 4px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--surface);
}
.sched-mcell:nth-child(7n) { border-right: 0; }
.sched-mcell.out { background: var(--surface-2); }
.sched-mcell.out .sched-mnum { opacity: .4; }
.sched-mcell.today { background: var(--accent-soft); }

.sched-mnum {
  font: inherit;
  flex: 0 0 auto;
  align-self: flex-start;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  padding: 1px 5px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
}
.sched-mnum:hover { background: var(--surface-2); color: var(--text); }
.sched-mcell.today .sched-mnum { color: var(--accent); font-weight: 700; }

/* 事件列表：**默认露出 5 条的高度**，多了在格内滚动。
   用户说：「默认是 5 条事件，允许超过 5 条，可以滚动」。 */
.sched-mlist {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 2px;
  /* 5 行 × 约 15px。超过就滚，不把整张表撑高。 */
  max-height: calc(5 * 15px);
}

.sched-mev {
  font: inherit;
  font-size: 10.5px;
  display: flex;
  align-items: baseline;
  gap: 3px;
  width: 100%;
  text-align: left;
  padding: 1px 4px;
  border: 0;
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  overflow: hidden;
  flex: 0 0 auto;
}
.sched-mev:hover { background: var(--accent-soft); }
.sched-mev-t {
  flex: 0 0 auto;
  font-size: 9px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.sched-mev-x {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sched-mev.task { border-left: 2px solid #4a8f6a; }
.sched-mev.task.done { opacity: .5; text-decoration: line-through; }
.sched-mev.slice { border-left: 2px solid currentColor; }
.sched-mev.slice.k-work  { color: var(--green); }
.sched-mev.slice.k-study { color: #4a7fa8; }
.sched-mev.slice.k-rest  { color: #d59a2e; }
.sched-mev.slice.k-life  { color: #a86fa8; }
.sched-mev.rem { border-left: 2px solid #d59a2e; border-style: dashed; }

.sched-madd {
  font: inherit;
  font-size: 10.5px;
  flex: 0 0 auto;
  padding: 1px;
  border-radius: 4px;
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s;
}
.sched-mcell:hover .sched-madd { opacity: 1; }
.sched-madd:hover { color: var(--accent); border-color: var(--accent); }

/* ============================== 通用 ============================== */

/* --------------------------------------------------------------------------
   日程编辑框里"公共控件盖不住"的那几小块
   --------------------------------------------------------------------------
   2026-09-27：用户说「日程新建的 UI 不好看，参考待办模块新建待办的 UI」。
   根子是那个框用的类名（.sched-form / .sched-field / .sched-input / …）
   **在 CSS 里一个都没有**，所以它一直在用浏览器默认长相。
   现在标签、输入框、几选一、底部按钮全部换成公共控件
   （.field / .input / .textarea / .segment，见 base.css），
   这里只留三块公共控件确实没有的东西：
     · 多天时排一排的日期小标签
     · 两个时刻中间的破折号
     · "全天"时把两个时刻压暗（仍然看得见，知道自己在关掉什么）
   ========================================================================== */

.sched-days {
  flex-wrap: wrap;
}

/* 【选择器为什么带 .sched-days 前缀】
   `.sched-day` 这个名字**日视图在用**（.sched-day 是那天的时间轴外框，
   见上面「日视图」那一节，它有固定高度）。所以这里必须限定在
   "多天日期小标签"的容器里，否则会把日视图整块改成小药丸。 */
.sched-days .sched-day-chip {
  padding: 3px 9px;
  font-size: 11.5px;
  color: var(--text-2);
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
}

.sched-times .input {
  flex: 1 1 0;
  min-width: 0;
}

.sched-dash {
  color: var(--text-3);
}

.sched-times.is-off .input {
  opacity: 0.5;
}

.gl-empty {
  padding: 12px 2px 2px;
  font-size: 11.5px;
  color: var(--text-3);
  text-align: center;
}

.gl-legend {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--text-3);
  flex: 0 0 auto;
  padding-top: 2px;
}

.gl-legend .lg { display: flex; align-items: center; gap: 4px; }

.gl-legend i {
  display: inline-block;
  width: 12px;
  height: 8px;
  border-radius: 2px;
}
.gl-legend i.k-work  { background: var(--green); }
.gl-legend i.k-study { background: #4a7fa8; }
.gl-legend i.k-rest  { background: #d59a2e; }
.gl-legend i.k-life  { background: #a86fa8; }
.gl-legend i.sched-dot-leg { background: #4a8f6a; height: 7px; border-radius: 3px; }
.gl-legend i.sched-rem-dot-leg { background: #d59a2e; width: 7px; height: 7px; border-radius: 50%; }
.gl-legend .lg.hint { opacity: .75; margin-left: auto; }

/* ---------- 窄屏 ---------- */

@media (max-width: 980px) {
  /* 【手机上高度要矮一点】
     560px 在手机竖屏上会占满整屏，下面的行程卡片就看不见了。
     360px 还能显示 7 个多小时的时间轴，够用。 */
  .fl-gantt { --sched-h: 360px; }
}

@media (max-width: 700px) {
  .fl-gantt { --sched-h: 320px; padding: 10px; }
  /* 周视图 7 列在手机上每列只剩 45px，横着滑 */
  .sched-week-grid { overflow-x: auto; }
  .sched-wdates, .sched-wbody { min-width: 560px; }
  .sched-scale { flex: 0 0 42px; }
  .sched-mlist { max-height: calc(3 * 15px); }
}

/* ============================ 情绪 ============================ */

.fl-mood {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
  /* 【2026-10-03：由它来接左栏剩下的高度（用户要"左栏刚好铺满屏幕"）】
     日历卡被固定成"自己多高就多高"之后，左栏在高屏上会多出一截，
     这一截交给情绪卡最自然：它是左栏最后一块，撑高它等于让
     卡片的下沿去对齐右栏的下沿 —— 左栏底部那块空白就没了。
     （为什么不让日历卡接：它被拉高之后格子封了顶，
     多出来的空间会空在网格下方，反而变成卡片内部的空白 —— 试过，见 .fc-card 注释。）
     矮屏（可用高度比内容还小时）它不缩：flex-shrink 给 0，
     内容装不下就交给外层 .main 滚动，不把卡片压烂。 */
  flex: 1 1 auto;
  min-height: 0;
  /* 【卡片内部的间距统一由这一个 gap 管】
     2026-09-27 样式体检（npm run audit:styles）之后统一过一遍：
     这块卡片原来是靠各个元素自己的 margin 一点点拼出间距的
     （标题条 10px、标签 8px、备注框 9px…），改一处就散一处。
     现在和 .vault-wrap / .mail-form 一样：容器是列 + 一个 gap，
     里面那些 margin 归零。 */
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 上面已经有 gap 了，标题条自己的下边距要撤掉，否则是 18px */
.fl-mood .fl-card-head { margin-bottom: 0; }

/* 【.mood-top / .mood-note-wrap / .mood-bottom 是三个"锚点"容器】
   它们的作用不是长相，而是**让备注框永不重建**：重绘时只换 moodTop /
   moodBottom 里面的东西，mood-note-wrap 从头到尾挂在文档上不动 ——
   这样输入法的拼字状态不会被打断（见 daymark.js 的 drawMood）。
   但"没有视觉职责"不等于"不用管布局"：这里给它们和卡片里其它容器
   同一套列布局，间距统一由 .fl-mood 的 gap 给。 */
.mood-top,
.mood-bottom {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* 【只有 .mood-bottom 吃剩余高度】
   它装着"最近两周"的折线图 —— 图长高是有意义的。
   .mood-top（标题 + 今天感觉 + 五个表情按钮）是固定控件，
   被拉高只会让按钮之间的空隙变大，所以它保持内容高。
   【为什么不用 min-height:0 之外的东西】flex: 1 要生效，
   父级 .fl-mood 必须是列 flex 且自己有确定高度 —— 两条都满足
   （见 .fl-mood 那段：它被左栏撑高）。 */
.mood-bottom {
  flex: 1 1 auto;
  min-height: 0;
}
.mood-note-wrap {
  min-width: 0;
}

.fl-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.flh-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 600;
}

.flh-title > span { font-size: 13px; opacity: .65; }
.flh-right { font-size: 11.5px; }

.mood-sum { font-size: 11.5px; font-weight: 500; }

.mood-label {
  font-size: 11.5px;
  color: var(--text-3);
  /* 上边距交给 .fl-mood 的 gap（原来是 8px 自己拼的） */
  margin: 0 0 5px;
}

.mood-row {
  display: flex;
  gap: 4px;
}

.mood-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 2px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .12s;
}

.mood-btn .face { font-size: 17px; line-height: 1.2; }

.mood-btn:hover {
  background: var(--surface-2);
  transform: translateY(-1px);
}

.mood-btn.on {
  border-color: var(--brand, #48ab93);
  background: var(--brand-soft, rgba(107,122,90,.14));
}

.mood-note {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 12px;
  /* 上边距交给 .fl-mood 的 gap（原来是 9px 自己拼的） */
  margin-top: 0;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  outline: none;
}

.mood-note:focus { border-color: var(--brand, #48ab93); }

/* 最近两周的心情折线图
   ------------------------------------------------------------------
   原来是 14 根小柱子（.mt-col）。用户说「方块有点不优雅」，
   改成折线 —— 折线能看出**走势**，柱子只能看出单天高低。

   用 SVG 画的（app/scripts/views/daymark.js 的 moodChart）。
   这里只管样式，坐标计算在 JS 里。 */
   【2026-10-03：这一块要"接住"情绪卡多出来的高度】
   情绪卡现在会跟着左栏一起被撑高（见 .fl-mood 那段，
   用户要"左栏刚好铺满屏幕"）。如果里面的东西都保持内容高，
   多出来的高度就会变成卡片**内部**的空白 —— 那只是把
   用户抱怨的那块空白从"左栏底部"挪到了"情绪卡中间"，问题没解决。

   所以这里的链条也做成"往下传"：
     .fl-mood（被撑高）→ .mood-bottom（吃掉剩下的）→ .mood-trend
     → .mood-chart → .mood-svg（折线图长高）
   折线图长高是对的：它是"能看出走势"的图，高一点更好读；
   而按钮行、备注框都保持自己的高度（它们是固定控件，不该被拉扁）。 */
.mood-trend {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 0 0;
  /* 吃掉 .mood-bottom 里除标签之外的高度 */
  flex: 1 1 auto;
  min-height: 0;
}

.mood-chart {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* 折线图自己去吃 .mood-trend 里剩下的高度（"平均 x 分"那行小字留在下面） */
  flex: 1 1 auto;
  min-height: 0;
}

.mood-svg {
  display: block;
  width: 100%;
  /* 【76px 从固定高度改成"上下界"】
     改前是 height: 76px 写死 —— 情绪卡被撑高之后它就接不住，
     多余的高度全变成卡片底部的空白。
     现在默认还是 76px（矮屏 / 没被撑高时长相不变），
     但允许长到 200px（够看清两周的走势），封顶免得在一台很高的
     显示器上变成一大块空白画布。
     【为什么不用 preserveAspectRatio 保持比例】
     保持比例的话，容器变宽时图形会跟着变高，把卡片撑开。
     这里用 none 让它在横向拉伸、纵向跟着容器走 ——
     折线图的横向拉伸不影响可读性（日期本来就稀疏）。 */
  height: 76px;
  flex: 1 1 auto;
  min-height: 76px;
  max-height: 200px;
  overflow: visible;
}

/* 参考线（5 / 3 / 1 分） */
.mood-grid {
  stroke: var(--line);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: .7;
  vector-effect: non-scaling-stroke;
}
.mood-grid.mid { stroke-dasharray: none; opacity: .5; }

/* 折线本体 */
.mood-line {
  fill: none;
  stroke: #c8553d;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* 【非缩放描边】
     viewBox 是 300 宽，实际容器可能 600 宽 —— 会被横向拉伸两倍。
     不加这一条，线宽也会跟着变成 4px，看着很粗。 */
  vector-effect: non-scaling-stroke;
}

.mood-dot {
  fill: #c8553d;
  stroke: var(--surface);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
.mood-dot.clickable { cursor: pointer; }
.mood-dot.clickable:hover { r: 5; }
/* 当前选中的那天放大 + 描一圈 */
.mood-dot.on {
  fill: var(--accent);
  stroke: var(--accent-soft);
  stroke-width: 3;
}

.mood-axis {
  display: flex;
  justify-content: space-between;
  font-size: 9.5px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.mood-axis-mid { opacity: .7; padding: 0 10px; }

.mood-sum-line {
  display: flex;
  gap: 4px;
  font-size: 10.5px;
  color: var(--text-3);
  padding-top: 2px;
}

.mood-trend-empty {
  font-size: 11px;
  color: var(--text-3);
  padding: 12px 0;
  width: 100%;
  text-align: center;
}

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

.btn-ghost.sm {
  font-size: 11.5px;
  padding: 4px 10px;
  border-radius: 7px;
}

/* ============================ 窄屏 ============================ */

@media (max-width: 900px) {
  .fl-wrap {
    grid-template-columns: minmax(0, 1fr);
  }
  /* 【窄屏是单栏，"铺满一屏"这个要求在这里不成立（2026-10-03）】
     两栏变一栏之后，左栏（日历+情绪）和右栏是**上下叠着**的，
     非要一起铺满一屏的话它们会互相挤压。所以这里把 .fl-fit 的
     min-height 和 .fl-wrap 的 flex 增长都收掉，让单栏回到
     "内容多高就多高、页面自己滚"的正常文档流 ——
     这正是 390×844 那一档要的结果（纵向可滚、不横向溢出）。
     position: static 仍然显式写着：宽度方向换成了单栏，
     但"左栏不 sticky"这个决定和宽屏是同一条理由，不需要分叉。 */
  .fl-fit { min-height: 0; }
  .fl-wrap { flex: 0 0 auto; }
  .fl-side { position: static; }
  .fl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================ 行程 ============================ */

/* 和 .fl-mood 同一套卡片外观 —— 日迹里每块内容看起来该是一致的 */
.fl-trips {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
}

/* --------------------------------------------------------------------------
   全年轨迹（行程页的下半张卡）
   --------------------------------------------------------------------------
   2026-09-27：用户问「地图为什么是出现在年的分页里，不应该是在行程页吗？」
   —— 那一整块从日程的「年」档位搬到这里。

   【为什么不直接复用原来那套尺寸】
   以前它住在甘特图那张**固定高度 560px** 的卡里，所以 .gl-year 是
   `flex: 1 1 auto` 去"撑满剩下的高度"、.gy-map 靠父级的高度活。
   行程这一页是**内容自适应高度**的（上面那张当天行程卡就是短列表），
   照搬过来的话地图会因为没有高度直接塌成 0 —— 图上什么都看不见。
   所以这里给地图一个自己的宽高比（和 viewBox 660×400 一致），
   整块也不再"撑满"，而是跟着内容走。
   ========================================================================== */
.fl-year {
  margin-top: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
}

.fl-year .gl-year {
  flex: none;
  min-height: 0;
  overflow: visible;
}

/* 地图高度自己算：宽高比 = 中国版图的宽高比（不变形），上下留个界 */
.fl-year .gy-map {
  aspect-ratio: 660 / 400;
  min-height: 220px;
  max-height: 420px;
}

/* 窄屏：地点榜挪到地图下面，别把地图挤成一条 */
@media (max-width: 900px) {
  .fl-year .gy-body {
    grid-template-columns: minmax(0, 1fr);
  }
}

.tr-sum { font-size: 11.5px; font-weight: 500; }
.tr-empty {
  font-size: 12px;
  color: var(--text-3);
  padding: 10px 2px 12px;
}

.tr-list { display: flex; flex-direction: column; }

.tr-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 2px;
  border-bottom: 1px solid var(--line);
}
.tr-row:last-child { border-bottom: 0; }

/* 时间列定宽 —— 不定宽的话"9:30–10:15"和"14:00–14:30"会让每行的
   中间那列起点不一样，一列行程看着是锯齿状的。 */
.tr-time {
  flex: 0 0 96px;
  font-family: var(--font-num);
  font-size: 11.5px;
  color: var(--text-2);
  white-space: nowrap;
}

.tr-mid { flex: 1; min-width: 0; }

.tr-route {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  min-width: 0;
}
.tr-place {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 180px;
}
.tr-arrow { color: var(--text-3); flex: 0 0 auto; }
.tr-tag {
  font-size: 10px;
  color: var(--text-3);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 0 4px;
  line-height: 15px;
}

.tr-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  font-size: 11px;
  color: var(--text-3);
  flex-wrap: wrap;
}
.tr-mode { display: inline-flex; align-items: center; gap: 3px; }
.tr-meta.note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 240px;
}

.tr-ops {
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
  /* 【平时藏起来，鼠标放上去才出现】
     一行行程最主要的用途是"看"，不是"改"。
     两个按钮一直摆着会把地点挤窄，所以默认只留淡淡的一层。 */
  opacity: 0;
  transition: opacity .15s;
}
.tr-row:hover .tr-ops,
.tr-row:focus-within .tr-ops { opacity: 1; }

.tr-op {
  border: 0;
  background: transparent;
  color: var(--text-3);
  font-size: 11.5px;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 6px;
}
.tr-op:hover { background: var(--surface-2); color: var(--text); }
/* 注意用 --red 而不是 --danger：
   --danger 是后台管理那套主题（admin-theme.css）里的变量，
   主应用这边叫 --red（tokens.css）。用错了在暗色主题下会没有颜色。 */
.tr-op.danger:hover { color: var(--red); }

/* ---------- 简易地图 ---------- */

.tr-map {
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  padding: 6px;
  overflow: hidden;
}

.tr-map-svg {
  display: block;
  width: 100%;
  height: 190px;
}

.tr-line {
  stroke: var(--line-strong);
  stroke-width: 1.4;
  stroke-dasharray: 4 3;
  opacity: .75;
}
/* 飞机 / 火车画成实线，近程的步行骑行用点线 —— 一眼分得出远近距离 */
.tr-line.mode-plane,
.tr-line.mode-train { stroke-dasharray: none; stroke-width: 1.8; opacity: .9; }

.tr-dot { fill: var(--accent); }
.tr-dot.origin {
  /* 起点用醒目色，一眼看出行程从哪开始 */
  fill: var(--red);
  stroke: var(--surface);
  stroke-width: 1.2;
}

.tr-dot-label {
  font-size: 8.5px;
  fill: var(--text-3);
  font-family: var(--font-num);
  pointer-events: none;
}

.tr-no-map,
.tr-map-note {
  font-size: 11px;
  color: var(--text-3);
  padding: 8px 4px;
  text-align: center;
}

/* ---------- 记一段行程的表单 ---------- */

.tr-add-wrap { margin-top: 10px; }

.tr-form {
  margin-top: 10px;
  padding: 10px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  display: grid;
  gap: 8px;
}

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

.tr-form-arrow { color: var(--text-3); font-size: 12px; }

.tr-in {
  flex: 1 1 120px;
  min-width: 0;
  height: 30px;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
}
.tr-in:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

.tr-time-in { flex: 0 0 104px; }
.tr-mode-in { flex: 0 0 116px; }
.tr-dist-in { flex: 0 0 124px; }

.tr-form-ops {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

@media (max-width: 900px) {
  /* 窄屏上时间列不再定宽，整行堆起来更省地方 */
  .tr-row { flex-wrap: wrap; }
  .tr-time { flex: 0 0 auto; }
  .tr-ops { opacity: 1; }
}

@media (max-width: 560px) {
  .fl-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mood-btn .face { font-size: 15px; }
  /* 【月视图不再横向滑动】
     旧的甘特图月视图是"42 个窄列"，窄屏上列宽只有十几像素、
     根本看不清，所以那时改成横向滑。
     新版的月视图是 7 列 × 5~6 行的**真月历**，每列宽
     ≈ 屏宽 / 7 ≈ 50px，已经放得下了 —— 再横向滑反而多余。
     这里只把范围文字藏掉（窄屏上它会把导航按钮挤下去）。 */
  .gl-range { display: none; }
}

/* ==========================================================================
   日程 ·「年」档位：全年行动轨迹
   --------------------------------------------------------------------------
   用户的要求：「日程组件，没做地图吗？我要看到我全年的行动轨迹」。

   和「行程」那一页的当天地图**不是同一张图**：
     · 当天图   自动缩放（同城的几个点也能分开看）
     · 全年图   固定范围（整块中国），这样"从南到北"的跨度才有地理意义
   中国轮廓是手绘的简化版（见 daymark.js 里的 CHINA_OUTLINE），只当背景板。
   ========================================================================== */
.gl-year {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
}

/* 四张小统计卡 */
.gy-stats {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.gy-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  padding: 7px 10px;
}
.gy-k { font-size: 11px; color: var(--text-3); }
.gy-v { display: flex; align-items: baseline; gap: 3px; margin-top: 2px; }
.gy-v b { font-size: 18px; font-variant-numeric: tabular-nums; }
.gy-v span { font-size: 11px; color: var(--text-3); }

.gy-body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px;
  gap: 10px;
}

/* ------------------------------ 地图 ------------------------------ */
.gy-map {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  overflow: hidden;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.gy-map-svg { display: block; width: 100%; height: 100%; }

/* 中国轮廓：很淡，只是给人一个方位感 */
.gy-land {
  fill: var(--surface-3);
  stroke: var(--line-strong, #d8cfc4);
  stroke-width: 1;
  stroke-linejoin: round;
  opacity: .85;
}
/* 轨迹线：一条接一条，表示"时间上依次走过" */
.gy-track {
  stroke: var(--brand, #48ab93);
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: .8;
  fill: none;
}
/* 走路 / 骑车的段用虚线，一眼分出"这趟是慢慢走的" */
.gy-track.mode-walk, .gy-track.mode-bike { stroke-dasharray: 4 3; }
.gy-track.mode-plane { stroke-dasharray: 2 4; }

.gy-dot { fill: var(--brand, #48ab93); stroke: var(--surface); stroke-width: 1.5; }
/* 起点 / 最后落脚点单独标出来 */
.gy-dot.origin { fill: #c0392b; }
.gy-dot.latest { fill: #2471a3; }
.gy-dot-label {
  font-size: 8.5px;
  fill: var(--text-2);
  paint-order: stroke;
  stroke: var(--surface-2);
  stroke-width: 2.5px;
  stroke-linejoin: round;
}
.gy-map-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--text-3);
  text-align: center;
  padding: 16px;
}

/* ------------------------------ 地点榜 ------------------------------ */
.gy-places {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  overflow-y: auto;
  min-height: 0;
  padding: 7px 9px;
}
.gy-places-head { font-size: 11px; color: var(--text-3); margin-bottom: 5px; }
.gy-place {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 0;
  border-bottom: 1px dashed var(--line);
  font-size: 12px;
}
.gy-place:last-child { border-bottom: 0; }
.gy-place-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gy-place-n { flex: none; font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.gy-place-date { flex: none; font-size: 10.5px; color: var(--text-3); }
.gy-place-nocoord { flex: none; font-size: 10px; color: #a8762f; }
[data-theme='night'] .gy-place-nocoord { color: #d8b45c; }

/* 空状态 / 提示 */
.gy-empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--text-3);
  font-size: 13px;
  text-align: center;
}
.gy-empty .ico { font-size: 30px; opacity: .6; }
.gy-empty-hint { font-size: 11.5px; max-width: 420px; line-height: 1.7; }
.gy-tip {
  flex: 0 0 auto;
  font-size: 11.5px;
  color: #a8762f;
  background: rgba(201, 165, 74, .12);
  border: 1px solid rgba(201, 165, 74, .3);
  border-radius: 8px;
  padding: 6px 10px;
}
[data-theme='night'] .gy-tip { color: #d8b45c; }

/* 窄屏：地图和地点榜改成上下 */
@media (max-width: 900px) {
  .gy-body { grid-template-columns: 1fr; grid-template-rows: minmax(180px, 1fr) auto; }
  .gy-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   日迹 · 三个页（日程 / 行程 / 日记）
   --------------------------------------------------------------------------
   2026-09-26：行程和日程原来是**上下叠着**的两张卡（行程要滚到底才看到），
   而它们其实是同级的两个视角 —— 甘特图回答"时间花在哪了"，
   行程回答"人跑到哪了"。现在改成同级的三页，并加一页 Markdown 日记。
   页签用的是项目统一的 `.segment` 控件（待办、记账、日程内部那三档都一样）。
   【2026-10-02】用户说「日迹 也增加标题，统一UI」，并选了"加页头标题 +
   页签也挪到页头右上角"那一版 —— 于是页签从 .fl-main 的直接子节点
   搬进了 .page-head .page-tools（和记账 / 待办 / 灵感一致）。
   ========================================================================== */
/* 【对齐值必须跟着父级方向一起改】
   父级从 .fl-main（**纵向** flex 栏）换成了 .page-tools（**横向** flex 行），
   跨轴方向跟着换了：
     · 原来的 align-self: flex-start 是让 .segment 在纵栏里别被拉成整行宽；
       现在跨轴成了纵向，flex-start 会把页签顶到那一行的上沿，
       和左边的标题不在一条中线上 —— 改成 center。
     · margin: 0 2px 是当年在 .fl-main 里单独微调的；现在间距由
       .page-head / .page-tools 自己的 gap 负责，留着那 2px 只会让它偏。 */
.fl-pages {
  flex: 0 0 auto;
  align-self: center;
  margin: 0;
}

/* 每一页是一个普通容器，显示/隐藏用 hidden 属性。
   【为什么用 hidden，而不是"只把当前页建出来"】
   日程内部那三档（日/周/月）和行程的状态都要保住 —— 你停在周视图，
   切到行程再切回来还该是周视图。整块重建会把状态丢掉。
   顺带也让 `.fl-gantt` 一直是同一块 DOM，
   那条"日/周/月尺寸一致"的断言才不会被切页影响。 */
.fl-page[hidden] { display: none; }

/* ------------------------------ 日记页 ------------------------------ */

.dm-diary {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius, 14px);
  padding: 14px;
  /* 【让日记和日程两张"大卡"一样高，切页时不跳】
     .fl-gantt 的总高实测 **630px**（内容 560 + 标题栏 + 上下内边距 + 边框）。
     日记也是"整页大卡"，所以直接对齐那个数。
     这里的 630 是**量出来的**，不是猜的：check:daymark-diary 里有一条断言
     要求两者相差不超过 4px —— 将来日程那张卡的高度要是变了，
     那条断言会红，提醒把这个数字一起改掉，而不是悄悄错位。
     行程那张卡**故意不跟** —— 它就是一张短列表（没有行程时只有 140px 左右），
     硬撑到 630 会留一大片空白。 */
  height: 630px;
  min-height: 0;
}
.fd-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}
.fd-date { display: flex; align-items: baseline; gap: 8px; }
.fd-date b { font-size: 14px; }
.fd-hint { font-size: 11.5px; color: var(--text-3); }
.fd-ops { display: flex; align-items: center; gap: 8px; }
.fd-status {
  font-size: 11.5px;
  color: var(--text-3);
  min-width: 96px;
  text-align: right;
}
.fd-status.ok { color: var(--brand, #48ab93); }
.fd-status.warn { color: #a8762f; }
.fd-status.err { color: var(--red, #b4483f); }

.fd-title {
  flex: 0 0 auto;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--text-1);
  outline: none;
}
.fd-title:focus { border-color: var(--brand, #48ab93); }

/* ------------------------------ 格式工具栏 ------------------------------
 * 类似飞书文档那一排：段落样式 / 加粗 / 斜体 / 下划线 / 删除线 / 代码 /
 * 颜色 / 填充 / 列表 / 序号 / 引用 / 清除格式。
 * 行为在 app/scripts/diary-wysiwyg.js：它直接在 contenteditable 上改富文本，
 * 库里存的仍然是 Markdown（进出编辑器时序列化，见那个文件）。
 * 【2026-10-01】双栏预览删掉之后，同一排按钮由那一套独占；
 * 以前这里写着"行为在 diary-toolbar.js"（那套是往 textarea 插 `**` 的），
 * 那个文件和它的检查一起删了。
 */
.dt-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 3px;
  flex-wrap: wrap;
  padding: 5px 6px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}
.dt-btn {
  font: inherit;
  font-size: 12.5px;
  line-height: 1;
  min-width: 28px;
  height: 26px;
  padding: 0 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.dt-btn:hover { background: var(--surface-3); color: var(--text-1); }
/* 当前生效的格式：按钮亮起来（不然用户不知道这一段是不是标题） */
.dt-btn.on {
  background: var(--surface);
  border-color: var(--line-strong, #d8cfc4);
  color: var(--text-1);
  font-weight: 600;
  box-shadow: var(--shadow-xs);
}
.dt-b { font-weight: 700; }
.dt-i { font-style: italic; }
.dt-u { text-decoration: underline; }
.dt-s { text-decoration: line-through; }
.dt-code { font-family: ui-monospace, Menlo, Consolas, monospace; }
/* 「正文 ▾」那颗宽一点，它还要显示当前是几级标题 */
.dt-wide { min-width: 68px; justify-content: flex-start; }
/* 文字颜色那颗：底下一条彩色杠，提示它是干嘛的 */
.dt-color { font-weight: 700; border-bottom: 2px solid #c0392b; border-radius: 7px 7px 4px 4px; }
.dt-fill { font-size: 13px; }
.dt-sep {
  width: 1px;
  height: 16px;
  background: var(--line);
  margin: 0 3px;
  flex: none;
}

/* 弹出层（颜色 / 填充 / 段落样式） */
.dt-pop {
  position: fixed;
  z-index: 60;
  background: var(--surface);
  border: 1px solid var(--line-strong, #d8cfc4);
  border-radius: 11px;
  box-shadow: 0 10px 28px -14px rgba(0, 0, 0, .35);
  padding: 7px;
}
/* 【弹出层里面也是一列 + 一个 gap】
   2026-09-27 样式体检发现 .dt-pop-in 一直没有规则：标题和下面那格颜色/样式
   原来是靠 .dt-pop-title 自己的 padding-bottom 撑开的 ——
   换了内容（颜色格 / 段落列表）间距就不一样。
   现在统一：里面的容器自己排，标题那一格的底部 padding 交给 gap。 */
.dt-pop-in {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.dt-pop-title { font-size: 11px; color: var(--text-3); padding: 2px 4px 0; }
.dt-swatches { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.dt-sw {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  border: 1px solid var(--line);
  cursor: pointer;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  color: var(--text-2);
}
.dt-sw:hover { border-color: var(--brand, #48ab93); }

/* 段落样式菜单 */
.dt-menu { display: flex; flex-direction: column; min-width: 210px; }
.dt-mi {
  display: flex;
  align-items: baseline;
  gap: 8px;
  text-align: left;
  border: 0;
  background: transparent;
  border-radius: 7px;
  padding: 6px 8px;
  cursor: pointer;
  color: var(--text-1);
  font: inherit;
}
.dt-mi:hover { background: var(--surface-3); }
.dt-mi-label { flex: 0 0 auto; }
.dt-mi-note { font-size: 11px; color: var(--text-3); }
/* 菜单里每一档用对应的字号，选之前就看得出大小 */
.dt-mi-h1 .dt-mi-label { font-size: 17px; font-weight: 650; }
.dt-mi-h2 .dt-mi-label { font-size: 15.5px; font-weight: 650; }
.dt-mi-h3 .dt-mi-label { font-size: 14px; font-weight: 650; }
.dt-mi-h4 .dt-mi-label { font-size: 13px; font-weight: 600; }
.dt-mi-h5 .dt-mi-label { font-size: 12.5px; font-weight: 600; }
.dt-mi-h6 .dt-mi-label { font-size: 12px; font-weight: 600; color: var(--text-2); }

/* --------------------- 颜色 / 填充的实际效果 ---------------------
 * 渲染器（md.js）把 {color:red} 变成 md-c-red 这类**类名**，样式在这里定义。
 * 只认下面这几个类名 —— 所以日记原文里写什么颜色都注入不了 CSS
 * （这就是当初选"颜色名"而不是"#十六进制"的原因）。
 */
.md-c-red { color: #c0392b; }
.md-c-orange { color: #d35400; }
.md-c-yellow { color: #b7950b; }
.md-c-green { color: #1e8449; }
.md-c-blue { color: #2471a3; }
.md-c-purple { color: #7d3c98; }
.md-c-gray { color: var(--text-3); }
/* 工具栏调色板上的小色块 */
.dt-sw-color-red { color: #c0392b; }
.dt-sw-color-orange { color: #d35400; }
.dt-sw-color-yellow { color: #b7950b; }
.dt-sw-color-green { color: #1e8449; }
.dt-sw-color-blue { color: #2471a3; }
.dt-sw-color-purple { color: #7d3c98; }
.dt-sw-color-gray { color: var(--text-3); }

.md-f-yellow { background: rgba(241, 196, 15, .35); }
.md-f-green { background: rgba(88, 214, 141, .32); }
.md-f-blue { background: rgba(133, 193, 233, .38); }
.md-f-pink { background: rgba(241, 148, 182, .32); }
.md-f-gray { background: var(--surface-3); }
.dt-sw-fill-yellow { background: rgba(241, 196, 15, .55); }
.dt-sw-fill-green { background: rgba(88, 214, 141, .5); }
.dt-sw-fill-blue { background: rgba(133, 193, 233, .55); }
.dt-sw-fill-pink { background: rgba(241, 148, 182, .5); }
.dt-sw-fill-gray { background: var(--surface-3); }

/* 深色主题下这几个颜色要提亮，否则在深底上糊成一片 */
[data-theme='night'] .md-c-red { color: #e8776b; }
[data-theme='night'] .md-c-orange { color: #e8965a; }
[data-theme='night'] .md-c-yellow { color: #dcb84a; }
[data-theme='night'] .md-c-green { color: #61c48a; }
[data-theme='night'] .md-c-blue { color: #6fb0dd; }
[data-theme='night'] .md-c-purple { color: #b98ad4; }

/* --------------------- 日记：所见即所得的单框编辑器 ---------------------
 * 用户的原话：「日记只能编辑和预览分开吗？不能共用同一个编辑框？」
 * 现在（2026-10-01 起）**就只有这一个框**（.fd-wys，contenteditable），
 * 看到的是加粗、标题的真样子；原来那套"左写右看"的双栏连它那个
 * textarea（.fd-edit）、预览框（.fd-preview）、左右两个 .fd-pane 一起删了。
 *
 * 行为在 app/scripts/diary-wysiwyg.js，那里有"为什么库里仍然存 Markdown"。
 * 这里只管长相：块级样式直接吃 .md-body 那一套（和列表摘要用的是同一份规则），
 * 所以"编辑时看到的"和"存下来再看"长得一样 —— 这也正是「所见即所得」的意思。
 */
.fd-wys {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 12px;
  outline: none;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text-1);
  caret-color: var(--brand, #48ab93);
  word-break: break-word;
}
.fd-wys:focus { border-color: var(--brand, #48ab93); }
/* 【占位文字用 CSS 的 :empty::before，不要往 DOM 里塞东西】
   塞一个真的占位段落的话，序列化时就得记得把它排除掉 ——
   而"清空日记"正是靠"序列化出来是空"来触发服务端删除的，
   多一个会被漏掉的节点就是数据事故。CSS 这份不参与序列化，最安全。
   （光标进去之后 :empty 不成立，占位自然消失。）
   第二条 `:has(> p:only-child)` 照顾"点完清空"那一屏 ——
   编辑器里剩下一个只带零宽空格的空段落，DOM 已经不是 :empty 了，
   可是对用户来说仍然是"一个字都没有"，那时也该看见占位提示。
   （`:has` 在现代 Edge/Chromium 上都有；不支持也就是退回上面那一条，不影响功能。） */
.fd-wys:empty::before,
.fd-wys:has(> p:only-child:not(:has(*))):not(:focus)::before {
  content: attr(data-placeholder);
  color: var(--text-3);
  white-space: pre-wrap;
  pointer-events: none;
}
.fd-wys p { margin: 7px 0; }
.fd-wys > :first-child { margin-top: 0; }
/* 引用里的空行（序列化时会写成裸 `>`）在编辑区里也要看得见分隔 */
.fd-wys blockquote p { margin: 3px 0; }

/* 单框那一套的外层：工具栏在上、编辑区在下。
   【为什么要有这一层】
   日记这张卡的高度是写死的 630px，工具栏和编辑区得有个东西把它们
   按"工具栏固定、正文吃掉剩下的空间"排好。 */
.fd-wys-wrap {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ------------------------ 日记：全部日记（批量管理） ------------------------
 * 用户的要求：「日记没办法批量管理」。
 * 头上那个「写日记 / 全部日记」用的是页面里统一的 segment 控件（见 util.js），
 * 批量条用的是公共的 .batch-bar —— 这里只管列表本身长什么样。
 *
 * 【列表必须自己滚】
 * 这张卡的高度是 .dm-diary 上写死的 630px（要和日程那张大卡一样高，
 * 见上面那段说明和 check:daymark-diary 的断言）。日记几百篇的时候
 * 列表要是把卡片撑开，切页就会上下跳，所以滚动留给 .dm-diary-body。
 */
.fd-date > .segment { align-self: center; }

.fd-loading {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-3);
  font-size: 12.5px;
}

.dm-diary-list {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* 没进批量模式时这一层是空的，别让它占一个 8px 的缝 */
.dm-diary-bar:empty { display: none; }
.dm-diary-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.dm-diary-search {
  width: 176px;
  font: inherit;
  font-size: 12.5px;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-1);
  outline: none;
}
.dm-diary-search:focus { border-color: var(--brand, #48ab93); }

.dm-diary-rows { display: flex; flex-direction: column; gap: 6px; }
.dm-diary-li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.dm-diary-li:hover { border-color: var(--brand, #48ab93); }
/* 批量模式：勾中的那几篇整行高亮，一眼看出勾了哪几天 */
.dm-diary-li.picked { background: var(--brand-soft); border-color: var(--brand, #48ab93); }
.dm-diary-li > .pick { margin-top: 2px; }

.dl-main { flex: 1 1 auto; min-width: 0; }
.dl-top { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.dl-date { font-size: 13px; font-variant-numeric: tabular-nums; }
.dl-week { flex: none; font-size: 11px; color: var(--text-3); }
.dl-title {
  font-size: 12.5px;
  color: var(--text-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dl-priv {
  flex: none;
  font-size: 10.5px;
  color: var(--text-3);
  border: 1px solid var(--line-strong, #d8cfc4);
  border-radius: 5px;
  padding: 0 5px;
}
.dl-bottom {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 3px;
}
.dl-excerpt {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12px;
  color: var(--text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dl-chars { flex: none; font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.dm-diary-more { font-size: 11.5px; color: var(--text-3); text-align: center; padding: 6px 0; }

/* ------------------------ Markdown 正文样式 ------------------------
 * 渲染器在 app/scripts/md.js，这里只管它产出的标签怎么显示。
 * 颜色全部走主题变量，三个主题自动适配。
 */
.md-body { font-size: 13px; line-height: 1.8; color: var(--text-1); }
.md-body > :first-child { margin-top: 0; }
.md-body h1, .md-body h2, .md-body h3,
.md-body h4, .md-body h5, .md-body h6 {
  margin: 14px 0 6px;
  line-height: 1.35;
  font-weight: 650;
}
.md-body h1 { font-size: 19px; }
.md-body h2 { font-size: 16.5px; }
.md-body h3 { font-size: 14.5px; }
.md-body h4, .md-body h5, .md-body h6 { font-size: 13px; color: var(--text-2); }
.md-body p { margin: 7px 0; }
/* 【列表的圆点 / 序号必须在这里"再打开一次"】
 * app/styles/base.css 里有一条全局重置 `ul, ol { list-style: none }`
 * （那是给侧边栏、菜单那种"用 ul 排版但不是列表"的地方用的），
 * 而 .md-body 是**真的** Markdown 列表 —— 不把标记打开，用户点完
 * 「• 列表 / 1. 序号」左边什么都看不见（2026-10-01 用户报的
 * 「序号、列表 左边不显示点和序号」就是这个）。
 *
 * 【为什么用 list-style-type 而不是 list-style 简写】
 * 简写会顺手把 list-style-position / image 也重置掉；这里只想要"显示什么标记"。
 *
 * 【为什么标记颜色写 currentColor】
 * ::marker 默认吃的是元素自己的 color，也就是 .md-body 的 --text-1。
 * 显式写 currentColor 是为了把这条**意图**钉下来：标记和正文同色，
 * 换主题时跟着主题变，而不是被某条更具体的选择器染成别处。
 *
 * 【缩进为什么从 22px 调到 24px】
 * 标记本身要占掉一块宽度；开标记之后 22px 会让文字紧贴着圆点。
 * 24px 是开了标记之后文字起点和段落文字看起来仍然"一样齐"的值。
 *
 * 【影响面】.md-body 不止日记在用：灵感卡片正文（app/scripts/views/ideas.js
 * 的 .idea-text）也是它。这里只动列表的符号和缩进，块级间距 / 颜色一律不改，
 * 所以在灵感卡片上同样是"圆点回来了"，不会有别的变化。
 */
.md-body ul, .md-body ol { margin: 7px 0; padding-left: 24px; list-style-position: outside; }
.md-body ul { list-style-type: disc; }
.md-body ol { list-style-type: decimal; }
/* 嵌套两层用不同符号，不然"子项"和"父项"看起来是同一层 */
.md-body ul ul { list-style-type: circle; }
.md-body ul ul ul { list-style-type: square; }
/* 有序列表里嵌的无序项也当子层看待（md.js 两种都能渲染出来） */
.md-body ol ul { list-style-type: circle; }
.md-body ol ol { list-style-type: lower-alpha; }
.md-body li { margin: 3px 0; }
/* 标记和正文同色：换主题时圆点 / 序号跟着走，不写死颜色 */
.md-body li::marker { color: currentColor; }
/* 【子列表的缩进要小一点】
   外层已经占掉 24px，子层再占满就会把正文挤得很窄；
   18px 是"看得出是一层"和"别把字挤没了"之间的值。 */
.md-body li > ul, .md-body li > ol { margin: 3px 0; padding-left: 18px; }
.md-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--surface-3);
}
.md-body pre.md-code {
  margin: 8px 0;
  padding: 9px 11px;
  border-radius: 9px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  overflow-x: auto;
}
.md-body pre.md-code code { background: transparent; padding: 0; font-size: 12px; }
.md-body blockquote {
  margin: 8px 0;
  padding: 3px 0 3px 11px;
  border-left: 3px solid var(--line-strong, #d8cfc4);
  color: var(--text-2);
}
.md-body hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
.md-body a { color: var(--brand, #48ab93); text-decoration: underline; }
.md-body table { border-collapse: collapse; margin: 8px 0; font-size: 12.5px; }
.md-body th, .md-body td { border: 1px solid var(--line); padding: 4px 9px; text-align: left; }
.md-body th { background: var(--surface-2); font-weight: 600; }
.md-body del { color: var(--text-3); }
/* 【2026-10-01 删掉的那条媒体查询】
   原来是 `@media (max-width: 900px) { .fd-split { grid-template-columns: 1fr; … } }`
   —— 窄屏时把双栏那个 grid 改成上下堆叠。双栏没了，这条规则也就没有对象了。 */
