/* ===================================================================
   Mobile Shop Inventory Management System
   Application theme, layered on top of Bootstrap 5.3.

   Palette (from the specification):
     sidebar   dark navy
     primary   purple
     positive  green
     negative  red
     content   white / light
   =================================================================== */

:root {
    /* Brand */
    --ms-primary:        #6d28d9;
    --ms-primary-dark:   #5b21b6;
    --ms-primary-light:  #8b5cf6;
    --ms-primary-soft:   #f5f3ff;
    --ms-primary-border: #ddd6fe;

    /* Sidebar */
    --ms-sidebar-bg:     #111c3a;
    --ms-sidebar-bg-alt: #0c1530;
    --ms-sidebar-text:   #b8c2dc;
    --ms-sidebar-active: #ffffff;
    --ms-sidebar-hover:  rgba(255, 255, 255, .07);
    --ms-sidebar-width:  268px;
    --ms-sidebar-collapsed: 76px;

    /* Semantic */
    --ms-positive:       #059669;
    --ms-positive-soft:  #ecfdf5;
    --ms-negative:       #dc2626;
    --ms-negative-soft:  #fef2f2;
    --ms-warning:        #d97706;
    --ms-warning-soft:   #fffbeb;
    --ms-info:           #0284c7;
    --ms-info-soft:      #f0f9ff;

    /* Surfaces */
    --ms-body-bg:        #f6f7fb;
    --ms-surface:        #ffffff;
    --ms-border:         #e5e7eb;
    --ms-border-strong:  #d1d5db;
    --ms-text:           #111827;
    --ms-text-muted:     #6b7280;
    --ms-text-subtle:    #9ca3af;

    /* Shape */
    --ms-radius:         .625rem;
    --ms-radius-sm:      .375rem;
    --ms-radius-lg:      1rem;
    --ms-shadow-sm:      0 1px 2px rgba(16, 24, 40, .05);
    --ms-shadow:         0 1px 3px rgba(16, 24, 40, .1), 0 1px 2px rgba(16, 24, 40, .06);
    --ms-shadow-lg:      0 10px 24px rgba(16, 24, 40, .08);

    --ms-topbar-height:  62px;

    /* Text ON a soft badge or alert. These need their own tokens because a
       dark green that reads well on a pale green tint is invisible on a dark
       one - the background flips, so the text has to flip with it. */
    --ms-badge-success:  #047857;
    --ms-badge-danger:   #b91c1c;
    --ms-badge-warning:  #b45309;
    --ms-badge-info:     #0369a1;
    --ms-badge-secondary:    #4b5563;
    --ms-badge-secondary-bg: #f3f4f6;

    --ms-alert-success: #065f46;  --ms-alert-success-border: #a7f3d0;
    --ms-alert-danger:  #991b1b;  --ms-alert-danger-border:  #fecaca;
    --ms-alert-warning: #92400e;  --ms-alert-warning-border: #fde68a;
    --ms-alert-info:    #075985;  --ms-alert-info-border:    #bae6fd;

    --ms-thead-bg:       #fafbfc;
    --ms-row-hover:      #fafbff;

    color-scheme: light;
}

/* -------------------------------------------------------------------
   Dark mode

   Only the colour tokens are redefined - every rule below already reads
   them, so nothing else in this stylesheet needs to know dark mode exists.

   Three states, deliberately:
     - data-theme="dark"   the person chose dark
     - data-theme="light"  the person chose light, so the OS is overruled
     - nothing set         follow the OS

   The soft semantic colours are darkened rather than reused: #ecfdf5 on a
   dark surface is a glaring white block, not a gentle tint.
   ------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --ms-body-bg:        #0f1420;
        --ms-surface:        #171e2e;
        --ms-border:         #2a3446;
        --ms-border-strong:  #3a4658;
        --ms-text:           #e8ecf4;
        --ms-text-muted:     #9aa6bd;
        --ms-text-subtle:    #6f7b93;

        --ms-sidebar-bg:     #0b1120;
        --ms-sidebar-bg-alt: #070c18;

        --ms-positive-soft:  #06281d;
        --ms-negative-soft:  #2d1315;
        --ms-warning-soft:   #2b2008;
        --ms-info-soft:      #07253a;

        /* Light text on the dark tints above. Without these the badges and
           alerts keep their dark ink and become unreadable - dark on dark. */
        --ms-badge-success:  #6ee7b7;
        --ms-badge-danger:   #fca5a5;
        --ms-badge-warning:  #fcd34d;
        --ms-badge-info:     #7dd3fc;
        --ms-badge-secondary:    #cbd5e1;
        --ms-badge-secondary-bg: #232b3a;

        --ms-alert-success: #a7f3d0;  --ms-alert-success-border: #0d5c43;
        --ms-alert-danger:  #fecaca;  --ms-alert-danger-border:  #7f2226;
        --ms-alert-warning: #fde68a;  --ms-alert-warning-border: #6b4c0a;
        --ms-alert-info:    #bae6fd;  --ms-alert-info-border:    #0b4a6f;

        --ms-thead-bg:       #1c2436;
        --ms-row-hover:      #1e2739;

        --ms-shadow-sm:      0 1px 2px rgba(0, 0, 0, .5);
        --ms-shadow:         0 1px 3px rgba(0, 0, 0, .6), 0 1px 2px rgba(0, 0, 0, .4);
        --ms-shadow-lg:      0 10px 24px rgba(0, 0, 0, .55);

        color-scheme: dark;
    }
}

