/* ═══════════════════════════════════════════════════════════════════
   Umbra Network — Shared components

   Loaded after umbra.css, before the page CSS. Holds every cross-page
   pattern so the product stays visually consistent.

   Sections:
     1. Animations
     2. Status dots
     3. Titles (cards + modals + sections)
     4. Buttons (base + variants)
     5. Corner brackets
     6. Typography utilities
     7. Custom dropdown
     8. A11y (reduced motion + touch)
     9. Modal primitive
    10. Card footer + view-all button
    11. Modal size variants + body
    12. Modal ↔ app-header layering + mobile fullscreen
    13. Modal centering
    14. Cards, feeds (events / sessions), skeletons
   ─────────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════
   1. ANIMATIONS
   ─────────────────────────────────────────────────────────────────── */

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.6; }
}

@keyframes ban-pulse {
    0%, 100% {
        box-shadow:
            0 0 10px color-mix(in srgb, var(--umbra-ban) 70%, transparent),
            0 0 4px  color-mix(in srgb, var(--umbra-ban) 90%, transparent);
        transform: scale(1);
    }
    50% {
        box-shadow:
            0 0 22px var(--umbra-ban),
            0 0 10px var(--umbra-ban);
        transform: scale(1.12);
    }
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ═══════════════════════════════════════════════════════════════════
   2. STATUS DOTS
   ─────────────────────────────────────────────────────────────────── */

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    flex-shrink: 0;
    display: inline-block;
    animation: pulse 2s ease-in-out infinite;

    &.success { background: var(--umbra-success); box-shadow: 0 0 8px var(--success-glow); }
    &.warning { background: var(--umbra-warning); box-shadow: 0 0 8px var(--warning-glow); }
    &.error   { background: var(--umbra-error);   box-shadow: 0 0 8px var(--error-glow); animation: ban-pulse 2s ease-in-out infinite; }
    &.info    { background: var(--umbra-info);    box-shadow: 0 0 8px var(--info-glow); }
    &.neutral { background: var(--umbra-fg-dim);  box-shadow: 0 0 6px color-mix(in srgb, var(--umbra-fg-dim) 40%, transparent); animation: none; }
    &.banned  { background: var(--umbra-ban);     box-shadow: 0 0 12px var(--ban-glow), 0 0 6px var(--umbra-ban); animation: ban-pulse 2s ease-in-out infinite; }
}

/* ═══════════════════════════════════════════════════════════════════
   3. TITLES — shared pattern for cards + section headers

   Constant: font-display + 700 + uppercase. Colour varies by context.
   Modal titles diverge enough (size lg, letter-spacing, ink-strong) to
   own their rule in section 9.
   ─────────────────────────────────────────────────────────────────── */

.card-title,
.mail-tracker-card .card-header h2,
.rspamd-card .card-header h2 {
    margin: 0;
    font-family: var(--umbra-font-display);
    font-size: var(--text-md);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: var(--leading-snug);
    color: var(--ink-title);
}

/* ═══════════════════════════════════════════════════════════════════
   4. BUTTONS — shared base + variants

   Base pattern is common (cursor, appearance, radius, uppercase); size
   and font family vary per variant (.btn = dense mono / .auth-button =
   display CTA, kept apart as the login brand button).
   ─────────────────────────────────────────────────────────────────── */

.auth-button {
    border-radius: 0;
    text-transform: uppercase;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: all var(--t-fast) ease;
    line-height: var(--leading-snug);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    border: 1px solid transparent;
    border-radius: 0;
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: var(--leading-snug);
    padding: var(--space-2) 14px;
    transition: background var(--t-fast) ease, border-color var(--t-fast) ease,
                color var(--t-fast) ease, box-shadow var(--t-med) ease;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
.btn:focus-visible { outline: 2px solid var(--umbra-accent); outline-offset: 2px; }

.btn--secondary {
    background: var(--umbra-btn-secondary);
    color: var(--umbra-fg);
    border-color: var(--umbra-accent);
}
.btn--secondary:hover:not(:disabled) {
    background: var(--umbra-btn-secondary-hover);
    border-color: var(--umbra-accent-bright);
    box-shadow: 0 0 16px color-mix(in srgb, var(--umbra-accent) 25%, transparent);
}

.btn--primary {
    background: var(--umbra-accent-deep);
    border-color: var(--umbra-accent-deep);
    color: var(--umbra-on-accent);
    box-shadow: 0 0 20px color-mix(in srgb, var(--umbra-accent) 30%, transparent);
}

.btn--primary:hover:not(:disabled) {
    background: var(--umbra-accent-bright);
    border-color: var(--umbra-accent-bright);
    box-shadow: 0 0 28px color-mix(in srgb, var(--umbra-accent) 50%, transparent);
}

.btn--danger {
    background: var(--umbra-ban);
    border-color: var(--umbra-ban);
    color: var(--umbra-on-accent);
    box-shadow: 0 0 20px color-mix(in srgb, var(--umbra-ban) 30%, transparent);
}
.btn--danger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--umbra-ban) 82%, var(--umbra-on-accent));
    border-color: color-mix(in srgb, var(--umbra-ban) 82%, var(--umbra-on-accent));
    box-shadow: 0 0 26px color-mix(in srgb, var(--umbra-ban) 50%, transparent);
}

