/* index.css — page-specific styles for index.html (home / tabs) */

/* ── App footer ───────────────────────────────── */
.app-footer {
  text-align: center;
  padding: 20px 16px 80px;
  color: var(--text-secondary);
  font-size: 12px;
  border-top: 1px solid var(--border);
  margin-top: 24px;
  background: var(--bg);
}
/* UX-004：这三条实测 14px。**页脚长高几像素无害，所以让它们真的长大** ——
   相邻链接用负外边距扩会互相重叠，那把误触从「按不中」变成「按错」。 */
.app-footer a {
  color: var(--text-secondary); text-decoration: none;
  display: inline-block; min-height: 44px; line-height: 44px; padding: 0 6px;
}
/* RT-10451 AC2: footer-sub 对比度修复 — #aaa (≈2.6:1 on #F7F5F2) → #4B5563 (≈6.2:1) 满足 WCAG AA 小文本 4.5:1 */
.app-footer .footer-sub { font-size: 11px; color: #4B5563; margin-top: 4px; }
/* t-227：「+」出现的那一页（家长圈），页脚底边距让到 FAB 外环上沿再高 8px —— 以前滚到页底，
   「+」正压在「Contact us」上（闸 2 间距 0）：FAB 底 = 导航 + 20，高 54，外环 4 → 上沿离视口底 nav + 78。
   FAB 在 DOM 里排在页脚前面，所以用兄弟选择器只改这一页；别的页页脚不动。 */
.fab.show ~ .app-footer { padding-bottom: calc(var(--nav-height) + 20px + 54px + 4px + 8px + env(safe-area-inset-bottom, 0px)); }

/* RT-10451 AC5: Coming Up card padding 标准化 — 将 index.html 内联 style="padding:4px 16px" 提取为类 */
/* 2026-08 视觉定稿：容器透明，行内 .event-mini 各自成卡 */
.card.coming-up-card { padding: 0; background: transparent; box-shadow: none; }

/* ── Notice-history link ──────────────────────── */
.notice-history-link {
  text-align: right;
  margin: 4px 4px 12px;
}
.notice-history-link button {
  background: none;
  border: none;
  color: var(--primary);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  padding: 6px 4px;
  font-weight: 500;
}

/* ── Photo modal (index-only) ─────────────────── */
.photo-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.92);
  z-index: 500;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  /* T131：**这一层必须真的退出命中测试，光靠 opacity+pointer-events 不够。**
     shared.css:700 本来用 `display:none` 藏它；这条规则（index.css 后加载）把
     display 覆盖成了 flex，改用 opacity 藏 —— 于是它变成一层**永远铺满全屏、
     看不见、z-index 500** 的东西。父级的 pointer-events:none 本可以救，
     **但 shared.css:728 的 `.photo-modal-back { pointer-events: auto }` 又把它打开了**
     （那条在 display 隐藏的世界里是对的：藏着的时候整棵树都不参与命中）。
     结果：每一屏**左上角**的点击都被这颗看不见的返回键吃掉 ——
     用户报的「详情页左上角返回箭头无效」就是它，而两处详情的按钮本身都是好的。
     `visibility: hidden` 让整棵子树退出命中，子元素的 pointer-events 也救不回来；
     它可以参与 transition，所以淡入淡出不受影响。 */
  visibility: hidden;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.photo-modal.show { opacity: 1; pointer-events: all; visibility: visible; }
.photo-modal-topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  padding: 12px 16px;
  z-index: 10;
}
.photo-modal-back {
  background: rgba(255,255,255,0.15);
  border: none;
  color: white;
  padding: 7px 14px;
  border-radius: 20px;
  font-size: 15px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 4px;
}
.photo-modal-back-arrow { font-size: 22px; line-height: 1; }
.photo-modal-counter {
  /* 右上角让给了下载与「⋯」（2026-09-28），计数挪到顶栏正中 */
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 22px);
  left: 50%; right: auto; transform: translateX(-50%);
  color: rgba(255,255,255,0.7);
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  transition: opacity var(--t-base);
}
.photo-modal-counter.show { opacity: 1; }
.photo-modal-content {
  /* 2026-09-28 反馈 (3)(a)：要能放大。原来是 min(90vw,440px) × min(72vw,360px) 的一个小框，
     在 390 宽的手机上照片只有 351×280 —— 放大也只能在这个小框里放大。
     现在占满顶栏与底部提示之间的整块，放大后的平移也在这一块里裁切（overflow: hidden）。
     `touch-action: none`：捏合、双击、平移、左右翻页全部由 tab-photos.js 的指针事件接管，
     不让浏览器先把整页放大了（那样查看器的按钮会被放出屏幕）。 */
  width: 100%; max-width: 960px;
  height: calc(100dvh - 150px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  aspect-ratio: auto;
  overflow: hidden;
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 60px;
  user-select: none; -webkit-user-select: none;
  touch-action: none;
  transition: transform 0.08s linear;
  will-change: transform;
}
.photo-modal-content.dragging { transition: none; }
.photo-modal-hint {
  position: absolute;
  bottom: 24px;
  color: rgba(255,255,255,0.45);
  font-size: 12px;
}
.photo-modal-edge-hint {
  position: absolute;
  bottom: 52px;
  background: rgba(255,255,255,0.18);
  color: white;
  padding: 6px 16px;
  border-radius: 20px;
  font-size: 13px;
  opacity: 0;
  transition: opacity var(--t-base);
  pointer-events: none;
}
.photo-modal-edge-hint.show { opacity: 1; }

/* ── 查看器右上角：下载 · ⋯（2026-09-28 反馈 (2)(3)）────────────────────────
   **低调**：和 Back 同一种半透明深底白字，不是红旗、不是主按钮。
   举报在「⋯」里面 —— 需要的时候找得到，平时不抢照片。 */
.photo-modal-tools {
  margin-left: auto; position: relative;
  display: flex; align-items: center; gap: 8px;
  pointer-events: auto;
}
.photo-tool {
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); color: #fff; border: none; padding: 0;
  font-size: 22px; line-height: 1; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.photo-tool[hidden] { display: none; }
.photo-tool svg { width: 20px; height: 20px; }
.photo-tool:active { background: rgba(0,0,0,0.75); }
.photo-tool[aria-busy="true"] { opacity: .6; }
.photo-more-menu {
  position: absolute; top: 52px; right: 0; min-width: 210px;
  background: var(--card); color: var(--text);
  border-radius: var(--radius-note); box-shadow: var(--shadow-pop);
  padding: 6px; z-index: 12;
}
.photo-more-menu[hidden] { display: none; }
.photo-more-menu button {
  display: block; width: 100%; min-height: 44px; padding: 10px 12px;
  background: none; border: none; border-radius: var(--radius-sm);
  font: inherit; font-size: 15px; font-weight: 500; color: var(--text);
  text-align: left; cursor: pointer;
}
.photo-more-menu button[hidden] { display: none; }
.photo-more-menu button:hover, .photo-more-menu button:focus-visible { background: var(--hairline); }

/* 举报之后那一行安静的状态：「You reported this photo · Undo」 */
.photo-modal-status {
  /* 左右都钉住再 margin auto —— 用 left:50% + translateX 的话，收缩宽度只按右半屏算，一句话折成三行 */
  position: absolute; left: 0; right: 0; margin: 0 auto;
  width: max-content; max-width: calc(100% - 32px); box-sizing: border-box;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 44px);
  display: flex; align-items: center; gap: 4px;
  background: rgba(0,0,0,0.6); color: rgba(255,255,255,0.9);
  border-radius: var(--radius-btn); padding: 0 6px 0 14px;
  font-size: 13px; z-index: 3;
}
.photo-modal-status[hidden] { display: none; }
.photo-status-undo {
  min-height: 44px; padding: 0 10px; background: none; border: none;
  color: #fff; font: inherit; font-weight: 700; text-decoration: underline; cursor: pointer;
}


/* 举报前的确认层（反馈 (2)(a)：点错了不能直接发出去）。收起时退出命中与读屏树，同 .photo-modal */
.photo-sheet {
  position: absolute; inset: 0; z-index: 20;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(0,0,0,0.45);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.photo-sheet.show { opacity: 1; visibility: visible; pointer-events: auto; }
.photo-sheet-card {
  width: 100%; max-width: 480px;
  background: var(--card); color: var(--text);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  padding: 20px 16px calc(env(safe-area-inset-bottom, 0px) + 16px);
  box-shadow: var(--shadow-xl);
}
.photo-sheet-card h3 { font-family: var(--font-display); font-size: 18px; margin: 0 0 4px; }
.prs-lead { font-size: 14px; color: var(--text-body); margin: 0 0 12px; }
.prs-choice {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px; margin-bottom: 8px; cursor: pointer;
  border: 1.5px solid var(--border); border-radius: var(--radius-sm);
}
.prs-choice:has(input:checked) { border-color: var(--primary); background: var(--primary-light); }
.prs-choice input { margin-top: 3px; accent-color: var(--primary); width: 18px; height: 18px; flex: none; }
.prs-choice strong { display: block; font-size: 15px; font-weight: 600; }
.prs-choice strong + span { display: block; font-size: 13px; color: var(--text-secondary); margin-top: 2px; }
#prs-note {
  width: 100%; box-sizing: border-box; margin: 4px 0 12px; padding: 10px 12px;
  font: inherit; font-size: 14px; color: var(--text);
  border: 1.5px solid var(--border); border-radius: var(--radius-sm); resize: vertical;
}
.prs-actions { display: flex; gap: 8px; }
.prs-actions .btn-cancel { flex: 1; }
.prs-actions .btn-post { flex: 2; }