:root[data-theme="dark"] {
    --ms-body-bg:        #0f1420;
    --ms-surface:        #171e2e;
    --ms-border:         #2a3446;
    --ms-border-strong:  #3a4658;
    --ms-text:           #e8ecf4;
    --ms-text-muted:     #9aa6bd;
    --ms-text-subtle:    #6f7b93;

    --ms-sidebar-bg:     #0b1120;
    --ms-sidebar-bg-alt: #070c18;

    --ms-positive-soft:  #06281d;
    --ms-negative-soft:  #2d1315;
    --ms-warning-soft:   #2b2008;
    --ms-info-soft:      #07253a;

    /* Keep in step with the prefers-color-scheme block above - CSS cannot
       share one declaration list between a media query and a plain selector. */
    --ms-badge-success:  #6ee7b7;
    --ms-badge-danger:   #fca5a5;
    --ms-badge-warning:  #fcd34d;
    --ms-badge-info:     #7dd3fc;
    --ms-badge-secondary:    #cbd5e1;
    --ms-badge-secondary-bg: #232b3a;

    --ms-alert-success: #a7f3d0;  --ms-alert-success-border: #0d5c43;
    --ms-alert-danger:  #fecaca;  --ms-alert-danger-border:  #7f2226;
    --ms-alert-warning: #fde68a;  --ms-alert-warning-border: #6b4c0a;
    --ms-alert-info:    #bae6fd;  --ms-alert-info-border:    #0b4a6f;

    --ms-thead-bg:       #1c2436;
    --ms-row-hover:      #1e2739;

    --ms-shadow-sm:      0 1px 2px rgba(0, 0, 0, .5);
    --ms-shadow:         0 1px 3px rgba(0, 0, 0, .6), 0 1px 2px rgba(0, 0, 0, .4);
    --ms-shadow-lg:      0 10px 24px rgba(0, 0, 0, .55);

    color-scheme: dark;
}

/* -------------------------------------------------------------------
   Bootstrap in dark

   Bootstrap 5.3 carries its own dark palette behind [data-bs-theme="dark"],
   and theme.js sets that attribute alongside data-theme. That covers tables,
   dropdowns, modals and form controls properly - far better than overriding
   each one here, which is what left table text near-black on a dark card.

   Only the handful of places where Bootstrap's surface should be OUR surface
   are pinned below, so a card and the table inside it are the same colour.
   ------------------------------------------------------------------- */

[data-bs-theme="dark"] {
    --bs-body-bg:        var(--ms-body-bg);
    --bs-body-color:     var(--ms-text);
    --bs-border-color:   var(--ms-border);
    --bs-secondary-color: var(--ms-text-muted);
}

[data-bs-theme="dark"] .table {
    --bs-table-bg:    var(--ms-surface);
    --bs-table-color: var(--ms-text);
}

