:root { --bg: #f9f8f4; --bg-secondary: #f2f0ea; --bg-tertiary: #ebe7dc; --bg-soft: #f2f0ea; --surface: #ffffff; --bg-hover: #f2f0ea; --text: #0d0c0a; --text-secondary: #3c3830; --text-tertiary: #6c6660; --muted: #6c6660; --subtle: #9c9690; --border: #e5e1d7; --border-light: #ede9df; --line: #e5e1d7; --line-strong: #cac5b8; --accent: #0b3d2a; --accent-hover: #0f4e35; --accent-light: #ecf3ee; --accent-contrast: #ffffff; --sev-high: #9d2f25; --sev-high-bg: #f8ece9; --sev-medium: #8c6310; --sev-medium-bg: #f6eedb; --sev-low: #1c5c38; --sev-low-bg: #ecf3ee; --success: #1c5c38; --success-bg: #ecf3ee; --green: #1c5c38; --amber: #8c6310; --red: #9d2f25; --terminal-bg: #0d0e12; --terminal-bar: #181a21; --terminal-line: #2a2d37; --terminal-text: #f4f2eb; --terminal-muted: #9fa3ad; --shadow: 0 1px 3px rgba(13, 12, 10, 0.07); --shadow-lg: 0 20px 56px rgba(13, 12, 10, 0.13); --radius: 8px; --radius-sm: 4px; --radius-lg: 12px; --font-display: 'Playfair Display', Georgia, serif; --font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; --font-sans: var(--font); --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; /* Spacing scale */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-7: 32px; --space-8: 48px; /* Typography scale */ --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.0625rem; --text-xl: 1.375rem; --text-2xl: 2rem; /* Font weights */ --weight-normal: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700; --font-medium: var(--weight-medium); --font-semibold: var(--weight-semibold); --font-bold: var(--weight-bold); /* Confidence colors */ --conf-high: #1c5c38; --conf-high-bg: #ecf3ee; --conf-medium: #8c6310; --conf-medium-bg: #f6eedb; --conf-low: #6c6660; --conf-low-bg: #f2f0ea; /* Shadows (refined scale) */ --shadow-sm: 0 1px 3px rgba(13, 12, 10, 0.07); --shadow-md: 0 4px 14px rgba(13, 12, 10, 0.09); --shadow-xl: 0 20px 56px rgba(13, 12, 10, 0.13); /* Transitions */ --transition-fast: 0.1s ease; --transition-base: 0.15s ease; /* Layout */ --sidebar-width: 200px; --header-height: 47px; --explorer-header-height: 96px; /* Header frosted-glass bg (overridden per theme) */ --header-bg: rgba(249, 248, 244, 0.84); } /* ── Reset & Base ──────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 16px; } body { font-family: var(--font); background: var(--bg); color: var(--text); line-height: 1.65; -webkit-font-smoothing: antialiased; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } /* ── Layout ────────────────────────────────────────────────────────── */ #app { display: flex; min-height: 100vh; background: var(--bg); } .sidebar { width: var(--sidebar-width); background: var(--bg); border-right: 1px solid var(--border); display: flex; flex-direction: column; position: fixed; top: 0; left: 0; bottom: 0; z-index: 10; } .main-panel { margin-left: var(--sidebar-width); flex: 1; display: flex; flex-direction: column; min-height: 100vh; background: var(--bg); } .sidebar-header { padding: 14px 16px; display: flex; align-items: center; flex-direction: row; gap: var(--space-2); } .sidebar-logo-img { width: 44px; height: 44px; object-fit: contain; flex-shrink: 0; } .logo { font-family: var(--font-display); font-size: 1.4rem; font-weight: 700; color: var(--text); letter-spacing: 0; line-height: 1; } .version { font-size: var(--text-xs); color: var(--text-tertiary); font-family: var(--font-mono); } .target-switcher { position: relative; padding: 0 var(--space-3) var(--space-2); } .target-trigger, .target-option, .target-add-button { appearance: none; border: 0; font: inherit; cursor: pointer; } .target-trigger { width: 100%; min-height: 48px; display: grid; grid-template-columns: 32px minmax(0, 1fr) 12px; align-items: center; gap: var(--space-2); padding: 7px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); text-align: left; } .target-trigger:hover, .target-trigger[aria-expanded='true'] { border-color: var(--line-strong); background: var(--bg-secondary); } .target-avatar, .target-option-avatar { width: 32px; height: 32px; border-radius: var(--radius-sm); display: inline-flex; align-items: center; justify-content: center; background: var(--accent-light); color: var(--accent); font-weight: var(--weight-semibold); flex-shrink: 0; } .target-trigger-copy, .target-option-copy { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; } .target-name, .target-option-name { color: var(--text); font-size: var(--text-sm); font-weight: var(--weight-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .target-path, .target-option-path { color: var(--text-tertiary); font-size: 0.7rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .target-caret { width: 8px; height: 8px; border-right: 1.5px solid var(--text-tertiary); border-bottom: 1.5px solid var(--text-tertiary); transform: rotate(45deg) translateY(-2px); transition: transform var(--transition-base); } .target-caret.open { transform: rotate(225deg) translateY(-2px); } .target-menu { position: absolute; left: var(--space-3); right: var(--space-3); top: calc(100% - var(--space-1)); z-index: 30; padding: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-lg); } .target-options { display: flex; flex-direction: column; gap: var(--space-1); max-height: 220px; overflow-y: auto; } .target-option { display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: center; gap: var(--space-2); width: 100%; min-height: 42px; padding: 5px 6px; border-radius: var(--radius-sm); background: transparent; color: var(--text); text-align: left; } .target-option:hover:not(:disabled) { background: var(--bg-secondary); } .target-option.active { background: var(--accent-light); } .target-option:disabled { cursor: default; opacity: 0.7; } .target-option-avatar { width: 28px; height: 28px; font-size: 0.8rem; } .target-add-form { display: grid; grid-template-columns: minmax(0, 1fr) 30px; gap: var(--space-1); margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border-light); } .target-add-form input { min-width: 0; height: 30px; padding: 5px 8px; font-size: 0.75rem; } .target-add-button { width: 30px; height: 30px; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-contrast); font-size: 1rem; font-weight: var(--weight-semibold); } .target-add-button:disabled { opacity: 0.45; cursor: not-allowed; } .target-error { margin-top: var(--space-2); color: var(--sev-high); font-size: 0.72rem; line-height: 1.3; } .nav-list { list-style: none; padding: var(--space-3) var(--space-3); flex: 1; } .nav-link { display: flex; align-items: center; gap: var(--space-3); padding: 6px 10px; border-radius: var(--radius-sm); color: var(--text-secondary); font-size: var(--text-sm); font-weight: var(--weight-medium); transition: background var(--transition-base), color var(--transition-base); } .nav-link:hover { background: var(--bg-secondary); color: var(--text); text-decoration: none; } .nav-link.active { background: var(--accent-light); color: var(--accent); } .nav-section-header { padding: 16px 10px 4px; font-size: 0.7rem; font-weight: var(--weight-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-tertiary); } .nav-icon { display: flex; align-items: center; flex-shrink: 0; width: 18px; height: 18px; } .nav-icon svg { width: 18px; height: 18px; } .nav-separator { height: 1px; background: var(--border); margin: var(--space-2) var(--space-3); } .content { flex: 1; padding: 34px 42px 56px; max-width: 1280px; width: 100%; } /* ── Sidebar Footer & Meta ─────────────────────────────────────────── */ .sidebar-footer { border-top: 1px solid var(--border); padding: var(--space-1) var(--space-3); } .sidebar-footer .nav-list { padding: 0; } .sidebar-meta { padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); } .sidebar-meta-item { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-tertiary); margin-bottom: var(--space-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sidebar-meta-item svg { width: 14px; height: 14px; flex-shrink: 0; } .scan-indicator { display: none; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--sev-medium); margin-top: var(--space-1); } .scan-indicator.visible { display: flex; } /* ── Header Bar ────────────────────────────────────────────────────── */ .header-bar { display: flex; align-items: center; justify-content: space-between; height: var(--header-height); padding: 0 42px; border-bottom: 1px solid var(--border); background: var(--header-bg); position: sticky; top: 0; z-index: 5; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); } .header-left { display: flex; align-items: center; gap: var(--space-2); min-width: 0; } .header-right { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; } .header-right .btn { height: 26px; padding: 0 10px; font-size: 0.8rem; line-height: 1; } /* ── Breadcrumbs ───────────────────────────────────────────────────── */ .breadcrumbs { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-xs); min-width: 0; text-transform: uppercase; letter-spacing: 0.1em; } .breadcrumb-link { color: var(--text-tertiary); white-space: nowrap; } .breadcrumb-link:hover { color: var(--accent); text-decoration: none; } .breadcrumb-sep { color: var(--text-tertiary); font-size: var(--text-xs); user-select: none; margin: 0 var(--space-2); } .breadcrumb-current { color: var(--text); font-weight: var(--weight-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .header-search-input { width: 200px; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-secondary); color: var(--text-tertiary); font-family: var(--font); font-size: var(--text-sm); } .header-search-input:disabled { cursor: not-allowed; opacity: 0.6; } /* ── Layout Primitives ─────────────────────────────────────────────── */ .split-pane { display: flex; height: 100%; } .pane { flex: 1; overflow: auto; } .pane-resizer { width: 4px; background: var(--border); cursor: col-resize; flex-shrink: 0; } .pane-resizer:hover { background: var(--accent); } /* ── Tabs Base ─────────────────────────────────────────────────────── */ .tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: var(--space-4); } .tab { padding: var(--space-2) var(--space-4); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); border-bottom: 2px solid transparent; cursor: pointer; transition: color var(--transition-base), border-color var(--transition-base); background: none; border-top: none; border-left: none; border-right: none; font-family: var(--font); } .tab:hover { color: var(--text); } .tab.active { color: var(--accent); border-bottom-color: var(--accent); } /* ── Cards ─────────────────────────────────────────────────────────── */ .card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow-sm); } .card-header { font-weight: 600; font-size: 0.72rem; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 8px; } .card-value { font-size: 2.25rem; font-weight: 700; font-family: var(--font-display); } .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 24px; } /* ── Badges ────────────────────────────────────────────────────────── */ .badge { display: inline-block; padding: 2px 7px; border-radius: var(--radius-sm); border: 1px solid currentColor; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.4; } .badge-high { background: var(--sev-high-bg); color: var(--sev-high); } .badge-medium { background: var(--sev-medium-bg); color: var(--sev-medium); } .badge-low { background: var(--sev-low-bg); color: var(--sev-low); } .badge-success { background: var(--success-bg); color: var(--success); } /* ── Tables ────────────────────────────────────────────────────────── */ .table-wrap { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); } table { width: 100%; border-collapse: collapse; } th { text-align: left; padding: 11px 16px; font-size: 0.72rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.1em; background: var(--bg-secondary); border-bottom: 1px solid var(--border); } td { padding: 11px 16px; border-bottom: 1px solid var(--border-light); font-size: 0.9rem; } tr:last-child td { border-bottom: none; } tr:hover td { background: var(--bg-secondary); } .clickable { cursor: pointer; } /* ── Buttons ───────────────────────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: var(--radius-sm); font-size: 0.85rem; font-weight: 600; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; transition: background var(--transition-base), border-color var(--transition-base); } .btn:hover { background: var(--bg-secondary); border-color: var(--line-strong); } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .btn:disabled:hover { background: var(--bg); border-color: var(--border); } .btn-primary { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); } .btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); } .btn-primary:disabled:hover { opacity: 0.5; background: var(--accent); } .btn-danger { color: var(--sev-high); border-color: var(--sev-high); } .btn-sm { padding: 4px 10px; font-size: 0.8rem; } /* ── Forms ─────────────────────────────────────────────────────────── */ .form-group { margin-bottom: 16px; } .form-group label { display: block; font-size: 0.8rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 4px; } input, select { width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font-family: var(--font); font-size: 0.9rem; } input:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); } input.input-error, select.input-error { border-color: var(--sev-high); box-shadow: 0 0 0 2px var(--sev-high-bg); } .search-input { max-width: 320px; } /* ── Filter Bar ────────────────────────────────────────────────────── */ .filter-bar { display: flex; gap: 12px; align-items: center; margin-bottom: 16px; flex-wrap: wrap; } .filter-bar select, .filter-bar input { width: auto; min-width: 140px; } /* ── Code Context ──────────────────────────────────────────────────── */ .code-block { background: var(--terminal-bg); border: 1px solid var(--terminal-line); border-radius: var(--radius); overflow-x: auto; font-family: var(--font-mono); font-size: 0.82rem; line-height: 1.6; color: var(--terminal-text); } .code-line { display: flex; padding: 0 16px; } .code-line.highlight { background: rgba(140, 99, 16, 0.26); } .line-number { color: var(--terminal-muted); min-width: 40px; text-align: right; padding-right: 16px; user-select: none; } .line-content { white-space: pre; } /* ── Finding Detail ────────────────────────────────────────────────── */ .detail-header { margin-bottom: 24px; } .detail-header h2 { font-size: 1.5rem; font-weight: 600; margin-bottom: 4px; font-family: var(--font-display); } .detail-meta { display: flex; gap: 12px; align-items: center; color: var(--text-secondary); font-size: 0.85rem; } .detail-section { margin-bottom: 24px; } .detail-section h3 { font-size: 0.85rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.3px; margin-bottom: 8px; } .label-list { display: flex; gap: 8px; flex-wrap: wrap; } .label-item { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 4px 10px; font-size: 0.82rem; } .label-key { font-weight: 600; color: var(--text-secondary); } .label-value { color: var(--text); } /* ── Page Header ───────────────────────────────────────────────────── */ .page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; gap: var(--space-4); } .page-header h2 { font-family: var(--font-display); font-size: 2rem; font-weight: 700; line-height: 1; letter-spacing: 0; } /* (Pagination styles moved to Enhanced Pagination section below) */ /* ── Empty/Loading/Error States ────────────────────────────────────── */ .loading, .empty-state, .error-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 60px 20px; color: var(--text-tertiary); text-align: center; } .empty-state h3 { font-size: 1.1rem; color: var(--text-secondary); margin-bottom: 8px; } .error-state { color: var(--sev-high); } /* ── Status Indicator ──────────────────────────────────────────────── */ .status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; } .status-dot.running { background: var(--sev-medium); animation: pulse 1.5s infinite; } .status-dot.completed { background: var(--success); } .status-dot.failed { background: var(--sev-high); } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* ── Sortable Headers ──────────────────────────────────────────────── */ th.sortable { cursor: pointer; user-select: none; transition: color var(--transition-base); } th.sortable:hover { color: var(--accent); } th.sortable.active { color: var(--accent); } th.sortable .sort-arrow { margin-left: 4px; font-size: var(--text-xs); } /* ── Alternating Rows ─────────────────────────────────────────────── */ tbody tr:nth-child(even) td { background: var(--bg-secondary); } tbody tr:hover td { background: var(--bg-tertiary); } /* ── Checkbox Column ──────────────────────────────────────────────── */ .col-checkbox { width: 40px; text-align: center; } .col-checkbox input[type='checkbox'] { width: auto; min-width: auto; cursor: pointer; } tr.selected td { background: var(--accent-light); } /* ── Confidence Badges ────────────────────────────────────────────── */ .badge-conf-high { background: var(--conf-high-bg); color: var(--conf-high); } .badge-conf-medium { background: var(--conf-medium-bg); color: var(--conf-medium); } .badge-conf-low { background: var(--conf-low-bg); color: var(--conf-low); } /* ── Status Badges ────────────────────────────────────────────────── */ .badge-status-open { background: var(--sev-high-bg); color: var(--sev-high); } .badge-status-validated { background: var(--conf-high-bg); color: var(--conf-high); } .badge-status-suppressed { background: var(--conf-low-bg); color: var(--conf-low); } /* ── Triage State Badges ─────────────────────────────────────────── */ .badge-triage-open { background: var(--sev-high-bg); color: var(--sev-high); } .badge-triage-investigating { background: var(--sev-medium-bg); color: var(--sev-medium); } .badge-triage-false_positive { background: var(--bg-secondary); color: var(--muted); } .badge-triage-accepted_risk { background: var(--sev-medium-bg); color: var(--sev-medium); } .badge-triage-suppressed { background: var(--conf-low-bg); color: var(--conf-low); } .badge-triage-fixed { background: var(--success-bg); color: var(--success); } /* ── Triage Actions Panel (Finding Detail) ───────────────────────── */ .triage-actions { margin: var(--space-4) 0; padding: var(--space-4); background: var(--bg-secondary); border-radius: var(--radius); border: 1px solid var(--border); } .triage-current-note { margin-bottom: var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); } .triage-buttons { display: flex; gap: var(--space-2); flex-wrap: wrap; } .btn-triage { text-transform: capitalize; font-size: var(--text-xs); } .btn-triage-investigating { border-color: var(--sev-medium); color: var(--sev-medium); } .btn-triage-false_positive { border-color: var(--line-strong); color: var(--muted); } .btn-triage-accepted_risk { border-color: var(--sev-medium); color: var(--sev-medium); } .btn-triage-suppressed { border-color: var(--conf-low); color: var(--conf-low); } .btn-triage-fixed { border-color: var(--success); color: var(--success); } .btn-triage-open { border-color: var(--sev-high); color: var(--sev-high); } .triage-note-input { margin-top: var(--space-3); } .triage-note-input textarea { width: 100%; padding: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: inherit; font-size: var(--text-sm); resize: vertical; background: var(--bg); color: var(--text); } .triage-note-input textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); } .triage-note-actions { display: flex; gap: var(--space-2); margin-top: var(--space-2); } /* ── Triage Page ─────────────────────────────────────────────────── */ .triage-page { max-width: 1400px; } /* Hero / summary */ .triage-hero { margin-bottom: var(--space-5); padding-bottom: var(--space-4); border-bottom: 1px solid var(--border); } .triage-hero-row { display: flex; align-items: center; gap: var(--space-4); margin-bottom: 0; flex-wrap: wrap; } .triage-hero-title { font-size: 1.5rem; font-weight: 600; line-height: 1.2; color: var(--text); letter-spacing: 0; margin: 0; } .triage-hero-toggle { display: inline-flex; align-items: center; gap: 4px; background: transparent; border: none; color: var(--text-secondary); font-size: var(--text-sm); cursor: pointer; padding: 4px 6px; border-radius: var(--radius-sm); } .triage-hero-toggle:hover { color: var(--text); background: var(--bg-secondary); } .triage-caret { display: inline-block; font-size: 0.7rem; line-height: 1; transition: transform 120ms ease-out; } .triage-caret.open { transform: rotate(-180deg); } .triage-hero-severity { display: flex; align-items: center; gap: var(--space-5); font-size: var(--text-sm); color: var(--text-secondary); } .triage-sev-stat { display: inline-flex; align-items: baseline; gap: 6px; } .triage-sev-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; align-self: center; } .triage-sev-high .triage-sev-dot { background: var(--sev-high); } .triage-sev-medium .triage-sev-dot { background: var(--sev-medium); } .triage-sev-low .triage-sev-dot { background: var(--sev-low); } .triage-sev-count { font-size: var(--text-base); font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; } .triage-sev-name { text-transform: uppercase; letter-spacing: 0.04em; font-size: var(--text-xs); font-weight: 500; } .triage-state-row { display: flex; gap: var(--space-2); margin-top: var(--space-4); flex-wrap: wrap; } .triage-state-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--border); background: var(--bg); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-xs); color: var(--text-secondary); transition: border-color var(--transition-base), background var(--transition-base); } .triage-state-chip:hover { border-color: var(--text-tertiary); color: var(--text); } .triage-state-chip.active { background: var(--accent-light); color: var(--accent); border-color: var(--accent); } .triage-state-chip.muted { opacity: 0.55; } .triage-state-chip .triage-state-count { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); } .triage-state-chip.active .triage-state-count { color: var(--accent); } .triage-state-chip .triage-state-label { text-transform: capitalize; } /* Tabs */ .triage-tabs-row { display: flex; align-items: flex-end; justify-content: space-between; border-bottom: 1px solid var(--border); margin-bottom: var(--space-4); gap: var(--space-4); flex-wrap: wrap; } .triage-tabs { display: flex; gap: var(--space-1); padding-bottom: 0; } .triage-tab { padding: var(--space-2) var(--space-4); background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; font-size: var(--text-sm); font-weight: 500; color: var(--text-secondary); display: inline-flex; align-items: center; gap: 6px; transition: color 0.15s, border-color 0.15s; } .triage-tab:hover { color: var(--text); } .triage-tab.active { color: var(--text); border-bottom-color: var(--accent); } .triage-tab.empty { color: var(--text-tertiary); } .triage-tab.empty:hover { color: var(--text-secondary); } .triage-tab-count { font-size: var(--text-xs); padding: 1px 6px; border-radius: var(--radius-sm); background: var(--bg-tertiary); color: var(--text-secondary); font-variant-numeric: tabular-nums; } .triage-tab.active .triage-tab-count { background: var(--accent-light); color: var(--accent); } /* Controls row */ .triage-controls { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; } .triage-control-btn { display: inline-flex; align-items: center; gap: 6px; } .triage-control-btn strong { font-weight: 600; color: var(--text); } .triage-search { flex: 1; min-width: 200px; max-width: 360px; padding: 6px 10px; font-size: var(--text-sm); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); color: var(--text); } .triage-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); } .triage-result-count { margin-left: auto; font-size: var(--text-xs); color: var(--text-secondary); font-variant-numeric: tabular-nums; } /* Rule filter chips */ .triage-rule-filter { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; font-size: var(--text-sm); } .triage-rule-filter-label { color: var(--text-secondary); font-weight: 500; } .rule-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border: 1px solid var(--border); background: var(--bg); color: var(--text); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-xs); font-family: var(--font-mono); transition: border-color var(--transition-base), background var(--transition-base); } .rule-chip:hover { border-color: var(--text-tertiary); background: var(--bg-secondary); } .rule-chip.active { background: var(--accent-light); border-color: var(--accent); color: var(--accent); } .rule-chip-count { background: var(--bg-tertiary); color: var(--text-secondary); padding: 0 6px; border-radius: var(--radius-sm); font-family: var(--font); font-weight: 600; font-variant-numeric: tabular-nums; } .rule-chip.active .rule-chip-count { background: var(--bg); color: var(--accent); } .rule-chip-x { font-size: 0.9rem; line-height: 1; opacity: 0.8; } .triage-rule-more, .triage-rule-clear { background: transparent; border: none; color: var(--text-secondary); font-size: var(--text-xs); cursor: pointer; padding: 3px 8px; border-radius: var(--radius-sm); } .triage-rule-more:hover, .triage-rule-clear:hover { color: var(--text); background: var(--bg-secondary); } /* Sticky bulk bar for triage */ .triage-bulk-bar { position: sticky; top: var(--header-height); z-index: 4; } /* Finding list */ .finding-list { display: flex; flex-direction: column; gap: var(--space-3); } .finding-list-more { display: flex; align-items: center; justify-content: center; gap: var(--space-3); padding: var(--space-4) 0; color: var(--text-secondary); font-size: var(--text-xs); } .finding-list-more-count { font-variant-numeric: tabular-nums; } /* Group */ .finding-group { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); overflow: hidden; } .finding-group-header { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-bottom: 1px solid var(--border); font-size: var(--text-sm); } .finding-group-header.collapsed { border-bottom: none; } .finding-group-check { width: auto; min-width: auto; cursor: pointer; } .finding-group-toggle { display: inline-flex; align-items: center; gap: 8px; background: none; border: none; cursor: pointer; padding: 2px 4px; color: var(--text); font-size: var(--text-sm); font-weight: 500; } .finding-group-toggle:hover { color: var(--accent); } .finding-group-label { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text); } .finding-group-count { background: var(--bg-tertiary); color: var(--text-secondary); padding: 1px 8px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: 600; font-variant-numeric: tabular-nums; font-family: var(--font); } .finding-group-sev { margin-left: auto; display: flex; gap: var(--space-2); } .finding-group-sev-pill { font-size: var(--text-xs); font-weight: 500; padding: 1px 8px; border-radius: var(--radius-sm); background: var(--bg); border: 1px solid var(--border); color: var(--text-secondary); } .finding-group-sev-pill.sev-high { color: var(--sev-high); border-color: var(--sev-high-bg); background: var(--sev-high-bg); } .finding-group-sev-pill.sev-medium { color: var(--sev-medium); border-color: var(--sev-medium-bg); background: var(--sev-medium-bg); } .finding-group-sev-pill.sev-low { color: var(--sev-low); border-color: var(--sev-low-bg); background: var(--sev-low-bg); } .finding-group-body { display: flex; flex-direction: column; } /* Finding row */ .finding-row { border-bottom: 1px solid var(--border-light); background: var(--bg); transition: background var(--transition-base); } .finding-row:last-child { border-bottom: none; } .finding-row.selected { background: var(--accent-light); } .finding-row:hover:not(.selected) { background: var(--bg-secondary); } .finding-row-main { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); cursor: pointer; } .finding-row-check { width: auto; min-width: auto; cursor: pointer; flex-shrink: 0; } .finding-row-sev { display: inline-flex; align-items: center; justify-content: center; padding: 3px 10px; border-radius: var(--radius-sm); font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; min-width: 60px; flex-shrink: 0; } .finding-row-sev.sev-high { background: var(--sev-high-bg); color: var(--sev-high); } .finding-row-sev.sev-medium { background: var(--sev-medium-bg); color: var(--sev-medium); } .finding-row-sev.sev-low { background: var(--sev-low-bg); color: var(--sev-low); } .finding-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; } .finding-row-title { display: flex; align-items: center; gap: var(--space-2); min-width: 0; } .finding-row-rule { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .finding-row-state { text-transform: uppercase; font-size: 0.65rem; letter-spacing: 0.05em; padding: 1px 6px; border-radius: var(--radius-sm); flex-shrink: 0; } .finding-row-meta { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-xs); color: var(--text-tertiary); min-width: 0; } .finding-row-path { font-family: var(--font-mono); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .finding-row-line { color: var(--text-tertiary); } .finding-row-conf { text-transform: uppercase; font-size: 0.65rem; letter-spacing: 0.04em; color: var(--text-tertiary); } .finding-row-conf.conf-medium { color: var(--conf-medium); } .finding-row-conf.conf-low { color: var(--conf-low); } .finding-row-lang { text-transform: uppercase; font-size: 0.65rem; letter-spacing: 0.04em; color: var(--text-tertiary); } .finding-row-actions { display: flex; align-items: center; gap: var(--space-1); flex-shrink: 0; } .finding-row-investigate { padding: 4px 12px; } .finding-row-kebab { padding: 2px 8px; font-size: 1rem; line-height: 1; color: var(--text-secondary); background: transparent; border-color: transparent; } .finding-row-kebab:hover { background: var(--bg-secondary); border-color: var(--border); } .finding-row-chevron { background: transparent; border: none; color: var(--text-tertiary); cursor: pointer; padding: 4px 6px; border-radius: var(--radius-sm); } .finding-row-chevron:hover { background: var(--bg-secondary); color: var(--text); } .chev { display: inline-block; font-size: 0.75rem; line-height: 1; transition: transform 120ms ease-out; } .chev.open { transform: rotate(-180deg); } /* Row details */ .finding-row-details { padding: var(--space-3) var(--space-4) var(--space-4) 96px; background: var(--bg-secondary); border-top: 1px solid var(--border-light); } .finding-row-details-grid { display: grid; grid-template-columns: 90px 1fr; gap: var(--space-3) var(--space-4); align-items: baseline; } .finding-row-details-item { display: contents; } .finding-row-details-label { text-transform: uppercase; font-size: 0.7rem; letter-spacing: 0.05em; color: var(--text-tertiary); font-weight: 600; padding-top: 2px; } .finding-row-details-path { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text); word-break: break-all; } .finding-row-details-text { font-size: var(--text-sm); color: var(--text); line-height: 1.5; } .finding-row-details-labels { display: flex; gap: 6px; flex-wrap: wrap; } .finding-row-details-actions { display: flex; gap: var(--space-2); } /* Misc retained */ .triage-audit-table td { vertical-align: middle; } .triage-arrow { color: var(--text-secondary); margin: 0 2px; } .triage-sync-controls { display: flex; align-items: center; gap: var(--space-2); padding-bottom: var(--space-2); font-size: var(--text-xs); } .triage-sync-status { display: flex; align-items: center; gap: 6px; color: var(--text-secondary); } .triage-sync-text { font-variant-numeric: tabular-nums; } .triage-sync-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; } .triage-sync-dot.synced { background: var(--success); } .triage-sync-dot.unsynced { background: var(--text-tertiary); } /* ── Suppress by Pattern Modal ───────────────────────────────────── */ .suppress-modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); display: flex; align-items: center; justify-content: center; z-index: 2000; } .suppress-modal { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-6); min-width: 400px; max-width: 600px; box-shadow: var(--shadow-lg); } .suppress-modal h3 { margin: 0 0 var(--space-4) 0; } .suppress-options { display: flex; flex-direction: column; gap: var(--space-2); } .suppress-opt { text-align: left; font-size: var(--text-sm); } /* ── Bulk Action Bar ──────────────────────────────────────────────── */ .bulk-action-bar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-4); background: var(--accent-light); border: 1px solid var(--accent); border-radius: var(--radius); margin-bottom: var(--space-3); font-size: var(--text-sm); color: var(--accent); font-weight: var(--weight-medium); opacity: 0; transform: translateY(-4px); max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: 0; border-width: 0; overflow: hidden; pointer-events: none; transition: opacity 120ms ease-out, transform 120ms ease-out, max-height 160ms ease-out, padding 160ms ease-out, margin-bottom 160ms ease-out, border-width 160ms ease-out; } .bulk-action-bar.visible { opacity: 1; transform: translateY(0); max-height: 80px; padding-top: var(--space-2); padding-bottom: var(--space-2); margin-bottom: var(--space-3); border-width: 1px; pointer-events: auto; overflow: visible; } .bulk-action-bar .bulk-count { flex: 1; } .bulk-actions { display: flex; align-items: center; gap: var(--space-2); } .bulk-menu-btn { display: inline-flex; align-items: center; gap: 4px; } .bulk-menu-btn--warning { color: var(--sev-high); border-color: var(--sev-high); } .bulk-menu-btn--warning:hover:not(:disabled) { background: color-mix(in srgb, var(--sev-high) 8%, transparent); border-color: var(--sev-high); } .bulk-caret { display: inline-block; font-size: 0.7rem; line-height: 1; transition: transform 120ms ease-out; } .bulk-caret--open { transform: rotate(-180deg); } .bulk-divider { width: 1px; align-self: stretch; margin: 0 var(--space-1); background: color-mix(in srgb, var(--accent) 30%, transparent); } .bulk-copy-btn { color: var(--text-secondary); border-color: transparent; background: transparent; } .bulk-copy-btn:hover:not(:disabled) { color: var(--text); background: var(--bg-secondary); border-color: var(--border); } /* ── Dropdown ─────────────────────────────────────────────────────── */ .dropdown { position: relative; display: inline-block; } .dropdown-trigger { display: inline-block; } .dropdown-menu { position: absolute; top: calc(100% + 4px); min-width: 220px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 4px; z-index: 1000; display: flex; flex-direction: column; } .dropdown-menu--left { left: 0; } .dropdown-menu--right { right: 0; } .dropdown-item { display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: 6px 10px; border: none; background: transparent; color: var(--text); font-size: var(--text-sm); text-align: left; cursor: pointer; border-radius: var(--radius-sm); font-weight: 400; } .dropdown-item:hover { background: var(--bg-secondary); } .dropdown-item--warning { color: var(--sev-high); } .dropdown-item--warning:hover { background: color-mix(in srgb, var(--sev-high) 8%, transparent); } .dropdown-item-check { width: 14px; flex-shrink: 0; color: var(--accent); font-size: 0.85rem; text-align: center; } .dropdown-item-label { flex: 1; } .dropdown-item-hint { color: var(--text-tertiary); font-size: var(--text-xs); font-style: italic; } /* ── Copy button ────────────────────────────────────────────────── */ .copy-btn--copied { background: var(--success); color: var(--bg); border-color: var(--success); } .copy-btn--failed { background: var(--sev-high); color: var(--bg); border-color: var(--sev-high); } /* Icon-only variant */ .copy-btn--icon { display: inline-flex; align-items: center; justify-content: center; padding: 4px 6px; line-height: 1; } .copy-btn--icon svg { display: block; } .copy-btn--icon:hover:not(:disabled) { background: transparent; border-color: var(--border); } /* Finding detail header: title + copy button on one row */ .detail-title-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); } .detail-title-row h2 { margin: 0; flex: 1; min-width: 0; } /* ── Enhanced Pagination ──────────────────────────────────────────── */ .pagination { display: flex; gap: 8px; align-items: center; justify-content: space-between; margin-top: 16px; color: var(--text-secondary); font-size: 0.85rem; } .pagination-left, .pagination-right { display: flex; align-items: center; gap: var(--space-2); } .pagination-center { display: flex; align-items: center; gap: var(--space-2); } .pagination select { width: auto; min-width: 60px; padding: 4px 8px; font-size: var(--text-sm); } /* ── Cell Styles ──────────────────────────────────────────────────── */ .cell-path { font-family: var(--font-mono); font-size: 0.82rem; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* ── Filter Bar Enhancements ──────────────────────────────────────── */ .filter-bar .filter-count { font-size: var(--text-sm); color: var(--text-secondary); white-space: nowrap; } .filter-bar .btn-clear { font-size: var(--text-sm); white-space: nowrap; } /* ── Responsive ────────────────────────────────────────────────────── */ @media (max-width: 768px) { .sidebar { width: 100%; position: static; border-right: none; border-bottom: 1px solid var(--border); } .sidebar-header { display: flex; align-items: center; gap: 8px; padding: 12px 16px; } .nav-list { display: flex; gap: 4px; padding: 4px 8px; overflow-x: auto; } .nav-link { font-size: var(--text-sm); padding: 6px 10px; white-space: nowrap; } .nav-link span:not(.nav-icon) { display: none; } .nav-icon { margin: 0; } .nav-separator { display: none; } .sidebar-meta { display: none; } .sidebar-footer { border-top: none; padding: 0; } .sidebar-footer .nav-list { padding: 0 8px 4px; } .main-panel { margin-left: 0; } .content { padding: 16px; } .header-bar { padding: 0 16px; } .header-search-input { display: none; } #app { flex-direction: column; } .card-grid { grid-template-columns: repeat(2, 1fr); } } /* ── Add Rule Form ─────────────────────────────────────────────────── */ .inline-form { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 16px; } .inline-form .form-group { margin-bottom: 0; } .inline-form input, .inline-form select { min-width: 120px; } /* ── Finding Detail Panel ─────────────────────────────────────────── */ .detail-panel { padding: var(--space-4) 0; } .detail-panel h2 { font-size: var(--text-xl); font-weight: var(--weight-semibold); margin-bottom: var(--space-2); } .detail-panel .badge-row { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; margin-bottom: var(--space-3); } .detail-panel .file-location { display: inline-block; font-family: var(--font-mono); font-size: var(--text-sm); color: var(--accent); cursor: pointer; margin-bottom: var(--space-4); text-decoration: none; } .detail-panel .file-location:hover { text-decoration: underline; } .evidence-card { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-3); margin-bottom: var(--space-2); font-size: var(--text-sm); } .evidence-card .evidence-kind { font-weight: var(--weight-semibold); text-transform: uppercase; font-size: var(--text-xs); letter-spacing: 0.3px; color: var(--text-secondary); margin-bottom: var(--space-1); } .evidence-card .evidence-snippet { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text); background: var(--bg); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); margin-top: var(--space-1); white-space: pre; overflow-x: auto; } .sanitizer-badge-none { background: var(--conf-low-bg); color: var(--conf-low); } .sanitizer-badge-bypassed { background: var(--sev-medium-bg); color: var(--sev-medium); } .sanitizer-badge-applied { background: var(--conf-high-bg); color: var(--conf-high); } .section-toggle { display: flex; align-items: center; gap: var(--space-2); cursor: pointer; user-select: none; font-size: 0.85rem; font-weight: var(--weight-semibold); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.3px; margin-bottom: var(--space-2); padding: var(--space-1) 0; } .section-toggle .toggle-arrow { font-size: var(--text-xs); transition: transform var(--transition-base); } .section-toggle .toggle-arrow.collapsed { transform: rotate(-90deg); } .section-body.collapsed { display: none; } .detail-panel .related-row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-sm); cursor: pointer; } .detail-panel .related-row:hover { background: var(--bg-tertiary); } .evidence-note { font-size: var(--text-sm); color: var(--text-secondary); padding: var(--space-1) 0; } /* ── Flow Timeline ───────────────────────────────────────────────── */ .flow-timeline { display: flex; flex-direction: column; gap: 0; padding: var(--space-2) 0; } .flow-step { display: flex; gap: var(--space-3); border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2); } .flow-step-connector { display: flex; flex-direction: column; align-items: center; width: 16px; flex-shrink: 0; } .flow-step-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; } .flow-step-line { width: 2px; flex: 1; background: var(--border); min-height: 8px; } .flow-step-card { flex: 1; min-width: 0; padding-bottom: var(--space-2); } .flow-step-badge { font-weight: var(--weight-semibold); text-transform: uppercase; font-size: var(--text-xs); letter-spacing: 0.3px; } .flow-step-snippet { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text); background: var(--bg); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); margin-top: 4px; white-space: pre; overflow-x: auto; border: 1px solid var(--border); } .flow-step-cross-file .flow-step-card { border-left: 2px solid var(--sev-medium); } .confidence-limiters { list-style: disc; padding-left: 20px; margin: var(--space-1) 0 0 0; font-size: var(--text-sm); color: var(--text-secondary); } .confidence-limiters li { padding: 2px 0; } /* ── State Transition Card ────────────────────────────────────────── */ .state-transition-card { background: var(--bg-secondary); border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: var(--radius-sm); padding: var(--space-4); margin-bottom: var(--space-3); } .state-machine-label { font-weight: var(--weight-semibold); text-transform: uppercase; font-size: var(--text-xs); letter-spacing: 0.3px; color: var(--text-secondary); margin-bottom: var(--space-2); } .state-subject { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); font-size: var(--text-sm); } .state-subject-label { color: var(--text-secondary); } .state-subject-name { font-family: var(--font-mono); font-size: var(--text-sm); background: var(--bg); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); border: 1px solid var(--border); } .state-transition-visual { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); background: var(--bg); border-radius: var(--radius-sm); border: 1px solid var(--border); margin-bottom: var(--space-2); } .state-from, .state-to { font-family: var(--font-mono); font-weight: var(--weight-semibold); font-size: var(--text-base); padding: var(--space-1) var(--space-3); border-radius: var(--radius-sm); } .state-from { background: var(--sev-low-bg); color: var(--sev-low); } .state-to { background: var(--sev-high-bg); color: var(--sev-high); } .state-arrow { font-size: var(--text-xl); color: var(--text-tertiary); } .state-acquire-location { font-size: var(--text-xs); color: var(--text-secondary); margin-top: var(--space-2); } .state-remediation { background: var(--accent-light); border: 1px solid var(--accent); border-radius: var(--radius-sm); padding: var(--space-3); margin-top: var(--space-3); font-size: var(--text-sm); color: var(--text); line-height: 1.5; } .state-remediation-label { font-weight: var(--weight-semibold); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.3px; color: var(--accent); margin-bottom: var(--space-1); } /* ── Finding Detail: header + meta ─────────────────────────────────── */ .finding-heading { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin: 0; } .finding-rule-id { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--text); letter-spacing: 0; } .severity-pill { display: inline-flex; align-items: center; padding: 2px 10px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--weight-bold); text-transform: uppercase; letter-spacing: 0.6px; line-height: 1.6; } .severity-pill-high { background: var(--sev-high-bg); color: var(--sev-high); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sev-high) 25%, transparent); } .severity-pill-medium { background: var(--sev-medium-bg); color: var(--sev-medium); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sev-medium) 25%, transparent); } .severity-pill-low { background: var(--sev-low-bg); color: var(--sev-low); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sev-low) 25%, transparent); } .finding-meta { margin-bottom: var(--space-5); color: var(--text-secondary); font-size: var(--text-sm); line-height: 1.7; } .finding-meta-item { color: var(--text-secondary); } .finding-meta-sep { margin: 0 var(--space-2); color: var(--text-tertiary); } .finding-detail .detail-section { padding-top: var(--space-4); margin-top: var(--space-4); border-top: 1px solid var(--border-light); } .finding-detail .detail-section:first-of-type { border-top: none; padding-top: 0; margin-top: 0; } .finding-detail .section-toggle { margin-bottom: var(--space-3); } /* ── Finding Detail: status control ─────────────────────────────────── */ .status-control { margin: var(--space-4) 0 var(--space-5) 0; padding: var(--space-3) var(--space-4); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); } .status-control-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; } .status-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.3px; color: var(--text-secondary); } .status-trigger { display: inline-flex; align-items: center; gap: var(--space-2); padding: 6px 10px; min-width: 180px; border: 1px solid var(--border); background: var(--bg); color: var(--text); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm); text-align: left; } .status-trigger:hover { border-color: var(--text-tertiary); } .status-trigger:disabled { opacity: 0.6; cursor: not-allowed; } .status-value { flex: 1; text-transform: capitalize; } .status-caret { color: var(--text-tertiary); transition: transform var(--transition-base); } .status-caret.open { transform: rotate(180deg); } .status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--text-tertiary); } .status-dot-open { background: var(--sev-high); } .status-dot-investigating { background: var(--sev-medium); } .status-dot-fixed { background: var(--success); } .status-dot-false_positive, .status-dot-accepted_risk, .status-dot-suppressed { background: var(--conf-low); } .status-group { display: flex; flex-direction: column; padding: 2px 0; } .status-group + .status-group { border-top: 1px solid var(--border-light); margin-top: 4px; padding-top: 6px; } .status-group-heading { padding: 4px 10px 2px; font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-tertiary); } .status-note-toggle { background: none; border: none; padding: 0; font-size: var(--text-sm); color: var(--accent); cursor: pointer; text-decoration: none; } .status-note-toggle:hover { text-decoration: underline; } .status-current-note { margin-top: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--bg); border-radius: var(--radius-sm); font-size: var(--text-sm); color: var(--text-secondary); border-left: 2px solid var(--border); } .status-note-input { margin-top: var(--space-3); } .status-note-input textarea { width: 100%; padding: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: inherit; font-size: var(--text-sm); resize: vertical; background: var(--bg); color: var(--text); } .status-note-input textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); } .status-note-actions { display: flex; gap: var(--space-2); margin-top: var(--space-2); } /* ── Finding Detail: structured explanation ─────────────────────────── */ .struct-expl { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-4); margin: 0; font-size: var(--text-sm); line-height: 1.6; } .struct-expl-row { display: contents; } .struct-expl dt { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.3px; color: var(--text-secondary); padding-top: 2px; } .struct-expl dd { margin: 0; color: var(--text); } .struct-expl-code { font-family: var(--font-mono); font-size: var(--text-sm); background: var(--bg-secondary); padding: 1px 6px; border-radius: var(--radius-sm); border: 1px solid var(--border); } /* ── Finding Detail: flow emphasis ──────────────────────────────────── */ .flow-step-num { font-size: var(--text-xs); color: var(--text-tertiary); } .flow-step-endpoint .flow-step-card { background: var(--bg-secondary); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-1); } .flow-step-endpoint .flow-step-badge { font-size: var(--text-xs); padding: 1px 6px; border-radius: var(--radius-sm); } .flow-step-source .flow-step-card { border-left: 3px solid var(--success); } .flow-step-source .flow-step-badge { background: var(--success-bg); color: var(--success) !important; } .flow-step-sink .flow-step-card { border-left: 3px solid var(--sev-high); background: var(--sev-high-bg); } .flow-step-sink .flow-step-badge { background: var(--bg); color: var(--sev-high) !important; } .flow-step-sink .flow-step-dot { box-shadow: 0 0 0 3px color-mix(in srgb, var(--sev-high) 20%, transparent); } .flow-expand-toggle { align-self: flex-start; margin: var(--space-2) 0 0 28px; background: none; border: none; padding: 0; color: var(--accent); font-size: var(--text-sm); cursor: pointer; } .flow-expand-toggle:hover { text-decoration: underline; } /* ── Finding Detail: how-to-fix ─────────────────────────────────────── */ .how-to-fix-list { list-style: disc; padding-left: 20px; margin: 0; font-size: var(--text-sm); line-height: 1.6; } .how-to-fix-list li { padding: 2px 0; color: var(--text); } /* ── Finding Detail: dynamic verification ─────────────────────────── */ .badge-dyn-confirmed { background: var(--success-bg); color: var(--success); } .badge-dyn-partiallyconfirmed { background: var(--conf-medium-bg); color: var(--conf-medium); } .badge-dyn-notconfirmed { background: var(--bg-secondary); color: var(--text-secondary); } .badge-dyn-inconclusive { background: var(--sev-medium-bg); color: var(--sev-medium); } .badge-dyn-unsupported { background: var(--conf-low-bg); color: var(--conf-low); } .dynamic-verdict-section { display: flex; flex-direction: column; gap: var(--space-3); font-size: var(--text-sm); line-height: 1.45; } .dynamic-verdict-badge-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); } .dynamic-toolchain-match { display: inline-flex; align-items: center; min-height: 22px; padding: 2px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-secondary); color: var(--text-secondary); font-size: var(--text-xs); } .repro-panel, .dynamic-verdict-detail, .dynamic-attempts { border: 1px solid var(--border-light); border-radius: 6px; background: var(--bg); padding: var(--space-3); } .repro-cmd-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; flex-wrap: wrap; } .repro-label, .dynamic-attempts > strong, .dynamic-verdict-detail strong { color: var(--text-secondary); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; } .repro-cmd { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; padding: 4px 7px; border-radius: var(--radius-sm); background: var(--terminal-bg); color: var(--terminal-text); font-size: 0.78rem; } .repro-copy-btn { flex: 0 0 auto; } .dynamic-verdict-detail { display: grid; gap: var(--space-2); } .dynamic-verdict-detail-text { color: var(--text-secondary); overflow-wrap: anywhere; } .dynamic-attempt-list { list-style: none; display: grid; gap: var(--space-2); margin: var(--space-2) 0 0; padding: 0; } .attempt-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: var(--space-2); padding: 8px 10px; border: 1px solid var(--border-light); border-radius: 6px; background: var(--surface); } .attempt-row.triggered { border-color: color-mix(in srgb, var(--success) 35%, var(--border)); background: var(--success-bg); } .attempt-row code { min-width: 0; overflow-wrap: anywhere; font-size: 0.8rem; } .attempt-outcome, .attempt-exit-code { color: var(--text-secondary); font-size: var(--text-xs); white-space: nowrap; } .attempt-row.triggered .attempt-outcome { color: var(--success); font-weight: var(--weight-semibold); } @media (max-width: 640px) { .attempt-row { grid-template-columns: 1fr; align-items: start; } .attempt-outcome, .attempt-exit-code { white-space: normal; } } /* ── Code Viewer Modal ────────────────────────────────────────────── */ .code-modal-overlay { position: fixed; inset: 0; z-index: 100; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; } .code-modal { background: var(--bg); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); width: 90vw; max-width: 1100px; height: 85vh; display: flex; flex-direction: column; overflow: hidden; } .code-modal-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); background: var(--bg-secondary); flex-shrink: 0; } .code-modal-title { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .code-modal-body { flex: 1; overflow-y: auto; } .code-viewer-body { font-family: var(--font-mono); font-size: 0.82rem; line-height: 1.6; } .code-line.highlight-source { border-left: 4px solid var(--success); background: var(--success-bg); } .code-line.highlight-sink { border-left: 4px solid var(--sev-high); background: var(--sev-high-bg); } .code-line.highlight-finding { background: var(--sev-medium-bg); } .code-line.highlight-flow { background: var(--accent-light); } /* Syntax token colors */ .tok-keyword { color: var(--accent); font-weight: var(--weight-medium); } .tok-string { color: var(--green); } .tok-comment { color: var(--text-tertiary); font-style: italic; } .tok-number { color: var(--amber); } .tok-function { color: var(--accent); } /* ── Scan Modal ───────────────────────────────────────────────────── */ .scan-modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; } .scan-modal { background: var(--bg); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); width: min(480px, 90vw); max-height: 85vh; overflow-y: auto; padding: var(--space-6); } .scan-modal h3 { margin: 0 0 var(--space-4); font-size: var(--text-xl); } .scan-modal-form { display: flex; flex-direction: column; gap: var(--space-4); } .scan-modal-form .form-group { display: flex; flex-direction: column; gap: var(--space-1); } .scan-modal-form .form-group label { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); } .scan-modal-form .form-group input, .scan-modal-form .form-group textarea, .scan-modal-form .form-group select { padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: var(--text-sm); background: var(--bg); color: var(--text); } .scan-modal-form .form-group .form-hint { margin-top: var(--space-1); font-size: var(--text-xs); color: var(--text-secondary); font-family: var(--font-sans); } .scan-modal-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); } /* ── Scan Progress ────────────────────────────────────────────────── */ .scan-progress { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); margin-bottom: var(--space-4); } .scan-progress-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-3); } .scan-progress-header h3 { margin: 0; font-size: var(--text-lg); } /* Stage pipeline */ .stage-pipeline { display: flex; gap: 0; margin-bottom: var(--space-3); } .stage-step { flex: 1; display: flex; flex-direction: column; align-items: center; position: relative; padding: var(--space-2) var(--space-1); } .stage-step::after { content: ''; position: absolute; top: 50%; right: -1px; width: 2px; height: 60%; transform: translateY(-50%); background: var(--border); } .stage-step:last-child::after { display: none; } .stage-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--border); margin-bottom: var(--space-1); transition: background 0.3s; } .stage-step.active .stage-dot { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); } .stage-step.done .stage-dot { background: var(--success); } .stage-label { font-size: var(--text-xs); color: var(--text-tertiary); text-align: center; } .stage-step.active .stage-label { color: var(--accent); font-weight: var(--weight-medium); } .stage-step.done .stage-label { color: var(--success); } /* Progress bar */ .progress-bar { height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; margin-bottom: var(--space-2); } .progress-bar-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width 0.3s ease; min-width: 0; } .progress-stats { display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--text-secondary); } .progress-current-file { font-size: var(--text-xs); color: var(--text-tertiary); font-family: var(--font-mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: var(--space-1); } /* ── Scan Detail Tabs ─────────────────────────────────────────────── */ .scan-detail-tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: var(--space-4); } .scan-detail-tab { padding: var(--space-2) var(--space-4); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); cursor: pointer; border-bottom: 2px solid transparent; transition: color 0.2s, border-color 0.2s; background: none; border-top: none; border-left: none; border-right: none; } .scan-detail-tab:hover { color: var(--text); } .scan-detail-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .scan-detail-tab-content { display: none; } .scan-detail-tab-content.active { display: block; } /* ── Log Viewer ───────────────────────────────────────────────────── */ .log-viewer { max-height: 500px; overflow-y: auto; font-family: var(--font-mono); font-size: var(--text-xs); border: 1px solid var(--border); border-radius: var(--radius-sm); } .log-entry { padding: var(--space-1) var(--space-3); border-bottom: 1px solid var(--border-light); display: flex; gap: var(--space-2); align-items: flex-start; } .log-entry:last-child { border-bottom: none; } .log-entry.log-warn { background: var(--sev-medium-bg); } .log-entry.log-error { background: var(--sev-high-bg); } .log-level { font-weight: var(--weight-semibold); text-transform: uppercase; font-size: 0.65rem; padding: 1px 4px; border-radius: 2px; flex-shrink: 0; min-width: 36px; text-align: center; } .log-level.info { background: var(--accent-light); color: var(--accent); } .log-level.warn { background: var(--sev-medium-bg); color: var(--sev-medium); } .log-level.error { background: var(--sev-high-bg); color: var(--sev-high); } .log-time { color: var(--text-tertiary); flex-shrink: 0; font-size: 0.65rem; } .log-message { color: var(--text); word-break: break-all; } .log-filters { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); } .log-filter-btn { padding: var(--space-1) var(--space-3); font-size: var(--text-xs); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); cursor: pointer; color: var(--text-secondary); } .log-filter-btn.active { background: var(--accent-light); border-color: var(--accent); color: var(--accent); } /* ── Metric Cards Grid ────────────────────────────────────────────── */ .metric-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: var(--space-3); } .metric-card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); text-align: center; } .metric-card-label { font-size: var(--text-xs); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--space-1); } .metric-card-value { font-size: var(--text-2xl); font-weight: var(--weight-semibold); color: var(--text); font-family: var(--font-mono); } /* ── Scan List Enhancements ───────────────────────────────────────── */ .lang-badge { display: inline-block; padding: 1px 6px; font-size: 0.65rem; background: var(--bg-tertiary); border-radius: 3px; color: var(--text-secondary); margin-right: 2px; } .status-badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: 2px 8px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--weight-medium); } .status-badge.running { background: var(--accent-light); color: var(--accent); } .status-badge.completed { background: var(--success-bg); color: var(--success); } .status-badge.failed { background: var(--sev-high-bg); color: var(--sev-high); } .status-badge .status-dot { width: 6px; height: 6px; } /* Pulse animation for running status */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } .status-badge.running .status-dot { animation: pulse 1.5s ease-in-out infinite; } /* Timing breakdown bar */ .timing-bar { display: flex; height: 24px; border-radius: var(--radius-sm); overflow: hidden; margin: var(--space-2) 0; } .timing-bar-segment { display: flex; align-items: center; justify-content: center; font-size: 0.6rem; font-weight: var(--weight-medium); color: white; min-width: 2px; transition: width 0.3s; } .timing-bar-segment.walk { background: var(--sev-low); } .timing-bar-segment.pass1 { background: var(--accent); } .timing-bar-segment.callgraph { background: var(--sev-medium); } .timing-bar-segment.pass2 { background: var(--success); } .timing-bar-segment.postprocess { background: var(--text-tertiary); } .timing-legend { display: flex; gap: var(--space-3); flex-wrap: wrap; font-size: var(--text-xs); color: var(--text-secondary); margin-top: var(--space-1); } .timing-legend-item { display: flex; align-items: center; gap: var(--space-1); } .timing-legend-dot { width: 8px; height: 8px; border-radius: 2px; } /* Scan detail stat cards */ .scan-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-4); } .scan-stat-card { background: var(--bg-secondary); border-radius: var(--radius); padding: var(--space-3) var(--space-4); } .scan-stat-label { font-size: var(--text-xs); color: var(--text-secondary); margin-bottom: var(--space-1); } .scan-stat-value { font-size: var(--text-lg); font-weight: var(--weight-semibold); } /* ── Scan Comparison ──────────────────────────────────────────────── */ .compare-header { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-4); } .compare-scan-pill { display: inline-flex; align-items: center; gap: var(--space-2); background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-2) var(--space-3); font-size: var(--text-sm); } .compare-scan-pill .pill-id { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-secondary); } .compare-scan-pill .pill-count { font-weight: var(--weight-semibold); } .compare-vs { font-size: var(--text-sm); color: var(--text-tertiary); font-weight: var(--weight-semibold); } .compare-summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); margin-bottom: var(--space-4); } .compare-card { background: var(--bg-secondary); border-radius: var(--radius); padding: var(--space-3) var(--space-4); border-left: 3px solid var(--border); } .compare-card--new { border-left-color: var(--success); } .compare-card--fixed { border-left-color: var(--sev-high); } .compare-card--changed { border-left-color: var(--sev-medium); } .compare-card--unchanged { border-left-color: var(--text-tertiary); } .compare-card .compare-card-label { font-size: var(--text-xs); color: var(--text-secondary); margin-bottom: var(--space-1); } .compare-card .compare-card-value { font-size: var(--text-lg); font-weight: var(--weight-semibold); } .compare-card--new .compare-card-value { color: var(--success); } .compare-card--fixed .compare-card-value { color: var(--sev-high); } .compare-card--changed .compare-card-value { color: var(--sev-medium); } .severity-delta { display: flex; gap: var(--space-4); margin-bottom: var(--space-4); font-size: var(--text-sm); } .severity-delta-item { display: inline-flex; align-items: center; gap: var(--space-1); } .severity-delta-item .delta-positive { color: var(--sev-high); font-weight: var(--weight-semibold); } .severity-delta-item .delta-negative { color: var(--success); font-weight: var(--weight-semibold); } .severity-delta-item .delta-zero { color: var(--text-tertiary); } .compare-badge--new { background: var(--success-bg); color: var(--green); font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 1px 6px; border-radius: var(--radius-sm); } .compare-badge--fixed { background: var(--sev-high-bg); color: var(--sev-high); font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 1px 6px; border-radius: var(--radius-sm); } .compare-badge--changed { background: var(--sev-medium-bg); color: var(--sev-medium); font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 1px 6px; border-radius: var(--radius-sm); } .compare-badge--unchanged { background: var(--bg-tertiary); color: var(--text-tertiary); font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 1px 6px; border-radius: var(--radius-sm); } .compare-section { margin-bottom: var(--space-4); } .compare-section-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-radius: var(--radius-sm); cursor: pointer; user-select: none; font-size: var(--text-sm); font-weight: var(--weight-medium); } .compare-section-header:hover { background: var(--bg-tertiary); } .compare-section-header .section-toggle { transition: transform 0.15s; font-size: var(--text-xs); color: var(--text-tertiary); } .compare-section-header .section-toggle.collapsed { transform: rotate(-90deg); } .compare-section-body { padding-top: var(--space-2); } .compare-finding-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-left: 3px solid transparent; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; font-size: var(--text-sm); cursor: pointer; } .compare-finding-row:hover { background: var(--bg-secondary); } .compare-finding-row--new { border-left-color: var(--success); } .compare-finding-row--fixed { border-left-color: var(--sev-high); } .compare-finding-row--changed { border-left-color: var(--sev-medium); } .compare-finding-row--unchanged { border-left-color: var(--bg-tertiary); } .compare-finding-row .finding-path { color: var(--text-secondary); font-family: var(--font-mono); font-size: var(--text-xs); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .compare-delta-inline { display: inline-flex; align-items: center; gap: 3px; font-size: var(--text-xs); color: var(--sev-medium); font-family: var(--font-mono); } .compare-delta-inline .delta-arrow { color: var(--text-tertiary); } .compare-select-bar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--accent-light); border: 1px solid var(--accent); border-radius: var(--radius); margin-bottom: var(--space-3); font-size: var(--text-sm); } .compare-group-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-radius: var(--radius-sm); cursor: pointer; user-select: none; font-size: var(--text-sm); font-weight: var(--weight-medium); margin-top: var(--space-2); } .compare-group-header:hover { background: var(--bg-tertiary); } .compare-group-summary { font-weight: var(--weight-normal); color: var(--text-secondary); font-size: var(--text-xs); margin-left: auto; } /* ── Rules Page ───────────────────────────────────────────────────── */ .rules-layout { display: grid; grid-template-columns: 2fr 1fr; gap: 0; height: calc(100vh - 160px); min-height: 400px; } .rules-list-panel { overflow-y: auto; border-right: 1px solid var(--border); padding-right: var(--space-4); } .rules-detail-panel { overflow-y: auto; padding-left: var(--space-4); } .rules-filters { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; align-items: center; } .rules-table { width: 100%; border-collapse: collapse; table-layout: fixed; } /* Fixed pixel widths for stable columns; col-title has no explicit width -> takes remainder */ .rules-table .col-toggle { width: 60px; } .rules-table .col-lang { width: 100px; } .rules-table .col-kind { width: 110px; } .rules-table .col-cap { width: 100px; } .rules-table .col-finds { width: 64px; } .rules-table th, .rules-table td { padding: 8px 12px; font-size: var(--text-sm); text-align: left; border-bottom: 1px solid var(--border-light); overflow: hidden; white-space: nowrap; vertical-align: middle; } /* Title cell: let the inner .rule-title-text handle truncation */ .rules-table .col-title-cell { overflow: hidden; } .rule-title-text { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .rules-table th { position: sticky; top: 0; z-index: 2; background: var(--bg-secondary); font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.3px; border-bottom: 1px solid var(--border); } /* display: table-row is explicit so no global .rule-row flex can bleed in */ .rule-row { display: table-row; cursor: pointer; } .rule-row:hover td { background: var(--bg-secondary); } .rule-row.selected td { background: var(--accent-light); } .rule-row.rule-disabled { opacity: 0.55; } .rules-table tr:last-child td { border-bottom: none; } .rules-table tbody tr:hover td { background: var(--bg-secondary); } .rule-toggle { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 6px; font-size: var(--text-xs); cursor: pointer; background: var(--bg-secondary); } .rule-toggle.toggle-on { background: var(--success-bg); color: var(--success); border-color: var(--success); } .rule-toggle.toggle-off { background: var(--bg-secondary); color: var(--text-tertiary); } .matcher-tag { display: inline-block; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px 8px; margin: 2px; font-size: var(--text-sm); } .detail-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-top: var(--space-3); } .detail-meta > div { font-size: var(--text-sm); } /* ── Rule Detail Card ─────────────────────────────────────────────── */ .rule-detail-card h3 { margin: 0 0 var(--space-3) 0; font-size: var(--text-lg); word-break: break-word; } .rule-detail-grid { display: grid; grid-template-columns: auto 1fr; gap: var(--space-1) var(--space-3); font-size: var(--text-sm); } .rule-detail-label { color: var(--text-secondary); font-weight: var(--weight-medium); white-space: nowrap; } /* ── Config Page ──────────────────────────────────────────────────── */ .config-section { margin-bottom: var(--space-6); } .config-section-header { cursor: pointer; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-radius: var(--radius); user-select: none; font-size: var(--text-base); } .config-section-header:hover { background: var(--bg-tertiary); } .config-section-header-static { cursor: default; } .config-section-header-static:hover { background: var(--bg-secondary); } .config-collapse-arrow { font-size: 10px; display: inline-block; transition: transform 0.15s ease; } .config-section-header.collapsed .config-collapse-arrow { transform: rotate(-90deg); } .config-section-header.collapsed + .config-section-body { display: none; } .config-section-body { padding: var(--space-3) 0; } /* Label entry tables */ .label-table { width: 100%; border-collapse: collapse; } .label-table td, .label-table th { padding: 6px 10px; text-align: left; } .label-builtin { opacity: 0.7; } .add-label-form { margin-bottom: var(--space-2); } /* ── Config form rows (aligned inputs/buttons) ───────────────────────── */ .config-form-row { display: grid; grid-template-columns: minmax(140px, 180px) 1fr minmax(140px, 200px) auto; gap: var(--space-3); align-items: end; margin-bottom: var(--space-2); } .config-form-row .form-group { margin-bottom: 0; min-width: 0; } .config-form-row .form-group-grow { /* placeholder for cases where the matcher should stretch */ } .config-form-row.config-form-row-2col { grid-template-columns: minmax(200px, 320px) auto; justify-content: start; } .config-form-row input, .config-form-row select, .config-form-row .btn { height: 38px; box-sizing: border-box; line-height: 1.2; } .config-form-row .btn { align-self: end; padding-left: var(--space-4); padding-right: var(--space-4); } @media (max-width: 720px) { .config-form-row { grid-template-columns: 1fr 1fr; } .config-form-row .btn { grid-column: 1 / -1; } } /* ── Config tabs ─────────────────────────────────────────────────────── */ .config-tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border); margin-bottom: var(--space-4); } .config-tab { background: transparent; border: none; border-bottom: 2px solid transparent; padding: var(--space-2) var(--space-3); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); cursor: pointer; margin-bottom: -1px; } .config-tab:hover { color: var(--text); } .config-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .page-header-sub { color: var(--text-secondary); font-size: var(--text-sm); margin-left: var(--space-3); } .config-help { color: var(--text-secondary); font-size: var(--text-sm); margin: 0 0 var(--space-3) 0; } .config-help code { font-size: 0.95em; padding: 1px 4px; background: var(--bg-secondary); border-radius: 3px; } .config-mono { font-family: var(--font-mono); font-size: var(--text-sm); } .config-profile-settings { font-size: var(--text-xs); font-family: var(--font-mono); max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); } /* ── Effective config kv grid ────────────────────────────────────────── */ .config-kv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-2) var(--space-4); } .config-kv-row { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2) 0; border-bottom: 1px solid var(--border); min-width: 0; } .config-kv-key { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); font-weight: var(--weight-semibold); } .config-kv-val { font-size: var(--text-sm); word-break: break-word; } .config-kv-val .muted { color: var(--text-secondary); font-style: italic; } .config-list-inline { display: inline-flex; flex-wrap: wrap; gap: 4px; } .config-tag { background: var(--bg-secondary); color: var(--text); font-family: var(--font-mono); font-size: var(--text-xs); padding: 1px 6px; border-radius: var(--radius-sm); } .pill { display: inline-block; padding: 1px 8px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--weight-medium); } .pill-on { background: var(--success-bg, var(--accent-light)); color: var(--success, var(--accent)); } .pill-off { background: var(--bg-secondary); color: var(--text-secondary); } /* ── Raw nyx.local editor ────────────────────────────────────────────── */ .raw-editor { display: flex; flex-direction: column; gap: var(--space-2); } .raw-editor-header { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-radius: var(--radius); flex-wrap: wrap; } .raw-editor-path { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-secondary); margin-top: 2px; } .raw-editor-actions { display: flex; align-items: center; gap: var(--space-2); } .raw-editor-dirty { color: var(--sev-medium, var(--accent)); font-size: var(--text-xs); font-weight: var(--weight-medium); } .raw-editor-saved { color: var(--success, var(--accent)); font-size: var(--text-xs); font-weight: var(--weight-medium); } .raw-editor-error { background: var(--sev-high-bg); color: var(--sev-high); padding: var(--space-2) var(--space-3); border-radius: var(--radius); font-size: var(--text-sm); white-space: pre-wrap; word-break: break-word; } .raw-editor-textarea { width: 100%; min-height: 480px; font-family: var(--font-mono); font-size: 0.85rem; line-height: 1.5; padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); color: var(--text); resize: vertical; white-space: pre; tab-size: 2; } .raw-editor-textarea:focus { outline: none; border-color: var(--accent); } /* Badges */ .badge-custom { background: var(--accent-light); color: var(--accent); padding: 2px 6px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--weight-medium); } .badge-builtin { background: var(--bg-secondary); color: var(--text-secondary); padding: 2px 6px; border-radius: var(--radius-sm); font-size: var(--text-xs); } .badge-source { background: var(--sev-low-bg); color: var(--sev-low); } .badge-sanitizer { background: var(--success-bg); color: var(--success); } .badge-sink { background: var(--sev-high-bg); color: var(--sev-high); } /* Toggle switch inline */ .toggle-inline { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); } .toggle-inline input[type='checkbox'] { width: 16px; height: 16px; } /* Settings panel rows (theme picker etc.) */ .settings-row { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); margin-bottom: var(--space-3); } .settings-row-label { min-width: 80px; font-weight: var(--weight-medium); } .settings-row-control { flex: 1; min-width: 160px; height: 32px; box-sizing: border-box; } .settings-row-toggle { margin-top: var(--space-2); } /* ── Code Modal Responsive ────────────────────────────────────────── */ @media (max-width: 768px) { .code-modal { width: 100vw; height: 100vh; border-radius: 0; } .scan-modal { width: 100vw; margin: 0; border-radius: 0; max-height: 100vh; } .metric-grid { grid-template-columns: repeat(2, 1fr); } } /* ── Overview Page ───────────────────────────────────────────────── */ .overview-stat-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--space-3); margin-bottom: var(--space-6); } .overview-stat-grid-5 { grid-template-columns: repeat(5, 1fr); } .card-full { grid-column: 1 / -1; } .backlog-empty { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) 0; } .overview-stat-card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-4); text-align: center; box-shadow: var(--shadow-sm); } .stat-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--space-1); } .stat-value { font-size: var(--text-2xl); font-weight: var(--weight-bold); font-family: var(--font-mono); color: var(--text); } .stat-delta { font-size: var(--text-xs); font-weight: var(--weight-semibold); margin-left: 4px; vertical-align: middle; } .delta-up { color: var(--sev-high); } .delta-down { color: var(--success); } .delta-neutral { color: var(--text-tertiary); } .stat-subtitle { font-size: var(--text-xs); color: var(--text-tertiary); margin-top: 2px; } .overview-chart-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); margin-bottom: var(--space-6); } .overview-chart-grid .card { padding: var(--space-4); } .overview-chart-grid .card-header { margin-bottom: var(--space-3); } .overview-table-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); margin-bottom: var(--space-6); } .overview-table-grid .card { overflow: hidden; } .overview-table-grid table { font-size: var(--text-sm); } .overview-table-grid td:last-child, .overview-table-grid th:last-child { text-align: right; } .overview-fresh-banner { background: var(--success-bg); border: 1px solid var(--success); border-radius: var(--radius); padding: var(--space-3) var(--space-4); margin-bottom: var(--space-5); font-size: var(--text-sm); display: flex; align-items: center; gap: var(--space-3); } .overview-fresh-banner strong { color: var(--success); } .overview-fresh-banner a { margin-left: auto; color: var(--accent); text-decoration: none; font-weight: var(--weight-medium); } .overview-fresh-banner a:hover { text-decoration: underline; } .overview-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 80px 20px; text-align: center; } .overview-empty h2 { margin: var(--space-5) 0 var(--space-2); font-size: var(--text-xl); } .overview-empty p { color: var(--text-secondary); margin-bottom: var(--space-5); } .overview-empty svg { width: 64px; height: 64px; color: var(--text-tertiary); } .overview-insights { margin-bottom: var(--space-6); } .insight-list { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); } .insight-card { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); font-size: var(--text-sm); gap: var(--space-3); } .insight-warning { background: var(--sev-medium-bg); border-left: 3px solid var(--sev-medium); } .insight-info { background: var(--sev-low-bg); border-left: 3px solid var(--sev-low); } .insight-success { background: var(--success-bg); border-left: 3px solid var(--success); } .insight-card a { color: var(--accent); text-decoration: none; font-weight: var(--weight-medium); white-space: nowrap; } .insight-card a:hover { text-decoration: underline; } /* SVG chart styles */ .chart-container { width: 100%; min-height: 120px; } .chart-container svg { width: 100%; height: auto; display: block; } /* Overview responsive */ @media (max-width: 1200px) { .overview-stat-grid { grid-template-columns: repeat(3, 1fr); } .overview-posture-row { grid-template-columns: 1fr; } } @media (max-width: 768px) { .overview-stat-grid { grid-template-columns: repeat(2, 1fr); } .overview-chart-grid, .overview-table-grid { grid-template-columns: 1fr; } } /* ── Overview: health, posture, backlog ────────────────────────────── */ .health-card { padding: var(--space-4) var(--space-5); margin-bottom: var(--space-5); } .health-eyebrow { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-tertiary); margin-bottom: var(--space-2); } .health-headline { display: grid; grid-template-columns: auto auto 1fr; gap: var(--space-4); align-items: stretch; } .health-grade-block { display: flex; align-items: center; justify-content: center; border-radius: 50%; color: white; flex-shrink: 0; width: 64px; height: 64px; } .health-grade-letter { font-size: 40px; line-height: 1; font-weight: var(--weight-bold); font-family: var(--font-mono); letter-spacing: 0; } .grade-a { background: var(--green); } .grade-b { background: var(--green); } .grade-c { background: var(--amber); } .grade-d { background: var(--red); } .grade-f { background: var(--red); } .health-headline-text { display: flex; flex-direction: column; gap: var(--space-2); justify-content: center; } .health-summary { display: flex; align-items: baseline; gap: var(--space-2); } .health-number { font-size: 40px; line-height: 1; font-weight: var(--weight-bold); font-family: var(--font-mono); color: var(--text); letter-spacing: 0; } .health-of { font-size: var(--text-sm); color: var(--text-tertiary); font-family: var(--font-mono); } .health-posture { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.4; } .health-posture.posture-success { color: var(--green); } .health-posture.posture-warning { color: var(--amber); } .health-posture.posture-danger { color: var(--red); } .health-posture.posture-info { color: var(--text-secondary); } .health-components { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-1); border-left: 1px solid var(--border); padding-left: var(--space-5); } .health-component { display: flex; flex-direction: column; gap: 2px; padding: 0 var(--space-2); } .health-component-score { font-size: var(--text-xl); font-weight: var(--weight-semibold); font-family: var(--font-mono); color: var(--text); line-height: 1.1; } .health-component-label { font-size: var(--text-xs); color: var(--text-tertiary); line-height: 1.3; } /* Backlog card */ .backlog-card { margin-bottom: var(--space-5); padding: var(--space-4) var(--space-5); } .backlog-body { display: grid; grid-template-columns: repeat(3, auto) 1fr; align-items: center; gap: var(--space-6); } .backlog-stat { display: flex; flex-direction: column; gap: 2px; } .backlog-stat-value { font-size: var(--text-xl); font-weight: var(--weight-semibold); font-family: var(--font-mono); } .backlog-stat-label { font-size: var(--text-xs); color: var(--text-tertiary); } .backlog-bucket .bucket-bar { margin-top: 0; } .bucket-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; background: var(--bg-secondary); } .bucket-segment { height: 100%; } /* Confidence distribution */ .confidence-dist { padding: var(--space-2); } .confidence-bar { display: flex; height: 18px; border-radius: 4px; overflow: hidden; background: var(--bg-secondary); margin-bottom: var(--space-3); } .confidence-segment { height: 100%; } .confidence-legend { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-1) var(--space-3); font-size: var(--text-xs); } .confidence-legend-item { display: flex; align-items: center; gap: 6px; } .confidence-swatch { width: 10px; height: 10px; border-radius: 2px; } .confidence-count { margin-left: auto; font-family: var(--font-mono); color: var(--text-secondary); } /* Definition list used by Scanner Quality + Suppression Hygiene */ .kv-list { margin: 0; padding: var(--space-2) var(--space-4) var(--space-3); display: flex; flex-direction: column; } .kv-row { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid var(--border-light); } .kv-row:last-child { border-bottom: none; } .kv-row-emphasis { padding-bottom: var(--space-3); margin-bottom: var(--space-1); border-bottom: 1px solid var(--border); } .kv-row-emphasis .kv-number { font-size: var(--text-2xl); font-weight: var(--weight-bold); } .kv-label { font-size: var(--text-sm); color: var(--text); margin: 0; font-weight: var(--weight-medium); display: flex; flex-direction: column; gap: 2px; } .kv-hint { font-size: var(--text-xs); color: var(--text-tertiary); font-weight: var(--weight-regular, 400); } .kv-value { margin: 0; text-align: right; display: flex; flex-direction: column; gap: 2px; } .kv-number { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--text); line-height: 1.1; } .kv-detail { font-size: var(--text-xs); color: var(--text-tertiary); font-family: var(--font); } /* OWASP */ .owasp-list { list-style: none; margin: 0; padding: var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); } .owasp-row { display: grid; grid-template-columns: 40px minmax(0, 1fr) minmax(30px, 80px) 28px; align-items: center; gap: var(--space-2); font-size: var(--text-sm); } .owasp-code { font-family: var(--font-mono); font-weight: var(--weight-semibold); color: var(--accent); } .owasp-label { color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .owasp-bar { height: 6px; background: var(--bg-secondary); border-radius: 3px; overflow: hidden; } .owasp-fill { height: 100%; background: var(--accent); } .owasp-count { text-align: right; font-family: var(--font-mono); font-weight: var(--weight-semibold); } /* Severity stack */ .severity-stack { display: flex; height: 18px; border-radius: 3px; overflow: hidden; background: var(--bg-secondary); min-width: 80px; } .sev-segment { font-size: 10px; color: white; display: flex; align-items: center; justify-content: center; font-weight: var(--weight-semibold); font-family: var(--font-mono); } .sev-segment.sev-high { background: var(--sev-high); } .sev-segment.sev-medium { background: var(--sev-medium); } .sev-segment.sev-low { background: var(--sev-low); } /* Baseline strip */ .baseline-strip { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-4); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: var(--space-3); font-size: var(--text-sm); } .baseline-strip-empty { color: var(--text-secondary); } .baseline-label { font-weight: var(--weight-semibold); color: var(--text-secondary); } .baseline-link { background: none; border: none; color: var(--accent); font-family: var(--font-mono); cursor: pointer; padding: 0; } .baseline-link:hover { text-decoration: underline; } .baseline-action { margin-left: auto; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px 10px; font-size: var(--text-xs); cursor: pointer; color: var(--text); } .baseline-action:hover { background: var(--bg-secondary); } .baseline-action:disabled { opacity: 0.5; cursor: not-allowed; } .baseline-drift-good { color: var(--success); } .baseline-drift-bad { color: var(--sev-high); } .baseline-drift-flat { color: var(--text-tertiary); } /* Empty-state CLI hint */ .cli-hint { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: var(--space-3); font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text); display: inline-block; } /* ── Explorer Page ─────────────────────────────────────────────────── */ /* Override .content padding/max-width when explorer is inside it */ .content:has(.explorer-page) { padding: 0; max-width: none; } .explorer-page { height: calc(100vh - 48px); overflow: hidden; } .explorer-page-code { display: grid; grid-template-columns: 220px minmax(0, 1fr) 300px; } .explorer-page-analysis { display: grid; grid-template-columns: 220px minmax(0, 1fr); } /* Left panel */ .explorer-left { border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; background: var(--bg); } .explorer-left-header { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); flex-shrink: 0; } .explorer-left-body { flex: 1; overflow-y: auto; } /* Mode toggle */ .explorer-mode-toggle { display: flex; gap: 1px; background: var(--border); border-radius: var(--radius-sm); overflow: hidden; } .mode-btn { flex: 1; padding: var(--space-1) var(--space-2); font-size: var(--text-xs); font-weight: var(--weight-medium); border: none; background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; transition: background 0.15s, color 0.15s; } .mode-btn:hover { background: var(--bg-tertiary); } .mode-btn.active { background: var(--accent); color: var(--accent-contrast); } /* File tree */ .file-tree { padding: var(--space-1) 0; } .tree-node { display: flex; align-items: center; gap: var(--space-1); padding: 3px 8px; cursor: pointer; font-size: 0.78rem; color: var(--text); user-select: none; border-left: 3px solid transparent; transition: background 0.1s; } .tree-node:hover { background: var(--bg-secondary); } .tree-node.selected { background: var(--accent-light); } .tree-node.sev-high { border-left-color: var(--sev-high); } .tree-node.sev-medium { border-left-color: var(--sev-medium); } .tree-node.sev-low { border-left-color: var(--sev-low); } .tree-chevron { width: 14px; flex-shrink: 0; font-size: var(--text-xs); color: var(--text-tertiary); text-align: center; } .tree-chevron.invisible { visibility: hidden; } .tree-node-icon { flex-shrink: 0; display: flex; align-items: center; color: var(--text-secondary); } .tree-node-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tree-node-badge { flex-shrink: 0; font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 0 6px; border-radius: var(--radius-sm); background: var(--accent-light); color: var(--accent); line-height: 1.6; } .file-icon { font-size: var(--text-xs); font-weight: var(--weight-bold); font-family: var(--font-mono); width: 14px; text-align: center; display: inline-block; } /* Main shell */ .explorer-main-shell { overflow: hidden; display: flex; flex-direction: column; background: var(--bg); min-width: 0; height: 100%; } .explorer-file-header { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); display: flex; flex-direction: column; justify-content: center; gap: var(--space-3); flex-shrink: 0; background: var(--bg); min-height: var(--explorer-header-height); box-sizing: border-box; } .explorer-file-header-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; } .explorer-file-header-copy { display: flex; align-items: baseline; gap: var(--space-2); min-width: 0; flex-wrap: nowrap; flex: 0 1 auto; } .explorer-file-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.06em; flex-shrink: 0; } .explorer-file-path { font-size: var(--text-sm); font-family: var(--font-mono); color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .explorer-function-picker { min-width: 0; width: min(460px, 100%); max-width: 100%; flex: 0 1 460px; } .explorer-function-picker .function-selector { padding: 0; flex-wrap: nowrap; width: 100%; } .function-selector-flat { display: contents; } .function-selector-flat > .function-selector-field { padding: 0; flex: 0 1 auto; } .explorer-view-tabs { display: flex; align-items: stretch; gap: var(--space-4); overflow-x: auto; scrollbar-width: thin; } .explorer-view-tab { padding: var(--space-2) 0; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--text-secondary); cursor: pointer; white-space: nowrap; font-size: var(--text-sm); font-weight: var(--weight-medium); transition: color 0.12s, border-color 0.12s; } .explorer-view-tab:hover { color: var(--text); } .explorer-view-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .explorer-inline-notice { padding: var(--space-2) var(--space-3); border-radius: var(--radius); background: var(--accent-light); color: var(--text-secondary); font-size: var(--text-sm); } .explorer-inline-notice-warning { background: var(--sev-medium-bg); color: var(--sev-medium); } .explorer-main-body { flex: 1; overflow: auto; min-height: 0; } .explorer-main-body .code-viewer-body { min-height: 100%; } .explorer-main-body .empty-state { padding: var(--space-8) var(--space-4); color: var(--text-tertiary); } /* Gutter markers */ .line-gutter { display: inline-flex; align-items: center; justify-content: center; width: 16px; flex-shrink: 0; } .gutter-marker { width: 8px; height: 8px; border-radius: 50%; display: inline-block; } .gutter-marker-spacer { width: 8px; height: 8px; display: inline-block; } .gutter-marker.sev-high { background: var(--sev-high); } .gutter-marker.sev-medium { background: var(--sev-medium); } .gutter-marker.sev-low { background: var(--sev-low); } /* Right panel */ .explorer-right { border-left: 1px solid var(--border); overflow-y: auto; background: var(--bg); } .explorer-right-section { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-light); } .explorer-right > .explorer-right-section:first-child { border-bottom-color: var(--border); min-height: var(--explorer-header-height); display: flex; flex-direction: column; justify-content: center; box-sizing: border-box; } .explorer-right-section h3 { font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.05em; margin: 0 0 var(--space-2) 0; } .explorer-file-meta { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); } .meta-text { font-size: var(--text-sm); color: var(--text-secondary); } .explorer-sev-breakdown { display: flex; gap: var(--space-1); flex-wrap: wrap; } /* Severity badges */ .badge-sev { font-size: var(--text-xs); font-weight: var(--weight-medium); padding: 1px 8px; border-radius: var(--radius-sm); } .badge-sev-high { background: var(--sev-high-bg); color: var(--sev-high); } .badge-sev-medium { background: var(--sev-medium-bg); color: var(--sev-medium); } .badge-sev-low { background: var(--sev-low-bg); color: var(--sev-low); } /* Symbol items */ .explorer-symbol-list { padding: var(--space-2); } .explorer-symbol-item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); font-size: var(--text-sm); border-radius: var(--radius-sm); } .explorer-symbol-item:hover { background: var(--bg-secondary); } .explorer-symbol-item.compact { padding: 2px var(--space-2); font-size: var(--text-xs); } .symbol-kind { font-family: var(--font-mono); font-weight: var(--weight-bold); font-size: var(--text-xs); width: 16px; text-align: center; flex-shrink: 0; } .symbol-kind-function { color: var(--accent); } .symbol-kind-method { color: var(--sev-medium); } .symbol-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); } .symbol-arity { color: var(--text-tertiary); font-size: var(--text-xs); } .explorer-symbol-toggle { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); font-size: var(--text-xs); color: var(--text-secondary); cursor: pointer; user-select: none; } .explorer-symbol-toggle-link { display: block; margin-top: var(--space-2); background: none; border: none; color: var(--accent); font-size: var(--text-xs); cursor: pointer; padding: 0; } .explorer-symbol-toggle-link:hover { text-decoration: underline; } .summary-toggle, .function-selector-toggle { display: inline-flex; align-items: center; gap: var(--space-2); margin-left: var(--space-3); font-size: var(--text-xs); color: var(--text-secondary); cursor: pointer; user-select: none; text-transform: none; letter-spacing: normal; font-weight: var(--weight-normal, 400); white-space: nowrap; flex-shrink: 0; } .function-selector-flat .function-selector-toggle { margin-left: 0; } .function-selector-toggle > span { white-space: nowrap; } /* Explorer findings sidebar list */ .explorer-findings-list { display: flex; flex-direction: column; gap: 1px; } .explorer-finding-item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); cursor: pointer; border-radius: var(--radius-sm); font-size: var(--text-xs); transition: background 0.1s; } .explorer-finding-item:hover { background: var(--bg-secondary); } .explorer-finding-item.active { background: var(--accent-light); } .finding-sev-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .finding-sev-dot.sev-high { background: var(--sev-high); } .finding-sev-dot.sev-medium { background: var(--sev-medium); } .finding-sev-dot.sev-low { background: var(--sev-low); } .finding-line { font-family: var(--font-mono); color: var(--text-tertiary); flex-shrink: 0; min-width: 36px; } .finding-rule { font-family: var(--font-mono); font-weight: var(--weight-medium); color: var(--text); flex-shrink: 0; } .finding-msg { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); } /* Hotspot view */ .explorer-hotspot-list { padding: var(--space-1) 0; } .hotspot-item { display: flex; align-items: center; justify-content: space-between; padding: var(--space-1) var(--space-3); cursor: pointer; font-size: var(--text-sm); transition: background 0.1s; } .hotspot-item:hover { background: var(--bg-secondary); } .hotspot-item.selected { background: var(--accent-light); } .hotspot-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); } .hotspot-count { flex-shrink: 0; margin-left: var(--space-2); } /* Explorer hint text */ .explorer-hint { padding: var(--space-4); font-size: var(--text-sm); color: var(--text-tertiary); text-align: center; } /* Explorer flow timeline, compact variant */ .explorer-flow .flow-step { padding: var(--space-1) var(--space-2); } .explorer-flow .flow-step-card { padding-bottom: var(--space-1); } .flow-step-header { display: flex; align-items: center; gap: var(--space-2); margin-bottom: 1px; } .flow-step-var { font-size: var(--text-sm); font-family: var(--font-mono); } .flow-step-callee { font-size: var(--text-xs); color: var(--text-secondary); } .flow-step-loc { font-size: var(--text-xs); color: var(--text-tertiary); } .analysis-workspace { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); height: 100%; min-height: 0; padding: var(--space-3) var(--space-4); } .analysis-workspace-with-inspector { grid-template-columns: 320px minmax(0, 1fr); } .analysis-workspace-inspector-right { grid-template-columns: minmax(0, 1fr) 320px; } .analysis-inspector { overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); padding: var(--space-3); } .analysis-inspector h3 { margin: 0 0 var(--space-2); font-size: var(--text-base); } .analysis-canvas { min-width: 0; min-height: 0; } .analysis-graph-frame { height: 100%; min-height: 560px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--bg); } .analysis-node-detail { display: flex; flex-direction: column; gap: var(--space-2); } .explorer-analysis-content { padding: var(--space-3) var(--space-4); } /* Explorer responsive */ @media (max-width: 1200px) { .explorer-page-code { grid-template-columns: 260px 1fr; } .explorer-page-analysis { grid-template-columns: 260px 1fr; } .explorer-page-code .explorer-right { display: none; } .analysis-workspace-with-inspector { grid-template-columns: minmax(0, 1fr); } } @media (max-width: 768px) { .explorer-page-code { grid-template-columns: 1fr; } .explorer-page-analysis { grid-template-columns: 1fr; } .explorer-left { display: none; } .explorer-file-header-top { flex-direction: column; } .explorer-file-header-copy { align-items: flex-start; width: 100%; } .explorer-function-picker { width: 100%; min-width: 0; } .function-selector-flat > .function-selector-field { width: 100%; } } /* ═══════════════════════════════════════════════════════════════════════════ Debug Views ═══════════════════════════════════════════════════════════════════════════ */ /* Override .content padding/max-width when debug layout is inside it */ .content:has(.debug-layout) { padding: 0; max-width: none; } .debug-layout { display: flex; flex-direction: row; gap: 0; height: calc(100vh - var(--header-height)); } /* Sidebar file tree */ .debug-sidebar { width: 260px; flex-shrink: 0; display: flex; flex-direction: column; border-right: 1px solid var(--border); background: var(--bg); overflow: hidden; transition: width 0.15s ease; } .debug-sidebar.collapsed { width: 0; border-right: none; } .debug-sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); flex-shrink: 0; font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .debug-sidebar-toggle { background: none; border: none; cursor: pointer; color: var(--text-tertiary); padding: 2px 4px; font-size: var(--text-base); line-height: 1; } .debug-sidebar-toggle:hover { color: var(--text); } .debug-sidebar-body { flex: 1; overflow-y: auto; } .debug-sidebar-expand { position: absolute; left: 0; top: 50%; transform: translateY(-50%); background: var(--surface); border: 1px solid var(--border); border-left: none; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; cursor: pointer; color: var(--text-tertiary); padding: var(--space-2) 4px; font-size: var(--text-base); line-height: 1; z-index: 10; } .debug-sidebar-expand:hover { color: var(--text); background: var(--bg-hover); } /* Main content area */ .debug-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3) var(--space-4); } /* Tab navigation */ .debug-tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border); padding-bottom: 0; overflow-x: auto; } .debug-tab { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-secondary); text-decoration: none; border-bottom: 2px solid transparent; white-space: nowrap; transition: color var(--transition-fast), border-color var(--transition-fast); } .debug-tab:hover { color: var(--text); } .debug-tab-active { color: var(--accent); border-bottom-color: var(--accent); } /* Function selector */ .function-selector { display: flex; gap: var(--space-3); align-items: center; padding: var(--space-2) 0; min-width: 0; } .function-selector-path { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); min-width: 0; } .function-selector-path-label { font-size: var(--text-xs); font-weight: var(--font-medium); text-transform: uppercase; letter-spacing: 0.05em; flex-shrink: 0; } .function-selector-path-value { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 400px; } .function-selector-field { display: flex; align-items: center; gap: var(--space-2); min-width: 0; flex: 1 1 auto; } .function-selector-field label { font-size: var(--text-xs); font-weight: var(--font-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; flex-shrink: 0; } .function-selector-select { min-width: 0; width: 100%; max-width: 100%; padding: var(--space-1) var(--space-2); font-size: var(--text-sm); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); } @media (max-width: 1200px) { .explorer-file-header-top { align-items: flex-start; } .explorer-file-header-copy, .explorer-function-picker { width: 100%; flex-basis: 100%; } } @media (max-width: 768px) { .function-selector { flex-wrap: wrap; align-items: flex-start; } .function-selector-field { flex-direction: column; align-items: flex-start; width: 100%; gap: var(--space-1); } .function-selector-select { min-width: 0; width: 100%; } } .debug-content { flex: 1; min-height: 0; overflow: auto; } /* Split layout (graph + sidebar) */ .debug-split { display: grid; gap: var(--space-3); height: 100%; min-height: 500px; } .debug-split-full { grid-template-columns: minmax(0, 1fr); } .debug-split-with-sidebar { grid-template-columns: minmax(0, 1fr) 300px; } .debug-split-main { min-width: 0; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); display: flex; flex-direction: column; } .debug-split-sidebar { overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); padding: var(--space-3); } .debug-split-sidebar h3 { margin: 0 0 var(--space-2); font-size: var(--text-base); } /* Toolbar */ .debug-toolbar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); font-size: var(--text-sm); } .debug-toolbar label { display: flex; align-items: center; gap: var(--space-1); } .debug-toolbar-label { font-size: var(--text-xs); font-weight: var(--font-medium); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary); } .debug-toolbar select { padding: 2px var(--space-1); font-size: var(--text-sm); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); } /* Node detail */ .debug-node-detail { display: flex; flex-direction: column; gap: var(--space-2); } .debug-detail-row { display: flex; flex-direction: column; gap: 2px; } .debug-detail-label { font-size: var(--text-xs); font-weight: var(--font-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .debug-detail-value { font-size: var(--text-sm); word-break: break-all; } /* Graph renderer */ .graph-renderer-container { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 400px; overflow: hidden; background: var(--surface); } .graph-renderer { flex: 1; width: 100%; min-height: 0; background: var(--bg-secondary); background-image: none; background-size: 20px 20px; } .graph-surface { position: relative; flex: 1; min-height: 0; background: var(--surface); } .graph-surface > canvas { position: absolute; inset: 0; } .graph-loading-overlay { position: absolute; right: var(--space-3); bottom: var(--space-3); z-index: 3; padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-secondary); font-size: var(--text-xs); box-shadow: var(--shadow-sm); backdrop-filter: blur(8px); } /* Graph toolbar */ .graph-toolbar { display: flex; align-items: center; gap: var(--space-2); justify-content: space-between; flex-wrap: wrap; padding: var(--space-1) var(--space-2); border-bottom: 1px solid var(--border); background: var(--bg-secondary); flex-shrink: 0; min-height: 40px; } .graph-toolbar-group, .graph-toolbar-extras { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; } .graph-toolbar-btn { display: inline-flex; align-items: center; gap: 2px; padding: 3px 6px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); color: var(--text-secondary); cursor: pointer; font-size: 11px; font-family: var(--font-mono); line-height: 1; transition: background 100ms, color 100ms, border-color 100ms; } .graph-toolbar-btn:disabled { opacity: 0.45; cursor: not-allowed; } .graph-toolbar-btn:hover { background: var(--bg-secondary); color: var(--text); border-color: var(--text-tertiary); } .graph-toolbar-btn-active { background: var(--accent-light); color: var(--accent); border-color: var(--accent); } .graph-toolbar-zoom { font-family: var(--font-mono); font-size: 10px; color: var(--text-tertiary); min-width: 36px; text-align: center; user-select: none; } .graph-toolbar-sep { width: 1px; height: 16px; background: var(--border); margin: 0 var(--space-1); } .graph-toolbar-field, .graph-toolbar-check { display: inline-flex; align-items: center; gap: 6px; padding: 0 4px; color: var(--text-secondary); font-size: 11px; font-family: var(--font-mono); } .graph-toolbar-field span, .graph-toolbar-check span { text-transform: uppercase; letter-spacing: 0.05em; } .graph-toolbar-field-compact strong { min-width: 10px; color: var(--text); font-size: 11px; } .graph-toolbar-input, .graph-toolbar-select { min-height: 26px; padding: 4px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font-size: 12px; font-family: var(--font-mono); } .graph-toolbar-input { min-width: 150px; } .graph-toolbar-select { max-width: 220px; } .graph-toolbar-range { width: 72px; } .graph-toolbar-check input { accent-color: var(--accent); } .graph-toolbar-status { margin-left: auto; } .graph-toolbar-pill { display: inline-flex; align-items: center; padding: 4px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text-secondary); font-size: 11px; font-family: var(--font-mono); } /* SSA viewer */ .ssa-viewer { display: flex; flex-direction: column; gap: var(--space-3); } .ssa-header { padding: var(--space-1) 0; } .ssa-block { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); overflow: hidden; } .ssa-block-entry { border-left: 3px solid var(--success); } .ssa-block-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-bottom: 1px solid var(--border); font-size: var(--text-sm); } .ssa-block-id { font-family: var(--font-mono); font-weight: var(--font-bold); font-size: var(--text-sm); } .ssa-block-preds, .ssa-block-succs { font-size: var(--text-xs); font-family: var(--font-mono); } .ssa-phi-section { padding: var(--space-1) var(--space-3); background: var(--accent-light); border-bottom: 1px solid var(--border); } .ssa-body-section { padding: var(--space-1) var(--space-3); } .ssa-inst { font-family: var(--font-mono); font-size: var(--text-sm); line-height: 1.6; white-space: nowrap; } .ssa-inst-phi { color: var(--accent); } .ssa-value { color: var(--accent); font-weight: var(--font-semibold); } .ssa-eq { color: var(--text-secondary); } .ssa-op { color: var(--text); font-weight: var(--font-medium); } .ssa-operands { color: var(--text-secondary); } .ssa-var-name { color: var(--text-tertiary); font-style: italic; } .ssa-line-ref { color: var(--text-tertiary); font-size: var(--text-xs); margin-left: var(--space-2); } .ssa-terminator { padding: var(--space-1) var(--space-3); font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-secondary); border-top: 1px solid var(--border); background: var(--bg-secondary); } /* Badge helpers */ .badge-info { display: inline-block; padding: 1px 6px; font-size: var(--text-xs); font-weight: var(--font-medium); border-radius: var(--radius-sm); background: var(--accent-light); color: var(--accent); } .badge-success { display: inline-block; padding: 1px 6px; font-size: var(--text-xs); font-weight: var(--font-medium); border-radius: var(--radius-sm); background: var(--success-bg); color: var(--success); } /* Cap badges */ .cap-badge { display: inline-block; padding: 1px 6px; margin: 1px 2px; font-size: var(--text-xs); font-family: var(--font-mono); font-weight: var(--font-medium); border-radius: var(--radius-sm); background: var(--bg-tertiary); color: var(--text-secondary); } .cap-badge-source { background: var(--success-bg); color: var(--success); } .cap-badge-sanitizer { background: var(--accent-light); color: var(--accent); } .cap-badge-sink { background: var(--sev-high-bg); color: var(--sev-high); } /* Taint viewer */ .taint-viewer { display: flex; flex-direction: column; gap: var(--space-4); } .taint-events-section h3, .taint-blocks-section h3 { margin: 0 0 var(--space-2); font-size: var(--text-base); } .taint-event { border: 1px solid var(--sev-high); border-radius: var(--radius); padding: var(--space-2) var(--space-3); margin-bottom: var(--space-2); background: var(--sev-high-bg); } .taint-event-validated { border-color: var(--success); background: var(--success-bg); } .taint-event-header { display: flex; align-items: center; gap: var(--space-2); font-weight: var(--font-medium); font-size: var(--text-sm); margin-bottom: var(--space-1); } .taint-event-caps { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); margin-bottom: var(--space-1); } .taint-event-values { display: flex; flex-direction: column; gap: 2px; } .taint-block-state { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: var(--space-2); overflow: hidden; } .taint-block-state-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); background: var(--bg-secondary); border-bottom: 1px solid var(--border); font-size: var(--text-sm); } .taint-block-state-values { padding: var(--space-1) var(--space-3); } .taint-value { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); padding: 2px 0; } .taint-value-id { font-family: var(--font-mono); font-weight: var(--font-semibold); color: var(--accent); min-width: 40px; } .taint-value-name { font-family: var(--font-mono); color: var(--text-secondary); min-width: 80px; } .taint-value-caps { display: flex; gap: 2px; } /* Abstract interpretation */ .abstract-interp-viewer { display: flex; flex-direction: column; gap: var(--space-3); } .abstract-block { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; } .abstract-block-header { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: var(--bg-secondary); border-bottom: 1px solid var(--border); font-size: var(--text-sm); } .abstract-block-header:last-child { border-bottom: 0; } .abstract-subtitle { margin: 0; padding: var(--space-2) var(--space-3); background: var(--bg); border-bottom: 1px solid var(--border); font-size: var(--text-xs); color: var(--text-secondary); line-height: 1.4; } .abstract-empty { margin: 0; padding: var(--space-2) var(--space-3); font-size: var(--text-sm); color: var(--text-secondary); } .abstract-table { width: 100%; font-size: var(--text-sm); border-collapse: collapse; } .abstract-table th { text-align: left; padding: var(--space-2); font-size: var(--text-xs); font-weight: var(--weight-medium, 500); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); background: var(--bg-secondary); border-bottom: 1px solid var(--border); } .abstract-table td { padding: var(--space-2); border-top: 1px solid var(--border); vertical-align: middle; } .abstract-table tbody tr:first-child td { border-top: 0; } .abstract-table tbody tr:hover { background: var(--bg-secondary); } /* Auth analysis (within abstract-block layout) */ .auth-detail-list { display: flex; flex-direction: column; padding: var(--space-1) 0; background: var(--bg); } .auth-detail-row { display: grid; grid-template-columns: minmax(160px, max-content) 1fr; gap: var(--space-3); align-items: baseline; padding: var(--space-1) var(--space-3); } .auth-detail-label { font-size: var(--text-xs); font-weight: var(--weight-medium, 500); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); } .auth-detail-value { font-size: var(--text-sm); word-break: break-word; color: var(--text); } .auth-subsection { border-top: 1px solid var(--border); background: var(--bg); } .abstract-block-header + .auth-subsection { border-top: 0; } .auth-subsection-title { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); font-weight: var(--weight-semibold, 600); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-secondary); background: var(--bg-secondary); border-bottom: 1px solid var(--border); } .auth-subject-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; } /* Symex viewer */ .symex-viewer { display: flex; flex-direction: column; gap: var(--space-4); } .symex-section h3 { margin: 0 0 var(--space-2); font-size: var(--text-base); } .symex-roots { display: flex; gap: var(--space-1); flex-wrap: wrap; } .symex-constraint { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) 0; font-size: var(--text-sm); } .symex-polarity { font-size: var(--text-xs); font-weight: var(--font-bold); padding: 1px 6px; border-radius: var(--radius-sm); } .symex-true { background: var(--success-bg); color: var(--success); } .symex-false { background: var(--sev-high-bg); color: var(--sev-high); } .symex-table { width: 100%; font-size: var(--text-sm); border-collapse: collapse; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; } .symex-table th { text-align: left; padding: var(--space-2); font-size: var(--text-xs); font-weight: var(--weight-medium, 500); text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); background: var(--bg-secondary); border-bottom: 1px solid var(--border); } .symex-table td { padding: var(--space-2); border-top: 1px solid var(--border); vertical-align: middle; } .symex-table tbody tr:first-child td { border-top: 0; } .symex-table tbody tr:hover { background: var(--bg-secondary); } /* Summary explorer */ .summary-explorer { display: flex; flex-direction: column; gap: var(--space-2); } .summary-header { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) 0 var(--space-2); font-size: var(--text-sm); color: var(--text-secondary); } .summary-table { width: 100%; font-size: var(--text-sm); border-collapse: collapse; table-layout: fixed; } .summary-table th { text-align: left; padding: var(--space-1) var(--space-2); font-size: var(--text-xs); text-transform: uppercase; color: var(--text-secondary); background: var(--bg-secondary); border-bottom: 1px solid var(--border); } .summary-table td { padding: var(--space-1) var(--space-2); border-bottom: 1px solid var(--border); vertical-align: top; } .summary-table tbody tr:hover { background: var(--bg-secondary); } .summary-detail { padding: var(--space-2) var(--space-3); background: var(--bg-tertiary); display: flex; flex-direction: column; gap: var(--space-2); } .summary-ssa-detail { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border); } .summary-ssa-detail h4 { margin: 0 0 var(--space-1); font-size: var(--text-sm); color: var(--accent); } /* Debug landing */ .debug-landing { text-align: center; padding: var(--space-6) 0; } .debug-landing h2 { margin: 0 0 var(--space-2); } .debug-landing-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-3); margin-top: var(--space-4); text-align: left; } .debug-landing-grid .card { padding: var(--space-3); } .debug-landing-grid .card h3 { margin: 0 0 var(--space-1); font-size: var(--text-sm); font-weight: var(--font-semibold); } .debug-landing-grid .card p { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); } /* Mono helper */ .mono { font-family: var(--font-mono); } /* ── Dark Theme ────────────────────────────────────────────────────── */ [data-theme='dark'] { --bg: #15130f; --bg-secondary: #1f1c16; --bg-tertiary: #2a251d; --bg-soft: #1f1c16; --surface: #201d18; --bg-hover: #2a251d; --text: #f4f2eb; --text-secondary: #d4cec3; --text-tertiary: #a49b8c; --muted: #a49b8c; --subtle: #7c7468; --border: #3b352a; --border-light: #2f2a22; --line: #3b352a; --line-strong: #5a5042; --accent: #98b8a3; --accent-hover: #b4cdbb; --accent-light: #223228; --accent-contrast: #0d0c0a; --sev-high: #dc7c72; --sev-high-bg: #351d1a; --sev-medium: #d2ad61; --sev-medium-bg: #322719; --sev-low: #98b8a3; --sev-low-bg: #223228; --success: #98b8a3; --success-bg: #223228; --conf-high: #98b8a3; --conf-high-bg: #223228; --conf-medium: #d2ad61; --conf-medium-bg: #322719; --conf-low: #a49b8c; --conf-low-bg: #2a251d; --shadow: 0 1px 3px rgba(0, 0, 0, 0.36); --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3); --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.34); --shadow-lg: 0 20px 56px rgba(0, 0, 0, 0.45); --shadow-xl: 0 20px 56px rgba(0, 0, 0, 0.5); --header-bg: rgba(21, 19, 15, 0.84); color-scheme: dark; } [data-theme='dark'] body { background: var(--bg); } [data-theme='dark'] .sidebar-logo-img, [data-theme='hc-dark'] .sidebar-logo-img { filter: invert(1); } /* ── High-Contrast Light Theme ─────────────────────────────────────── */ [data-theme='hc-light'] { --bg: #ffffff; --bg-secondary: #f2f2f2; --bg-tertiary: #e2e2e2; --text: #000000; --text-secondary: #1a1a1a; --text-tertiary: #2b2b2b; --border: #000000; --border-light: #4a4a4a; --accent: #0000c8; --accent-light: #d8d8ff; --accent-contrast: #ffffff; --sev-high: #b30000; --sev-high-bg: #ffe0e0; --sev-medium: #8a3b00; --sev-medium-bg: #ffe7d2; --sev-low: #00408a; --sev-low-bg: #d6e8ff; --success: #006e2e; --success-bg: #d6f5dc; --conf-high: #006e2e; --conf-high-bg: #d6f5dc; --conf-medium: #8a3b00; --conf-medium-bg: #ffe7d2; --conf-low: #2b2b2b; --conf-low-bg: #e2e2e2; --bg-soft: #f2f2f2; --surface: #ffffff; --bg-hover: #e2e2e2; --muted: #2b2b2b; --subtle: #4a4a4a; --line: #000000; --line-strong: #4a4a4a; --accent-hover: #0000a0; --green: #006e2e; --amber: #8a3b00; --red: #b30000; --shadow: 0 0 0 1px #000000; --shadow-sm: 0 0 0 1px #000000; --shadow-md: 0 0 0 1px #000000; --shadow-lg: 0 0 0 2px #000000; --shadow-xl: 0 0 0 2px #000000; --header-bg: rgba(255, 255, 255, 0.92); color-scheme: light; } [data-theme='hc-light'] body { background: var(--bg); } /* ── High-Contrast Dark Theme ──────────────────────────────────────── */ [data-theme='hc-dark'] { --bg: #000000; --bg-secondary: #0d0d0d; --bg-tertiary: #1a1a1a; --text: #ffffff; --text-secondary: #ededed; --text-tertiary: #d4d4d4; --border: #ffffff; --border-light: #b8b8b8; --accent: #8ab4ff; --accent-light: #1a2540; --accent-contrast: #000000; --sev-high: #ff8a80; --sev-high-bg: #3a0000; --sev-medium: #ffc266; --sev-medium-bg: #3a2200; --sev-low: #82c8ff; --sev-low-bg: #00263d; --success: #7cf09a; --success-bg: #002e15; --conf-high: #7cf09a; --conf-high-bg: #002e15; --conf-medium: #ffc266; --conf-medium-bg: #3a2200; --conf-low: #d4d4d4; --conf-low-bg: #1a1a1a; --bg-soft: #0d0d0d; --surface: #0d0d0d; --bg-hover: #1a1a1a; --muted: #d4d4d4; --subtle: #b8b8b8; --line: #ffffff; --line-strong: #b8b8b8; --accent-hover: #b8d4ff; --green: #7cf09a; --amber: #ffc266; --red: #ff8a80; --shadow: 0 0 0 1px #ffffff; --shadow-sm: 0 0 0 1px #ffffff; --shadow-md: 0 0 0 1px #ffffff; --shadow-lg: 0 0 0 2px #ffffff; --shadow-xl: 0 0 0 2px #ffffff; --header-bg: rgba(0, 0, 0, 0.92); color-scheme: dark; } [data-theme='hc-dark'] body { background: var(--bg); } /* High-contrast: bolder borders and focus rings on common surfaces. */ [data-theme='hc-light'] .btn, [data-theme='hc-dark'] .btn, [data-theme='hc-light'] input, [data-theme='hc-dark'] input, [data-theme='hc-light'] select, [data-theme='hc-dark'] select, [data-theme='hc-light'] textarea, [data-theme='hc-dark'] textarea { border-width: 2px; } [data-theme='hc-light'] :focus-visible, [data-theme='hc-dark'] :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } /* ── Loading Spinner ───────────────────────────────────────────────── */ .loading { flex-direction: row; gap: var(--space-3); } .spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spinner-rotate 0.7s linear infinite; flex-shrink: 0; } .loading-message { font-size: var(--text-sm); color: var(--text-tertiary); } @keyframes spinner-rotate { to { transform: rotate(360deg); } } /* ── Error State Polish ────────────────────────────────────────────── */ .error-state { color: var(--text); } .error-state h3 { font-size: var(--text-lg); color: var(--sev-high); margin-bottom: var(--space-2); } .error-state p { color: var(--text-secondary); margin-bottom: var(--space-2); } .error-state .error-hint { font-size: var(--text-sm); color: var(--text-tertiary); } .error-state .error-retry { margin-top: var(--space-3); } /* ── Buttons: ghost + icon variants ────────────────────────────────── */ .btn-secondary { background: var(--bg); color: var(--text-secondary); border-color: var(--border); } .btn-secondary:hover { background: var(--bg-secondary); color: var(--text); } .btn-ghost { background: transparent; border-color: transparent; color: var(--text-secondary); } .btn-ghost:hover { background: var(--bg-secondary); border-color: transparent; color: var(--text); } .btn-icon { padding: 6px; width: 30px; height: 30px; justify-content: center; } .btn-icon.btn-sm { padding: 4px; width: 26px; height: 26px; } /* ── Toaster ───────────────────────────────────────────────────────── */ .toaster { position: fixed; bottom: var(--space-5); right: var(--space-5); z-index: 1000; display: flex; flex-direction: column; gap: var(--space-2); pointer-events: none; max-width: 420px; } .toast { pointer-events: auto; display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--bg); border: 1px solid var(--border); border-left: 3px solid var(--text-tertiary); border-radius: var(--radius); box-shadow: var(--shadow-lg); font-size: var(--text-sm); animation: toast-in 0.16s ease-out; } .toast-info { border-left-color: var(--sev-low); } .toast-success { border-left-color: var(--success); } .toast-warning { border-left-color: var(--sev-medium); } .toast-error { border-left-color: var(--sev-high); } .toast-body { flex: 1; min-width: 0; } .toast-title { font-weight: var(--weight-semibold); margin-bottom: 2px; color: var(--text); } .toast-message { color: var(--text-secondary); word-wrap: break-word; } .toast-close { flex-shrink: 0; background: transparent; border: none; color: var(--text-tertiary); cursor: pointer; padding: 2px; display: inline-flex; align-items: center; border-radius: var(--radius-sm); } .toast-close:hover { color: var(--text); background: var(--bg-secondary); } @keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } /* ── Theme Toggle ──────────────────────────────────────────────────── */ .theme-toggle { color: var(--text-secondary); } .theme-toggle:hover { color: var(--text); } /* ── Palette Trigger Button ────────────────────────────────────────── */ .palette-trigger { color: var(--text-tertiary); gap: 8px; background: var(--bg-secondary); border-color: var(--border); } .palette-trigger:hover { color: var(--text); background: var(--bg-tertiary); } .palette-trigger kbd { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 5px; font-size: var(--text-xs); font-family: var(--font); color: var(--text-tertiary); } /* ── Command Palette ───────────────────────────────────────────────── */ .palette-overlay { position: fixed; inset: 0; z-index: 999; display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; } .palette-backdrop { position: absolute; inset: 0; background: rgba(10, 10, 14, 0.45); backdrop-filter: blur(2px); } .palette { position: relative; width: min(560px, 92vw); max-height: 70vh; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); display: flex; flex-direction: column; overflow: hidden; } .palette-input { width: 100%; border: 0; outline: 0; padding: var(--space-4) var(--space-5); font-size: var(--text-lg); background: var(--bg); color: var(--text); border-bottom: 1px solid var(--border); font-family: var(--font); } .palette-input::placeholder { color: var(--text-tertiary); } .palette-list { list-style: none; margin: 0; padding: var(--space-2) 0; overflow-y: auto; } .palette-list ul { list-style: none; margin: 0; padding: 0; } .palette-group-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-tertiary); padding: var(--space-2) var(--space-5) var(--space-1); font-weight: var(--weight-semibold); } .palette-item { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-5); cursor: pointer; font-size: var(--text-base); color: var(--text); } .palette-item.active { background: var(--accent-light); color: var(--text); } .palette-icon { flex-shrink: 0; display: inline-flex; color: var(--text-tertiary); } .palette-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .palette-hint { color: var(--text-tertiary); font-size: var(--text-sm); } .palette-shortcut { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 1px 6px; font-family: var(--font); font-size: var(--text-xs); color: var(--text-tertiary); } .palette-empty { padding: var(--space-4) var(--space-5); color: var(--text-tertiary); font-size: var(--text-sm); text-align: center; } /* ── Shortcuts Help Modal ──────────────────────────────────────────── */ .shortcuts-modal { position: relative; width: min(560px, 92vw); max-height: 80vh; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); display: flex; flex-direction: column; overflow: hidden; } .shortcuts-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); } .shortcuts-header h2 { font-size: var(--text-xl); font-weight: var(--weight-semibold); color: var(--text); margin: 0; } .shortcuts-body { padding: var(--space-4) var(--space-5); overflow-y: auto; } .shortcuts-body section { margin-bottom: var(--space-5); } .shortcuts-body section:last-child { margin-bottom: 0; } .shortcuts-body h3 { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-tertiary); margin-bottom: var(--space-2); font-weight: var(--weight-semibold); } .shortcuts-body dl { display: flex; flex-direction: column; gap: var(--space-2); } .shortcut-row { display: flex; align-items: center; gap: var(--space-4); font-size: var(--text-sm); } .shortcut-row dt { flex: 0 0 130px; display: inline-flex; align-items: center; gap: var(--space-1); } .shortcut-row dd { flex: 1; color: var(--text-secondary); } .shortcut-row kbd, .shortcuts-body kbd { background: var(--bg-secondary); border: 1px solid var(--border); border-bottom-width: 2px; border-radius: var(--radius-sm); padding: 2px 6px; font-family: var(--font); font-size: var(--text-xs); color: var(--text); } .shortcut-sep { color: var(--text-tertiary); font-size: var(--text-xs); margin: 0 var(--space-1); } /* ── Findings Row Cursor (j/k navigation) ──────────────────────────── */ tr.cursor { box-shadow: inset 3px 0 0 var(--accent); } tr.cursor td { background: var(--accent-light); } /* Editorial shell refinements */ h1, h2 { font-family: var(--font-display); font-weight: 700; letter-spacing: 0; } h3 { font-family: var(--font); font-size: 1rem; font-weight: var(--weight-semibold); } .nav-label { flex: 1; min-width: 0; } .nav-badge { margin-left: auto; min-width: 26px; padding: 1px 7px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--muted); font-family: var(--font-mono); font-size: 0.68rem; line-height: 1.45; text-align: center; } .nav-link.active .nav-badge { border-color: var(--accent); color: var(--accent); } .filter-count, .page-header-sub { color: var(--muted); font-size: var(--text-sm); } .filter-bar, .rules-filters, .triage-controls, .log-filters { gap: 10px; padding: 0; } .filter-bar select, .filter-bar input, .rules-filters select, .rules-filters input, .triage-search { min-height: 36px; box-shadow: none; } .tabs, .triage-tabs-row, .config-tabs, .scan-detail-tabs, .debug-tabs, .explorer-view-tabs { border-bottom-color: var(--line); } .tab.active, .triage-tab.active, .config-tab.active, .scan-detail-tab.active, .debug-tab-active, .explorer-view-tab.active { color: var(--accent); border-bottom-color: var(--accent); } .triage-hero { margin-bottom: var(--space-6); padding-bottom: var(--space-5); border-bottom: 1px solid var(--line); } .triage-hero-title { font-size: 1.1rem; font-weight: 600; line-height: 1.2; color: var(--text); letter-spacing: 0; margin: 0; } .triage-hero-toggle, .triage-rule-more, .triage-rule-clear, .status-note-toggle, .baseline-link, .explorer-symbol-toggle-link, .flow-expand-toggle { color: var(--accent); } .triage-state-chip, .rule-chip, .triage-tab-count, .finding-group-count, .finding-group-sev-pill, .badge-sev, .tree-node-badge, .graph-toolbar-pill, .pill, .lang-badge, .compare-scan-pill, .compare-badge--new, .compare-badge--fixed, .compare-badge--changed, .compare-badge--unchanged { border-radius: var(--radius-sm); } .triage-state-chip, .rule-chip, .finding-group-sev-pill, .baseline-strip, .compare-select-bar, .bulk-action-bar, .scan-progress, .status-control, .triage-actions, .config-section-header, .raw-editor-header { background: var(--surface); border: 1px solid var(--line); box-shadow: none; } .triage-state-chip.active, .rule-chip.active, .log-filter-btn.active, .graph-toolbar-btn-active, .mode-btn.active, .tree-node.selected, .explorer-finding-item.active, .hotspot-item.selected { background: var(--accent-light); color: var(--accent); } .rule-row.selected td, tr.selected td { background: var(--accent-light); } .bulk-action-bar, .compare-select-bar { color: var(--accent); background: var(--accent-light); border-color: var(--line); } .finding-group { background: var(--surface); border-color: var(--line); border-radius: var(--radius); } .finding-group-header, .finding-row-details, .config-section-header, .raw-editor-header, .rules-table th, .graph-toolbar, .ssa-block-header, .abstract-block-header, .taint-block-state-header, .auth-subsection-title, .summary-table th, .symex-table th, .abstract-table th { background: var(--bg-secondary); } .finding-row { background: var(--surface); border-bottom-color: var(--border-light); } .finding-row:hover:not(.selected) { background: var(--bg-secondary); } .finding-row-sev, .severity-pill, .status-badge, .finding-row-state, .badge-info, .badge-success, .cap-badge, .badge-custom, .badge-builtin, .badge-source, .badge-sanitizer, .badge-sink, .sanitizer-badge-none, .sanitizer-badge-bypassed, .sanitizer-badge-applied { border-radius: var(--radius-sm); border: 1px solid currentColor; text-transform: uppercase; letter-spacing: 0.1em; } .severity-pill { box-shadow: none; } .finding-rule-id { font-family: var(--font-mono); font-size: 1rem; letter-spacing: 0; } .file-location { color: var(--accent); border-bottom: 1px solid var(--line-strong); } .path-trace { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: var(--space-3); align-items: stretch; margin: var(--space-4) 0 var(--space-5); } .path-trace-card { min-width: 0; padding: var(--space-3) var(--space-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); } .path-trace-label { display: block; margin-bottom: 4px; color: var(--muted); font-size: 0.72rem; font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.1em; } .path-trace-path { display: block; overflow-wrap: anywhere; color: var(--text); font-family: var(--font-mono); font-size: var(--text-sm); line-height: 1.45; } .path-trace-arrow { display: flex; align-items: center; color: var(--subtle); font-family: var(--font-mono); font-size: var(--text-lg); } .overview-stat-card, .metric-card, .scan-stat-card, .compare-card, .evidence-card, .state-transition-card, .debug-split-main, .debug-split-sidebar, .analysis-inspector, .analysis-graph-frame, .ssa-block, .abstract-block, .taint-event, .taint-block-state, .symex-table, .abstract-table, .symex-constraint, .summary-table { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: none; } .overview-stat-card { text-align: left; } .stat-label, .metric-card-label, .scan-stat-label, .health-eyebrow, .state-machine-label, .detail-section h3, .section-toggle, .rule-detail-label, .config-kv-key, .debug-toolbar-label, .debug-detail-label, .function-selector-path-label, .function-selector-field label, .explorer-file-label, .explorer-right-section h3, .palette-group-label, .shortcuts-body h3 { color: var(--muted); font-size: 0.72rem; font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.1em; } .stat-value, .metric-card-value, .scan-stat-value, .health-number, .health-grade-letter, .kv-number, .backlog-stat-value { font-family: var(--font-display); letter-spacing: 0; } .health-card, .backlog-card { box-shadow: var(--shadow-sm); } .health-grade-block, .grade-a, .grade-b { background: var(--green); } .grade-c { background: var(--amber); } .grade-d, .grade-f { background: var(--red); } .health-posture.posture-success { color: var(--green); } .health-posture.posture-warning { color: var(--amber); } .health-posture.posture-danger { color: var(--red); } .overview-fresh-banner, .insight-success { background: var(--accent-light); border-color: var(--line); } .insight-warning { background: var(--sev-medium-bg); border-left-color: var(--amber); } .insight-info { background: var(--accent-light); border-left-color: var(--accent); } .badge-high, .severity-pill-high, .finding-row-sev.sev-high, .badge-sev-high, .finding-group-sev-pill.sev-high, .badge-sink, .cap-badge-sink { background: var(--sev-high-bg); color: var(--red); } .badge-medium, .severity-pill-medium, .finding-row-sev.sev-medium, .badge-sev-medium, .finding-group-sev-pill.sev-medium, .badge-sanitizer, .cap-badge-sanitizer { background: var(--sev-medium-bg); color: var(--amber); } .badge-low, .severity-pill-low, .finding-row-sev.sev-low, .badge-sev-low, .finding-group-sev-pill.sev-low, .badge-source, .cap-badge-source { background: var(--accent-light); color: var(--green); } .badge-status-open, .badge-triage-open { background: var(--sev-high-bg); color: var(--red); } .badge-status-validated, .badge-triage-fixed, .status-badge.completed { background: var(--success-bg); color: var(--green); } .badge-status-suppressed, .badge-triage-suppressed, .badge-triage-false_positive, .badge-triage-accepted_risk { background: var(--bg-secondary); color: var(--muted); } .badge-triage-investigating, .status-badge.running { background: var(--sev-medium-bg); color: var(--amber); } .status-dot.completed, .status-dot-fixed { background: var(--green); } .status-dot.running, .status-dot-running, .status-dot-investigating { background: var(--amber); } .status-dot-false_positive, .status-dot-accepted_risk, .status-dot-suppressed { background: var(--muted); } .status-dot, .triage-sev-dot, .finding-sev-dot, .gutter-marker, .stage-dot, .timing-legend-dot, .confidence-swatch { border-radius: 50%; } .progress-bar, .confidence-bar, .bucket-bar, .owasp-bar, .severity-stack, .timing-bar { border-radius: var(--radius-sm); background: var(--bg-secondary); } .progress-bar-fill, .owasp-fill { background: var(--accent); border-radius: var(--radius-sm); } .stage-step.active .stage-dot { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-light); } .stage-step.done .stage-dot { background: var(--green); } .tok-keyword { color: #b8d5c3; } .tok-string { color: #b7d88b; } .tok-comment { color: #858b96; } .tok-number { color: #d1bc83; } .tok-function { color: #e6c07b; } .code-viewer-body, .code-block, .log-viewer, .raw-editor-textarea, .evidence-snippet, .flow-step-snippet { background: var(--terminal-bg); border-color: var(--terminal-line); color: var(--terminal-text); } .evidence-snippet { border: 1px solid var(--terminal-line); } .code-viewer-body { overflow: auto; } .code-viewer-body .code-line, .code-block .code-line { color: var(--terminal-text); } .code-viewer-body .line-number, .code-block .line-number, .log-time { color: var(--terminal-muted); } .code-viewer-body .line-content, .code-block .line-content { color: var(--terminal-text); } .code-line.highlight-source { background: rgba(28, 92, 56, 0.32); border-left-color: var(--green); } .code-line.highlight-sink { background: rgba(157, 47, 37, 0.32); border-left-color: var(--red); } .code-line.highlight-finding, .code-line.highlight-flow { background: rgba(140, 99, 16, 0.28); } .code-modal { background: var(--terminal-bg); border: 1px solid var(--terminal-line); border-radius: var(--radius); } .code-modal-header { background: var(--terminal-bar); border-bottom-color: var(--terminal-line); } .code-modal-title { color: var(--terminal-text); } .log-entry { border-bottom-color: var(--terminal-line); } .log-entry.log-warn { background: rgba(140, 99, 16, 0.18); } .log-entry.log-error { background: rgba(157, 47, 37, 0.22); } .log-message { color: var(--terminal-text); } .raw-editor-textarea { min-height: 520px; } .graph-renderer-container, .graph-surface, .graph-toolbar { background: var(--surface); background-image: none; } .graph-renderer { background: var(--bg-secondary); background-image: none; } .graph-loading-overlay, .graph-toolbar-input, .graph-toolbar-select, .graph-toolbar-pill { background: var(--surface); backdrop-filter: none; } .mode-btn.active { background: var(--accent); color: var(--accent-contrast); } .palette, .shortcuts-modal, .scan-modal, .suppress-modal, .dropdown-menu { background: var(--surface); border-color: var(--line); border-radius: var(--radius); box-shadow: var(--shadow-lg); } .palette-backdrop, .scan-modal-overlay, .suppress-modal-overlay, .code-modal-overlay { background: rgba(13, 12, 10, 0.42); } @media (max-width: 768px) { .sidebar-header { min-height: 64px; padding: 10px 16px; flex-direction: row; justify-content: flex-start; } .content { padding: 22px 16px 40px; } .header-bar { padding: 0 16px; } .triage-hero-title { font-size: 1.05rem; } .path-trace { grid-template-columns: 1fr; } .path-trace-arrow { justify-content: flex-start; } } /* -------------------------------------------------------------------------- Route layout refinement -------------------------------------------------------------------------- */ body { font-size: 16px; line-height: 1.58; } .content:has(.page-shell) { max-width: none; } .page-shell { width: min(100%, 1160px); margin: 0 auto; } .overview-page { width: min(100%, 1240px); } .findings-page, .scans-page, .scan-detail-page, .scan-compare-page, .rules-page, .config-page { width: min(100%, 1140px); } .triage-page { width: min(100%, 1260px); } .finding-detail { width: min(100%, 940px); } .page-action-row { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); } .page-action-push { margin-left: auto; } .page-header { align-items: flex-end; padding-bottom: var(--space-4); margin-bottom: var(--space-5); border-bottom: 1px solid var(--line); } .page-header h2 { font-size: 1.85rem; line-height: 1.05; letter-spacing: 0; } .page-header-sub { display: block; max-width: 640px; margin-left: 0; line-height: 1.45; } .card, .table-wrap, .scan-progress, .bulk-action-bar, .compare-select-bar, .config-section, .finding-group, .status-control { border-radius: 6px; } .card { padding: var(--space-4); box-shadow: none; } .card-header { padding-bottom: var(--space-2); margin-bottom: var(--space-3); border-bottom: 1px solid var(--line); color: var(--muted); font-size: 0.68rem; } .table-wrap { overflow: auto; box-shadow: none; } th { padding: 10px 14px; font-size: 0.68rem; } td { padding: 10px 14px; font-size: 0.875rem; vertical-align: middle; } tbody tr:nth-child(even) td { background: transparent; } tbody tr.clickable:hover td, tbody tr.clickable:nth-child(even):hover td { background: var(--bg-secondary); } .badge, .severity-pill, .status-badge, .lang-badge, .badge-sev, .badge-builtin, .badge-custom, .badge-source, .badge-sanitizer, .badge-sink { border-radius: 4px; font-size: 0.66rem; letter-spacing: 0.09em; line-height: 1.45; } .status-badge { border: 1px solid currentColor; text-transform: uppercase; letter-spacing: 0.08em; font-weight: var(--weight-semibold); } .filter-bar { padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; margin-bottom: var(--space-4); } .filter-bar input, .filter-bar select, .rules-filters input, .rules-filters select, .triage-search, .function-selector-select { min-height: 34px; font-size: 0.875rem; } .btn { min-height: 34px; padding: 7px 13px; border-radius: 4px; } .btn-sm { min-height: 28px; padding: 4px 9px; font-size: 0.78rem; } .stat-value, .metric-card-value, .scan-stat-value, .compare-card .compare-card-value, .health-number, .health-grade-letter, .kv-number, .backlog-stat-value { font-family: var(--font-mono); letter-spacing: 0; } /* Overview */ .overview-page .baseline-strip { margin-bottom: var(--space-4); } .overview-page .overview-stat-grid { gap: 10px; margin-bottom: var(--space-5); } .overview-page .overview-stat-grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } .overview-page .overview-stat-card { min-height: 82px; padding: 14px 16px; display: flex; flex-direction: column; justify-content: space-between; } .overview-page .stat-value { font-size: 1.45rem; line-height: 1.15; } .overview-page .stat-subtitle { line-height: 1.35; } .overview-page .health-card { padding: 22px 28px; margin-bottom: var(--space-5); border-top: 3px solid var(--health-accent, var(--accent)); } .overview-page .health-headline { grid-template-columns: auto minmax(180px, 0.55fr) minmax(360px, 1.45fr); gap: var(--space-5); align-items: center; } .overview-page .health-grade-block { width: 96px; height: 96px; } .overview-page .health-grade-letter { font-size: 4rem; } .overview-page .health-number { font-size: 3.25rem; } .overview-page .health-of { font-size: 1.1rem; } .overview-page .health-posture { font-size: 0.85rem; margin-top: 6px; } .overview-page .health-eyebrow { margin-bottom: var(--space-3); font-size: 0.65rem; } .overview-page .health-components { display: flex; flex-direction: column; gap: 10px; padding-left: var(--space-5); border-left: 1px solid var(--border); justify-content: center; } .overview-page .health-component { display: grid; grid-template-columns: minmax(120px, 1.1fr) 1fr auto; align-items: center; gap: var(--space-3); padding: 0; background: none; } .overview-page .health-component-label { font-size: 0.72rem; color: var(--text-secondary); } .overview-page .health-component-bar-track { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; } .overview-page .health-component-fill { height: 100%; background: var(--health-accent, var(--accent)); border-radius: 2px; opacity: 0.8; } .overview-page .health-component-score { font-size: 0.82rem; font-family: var(--font-mono); color: var(--text); text-align: right; min-width: 26px; } .overview-page .overview-fresh-banner { margin-bottom: var(--space-4); padding: 12px 16px; border-color: var(--line); } .overview-page .overview-chart-grid { grid-template-columns: minmax(0, 1.35fr) minmax(240px, 0.72fr) minmax( 220px, 0.68fr ); gap: var(--space-4); margin-bottom: var(--space-5); } .overview-page .overview-chart-grid .card { min-height: 210px; } .overview-page .overview-chart-grid .card:nth-child(1) { grid-column: 1; grid-row: 1 / 3; min-height: 430px; } .overview-page .overview-chart-grid .card:nth-child(2) { grid-column: 2; grid-row: 1; } .overview-page .overview-chart-grid .card:nth-child(3) { grid-column: 2; grid-row: 2; } .overview-page .overview-chart-grid .card:nth-child(4) { grid-column: 3; grid-row: 1 / 3; overflow: hidden; } .overview-page .chart-container { min-height: 180px; } .overview-page .overview-table-grid { gap: var(--space-4); margin-bottom: var(--space-5); } .overview-page .overview-table-grid .card { padding: 0; } .overview-page .overview-table-grid .card-header { margin: 0; padding: 13px 16px 10px; } .overview-page .overview-table-grid table { min-width: 0; } .overview-page .overview-table-grid th, .overview-page .overview-table-grid td { padding: 9px 16px; } .overview-page .insight-list, .overview-page .owasp-list, .overview-page .confidence-dist, .overview-page .kv-list { padding: var(--space-3) var(--space-4); } .overview-page .backlog-card { padding: 16px 20px; margin-bottom: var(--space-5); } /* Findings list */ .findings-page .filter-bar { position: sticky; top: calc(var(--header-height) + 1px); z-index: 3; } .findings-page .search-input { flex: 1 1 260px; max-width: 360px; } .findings-page table { min-width: 1080px; table-layout: fixed; } .findings-page .col-checkbox { width: 42px; } .findings-page th:nth-child(2) { width: 88px; } .findings-page th:nth-child(3) { width: 118px; } .findings-page th:nth-child(4) { width: 168px; } .findings-page th:nth-child(5) { width: 160px; } .findings-page th:nth-child(7) { width: 70px; } .findings-page th:nth-child(8) { width: 96px; } .findings-page th:nth-child(9) { width: 150px; } .findings-page td:nth-child(4), .findings-page .cell-path { font-family: var(--font-mono); font-size: 0.8rem; } .findings-page td:nth-child(4) { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .findings-page td:nth-child(5), .findings-page td:nth-child(8) { color: var(--muted); } .findings-page .bulk-action-bar.visible { margin-bottom: var(--space-4); } .findings-page .pagination { padding-top: var(--space-3); border-top: 1px solid var(--line); } tr.cursor td { background: var(--accent-light); } /* Finding detail */ .finding-detail.detail-panel { padding: 0; } .finding-detail .detail-title-row { align-items: flex-start; padding-bottom: var(--space-3); margin-bottom: var(--space-3); border-bottom: 1px solid var(--line); } .finding-detail .finding-heading { align-items: baseline; gap: var(--space-2); } .finding-detail .finding-rule-id { font-size: 1rem; line-height: 1.4; } .finding-detail .file-location { margin-bottom: var(--space-2); padding-bottom: 2px; line-height: 1.5; } .finding-detail .finding-meta { margin-bottom: var(--space-4); } .finding-detail .path-trace { margin: var(--space-4) 0; } .finding-detail .path-trace-card { padding: 12px 14px; } .finding-detail .status-control { margin: var(--space-4) 0; background: var(--surface); } .finding-detail .detail-section { padding: 0; margin: 0 0 var(--space-3); background: var(--surface); border: 1px solid var(--line); border-radius: 6px; } .finding-detail .detail-section:first-of-type { padding: 0; margin-top: 0; border-top: 1px solid var(--line); } .finding-detail .section-toggle { margin: 0; padding: 12px 14px; border-bottom: 1px solid var(--line); } .finding-detail .section-body { padding: 14px; } .finding-detail .section-body.collapsed { display: none; } .finding-detail .evidence-card, .finding-detail .state-transition-card { border-radius: 4px; } .finding-detail .flow-step { padding: 0 0 var(--space-2); } .finding-detail .flow-step-card { padding: 10px 12px; } /* Triage */ .triage-page .triage-hero { padding: 0 0 var(--space-4); margin-bottom: var(--space-4); background: none; border: none; border-radius: 0; border-bottom: 1px solid var(--line); } .triage-page .triage-hero-row { align-items: center; gap: var(--space-5); flex-wrap: wrap; } .triage-page .triage-hero-title { font-size: 1.1rem; font-weight: 600; font-family: var(--font); line-height: 1.2; flex-shrink: 0; } .triage-page .triage-hero-severity { gap: var(--space-4); flex-wrap: wrap; margin-bottom: 0; } .triage-page .triage-state-row { margin-top: var(--space-3); } .triage-page .triage-tabs-row { margin-bottom: var(--space-3); } .triage-page .triage-controls { padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; } .triage-page .triage-search { max-width: none; background: var(--surface); } .triage-page .triage-rule-filter { padding: 2px 0 var(--space-2); } .triage-page .finding-list { gap: 10px; } .triage-page .finding-group-header { padding: 10px 14px; } .triage-page .finding-row-main { padding: 10px 14px; } .triage-page .finding-row-details { padding: 12px 16px 14px 86px; } .triage-page .finding-row-sev { min-width: 58px; padding: 2px 8px; } .triage-page .finding-row-rule { font-size: 0.84rem; } /* Scans and comparison */ .scans-page table { min-width: 900px; table-layout: fixed; } .scans-page th:nth-child(2) { width: 150px; } .scans-page th:nth-child(4), .scans-page th:nth-child(5) { width: 110px; } .scans-page th:last-child { width: 88px; } .scan-progress { padding: 16px; background: var(--surface); } .scan-progress-header h3 { font-size: 1rem; } .stage-pipeline { padding: 4px 0 8px; } .stage-step::after { top: 13px; left: calc(50% + 10px); right: calc(-50% + 10px); width: auto; height: 1px; transform: none; } .stage-label { font-size: 0.68rem; line-height: 1.25; } .scan-detail-page .scan-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: var(--space-4); } .scan-detail-page .scan-stat-card { padding: 14px 16px; background: var(--surface); border: 1px solid var(--line); } .scan-detail-page .scan-stat-value { font-size: 1.15rem; } .scan-summary-grid { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(320px, 0.75fr); gap: var(--space-4); align-items: start; } .scan-summary-grid .card { min-width: 0; } .scan-detail-card table { table-layout: fixed; } .scan-detail-card td:first-child { color: var(--muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; } .scan-detail-card td:last-child { overflow-wrap: anywhere; } .scan-timing-card { align-self: stretch; } .timing-bar { height: 18px; border: 1px solid var(--line); } .timing-bar-segment { font-size: 0; } .timing-legend { gap: var(--space-2); margin-top: var(--space-3); } .scan-detail-tabs, .config-tabs, .triage-tabs-row { margin-bottom: var(--space-4); } .scan-compare-page .compare-header { padding: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; } .compare-summary-grid { gap: 10px; } .compare-card { padding: 14px 16px; border-left-width: 2px; } .compare-card .compare-card-value { font-size: 1.4rem; } .severity-delta { padding-bottom: var(--space-3); border-bottom: 1px solid var(--line); } .compare-section { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--surface); } .compare-section-header, .compare-group-header { border-radius: 0; border-bottom: 1px solid var(--line); } .compare-section-body { padding: 8px; } .compare-finding-row { padding: 8px 10px; border-left-width: 2px; } /* Rules */ .rules-page { width: min(100%, 1240px); } .rules-layout { grid-template-columns: minmax(0, 1fr) 380px; gap: 0; height: calc(100vh - 190px); min-height: 520px; overflow: hidden; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; } .rules-list-panel, .rules-detail-panel { padding: 0; background: var(--surface); } .rules-list-panel { border-right: 1px solid var(--line); } .rules-filters { margin: 0; padding: 12px; background: var(--surface); border-bottom: 1px solid var(--line); } #rules-table-wrap { height: calc(100% - 59px); overflow: auto; } .rules-table { min-width: 780px; } .rules-table th, .rules-table td { padding: 9px 11px; font-size: 0.82rem; } .rules-table th { letter-spacing: 0.08em; } .rules-detail-panel { padding: 18px; } .rule-detail-card h3 { font-family: var(--font-display); font-size: 1.25rem; line-height: 1.15; letter-spacing: 0; } .rule-detail-grid { gap: 8px 14px; } /* Config */ .config-page { width: min(100%, 1060px); } .config-tabs { gap: var(--space-4); margin-bottom: var(--space-5); } .config-tab { padding: 9px 0; } .config-section { margin-bottom: var(--space-4); background: var(--surface); border: 1px solid var(--line); overflow: hidden; } .config-section-header { padding: 13px 16px; border: 0; border-radius: 0; border-bottom: 1px solid var(--line); background: var(--surface); font-weight: var(--weight-semibold); } .config-section-header:hover, .config-section-header-static:hover { background: var(--surface); } .config-section-body { padding: 16px; } .config-help { max-width: 760px; line-height: 1.5; } .config-kv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-5); } .config-kv-row { padding: 10px 0; } .config-form-row { grid-template-columns: minmax(120px, 170px) minmax(220px, 1fr) minmax(120px, 180px) auto; } .label-table th, .label-table td { padding: 9px 12px; } .raw-editor-textarea { min-height: 560px; font-size: 0.82rem; } /* Explorer */ .content:has(.explorer-page) { padding: 0; max-width: none; } .explorer-page { height: calc(100vh - var(--header-height)); background: var(--bg-soft); } .explorer-page-code { grid-template-columns: 300px minmax(0, 1fr) 320px; } .explorer-page-analysis { grid-template-columns: 300px minmax(0, 1fr); } .explorer-left, .explorer-main-shell, .explorer-right { background: var(--surface); } .explorer-left-header { padding: 12px; } .explorer-mode-toggle { background: transparent; border: 1px solid var(--line); border-radius: 4px; } .mode-btn { padding: 7px 9px; background: var(--surface); font-size: 0.72rem; } .tree-node, .hotspot-item { padding: 4px 8px; font-size: 0.75rem; border-left-width: 2px; } .explorer-file-header { min-height: 108px; padding: 16px 20px 14px; background: rgba(255, 255, 255, 0.86); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); } .explorer-file-header-top { gap: var(--space-3); } .explorer-file-label { font-size: 0.68rem; } .explorer-file-path { font-size: 0.86rem; } .explorer-view-tabs { gap: var(--space-5); } .explorer-view-tab { padding: 7px 0; font-size: 0.84rem; } .explorer-main-body .empty-state { min-height: 100%; } .explorer-right-section { padding: 15px 18px; } .explorer-right > .explorer-right-section:first-child { min-height: 108px; } .explorer-symbol-item, .explorer-finding-item { border-radius: 4px; } .explorer-analysis-content, .analysis-workspace { padding: 16px 18px; } .analysis-workspace-with-inspector, .analysis-workspace-inspector-right { grid-template-columns: minmax(280px, 0.34fr) minmax(0, 1fr); } .analysis-workspace-inspector-right { grid-template-columns: minmax(0, 1fr) minmax(280px, 0.34fr); } .analysis-inspector, .analysis-graph-frame { background: var(--surface); border-radius: 6px; } /* Debug */ .content:has(.debug-layout) { padding: 0; max-width: none; } .debug-layout { background: var(--bg-soft); } .debug-main { padding: 18px 22px; gap: var(--space-4); } .debug-tabs { padding: 0 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 6px; } .debug-tab { padding: 10px 0; margin-right: 22px; font-size: 0.84rem; } .debug-content { background: transparent; } .debug-split { gap: var(--space-4); } .debug-split-main, .debug-split-sidebar { background: var(--surface); border-radius: 6px; } .debug-toolbar { padding: 12px; } @media (max-width: 1200px) { .overview-page .overview-stat-grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .overview-page .overview-chart-grid, .scan-summary-grid { grid-template-columns: 1fr; } .overview-page .overview-chart-grid .card:first-child, .overview-page .overview-chart-grid .card:nth-child(4) { grid-column: auto; grid-row: auto; min-height: 240px; } .rules-layout { grid-template-columns: 1fr; height: auto; } .rules-list-panel { border-right: 0; border-bottom: 1px solid var(--line); } #rules-table-wrap { height: 440px; } } @media (max-width: 900px) { .content:has(.page-shell) { padding: 24px 18px 44px; } .page-header { align-items: flex-start; flex-direction: column; gap: var(--space-2); } .overview-page .overview-stat-grid-5, .scan-detail-page .scan-stat-grid, .compare-summary-grid, .config-kv-grid { grid-template-columns: 1fr 1fr; } .overview-page .health-headline { grid-template-columns: auto minmax(0, 1fr); } .overview-page .health-components { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--line); padding: var(--space-4) 0 0; } .triage-page .finding-row-main { align-items: flex-start; } .triage-page .finding-row-actions { display: none; } .triage-page .finding-row-details { padding-left: 16px; } .config-form-row, .config-form-row.config-form-row-2col { grid-template-columns: 1fr; } } @media (max-width: 640px) { .overview-page .overview-stat-grid-5, .scan-detail-page .scan-stat-grid, .compare-summary-grid, .config-kv-grid { grid-template-columns: 1fr; } .page-header h2 { font-size: 1.55rem; } .triage-page .triage-hero-title { font-size: 1.55rem; } .triage-page .triage-hero-severity { gap: var(--space-3); } .path-trace { grid-template-columns: 1fr; } .path-trace-arrow { justify-content: flex-start; } } /* -------------------------------------------------------------------------- Targeted page fixes from visual QA -------------------------------------------------------------------------- */ input[type='checkbox'] { width: 16px; height: 16px; min-width: 16px; min-height: 16px; padding: 0; margin: 0; accent-color: var(--accent); cursor: pointer; } /* Scans: compact operational table */ .scans-page { width: min(100%, 1180px); } .scans-page .table-wrap { overflow-x: auto; } .scans-table { min-width: 940px; table-layout: fixed; } .scans-table .scan-select-col { width: 38px; } .scans-table .scan-status-col { width: 140px; } .scans-table .scan-root-col { width: auto; } .scans-table .scan-duration-col, .scans-table .scan-findings-col { width: 108px; } .scans-table .scan-languages-col { width: 230px; } .scans-table .scan-started-col { width: 110px; } .scans-table .scan-actions-col { width: 82px; } .scans-table th, .scans-table td { padding: 12px 14px; } .scans-table tbody tr { height: 62px; } .scans-table td { line-height: 1.35; } .scan-root-cell { overflow: hidden; color: var(--text); font-family: var(--font-mono); font-size: 0.82rem; text-overflow: ellipsis; white-space: nowrap; } .scan-number-cell { font-family: var(--font-mono); font-size: 0.86rem; color: var(--text); } .scan-language-list { display: flex; max-width: 100%; flex-wrap: wrap; gap: 4px; } .scans-page .lang-badge { margin: 0; padding: 1px 6px; border: 1px solid var(--line); background: var(--bg-secondary); color: var(--text-secondary); font-family: var(--font-mono); font-size: 0.72rem; line-height: 1.35; letter-spacing: 0; text-transform: none; white-space: nowrap; } .scans-page .lang-badge-more { color: var(--accent); background: var(--accent-light); } .scan-actions-cell { overflow: visible; text-align: right; } .scan-actions-cell .btn-danger { color: var(--red); background: var(--surface); } /* Triage: compact single-row hero */ .triage-page .triage-hero-title { font-size: 1.05rem; line-height: 1.2; } .triage-page .triage-sev-count { font-size: 0.98rem; } .triage-page .triage-sev-name { font-size: 0.68rem; letter-spacing: 0.08em; } .triage-page .triage-tab { padding: 8px 12px; font-size: 0.88rem; } .triage-page .triage-controls { padding: 8px; } .triage-page .triage-control-btn { font-size: 0.82rem; } .triage-page .triage-search { font-size: 0.86rem; } .triage-page .triage-result-count { font-size: 0.78rem; } .triage-page .triage-rule-filter { align-items: center; gap: 8px; font-size: 0.84rem; } .triage-page .rule-chip { padding: 3px 8px; font-size: 0.74rem; } .triage-page .rule-chip-count { padding: 0 5px; } .triage-page .finding-row-main { min-height: 56px; padding: 8px 12px; } .triage-page .finding-row-title { gap: 8px; } .triage-page .finding-row-rule { max-width: min(58vw, 620px); font-size: 0.82rem; line-height: 1.35; } .triage-page .finding-row-meta { gap: 10px; font-size: 0.76rem; line-height: 1.35; } .triage-page .finding-row-sev { min-width: 52px; padding: 2px 7px; font-size: 0.64rem; } .triage-page .finding-row-investigate { min-height: 30px; padding: 5px 12px; font-size: 0.8rem; } /* Explorer and code: code surfaces stay intentionally dark */ .explorer-page-code .explorer-main-body, .explorer-page-code .code-viewer-body, .code-viewer-body, .code-block, .evidence-card .evidence-snippet, .flow-step-snippet, .raw-editor-textarea { background: var(--terminal-bg); color: var(--terminal-text); } .code-viewer-body, .code-block, .evidence-card .evidence-snippet, .flow-step-snippet { border-color: var(--terminal-line); font-size: 0.78rem; } .explorer-page-code .explorer-main-body { border-top: 1px solid var(--terminal-line); } .explorer-page-code .code-line { color: var(--terminal-text); } .explorer-page-code .line-number, .code-viewer-body .line-number, .code-block .line-number { color: var(--terminal-muted); } .explorer-file-header .explorer-view-tabs { gap: 16px; overflow-x: visible; } .explorer-file-header .explorer-view-tab { flex: 0 0 auto; padding: 6px 0; font-size: 0.74rem; line-height: 1.2; } /* Debug: make summary/analysis tables fit without horizontal wandering */ .debug-content .summary-table, .debug-content .abstract-table, .debug-content .symex-table { min-width: 0; table-layout: fixed; font-size: 0.76rem; } .debug-content .summary-table th, .debug-content .summary-table td, .debug-content .abstract-table th, .debug-content .abstract-table td, .debug-content .symex-table th, .debug-content .symex-table td { padding: 5px 6px; font-size: 0.74rem; line-height: 1.35; } .summary-table th:nth-child(1) { width: 27%; } .summary-table th:nth-child(2) { width: 8%; } .summary-table th:nth-child(3) { width: 6%; } .summary-table th:nth-child(4), .summary-table th:nth-child(5), .summary-table th:nth-child(6) { width: 16%; } .summary-table th:nth-child(7) { width: 11%; } .summary-table td { overflow: hidden; text-overflow: ellipsis; } .summary-table td:first-child, .summary-table .mono { font-size: 0.74rem; } .debug-content .cap-badge { margin: 1px; padding: 1px 5px; font-size: 0.6rem; line-height: 1.35; letter-spacing: 0.04em; } .debug-detail-row { gap: 8px; font-size: 0.78rem; } .debug-detail-label { font-size: 0.66rem; } .debug-detail-value { min-width: 0; overflow-wrap: anywhere; font-size: 0.78rem; } /* Rules: custom-only checkbox */ .rules-custom-toggle { display: inline-flex; align-items: center; gap: 8px; min-height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--text-secondary); font-size: 0.84rem; font-weight: var(--weight-medium); white-space: nowrap; } /* ── Light-mode code surfaces ──────────────────────────────────────── */ [data-theme='light'] .code-block, [data-theme='light'] .evidence-card .evidence-snippet, [data-theme='light'] .flow-step-snippet, [data-theme='light'] .log-viewer, [data-theme='light'] .raw-editor-textarea { background: var(--bg-secondary); border-color: var(--border); color: var(--text); } [data-theme='light'] .code-block, [data-theme='light'] .evidence-card .evidence-snippet, [data-theme='light'] .flow-step-snippet { border-color: var(--border); } [data-theme='light'] .code-viewer-body, [data-theme='light'] .explorer-page-code .explorer-main-body { background: var(--bg-secondary); border-color: var(--border); } [data-theme='light'] .code-viewer-body .code-line, [data-theme='light'] .code-block .code-line, [data-theme='light'] .explorer-page-code .code-line { color: var(--text); } [data-theme='light'] .code-viewer-body .line-number, [data-theme='light'] .code-block .line-number, [data-theme='light'] .explorer-page-code .line-number, [data-theme='light'] .log-time { color: var(--text-tertiary); } [data-theme='light'] .code-viewer-body .line-content, [data-theme='light'] .code-block .line-content { color: var(--text); } [data-theme='light'] .log-message { color: var(--text); } [data-theme='light'] .log-entry { border-bottom-color: var(--border); } [data-theme='light'] .code-modal { background: var(--surface); border-color: var(--border); } [data-theme='light'] .code-modal-header { background: var(--bg-secondary); border-bottom-color: var(--border); } [data-theme='light'] .code-modal-title { color: var(--text); } /* SurfacePage */ .surface-header { display: flex; align-items: baseline; gap: var(--space-4); margin-bottom: var(--space-4); } .surface-header h1 { margin: 0; } .surface-header-summary { color: var(--text-tertiary); font-size: var(--text-sm); } .surface-filter-row { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; } .surface-filter-input { flex: 1 1 220px; padding: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-1); background: var(--surface-1); color: var(--text-primary); } .surface-filter-select { padding: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius-1); background: var(--surface-1); color: var(--text-primary); } .surface-grid { display: grid; grid-template-columns: minmax(280px, 1fr) minmax(320px, 1.4fr); gap: var(--space-4); align-items: flex-start; } .surface-node-list { display: flex; flex-direction: column; gap: var(--space-2); max-height: 70vh; overflow-y: auto; } .surface-node-list-empty { color: var(--text-tertiary); } .surface-sidebar { border: 1px solid var(--border); border-radius: var(--radius-2); padding: var(--space-4); background: var(--surface-1); } .surface-node-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); padding: var(--space-3); border-radius: var(--radius-2); cursor: pointer; text-align: left; width: 100%; } .surface-node-card-meta { font-size: var(--text-2xs); color: var(--text-tertiary); } .surface-node-card-title { font-weight: 600; font-size: var(--text-sm); } .surface-node-card-subtitle { font-size: var(--text-xs); color: var(--text-secondary); } .surface-node-card-loc { font-size: var(--text-2xs); color: var(--text-tertiary); } .surface-neighbor-empty { color: var(--text-tertiary); } .surface-neighbor-title { margin-top: 0; } .surface-neighbor-subtitle { color: var(--text-secondary); margin-top: 0; } .surface-neighbor-edges { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-1); } .surface-neighbor-edge { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); } .surface-neighbor-edge-kind { padding: 2px 6px; border-radius: var(--radius-1); background: var(--surface-2); color: var(--text-secondary); } .surface-neighbor-edge-loc { font-size: var(--text-2xs); color: var(--text-tertiary); } .surface-view-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-1); overflow: hidden; background: var(--surface-1); } .surface-view-toggle-button { padding: var(--space-2) var(--space-3); background: transparent; border: 0; color: var(--text-secondary); cursor: pointer; font-size: var(--text-xs); } .surface-view-toggle-button:not(:last-child) { border-right: 1px solid var(--border); } .surface-view-toggle-button.selected { background: var(--surface-2); color: var(--text-primary); font-weight: 600; } .surface-graph-frame { position: relative; min-height: 70vh; border: 1px solid var(--border); border-radius: var(--radius-2); background: var(--surface-1); overflow: hidden; }