/* ============================================================================
   日程页专属样式（assets/schedule.css）
   ----------------------------------------------------------------------------
   只放「日程页新长出来的东西」，**不改 session.css** —— 那个文件还服务着
   咨询工作台等页面，日程页的需求不该顺着它传染出去。

   新增的只有这几类：
     1. 可约空档（`.ev--open`）—— 日历上表达「开放给来访、但还没被约走」的块
     2. 拖拽状态（`.is-dragging` / `.is-drop`）
     3. 指针小菜单（`.s-pop`）—— 飞书式，点在时间块上就地弹出
     4. 新建/编辑弹窗里的两列表单（`.s-dlg__grid`）
     5. 网格行数随数据走 + 分格线不抢点击
     6. 空态与加载态

   色值一律取 tokens.css 的既有变量；没有新造颜色。
   ========================================================================== */

/* ---------------------------------------------------------------- 1. 可约空档
   语义是「可约、尚未被占用」。与已预约（实心蓝）必须一眼可分，
   所以走**虚线边 + 更浅的底**：虚线在日历语境里天然读作"还没定下来"。 */
.ev--open {
  --ev-a: var(--anlan-blue);
  background: color-mix(in srgb, var(--anlan-blue) 3%, var(--surface));
  border-style: dashed;
  border-left-style: solid; /* 左色条保持实心，色相识别不受虚线影响 */
}
.ev--open:hover { background: color-mix(in srgb, var(--anlan-blue) 8%, var(--surface)); }
.ev--open .ev__t { color: var(--ink-700); }
.ev--open .ev__m { color: var(--ink-500); }

/* 被单独改过期的那一节：加一个小圆点，提示"它已经不在规则原位了" */
.ev__moved {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--warn);
  margin-left: 6px;
  vertical-align: middle;
  flex: none;
}

/* 图例里的虚线色块（与 .ev--open 的边一致） */
.s-swatch--open {
  background: color-mix(in srgb, var(--anlan-blue) 3%, var(--surface));
  border-style: dashed;
  border-color: var(--anlan-blue);
}

/* 网格行数改为随数据走：日程可能落在 08:00–22:00 之外，
   写死 14 行会把早/晚的块裁掉。--s-rows 由 schedule.js 按数据算出来挂在 .s-cal 上。 */
.s-cal .wk__col,
.s-cal .day__col {
  min-height: calc(var(--s-hour) * var(--s-rows, 14));
}

/* 分格线层不许抢点击。
   `.wk__slot` 与 `.ev` 同为 position:absolute 且都没有 z-index，而 slot 在 DOM 里
   是 append 在事件块**之后**的（schedule.js 先放块、再铺线）—— 于是线盖在块上，
   把落在块上的点击全吃了：真实用户点不开日程块（指针小菜单永远弹不出来），
   拖拽也永远起不来。Playwright 报的 `wk__slot intercepts pointer events` 就是这个。
   slot 本身没有任何交互（只负责画横线），所以让它彻底退出命中测试；
   点在空白处会命中 `.wk__col` —— 它有 data-day，拖拽落点判定照旧成立。 */
.s-cal .wk__slot {
  pointer-events: none;
}

/* ---------------------------------------------------------------- 2. 拖拽 */
.ev.is-dragging {
  opacity: .55;
  box-shadow: var(--shadow-md);
  z-index: 5;
}
.ev.is-locked {
  /* 已预约的那一节不可拖 —— 光标要如实反映这一点，而不是拖了才发现没反应 */
  cursor: default;
}
.wk__col.is-drop,
.mth__cell.is-drop {
  background: var(--anlan-blue-50);
  box-shadow: inset 0 0 0 2px var(--anlan-blue-100);
}

/* P9 · 空白处拖选建日程：选区幽灵块。
   定位与 `.ev` 同一套（`--t` 起点分钟 / `--d` 时长分钟），所以纵向必然对得齐；
   `pointer-events:none` 是必须的 —— 它盖在指针下面，若参与命中测试，
   后续 mousemove 的落点判定就会一直命中自己，选区再也长不大。 */
.sel-ghost {
  position: absolute;
  left: 4px; right: 4px;
  top: calc(var(--s-hour) * var(--t, 0) / 60);
  height: calc(var(--s-hour) * var(--d, 60) / 60);
  min-height: 22px;
  z-index: 4;
  pointer-events: none;
  border: 1px dashed var(--anlan-blue);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--anlan-blue) 8%, var(--surface));
}
/* 压到已有日程 → 这次选择无效。颜色必须**明显不同**于有效态，
   否则用户看不出"为什么松手没反应"。 */
.sel-ghost.is-invalid {
  border-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, var(--surface));
}
.sel-ghost::after {
  content: attr(data-label);
  position: absolute;
  left: 8px; top: 4px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-700);
}
/* 拖动时禁掉文本选择，否则整页会被刷蓝 */
.s-cal.is-dragging {
  user-select: none;
  -webkit-user-select: none;
}

