/* ==========================================================================
   Bablu Car Care - billing application
   ==========================================================================
   Direction: "service bay". The workshop's own signage, made digital.
   Graphite floor, caution amber, and the Indian number plate as the recurring
   artifact. Colour is never decoration here - every hue is doing a job:

     amber   attention, the thing you must deal with
     blue    bills and information
     emerald money that came in
     rose    overdue
     violet  people
     teal    vehicles

   Each area of the app owns one of those hues. `body[data-area]` in _Layout
   sets --accent, so a page's panels, tabs and focus rings match the colour of
   its own icon in the sidebar without a single view making a colour decision.
   ========================================================================== */

:root {
    /* -- Surfaces. Graphite has a blue cast; a neutral grey read as dead. -- */
    --ink: #12161d;
    --ink-2: #1a202a;
    --ink-3: #242c39;
    --ink-line: #2c3542;
    --paper: #e9edf3;
    --surface: #ffffff;
    --surface-2: #f7f9fb;
    --line: #e2e7ee;
    --line-strong: #c8d1dd;

    /* -- Text -- */
    --text: #10151c;
    --text-muted: #5b6675;
    --text-faint: #8b96a6;
    --text-on-ink: #ced6e2;
    --text-on-ink-muted: #7c8798;

    /* -- The accent. Reserved for attention, never for decoration. -- */
    --amber: #f59e0b;
    --amber-deep: #b45309;
    --amber-wash: #fff8ec;

    /* -- The working palette. Each hue has a job; see the header. -- */
    --blue: #1d4ed8;
    --blue-wash: #eff4ff;
    --emerald: #047857;
    --emerald-wash: #ecfdf5;
    --rose: #be123c;
    --rose-wash: #fff1f3;
    --violet: #6d28d9;
    --violet-wash: #f5f1ff;
    --teal: #0f766e;
    --teal-wash: #effcfa;
    --cyan: #0e7490;
    --cyan-wash: #ecfeff;
    --slate: #475569;
    --slate-wash: #f4f6f9;

    /* Semantic aliases, so components read by meaning rather than by hue. */
    --danger: var(--rose);
    --danger-wash: var(--rose-wash);
    --ok: var(--emerald);
    --ok-wash: var(--emerald-wash);
    --info: var(--blue);
    --info-wash: var(--blue-wash);

    /* -- Type. Barlow Condensed is signage: narrow, square-shouldered, the
          lettering on a workshop board. Inter carries the reading. Roboto Mono
          keeps every rupee column aligned. -- */
    --font-display: "Barlow Condensed", "Bahnschrift", "Arial Narrow", sans-serif;
    --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-data: "Roboto Mono", ui-monospace, Consolas, monospace;

    --radius-sm: 6px;
    --radius: 9px;
    --radius-lg: 14px;

    --shadow-sm: 0 1px 2px rgb(16 24 40 / 5%), 0 1px 3px rgb(16 24 40 / 4%);
    --shadow: 0 2px 4px rgb(16 24 40 / 4%), 0 8px 20px -8px rgb(16 24 40 / 12%);
    --shadow-lg: 0 12px 32px -10px rgb(16 24 40 / 22%);

    --sidebar-w: 254px;
    --topbar-h: 62px;

    /* Overridden per area by body[data-area]. Amber is the fallback. */
    --accent: #b45309;
    --accent-wash: var(--amber-wash);
}

/* An area owns a hue. Same hue as that area's icon in the sidebar, so the page
   and the menu agree about where you are. */
body[data-area="home"]              { --accent: var(--blue);    --accent-wash: var(--blue-wash); }
body[data-area="bills"]             { --accent: var(--blue);    --accent-wash: var(--blue-wash); }
body[data-area="payments"]          { --accent: var(--emerald); --accent-wash: var(--emerald-wash); }
body[data-area="notifications"]     { --accent: var(--amber-deep); --accent-wash: var(--amber-wash); }
body[data-area="customers"]         { --accent: var(--violet);  --accent-wash: var(--violet-wash); }
body[data-area="vehicles"]          { --accent: var(--teal);    --accent-wash: var(--teal-wash); }
body[data-area="reports"]           { --accent: var(--cyan);    --accent-wash: var(--cyan-wash); }
body[data-area="users"],
body[data-area="billsettings"],
body[data-area="whatsappsettings"],
body[data-area="googledrive"]       { --accent: var(--slate);   --accent-wash: var(--slate-wash); }

/* ========================================================================== */
/* Base                                                                       */
/* ========================================================================== */

* { box-sizing: border-box; }

html { font-size: 16px; }

