/*
 * NovaSpark design system — token layer.
 * ---------------------------------------------------------------------------
 * Generated from novaspark-design-system-DESIGN.md.
 *
 * WHAT THIS IS
 * Every value in the design document, expressed once as a CSS custom property,
 * plus the components the document specifies. Nothing here hardcodes a colour
 * or a size that the document names — change the token and every use follows.
 *
 * WHAT THIS IS NOT
 * A rebrand. The document carries a "NovaSpark" brand block; this file takes
 * its VISUAL LANGUAGE only. The panel keeps its own name and logo, which come
 * from Settings via App_Name() and App_Logo().
 *
 * SCOPE TODAY
 * Loaded only by the guest layout (sign in, 2FA, password reset) so it can be
 * judged on one screen before it touches the rest of the panel. It is written
 * to serve all of it: the tokens are global, and the .ns-* components are
 * namespaced so they cannot collide with Bootstrap or the existing style.css.
 *
 * ORDER MATTERS. This must load AFTER bootstrap.min.css and style.css — some
 * rules below deliberately override Bootstrap's .form-control and .btn.
 */

/* ==========================================================================
   Tokens
   ========================================================================== */

:root {
    /* --- Brand ---------------------------------------------------------- */
    --nova-blue: #2563EB;
    --nova-dark: #0F172A;
    --nova-light: #F8FAFC;

    /* Hover/active are the document's "10% darker" and "20% darker" for
       Nova Blue, resolved to fixed hex so they do not depend on a colour
       function browsers disagree about. */
    --nova-blue-hover: #1D4ED8;
    --nova-blue-active: #1E40AF;

    /* --- Accent --------------------------------------------------------- */
    --spark-orange: #F97316;
    --spark-green: #22C55E;
    --spark-red: #EF4444;

    /* --- Neutrals ------------------------------------------------------- */
    --gray-900: #111827;
    --gray-600: #4B5563;
    --gray-400: #9CA3AF;
    --gray-300: #D1D5DB;
    --gray-200: #E5E7EB;
    --gray-100: #F3F4F6;
    --white: #FFFFFF;

    /* --- Semantic surfaces ---------------------------------------------- */
    --ns-bg-page: var(--nova-light);
    --ns-bg-surface: var(--white);
    --ns-bg-subtle: var(--gray-100);
    --ns-text: var(--gray-900);
    --ns-text-muted: var(--gray-600);
    --ns-text-placeholder: var(--gray-400);
    --ns-border: var(--gray-200);
    --ns-border-strong: var(--gray-300);

    /* --- Typography ----------------------------------------------------- */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    --text-display: 48px;
    --text-h1: 36px;
    --text-h2: 28px;
    --text-h3: 22px;
    --text-h4: 18px;
    --text-body-lg: 18px;
    --text-body: 16px;
    --text-body-sm: 14px;
    --text-caption: 12px;

    --leading-display: 1.1;
    --leading-h1: 1.2;
    --leading-h2: 1.3;
    --leading-heading: 1.4;
    --leading-body: 1.6;
    --leading-tight: 1.5;

    --weight-regular: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    /* --- Spacing (4px base) --------------------------------------------- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-6: 24px;
    --space-8: 32px;
    --space-12: 48px;
    --space-16: 64px;
    --space-24: 96px;

    /* --- Radius --------------------------------------------------------- */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-full: 9999px;

    /* --- Shadows -------------------------------------------------------- */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
    --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);

    /* --- Motion --------------------------------------------------------- */
    --anim-fast: 100ms ease-out;
    --anim-base: 200ms ease-in-out;
    --anim-slow: 350ms ease-in-out;
    --anim-spring: 400ms cubic-bezier(0.34, 1.56, 0.64, 1);

    /* --- Control sizing ------------------------------------------------- */
    --control-sm: 32px;
    --control-md: 40px;
    --control-lg: 48px;

    /* --- Layout --------------------------------------------------------- */
    --max-content: 1280px;
    --gutter: 24px;
    --sidebar-width: 240px;
    --sidebar-collapsed: 64px;
    --navbar-height: 64px;
}

/*
 * Dark mode, from the document's light -> dark token table.
 *
 * OPT-IN, not automatic. It is tempting to hang this on
 * @media (prefers-color-scheme: dark) and be done — but the signed-in panel is
 * light-only today, so an OS-driven dark login would hand the user a dark
 * screen that flips to a light one the moment they sign in. A theme that
 * changes underneath someone mid-task reads as a bug, not a feature.
 *
 * So the tokens are ready and the switch is not thrown. Add data-theme="dark"
 * to <html> to preview it, and change this to prefers-color-scheme once the
 * whole panel can follow.
 *
 * Re-points the SEMANTIC tokens only; the brand palette is unchanged, which is
 * what keeps Nova Blue recognisable in both.
 */