[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select,
[data-bs-theme="dark"] .list-group-item,
[data-bs-theme="dark"] .modal-content,
[data-bs-theme="dark"] .dropdown-menu {
    background-color: var(--ms-surface);
    color: var(--ms-text);
    border-color: var(--ms-border);
}

[data-bs-theme="dark"] .form-control::placeholder { color: var(--ms-text-subtle); }
[data-bs-theme="dark"] .table-active > *          { background-color: rgba(255, 255, 255, .05); }
[data-bs-theme="dark"] .bg-light                  { background-color: var(--ms-surface) !important; }
[data-bs-theme="dark"] .text-muted                { color: var(--ms-text-muted) !important; }
[data-bs-theme="dark"] .btn-light                 { background-color: var(--ms-surface); color: var(--ms-text); border-color: var(--ms-border); }

/* The printed invoice is always on white paper. */
@media print {
    :root, :root[data-theme="dark"] {
        --ms-body-bg: #ffffff;
        --ms-surface: #ffffff;
        --ms-text:    #000000;
        --ms-border:  #cccccc;
        color-scheme: light;
    }
}

/* -------------------------------------------------------------------
   Base
   ------------------------------------------------------------------- */

body {
    background-color: var(--ms-body-bg);
    color: var(--ms-text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    /* 15px base: dense financial tables stay readable without shrinking text
       below an accessible size. */
    font-size: .9375rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

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

a:hover {
    color: var(--ms-primary-dark);
    text-decoration: underline;
}

/* Visible focus everywhere - never remove the outline without a replacement. */
:focus-visible {
    outline: 3px solid var(--ms-primary-light);
    outline-offset: 2px;
    border-radius: var(--ms-radius-sm);
}

/* Keyboard users can jump straight to the content. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 2000;
    padding: .75rem 1.25rem;
    background: var(--ms-primary);
    color: #fff;
    border-radius: 0 0 var(--ms-radius) 0;
    font-weight: 600;
}

.skip-link:focus {
    left: 0;
    color: #fff;
}

/* Numeric columns: tabular figures so digits align in a money column. */
.num,
.text-money,
td.num,
th.num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
    text-align: right;
    white-space: nowrap;
}

.mono {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: .875em;
    letter-spacing: -.01em;
}

.text-positive { color: var(--ms-positive) !important; }
.text-negative { color: var(--ms-negative) !important; }
.text-muted-2  { color: var(--ms-text-subtle) !important; }

/* -------------------------------------------------------------------
   App shell
   ------------------------------------------------------------------- */

.app-shell {
    display: flex;
    min-height: 100vh;
}

/* --- Sidebar --- */

.app-sidebar {
    width: var(--ms-sidebar-width);
    flex: 0 0 var(--ms-sidebar-width);
    background: linear-gradient(180deg, var(--ms-sidebar-bg) 0%, var(--ms-sidebar-bg-alt) 100%);
    color: var(--ms-sidebar-text);
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 1040;
    transition: transform .22s ease, width .22s ease;
    overflow: hidden;
}

.app-sidebar__brand {
    display: flex;
    align-items: center;
    gap: .7rem;
    height: var(--ms-topbar-height);
    padding: 0 1.15rem;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
    flex-shrink: 0;
}

.app-sidebar__logo {
    width: 36px;
    height: 36px;
    border-radius: var(--ms-radius-sm);
    background: var(--ms-primary);
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 1.15rem;
    flex-shrink: 0;
}

.app-sidebar__title {
    color: #fff;
    font-weight: 650;
    font-size: .95rem;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-sidebar__subtitle {
    font-size: .7rem;
    color: var(--ms-sidebar-text);
    opacity: .75;
    white-space: nowrap;
}

.app-sidebar__nav {
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: .85rem .7rem 1.5rem;
}

/* Thin scrollbar so the dark sidebar does not get a bright native bar. */
.app-sidebar__nav::-webkit-scrollbar { width: 6px; }
.app-sidebar__nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .16);
    border-radius: 3px;
}

.nav-section {
    padding: 1rem .75rem .35rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: rgba(184, 194, 220, .55);
    white-space: nowrap;
}

.nav-section:first-child { padding-top: .25rem; }

.app-sidebar .nav-link {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .62rem .78rem;
    margin-bottom: .12rem;
    border-radius: var(--ms-radius-sm);
    color: var(--ms-sidebar-text);
    font-size: .875rem;
    font-weight: 500;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease;
    /* 44px minimum touch target */
    min-height: 44px;
}

.app-sidebar .nav-link:hover {
    background: var(--ms-sidebar-hover);
    color: #fff;
    text-decoration: none;
}

.app-sidebar .nav-link.active {
    background: var(--ms-primary);
    color: var(--ms-sidebar-active);
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(109, 40, 217, .35);
}

.app-sidebar .nav-link i {
    font-size: 1.05rem;
    width: 20px;
    text-align: center;
    flex-shrink: 0;
}

.nav-link__badge {
    margin-left: auto;
    background: var(--ms-negative);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    padding: .1rem .42rem;
    border-radius: 999px;
    min-width: 20px;
    text-align: center;
}

/* Module that exists in the roadmap but has not been built yet.
   Rendered as a <span>, so it is not focusable and cannot be clicked
   through to a 404. Dimmed AND labelled - the state is never conveyed
   by colour alone. */
.app-sidebar .nav-link.is-upcoming {
    opacity: .38;
    cursor: default;
    -webkit-user-select: none;
    user-select: none;
}

.app-sidebar .nav-link.is-upcoming:hover {
    background: transparent;
    color: var(--ms-sidebar-text);
}

.nav-link__soon {
    margin-left: auto;
    background: rgba(255, 255, 255, .1);
    color: rgba(255, 255, 255, .75);
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: .12rem .4rem;
    border-radius: 4px;
    flex-shrink: 0;
}

.sidebar-collapsed .nav-link__soon { display: none; }

/* Name and contact on one line, wrapping only if the sidebar is too narrow
   to hold both. */
.app-sidebar__footer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .25rem .6rem;
    padding: .8rem 1rem;
    border-top: 1px solid rgba(255, 255, 255, .08);
    font-size: .72rem;
    color: rgba(184, 194, 220, .6);
    flex-shrink: 0;
    overflow: hidden;
}

