/*
 * laxFW
 * Copyright (c) 2026 Jacques Amar
 * Author: Jacques Amar
 *
 * All rights reserved. Proprietary software — see LICENSE for terms.
 *
 * Version: 0.1.0
 */

/* ---- Design tokens (semantic; base/ components consume these) ---- */
:root {
    color-scheme: light dark;

    --text-primary: #1c2430;
    --text-muted: #5b6675;
    --page-bg: #f4f6f9;
    --surface: #ffffff;
    --border: #d4dae2;

    --primary: #1f5fa8;
    --primary-contrast: #ffffff;
    --danger: #b3261e;
    --success: #2e7d32;
    --warning-bg: #fff3cd;   /* traffic-light: dirty cell */
    --error-bg: #f8d7da;     /* traffic-light: refused cell */

    --menu-bg: #1f2a3a;
    --menu-fg: #e8edf4;
    --footer-bg: #e3e8ef;   /* distinct band; bookends the header */
    --footer-fg: #4a5563;
    --highlight: #2f80ed;
    --group-accent: #d9822b; /* distinct from --highlight: frames open groups */

    /* Rule-tier palette — machine/global/campus, so a count's origin
       reads at a glance on the Overview page (is_system 0/1/2). */
    --tier-machine: #2f6fb0;
    --tier-global:  #7c5cbf;
    --tier-campus:  #c9761f;

    --btn-radius: 0.25rem;
    --field-radius: 0.25rem;
    --focus-ring: 0 0 0 0.15rem var(--highlight);

    /* data-table column-hiding tiers (base/table.css) */
    --bp-p4: 68rem;
    --bp-p3: 56rem;
    --bp-p2: 40rem;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text-primary: #e4e9f0;
        --text-muted: #96a1b0;
        --page-bg: #12161c;
        --surface: #1a212b;
        --border: #313c4a;
        --warning-bg: #4d3f12;
        --error-bg: #4d1f22;
        --menu-bg: #0d1319;
        --footer-bg: #0d1319;
        --footer-fg: #96a1b0;
        --group-accent: #e0913f;
        --tier-machine: #5b9bd8;
        --tier-global:  #a488e0;
        --tier-campus:  #e0913f;
    }
}

/* ---- Base ---- */
* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, sans-serif;
    font-size: 0.9rem;
    color: var(--text-primary);
    background: var(--page-bg);
    /* Full-height column: header pinned to the top, footer pinned to the
       bottom, and only <main> scrolls in the space between them so the
       nav and version bar are always visible. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    max-height: 100vh;
}

.site-header,
.site-footer {
    flex: none; /* never shrink — they hold the viewport edges */
}

main {
    flex: 1 1 auto;
    overflow-y: auto;
    padding-block: 0.5rem;
    padding-inline: 0.75rem;
}

h1 { font-size: 1.15rem; margin-block: 0.25rem; }
h2 { font-size: 0.95rem; margin-block: 0.25rem; }

a { color: var(--primary); }

:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--btn-radius);
}

[hidden] { display: none !important; }

.visually-hidden {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

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

/* ---- Page chrome ---- */
.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.page-head .blurb {
    flex: 1 1 14rem;
    margin: 0;
    color: var(--text-muted);
    font-size: 0.8rem;
}

.site-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding-block: 0.35rem;
    padding-inline: 0.75rem;
    background: var(--footer-bg);
    color: var(--footer-fg);
    font-size: 0.7rem;
    border-block-start: 1px solid var(--border);
}

/* Operator branding, right side — copyright line + optional logo. */
.footer-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-align: end;
}

.footer-logo {
    display: block;
    block-size: 1.1rem;   /* scale to the footer height; width follows */
    inline-size: auto;
    max-inline-size: 9rem;
}

/* ---- Error bar (role=alert, populated by JS) ---- */
#error-bar {
    padding-block: 0.4rem;
    padding-inline: 0.6rem;
    margin-block-end: 0.5rem;
    background: var(--error-bg);
    color: var(--danger);
    border: 1px solid var(--danger);
    border-radius: var(--btn-radius);
    font-size: 0.8rem;
}

