/* ==========================================================================
   ISAM Monitor — "dark fiber" NOC theme.
   Palette is grounded in optical signalling: near-black fiber, photon-cyan
   accent, and signal-level colours an operator already reads by instinct.
   ========================================================================== */
:root {
    --bg:        #090d13;
    --bg-grid:   #0d131c;
    --panel:     #111823;
    --panel-2:   #0e141d;
    --border:    #1c2735;
    --border-lit:#26384d;
    --text:      #ccd6e2;
    --text-dim:  #6f8098;
    --text-mute: #4c5a6e;

    --accent:    #35d0ba;   /* 1490 nm downstream photon */
    --accent-2:  #7aa2ff;   /* 1310 nm upstream          */

    --good:      #3ddc84;
    --warn:      #f5b13d;
    --bad:       #ff5f5f;

    --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;
    --sans: "IBM Plex Sans", system-ui, -apple-system, sans-serif;

    --r: 10px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--sans);
    color: var(--text);
    background:
        radial-gradient(1200px 600px at 80% -10%, #0f1a24 0%, transparent 60%),
        linear-gradient(0deg, var(--bg-grid) 1px, transparent 1px) 0 0 / 100% 44px,
        var(--bg);
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
}

/* ---- top bar ------------------------------------------------------------- */
.topbar {
    display: flex; align-items: center; justify-content: space-between;
    padding: 20px 28px;
    border-bottom: 1px solid var(--border);
    background: linear-gradient(180deg, rgba(53,208,186,0.04), transparent);
}
.brand { display: flex; align-items: center; gap: 16px; }
.brand h1 {
    margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -0.01em;
}
.brand .sub {
    margin: 2px 0 0; font-size: 12px; color: var(--text-dim);
    font-family: var(--mono);
}
/* The photon: a pulse of light travelling down fiber — the page's motif. */
.photon {
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 0 rgba(53,208,186,0.6);
    animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 rgba(53,208,186,0.55); }
    70%  { box-shadow: 0 0 0 14px rgba(53,208,186,0); }
    100% { box-shadow: 0 0 0 0 rgba(53,208,186,0); }
}
/* ---- nav tabs -------------------------------------------------------------- */
.topnav { display: flex; align-items: center; gap: 4px; }
.topnav a {
    color: var(--text-dim); text-decoration: none; font-size: 13px; font-weight: 600;
    padding: 7px 14px; border-radius: 7px; transition: background .15s, color .15s;
}
.topnav a:hover { color: var(--text); background: rgba(255,255,255,.04); }
.topnav a.active { color: var(--accent); background: rgba(53,208,186,.1); }

.topbar-right { display: flex; align-items: center; gap: 20px; }
.run-status {
    display: flex; align-items: center; gap: 8px;
    font-family: var(--mono); font-size: 12px; color: var(--text-dim);
}
.run-status .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-mute); }
.run-status.ok .dot   { background: var(--good); }
.run-status.warn .dot { background: var(--warn); }
.run-status.err .dot  { background: var(--bad); }

/* ---- admin dropdown (OLTs / Settings / Log out) ---------------------------
   Everything config/admin-related lives here, off the main nav, so the top
   nav stays purely about using the tool (Dashboard, Search). */
.admin-menu { position: relative; padding-left: 18px; border-left: 1px solid var(--border); }
.admin-toggle {
    display: flex; align-items: center; gap: 10px; cursor: pointer;
    background: transparent; border: 1px solid var(--border); border-radius: 7px;
    padding: 6px 10px 6px 12px;
    font-family: var(--mono); font-size: 12px; color: var(--text-dim);
    transition: background .15s, border-color .15s;
}
.admin-toggle:hover, .admin-toggle[aria-expanded="true"] {
    background: rgba(255,255,255,.04); border-color: var(--border-lit); color: var(--text);
}
.admin-toggle .burger { display: flex; flex-direction: column; gap: 3px; width: 15px; flex: none; }
.admin-toggle .burger span { display: block; height: 2px; border-radius: 1px; background: currentColor; }

.admin-dropdown {
    position: absolute; top: calc(100% + 8px); right: 0; min-width: 170px;
    background: var(--panel); border: 1px solid var(--border-lit); border-radius: 9px;
    padding: 6px; box-shadow: 0 14px 40px rgba(0,0,0,.45); z-index: 40;
}
.admin-dropdown:not([hidden]) { display: flex; flex-direction: column; }
.admin-dropdown a {
    display: block; padding: 8px 11px; border-radius: 6px;
    color: var(--text); text-decoration: none; font-size: 13px;
    transition: background .15s;
}
.admin-dropdown a:hover { background: rgba(255,255,255,.05); }
.admin-dropdown a.active { color: var(--accent); background: rgba(53,208,186,.1); }
.admin-dropdown a.logout-link { color: var(--bad); }
.dropdown-sep { height: 1px; background: var(--border); margin: 6px 3px; }

