/* public/css/app.css */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');

:root {
    --bg-color: #f9fafb;
    --text-color: #111827;
    --text-muted: #6b7280;
    --primary-color: #16402b;
    /* Brand deep green */
    --primary-hover: #1d5138;
    --surface-color: #ffffff;
    --border-color: #e5e7eb;
    --sidebar-width: 80px;
    --danger-color: #ef4444;
    --success-color: #10b981;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background-color: var(--bg-color);
    color: var(--text-color);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a {
    color: inherit;
    text-decoration: none;
}

/* Auth Container */
.auth-container {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: var(--bg-color);
}

.auth-card {
    background: var(--surface-color);
    padding: 2rem;
    border-radius: 12px;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    width: 100%;
    max-width: 400px;
}

.auth-logo {
    display: flex;
    justify-content: center;
    margin-bottom: 2rem;
    font-size: 1.5rem;
    font-weight: 700;
}

/* Forms */
.form-group {
    margin-bottom: 1rem;
}

.form-label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    color: var(--text-color);
}

.form-input {
    width: 100%;
    padding: 0.75rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    font-family: inherit;
    font-size: 1rem;
    outline: none;
    transition: border-color 0.2s;
}

.form-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(22, 64, 43, 0.1);
}

.btn {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    padding: 0.75rem 1.5rem;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    border: none;
    font-family: inherit;
    font-size: 1rem;
}

.btn-primary {
    background-color: var(--primary-color);
    color: white;
    width: 100%;
}

.btn-primary:hover {
    background-color: var(--primary-hover);
}

/* Destructive actions. Deliberately not the brand green: removing a
   collaborator or a site should not look like every other button. */
.btn-danger {
    background-color: var(--danger-color);
    color: white;
}

.btn-danger:hover {
    background-color: #dc2626;
}

/* Dashboard Layout */
.app-layout {
    display: flex;
    min-height: 100vh;
}

/* Sidebar */
.sidebar {
    width: var(--sidebar-width);
    background-color: var(--surface-color);
    border-right: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    height: 100vh;
    position: fixed;
}

.sidebar-header {
    height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-bottom: 1px solid var(--border-color);
    font-size: 1.5rem;
    font-weight: 700;
}

.sidebar-nav {
    padding: 1rem 0;
    flex: 1;
    overflow-y: auto;
}

.nav-section {
    margin-bottom: 1.5rem;
}

.nav-section-title {
    display: none;
    /* Hide titles in icon-only sidebar */
}

.nav-item {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 56px;
    color: var(--text-color);
    transition: all 0.2s;
    margin: 0.5rem;
    border-radius: 8px;
}

.nav-item:hover,
.nav-item.active {
    background-color: #e6efe9;
    color: var(--primary-hover);
}

/* Main Content */
.main-content {
    flex: 1;
    margin-left: var(--sidebar-width);
    min-height: 100vh;
    min-width: 0;
}

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2rem;
}

.page-title {
    font-size: 1.875rem;
    font-weight: 700;
}

.page-subtitle {
    color: var(--text-muted);
    margin-top: 0.25rem;
}

/* Cards / Metrics */
.metrics-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 1.5rem;
    margin-bottom: 2rem;
}

.card {
    background: var(--surface-color);
    border-radius: 12px;
    padding: 1.5rem;
    border: 1px solid var(--border-color);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 1rem;
}

.card-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-muted);
}

.card-value {
    font-size: 2rem;
    font-weight: 700;
}

.card-subtext {
    font-size: 0.875rem;
    color: var(--text-muted);
    margin-top: 0.5rem;
}

/* Tables */
.table-container {
    background: var(--surface-color);
    border-radius: 12px;
    border: 1px solid var(--border-color);
    overflow: hidden;
}

.table-header {
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--border-color);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th,
td {
    padding: 1rem 1.5rem;
    text-align: left;
    border-bottom: 1px solid var(--border-color);
}

th {
    background-color: #fdfdfd;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
}

tr:last-child td {
    border-bottom: none;
}

.badge {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 600;
}

.badge-success {
    background-color: #d1fae5;
    color: #065f46;
}

.badge-warning {
    background-color: #fef3c7;
    color: #92400e;
}

.badge-neutral {
    background-color: #e5e7eb;
    color: #374151;
}

.badge-danger {
    background-color: #fee2e2;
    color: #b91c1c;
}

/* Site Views */
.sites-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.5rem;
}

.sites-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.view-toggle {
    display: flex;
    gap: 0.5rem;
    background: var(--surface-color);
    padding: 0.25rem;
    border-radius: 8px;
    border: 1px solid var(--border-color);
}

.view-btn {
    padding: 0.5rem;
    border: none;
    background: transparent;
    border-radius: 6px;
    cursor: pointer;
    color: var(--text-muted);
}

.view-btn.active {
    background: #f3f4f6;
    color: var(--text-color);
}

/* Tooltips */
[title] {
    position: relative;
}

/* Site Navigation Buttons */
.site-nav-btn {
    background: transparent;
    border: none;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.6);
    cursor: pointer;
    text-align: left;
    transition: all 0.2s;
}

.site-nav-btn:hover {
    color: rgba(255, 255, 255, 0.9);
    background: rgba(255, 255, 255, 0.1);
}

.site-nav-btn.active {
    background: rgba(255, 255, 255, 0.2);
    color: white;
}

.tab-content {
    display: none;
}

/* Dropdown */
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-menu {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: 0.5rem;
    background-color: var(--surface-color);
    min-width: 160px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    border-radius: 8px;
    border: 1px solid var(--border-color);
    z-index: 10;
    overflow: hidden;
}

