/* Admin pages: dashboard, server, diagnostics, maintenance, site access
   (admin sheet + live preview), beta. */

/* ==========================================================================
   Admin dashboard
   ========================================================================== */

/* Stat-tile trend sparkline (admin/dashboard.html.twig's sparkline()
   macro) - just spacing; the SVG carries its own colors via var(...) on
   its stroke/fill presentation attributes. */
.stat-sparkline {
    margin-top: 0.5rem;
}

/* Compact variants of the homepage's .feature-card/.feature-icon (see
   "Cards / surfaces" above) for the admin dashboard's "Admin sections"
   grid - a secondary quick-nav surface, not the page's hero content, so
   it uses the same idiom at a tighter density rather than the homepage's
   full padding/icon size. */
.feature-card--compact {
    padding: 1.1rem;
}

.feature-icon-sm {
    width: 2.25rem;
    height: 2.25rem;
    font-size: 1.1rem;
    margin-bottom: 0.5rem;
}

/* The System Health panel's aggregate status pill - a calm static dot
   when everything's fine, and the ONLY thing on the page that moves when
   it isn't (see --attention below). Real signal, not decoration. */
.health-dot {
    display: inline-block;
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 50%;
    background: var(--bs-success);
    flex-shrink: 0;
}

.health-dot--attention {
    background: var(--bs-danger);
    box-shadow: 0 0 0 0 rgba(var(--bs-danger-rgb), 0.6);
}

/* Site access / Beta: something is closed or paused (amber, see the site
   access section below). */
.health-dot--paused {
    background: var(--accent-500);
}

@media (prefers-reduced-motion: no-preference) {
    .health-dot--attention {
        animation: health-pulse 2s ease-out infinite;
    }
}

@keyframes health-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(var(--bs-danger-rgb), 0.55);
    }
    100% {
        box-shadow: 0 0 0 0.6rem rgba(var(--bs-danger-rgb), 0);
    }
}

/* ==========================================================================
   Admin server page (admin/server.html.twig)
   The idle-reclaim panel is the page's one loud element; meters and charts
   share its bar/track vocabulary and stay quiet. Chart series colors are
   the accent stepped down into a chart-safe lightness band (accent-500 is
   too light to read as a 2px line) plus a blue second series - validated
   as a pair against --surface-1 for CVD separation and contrast.
   ========================================================================== */

:root {
    --vm-series-1: #cf7529;
    --vm-series-2: #3987e5;
}

.vm-status-dot--close {
    background: var(--bs-warning);
}

.vm-status-dot--collecting {
    background: var(--text-muted);
}

.vm-reclaim--at-risk {
    border-color: rgba(var(--bs-danger-rgb), 0.5);
}

.vm-reclaim__lede {
    max-width: 68ch;
}

.vm-reclaim__rows {
    display: grid;
    grid-template-columns: 7rem 1fr 3.5rem;
    gap: 0.6rem 1rem;
    align-items: center;
    margin-bottom: 1.25rem;
}

.vm-reclaim__row {
    display: contents;
}

.vm-reclaim__row--muted .vm-bar__fill {
    background: var(--text-muted);
}

.vm-reclaim__name {
    color: var(--text-muted);
    font-size: 0.875rem;
}

.vm-reclaim__value {
    font-variant-numeric: tabular-nums;
    text-align: right;
    font-weight: 600;
}

/* Sits under the bar column only, carrying the idle-line label at the
   same x as the tick drawn through each bar above it. */
