/* ShopManager — dashboard styles. No build step, no CDN. */

:root {
    --bg: #f4f6fb;
    --surface: #ffffff;
    --sidebar: #131a2b;
    --sidebar-muted: #8d97ad;
    --text: #1a2233;
    --muted: #6b7689;
    --line: #e6e9f2;
    --primary: #2f6fed;
    --primary-dark: #2559c9;
    --green: #12a67a;
    --red: #e04a5f;
    --red-dark: #c53a50;
    --red-ink: #a8283c;   /* red text that still reads on a red tint */
    --amber: #e8912a;
    --violet: #7c5cf0;
    --radius: 14px;

    /* Layered shadows: a hairline to seat the edge, a soft pool for depth. */
    --shadow-xs: 0 1px 2px rgba(19, 26, 43, .06);
    --shadow: 0 1px 2px rgba(19, 26, 43, .05), 0 6px 18px rgba(19, 26, 43, .05);
    --shadow-lg: 0 2px 4px rgba(19, 26, 43, .05), 0 14px 38px rgba(19, 26, 43, .10);
    --ring: 0 0 0 3px rgba(47, 111, 237, .16);

    /* Latin runs on the system UI face; Bengali glyphs fall through to a
       deliberately chosen Bengali face instead of whatever the OS picks. */
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
            "Noto Sans Bengali", "Hind Siliguri", "Nirmala UI", "Bangla Sangam MN",
            "Kalpurush", "SolaimanLipi", sans-serif;

    --ease: cubic-bezier(.4, 0, .2, 1);
}

* { box-sizing: border-box; }

/* `hidden` must beat the display rules below it (.field, .btn are flex). */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    /* Bengali carries matras above and descenders below, so it needs more
       leading than a Latin-only UI would. */
    font: 15px/1.6 var(--font);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

::selection { background: rgba(47, 111, 237, .18); }

h1, h2 { margin: 0; font-weight: 650; letter-spacing: normal; line-height: 1.35; }
h1 { font-size: 21px; }
h2 { font-size: 15.5px; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }

.muted { color: var(--muted); }
/* A muted line turned red — used for the restore page's own file warnings. */
.muted.is-error { color: var(--red-ink); }
.num, .stat-value, .line-total, .alert-count, .chart-foot strong,
input[type=number] { font-variant-numeric: tabular-nums; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
.icon { width: 18px; height: 18px; flex: none; }
.link { color: var(--primary); font-size: 13px; font-weight: 600; }
.link:hover { text-decoration: underline; }

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

.shell { display: flex; min-height: 100vh; }
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.content { padding: 24px; display: flex; flex-direction: column; gap: 20px; }

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

.sidebar {
    width: 250px;
    flex: none;
    background: var(--sidebar);
    color: #e8ecf5;
    display: flex;
    flex-direction: column;
    padding: 20px 14px;
    gap: 22px;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand { display: flex; align-items: center; gap: 11px; padding: 0 8px; }
.brand-mark {
    width: 38px; height: 38px; border-radius: 11px;
    background: linear-gradient(140deg, var(--primary), var(--violet));
    display: grid; place-items: center;
    font-weight: 700; font-size: 14px; letter-spacing: .02em;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.25; }
.brand-text strong { font-size: 15px; }
.brand-text small { color: var(--sidebar-muted); font-size: 11.5px; }

.nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.nav-item {
    display: flex; align-items: center; gap: 11px;
    padding: 10px 12px; border-radius: 10px;
    color: var(--sidebar-muted); font-size: 14px; font-weight: 500;
    transition: background .15s, color .15s;
}
.nav-item:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.nav-item.is-active { background: var(--primary); color: #fff; box-shadow: 0 6px 16px rgba(47, 111, 237, .35); }

.upsell {
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .08);
    border-radius: 12px; padding: 14px;
}
.upsell strong { display: block; font-size: 13.5px; margin-bottom: 4px; }
.upsell p { color: var(--sidebar-muted); font-size: 12.5px; margin-bottom: 11px; }

/* ---------- topbar ---------- */

.topbar {
    display: flex; align-items: center; gap: 16px;
    padding: 14px 24px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 20;
}
.page-heading p { font-size: 13px; color: var(--muted); }

.search {
    margin-left: auto;
    display: flex; align-items: center; gap: 9px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 0 12px;
    width: min(340px, 34vw);
    color: var(--muted);
}
.search input {
    border: 0; background: none; outline: none;
    padding: 9px 0; width: 100%;
    font: inherit; font-size: 13.5px; color: var(--text);
}
.search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(47, 111, 237, .12); }

.topbar-actions { display: flex; align-items: center; gap: 10px; }

.icon-btn {
    width: 38px; height: 38px; border-radius: 10px;
    border: 1px solid var(--line); background: var(--surface);
    color: var(--muted); cursor: pointer;
    display: grid; place-items: center; position: relative;
}
.icon-btn:hover { background: var(--bg); color: var(--text); }
.has-dot::after {
    content: ""; position: absolute; top: 9px; right: 10px;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--red); border: 2px solid var(--surface);
}
.menu-toggle { display: none; }

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    border: 0; border-radius: 10px; cursor: pointer;
    padding: 10px 15px; font: inherit; font-size: 13.5px; font-weight: 600;
    line-height: 1.25; white-space: nowrap;
    transition: background .15s var(--ease), box-shadow .15s var(--ease), transform .08s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--primary); color: #fff; box-shadow: 0 4px 12px rgba(47, 111, 237, .24); }
.btn-primary:hover { background: var(--primary-dark); box-shadow: 0 6px 18px rgba(47, 111, 237, .30); }
.btn-light { background: #fff; color: var(--text); width: 100%; justify-content: center; }
.btn-sm { padding: 7px 12px; font-size: 12.5px; }

/* ---------- cards ---------- */

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 20px;
}
.card-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 18px;
}
.card-head p { font-size: 12.5px; margin-top: 3px; line-height: 1.45; }

