/* Cold Snipe Webapp Styles */

/* ============================================
   CSS Variables - Dark Theme (Matches Extension)
   ============================================ */
:root {
    /* --- Brand green as a RAMP -------------------------------------------
       Every colour here used to sit between hue 150 and 165 at 4-20%
       saturation: surfaces, body text, borders, primary, success and info were
       all the same green, so nothing could stand out against anything else.
       The green is now a ramp -- deep fills at the bottom, a saturated accent
       at the top -- with near-neutral surfaces and text in between, so the
       green reads as emphasis rather than as the whole interface. */
       Kept deliberately low-saturation -- grey with a touch of green -- rather
       than a vivid mint. The accent and bright steps are the ORIGINAL brand
       tones; only the surfaces, text and semantics around them changed. */
    --green-deep: #1E2B26;     /* fills: active nav, badges, wells */
    --green-mid: #5C6E68;      /* accent borders, secondary emphasis */
    --green-accent: #7FA096;   /* the accent proper: buttons, links, focus */
    --green-bright: #C5D8D1;   /* hover on the accent */

    /* Legacy names kept so the ~36 existing var() call sites keep working;
       they now point into the ramp above rather than at flat sage tones. */
    --mint-green: var(--green-bright);
    --sage-green: var(--green-accent);
    --forest-green: var(--green-mid);

    /* Neutral surface tones */
    --true-black: #060807;
    --dark-charcoal: #141917;
    --charcoal: #1B211E;

    /* Semantic Colors -- each its own hue. `success` used to be literally
       `var(--sage-green)`, i.e. identical to primary, and `info` was a surface
       tone, so neither could be told apart from an ordinary control. */
    --primary: var(--green-accent);
    --primary-dark: var(--green-mid);
    --primary-light: var(--green-bright);
    --secondary: var(--green-mid);
    --success: #3FB950;
    --warning: #D29922;
    --danger: #F85149;
    --info: #58A6FF;

    /* Background Layers (page -> raised). The page sat at 4.7% lightness and
       cards at 17.6%, with list rows at 26.3% -- light enough that everything
       read as one flat grey-green field. Pulled down and spread out so raised
       surfaces actually look raised. */
    --bg-secondary: var(--true-black);    /* page / body            2.7% */
    --bg-primary: var(--dark-charcoal);   /* cards, panels, modals  8.8% */
    --bg-tertiary: var(--charcoal);       /* list rows, wells      11.8% */
    --bg-hover: #232A26;
    --bg-active: var(--green-deep);       /* selected nav, active tab */

    /* --- Chrome ----------------------------------------------------------
       The sidebar and the topbar get tokens of their own so a theme can move
       them independently of the cards. They default to exactly what was
       painted before they existed -- the sidebar shared --bg-primary with
       cards, the topbar was mixed from --bg-secondary -- so the shipped look
       is unchanged and "Midnight" in the theme picker is a true revert.

       Splitting them apart is the point: a sidebar the same colour as a card
       is why the app reads as one flat sheet. See styles/themes.css. */
    --bg-nav: var(--bg-primary);          /* sidebar */
    --bg-topbar: var(--bg-secondary);     /* topbar, before its alpha mix */

    /* The recessed ground of a form field. Was --true-black written out at
       four call sites; that is a raw palette value, not a role, and a light
       theme has no way to reach it. */
    --bg-input: var(--true-black);

    /* Text that sits ON an accent or semantic fill -- a badge, a solid
       button, a counter pip. On the dark themes the fills are pale and this
       is near-black; a light theme darkens the fills, so it becomes white.
       Fourteen rules wrote --true-black here for want of a name for it. */
    --on-accent: var(--true-black);

    /* Text Hierarchy -- near-neutral. Body copy was --mint-green and muted
       text was --forest-green, i.e. the text was made of the brand colour.
       --text-muted scored 1.77:1 on cards, far below the 4.5:1 AA floor,
       which is why previews, timestamps and hints looked washed out. */
    --text-primary: #E9EDEB;
    --text-secondary: #A9B3AE;
    --text-muted: #97A19B;

    /* Borders */
    --border-color: #232B27;
    /* Controls need a border you can actually see. #2E3833 measured
       1.46:1 against a card, so outlined buttons and inputs had no visible
       edge at all -- the footer Close button read as floating text. But
       #4F5F57 (2.7:1) went too far the other way: every input and select
       on a dark page wore a bright frame and a form read as a grid of
       boxes. #3D4943 is the middle: about 2:1 on a card, present, quiet. */
    --border-dark: #3D4943;
    /* The edge of something CHOSEN: a checked pill, a switched-on channel,
       a connected tile. Used to be the full accent colour, which on a
       near-black card is the brightest line on the screen -- and a form
       with five chosen days lit up like a circuit board. Muted toward the
       ordinary border; the tinted background carries the "on" state. */
    --border-on: color-mix(in srgb, var(--green-accent) 50%, var(--border-color));

    /* Shadows & Glows */
    --border-radius: 8px;
    --shadow-sm: 0 1px 3px rgba(0,0,0,0.4);
    --shadow: 0 2px 4px rgba(0,0,0,0.5);
    --shadow-lg: 0 4px 12px rgba(0,0,0,0.6);

    /* Accent Glows. These two were left over from a vivid mint (92,201,160)
       that is no longer anywhere in the ramp, so every focus ring and button
       glow lit up in a green the rest of the interface does not contain.
       Rebuilt from --green-accent (#7FA096) so emphasis matches the brand. */
    --mint-glow: rgba(127, 160, 150, 0.20);
    --sage-glow: rgba(127, 160, 150, 0.38);

    /* --- Elevation -------------------------------------------------------
       The page sits at 2.7% lightness, where a plain drop shadow is invisible:
       black on near-black is still near-black. Depth on a dark UI comes from
       a hairline of light along the top edge -- the same cue a raised surface
       gives in the real world -- with the shadow only grounding it. Each step
       pairs that inset highlight with a wider, softer cast. */
    --elev-1: inset 0 1px 0 rgba(255, 255, 255, 0.035),
              0 1px 2px rgba(0, 0, 0, 0.5);
    --elev-2: inset 0 1px 0 rgba(255, 255, 255, 0.05),
              0 2px 6px rgba(0, 0, 0, 0.45),
              0 8px 24px rgba(0, 0, 0, 0.35);
    --elev-3: inset 0 1px 0 rgba(255, 255, 255, 0.07),
              0 12px 32px rgba(0, 0, 0, 0.55),
              0 32px 64px rgba(0, 0, 0, 0.4);

    /* Legacy names, now pointing at the elevation scale. */
    --shadow-sm: var(--elev-1);
    --shadow: var(--elev-2);
    --shadow-lg: var(--elev-3);

    /* --- Radius ----------------------------------------------------------
       Everything was one 8px token, so a 24px badge and a full-page modal
       curved identically and nothing read as a different kind of object.
       Radius should scale with the surface it belongs to. */
    --radius-xs: 3px;    /* small badges: a corner, not a curve */
    --radius-sm: 5px;    /* chips, inline controls */
    --radius-md: 8px;    /* buttons, inputs, list rows */
    --radius-lg: 12px;   /* cards, panels */
    --radius-xl: 16px;   /* modals, the largest surfaces */
    --border-radius: var(--radius-md);

    /* --- Focus -----------------------------------------------------------
       One ring, used by every control, so focus always looks the same.

       A 4px double ring reads as a glow around a small button and as a thick
       bright outline around anything the width of a textarea. This is a
       single 2px halo at low opacity: unmistakable when you tab to something,
       quiet when you click into a large field.  */
    --focus-ring: 0 0 0 2px rgba(127, 160, 150, 0.45);

    /* --- Motion ----------------------------------------------------------
       Controls transitioned `all`, which animates layout properties too and
       is what makes an interface feel loose. These name the two speeds worth
       having, on an ease-out curve so movement decelerates into place. */
    --ease: cubic-bezier(0.2, 0, 0, 1);
    --fast: 120ms;
    --slow: 220ms;

    --topbar-height: 56px;
    --sidebar-width: 240px;
    --header-height: 60px;
}

