/*
    KPI.tv shared "app shell" stylesheet - linked by every logged-in screen
    (dashboard/kpi/kpi-detail/page/channel/channel-list/account/user-profile/
    displays/products/schedule) BEFORE that screen's own CSS file, so a
    screen's own rules still win on cascade if it genuinely needs to
    override something.

    Covers only what was previously copy-pasted byte-for-byte (or near
    enough) into every one of those screens: design tokens, base
    typography/reset, the .btn system, the header/nav/user-menu dropdown,
    and generic modal chrome. Anything genuinely screen-specific (panel
    layouts, chart previews, page-specific content width) stays in that
    screen's own CSS file - this file is not a place to put one-off rules.

    Consolidated 2026-08-06 out of 11 screens that had each independently
    reinvented this same chrome, with real drift between copies (e.g.
    --radius was 16px in channel.css vs 14px everywhere else; kpi.css never
    defined .btn-success/.btn-xs at all, so framework-emitted buttons using
    those classes - "Log", from ViewDataForm()/modalContent() - silently
    rendered unstyled). Fixing that drift here means every screen now gets
    the same corrected values, not just newly-migrated ones.
*/

:root {
    --ink:        #0b1119;
    --ink-2:      #080c12;
    --panel:      #131b28;
    --panel-2:    #182233;
    --line:       rgba(148, 163, 184, 0.14);
    --line-2:     rgba(148, 163, 184, 0.24);
    --paper:      #f2f5f9;
    --muted:      #8b97ab;
    --muted-2:    #5f6b80;
    --on-air:     #ff4136;
    --on-air-dim: rgba(255, 65, 54, 0.16);
    --tally:      #ffb020;
    --tally-dim:  rgba(255, 176, 32, 0.14);
    --signal:     #34d399;
    --signal-dim: rgba(52, 211, 153, 0.14);

    --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
    --font-mono:    "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
    --font-body:    "Inter", "Helvetica Neue", Arial, sans-serif;

    --radius: 14px;

    /* Standard content width for a single-column app screen (dashboard's
       .db-main and channel's .db-main are flex layouts that intentionally
       don't use this - a fixed-width narrower screen like /user-profile or
       /account is also a deliberate choice, set locally in that screen's
       own CSS, not a bug). */
    --app-width: 1160px;
}

* { box-sizing: border-box; }

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

body {
    margin: 0;
    background: var(--ink);
    color: var(--paper);
    font-family: var(--font-body);
    font-size: 15.5px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

a { color: inherit; }

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 800;
    letter-spacing: -0.02em;
    margin: 0;
    color: var(--paper);
}

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    border-radius: 999px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 14px;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    background: none;
    color: var(--paper);
    transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}
.btn:focus-visible {
    outline: 2px solid var(--paper);
    outline-offset: 3px;
}
.btn-primary {
    background: var(--on-air);
    color: #fff;
    box-shadow: 0 8px 20px -8px rgba(255, 65, 54, 0.6);
}
.btn-primary:hover { transform: translateY(-1px); }

.btn-ghost {
    background: transparent;
    color: var(--paper);
    border-color: var(--line-2);
}
.btn-ghost:hover { border-color: var(--paper); }

.btn-danger {
    background: transparent;
    color: var(--on-air);
    border-color: rgba(255, 65, 54, 0.4);
}
.btn-danger:hover { background: var(--on-air-dim); border-color: var(--on-air); }

.btn-secondary {
    background: var(--panel-2);
    color: var(--paper);
    border-color: var(--line-2);
}
.btn-secondary:hover { border-color: var(--paper); }

/* Compatibility shim for plain Bootstrap-3 utility classes the framework
   itself emits (ViewDataForm()/modalContent()/auto-forms' Save buttons) -
   Bootstrap's own CSS isn't loaded, so these need real styling here or
   they render as unstyled browser-default buttons. */
.btn-info, .btn-success {
    background: var(--panel-2);
    color: var(--paper);
    border-color: var(--line-2);
}
.btn-info:hover, .btn-success:hover { border-color: var(--on-air); color: var(--on-air); }

.btn-sm { padding: 8px 15px; font-size: 13px; }
.btn-xs { padding: 5px 12px; font-size: 12px; }
.btn-block { display: flex; width: 100%; }

/* ---------- App header ---------- */

.db-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 24px;
    border-bottom: 1px solid var(--line);
}

.brand {
    display: flex;
    align-items: center;
    gap: 9px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 19px;
    text-decoration: none;
    color: var(--paper);
    flex: none;
}
.brand .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--on-air);
    box-shadow: 0 0 0 4px var(--on-air-dim);
}
.brand .tv { color: var(--muted); font-weight: 600; }

.db-header-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 1;
    gap: 16px;
    min-width: 0;
}
.db-header-actions a {
    color: var(--muted);
    text-decoration: none;
    font-size: 14px;
}
.db-header-actions a:hover { color: var(--paper); }
.db-header-actions a.is-current { color: var(--paper); }