/* A small input parked in a card header — a date the card as a whole is about. */
.head-field { flex: none; width: 170px; gap: 4px; }
.head-field label { font-size: 11.5px; color: var(--muted); }
.head-field input { padding-top: 7px; padding-bottom: 7px; font-size: 13px; }

/* A single figure parked in a card header — label above, amount below. */
.head-figure { text-align: right; line-height: 1.3; flex: none; }
.head-figure strong { display: block; font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.head-figure-note { display: block; font-size: 12px; font-weight: 650; margin-top: 3px; }
.head-figure-note.is-invest { color: var(--amber); }
.head-figure-note.is-left { color: var(--muted); }

.grid-2 { display: grid; grid-template-columns: 1.55fr 1fr; gap: 20px; }
.grid-2--wide { grid-template-columns: 1.55fr 1fr; align-items: start; }
.stack { display: flex; flex-direction: column; gap: 20px; }

/* ---------- the day's till ---------- */

/* One card read as a single sum: takings, plus collections, less what was paid
   out, is what should be in the drawer. The operators sit between the figures
   so the row reads the way it would be worked out on paper. */
.till-flow {
    display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap;
}
.till-step {
    flex: 1 1 150px; min-width: 0;
    padding: 13px 15px; border-radius: 14px;
    /* A hair of top-light on the tint gives the tile a lifted, rounded feel. */
    background: linear-gradient(180deg, #fafbfe, #f4f7fc);
    border: 1px solid var(--line);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7);
    transition: transform .15s var(--ease), box-shadow .15s var(--ease);
}
.till-step:hover {
    transform: translateY(-1px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), var(--shadow-xs);
}
/* The operator sits in its own quiet chip so the eye reads figure → sign →
   figure, the way the sum is worked on paper. */
.till-op {
    flex: 0 0 auto; align-self: center;
    display: grid; place-items: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--surface); border: 1px solid var(--line);
    font-size: 15px; font-weight: 700; color: var(--muted);
}
.till-label {
    font-size: 12px; color: var(--muted); font-weight: 600;
    text-transform: uppercase; letter-spacing: .02em;
}
.till-value {
    font-size: 23px; font-weight: 750; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    margin: 5px 0 0; line-height: 1.2;
}
.till-note { font-size: 11.5px; color: var(--muted); margin-top: 4px; line-height: 1.45; }
/* The cash/credit breakdown reads as a figure, not a footnote. */
.till-split { margin-top: 2px; font-weight: 650; color: var(--text); }

/* The answer to the sum carries the weight the others do not: a deeper tint,
   a soft ring of colour, and the figure in the brand blue. */
.till-step.is-total {
    background: linear-gradient(180deg, rgba(47, 111, 237, .10), rgba(47, 111, 237, .05));
    border-color: rgba(47, 111, 237, .28);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 4px 14px rgba(47, 111, 237, .12);
}
.till-step.is-total .till-label { color: var(--primary-dark); }
.till-step.is-total .till-value { font-size: 27px; color: var(--primary-dark); }
.till-value.neg { color: var(--red); }
.till-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }

@media (max-width: 700px) {
    /* Stacked, the operators belong at the start of the line they apply to. */
    .till-flow { display: grid; grid-template-columns: 22px 1fr; align-items: center; gap: 8px 4px; }
    .till-step { grid-column: 2; }
    .till-step:first-child { grid-column: 1 / -1; }
    .till-op { justify-self: center; }
}

/* ---------- today, one panel ---------- */

/* The day's headline figures and the drawer sum that explains them read as one
   card: the tiles up top, a hairline, then the cash flow that nets to what is
   left. The tiles shed their own card chrome so they sit as inner cells. */
.today-panel { padding: 16px; }
.today-panel .card-head { margin-bottom: 14px; }
.today-panel .stat-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
.today-panel .stat {
    padding: 12px 13px;
    border: 1px solid var(--line); border-radius: 11px;
    background-color: #fafbfe;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7);
}
.today-panel .stat-icon { top: 12px; right: 12px; width: 28px; height: 28px; border-radius: 9px; }
.today-panel .stat-icon .icon { width: 14px; height: 14px; }
.today-panel .stat-label { font-size: 11.5px; padding-right: 34px; }
.today-panel .stat-value { font-size: 21px; margin-top: 3px; }
.today-panel .stat-foot { font-size: 11px; margin-top: 9px; padding-top: 8px; }

/* The drawer sum, tightened to sit under the tiles as a compact strip. */
.today-panel .till-flow { margin-top: 12px; padding-top: 12px; gap: 6px; border-top: 1px solid var(--line); }
.today-panel .till-step { padding: 10px 12px; border-radius: 11px; }
.today-panel .till-label { font-size: 11px; }
.today-panel .till-value { font-size: 19px; margin-top: 3px; }
.today-panel .till-step.is-total .till-value { font-size: 21px; }
.today-panel .till-note { font-size: 11px; margin-top: 3px; }
.today-panel .till-op { width: 22px; height: 22px; font-size: 13px; }

@media (max-width: 760px) {
    .today-panel .stat-grid { grid-template-columns: 1fr; }
}

/* ---------- stat tiles ---------- */

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
/* A denser row that fits all five lifetime tiles across a single line. The
   figure and its chrome shrink so the numbers stay on one line each. */
.stat-grid--compact { grid-template-columns: repeat(5, 1fr); gap: 12px; }
.stat-grid--compact .stat { padding: 13px 14px; }
.stat-grid--compact .stat-icon { top: 12px; right: 12px; width: 28px; height: 28px; border-radius: 9px; }
.stat-grid--compact .stat-icon .icon { width: 14px; height: 14px; }
.stat-grid--compact .stat-label { font-size: 11.5px; padding-right: 34px; }
.stat-grid--compact .stat-value { font-size: 20px; margin-top: 4px; }
.stat-grid--compact .stat-foot { font-size: 11px; margin-top: 9px; padding-top: 8px; }
/* Names a group of tiles. The flex gap already spaces the page, so the caption
   pulls itself down onto the grid it belongs to. */