.dropdown.open .dropdown-menu {
    display: block;
}

.dropdown-item {
    padding: 0.75rem 1rem;
    display: block;
    color: var(--text-color);
    text-decoration: none;
    font-size: 0.875rem;
    width: 100%;
    text-align: left;
    border: none;
    background: transparent;
    cursor: pointer;
}

.dropdown-item:hover {
    background-color: #f3f4f6;
}

.text-danger {
    color: var(--danger-color);
}

/* Split Layout for Auth pages */
.split-layout-container {
    display: flex;
    min-height: 100vh;
    width: 100%;
    margin: 0;
    padding: 0;
    background-color: var(--surface-color);
}

.split-left-pane {
    width: 35%;
    background-color: #eaf4ed;
    /* Light green from the design */
    display: flex;
    flex-direction: column;
    padding: 2.5rem;
    position: relative;
}

@media (max-width: 768px) {
    .split-left-pane {
        display: none;
    }

    .split-right-pane {
        width: 100% !important;
    }
}

.split-right-pane {
    width: 65%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: var(--surface-color);
    padding: 2rem;
}

.split-right-content {
    width: 100%;
    max-width: 440px;
}

.split-logo {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 4rem;
    color: var(--text-color);
}

.split-stepper {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-left: 1rem;
}

.stepper-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 1rem;
    position: relative;
    z-index: 1;
}

.stepper-item:not(:last-child)::after {
    content: '';
    position: absolute;
    left: 17px;
    top: 36px;
    bottom: -1rem;
    width: 2px;
    background-color: #10b981;
    /* Green line */
    z-index: -1;
}

.stepper-icon {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 1rem;
    flex-shrink: 0;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.stepper-icon svg {
    color: var(--text-color);
    width: 18px;
    height: 18px;
}

.stepper-content {
    padding-top: 0.25rem;
}

.stepper-title {
    font-weight: 600;
    font-size: 1rem;
    color: var(--text-color);
    margin-bottom: 0.25rem;
}

.stepper-desc {
    font-size: 0.85rem;
    color: #4b5563;
}

.split-footer {
    display: flex;
    justify-content: space-between;
    font-size: 0.875rem;
    font-weight: 500;
    color: #4b5563;
    margin-top: auto;
}

.split-footer a {
    color: #4b5563;
}

.split-footer a:hover {
    color: var(--text-color);
}

/* Registration Form Specific */
.auth-title {
    font-size: 1.875rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
    text-align: center;
}

.auth-subtitle {
    color: var(--text-muted);
    font-size: 0.95rem;
    margin-bottom: 2.5rem;
    text-align: center;
}

.form-input {
    background-color: #ffffff;
    border: 1px solid #d1d5db;
    border-radius: 8px;
}

.btn-primary.btn-dark-green {
    background-color: #243e30;
    /* Dark green from design */
    color: white;
    border-radius: 8px;
    padding: 0.85rem;
}

.btn-primary.btn-dark-green:hover {
    background-color: #1a2d23;
}

.auth-bottom-text {
    text-align: center;
    margin-top: 1rem;
    font-size: 0.875rem;
    color: var(--text-muted);
}

.auth-bottom-text a {
    color: #10b981;
    font-weight: 600;
}

/* Login Page Specific Split Layout */
.login-left-pane {
    width: 50%;
    background-color: var(--surface-color);
    display: flex;
    flex-direction: column;
    padding: 2.5rem;
    position: relative;
}

.login-content-wrapper {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin: 0 auto;
}

.login-logo {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-color);
}

.login-right-pane {
    width: 50%;
}

.bg-dark-green {
    background-color: #243e30;
}

@media (max-width: 768px) {
    .login-right-pane {
        display: none;
    }

    .login-left-pane {
        width: 100% !important;
    }
}
/* ==========================================================================
   WordNyte panel — responsive layer + UI refresh
   Everything below is additive; it layers on top of the base styles above
   rather than replacing them, so existing markup keeps working.
   ========================================================================== */

:root {
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --shadow-sm: 0 1px 2px rgba(16, 24, 40, .05);
    --shadow-md: 0 4px 12px -2px rgba(16, 24, 40, .08), 0 2px 4px -2px rgba(16, 24, 40, .04);
    --shadow-lg: 0 12px 28px -8px rgba(16, 24, 40, .16);
    --brand-deep: #16402b;
    --brand-deep-soft: #1d5138;
    --header-height: 68px;
}

/* ---------- Shared surface polish ---------- */
.card {
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--border-color);
}

.btn {
    border-radius: var(--radius-sm);
    transition: background .18s ease, color .18s ease, border-color .18s ease, transform .06s ease;
}

.btn:active {
    transform: translateY(1px);
}

:where(button, a, input, select, textarea):focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* ---------- Mobile drawer plumbing (shared by both sidebars) ---------- */
.mobile-only {
    display: none;
}

.drawer-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(16, 24, 40, .5);
    z-index: 45;
}

.drawer-backdrop.open {
    display: block;
}

.icon-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px;
    border-radius: var(--radius-sm);
    transition: background .18s ease, color .18s ease;
}

.icon-btn:hover {
    background: #f3f4f6;
    color: var(--text-color);
}

/* ---------- Page header ---------- */
.wn-header {
    padding: 1rem 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    border-bottom: 1px solid var(--border-color);
    background: var(--surface-color);
    position: sticky;
    top: 0;
    z-index: 30;
    min-height: var(--header-height);
}

