/* Dashboard styles. Pure CSS, no framework. */

:root {
    --bg:           #0c1220;
    --bg-tile:      #161e34;
    --bg-tile-hi:   #1c2746;
    --fg:           #e6ecf7;
    --fg-dim:       #8a93a8;
    --border:       #283454;

    --sev-0: #2e9d4d;   /* green   — ok        */
    --sev-1: #3b82f6;   /* blue    — info      */
    --sev-2: #06b6d4;   /* cyan    — notice    */
    --sev-3: #eab308;   /* yellow  — warning   */
    --sev-4: #f97316;   /* orange  — error     */
    --sev-5: #dc2626;   /* red     — critical  */
    --sev-6: #dc2626;   /* red, but flashing   */
}

* { box-sizing: border-box; }
html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
    min-height: 100vh;
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.25rem;
    background: #0a0f1c;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 5;
}
.topbar h1 { font-size: 1.05rem; margin: 0; font-weight: 600; }
.topbar-meta { display: flex; gap: 1rem; align-items: center; font-variant-numeric: tabular-nums; }
#topbar-clock { color: var(--fg-dim); }
#audio-toggle {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--fg);
    padding: 0.35rem 0.75rem;
    border-radius: 0.4rem;
    cursor: pointer;
}
#audio-toggle[aria-pressed="true"] { border-color: var(--sev-0); color: var(--sev-0); }

.tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    /* Pin row height so loading state and loaded state occupy the same space —
       prevents the big first-paint shift when data arrives. */
    grid-auto-rows: 280px;
    gap: 1rem;
    padding: 1rem;
}

.tile {
    position: relative;
    background: var(--bg-tile);
    border: 1px solid var(--border);
    border-radius: 0.65rem;
    padding: 0.85rem 1rem 0.65rem;
    /* height comes from grid-auto-rows; min-height is a safety net only */
    min-height: 280px;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    cursor: pointer;
    transition: background 120ms;
    /* Avoids layout shift if a child briefly overflows during rerender. */
    overflow: hidden;
    contain: layout style;
}
/* Wide tiles span multiple grid columns. The auto-fit grid will fall back
   to one tile per row on narrow viewports so this still behaves sensibly. */
.tile[data-wide="2"] { grid-column: span 2; }
.tile[data-wide="3"] { grid-column: span 3; }
.tile:hover { background: var(--bg-tile-hi); }

.tile-status-strip {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    border-radius: 0.65rem 0.65rem 0 0;
    background: var(--sev-0);
    transition: background 200ms;
}

.tile[data-sev="0"] .tile-status-strip { background: var(--sev-0); }
.tile[data-sev="1"] .tile-status-strip { background: var(--sev-1); }
.tile[data-sev="2"] .tile-status-strip { background: var(--sev-2); }
.tile[data-sev="3"] .tile-status-strip { background: var(--sev-3); }
.tile[data-sev="4"] .tile-status-strip { background: var(--sev-4); }
.tile[data-sev="5"] .tile-status-strip { background: var(--sev-5); }
.tile[data-sev="6"] .tile-status-strip { background: var(--sev-6); animation: flash 0.8s steps(2) infinite; }

@keyframes flash {
    0%, 49%   { opacity: 1; }
    50%, 100% { opacity: 0.25; }
}

.tile[data-sev="5"], .tile[data-sev="6"] {
    border-color: var(--sev-5);
    box-shadow: 0 0 0 1px rgba(220, 38, 38, 0.4);
}
.tile[data-sev="6"] { animation: flashbg 0.9s steps(2) infinite; }
@keyframes flashbg {
    0%, 49%   { background: var(--bg-tile); }
    50%, 100% { background: rgba(220, 38, 38, 0.18); }
}

.tile-title {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--fg-dim);
}

.tile-body {
    flex: 1;
    /* Reserve a stable area so the body doesn't change height between
       loading state, default renderer, weather, etc. */
    min-height: 180px;
    display: flex;
    flex-direction: column;
}
.tile-loading {
    color: var(--fg-dim);
    font-size: 0.9rem;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.tile-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.72rem;
    color: var(--fg-dim);
    border-top: 1px dashed var(--border);
    padding-top: 0.4rem;
}

