diff --git a/app/helpers.php b/app/helpers.php
index 96617b9..375bfd7 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -431,18 +431,36 @@ function fb_entry_json(array $ev, string $detail = '', string $edit = '', array
$evOwn = ($evKind === 'custom' && $evRef > 0);
$evW = !empty($ev['_can_write']); // 由调用方按日历权限给出(见模板)
+ /* 🔴🔴 v93(用户 2026-10-25):「编辑重复日历时,也会有这三个选项
+ (修改当前 / 修改从现在到以后 / 修改全部)」
+ —— 浮层里的编辑表单要能给出这三档,就必须知道**打开的是哪一次**:
+ `calendar/event` 路由从 `?d=YYYY-MM-DD` 读它(`index.php` 里的 `$occ`),
+ `templates/calendar/event.php` 再据此输出那三档单选。
+ 而浮层的 `edit` 地址原来是 `url('calendar/event', ['id'=>…, 'embed'=>1])` ——
+ **没带 d** ⇒ 表单里只显示"改全部",另外两档连出现都不出现,
+ 用户会以为"重复日程不能只改这一次"(实测就是这样)。
+ ⚠️ 只在 `source='event'`(自定义日程)且 occ 是合法日期时追加:
+ 观影 / 旅程 / 任务 / 纪念日这些派生条目没有"第几次"的概念。
+ ⚠️ 是否加 `&` 按 `$edit` 里有没有 `?` 判 —— `url()` 生成的一定带,
+ 但别赌(换一处调用方就会静默拼出 `?id=1&embed=1d=2026-10-25` 这种废地址)。 */
+ $editUrl = $edit;
+ $occDay = (string)($ev['occ'] ?? '');
+ if ($evOwn && $editUrl !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $occDay)) {
+ $editUrl .= (strpos($editUrl, '?') === false ? '?' : '&') . 'd=' . rawurlencode($occDay);
+ }
+
$payload = [
'title' => trim((string)($ev['title'] ?? '')),
'rows' => $rows,
'detail' => $detail,
- 'edit' => $edit,
+ 'edit' => $editUrl,
// 新增(v49)
'source' => $evOwn ? 'event' : 'derived',
'ref' => $evOwn ? $evRef : 0, // 日程 id(前端删/改要按它定位,别从 URL 里抠)
'del' => ($evOwn && $evW) ? url('calendar/event_del') : '',
'info' => $evOwn ? url('calendar/event', ['id' => $evRef, 'embed' => 'detail']) : '',
'repeat' => (string)($ev['repeat'] ?? '') !== '',
- 'occ' => (string)($ev['occ'] ?? ''),
+ 'occ' => $occDay,
/* 🔴 v78(用户 2026-10-22):**就地面板**的地址。
首页「近期任务」点开时不再只给一行行只读信息,而是直接给出这张
面板(状态 / 看板 / 子任务 / 附件 / 评论 都能就地改),用户不必离开首页。
diff --git a/assets/css/app.css b/assets/css/app.css
index d64ceb8..cdb3bd3 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -5415,7 +5415,21 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
③ **加上下边距**,让标题与正文之间出现明确的段落呼吸。
⚠️ 为什么从 h4 起而不是 h1/h2:见 `Markdown::render()` 里的说明 ——
h1/h2 留给页面本身,笔记里的标题不许盖过页面标题。
- 所以这里必须把 **h4/h5/h6 这三级**都调大,光调 h4 不够。 */
+ 所以这里必须把 **h4/h5/h6 这三级**都调大,光调 h4 不够。
+
+ 🔴🔴 v93(2026-10-25,全量套件抓出来的**上一版没做完的地方**):
+ 上一版只把 h4(`##`)做到 17px,**h5(`###`)留在 15.5px、h6 留在 14.5px**
+ —— 15.5 只比正文 15 大 0.5px,肉眼仍是"和正文一样";h6 更是**比正文还小**。
+ 而上面这段注释自己写的是"三级都要调大、要拉开 ≥2px",实现违背了自己的规则。
+ ⇒ 阶梯整体重排,**最小的一级也必须 ≥ 正文 + 2px**:
+ h3 `#` → 22px
+ h4 `##` → 20px
+ h5 `###` → 18px
+ h6 `####`起(Markdown 里 h4 及更深都收敛到 h6)→ 17px,另配 --muted 灰
+ 四级字号**两两不同**(A9d 守的就是"同级同号、异级不同号"),
+ 且 h6 靠灰色与字号双重区分 —— 否则 `####` 与正文挤在一起。
+ ⚠️ 正文基准是 `.note-read-block { font-size: 15px }`(见下面那条规则)。
+ 将来正文若改号,这里的四级要**一起**复核,别只改 h4。 */
.md-h {
margin: 16px 0 8px;
font-weight: 600;
@@ -5423,10 +5437,10 @@ button.btn, a.btn, summary.btn, .seg-btn, .icon-btn, .rv-act-btn, .cs-btn, .bf-b
line-height: 1.45;
}
.md-h:first-child { margin-top: 0; }
-h3.md-h { font-size: 18px; }
-h4.md-h { font-size: 17px; }
-h5.md-h { font-size: 15.5px; }
-h6.md-h { font-size: 14.5px; color: var(--muted); }
+h3.md-h { font-size: 22px; }
+h4.md-h { font-size: 20px; }
+h5.md-h { font-size: 18px; }
+h6.md-h { font-size: 17px; color: var(--muted); }
.md-list { margin: 4px 0 8px; padding-left: 22px; }
.md-li { margin: 2px 0; }
/* 多级清单:子层用空心点,层级一眼可分(用户第 12 条"清单可以多级") */
diff --git a/assets/js/cs_picker.js b/assets/js/cs_picker.js
new file mode 100644
index 0000000..0abd69a
--- /dev/null
+++ b/assets/js/cs_picker.js
@@ -0,0 +1,163 @@
+/* ============================================================================
+ 通用「色点下拉」(`.cs`)—— 全站一份
+ ----------------------------------------------------------------------------
+ 起源 v44(用户 2026-10-12 第 1 条):「新建日程,放在哪本,改成日历本后面加冒号。
+ 现在这句话和日历本下拉框还有前面的颜色,仍然不在一行,我建议把颜色放在下拉框里面,
+ 就跟电影的影院选择一样」。当时那段交互是**内联在 templates/calendar/index.php**
+ 里的,只服务日程页那一个 `#calPicker`。
+
+ 🔴🔴 v93(用户 2026-10-25):
+ 「如果新建日程,日历本是拉不下来的,是空的,好像只有一个"工作"什么的。」
+ 真根因:首页「今天的日程」卡片右上角的「新建日程」,用的是**与日程页同一份**
+ 模板块(`templates/calendar/_add_modal.php`),HTML 一模一样 ⇒ 日历本那颗
+ 按钮和菜单都在页面上;可**交互全在日程页的内联脚本里**,首页没有那一段
+ ⇒ 按钮点了没反应、菜单永远 `hidden`。用户看到的就是"拉不下来";
+ 而按钮上那个默认值(「工作」)是服务端渲染出来的,所以"只有一个工作"。
+
+ ⇒ 把那段交互抽成这一份,**按标记初始化**(`[data-cs-picker]`):
+ 不认具体 id、不认哪个页面 —— 谁 require 了模板块谁就能用。
+
+ 契约(模板只需给容器加 `data-cs-picker`,其余全按类名找):
+
+
+
+ ⚠️ **只认 `[data-cs-picker]`,不扫所有 `.cs`**:观影表单里的影院下拉
+ (`templates/movies/form.php` 的 `#csBtn`)有它自己的一套内联脚本,
+ 两边都绑 = 点一次开两次、关两次(`add_modal.js` 头部记着同一个坑)。
+ ⚠️ 幂等闸门 `data-cs-ready`:AJAX 换进来的表单(浮层里点「编辑」)要能被
+ 重复初始化,但同一个容器绝不能被绑两遍。
+ ⚠️ 列表项**从 `