.wn-header-left {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
}

.wn-header-right {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-shrink: 0;
}

.wn-header-wp-badge {
    overflow: hidden;
}

.wn-header-title {
    font-size: 1.15rem;
    font-weight: 600;
    margin: 0;
    text-transform: capitalize;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wn-search {
    position: relative;
}

.wn-search input {
    padding: .5rem 1rem .5rem 2.5rem;
    border: 1px solid var(--border-color);
    border-radius: 9999px;
    outline: none;
    font-size: .875rem;
    width: 240px;
    font-family: inherit;
    background: var(--bg-color);
    transition: width .2s ease, border-color .2s ease, background .2s ease;
}

.wn-search input:focus {
    width: 280px;
    background: var(--surface-color);
    border-color: var(--primary-color);
}

.wn-search .wn-search-icon {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
    display: flex;
}

/* ---------- Dashboard-specific ---------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1.25rem;
    margin-bottom: 2rem;
}

.stat-card {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1.25rem 1.35rem;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: .35rem;
    position: relative;
    overflow: hidden;
}

.stat-card .stat-label {
    font-size: .8rem;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: .02em;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

.stat-card .stat-value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stat-card .stat-sub {
    font-size: .78rem;
    color: var(--text-muted);
}

.stat-card.is-good .stat-value { color: var(--success-color); }
.stat-card.is-warn .stat-value { color: var(--primary-hover); }
.stat-card.is-bad .stat-value { color: var(--danger-color); }

.panel-grid {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 1.5rem;
    align-items: start;
}

/* Same min-width: auto trap as .wn-overview-layout above — grid items
   don't shrink below their content's max-content size by default. */
.panel-grid > div {
    min-width: 0;
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.status-dot.connected { background: var(--success-color); }
.status-dot.disconnected { background: var(--danger-color); }
.status-dot.never { background: #d1d5db; }

.attention-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .85rem 0;
    border-bottom: 1px solid var(--border-color);
}

.attention-row:last-child {
    border-bottom: none;
}

.attention-meta {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-width: 0;
}

.attention-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pill {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .6rem;
    border-radius: 9999px;
    font-size: .72rem;
    font-weight: 600;
    white-space: nowrap;
}

.pill-warn { background: #fef3c7; color: #92400e; }
.pill-bad { background: #fee2e2; color: #b91c1c; }
.pill-good { background: #d1fae5; color: #065f46; }
.pill-muted { background: #f3f4f6; color: #4b5563; }

.empty-state {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--text-muted);
    font-size: .9rem;
}

/* ---------- Site detail context pane ---------- */
.site-shell {
    display: flex;
    min-height: 100vh;
}

.site-context-pane {
    width: 280px;
    background-color: var(--brand-deep);
    color: #fff;
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    height: 100vh;
    position: sticky;
    top: 0;
    z-index: 50;
}

.site-main-pane {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--surface-color);
    min-width: 0;
}

.site-nav-btn {
    display: block;
    width: 100%;
    text-align: left;
    padding: .75rem 1rem;
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, .82);
    font-size: .92rem;
    font-weight: 500;
    font-family: inherit;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}

.site-nav-btn:hover {
    background: rgba(255, 255, 255, .08);
    color: #fff;
}

.site-nav-btn.active {
    background: var(--brand-deep-soft);
    color: #fff;
    font-weight: 600;
}

/* ---------- Tables ---------- */
.table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table-container table {
    min-width: 520px;
}

/* ==========================================================================
   Responsive
   ========================================================================== */

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

@media (max-width: 900px) {
    /* --- Global icon rail becomes a slide-in drawer --- */
    .sidebar {
        transform: translateX(-100%);
        transition: transform .25s ease;
        z-index: 50;
        width: 240px;
    }

    .sidebar.open {
        transform: translateX(0);
        box-shadow: var(--shadow-lg);
    }

    .sidebar .nav-item {
        justify-content: flex-start;
        gap: .85rem;
        padding: 0 1rem;
    }

    .main-content {
        margin-left: 0;
    }

    .mobile-only {
        display: flex;
    }

    /* --- Site detail context pane becomes a drawer too --- */
    .site-context-pane {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        height: 100dvh;
        transform: translateX(-100%);
        transition: transform .25s ease;
        overflow-y: auto;
    }

    .site-context-pane.open {
        transform: translateX(0);
        box-shadow: var(--shadow-lg);
    }
}

@media (max-width: 768px) {
    .wn-header {
        padding: .75rem 1rem;
    }

    /* Search collapses to an icon-triggered full-width row on small screens */
    .wn-search input {
        width: 150px;
    }

    .wn-search input:focus {
        width: 180px;
    }

    .stat-grid {
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        gap: 1rem;
    }

    .stat-card .stat-value {
        font-size: 1.6rem;
    }

    .metrics-grid {
        grid-template-columns: 1fr;
    }

    .attention-row {
        flex-direction: column;
        align-items: flex-start;
        gap: .5rem;
    }
}

@media (max-width: 560px) {
    .wn-search {
        display: none;
    }

    /* The WP-version badge + resync button is secondary info that was
       crowding the bell/avatar off-screen on narrow phones — drop it here
       and rely on the tab content area to show that same info.
       !important is required: the element carries an inline display:flex,
       which otherwise always wins over an external class rule. */
    .wn-header-wp-badge {
        display: none !important;
    }

    .wn-header-title {
        font-size: 1rem;
    }

    .wn-header-right {
        gap: .6rem;
    }

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

    /* Notification dropdown goes near-full-width so it never overflows */
    #notif-menu {
        width: calc(100vw - 2rem) !important;
        right: -0.5rem !important;
        max-width: 340px;
    }
}

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

/* Respect reduced-motion preferences for every transition added above */
@media (prefers-reduced-motion: reduce) {
    .sidebar,
    .site-context-pane,
    .btn,
    .wn-search input,
    .icon-btn {
        transition: none;
    }
}

/* ==========================================================================
   Site detail — responsive interiors
   Classes extracted from previously-inline layouts so they can actually
   respond to viewport width.
   ========================================================================== */

.wn-tab-content-area {
    padding: 1.5rem;
    flex: 1;
    overflow-y: auto;
    background-color: var(--bg-color);
}

/* --- Card grids (plugins / themes / users) --- */
.wn-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1.5rem;
}

/* Grid items don't shrink below their content's intrinsic width by default
   (min-width: auto) — without this, a 2-column grid can silently overflow
   its container on narrow screens instead of actually fitting the fr track. */
.wn-quickinfo-grid > div {
    min-width: 0;
}

@media (max-width: 480px) {
    .wn-quickinfo-card {
        padding: 1.25rem !important;
    }
}

/* --- Modals --- */
.wn-modal {
    background: #fff;
    border-radius: 20px;
    padding: 2rem;
    width: 100%;
    box-shadow: var(--shadow-lg);
    position: relative;
    max-height: 90dvh;
    overflow-y: auto;
}

/* --- Form grids inside modals --- */
.wn-form-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.25rem;
    margin-bottom: 1.25rem;
}