/* Someone who has asked their system to reduce motion gets none of it. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ============================================
   Reset & Base
   ============================================ */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-primary);
    background: var(--bg-secondary);
    /* Light text on a near-black ground renders heavier than it should
       without this; the stems bloom and the whole app looks slightly out of
       focus. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Figures that update in place -- counters, stats, rates, timers -- jitter as
   digits of different widths swap in. Tabular figures hold their columns. */
.stat-value,
.stat-number,
.metric-value,
td,
.mono {
    font-variant-numeric: tabular-nums;
}

a {
    color: var(--primary);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* ============================================
   Layout
   ============================================ */
#app {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: var(--sidebar-width);
    background: var(--bg-nav);
    border-right: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 100;
}

.sidebar-header {
    padding: 16px 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-bottom: 1px solid var(--border-color);
}

.logo {
    width: 100%;
    max-width: 180px;
    height: auto;
    object-fit: contain;
}

.nav-menu {
    list-style: none;
    padding: 12px;
    flex: 1;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-radius: var(--border-radius);
    color: var(--text-secondary);
    transition: all 0.2s;
}

.nav-link:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    text-decoration: none;
}

.nav-link.active {
    background: var(--primary);
    color: white;
}

.nav-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.sidebar-footer {
    padding: 16px;
    border-top: 1px solid var(--border-color);
}