/* 相册下面那一行：被我的安全举报藏起来的照片 —— 关掉查看器之后撤回走这里 */
.album-my-hidden {
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
  font-size: 13px; color: var(--text-secondary); margin-top: 8px;
}
.album-my-hidden button {
  min-height: 44px; padding: 0 8px; background: none; border: none;
  font: inherit; font-weight: 700; color: var(--primary); text-decoration: underline; cursor: pointer;
}

/* ── New-post modal ───────────────────────────── */
.modal-overlay {
  position: fixed;
  inset: 0;
  /* **`inset: 0` 在 iOS Safari 上量的是「大视口」**（地址栏收起时的那个高度），
     不是当下看得见的那块。这一层又是**底部对齐**的，于是这张纸贴着大视口的底，
     它的**顶**就顶到了地址栏后面 —— 用户 2026-09-08 报的
     「进了帖子看不见页头，也看不到返回上一页的按键」就是这么来的：
     顶栏在，只露出下半行，上半截被地址栏切掉了。
     `dvh` 跟着可见视口伸缩，正是为这件事造的。老浏览器读不懂就忽略这一行，
     退回上面 `inset: 0` 的老行为 —— 不会更坏。
     **桌面 Chromium 复现不出来，因为它没有那条会伸缩的地址栏** —— 我的探针
     跑了三遍全绿，是用户的截图把它照出来的。 */
  height: 100dvh;
  background: rgba(0,0,0,0.5);
  z-index: 400;
  display: flex;
  align-items: flex-end;
  /* T164 / BUG-039：**只靠 opacity:0 收起，它仍然在 Tab 顺序和读屏树里** ——
     键盘和读屏器用户会走进一个看不见的弹层里迷路，家长端每一屏都有 9 颗。
     `visibility: hidden` 同时拿掉这两样，而把 visibility 放进 transition
     可以让它**在淡出结束时才生效**，淡入淡出一点不丢。
     这不是新做法：`.photo-modal` / `.post-detail-overlay` 早就是这么写的，
     index.css:448 那条注释还写着「新写的层从第一天就带上」——
     **这三层是漏网的，不是例外。** */
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.modal-overlay.show { opacity: 1; pointer-events: all; visibility: visible; }
.modal-sheet {
  background: var(--card);
  border-radius: 20px 20px 0 0;
  padding: 20px 20px 32px;
  width: 100%;
  max-height: 90vh;
  max-height: 90dvh;          /* 同上：`vh` 是大视口，`dvh` 是看得见的那块 */
  overflow-y: auto;
  padding-bottom: max(32px, env(safe-area-inset-bottom));   /* 底部横条不压住 Close */
  transform: translateY(100%);
  transition: transform var(--t-slow) cubic-bezier(.32,1,.31,1);
}
.modal-overlay.show .modal-sheet { transform: translateY(0); }

/* 通知详情的常驻顶栏（T036）：滚到哪儿都能一步退出。与 Circle 的
   .post-detail-topbar 同一套视觉，两处详情不该长得不一样。 */
/* 弹层自己的上内边距交给顶栏：留着的话 sticky 会钉在内边距**下沿**，
   正文会从上面那 20px 的缝里滚过去，顶栏上方露出半行字。 */
#school-detail-modal .modal-sheet { padding-top: 0; }
/* UIV-03 §3.2：半屏白纸 → **整屏**（画板 SchoolItem）。同一个 DOM、同一条打开 / 关闭的路径，
   只改这一张纸：高 100dvh、圆角 0、纸底 --bg（白交给 .sd-card）、左右内边距 20 → 16。
   其余纸（家长圈详情等）不动 —— 它们归各自的 UIV 表。 */
#school-detail-modal .modal-sheet {
  background: var(--bg); border-radius: 0;
  height: 100dvh; max-height: none;
  padding-left: 16px; padding-right: 16px;
  /* 纸不再随内容收缩：短帖的时候吸底答题栏会停在屏幕半中间（sticky 只在滚得动时才贴底）。
     纵向 flex + 答题栏 margin-top: auto，把它（连同住在里面的 Close）推到纸底 —— 长帖照旧滚动、照旧贴底。 */
  display: flex; flex-direction: column;
}
#school-detail-modal .modal-sheet > * { flex-shrink: 0; }
#school-detail-modal #sd-answer:not([hidden]) { margin-top: auto; }
/* 有答题栏时，纸的底内边距（给 Close 躲开底部横条的那 32 / safe-area）交给白栏自己
   （它的 padding-bottom 本来就含这一段）：否则没吸住的时候（短帖，或长帖滚到底）
   白栏停在这段内边距的上沿，底下露一截米绿。纸底没了内边距，吸底的偏移也回到 0。 */
#school-detail-modal .modal-sheet:has(> #sd-answer:not([hidden])) { padding-bottom: 0; }
#school-detail-modal .modal-sheet:has(> #sd-answer:not([hidden])) > #sd-answer { bottom: 0; }
/* 清单层级那一行（T054 ①②）：整张清单共有的东西在这儿说一次，行里就不再重复。
   它比行文字略小一号 —— 它是这张清单的条件，不是其中一项。 */
/* 举报没送出去时那条**不会自己走**的提示（BUG-020）。
   toast 会消失，而这句话的用处恰恰在几秒之后：她要知道刚才那下不算数。
   红底白字，压在那张照片上，重新载入相册或下一次举报成功才清掉。 */
.photo-report-failed {
  /* **它自己不能挡住重试。** 这条提示说的正是「请再试一次」，而它盖在照片上；
     图片没加载出来时槽位很矮，它会正好压住右上角那颗举报按钮 ——
     **一条劝人重试的提示挡住了重试用的按钮**，这就是界面自己和自己打架。
     它纯粹是给人看的，永远不需要接收点击。 */
  pointer-events: none;
  position: absolute; left: 6px; right: 6px; bottom: 6px; z-index: 3;
  background: var(--danger, #C24E42); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1.35;
  padding: 6px 8px; border-radius: 8px;
}

.sd-todo-common {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 0 0 8px; font-size: 12px;
}
.sd-todo-common[hidden] { display: none; }
.sd-todo-common .stc-verb {
  font-size: 13px; font-weight: 700; color: var(--text);
}
.sd-todo-common .stc-verb::after { content: ':'; }

.sd-topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px;
  margin: 0 -16px 16px;                  /* 左右抵掉内边距（16），铺满整宽 */
  /* UIV-03 表二：换成首页头部那一套 —— 深绿底、底两角 24、白字（画板 SchoolItem）。
     原来那条 1px 下边线是白顶栏和白正文之间的分界；深绿底自己就分得开，
     留着它会横穿两个圆角（画板没有，design 09-11 同意去掉）。 */
  padding: 18px 20px 20px;
  background: var(--primary-deep); color: white;
  border-radius: 0 0 var(--radius-header) var(--radius-header);
}
.sd-topbar .sd-back-btn {
  background: none; border: none; font-size: 24px; line-height: 1;
  color: white; cursor: pointer; flex-shrink: 0;
  /* **可点区域 44×44**（T054 ④ / PD-0033 ⑦）。用户说「看不到返回键」，QA 一量：
     它在，但只有 17×24 —— 一个 ‹ 字符本身的大小。**不是缺失，是够不着。**
     iOS HIG 要求 44×44，Material 要求 48×48；照小的那个来，因为这是手机上的一颗
     退出键，够不着的后果是她被困在一屏里。
     负外边距把这 44 收回去，顶栏高度不变——放大的是手指够得着的范围，不是版面。 */
  /* UIV-03：字形「‹」换成画板的 SVG 折角（20 · 笔宽 2.2）。44 − 20 = 24，四边各收 12，
     看得见的折角正好落在顶栏内边距（20）的位置上，和画板一样。 */
  min-width: 44px; min-height: 44px; margin: -12px;
  display: flex; align-items: center; justify-content: center;
}
.sd-topbar .sd-back-btn svg { width: 20px; height: 20px; display: block; }
.sd-topbar-title {
  font-family: var(--font-display); font-size: 19px; font-weight: 800; letter-spacing: -0.2px;
  color: inherit;                        /* 白：同首页头部标题 */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;   /* 长标题截断，不换行撑高 */
}
.modal-sheet h3 { font-size: 17px; font-weight: 700; margin-bottom: 14px; }

/* UIV-03 表四：内容卡 —— 包住「已更新」→ 头像行 → 标题 → 摘要 → 正文 → 字段 */
.sd-card {
  background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 16px; margin-bottom: 12px;
}
.sd-card > :last-child { margin-bottom: 0; }   /* 卡的下内边距就是 16，最后一块自己的下边距不再叠上去 */
/* 头像行：原来 #sd-meta 那一行字（作者 · 日期 · 类型）拆成画板的样子。
   容器保留 .sd-meta 的 12px · 次级色（表二那三格按它量），名字自己加粗、换 --text。 */
.sd-author { display: flex; align-items: center; gap: 10px; }
.sd-author .sd-avatar {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary); color: #fff;          /* 白压 --primary 7.9 */
  font-size: 13px; font-weight: 700;
}
.sd-author .sd-author-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sd-author .sd-author-name { font-size: 13.5px; font-weight: 700; color: var(--text); }
.sd-author .sd-author-when { font-size: 12px; font-weight: 400; color: var(--text-secondary); }
/* 类型胶囊：颜色跟列表里同一种类型的标签（.notice-type-tag.t-*）走；这里只改形状。
   签字那一种照画板那一枚暖橙字（压 --tag-warning-bg 4.48，PD-0072 v2 · S-019 §4，进闸 8 豁免表）。
   **只签字**：「回应」画板上没有值，按 PD-0072 v2「画板没值的格照旧按闸 8 判」留 --tag-warning-fg（design 09-11）。 */
.sd-author .sd-type-pill {
  flex-shrink: 0; font-size: 11px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
}
.sd-author .sd-type-pill.t-sign { color: var(--accent-text); }