/* ---- login page ------------------------------------------------------------ */
.login-wrap {
    min-height: 100vh; display: flex; align-items: center; justify-content: center;
    padding: 24px;
}
.login-card {
    width: 100%; max-width: 380px;
    background: var(--panel); border: 1px solid var(--border);
    border-radius: var(--r); padding: 28px 26px;
    display: flex; flex-direction: column; gap: 18px;
}
.login-brand { display: flex; align-items: center; gap: 16px; margin-bottom: 4px; }
.login-brand h1 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.login-brand .sub { margin: 2px 0 0; font-size: 11px; color: var(--text-dim); font-family: var(--mono); }
.login-error {
    margin: 0; padding: 9px 12px; border-radius: 8px; font-size: 12.5px;
    color: var(--bad); background: rgba(255,95,95,.1); border: 1px solid rgba(255,95,95,.25);
}
.login-field { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.login-field input {
    background: var(--panel-2); border: 1px solid var(--border);
    color: var(--text); border-radius: 6px; padding: 9px 11px;
    font-family: var(--sans); font-size: 14px;
}
.login-field input:focus { outline: 2px solid var(--accent); border-color: transparent; }
.login-submit {
    margin-top: 4px; padding: 10px 14px; border-radius: 6px; border: 1px solid transparent;
    background: var(--accent); color: #06231f; font-weight: 600; font-size: 13.5px;
    cursor: pointer; transition: filter .15s;
}
.login-submit:hover { filter: brightness(1.08); }

/* ---- layout -------------------------------------------------------------- */
main { padding: 24px 28px 40px; max-width: 1500px; margin: 0 auto; }

.kpis {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
    margin-bottom: 22px;
}
.kpi {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: var(--r); padding: 16px 18px;
    position: relative; overflow: hidden;
}
.kpi::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
    background: var(--accent); opacity: .5;
}
.kpi.alert::before { background: var(--warn); opacity: 1; }
.kpi.bad::before   { background: var(--bad);  opacity: 1; }
.kpi .n { font-family: var(--mono); font-size: 30px; font-weight: 600; line-height: 1; }
.kpi .l { font-size: 12px; color: var(--text-dim); margin-top: 8px; text-transform: uppercase; letter-spacing: .06em; }

.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.span-2 { grid-column: span 2; }
.span-3 { grid-column: span 3; }

.panel {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: var(--r); overflow: hidden;
}
.panel-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; padding: 15px 18px; border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.panel-head h2 { margin: 0; font-size: 14px; font-weight: 600; letter-spacing: .01em; }
.panel-note { margin: 0; font-size: 11px; color: var(--text-mute); font-family: var(--mono); }

/* ---- filters ------------------------------------------------------------- */
.filters { display: flex; align-items: center; gap: 14px; }
.filters input[type=search] {
    background: var(--panel-2); border: 1px solid var(--border);
    color: var(--text); border-radius: 6px; padding: 6px 10px;
    font-family: var(--mono); font-size: 12px; width: 240px;
}
.filters input[type=search]:focus { outline: 2px solid var(--accent); border-color: transparent; }
.chk { font-size: 12px; color: var(--text-dim); display: flex; align-items: center; gap: 6px; cursor: pointer; }

/* ---- tables -------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th {
    text-align: left; font-weight: 600; color: var(--text-dim);
    font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
    padding: 10px 14px; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; background: var(--panel); z-index: 1;
}
td { padding: 9px 14px; border-bottom: 1px solid var(--panel-2); font-family: var(--mono); }
tr:hover td { background: rgba(53,208,186,0.035); }
.mono { font-family: var(--mono); }
.dim { color: var(--text-dim); }

/* status pills */
.pill {
    display: inline-block; padding: 2px 8px; border-radius: 999px;
    font-size: 10.5px; font-family: var(--mono); border: 1px solid transparent;
}
.pill.up   { color: var(--good); background: rgba(61,220,132,.1); border-color: rgba(61,220,132,.25); }
.pill.down { color: var(--bad);  background: rgba(255,95,95,.1);  border-color: rgba(255,95,95,.25); }
.pill.new  { color: var(--accent-2); background: rgba(122,162,255,.1); border-color: rgba(122,162,255,.25); }
.pill.slot { color: var(--accent); background: rgba(53,208,186,.08); border-color: rgba(53,208,186,.22); }
.pill.sev-critical { color: var(--bad);  background: rgba(255,95,95,.12); border-color: rgba(255,95,95,.3); }
.pill.sev-warning  { color: var(--warn); background: rgba(245,177,61,.12); border-color: rgba(245,177,61,.3); }
.pill.sev-info     { color: var(--accent-2); background: rgba(122,162,255,.1); border-color: rgba(122,162,255,.25); }