.vm-reclaim__scale {
    grid-column: 2;
    position: relative;
    height: 1.1rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.vm-reclaim__scale span {
    position: absolute;
    transform: translateX(-50%);
    white-space: nowrap;
}

.vm-reclaim__notes {
    padding-left: 1.1rem;
}

.vm-bar {
    position: relative;
    height: 0.6rem;
    border-radius: 999px;
    background: var(--surface-2);
}

.vm-reclaim .vm-bar {
    height: 0.9rem;
}

.vm-bar__fill {
    height: 100%;
    min-width: 2px;
    border-radius: 999px;
    background: var(--vm-series-1);
}

.vm-meter--full .vm-bar__fill {
    background: var(--bs-danger);
}

/* The idle line itself - drawn taller than the track so it reads as a
   threshold the fill has to cross, not as part of the fill. */
.vm-bar__mark {
    position: absolute;
    top: -0.3rem;
    bottom: -0.3rem;
    width: 2px;
    margin-left: -1px;
    background: var(--text-primary);
    border-radius: 1px;
}

.vm-meter__value {
    font-size: 1.15rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    margin: 0.15rem 0 0.6rem;
}

.vm-legend {
    display: flex;
    gap: 1rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.vm-legend li {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.vm-legend__swatch {
    display: inline-block;
    width: 0.75rem;
    height: 2px;
    border-radius: 1px;
    flex-shrink: 0;
}

.vm-chart {
    padding: 0.25rem 0 1.5rem 2.5rem;
}

.vm-chart__plot {
    position: relative;
    height: 180px;
    touch-action: pan-y;
}

.vm-chart__plot svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.vm-chart__grid {
    stroke: var(--border-subtle);
    stroke-width: 1;
}

.vm-chart__threshold {
    stroke: var(--text-muted);
    stroke-width: 1;
    stroke-dasharray: 4 4;
}

.vm-chart__ylabel,
.vm-chart__xlabel,
.vm-chart__threshold-label {
    position: absolute;
    font-size: 0.7rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    pointer-events: none;
    white-space: nowrap;
}

.vm-chart__ylabel {
    right: calc(100% + 0.5rem);
    transform: translateY(-50%);
}

.vm-chart__xlabel {
    top: calc(100% + 0.5rem);
    transform: translateX(-50%);
}

.vm-chart__threshold-label {
    right: 0;
    transform: translateY(calc(-100% - 0.25rem));
    background: var(--surface-1);
    padding: 0 0.25rem;
}

.vm-chart__crosshair {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--border-strong);
    pointer-events: none;
}

.vm-chart__dot {
    position: absolute;
    width: 8px;
    height: 8px;
    margin: -4px 0 0 -4px;
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--surface-1);
    pointer-events: none;
}

.vm-chart__tooltip {
    position: absolute;
    top: 0;
    margin-left: 0.75rem;
    min-width: 9rem;
    padding: 0.5rem 0.65rem;
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--bs-border-radius-sm);
    font-size: 0.8rem;
    pointer-events: none;
    z-index: 2;
}

.vm-chart__tooltip--left {
    transform: translateX(calc(-100% - 1.5rem));
}

.vm-chart__tooltip-time {
    color: var(--text-muted);
    margin-bottom: 0.25rem;
}