/* ---------------------------------------------------------------- 3. 指针小菜单
   定位用 fixed + JS 摆位（跟随指针并做视口夹取），所以这里只管外观。 */
.s-pop {
  position: fixed;
  z-index: 300;
  min-width: 168px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.s-pop[hidden] { display: none; }
.s-pop__head {
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 4px;
}
.s-pop__head-title {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-900);
}
.s-pop__head-meta {
  font-size: 12px;
  color: var(--ink-500);
  margin-top: 2px;
}
.s-pop__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 0 10px;
  border: 0;
  border-radius: calc(var(--radius) - 4px);
  background: transparent;
  color: var(--ink-900);
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}
.s-pop__item:hover { background: var(--anlan-blue-50); color: var(--anlan-blue); }
.s-pop__item--risk { color: var(--risk); }
.s-pop__item--risk:hover { background: color-mix(in srgb, var(--risk) 8%, var(--surface)); color: var(--risk); }
.s-pop__item[disabled] {
  color: var(--ink-300);
  cursor: not-allowed;
}
.s-pop__item[disabled]:hover { background: transparent; color: var(--ink-300); }

/* ---------------------------------------------------------------- 4. 弹窗表单 */
.modal__panel--wide { max-width: 560px; }

.s-dlg__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.s-dlg__grid .field { display: grid; gap: 6px; }
.s-dlg__grid .field--full { grid-column: 1 / -1; }
.s-dlg__grid label { font-size: 13px; font-weight: 500; color: var(--ink-700); }
.s-dlg__hint {
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-500);
}
.s-dlg__scope {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}
.s-dlg__scope-legend {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-700);
  margin-bottom: 8px;
}
.s-dlg__scope-opts { display: grid; gap: 8px; }
.s-dlg__radio {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 13px;
  color: var(--ink-700);
  cursor: pointer;
}
.s-dlg__radio:has(input:checked) {
  border-color: var(--anlan-blue-100);
  background: var(--anlan-blue-50);
  color: var(--ink-900);
}
.s-dlg__radio input { margin-top: 2px; flex: none; }
.s-dlg__radio small { display: block; color: var(--ink-500); font-size: 12px; margin-top: 2px; }

/* ---------------------------------------------------------------- 5. 空态 */
.s-empty {
  padding: 28px 16px;
  text-align: center;
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-500);
}
.s-empty strong { display: block; color: var(--ink-700); font-weight: 500; margin-bottom: 4px; }
.mth__more { font-size: 12px; color: var(--ink-500); padding-left: 2px; }

/* 视图里的加载态：不要用骨架屏假装有数据，直接说明"正在读" */
.s-loading { padding: 40px 16px; text-align: center; font-size: 13px; color: var(--ink-500); }

/* ---------------------------------------------------------------- 待确认预约：就地确认 / 取消
   2026-10-08 加。这一栏此前是指向 `session-workspace.html` 的链接（一个还没确认的
   会谈，进工作区没有意义），而且**根本没有地方能确认它** —— 见 schedule.js
   `pendingRow()` 的注释。现在这一行自己带两个按钮。 */
.s-aside__row--pending {
  flex-wrap: wrap;
  row-gap: 6px;
}
.s-aside__row--pending .s-aside__when {
  font-size: 14px;
  color: var(--ink-900);
}
.s-aside__ops {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
/* `.s-meta{margin-left:auto}` 只把状态推到右侧；有了按钮之后，让按钮成为最右的那个，
   状态紧跟在时间后面。 */
.s-aside__row--pending .s-meta { margin-left: 0; }
.s-aside__row.is-busy { opacity: .55; }

/* ---------------------------------------------------------------- hidden 归还
   ⚠️ **2026-10-08 起这条已是冗余**：`app.css` 顶部加了全局的
   `[hidden] { display: none !important; }`，同类问题在 7 个 CSS 文件里共 55 处，
   已经一次性收口（见那里的注释）。这里留着只是不顺手删别的文件的东西 ——
   它现在既不会出错，也不需要再有人照着它写第 56 条。
   下面这段记录保留，因为它说清了当初是怎么发现的。 */
/* 老坑（与 clients-actions.css 里 `.form-grid[hidden]` 那条同源）：`[hidden]` 只是
   UA 样式表里的一条 display:none，只要别处写了 `display:grid/flex` 就会被盖掉。
   弹窗里的「重复到」正是 `.s-dlg__grid .field`（display:grid）—— 明明设了 hidden
   却照样显示，而旁边没写 display 的 `.s-dlg__scope` 反倒藏得好好的，看着像两个 bug。 */
.s-dlg__grid .field[hidden] {
  display: none;
}
