:root {
    --ink: #172033;
    --ink-soft: #344258;
    --muted: #647287;
    --line: #dfe5ec;
    --line-strong: #cbd4df;
    --paper: #ffffff;
    --canvas: #f4f7fa;
    --nav: #111a2b;
    --nav-soft: #1b2940;
    --brand: #69e1b2;
    --brand-dark: #176c55;
    --blue: #245dcc;
    --blue-soft: #e8efff;
    --red: #a52d42;
    --red-soft: #fce9ed;
    --amber: #8d5614;
    --amber-soft: #fff2df;
    --green: #16704a;
    --green-soft: #e5f7ee;
    --slate-soft: #edf1f5;
    --shadow: 0 8px 28px rgba(22, 34, 53, 0.07);
    --radius: 14px;
}

* {
    box-sizing: border-box;
}

html {
    min-width: 320px;
    background: var(--canvas);
}

body {
    margin: 0;
    color: var(--ink);
    background: var(--canvas);
    font: 14px/1.5 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    -webkit-font-smoothing: antialiased;
}

button,
input,
select {
    font: inherit;
}

a {
    color: inherit;
}

.sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.skip-link {
    position: fixed;
    z-index: 1000;
    top: 12px;
    left: 12px;
    padding: 10px 14px;
    color: #fff;
    background: var(--ink);
    border-radius: 8px;
    transform: translateY(-150%);
}

.skip-link:focus {
    transform: translateY(0);
}

:focus-visible {
    outline: 3px solid rgba(36, 93, 204, 0.3);
    outline-offset: 2px;
}

.app-shell {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 258px minmax(0, 1fr);
}

.sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    padding: 24px 18px;
    color: #d9e3f0;
    background: var(--nav);
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 8px 28px;
    text-decoration: none;
}

/* The artwork carries its own shape and colour, so no tile, no radius and no
   background behind it — a rounded square under a shield reads as a mistake. */
.brand-mark {
    width: 40px;
    height: 40px;
    flex: none;
    display: block;
}

.brand strong,
.brand small {
    display: block;
}

.brand strong {
    color: #fff;
    font-size: 15px;
}

.brand small {
    margin-top: 2px;
    color: #93a5bb;
    font-size: 11px;
}

.nav-label {
    padding: 0 10px 8px;
    color: #7689a1;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.primary-nav {
    display: grid;
    gap: 4px;
}

.primary-nav a {
    display: grid;
    gap: 1px;
    padding: 10px 12px;
    color: #b9c6d6;
    border-left: 3px solid transparent;
    border-radius: 8px;
    text-decoration: none;
}

.primary-nav a span {
    font-weight: 750;
}

.primary-nav a small {
    color: #7f91a8;
    font-size: 11px;
}

.primary-nav a:hover {
    color: #fff;
    background: var(--nav-soft);
}

.primary-nav a.active {
    color: #fff;
    border-left-color: var(--brand);
    background: #22334d;
}

.primary-nav a.active small {
    color: #a9bbcf;
}

.sidebar-note {
    display: grid;
    gap: 5px;
    margin: 28px 6px 0;
    padding: 13px;
    color: #a9b8ca;
    background: rgba(255, 255, 255, 0.045);
    border: 1px solid rgba(255, 255, 255, 0.07);
    border-radius: 10px;
    font-size: 11px;
}

.sidebar-note strong {
    color: var(--brand);
    font-size: 12px;
}

/*
 * Sign-out, pinned under the note in the dark sidebar. Its own rules rather
 * than .btn, because every .btn variant is built for the light workspace and
 * would sit on this background as a white slab.
 */
.sidebar-signout {
    display: grid;
    gap: 8px;
    margin: 14px 6px 0;
    padding: 0 7px;
    color: #93a5bb;
    font-size: 11px;
}

.sidebar-signout strong {
    color: #d7e0ea;
    font-weight: 600;
}