.vm-chart__tooltip-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.vm-chart__tooltip-row strong {
    margin-left: auto;
    padding-left: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.vm-table-wrap {
    max-height: 20rem;
    overflow-y: auto;
}

@media (max-width: 575.98px) {
    .vm-reclaim__rows {
        grid-template-columns: 5.5rem 1fr 3rem;
    }

    .vm-meter__value {
        font-size: 1rem;
    }
}

/* ==========================================================================
   Admin diagnostics page (diagnostics/index.html.twig)
   Same idiom as the server page: the overall-status panel is the one loud
   element, everything below is quiet rows. Every check is a dot + name +
   right-aligned value, with errors/explanations on a line underneath, so
   a red row reads the same in every section.
   ========================================================================== */

.diag-summary--attention {
    border-color: rgba(var(--bs-danger-rgb), 0.5);
}

.diag-checks {
    list-style: none;
    margin: 0;
    padding: 0;
}

.diag-check {
    display: grid;
    grid-template-columns: 0.55rem minmax(0, 1fr) auto;
    column-gap: 0.85rem;
    align-items: baseline;
    padding: 0.75rem 0;
    border-top: 1px solid var(--border-subtle);
}

.diag-check:first-child {
    border-top: 0;
    padding-top: 0.25rem;
}

.diag-check:last-child {
    padding-bottom: 0;
}

.diag-check__dot {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: var(--bs-success);
    flex-shrink: 0;
}

.diag-check > .diag-check__dot {
    align-self: center;
}

.diag-check--warn .diag-check__dot,
.diag-status--warn .diag-check__dot {
    background: var(--bs-warning);
}

.diag-check--bad .diag-check__dot,
.diag-status--bad .diag-check__dot,
.diag-pill--bad .diag-check__dot {
    background: var(--bs-danger);
}

.diag-check__name {
    font-size: 0.9375rem;
}

.diag-check__name.mono {
    font-size: 0.8125rem;
}

.diag-check__value {
    text-align: right;
    font-size: 0.9375rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.diag-check--bad .diag-check__value {
    color: var(--bs-danger-text-emphasis);
}

.diag-check--warn .diag-check__value {
    color: var(--bs-warning-text-emphasis);
}

.diag-check__meta {
    margin-left: 0.5rem;
    font-weight: 400;
    color: var(--text-muted);
}

.diag-check__detail {
    grid-column: 2 / -1;
    margin-top: 0.3rem;
    font-size: 0.8125rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

.diag-check__detail.mono {
    font-size: 0.75rem;
}

.diag-limits {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1.25rem;
}

.diag-limits .mono {
    font-size: 0.75rem;
}

.diag-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.diag-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.8rem;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    background: var(--surface-2);
    font-size: 0.8125rem;
}

.diag-pill--bad {
    border-color: rgba(var(--bs-danger-rgb), 0.5);
    color: var(--bs-danger-text-emphasis);
}

.diag-status {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    white-space: nowrap;
}

.diag-status--bad {
    color: var(--bs-danger-text-emphasis);
}

.diag-status--warn,
.diag-pill--warn {
    color: var(--bs-warning-text-emphasis);
}

.diag-pill--warn {
    border-color: rgba(var(--bs-warning-rgb), 0.5);
}

.diag-pill--warn .diag-check__dot {
    background: var(--bs-warning);
}

/* "Newer version" / "Unknown": information, not a problem. */
.diag-status--muted,
.diag-pill--muted {
    color: var(--text-muted);
}

.diag-status--muted .diag-check__dot,
.diag-pill--muted .diag-check__dot {
    background: var(--text-muted);
}

/* Software updates: one row per component, grouped under a plain
   heading. A row with something pending is a <details> - same disclosure
   language as the Maintenance page's integrity findings (.mnt-finding):
   hairline rows, chevron at the end that turns when open. */
.diag-updates__group {
    margin: 1.25rem 0 0;
    padding-bottom: 0.4rem;
    font-size: 0.8125rem;
    font-weight: 600;
    border-bottom: 1px solid var(--border-subtle);
}

.diag-updates__list > .diag-updates__group:first-child {
    margin-top: 0.25rem;
}

.diag-update {
    border-bottom: 1px solid var(--border-subtle);
}

.diag-update__summary {
    display: grid;
    grid-template-columns: 0.55rem minmax(0, 1fr) minmax(9rem, auto) 10rem 0.75rem;
    column-gap: 0.85rem;
    align-items: center;
    padding: 0.6rem 0;
    list-style: none;
}

.diag-update__summary > .diag-check__dot {
    background: var(--text-muted);
}

.diag-update--ok .diag-update__summary > .diag-check__dot {
    background: var(--bs-success);
}

.diag-update--warn .diag-update__summary > .diag-check__dot {
    background: var(--bs-warning);
}

.diag-update--bad .diag-update__summary > .diag-check__dot {
    background: var(--bs-danger);
}

details.diag-update > .diag-update__summary {
    cursor: pointer;
}

.diag-update__summary::-webkit-details-marker {
    display: none;
}

details.diag-update > .diag-update__summary:hover .diag-update__name {
    text-decoration: underline;
    text-decoration-color: var(--text-muted);
    text-underline-offset: 0.2em;
}

.diag-update__summary:focus-visible {
    outline: 2px solid var(--accent-500);
    outline-offset: 2px;
    border-radius: var(--bs-border-radius-sm);
}

details.diag-update > .diag-update__summary::after {
    content: '';
    justify-self: end;
    width: 0.45rem;
    height: 0.45rem;
    border-right: 1.5px solid var(--text-muted);
    border-bottom: 1.5px solid var(--text-muted);
    transform: translateY(-0.15rem) rotate(45deg);
}

details.diag-update[open] > .diag-update__summary::after {
    transform: translateY(0.05rem) rotate(-135deg);
}

@media (prefers-reduced-motion: no-preference) {
    details.diag-update > .diag-update__summary::after {
        transition: transform 0.15s ease;
    }
}

.diag-update__name {
    font-size: 0.9375rem;
    overflow-wrap: anywhere;
}

.diag-update__name .mono {
    font-size: 0.8125rem;
}

.diag-update__versions {
    font-variant-numeric: tabular-nums;
}

/* The expanded explanation: indented to the name column so the row's
   dot stays the left edge, two halves side by side where there's room. */
.diag-update__body {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem 2rem;
    margin: 0 0 0.9rem 1.4rem;
    padding: 0.8rem 1rem;
    border-left: 2px solid var(--border-subtle);
    background: var(--surface-2);
    border-radius: 0 var(--bs-border-radius-sm) var(--bs-border-radius-sm) 0;
    font-size: 0.8125rem;
}

.diag-update--bad .diag-update__body {
    border-left-color: rgba(var(--bs-danger-rgb), 0.6);
}

.diag-update--warn .diag-update__body {
    border-left-color: rgba(var(--bs-warning-rgb), 0.6);
}

.diag-update__body p {
    margin-bottom: 0.5rem;
    max-width: 62ch;
}

.diag-update__heading {
    margin-bottom: 0.4rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-muted);
}

/* Where the steps run - the server over SSH, or the local checkout -
   since running a checkout step on the server gets undone by the next
   deploy. */
.diag-update__where {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.1rem 0.55rem;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    font-weight: 600;
}

.diag-update__where::before {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: currentColor;
}

.diag-update__where--server {
    border-color: rgba(var(--bs-warning-rgb), 0.5);
    color: var(--bs-warning-text-emphasis);
}

.diag-update__where--repo {
    border-color: rgba(var(--bs-info-rgb), 0.5);
    color: var(--bs-info-text-emphasis);
}

.diag-update__advisories {
    max-height: 14rem;
    overflow-y: auto;
    margin: 0 0 0.5rem;
    padding-left: 1.1rem;
}

.diag-update__advisories li {
    padding: 0.1rem 0;
}

.diag-update__steps {
    margin: 0;
    padding-left: 1.2rem;
}

.diag-update__steps li {
    padding: 0.15rem 0;
}

.diag-update__steps code,
.mnt-finding__command {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin-top: 0.3rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--bs-border-radius-sm);
    background: var(--bg-page, transparent);
    color: var(--bs-body-color);
    overflow-wrap: anywhere;
    user-select: all;
}