.app-sidebar__user {
    font-size: .82rem;
    font-weight: 600;
    color: #fff;
    text-overflow: ellipsis;
    overflow: hidden;
    min-width: 0;
}

.app-sidebar__whatsapp {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .75rem;
    color: #25d366;              /* WhatsApp green, recognised at a glance */
    text-decoration: none;
    white-space: nowrap;
}

.app-sidebar__whatsapp:hover,
.app-sidebar__whatsapp:focus-visible {
    color: #4ce88a;
    text-decoration: underline;
}

/* --- Main column --- */

.app-main {
    flex: 1;
    min-width: 0;                     /* lets wide tables scroll instead of pushing the layout */
    margin-left: var(--ms-sidebar-width);
    display: flex;
    flex-direction: column;
    transition: margin-left .22s ease;
}

.app-topbar {
    height: var(--ms-topbar-height);
    background: var(--ms-surface);
    border-bottom: 1px solid var(--ms-border);
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 0 1.25rem;
    position: sticky;
    top: 0;
    z-index: 1030;
}

.app-content {
    flex: 1;
    padding: 1.5rem 1.25rem 3rem;
}

/* Collapsed sidebar (desktop) */
.sidebar-collapsed .app-sidebar { width: var(--ms-sidebar-collapsed); flex-basis: var(--ms-sidebar-collapsed); }
.sidebar-collapsed .app-main    { margin-left: var(--ms-sidebar-collapsed); }

/* The whole brand text block goes, not just the two lines inside it: the
   wrapper is flex-grow, so leaving it in place ate the rail's width and
   pushed the logo off centre. */
.sidebar-collapsed .app-sidebar__brand-text,
.sidebar-collapsed .app-sidebar__title,
.sidebar-collapsed .app-sidebar__subtitle,
.sidebar-collapsed .nav-section,
.sidebar-collapsed .app-sidebar__footer,
.sidebar-collapsed .nav-link span,
.sidebar-collapsed .nav-link__badge { display: none; }

.sidebar-collapsed .app-sidebar .nav-link { justify-content: center; padding-inline: 0; }
.sidebar-collapsed .app-sidebar__brand    { justify-content: center; padding-inline: 0; }

/* -------------------------------------------------------------------
   Global search
   ------------------------------------------------------------------- */

.global-search {
    position: relative;
    flex: 1;
    max-width: 480px;
}

.global-search input {
    padding-left: 2.35rem;
    background: var(--ms-body-bg);
    border-color: transparent;
    border-radius: var(--ms-radius);
    height: 40px;
}

.global-search input:focus {
    background: var(--ms-surface);
    border-color: var(--ms-primary-light);
    box-shadow: 0 0 0 .2rem rgba(139, 92, 246, .18);
}

.global-search i {
    position: absolute;
    left: .85rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ms-text-subtle);
    pointer-events: none;
}

/* -------------------------------------------------------------------
   Cards & stats
   ------------------------------------------------------------------- */

.card {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius);
    box-shadow: var(--ms-shadow-sm);
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--ms-border);
    padding: .9rem 1.1rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
}