/* ── 出席区 #sd-attend（PD-0084 ① · t-253 · S-023 §1）──
   住在吸底答题栏 #sd-answer 里，attend 时替换「要 / 不要」那两颗的问法（两颗键本身沿用 .sd-ans-btn）。
   每一处借的都是既有规矩：勾选框 = t-224 矩阵那套（看得见 24，点得到整行 ≥44）· 名字 15/600 同 #sd-title 家族 ·
   关系 12.5 同 .sd-author-when · 「Someone else」是输入框（S-022 §1 ② 进闸 1，自己 44）· 那句话用 --tag-warning-bg / --radius-note。 */
.sd-attend[hidden] { display: none; }
.sd-attend .at-title { font-size: 13px; font-weight: 700; color: var(--text); margin: 0 0 6px; }
.sd-attend .at-kids .at-title { margin-top: 10px; }
.sd-attend .at-row { display: flex; align-items: center; gap: 12px; min-height: 44px; cursor: pointer; margin: 0; }
.sd-attend .at-box {
  -webkit-appearance: none; appearance: none; margin: 0; padding: 0; flex-shrink: 0;   /* padding 0：盖掉 .modal-sheet input 的 10/12，否则 24 的框被撑宽 */
  width: 24px; height: 24px; border-radius: 8px;
  background: var(--card) center / 13px 13px no-repeat;
  border: 1.5px solid var(--text-secondary);
  cursor: pointer;
}
/* 选中 = 选了什么内容（深绿，照 t-224）；答案键的橙是「提交了哪个答案」—— 同屏两种选中色各管一件事（S-023 §6 ③）。
   `.on` 与 :checked 同步（JS 每次 change 打上），给 qa 的表一个能查的选择器。 */
.sd-attend .at-box:checked, .sd-attend .at-box.on {
  background-color: var(--primary); border-color: var(--primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
@media (forced-colors: active) { .sd-attend .at-box { -webkit-appearance: auto; appearance: auto; } }
.sd-attend .at-name { font-size: 15px; font-weight: 600; color: var(--text); min-width: 0; }
.sd-attend .at-rel { font-size: 12.5px; font-weight: 400; color: var(--text-secondary); margin-left: 6px; }
/* 「Someone else」不放勾选框，整行就是输入框；左缘与上面几行的名字对齐（36 = 框 24 + 间距 12）。写了名字即算勾上。 */
.sd-attend .at-else { display: flex; align-items: center; min-height: 44px; padding-left: 36px; }
.sd-attend .at-else input {
  flex: 1; min-width: 0; min-height: 44px; box-sizing: border-box;
  border: 1.5px solid var(--border); border-radius: 10px; padding: 0 12px;
  font: inherit; font-size: 14.5px; color: var(--text); background: var(--card);
}
.sd-attend .at-else input::placeholder { color: var(--text-placeholder-field); opacity: 1; }
.sd-attend .at-note { background: var(--tag-warning-bg); border-radius: var(--radius-note); padding: 12px; font-size: 13.5px; line-height: 1.5; color: var(--text-body); margin: 0 0 12px; }
.sd-attend .at-error { font-size: 13px; font-weight: 600; color: var(--danger); margin: 8px 0 0; }
.sd-attend .at-error[hidden] { display: none; }
.sd-attend .at-kids { margin-bottom: 4px; }
/* 大标题：画板的展示字体 19 / 1.3 */
#sd-title { font-family: var(--font-display); font-size: 19px; line-height: 1.3; margin-bottom: 9px; }
.modal-hint { font-size: 13px; color: var(--text-secondary); margin-bottom: 12px; }
.modal-sheet label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin: 12px 0 4px;
  color: var(--text);
}
.modal-sheet input, .modal-sheet textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  font-size: 14px;
  font-family: inherit;
  outline: none;
  color: var(--text);
  background: var(--bg);
}
.modal-sheet input:focus, .modal-sheet textarea:focus { border-color: var(--primary); }
.modal-sheet textarea { min-height: 72px; resize: vertical; }
.required-asterisk { color: var(--danger); margin-left: 2px; }

/* ── UIV-07 表二 / 表三 · 发帖纸（画板 CircleCompose） ──
   纸底换 --bg：画板的白胶囊、白框是落在米绿底上的；纸还是白的话，去掉边框的白胶囊就看不见了
   （同 UIV-03 §3.2 把详情纸换 --bg）。 */
#new-post-modal .modal-sheet { background: var(--bg); }
/* 字段标签 14 / 700 · 下距 9（Title / Body / 模板字段同一条）；「类型」那一行是分组标签：小号大写（i18n 串不改） */
#new-post-modal label { font-size: 14px; font-weight: 700; margin-bottom: 9px; }
#new-post-modal label:has(+ .type-chips) {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; color: var(--text-secondary);
}
/* 类型胶囊：白底无边、12.5 · 9 / 14；选中换头部同色 --primary-deep（白字 11.39） */
#new-post-modal .type-chip { background: var(--card); border: 0; padding: 9px 14px; font-size: 12.5px; }
#new-post-modal .type-chip.active { background: var(--primary-deep); color: #fff; font-weight: 700; }
/* 输入框：纸底换成 --bg 以后框自己要白（画板的框落在白卡上；线上没有白卡），12 圆角。
   正文框的字号 / 行高 / 上内边距按表二改。占位字照画板（2.44，PD-0072 v2 · S-019 §4，进闸 8 豁免表） */
#new-post-modal input[type="text"], #new-post-modal textarea, #new-post-modal select {
  background: var(--card); border-radius: var(--radius-sm);
}
#post-message { padding-top: 12px; font-size: 13.5px; line-height: 1.5; }
/* opacity：Firefox 给占位字默认 .54，不写就不是这个色 */
#post-message::placeholder, #post-title::placeholder { color: var(--text-placeholder); opacity: 1; }

.segment-tabs {
  display: flex;
  background: var(--bg);
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
  margin-bottom: 10px;
}
.segment-tab {
  flex: 1;
  padding: 8px;
  border: none;
  background: transparent;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  color: var(--text-secondary);
  transition: background var(--t-fast), color var(--t-fast);
}
.segment-tab.active { background: var(--card); color: var(--primary); box-shadow: 0 1px 4px rgba(0,0,0,0.1); }

.post-more { display: none; }
.post-more.show { display: block; }

.type-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.type-chip {
  padding: 6px 12px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  font-size: 13px;
  cursor: pointer;
  background: white;
  color: var(--text-secondary);
  font-family: inherit;
}
.type-chip.active { background: var(--primary); color: white; border-color: var(--primary); }

.template-collapsed-row {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg);
  border-radius: 10px;
  cursor: pointer;
  font-size: 13.5px;
  margin-bottom: 8px;
}
.template-collapsed-row.show { display: flex; }
.template-collapsed-row .label { color: var(--text-secondary); }
.template-collapsed-row .current-type { font-weight: 600; flex: 1; }
.template-collapsed-row .expand-hint { color: var(--primary); font-size: 12px; }

.template-field { margin-bottom: 8px; }

.image-upload-btn {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 10px;
  background: var(--bg);
  border: 1.5px dashed var(--border);
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--text-secondary);
  cursor: pointer;
  font-family: inherit;
}
.image-thumb-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.image-thumb {
  width: 56px; height: 56px;
  border-radius: 10px;
  position: relative;
  display: flex; align-items: center; justify-content: center;
}
.remove-thumb {
  position: absolute; top: -6px; right: -6px;
  width: 18px; height: 18px;
  background: var(--danger); color: white;
  border: none; border-radius: 50%;
  font-size: 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
}

.visibility-note {
  font-size: 12.5px;
  color: var(--text-secondary);
  background: #F0F7F2;
  border-radius: 8px;
  padding: 8px 10px;
  margin-top: 10px;
  line-height: 1.5;
}
.publish-rules-link {
  /* UX-004：22px */
  min-height: 44px; padding: 10px 0;
  display: block;
  background: none;
  border: none;
  color: var(--primary);
  font-size: 12.5px;
  cursor: pointer;
  padding: 6px 0;
  font-family: inherit;
}
.post-required-counter {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--danger);
  margin-top: 6px;
  min-height: 22px;
}
.post-required-counter.complete { color: var(--success); }
.prc-list { color: var(--text-secondary); font-size: 11.5px; }

.modal-btns { display: flex; gap: 10px; margin-top: 16px; }
/* **同一族的第二份本体**，而且它和 shared.css 里那份不一样：
   这一份没有 `min-height`，于是家长端那两颗比老师端矮
   （族里定的是 48 / 44）。index.css 在 shared.css 之后加载，赢的是这一份。

   **两份本体就是下一次漂移的种子** —— 这里只留布局那两行，
   长相全部回到 shared.css 的那一份。 */
.modal-btns .btn-cancel { flex: 1; }
.modal-btns .btn-post { flex: 2; }

.preselect-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--primary-light);
  color: var(--primary);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12.5px;
  font-weight: 600;
  margin-bottom: 10px;
}
.clear-preselect {
  background: none; border: none;
  color: var(--primary); cursor: pointer;
  font-size: 14px; padding: 0 2px; line-height: 1;
}

