/* ATMOS Common Styles — shared variables, reset, animations */

/* Fonts (offline, served from atmos-web webjars). Each weight CSS file
   ships its own @font-face for all unicode subsets (latin, cyrillic, ...). */
@import url('/webjars/fontsource__jetbrains-mono/4.5.11/400.css');
@import url('/webjars/fontsource__jetbrains-mono/4.5.11/500.css');
@import url('/webjars/fontsource__jetbrains-mono/4.5.11/600.css');
@import url('/webjars/fontsource__jetbrains-mono/4.5.11/700.css');

:root {
    --bg: #0c0e14;
    --surface: #161922;
    --surface2: #1c2030;
    --surface3: #222638;
    --border: #2a2e3f;
    --border-light: #353a50;
    --text: #e1e4ed;
    --text-dim: #7b819a;
    --text-muted: #4e5370;
    --accent: #3b82f6;
    --accent-hover: #2563eb;
    --accent-glow: rgba(59, 130, 246, 0.15);
    --accent-border: rgba(59, 130, 246, 0.3);
    --success: #22c55e;
    --success-bg: rgba(34, 197, 94, 0.08);
    --success-border: rgba(34, 197, 94, 0.25);
    --error: #ef4444;
    --error-bg: rgba(239, 68, 68, 0.08);
    --error-border: rgba(239, 68, 68, 0.25);
    --warn: #f59e0b;
    --warn-bg: rgba(245, 158, 11, 0.08);
    --warn-border: rgba(245, 158, 11, 0.25);
    --offline: #6b7280;
    --offline-bg: rgba(107, 114, 128, 0.08);
    /* State-bit chip palette (dark theme). bg = chip background, fg = icon/text colour. */
    --state-red-fg:    #fca5a5;  --state-red-bg:    rgba(239, 68, 68, 0.18);
    --state-yellow-fg: #fcd34d;  --state-yellow-bg: rgba(245, 158, 11, 0.18);
    --state-cyan-fg:   #67e8f9;  --state-cyan-bg:   rgba(34, 211, 238, 0.18);
    --state-violet-fg: #c4b5fd;  --state-violet-bg: rgba(167, 139, 250, 0.18);
    --state-blue-fg:   #93c5fd;  --state-blue-bg:   rgba(59, 130, 246, 0.18);
    --state-green-fg:  #86efac;  --state-green-bg:  rgba(34, 197, 94, 0.18);
    --state-grey-fg:   #cbd5e1;  --state-grey-bg:   rgba(148, 163, 184, 0.18);
    --overlay: rgba(0, 0, 0, 0.7);
    --overlay-heavy: rgba(0, 0, 0, 0.95);
    --shadow-modal: rgba(0, 0, 0, 0.5);
    --shadow-dropdown: rgba(0, 0, 0, 0.4);
    --shadow-toast: rgba(0, 0, 0, 0.3);
    --row-hover: rgba(255, 255, 255, 0.03);
    --row-hover-strong: rgba(255, 255, 255, 0.06);
    color-scheme: dark;
}