.db-nav-left { display: flex; align-items: center; gap: 16px; }

/* Name-triggered dropdown (Profile/Account/Log out). */
.db-user-menu { position: relative; flex: none; }
.db-user-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    color: var(--paper);
    font-family: var(--font-body);
    font-size: 14px;
    cursor: pointer;
    padding: 6px 4px;
}
.db-user-btn svg {
    width: 14px;
    height: 14px;
    color: var(--muted);
    transition: transform 0.15s ease;
}
.db-user-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.db-user-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 20;
    min-width: 180px;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    background: var(--panel);
    border: 1px solid var(--line-2);
    border-radius: 10px;
    box-shadow: 0 20px 40px -16px rgba(0, 0, 0, 0.6);
}
.db-user-dropdown.is-open { display: flex; }
.db-user-dropdown a {
    padding: 8px 10px;
    border-radius: 7px;
    color: var(--paper);
    text-decoration: none;
    font-size: 13.5px;
}
.db-user-dropdown a:hover { background: var(--panel-2); }
.db-user-dropdown a.is-current { color: var(--on-air); font-weight: 600; }
.db-user-dropdown hr {
    border: none;
    border-top: 1px solid var(--line-2);
    margin: 4px 2px;
}
.db-user-dropdown .db-user-logout { color: var(--on-air); }

/* Dashboard/Channels/Programmes/Displays, repeated inside the dropdown for
   narrow screens (see the @media block below) - hidden here by default so
   desktop only ever shows them once, in .db-nav-left. */
.db-nav-mobile-item { display: none; }

/* ---------- Generic modal chrome ---------- */
/* Backdrop element/id is now the same on every screen (#modal-backdrop) -
   previously each screen prefixed both the class and the id
   (kpi-modal-backdrop, page-modal-backdrop, ...), which only ever needed
   to be different because each screen's JS looked itself up by that
   prefixed id - shared/js/app.js now looks up the one shared id instead. */
.modal-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(4, 6, 10, 0.7);
    z-index: 90;
}
.modal-backdrop.is-open { display: block; }

.modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 95;
    overflow-y: auto;
    padding: 40px 16px;
}
.modal.is-open { display: block; }

/* width:100% (not just max-width) so a dialog is always sized from the
   viewport and stays inside .modal's padding on a phone. max-width alone
   left the width to whatever the markup happened to say - and framework
   markup said a fixed px value, which can't shrink, so the dialog overflowed
   narrow screens and put the whole page into horizontal scroll. !important
   because the offending width came in as an inline style; that one is gone
   (see modalContent() in _system/core/themeElements.php) but every modal on
   every screen shares this rule, and none of them should ever be able to
   reintroduce the bug. */
.modal-dialog { width: 100% !important; max-width: 480px; margin: 0 auto; }
.modal-content {
    background: var(--panel);
    border: 1px solid var(--line-2);
    border-radius: var(--radius);
    box-shadow: 0 40px 80px -24px rgba(0, 0, 0, 0.7);
}
.modal-header {
    padding: 18px 22px;
    border-bottom: 1px solid var(--line);
    position: relative;
}
.modal-title {
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 800;
    margin: 0;
}
.modal-header .close {
    position: absolute;
    top: 14px; right: 18px;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 20px;
    cursor: pointer;
}
.modal-body { padding: 22px; display: flex; flex-direction: column; gap: 16px; }
.modal-footer { padding: 0 22px 22px; display: flex; justify-content: flex-end; gap: 10px; }

/* ---------- Responsive header ---------- */

/* Below this width, brand + the 4 nav links + a real username routinely
   don't fit .db-header in one row (measured ~550-650px depending on name
   length) - .db-nav-left disappears and its links move into the
   .db-user-dropdown copy (.db-nav-mobile-item) instead, rather than
   overflowing and pushing the dropdown trigger off-screen. */
@media (max-width: 760px) {
    .db-nav-left { display: none; }
    .db-nav-mobile-item { display: block; }

    /* .db-nav-left was the only other child of .db-header-actions, so once
       it's hidden the space-between leaves .db-user-menu at the start of the
       row - i.e. the trigger sits just right of the brand, not at the right
       edge. The desktop right:0 dropdown then hangs off the left of the
       screen, so anchor it to the trigger's left edge here instead. */
    .db-user-dropdown { left: 0; right: auto; }
}

@media (max-width: 480px) {
    .db-header { padding: 14px 16px; gap: 8px; }
    .db-user-name { display: none; }

    /* Desktop gutters cost ~76px of a 360px-wide phone before a form field
       even starts - tightened here so inputs and their labels get the width
       they need instead of sitting in a cramped column. */
    .modal { padding: 24px 12px; }
    .modal-header { padding: 16px 18px; }
    .modal-body { padding: 18px; }
    .modal-footer { padding: 0 18px 18px; }
}
