/* SPEC: PJ2026-01060508 Web哨兵 draft-2026-06-26-p7-web-probe-sentinel-dashboard. */ /* Responsibility: Responsive visual foundation for the web-probe sentinel dashboard. */ :root { color-scheme: light; --bg: #f6f7f9; --panel: #ffffff; --panel-soft: #f0f5f7; --text: #18212f; --muted: #667085; --border: #d9e0e7; --blue: #2563eb; --green: #059669; --amber: #b7791f; --red: #c2413d; --violet: #6d5bd0; --shadow: 0 8px 24px rgb(30 41 59 / 8%); } * { box-sizing: border-box; } html, body { min-height: 100%; } body { margin: 0; background: var(--bg); color: var(--text); font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; letter-spacing: 0; } button, select, input { font: inherit; } .sentinel-shell { width: min(1440px, 100%); margin: 0 auto; padding: 24px; } .sentinel-topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; } .sentinel-title { display: flex; align-items: center; min-width: 0; gap: 12px; } .sentinel-mark { width: 36px; height: 36px; border-radius: 8px; background: linear-gradient(135deg, rgb(37 99 235 / 90%), rgb(5 150 105 / 88%)), #2563eb; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 30%); flex: 0 0 auto; } h1, h2, p { margin: 0; } h1 { font-size: 22px; line-height: 1.18; font-weight: 700; } h2 { font-size: 15px; line-height: 1.3; font-weight: 700; } #sentinel-subtitle, .panel-subtitle, .metric-card small { color: var(--muted); } #sentinel-subtitle { margin-top: 3px; font-size: 13px; overflow-wrap: anywhere; } .sentinel-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; } .status-pill, .severity-pill { display: inline-flex; align-items: center; min-height: 28px; padding: 4px 10px; border-radius: 999px; border: 1px solid transparent; font-size: 12px; font-weight: 700; text-transform: uppercase; white-space: nowrap; } .status-healthy, .status-operational { background: #e8f7ef; color: var(--green); border-color: #b9e6cc; } .status-warning, .status-degraded, .severity-warning, .severity-amber { background: #fff6df; color: var(--amber); border-color: #f2d893; } .status-blocked, .status-error, .severity-red, .severity-critical, .severity-error { background: #fdecea; color: var(--red); border-color: #f4bbb7; } .status-idle, .severity-info, .severity-unknown { background: #eef2f7; color: #526071; border-color: #d8e0ea; } .refresh-toggle { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 4px 8px; color: #344054; font-size: 13px; white-space: nowrap; } .refresh-toggle input { width: 16px; height: 16px; } select, .icon-button { min-height: 34px; border: 1px solid var(--border); border-radius: 8px; background: #ffffff; color: #1f2937; } select { padding: 0 28px 0 10px; } .icon-button { padding: 0 12px; font-size: 13px; font-weight: 700; cursor: pointer; } .icon-button:disabled { cursor: progress; opacity: 0.62; } .banner { margin-bottom: 14px; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--border); font-size: 13px; overflow-wrap: anywhere; } .banner-muted { background: #edf4ff; color: #1d4ed8; border-color: #bfd5ff; } .banner-danger { background: #fff0ee; color: var(--red); border-color: #f2c0bc; } .metric-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; } .metric-card, .panel { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow); } .metric-card { min-height: 112px; padding: 14px; display: grid; align-content: space-between; gap: 8px; } .metric-label { color: var(--muted); font-size: 12px; font-weight: 700; text-transform: uppercase; } .metric-card strong { min-width: 0; font-size: 24px; line-height: 1.1; overflow-wrap: anywhere; } .metric-card small { font-size: 12px; line-height: 1.35; overflow-wrap: anywhere; } .overview-checks { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; } .check-chip { display: inline-flex; align-items: center; min-height: 30px; max-width: 100%; padding: 5px 10px; border: 1px solid #d8e0ea; border-radius: 999px; background: #ffffff; color: #475467; font-size: 12px; font-weight: 700; overflow-wrap: anywhere; } .check-ok { border-color: #b9e6cc; background: #eefaf4; color: var(--green); } .check-blocked { border-color: #f4bbb7; background: #fff0ee; color: var(--red); } .timeline-panel { margin-bottom: 14px; } .run-timeline { display: flex; gap: 8px; min-height: 68px; padding: 14px 16px; overflow-x: auto; } .timeline-node { display: inline-grid; grid-template-rows: 18px auto; justify-items: center; gap: 4px; min-width: 76px; max-width: 120px; border: 0; background: transparent; color: #475467; cursor: pointer; } .timeline-dot { width: 16px; height: 16px; border: 3px solid currentColor; border-radius: 999px; background: #ffffff; } .timeline-label { width: 100%; font-size: 11px; font-weight: 800; text-align: center; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; } .dashboard-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(320px, 0.9fr); gap: 14px; } .panel { min-width: 0; overflow: hidden; } .panel-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 52px; padding: 14px 16px; border-bottom: 1px solid var(--border); } .table-frame { width: 100%; overflow: auto; } .runs-filter, .findings-filter { display: grid; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: #fbfcfe; } .runs-filter { grid-template-columns: repeat(4, minmax(120px, 1fr)) minmax(180px, 1.4fr) auto; } .findings-filter { grid-template-columns: repeat(2, minmax(96px, 0.9fr)) repeat(2, minmax(120px, 1.1fr)) auto; } .runs-filter label, .findings-filter label { display: grid; gap: 4px; min-width: 0; } .runs-filter label span, .findings-filter label span { color: var(--muted); font-size: 11px; font-weight: 800; text-transform: uppercase; } .runs-filter input, .runs-filter select, .findings-filter input, .findings-filter select { width: 100%; } .runs-filter input, .findings-filter input { min-height: 34px; padding: 0 10px; border: 1px solid var(--border); border-radius: 8px; background: #ffffff; color: #1f2937; } .runs-filter .icon-button, .findings-filter .icon-button { align-self: end; } .runs-table { width: 100%; min-width: 760px; border-collapse: collapse; } .runs-table th, .runs-table td { padding: 11px 12px; border-bottom: 1px solid #edf0f4; text-align: left; vertical-align: top; font-size: 13px; } .runs-table th { color: var(--muted); background: #f8fafc; font-size: 11px; font-weight: 800; text-transform: uppercase; } .runs-table tr { cursor: pointer; } .runs-table tr:hover { background: #f7fbff; } .runs-table tr.selected-row { background: #eef7ff; } .runs-table td small { display: block; margin-top: 3px; color: var(--muted); font-size: 11px; overflow-wrap: anywhere; } .mono { font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; font-size: 12px; overflow-wrap: anywhere; } .finding-list { display: grid; gap: 10px; padding: 12px; } .finding-aggregation { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; padding: 12px; border-bottom: 1px solid var(--border); background: #ffffff; } .aggregation-group { display: grid; align-content: start; gap: 6px; min-width: 0; } .aggregation-group > span { color: var(--muted); font-size: 11px; font-weight: 800; text-transform: uppercase; } .finding-item { display: grid; gap: 8px; padding: 12px; border: 1px solid #e3e8ef; border-radius: 8px; background: var(--panel-soft); } .finding-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .finding-title { min-width: 0; font-weight: 700; overflow-wrap: anywhere; } .finding-actions { display: flex; flex-wrap: wrap; gap: 6px; } .filter-chip, .link-button { min-width: 0; border: 1px solid var(--border); border-radius: 999px; background: #ffffff; color: #344054; cursor: pointer; font-size: 12px; font-weight: 700; line-height: 1.3; } .filter-chip { min-height: 28px; padding: 4px 9px; overflow-wrap: anywhere; text-align: left; } .filter-chip.active { border-color: #bdd7ff; background: #edf4ff; color: #1d4ed8; } .link-button { justify-self: start; min-height: 30px; padding: 5px 10px; } .link-button:disabled { cursor: default; opacity: 0.6; } .finding-meta, .detail-grid { color: var(--muted); font-size: 12px; line-height: 1.45; } .detail-panel { margin-top: 14px; } .detail-content { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; padding: 14px 16px 16px; } .detail-block { min-width: 0; padding: 2px 0 2px 12px; border-left: 3px solid #dbe5ee; } .detail-block-wide { grid-column: span 2; } .detail-block strong { display: block; margin-bottom: 8px; font-size: 12px; text-transform: uppercase; color: var(--muted); } .detail-table-frame { width: 100%; overflow: auto; } .detail-table { width: 100%; min-width: 720px; border-collapse: collapse; } .detail-table th, .detail-table td { padding: 8px 9px; border-bottom: 1px solid #edf0f4; text-align: left; vertical-align: top; font-size: 12px; } .detail-table th { color: var(--muted); font-size: 10px; font-weight: 800; text-transform: uppercase; } .command-list { display: grid; gap: 8px; } .command-list div { display: grid; gap: 4px; } .command-list span, .view-note { color: var(--muted); font-size: 11px; font-weight: 800; text-transform: uppercase; } .command-list code, .detail-pre { display: block; width: 100%; max-width: 100%; border: 1px solid #e3e8ef; border-radius: 8px; background: #f8fafc; color: #1f2937; font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; font-size: 12px; line-height: 1.45; overflow: auto; } .command-list code { padding: 8px 9px; white-space: pre-wrap; overflow-wrap: anywhere; } .detail-pre { min-height: 160px; max-height: 420px; margin: 8px 0 0; padding: 10px; white-space: pre-wrap; } .trace-reader-grid { display: grid; grid-template-columns: minmax(240px, 0.72fr) minmax(0, 1.28fr); gap: 12px; } .trace-turn-picker, .trace-frame-view { min-width: 0; } .trace-choice-list { display: grid; gap: 8px; margin-top: 8px; max-height: 420px; overflow: auto; } .trace-choice { display: grid; gap: 4px; width: 100%; padding: 9px 10px; border: 1px solid #d8e0ea; border-radius: 8px; background: #ffffff; color: #344054; cursor: pointer; text-align: left; } .trace-choice.active { border-color: #95c7ff; background: #edf6ff; } .trace-choice span { min-width: 0; font-size: 12px; font-weight: 800; overflow-wrap: anywhere; } .trace-choice small { color: var(--muted); font-size: 11px; overflow-wrap: anywhere; } .trace-frame-pre { min-height: 360px; max-height: 620px; } .trace-source-note { margin-top: 8px; color: var(--muted); } .final-response-block { margin-top: 12px; padding: 10px; border: 1px solid #b9e6cc; border-radius: 8px; background: #eefaf4; } .final-response-block.empty, .final-response-block.unavailable { border-color: #d8e0ea; background: #f8fafc; } .final-response-block strong { display: block; margin-bottom: 6px; color: #1f2937; font-size: 12px; text-transform: uppercase; } .final-response-text { min-height: 64px; max-height: 260px; margin: 8px 0 0; padding: 9px; border: 1px solid #d8e0ea; border-radius: 8px; background: #ffffff; color: #1f2937; font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; font-size: 12px; line-height: 1.45; overflow: auto; white-space: pre-wrap; } .empty-state { padding: 28px 16px; color: var(--muted); text-align: center; font-size: 13px; } .empty-state.compact { padding: 8px; text-align: left; } [hidden] { display: none !important; } @media (max-width: 980px) { .sentinel-shell { padding: 16px; } .sentinel-topbar { align-items: flex-start; flex-direction: column; } .sentinel-toolbar { justify-content: flex-start; width: 100%; } .metric-grid, .dashboard-grid, .detail-content { grid-template-columns: 1fr; } .runs-filter { grid-template-columns: repeat(2, minmax(0, 1fr)); } .findings-filter, .finding-aggregation { grid-template-columns: 1fr; } .detail-block-wide { grid-column: span 1; } .trace-reader-grid { grid-template-columns: 1fr; } .metric-card { min-height: 96px; } } @media (max-width: 560px) { .sentinel-shell { padding: 12px; } h1 { font-size: 19px; } .sentinel-toolbar > * { flex: 1 1 auto; } .status-pill { justify-content: center; } .icon-button { width: 100%; } .panel-header { align-items: flex-start; flex-direction: column; } .runs-filter { grid-template-columns: 1fr; } .findings-filter { grid-template-columns: 1fr; } }