/* "Fixed in the last 30 days": date first, it's a log. */
.diag-fixed__item {
    display: grid;
    grid-template-columns: 6rem minmax(0, 14rem) minmax(0, 1fr);
    column-gap: 0.85rem;
    align-items: baseline;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border-subtle);
}

.diag-fixed__name {
    font-size: 0.9375rem;
    overflow-wrap: anywhere;
}

.diag-fixed__name.mono {
    font-size: 0.8125rem;
}

@media (max-width: 767.98px) {
    .diag-update__summary {
        grid-template-columns: 0.55rem minmax(0, 1fr) 0.75rem;
        row-gap: 0.2rem;
    }

    .diag-update__summary > .diag-update__versions,
    .diag-update__summary > .diag-status {
        grid-column: 2;
    }

    details.diag-update > .diag-update__summary::after {
        grid-column: 3;
        grid-row: 1;
    }

    .diag-update__body {
        grid-template-columns: minmax(0, 1fr);
        margin-left: 0;
    }

    .diag-fixed__item {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0.15rem;
    }
}

.diag-table td,
.diag-table th {
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
    vertical-align: middle;
}

.diag-table th {
    font-weight: 500;
    color: var(--text-muted);
}

.diag-wrap {
    overflow-wrap: anywhere;
}

.diag-note {
    max-width: 68ch;
}

@media (max-width: 575.98px) {
    .diag-check__value {
        grid-column: 2 / -1;
        text-align: left;
        margin-top: 0.15rem;
    }
}

/* ==========================================================================
   Admin maintenance page (admin/maintenance.html.twig)
   The run board is the page's one loud element: one row per scheduled job,
   each with a strip of its recent schedule slots. A filled square is a run
   (green / amber / red by result); a hollow red ring is a slot where the
   cron entry never fired - the difference between "the job is broken" and
   "the job isn't running at all", which a single status dot can't show.
   Everything below the board reuses the diagnostics page's quiet rows.
   ========================================================================== */