/* No screen in this application may scroll sideways. */
html, body { max-width: 100%; overflow-x: hidden; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 0.9375rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6, .display-face {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.005em;
    color: var(--text);
}

a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Money and any figure that must line up column-wise. */
.num {
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    letter-spacing: -0.01em;
}

/* -------------------------------------------------------------------- icons */

/* One vendored Lucide sprite, referenced by <use>. Stroke colour follows the
   text colour of whatever the icon sits in, so an icon never needs its own rule. */
.i {
    width: 1.125em;
    height: 1.125em;
    flex: none;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -0.2em;
}

.i-sm { width: 1em; height: 1em; }
.i-lg { width: 1.375em; height: 1.375em; stroke-width: 1.85; }

/* ========================================================================== */
/* Signature: the number plate, and the caution stripe                        */
/* ========================================================================== */

.plate {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    border: 2px solid #111;
    border-radius: 4px;
    background: #fff;
    color: #111;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.35;
    white-space: nowrap;
}

.plate-sm { font-size: 0.75rem; padding: 0 5px; border-width: 1.5px; }
.plate-lg { font-size: 1.0625rem; padding: 3px 11px; }

/* Commercial vehicles carry yellow plates. */
.plate-commercial { background: #ffce00; }

/* Hazard tape. The one ornament in the application, and it means caution:
   it edges the brand block and the "needs attention" board, nowhere else. */
.hazard {
    height: 4px;
    flex: none;
    background: repeating-linear-gradient(
        -45deg,
        var(--amber) 0 8px,
        #1a202a 8px 16px
    );
}

/* ========================================================================== */
/* Shell                                                                      */
/* ========================================================================== */

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

/* Fixed, not sticky: a sticky sidebar stops scrolling once the page grows past
   one screen, which left it cut off half way down a long bill. */
.sidebar {
    width: var(--sidebar-w);
    background:
        radial-gradient(120% 60% at 0% 0%, rgb(245 158 11 / 13%), transparent 62%),
        linear-gradient(180deg, #161c25 0%, var(--ink) 42%, #0d1117 100%);
    color: var(--text-on-ink);
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0 auto 0 0;
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 30;
    scrollbar-width: thin;
    scrollbar-color: #333c4a transparent;
}

.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-thumb { background: #333c4a; border-radius: 4px; }

/* ------------------------------------------------------------ brand block */

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 17px 18px;
    color: inherit;
}

.sidebar-brand:hover { text-decoration: none; }

/* The shop's initials on an amber plate - the same object as a number plate,
   shrunk to a badge. */
.sidebar-brand .mark {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: 10px;
    background: linear-gradient(150deg, var(--amber), #d97706);
    color: #14181f;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.0625rem;
    letter-spacing: 0.04em;
    display: grid;
    place-items: center;
    box-shadow: 0 4px 12px rgb(245 158 11 / 30%);
}

.sidebar-brand .brand-text { min-width: 0; }

.sidebar-brand .shop {
    font-family: var(--font-display);
    font-size: 1.3125rem;
    font-weight: 700;
    letter-spacing: 0.035em;
    text-transform: uppercase;
    color: #fff;
    line-height: 1.05;
    display: block;
}

.sidebar-brand .tagline {
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: var(--amber);
    display: block;
    margin-top: 1px;
}

/* -------------------------------------------------------------------- nav */

.sidebar-nav { padding: 12px 10px 20px; flex: 1; }

.nav-section {
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: #6b7787;
    padding: 18px 10px 7px;
    display: flex;
    align-items: center;
    gap: 9px;
}

/* A hairline that runs out from the label to the edge, the way a rule does on
   a printed job card. */
.nav-section::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, var(--ink-line), transparent);
}

.nav-link-app {
    position: relative;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 11px;
    margin-bottom: 2px;
    border-radius: var(--radius);
    color: var(--text-on-ink);
    font-size: 0.9375rem;
    font-weight: 500;
    transition: background-color .13s ease, color .13s ease;
}

/* Each area's icon sits on a tinted tile in that area's own hue, so the menu
   is read by colour and shape before it is read as words. */
.nav-link-app .ico {
    width: 29px;
    height: 29px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 8px;
    background: color-mix(in srgb, var(--nav-accent, #94a3b8) 16%, transparent);
    color: var(--nav-accent, #94a3b8);
    transition: background-color .13s ease, color .13s ease;
}

.nav-link-app .ico .i { width: 17px; height: 17px; }
.nav-link-app .txt { min-width: 0; }

.nav-link-app:hover {
    background: rgb(255 255 255 / 6%);
    color: #fff;
    text-decoration: none;
}

.nav-link-app:hover .ico { background: color-mix(in srgb, var(--nav-accent, #94a3b8) 28%, transparent); }

/* Bay marking: the active route gets a filled tile in its own colour and an
   amber tab on the rail, the way a parked bay is marked on a workshop floor. */
.nav-link-app.active {
    background: rgb(255 255 255 / 9%);
    color: #fff;
    font-weight: 600;
}

.nav-link-app.active .ico {
    background: var(--nav-accent, #94a3b8);
    color: #0f1319;
    box-shadow: 0 3px 10px -2px var(--nav-accent, #94a3b8);
}

.nav-link-app.active::before {
    content: "";
    position: absolute;
    left: -10px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 22px;
    border-radius: 0 3px 3px 0;
    background: var(--amber);
}

.nav-dashboard { --nav-accent: #60a5fa; }
.nav-new       { --nav-accent: #fbbf24; }
.nav-bills     { --nav-accent: #7dd3fc; }
.nav-payments  { --nav-accent: #4ade80; }
.nav-reminders { --nav-accent: #fb7185; }
.nav-customers { --nav-accent: #c4b5fd; }
.nav-vehicles  { --nav-accent: #5eead4; }
.nav-reports   { --nav-accent: #67e8f9; }

/* Admin gets its own hues too. WhatsApp keeps its real brand green, because
   that is the colour the owner already associates with the thing. */
.nav-users     { --nav-accent: #f472b6; }
.nav-settings  { --nav-accent: #fb923c; }
.nav-whatsapp  { --nav-accent: #25d366; }
.nav-drive     { --nav-accent: #38bdf8; }

.nav-count {
    margin-left: auto;
    font-family: var(--font-data);
    font-size: 0.6875rem;
    background: var(--amber);
    color: #14181f;
    border-radius: 999px;
    min-width: 20px;
    text-align: center;
    padding: 1px 6px;
    font-weight: 700;
}

/* ------------------------------------------------------------ sidebar foot */

.sidebar-foot {
    padding: 14px 18px 18px;
    border-top: 1px solid var(--ink-line);
    font-size: 0.8125rem;
    color: var(--text-on-ink-muted);
    line-height: 1.7;
}

.sidebar-foot .row-line { display: flex; align-items: center; gap: 8px; }
.sidebar-foot .row-line .i { color: #5f6b7c; }
.sidebar-foot a { color: var(--text-on-ink-muted); }
.sidebar-foot a:hover { color: var(--amber); text-decoration: none; }

/* -------------------------------------------------------------- main column */

.main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    margin-left: var(--sidebar-w);
}

.topbar {
    height: var(--topbar-h);
    background: rgb(255 255 255 / 88%);
    backdrop-filter: saturate(160%) blur(10px);
    -webkit-backdrop-filter: saturate(160%) blur(10px);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 1px 0 rgb(16 24 40 / 3%);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 26px;
    position: sticky;
    top: 0;
    z-index: 20;
}

/* The page's own colour, as a short tab under the title. */
.topbar h1 {
    position: relative;
    font-size: 1.375rem;
    font-weight: 600;
    margin: 0;
    letter-spacing: 0.01em;
    padding-left: 13px;
}

.topbar h1::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 1.05em;
    border-radius: 2px;
    background: var(--accent);
}

.topbar .spacer { flex: 1; }

.user-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 0.875rem;
    color: var(--text-muted);
}

.user-avatar {
    width: 31px;
    height: 31px;
    border-radius: 50%;
    background: linear-gradient(150deg, var(--ink-3), var(--ink));
    color: #fff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.875rem;
    display: grid;
    place-items: center;
    box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--accent);
}

/* A max width stops tables stretching edge-to-edge on a wide monitor, which is
   the single biggest thing that makes a business app look unfinished. */
.content {
    padding: 24px 26px 60px;
    flex: 1;
    width: 100%;
    max-width: 1400px;
    margin: 0 auto;
}

/* Forms read badly at full width - the eye loses the line between label and box.
   Centred, not left-hugging, so the dead space sits evenly on both sides. */
.content-narrow { max-width: 980px; margin-inline: auto; }

.sidebar-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    width: 36px;
    height: 34px;
    color: var(--text);
    cursor: pointer;
}

.sidebar-toggle:hover { background: var(--surface-2); }

/* ========================================================================== */
/* Panels                                                                     */
/* ========================================================================== */

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

.panel + .panel { margin-top: 18px; }

.panel-head {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--line);
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
}

/* The page's colour, repeated as a short tick before every section title. It is
   the same mark as the tab beside the page title, one size down. */
.panel-head::before {
    content: "";
    width: 3px;
    height: 15px;
    flex: none;
    border-radius: 2px;
    background: var(--accent);
}

/* The icon already carries the page's colour, so the tick would say it twice. */
.panel-head:has(.head-ico)::before { display: none; }

.panel-head h2 {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text);
}

.panel-head .spacer { flex: 1; }
.panel-body { padding: 20px; }

/* A head that carries its own icon, for the few places where the section needs
   naming twice - the dashboard board, mainly. */
.panel-head .head-ico {
    width: 26px;
    height: 26px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 7px;
    background: var(--accent-wash);
    color: var(--accent);
}

/* ========================================================================== */
/* Stat tiles                                                                 */
/* ========================================================================== */

.stat-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

/* Explicit counts where the layout must not reflow into an odd shape. */
.stat-strip--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat-strip--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* Each tile carries the colour of the thing it counts, so the eye finds
   "overdue" or "still to collect" without reading a word. */
.stat {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 16px 17px;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: transform .14s ease, box-shadow .14s ease;
}

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

/* A wash of the tile's own hue, bled in from the top-right. A soft field, not a
   disc - a hard circle edge read as a rendering artefact rather than as design. */
.stat::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(90% 120% at 100% 0%,
        color-mix(in srgb, var(--stat-accent, var(--line-strong)) 16%, transparent),
        transparent 62%);
    pointer-events: none;
}

.stat::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background: var(--stat-accent, var(--line-strong));
}

.stat .label {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
    display: block;
}

.stat .value {
    font-family: var(--font-display);
    font-size: 2.125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    margin-top: 2px;
    display: block;
    color: var(--stat-accent, var(--text));
}

.stat.is-money .value { font-size: 1.75rem; }

/* Position in the strip decides the hue, so views stay free of colour decisions. */
.stat-strip .stat:nth-child(1) { --stat-accent: var(--blue); }
.stat-strip .stat:nth-child(2) { --stat-accent: var(--violet); }
.stat-strip .stat:nth-child(3) { --stat-accent: var(--emerald); }
.stat-strip .stat:nth-child(4) { --stat-accent: var(--cyan); }
.stat-strip .stat:nth-child(5) { --stat-accent: var(--amber-deep); }

/* State always beats position. */
.stat.is-alert {
    --stat-accent: var(--rose);
    border-color: #fbcfd8;
    background: linear-gradient(180deg, #fff, var(--rose-wash));
}

.stat.is-due {
    --stat-accent: var(--amber-deep);
    border-color: #f8dfb4;
    background: linear-gradient(180deg, #fff, var(--amber-wash));
}

.stat.is-ok {
    --stat-accent: var(--emerald);
    border-color: #a7f3d0;
    background: linear-gradient(180deg, #fff, var(--emerald-wash));
}

/* ========================================================================== */
/* Attention board                                                            */
/* ========================================================================== */

.board-group + .board-group { margin-top: 2px; }

.board-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 13px 18px 6px;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.board-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
    border-top: 1px solid var(--line);
    border-left: 3px solid transparent;
    transition: background-color .12s ease;
}

.board-row:hover { background: var(--surface-2); }
.board-row.is-overdue { border-left-color: var(--rose); background: linear-gradient(90deg, var(--rose-wash), transparent 42%); }
.board-row.is-today { border-left-color: var(--amber); background: linear-gradient(90deg, var(--amber-wash), transparent 42%); }
.board-row.is-upcoming { border-left-color: var(--line-strong); }

.board-row .who { min-width: 0; flex: 1; }
.board-row .who .name { font-weight: 600; display: block; }

.board-row .meta {
    font-size: 0.8125rem;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 2px;
}

.board-row .amount {
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    text-align: right;
    white-space: nowrap;
}

.board-row .when {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    white-space: nowrap;
    text-align: right;
    min-width: 108px;
}

.board-row.is-overdue .when { color: var(--rose); font-weight: 700; }
.board-row.is-today .when { color: var(--amber-deep); font-weight: 700; }
.board-row.is-upcoming .when { color: var(--text-muted); }

/* ========================================================================== */
/* Tables                                                                     */
/* ========================================================================== */

.table-app { width: 100%; border-collapse: collapse; }

.table-app thead th {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    text-align: left;
    padding: 11px 15px;
    border-bottom: 1px solid var(--line);
    background: var(--surface-2);
    white-space: nowrap;
}

.table-app tbody td {
    padding: 12px 15px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

/* Column widths as classes, so no view needs an inline style. */
.col-sr { width: 42px; }
.col-num { width: 120px; }

/* An invoice number and a date are single tokens - breaking "0001/2026-27"
   across two lines makes the whole row look broken. */
.table-app td .num,
.table-app td.num { white-space: nowrap; font-size: 0.875rem; }
.col-unit { width: 130px; }
.col-money { width: 124px; }
.col-tax { width: 95px; }
.col-action { width: 52px; }

.table-app tbody tr:last-child td { border-bottom: 0; }
.table-app tbody tr { transition: background-color .1s ease; }
.table-app tbody tr:hover { background: var(--accent-wash); }
.table-app .right { text-align: right; }

.table-app .money {
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
    letter-spacing: -0.02em;
}

.table-wrap { overflow-x: auto; }

/* ========================================================================== */
/* Status tags                                                                */
/* ========================================================================== */

.tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 600;
    padding: 2px 9px;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
    line-height: 1.4;
}

/* A dot ahead of the word, so status survives being read in a hurry. */
.tag::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.tag-draft { background: #eef1f5; color: var(--slate); border-color: var(--line-strong); }
.tag-pending { background: var(--blue-wash); color: var(--blue); border-color: #c3d6ff; }
.tag-partial { background: var(--amber-wash); color: var(--amber-deep); border-color: #f8dfb4; }
.tag-paid { background: var(--emerald-wash); color: var(--emerald); border-color: #a7f3d0; }
.tag-overdue { background: var(--rose-wash); color: var(--rose); border-color: #fbcfd8; }

.tag-cancelled {
    background: #eef1f5;
    color: var(--text-faint);
    border-color: var(--line);
    text-decoration: line-through;
}

/* ========================================================================== */
/* Controls                                                                   */
/* ========================================================================== */

.btn {
    --bs-btn-border-radius: var(--radius);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font-family: var(--font-body);
    font-weight: 550;
    font-size: 0.875rem;
    padding: 8px 15px;
    border-radius: var(--radius);
    transition: background-color .13s ease, border-color .13s ease,
                transform .13s ease, box-shadow .13s ease;
}

.btn-sm { padding: 5px 11px; font-size: 0.8125rem; }

/* A disabled button has to stay readable. Bootstrap's default opacity turned the
   dark buttons into a grey box with grey text on it - it looked broken rather
   than unavailable. Flat, light, obviously inert, and the label still legible. */
.btn:disabled,
.btn.disabled,
a.btn.disabled {
    background: #eef1f5;
    background-image: none;
    border-color: var(--line-strong);
    color: #7c8798;
    opacity: 1;
    box-shadow: none;
    transform: none;
    cursor: not-allowed;
    pointer-events: auto;
}

.btn-ink {
    background: linear-gradient(175deg, var(--ink-3), var(--ink));
    border: 1px solid var(--ink);
    color: #fff;
    box-shadow: 0 1px 2px rgb(16 24 40 / 20%);
}

.btn-ink:hover, .btn-ink:focus {
    background: linear-gradient(175deg, #2d3746, #171d26);
    border-color: #000;
    color: #fff;
    transform: translateY(-1px);
    box-shadow: 0 6px 16px -4px rgb(16 24 40 / 40%);
}

.btn-ink:active { transform: translateY(0); box-shadow: none; }

/* The page's own colour, for the one action that page exists to perform. */
.btn-accent {
    background: var(--accent);
    border: 1px solid var(--accent);
    color: #fff;
    box-shadow: 0 1px 2px rgb(16 24 40 / 16%);
}

.btn-accent:hover, .btn-accent:focus {
    color: #fff;
    filter: brightness(1.08);
    transform: translateY(-1px);
    box-shadow: 0 6px 16px -5px var(--accent);
}

.btn-accent:active { transform: translateY(0); box-shadow: none; }

.btn-quiet {
    background: var(--surface);
    border: 1px solid var(--line-strong);
    color: var(--text);
}

.btn-quiet:hover {
    background: var(--surface-2);
    border-color: #aab6c6;
    color: var(--text);
}

.btn-danger-quiet {
    background: var(--surface);
    border: 1px solid #fbcfd8;
    color: var(--rose);
}

.btn-danger-quiet:hover { background: var(--rose-wash); color: var(--rose); }

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

.form-label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    color: #33404f;
    margin-bottom: 5px;
    letter-spacing: 0.005em;
}

.form-label .req { color: var(--rose); margin-left: 2px; }

.form-control, .form-select {
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background-color: var(--surface);
    font-size: 0.9375rem;
    padding: 9px 12px;
    transition: border-color .13s ease, box-shadow .13s ease, background-color .13s ease;
}

/* Room for the chevron. Without this the shorthand above clipped the last letter
   of a narrow select against its own arrow. */
.form-select { padding-right: 2.4rem; }

.form-control::placeholder { color: #a7b1bf; }

.form-control:hover:not(:focus), .form-select:hover:not(:focus) { border-color: #aab6c6; }

.form-control:focus, .form-select:focus {
    border-color: var(--accent);
    background-color: #fff;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

textarea.form-control { line-height: 1.6; }

.form-check-input { width: 1.05em; height: 1.05em; margin-top: 0.22em; cursor: pointer; }
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.form-check-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.form-check-label { cursor: pointer; }

.field-hint { font-size: 0.8125rem; color: var(--text-muted); margin-top: 4px; }
.text-danger, .validation-summary-errors { color: var(--rose) !important; font-size: 0.8125rem; }

/* A checkbox that has to sit level with the input beside it, not with its label. */
.field-aligned { padding-top: 27px; }

/* A field that only exists because of the answer to the field above it. Indented
   and washed so the dependency is visible without a sentence explaining it. */
.subfield {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    padding: 13px 15px;
}

/* ==========================================================================
   Page scaffolding. Every screen uses these three pieces in the same order:
   .page-bar (context + actions) -> .toolbar (filters) -> .panel (content).
   The page title itself lives in the topbar and is never repeated in the body.
   ========================================================================== */

.page-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px 18px;
    flex-wrap: wrap;
    margin-bottom: 18px;
    min-height: 36px;
}

/* Summary line under the title: "12 bills - Rs 1,20,000 outstanding" */
.page-meta {
    display: flex;
    align-items: center;
    gap: 8px 18px;
    flex-wrap: wrap;
    color: var(--text-muted);
    font-size: 0.875rem;
    margin: 0;
}

.page-meta .k {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-right: 5px;
}

.page-meta strong { color: var(--text); font-weight: 600; }

.page-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* --------------------------------------------------------- summary strip --
   The headline figures for a list page. These were loose grey text sitting on
   the page background, which read as a caption rather than as the numbers the
   page is about. Now one card, split into cells by hairlines, with the page's
   primary action riding on the right of the same card. */

.page-summary {
    position: relative;
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 0 18px;
    margin-bottom: 18px;
    overflow: hidden;
}

/* The page's colour, as the card's left edge - the same mark as the tab beside
   the page title. */
.page-summary::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background: var(--accent);
}

.fig {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 15px 24px 15px 0;
    min-width: 0;
}

.fig + .fig {
    border-left: 1px solid var(--line);
    padding-left: 24px;
}

.fig-ico {
    width: 34px;
    height: 34px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 9px;
    background: color-mix(in srgb, var(--fig-accent, var(--accent)) 12%, transparent);
    color: var(--fig-accent, var(--accent));
}

.fig-ico .i { width: 18px; height: 18px; }

.fig .k {
    display: block;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    line-height: 1.3;
}

.fig .v {
    display: block;
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
    color: var(--text);
    white-space: nowrap;
}

.fig .v.owing { color: var(--rose); }
.fig .v.is-ok { color: var(--emerald); }

/* Position decides the hue, exactly as it does for the dashboard tiles, so no
   view has to make a colour decision. */
.page-summary .fig:nth-child(1) { --fig-accent: var(--blue); }
.page-summary .fig:nth-child(2) { --fig-accent: var(--violet); }
.page-summary .fig:nth-child(3) { --fig-accent: var(--emerald); }
.page-summary .fig:nth-child(4) { --fig-accent: var(--amber-deep); }
.page-summary .fig:nth-child(5) { --fig-accent: var(--cyan); }

/* Meaning beats position, exactly as it does on the dashboard tiles. The doubled
   class is deliberate: it has to outrank the :nth-child rules above. */
.page-summary .fig.fig--alert { --fig-accent: var(--rose); }
.page-summary .fig.fig--due { --fig-accent: var(--amber-deep); }
.page-summary .fig.fig--ok { --fig-accent: var(--emerald); }

.page-summary .page-tools {
    margin-left: auto;
    padding: 12px 0 12px 24px;
}

/* When the strip carries the page's Save button it has to stay put, because the
   form underneath it can be taller than the screen. Detected rather than declared:
   a strip only holds a submit when a view puts one there. */
.page-summary:has(button[form]) {
    position: sticky;
    top: var(--topbar-h);
    z-index: 15;
    box-shadow: var(--shadow);
}

@media (max-width: 780px) {
    .page-summary { padding: 0 14px; }
    .fig { padding: 12px 16px 12px 0; }
    .fig + .fig { padding-left: 16px; }
    .fig .v { font-size: 1.25rem; }
    .page-summary .page-tools { padding-left: 0; width: 100%; margin-left: 0; border-top: 1px solid var(--line); }
}

/* Filters always sit in their own bordered strip, never loose on the page. */
.toolbar {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 15px 17px;
    margin-bottom: 18px;
}

/* A fixed 4-column grid, not auto-fit. auto-fit packed as many controls as would
   fit and left the remainder stranded alone on the next row, which read as a
   mistake. Four columns with the search box spanning two means every toolbar
   lands on tidy, full rows. */
.toolbar form,
form.toolbar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px 16px;
    align-items: end;
}

.toolbar .form-label {
    margin-bottom: 4px;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.toolbar .grow { grid-column: span 2; }

/* Buttons always take their own final row, right-aligned, so they never sit
   alone in a stray column. */
.toolbar-actions {
    grid-column: 1 / -1;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    border-top: 1px solid var(--line);
    padding-top: 14px;
    margin-top: 2px;
}

.toolbar-actions .btn { white-space: nowrap; min-width: 96px; }

.form-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}

/* Form buttons ride along the bottom of the screen on a long form, so "Save"
   is never a scroll away. */
.form-actions--sticky {
    position: sticky;
    bottom: 0;
    z-index: 10;
    margin: 0 -4px;
    padding: 14px 4px;
    background: linear-gradient(180deg, rgb(233 237 243 / 0%), var(--paper) 42%);
}

@media (max-width: 1000px) {
    .toolbar form,
    form.toolbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
    .toolbar form,
    form.toolbar { grid-template-columns: minmax(0, 1fr); }

    .toolbar .grow { grid-column: span 1; }
    .toolbar-actions .btn { flex: 1; }
    .field-aligned { padding-top: 0; }
}

/* ------------------------------------------------------- detail list, cells */

.detail-list {
    display: grid;
    grid-template-columns: minmax(100px, auto) 1fr;
    gap: 9px 18px;
    margin: 0;
}

.detail-list dt {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    padding-top: 2px;
}

.detail-list dd { margin: 0; }

.cell-sub { font-size: 0.8125rem; color: var(--text-muted); margin-top: 1px; }

.table-app .money.owing,
.owing { color: var(--rose); font-weight: 600; }

.note-block {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    padding: 11px 13px;
    font-size: 0.875rem;
    white-space: pre-wrap;
}

.plate-input {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.0625rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* ========================================================================== */
/* Bill editor + totals                                                       */
/* ========================================================================== */

.filter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
    padding: 17px 19px;
}

.filter-grid .form-label { margin-bottom: 4px; }

.items-table { table-layout: fixed; }

/* The editor is a grid of inputs, not a reading table, so it gets tighter cells
   than the list tables do. `.table-app tbody td` is (0,1,2), so these have to
   carry both classes or the roomier list padding wins and the money columns get
   squeezed until the amounts clip. */
.table-app.items-table tbody td { padding: 4px 4px; vertical-align: middle; }
.table-app.items-table thead th { padding: 8px 4px; letter-spacing: 0.06em; }
.table-app.items-table tbody td:first-child,
.table-app.items-table thead th:first-child { padding-left: 12px; }
.table-app.items-table tbody td:last-child,
.table-app.items-table thead th:last-child { padding-right: 10px; }

/* "Part or work done" holds the longest text on the bill - real lines run to
   "COMBINETION SWITCH AND WIPER LINKEG MOTORS RR LB". Every other column is
   pinned as narrow as its own content allows so the description takes the rest. */
.items-table thead th:nth-child(2) { width: auto; }
/* Widths are measured, not guessed. In Roboto Mono at 15px the widest figure the
   garage will realistically bill - 99,99,999.00 - renders at 97px, and 1,00,557.00
   at 87px. The amount cell therefore needs 106px of inner width and the price
   input 88px; everything else is squeezed to pay for that. */
.items-table .col-sr { width: 34px; }
.items-table .col-num { width: 78px; }
.items-table .col-unit { width: 88px; }
.items-table .col-money { width: 120px; }
.items-table .col-tax { width: 70px; }
.items-table thead th.col-money.right { width: 114px; }

.items-table input,
.items-table select { width: 100%; }

/* Roomy enough to read the whole number at a glance - the narrow boxes were
   cutting values like "0.98" off mid-digit. */
.items-table input,
.items-table select {
    font-size: 0.9375rem;
    padding: 7px 7px;
    height: auto;
}

.items-table .form-select { padding-right: 1.6rem; background-position: right 0.4rem center; }

/* The rupee sign is tucked in close so the digits get the width, not the symbol. */
.items-table .rupee-input .rupee-sign { left: 7px; }
.items-table .rupee-input input { padding-left: 19px !important; padding-right: 5px; }

/* Spinner arrows are dead weight on a price and a quantity - nobody nudges a rate
   up by one rupee at a time - and they were eating the width the digits needed. */
.items-table input[type="number"] { appearance: textfield; -moz-appearance: textfield; }

.items-table input[type="number"]::-webkit-outer-spin-button,
.items-table input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.items-table .qty,
.items-table .rate {
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.items-table .sr { color: var(--text-faint); font-family: var(--font-data); font-size: 0.875rem; }

.items-table .line-total {
    font-family: var(--font-data);
    font-weight: 700;
    white-space: nowrap;
    font-size: 0.9375rem;
}

/* Rupee sign sits inside the box so there is no doubt what the number means. */
.rupee-input { position: relative; }

.rupee-input .rupee-sign {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: 0.9375rem;
    pointer-events: none;
}

.rupee-input input { padding-left: 25px !important; }

/* Reorder and remove sit together at the end of the row, in that order: the two
   safe actions first, the destructive one last and set apart by its own hover. */
.row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0;
}

.btn-row-move,
.btn-row-remove {
    border: 0;
    background: none;
    color: var(--text-faint);
    display: inline-flex;
    padding: 5px 4px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease, opacity .12s ease;
}

.btn-row-move:hover { background: var(--accent-wash); color: var(--accent); }
.btn-row-remove:hover { background: var(--rose-wash); color: var(--rose); }

/* The first row cannot move up and the last cannot move down. Kept in the layout
   rather than hidden, so the buttons never shift position under the pointer. */
.btn-row-move:disabled {
    opacity: .25;
    cursor: default;
    background: none;
    color: var(--text-faint);
}

.items-table .col-rowactions { width: 84px; }

.totals-list {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px 16px;
    margin: 0;
}

.totals-list dt { color: var(--text-muted); font-weight: 500; }

.totals-list dd {
    margin: 0;
    text-align: right;
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
}

.totals-list dt.grand,
.totals-list dd.grand {
    border-top: 1px solid var(--line);
    padding-top: 9px;
    margin-top: 2px;
    font-weight: 700;
    color: var(--text);
    font-size: 1.1875rem;
}

.totals-list dd.grand { color: var(--accent); }

.totals-panel { position: sticky; top: calc(var(--topbar-h) + 16px); }
.totals-list--narrow { max-width: 340px; margin-left: auto; }

.nowrap { white-space: nowrap; }
.field-short { max-width: 300px; }

/* ========================================================================== */
/* Step list, settings, WhatsApp                                              */
/* ========================================================================== */

.steps { list-style: none; margin: 0 0 20px; padding: 0; }

.step {
    display: flex;
    gap: 15px;
    padding: 17px 0;
    border-bottom: 1px solid var(--line);
}

.step:last-child { border-bottom: 0; }

.step-num {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1rem;
    display: grid;
    place-items: center;
}

.step-body h3 { font-size: 1.125rem; margin: 3px 0 4px; }
.step-body p { color: var(--text-muted); margin-bottom: 10px; }

.wa-preview {
    background: #e7f6ea;
    border: 1px solid #bfe3c6;
    border-radius: var(--radius);
    padding: 14px 16px;
    font-size: 0.9375rem;
    white-space: pre-wrap;
    margin: 0 0 10px;
}

.wa-editor { font-family: var(--font-data); font-size: 0.875rem; line-height: 1.7; }

.logo-preview {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 13px 17px;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 14px;
}

.logo-preview img { max-height: 70px; max-width: 260px; display: block; }

.sample-number {
    display: inline-block;
    background: var(--amber-wash);
    border: 1px solid #f8dfb4;
    border-radius: var(--radius);
    padding: 9px 14px;
}

.sample-number .label {
    display: block;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--amber-deep);
}

.sample-number .value {
    display: block;
    font-family: var(--font-data);
    font-size: 1.1875rem;
    font-weight: 700;
    color: var(--text);
    margin-top: 2px;
}

/* Placeholder chips on the WhatsApp template editor. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; }

.chip {
    font-family: var(--font-data);
    font-size: 0.75rem;
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    background: var(--surface);
    color: #33404f;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

.chip:hover { background: var(--ink); color: #fff; border-color: var(--ink); }

.folder-tree {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 13px 15px;
    font-family: var(--font-data);
    font-size: 0.8125rem;
    line-height: 1.7;
    margin: 0 0 12px;
    overflow-x: auto;
    white-space: pre;
}

/* ------------------------------------------------------ report bar chart -- */

.bars { display: flex; flex-direction: column; gap: 10px; }

.bar-row {
    display: grid;
    grid-template-columns: 96px 1fr 112px;
    align-items: center;
    gap: 12px;
}

.bar-label { font-size: 0.8125rem; color: var(--text-muted); white-space: nowrap; }

.bar-track {
    background: #eaeef3;
    border-radius: 5px;
    height: 22px;
    overflow: hidden;
}

.bar-fill {
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--accent) 60%, #fff),
        var(--accent));
    height: 100%;
    border-radius: 5px;
    min-width: 3px;
}

.bar-value {
    text-align: right;
    font-family: var(--font-data);
    font-variant-numeric: tabular-nums;
    font-size: 0.8125rem;
    font-weight: 600;
}

.error-code {
    font-family: var(--font-display);
    font-size: 4.5rem;
    font-weight: 700;
    color: var(--text-faint);
    line-height: 1;
}

/* ========================================================================== */
/* Pager                                                                      */
/* ========================================================================== */

.pager {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding: 12px 18px;
    border-top: 1px solid var(--line);
    background: var(--surface-2);
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.pager-count { white-space: nowrap; }
.pager-count strong { color: var(--text); font-weight: 600; }

.pager-size { display: flex; align-items: center; gap: 4px; }

.pager-size a {
    padding: 3px 9px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    text-decoration: none;
    font-weight: 500;
}

.pager-size a:hover { background: #e6ebf1; text-decoration: none; }
.pager-size a.on { background: var(--ink); color: #fff; font-weight: 600; }

.pager-pages { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.pager-pages a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-weight: 600;
}

.pager-pages a:hover { background: var(--accent-wash); border-color: var(--accent); text-decoration: none; }
.pager-pages .off { color: var(--text-faint); padding: 4px 10px; }
.pager-current { font-family: var(--font-display); font-weight: 600; letter-spacing: 0.04em; }

/* ========================================================================== */
/* Empty state, notices                                                       */
/* ========================================================================== */

.empty {
    text-align: center;
    padding: 52px 20px;
    color: var(--text-muted);
}

.empty .empty-ico {
    width: 52px;
    height: 52px;
    margin: 0 auto 14px;
    display: grid;
    place-items: center;
    border-radius: 14px;
    background: var(--accent-wash);
    color: var(--accent);
}

.empty .empty-ico .i { width: 26px; height: 26px; }

.empty .headline {
    font-family: var(--font-display);
    font-size: 1.3125rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 4px;
}

.notice {
    display: flex;
    gap: 11px;
    align-items: flex-start;
    padding: 12px 15px;
    border-radius: var(--radius);
    border: 1px solid;
    border-left-width: 4px;
    font-size: 0.875rem;
    margin-bottom: 18px;
    box-shadow: var(--shadow-sm);
}

.notice .i { margin-top: 0.15em; }
.notice-ok { background: var(--emerald-wash); border-color: #a7f3d0; border-left-color: var(--emerald); color: #04543c; }
.notice-warn { background: var(--amber-wash); border-color: #f8dfb4; border-left-color: var(--amber); color: #7a3f02; }
.notice-error { background: var(--rose-wash); border-color: #fbcfd8; border-left-color: var(--rose); color: #8c0f2f; }

/* ========================================================================== */
/* Login                                                                      */
/* ========================================================================== */

.auth {
    min-height: 100vh;
    display: grid;
    /* minmax(0, ...) - a bare 1fr floors at min-content and would push the card off-screen. */
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    background: var(--paper);
    overflow-x: hidden;
}

.auth-side {
    position: relative;
    overflow: hidden;
    background: linear-gradient(152deg, #10141b 0%, var(--ink) 46%, #232b37 100%);
    color: #fff;
    padding: 52px 56px 56px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 32px;
}

/* Warmth off the top-left corner so the panel is not a flat black rectangle. */
.auth-side::before {
    content: "";
    position: absolute;
    inset: -30% 40% 45% -25%;
    background: radial-gradient(closest-side, rgb(245 158 11 / 20%), transparent 70%);
    pointer-events: none;
}

/* ---- Signature: a tachometer bleeding off the panel edge. Ornament, not a
       readout: no numbers, nothing that could be mistaken for real data. ---- */

.gauge {
    position: absolute;
    right: -110px;
    bottom: -120px;
    width: clamp(280px, 42%, 460px);
    height: auto;
    opacity: .38;
    pointer-events: none;
    z-index: 0;
}

.gauge .track { fill: none; stroke: #39414e; stroke-width: 8; stroke-linecap: round; }
.gauge .sweep { fill: none; stroke: var(--amber); stroke-width: 8; stroke-linecap: round; }
.gauge .tick { stroke: #525b6c; stroke-width: 4; stroke-linecap: round; }
.gauge .tick-hot { stroke: var(--amber); }
.gauge .hub { fill: #12151a; stroke: #525b6c; stroke-width: 3; }
.gauge .needle { fill: var(--amber); }

.gauge .needle-group {
    transform-box: view-box;
    transform-origin: 300px 300px;
    transform: rotate(414deg);
}

/* Content sits above the ornament. Scoped to the content elements only - a bare
   `> *` here would also hit .gauge and cancel its absolute positioning. */
.auth-side > div,
.auth-side > p { position: relative; z-index: 1; }

.auth-side .shop {
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 5vw, 3.75rem);
    font-weight: 700;
    letter-spacing: 0.025em;
    text-transform: uppercase;
    line-height: 1;
}

.auth-side .tagline {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 500;
    letter-spacing: 0.34em;
    text-transform: uppercase;
    color: var(--amber);
    margin-top: 10px;
}

/* Short amber rule: the same mark that flags the active page in the sidebar. */
.auth-side .rule {
    width: 56px;
    height: 3px;
    background: var(--amber);
    margin: 26px 0 22px;
    border-radius: 2px;
}

.auth-side .blurb {
    color: #c7cdd7;
    font-size: 1rem;
    line-height: 1.6;
    max-width: 32ch;
    margin: 0;
}

.auth-side .contact {
    margin: 0;
    font-size: 0.875rem;
    color: var(--text-on-ink-muted);
    line-height: 1.8;
}

.auth-side .contact strong {
    display: block;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #7c8698;
    font-weight: 600;
    margin-bottom: 4px;
}

.auth-main { display: grid; place-items: center; padding: 32px; min-width: 0; }
.auth-main--full { min-height: 100vh; }
.auth-card { width: min(100%, 410px); min-width: 0; }
.auth-top { margin-bottom: 4px; }

.auth-card .panel {
    padding: 34px 32px;
    box-shadow: 0 20px 48px rgb(16 24 40 / 13%), 0 2px 6px rgb(16 24 40 / 6%);
}

.auth-card h1 { font-size: 2rem; margin: 0 0 4px; letter-spacing: 0.01em; }
.auth-card .sub { color: var(--text-muted); font-size: 0.9375rem; margin-bottom: 24px; }
.auth-card .form-control { padding: 11px 13px; }

/* Monogram badge: the shop's initials, cut by an amber corner. */
.monogram {
    width: 46px;
    height: 46px;
    border-radius: 11px;
    background: var(--ink);
    color: #fff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.125rem;
    letter-spacing: 0.06em;
    display: grid;
    place-items: center;
    position: relative;
    overflow: hidden;
    margin-bottom: 18px;
}

.monogram::after {
    content: "";
    position: absolute;
    right: -12px;
    bottom: -12px;
    width: 24px;
    height: 24px;
    background: var(--amber);
    transform: rotate(45deg);
}

.auth-foot {
    text-align: center;
    margin-top: 18px;
    font-size: 0.8125rem;
    color: var(--text-faint);
}

/* ========================================================================== */
/* Motion - one orchestrated entrance, nothing scattered                      */
/* ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
    .gauge .needle-group { animation: sweep 1.5s cubic-bezier(.34, .8, .3, 1) both; }

    @keyframes sweep {
        0% { transform: rotate(225deg); }
        68% { transform: rotate(428deg); }
        100% { transform: rotate(414deg); }
    }

    .fade-up { animation: fadeUp .5s ease-out both; }
    .d1 { animation-delay: .05s; }
    .d2 { animation-delay: .12s; }
    .d3 { animation-delay: .19s; }
    .d4 { animation-delay: .26s; }

    @keyframes fadeUp {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: none; }
    }

    .auth-card .panel { animation: cardIn .55s cubic-bezier(.2, .7, .3, 1) both .1s; }

    @keyframes cardIn {
        from { opacity: 0; transform: translateY(14px) scale(.985); }
        to { opacity: 1; transform: none; }
    }

    .board-row { animation: rise .28s ease-out both; }
    .board-row:nth-child(2) { animation-delay: .03s; }
    .board-row:nth-child(3) { animation-delay: .06s; }
    .board-row:nth-child(4) { animation-delay: .09s; }
    .board-row:nth-child(n+5) { animation-delay: .12s; }

    @keyframes rise {
        from { opacity: 0; transform: translateY(4px); }
        to { opacity: 1; transform: none; }
    }
}

/* ========================================================================== */
/* Responsive                                                                 */
/* ========================================================================== */

@media (max-width: 1100px) {
    .stat-strip--5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
    .auth { grid-template-columns: minmax(0, 1fr); }
    .auth-side { padding: 30px 22px; gap: 0; }
    .auth-main { padding: 24px 16px 32px; }
    .auth-card { max-width: 100%; }
    .auth-card .panel { padding: 26px 20px; }
    .auth-side .shop { font-size: 2.125rem; }
    .auth-side .blurb,
    .auth-side .contact { display: none; }

    /* The gauge is ornament; on a phone the space belongs to the form. */
    .gauge { display: none; }
}

@media (max-width: 780px) {
    .stat-strip,
    .stat-strip--3,
    .stat-strip--5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    .sidebar {
        z-index: 60;
        transform: translateX(-100%);
        transition: transform .18s ease-out;
        box-shadow: 0 0 40px rgb(0 0 0 / 35%);
    }

    .sidebar.open { transform: none; }
    .main { margin-left: 0; }
    .sidebar-toggle { display: inline-flex; }
    .content { padding: 16px 14px 44px; }
    .topbar { padding: 0 14px; gap: 10px; }
    .topbar h1 { font-size: 1.1875rem; }

    .board-row { flex-wrap: wrap; gap: 6px 12px; }
    .board-row .when { min-width: 0; text-align: left; }

    .scrim {
        position: fixed;
        inset: 0;
        background: rgb(16 24 40 / 45%);
        z-index: 50;
    }
}

@media (max-width: 600px) {
    .bar-row { grid-template-columns: 78px 1fr 94px; gap: 8px; }
    .stat .value { font-size: 1.75rem; }
    .stat.is-money .value { font-size: 1.375rem; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