/* ── Publishing rules popover ─────────────────── */
.publish-rules-popover {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* T164 / BUG-039：**只靠 opacity:0 收起，它仍然在 Tab 顺序和读屏树里** ——
     键盘和读屏器用户会走进一个看不见的弹层里迷路，家长端每一屏都有 9 颗。
     `visibility: hidden` 同时拿掉这两样，而把 visibility 放进 transition
     可以让它**在淡出结束时才生效**，淡入淡出一点不丢。
     这不是新做法：`.photo-modal` / `.post-detail-overlay` 早就是这么写的，
     index.css:448 那条注释还写着「新写的层从第一天就带上」——
     **这三层是漏网的，不是例外。** */
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.publish-rules-popover.show { opacity: 1; pointer-events: all; visibility: visible; }
.popover-card {
  background: var(--card);
  border-radius: 16px;
  padding: 20px;
  width: 100%;
  max-width: 360px;
}
.popover-card h4 { margin-bottom: 12px; }
.popover-card ul { padding-left: 0; list-style: none; }
.popover-card li { padding: 5px 0; font-size: 13.5px; color: var(--text); }
.popover-card li.no { color: var(--danger); }
.timing-note { font-size: 12px; color: var(--text-secondary); margin-top: 10px; }
.popover-close {
  display: block; width: 100%;
  margin-top: 14px;
  padding: 11px;
  background: var(--primary);
  color: white;
  border: none;
  /* 这一颗是那一屏上唯一的主行动，而它是全站第四种圆角（实测 8/10 两份，
     index.css 这一份赢）。并进族里那一个。 */
  border-radius: var(--radius-btn);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  min-height: 44px;
}

/* ── Post-detail overlay ──────────────────────── */
/* T137：和 `.modal-overlay` / `.modal-sheet` 同一种壳 —— 底部纸滑上来，
   不再是整屏从右滑入。**两处详情不该长得不一样**（index.css 里本来就写着这句，
   T036 那一版是让学校那层追上 Circle 的顶栏；这一次是反过来，让 Circle 追上壳）。
   `dvh` 与 `visibility` 两条是 T134 / T131 的结论，**新写的层从第一天就带上**，
   不要等它在某个人的手机上坏一次再补。 */
.post-detail-overlay {
  position: fixed;
  inset: 0;
  height: 100dvh;
  background: rgba(0,0,0,0.5);
  z-index: 450;
  display: flex;
  align-items: flex-end;
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.post-detail-overlay.show { opacity: 1; pointer-events: all; visibility: visible; }
.post-detail-sheet {
  background: var(--card);
  border-radius: 20px 20px 0 0;
  width: 100%;
  max-height: 90vh;
  max-height: 90dvh;
  overflow-y: auto;
  /* 上内边距交给顶栏 —— 留着的话 sticky 会钉在内边距**下沿**，
     正文从上面那条缝里滚过去（`#school-detail-modal .modal-sheet` 同一条注释）。 */
  padding: 0 20px max(32px, env(safe-area-inset-bottom));
  transform: translateY(100%);
  transition: transform var(--t-slow) cubic-bezier(.32,1,.31,1);
}
.post-detail-overlay.show .post-detail-sheet { transform: translateY(0); }
/* UIV-03 的壳同样套在这里（T137：用户要两处详情「体验是一样的」；
   verify-circle-detail-matches-school.py 量顶栏高度，差 4px 以上就红）。
   **只动壳** —— 整屏、纸底 --bg、左右 16、深绿顶栏；帖子内容本身留给 UIV-14
   （UIV-07 残留一：「与 UIV-03 的详情纸是同一类纸，按 §3.2 外推」）。
   数值和 `#school-detail-modal .modal-sheet` / `.sd-topbar` 逐条相同，守卫逐条对。 */
.post-detail-sheet {
  background: var(--bg); border-radius: 0;
  height: 100dvh; max-height: none;
  padding-left: 16px; padding-right: 16px;
}
.post-detail-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 -16px 16px;                  /* 左右抵掉内边距（16），铺满整宽（同 .sd-topbar）*/
  padding: 18px 20px 20px;
  background: var(--primary-deep); color: white;
  border-radius: 0 0 var(--radius-header) var(--radius-header);
  position: sticky;
  top: 0;
  z-index: 10;
}
.post-detail-topbar .back-btn {
  background: none; border: none;
  font-size: 24px; cursor: pointer;
  color: white;
  /* 同 `.sd-back-btn`：可点区域 44×44。这一颗和那一颗是同一种东西，
     **一起改，否则下一次量到的就是这一颗** —— 两处详情不该长得不一样，
     也不该只有一处够得着。 */
  min-width: 44px; min-height: 44px; margin: -12px;          /* 同 .sd-back-btn：20px 折角，四边各收 12 */
  display: flex; align-items: center; justify-content: center;
}
.post-detail-topbar .back-btn svg { width: 20px; height: 20px; display: block; }
/* 内容卡：与 .sd-card 逐值相同（守卫逐条对）—— 两处详情的白卡是同一张 */
.pd-card {
  background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 16px; margin-bottom: 12px;
}
.pd-card > :last-child { margin-bottom: 0; }
.post-detail-topbar .title {
  font-family: var(--font-display); font-size: 19px; font-weight: 800; letter-spacing: -0.2px;
  color: inherit;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;   /* 同 .sd-topbar-title */
}
/* meta 行：和 `.sd-meta` 同一组数（12px · 次级色 · 下边距 12），
   只是多承载一个头像和分类标签 —— 见 index.html 那段注释里为什么留着它们。 */
.pd-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--text-secondary); margin-bottom: 12px;
}
.pd-meta .avatar { width: 28px; height: 28px; font-size: 12px; }
/* ── UIV-07 表一 · 家长圈信息流（画板 CircleList） ── */
#circle-list .community-card { border-radius: var(--radius-card); margin-bottom: 10px; }
#circle-list .community-card .community-header { gap: 10px; margin-bottom: 10px; }
#circle-list .community-card .avatar { font-size: 14px; }
#circle-list .community-card .post-title { line-height: 1.35; margin-bottom: 6px; }
/* 受众条（UIV-07 表六 · PD-0093）：米绿底落在白卡上，作者行之下、标题之上；不可点（D-003：不占动作槽位）。
   锁与字同色 --text-body（页头那枚锁是 --on-dark-muted，两处不是一枚）；只有名字加重。10 的圆角与 UIV-08 那三处同一条待拍板的 --radius-*。 */
#circle-list .community-card .post-audience { display: flex; align-items: center; column-gap: 7px; background: var(--bg); border-radius: 10px; padding: 8px 11px; margin-bottom: 11px; }
#circle-list .community-card .post-audience svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--text-body); }
#circle-list .community-card .post-audience span { font-size: 12px; font-weight: 600; color: var(--text-body); min-width: 0; }
#circle-list .community-card .post-audience strong { font-weight: 700; }
#circle-list .community-card .community-body { font-size: 13.5px; color: var(--text-body); margin-bottom: 12px; }
/* 表一 · 页头副标题只在家长圈这一页加粗、前面一枚锁（表四）—— index.js 切 tab 时给头部写 data-tab */
/* 字加粗后这句在 390 宽下会折成两行 —— 锁对齐第一行，不悬在两行中间 */
.app-header[data-tab="community"] #header-tab-sub { font-weight: 600; display: flex; align-items: flex-start; gap: 5px; }
#header-tab-sub svg { width: 13px; height: 13px; flex-shrink: 0; margin-top: 2px; stroke: var(--on-dark-muted); stroke-width: 2.2; fill: none; }
.post-detail-status-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 0 12px;
  font-size: 13px;
  color: var(--text-secondary);
}
.post-status-pill {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
}
.post-status-pill.published { background: #D1FAE5; color: #065F46; }
.post-status-pill.pending { background: #FEF3C7; color: #92400E; }
.post-status-pill.rejected { background: #FEE2E2; color: #991B1B; }
.post-detail-body { padding: 0 0 4px; }   /* 内边距归纸张所有，不再自己留一份 */
.post-detail-card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 12px;
  box-shadow: var(--shadow);
}
.post-detail-image-row {
  position: relative;
  margin-top: 10px;
  border-radius: 12px;
  overflow: hidden;
}
.post-detail-image-row .scroll-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: 12px;
}
.post-detail-image-row .scroll-track::-webkit-scrollbar { display: none; }
.post-detail-image-row .img-cell {
  min-width: 100%;
  height: 200px;
  scroll-snap-align: start;
  display: flex; align-items: center; justify-content: center;
  font-size: 36px;
}
.post-detail-image-row .page-counter {
  position: absolute; right: 10px; bottom: 10px;
  background: rgba(0,0,0,0.55); color: white;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  pointer-events: none;
}
.first-reply-preview {
  background: var(--card);
  border-radius: 12px;
  padding: 12px 14px;
  margin-top: 12px;
}
.first-reply-preview .reply-label {
  font-size: 11.5px; color: var(--text-secondary);
  font-weight: 600; margin-bottom: 8px;
}
.first-reply-preview .reply-row { display: flex; gap: 10px; align-items: flex-start; }
.first-reply-preview .reply-content { flex: 1; font-size: 13px; line-height: 1.5; }
.first-reply-preview .reply-name { font-weight: 600; margin-bottom: 2px; }
.first-reply-preview .reply-time { font-weight: 400; color: var(--text-secondary); font-size: 11.5px; margin-left: 6px; }
.first-reply-preview .view-all-btn {
  display: block; width: 100%;
  margin-top: 10px;
  background: none; border: 1px solid var(--border);
  color: var(--primary); padding: 8px;
  border-radius: 8px; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.first-reply-preview .empty-reply { font-size: 12.5px; color: var(--text-secondary); text-align: center; padding: 6px 0; }

/* ── My-posts: pending / rejected / approved states ─ */
.review-status-bar {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--text-secondary);
  padding-top: 8px;
}
.review-only-self { font-size: 11.5px; color: var(--text-secondary); margin-top: 4px; }
.pending-badge {
  background: #FEF3C7; color: #92400E;
  border-radius: 999px; padding: 2px 8px;
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.rejection-banner {
  background: #FEE2E2; border-radius: 10px;
  padding: 10px 12px; margin-top: 8px; font-size: 13px;
}
.rejection-banner .reason-row { margin-top: 4px; color: var(--text-secondary); }
.rejection-banner .label { font-weight: 600; color: var(--text); }
.btn-edit-republish {
  display: inline-block; margin-top: 8px;
  padding: 7px 14px;
  background: var(--danger); color: white;
  border: none; border-radius: 8px;
  font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit;
}

/* ── Tab onboarding overlay ───────────────────── */
.tab-onboard-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 700;
  /* T164 / BUG-039：**只靠 opacity:0 收起，它仍然在 Tab 顺序和读屏树里** ——
     键盘和读屏器用户会走进一个看不见的弹层里迷路，家长端每一屏都有 9 颗。
     `visibility: hidden` 同时拿掉这两样，而把 visibility 放进 transition
     可以让它**在淡出结束时才生效**，淡入淡出一点不丢。
     这不是新做法：`.photo-modal` / `.post-detail-overlay` 早就是这么写的，
     index.css:448 那条注释还写着「新写的层从第一天就带上」——
     **这三层是漏网的，不是例外。** */
  visibility: hidden;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t-base), visibility var(--t-base);
}
.tab-onboard-overlay.show { opacity: 1; pointer-events: all; visibility: visible; }
.tab-onboard-tooltip {
  position: fixed;
  z-index: 701;
  background: var(--card);
  border-radius: 14px;
  padding: 14px 16px 12px;
  width: 220px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.18);
  font-size: 13.5px;
}
.tab-onboard-tooltip::after {
  content: '';
  position: absolute; bottom: -8px;
  left: var(--arrow-x, 50%);
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 8px solid var(--card);
}
.tt-step { font-size: 11px; color: var(--text-secondary); margin-bottom: 4px; }
.tt-title { font-weight: 700; margin-bottom: 4px; }
.tt-body { color: var(--text-secondary); line-height: 1.45; margin-bottom: 10px; }
.tt-actions { display: flex; justify-content: space-between; align-items: center; }
/* UX-004：Skip 22px 高、36px 宽 —— **判据是 44×44，两个方向都要量** */
.tt-skip { background: none; border: none; color: var(--text-secondary); font-size: 13px; cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; }
.tt-next {
  background: var(--primary); color: white;
  border: none; border-radius: 8px;
  padding: 7px 14px; font-size: 13px; font-weight: 600;
  cursor: pointer; font-family: inherit;
}
.nav-item.onboard-spotlight { position: relative; z-index: 702; }