.user-info {
    margin-bottom: 8px;
    font-size: 12px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.main-content {
    flex: 1;
    /* min-width:0 lets the column actually shrink; without it a wide table or
       a long unbroken string pushes the whole layout past the viewport. */
    min-width: 0;
    margin-left: var(--sidebar-width);
    /* The gutter grows with the window instead of staying a flat 24px, so
       content is not pinned to the sidebar on a large screen. */
    padding: 28px clamp(20px, 3vw, 44px) 64px;
    max-width: 1320px;
}

#page-container {
    animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ============================================
   Typography
   ============================================ */
/* Headings carried no letter-spacing, so at 600 weight the larger sizes read
   loose and soft. Tightening as size goes up is what makes a heading look set
   rather than merely enlarged. */
h1 {
    font-size: 24px;
    font-weight: 650;
    line-height: 1.25;
    letter-spacing: -0.02em;
    margin-bottom: 8px;
}

h2 {
    font-size: 20px;
    font-weight: 650;
    line-height: 1.3;
    letter-spacing: -0.015em;
}

h3 {
    font-size: 16px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: -0.01em;
}

h4 {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
}

.text-muted {
    color: var(--text-muted);
}

/* ===== Scrollbars =====
   Every scroller, up-down and side-to-side: a slim rounded thumb in the
   theme's border tone that darkens under the pointer, no track, no arrows.
   Chromium styles the pseudo-elements; Firefox takes the two properties.
   Both come from the theme tokens, so they follow the selected theme. */
:root {
    --scroll-thumb: var(--border-color);
    --scroll-thumb-hover: var(--text-muted);
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-button { width: 0; height: 0; display: none; }
::-webkit-scrollbar-thumb {
    background: var(--scroll-thumb);
    border-radius: 999px;
    /* The transparent border keeps the thumb off the edge; padding-box
       clipping stops the colour from filling it. */
    border: 3px solid transparent;
    background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--scroll-thumb-hover); }
::-webkit-scrollbar-thumb:active { background-color: var(--primary); }

@supports not selector(::-webkit-scrollbar) {
    * {
        scrollbar-width: thin;
        scrollbar-color: var(--scroll-thumb) transparent;
    }
}