[data-theme="dark"] {
    --ns-bg-page: #0F172A;
    --ns-bg-surface: #1E293B;
    --ns-bg-subtle: #1E293B;
    --ns-text: #F1F5F9;
    --ns-text-muted: #94A3B8;
    --ns-text-placeholder: #64748B;
    --ns-border: #334155;
    --ns-border-strong: #475569;
}

/* ==========================================================================
   Type scale
   ========================================================================== */

.ns-display { font-size: var(--text-display); line-height: var(--leading-display); font-weight: var(--weight-bold); }
.ns-h1      { font-size: var(--text-h1);      line-height: var(--leading-h1);      font-weight: var(--weight-bold); }
.ns-h2      { font-size: var(--text-h2);      line-height: var(--leading-h2);      font-weight: var(--weight-semibold); }
.ns-h3      { font-size: var(--text-h3);      line-height: var(--leading-heading); font-weight: var(--weight-semibold); }
.ns-h4      { font-size: var(--text-h4);      line-height: var(--leading-heading); font-weight: var(--weight-semibold); }
.ns-body-lg { font-size: var(--text-body-lg); line-height: var(--leading-body);    font-weight: var(--weight-regular); }
.ns-body    { font-size: var(--text-body);    line-height: var(--leading-body);    font-weight: var(--weight-regular); }
.ns-body-sm { font-size: var(--text-body-sm); line-height: var(--leading-tight);   font-weight: var(--weight-regular); }
.ns-caption { font-size: var(--text-caption); line-height: var(--leading-heading); font-weight: var(--weight-medium); }

.ns-muted { color: var(--ns-text-muted); }
.ns-mono  { font-family: var(--font-mono); }

/* ==========================================================================
   Focus
   --------------------------------------------------------------------------
   "2px offset ring in Nova Blue", applied through :focus-visible so a mouse
   click does not leave a ring behind but a Tab press always does. Declared
   once, here, rather than per-component — a focus style that some components
   forget is an accessibility failure that only keyboard users ever hit.
   ========================================================================== */

.ns-scope :focus-visible {
    outline: 2px solid var(--nova-blue);
    outline-offset: 2px;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.ns-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    font-family: var(--font-sans);
    font-weight: var(--weight-medium);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--anim-fast), border-color var(--anim-fast), color var(--anim-fast);
}

.ns-btn--sm { height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--text-body-sm); }
.ns-btn--md { height: var(--control-md); padding: 0 var(--space-4); font-size: 15px; }
.ns-btn--lg { height: var(--control-lg); padding: 0 var(--space-6); font-size: var(--text-body); }

.ns-btn--block { display: flex; width: 100%; }

.ns-btn--primary { background: var(--nova-blue); color: var(--white); }
.ns-btn--primary:hover { background: var(--nova-blue-hover); color: var(--white); }
.ns-btn--primary:active { background: var(--nova-blue-active); }

.ns-btn--secondary { background: transparent; border-color: var(--nova-blue); color: var(--nova-blue); }
.ns-btn--secondary:hover { background: rgba(37, 99, 235, 0.06); }

.ns-btn--ghost { background: transparent; color: var(--ns-text); }
.ns-btn--ghost:hover { background: var(--ns-bg-subtle); }

.ns-btn--destructive { background: var(--spark-red); color: var(--white); }
.ns-btn--destructive:hover { background: #DC2626; color: var(--white); }

.ns-btn--link { background: none; border: none; color: var(--nova-blue); padding: 0; height: auto; }
.ns-btn--link:hover { text-decoration: underline; }

.ns-btn:disabled,
.ns-btn.is-disabled { opacity: 0.4; cursor: not-allowed; }

/* ==========================================================================
   Inputs
   ========================================================================== */

.ns-field { margin-bottom: var(--space-4); }

.ns-label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--text-body-sm);
    font-weight: var(--weight-medium);
    color: var(--ns-text);
}

.ns-input {
    display: block;
    width: 100%;
    height: var(--control-md);
    padding: var(--space-3) var(--space-4);
    font-family: var(--font-sans);
    font-size: var(--text-body);
    color: var(--ns-text);
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border-strong);
    border-radius: var(--radius-md);
    transition: border-color var(--anim-fast), box-shadow var(--anim-fast);
}

.ns-input--lg { height: var(--control-lg); }

.ns-input::placeholder { color: var(--ns-text-placeholder); }

/*
 * The document asks for a 2px focus border. A border that grows from 1px to
 * 2px reflows the text inside it by a pixel, so the second pixel is drawn as
 * an inset shadow instead — same appearance, no jump.
 */
.ns-input:focus {
    outline: none;
    border-color: var(--nova-blue);
    box-shadow: inset 0 0 0 1px var(--nova-blue);
}

.ns-input.is-invalid,
.ns-input[aria-invalid="true"] {
    border-color: var(--spark-red);
}