@media (min-width: 768px) {
  body { border-left: 1px solid var(--border); border-right: 1px solid var(--border); }
  .photo-grid { grid-template-columns: repeat(4, 1fr); }
}

/* ── 相册（真实数据）───────────────────────────────────────── */
.album-actions { margin-bottom: 12px; }
.album-block { margin-bottom: 18px; }   /* UIV-06：20 → 18 */
.album-block .photo-group-label { display: flex; align-items: center; gap: 8px; }
.album-add-btn {
  margin-left: 0; background: none;          /* 推到行尾的是权限胶囊（UIV-06），「+ Add」跟在它后面 */ border: none; color: var(--primary);
  font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit;
  /* **高够了、宽不够**（实测命中区 45×41.3）。UX-004 是 44×44 两个方向，
     而这一颗只补了高的那一半 —— 12px 的「+ Add」本来就窄。 */
  min-height: 44px; min-width: 44px; padding: 0 8px;
}
.album-block .photo-card { object-fit: cover; width: 100%; height: 100%; display: block; border-radius: var(--radius-note); }
/* UIV-06 表二：相册日期行 —— created_at（与校方列表同一个 shortDate）。「· n photos」是新文案，归 pd，没定之前只放日期 */
.album-block .album-meta { font-size: 12px; font-weight: 400; color: var(--text-secondary); margin: -4px 0 8px; }
.album-block video.photo-card { background: #000; }

/* 上传进度。转码是实时速度的，这一行必须一直在说话 */
.au-list { list-style: none; margin: 12px 0 0; padding: 0; }
.au-item {
  display: flex; gap: 10px; align-items: baseline;
  font-size: 13px; padding: 6px 0; border-bottom: 1px solid var(--border);
}
.au-item .au-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.au-item .au-state { color: var(--text-secondary); font-weight: 600; white-space: nowrap; }
.au-item.ok .au-state { color: var(--success); }
.au-item.failed .au-state { color: var(--danger); white-space: normal; text-align: right; }

/* 举报入口原来是每张缩略图右上角一颗 ⚑（T066 那颗 44×44 的小圆）。
   2026-09-28 产品负责人反馈 (2)：「太显眼了，不该在第一屏」—— 挪进单张查看器的「⋯」菜单里，
   样式见上面 .photo-modal-tools / .photo-more-menu。 */
.photo-slot { position: relative; }

/* ── 活动卡（真数据） ────────────────────────────── */
.event-card { cursor: pointer; }
/* S-010 §3.1：卡与日期面板里那一条换成了 <button> —— 外观归零，长得和以前的 div 一样
   （.card 自己没有边框，所以 border:0 只拿掉 UA 的按钮边）。卡高实测不动。 */
button.event-card, button.cal-detail-event {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  border: 0; cursor: pointer; -webkit-appearance: none; appearance: none;
}
/* 「我答过了吗」是家长在这一页唯一会问的问题 —— 没答的要看得出来。
   (0,2,0) 压得过上面的 button.event-card (0,1,1)，琥珀边不会被归零吃掉 */
.event-card.needs-reply { border: 1.5px solid #EFD9BE; }
/* UIV-05 表一（画板 CEvents）：卡上下内边距 16 → 14、卡间距 12 → 8（只改活动卡，.card 不动）；
   标题上距 0 —— 画板的 8 是给标题上面那颗类型胶囊留的，类型不做（无数据），留着就是卡顶一段空白（§3）。 */
#cal-list .event-card { position: relative; padding-top: 14px; padding-bottom: 14px; margin-bottom: 8px; }
#cal-list .event-card h4 { margin-top: 0; }
/* 表二：今天 / 明天的相对日期，和标题同一行、在右端（不占行）。
   design 写的是 absolute 右上角；这里用同一行的 flex —— 长标题会换行让开它，不会压在字上。
   颜色照画板那一枚暖橙字（PD-0072 v2；压白 5.12，这一格本身过，不进豁免表）。 */
.event-head { display: flex; align-items: baseline; gap: 8px; }
.event-head h4 { flex: 1; min-width: 0; }
.event-when { flex-shrink: 0; font-size: 12px; font-weight: 700; color: var(--accent-text); }
/* 地点并进时间那一行（「时间, 地点」），去掉 📍 */
.event-place { font-size: 13px; color: var(--text-secondary); }
/* 回应胶囊：画板卡内胶囊的尺寸 11px · 4 / 10（颜色仍是 S-010 那两对） */
.event-answered, .event-needs-reply {
  display: inline-block; margin-top: 8px;
  font-size: 11px; font-weight: 700; border-radius: 999px; padding: 4px 10px;
}
/* S-010 §3.3，照 S-008 那两对走：「Please reply」是这一屏唯一要她动手的 —— 琥珀底深字 12.16；
   「You replied」是做完了 —— 退成中性 5.32。以前两个都是写死的绿 / 黄，而「You replied: no」
   也是绿 —— 绿在这套 token 里是「好」，答「不去」配绿是错的意思。 */
.event-answered { background: var(--tag-neutral-bg); color: var(--tag-neutral-fg); }
.event-needs-reply { background: var(--tag-warning-bg); color: var(--text); }
.cal-detail-event { cursor: pointer; }
/* 活动列表里「New」角标（2026-10-02）：和底栏红点同一个橘色，挂在卡的左上角 */
#cal-list .event-card { position: relative; }
#cal-list .event-card .new-tag {
  position: absolute; top: -7px; left: 14px;
  background: var(--accent); color: var(--text);   /* 橙底配深色字：白字在这个橙上对比度不够（仓库的焦点 / 配色守卫） */
  font-size: 11px; font-weight: 800; letter-spacing: 0.2px; line-height: 1;
  padding: 4px 8px; border-radius: 999px; border: 2px solid var(--bg);
}

/* ── 作业：照片是主体 ─────────────────────────────────────
   老师真实的动作是拍一张黑板或那页题再补两句，所以照片排在标题上面、
   占满卡宽 —— 缩成一个小角标就等于把内容当成了附件。 */
.hw-photos { display: grid; gap: 6px; margin: -14px -14px 12px; }   /* 负边距跟着作业卡的内边距（UIV-04：14），照片仍贴满卡宽 */
.hw-photo {
  width: 100%; display: block; border-radius: var(--radius) var(--radius) 0 0;
  /* 竖构图的作业纸（3:4）在 430 宽下有 570 高，再高就把整屏占满了。
     contain 而不是 cover —— 裁掉一角的板书等于没拍。 */
  max-height: 65vh; object-fit: contain; background: #1a1a1a;
}
.hw-photos .hw-photo + .hw-photo { border-radius: 0; }

.hw-card { display: block; cursor: pointer; }
.hw-card:focus-visible { outline: 2px solid var(--primary-deep); outline-offset: 2px; }
/* 列表里的视频只是预览：不带控件（一碰就在卡里播，点卡进不了详情），#t=0.1 让 iPhone 画出第一帧
   而不是一块黑；上面盖一个播放标，告诉她这是视频、点开看。 */
.hw-vid { position: relative; }
.hw-vid .hw-photo { pointer-events: none; }
.hw-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 56px; height: 56px; border-radius: 50%; background: rgba(0,0,0,0.55);
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.hw-play svg { width: 24px; height: 24px; margin-left: 3px; fill: #fff; }
.hw-desc { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }

/* 作业详情：同 #school-detail-modal 那张整屏纸 */
#hw-detail-modal .modal-sheet {
  background: var(--bg); border-radius: 0; height: 100dvh; max-height: none;
  padding-top: 0; padding-left: 16px; padding-right: 16px;
}
.hwd-media { display: grid; gap: 8px; margin: -16px -16px 14px; }
.hwd-media:empty { display: none; }
.hwd-media img, .hwd-media video {
  width: 100%; display: block; max-height: 80vh; object-fit: contain; background: #1a1a1a;
}
.hwd-media > :first-child { border-radius: var(--radius-card) var(--radius-card) 0 0; }
#hwd-title { margin-bottom: 0; }
#hwd-due { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-top: 6px; }
.hwd-body { white-space: pre-wrap; font-size: 15px; line-height: 1.55; color: var(--text); margin-top: 10px; }
.hwd-body:empty { display: none; }
/* UIV-04：作业卡内边距 16 → 14、卡间距 12 → 8（画板 CHomework）。只改作业卡，通用 .card 不动；
   「更早的」折起来那几张是同一种卡，一起改。 */
#hw-list .hw-card { padding: 14px; margin-bottom: 8px; }
/* **没有 .is-overdue。** 一条过期而没打勾的作业和别的长得一样 ——
   把「还没弄」持续摆在家长眼前，是一台施压机器。这个勾只是「我看到了」。 */

/* 更早的作业默认折起来：一整学期铺在那儿，往下滑到的每一条都在提醒她 */
.hw-older { margin-top: 4px; }
.hw-older-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; min-height: 44px; padding: 10px 14px;
  background: transparent; border: none; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--text-secondary); cursor: pointer;
}
/* UIV-04：「更早的作业」的字换成画板的分组标题（展示字体 16 / 700 / --text）。
   只改这行字 —— 折叠键仍是整颗按钮，▼ 的大小和颜色不动。 */