/* Tile body layouts shared across renderers */
.kpi {
    font-size: 2.2rem;
    line-height: 1.05;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.kpi-row {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.25rem;
}
.kpi-pill {
    background: rgba(255,255,255,0.04);
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
    font-size: 0.78rem;
    color: var(--fg-dim);
}
.kpi-pill[data-sev="3"] { color: var(--sev-3); border: 1px solid var(--sev-3); }
.kpi-pill[data-sev="4"] { color: var(--sev-4); border: 1px solid var(--sev-4); }
.kpi-pill[data-sev="5"] { color: var(--sev-5); border: 1px solid var(--sev-5); }

/* Datetime tile */
.dt-time {
    font-size: 2.4rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    /* Reserve width so HH:MM:SS doesn't reflow as digits change. */
    min-width: 8ch;
    display: inline-block;
}
.dt-date { color: var(--fg-dim); margin-top: 0.2rem; }

/* Weather tile — 2-column layout.
   Top row: TEMP and RH side-by-side as large readouts (same size + font).
   Middle: station + conditions pill, full width.
   Bottom: small key/value lines, split across the same two columns. */
.wx-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto 1fr;
    column-gap: 0.75rem;
    row-gap: 0.45rem;
    height: 100%;
}
.wx-headline {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.wx-big {
    font-size: 1.95rem;
    font-weight: 700;
    line-height: 1.0;
    font-variant-numeric: tabular-nums;
    /* Reserve enough width for "−10.5°C" / "100%" so the column won't reflow. */
    min-width: 5ch;
}
.wx-big-sub {
    color: var(--fg-dim);
    font-size: 0.72rem;
    margin-top: 0.2rem;
    font-variant-numeric: tabular-nums;
}
.wx-pill {
    grid-column: 1 / -1;
    align-self: start;
    background: rgba(255,255,255,0.04);
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
    font-size: 0.78rem;
    color: var(--fg-dim);
    justify-self: start;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.wx-col {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}
.wx-line {
    display: flex;
    justify-content: space-between;
    gap: 0.4rem;
    font-size: 0.78rem;
    /* Tabular figures keep "8.0" and "10.5" the same width column. */
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
}
.wx-line span:first-child { color: var(--fg-dim); }
.wx-line span:last-child {
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Uptime Robot tile — similar to the default KPI/pills layout, but with a
   meta footer carrying total + paused monitor counts. */
.ur-grid {
    display: flex;
    flex-direction: column;
    height: 100%;
    gap: 0.4rem;
}
.ur-top { flex: 1; min-height: 0; }
.ur-meta {
    margin-top: auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.72rem;
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
}
.ur-paused, .ur-verifying {
    cursor: help;
    /* Symbol + count travel together as one chip-like token. */
    white-space: nowrap;
}
.ur-paused[data-active="true"] {
    color: var(--fg);
}
.ur-verifying {
    color: var(--sev-2);
}
.ur-verifying-pill {
    /* In-row verifying pill — slightly emphasised so it's noticeable but
       not as loud as a real warning. */
    border: 1px dashed var(--sev-2) !important;
    color: var(--sev-2) !important;
}
.ur-meta-right {
    display: flex;
    gap: 0.55rem;
    align-items: center;
}

/* Phoenix Server Monitor tile. Same KPI/pills shape as the default, plus an
   inline list of currently-open issues (host • summary • age) so the tile
   surfaces *which* server is in trouble without requiring a drill-down. */
.phx-grid {
    display: flex;
    flex-direction: column;
    height: 100%;
    gap: 0.4rem;
}
.phx-top { /* nothing extra */ }
.phx-issues {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    flex: 1;
    min-height: 0;
    font-size: 0.78rem;
    line-height: 1.25;
}
.phx-issue {
    display: grid;
    grid-template-columns: 0.7rem minmax(0, auto) minmax(0, 1fr) auto;
    gap: 0.4rem;
    align-items: center;
    padding: 0.18rem 0;
    border-top: 1px solid var(--bd-faint, rgba(255,255,255,0.06));
}
.phx-issue:first-child { border-top: 0; }
.phx-issue .phx-host {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.phx-issue .phx-sum {
    color: var(--fg-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.phx-issue time {
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
    font-size: 0.72rem;
}
.phx-more {
    padding: 0.18rem 0;
    color: var(--fg-dim);
    font-size: 0.72rem;
    font-style: italic;
}
.phx-meta {
    margin-top: auto;
    font-size: 0.72rem;
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
}
.phx-fleet-empty { font-style: italic; }
.phx-fleet-late  { color: var(--sev-3); }

/* Self-status tile. Layout: headline on top, poller pills, then a stack of
   key/value rows ending with a usage bar. */
.ss-grid {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    height: 100%;
}
.ss-headline {
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.1;
    margin-bottom: 0.1rem;
}
.ss-headline.sev-0 { color: var(--sev-0); }
.ss-headline.sev-2 { color: var(--sev-2); }
.ss-headline.sev-3 { color: var(--sev-3); }
.ss-headline.sev-4 { color: var(--sev-4); }
.ss-headline.sev-5 { color: var(--sev-5); }

.ss-pollers {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
}
.ss-pill {
    background: rgba(255,255,255,0.04);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    font-size: 0.7rem;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.ss-pill[data-sev="0"] .ss-dot { color: var(--sev-0); }
.ss-pill[data-sev="2"] .ss-dot { color: var(--sev-2); }
.ss-pill[data-sev="3"] { border-color: var(--sev-3); }
.ss-pill[data-sev="3"] .ss-dot { color: var(--sev-3); }
.ss-pill[data-sev="4"] { border-color: var(--sev-4); }
.ss-pill[data-sev="4"] .ss-dot { color: var(--sev-4); }
.ss-pill[data-sev="5"] { border-color: var(--sev-5); }
.ss-pill[data-sev="5"] .ss-dot { color: var(--sev-5); }
.ss-pill-age { color: var(--fg-dim); }

.ss-row {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.78rem;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
}
.ss-row > :first-child { color: var(--fg-dim); }
.ss-row > :last-child  { text-align: right; }
.ss-row [data-sev="3"] { color: var(--sev-3); }
.ss-row [data-sev="5"] { color: var(--sev-5); font-weight: 600; }
.ss-row strong         { font-weight: 600; }
.ss-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dashed currentColor;
}
.ss-link:hover { opacity: 0.85; }

.ss-bar {
    height: 4px;
    background: rgba(255,255,255,0.05);
    border-radius: 2px;
    overflow: hidden;
    margin-top: -0.1rem;
}
.ss-bar-fill { height: 100%; transition: width 200ms ease-out, background 200ms; }

.ss-muted { color: var(--fg-dim); font-size: 0.78rem; }

/* Traffic-graph tile (HE traffic.he.net ports). */
.traffic-grid {
    display: grid;
    grid-template-rows: auto 1fr auto;
    height: 100%;
    gap: 0.4rem;
}
.traffic-headline {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 1.25rem;
    align-items: end;
}
.traffic-headline .traffic-num {
    font-size: 2.0rem;
    font-weight: 700;
    line-height: 1.0;
    font-variant-numeric: tabular-nums;
    min-width: 7ch;
}
.traffic-headline .traffic-label {
    font-size: 0.7rem;
    color: var(--fg-dim);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-top: 0.2rem;
}
.traffic-headline .traffic-label .dot { vertical-align: middle; }
.traffic-headline .traffic-num.in  { color: #00cc66; }
.traffic-headline .traffic-num.out { color: #4ea0ff; }
.traffic-svg {
    width: 100%;
    height: 100%;
    display: block;
}
.traffic-svg .grid-line { stroke: var(--border); stroke-width: 0.5; }
.traffic-svg .grid-x    { stroke-dasharray: 2 3; opacity: 0.6; }
.traffic-svg .axis-label {
    fill: var(--fg-dim);
    font-size: 9px;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
}
.traffic-svg .line-in  { fill: none; stroke: #00cc66; stroke-width: 1.5; }
.traffic-svg .line-out { fill: none; stroke: #4ea0ff; stroke-width: 1.5; }
.traffic-svg .area-in  { fill: rgba(0, 204, 102, 0.12); stroke: none; }
.traffic-svg .area-out { fill: rgba(78, 160, 255, 0.10); stroke: none; }
.traffic-stats {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    font-size: 0.72rem;
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
}
.traffic-stats .traffic-pill {
    background: rgba(255,255,255,0.04);
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
}
.traffic-meta {
    font-size: 0.7rem;
    color: var(--fg-dim);
    margin-top: -0.15rem;
}
.traffic-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--fg-dim);
    font-size: 0.85rem;
    width: 100%;
    height: 100%;
}

/* Lightning indicator — colour follows strike activity. */
.wx-ltg[data-ltg="active"] span:last-child { color: var(--sev-5); font-weight: 600; }
.wx-ltg[data-ltg="recent"] span:last-child { color: var(--sev-3); font-weight: 600; }
.wx-ltg[data-ltg="idle"]   span:last-child { color: var(--fg-dim); }

/* Kept for backwards compat with the unconfigured-state placeholder. */
.wx-temp { font-size: 1.95rem; font-weight: 700; font-variant-numeric: tabular-nums; }

/* Recent alerts tile.
   One line per entry, no scrollbar — list is clipped to whatever fits the
   reserved height. Drill-down dialog (click the tile) shows the full set. */
.recent-list {
    list-style: none;
    margin: 0;
    padding: 0;
    height: 200px;
    overflow: hidden;
}
.recent-list li {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.45rem;
    align-items: center;
    padding: 0.25rem 0;
    font-size: 0.8rem;
    border-bottom: 1px dashed var(--border);
    white-space: nowrap;
    overflow: hidden;
    line-height: 1.2;
}
.recent-list li:last-child { border-bottom: none; }
.recent-list li > span:nth-child(2) {
    overflow: hidden;
    text-overflow: ellipsis;
}
.recent-list time {
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
    /* Reserve enough width for "59m" / "12h" so the summary column doesn't shift. */
    min-width: 3ch;
    text-align: right;
}

/* Server Logins tile — same shape as Recent Alerts, with a coloured protocol
   badge (SSH / FTP) at the start of each row. Sev 0 by policy, so no severity
   dot — the protocol badge is the visual anchor instead. */
.logins-list {
    list-style: none;
    margin: 0;
    padding: 0;
    height: 200px;
    overflow: hidden;
}
.logins-list .logins-row {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    gap: 0.45rem;
    align-items: center;
    padding: 0.25rem 0;
    font-size: 0.8rem;
    border-bottom: 1px dashed var(--border);
    white-space: nowrap;
    overflow: hidden;
    line-height: 1.2;
}
.logins-list .logins-row:last-child { border-bottom: none; }
.logins-list .logins-host {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
}
.logins-list .logins-sum {
    color: var(--fg-dim);
    overflow: hidden;
    text-overflow: ellipsis;
}
.logins-list time {
    color: var(--fg-dim);
    font-variant-numeric: tabular-nums;
    min-width: 3ch;
    text-align: right;
}
.logins-proto {
    display: inline-block;
    min-width: 2.6em;
    padding: 0.05rem 0.4rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-align: center;
    border-radius: 3px;
    /* Default colour is overridden per protocol below. */
    background: var(--bg-soft, rgba(255,255,255,0.08));
    color: var(--fg-dim);
}
.logins-proto[data-proto="SSH"] {
    background: rgba(80, 160, 240, 0.18);
    color: #6cb4ff;
}
.logins-proto[data-proto="FTP"] {
    background: rgba(220, 180, 80, 0.18);
    color: #f0c060;
}
.logins-empty { padding: 0.5rem 0; }
.dot {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    background: var(--sev-0); margin-right: 0.3rem;
}
.dot[data-sev="0"] { background: var(--sev-0); }
.dot[data-sev="1"] { background: var(--sev-1); }
.dot[data-sev="2"] { background: var(--sev-2); }
.dot[data-sev="3"] { background: var(--sev-3); }
.dot[data-sev="4"] { background: var(--sev-4); }
.dot[data-sev="5"], .dot[data-sev="6"] { background: var(--sev-5); }

/* Drill-down dialog */
dialog#drill-dialog {
    background: var(--bg-tile);
    color: var(--fg);
    border: 1px solid var(--border);
    border-radius: 0.65rem;
    width: min(720px, 92vw);
    max-height: 80vh;
    padding: 0;
}
dialog#drill-dialog::backdrop { background: rgba(0,0,0,0.55); }
.drill-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 0.75rem 1rem; border-bottom: 1px solid var(--border);
}
.drill-header h3 { margin: 0; font-size: 1rem; }
.drill-header-actions {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}
#drill-view-all {
    color: var(--sev-1);
    text-decoration: none;
    font-size: 0.82rem;
    border-bottom: 1px dashed transparent;
}
#drill-view-all:hover { border-bottom-color: var(--sev-1); }
#drill-close { background: none; border: none; color: var(--fg); font-size: 1.4rem; cursor: pointer; }
#drill-body { padding: 0.75rem 1rem; overflow-y: auto; max-height: 60vh; font-size: 0.85rem; }
#drill-body table { width: 100%; border-collapse: collapse; }
#drill-body th, #drill-body td { text-align: left; padding: 0.3rem 0.4rem; border-bottom: 1px dashed var(--border); }
#drill-body th { color: var(--fg-dim); font-weight: 500; font-size: 0.75rem; text-transform: uppercase; }