.ns-input.is-invalid:focus {
    box-shadow: inset 0 0 0 1px var(--spark-red);
}

.ns-error {
    display: block;
    margin-top: var(--space-2);
    font-size: var(--text-body-sm);
    color: var(--spark-red);
}

/* ==========================================================================
   Cards
   ========================================================================== */

.ns-card {
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-md);
}

.ns-card--interactive {
    transition: box-shadow var(--anim-base), transform var(--anim-base);
}

.ns-card--interactive:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
}

/* ==========================================================================
   Badges
   ========================================================================== */

.ns-badge {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-caption);
    font-weight: var(--weight-medium);
    border-radius: var(--radius-full);
    background: var(--gray-200);
    color: #374151;
}

.ns-badge--primary { background: #DBEAFE; color: #1D4ED8; }
.ns-badge--success { background: #DCFCE7; color: #15803D; }
.ns-badge--warning { background: #FEF3C7; color: #B45309; }
.ns-badge--danger  { background: #FEE2E2; color: #B91C1C; }

/* ==========================================================================
   Alerts
   ========================================================================== */

.ns-alert {
    padding: var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-body-sm);
    line-height: var(--leading-tight);
    margin-bottom: var(--space-4);
}

.ns-alert--danger  { background: #FEE2E2; color: #B91C1C; border: 1px solid #FECACA; }
.ns-alert--success { background: #DCFCE7; color: #15803D; border: 1px solid #BBF7D0; }
.ns-alert--warning { background: #FEF3C7; color: #B45309; border: 1px solid #FDE68A; }

.ns-alert ul { margin: var(--space-2) 0 0; padding-left: var(--space-4); }

/* ==========================================================================
   Guest layout — sign in, 2FA, password reset
   --------------------------------------------------------------------------
   A two-panel split: the brand on Nova Dark, the form on Nova Light.

   Nova Dark is specified in the design document for "Backgrounds, headers" and
   had no job anywhere else in the panel. Giving it the whole left half is what
   makes this screen look like a product rather than a form — and it is the one
   screen where spending space on brand is justified, because it is the only
   one an outsider ever sees.

   The brand panel is DECORATION. Every word on it is repeated or unnecessary
   for signing in, so below the lg breakpoint it is dropped entirely rather
   than stacked, and a compact header takes its place.
   ========================================================================== */

.ns-scope {
    font-family: var(--font-sans);
    font-size: var(--text-body);
    line-height: var(--leading-body);
    color: var(--ns-text);
    background: var(--ns-bg-page);
    -webkit-font-smoothing: antialiased;
}

.ns-auth {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1fr;
}

@media (min-width: 1024px) {
    .ns-auth {
        /*
         * Form column first (it is first in the DOM), sized to its content;
         * the brand takes whatever is left.
         *
         * This way round on purpose: a 380px form marooned in the middle of a
         * 900px white column looks like a mistake, while artwork simply gets
         * better with more room. Widening the browser should grow the picture,
         * not the emptiness around the inputs.
         */
        grid-template-columns: minmax(460px, 42%) 1fr;
    }
}

/* --- Brand panel ------------------------------------------------------- */

.ns-auth__brandpanel {
    display: none;
    position: relative;
    overflow: hidden;
    padding: var(--space-16);
    background: linear-gradient(160deg, #0F172A 0%, #172033 55%, #1E293B 100%);
    color: #F1F5F9;
    flex-direction: column;
    justify-content: space-between;
}

@media (min-width: 1024px) {
    .ns-auth__brandpanel { display: flex; }
}

/*
 * Two soft light sources — Nova Blue high left, a much fainter Spark Orange
 * low right. The orange is at 6%: enough to stop the panel reading as flat
 * navy, not enough to be seen as a second colour competing with the brand.
 */
.ns-auth__brandpanel::before,
.ns-auth__brandpanel::after {
    content: '';
    position: absolute;
    border-radius: var(--radius-full);
    pointer-events: none;
}

.ns-auth__brandpanel::before {
    top: -220px;
    left: -160px;
    width: 640px;
    height: 640px;
    background: radial-gradient(circle, rgba(37, 99, 235, 0.34) 0%, rgba(37, 99, 235, 0) 68%);
}

.ns-auth__brandpanel::after {
    bottom: -260px;
    right: -180px;
    width: 560px;
    height: 560px;
    background: radial-gradient(circle, rgba(249, 115, 22, 0.13) 0%, rgba(249, 115, 22, 0) 70%);
}

.ns-auth__brandinner {
    position: relative;
    max-width: 460px;
    margin: auto 0;
}

.ns-auth__brandmark {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-12);
}

.ns-auth__brandmark img {
    height: 40px;
    width: auto;
    border-radius: var(--radius-md);
}

.ns-auth__brandname {
    font-size: var(--text-h3);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.01em;
}

.ns-auth__headline {
    font-size: var(--text-h1);
    line-height: var(--leading-h1);
    font-weight: var(--weight-bold);
    letter-spacing: -0.02em;
    margin: 0 0 var(--space-4);
    color: #FFFFFF;
}

.ns-auth__tagline {
    font-size: var(--text-body-lg);
    line-height: var(--leading-body);
    color: #94A3B8;
    margin: 0;
    max-width: 42ch;
}

/* A short Nova Blue rule under the headline — one accent, doing one job. */
.ns-auth__rule {
    width: 56px;
    height: 3px;
    border-radius: var(--radius-full);
    background: var(--nova-blue);
    margin: var(--space-6) 0;
}

.ns-auth__notice {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-body-sm);
    color: #64748B;
}

/* --- Form panel -------------------------------------------------------- */

.ns-auth__formpanel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-8) var(--space-4);
    background: var(--ns-bg-surface);
}

@media (min-width: 1024px) {
    .ns-auth__formpanel { padding: var(--space-16) var(--space-12); }
}

.ns-auth__form {
    width: 100%;
    max-width: 380px;
}

/*
 * The compact brand, shown only where the brand panel is not. Without it a
 * narrow screen would open on an unlabelled form, which is disorienting on a
 * page whose whole job is proving you are in the right place.
 */
.ns-auth__compactbrand {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-8);
}

@media (min-width: 1024px) {
    .ns-auth__compactbrand { display: none; }
}

.ns-auth__compactbrand img { height: 36px; width: auto; border-radius: var(--radius-sm); }

.ns-auth__compactbrand span {
    font-size: var(--text-h4);
    font-weight: var(--weight-semibold);
}

.ns-auth__title {
    margin: 0 0 var(--space-2);
    color: var(--ns-text);
    letter-spacing: -0.01em;
}

.ns-auth__subtitle {
    color: var(--ns-text-muted);
    margin: 0 0 var(--space-8);
}

.ns-auth__footer {
    margin-top: var(--space-4);
}

.ns-auth__legal {
    margin-top: var(--space-12);
    font-size: var(--text-caption);
    color: var(--ns-text-muted);
}

/* --- Password reveal --------------------------------------------------- */

.ns-input-wrap { position: relative; }

/* Room for the button, so a long password never runs underneath it. */
.ns-input-wrap .ns-input { padding-right: 48px; }

.ns-input-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 0;
    padding: 0;
    color: var(--ns-text-muted);
    cursor: pointer;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    transition: color var(--anim-fast);
}

.ns-input-toggle:hover { color: var(--ns-text); }

/*
 * "Touch targets minimum 44x44px". A text link is naturally ~20px tall, so the
 * hit area is padded out to 44 without moving the text.
 */
.ns-auth__footer a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--space-3);
    font-size: var(--text-body-sm);
    color: var(--nova-blue);
    text-decoration: none;
}