/* Icon button — square, neutral, accent on hover. Default 36px; modifiers
   --icon-md (32) / --icon-sm (22) / --icon-danger (solid red on hover).
   .session-kick / .settings-session-revoke stay in markup as JS hooks. */
.btn--icon {
    width: 36px;
    height: 36px;
    padding: 0;
    letter-spacing: 0;
    background: transparent;
    border-color: var(--umbra-border);
    color: var(--umbra-fg-dim);
}
.btn--icon:hover:not(:disabled) {
    color: var(--umbra-accent);
    border-color: var(--umbra-accent);
    box-shadow: 0 0 12px color-mix(in srgb, var(--umbra-accent) 28%, transparent);
}
.btn--icon svg { width: 18px; height: 18px; }

.btn--icon-md { width: 32px; height: 32px; }
.btn--icon-md svg { width: 16px; height: 16px; }

.btn--icon-sm { width: 22px; height: 22px; }
.btn--icon-sm svg { width: 12px; height: 12px; }

.btn--icon-danger:hover:not(:disabled) {
    background: var(--umbra-error);
    border-color: var(--umbra-error);
    color: var(--umbra-on-accent);
    box-shadow: 0 0 12px color-mix(in srgb, var(--umbra-error) 40%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════
   5. CORNER BRACKETS — 4 absolute spans framing a "tactical window".
   Sizes: .bracket (login) / .card-bracket (14px, cards).
   ─────────────────────────────────────────────────────────────────── */

.card-bracket {
    position: absolute;
    z-index: var(--z-raised);
    width: 14px;
    height: 14px;
    pointer-events: none;
    box-sizing: border-box;

    &.tl { top:    -7px; left:  -7px; border-top:    1.5px solid var(--umbra-accent); border-left:  1.5px solid var(--umbra-accent); }
    &.tr { top:    -7px; right: -7px; border-top:    1.5px solid var(--umbra-accent); border-right: 1.5px solid var(--umbra-accent); }
    &.bl { bottom: -7px; left:  -7px; border-bottom: 1.5px solid var(--umbra-accent); border-left:  1.5px solid var(--umbra-accent); }
    &.br { bottom: -7px; right: -7px; border-bottom: 1.5px solid var(--umbra-accent); border-right: 1.5px solid var(--umbra-accent); }
}

/* ═══════════════════════════════════════════════════════════════════
   6. TYPOGRAPHY UTILITIES
   ─────────────────────────────────────────────────────────────────── */

.text-mono       { font-family: var(--umbra-mono); }
.text-display    { font-family: var(--umbra-font-display); }
.text-dim        { color: var(--umbra-fg-dim); }
.text-accent     { color: var(--umbra-accent); }
.text-success    { color: var(--umbra-success); }
.text-warning    { color: var(--umbra-warning); }
.text-error      { color: var(--umbra-error); }

.truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════
   7. CUSTOM DROPDOWN — shared by health (history) + alias (filters)
   ─────────────────────────────────────────────────────────────────── */

.custom-dropdown {
    position: relative;
    display: inline-block;
}

.custom-dropdown-trigger {
    background: var(--umbra-bg-input);
    border: 1px solid var(--umbra-border);
    color: var(--umbra-fg);
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    letter-spacing: 0.04em;
    padding: 6px 10px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 180px;
    justify-content: space-between;
    transition: border-color var(--t-fast) ease;

    &:hover,
    &:focus {
        border-color: var(--umbra-accent);
    }
}

.custom-dropdown.open .custom-dropdown-trigger {
    border-color: var(--umbra-accent);
}

.custom-dropdown-caret {
    color: var(--umbra-fg-dim);
    font-size: var(--text-sm);
    transition: transform var(--t-fast) ease;
}

.custom-dropdown.open .custom-dropdown-caret {
    transform: rotate(180deg);
}

.custom-dropdown-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    min-width: 100%;
    max-width: 280px;
    max-height: 360px;
    overflow-y: auto;
    margin: 0;
    padding: var(--space-1) 0;
    list-style: none;
    background: var(--umbra-bg-card);
    border: 1px solid var(--umbra-border);
    z-index: var(--z-header);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);

    &[hidden] { display: none; }

    &::-webkit-scrollbar { width: 6px; }
    &::-webkit-scrollbar-track { background: transparent; }
    &::-webkit-scrollbar-thumb { background: var(--umbra-border); }
    &::-webkit-scrollbar-thumb:hover { background: var(--umbra-accent); }
}