.grid-title {
    font-size: 12.5px; font-weight: 650; color: var(--muted);
    letter-spacing: .01em; margin: 4px 2px -14px;
}

/*
 * A tile is read in one order: what it is, how much, and what that compares
 * to. So the icon steps out of that column and sits in the corner as a colour
 * marker, the number gets the room it deserves, and the footnote is fenced off
 * below a hairline instead of crowding the figure.
 *
 * Each accent is declared once as a variable, and the corner tint, the icon
 * chip and anything else that wants the colour all read it from there.
 */
.stat {
    position: relative;
    padding: 18px;
    --accent: var(--primary);
    --accent-soft: rgba(47, 111, 237, .13);
    /* A breath of the accent behind the icon — enough to group the tiles by
       colour at a glance, too faint to compete with the number. */
    background-image: radial-gradient(150px 110px at 100% 0%, var(--accent-soft), transparent 72%);
}
.accent-green  { --accent: var(--green);   --accent-soft: rgba(18, 166, 122, .14); }
.accent-blue   { --accent: var(--primary); --accent-soft: rgba(47, 111, 237, .13); }
.accent-violet { --accent: var(--violet);  --accent-soft: rgba(124, 92, 240, .14); }
.accent-amber  { --accent: var(--amber);   --accent-soft: rgba(232, 145, 42, .16); }

.stat-icon {
    position: absolute; top: 16px; right: 16px;
    width: 36px; height: 36px; border-radius: 11px;
    display: grid; place-items: center;
    background: var(--surface);
    color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent-soft), var(--shadow-xs);
}
.stat-icon .icon { width: 17px; height: 17px; }

.stat-body { min-width: 0; }
/* Keep the label clear of the icon; the number may run the full width. */
.stat-label { font-size: 12.5px; color: var(--muted); font-weight: 600; padding-right: 46px; }
.stat-value { font-size: 27px; font-weight: 700; letter-spacing: -.022em; margin: 6px 0 0; line-height: 1.25; }
.stat-foot {
    display: flex; align-items: center; gap: 8px; font-size: 12px; flex-wrap: wrap;
    margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--line);
}
.stat-foot .link { font-size: 12.5px; }
/* A second footnote line continues the first, so it drops the rule above it. */
.stat-split { margin-top: 5px; padding-top: 0; border-top: 0; }
.stat-split .muted { color: var(--text); font-weight: 650; }

/* A tile that leads somewhere says so when the pointer is on it. */
.stat:has(.link) { transition: box-shadow .18s var(--ease), transform .18s var(--ease); }
.stat:has(.link):hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }

/*
 * The change against yesterday is a verdict, so it is coloured by whether it
 * is good news — not by which way the arrow points. Spending less is a fall
 * and a win at the same time, and the tile that says so marks itself is-good.
 */
.delta {
    display: inline-flex; align-items: center; gap: 3px; font-weight: 650;
    padding: 2px 8px 2px 6px; border-radius: 999px; font-size: 11.5px;
    background: rgba(107, 118, 137, .12); color: var(--muted);
}
.delta .icon { width: 12px; height: 12px; }
.delta.is-up, .delta.is-good { background: rgba(18, 166, 122, .13); color: var(--green); }
.delta.is-down, .delta.is-bad { background: rgba(224, 74, 95, .12); color: var(--red-ink); }

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

