diff --git a/web/static/view.css b/web/static/view.css index 081eb80..72cf0e6 100644 --- a/web/static/view.css +++ b/web/static/view.css @@ -1,18 +1,20 @@ -@import url('https://fonts.googleapis.com/css2?family=Public+Sans:wght@400;500;600;700&display=swap'); - :root { - --bg: #f6f7fb; - --surface: #ffffff; - --surface-2: #f2f4f8; - --border: #d9dee7; - --border-lite: #e8ecf2; - --ink: #1d2433; - --muted: #677287; - --accent: #2f6fed; - --danger-bg: #fff4f3; - --danger-border: #f2c3bc; - --danger-text: #8b2f23; - --shadow: 0 10px 30px rgba(18, 30, 55, 0.06); + --bg: #ffffff; + --surface: #ffffff; + --surface-2: #f9fafb; + --border: rgba(34, 36, 38, 0.15); + --border-lite: rgba(34, 36, 38, 0.1); + --ink: rgba(0, 0, 0, 0.87); + --muted: rgba(0, 0, 0, 0.6); + --accent: #2185d0; + --accent-dark: #1678c2; + --accent-bg: #dff0ff; + --crit-border: #e0b4b4; + --ok-bg: #fcfff5; --ok-fg: #2c662d; + --warn-bg: #fffaf3; --warn-fg: #573a08; + --crit-bg: #fff6f6; --crit-fg: #9f3a38; + --unknown-bg: #f9fafb; --unknown-fg: rgba(0, 0, 0, 0.5); + --empty-bg: #f9fafb; --empty-fg: rgba(0, 0, 0, 0.4); } * { @@ -21,264 +23,287 @@ body { margin: 0; - background: - radial-gradient(circle at top left, rgba(47, 111, 237, 0.09), transparent 32%), - linear-gradient(180deg, #f7f9fc 0%, #eef2f7 100%); + background: var(--bg); color: var(--ink); - font-family: "Public Sans", "Segoe UI", sans-serif; + font: 14px/1.5 Lato, "Helvetica Neue", Arial, Helvetica, sans-serif; } +/* ── Header ──────────────────────────────────────── */ + .page-header { + background: #1b1c1d; + padding: 14px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; - padding: 18px 24px; - border-bottom: 1px solid rgba(217, 222, 231, 0.9); - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(14px); - position: sticky; - top: 0; - z-index: 20; } .page-header h1 { margin: 0; - font-size: clamp(22px, 3vw, 30px); + font-size: 18px; font-weight: 700; - letter-spacing: -0.03em; + color: rgba(255, 255, 255, 0.9); } +/* ── Main layout ─────────────────────────────────── */ + .header-actions { display: flex; align-items: center; - gap: 10px; } .header-action { - display: inline-flex; - align-items: center; - justify-content: center; - min-height: 38px; - padding: 0 16px; - border-radius: 999px; - border: 1px solid rgba(47, 111, 237, 0.18); - background: rgba(47, 111, 237, 0.08); - color: var(--accent); + display: inline-block; text-decoration: none; - font-weight: 600; + border-radius: 4px; + background: rgba(255, 255, 255, 0.12); + color: rgba(255, 255, 255, 0.85); + padding: 6px 14px; + font-size: 13px; + font-weight: 700; + white-space: nowrap; + transition: background 0.1s ease; } .header-action:hover { - background: rgba(47, 111, 237, 0.14); + background: rgba(255, 255, 255, 0.2); } .page-main { - width: min(1480px, calc(100vw - 40px)); - margin: 26px auto 40px; + width: min(1500px, calc(100vw - 48px)); + margin: 28px auto 56px; } -.notice-panel, -.meta-panel, +/* ── Meta-panel and upload — классические карточки ── */ + .empty-panel, -.section-card { - background: rgba(255, 255, 255, 0.92); - border: 1px solid rgba(217, 222, 231, 0.92); - box-shadow: var(--shadow); - border-radius: 18px; -} - -.notice-panel, .meta-panel, -.empty-panel { - padding: 20px 22px; - margin-bottom: 18px; +.notice-panel, +.upload-panel { + background: var(--surface); + border: 1px solid var(--border); + border-radius: 4px; + box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15); + overflow: hidden; + margin-bottom: 28px; } -.notice-panel h2, -.meta-panel h2, .empty-panel h2, +.meta-panel h2, +.notice-panel h2, +.upload-panel h2 { + display: block; + margin: 0; + padding: 13px 16px; + background: var(--surface-2); + border-bottom: 1px solid var(--border); + font-size: 13px; + font-weight: 700; + color: var(--ink); +} + +.empty-panel p, +.notice-panel p, +.upload-panel p { + margin: 0; + padding: 12px 16px 0; + color: var(--muted); +} + +.empty-panel p:last-child { + padding-bottom: 16px; +} + +/* ── Section cards — heading + table, без обёртки ─── */ + +.section-card { + background: transparent; + border: none; + box-shadow: none; + overflow: visible; + margin-bottom: 32px; +} + .section-card h2 { - margin: 0 0 14px; + display: block; + margin: 0 0 10px; + padding: 0; + background: transparent; + border: none; font-size: 18px; font-weight: 700; - letter-spacing: -0.02em; + color: rgba(0, 0, 0, 0.87); } -.notice-panel p, -.empty-panel p { - margin: 0; - color: var(--muted); - line-height: 1.55; +/* таблица внутри section-card получает свой бордер */ +.section-card .table-wrap { + border: 1px solid var(--border); + border-radius: 4px; + box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15); + overflow-x: auto; } +.section-card .kv-table { + border: 1px solid var(--border); + border-radius: 4px; + box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15); +} + +/* ── Upload ──────────────────────────────────────── */ + +.upload-panel { + width: min(520px, 100%); + margin-left: auto; + margin-right: auto; +} + +.upload-dropzone { + display: block; + margin: 12px 16px 0; + border: 1px dashed var(--border); + border-radius: 4px; + padding: 16px; + background: var(--surface-2); + cursor: pointer; + transition: border-color 0.1s ease, background 0.1s ease; +} + +.upload-dropzone:hover { + border-color: var(--accent); + background: var(--accent-bg); +} + +.upload-dropzone input { + display: block; + width: 100%; + margin-bottom: 12px; + font: inherit; + color: var(--ink); +} + +.upload-eyebrow { + display: block; + margin-bottom: 4px; + color: var(--accent); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.05em; + text-transform: uppercase; +} + +.upload-dropzone strong { + display: block; + margin-bottom: 3px; + font-size: 14px; + font-weight: 700; + color: var(--ink); +} + +.upload-dropzone span:last-child { + color: var(--muted); + font-size: 13px; +} + +.upload-actions { + padding: 12px 16px 16px; +} + +.upload-actions button { + background: var(--accent); + color: #fff; + border: none; + border-radius: 4px; + padding: 8px 18px; + font: inherit; + font-weight: 700; + cursor: pointer; + transition: background 0.1s ease; +} + +.upload-actions button:hover { + background: var(--accent-dark); +} + +.upload-actions button:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +/* ── Error ───────────────────────────────────────── */ + +.error-box { + margin: 12px 16px; + border: 1px solid var(--crit-border); + border-radius: 4px; + padding: 10px 14px; + background: var(--crit-bg); + color: var(--crit-fg); +} + +/* ── Sections grid ───────────────────────────────── */ + .sections-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 18px; + gap: 0 32px; } -.section-card { - overflow: hidden; -} +.section-card-half { grid-column: span 1; } +.section-card-full { grid-column: 1 / -1; } -.section-card h2 { - padding: 18px 20px 14px; -} +/* ── Tables ──────────────────────────────────────── */ -.section-card-half { - grid-column: span 1; -} - -.section-card-full { - grid-column: 1 / -1; -} - -.section-card .kv-table, -.section-card .table-wrap, -.meta-panel .kv-table { +.kv-table, +.data-table { width: 100%; -} - -.section-card .table-wrap, -.meta-panel .kv-table { - border-top: 1px solid var(--border-lite); -} - -table { border-collapse: collapse; + font-size: 14px; + background: var(--surface); } .kv-table th, .kv-table td, .data-table th, .data-table td { - border-bottom: 1px solid var(--border-lite); - padding: 11px 14px; vertical-align: top; + text-align: left; + border-top: 1px solid var(--border-lite); + padding: 11px 14px; } -.kv-table tr:last-child th, -.kv-table tr:last-child td, -.data-table tbody tr:last-child td { - border-bottom: none; +.kv-table tr:first-child th, +.kv-table tr:first-child td, +.data-table tr:first-child th, +.data-table tr:first-child td { + border-top: 0; } .kv-table th, .data-table th { - text-align: left; - font-weight: 700; + background: var(--surface-2); color: var(--ink); - background: rgba(242, 244, 248, 0.72); + font-weight: 700; + white-space: nowrap; + border-bottom: 1px solid var(--border-lite); + border-top: 0; } .kv-table th { - width: 240px; -} - -.kv-table td, -.data-table td { - color: var(--ink); - line-height: 1.45; -} - -.data-table { - width: 100%; - min-width: 680px; -} - -.data-table tbody tr:nth-child(even) { - background: rgba(246, 247, 251, 0.55); + width: 1%; } .data-table tbody tr:hover { - background: rgba(47, 111, 237, 0.06); + background: rgba(0, 0, 0, 0.04); + transition: background 0.1s ease; } -.error-box { - margin-top: 18px; - padding: 14px 16px; - border-radius: 12px; - border: 1px solid var(--danger-border); - background: var(--danger-bg); - color: var(--danger-text); -} - -.upload-shell { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - padding: 28px; -} - -.upload-panel { - width: min(620px, 100%); - background: rgba(255, 255, 255, 0.94); - border-radius: 22px; - border: 1px solid rgba(217, 222, 231, 0.92); - box-shadow: 0 24px 60px rgba(16, 27, 49, 0.12); - padding: 28px 28px 24px; -} - -.upload-panel h1 { - margin: 0 0 10px; - font-size: clamp(28px, 4vw, 36px); - letter-spacing: -0.04em; -} - -.upload-panel p { - margin: 0 0 20px; - color: var(--muted); - line-height: 1.55; -} - -.upload-form { - display: grid; - gap: 14px; -} - -.upload-form label { - display: grid; - gap: 7px; - font-weight: 600; -} - -.upload-form input[type="file"] { - border: 1px dashed var(--border); - border-radius: 14px; - padding: 16px; - background: var(--surface-2); - color: var(--muted); -} - -.upload-form button { - justify-self: start; - min-height: 42px; - padding: 0 18px; - border: none; - border-radius: 999px; - background: linear-gradient(135deg, #2f6fed 0%, #1746b3 100%); - color: #fff; - font: inherit; - font-weight: 700; - cursor: pointer; -} - -.upload-form button:hover { - filter: brightness(1.05); -} - -.upload-error { - margin: 0 0 18px; -} - -/* table-wrap already gets border from .section-card .table-wrap */ +/* table-wrap уже получил border в .section-card .table-wrap */ .table-wrap { overflow-x: auto; } -/* meta-panel table-wrap without duplicate border */ +/* для meta-panel table-wrap без дублирования бордера */ .meta-panel .table-wrap { border: none; box-shadow: none; @@ -399,4 +424,14 @@ table { .section-card-full { grid-column: auto; } + + .table-toolbar { + align-items: stretch; + flex-direction: column; + } + + .table-severity-filter { + min-width: 0; + width: 100%; + } }