.custom-dropdown-group-header {
    padding: var(--space-2) var(--space-3) var(--space-1);
    font-family: var(--umbra-mono);
    font-size: var(--text-xs);
    color: var(--umbra-fg-dim);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    pointer-events: none;
    border-top: 1px dashed var(--umbra-border);

    &:first-child { border-top: none; }
}

.custom-dropdown-option {
    padding: 7px var(--space-3);
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    color: var(--umbra-fg);
    letter-spacing: 0.04em;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    transition: background var(--t-fast) ease, color var(--t-fast) ease;

    &:hover,
    &.focused {
        background: var(--accent-soft);
        color: var(--umbra-accent);
    }

    &.selected {
        color: var(--umbra-accent);
        background: color-mix(in srgb, var(--umbra-accent) 5%, transparent);
    }
}

.custom-dropdown-option-check {
    color: var(--umbra-accent);
    font-size: var(--text-base);
    visibility: hidden;
}

.custom-dropdown-option.selected .custom-dropdown-option-check {
    visibility: visible;
}

/* ═══════════════════════════════════════════════════════════════════
   8. A11Y — reduced motion + touch tuning
   ─────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

button,
a,
summary,
[role="button"],
input[type="submit"] {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.gauge-value,
.gauge-extra-value,
.storage-metric-value,
.card-metric-value,
.sidebar-monitoring-value,
#live-clock {
    font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════
   9. MODAL PRIMITIVE — shared by alias, dashboard and future pages.
   ─────────────────────────────────────────────────────────────────── */

/* Freeze the page while a modal is open — only the dialog scrolls. */
html:has(.umbra-modal.open),
body:has(.umbra-modal.open) {
    overflow: hidden;
}

.umbra-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    align-items: center;
    justify-content: center;
}
.umbra-modal.open { display: flex; }
.umbra-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}
.umbra-modal-dialog {
    position: relative;
    background: var(--umbra-bg-card);
    border: 1px solid var(--umbra-border);
    width: min(460px, 92vw);
    max-height: calc(100dvh - var(--header-pad, 60px) * 2 - 64px);
    overflow: auto;
    overscroll-behavior: contain;
    box-shadow: var(--shadow-modal);
}
.umbra-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 0 0 auto;
    padding: 14px 18px;
    border-bottom: 1px solid transparent;
    /* Sticky so it stays put while the dialog scrolls; opaque bg = dialog bg
       so content scrolls cleanly underneath. */
    position: sticky;
    top: 0;
    background: var(--umbra-bg-card);
    z-index: var(--z-base);
}
/* White anchor title (18px) + red gradient divider — the Dashboard pilot. */
.umbra-modal-header h3 {
    margin: 0;
    font-family: var(--umbra-font-display);
    font-size: var(--text-lg);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: var(--leading-snug);
    color: var(--ink-strong);
}
.umbra-modal-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--umbra-accent), transparent);
    box-shadow: 0 0 8px var(--umbra-accent-glow);
    pointer-events: none;
}
.umbra-modal-period {
    color: var(--umbra-fg-dim);
    font-size: var(--text-sm);
    font-weight: 400;
}
.umbra-modal-close {
    background: none;
    border: 0;
    color: var(--umbra-fg-dim);
    font-size: var(--text-xl);
    line-height: var(--leading-none);
    cursor: pointer;
    padding: 0 var(--space-1);
}
.umbra-modal-close:hover { color: var(--umbra-accent); }

.umbra-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: var(--space-3) 18px 18px;
}
@media (max-width: 480px) {
    .umbra-modal-footer { flex-direction: column-reverse; }
    .umbra-modal-footer .btn { width: 100%; text-align: center; }
}