.mnt-lede {
    max-width: 68ch;
}

.mnt-board--attention {
    border-color: rgba(var(--bs-danger-rgb), 0.5);
}

.mnt-jobs {
    display: grid;
    grid-template-columns: 0.55rem minmax(11rem, 1fr) minmax(0, 1.5fr) minmax(10rem, auto);
    column-gap: 1rem;
}

.mnt-job {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
    align-items: center;
    row-gap: 0.4rem;
    padding: 0.9rem 0;
    border-top: 1px solid var(--border-subtle);
}

.mnt-job:first-child {
    border-top: 0;
    padding-top: 0;
}

.mnt-job--warn .mnt-job__dot {
    background: var(--bs-warning);
}

.mnt-job--bad .mnt-job__dot {
    background: var(--bs-danger);
}

.mnt-job--never .mnt-job__dot {
    background: var(--text-muted);
}

.mnt-job__name {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.mnt-job__link {
    color: var(--text-primary);
    font-size: 0.9375rem;
    font-weight: 500;
    text-decoration: none;
}

.mnt-job__link:hover,
.mnt-job__link:focus-visible {
    color: var(--accent-400);
    text-decoration: underline;
}

.mnt-job__schedule,
.mnt-strip__caption,
.mnt-job__when {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.mnt-job__strip {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 0;
}

.mnt-strip {
    display: grid;
    grid-template-columns: repeat(var(--mnt-slots), minmax(0, 0.95rem));
    gap: 3px;
}

.mnt-slot {
    display: inline-block;
    aspect-ratio: 1;
    min-width: 0;
    border-radius: 3px;
    background: var(--bs-success);
}

.mnt-slot--warn {
    background: var(--bs-warning);
}

.mnt-slot--bad {
    background: var(--bs-danger);
}

.mnt-slot--missed {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px rgba(var(--bs-danger-rgb), 0.8);
}

.mnt-slot--pending {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--border-strong);
}

.mnt-slot--none {
    background: var(--surface-2);
}

.mnt-job__status {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
}

.mnt-job__state {
    font-size: 0.9375rem;
    font-weight: 600;
}

.mnt-job--warn .mnt-job__state {
    color: var(--bs-warning-text-emphasis);
}

.mnt-job--bad .mnt-job__state {
    color: var(--bs-danger-text-emphasis);
}

.mnt-job--never .mnt-job__state {
    color: var(--text-muted);
}

.mnt-job__message {
    grid-column: 2 / -1;
    margin: 0;
    font-size: 0.8125rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

.mnt-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.25rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-subtle);
}

.mnt-legend li {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.mnt-legend .mnt-slot {
    width: 0.75rem;
}

.mnt-findings {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--border-subtle);
}

.mnt-finding {
    border-bottom: 1px solid var(--border-subtle);
}

.mnt-finding__summary {
    display: grid;
    grid-template-columns: 0.55rem minmax(0, 1fr) auto;
    column-gap: 0.85rem;
    align-items: center;
    padding: 0.7rem 0;
    cursor: pointer;
    list-style: none;
}

.mnt-finding__summary::-webkit-details-marker {
    display: none;
}

.mnt-finding__summary:focus-visible {
    outline: 2px solid var(--accent-500);
    outline-offset: 2px;
    border-radius: var(--bs-border-radius-sm);
}

.mnt-finding--warn .diag-check__dot {
    background: var(--bs-warning);
}

.mnt-finding--bad .diag-check__dot {
    background: var(--bs-danger);
}

.mnt-finding__label {
    font-size: 0.9375rem;
}

/* The count doubles as the open/closed affordance: a chevron after it
   turns when the group expands. */