/* --- Overview hero --- */
.wn-hero {
    background: linear-gradient(135deg, #0e301f 0%, #081d11 100%);
    border-radius: 20px;
    padding: 2.5rem 2rem;
    color: #fff;
    position: relative;
    overflow: hidden;
    margin-bottom: 1.5rem;
}

.wn-hero-eyebrow {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: .35rem;
    position: relative;
    z-index: 1;
}

.wn-hero-title {
    font-size: 2.25rem;
    font-weight: 800;
    margin-bottom: .85rem;
    position: relative;
    z-index: 1;
    letter-spacing: -.025em;
    line-height: 1.1;
}

.wn-hero-sub {
    opacity: .9;
    margin-bottom: 2rem;
    font-size: 1.05rem;
    position: relative;
    z-index: 1;
}

.wn-hero-actions {
    display: flex;
    gap: .75rem;
    position: relative;
    z-index: 1;
    flex-wrap: wrap;
}

.wn-hero-actions button {
    font-family: inherit;
    font-size: .9rem;
}

/* --- Overview two-column layout --- */
.wn-overview-layout {
    display: grid;
    grid-template-columns: minmax(280px, 340px) 1fr;
    gap: 1.5rem;
    align-items: start;
}

/* Grid items default to min-width: auto (their content's max-content size),
   so a track can grow past its container instead of actually shrinking —
   the same failure mode as flexbox's default min-width: auto on items. */
.wn-overview-layout > div {
    min-width: 0;
}

@media (max-width: 1100px) {
    .wn-overview-layout {
        grid-template-columns: 1fr;
    }
}

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

@media (max-width: 768px) {
    .wn-tab-content-area {
        padding: 1rem;
    }

    .wn-hero {
        padding: 1.75rem 1.25rem;
        border-radius: 16px;
    }

    .wn-hero-eyebrow {
        font-size: 1.15rem;
    }

    .wn-hero-title {
        font-size: 1.6rem;
    }

    .wn-hero-sub {
        font-size: .95rem;
        margin-bottom: 1.25rem;
    }

    .wn-hero-actions {
        flex-direction: column;
        align-items: stretch;
    }

    .wn-hero-actions button {
        width: 100%;
        justify-content: center;
    }

    .wn-card-grid {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .wn-modal {
        padding: 1.5rem 1.25rem;
        border-radius: 16px;
    }

    .wn-form-grid {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    /* Site context pane: give the screenshot banner less vertical weight */
    .site-context-pane {
        width: 265px;
    }
}

@media (max-width: 560px) {
    .wn-hero-title {
        font-size: 1.35rem;
    }

    .wn-tab-content-area {
        padding: .85rem;
    }
}

/* Modal overlays need padding so cards never touch the viewport edge */
#userModalOverlay,
#deleteResourceModal,
#addSiteModal {
    padding: 1rem;
}

/* Long plugin/theme/user names must wrap rather than push the card wide */
.wn-card-grid h3,
.wn-card-grid h4,
.wn-card-grid p {
    overflow-wrap: anywhere;
}

/* The updates table's action cell uses flex; keep it from collapsing weirdly
   while still allowing the table itself to scroll horizontally on mobile. */
.table-container td > .btn {
    white-space: nowrap;
}

/* Never let the app scroll sideways as a whole — individual containers
   (tables, code blocks) do their own scrolling instead. */
html, body {
    max-width: 100%;
    overflow-x: hidden;
}

/* --- A5: filter panel --- */
.wn-filter-label {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.4rem;
}

.wn-filter-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    min-width: 0;
}

.wn-filter-row .pill {
    cursor: pointer;
    transition: opacity 0.15s;
}

.wn-filter-row .pill:hover {
    opacity: 0.8;
}

/* Tag chips on site cards */
.wn-tag-chip {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 600;
    padding: 0.12rem 0.45rem;
    border-radius: 999px;
    border: 1px solid currentColor;
    line-height: 1.5;
    white-space: nowrap;
}

/* ==========================================================================
   Profile page
   --------------------------------------------------------------------------
   This page was the last one still carrying stock Breeze markup — Tailwind
   utility classes against a stylesheet that has no Tailwind in it, so every
   one of them resolved to nothing, and Alpine directives against a layout
   that loads no JavaScript. These classes replace both.
   ========================================================================== */

.wn-profile {
    padding: 1.5rem;
    max-width: 820px;
    /* Flex/grid children default to min-width: auto and refuse to shrink
       below their content; without this the page overflows on a phone. */
    min-width: 0;
}

.wn-profile-card {
    margin-bottom: 1.25rem;
}

.wn-profile-danger {
    border-color: #fecaca;
}

.wn-section-head {
    margin-bottom: 1.25rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--border-color);
}