/* Unprovisioned-queue conflict flag — click toggles the detail row below it.
   Same treatment on the OLT overview table's aggregated per-OLT badge. */
.conflict-badge, .olt-conflict-badge { cursor: pointer; }
.conflict-detail td, .olt-conflict-detail td {
    background: rgba(255,255,255,.02); font-size: 12px; padding: 8px 12px;
}

/* Client-side pager under a long table (Active alerts / Duplicate serials). */
.pager {
    display: flex; align-items: center; justify-content: center; gap: 14px;
    padding: 10px 0; font-size: 12px;
}
.pager .btn-plain:disabled { opacity: .35; cursor: default; }
.conflict-item { padding: 3px 0; }
.conflict-item + .conflict-item { border-top: 1px solid var(--border); }

/* Notifications page: alert-type checkbox list under "All types". */
.type-list {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 4px 12px; margin-top: 8px;
}

/* active-alerts panel + provisioning action */
.alerts-panel { border-color: var(--border-lit); box-shadow: 0 0 0 1px rgba(255,95,95,.06); }
.btn-prov {
    font-family: var(--mono); font-size: 11px; cursor: pointer;
    color: var(--accent); background: rgba(53,208,186,.08);
    border: 1px solid rgba(53,208,186,.3); border-radius: 6px; padding: 4px 10px;
    transition: background .15s, border-color .15s;
}
.btn-prov:hover { background: rgba(53,208,186,.18); border-color: var(--accent); }
.btn-prov:disabled { color: var(--text-mute); border-color: var(--border); background: transparent; cursor: not-allowed; }

/* ---- signature: optical budget bar --------------------------------------
   GPON class B+ receive window is roughly -8 dBm (hot) to -28 dBm (edge).
   We map Rx into that window and colour it the way an operator triages. */