.mnt-finding__count {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.mnt-finding__count::after {
    content: '';
    display: inline-block;
    width: 0.45rem;
    height: 0.45rem;
    margin-left: 0.6rem;
    border-right: 1.5px solid var(--text-muted);
    border-bottom: 1.5px solid var(--text-muted);
    transform: translateY(-0.15rem) rotate(45deg);
}

.mnt-finding[open] .mnt-finding__count::after {
    transform: translateY(0.05rem) rotate(-135deg);
}

@media (prefers-reduced-motion: no-preference) {
    .mnt-finding__count::after {
        transition: transform 0.15s ease;
    }
}

.mnt-finding__items {
    max-height: 16rem;
    overflow-y: auto;
    padding: 0 0 0.8rem 1.4rem;
}

.mnt-finding__items li {
    padding: 0.2rem 0;
    font-size: 0.75rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

.mnt-finding__items .mnt-finding__error {
    color: var(--bs-danger-text-emphasis);
}

/* The explanation panel opening a finding group - .diag-update__body from
   the Diagnostics page, so both pages explain things the same way. */
.mnt-finding--resolved .diag-check__dot {
    background: var(--bs-success);
}

.mnt-finding--bad .mnt-finding__advice {
    border-left-color: rgba(var(--bs-danger-rgb), 0.6);
}

.mnt-finding--warn .mnt-finding__advice {
    border-left-color: rgba(var(--bs-warning-rgb), 0.6);
}

.mnt-finding__items li + li {
    margin-top: 0.35rem;
}

.mnt-finding__since {
    display: block;
    color: var(--text-muted);
}

.mnt-finding__command {
    margin-top: 0.25rem;
    font-size: 0.75rem;
}

/* A cleanup command listing dozens of leftover folders stays copyable
   (user-select: all) without pushing the rest of the page down. */
.mnt-finding__advice code {
    max-height: 10rem;
    overflow-y: auto;
}

.mnt-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.mnt-filter {
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 0.8125rem;
    text-decoration: none;
}

.mnt-filter:hover,
.mnt-filter:focus-visible {
    border-color: var(--border-strong);
    color: var(--text-primary);
}

.mnt-filter--active {
    border-color: var(--accent-600);
    color: var(--accent-400);
}

.mnt-num {
    font-variant-numeric: tabular-nums;
}

/* Without a floor, the wrap-anywhere message column collapses to a single
   character on a phone and every row grows hundreds of pixels tall - with
   it, the table scrolls sideways inside .table-responsive instead. */
.mnt-history td:last-child {
    min-width: 16rem;
}

/* Phones: name, then strip, then status as one left-aligned line, each on
   its own row - side by side, the long "last run" line squeezed the job
   name down to a word per line. */
@media (max-width: 767.98px) {
    .mnt-jobs {
        grid-template-columns: 0.55rem minmax(0, 1fr);
    }

    .mnt-job__name,
    .mnt-job__strip,
    .mnt-job__status,
    .mnt-job__message {
        grid-column: 2;
    }

    .mnt-job__status {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0 0.6rem;
        text-align: left;
    }

    .mnt-job__state {
        font-size: 0.8125rem;
    }
}

/* --- Admin sheet --- */

.sa-sheet.panel {
    padding: 0;
}

.sa-row {
    padding: 1.5rem 1.75rem;
}

.sa-row + .sa-row {
    border-top: 1px solid var(--border-subtle);
}

.sa-row__head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: 0.25rem 0.85rem;
}

.sa-row__head .health-dot {
    margin-top: 0.45rem;
}

.sa-row__desc {
    color: var(--text-muted);
    font-size: 0.875rem;
    margin: 0.15rem 0 0;
    max-width: 52ch;
}

.sa-switch {
    position: relative;
    display: inline-flex;
    padding: 2px;
    border: 1px solid var(--border-strong);
    border-radius: var(--bs-border-radius-pill);
}

.sa-switch__input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.sa-switch__option {
    padding: 0.3rem 0.85rem;
    border-radius: var(--bs-border-radius-pill);
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
}

.sa-switch__option:hover {
    color: var(--text-primary);
}

.sa-switch__input:checked + .sa-switch__option {
    background: var(--surface-2);
    color: var(--text-primary);
    box-shadow: inset 0 0 0 1px var(--border-strong);
}

.sa-switch__input:focus-visible + .sa-switch__option {
    outline: 2px solid var(--accent-500);
    outline-offset: 2px;
}

.sa-message {
    margin-top: 1.25rem;
}

.sa-message__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.sa-message__head .pref-toggle {
    flex-shrink: 0;
}

/* A language whose text is still empty while another one has custom
   text - saving is refused until it's filled in or both are cleared. */
.sa-message__head .pref-toggle-option.is-missing:not(.active) {
    color: var(--accent-400);
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}

.sa-message__input {
    font-size: 0.925rem;
}

.sa-message__foot {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    margin-top: 0.4rem;
    color: var(--text-muted);
    font-size: 0.8rem;
}

.sa-message__foot .btn-link {
    font-size: inherit;
}

.sa-window {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
    margin-top: 1.25rem;
}

.sa-placeholders {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0.5rem 0 0;
    color: var(--text-muted);
    font-size: 0.8rem;
}

.sa-placeholder {
    appearance: none;
    padding: 0.05rem 0.45rem;
    border: 1px solid var(--border-strong);
    border-radius: 0.35rem;
    background: var(--surface-2);
    color: var(--text-primary);
    font: inherit;
}

.sa-placeholder:hover {
    border-color: var(--accent-600);
}

.sa-link-hint {
    margin: 0.5rem 0 0;
    font-size: 0.8rem;
}

.sa-link-hint code {
    color: var(--text-primary);
    white-space: nowrap;
}

.sa-save {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin-top: 1rem;
}

.sa-save__state {
    color: var(--accent-400);
    font-size: 0.875rem;
}

.sa-save__meta {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 0.8rem;
}

/* --- Live preview --- */

.sa-preview__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
}

