:root{--ink:#17233a;--muted:#64748b;--bg:#f4f7fb;--card:#fff;--line:#e5eaf2;--accent:#335cff;--success:#0f9d78;--danger:#c74040}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px Inter,"PingFang SC",Arial,sans-serif}main{max-width:1160px;margin:auto;padding:42px 24px 56px}header{display:flex;justify-content:space-between;align-items:start;margin-bottom:28px}.eyebrow{letter-spacing:1.8px;color:var(--accent);font-size:12px;font-weight:700;margin:0 0 8px}h1{font-size:32px;margin:0 0 10px}.subtitle,.muted{color:var(--muted);margin:0}.live{color:var(--success);font-weight:600;padding-top:10px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:18px}.metrics article,.panel{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:0 8px 28px #26365b0b}.metrics article{padding:19px}.metrics span{color:var(--muted);font-size:13px}.metrics strong{display:block;font-size:30px;margin-top:7px}.grid{display:grid;grid-template-columns:1.35fr .85fr;gap:18px}.panel{padding:21px}.panel-title{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}.panel-title h2{font-size:17px;margin:0}.panel-title span{font-size:12px;color:var(--muted)}.messages{height:255px;overflow:auto;padding:4px 0 12px}.bot,.user{max-width:82%;padding:11px 13px;border-radius:11px;line-height:1.55;margin:8px 0}.bot{background:#edf2ff}.user{background:var(--accent);color:white;margin-left:auto}.quick-actions{display:flex;gap:6px;margin:10px 0 4px;flex-wrap:wrap}.quick-actions button{background:#eef2ff;color:#304fc8;font-size:12px;padding:7px 11px;border-radius:8px;font-weight:500}.quick-actions button:hover{background:#dde5ff}.quick-actions button[data-type="urgent"]{background:#ffeded;color:#c74040}.quick-actions button[data-type="urgent"]:hover{background:#ffd6d6}.quick-actions button[data-type="repair"]{background:#fff3e9;color:#a75800}.quick-actions button[data-type="repair"]:hover{background:#ffe6cc}.quick-actions button[data-type="vehicle"]{background:#e0f2fe;color:#075985}.quick-actions button[data-type="vehicle"]:hover{background:#bae6fd}form{display:flex;gap:9px;border-top:1px solid var(--line);padding-top:16px}input{flex:1;min-width:0;border:1px solid var(--line);border-radius:9px;padding:11px;font:inherit}button{border:0;border-radius:9px;background:var(--accent);color:#fff;padding:11px 17px;font:inherit;font-weight:600;cursor:pointer}.wide{width:100%;margin:17px 0}.secondary{background:#eef2ff;color:#304fc8}.camera{border-top:1px solid var(--line);padding:12px 0;display:grid;grid-template-columns:1fr auto}.camera b{font-size:12px;color:var(--success)}.camera small{color:var(--muted);grid-column:1/3;margin-top:4px}.tickets{margin-top:18px}.ticket{display:grid;grid-template-columns:90px 1fr auto;gap:14px;padding:15px 0;border-top:1px solid var(--line);align-items:center}.ticket:first-child{border-top:0}.tag{font-size:11px;padding:5px 7px;border-radius:99px;text-align:center;background:#fff3e9;color:#a75800}.tag.high{background:#ffeded;color:var(--danger)}.tag.ok{background:#eaf8f4;color:#087056}.tag.pending{background:#fef3c7;color:#a75800}.tag.placeholder{background:#f5f5f5;color:#64748b}.ticket p{margin:3px 0;color:var(--muted);font-size:13px}.ticket h3{margin:0;font-size:15px}.resolve{background:#eaf8f4;color:#087056;font-size:12px}

/* 投诉列表 */
.complaints{margin-top:18px}
.complaint-row{display:grid;grid-template-columns:90px 1fr auto;gap:14px;padding:15px 0;border-top:1px solid var(--line);align-items:center;cursor:pointer;transition:background .15s}
.complaint-row:first-child{border-top:0}
.complaint-row:hover{background:#f8faff}
.complaint-row .tag{background:#fff3e9;color:#a75800}
.complaint-row .tag.resolved{background:#eaf8f4;color:#087056}
.complaint-row h3{margin:0;font-size:15px}
.complaint-row p{margin:3px 0;color:var(--muted);font-size:13px}

/* 模态框 */
.modal{position:fixed;inset:0;background:rgba(15,23,42,.55);display:flex;align-items:center;justify-content:center;z-index:100;padding:20px}
.modal.hidden{display:none}
.modal-content{background:var(--card);border-radius:16px;max-width:780px;width:100%;max-height:90vh;display:flex;flex-direction:column;box-shadow:0 20px 60px rgba(0,0,0,.25)}
.modal-header{display:flex;justify-content:space-between;align-items:flex-start;padding:22px 24px 16px;border-bottom:1px solid var(--line)}
.modal-header h2{margin:0 0 4px;font-size:22px}
.modal-header .muted{margin:0;font-size:13px}
.modal-close{background:transparent;color:var(--muted);font-size:22px;padding:4px 10px}
.modal-body{padding:18px 24px 22px;overflow:auto}
.modal-section{margin-bottom:22px}
.modal-section h3{font-size:14px;margin:0 0 10px;color:var(--muted);font-weight:600;letter-spacing:.5px;text-transform:uppercase}
.modal-section h3 span{font-size:12px;text-transform:none;letter-spacing:0;margin-left:6px;font-weight:400}
.modal-ticket{background:var(--bg);border-radius:10px;padding:14px 16px;display:grid;grid-template-columns:auto 1fr;gap:8px 14px;font-size:13px}
.modal-ticket .k{color:var(--muted)}
.modal-ticket .v{color:var(--ink);font-weight:500}

/* 时间线 */
.timeline{position:relative;padding-left:22px}
.timeline:before{content:"";position:absolute;left:6px;top:6px;bottom:6px;width:2px;background:var(--line)}
.timeline-item{position:relative;padding:8px 0 12px}
.timeline-item:before{content:"";position:absolute;left:-19px;top:14px;width:11px;height:11px;border-radius:50%;background:var(--card);border:2px solid var(--accent)}
.timeline-item.resolved:before{border-color:var(--success)}
.timeline-item.media:before{border-color:#a75800}
.timeline-item.push:before{border-color:#8b5cf6}
.timeline-item.push{background:#f5f0ff;border-radius:6px;padding:8px 10px;margin:6px -10px}
.timeline-item .ts{font-size:11px;color:var(--muted);margin-bottom:2px}
.timeline-item .desc{font-size:14px;color:var(--ink)}
.timeline-item .meta{font-size:11px;color:var(--muted);margin-top:3px}

/* 媒体画廊 */
.media-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
.media-gallery img,.media-gallery video{width:100%;height:140px;object-fit:cover;border-radius:8px;border:1px solid var(--line);background:#000}
.media-gallery video{cursor:pointer}

@media(max-width:720px){main{padding:24px 15px}header{display:block}.live{display:block;padding-top:14px}.metrics,.grid{grid-template-columns:1fr}.ticket{grid-template-columns:70px 1fr}.ticket button{grid-column:2}.messages{height:220px}.modal-content{max-height:95vh}.modal-header{padding:16px}.modal-body{padding:14px 16px 18px}.media-gallery{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}}

/* ===== 登录 + 用户胶囊（v5 · 2026-08-17）===== */

/* 登录模态框：默认全屏覆盖（与投诉模态框一致），内容卡片更窄 */
.login-modal{display:flex}
.login-content{max-width:420px}
.login-form{display:flex;flex-direction:column;gap:14px;padding:4px 0}
.login-form label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--muted);font-weight:600}
.login-form input{padding:11px 12px;font-size:14px}
.login-form button{margin-top:6px}
.error{color:var(--danger);font-size:13px;min-height:18px;margin:0}
.login-hint{margin-top:18px;border-top:1px solid var(--line);padding-top:14px;font-size:13px}
.login-hint summary{cursor:pointer;color:var(--accent);font-weight:600;padding:4px 0;user-select:none}
.login-hint table{width:100%;border-collapse:collapse;margin:12px 0 6px;font-size:12px}
.login-hint th,.login-hint td{text-align:left;padding:6px 8px;border-bottom:1px solid var(--line)}
.login-hint th{color:var(--muted);font-weight:600}
.login-hint td{color:var(--ink)}
.login-hint td:first-child,.login-hint td:nth-child(2){font-family:Menlo,Consolas,monospace;font-size:11px;color:var(--accent)}

/* 头部右侧：服务状态 + 用户胶囊 + 退出按钮 */
.header-right{display:flex;align-items:center;gap:12px}
.user-chip{background:#eef2ff;color:#304fc8;padding:5px 11px;border-radius:99px;font-size:12px;font-weight:600}
.logout-btn{background:transparent;color:var(--muted);font-size:12px;padding:7px 13px;border:1px solid var(--line);font-weight:500}
.logout-btn:hover{background:#f4f7fb;color:var(--ink);border-color:var(--ink)}

/* owner 角色下隐藏看板/工单/投诉（由 JS 设置 style.display=none，
   此处只是兜底：默认显示所有面板，登录后 JS 会按 role 切） */

/* ===== v5.2 样式 ===== */

/* 头部 🔔 铃铛 + 未读徽章 */
.bell-btn{background:transparent;color:var(--ink);font-size:18px;padding:6px 10px;border:0;cursor:pointer;position:relative;display:inline-flex;align-items:center}
.bell-btn:hover{background:#f4f7fb;border-radius:8px}
.bell-icon{display:inline-block}
.unread-badge{position:absolute;top:-2px;right:-2px;background:#dc2626;color:#fff;font-size:10px;font-weight:700;border-radius:99px;padding:2px 6px;min-width:18px;text-align:center;line-height:1.2}
.unread-badge.hidden{display:none}

/* 工单提醒 — 🔔 蓝色高亮 */
.ticket.has-reminder{background:linear-gradient(90deg,#fff8e1 0%,transparent 30%);border-left:3px solid #f59e0b;padding-left:12px}
.reminder-bell{font-size:18px;margin-right:6px;animation:bellShake 2s ease-in-out infinite}
@keyframes bellShake{0%,50%,100%{transform:rotate(0)}10%,30%{transform:rotate(-15deg)}20%,40%{transform:rotate(15deg)}}

/* 消息中心列表 */
.messages-panel{margin-top:18px}
.message{padding:14px 16px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:6px}
.message:first-child{border-top:0}
.message.unread{background:#fef3c7;border-left:3px solid #f59e0b;padding-left:13px}
.message.read{background:transparent}
.message-header{display:flex;align-items:center;gap:10px;font-size:13px}
.message-header .sender{font-weight:600;color:var(--ink)}
.message-header .sender.system{color:#7c3aed}
.message-header .sender.admin,.message-header .sender.manager{color:#335cff}
.message-header .sender.guard{color:#0f9d78}
.message-header .sender.owner{color:#a75800}
.message-header .time{margin-left:auto;color:var(--muted);font-size:11px}
.message-header .new-tag{background:#dc2626;color:#fff;font-size:10px;padding:1px 6px;border-radius:99px;font-weight:600}
.message-header .read-tag{color:#0f9d78;font-size:14px}
.message-content{font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word}
.message-meta{display:flex;align-items:center;gap:12px;font-size:12px}
.message-meta .ticket-link{color:#335cff;text-decoration:none}
.message-meta .ticket-link:hover{text-decoration:underline}
.reply-form{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.reply-form.hidden{display:none}
.reply-form textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:8px;font:13px Inter,"PingFang SC",Arial,sans-serif;resize:vertical}
.reply-actions{display:flex;justify-content:flex-end;gap:8px}
.text-btn{background:transparent;color:var(--accent);border:0;padding:4px 8px;font-size:12px;cursor:pointer;font-weight:500}
.text-btn:hover{background:#eef2ff;border-radius:6px}
.primary-btn{background:var(--accent);color:#fff;border:0;padding:6px 14px;border-radius:6px;font-size:12px;cursor:pointer;font-weight:600}
.primary-btn:hover{background:#2545d8}

/* ===== v5.2.1 角色分级提醒 ===== */
/* 其他人的工单 — 灰色 + 半透明，不显示 🔔，不能操作 */
.ticket.no-reminder{opacity:.55;background:#fafbfc}
.ticket.no-reminder .reminder-bell{display:none}
.ticket.no-reminder .resolve{display:none}
.ticket.no-reminder:hover{opacity:.85}

/* ===== v5.3 Toast 通知 ===== */
.toast-container{position:fixed;top:80px;right:24px;z-index:200;display:flex;flex-direction:column;gap:10px;max-width:360px}
.toast{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:10px;padding:14px 16px;box-shadow:0 8px 24px rgba(0,0,0,.12);cursor:pointer;opacity:0;transform:translateX(20px);transition:opacity .25s ease,transform .25s ease}
.toast.show{opacity:1;transform:translateX(0)}
.toast:hover{background:#f8faff}
.toast-title{font-weight:600;font-size:13px;color:var(--ink);margin-bottom:4px}
.toast-content{font-size:13px;color:var(--muted);line-height:1.4;word-break:break-word}
@keyframes slideIn{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}

/* v5.7: 测试账号行 hover 效果（提示可点击）*/
#login-test-accounts tr[data-u]:hover {
  background: #eef2ff;
}
#login-test-accounts tr[data-u]:hover td {
  color: #2545d8;
}

/* ===== v8.0 AI Ops 完整集 · 前端优化 (2026-08-20) ===== */

/* 顶部指标卡 5 列布局 */
.metrics{grid-template-columns:repeat(5,1fr);gap:14px}
@media(max-width:900px){.metrics{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.metrics{grid-template-columns:1fr}}

/* 经理看板 KPI 卡片 */
.dashboard{margin-bottom:18px}
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:18px}
@media(max-width:900px){.kpi-grid{grid-template-columns:repeat(2,1fr)}}
.kpi-card{background:#fff;border:1px solid var(--line);border-radius:11px;padding:14px 16px;position:relative;overflow:hidden}
.kpi-card.warn{background:linear-gradient(135deg,#fff5f5,#fff)}
.kpi-card.warn .kpi-value{color:var(--danger)}
.kpi-label{font-size:12px;color:var(--muted);font-weight:600;letter-spacing:.3px}
.kpi-value{font-size:28px;font-weight:700;margin:6px 0 8px;color:var(--ink)}
.kpi-sub{font-size:11px;color:var(--muted)}
.kpi-bar{height:6px;background:#e5eaf2;border-radius:3px;overflow:hidden;margin-top:8px}
.kpi-fill{height:100%;background:linear-gradient(90deg,#0f9d78,#0fbf88);transition:width .4s}
.kpi-fill.warn{background:linear-gradient(90deg,#c74040,#e85555)}

/* 看板双栏 */
.dashboard-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:18px}
@media(max-width:900px){.dashboard-grid{grid-template-columns:1fr}}
.dashboard-block h3{font-size:14px;margin:0 0 10px;display:flex;align-items:center;gap:6px}
.dashboard-block h3::before{content:"";width:3px;height:14px;background:var(--accent);border-radius:2px}

/* 维修工负载条 */
.load-list{display:flex;flex-direction:column;gap:10px}
.load-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;background:#f8faff}
.load-item-name{font-weight:600;font-size:14px;flex:0 0 90px}
.load-item-bar{flex:1;height:8px;background:#e5eaf2;border-radius:4px;overflow:hidden;position:relative}
.load-item-fill{height:100%;background:linear-gradient(90deg,#335cff,#5a7dff);border-radius:4px;transition:width .4s}
.load-item-fill.high{background:linear-gradient(90deg,#e85555,#ff7e7e)}
.load-item-count{font-size:13px;color:var(--muted);min-width:30px;text-align:right}

/* 紧急分布条（紫/橙/绿） */
.urgency-bar{display:flex;gap:6px;height:24px;border-radius:6px;overflow:hidden;margin-top:6px}
.urgency-bar > div{padding:4px 10px;color:#fff;font-size:11px;font-weight:600;display:flex;align-items:center;transition:flex .4s}
.urgency-high{background:#c74040}
.urgency-medium{background:#a75800}
.urgency-low{background:#0f9d78}

/* 超期工单列表 */
.breached-row{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;background:#fff5f5;border-radius:8px;margin-bottom:6px;border-left:3px solid var(--danger)}
.breached-row small{color:var(--muted);font-size:12px}
.breached-row b{color:var(--danger);font-size:12px}

/* 双栏两列 */
.grid.two-col{grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}
@media(max-width:900px){.grid.two-col{grid-template-columns:1fr}}

/* 卡片列表（房号/业主） */
.cards-list{display:flex;flex-direction:column;gap:10px}
.card-row{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;background:#f8faff;border-radius:8px;transition:background .2s}
.card-row:hover{background:#edf2ff}
.card-row .name{font-weight:600;font-size:14px}
.card-row small{color:var(--muted);font-size:11px}
.card-row .tag{font-size:10px;padding:2px 7px;border-radius:99px;background:#eef2ff;color:#304fc8;font-weight:600}

/* FAQ 网格 */
.faq-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}
.faq-item{background:#fff;border:1px solid var(--line);border-radius:10px;padding:12px 14px;cursor:pointer;transition:all .2s}
.faq-item:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:0 4px 12px rgba(51,92,255,.12)}
.faq-cat{font-size:10px;padding:2px 7px;border-radius:99px;background:#fff3e9;color:#a75800;font-weight:600;display:inline-block;margin-bottom:6px}
.faq-q{font-size:13px;font-weight:600;color:var(--ink);margin-bottom:4px}
.faq-k{font-size:11px;color:var(--muted)}

/* 公告列表 */
.announcement{padding:14px 16px;background:#fff;border-radius:10px;margin-bottom:10px;border-left:4px solid var(--accent)}
.announcement.high{border-left-color:#c74040;background:#fff5f5}
.announcement.urgent{border-left-color:#a75800;background:#fff8e1}
.announcement h3{margin:0 0 6px;font-size:15px}
.announcement .meta{font-size:11px;color:var(--muted)}
.announcement p{margin:8px 0 0;font-size:13px;color:var(--ink);line-height:1.55;white-space:pre-wrap}

/* 优化工单列表：显示 SLA 状态灯 + 催办按钮 */
.ticket-meta{display:flex;gap:8px;align-items:center;margin-top:4px}
.sla-pill{font-size:10px;padding:2px 7px;border-radius:99px;font-weight:600}
.sla-pill.ok{background:#eaf8f4;color:#087056}
.sla-pill.warn{background:#fff3e9;color:#a75800}
.sla-pill.overdue{background:#ffeded;color:#c74040}
.nudge-btn{background:transparent;color:var(--accent);border:1px solid var(--accent);font-size:11px;padding:4px 9px;border-radius:6px;cursor:pointer;font-weight:600}
.nudge-btn:hover{background:var(--accent);color:#fff}
.nudge-btn:disabled{opacity:.4;cursor:not-allowed}

/* ===== Sprint 2 v6.0.3 · 公告发布按钮 ===== */
.kpi-action{background:linear-gradient(135deg,var(--accent),#5a7dff);color:#fff;border:0;border-radius:8px;padding:5px 12px;font-size:12px;font-weight:600;cursor:pointer;margin-left:10px;transition:transform .15s}
.kpi-action:hover{transform:translateY(-1px);box-shadow:0 4px 12px rgba(51,92,255,.25)}
.kpi-action:active{transform:translateY(0)}
select{padding:11px 12px;font-size:14px;border:1px solid var(--line);border-radius:9px;font-family:inherit}
textarea{padding:11px 12px;font-family:inherit;font-size:14px;border:1px solid var(--line);border-radius:9px}
.hidden{display:none}

/* ===== v6.0.4 · 房号管理按钮 ===== */
.delete-btn{background:transparent;border:0;color:var(--danger);cursor:pointer;font-size:14px;padding:2px 6px;margin-left:6px;border-radius:4px;transition:background .15s}
.delete-btn:hover{background:#ffeded}

/* ===== v5.7 视觉平台联动样式 ===== */
.cv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}
.cv-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  cursor: pointer;
  transition: all 0.15s ease;
  font-size: 13px;
}
.cv-btn:hover:not(:disabled) {
  background: var(--surface-hover, #f4f8ff);
  border-color: var(--primary, #2e75b6);
  transform: translateY(-1px);
}
.cv-btn:disabled, .cv-btn.loading {
  opacity: 0.5;
  cursor: wait;
}
.cv-btn span:first-child {
  font-size: 22px;
}
.cv-btn-text {
  font-weight: 500;
}
#cv-recent {
  margin-top: 8px;
  border-top: 1px dashed var(--border, #e2e8f0);
  padding-top: 8px;
  max-height: 160px;
  overflow-y: auto;
}
.cv-event-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid #f0f0f0;
  font-size: 12px;
}
.cv-event-row:last-child {
  border-bottom: 0;
}
.cv-icon {
  font-size: 18px;
  flex-shrink: 0;
}
.cv-info {
  flex: 1;
  min-width: 0;
}
.cv-info b {
  display: block;
  color: var(--text, #1f2937);
  font-weight: 600;
}
.cv-info small {
  color: var(--muted, #6b7280);
}

/* ===== v8.3 · 智慧用车管理样式 ===== */
.inner-panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
}
.inner-panel .panel-title h3 { font-size: 15px; margin: 0; }

.vehicle-kpi { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 900px) { .vehicle-kpi { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .vehicle-kpi { grid-template-columns: 1fr; } }

.vehicle-board {
  display: grid;
  gap: 10px;
  max-height: 380px;
  overflow-y: auto;
}
.vehicle-group {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 12px;
  background: #f8fafd;
}
.vehicle-group.v-status-in_use { background: #fff8eb; border-color: #f5d590; }
.vehicle-group.v-status-maintenance { background: #ffeded; border-color: #f5b3b3; }
.vehicle-group-header {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: 6px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
.vehicle-card {
  display: grid;
  grid-template-columns: 1.1fr 1.5fr auto 1fr;
  gap: 10px;
  align-items: center;
  padding: 6px 0;
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.vehicle-card:first-child { border-top: 0; }
.v-plate {
  font-family: 'SF Mono', 'Consolas', monospace;
  font-weight: 700;
  color: var(--ink);
  background: #fff;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid var(--line);
}
.v-model { color: var(--ink); }
.v-mileage {
  font-family: 'SF Mono', 'Consolas', monospace;
  font-size: 11px;
  color: var(--muted);
  text-align: right;
}

.quick-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.quick-form .form-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-end;
}
.quick-form .form-row label {
  flex: 1;
  min-width: 130px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.quick-form .form-row label input,
.quick-form .form-row label select {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  font: inherit;
  font-size: 13px;
  background: white;
  color: var(--ink);
  text-transform: none;
  letter-spacing: normal;
}
.quick-form .form-row label input:focus,
.quick-form .form-row label select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(51, 92, 255, 0.15);
}
.quick-form button {
  align-self: flex-start;
}
.form-msg {
  margin-left: 10px;
  font-size: 12px;
  font-weight: 500;
}
.form-msg.ok { color: var(--success); }
.form-msg.err { color: var(--danger); }

.v-btn-approve, .v-btn-reject, .v-btn-resolve {
  border: 0;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  margin-left: 4px;
  font-family: inherit;
}
.v-btn-approve { background: #eaf8f4; color: #087056; }
.v-btn-approve:hover { background: #d4f0e6; }
.v-btn-reject { background: #ffeded; color: var(--danger); }
.v-btn-reject:hover { background: #ffd6d6; }
.v-btn-resolve { background: #eef2ff; color: #304fc8; }
.v-btn-resolve:hover { background: #dde5ff; }

/* ============================================================
   v9.0-university Phase 1+2 管理后台样式
   ============================================================ */

/* Tab 切换（v9 子模块） */
.v9-tabs {
  display: flex;
  gap: 6px;
  border-bottom: 1px solid #e0e0e0;
  margin-bottom: 16px;
  padding-bottom: 0;
}

.v9-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 16px;
  cursor: pointer;
  color: #666;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s;
}

.v9-tab:hover {
  color: #304fc8;
  background: rgba(48, 79, 200, 0.05);
}

.v9-tab.active {
  color: #304fc8;
  border-bottom-color: #304fc8;
  font-weight: 600;
}

/* Sprint 26: 待审批申请列表·审批状态徽章 */
.v-status-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid transparent;
}
.v-status-pending {
  background: #fef3c7;
  color: #92400e;
  border-color: #fbbf24;
}
.v-status-approved {
  background: #d1fae5;
  color: #065f46;
  border-color: #34d399;
}
.v-status-rejected {
  background: #fee2e2;
  color: #991b1b;
  border-color: #fca5a5;
}
.v-pending-status-row {
  margin: 4px 0 2px 0;
}

/* Sprint 25: 创建调拨资产搜索提示下拉 */
.v9-asset-suggest-list {
  position: absolute;
  z-index: 100;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  max-height: 240px;
  overflow-y: auto;
  margin-top: -8px;
}
.v9-asset-suggest-item:hover {
  background: #f1f5f9 !important;
}
.v9-asset-suggest-empty {
  padding: 8px 12px;
  color: #94a3b8;
  font-size: 13px;
  font-style: italic;
}

.v9-tab-content {
  padding-top: 8px;
}

/* ===== v9.0-r15+ Sprint 19: 主导航 Tab（运营 / 系统管理） ===== */
.main-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 2px solid var(--line);
  margin: 0 0 18px 0;
  padding: 0;
  background: transparent;
}

.main-tab {
  background: transparent;
  border: none;
  border-bottom: 3px solid transparent;
  padding: 12px 22px;
  cursor: pointer;
  color: var(--muted);
  font-size: 15px;
  font-weight: 500;
  margin-bottom: -2px;
  transition: all 0.2s ease;
  border-radius: 8px 8px 0 0;
}

.main-tab:hover {
  color: var(--ink);
  background: rgba(48, 79, 200, 0.06);
}

.main-tab.active {
  color: #304fc8;
  border-bottom-color: #304fc8;
  font-weight: 600;
  background: rgba(48, 79, 200, 0.04);
}

/* admin quick entry card (仅 admin/super_admin 可见) */
.admin-quick-card {
  margin-bottom: 18px;
  grid-column: 1 / -1;  /* Sprint 21: 占整行，避免被 metrics 5列网格挤成 1 列 */
  grid-template-columns: 1fr;  /* Sprint 21: 内部 grid item 占满整行 */
}
.admin-quick-card > a,
.admin-quick-card > div {
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.admin-quick-card > a:hover,
.admin-quick-card > div:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

/* Toolbar */
.v9-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.v9-toolbar label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: #555;
}

/* KPI 卡片 */
.v9-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.v9-kpi {
  background: linear-gradient(135deg, #f5f7ff 0%, #e8edff 100%);
  border: 1px solid #d8e0ff;
  border-radius: 10px;
  padding: 18px 14px;
  text-align: center;
  transition: transform 0.2s;
}

.v9-kpi:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(48, 79, 200, 0.15);
}

.v9-kpi-num {
  font-size: 28px;
  font-weight: 700;
  color: #304fc8;
  line-height: 1.2;
}

.v9-kpi-label {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

/* RBAC 矩阵 */
.v9-rbac-grid {
  overflow-x: auto;
  max-height: 600px;
  overflow-y: auto;
}

.rbac-table {
  font-size: 11px;
  white-space: nowrap;
}

.rbac-table th {
  background: #f5f5f5;
  position: sticky;
  top: 0;
  z-index: 1;
}

.rbac-cell {
  padding: 4px 6px;
  text-align: center;
  min-width: 28px;
  font-family: monospace;
}

.rbac-cell.ok {
  background: #eaf8f4;
  color: #087056;
}

.rbac-cell.off {
  background: #fafafa;
  color: #ccc;
}

/* 通用 metric grid */
.v9-metric-grid {
  padding: 8px 0;
}

/* 状态徽章 */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 500;
  background: #f0f0f0;
  color: #555;
  margin: 0 2px;
}

.badge.ok {
  background: #eaf8f4;
  color: #087056;
}

.badge.warn {
  background: #fff5e0;
  color: #b8750c;
}

.badge.off, .badge.danger {
  background: #ffeded;
  color: var(--danger, #c43);
}

.badge.muted {
  background: #f5f5f5;
  color: #888;
}

/* 链接按钮 */
.link {
  background: none;
  border: none;
  color: #304fc8;
  cursor: pointer;
  padding: 2px 6px;
  font-size: 12px;
  text-decoration: underline;
}

.link:hover {
  color: #1a3499;
}

.link.ok {
  color: #087056;
}

.link.ok:hover {
  color: #054d3d;
}

.link.danger {
  color: #c43;
}

.link.danger:hover {
  color: #8c1d1d;
}

/* 数据表 */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin: 8px 0;
}

.data-table th,
.data-table td {
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid #eee;
}

.data-table th {
  background: #f7f8fc;
  font-weight: 600;
  color: #444;
}

.data-table tbody tr:hover {
  background: #f9faff;
}

.data-table .muted {
  color: #999;
  text-align: center;
  padding: 20px;
}

/* 表单消息 */
.form-msg {
  font-size: 13px;
  margin-top: 8px;
  min-height: 18px;
}

.form-msg.ok {
  color: #087056;
}

.form-msg.err {
  color: #c43;
}

/* 隐藏元素 */
.hidden {
  display: none !important;
}

.muted {
  color: #999;
  font-size: 12px;
}

/* 表单字段通用 */
#v9-booking-create-form input,
#v9-booking-create-form textarea,
#v9-blackout-create-form input,
#v9-transfer-create-form input,
#v9-transfer-create-form textarea,
#v9-tenant-user-form input,
#v9-tenant-user-form select,
#v9-availability-form input,
#v9-rbac-check-form select {
  padding: 6px 10px;
  border: 1px solid #d0d0d0;
  border-radius: 6px;
  font-size: 13px;
  margin: 4px;
}

#v9-booking-create-form label,
#v9-blackout-create-form label,
#v9-transfer-create-form label,
#v9-tenant-user-form label,
#v9-availability-form label,
#v9-rbac-check-form label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: #555;
  margin-right: 8px;
}

#v9-booking-create-form button,
#v9-blackout-create-form button,
#v9-transfer-create-form button,
#v9-tenant-user-form button,
#v9-availability-form button,
#v9-rbac-check-form button,
#v9-venue-usage-refresh,
#v9-assets-stats-refresh,
#v9-approval-refresh,
#v9-workflow-refresh,
#v9-workflow-create-btn,
#v9-blackout-refresh,
#v9-blackout-create-btn,
#v9-tenant-create-btn {
  padding: 6px 14px;
  background: #304fc8;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s;
}

#v9-booking-create-form button:hover,
#v9-blackout-create-form button:hover,
#v9-transfer-create-form button:hover,
#v9-tenant-user-form button:hover,
#v9-availability-form button:hover,
#v9-rbac-check-form button:hover,
#v9-venue-usage-refresh:hover,
#v9-assets-stats-refresh:hover,
#v9-approval-refresh:hover,
#v9-workflow-refresh:hover,
#v9-workflow-create-btn:hover,
#v9-blackout-refresh:hover,
#v9-blackout-create-btn:hover,
#v9-tenant-create-btn:hover {
  background: #1a3499;
}

/* ============================================================
 * v9.0 资产管理面板（2026-08-27）
 * ============================================================ */

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

.v9-form-row > label {
  flex: 1;
  min-width: 140px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
}

.v9-form-row input,
.v9-form-row select,
.v9-form-row textarea {
  width: 100%;
}

#v9-asset-create-form,
#v9-asset-maintenance-form,
#v9-booking-create-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 720px;
}

#v9-asset-create-form label,
#v9-asset-maintenance-form label,
#v9-booking-create-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
}

#v9-booking-create-form input,
#v9-booking-create-form select,
#v9-booking-create-form textarea {
  width: 100%;
  min-width: 0;
}

.v9-asset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 12px;
}

.v9-asset-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px;
  background: white;
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.15s;
}

.v9-asset-card:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}

.v9-asset-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.v9-asset-card-icon {
  font-size: 22px;
}

.v9-asset-card-code {
  font-weight: 600;
  font-size: 14px;
  color: #2545d8;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.v9-asset-card-status {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
}

.v9-asset-card-status.active {
  background: #dcfce7;
  color: #166534;
}

.v9-asset-card-status.maintenance {
  background: #fef3c7;
  color: #a75800;
}

.v9-asset-card-status.retired {
  background: #f3f4f6;
  color: #6b7280;
}

.v9-asset-card-location {
  font-size: 12px;
  color: #6b7280;
  margin: 4px 0;
}

.v9-asset-card-meta {
  display: flex;
  gap: 12px;
  font-size: 11px;
  color: #9ca3af;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed #f3f4f6;
}

.v9-asset-type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  margin-top: 12px;
}

.v9-asset-type-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 10px 12px;
  background: white;
}

.v9-asset-type-card h4 {
  margin: 0 0 6px;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.v9-asset-type-card .fields {
  font-size: 11px;
  color: #6b7280;
}

#v9-asset-detail-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  padding: 10px;
  background: #f9fafb;
  border-radius: 8px;
}

#v9-asset-detail-info .field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

#v9-asset-detail-info .field label {
  font-size: 11px;
  color: #9ca3af;
}

#v9-asset-detail-info .field .value {
  font-size: 13px;
  color: #1f2937;
  font-weight: 500;
}

#v9-asset-detail-maintenance {
  margin-top: 8px;
}

.maint-row {
  border-left: 3px solid #dbeafe;
  padding: 6px 10px;
  margin-bottom: 6px;
  background: #f9fafb;
  border-radius: 0 6px 6px 0;
  font-size: 13px;
}

.maint-row .type-tag {
  display: inline-block;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 8px;
  margin-right: 6px;
  background: #dbeafe;
  color: #1e40af;
}

.maint-row .cost {
  color: #059669;
  font-weight: 600;
}

/* 风控预警过滤芯片（v9.0-r11） */
.filter-chip {
  font: inherit; font-size: 12px; font-weight: 600;
  padding: 5px 11px; border-radius: 99px;
  background: #f4f7fb; color: #64748b; border: 1px solid #e5eaf2;
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.filter-chip:hover { background: #eef2ff; color: #304fc8; border-color: #dde5ff; }
.filter-chip.active[data-alert-filter="status"] {
  background: #fef3c7; color: #a75800; border-color: #f5d590;
}
.filter-chip.active[data-alert-filter="level"] {
  background: #ffeded; color: #c74040; border-color: #f5b3b3;
}

/* v9.0-r11+ 车辆池 modal 表格 */
.v-pool-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.v-pool-table th { background: #f4f7fb; color: #64748b; font-weight: 600; padding: 10px 12px;
  text-align: left; border-bottom: 1px solid var(--line); position: sticky; top: 0; }
.v-pool-table td { padding: 9px 12px; border-bottom: 1px solid #eef2f7; }
.v-pool-table tr:hover td { background: #f8fafc; }
.v-pool-table td:first-child { white-space: nowrap; }


# v9.0-r15+: 场馆预定表单可订性状态样式
.v9-avail-status {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 13px;
  border: 1px solid transparent;
  transition: all 0.2s ease;
  min-height: 40px;
}
.v9-avail-icon {
  font-size: 16px;
  flex-shrink: 0;
  line-height: 1.4;
}
.v9-avail-text {
  font-weight: 600;
  line-height: 1.4;
}
.v9-avail-detail {
  flex: 1;
  font-size: 12px;
  line-height: 1.5;
  color: inherit;
  opacity: 0.85;
}
.v9-avail-detail.muted {
  opacity: 0.6;
  font-weight: normal;
}
.v9-avail-detail ul {
  margin: 4px 0 0;
  padding-left: 18px;
}
.v9-avail-detail li {
  margin: 2px 0;
}
.v9-avail-status.v9-avail-idle {
  background: #f8fafc;
  border-color: #e5eaf2;
  color: #64748b;
}
.v9-avail-status.v9-avail-loading {
  background: #f0f9ff;
  border-color: #bae6fd;
  color: #075985;
}
.v9-avail-status.v9-avail-ok {
  background: #eaf8f4;
  border-color: #86efac;
  color: #087056;
}
.v9-avail-status.v9-avail-warn {
  background: #fff8e8;
  border-color: #fcd34d;
  color: #a75800;
}
.v9-avail-status.v9-avail-bad {
  background: #ffeded;
  border-color: #fca5a5;
  color: #c74040;
}
.v9-avail-status.v9-avail-error {
  background: #fef3c7;
  border-color: #fbbf24;
  color: #92400e;
}

/* ===== Sprint 29: 多轮预订会话状态条 ===== */
.mt-banner {
  margin: 6px 0;
  padding: 8px 10px;
  background: #eef4ff;
  border: 1px solid #b6c8ef;
  border-radius: 8px;
  font-size: 12px;
  color: #2c4a8a;
}
.mt-banner .mt-banner-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: center;
}
.mt-banner b { color: #1d3f7d; }
.mt-banner b[data-remaining] { font-variant-numeric: tabular-nums; }

/* ===== Sprint 31: 多轮确认卡片按钮 ===== */
.mt-banner .mt-btn {
  border: none;
  border-radius: 6px;
  padding: 4px 14px;
  font-size: 12px;
  cursor: pointer;
  margin-right: 6px;
}
.mt-banner .mt-btn-ok { background: #1f8a4c; color: #fff; }
.mt-banner .mt-btn-ok:hover { background: #17703d; }
.mt-banner .mt-btn-cancel { background: #eef1f6; color: #444; border: 1px solid #c8d0dd; }
.mt-banner .mt-confirm { background: #f3faf5; border-color: #9fd4b2; color: #1c5c34; }

/* ===== Sprint 38: 审批面板三 Tab ===== */
.approval-tab-list .approval-row { display:flex; align-items:center; gap:8px; padding:8px; border-bottom:1px solid #e2e8f0; font-size:13px; }
.approval-row .approval-tag { padding:2px 8px; border-radius:4px; font-size:11px; font-weight:600; }
.approval-tag.pending { background:#fef3c7; color:#92400e; }
.approval-tag.approved { background:#dcfce7; color:#166534; }
.approval-tag.rejected { background:#fee2e2; color:#991b1b; }
.approval-tag.cancelled { background:#f1f5f9; color:#64748b; }
.approval-row .approval-actions { margin-left:auto; display:flex; gap:4px; }
.approval-row .approval-actions button { padding:3px 10px; border-radius:4px; font-size:11px; cursor:pointer; border:1px solid #cbd5e1; background:#f8fafc; }
.approval-row .approval-actions button:hover { background:#e2e8f0; }
.approval-row .approval-actions button.nudge-btn { color:#c2410c; }
.approval-row .approval-actions button.cancel-btn { color:#dc2626; }

/* ===== Sprint 47 · 智慧停车（app_detailed_design）===== */
/* 导航路线流光动画（§二.2 绿色高亮流光，SVG stroke-dashoffset 滚动） */
.pk-route-flow {
  animation: pk-flow 1.6s linear infinite;
}
@keyframes pk-flow {
  to { stroke-dashoffset: -40; }
}
/* 违停态：原分配车位灰色闪烁 */
.pk-space-blink {
  animation: pk-blink 0.9s ease-in-out infinite;
}
@keyframes pk-blink {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 0.75; }
}
/* 违停态：实际错停车位红色脉冲高亮 */
.pk-space-alert {
  animation: pk-pulse 0.7s ease-in-out infinite;
}
@keyframes pk-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* ===== Sprint 48 · AI 动态预测排队进度条（ai_progress_component Web 适配）===== */
.pk-q-badge {
  background: rgba(16, 185, 129, 0.12);
  color: #059669;
  font-size: 12px;
  font-weight: 700;
  padding: 3px 12px;
  border-radius: 16px;
  display: inline-flex;
  align-items: center;
}
/* ✦ 徽标微闪（AI 实时推演感） */
.pk-q-sparkle {
  margin-right: 4px;
  display: inline-block;
  animation: pk-q-pulse 1.5s infinite;
}
@keyframes pk-q-pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}
/* 倒计时大字（等宽字体防跳动） */
.pk-q-time {
  font-size: 34px;
  font-weight: 700;
  font-family: 'Courier New', Courier, monospace;
  color: #1e293b;
}
/* 渐变进度条：宽度 1s linear 平滑过渡 + 流光微闪覆盖层 */
.pk-q-track {
  height: 9px;
  background: #eef2f7;
  border-radius: 6px;
  overflow: hidden;
}
.pk-q-fill {
  height: 100%;
  border-radius: 6px;
  background: linear-gradient(90deg, #10B981, #059669);
  transition: width 1s linear;
  position: relative;
  overflow: hidden;
}
.pk-q-fill::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
  animation: pk-q-sheen 1.8s linear infinite;
}
@keyframes pk-q-sheen {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

/* Sprint 49 · 准空闲态（optimization_design §三 黄绿闪烁："车位即将释放，请稍作等待"） */
.pk-space-leaving {
  animation: pk-leaving-blink 1.1s ease-in-out infinite;
}
@keyframes pk-leaving-blink {
  0%, 100% { fill: #eab308; opacity: 1; }      /* 黄 */
  50% { fill: #22c55e; opacity: 0.65; }         /* 绿 */
}

/* Sprint 60 · 导航目标车位高亮（navi-map.js 借鉴）：绿描边脉冲，🎯 标记 */
.pk-space-target {
  animation: pk-target-pulse 1.6s ease-in-out infinite;
}
@keyframes pk-target-pulse {
  0%, 100% { stroke: #16a34a; stroke-width: 2.5; }
  50% { stroke: #22c55e; stroke-width: 4; }
}