[data-theme="light"] {
    --bg: #f0f1f5;
    --surface: #ffffff;
    --surface2: #f5f6f8;
    --surface3: #eaecf0;
    --border: #d0d4dc;
    --border-light: #e2e5eb;
    --text: #1e2230;
    --text-dim: #454a5c;
    --text-muted: #6b7084;
    --accent: #4a76c4;
    --accent-hover: #3d65ad;
    --accent-glow: rgba(74, 118, 196, 0.1);
    --accent-border: rgba(74, 118, 196, 0.25);
    --success: #3a8a5c;
    --success-bg: rgba(58, 138, 92, 0.07);
    --success-border: rgba(58, 138, 92, 0.2);
    --error: #c0504d;
    --error-bg: rgba(192, 80, 77, 0.06);
    --error-border: rgba(192, 80, 77, 0.2);
    --warn: #b8862e;
    --warn-bg: rgba(184, 134, 46, 0.06);
    --warn-border: rgba(184, 134, 46, 0.2);
    --offline: #7a7f8e;
    --offline-bg: rgba(122, 127, 142, 0.06);
    /* State-bit chip palette (light theme) — darker fg for AA contrast on light bg. */
    --state-red-fg:    #b91c1c;  --state-red-bg:    #fee2e2;
    --state-yellow-fg: #b45309;  --state-yellow-bg: #fef3c7;
    --state-cyan-fg:   #0e7490;  --state-cyan-bg:   #cffafe;
    --state-violet-fg: #6d28d9;  --state-violet-bg: #ede9fe;
    --state-blue-fg:   #1d4ed8;  --state-blue-bg:   #dbeafe;
    --state-green-fg:  #15803d;  --state-green-bg:  #dcfce7;
    --state-grey-fg:   #4b5563;  --state-grey-bg:   #e5e7eb;
    --overlay: rgba(0, 0, 0, 0.4);
    --overlay-heavy: rgba(0, 0, 0, 0.7);
    --shadow-modal: rgba(0, 0, 0, 0.12);
    --shadow-dropdown: rgba(0, 0, 0, 0.1);
    --shadow-toast: rgba(0, 0, 0, 0.08);
    --row-hover: rgba(0, 0, 0, 0.03);
    --row-hover-strong: rgba(0, 0, 0, 0.05);
    color-scheme: light;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

.mono { font-family: 'JetBrains Mono', monospace; }

@keyframes pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ====== Forms (shared across admin + dashboard report panels) ======
   Lifted from admin.css so report plugins on the dashboard pick up
   the same dark/rounded style without having to import admin.css. */
.form-group { margin-bottom: 0.85rem; }
.form-label {
    display: block; font-size: 0.65rem; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 0.3rem; font-weight: 600;
}
.form-input {
    width: 100%; background: var(--bg); border: 1px solid var(--border);
    border-radius: 6px; padding: 0.5rem 0.7rem; color: var(--text);
    font-family: 'JetBrains Mono', monospace; font-size: 0.82rem; outline: none;
    transition: border-color 0.2s;
}
.form-input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-glow); }

/* ====== Buttons (shared across admin + dashboard) ======
   Lifted from admin.css for the same reason as .form-input —
   so report panels on the dashboard share the same look. */
.btn {
    border-radius: 6px; font-size: 0.72rem; padding: 0.35rem 0.75rem;
    cursor: pointer; font-family: 'JetBrains Mono', monospace;
    transition: all 0.15s; border: 1px solid; display: inline-flex;
    align-items: center; gap: 0.35rem;
}
.btn-default,
.btn-secondary { background: var(--surface2); border-color: var(--border); color: var(--text-dim); }
.btn-default:hover,
.btn-secondary:hover { border-color: var(--border-light); color: var(--text); }
.btn-primary { background: var(--accent-glow); border-color: var(--accent-border); color: var(--accent); }
.btn-primary:hover { background: var(--accent); color: white; }
.btn-danger { background: var(--error-bg); border-color: var(--error-border); color: var(--error); }
.btn-danger:hover { background: var(--error); color: white; }
.btn-success { background: var(--success-bg); border-color: var(--success-border); color: var(--success); }
.btn-success:hover { background: var(--success); color: white; }

.btn-sm { padding: 3px 10px; font-size: 0.72rem; border-radius: 4px;
    background: var(--surface3); color: var(--text-dim); border: 1px solid var(--border); cursor: pointer; }
.btn-sm:hover:not(:disabled) { background: var(--surface); color: var(--text); }
.btn-sm:disabled { opacity: 0.4; cursor: default; }

.btn-xs {
    padding: 0.1em 0.5em; font-size: 0.85em;
    border: 1px solid var(--border); background: transparent;
    color: var(--text); cursor: pointer; border-radius: 2px;
}
.btn-xs.danger,
.btn-xs.btn-danger { color: var(--error); border-color: var(--error); }
.btn-xs.danger:hover,
.btn-xs.btn-danger:hover { background: var(--error); color: var(--surface); }