.optic { display: flex; align-items: center; gap: 8px; min-width: 150px; }
.optic .track {
    position: relative; height: 6px; width: 96px; border-radius: 3px;
    background: linear-gradient(90deg, #2a1414, #2a2414 45%, #14261a);
    overflow: hidden;
}
.optic .fill { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 3px; }
.optic .val { font-family: var(--mono); font-size: 11px; width: 52px; }
.sig-good .fill { background: var(--good); }
.sig-warn .fill { background: var(--warn); }
.sig-bad  .fill { background: var(--bad); }
.sig-good .val { color: var(--good); }
.sig-warn .val { color: var(--warn); }
.sig-bad  .val { color: var(--bad); }
.sig-na .val { color: var(--text-mute); }

/* ---- fleet-wide signal bands -----------------------------------------------
   Same visual grammar as .optic above (a coloured track), just aggregated:
   one segment per Rx band instead of one dot's position within the window. */
.band-bar {
    display: flex; height: 14px; border-radius: 7px; overflow: hidden;
    background: var(--panel-2); border: 1px solid var(--border);
}
.band-seg { height: 100%; transition: width .3s; }
.band-seg + .band-seg { border-left: 2px solid var(--panel-2); }
.band-seg.good     { background: var(--good); }
.band-seg.warning  { background: var(--warn); }
.band-seg.critical { background: var(--bad); }
.band-seg.unknown  { background: var(--text-mute); }
/* Compact per-row variant for the OLT overview table — no legend, just the bar (a title attribute on each segment carries the breakdown). */
.band-bar.mini { height: 10px; width: 130px; }

.band-legend { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 14px; font-size: 12.5px; }
.band-item { display: flex; align-items: center; gap: 7px; color: var(--text-dim); }
.band-item b { color: var(--text); font-family: var(--mono); }
.band-item .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.band-item .dot.good     { background: var(--good); }
.band-item .dot.warning  { background: var(--warn); }
.band-item .dot.critical { background: var(--bad); }
.band-item .dot.unknown  { background: var(--text-mute); }

/* ---- OLT list ------------------------------------------------------------ */
.olt-list { padding: 6px; }
.olt {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 12px; border-radius: 8px;
}
.olt:hover { background: rgba(255,255,255,.02); }
.olt .st { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.olt .st.ok { background: var(--good); }
.olt .st.error { background: var(--bad); }
.olt .st.never { background: var(--text-mute); }
.olt .meta { flex: 1; min-width: 0; }
.olt .name { font-weight: 600; font-size: 13px; }
.olt .info { font-family: var(--mono); font-size: 11px; color: var(--text-dim); }
/* Second, smaller status dot in the info line — the fast unprovisioned
   poll's freshness, tracked separately from the full poll's .st dot. */
.st-inline { display: inline-block; width: 6px; height: 6px; border-radius: 50%; margin-left: 5px; }
.st-inline.ok { background: var(--good); }
.st-inline.error { background: var(--bad); }
.st-inline.never { background: var(--text-mute); }

/* ---- empty / foot -------------------------------------------------------- */
.empty { padding: 30px; text-align: center; color: var(--text-mute); font-family: var(--mono); font-size: 12px; }
.foot {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 16px 28px; color: var(--text-mute); font-size: 11px;
    font-family: var(--mono); border-top: 1px solid var(--border);
    flex-wrap: wrap;
}

@media (max-width: 1000px) {
    .kpis { grid-template-columns: repeat(2, 1fr); }
    .grid { grid-template-columns: 1fr; }
    .span-2, .span-3 { grid-column: span 1; }
}

/* ---- plain button (secondary action, e.g. modal Cancel) ------------------ */
.btn-plain {
    font-family: var(--sans); font-size: 13px; cursor: pointer;
    color: var(--text-dim); background: transparent;
    border: 1px solid var(--border); border-radius: 6px; padding: 8px 14px;
    transition: background .15s, color .15s;
}
.btn-plain:hover { color: var(--text); background: rgba(255,255,255,.04); }

/* ---- modal ----------------------------------------------------------------
   Shared by the OLT add/edit form. */
.modal-backdrop {
    position: fixed; inset: 0; background: rgba(4,7,11,.72);
    align-items: center; justify-content: center;
    padding: 24px; z-index: 50;
}
/* Scoped to :not([hidden]) so the [hidden] attribute (toggled by JS to
   open/close the modal) isn't overridden by this class's own display rule —
   both are author/class-level specificity, so an unconditional `display:
   flex` here would always win over the browser's `[hidden]{display:none}`
   and the modal could never actually be hidden. */
.modal-backdrop:not([hidden]) { display: flex; }
.modal {
    width: 100%; max-width: 460px;
    background: var(--panel); border: 1px solid var(--border-lit);
    border-radius: var(--r); padding: 24px;
    display: flex; flex-direction: column; gap: 14px;
    box-shadow: 0 20px 60px rgba(0,0,0,.4);
}
.modal h3 { margin: 0 0 4px; font-size: 16px; font-weight: 700; }
.field { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.field input, .field select {
    background: var(--panel-2); border: 1px solid var(--border);
    color: var(--text); border-radius: 6px; padding: 9px 11px;
    font-family: var(--sans); font-size: 14px;
}
.field input:focus, .field select:focus { outline: 2px solid var(--accent); border-color: transparent; }
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; }
.field-row .field-narrow { flex: 0 0 110px; }
.modal-error {
    margin: 0; padding: 9px 12px; border-radius: 8px; font-size: 12.5px;
    color: var(--bad); background: rgba(255,95,95,.1); border: 1px solid rgba(255,95,95,.25);
}
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }

/* ---- settings page --------------------------------------------------------- */
.settings-main { padding: 24px 28px 40px; max-width: 860px; margin: 0 auto; }
.settings-form { display: flex; flex-direction: column; gap: 16px; }
.settings-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.settings-body .field-grid { margin-top: 4px; }
.settings-actions { display: flex; justify-content: flex-end; }

.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
.field-grid .field-span { grid-column: 1 / -1; }
.field small { color: var(--text-mute); font-weight: 400; }
.field-with-btn { display: flex; gap: 8px; }
.field-with-btn input { flex: 1; }

.banner {
    margin: 0; padding: 11px 14px; border-radius: 8px; font-size: 13px;
}
.banner-ok {
    color: var(--good); background: rgba(61,220,132,.1); border: 1px solid rgba(61,220,132,.25);
}
.banner-err {
    color: var(--bad); background: rgba(255,95,95,.1); border: 1px solid rgba(255,95,95,.25);
}

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

/* ---- search page ------------------------------------------------------------ */
.search-input {
    width: 100%; background: var(--panel-2); border: 1px solid var(--border);
    color: var(--text); border-radius: 8px; padding: 12px 14px;
    font-family: var(--mono); font-size: 15px;
}
.search-input:focus { outline: 2px solid var(--accent); border-color: transparent; }
tr.row-click { cursor: pointer; }
tr.row-click:hover td { background: rgba(53,208,186,.06); }
.detail-subhead { margin: 18px 0 10px; font-size: 13px; font-weight: 600; color: var(--text-dim); }
.field b { font-size: 14px; font-weight: 600; }