.hw-older-head > span:first-child { font-family: var(--font-display); font-size: 16px; font-weight: 700; color: var(--text); }
.hw-older-body { display: none; }
.hw-older.open .hw-older-body { display: block; }
.hw-older.open .fold-indicator { transform: rotate(180deg); }
.hw-older .fold-indicator { transition: transform var(--t-fast); }


/* 老师端建作业时的上传进度 */
.hw-upload-status { font-size: 12.5px; color: var(--text-secondary); margin: 6px 0; }

/* ── 帖子摘要卡 ──────────────────────────────────── */
/* .sd-summary 那一族的本体挪去 shared.css —— T113：老师端要用**同一个**
   形状看「家长收到了什么」。两份本体就是下一次两边长得不一样的起点
   （T103/T104 已经证过）。 */


/* ── T088：列表先回答「哪条需要我做事」 ──
   五种 action_type 在这里塌成两档。**不是给五种各配一个小图** —— 那是一排看不懂
   的符号；这里要的是一条分界线：要她动手的抢注意力，做完之后让出来。 */
/* S-008 §2 待签：底收敛成 token 琥珀，字用 --text —— **6.14 → 12.16，比现在更高**。
   不直接换成 --tag-warning-fg（那是 5.39，**比现在低**）：D-004 ③ 说承载最要紧
   信息的那一行不许降，而这一个正是这一屏上最要她动手的那一个。

   **去掉边之后外框尺寸不变**（qa 验收 t-153 时指出规格没写清）：
       今天  padding 3px 9px + border 1px  → 外框每边 4px / 10px
       改为  padding 4px 10px，无边         → 同一个大小
   它比已签/必达（2px 8px）**故意大一圈** —— 上面那段注释写明的「要她动手的
   抢注意力」，去边不许把它顺带缩掉。边原本也不承担识别（旧边对白卡 1.42），
   标签的形状从来靠**底色 + 粗体**认。 */
.notice-todo-tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  background: var(--tag-warning-bg); color: var(--text);
}
/* UIV-03 §8 那枚 14px 小图标（.ntt-icon）在 PD-0078 ① 之后挪到了行首的 .ni-icon 块里（shared.css）—— 标签只留字。 */
/* 做完之后退成轻的 —— 它还在（她想确认自己办过），但不再抢眼睛 */
.notice-done-tag {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 999px;
  /* S-008 §2：**成对用**。拿 --text-secondary（一个通用文字色）去配 tag 的底
     只有 4.46（贴着门槛下沿）；换成配对的 --tag-neutral-fg 是 5.32。 */
  background: var(--tag-neutral-bg); color: var(--tag-neutral-fg);
}
.notice-done-tag::before { content: "\2713"; margin-right: 4px; }
/* 必达：行内说出来。**光一个红点是颜色单编码** —— 分不清红绿的人看到的是一个灰点。 */
.notice-urgent-tag {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  /* S-008 §2：**这一屏最要紧的标签，偏偏是唯一不过的那个** —— 用 --danger
     （一个独立强调色）去配 tag 的底只有 3.72；成对的 --tag-danger-fg 是 5.46。

     兜底一并删掉（D-006 A 类）：两个 token 都定义了，那对兜底**永远不会生效** ——
     而它们（#B42318/#FDECEC = 5.76）比真正在渲染的那一对（3.72）还好。
     **写这行的人知道一对过的色，token 把它盖掉了。** */
  background: var(--tag-danger-bg); color: var(--tag-danger-fg);
}

/* T162 / BUG-037：查看器里那张真照片。
   容器是定尺的（09-28 起是顶栏到底部提示之间的整块），所以图要**整张装进去**
   而不是被裁 —— 她点开是为了看清楚，不是为了看一个放大的局部。
   `contain` 而不是 `cover`：竖图横图都完整。 */
.photo-modal-media {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: 16px;
  display: block;
}
/* 放大（2026-09-28 反馈 (3)(a)）：变换落在图上，翻页的 translateX 仍落在外面那个框上，两者不打架。
   `pointer-events: none`：桌面上按住图拖会触发浏览器自带的「拖出一张图片」，抢走平移。 */
img.photo-modal-media {
  pointer-events: none; -webkit-user-drag: none;
  transform-origin: center center;
  transition: transform var(--t-base) ease-out;
}
img.photo-modal-media.no-anim { transition: none; }
/* 查看器开着时 toast 要浮在它上面（toast 300 < 查看器 500，原来举报成功那句是压在黑底后面的），
   并且让开底下那一行「You reported this photo · Undo」 */