/* ====== Admin panel head ======
   Shared "title left, action buttons top-right" header used at the top of
   admin section panels (devices list, formula editor, etc.). Both columns
   of a list/editor split should start with .adm-panel-head so their tops
   align by height and font. Lifted out of admin-availability.js so any
   admin tab can reuse the same look without re-injecting styles.
   Per-tab specific styles (e.g. .avl-section grey-panel wrappers) stay
   in their respective tabs/files. */
.adm-panel-head {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.35rem 0.45rem 0.6rem; margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap; min-height: 2.1rem;
}
.adm-panel-title {
    font-family: 'JetBrains Mono', monospace; font-size: 0.95rem;
    font-weight: 600; color: var(--text);
}
.adm-panel-actions {
    margin-left: auto; display: flex; gap: 0.4rem;
    flex-wrap: wrap; align-items: center;
}

/* ====== Admin grey-panel sections ======
   Group fields inside a tab into bordered grey panels with white inputs.
   Originated as .avl-section in availability formulas; lifted to common.css
   so devices, hierarchy, profiles etc. can reuse the same look without
   re-injecting per-tab CSS. */
.adm-section {
    margin: 0.6rem 0;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface2);
}
.adm-section:first-child { margin-top: 0; }
.adm-section-title {
    font-weight: 600; font-size: 0.95em;
    color: var(--text);
    margin-bottom: 0.45rem;
}
/* Nested panel inside an .adm-section — slightly different shade so the
   nesting reads visually. Used for "AND" groups in availability formulas. */
.adm-group {
    margin: 0.6rem 0 0.4rem;
    padding: 0.5rem 0.6rem;
    border: 1px dashed var(--border);
    border-radius: 6px;
    background: var(--surface3);
}
/* Inputs/selects inside admin grey panels:
   * dark theme — keep the default --bg (truly dark, contrasts with --surface2 panel)
   * light theme — promote to --surface (white, stands out on the grey panel)
   The .form-input default is already var(--bg), so we only need a light-theme
   override here. Covers both .form-input and the legacy .prop-field inputs. */
[data-theme="light"] .adm-section .form-input,
[data-theme="light"] .adm-group   .form-input,
[data-theme="light"] .adm-section .prop-field input,
[data-theme="light"] .adm-section .prop-field select,
[data-theme="light"] .adm-group   .prop-field input,
[data-theme="light"] .adm-group   .prop-field select { background: var(--surface); }

/* ====== Admin confirmation modal ======
   Promise-based confirm() replacement (window.admConfirm). Markup is built
   on demand by /js/adm-modal.js — only the styles live here. */
.adm-modal-backdrop {
    position: fixed; inset: 0; z-index: 10000;
    background: var(--overlay); backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center;
    animation: fadeUp 0.12s ease-out;
}
.adm-modal {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 10px; box-shadow: 0 10px 40px var(--shadow-modal);
    min-width: 320px; max-width: 480px;
    padding: 1rem 1.1rem 0.9rem;
    font-family: 'JetBrains Mono', monospace;
}
.adm-modal-title {
    font-size: 0.95rem; font-weight: 600; color: var(--text);
    margin-bottom: 0.5rem;
}
.adm-modal-body {
    font-size: 0.82rem; color: var(--text-dim); line-height: 1.4;
    margin-bottom: 1rem;
}
.adm-modal-actions {
    display: flex; justify-content: flex-end; gap: 0.5rem;
}

/* Page header — shared layout between dashboard and admin headers.
   Per-page CSS may add positioning (e.g. dashboard's grid-column). */
.header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 0.35rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Header icon — shared between dashboard and admin headers.
   Default: a 38×38 gradient tile (used for emoji icons like the gear).
   .header-icon-logo overrides for the ATMOS mark, which draws itself
   on a transparent square. The +div selector pulls the title block in
   tighter than the rest of the header gap. */