.sidebar-signout button {
    min-height: 32px;
    padding: 6px 12px;
    color: #d7e0ea;
    background: rgba(255, 255, 255, 0.055);
    border: 1px solid rgba(255, 255, 255, 0.11);
    border-radius: 9px;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.sidebar-signout button:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.sidebar-signout button:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.workspace {
    min-width: 0;
}

.topbar {
    min-height: 82px;
    display: flex;
    align-items: center;
    gap: 18px;
    justify-content: space-between;
    padding: 18px 32px;
    background: rgba(255, 255, 255, 0.94);
    border-bottom: 1px solid var(--line);
}

.topbar h1 {
    margin: 0;
    font-size: 23px;
    line-height: 1.2;
    letter-spacing: -0.025em;
}

.topbar p {
    margin: 3px 0 0;
    color: var(--muted);
    font-size: 12px;
}

.page-time {
    display: grid;
    text-align: right;
}

.page-time span {
    color: var(--muted);
    font-size: 11px;
}

.page-time strong {
    margin-top: 2px;
    color: var(--ink-soft);
    font-size: 12px;
}

.nav-toggle {
    display: none;
    width: 40px;
    height: 40px;
    color: var(--ink);
    background: var(--slate-soft);
    border: 0;
    border-radius: 9px;
    cursor: pointer;
}

.content {
    max-width: 1480px;
    margin: 0 auto;
    padding: 28px 32px 56px;
}

.page-intro {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: 18px;
}

.page-intro h2,
.page-intro p {
    margin: 0;
}

.page-intro h2 {
    font-size: 19px;
}

.page-intro p {
    max-width: 700px;
    margin-top: 5px;
    color: var(--muted);
}

.grid {
    display: grid;
    gap: 18px;
}

.stats-grid {
    display: grid;
    gap: 18px;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-bottom: 20px;
}

.two-column {
    grid-template-columns: minmax(0, 1.55fr) minmax(290px, 0.75fr);
}

.split-equal {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.card {
    min-width: 0;
    overflow: hidden;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.section-gap {
    margin-top: 20px;
}

.card-head {
    min-height: 64px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 15px 19px;
    border-bottom: 1px solid var(--line);
}

.card-head h2,
.card-head p {
    margin: 0;
}

.card-head h2 {
    font-size: 15px;
}

.card-head p {
    margin-top: 3px;
    color: var(--muted);
    font-size: 12px;
}

.card-body {
    padding: 19px;
}

.metric-card {
    position: relative;
    min-height: 132px;
    padding: 20px;
}

.metric-card::before {
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    content: "";
    background: var(--blue);
}

.metric-card.red::before {
    background: var(--red);
}

.metric-card.amber::before {
    background: #c77a18;
}

.metric-card.green::before {
    background: var(--green);
}

.eyebrow {
    color: var(--muted);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.metric {
    margin-top: 8px;
    font-size: 30px;
    font-weight: 780;
    line-height: 1;
    letter-spacing: -0.04em;
}

.metric-note {
    margin-top: 10px;
    color: var(--muted);
    font-size: 12px;
}

.muted,
.cell-note {
    color: var(--muted);
}

.cell-note {
    display: block;
    margin-top: 3px;
    font-size: 11px;
}

.mono {
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
}

.sender {
    max-width: 290px;
    overflow-wrap: anywhere;
    font-size: 12px;
}

.score {
    font-size: 16px;
}

.text-link {
    color: var(--blue);
    font-weight: 750;
    text-decoration: none;
}

.text-link:hover {
    text-decoration: underline;
}

.notice {
    margin-bottom: 18px;
    padding: 13px 15px;
    border: 1px solid;
    border-radius: 10px;
}

.notice strong {
    margin-right: 4px;
}

.notice.success {
    color: var(--green);
    background: var(--green-soft);
    border-color: #b6e4ce;
}

.notice.error {
    color: var(--red);
    background: var(--red-soft);
    border-color: #efbdc7;
}

.notice.info {
    color: #214f9e;
    background: var(--blue-soft);
    border-color: #c7d7fb;
}

.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 800;
    white-space: nowrap;
}

.status-dot {
    width: 7px;
    height: 7px;
    flex: none;
    background: currentColor;
    border-radius: 50%;
}

.status-badge.positive {
    color: var(--green);
    background: var(--green-soft);
}

.status-badge.danger {
    color: var(--red);
    background: var(--red-soft);
}

.status-badge.warning {
    color: var(--amber);
    background: var(--amber-soft);
}

.status-badge.info {
    color: var(--blue);
    background: var(--blue-soft);
}

.status-badge.neutral {
    color: #526174;
    background: var(--slate-soft);
}

.data-scroll {
    max-height: min(64vh, 680px);
    overflow: auto;
    scrollbar-gutter: stable;
}

.data-scroll:focus-visible {
    outline-offset: -3px;
}

.data-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
}

.data-table th {
    position: sticky;
    z-index: 2;
    top: 0;
    padding: 11px 13px;
    color: #5f6d80;
    background: #f8fafc;
    border-bottom: 1px solid var(--line-strong);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.045em;
    text-align: left;
    text-transform: uppercase;
}

.data-table td {
    padding: 12px 13px;
    border-bottom: 1px solid #e9edf2;
    vertical-align: top;
}

.data-table tbody tr:last-child td {
    border-bottom: 0;
}

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

.decision-row--danger td:first-child {
    box-shadow: inset 3px 0 var(--red);
}

.decision-row--warning td:first-child {
    box-shadow: inset 3px 0 #c77a18;
}

.decision-row--positive td:first-child {
    box-shadow: inset 3px 0 var(--green);
}

.btn {
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 12px;
    color: var(--ink-soft);
    background: var(--slate-soft);
    border: 1px solid transparent;
    border-radius: 8px;
    font-size: 12px;
    font-weight: 750;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
}

.btn:hover {
    filter: brightness(0.98);
}

.btn.primary {
    color: #fff;
    background: var(--blue);
}

.btn.danger {
    color: var(--red);
    background: var(--red-soft);
}

.btn.good {
    color: var(--green);
    background: var(--green-soft);
}

.btn.subtle {
    color: var(--ink-soft);
    background: #fff;
    border-color: var(--line-strong);
}

.btn.inspect {
    color: var(--blue);
    background: var(--blue-soft);
}

.btn[disabled],
.btn.is-loading {
    opacity: 0.62;
    cursor: wait;
}

.actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

/*
 * Each action is a separate POST, so every button is wrapped in its own form.
 * Without this the form is the flex item, not the button: forms stretch to the
 * tallest row by default and size to their own content, so the buttons ended up
 * different heights and out of line. display:contents removes the form from
 * layout entirely and lets the buttons be the flex items they look like.
 */
.actions form {
    display: contents;
}

/* One width for every action, so the columns line up down the table. Nowrap
   because a two-word label breaking in half is what made a row of equal-width
   buttons render at two different heights. */
.actions .btn {
    min-width: 86px;
    box-sizing: border-box;
    white-space: nowrap;
}

/* ---------------- bulk selection ---------------- */

/* Narrow, and never the cell that decides the row height. */
.col-select {
    width: 34px;
    padding-right: 0;
    text-align: center;
    vertical-align: middle;
}

.col-select input[type="checkbox"] {
    width: 16px;
    min-height: 0;
    height: 16px;
    margin: 0;
    padding: 0;
    accent-color: var(--ink);
    cursor: pointer;
}

/*
 * Sits between the filter bar and the table it acts on, so the count and the
 * buttons are next to the rows they refer to rather than at the far end of a
 * 50-row scroll.
 */
.bulk-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    padding: 12px 19px;
    background: #fbfcfd;
    border-bottom: 1px solid var(--line);
}

/* Selected rows are a live state, so the bar says so rather than looking
   identical whether or not it will do anything. */
.bulk-bar.is-active {
    background: #f2f6ff;
    box-shadow: inset 3px 0 0 var(--ink);
}

.bulk-bar-count {
    flex: 1 1 200px;
    margin: 0;
    padding-bottom: 10px;
    color: var(--muted);
    font-size: 12px;
}

.bulk-bar-count strong {
    color: var(--ink);
    font-size: 14px;
}

.bulk-bar-hint {
    display: block;
    margin-top: 2px;
    font-size: 11px;
}

.bulk-bar-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px;
}