body:has(#photo-modal.show) .toast { z-index: 510; bottom: calc(env(safe-area-inset-bottom, 0px) + 100px); }
/* 我的安全举报刚把它藏起来：屏上这张压暗、糊掉，和「Hidden · you reported it」那一行说的一致 */
.photo-modal-content.is-reported-hidden .photo-modal-media { opacity: .35; filter: blur(6px); }

/* S-011 §3.1：缩略图外面那颗按钮。
   它只负责「可聚焦、有名字、按得动」—— **看得见的仍然是那张图**，
   所以把按钮自己的外观全部清掉（无边框、无内外边距、无底色）。
   `border-radius` 跟着缩略图走：全局聚焦环那条规则是 8px，缩略图是 12。 */
button.photo-open {
  /* **每一条都是在关掉按钮的默认长相**，不是可选的美化：
     qa 21:41 指出的坏法 —— 图片 404 或带透明边时，按钮的默认底色/边框/内边距
     会**从图后面透出来**，而这时候盒子尺寸一点不变。也就是说
     「盒子一样」这个读数**看不见这种坏**。`appearance: none` 一并关掉，
     免得某些引擎还画一层原生外观。 */
  display: block; padding: 0; margin: 0; border: 0; background: none;
  appearance: none; -webkit-appearance: none;
  font: inherit; color: inherit; cursor: pointer; width: 100%;
  border-radius: var(--radius-note);        /* UIV-06：12 → 14，与缩略图（.album-block .photo-card）同一个 token */
}
button.photo-open > img.photo-card { display: block; }

/* ── 家长圈发帖「给谁」受众卡 + 「谁不该看到」那一页（S-026 · t-262 · 照画板 CircleCompose / ComposeAudience）──
   卡：白 · r18 · 16 内边距；**未选时 2px --accent 边 + `*`**（「这一格还要你答」的记号，不是装饰 —— 答完还留着等于一直在喊），
   选完退成 1px --hairline、`*` 消失。人行 54 高 r12（有效命中盒 ≥44）；范围行 = 既有的「谁能看到」摘要行搬进来，加 --tag-warning-bg 底。
   橙框 2.70（非文字 3.0 门槛）照 PD-0072 口径进豁免表（S-026 §4）。 */
#new-post-modal .np-audience { background: var(--card); border: 1px solid var(--hairline); border-radius: var(--radius-card); padding: 16px; margin-top: 12px; }
#new-post-modal .np-audience.is-unset { border: 2px solid var(--accent); }
#new-post-modal .np-head { display: flex; align-items: baseline; gap: 4px; margin-bottom: 4px; }
#new-post-modal .np-title { font-size: 14px; font-weight: 700; color: var(--text); }
#new-post-modal .np-required { color: var(--danger); font-weight: 700; }
#new-post-modal .np-audience:not(.is-unset) .np-required { display: none; }
#new-post-modal .np-desc { font-size: 12.5px; line-height: 1.45; color: var(--text-secondary); margin: 0 0 12px; }
#new-post-modal .np-person {
  display: flex; align-items: center; gap: 10px; width: 100%; height: 54px; box-sizing: border-box;
  background: var(--bg); border: none; border-radius: var(--radius-sm); padding: 10px 12px;
  font-family: inherit; text-align: left; color: var(--text); cursor: pointer;
}
#new-post-modal .np-person .np-av { width: 34px; height: 34px; border-radius: 50%; background: var(--primary); color: var(--on-accent); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; flex-shrink: 0; }
#new-post-modal .np-person .np-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#new-post-modal .np-person .np-name { font-size: 13.5px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#new-post-modal .np-person .np-role { font-size: 11.5px; font-weight: 400; color: var(--text-secondary); }
#new-post-modal .np-person .np-chev { width: 17px; height: 17px; color: var(--icon-muted); flex-shrink: 0; }
#new-post-modal .np-person .np-chev svg { width: 17px; height: 17px; }
#new-post-modal .np-audience .visibility-summary { margin-top: 12px; }
#new-post-modal .np-scope { background: var(--tag-warning-bg); }
/* 「谁不该看到」那一页：推入的一页（不是弹层叠弹层），盖住发帖层，返回即回去、输入不丢 */
.audience-page { position: fixed; inset: 0; z-index: 450; background: var(--bg); overflow-y: auto; max-width: 480px; margin: 0 auto; }
.audience-page[hidden] { display: none; }
.audience-page .ap-head { background: var(--primary-deep); color: #fff; padding: 16px 16px 20px; display: flex; align-items: center; gap: 8px; border-radius: 0 0 var(--radius-header) var(--radius-header); }
.audience-page .ap-back { width: 44px; height: 44px; border: none; border-radius: 999px; background: var(--on-dark-fill); color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }
.audience-page .ap-back svg { width: 22px; height: 22px; }
.audience-page .ap-head-text { min-width: 0; }
.audience-page .ap-title { font-family: var(--font-display); font-size: 19px; font-weight: 800; color: #fff; margin: 0; }
.audience-page .ap-sub { font-size: 12.5px; font-weight: 500; color: var(--on-dark-muted); margin: 2px 0 0; }
.audience-page .ap-body { padding: 16px 16px calc(24px + env(safe-area-inset-bottom, 0px)); }
.audience-page .ap-sec { font-size: 11.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-secondary); margin: 0 0 9px; }
.audience-page .ap-list { background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-md); overflow: hidden; margin-bottom: 8px; }
.audience-page .ap-empty { margin: 0; padding: 16px; font-size: 13px; color: var(--text-secondary); }
/* 选项行 68 高：38 图标块 r11（选中 --primary-light / 未选 --bg）+ 标题 14.5/700（选中 --text / 未选 --text-body）+ 副 12 + 右侧 22 圆（选中 --primary 实心白勾 / 未选 1.5px --border 空心） */
.audience-page .ap-opt { display: flex; align-items: center; gap: 12px; width: 100%; height: 68px; box-sizing: border-box; padding: 15px 16px; border: none; background: transparent; font-family: inherit; text-align: left; cursor: pointer; position: relative; }
.audience-page .ap-opt + .ap-opt::before { content: ''; position: absolute; left: 16px; right: 16px; top: 0; height: 1px; background: var(--divider); }
.audience-page .ap-opt .ap-ico { width: 38px; height: 38px; border-radius: 11px; background: var(--bg); color: var(--primary-deep); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; flex-shrink: 0; }
.audience-page .ap-opt.on .ap-ico { background: var(--primary-light); }
.audience-page .ap-opt .ap-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.audience-page .ap-opt .ap-t { font-size: 14.5px; font-weight: 700; color: var(--text-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audience-page .ap-opt.on .ap-t { color: var(--text); }
.audience-page .ap-opt .ap-s { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.audience-page .ap-opt .ap-check { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--border);   /* 画板原样式串是 2px（S-026 表二写 1.5 是抄错；1.5 在 1x 屏上算成 1px，qa run 156） */ box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--on-accent); }
.audience-page .ap-opt.on .ap-check { background: var(--primary); border-color: var(--primary); }
.audience-page .ap-opt .ap-check svg { width: 13px; height: 13px; }
.audience-page .ap-state { font-size: 13px; font-weight: 600; color: var(--text); margin: 8px 4px 14px; min-height: 1.4em; }
.audience-page .ap-note { display: flex; align-items: flex-start; gap: 8px; margin: 0; padding: 0 4px; font-size: 12px; line-height: 1.5; color: var(--text-disabled); }
.audience-page .ap-note svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; }
/* ── 家长通讯录（S-028 · t-270 · 画板没有这一页，值按体系里已有的同类元素取）──
   页壳借 .audience-page（同一条推入一页）；入口行 #dir-entry 是 shared.css 的 .cal-entry-row，这里一格不写。
   行卡 --card / --radius-card / --shadow-md · 名字 15/700 · 「Parent of …」13/500/--text-secondary · 联系方式 13.5/600/--primary、行高 44（可点的只有它）·
   「改我公开什么」13/700/--primary、44 · 当面话底框 --primary-light / 14 / 12 14 · 字 12.5/600/--primary-dark · 设置行 60 白卡 / --radius-sm、整行是 <label> · 勾选框 24 / 8 / 2px --text-secondary，选中 --primary。 */
