/* 经营工作台：公共视觉层，保留定价状态语义和现有页面功能。 */
:root {
  --bg: #f3f5f7;
  --dark: #25364a;
  --text: #263447;
  --muted: #647182;
  --border: #dfe5ec;
  --gold: #b28a40;
  --gold-light: #cda761;
  /* 2026-09-10 令牌源唯一：原 app.py 内联 :root 独有变量迁入（值不变） */
  --card: #fff; --gold-bg: #faf6ee; --radius: 12px; --transition: 0.2s ease;
  /* 阴影三档 + 圆角档位（R-VIS-005，2026-09-10 收敛）：L1 卡片 / L2 浮层 / L3 模态 */
  --shadow-1: 0 1px 3px rgb(31 47 68 / 6%);
  --shadow-2: 0 4px 16px rgb(31 47 68 / 12%);
  --shadow-3: 0 12px 40px rgb(14 30 48 / 20%);
  --shadow: var(--shadow-1);      /* 兼容旧引用 */
  --shadow-lg: var(--shadow-2);   /* 兼容旧引用 */
  --radius-xs: 4px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 14px;
  /* 灰阶 + 语义色（R-VIS-001，2026-09-10）：值取现有高频字面量，先做"同值换引用"，
     近似色归并（B3c）留到下一步，避免一步到位导致观感不可控。 */
  --gray-50: #FAFBFD; --gray-100: #F4F7FA; --gray-200: #EEF1F5; --gray-300: #E0E6EE;
  --gray-400: #CCC; --gray-500: #BBB; --gray-600: #999; --gray-700: #888; --gray-800: #666; --gray-900: #555;
  --danger: #C62828; --danger-bg: #FDECEA;
  --success: #2E7D32; --success-bg: #E8F5E9;
  --warning: #B33A00; --warning-strong: #8B6508;
  --info: #1565C0; --info-bg: #E3F2FD;
  /* 一次性色值令牌化（R-VIS-001，2026-09-10 B3c）：只令牌化、不归并，观感零变化。
     命名 --tone-<色系>-<序号>（同族内由浅到深）；后续如需收敛可再做归并。 */
  --tone-blue-1: #1A1E2E; --tone-blue-2: #1E2130; --tone-blue-3: #1F2430; --tone-blue-4: #252A3E; --tone-blue-5: #1A2B4A; --tone-blue-6: #2B3040; --tone-blue-7: #243449; --tone-blue-8: #2A3148; --tone-blue-9: #354256; --tone-blue-10: #35465C; --tone-blue-11: #31485F; --tone-blue-12: #324E6C; --tone-blue-13: #285777; --tone-blue-14: #315776; --tone-blue-15: #425469; --tone-blue-16: #43546B; --tone-blue-17: #465A70; --tone-blue-18: #526176; --tone-blue-19: #5A6270; --tone-blue-20: #536478; --tone-blue-21: #51647B; --tone-blue-22: #42668B; --tone-blue-23: #2471A3; --tone-blue-24: #4A6B8A; --tone-blue-25: #586A7F; --tone-blue-26: #526C85; --tone-blue-27: #627087; --tone-blue-28: #637185; --tone-blue-29: #607288; --tone-blue-30: #69768A; --tone-blue-31: #67778B; --tone-blue-32: #6C7887; --tone-blue-33: #4382B7; --tone-blue-34: #718096; --tone-blue-35: #1E88E5; --tone-blue-36: #6C8DAA; --tone-blue-37: #6593B5; --tone-blue-38: #87909C; --tone-blue-39: #7894B0; --tone-blue-40: #8B92A5; --tone-blue-41: #9AA3B2; --tone-blue-42: #9AB; --tone-blue-43: #BCD; --tone-blue-44: #CCDDE9; --tone-blue-45: #D2E3F2;
  --tone-gold-1: #FFE082; --tone-gold-2: #ECDFAE; --tone-gold-3: #E8DFC4; --tone-gold-4: #FFF59D; --tone-gold-5: #FFF9C4;
  --tone-green-1: #1B5E20; --tone-green-2: #1E7E34; --tone-green-3: #1B8A3D; --tone-green-4: #277355; --tone-green-5: #558B2F; --tone-green-6: #27AE60;
  --tone-ink-1: #000; --tone-ink-2: #222; --tone-ink-3: #333; --tone-ink-4: #444; --tone-ink-5: #868D95; --tone-ink-6: #8A8F98; --tone-ink-7: #8C929E; --tone-ink-8: #8E94A0; --tone-ink-9: #9AA0AA; --tone-ink-10: #AAA; --tone-ink-11: #A8AEB8; --tone-ink-12: #B0B6C3; --tone-ink-13: #B0B8C4; --tone-ink-14: #BCC0C8; --tone-ink-15: #C0C6D0; --tone-ink-16: #C4C8D0; --tone-ink-17: #C5CEDB; --tone-ink-18: #D0D1D4; --tone-ink-19: #D0D4DC; --tone-ink-20: #D0D5DC; --tone-ink-21: #D4DBE8; --tone-ink-22: #DDD; --tone-ink-23: #D8DCE6; --tone-ink-24: #D2DFED; --tone-ink-25: #DDE1E7; --tone-ink-26: #DCE3EB; --tone-ink-27: #E0E3EA; --tone-ink-28: #DCE4ED; --tone-ink-29: #DDE4EC; --tone-ink-30: #E2E4E8; --tone-ink-31: #E2E5EA; --tone-ink-32: #E3E6EC; --tone-ink-33: #E3E6EE; --tone-ink-34: #E1E7EF; --tone-ink-35: #E6E9EE; --tone-ink-36: #E8EAEF; --tone-ink-37: #E6F4E8; --tone-ink-38: #E6F4EA; --tone-ink-39: #E8EDF2; --tone-ink-40: #EEE; --tone-ink-41: #F7F1E2; --tone-ink-42: #E3EEF9; --tone-ink-43: #F5F0E8; --tone-ink-44: #F3E5F5; --tone-ink-45: #F7F3E6; --tone-ink-46: #FDF3E0; --tone-ink-47: #EFEFF3; --tone-ink-48: #EDF0F4; --tone-ink-49: #EDF1F6; --tone-ink-50: #F4F3EE; --tone-ink-51: #EDF2F6; --tone-ink-52: #FDF6E3; --tone-ink-53: #EDF2F7; --tone-ink-54: #F0F2F5; --tone-ink-55: #F5F4EF; --tone-ink-56: #FFF8E1; --tone-ink-57: #FFEBEE; --tone-ink-58: #FFF4E5; --tone-ink-59: #EDF3F8; --tone-ink-60: #F0F2F8; --tone-ink-61: #F5F5F0; --tone-ink-62: #F0F3F7; --tone-ink-63: #FAF3F0; --tone-ink-64: #F2F4F8; --tone-ink-65: #F3F4F7; --tone-ink-66: #FFF2EE; --tone-ink-67: #F4F5F7; --tone-ink-68: #F3F5F8; --tone-ink-69: #FCF8EF; --tone-ink-70: #F5F6FA; --tone-ink-71: #F6F8FA; --tone-ink-72: #F7F8FB; --tone-ink-73: #F8F9FB; --tone-ink-74: #F7F9FC; --tone-ink-75: #FAFAFA; --tone-ink-76: #FFFCF5;
  --tone-orange-1: #6D5B2F; --tone-orange-2: #935F0B; --tone-orange-3: #805F22; --tone-orange-4: #826322; --tone-orange-5: #8A6D1A; --tone-orange-6: #7B5E3B; --tone-orange-7: #8A6D1F; --tone-orange-8: #7B6A3F; --tone-orange-9: #D35400; --tone-orange-10: #B8860B; --tone-orange-11: #EF6C00; --tone-orange-12: #9B8B5C; --tone-orange-13: #E67E22; --tone-orange-14: #F57F17; --tone-orange-15: #B08D4F; --tone-orange-16: #BF9B4E; --tone-orange-17: #F9A825; --tone-orange-18: #D4B76A; --tone-orange-19: #FFE08A; --tone-orange-20: #FDF3D7; --tone-orange-21: #FDEEDE;
  --tone-purple-1: #6A1B9A; --tone-purple-2: #7B1FA2; --tone-purple-3: #E1BEE7;
  --tone-red-1: #A51F1F; --tone-red-2: #B71C1C; --tone-red-3: #9B382A; --tone-red-4: #A53C2D; --tone-red-5: #C0392B; --tone-red-6: #D32F2F; --tone-red-7: #E53935; --tone-red-8: #F2C4BE; --tone-red-9: #EFD1C8; --tone-red-10: #FADBD8;
  --tone-teal-1: #00897B; --tone-teal-2: #16A085;
}
body { font-size: 14px; line-height: 1.5; }
button, input, select, textarea { font: inherit; }
button { min-height: 40px; box-shadow: none; padding: 8px 15px; }
button:hover { transform: none; box-shadow: none; }
button:disabled { cursor: wait; opacity: .6; }
a:focus-visible, button:focus-visible, [tabindex]:focus-visible, summary:focus-visible {
  outline: 3px solid var(--tone-blue-33); outline-offset: 3px;
}
nav { box-shadow: none; gap: 20px; border-bottom: 1px solid var(--tone-blue-9); top: var(--banner-height, 0px); }
.session-banners { position: sticky; top: 0; z-index: 11; }
.store.grid h2 { top: calc(44px + var(--banner-height, 0px)); }
nav a { color: var(--tone-ink-17); }
nav b { white-space: nowrap; }
.wrap { padding: 24px 32px 40px; }
.workspace-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 24px; }
.workspace-heading h1 { font-size: 27px; line-height: 1.3; letter-spacing: -.6px; margin: 4px 0 0; }
.eyebrow { color: var(--tone-blue-32); font-size: 12px; letter-spacing: 1px; }
.workspace-meta { display: flex; gap: 12px; align-items: center; color: var(--muted); font-size: 13px; }
.access-chip { padding: 4px 10px; background: var(--tone-ink-39); border-radius: var(--radius-sm); color: var(--tone-blue-15); }
.card, .store { border: 1px solid var(--border); box-shadow: var(--shadow-1); margin-bottom: 20px; }
.card { padding: 24px; }
.card h2 { font-size: 19px; margin: 0 0 7px; }
.card p { color: var(--muted); font-size: 14px; line-height: 1.7; }
.overview-card { border-top: 3px solid var(--gold); }
.overview-card > div { gap: 16px !important; }
.overview-card > div > span { line-height: 1.9; }
.overview-card > div > span:last-child { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; white-space: normal !important; }
.overview-card .legend { padding: 16px 0 0; margin: 8px 0 0; }
summary { cursor: pointer; min-height: 36px; display: list-item; align-content: center; font-size: 13px; color: var(--tone-blue-18); }
.legend { color: var(--tone-blue-30); font-size: 12px; line-height: 1.75; }
.store.grid h2 { padding: 20px 18px 12px; font-size: 16px; }
.store.grid h2 button { background: var(--tone-ink-53) !important; color: var(--tone-blue-12) !important; border: 1px solid var(--tone-ink-28); margin: 4px 0; }
.store.grid h2 .coefbar { color: var(--tone-blue-27); font-size: 12px; line-height: 1.7; }
.store.grid .tblwrap { border-top: 1px solid var(--border); position: relative; overscroll-behavior-x: contain; }
.store.grid table { border-collapse: separate; border-spacing: 0; }
.store.grid th, .store.grid td { border-width: 0 1px 1px 0; }
.store.grid th { min-width: 68px; font-size: 12px; padding: 8px 4px; }
.store.grid th.room { background: var(--tone-ink-49); color: var(--tone-blue-10); z-index: 5; }
.store.grid th.room, .store.grid td.room { min-width: 92px; width: 92px; font-size: 13px; }
.store.grid th.base, .store.grid td.base { min-width: 62px; font-size: 12px; }
.store.grid td.c { height: 58px; }
.store.grid td.oc .pa { font-size: 15px; top: 7px; left: 6px; }
.store.grid td.oc .pb { font-size: 11px; bottom: 6px; right: 6px; }
.store.grid .occ { font-size: 11px; white-space: nowrap; }
.store.grid th .dcoef { font-size: 10px; }
.store.grid td[tabindex] { cursor: pointer; }
.store.grid td[tabindex]:hover { box-shadow: inset 0 0 0 2px var(--tone-blue-39); }
.store.grid td.editable-cell { position: relative; }  /* 角标定位上下文（2026-09-10：此前 td 为 static，::after 相对 viewport 漂到页面右上角） */
.store.grid td.editable-cell::after { content: ''; position: absolute; right: 5px; top: 3px; width: 11px; height: 11px; background: var(--tone-blue-26); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z'/%3E%3C/svg%3E") no-repeat center/contain; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z'/%3E%3C/svg%3E") no-repeat center/contain; }
.store.grid th.dcedit::after { content: ' · 编辑'; font-size: 10px; opacity: .9; }
.grid-tools { display: flex; align-items: center; justify-content: space-between; padding: 8px 18px; gap: 8px; background: var(--gray-50); border-top: 1px solid var(--tone-ink-48); }
.grid-tools span { font-size: 12px; color: var(--tone-blue-28); }
.grid-tools button { background: transparent; color: var(--tone-blue-22); border: 1px solid var(--tone-ink-28); min-height: 36px; padding: 4px 10px; font-size: 12px; }
.advice-overview { display: flex; gap: 20px; align-items: center; justify-content: space-between; border-left: 3px solid var(--tone-blue-36); }
.advice-overview button { white-space: nowrap; }
.advice-rules { background: var(--gray-50); padding: 12px 20px; }
.advice-rules .legend { padding: 8px 0; }
body[data-page='8'] .card button { min-height: 40px; }
table.jobs td { padding: 12px 14px; font-size: 13px; text-align: left; overflow-wrap: anywhere; }
table.jobs th { white-space: nowrap; }
.jobs-mobile { display: none; }
.job-failed { color: var(--tone-red-4); font-weight: 600; }
.job-complete { color: var(--tone-green-4); font-weight: 600; }
.job-pending { color: var(--tone-orange-4); font-weight: 600; }
#work-status { background: var(--tone-ink-59); color: var(--tone-blue-14); border: 1px solid var(--tone-blue-44); padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; }
#work-status[data-error='true'] { background: var(--tone-ink-66); color: var(--tone-red-3); border-color: var(--tone-red-9); }
.price-detail { border: 1px solid var(--tone-ink-26); border-radius: 16px; box-shadow: var(--shadow-3); width: min(520px, calc(100% - 32px)); max-height: 84dvh; padding: 0; margin: auto; color: var(--text); }
.price-detail::backdrop { background: rgb(20 32 47 / 48%); }
.price-detail-head { display: flex; justify-content: space-between; align-items: center; padding: 20px 22px; border-bottom: 1px solid var(--border); }
.price-detail-head h2 { font-size: 18px; margin: 0; }
.price-detail-head button { background: var(--tone-ink-62); color: var(--tone-blue-16); min-width: 44px; }
.price-detail-body { padding: 20px 22px; }
.price-detail-price { font-size: 27px; font-weight: 700; margin-bottom: 12px; }
.price-detail-body pre { white-space: pre-wrap; overflow-wrap: anywhere; font-family: inherit; font-size: 14px; line-height: 1.9; color: var(--tone-blue-17); background: var(--gray-100); padding: 16px; margin: 12px 0; border-radius: 8px; }
.price-detail-foot { border-top: 1px solid var(--border); padding: 16px 22px; display: flex; gap: 8px; justify-content: flex-end; }
/* 明细卡内联改价（2026-09-11）：输入框就放在第一次弹窗里，不再有第二个弹窗 */
.price-detail-foot { flex-wrap: wrap; align-items: center; }
.price-edit { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; width: 100%; }
.price-edit input { width: 150px; min-height: 40px; padding: 6px 10px; font-size: 16px; border: 1px solid var(--tone-ink-26); border-radius: 8px; background: var(--card); color: var(--text); }
.price-edit input:focus-visible { outline: 2px solid var(--accent, var(--tone-blue-16)); outline-offset: 1px; }
.price-edit-actions { display: flex; gap: 8px; }
.price-edit-hint { flex-basis: 100%; font-size: 12px; color: var(--tone-blue-21); }
body[data-access-role='viewer'] [data-write], body[data-access-role='staff'] [data-write] { display: none !important; }
/* 写入口对 viewer 与 staff 都要隐藏：workspace.js 的 canWrite 判定是
   `accessRole === 'admin'`，viewer 与 staff 均不可写。此前只写 viewer，
   staff 会看到系数编辑区（与 JS 行为不一致）。服务端仍逐请求拦，这里是体验层。 */
body[data-access-role='viewer'] .coefedit,
body[data-access-role='staff'] .coefedit { display: none !important; }
/* staff 也要清掉「 · 编辑」角标：workspace.js 会移除 staff 的 dcedit 处理器
   （staff 不能改日期系数），但角标还在 → staff 看到可点的「编辑」却点不动，
   属误导性可供性。viewer/staff 两者都不能编辑，视觉就该一致。 */
body[data-access-role='viewer'] th.dcedit::after,
body[data-access-role='staff'] th.dcedit::after { content: ''; }
.role-notice { padding: 12px 14px; margin-bottom: 16px; background: var(--tone-ink-51); border-radius: 8px; font-size: 13px; color: var(--tone-blue-21); }
@media (max-width: 1100px) and (min-width: 769px) {
  nav { gap: 12px; padding: 0 14px; overflow-x: auto; white-space: nowrap; }
  nav a { font-size: 12px; }
}
@media (max-width: 768px) {
  body { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  .wrap { padding: 20px 12px 24px; }
  .workspace-heading { margin-bottom: 20px; align-items: flex-end; }
  .workspace-heading h1 { font-size: 24px; }
  .workspace-meta { flex-direction: row; flex-wrap: wrap; justify-content: flex-end; max-width: 155px; gap: 4px; font-size: 12px; }
  .store.grid h2 > span:first-of-type { display: block; font-size: 12px !important; line-height: 1.7; margin: 4px 0; }
  .store.grid h2 > span:last-child { float: none !important; display: inline-block; }
  .store.grid h2 .pbtns { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
  .card { padding: 16px; border-radius: 12px; }
  button { min-height: 44px; padding: 8px 12px; font-size: 13px; }
  .overview-card > div > span:first-child { font-size: 13px; }
  .store.grid h2 { position: static; padding: 16px 14px 10px; font-size: 16px; }
  .store.grid h2 button { min-height: 36px; font-size: 12px; }
  .store.grid h2 .coefbar { display: none; }
  .store.grid th.room, .store.grid td.room { min-width: 86px; width: 86px; max-width: 86px; padding: 8px; font-size: 12px; }
  .store.grid th.base, .store.grid td.base { display: none; }
  .store.grid th { min-width: 70px; font-size: 12px; padding: 8px 3px; }
  .store.grid td.c { height: 58px; }
  /* 移动端列头入住率要更小：窄列宽下「0%·空2」用 11px 必折行。
     注意必须写成 `.store.grid th .occ`（类数 2 + 元素 1）才能压过上面
     L56 的 `.store.grid .occ`（类数 2）——只写 `.store.grid .occ` 两处同具体度、
     后加载者胜，看起来"改了"其实没生效。app.py:353 原本有 `th .occ{font-size:8px}`
     的修复，但它是 (0,1,1)，被本文件 (0,2,0) 静默压回 11px。 */
  .store.grid th .occ { font-size: 8px; white-space: nowrap; letter-spacing: -0.2px; }
  .store.grid td.oc .pa { font-size: 15px; }
  .store.grid td.oc .pb { font-size: 11px; }
  .store.grid .legend { padding: 12px 14px; font-size: 12px; }
  .store.grid .grid-tools { padding: 8px 14px; }
  .advice-overview { align-items: stretch; flex-direction: column; gap: 16px; }
  .advice-overview h2 { font-size: 18px; }
  .advice-overview button { align-self: flex-start; }
  .tabbar { min-height: 62px; padding-bottom: env(safe-area-inset-bottom); border-top: 1px solid var(--tone-ink-29); box-shadow: var(--shadow-1); }
  .tabbar a { font-size: 12px; color: var(--tone-blue-31); min-height: 58px; justify-content: center; }
  .tabbar a.on { color: var(--tone-orange-3); background: var(--tone-ink-69); }
  .tabbar i { font-style: normal; font-size: 22px; }
  .price-detail { width: 100%; max-width: 100vw; box-sizing: border-box; max-height: 88dvh; margin: auto 0 0; border-radius: 16px 16px 0 0; padding-bottom: env(safe-area-inset-bottom); }
  .price-detail-foot button { flex: 1; }
  .jobs-enhanced table.jobs { display: none; }
  .jobs-mobile { display: grid; gap: 12px; }
  .job-mobile-card { border: 1px solid var(--border); border-radius: 10px; padding: 16px; background: var(--gray-50); }
  .job-mobile-card h4 { font-size: 15px; margin-bottom: 12px; color: var(--tone-blue-11); }
  .job-mobile-card dl { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 8px 10px; font-size: 13px; }
  .job-mobile-card dt { color: var(--tone-blue-34); }
  .job-mobile-card dd { margin: 0; overflow-wrap: anywhere; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; } }