.seg {
    display: inline-flex; background: var(--bg);
    border: 1px solid var(--line); border-radius: 9px; padding: 3px;
}
.seg button {
    border: 0; background: none; cursor: pointer;
    padding: 5px 12px; border-radius: 7px;
    font: inherit; font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.seg button.is-active { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(19, 26, 43, .1); }

.bars { display: flex; align-items: flex-end; gap: 12px; height: 210px; padding-top: 8px; }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 9px; height: 100%; }
.bar-track { flex: 1; width: 100%; display: flex; align-items: flex-end; }
.bar {
    width: 100%; border-radius: 8px 8px 4px 4px;
    background: linear-gradient(180deg, var(--primary), #6f9bf5);
    position: relative; min-height: 6px;
}
.bar-col:last-child .bar { background: linear-gradient(180deg, var(--violet), #a98ef7); }
.bar-tip {
    position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
    background: var(--sidebar); color: #fff;
    font-size: 11px; font-weight: 600; white-space: nowrap;
    padding: 4px 8px; border-radius: 6px;
    opacity: 0; transition: opacity .15s; pointer-events: none;
}
.bar:hover .bar-tip { opacity: 1; }
.bar-label { font-size: 12px; color: var(--muted); font-weight: 500; }

.chart-foot {
    display: flex; gap: 28px; flex-wrap: wrap;
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.chart-foot div { display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; }
.chart-foot strong { font-size: 15px; }

/* ---------- donut ---------- */

.donut-wrap { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.donut { width: 168px; height: 168px; }
.donut-value { text-anchor: middle; font-size: 19px; font-weight: 700; fill: var(--text); }
.donut-caption { text-anchor: middle; font-size: 9.5px; fill: var(--muted); }

.legend { list-style: none; margin: 0; padding: 0; width: 100%; display: flex; flex-direction: column; gap: 9px; }
.legend li { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.legend-label { flex: 1; color: var(--muted); }
.dot { width: 9px; height: 9px; border-radius: 3px; flex: none; }

/* ---------- table ---------- */

.table-wrap { overflow-x: auto; margin: 0 -20px -20px; padding: 0 20px 4px; }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
    text-align: left; font-size: 11px; font-weight: 650;
    /* Uppercase + wide tracking is a Latin device; Bengali headers keep their
       natural case and only borrow the muted colour. */
    letter-spacing: .04em; color: var(--muted);
    padding: 0 12px 11px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.table td { padding: 13px 12px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background .12s var(--ease); }
.table tbody tr:hover { background: var(--bg); }
.table .num { text-align: right; }
.table th:first-child, .table td:first-child { padding-left: 4px; }
.table th:last-child, .table td:last-child { padding-right: 4px; }

.badge {
    display: inline-block; padding: 3px 9px; border-radius: 999px;
    font-size: 11.5px; font-weight: 650;
}
.badge--paid { background: rgba(18, 166, 122, .12); color: var(--green); }
.badge--pending { background: rgba(232, 145, 42, .14); color: var(--amber); }
.badge--refund { background: rgba(224, 74, 95, .12); color: var(--red); }

/* ---------- rank list ---------- */

.rank { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 15px; }
.rank li { display: flex; gap: 11px; align-items: flex-start; }
.rank-no {
    width: 22px; height: 22px; border-radius: 7px; flex: none;
    background: var(--bg); color: var(--muted);
    display: grid; place-items: center; font-size: 11.5px; font-weight: 700;
}
.rank-body { flex: 1; min-width: 0; }
.rank-top { display: flex; justify-content: space-between; gap: 10px; font-size: 13.5px; margin-bottom: 6px; }
.rank-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-foot { display: flex; justify-content: space-between; font-size: 11.5px; margin-top: 5px; }

.meter { height: 6px; border-radius: 999px; background: var(--bg); overflow: hidden; }
.meter span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--primary), var(--violet)); }

/* ---------- alerts ---------- */

.alerts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.alerts li {
    display: flex; align-items: center; gap: 11px;
    padding: 10px; border-radius: 10px; background: var(--bg);
}
.alerts li > div { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.alert-icon { color: var(--amber); display: grid; place-items: center; flex: none; }
.alert-name { font-size: 13.5px; }
.alert-count { font-size: 13px; white-space: nowrap; }
.alert-count strong { color: var(--red); font-size: 15px; }

/* ---------- responsive ---------- */

.scrim { display: none; }

@media (max-width: 1180px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .grid-2, .grid-2--wide { grid-template-columns: 1fr; }
}

@media (max-width: 820px) {
    .menu-toggle { display: grid; }
    .search { display: none; }
    .content { padding: 16px; }
    .topbar { padding: 12px 16px; gap: 10px; }
    .topbar-actions { margin-left: auto; }
    .topbar-actions .btn span { display: none; }

    .sidebar {
        position: fixed; inset: 0 auto 0 0; z-index: 40;
        transform: translateX(-100%); transition: transform .22s ease;
    }
    body.nav-open .sidebar { transform: none; }
    body.nav-open .scrim {
        display: block; position: fixed; inset: 0; z-index: 30;
        background: rgba(19, 26, 43, .45);
    }
}

@media (max-width: 560px) {
    .stat-grid { grid-template-columns: 1fr; }
    .page-heading p { display: none; }
}

/* ============================================================
   Application chrome added with the real backend
   ============================================================ */

/* ---------- flash messages ---------- */

.flash {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 15px; border-radius: 11px;
    font-size: 13.5px; font-weight: 550;
    border: 1px solid transparent;
}
.flash--success { background: rgba(18, 166, 122, .1); border-color: rgba(18, 166, 122, .28); color: #0b6d50; }
.flash--error { background: rgba(224, 74, 95, .1); border-color: rgba(224, 74, 95, .28); color: #9d2537; }
.flash .icon { flex: none; }
.flash .link { margin-left: auto; color: inherit; text-decoration: underline; }

/* Flash messages live in a fixed stack in the top-right corner rather than
   pushing the page down, and fade themselves out after a few seconds. */
.toasts {
    position: fixed; top: 92px; right: 18px; z-index: 70;   /* clears the sticky topbar */
    display: flex; flex-direction: column; gap: 10px;
    width: min(400px, calc(100vw - 32px));
    pointer-events: none;
}
.toasts .flash {
    pointer-events: auto;
    box-shadow: var(--shadow-lg);
    opacity: 1; transform: translateY(0);
    transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.toasts .flash--success { background: #e6f7f1; }
.toasts .flash--error { background: #fdecef; }
.toasts .flash.is-hiding { opacity: 0; transform: translateY(-8px); }

@media (max-width: 640px) {
    .toasts { top: 80px; right: 12px; left: 12px; width: auto; }
}

/* ---------- page utilities ---------- */

.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }
.grow { flex: 1; min-width: 0; }
.mt { margin-top: 14px; }
.mb { margin-bottom: 14px; }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.small { font-size: 12.5px; }
.strong { font-weight: 650; }
.pos { color: var(--green); }
.neg { color: var(--red); }
.empty { padding: 40px 18px; text-align: center; color: var(--muted); font-size: 13.5px; line-height: 1.6; }

.btn-ghost { background: var(--bg); color: var(--text); border: 1px solid var(--line); }
.btn-ghost:hover { background: #eceffa; border-color: #cfd6e8; }
.btn-danger { background: rgba(224, 74, 95, .1); color: var(--red-ink); border: 1px solid rgba(224, 74, 95, .25); }
.btn-danger:hover { background: rgba(224, 74, 95, .18); }
.btn-block { width: 100%; justify-content: center; }
.btn-lg { padding: 13px 20px; font-size: 15px; border-radius: 12px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- quick actions ---------- */

.quick { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
.quick a {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 15px 12px; display: flex; flex-direction: column; gap: 9px;
    box-shadow: var(--shadow); transition: transform .12s, border-color .12s;
}
.quick a:hover { transform: translateY(-2px); border-color: var(--primary); }
.quick .quick-icon { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; background: rgba(47, 111, 237, .1); color: var(--primary); }
.quick strong { font-size: 13.5px; font-weight: 600; }

/* ---------- forms ---------- */

.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.form-grid--3 { grid-template-columns: repeat(3, 1fr); }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: 12.5px; font-weight: 600; color: var(--text); }
.field .hint { font-size: 11.5px; color: var(--muted); line-height: 1.5; }

input[type=text], input[type=number], input[type=date], input[type=search],
input[type=email], input[type=password], select, textarea {
    border: 1px solid var(--line); background: var(--surface); color: var(--text);
    border-radius: 10px; padding: 10px 12px; font: inherit; font-size: 14px;
    line-height: 1.4; width: 100%; outline: none;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
input:hover:not(:focus):not([readonly]):not(:disabled),
select:hover:not(:focus):not(:disabled),
textarea:hover:not(:focus) { border-color: #cfd6e8; }
input:focus, select:focus, textarea:focus { border-color: var(--primary); box-shadow: var(--ring); }
::placeholder { color: #9aa3b5; }
input[readonly], input:disabled, select:disabled { background: var(--bg); color: var(--muted); cursor: not-allowed; }

/* Native selects keep their caret but lose the platform chrome mismatch. */
select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7689' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 11px center; padding-right: 34px; }
[dir=rtl] select { background-position: left 11px center; padding: 10px 12px 10px 34px; }

textarea { resize: vertical; min-height: 78px; }

/* File pickers get the same frame as a text input; the button inside them is
   the browser's own, so it only needs to be sized to match. */
input[type=file] {
    border: 1px solid var(--line); background: var(--surface); color: var(--text);
    border-radius: 10px; padding: 8px 10px; font: inherit; font-size: 13.5px;
    width: 100%; outline: none;
}
input[type=file]:focus { border-color: var(--primary); box-shadow: var(--ring); }
input[type=file]::file-selector-button {
    border: 1px solid var(--line); background: var(--bg); color: var(--text);
    border-radius: 8px; padding: 6px 12px; margin-right: 10px;
    font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
input[type=file]::file-selector-button:hover { background: #eceffa; border-color: #cfd6e8; }
[dir=rtl] input[type=file]::file-selector-button { margin: 0 0 0 10px; }

/* A stacked form: one field per row, unlike the inline `.filters` bar. */
.form-stack { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }

.form-actions { display: flex; gap: 10px; justify-content: flex-end; align-items: center; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }

/* A form that cannot be submitted says why, next to the button that is off. */
.form-actions .hint { margin-right: auto; font-size: 12.5px; line-height: 1.4; }
.form-actions .hint.neg { color: var(--red-ink); font-weight: 600; }

/* A figure the shop cannot honour: more leaving the shelf than is on it. */
input.is-bad, input[readonly].is-bad {
    border-color: var(--red-ink);
    color: var(--red-ink);
    background: rgba(224, 74, 95, .06);
}

/* ---------- filter bar ---------- */

.filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.filters .field { min-width: 150px; }
.filters .field--wide { flex: 1; min-width: 220px; }

/* ---------- tabs / segmented links ---------- */

.tabs { display: flex; gap: 4px; flex-wrap: wrap; background: var(--bg); border: 1px solid var(--line); border-radius: 11px; padding: 4px; }
.tabs a { padding: 7px 13px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--muted); }
.tabs a:hover { color: var(--text); }
.tabs a.is-active { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(19, 26, 43, .1); }

/* ---------- pagination ---------- */

.pager { display: flex; gap: 6px; align-items: center; justify-content: flex-end; margin-top: 16px; font-size: 13px; }
.pager a, .pager span {
    min-width: 34px; height: 34px; padding: 0 10px; border-radius: 9px;
    border: 1px solid var(--line); background: var(--surface);
    display: inline-flex; align-items: center; justify-content: center; font-weight: 600;
}
.pager a:hover { border-color: var(--primary); color: var(--primary); }
.pager .is-current { background: var(--primary); border-color: var(--primary); color: #fff; }
.pager .is-muted { border: 0; background: none; color: var(--muted); font-weight: 500; }

/* ---------- POS ---------- */

.pos-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 20px; align-items: start; }
.pos-search { position: relative; }
.pos-results {
    position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; right: 0;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow); max-height: 320px; overflow-y: auto; display: none;
}
.pos-results.is-open { display: block; }
.pos-results button {
    width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
    padding: 10px 13px; font: inherit; display: flex; gap: 10px; align-items: center;
    border-bottom: 1px solid var(--line);
}
.pos-results button:last-child { border-bottom: 0; }
.pos-results button:hover, .pos-results button.is-cursor { background: var(--bg); }
.pos-results .r-name { flex: 1; font-size: 13.5px; }
.pos-results .r-meta { font-size: 12px; color: var(--muted); white-space: nowrap; }
.pos-results .r-out { color: var(--red); }
.pos-results button.is-out { cursor: not-allowed; opacity: .55; }
.pos-results button.is-out:hover { background: none; }

.cart-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.cart-table th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 0 8px 9px; border-bottom: 1px solid var(--line); }
.cart-table td { padding: 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.cart-table input { padding: 7px 9px; font-size: 13.5px; }
.cart-table .qty-in { width: 62px; text-align: center; }

/* Quantity stepper: − [ n ] + */
.qty-stepper { display: inline-flex; align-items: center; gap: 6px; }
.qty-btn {
    flex: 0 0 30px; width: 30px; height: 30px; padding: 0;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--muted);
    font-size: 16px; line-height: 1; cursor: pointer;
    display: grid; place-items: center; user-select: none;
}
.qty-btn:hover { border-color: var(--primary); color: var(--primary); }
.qty-btn:active { transform: translateY(1px); }
.qty-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.cart-table .line-total { font-weight: 650; white-space: nowrap; }
/* Loose goods can be sold by the taka, so the total doubles as an input. */
.cart-table .amt-in { width: 110px; text-align: right; font-weight: 650; }
.icon-x { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); cursor: pointer; font-size: 15px; line-height: 1; }
.icon-x:hover { border-color: var(--red); color: var(--red); }

.totals { display: flex; flex-direction: column; gap: 9px; font-size: 13.5px; }
.totals > div { display: flex; justify-content: space-between; gap: 12px; }
.totals .t-grand { border-top: 1px solid var(--line); padding-top: 11px; font-size: 17px; font-weight: 700; }
.totals .t-due { font-size: 15px; font-weight: 650; }

/* ---------- invoice ---------- */

.invoice { max-width: 860px; }
.invoice-head { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.invoice-head h2 { font-size: 22px; }
.invoice-meta { display: flex; flex-direction: column; gap: 3px; font-size: 13px; color: var(--muted); }
.invoice-total { display: flex; flex-direction: column; gap: 8px; margin-left: auto; max-width: 300px; width: 100%; }
.invoice-total > div { display: flex; justify-content: space-between; gap: 20px; font-size: 13.5px; }
.invoice-total .grand { border-top: 1px solid var(--line); padding-top: 9px; font-size: 17px; font-weight: 700; }

/* ---------- misc panels ---------- */

.kv { display: flex; flex-direction: column; gap: 11px; font-size: 13.5px; }
.kv > div { display: flex; justify-content: space-between; gap: 14px; }
.kv span { color: var(--muted); }
.kv strong { font-weight: 650; }

.pl-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.pl-table td { padding: 11px 4px; border-bottom: 1px solid var(--line); }
.pl-table td:last-child { text-align: right; font-weight: 650; white-space: nowrap; }
.pl-table .is-sub td { color: var(--muted); font-size: 13px; padding-left: 18px; }
.pl-table .is-total td { border-top: 2px solid var(--line); border-bottom: 0; font-size: 16px; font-weight: 700; padding-top: 14px; }

details.inline-form { display: inline-block; }
details.inline-form > summary { list-style: none; cursor: pointer; }
details.inline-form > summary::-webkit-details-marker { display: none; }
details.inline-form .pop {
    position: absolute; z-index: 25; margin-top: 8px; right: 24px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow); padding: 14px; width: min(320px, calc(100vw - 48px));
    display: flex; flex-direction: column; gap: 10px;
}

/* ---------- auth ---------- */

.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; background: var(--bg); }
.auth-card { width: min(400px, 100%); background: var(--surface); border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow); padding: 28px; }
.auth-card .brand { justify-content: center; margin-bottom: 6px; }
.auth-card h1 { text-align: center; margin-bottom: 4px; }
.auth-card > p { text-align: center; color: var(--muted); font-size: 13.5px; margin-bottom: 20px; }
.auth-card .field + .field { margin-top: 14px; }
.auth-card .btn { margin-top: 18px; }

/* ---------- sidebar footer ---------- */

.who { display: flex; align-items: center; gap: 10px; padding: 10px 8px; }
.who-meta { flex: 1; min-width: 0; line-height: 1.3; }
.who strong,
.who small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who strong { font-size: 13px; color: #e8ecf5; }
.who small { color: var(--sidebar-muted); font-size: 11.5px; }
.who a,
.who button {
    flex: 0 0 auto; color: var(--sidebar-muted); font-size: 12px;
    padding: 5px 9px; border-radius: 8px; background: rgba(255, 255, 255, .06);
    border: 0; font-family: inherit; cursor: pointer;
}
.who a:hover,
.who button:hover { color: #fff; background: rgba(255, 255, 255, .12); }

/* ---------- print ---------- */

.print-sheet { max-width: 780px; margin: 24px auto; background: #fff; padding: 30px; font-size: 13px; color: #1a2233; }
.print-sheet h1 { font-size: 22px; }
.print-sheet table { width: 100%; border-collapse: collapse; margin: 18px 0; }
.print-sheet th, .print-sheet td { padding: 8px 6px; border-bottom: 1px solid #dfe3ee; text-align: left; }
.print-sheet th { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: #6b7689; }
.print-toolbar { max-width: 780px; margin: 20px auto 0; display: flex; gap: 10px; justify-content: flex-end; }

@media print {
    .print-toolbar { display: none; }
    .print-sheet { margin: 0; padding: 0; max-width: none; }
    body { background: #fff; }
}

/* ---------- responsive additions ---------- */

@media (max-width: 1180px) {
    .quick { grid-template-columns: repeat(3, 1fr); }
    .pos-grid { grid-template-columns: 1fr; }
}

@media (max-width: 820px) {
    .form-grid, .form-grid--3 { grid-template-columns: 1fr; }
    .quick { grid-template-columns: repeat(2, 1fr); }
    .filters .field { min-width: 130px; }
    details.inline-form .pop { right: 16px; }
}

@media (max-width: 560px) {
    .quick { grid-template-columns: 1fr 1fr; }
    .form-actions { flex-direction: column-reverse; }
    .form-actions .hint { margin-right: 0; text-align: center; }
    .form-actions .btn { width: 100%; justify-content: center; }
}

/* ---------- language switch ---------- */

.lang-switch {
    display: flex; gap: 4px; padding: 4px; margin-bottom: 10px;
    background: rgba(255, 255, 255, .06); border-radius: 10px;
}
.lang-switch a {
    flex: 1; text-align: center; padding: 6px 8px; border-radius: 7px;
    font-size: 12.5px; font-weight: 600; color: var(--sidebar-muted);
}
.lang-switch a:hover { color: #fff; }
.lang-switch a.is-active { background: rgba(255, 255, 255, .12); color: #fff; }

.lang-switch--light { background: var(--bg); margin: 14px 0 0; }
.lang-switch--light a { color: var(--muted); }
.lang-switch--light a:hover { color: var(--text); }

/* ---------- POS customer card (compact) ---------- */

.card--tight { padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.card--tight .row { gap: 8px; }

.field-title { font-size: 13.5px; font-weight: 650; color: var(--text); }

.due-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    font-size: 11.5px; font-weight: 600;
    background: var(--bg); color: var(--muted);
}
.due-chip.is-owed { background: rgba(224, 74, 95, .1); color: var(--red); }
.due-chip strong { font-size: 12.5px; font-weight: 700; }

.mini-add > summary { list-style: none; cursor: pointer; font-size: 12.5px; }
.mini-add > summary::-webkit-details-marker { display: none; }
.mini-add-row { display: flex; gap: 7px; margin-top: 9px; }
.mini-add-row input { padding: 8px 10px; font-size: 13px; min-width: 0; }
.mini-add-row .btn { flex: none; }

/* ---------- confirm dialog ---------- */

body.is-modal-open { overflow: hidden; }

.modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 20px; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(19, 26, 43, .5); }

.modal-box {
    position: relative;
    width: min(430px, 100%);
    background: var(--surface);
    border-radius: 16px;
    box-shadow: 0 20px 50px rgba(19, 26, 43, .28);
    padding: 22px;
    display: flex; flex-direction: column; gap: 12px;
}
.modal-box h2 { font-size: 16px; }
.modal-text { font-size: 14px; color: var(--muted); line-height: 1.55; }
/* An extra question the dialog can put alongside the warning. */
.modal-box .check {
    display: flex; align-items: flex-start; gap: 10px;
    font-size: 14px; line-height: 1.5;
    padding: 12px; border-radius: 10px;
    background: rgba(224, 74, 95, .08);
    cursor: pointer;
}
.modal-box .check input { margin-top: 2px; width: 16px; height: 16px; flex: none; accent-color: var(--red); }

.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 4px; }
.modal-actions .btn { min-width: 96px; justify-content: center; }

@media (max-width: 560px) {
    .modal-actions { flex-direction: column-reverse; }
    .modal-actions .btn { width: 100%; }
}

/* Deleting is permanent, so it always reads as solid red — one shade louder
   than the tinted `btn-danger` used for reversible cancels. */
.btn-wipe { background: var(--red); color: #fff; border: 1px solid var(--red); }
.btn-wipe:hover { background: var(--red-dark); border-color: var(--red-dark); color: #fff; }

/* ---------- table row actions ----------
   Every list ends in an actions column. They all use the same quiet outline
   button so a row never mixes a bare text link with a bordered control. */

.btn-quiet { background: none; color: var(--text); border: 1px solid var(--line); }
.btn-quiet:hover { background: var(--bg); border-color: #cfd6e8; color: var(--primary-dark); }

.row-actions { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.row-actions form { display: inline-flex; margin: 0; }
.table td .row-actions .btn { padding: 5px 10px; font-size: 12.5px; border-radius: 8px; }

/* ---------- row action menu ----------
   One button per row instead of four. The panel is positioned: fixed and
   placed by script, because .table-wrap scrolls and would otherwise clip it.
   Without JS the details still opens; the panel simply sits under the button
   in the normal way, which is why the fallback offsets are on .row-menu. */
details.row-menu { position: relative; display: inline-block; }
details.row-menu > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 10px; font-size: 12.5px; border-radius: 8px;
}
details.row-menu > summary::-webkit-details-marker { display: none; }
details.row-menu[open] > summary { background: var(--bg); border-color: #cfd6e8; color: var(--primary-dark); }

/* Icon-only trigger: square, so a row of them lines up down the column. */
.row-menu__btn { width: 30px; height: 28px; padding: 0; justify-content: center; color: var(--muted); }
.row-menu__btn .icon { width: 16px; height: 16px; }

.row-menu__list {
    position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
    min-width: 176px; padding: 6px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 12px; box-shadow: var(--shadow);
    display: flex; flex-direction: column; gap: 2px;
}
/* Script takes over once it has measured the button. */
.row-menu__list.is-placed { position: fixed; top: auto; right: auto; margin: 0; }

/* An entry is a link, or a form's button where the action has to POST —
   deleting a row, for one. Both read as the same line in the menu. */
.row-menu__list form { display: block; margin: 0; }

.row-menu__list a,
.row-menu__list button {
    display: block; width: 100%; padding: 8px 10px; border: 0; border-radius: 8px;
    background: none; text-align: start; cursor: pointer;
    font: inherit; font-size: 13px; font-weight: 550; color: var(--text); white-space: nowrap;
}
.row-menu__list a:hover, .row-menu__list a:focus-visible,
.row-menu__list button:hover, .row-menu__list button:focus-visible { background: var(--bg); color: var(--primary-dark); }

.row-menu__list .is-danger { color: var(--red); }
.row-menu__list .is-danger:hover, .row-menu__list .is-danger:focus-visible {
    background: rgba(224, 74, 95, .1); color: var(--red-dark);
}
.modal-actions .btn-wipe { margin-right: auto; }

/* ============================================================
   Polish layer — accessibility, focus, motion, fine detail
   ============================================================ */

/* One visible focus ring for everything reachable by keyboard. Mouse users
   never see it; keyboard users always do. */
:where(a, button, [role="button"], summary, [tabindex]):focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 8px;
}
.nav-item:focus-visible { outline-color: #fff; outline-offset: -2px; }

/* An inline explanation that reads as guidance rather than stray body text. */
.note {
    display: flex; gap: 9px; align-items: flex-start;
    padding: 11px 13px; margin-bottom: 18px;
    background: rgba(47, 111, 237, .06);
    border: 1px solid rgba(47, 111, 237, .16);
    border-radius: 10px;
    font-size: 12.5px; line-height: 1.55; color: #33507f;
}
.note .icon { width: 15px; height: 15px; margin-top: 2px; color: var(--primary); }

/* Sidebar: a calmer active state than the heavy blue glow. */
.nav-item.is-active { box-shadow: 0 4px 12px rgba(47, 111, 237, .28); }

/* Quick actions lift on hover; give them a shadow to lift *into*. */
.quick a:hover { box-shadow: var(--shadow-lg); }

/* Cards that carry a whole page of content sit a touch higher. */
.pos-results { box-shadow: var(--shadow-lg); }

/* Slim, unobtrusive scrollbars inside scrolling panels. */
.table-wrap, .pos-results, .content {
    scrollbar-width: thin;
    scrollbar-color: #cfd6e8 transparent;
}
.table-wrap::-webkit-scrollbar, .pos-results::-webkit-scrollbar { height: 8px; width: 8px; }
.table-wrap::-webkit-scrollbar-thumb, .pos-results::-webkit-scrollbar-thumb {
    background: #cfd6e8; border-radius: 999px;
}
.table-wrap::-webkit-scrollbar-track, .pos-results::-webkit-scrollbar-track { background: transparent; }

/* Respect a stated preference for less movement. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .btn:active, .qty-btn:active, .quick a:hover { transform: none; }
}

/* On a phone the filter bar stacks: every field takes the full width and the
   actions share the last row instead of orphaning one button per line. */
@media (max-width: 560px) {
    .filters { gap: 12px; }
    .filters .field,
    .filters .field--wide { flex: 1 1 100%; min-width: 0; }
    .filters .btn { flex: 1 1 0; }
    .card { padding: 16px; }
    /* Only the bleed changes — the margin shorthand would wipe out .mt's
       top spacing and glue the table header to the filter buttons. */
    .table-wrap { margin-inline: -16px; margin-bottom: -16px; padding: 0 16px 4px; }
    .card-head { flex-direction: column; align-items: stretch; }
    .head-field { width: auto; }
    .card-head .btn { align-self: flex-start; }
}

/* Printed invoices should not carry screen furniture. */
@media print {
    .sidebar, .topbar, .form-actions, .pager, .filters { display: none !important; }
    .card { box-shadow: none; border-color: #ddd; }
    body { background: #fff; }
}

/* ── Searchable select ──────────────────────────────────────────────────────
   Enhancement for `select[data-searchable]`: a button that looks like the
   native control, plus a filterable listbox. The real <select> stays in the
   DOM for submission and validation, parked off-screen but still focusable so
   the browser's "please select an item" bubble has something to point at. */
.ss { position: relative; }

.ss-native {
    position: absolute;
    left: 12px; bottom: 6px;
    width: 1px; height: 1px;
    padding: 0; border: 0;
    opacity: 0;
    pointer-events: none;
}

.ss-trigger {
    display: flex; align-items: center;
    width: 100%; min-height: 42px;
    padding: 10px 34px 10px 12px;
    font: inherit; text-align: start;
    color: var(--text); background: var(--surface);
    border: 1px solid var(--line); border-radius: 10px;
    cursor: pointer;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7689' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
}

[dir=rtl] .ss-trigger { padding: 10px 12px 10px 34px; background-position: left 11px center; }

.ss-trigger:hover { border-color: #cfd6e8; }
.ss-trigger:focus-visible,
.ss.is-open .ss-trigger { border-color: var(--primary); box-shadow: var(--ring); outline: none; }
.ss-trigger.is-placeholder { color: var(--muted); }

.ss-value { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ss-panel {
    position: absolute; z-index: 40;
    top: calc(100% + 6px); left: 0; right: 0;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow-lg);
}

.ss-search { width: 100%; margin-bottom: 6px; }

.ss-list {
    max-height: 260px;
    margin: 0; padding: 0;
    overflow-y: auto;
    list-style: none;
}

.ss-option {
    padding: 9px 10px;
    border-radius: 8px;
    cursor: pointer;
}

.ss-option.is-active { background: var(--bg); }
.ss-option.is-selected { color: var(--primary); font-weight: 600; }
.ss-option[aria-disabled=true] { color: var(--muted); cursor: not-allowed; }

.ss-empty { margin: 6px 4px 2px; color: var(--muted); }

/* ---------- price lots ----------
   Stock bought at two different prices stays two things: the counter picks
   which one it is selling, so both the search list and the cart label the
   older lot apart from the newer one. */

.lot-tag {
    display: inline-block;
    margin-inline-start: 6px;
    padding: 1px 7px;
    font-size: 11px; font-weight: 600; line-height: 1.6;
    border-radius: 999px;
    background: rgba(47, 111, 237, .12); color: var(--primary);
    vertical-align: middle;
}

.lot-tag--old { background: rgba(232, 145, 42, .16); color: var(--amber); }

/* A row with four lots used to run four chips deep. The cell now says only
   how many purchases are behind the stock; the dialog carries the prices. */
.lot-count {
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: 5px;
    padding: 2px 9px;
    font: inherit; font-size: 11.5px; font-weight: 600; line-height: 1.7;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--bg); color: var(--muted);
    cursor: pointer; white-space: nowrap;
}
.lot-count:hover { border-color: #cfd6e8; color: var(--primary-dark); }

/* More than one lot means the counter has an older price to clear first. */
.lot-count--old::before {
    content: ''; width: 6px; height: 6px; flex: none;
    border-radius: 50%; background: var(--amber);
}

.modal-box--wide { width: min(620px, 100%); }

/* A wide table inside the dialog must scroll, not stretch it: the grid column
   would otherwise size itself to the table and push the box off a phone. */
.modal { grid-template-columns: minmax(0, 1fr); }
.modal-box .table-wrap { margin: 0; padding: 0 0 4px; }

/* The product's whole life in one strip: bought, sold, thrown away, what it
   earned and what is still on the shelf. Wraps to two rows on a phone. */
.lot-sum {
    display: grid; gap: 8px;
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
}

.lot-sum__item {
    padding: 9px 11px;
    border: 1px solid var(--line); border-radius: 12px;
    background: var(--bg);
}
.lot-sum__label { font-size: 11.5px; color: var(--muted); }
.lot-sum__value { margin-top: 2px; font-size: 15px; font-weight: 700; white-space: nowrap; }
.lot-sum__foot { margin-top: 1px; font-size: 11.5px; color: var(--muted); }

.lot-sum__item.is-gain .lot-sum__value { color: var(--green); }
.lot-sum__item.is-loss .lot-sum__value { color: var(--red); }

.lot-table { font-size: 13px; }
.lot-table td, .lot-table th { padding: 8px 10px; }
.lot-table tr.is-old td { background: rgba(232, 145, 42, .08); }

.lot-flag {
    margin-inline-start: 6px;
    padding: 1px 7px;
    font-size: 11px; font-weight: 600;
    border-radius: 999px;
    background: rgba(232, 145, 42, .16); color: var(--amber);
}