#tab-community #dir-entry { margin: 16px 0 4px; }
.audience-page .dir-row { background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-md); padding: 14px; margin-bottom: 10px; }
.audience-page .dir-name { font-size: 15px; font-weight: 700; color: var(--text); }
.audience-page .dir-of { font-size: 13px; font-weight: 500; color: var(--text-secondary); margin-top: 2px; }
.audience-page .dir-contact { display: flex; align-items: center; min-height: 44px; font-size: 13.5px; font-weight: 600; color: var(--primary); text-decoration: none; }
.audience-page .dir-mine-edit { display: inline-flex; align-items: center; min-height: 44px; padding: 0; border: 0; background: none; font-family: inherit; font-size: 13px; font-weight: 700; color: var(--primary); cursor: pointer; }
.audience-page .dir-empty { margin: 4px 0 0; }
.audience-page .dir-note { display: flex; align-items: flex-start; gap: 8px; background: var(--primary-light); border-radius: 14px; padding: 12px 14px; margin: 0 0 16px; }
.audience-page .dir-note .icon { flex-shrink: 0; color: var(--primary-dark); display: inline-flex; margin-top: 2px; }
.audience-page .dir-note .icon svg { width: 14px; height: 14px; }
.audience-page .dir-note .text { font-size: 12.5px; line-height: 1.5; font-weight: 600; color: var(--primary-dark); }
.audience-page .dir-opt { display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 0 14px; margin-bottom: 10px; background: var(--card); border-radius: var(--radius-sm); cursor: pointer; }
.audience-page .dir-opt .dir-opt-text { flex: 1; font-size: 14px; font-weight: 600; color: var(--text); }
.audience-page .dir-box { width: 24px; height: 24px; margin: 0; flex-shrink: 0; appearance: none; -webkit-appearance: none; border: 2px solid var(--text-secondary); border-radius: 8px; background: var(--card); position: relative; }
.audience-page .dir-box:checked { background: var(--primary); border-color: var(--primary); }
.audience-page .dir-box:checked::after { content: ''; position: absolute; left: 7px; top: 3px; width: 5px; height: 10px; border: solid var(--on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.audience-page .dir-box:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* ── 校方列表分段（S-025 · t-261 · 照画板 SchoolList，IA 用户 09-13 定）──
   段一「需要你签字」置顶大卡 + 段二「来自老师」白卡一行一条（行式样不动，PD-0078 ① 压画板：只 sign / respond 有块）。
   段标题 11.5 / 700 / 字距大写；段一 --accent-text（4.66）· 段二 --text-secondary；计数徽章白压 --accent 2.70 照稿豁免（PD-0072 批）。 */
#tab-school .sl-sec-title { font-size: 11.5px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase; display: flex; align-items: center; gap: 8px; margin: 0 0 8px; padding: 0 4px; }
#tab-school .sl-sec-sign .sl-sec-title { color: var(--accent-text); }
#tab-school .sl-sec-from .sl-sec-title { color: var(--text-secondary); margin-top: 18px; }
#tab-school .sl-sec-sign .sl-count { background: var(--accent); color: var(--on-accent); border-radius: 999px; font-size: 10.5px; font-weight: 700; padding: 2px 9px; letter-spacing: 0; }
/* 置顶大卡：画板 358×177 · --tag-warning-bg 底 · r18；整卡可点进详情，按钮是卡内独立目标 */
#tab-school .sl-pin { background: var(--tag-warning-bg); border-radius: var(--radius-card); padding: 16px; margin-bottom: 8px; cursor: pointer; }
#tab-school .sl-pin-head { display: flex; gap: 12px; align-items: flex-start; }
#tab-school .sl-pin-text { min-width: 0; }
/* 图标块 40 · --accent 实心 · r12 · 20 白笔 —— S-025 §4 例外：它是「要你动手」的最强形态，与「每类配一个装饰小图」不是一回事 */
#tab-school .sl-pin .sl-pin-icon { width: 40px; height: 40px; border-radius: var(--radius-sm); background: var(--accent); color: var(--on-accent); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
#tab-school .sl-pin .sl-pin-icon svg { width: 20px; height: 20px; }
#tab-school .sl-pin .sl-pin-title { font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.3; }
#tab-school .sl-pin .sl-pin-sub { font-size: 12px; font-weight: 600; color: var(--accent-text); margin-top: 2px; }   /* 压 --tag-warning-bg 4.48 照稿豁免（S-019 §2 同一对） */
#tab-school .sl-pin .sl-pin-body { font-size: 13.5px; line-height: 1.5; color: var(--text-body); margin: 10px 0 12px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 按钮 326×40 · --primary · r999 · 13.5/700 白字；本体 40 → 有效命中盒 44 靠 ::after 绝对高度 + 居中（S-022 §4.1，不给相对外扩） */
#tab-school .sl-pin .sl-pin-btn { position: relative; display: flex; align-items: center; justify-content: center; width: 100%; height: 40px; border: none; border-radius: var(--radius-btn); background: var(--primary); color: var(--on-accent); font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; }
#tab-school .sl-pin .sl-pin-btn::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
/* 月分组只在段二里，且当月那一组不出月标题（S-025 §3）—— 标题从第二个月起才是路标 */
#tab-school .notice-month-section.is-current .notice-month-header { display: none; }

/* ── 入口页（UIV-15 · PD-0086 · t-259）──
   画板 RolePick 的视觉语言，内容按 PD-0086 拆成「入口」：绿实底、两张白卡（两条登录路）、提示条、页脚。
   逐值照 UIV-15 表一：底 --primary-deep · 大字 26/800/白 · 副标题 14/--on-dark-muted · 卡 350 / r20 / --card ·
   图标块 46 / --radius-note 14 · 家长 --primary-light · 老师 --tag-warning-bg · 卡标题 18/700 · 卡说明 13.5/--text-body · 提示条 r16。
   卡的圆角 20 不是 --radius-card 18 —— 画板这一页就是 20（表一那一行写明了）。 */
.entry-page { min-height: 100vh; background: var(--primary-deep); padding: 0 0 24px; }
body.is-entry { background: var(--primary-deep); min-height: 100vh; }
html:has(> body.is-entry) { background: var(--primary-deep); }   /* 视口比内容高时，底下那一截也是绿的，不露页面底色 */
/* 没登录时整屏就是入口页：首页壳（头部 / 各 tab / 底部导航）不再露出来 */
body.is-entry .app-header, body.is-entry .tab-page, body.is-entry .bottom-nav { display: none; }
body.is-entry.has-bottom-nav::after { display: none; }   /* 导航底下那层从页面底色渐隐的遮罩也收起：导航不在，遮罩会在绿底上露一截米绿 */
.entry-page .ep-head { padding: 28px 20px 18px; text-align: center; }
.entry-page .ep-leaf { width: 34px; height: 34px; color: var(--primary-light); margin: 0 auto 12px; display: block; }
.entry-page .ep-leaf svg { width: 34px; height: 34px; }
.entry-page .ep-title { font-family: var(--font-display); font-size: 26px; font-weight: 800; color: #fff; margin: 0; letter-spacing: -0.2px; }
.entry-page .ep-sub { font-size: 14px; font-weight: 500; color: var(--on-dark-muted); margin: 6px 0 0; line-height: 1.4; }
.entry-page .ep-cards { padding: 0 20px; display: flex; flex-direction: column; gap: 14px; }
/* 整张卡是一个链接（闸 1：卡高 ≥44；闸 9：aria-label 说得出是哪条路）—— 不许预选、不许高亮「上次是这个」（PD-0086 E1） */
.entry-page .ep-card { display: block; background: var(--card); border-radius: 20px; padding: 20px; color: var(--text); text-decoration: none; }
.entry-page .ep-card:active { opacity: .92; }
.entry-page .ep-card-head { display: flex; align-items: center; gap: 14px; }
.entry-page .ep-icon { width: 46px; height: 46px; border-radius: var(--radius-note); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.entry-page .ep-icon svg { width: 23px; height: 23px; }
.entry-page .ep-icon.p { background: var(--primary-light); color: var(--primary-deep); }
.entry-page .ep-icon.t { background: var(--tag-warning-bg); color: var(--tag-warning-fg); }
.entry-page .ep-card-t { flex: 1; min-width: 0; }
.entry-page .ep-card-t b { display: block; font-size: 18px; font-weight: 700; color: var(--text); }
.entry-page .ep-card-t span { display: block; font-size: 12.5px; font-weight: 400; color: var(--text-secondary); }
.entry-page .ep-chev { width: 18px; height: 18px; color: var(--icon-muted); flex-shrink: 0; }
.entry-page .ep-chev svg { width: 18px; height: 18px; }
.entry-page .ep-card p { font-size: 13.5px; line-height: 1.5; color: var(--text-body); margin: 12px 0 0; }
.entry-page .ep-note { margin: 18px 20px 0; background: var(--on-dark-fill); border-radius: 16px; padding: 14px; display: flex; gap: 10px; align-items: flex-start; }
.entry-page .ep-note svg { width: 16px; height: 16px; color: var(--primary-light); flex-shrink: 0; margin-top: 1px; }
.entry-page .ep-note p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--on-dark-soft); }
/* 页脚：画板 #7E9682 压 --primary-deep 只有 3.57（画板自己的色对不过线，UIV-15 §5）。取 design 建议的 ② —— --on-dark-muted 6.06，与同屏副标题同值；
   最终照稿还是抬色归 pd（UIV-15 §5 那一格待号） */
.entry-page .ep-foot { padding: 20px; margin: 0; text-align: center; font-size: 12.5px; line-height: 1.5; color: var(--on-dark-muted); }

/* ── PD-0070 · t-219：首页「再问一次」（design 09-11 默认，画板没有这一块，按体系补） ──
   与首页待办卡同族：--card · 18 · --shadow-md · 16。**不放图标块、不用琥珀 / 橙** —— 它不是待办也不是警告，
   是我们的错、在问她意见。两颗按钮同等分量（一样大、都描边、都不涂实心）：同意不许被推。 */
.card.consent-reask {
  position: relative; background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 16px; margin-bottom: 12px;
}
.card.consent-reask[hidden] { display: none; }
.consent-reask .cr-title { font-size: 15px; font-weight: 700; color: var(--text); margin: 0 40px 4px 0; }   /* 右边给 × 让位 */
.consent-reask .cr-body { font-size: 13.5px; line-height: 1.5; color: var(--text-body); margin: 0; }
.consent-reask .cr-btns { display: flex; gap: 8px; margin-top: 12px; }
.consent-reask .cr-btn {
  flex: 1; min-height: 44px; padding: 10px 12px;
  background: var(--card); border: 1.5px solid var(--border); border-radius: var(--radius-btn);
  font-family: inherit; font-size: 14px; font-weight: 700; color: var(--text); cursor: pointer;
}
.consent-reask .cr-btn:disabled { cursor: progress; opacity: .6; }
.consent-reask .cr-done { font-size: 14px; font-weight: 600; color: var(--text); margin: 0; outline: none; }
.consent-reask .cr-done[hidden] { display: none; }
.push-ask .cr-body a { color: var(--primary); font-weight: 600; }
/* ×：命中 44×44，看得见的是 18 的叉 —— 名字说清「不算答」 */
.consent-reask .cr-close {
  position: absolute; top: 4px; right: 4px; width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 50%; color: var(--text-secondary); cursor: pointer;
}
.consent-reask .cr-close[hidden] { display: none; }

/* ── 家长圈的整理卡（issue #373）──────────────────────────
   活动名、哪天几点、在哪、链接 —— 读的人一眼看到要紧的那几样。原文在卡下面，一字不改。 */
.circle-card {
  background: var(--bg); border-radius: var(--radius-card); padding: 12px 14px; margin: 4px 0 14px;
  display: flex; flex-direction: column; gap: 6px;
}
.cc-name { font-family: var(--font-display); font-size: 16px; font-weight: 800; color: var(--text); }
.cc-when { font-size: 15px; color: var(--text); }
.cc-when strong { font-weight: 800; color: var(--primary-deep); }
.cc-place { font-size: 14px; color: var(--text); }
.cc-summary { font-size: 13.5px; line-height: 1.45; color: var(--text-secondary); margin: 0; }
.cc-link { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.cc-link .cc-join { flex: 1 1 160px; text-align: center; text-decoration: none; display: inline-flex;
  align-items: center; justify-content: center; min-height: 44px; }
.cc-link .cc-copy { flex: 0 0 auto; min-height: 44px; padding: 0 16px; }
.cc-ics { font-size: 13px; font-weight: 700; color: var(--primary-deep); align-self: flex-start; padding: 6px 0; }
/* 列表卡上的日期时间小标签 */
.cc-chip {
  display: inline-block; font-size: 12.5px; font-weight: 700; color: var(--primary-deep);
  background: var(--bg); border-radius: 999px; padding: 3px 10px; margin: 2px 0 6px;
}
.community-body a { color: var(--primary-deep); text-decoration: underline; word-break: break-all; }

/* 发帖前的预览：表单那几块收起来，只留标题和预览 */
#new-post-modal .modal-sheet.is-previewing > :not(h3):not(#post-preview) { display: none; }
.post-preview { display: flex; flex-direction: column; gap: 8px; }
.post-preview[hidden] { display: none; }
.post-preview #post-preview-body { max-height: 30vh; overflow-y: auto; white-space: pre-wrap; }
.post-preview textarea { width: 100%; }
.post-preview .post-preview-redo { align-self: flex-start; }
.post-preview .circle-card { background: var(--card); border: 1px solid var(--border, rgba(36,64,43,0.15)); }


/* ── 像 app（2026-10-01「都做吧」第 5、7 条）────────────────────────────
   整屏的二级页（校方详情、作业详情、家长圈详情、受众页）从右边推进来 —— 和左边缘右划返回是一对；
   半屏的纸（发帖、举报）照旧从下面滑上来。按下去的行稍微暗一下，手指知道自己点到了。 */
html body #school-detail-modal .modal-sheet, html body #hw-detail-modal .modal-sheet, html body .post-detail-sheet {
  transform: translateX(100%); transition: transform 0.3s cubic-bezier(.32,1,.31,1);
}
html body #school-detail-modal.show .modal-sheet, html body #hw-detail-modal.show .modal-sheet,
html body .post-detail-overlay.show .post-detail-sheet { transform: none; }
.audience-page:not([hidden]) { animation: d7-push-in 0.3s cubic-bezier(.32,1,.31,1); }
@keyframes d7-push-in { from { transform: translateX(100%); } to { transform: none; } }

@media (hover: none) {
  .notice-item, .community-card, .hw-card, .resource-item, .home-todo-open, .cal-detail-event, .album-card {
    transition: filter 0.12s;
  }
  .notice-item:active, .community-card:active, .hw-card:active, .resource-item:active,
  .home-todo-open:active, .cal-detail-event:active, .album-card:active { filter: brightness(0.95); }
}