.sa-preview__frame {
    overflow: hidden;
    border: 1px solid var(--border-strong);
    border-radius: var(--bs-border-radius-lg);
    background: var(--surface-0);
    min-height: 22rem;
}

.sa-preview__chrome {
    display: flex;
    align-items: center;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid var(--border-subtle);
    font-weight: 700;
    font-size: 0.9rem;
}

.sa-preview__chrome-links {
    display: flex;
    gap: 0.4rem;
    margin-left: auto;
}

.sa-preview__chrome-links i,
.sa-preview__page i {
    display: block;
    height: 0.45rem;
    border-radius: 0.25rem;
    background: var(--surface-2);
}

.sa-preview__chrome-links i {
    width: 1.6rem;
}

.sa-preview__pane {
    padding: 1.25rem;
}

.sa-preview__pane[data-kind='notice'],
.sa-preview__pane[data-kind='announcement'] {
    padding: 0;
}

.sa-preview__pane .panel {
    padding: 1.25rem;
}

.sa-preview__notice .site-notice__inner {
    padding: 0 1rem;
}

.sa-preview__page {
    padding: 1.5rem 1.25rem;
}

.sa-preview__page i {
    height: 0.6rem;
    margin-bottom: 0.7rem;
    background: var(--surface-1);
}

.sa-preview__page i:nth-child(1) {
    width: 45%;
    height: 1rem;
    margin-bottom: 1.1rem;
}

.sa-preview__page i:nth-child(2) {
    width: 85%;
}

.sa-preview__page i:nth-child(3) {
    width: 60%;
}

.sa-preview__caption {
    margin: 0.75rem 0 0;
    color: var(--text-muted);
    font-size: 0.85rem;
}

@media (prefers-reduced-motion: no-preference) {
    .sa-preview__pane:not([hidden]) {
        animation: sa-pane-in 160ms ease-out;
    }
}

@keyframes sa-pane-in {
    from {
        opacity: 0;
    }
}

@media (min-width: 992px) {
    .sa-preview {
        position: sticky;
        top: 6rem;
    }
}

@media (max-width: 575.98px) {
    .sa-row {
        padding: 1.25rem 1rem;
    }

    .sa-row__head {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .sa-row__head .sa-switch {
        grid-column: 2;
        justify-self: start;
        margin-top: 0.5rem;
    }

    .sa-window {
        grid-template-columns: minmax(0, 1fr);
    }

    .sa-save__meta {
        margin-left: 0;
    }
}

/* Admin Beta tab (admin/beta.html.twig) */
.beta-table td,
.beta-table th {
    vertical-align: middle;
}

.beta-table__message {
    max-width: 32rem;
    white-space: pre-line;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.beta-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.beta-actions form {
    display: flex;
    gap: 0.35rem;
    margin: 0;
}

.beta-actions .form-select {
    width: auto;
}

.beta-emails {
    font-family: var(--bs-font-monospace);
    font-size: 0.8rem;
}

/* Long free text in admin tables (job output, changelog, bug reports). */
.text-pre-wrap {
    white-space: pre-wrap;
    word-break: break-word;
}