.ns-auth__footer a:hover { text-decoration: underline; }

/* ==========================================================================
   Bootstrap bridge
   --------------------------------------------------------------------------
   Bootstrap 4 is still loaded for the toasts and the grid. These rules stop it
   fighting the tokens INSIDE .ns-scope only, so nothing here can reach the
   rest of the panel while the system is on trial.
   ========================================================================== */

.ns-scope .form-control {
    height: var(--control-lg);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-body);
    color: var(--ns-text);
    background-color: var(--ns-bg-surface);
    border: 1px solid var(--ns-border-strong);
    border-radius: var(--radius-md);
}

/*
 * Filter bars use .form-control-sm deliberately — they are secondary chrome and
 * should not stand as tall as a primary form field. Forcing every one of them
 * to 48px clipped the text inside filter selects across the panel.
 */
.ns-scope .form-control-sm {
    height: var(--control-sm);
    padding: 0 var(--space-3);
    font-size: var(--text-body-sm);
    border-radius: var(--radius-sm);
}

/*
 * A <select> is not an <input>, and treating them alike clips the text.
 *
 * A fixed 48px height with 12px of vertical padding leaves a 22px content box.
 * An input survives that — the browser centres its value regardless — but a
 * select renders its selected option INSIDE that box, and a 16px line at the
 * inherited 1.6 line-height needs about 26px. The descenders go first, so it
 * reads as a rendering fault rather than a sizing one.
 *
 * The height alone does the centring, so the vertical padding comes off and
 * line-height is returned to normal. Horizontal padding stays, with extra on
 * the right for the arrow the browser draws itself.
 */
.ns-scope select.form-control {
    padding-top: 0;
    padding-bottom: 0;
    padding-right: var(--space-8);
    line-height: normal;
}

.ns-scope select.form-control-sm {
    padding-top: 0;
    padding-bottom: 0;
    padding-right: var(--space-6);
    line-height: normal;
}