.bulk-bar-score {
    width: 96px;
}

/* Match the 40px inputs beside them; .btn is 36px and reads as sitting low. */
.bulk-bar-actions .btn {
    min-height: 40px;
    white-space: nowrap;
}

/* Nothing ticked: the buttons are visibly not offering anything yet, rather
   than looking pressable and then refusing. */
.bulk-bar .btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}

/* A bulk write can take a moment. The whole bar goes quiet for its duration so
   a second button cannot be pressed while the first is still running. */
form.is-busy {
    position: relative;
    opacity: 0.7;
    pointer-events: none;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 12px;
    align-items: end;
}

/* Helper text belongs under the whole row, never inside one cell of it. The
   cells are bottom-aligned, so a .field carrying a <small> puts that text on
   the shared baseline and lifts its own input above every neighbour — which is
   what made the filter bar look broken. */
.form-grid-note {
    grid-column: 1 / -1;
    margin: -4px 0 0;
    color: var(--muted);
    font-size: 11px;
}

/* More than one hint under the same row: each keeps its own line so they do not
   read as one run-on sentence. */
.form-grid-note span {
    display: block;
}

.form-grid-note span + span {
    margin-top: 3px;
}

/* .btn is 36px and the inputs it lines up with are 40px. */
.form-grid > .field > .btn {
    min-height: 40px;
}