/* Derived summary cells (ports, addresses) wrap across lines. */
.cell-derived {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* ---- Tier badge ---- */
.tier {
    font-size: 0.7rem;
    padding-block: 0.05rem;
    padding-inline: 0.35rem;
    border-radius: var(--btn-radius);
    border: 1px solid var(--border);
    color: var(--text-muted);
}

.tier-1 { border-color: var(--primary); color: var(--primary); }
.tier-2 { border-color: var(--success); color: var(--success); }

/* ---- Login page ---- */
.login-body {
    display: grid;
    place-items: center;
    min-block-size: 100dvh;
}

.login-card {
    inline-size: min(22rem, 90vw);
    padding: 1.25rem;
    border: 1px solid var(--border);
    border-radius: var(--btn-radius);
    background: var(--surface, transparent);
}

.login-card h1 { margin-block: 0 0.25rem; }
.login-card .form-row { display: grid; gap: 0.75rem; margin-block-start: 0.75rem; }

.login-error {
    margin: 0;
    font-size: 0.8rem;
    color: var(--danger);
}

/* ---- Signed-in user chip (nav) ---- */
.nav-user {
    margin-inline-start: auto;
    font-size: 0.8rem;
    color: var(--menu-fg, #fff);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

.nav-user small { opacity: 0.7; }
.nav-user .logout { color: inherit; opacity: 0.8; }
.nav-user .logout:hover { opacity: 1; }

/* ---- Status page ---- */
.status-block {
    margin-block-end: 1rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--border);
    border-inline-start: 0.25rem solid var(--border);
    border-radius: var(--btn-radius);
}

.status-block h2 { margin-block: 0 0.4rem; font-size: 1rem; }
.status-block ul { margin-block: 0.25rem; padding-inline-start: 1.2rem; }

.status-good { border-inline-start-color: var(--success); }
.status-bad  { border-inline-start-color: var(--danger); }
.status-warn { border-inline-start-color: var(--group-accent); }

.ruleset-pre {
    max-block-size: 60dvh;
    overflow: auto;
    font-size: 0.75rem;
    line-height: 1.35;
    padding: 0.5rem;
    border: 1px solid var(--border);
    border-radius: var(--btn-radius);
}

/* ---- Abuse dashboard ---- */
.abuse-badge {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 1rem;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.abuse-banned   { background: var(--danger);       color: #fff; }
.abuse-blocked  { background: var(--group-accent); color: #fff; }
.abuse-counting { background: var(--border);       color: var(--text); }
.abuse-events   { font-size: 0.8rem; color: var(--text-muted, inherit); }
.abuse-empty    { text-align: center; color: var(--text-muted, inherit); font-style: italic; }
.abuse-note     { font-size: 0.8rem; color: var(--text-muted, inherit); margin-block-start: 0.4rem; }

/* ---- Generate (status page) ---- */
.gen-result { margin-block-start: 0.5rem; font-size: 0.85rem; white-space: pre-line; }
.gen-result:empty { display: none; }
.gen-ok  { color: var(--success); }
.gen-bad { color: var(--danger); }

/* ---- Deploy menu (header, right cluster) ---- */
/* The traffic light inside the Deploy menu button. States mirror
   ajax/deploy.php: ok=green, degraded=yellow, stopped=red (box OPEN),
   simulated=hollow ring (this node never really deploys), unknown=grey. */
.deploy-dot {
    display: inline-block;
    inline-size: 0.6rem;
    block-size: 0.6rem;
    border-radius: 50%;
    background: #9aa4b2;                 /* unknown */
    flex: 0 0 auto;
}
.deploy-dot[data-state="ok"]        { background: var(--success, #3fae5a); }
.deploy-dot[data-state="degraded"]  { background: #d8a13a; }
.deploy-dot[data-state="stopped"]   { background: var(--danger, #d24b4b); }
.deploy-dot[data-state="simulated"] {
    background: transparent;
    border: 2px solid #9aa4b2;
}
.deploy-group .navbtn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
/* Action items are <button>s but must read exactly like the dropdown's
   <a> items. */
.dropdown .deploy-act {
    display: block;
    inline-size: 100%;
    padding-block: 0.4rem;
    padding-inline: 0.5rem;
    font: inherit;
    font-size: 0.85rem;
    text-align: start;
    color: var(--text-primary, #1a1a1a);
    background: none;
    border: none;
    border-radius: var(--btn-radius, 0.25rem);
    cursor: pointer;
    white-space: nowrap;
}
.dropdown .deploy-act:hover { background: color-mix(in srgb, var(--highlight, #46f) 12%, transparent); }
.dropdown .deploy-act-danger { color: var(--danger, #d24b4b); }
.dropdown .deploy-act[disabled] { opacity: 0.5; cursor: wait; }

/* Deploy status page + action-result modal */
.deploy-sim {
    padding: 0.6rem 0.8rem;
    border: 1px solid #d8a13a;
    border-radius: var(--btn-radius, 0.25rem);
    background: color-mix(in srgb, #d8a13a 12%, transparent);
}
.deploy-reason { font-size: 0.9rem; }
.deploy-table th[scope], .deploy-table tbody th { text-align: start; }
.deploy-problems h2 { color: var(--danger, #d24b4b); }
.deploy-result { white-space: pre-wrap; max-inline-size: 34rem; }
.deploy-result-bad { color: var(--danger, #d24b4b); }

/* ---- Sync status boxes (header) ---- */
.sync-bar {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-inline-start: auto;   /* push the sync group + user chip right */
}
/* When a sync bar is present it owns the right-push; the user chip just
   trails it. (Without a sync bar, .nav-user keeps its own auto margin.) */
.sync-bar ~ .nav-user { margin-inline-start: 0.6rem; }

.sync-pill { position: relative; }
.sync-pill-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding-block: 0.2rem;
    padding-inline: 0.5rem;
    font-size: 0.75rem;
    color: var(--menu-fg, #fff);
    background: color-mix(in srgb, var(--menu-fg, #fff) 12%, transparent);
    border: none;
    border-radius: var(--btn-radius, 0.25rem);
    cursor: pointer;
}
.sync-pill-btn:hover { background: color-mix(in srgb, var(--menu-fg, #fff) 20%, transparent); }

.sync-dot {
    inline-size: 0.6rem;
    block-size: 0.6rem;
    border-radius: 50%;
    background: #9aa4b2;                 /* unknown */
    flex: 0 0 auto;
}
.sync-dot[data-state="checking"] { background: #d8a13a; animation: sync-pulse 1s ease-in-out infinite; }
.sync-dot[data-state="ok"]       { background: var(--success, #3fae5a); }
.sync-dot[data-state="updates"]  { background: #d8a13a; }
.sync-dot[data-state="error"]    { background: var(--danger, #d24b4b); }
@keyframes sync-pulse { 50% { opacity: 0.35; } }

.sync-menu {
    position: absolute;
    inset-block-start: calc(100% + 0.3rem);
    inset-inline-end: 0;
    z-index: 50;
    min-inline-size: 15rem;
    padding: 0.6rem;
    background: var(--surface, #fff);
    color: var(--text, #1a1a1a);
    border: 1px solid var(--border, #ccc);
    border-radius: var(--btn-radius, 0.25rem);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
}
.sync-menu .sync-msg { margin: 0 0 0.5rem; font-size: 0.8rem; white-space: pre-line; }
.sync-menu .sync-actions { display: flex; gap: 0.4rem; }

/* ---- Sync settings page ---- */
.sync-form fieldset {
    border: 1px solid var(--border, #ccc);
    border-radius: var(--btn-radius, 0.25rem);
    padding: 0.75rem 1rem 1rem;
    margin-block-end: 1rem;
}
.sync-form legend { font-weight: 600; padding-inline: 0.35rem; }
.sync-form legend small { font-weight: 400; color: var(--text-muted, inherit); }
.sync-form .field { display: block; margin-block: 0.6rem; }
.sync-form .field > span { display: block; font-size: 0.85rem; margin-block-end: 0.2rem; }
.sync-form .field input[type="text"],
.sync-form .field input[type="password"] {
    inline-size: 100%;
    max-inline-size: 30rem;
    padding: 0.35rem 0.5rem;
}
.sync-form .field-check { display: flex; align-items: center; gap: 0.5rem; }
.sync-form .field-check > span { margin: 0; }
.secret-state {
    font-weight: 400;
    font-size: 0.7rem;
    padding-inline: 0.35rem;
    border-radius: 0.6rem;
    background: color-mix(in srgb, currentColor 12%, transparent);
    color: var(--text-muted, inherit);
}
/* Mode page: campus fields hang under their role radios. */
.mode-conditional {
    margin-block-start: 0.25rem;
    padding-inline-start: 1.5rem;
    border-inline-start: 0.15rem solid var(--border);
}

.sync-serve-fold { margin-block-end: 1rem; }
.sync-serve-fold summary { cursor: pointer; font-weight: 600; margin-block-end: 0.5rem; }
.form-actions { display: flex; align-items: center; gap: 0.75rem; }