.ns-scope .form-control:focus {
    color: var(--ns-text);
    background-color: var(--ns-bg-surface);
    border-color: var(--nova-blue);
    box-shadow: inset 0 0 0 1px var(--nova-blue);
}

/*
 * The other guest screens — 2FA, forgot password, reset password — have not
 * been converted to .ns-btn yet. Without this they would keep Bootstrap's
 * default blue next to Nova Blue inputs, which looks like a mistake rather
 * than a page awaiting conversion.
 */
.ns-scope .btn-primary {
    height: var(--control-lg);
    padding: 0 var(--space-6);
    font-family: var(--font-sans);
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    background-color: var(--nova-blue);
    border-color: var(--nova-blue);
    border-radius: var(--radius-md);
}

.ns-scope .btn-primary:hover,
.ns-scope .btn-primary:focus {
    background-color: var(--nova-blue-hover);
    border-color: var(--nova-blue-hover);
}

.ns-scope .btn-primary:active { background-color: var(--nova-blue-active); }

.ns-scope label { font-size: var(--text-body-sm); font-weight: var(--weight-medium); }

.ns-scope .alert { border-radius: var(--radius-md); font-size: var(--text-body-sm); }
.ns-scope .alert-danger { background: #FEE2E2; color: #B91C1C; border-color: #FECACA; }
.ns-scope .alert-success { background: #DCFCE7; color: #15803D; border-color: #BBF7D0; }

/* ==========================================================================
   Legacy guest classes — TEMPORARY
   --------------------------------------------------------------------------
   Only the sign-in view has been converted to the .ns-* components. The 2FA,
   forgot-password and reset-password views still use .dt-guest__* class names
   that the layout no longer defines, which would leave their headings at the
   browser default — a 32px left-aligned h1 wrapping across two lines, next to
   a card built to the design system.

   Mapping them here keeps the whole guest area coherent while only one view is
   genuinely converted. Delete this block once the other three are done.
   ========================================================================== */

.ns-scope .dt-guest__title {
    font-size: var(--text-h3);
    line-height: var(--leading-heading);
    font-weight: var(--weight-semibold);
    text-align: center;
    margin: 0 0 var(--space-1);
}

.ns-scope .dt-guest__subtitle {
    font-size: var(--text-body-sm);
    line-height: var(--leading-tight);
    color: var(--ns-text-muted);
    text-align: center;
    margin: 0 0 var(--space-6);
}

/* Footer links on the unconverted views: colour, and a 44px touch target. */
.ns-scope .text-center a.small {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--space-3);
    color: var(--nova-blue);
    font-size: var(--text-body-sm);
}

/* ==========================================================================
   App shell — signed-in panel
   --------------------------------------------------------------------------
   The shell's own CSS lives inline in admin/layout/app.blade.php, ~200 lines
   of it, and is shared by every screen. Rewriting that to use .ns-* classes
   would mean touching thirty views in one go.

   So this maps the design system onto the class names that are ALREADY there.
   Every page is upgraded at once, nothing else has to change, and the day the
   views are converted this block simply gets deleted. It loads after the
   inline styles, which is the only reason it wins.
   ========================================================================== */

.ns-scope .dt-sidebar {
    width: var(--sidebar-width);
    background: var(--nova-dark);
    border-right: 1px solid rgba(255, 255, 255, 0.06);
}

/*
 * Sidebar scrollbar — hidden until you are actually in the sidebar.
 *
 * The default one is a wide light gutter against Nova Dark, so it reads as a
 * seam down the middle of the chrome rather than as a control. It also sits
 * there permanently on a nav that only overflows on a short window.
 *
 * Hidden by default, a slim dark one on hover. Removing it ENTIRELY was
 * tempting and is one line — but then a short window silently hides the last
 * few nav items with nothing to suggest there is more, and the person who
 * loses "Settings" has no way to know it exists. Revealing it on hover keeps
 * the chrome clean without lying about the content.
 *
 * To hide it in every state, drop the :hover rules below.
 */
.ns-scope .dt-sidebar {
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* legacy Edge */
}

.ns-scope .dt-sidebar::-webkit-scrollbar {
    width: 0;
    height: 0;
}

.ns-scope .dt-sidebar:hover { scrollbar-width: thin; }

.ns-scope .dt-sidebar:hover::-webkit-scrollbar { width: 6px; }

.ns-scope .dt-sidebar:hover::-webkit-scrollbar-track { background: transparent; }

.ns-scope .dt-sidebar:hover::-webkit-scrollbar-thumb {
    background: rgba(148, 163, 184, 0.35);
    border-radius: var(--radius-full);
}

.ns-scope .dt-sidebar:hover::-webkit-scrollbar-thumb:hover {
    background: rgba(148, 163, 184, 0.55);
}

.ns-scope .dt-sidebar__brand {
    height: var(--navbar-height);
    padding: 0 var(--space-4);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.ns-scope .dt-sidebar__section {
    padding: var(--space-6) var(--space-4) var(--space-2);
    font-size: 11px;
    font-weight: var(--weight-semibold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #64748B;
}

.ns-scope .dt-sidebar__nav a {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    color: #94A3B8;
    font-size: var(--text-body-sm);
    font-weight: var(--weight-medium);
    text-decoration: none;
    transition: background-color var(--anim-fast), color var(--anim-fast);
}

.ns-scope .dt-sidebar__nav a i {
    width: 20px;
    font-size: 16px;
    text-align: center;
}

.ns-scope .dt-sidebar__nav a:hover {
    background: rgba(255, 255, 255, 0.04);
    color: #E2E8F0;
}

/*
 * "Nova Blue left border (3px) + light blue background", per the document.
 *
 * Drawn as an INSET SHADOW, not a border — which is how the shell already did
 * it, in the old pink accent. Worth matching rather than fighting: a shadow
 * costs no layout, so the label does not shift 3px sideways when a link
 * becomes active. Overriding the border alone left the pink line in place,
 * because there was never a border to override.
 */
.ns-scope .dt-sidebar__nav a.active {
    background: rgba(37, 99, 235, 0.16);
    box-shadow: inset 3px 0 0 var(--nova-blue);
    color: #FFFFFF;
}

.ns-scope .dt-topbar {
    height: var(--navbar-height);
    left: var(--sidebar-width);
    background: var(--ns-bg-surface);
    border-bottom: 1px solid var(--ns-border);
    box-shadow: none;
    padding: 0 var(--space-6);
}

.ns-scope .dt-content {
    padding: calc(var(--navbar-height) + var(--space-8)) var(--space-8) var(--space-16);
    margin-left: var(--sidebar-width);
    max-width: none;
}

@media (max-width: 991.98px) {
    .ns-scope .dt-topbar { left: 0; }
    .ns-scope .dt-content {
        margin-left: 0;
        padding: calc(var(--navbar-height) + var(--space-6)) var(--space-4) var(--space-12);
    }
}

.ns-scope .dt-card {
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.ns-scope .dt-page-title {
    font-size: var(--text-h2);
    line-height: var(--leading-h2);
    font-weight: var(--weight-semibold);
    letter-spacing: -0.01em;
    margin: 0;
}

.ns-scope .dt-avatar {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    object-fit: cover;
}

/*
 * Font Awesome selects its FACE by weight — Solid is 900, Regular is 400.
 * Any utility class that sets font-weight on an <i> silently drops it to a
 * face that has no such glyph, and the icon renders as an empty box. That is
 * exactly what .ns-caption (500) did to every chevron on the dashboard.
 *
 * Pinning the weight here fixes it once, for every icon, rather than forbidding
 * a class from landing on an <i> and hoping everyone remembers.
 */
.ns-scope .fa-solid,
.ns-scope .fas { font-weight: 900; }

.ns-scope .fa-regular,
.ns-scope .far { font-weight: 400; }

.ns-scope .fa-brands,
.ns-scope .fab { font-weight: 400; }

/* --- Collapsed sidebar -------------------------------------------------
   240px -> 64px, both from the design document.

   Driven by ONE class on <body>, so the sidebar, the topbar's left edge and
   the content margin can never disagree about how wide the rail currently is.
   Three independent widths is how a collapsed sidebar ends up with a 176px
   gap beside it.

   Desktop only. Below lg the sidebar is already an off-canvas drawer, and a
   64px rail permanently eating a phone screen would be worse than either.
   ---------------------------------------------------------------------- */

.ns-scope .dt-sidebar,
.ns-scope .dt-topbar,
.ns-scope .dt-content {
    transition: width var(--anim-base), left var(--anim-base), margin-left var(--anim-base);
}

@media (min-width: 992px) {
    .ns-collapsed .dt-sidebar { width: var(--sidebar-collapsed); }
    .ns-collapsed .dt-topbar { left: var(--sidebar-collapsed); }
    .ns-collapsed .dt-content { margin-left: var(--sidebar-collapsed); }

    /* Labels and section headings go; icons stay and centre themselves. */
    .ns-collapsed .dt-sidebar__nav a span,
    .ns-collapsed .dt-sidebar__section { display: none; }

    .ns-collapsed .dt-sidebar__nav a {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    /* The 3px marker would sit hard against a centred icon and read as a
       stray line, so the whole tile is tinted instead. */
    .ns-collapsed .dt-sidebar__nav a.active {
        background: rgba(37, 99, 235, 0.24);
        box-shadow: none;
    }

    .ns-collapsed .dt-sidebar__brand { justify-content: center; padding: 0; }
    .ns-collapsed .dt-sidebar__brand img { max-width: 32px; }

    /*
     * A gap where each section heading used to be. Without it the nav becomes
     * one undifferentiated column of icons and the grouping — which is the
     * only thing making 20 items navigable — is lost entirely.
     */
    .ns-collapsed .dt-sidebar__nav { margin-top: var(--space-4); }

    /*
     * A collapsed rail is unusable without labels — an icon alone is a guess,
     * made by someone trying to get work done. They are supplied as native
     * `title` attributes, set by JS on collapse and removed on expand.
     *
     * A CSS ::after tooltip was the first attempt and cannot work here: the
     * sidebar has to scroll vertically for twenty items, and an element that
     * scrolls on one axis clips the other. `overflow: visible` alongside
     * `overflow-y: auto` does not escape that — per spec the visible axis
     * computes to auto, which bought a stray horizontal scrollbar AND left the
     * labels clipped anyway.
     */
    .ns-collapsed .dt-sidebar {
        overflow-y: auto;
        overflow-x: hidden;
    }
}

.ns-collapse-btn {
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-md);
    background: var(--ns-bg-surface);
    color: var(--ns-text-muted);
    cursor: pointer;
    transition: color var(--anim-fast), border-color var(--anim-fast);
}

.ns-collapse-btn:hover { color: var(--nova-blue); border-color: var(--nova-blue); }

@media (min-width: 992px) {
    .ns-collapse-btn { display: inline-flex; }
}

/* --- Tables ------------------------------------------------------------ */

.ns-scope .table { margin-bottom: 0; color: var(--ns-text); }

.ns-scope .table thead th {
    background: var(--ns-bg-subtle);
    border-top: 0;
    border-bottom: 1px solid var(--ns-border);
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ns-text-muted);
    white-space: nowrap;
}

.ns-scope .table tbody td {
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--ns-border);
    font-size: var(--text-body-sm);
    vertical-align: middle;
}

.ns-scope .table-hover tbody tr:hover { background: var(--ns-bg-subtle); }

.ns-scope .badge {
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
    font-size: var(--text-caption);
    font-weight: var(--weight-medium);
}

/* ==========================================================================
   Dashboard
   ========================================================================== */

.ns-grid { display: grid; gap: var(--space-6); }

@media (min-width: 768px) {
    .ns-grid--kpi { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1280px) {
    .ns-grid--kpi { grid-template-columns: repeat(4, 1fr); }
    .ns-grid--split { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
}

.ns-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-8);
}

.ns-page-head__meta { color: var(--ns-text-muted); font-size: var(--text-body-sm); margin: var(--space-1) 0 0; }

/* --- KPI card ---------------------------------------------------------- */

.ns-kpi {
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--anim-base), transform var(--anim-base);
}

.ns-kpi:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }

.ns-kpi__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.ns-kpi__label {
    font-size: var(--text-body-sm);
    font-weight: var(--weight-medium);
    color: var(--ns-text-muted);
}

.ns-kpi__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: #DBEAFE;
    color: var(--nova-blue);
    flex: none;
}

.ns-kpi__icon--green  { background: #DCFCE7; color: #15803D; }
.ns-kpi__icon--orange { background: #FFEDD5; color: #C2410C; }
.ns-kpi__icon--slate  { background: var(--gray-100); color: var(--gray-600); }

/*
 * Tabular figures. Without this the digits are proportional, so a number that
 * updates on refresh jiggles its own width — small, but it is the difference
 * between a dashboard that feels engineered and one that does not.
 */
.ns-kpi__value {
    font-size: 30px;
    line-height: 1.15;
    font-weight: var(--weight-bold);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.ns-kpi__value small { font-size: 16px; font-weight: var(--weight-medium); color: var(--ns-text-muted); }

.ns-kpi__foot {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    font-size: var(--text-body-sm);
    color: var(--ns-text-muted);
}

.ns-delta {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
}

.ns-delta--up   { background: #DCFCE7; color: #15803D; }
.ns-delta--down { background: #FEE2E2; color: #B91C1C; }
.ns-delta--flat { background: var(--gray-100); color: var(--gray-600); }

/* --- Panels ------------------------------------------------------------ */

.ns-panel {
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.ns-panel__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-6);
    border-bottom: 1px solid var(--ns-border);
}

.ns-panel__title { font-size: var(--text-h4); font-weight: var(--weight-semibold); margin: 0; }
.ns-panel__body { padding: var(--space-6); }
.ns-panel__body--flush { padding: 0; }

/* --- Chart ------------------------------------------------------------- */

.ns-chart { display: block; width: 100%; height: auto; }

.ns-chart__legend {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-left: auto;
    font-size: var(--text-body-sm);
    color: var(--ns-text-muted);
}

.ns-chart__key {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: var(--radius-sm);
    margin-right: var(--space-2);
    vertical-align: middle;
}

/* --- Attention list ---------------------------------------------------- */

.ns-attention { list-style: none; margin: 0; padding: 0; }

.ns-attention li + li { border-top: 1px solid var(--ns-border); }

.ns-attention a {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-6);
    color: var(--ns-text);
    text-decoration: none;
    transition: background-color var(--anim-fast);
}

.ns-attention a:hover { background: var(--ns-bg-subtle); color: var(--ns-text); }

.ns-attention__label { flex: 1; font-size: var(--text-body-sm); }

.ns-attention__count {
    font-size: var(--text-body);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
}

/* A settled queue is good news and should look calm, not like a zero on a
   warning badge. */
.ns-attention__count--zero { color: var(--ns-text-muted); font-weight: var(--weight-regular); }

.ns-attention__dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    flex: none;
    background: var(--gray-300);
}

.ns-attention__dot--primary { background: var(--nova-blue); }
.ns-attention__dot--warning { background: var(--spark-orange); }
.ns-attention__dot--danger  { background: var(--spark-red); }

/* --- Misc -------------------------------------------------------------- */

.ns-stack { display: grid; gap: var(--space-6); }

.ns-inline-stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: var(--space-3) 0;
    font-size: var(--text-body-sm);
}

.ns-inline-stat + .ns-inline-stat { border-top: 1px solid var(--ns-border); }

.ns-inline-stat__value { font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }

.ns-empty {
    padding: var(--space-12) var(--space-6);
    text-align: center;
    color: var(--ns-text-muted);
    font-size: var(--text-body-sm);
}

/* --- List screens ------------------------------------------------------ */

.ns-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-6);
    background: var(--ns-bg-surface);
    border: 1px solid var(--ns-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    margin-bottom: var(--space-6);
}