/*
 * A cell that holds nothing but a button.
 *
 * .field spans 3 of 12 columns, which is right for a labelled input and absurd
 * for the word "Clear" — Search and Clear were taking half the filter bar
 * between them and pushing the field they belong to into a corner. Two columns
 * with the button sized to its own text keeps the row reading as one input
 * followed by its actions.
 */
.form-grid > .field.action {
    grid-column: span 2;
    align-content: end;
}

.form-grid > .field.action > .btn {
    justify-self: start;
    white-space: nowrap;
}

.form-stack {
    display: grid;
    gap: 13px;
}

.field {
    display: grid;
    grid-column: span 3;
    gap: 6px;
    min-width: 0;
}

.field.wide {
    grid-column: span 6;
}

.field.full {
    grid-column: 1 / -1;
}

.field label {
    color: #4f5d70;
    font-size: 12px;
    font-weight: 750;
}

.field small {
    color: var(--muted);
    font-size: 11px;
}

input,
select,
textarea {
    width: 100%;
    min-height: 40px;
    padding: 8px 10px;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
}

input:focus,
select:focus,
textarea:focus {
    border-color: #7197f2;
    outline: 3px solid rgba(36, 93, 204, 0.13);
}

textarea {
    /* Inherit rather than fall back to the browser monospace default, so a
       pasted list reads in the same face as the tables it will appear in. */
    font: inherit;
    line-height: 1.6;
    resize: vertical;
}

/* Bulk add: a textarea of one rule per line, then a single row of controls.
   Not .form-grid — that grid bottom-aligns its cells, so any field carrying
   helper text pushes its neighbours (and the submit button) off the shared
   baseline. Here the help sits under the textarea and the control row holds
   nothing but label + input pairs of equal height, which is what keeps the
   button level with the fields instead of hanging below them. */
/*
 * One explicit column. Without the template this was an implicit grid, and the
 * textarea's .field carries grid-column: span 3 for the 12-column .form-grid —
 * so it conjured three implicit columns and left the control row sitting in the
 * first one, at a third of the width.
 */
.bulk-add {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
}

/* Same reason: span 3 means nothing here, and full width is what is wanted. */
.bulk-add > .field {
    grid-column: 1 / -1;
}

.bulk-add textarea {
    min-height: 118px;
}

/*
 * The controls sit on one row; the note always takes a line of its own beneath.
 *
 * The note used to be flex:1 1 190px, wedged between the fields and the submit
 * button, so how much room it claimed depended on how many fields the current
 * tab rendered. On Domains it fitted and the button stayed on the line; on
 * Emails it did not, and the button dropped to a line of its own.
 *
 * The fix is flex-basis:100% plus order:99 on the note — it is pushed last and
 * forced to wrap, so the controls before it always share one row. An attempt at
 * this with grid-template-columns: repeat(auto-fit, minmax(0, max-content)) is
 * what shipped before, and that is invalid: repeat() rejects intrinsic sizes
 * under auto-fit, so the whole declaration was dropped and the container fell
 * back to one column with every control stacked.
 */
.bulk-add-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
}

.bulk-add-controls .field {
    display: grid;
    flex: 0 0 150px;
    gap: 6px;
    width: 150px;
}

.bulk-add-note {
    flex: 1 0 100%;
    /* After every control, whatever the tab rendered. */
    order: 99;
    margin: 0;
    color: var(--muted);
    font-size: 11px;
    line-height: 1.5;
}

.bulk-add-controls .btn {
    /* .btn is 36px; the inputs beside it are 40px. Bottom-aligned, that 4px
       reads as the button sitting low. Match the field height instead. */
    flex: 0 0 auto;
    min-height: 40px;
    white-space: nowrap;
}

.filter-bar {
    padding: 15px 19px;
    background: #fbfcfd;
    border-bottom: 1px solid var(--line);
}

.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