.header-icon {
    width: 38px; height: 38px;
    background: linear-gradient(135deg, var(--accent), #5b6abf);
    border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    font-size: 1rem;
    flex-shrink: 0;
}
.header-icon-logo {
    background: none;
    border-radius: 0;
    width: 60px; height: 60px;
    color: var(--text);
}
.header > .header-icon-logo + div { margin-left: -0.95rem; }

/* Header text — same typography on dashboard and admin headers. */
.header-title {
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}
.header-sub {
    font-size: 0.72rem;
    color: var(--text-dim);
    margin-top: 1px;
    font-family: 'JetBrains Mono', monospace;
}

/* ATMOS Concentric mark — three radar rings + solid core.
   Stroke/fill come from --accent so the mark adapts to the current theme. */
.atmos-mark { display: block; }
.atmos-mark .al-ring-outer { stroke: var(--accent); stroke-opacity: 0.3; stroke-width: 1.6; }
.atmos-mark .al-ring-mid   { stroke: var(--accent); stroke-opacity: 0.6; stroke-width: 1.6; }
.atmos-mark .al-ring-inner { stroke: var(--accent); stroke-width: 1.8; }
.atmos-mark .al-core       { fill: var(--accent); }

/* Plain ATMOS / АТМОС wordmark — used in headers and the login lockup. */
.atmos-wordmark {
    display: inline-block;
    line-height: 1;
    letter-spacing: 0.08em;
    font-weight: 600;
    white-space: nowrap;
}

/* ============================================================
   Device-state chip strip
   ----------------------------------------------------------
   Renders the FULL set of active devicestate bits next to a primary
   dot/badge. Used in two places:
     • Sidebar device row  (size sm, icon-only 14×14)
     • Detail-header strip (size lg, icon + label, flex-wrap)

   Source of truth for {bit → color, icon} is /js/state-bits.js.
   Color tokens (--state-{name}-bg/-fg) come from :root and are
   overridden in [data-theme="light"] above.
   ============================================================ */
.state-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    user-select: none;
    background: transparent;
    border: 1px solid transparent;
    transition: transform .1s ease, filter .1s ease;
    line-height: 1;
}
.state-chip:hover { transform: scale(1.08); filter: brightness(1.15); }
/* Read-only chips (events table) — no hover bling, no pointer. */
.state-chip-inert         { cursor: default; }
.state-chip-inert:hover   { transform: none; filter: none; }

/* Sidebar / events-table — icon-only, no fill. */
.state-chip-sm {
    width: 18px; height: 18px;
    font-size: 14px;
    border-radius: 3px;
}
/* Detail-header — bigger, icon + label, transparent background, color from *-fg. */
.state-chip-lg {
    padding: 3px 6px;
    font-size: 13px;
    border-radius: 4px;
    gap: 5px;
}
.state-chip-icon { display: inline-flex; align-items: center; justify-content: center; }
.state-chip-icon svg { width: 1em; height: 1em; display: block; }
.state-chip-lg .state-chip-icon  { font-size: 15px; }
.state-chip-lg .state-chip-label { font-size: 12px; font-weight: 500; letter-spacing: .02em; color: var(--text); }

/* Primary chip — first (highest-priority) bit. Headline status. */
.state-chip-lg.state-chip-primary {
    padding: 4px 10px;
    border-radius: 5px;
    border-color: currentColor;
    background: color-mix(in srgb, currentColor 12%, transparent);
}
.state-chip-lg.state-chip-primary .state-chip-icon  { font-size: 17px; }
.state-chip-lg.state-chip-primary .state-chip-label { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text); }

/* Color tokens — apply to icon/label foreground only. */
.state-chip-red    { color: var(--state-red-fg); }
.state-chip-yellow { color: var(--state-yellow-fg); }
.state-chip-cyan   { color: var(--state-cyan-fg); }
.state-chip-violet { color: var(--state-violet-fg); }
.state-chip-blue   { color: var(--state-blue-fg); }
.state-chip-green  { color: var(--state-green-fg); }
.state-chip-grey   { color: var(--state-grey-fg); }

.state-chip-more   {
    color: var(--text-dim);
    border-color: var(--border);
    padding: 1px 5px;
    font-size: 10px;
    font-weight: 600;
}
.state-chip-lg.state-chip-more { padding: 2px 8px; font-size: 11px; }