.ns-toolbar__field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 180px; }
.ns-toolbar__field--grow { flex: 1 1 260px; }

.ns-toolbar__label {
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ns-text-muted);
}

.ns-toolbar__actions { display: flex; gap: var(--space-2); margin-left: auto; }

/* A row of small square icon buttons — edit, delete, reorder. */
.ns-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--control-sm);
    height: var(--control-sm);
    padding: 0;
    border: 1px solid var(--ns-border-strong);
    border-radius: var(--radius-md);
    background: var(--ns-bg-surface);
    color: var(--ns-text-muted);
    cursor: pointer;
    transition: color var(--anim-fast), border-color var(--anim-fast), background-color var(--anim-fast);
}

.ns-icon-btn:hover { color: var(--nova-blue); border-color: var(--nova-blue); background: #EFF6FF; }
.ns-icon-btn--danger:hover { color: var(--spark-red); border-color: var(--spark-red); background: #FEF2F2; }

.ns-icon-btn:disabled,
.ns-icon-btn[disabled] { opacity: 0.35; cursor: not-allowed; }
.ns-icon-btn:disabled:hover { color: var(--ns-text-muted); border-color: var(--ns-border-strong); background: var(--ns-bg-surface); }

.ns-actions { display: inline-flex; gap: var(--space-2); justify-content: flex-end; }
.ns-actions form { display: inline-flex; margin: 0; }

/* Thumbnail + name + slug in one cell, so a row scans in one glance rather
   than three columns of near-empty space. */
.ns-media { display: flex; align-items: center; gap: var(--space-3); }

.ns-thumb {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    object-fit: cover;
    flex: none;
    background: var(--ns-bg-subtle);
}

.ns-thumb--empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-400);
}