.card-header h2,
.card-header h3 {
    font-size: .95rem;
    font-weight: 650;
    margin: 0;
}

.card-body { padding: 1.1rem; }

.stat-card {
    position: relative;
    height: 100%;
    padding: 1.1rem 1.15rem;
    overflow: hidden;
}

.stat-card__label {
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .045em;
    text-transform: uppercase;
    color: var(--ms-text-muted);
    margin-bottom: .45rem;
}

.stat-card__value {
    font-size: 1.55rem;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    word-break: break-word;
}

.stat-card__meta {
    font-size: .78rem;
    color: var(--ms-text-muted);
    margin-top: .35rem;
}

.stat-card__icon {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 38px;
    height: 38px;
    border-radius: var(--ms-radius-sm);
    display: grid;
    place-items: center;
    font-size: 1.1rem;
}

.stat-icon--primary  { background: var(--ms-primary-soft);  color: var(--ms-primary); }
.stat-icon--positive { background: var(--ms-positive-soft); color: var(--ms-positive); }
.stat-icon--negative { background: var(--ms-negative-soft); color: var(--ms-negative); }
.stat-icon--warning  { background: var(--ms-warning-soft);  color: var(--ms-warning); }
.stat-icon--info     { background: var(--ms-info-soft);     color: var(--ms-info); }

/* Left accent stripe conveys the same meaning as the colour, for users who
   cannot distinguish red from green. Paired with a text label everywhere. */
.stat-card--positive { border-left: 3px solid var(--ms-positive); }
.stat-card--negative { border-left: 3px solid var(--ms-negative); }
.stat-card--warning  { border-left: 3px solid var(--ms-warning); }
.stat-card--primary  { border-left: 3px solid var(--ms-primary); }

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

.table-wrapper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table {
    margin-bottom: 0;
    font-size: .875rem;
}

.table > thead > tr > th {
    background: var(--ms-thead-bg);
    border-bottom: 1px solid var(--ms-border-strong);
    color: var(--ms-text-muted);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: .7rem .85rem;
    white-space: nowrap;
    vertical-align: middle;
}

.table > tbody > tr > td {
    padding: .72rem .85rem;
    vertical-align: middle;
    border-bottom: 1px solid var(--ms-border);
}

.table > tbody > tr:hover > td { background: var(--ms-row-hover); }
.table > tbody > tr:last-child > td { border-bottom: none; }

.table-empty {
    padding: 3rem 1.5rem;
    text-align: center;
    color: var(--ms-text-muted);
}

.table-empty i {
    font-size: 2.5rem;
    color: var(--ms-border-strong);
    display: block;
    margin-bottom: .75rem;
}

/* -------------------------------------------------------------------
   Badges
   ------------------------------------------------------------------- */

.badge-status {
    display: inline-block;
    padding: .26rem .58rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}

.badge-success   { background: var(--ms-positive-soft); color: var(--ms-badge-success); }
.badge-danger    { background: var(--ms-negative-soft); color: var(--ms-badge-danger); }
.badge-warning   { background: var(--ms-warning-soft);  color: var(--ms-badge-warning); }
.badge-info      { background: var(--ms-info-soft);     color: var(--ms-badge-info); }
.badge-secondary { background: var(--ms-badge-secondary-bg); color: var(--ms-badge-secondary); }
.badge-primary   { background: var(--ms-primary-soft);  color: var(--ms-primary-dark); }

/* -------------------------------------------------------------------
   Buttons & forms
   ------------------------------------------------------------------- */

.btn {
    border-radius: var(--ms-radius-sm);
    font-weight: 500;
    font-size: .875rem;
    padding: .5rem .95rem;
    /* Comfortable on a phone without looking oversized on a desktop. */
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
}

.btn-lg { min-height: 46px; font-size: .95rem; padding: .65rem 1.25rem; }
.btn-sm { min-height: 34px; font-size: .8rem;  padding: .35rem .7rem; }

.btn-primary {
    background-color: var(--ms-primary);
    border-color: var(--ms-primary);
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--ms-primary-dark);
    border-color: var(--ms-primary-dark);
}

.btn-outline-primary {
    color: var(--ms-primary);
    border-color: var(--ms-primary-border);
}

.btn-outline-primary:hover {
    background-color: var(--ms-primary);
    border-color: var(--ms-primary);
}

.btn:disabled,
.btn.disabled { opacity: .6; cursor: not-allowed; }

.form-label {
    font-size: .82rem;
    font-weight: 600;
    color: var(--ms-text);
    margin-bottom: .35rem;
}