/* Containers: sidebar — single-line right-aligned strip; detail — wrap-friendly */
.device-state-chips {
    display: inline-flex;
    gap: 3px;
    align-items: center;
    margin-left: auto;
    margin-right: 6px;
    flex-shrink: 0;
}
.detail-state-chips {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    flex: 0 1 auto;
    min-width: 0;
}
.detail-state-empty {
    font-size: 0.82rem;
    color: var(--text-muted);
    font-style: italic;
}

/* ============================================================
   Primary device-dot colours
   ----------------------------------------------------------
   The new color set replaces the legacy 4-bucket .device-dot.online /
   .warning / .error / .offline classes — colours now match the
   highest-priority chip (computed in getDeviceDotColor()).

   .device-dot itself (size, shape, transition) is defined in
   dashboard.css; here we only add the per-color modifiers so they
   are also picked up by admin or any other page that loads
   common.css.
   ============================================================ */
.device-dot-red    { background: var(--state-red-fg);    box-shadow: 0 0 6px var(--state-red-fg); }
.device-dot-yellow { background: var(--state-yellow-fg); box-shadow: 0 0 6px var(--state-yellow-fg); }
.device-dot-cyan   { background: var(--state-cyan-fg);   box-shadow: 0 0 6px var(--state-cyan-fg); }
.device-dot-violet { background: var(--state-violet-fg); box-shadow: 0 0 6px var(--state-violet-fg); }
.device-dot-blue   { background: var(--state-blue-fg);   box-shadow: 0 0 6px var(--state-blue-fg); }
.device-dot-green  { background: var(--state-green-fg);  box-shadow: 0 0 6px var(--state-green-fg); }
.device-dot-grey   { background: var(--state-grey-fg); /* No glow for "no connection / not installed" — a quiet state. */ }
.device-dot-online { background: var(--success);         box-shadow: 0 0 6px var(--success); }
.device-dot-loading {
    background: var(--text-dim);
    animation: device-dot-pulse 1.4s ease-in-out infinite;
}
@keyframes device-dot-pulse {
    0%, 100% { opacity: 0.4; }
    50%      { opacity: 1; }
}

/* Detail-header badge — pill variant of the colour family. */
.detail-badge-red    { background: var(--state-red-bg);    color: var(--state-red-fg); }
.detail-badge-yellow { background: var(--state-yellow-bg); color: var(--state-yellow-fg); }
.detail-badge-cyan   { background: var(--state-cyan-bg);   color: var(--state-cyan-fg); }
.detail-badge-violet { background: var(--state-violet-bg); color: var(--state-violet-fg); }
.detail-badge-blue   { background: var(--state-blue-bg);   color: var(--state-blue-fg); }
.detail-badge-green  { background: var(--state-green-bg);  color: var(--state-green-fg); }
.detail-badge-grey   { background: var(--state-grey-bg);   color: var(--state-grey-fg); }
.detail-badge-online { background: var(--success-bg);      color: var(--success); }
.detail-badge-loading{ background: var(--surface2);        color: var(--text-dim); }
/* The .detail-badge .dot { background: currentColor } rule in dashboard.css
   already paints the inner dot from each badge variant's color. */

/* ============================================================
   Audit log table — admin → Audit tab.
   Лежит в common.css, потому что этот же стиль может в будущем
   потребоваться на дашборде (read-only view) или в отчётах.
   ============================================================ */
.audit-table {
    width: 100%;
    border-collapse: collapse;
    font-family: 'JetBrains Mono', monospace;
    font-size: .82rem;
}
.audit-table th,
.audit-table td {
    text-align: left;
    padding: .35rem .55rem;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}
.audit-table th {
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .72rem;
    font-weight: 600;
    background: var(--surface2);
    position: sticky;
    top: 0;
    z-index: 1;
}
.audit-table tbody tr:hover {
    background: var(--surface2);
}
.audit-cell-path {
    max-width: 30rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Status colour chips — same palette family as device dots. */
.audit-status-2xx { color: var(--success); }
.audit-status-4xx { color: var(--state-yellow-fg); }
.audit-status-5xx { color: var(--danger); }