.ns-cell-title { font-weight: var(--weight-medium); }
.ns-cell-sub { font-size: var(--text-caption); color: var(--ns-text-muted); }

/*
 * A status pill that is also a button. It reads as state, not as an action,
 * which is right: the admin is looking at what something IS, and only
 * sometimes changing it.
 */
.ns-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    border: 0;
    border-radius: var(--radius-full);
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
    cursor: pointer;
    background: var(--gray-200);
    color: #374151;
    transition: filter var(--anim-fast);
}

.ns-pill:hover { filter: brightness(0.96); }
.ns-pill--on { background: #DCFCE7; color: #15803D; }
.ns-pill--off { background: var(--gray-200); color: var(--gray-600); }
.ns-pill__dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; }

.ns-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    padding: 0 var(--space-2);
    height: 22px;
    border-radius: var(--radius-full);
    background: var(--ns-bg-subtle);
    font-size: var(--text-caption);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--ns-text-muted);
}

.ns-note {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background: #FEF3C7;
    color: #B45309;
    font-size: var(--text-body-sm);
    margin-bottom: var(--space-6);
}

/* ==========================================================================
   Reduced motion
   --------------------------------------------------------------------------
   Every transition in this file is decorative. Honouring the OS preference
   costs nothing and the alternative is making some people feel unwell.
   ========================================================================== */

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

    .ns-card--interactive:hover { transform: none; }
}