.tab {
    padding: 8px 12px;
    color: var(--muted);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 750;
    text-decoration: none;
}

.tab.active {
    color: #fff;
    background: var(--ink);
    border-color: var(--ink);
}

.guide-panel {
    margin-bottom: 16px;
    overflow: hidden;
    color: #294a74;
    background: #f0f6ff;
    border: 1px solid #ccddf7;
    border-radius: 11px;
}

.guide-panel summary {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 12px 14px;
    list-style: none;
    cursor: pointer;
}

.guide-panel summary::-webkit-details-marker {
    display: none;
}

.guide-panel summary span:not(.guide-icon) {
    display: grid;
}

.guide-panel summary small {
    color: #587193;
    font-size: 11px;
}

.guide-icon {
    width: 25px;
    height: 25px;
    display: grid;
    flex: none;
    place-items: center;
    color: #fff;
    background: var(--blue);
    border-radius: 50%;
    font-weight: 900;
}

.guide-panel ul {
    margin: 0;
    padding: 0 20px 14px 54px;
    color: #435f81;
}

.guide-panel li + li {
    margin-top: 5px;
}

/* Inline row editor: the summary is the Edit button, the panel is the form. */
.row-edit summary {
    display: inline-flex;
    min-width: 86px;
    box-sizing: border-box;
    list-style: none;
    cursor: pointer;
}

.row-edit summary::-webkit-details-marker {
    display: none;
}

/*
 * Open, the panel takes a line of its own below the buttons instead of forcing
 * itself into the middle of the row and shoving the others out of alignment.
 */
.row-edit[open] {
    flex-basis: 100%;
    order: 99;
    margin-top: 4px;
    padding: 10px;
    background: #f7f9fc;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.row-edit[open] summary {
    margin-bottom: 8px;
}

.row-edit .form-grid {
    gap: 8px;
}

.row-edit .field {
    min-width: 96px;
}

.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 13px 16px;
    color: var(--muted);
    background: #fbfcfd;
    border-top: 1px solid var(--line);
    font-size: 12px;
}

/* The approval queue is the one card on Overview that is asking a question
   rather than reporting. Warm edge so it reads as an inbox, not a status panel. */
.card.needs-attention {
    border-color: #e7c86a;
    box-shadow: 0 0 0 3px rgba(231, 200, 106, 0.14);
}

.page-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
}

.page-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Square-ish and equal width regardless of digit count, so the row does not
       shift under the pointer as the numbers grow from 9 to 10. */
    min-width: 32px;
    min-height: 32px;
    padding: 0 7px;
    color: var(--ink-soft);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    font-size: 12px;
    font-weight: 750;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}

.page-number:hover {
    border-color: var(--line-strong);
}

.page-number.is-current {
    color: #fff;
    background: var(--ink);
    border-color: var(--ink);
}

.page-gap {
    padding: 0 2px;
    color: var(--muted);
}

/* Prev/Next hold their place at both ends of the range rather than vanishing,
   so the numbers keep the same position on the first and last page. */
.btn.is-disabled {
    opacity: 0.4;
    pointer-events: none;
}

.empty-state {
    display: grid;
    gap: 5px;
    padding: 38px 20px;
    color: var(--muted);
    text-align: center;
}

.empty-state strong {
    color: var(--ink-soft);
}

.issue-list {
    display: grid;
}

.issue {
    display: grid;
    grid-template-columns: 10px minmax(0, 1fr);
    gap: 10px;
    padding: 12px 0;
    color: inherit;
    border-bottom: 1px solid var(--line);
    text-decoration: none;
}

.issue:last-child {
    border-bottom: 0;
}

.issue-dot {
    width: 9px;
    height: 9px;
    margin-top: 5px;
    background: #c77a18;
    border-radius: 50%;
}

.issue strong,
.issue span {
    display: block;
}

.issue span {
    margin-top: 2px;
    color: var(--muted);
    font-size: 12px;
}

.site-cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.site-card {
    display: grid;
    gap: 9px;
    padding: 15px;
    color: inherit;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 11px;
    text-decoration: none;
}

.site-card:hover {
    border-color: #aac0e9;
    box-shadow: 0 6px 18px rgba(36, 93, 204, 0.08);
}

.site-card h3,
.site-card p {
    margin: 0;
}

.site-card h3 {
    font-size: 14px;
}