.form-label .required { color: var(--ms-negative); margin-left: .15rem; }

.form-control,
.form-select {
    border-radius: var(--ms-radius-sm);
    border-color: var(--ms-border-strong);
    font-size: .9rem;
    padding: .5rem .75rem;
    min-height: 40px;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ms-primary-light);
    box-shadow: 0 0 0 .2rem rgba(139, 92, 246, .18);
}

.form-text {
    font-size: .78rem;
    color: var(--ms-text-muted);
}

.invalid-feedback { font-size: .8rem; }

/* Password field with a show/hide toggle */
.password-field { position: relative; }

.password-field .form-control { padding-right: 2.9rem; }

.password-toggle {
    position: absolute;
    right: .35rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: 0;
    color: var(--ms-text-muted);
    padding: .45rem .55rem;
    border-radius: var(--ms-radius-sm);
    line-height: 1;
    cursor: pointer;
}

.password-toggle:hover { color: var(--ms-primary); background: var(--ms-primary-soft); }

/* -------------------------------------------------------------------
   Auth pages
   ------------------------------------------------------------------- */

.auth-page {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1fr;
    background: var(--ms-body-bg);
}

@media (min-width: 992px) {
    .auth-page { grid-template-columns: 1.05fr .95fr; }
}

.auth-hero {
    display: none;
    background: linear-gradient(150deg, var(--ms-sidebar-bg) 0%, #2b1a6b 55%, var(--ms-primary-dark) 100%);
    color: #fff;
    padding: 3.5rem;
    flex-direction: column;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

@media (min-width: 992px) { .auth-hero { display: flex; } }

.auth-hero::after {
    /* Soft radial highlight; purely decorative. */
    content: "";
    position: absolute;
    width: 480px;
    height: 480px;
    right: -160px;
    top: -120px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(139, 92, 246, .35) 0%, transparent 68%);
    pointer-events: none;
}

.auth-hero__content { position: relative; z-index: 1; max-width: 460px; }

.auth-hero h1 {
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1.25;
    margin-bottom: 1rem;
}

.auth-hero p { color: rgba(255, 255, 255, .8); font-size: 1rem; }

.auth-feature {
    display: flex;
    align-items: flex-start;
    gap: .85rem;
    margin-top: 1.4rem;
}

.auth-feature i {
    font-size: 1.1rem;
    color: var(--ms-primary-light);
    margin-top: .15rem;
    flex-shrink: 0;
}

.auth-feature strong { display: block; font-weight: 600; font-size: .95rem; }
.auth-feature span   { color: rgba(255, 255, 255, .68); font-size: .85rem; }

.auth-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1.25rem 3rem;
}

.auth-card {
    width: 100%;
    max-width: 420px;
}

.auth-card__logo {
    width: 56px;
    height: 56px;
    border-radius: var(--ms-radius);
    background: var(--ms-primary);
    color: #fff;
    display: grid;
    place-items: center;
    font-size: 1.7rem;
    margin: 0 auto 1.1rem;
    box-shadow: 0 6px 18px rgba(109, 40, 217, .3);
}

.auth-card h1 {
    font-size: 1.45rem;
    font-weight: 700;
    text-align: center;
    margin-bottom: .3rem;
}

.auth-card__subtitle {
    text-align: center;
    color: var(--ms-text-muted);
    font-size: .9rem;
    margin-bottom: 1.6rem;
}

.auth-card__form {
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius-lg);
    box-shadow: var(--ms-shadow-lg);
    padding: 1.75rem;
}

.auth-card__footer {
    text-align: center;
    margin-top: 1.35rem;
    font-size: .82rem;
    color: var(--ms-text-muted);
}

/* Turnstile widget: let it size itself, but never overflow the card. */
.turnstile-wrapper {
    margin: 1rem 0 .25rem;
    min-height: 65px;
    display: flex;
    justify-content: center;
}

.turnstile-wrapper > div { max-width: 100%; }

/* -------------------------------------------------------------------
   Alerts & flash
   ------------------------------------------------------------------- */

.alert {
    border: 1px solid transparent;
    border-radius: var(--ms-radius-sm);
    font-size: .875rem;
    padding: .8rem 1rem;
    display: flex;
    align-items: flex-start;
    gap: .6rem;
}

.alert i { margin-top: .1rem; flex-shrink: 0; }