.wn-section-head h3 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0 0 0.3rem;
}

.wn-section-head p {
    color: var(--text-muted);
    font-size: 0.875rem;
    line-height: 1.5;
    margin: 0;
}

/* Two fields side by side on a roomy screen, stacked on a narrow one. */
.wn-field-pair {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 1rem;
}

.wn-field-error {
    color: var(--danger-color);
    font-size: 0.78rem;
    margin: 0.35rem 0 0;
}

/* Buttons in the panel are full-width by default, which is right inside a
   narrow auth card and wrong on a settings form. */
.wn-btn-inline {
    width: auto;
}

.wn-btn-quiet {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-color);
}

.wn-btn-quiet:hover {
    background: var(--bg-color);
}

.wn-linkbutton {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.wn-checkbox {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.9rem;
    margin-bottom: 1.25rem;
}

.wn-checkbox input {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
}

/* --- Banners --- */
.wn-banner {
    padding: 0.85rem 1rem;
    border-radius: var(--radius-sm);
    font-size: 0.875rem;
    line-height: 1.5;
    margin-bottom: 1.25rem;
}

.wn-banner-success { background: #d1fae5; color: #065f46; }
.wn-banner-warn    { background: #fef3c7; color: #92400e; }
.wn-banner-error   { background: #fee2e2; color: #b91c1c; }

/* --- Two-factor setup --- */
.wn-2fa-setup {
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1.25rem;
}

.wn-2fa-step {
    font-size: 0.9rem;
    margin: 0 0 0.35rem;
}

.wn-2fa-step:not(:first-child) {
    margin-top: 1.5rem;
}

.wn-2fa-hint {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin: 0 0 0.75rem;
    word-break: break-word;
}

.wn-secret {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1rem;
    letter-spacing: 0.12em;
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.6rem;
    word-break: break-all;
}

.wn-recovery-codes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 0.4rem;
}

.wn-recovery-codes code {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 0.4rem 0.5rem;
    font-size: 0.8rem;
    text-align: center;
    min-width: 0;
}

.wn-2fa-confirm {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.wn-2fa-confirm .form-group {
    flex: 1;
    min-width: 150px;
}

/* --- Modal overlay, shared shell for the .wn-modal card --- */
.wn-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 50;
}

.wn-modal-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.75rem;
    gap: 1rem;
}

.wn-modal-head h3 {
    font-size: 1.2rem;
    font-weight: 700;
    margin: 0;
}

.wn-modal-head button {
    background: none;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    color: var(--text-muted);
    flex-shrink: 0;
}

.wn-modal-actions {
    display: flex;
    gap: 0.6rem;
    justify-content: flex-end;
    flex-wrap: wrap;
}

.wn-modal-actions .btn {
    width: auto;
}

@media (max-width: 560px) {
    .wn-profile {
        padding: 1rem;
    }

    .wn-field-pair {
        grid-template-columns: minmax(0, 1fr);
    }

    .wn-btn-inline,
    .wn-2fa-confirm .btn {
        width: 100%;
    }
}

/* ==========================================================================
   Client portal (C1)
   --------------------------------------------------------------------------
   A separate shell from the panel on purpose: everything in the app layout —
   sidebar, search, notification bell — is an agency tool, and a client seeing
   greyed-out versions of them would read worse than not seeing them at all.
   Shares the panel's tokens so both halves of the product look related.
   ========================================================================== */

.wn-portal-body {
    background: var(--bg-color);
    color: var(--text-color);
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    /* Only the main region should absorb leftover space; the bar and footer
       are fixed-height and must not be compressed by a column flex parent. */
}

.wn-portal-bar {
    background: var(--brand-deep);
    color: #fff;
    flex-shrink: 0;
}

.wn-portal-bar-inner {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 1.5rem;
    min-height: var(--header-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.wn-portal-brand {
    color: #fff;
    font-weight: 600;
    font-size: 1rem;
    text-decoration: none;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wn-portal-nav {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-shrink: 0;
}

.wn-portal-nav a,
.wn-portal-nav button {
    color: rgba(255, 255, 255, 0.75);
    font-size: 0.875rem;
    font-weight: 500;
    font-family: inherit;
    text-decoration: none;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.wn-portal-nav a:hover,
.wn-portal-nav button:hover { color: #fff; }
.wn-portal-nav a.active { color: #fff; font-weight: 600; }

.wn-portal-main {
    flex: 1;
    min-width: 0;
}

.wn-portal-page,
.wn-portal-narrow {
    max-width: 960px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
    min-width: 0;
}

.wn-portal-narrow {
    max-width: 420px;
    padding-top: 4rem;
}

.wn-portal-foot {
    flex-shrink: 0;
    text-align: center;
    font-size: 0.75rem;
    color: var(--text-muted);
    padding: 2rem 1.5rem;
}

.wn-portal-head { margin-bottom: 1.5rem; }

.wn-portal-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0 0 0.3rem;
}

.wn-portal-lede {
    color: var(--text-muted);
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1.25rem;
}

.wn-portal-h2 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.3rem;
}

.wn-portal-hint {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin: 0 0 0.9rem;
}

.wn-portal-back {
    display: inline-block;
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
    margin-bottom: 1rem;
}

.wn-portal-back:hover { color: var(--text-color); }

/* --- Headline numbers --- */
.wn-portal-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.wn-portal-stat {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1rem 1.1rem;
    min-width: 0;
}

.wn-portal-inline-stats {
    display: flex;
    gap: 2rem;
    flex-wrap: wrap;
}

.wn-portal-stat-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin-bottom: 0.35rem;
}

.wn-portal-stat-value {
    display: block;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.15;
}

.wn-portal-stat-sub {
    display: block;
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.2rem;
}

/* --- Site rows --- */
.wn-portal-site {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.85rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.wn-portal-site:hover {
    border-color: var(--brand-deep-soft);
    box-shadow: var(--shadow-md);
}

.wn-portal-site-main { min-width: 0; }

.wn-portal-site-main h2 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.15rem;
}

.wn-portal-site-host {
    font-size: 0.8rem;
    color: var(--text-muted);
    word-break: break-all;
}

.wn-portal-site-meta {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

.wn-portal-block { margin-bottom: 1.25rem; }

.wn-portal-empty {
    text-align: center;
    padding: 2.5rem 1.5rem;
}

.wn-portal-empty h2 {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0 0 0.35rem;
}

.wn-portal-empty p {
    color: var(--text-muted);
    font-size: 0.875rem;
    margin: 0;
}

.wn-portal-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.wn-portal-list li {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--border-color);
    font-size: 0.875rem;
}

.wn-portal-list li:last-child { border-bottom: none; }

.wn-portal-list-meta { color: var(--text-muted); }

/* --- Uptime strip --- */
.wn-uptime-strip {
    display: flex;
    gap: 3px;
    align-items: flex-end;
    /* Scrolls inside its own box rather than pushing the page sideways. */
    overflow-x: auto;
    padding-bottom: 0.25rem;
}

.wn-uptime-bar {
    flex: 1 0 6px;
    min-width: 6px;
    height: 36px;
    border-radius: 3px;
}

.wn-uptime-bar.is-up { background: var(--success-color); }
.wn-uptime-bar.is-down { background: var(--danger-color); }

@media (max-width: 560px) {
    .wn-portal-page,
    .wn-portal-narrow { padding: 1.5rem 1rem; }
    .wn-portal-narrow { padding-top: 2rem; }
    .wn-portal-bar-inner { padding: 0.75rem 1rem; }
    .wn-portal-stat-value { font-size: 1.25rem; }
}

/* ==========================================================================
   Public status pages (C2)
   --------------------------------------------------------------------------
   Rendered for people who have never seen this product and will not log in.
   --status-brand is set per page from a value validated to #rrggbb on the way
   into the database, which is what makes writing it into a style attribute
   safe here.
   ========================================================================== */

.wn-status-body {
    background: var(--bg-color);
    color: var(--text-color);
    min-height: 100dvh;
}

.wn-status-wrap {
    max-width: 780px;
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
    min-width: 0;
}

.wn-status-head {
    text-align: center;
    margin-bottom: 2rem;
}

.wn-status-logo {
    max-height: 48px;
    max-width: 100%;
    margin-bottom: 1rem;
}

.wn-status-head h1 {
    font-size: 1.6rem;
    font-weight: 700;
    margin: 0 0 0.4rem;
    color: var(--status-brand, var(--primary-color));
}

.wn-status-head p {
    color: var(--text-muted);
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0;
}

/* --- The one-line answer, which is what most people came for --- */
.wn-status-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 1rem 1.25rem;
    border-radius: var(--radius-md);
    font-weight: 600;
    font-size: 1rem;
    text-align: center;
}

.wn-status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.wn-status-operational { background: #d1fae5; color: #065f46; }
.wn-status-partial     { background: #fef3c7; color: #92400e; }
.wn-status-outage      { background: #fee2e2; color: #b91c1c; }
.wn-status-unknown     { background: #f3f4f6; color: #4b5563; }

.wn-status-checked {
    text-align: center;
    font-size: 0.75rem;
    color: var(--text-muted);
    margin: 0.6rem 0 2rem;
}

/* --- One block per site --- */
.wn-status-site {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    margin-bottom: 1rem;
}

.wn-status-site-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.wn-status-site-head h2 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.15rem;
}

.wn-status-host {
    font-size: 0.8rem;
    color: var(--text-muted);
    word-break: break-all;
}

.wn-status-site-figures {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

.wn-status-figure {
    font-size: 1rem;
    font-weight: 700;
    text-align: right;
}

.wn-status-figure small {
    display: block;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* --- 90 days at a glance --- */
.wn-status-strip {
    display: flex;
    gap: 2px;
    align-items: stretch;
    height: 32px;
    /* Scrolls inside its own box rather than pushing the page sideways on a
       narrow screen — 90 bars will not fit a phone at a usable width. */
    overflow-x: auto;
}

.wn-status-bar {
    flex: 1 0 4px;
    min-width: 4px;
    border-radius: 2px;
}

.wn-status-bar.is-up   { background: var(--success-color); }
.wn-status-bar.is-down { background: var(--danger-color); }
.wn-status-bar.is-none { background: var(--border-color); }

.wn-status-scale {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    color: var(--text-muted);
    margin-top: 0.4rem;
}

/* --- Incidents --- */
.wn-status-incidents {
    background: var(--surface-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    margin-top: 1.5rem;
}

.wn-status-incidents h2 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.85rem;
}

.wn-status-incident {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border-color);
}

.wn-status-incident:last-child { border-bottom: none; }

.wn-status-incident-main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: 0.875rem;
}

.wn-status-incident-main span {
    color: var(--text-muted);
    font-size: 0.78rem;
}

.wn-status-empty {
    color: var(--text-muted);
    font-size: 0.875rem;
    margin: 0;
}

.wn-status-foot {
    text-align: center;
    margin-top: 2rem;
}

.wn-status-foot a {
    color: var(--status-brand, var(--primary-color));
    font-size: 0.85rem;
    font-weight: 600;
}

@media (max-width: 560px) {
    .wn-status-wrap { padding: 2rem 1rem 3rem; }
    .wn-status-site-figures { gap: 0.85rem; }
    .wn-status-figure { text-align: left; }
}

/* ==========================================================================
   Command palette (C7)
   ========================================================================== */

.wn-palette-overlay {
    position: fixed;
    inset: 0;
    background: rgba(17, 24, 39, 0.45);
    align-items: flex-start;
    justify-content: center;
    padding: 10vh 1rem 1rem;
    z-index: 200;
}

.wn-palette {
    background: var(--surface-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 560px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 70vh;
    min-width: 0;
}

.wn-palette-input {
    border: none;
    border-bottom: 1px solid var(--border-color);
    padding: 1.1rem 1.25rem;
    font-family: inherit;
    font-size: 1rem;
    outline: none;
    width: 100%;
    /* Fixed-height children of a column flex box are compressed once the box
       hits its max-height; the results list is the only part that should give. */
    flex-shrink: 0;
}

.wn-palette-results {
    overflow-y: auto;
    flex: 1;
    min-height: 0;
    padding: 0.4rem 0;
}

.wn-palette-group {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding: 0.6rem 1.25rem 0.3rem;
}

.wn-palette-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 1.25rem;
    font-size: 0.9rem;
    color: var(--text-color);
    text-decoration: none;
    min-width: 0;
}

.wn-palette-item > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.wn-palette-item.is-active,
.wn-palette-item:hover {
    background: var(--bg-color);
}

.wn-palette-hint {
    font-size: 0.75rem;
    color: var(--text-muted);
    flex-shrink: 0;
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wn-palette-empty {
    padding: 1.5rem 1.25rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.wn-palette-foot {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.6rem 1.25rem;
    border-top: 1px solid var(--border-color);
    font-size: 0.72rem;
    color: var(--text-muted);
    flex-shrink: 0;
}

.wn-palette-foot kbd {
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    padding: 0.05rem 0.3rem;
    margin-right: 0.2rem;
    font-family: inherit;
    font-size: 0.7rem;
}

/* ==========================================================================
   Collapsible sidebar
   --------------------------------------------------------------------------
   The rail was icon-only at a fixed 80px. With fifteen destinations that is
   taller than most laptop viewports, so it scrolled — and a scrolling strip of
   unlabelled icons is a memory test. Expanding is opt-in and remembered, so
   the people who know the icons keep their screen space and the people who do
   not can read the names.
   ========================================================================== */

.app-layout.sidebar-expanded {
    --sidebar-width: 232px;
}

.sidebar,
.main-content {
    transition: width 0.18s ease, margin-left 0.18s ease;
}

/* Expanded: icons and labels on one line, left aligned. */
.app-layout.sidebar-expanded .nav-item {
    justify-content: flex-start;
    gap: 0.85rem;
    padding: 0 0.9rem;
}

/* Beats `.mobile-only { display: none }` on specificity, which is the only
   reason the labels are hidden on desktop in the first place. */
.app-layout.sidebar-expanded .nav-item .nav-label.mobile-only {
    display: inline;
    font-size: 0.875rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.app-layout.sidebar-expanded .sidebar-header {
    justify-content: flex-start;
    padding-left: 1.4rem;
}

/* Slightly tighter than before: fifteen items at the old height overflowed a
   1080p viewport on their own. */
.nav-item {
    height: 48px;
    margin: 0.25rem 0.5rem;
    flex-shrink: 0;
}

.sidebar-nav {
    scrollbar-width: thin;
}

@media (max-width: 900px) {
    .app-layout.sidebar-expanded {
        --sidebar-width: 80px;
    }
}

/* ---------------------------------------------------------------------------
   Uptime heartbeat bars
   Modelled on Uptime Kuma's own strip: few enough bars to stay readable,
   capsule-rounded, with real gaps. Defined as classes rather than inline
   styles because the hover state cannot be expressed inline, and because the
   monitoring list and the site detail page must not drift apart.
--------------------------------------------------------------------------- */
.wn-beats {
    display: flex;
    align-items: stretch;
    gap: 3px;
    height: 26px;
}

.wn-beat {
    flex: 1 1 0;
    min-width: 4px;
    border-radius: 4px;
    background: #10b981;
    transition: transform .12s ease, filter .12s ease;
    transform-origin: center;
    cursor: default;
}

.wn-beat.is-down { background: #dc2626; }
.wn-beat.is-pending { background: #d1d5db; }

/* Lifts rather than recolours: the colour already carries the state, so hover
   should say "this one" without implying the status changed. */
.wn-beat:hover {
    transform: scaleY(1.18);
    filter: brightness(1.08);
}

@media (prefers-reduced-motion: reduce) {
    .wn-beat { transition: none; }
    .wn-beat:hover { transform: none; }
}

/* The detail page shows a longer window in the same visual language. */
.wn-beats-lg { height: 34px; gap: 3px; }

/* ---------------------------------------------------------------------------
   Monitor detail page — two-column rows that must stack on narrow viewports.
   Defined as classes rather than left inline, because inline styles cannot
   carry a media query at all; without this the ring/chart and outages/basic-
   info rows would squeeze a 200px-minimum column against the viewport edge
   on a phone instead of stacking.
--------------------------------------------------------------------------- */
.wn-uptime-summary-row {
    display: grid;
    grid-template-columns: minmax(200px, 260px) 1fr;
    gap: 1.25rem;
}

.wn-uptime-lower-row {
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: 1.25rem;
    align-items: start;
}

@media (max-width: 860px) {
    .wn-uptime-summary-row,
    .wn-uptime-lower-row {
        grid-template-columns: 1fr;
    }
}

/* A fixed four-up stat row (monitor detail page). The shared .stat-grid uses
   auto-fit(minmax(220px,1fr)), which is right for the dashboard's eight tiles
   but wrong for exactly four in a ~785px card: three fit per row and the
   fourth sits alone with a large empty gap beside it. Explicit column counts
   avoid that orphan without touching the shared class other pages rely on. */
.wn-stat-grid-4 {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
    margin-bottom: 1.25rem;
}

@media (max-width: 760px) {
    .wn-stat-grid-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 420px) {
    .wn-stat-grid-4 { grid-template-columns: 1fr; }
}

/* Monitor detail summary bar — domain name and status/SSL/domain chips.
   Third attempt at this row, and the earlier two explain why this one is
   deliberately not relying on organic flex-wrap at all:
     1. Domain name sharing a flex row with the chips wrapped unpredictably —
        a long variable-width string next to fixed-width chips has no stable
        wrap point, and different screens produced a different, uneven
        number of items per row.
     2. Separating the domain onto its own line and wrapping the chips with
        CSS Grid (1fr tracks) fixed that, but grid tracks stretch to fill
        their container — on a wide screen the four chips scattered across
        the whole card with large gaps instead of sitting in the tight,
        evenly-spaced row the reference actually shows.
   The reference row is domain + four chips *together*, spread with even
   gaps across the full width — which is exactly what justify-content:
   space-between does, as long as wrapping is not left to chance. So: one
   row, no wrap, space-between, above the breakpoint where five items
   plus real content stop fitting on real hardware; below it, an explicit
   layout swap to a stacked domain name plus a plain wrapping chip row —
   not organic reflow of the same five flex children, which is what
   produced problem #1 in the first place. */
.wn-uptime-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: nowrap;
    gap: 1.5rem;
}

.wn-uptime-summary > strong {
    flex-shrink: 0;
}

.wn-uptime-chip {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-width: 0;
    flex-shrink: 0;
}

@media (max-width: 900px) {
    .wn-uptime-summary {
        flex-direction: column;
        align-items: flex-start;
        gap: 1rem;
    }

    /* Below the breakpoint the chips leave the space-between row entirely
       and become a plain wrapping group under the domain name — the
       narrow-width behaviour already proven to wrap cleanly. */
    .wn-uptime-summary > .wn-uptime-chip {
        display: none;
    }

    /* Grid, not flex-wrap: a wrapping flex row's column count depends on
       how much space each chip's text happens to take, so it can silently
       become 1-per-row or 3-per-row depending on the label/value length.
       A fixed 2-column grid always gives 2x2 for these four chips regardless
       of content width. */
    .wn-uptime-chips-wrap {
        display: grid !important;
        grid-template-columns: repeat(2, 1fr);
        gap: 1.5rem 1rem;
        width: 100%;
        margin-top: 1rem;
    }

    /* The value/label text is nowrap for the single-line desktop row, where
       there's room. In a 2-column grid the same text needs to wrap instead
       of overflowing its column — the inline style wins over a plain class
       selector, so this has to carry !important to override it. */
    .wn-uptime-chips-wrap .wn-uptime-chip-value,
    .wn-uptime-chips-wrap .wn-uptime-chip-label {
        white-space: normal !important;
    }
}

@media (max-width: 360px) {
    /* Narrower than any current chip's natural width can comfortably hold
       two columns side by side — drop to one per row rather than letting
       the icon badge and label get cramped. */
    .wn-uptime-chips-wrap {
        grid-template-columns: 1fr;
    }
}

/* Hidden above the breakpoint: the same four chips render twice (once as
   direct space-between children, once pre-grouped for the stacked layout)
   so the swap is a pure CSS display toggle with no JS and no server-side
   viewport detection, at the cost of duplicating four small chips in the
   markup — a trade worth making for a page that ships no JS bundle. */
.wn-uptime-chips-wrap {
    display: none;
}

/* Admin Settings tab bar — an underline-tab style rather than the sidebar's
   dark pill (.site-nav-btn), since this sits on a light card background,
   not the dark site-nav rail. */
.wn-settings-tab-btn {
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: .65rem .9rem;
    font-size: .9rem;
    font-weight: 600;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
    margin-bottom: -1px;
    transition: color .15s, border-color .15s;
}

.wn-settings-tab-btn:hover {
    color: #111827;
}

.wn-settings-tab-btn.active {
    color: #047857;
    border-bottom-color: #047857;
}