.site-card p {
    color: var(--muted);
    overflow: hidden;
    font-size: 11px;
    text-overflow: ellipsis;
}

.site-card-data {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}

.site-card-data span {
    padding: 8px;
    color: var(--muted);
    background: #f5f7fa;
    border-radius: 8px;
    font-size: 10px;
    text-transform: uppercase;
}

.site-card-data strong {
    display: block;
    color: var(--ink);
    font-size: 16px;
}

.date-stack {
    display: grid;
    min-width: 116px;
}

.date-stack strong {
    font-size: 12px;
}

.date-stack span {
    color: var(--muted);
    font-size: 11px;
}

.decision-dialog {
    width: min(900px, calc(100vw - 32px));
    max-height: calc(100vh - 32px);
    padding: 0;
    color: var(--ink);
    background: var(--paper);
    border: 0;
    border-radius: 15px;
    box-shadow: 0 26px 80px rgba(7, 18, 33, 0.3);
}

.decision-dialog::backdrop {
    background: rgba(12, 22, 38, 0.64);
    backdrop-filter: blur(2px);
}

.dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    padding: 17px 20px;
    border-bottom: 1px solid var(--line);
}

.dialog-head h2 {
    margin: 2px 0 0;
    font-size: 18px;
}

.icon-btn {
    width: 38px;
    height: 38px;
    color: var(--muted);
    background: var(--slate-soft);
    border: 0;
    border-radius: 9px;
    font-size: 23px;
    cursor: pointer;
}

.dialog-body {
    max-height: calc(100vh - 110px);
    overflow-y: auto;
    padding: 18px 20px 24px;
}

.dialog-status {
    margin: 0 0 14px;
    color: var(--muted);
}

/*
 * auto-fit rather than a fixed count: the fifth cell (Form) would otherwise sit
 * alone on a second row at a quarter of the width, and the count changes again
 * the next time a field is worth showing here. The narrow breakpoints below
 * still override this deliberately.
 */
.detail-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 9px;
    margin-bottom: 14px;
}

.detail-summary span {
    display: grid;
    gap: 2px;
    padding: 10px;
    background: #f5f7fa;
    border-radius: 9px;
}

.detail-summary small {
    color: var(--muted);
    text-transform: uppercase;
}

.json-section {
    margin-top: 10px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.json-section summary {
    padding: 12px 14px;
    background: #f8fafc;
    font-weight: 750;
    cursor: pointer;
}

.json-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 12px;
    color: var(--muted);
    border-top: 1px solid var(--line);
    font-size: 11px;
}

.json-section pre {
    max-height: 390px;
    margin: 0;
    overflow: auto;
    padding: 15px;
    color: #d8e4f3;
    background: #111a28;
    font: 12px/1.55 "SFMono-Regular", Consolas, monospace;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.dialog-error {
    padding: 18px;
    color: var(--red);
    background: var(--red-soft);
    border-radius: 10px;
}

.dialog-error p {
    margin-top: 0;
}

.dialog-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 14px;
    padding: 14px;
    background: #f8fafc;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.dialog-actions p {
    max-width: 570px;
    margin: 3px 0 0;
    color: var(--muted);
    font-size: 11px;
}

.dialog-actions[hidden],
.dialog-actions form[hidden] {
    display: none;
}

.distribution {
    display: flex;
    height: 10px;
    overflow: hidden;
    background: var(--slate-soft);
    border-radius: 999px;
}

.distribution span {
    min-width: 0;
}

.distribution .blocked {
    background: var(--red);
}

.distribution .review {
    background: #d58a28;
}

.distribution .allowed {
    background: var(--green);
}

.breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 13px;
    color: var(--muted);
    font-size: 12px;
}

.breadcrumb a {
    color: var(--blue);
    text-decoration: none;
}

.section-tabs {
    display: flex;
    gap: 7px;
    margin-bottom: 18px;
    overflow-x: auto;
}