.alert-success { background: var(--ms-positive-soft); border-color: var(--ms-alert-success-border); color: var(--ms-alert-success); }
.alert-danger  { background: var(--ms-negative-soft); border-color: var(--ms-alert-danger-border); color: var(--ms-alert-danger); }
.alert-warning { background: var(--ms-warning-soft);  border-color: var(--ms-alert-warning-border); color: var(--ms-alert-warning); }
.alert-info    { background: var(--ms-info-soft);     border-color: var(--ms-alert-info-border); color: var(--ms-alert-info); }

/* -------------------------------------------------------------------
   GSMArena name search: the dropdown under the phone-name box.
   ------------------------------------------------------------------- */

.gsm-picker { position: relative; }

.gsm-picker__menu {
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    /* Above a Bootstrap modal backdrop, below a flash message. */
    z-index: 1060;
    max-height: 17rem;
    overflow-y: auto;
    background: var(--ms-surface);
    border: 1px solid var(--ms-border);
    border-radius: var(--ms-radius-sm);
    box-shadow: var(--ms-shadow-lg);
    padding: .25rem;
}

.gsm-picker__option {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    background: transparent;
    color: var(--ms-text);
    padding: .4rem .6rem;
    border-radius: calc(var(--ms-radius-sm) - 2px);
    font-size: .875rem;
    line-height: 1.3;
    cursor: pointer;
}

.gsm-picker__option:hover,
.gsm-picker__option.is-active {
    background: var(--ms-row-hover);
    color: var(--ms-text);
}

.gsm-picker__note {
    padding: .5rem .6rem;
    font-size: .8rem;
    color: var(--ms-text-muted);
}

/* A recessed panel inside a table or card - an expanded row, an inline form.
   Replaces Bootstrap's bg-light, which is a fixed near-white and blinds the
   content it holds once the dark theme is on. */
.ms-inset {
    background: var(--ms-thead-bg) !important;
}

/* A button sitting inside an alert.
   It borrows the alert's own text colour instead of picking one, so it stays
   readable in both themes. btn-outline-dark was used here originally and went
   invisible in dark mode - dark ink on a dark panel. */
.alert .btn-alert-action {
    color: currentColor;
    border: 1px solid currentColor;
    background: transparent;
    opacity: .85;
}

.alert .btn-alert-action:hover,
.alert .btn-alert-action:focus-visible {
    /* Deliberately NOT an inversion. Setting background:currentColor while
       also changing color makes both resolve to the same value and the label
       disappears. A faint wash of the alert's own colour is enough. */
    color: currentColor;
    background: color-mix(in srgb, currentColor 14%, transparent);
    opacity: 1;
}

#flash-container {
    position: fixed;
    top: calc(var(--ms-topbar-height) + .75rem);
    right: 1rem;
    z-index: 1080;
    max-width: min(400px, calc(100vw - 2rem));
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

#flash-container .alert { box-shadow: var(--ms-shadow-lg); }

/* -------------------------------------------------------------------
   Charts
   ------------------------------------------------------------------- */

.chart-container {
    position: relative;
    width: 100%;
    height: 300px;
}

.chart-container--sm { height: 230px; }

.chart-empty {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    text-align: center;
    color: var(--ms-text-subtle);
    font-size: .85rem;
}

/* -------------------------------------------------------------------
   Activity timeline
   ------------------------------------------------------------------- */

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

.timeline li {
    position: relative;
    padding: 0 0 1.05rem 1.55rem;
    border-left: 2px solid var(--ms-border);
}

.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }

.timeline li::before {
    content: "";
    position: absolute;
    left: -6px;
    top: .3rem;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--ms-primary);
    box-shadow: 0 0 0 3px var(--ms-primary-soft);
}

.timeline__text { font-size: .85rem; line-height: 1.4; }
.timeline__meta { font-size: .75rem; color: var(--ms-text-muted); margin-top: .1rem; }

/* -------------------------------------------------------------------
   Error pages
   ------------------------------------------------------------------- */

.error-page {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 2rem 1.25rem;
    text-align: center;
}

.error-page__code {
    font-size: clamp(4rem, 16vw, 7rem);
    font-weight: 800;
    line-height: 1;
    color: var(--ms-primary);
    letter-spacing: -.03em;
}

.error-page__title {
    font-size: 1.4rem;
    font-weight: 650;
    margin: .85rem 0 .5rem;
}

.error-page__message {
    color: var(--ms-text-muted);
    max-width: 34rem;
    margin: 0 auto 1.75rem;
}