/* Sticky group (header + filters) — e.g. Blocked modal: both stay visible
   while the list scrolls, without a magic height. */
.umbra-modal-stickytop {
    position: sticky;
    top: 0;
    z-index: var(--z-raised);
    background: var(--umbra-bg-card);
    flex: 0 0 auto;
}

/* ═══════════════════════════════════════════════════════════════════
   10. CARD FOOTER + VIEW-ALL BUTTON — shared (mail-tracker, recent events…)
   ─────────────────────────────────────────────────────────────────── */

.umbra-card-footer {
    padding-top: var(--space-3);
    border-top: 1px dashed var(--umbra-border);
    text-align: center;
}
.umbra-viewall-btn {
    background: transparent;
    border: 1px solid var(--umbra-border);
    color: var(--umbra-fg);
    padding: 6px var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.umbra-viewall-btn:hover:not(:disabled) {
    border-color: var(--umbra-accent);
    background: color-mix(in srgb, var(--umbra-accent) 5%, transparent);
}
.umbra-viewall-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* ═══════════════════════════════════════════════════════════════════
   11. MODAL — size variants + body defaults
   ─────────────────────────────────────────────────────────────────── */

.umbra-modal-dialog.umbra-modal-large {
    width: min(640px, 94vw);
    max-height: calc(100dvh - var(--header-pad, 60px) * 2 - 64px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.umbra-modal-dialog.umbra-modal-xlarge {
    width: min(760px, 92vw);
    max-height: calc(100dvh - var(--header-pad, 60px) * 2 - 64px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* NB: never add scrollbar-width/scrollbar-color here — on Chromium 120+ they
   override ::-webkit-scrollbar and revert to the native macOS scrollbar. */
.umbra-modal-body {
    padding: 18px;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;            /* required for a flex child to scroll */
}
.umbra-modal-body p {
    margin: 0;
    color: var(--umbra-fg);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
}
.umbra-modal-body p strong {
    color: var(--umbra-accent);
    font-weight: 600;
}

.umbra-modal-body::-webkit-scrollbar,
.umbra-modal-dialog::-webkit-scrollbar,
.alias-log-list::-webkit-scrollbar       { width: 6px; }
.umbra-modal-body::-webkit-scrollbar-track,
.umbra-modal-dialog::-webkit-scrollbar-track,
.alias-log-list::-webkit-scrollbar-track { background: transparent; }
.umbra-modal-body::-webkit-scrollbar-thumb,
.umbra-modal-dialog::-webkit-scrollbar-thumb,
.alias-log-list::-webkit-scrollbar-thumb { background: var(--umbra-border); }
.umbra-modal-body::-webkit-scrollbar-thumb:hover,
.umbra-modal-dialog::-webkit-scrollbar-thumb:hover,
.alias-log-list::-webkit-scrollbar-thumb:hover { background: var(--umbra-accent); }

/* ═══════════════════════════════════════════════════════════════════
   12. MODAL ↔ APP-HEADER LAYERING + mobile fullscreen
   ─────────────────────────────────────────────────────────────────── */

/* The backdrop (z 1000) would cover the header (z 100) — lift the header
   above the modal so it stays visible (desktop + iPad). */
body:has(.umbra-modal.open) .app-header {
    z-index: var(--z-above-modal);
}

/* iPhone (portrait ≤768 AND landscape ≤932×≤500h): modal = full page, body
   scrolls, header tucks away to free the X button. */
@media (max-width: 768px), (max-width: 932px) and (max-height: 500px) and (orientation: landscape) {
    body:has(.umbra-modal.open) {
        background: var(--umbra-bg-card);
    }
    body:has(.umbra-modal.open) .app-main * {
        visibility: hidden;
    }
    body:has(.umbra-modal.open) .umbra-modal,
    body:has(.umbra-modal.open) .umbra-modal * {
        visibility: visible;
    }
    .umbra-modal {
        align-items: stretch;
        justify-content: stretch;
    }
    .umbra-modal-backdrop {
        display: none;
    }
    .umbra-modal-dialog,
    .umbra-modal-dialog.umbra-modal-large,
    .umbra-modal-dialog.umbra-modal-xlarge {
        width: 100%;
        max-width: none;
        height: var(--app-height, 100%);
        max-height: var(--app-height, 100%);
        overflow-y: auto;
        overscroll-behavior: contain;
        border: none;
        box-shadow: none;
        box-sizing: border-box;
        padding-left: env(safe-area-inset-left);
        padding-right: env(safe-area-inset-right);
        padding-bottom: env(safe-area-inset-bottom);
    }
    body:has(.umbra-modal.open) .app-header {
        transform: translateY(-100%) !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════
   13. MODAL CENTERING — centered in the content area, not under the docked
   sidebar (mirrors the .app-header offset). Off-canvas drawer → full width.
   ─────────────────────────────────────────────────────────────────── */

.umbra-modal {
    left: var(--sidebar-width);
}
@media (any-pointer: coarse) and (max-width: 1024px) {
    .umbra-modal { left: 0; }
}

/* ═══════════════════════════════════════════════════════════════════
   14. CARDS + FEEDS + SKELETONS — multi-page base.
   .card / .card-header / .card-status: base for Dashboard, Health, Alias,
   Settings (each page layers its overrides after). Feeds + skeletons shared.
   ─────────────────────────────────────────────────────────────────── */

.card {
    position: relative;
    background: var(--umbra-bg-card);
    border: 1px solid var(--umbra-border);
    padding: var(--space-5);
    display: flex;
    flex-direction: column;

    &.placeholder {
        opacity: 0.5;

        .card-icon { opacity: 0.4; }
        .card-bracket { border-color: var(--umbra-border); }
    }
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-4);
}

.card-status {
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;

    &.online, &.healthy, &.active, &.ok { color: var(--umbra-success); }
    &.coming-soon                       { color: var(--umbra-fg-dim); }
    &.offline, &.error                  { color: var(--umbra-error); }
}

.empty-state {
    color: var(--umbra-fg-dim);
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    text-align: center;
    padding: var(--space-5);
    letter-spacing: 0.05em;
}

/* ─── Feeds: recent events + active sessions ─── */

/* No inter-item gap: the dash (border-bottom) stays equidistant from the
   content above and below → content vertically centred between two dashes. */
.events-list,
.sessions-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 0;
    margin: 0;
}

.event-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    font-family: var(--umbra-mono);
    font-size: var(--text-sm);
    border-bottom: 1px dashed var(--umbra-border);

    &:last-child { border-bottom: none; }
}

.event-dot {
    width: 6px;
    height: 6px;
    border-radius: var(--radius-full);
    flex-shrink: 0;
    background: var(--umbra-accent);
    box-shadow: 0 0 6px var(--umbra-accent-glow);

    &.success { background: var(--umbra-success); box-shadow: 0 0 6px var(--success-glow); }
    &.warning { background: var(--umbra-warning); box-shadow: 0 0 6px var(--warning-glow); }
    &.error   { background: var(--umbra-error);   box-shadow: 0 0 6px var(--error-glow); }
    &.neutral { background: var(--umbra-fg-dim);  box-shadow: 0 0 6px color-mix(in srgb, var(--umbra-fg-dim) 40%, transparent); }
    &.info    { background: var(--umbra-info);    box-shadow: 0 0 6px var(--info-glow); }
    &.banned {
        background: var(--umbra-ban);
        box-shadow: 0 0 12px var(--ban-glow), 0 0 6px var(--umbra-ban);
        animation: ban-pulse 2s ease-in-out infinite;
    }
}

.event-time {
    color: var(--umbra-fg-dim);
    font-size: var(--text-base);
    letter-spacing: 0.04em;
    flex-shrink: 0;
    width: 64px;
}

.event-tag {
    color: var(--umbra-accent);
    font-size: var(--text-base);
    letter-spacing: 0.08em;
    flex-shrink: 0;
    width: 88px;
    font-weight: 700;

    &.success { color: var(--umbra-success); }
    &.warning { color: var(--umbra-warning); }
    &.error   { color: var(--umbra-error); }
    &.info    { color: var(--umbra-info); }
    &.neutral { color: var(--umbra-fg-dim); }
    &.banned {
        color: var(--umbra-ban);
        text-shadow: 0 0 8px var(--ban-glow);
    }
}

.event-message {
    color: var(--umbra-fg);
    font-size: var(--text-base);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.event-alias {
    font-style: italic;
}

.session-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4) 0;
    border-bottom: 1px dashed var(--umbra-border);

    &:last-child { border-bottom: none; }
}

.session-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    overflow: hidden;
}

.session-line-1 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.session-user {
    color: var(--umbra-fg);
    font-size: var(--text-base);
    font-weight: 700;
    font-family: var(--umbra-font-display);
    letter-spacing: 0.05em;
}

.session-meta {
    color: var(--umbra-fg-dim);
    font-size: var(--text-sm);
    letter-spacing: 0.04em;
    font-family: var(--umbra-mono);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.session-ip {
    font-family: var(--umbra-mono);
}

.session-badge {
    display: inline-block;
    padding: 1px 6px;
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-family: var(--umbra-font-display);
    border: 1px solid currentColor;
    border-radius: 0;
    line-height: 1.4;

    &.self { color: var(--umbra-success); background: color-mix(in srgb, var(--umbra-success) 8%, transparent); }
    &.lan  { color: var(--umbra-fg-dim);  background: transparent; }
    &.wan  { color: var(--umbra-warning); background: color-mix(in srgb, var(--umbra-warning) 8%, transparent); }
}

.session-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-1);
    flex-shrink: 0;
}

.session-time {
    color: var(--umbra-fg-dim);
    font-size: var(--text-sm);
    font-family: var(--umbra-mono);
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* ─── ≤600: tap-to-expand event rows (verb collapses) ─── */
@media (max-width: 600px) {
    .event-item {
        cursor: pointer;
    }

    .event-item.expanded {
        align-items: flex-start;
    }
    .event-item.expanded .event-dot {
        margin-top: var(--space-1);
    }

    .event-item:not(.expanded) .event-sep,
    .event-item:not(.expanded) .event-numbers {
        display: none;
    }

    .event-item:not(.expanded) .event-verb::after {
        content: '…';
        color: var(--umbra-fg-dim);
        margin-left: 2px;
    }

    .event-item.expanded .event-message {
        white-space: normal;
        overflow: visible;
    }

    .event-item.expanded .event-sep {
        display: none;
    }

    .event-item.expanded .event-numbers {
        display: block;
    }
}

/* ─── ≤768 + landscape compact: tighten cards/feeds ─── */
@media (max-width: 768px) {
    .card { padding: 18px; }

    .event-time    { width: 56px; }
    .event-tag     { width: 82px; }
    .event-message { min-width: 0; }

    .session-meta,
    .session-ip {
        overflow-wrap: anywhere;
    }
}

@media (max-width: 932px) and (max-height: 500px) and (orientation: landscape) {
    .session-meta,
    .session-ip {
        overflow-wrap: anywhere;
    }
}

/* ─── Loading skeletons (reduced-motion frozen by the universal block) ─── */
.skeleton {
    display: inline-block;
    width: 100%;
    height: 0.7em;
    background: linear-gradient(90deg,
        var(--umbra-bg-input) 0%,
        var(--umbra-border) 50%,
        var(--umbra-bg-input) 100%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-row {
    list-style: none;
    padding: var(--space-3) 0;
    border-bottom: 1px dashed var(--umbra-border);
}
.skeleton-row:last-child { border-bottom: none; }
.skeleton-row .skeleton { height: 12px; }
.skeleton-row:nth-child(odd)  .skeleton { width: 82%; }
.skeleton-row:nth-child(even) .skeleton { width: 64%; }

/* ═══════════════════════════════════════════════════════════════════
   15. CARD DESIGN LANGUAGE — anchored + ruled modifiers
   The Dashboard-pilot card look, shared by every page. .card--anchored gives
   a card the subtle red hairline shadow and a dominant white h2 title;
   .card-header--ruled adds the aired red divider (18px above + below). Placed
   after the base .card rules and the rspamd/mail-tracker <h2> override so the
   anchored title wins on source order. --divider-bleed = the card's own side
   padding (fallback 20px; wider-padded cards set it to --space-6).
   ─────────────────────────────────────────────────────────────────── */

.card--anchored {
    box-shadow: var(--shadow-card);
}

.card--anchored .card-header h2.card-title {
    color: var(--ink-strong);
    font-size: var(--text-lg);
}

.card-header--ruled {
    position: relative;
    margin-bottom: 36px;
}

.card-header--ruled::after {
    content: "";
    position: absolute;
    left:  calc(var(--divider-bleed, var(--space-5)) * -1);
    right: calc(var(--divider-bleed, var(--space-5)) * -1);
    bottom: -18px;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0%,
        var(--umbra-accent) 15%,
        var(--umbra-accent-bright) 50%,
        var(--umbra-accent) 85%,
        transparent 100%);
    box-shadow: 0 0 12px var(--umbra-accent-glow);
    pointer-events: none;
}