@media (max-width: 1120px) {
    .stats-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .two-column,
    .split-equal {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 820px) {
    .app-shell {
        display: block;
    }

    .sidebar {
        position: fixed;
        z-index: 30;
        top: 0;
        bottom: 0;
        left: 0;
        width: 270px;
        height: auto;
        transform: translateX(-105%);
        transition: transform 180ms ease;
    }

    body.nav-open .sidebar {
        transform: translateX(0);
    }

    body.nav-open {
        overflow: hidden;
    }

    .nav-toggle {
        display: inline-grid;
        place-items: center;
    }

    .topbar {
        justify-content: flex-start;
        padding: 15px 18px;
    }

    .page-time {
        display: none;
    }

    .content {
        padding: 20px 18px 42px;
    }

    .field,
    .field.wide {
        grid-column: span 6;
    }

    .site-cards {
        grid-template-columns: 1fr;
    }

    .detail-summary {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 580px) {
    .stats-grid {
        grid-template-columns: 1fr;
    }

    .page-intro,
    .card-head,
    .pager,
    .json-toolbar,
    .dialog-actions {
        align-items: flex-start;
        flex-direction: column;
    }

    .field,
    .field.wide {
        grid-column: 1 / -1;
    }

    /* Too narrow for a shared baseline: give every control the full width and
       let the button finish the stack rather than wrap to a lonely half-row. */
    .bulk-add-controls .field,
    .bulk-add-controls .btn {
        flex: 1 0 100%;
        width: auto;
    }

    /* Same reasoning for the bulk bar: the count on its own line, then the
       buttons as a full-width stack rather than three orphaned half-rows. */
    .bulk-bar-actions {
        width: 100%;
    }

    .bulk-bar-actions .btn {
        flex: 1 1 100%;
    }

    .bulk-bar-score {
        width: 100%;
    }

    .detail-summary {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        transition: none !important;
    }
}

/* ------------------------------------------------------------------ */
/* Per-site detection rules (Site → Settings)                          */
/* ------------------------------------------------------------------ */

.rule-tune-intro {
    margin: 0 0 18px;
    max-width: 78ch;
    color: var(--ink-soft);
    font-size: 13.5px;
    line-height: 1.6;
}

.rule-group {
    margin: 26px 0 2px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--line-strong);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.rule-tune {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 190px;
    gap: 14px 24px;
    align-items: start;
    padding: 18px 0;
    border-bottom: 1px solid var(--line);
}

/* A rule carrying a stored row is marked, so "what has someone changed
   here" is answerable at a glance rather than by reading every control. */
.rule-tune.is-tuned {
    margin: 0 -14px;
    padding-left: 14px;
    padding-right: 14px;
    background: var(--blue-soft);
    border-radius: 8px;
}

.rule-tune-name {
    margin: 0 0 3px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink);
}

.rule-tune-name code {
    margin-left: 6px;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--muted);
}

.rule-tune-default {
    margin-left: 6px;
    font-size: 11px;
    font-weight: 500;
    color: var(--muted);
    white-space: nowrap;
}

.rule-tune-help {
    margin: 0 0 10px;
    max-width: 68ch;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--ink-soft);
}

/* The example is the point of this screen: an operator should not have to
   guess what "url_in_short_field" means when a filled-in field says it. */
.rule-example {
    border-left: 2px solid var(--line-strong);
    padding-left: 12px;
}

.rule-example-caption {
    display: block;
    margin-bottom: 5px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
}

.rule-example-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
}

.rule-example-field {
    flex: none;
    padding: 2px 8px;
    background: var(--slate-soft);
    border-radius: 4px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-soft);
}

.rule-example-value {
    flex: 1 1 260px;
    min-width: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    line-height: 1.5;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.rule-example-value em {
    color: var(--muted);
    font-style: italic;
}

/* One number, and what that number does. The reading matters more than the
   input, so the effect line is given real weight rather than hint styling. */
.rule-tune-control {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 12px 14px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
}

.rule-tune-control label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}

.rule-score {
    width: 100%;
    max-width: 110px;
    padding: 8px 10px;
    font-size: 20px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
    text-align: center;
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: var(--paper);
}

.rule-score:focus {
    outline: 2px solid var(--blue);
    outline-offset: 1px;
}

.rule-effect {
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
}

.rule-effect.is-off      { color: var(--muted); }
.rule-effect.is-partial  { color: var(--ink-soft); }
.rule-effect.is-blocks   { color: var(--red); }

.rule-reset {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 11.5px;
    color: var(--blue);
    text-decoration: underline;
    cursor: pointer;
}

.rule-reset:hover { color: var(--ink); }

.rule-tune-save {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 22px;
}

@media (max-width: 900px) {
    .rule-tune {
        grid-template-columns: 1fr;
    }

    .rule-tune-control {
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 10px 14px;
    }

    .rule-score {
        max-width: 88px;
    }
}