.error-page__reference {
    margin-top: 2rem;
    font-size: .75rem;
    color: var(--ms-text-subtle);
}

.error-page__debug {
    margin-top: 2rem;
    text-align: left;
    max-width: 60rem;
    width: 100%;
    background: #1f2937;
    color: #e5e7eb;
    border-radius: var(--ms-radius);
    padding: 1.1rem;
    font-size: .78rem;
    overflow-x: auto;
}

.error-page__debug pre { margin: 0; white-space: pre-wrap; word-break: break-word; }

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

/* Tablet and below: sidebar becomes an off-canvas drawer. */
@media (max-width: 991.98px) {
    .app-sidebar {
        transform: translateX(-100%);
        box-shadow: 0 0 40px rgba(0, 0, 0, .3);
    }

    .app-sidebar.is-open { transform: translateX(0); }

    .app-main { margin-left: 0; }

    .sidebar-backdrop {
        position: fixed;
        inset: 0;
        background: rgba(17, 28, 58, .5);
        z-index: 1035;
        opacity: 0;
        visibility: hidden;
        transition: opacity .2s ease, visibility .2s ease;
    }

    .sidebar-backdrop.is-visible { opacity: 1; visibility: visible; }
}

@media (max-width: 767.98px) {
    .app-content { padding: 1rem .75rem 4.5rem; }
    .app-topbar  { padding: 0 .75rem; }

    .stat-card__value { font-size: 1.3rem; }

    .card-header { padding: .8rem .9rem; }
    .card-body   { padding: .9rem; }

    /* Wide tables become stacked cards. Each cell carries its heading in a
       data-label attribute, set in the view. */
    .table-stack thead { display: none; }

    .table-stack,
    .table-stack tbody,
    .table-stack tr,
    .table-stack td { display: block; width: 100%; }

    .table-stack tr {
        border: 1px solid var(--ms-border);
        border-radius: var(--ms-radius-sm);
        margin-bottom: .7rem;
        padding: .3rem .1rem;
        background: var(--ms-surface);
    }

    .table-stack td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 1rem;
        border-bottom: 1px dashed var(--ms-border) !important;
        padding: .55rem .8rem;
        text-align: right;
    }

    .table-stack td:last-child { border-bottom: none !important; }

    .table-stack td::before {
        content: attr(data-label);
        font-size: .72rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--ms-text-muted);
        text-align: left;
        flex-shrink: 0;
    }

    /* Primary action stays reachable with one thumb. */
    .mobile-sticky-action {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        padding: .7rem .75rem calc(.7rem + env(safe-area-inset-bottom));
        background: var(--ms-surface);
        border-top: 1px solid var(--ms-border);
        z-index: 1020;
        box-shadow: 0 -2px 10px rgba(16, 24, 40, .06);
    }

    .mobile-sticky-action .btn { width: 100%; }

    #flash-container {
        left: .75rem;
        right: .75rem;
        max-width: none;
    }
}

@media (max-width: 400px) {
    :root { --ms-topbar-height: 56px; }

    body { font-size: .9rem; }

    .stat-card { padding: .9rem; }
    .stat-card__value { font-size: 1.2rem; }
    .stat-card__icon { display: none; }   /* reclaim the width at 360px */
}

/* -------------------------------------------------------------------
   Print - invoices and reports
   ------------------------------------------------------------------- */

@media print {
    .app-sidebar,
    .app-topbar,
    .sidebar-backdrop,
    #flash-container,
    .no-print,
    .btn { display: none !important; }

    .app-main    { margin-left: 0 !important; }
    .app-content { padding: 0 !important; }

    body { background: #fff; font-size: 11pt; }

    .card {
        border: none !important;
        box-shadow: none !important;
        break-inside: avoid;
    }

    a[href]::after { content: ""; }   /* do not print URLs after links */
}

/* -------------------------------------------------------------------
   Reduced motion
   ------------------------------------------------------------------- */

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

/* -------------------------------------------------------------------------
   Autofilled fields

   A field the form filled in from the chosen model glows briefly, so it is
   clear the value arrived automatically rather than having been there all
   along. It is only ever a suggestion: the field stays editable, and anything
   already typed is never overwritten.
   ------------------------------------------------------------------------- */
.is-autofilled {
    background-color: var(--ms-info-soft);
    transition: background-color .6s ease;
}

@media (prefers-reduced-motion: reduce) {
    .is-autofilled { transition: none; }
}
