h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ---- Ongshidar base styles (functional, not a design pass) ---- */

:root {
    --brand: #1a73e8;
    --ink: #202b3a;
    --muted: #607084;
    --border: #dce4ef;
    --paper: #f8faff;
    --due: #b32121;

    /* --- Admin redesign tokens (Products/Sales reference pass) --- */
    --surface-muted: #f2f6fc;
    --border-subtle: #e4eaf2;
    --warning-bg: #fff1c7;
    --warning-border: #f3df9e;
    --warning-text: #745714;
    --info-bg: #eef4fb;
    --info-border: #cfe0f3;
    --info-accent: #2f6fb0;
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-pill: 999px;
    --text-xs: 0.75rem;
    --text-sm: 0.85rem;
    --text-base: 1rem;
    --text-lg: 1.15rem;
    --text-xl: 1.5rem;
    --control-height: 2.25rem;

    /* The admin content column. .admin-main caps itself at this width; .admin-header keeps
       its full-bleed bar but pads its contents to the same column, so the logo lines up with
       the page title and the account menu with the table's right edge on any screen. */
    --admin-width: 1400px;
    --admin-gutter: 1.5rem;
}

/* Navigation feedback while the outgoing viewport stays fixed until the next page is ready. */
.nav-progress-bar {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0%;
    opacity: 0;
    background: var(--brand);
    z-index: 9999;
    pointer-events: none;
}

/* Icon.razor's inline Lucide SVGs — sized in em so they track the surrounding text/button
   font-size with no per-usage sizing needed, nudged up slightly since an inline SVG's default
   baseline alignment sits a bit low next to Bengali/Latin text otherwise. */
.icon {
    vertical-align: -0.15em;
    flex-shrink: 0;
}
/* Mirrors arrow-left into a right-pointing arrow — avoids maintaining a second, near-identical
   "arrow-right" entry in Icon.razor's dictionary for the one "পরের পাতা →" use. */
.icon-flip {
    transform: scaleX(-1);
}
/* Reuses chevron-down as an "ascending" sort indicator — same reasoning as .icon-flip above. */
.icon-flip-vertical {
    transform: scaleY(-1);
}

body {
    font-family: "Noto Sans Bengali", "Segoe UI", system-ui, sans-serif;
    color: var(--ink);
    background: var(--paper);
    margin: 0;
    /* Safety net — no single element should ever cause the whole page to scroll sideways;
       a layout bug should clip, not push the viewport wider (confirmed live: the mobile
       header row was doing exactly that before its own width was fixed below). */
    overflow-x: hidden;
}

/* Applied by js/overlay-escalation.js while any full-screen dialog/backdrop is open (order-now
   modal, checkout, image picker, gallery lightbox, mobile sheet, ...) — see that script's own
   comment for the bug this fixes: without it, the page underneath a "closed" modal was still
   independently scrollable, so scrolling over the dimmed backdrop moved the page instead of
   the modal, and content below the modal (even the footer) stayed reachable while it was open.
   position:fixed rather than plain overflow:hidden because overflow:hidden alone does not
   reliably stop a touchmove over the backdrop from rubber-band-scrolling the page on iOS
   Safari; the script pins body at its current scroll offset (via top) and restores that exact
   offset on unlock, which is the standard cross-browser-safe way to do this. */
body.ongsi-scroll-locked {
    position: fixed;
    left: 0;
    right: 0;
    overflow: hidden;
}

h1, h2 { color: var(--ink); }
/* Page-title h1s (e.g. "নতুন ক্রয়", "নতুন পণ্য") were rendering at the browser's unstyled
   default (~2em, ~0.67em top/bottom margin) — oversized for this app's density and leaving a
   large gap after BackLink above it. */
h1 { font-size: 1.5rem; margin: 0 0 1rem; }

a { color: var(--brand); }

label {
    display: block;
    margin: 0.75rem 0;
    font-size: 0.9rem;
    color: var(--muted);
}

label input:not([type=checkbox]):not([type=radio]):not([type=file]),
label select, label textarea,
input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]):not([type=file]),
select, textarea {
    display: block;
    width: 100%;
    max-width: 420px;
    box-sizing: border-box;
    margin-top: 0.25rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 1rem;
    line-height: 1.25;
}

/* Remove iOS/Safari native select styling so CSS can fully control appearance —
   without this, iOS renders a custom native picker that ignores padding/height/background.
   The dropdown arrow still renders natively but now respects our layout and colors. */
select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-color: white;
    /* Custom dropdown arrow — a chevron on the right that stays visible on all devices.
       Fits within the padding so it doesn't overlap text. */
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 1.2rem;
    padding-right: 2.4rem;
}

input[type=file] {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.95rem;
}

.checkbox-label, .radio-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: auto;
}
.checkbox-label input, .radio-label input { width: auto; margin: 0; }

/* Adjust.razor's "স্টক বাড়বে / কমবে" direction picker for a গণনা সংশোধন — one line, the two
   radios sitting next to the "স্টক কী হবে?" prompt. */
.adjust-direction { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 1rem; margin: 0.5rem 0 0.25rem; }

/* A due/partial-only filter is common enough to want visible at a glance, not hidden behind
   the ফিল্টার toggle like the date range — sits inline with ফিল্টার/এক্সপোর্ট instead. */
.toolbar-checkbox { font-size: var(--text-sm); color: var(--ink); white-space: nowrap; }

.required-mark {
    color: var(--due);
    margin-left: 0.15rem;
}

.field-help {
    margin: 0.1rem 0 0.75rem;
    font-size: 0.75rem;
    color: #8a8a8a;
    font-style: italic;
    line-height: 1.35;
    max-width: 420px;
}
/* Sits right under a pair of radio-labels (Variants.razor's own স্টক-method choice), whose
   own spacing left this butted right up against the second option with no breathing room. */
.stock-method-help { margin-top: 0.75rem; }

.field-help-hint {
    margin: 0 0 1rem;
    font-size: 0.8rem;
    color: var(--muted);
}

.field-help-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.2rem;
    height: 1.2rem;
    margin-left: 0.3rem;
    background: none;
    color: var(--muted);
    border: none;
    border-radius: 50%;
    padding: 0;
    margin-top: 0;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    vertical-align: middle;
}
.field-help-icon:hover, .field-help-icon:focus-visible { color: var(--brand); }

/* Shared "modal tier" (1100): every true full-screen confirmation dialog on the site
   (.facebook-preview-modal-backdrop, .field-help-backdrop, .order-now-backdrop,
   .mobile-sheet-backdrop, .gallery-backdrop) uses this same z-index. It has to clear
   the highest fixed chrome anywhere on the page — the mobile "⋮" bottom sheet (1001),
   small dropdown panels (901), the bottom nav (800) and the mobile FAB (700) — since a
   dialog like this can be triggered from inside any of them. Raising the dialog's own
   z-index isn't enough by itself when it's nested inside a container that ALSO sets a
   (low) z-index — position + z-index on an ancestor caps its whole subtree, dialog
   included, to that ancestor's level when compared against page-level siblings like the
   FAB. Containers known to host one of these dialogs as a descendant additionally
   escalate their OWN z-index above this tier while the dialog is open (see the
   ":has(...)" rules on .record-row-actions / .row-menu / .storefront-sticky-actions).

   Every "inset: 0" in this file is preceded by the equivalent top/right/bottom/left longhands
   on purpose — not redundancy to clean up. "inset" only exists from Safari 14.1 / Chrome 87;
   on the older phones this app's users actually carry (iPhone 6/6s-era iOS, low-end Android
   with a never-updated WebView) it is silently ignored, which left every fixed backdrop and
   click-catcher sized to nothing: the dialog it belongs to still rendered, but not centered,
   and tapping "outside" never closed it. The longhands are what those browsers honor; newer
   ones just read the same box twice. Same for the "inset: 3px" radio dot further down. */
.field-help-backdrop {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1100;
    padding: 1rem;
    box-sizing: border-box;
}
.field-help-dialog {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.25rem;
    max-width: 420px;
    width: 100%;
    background: var(--paper);
    color: var(--ink);
    box-sizing: border-box;
    min-width: 0;
    max-height: calc(100vh - 2rem);
    max-height: calc(100dvh - 2rem);
    overflow-y: auto;
    overflow-x: hidden;
    text-align: left;
    white-space: normal;
    overflow-wrap: break-word;
}
.field-help-dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin: -1.25rem -1.25rem 1rem;
    padding: .9rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--surface-muted);
}
/* white-space: normal — FieldHelp gets triggered from label rows that set nowrap (e.g.
   .settings-location-label-row, to keep a label+icon on one line), and since white-space
   inherits, that nowrap otherwise cascades into this popup's own text too even though it's
   position: fixed and visually escapes that row — DOM descendants still inherit from their
   ancestors regardless of how they're positioned. Without this reset the whole explanation
   rendered as one unbroken line and overflowed past the dialog's own width. */
.field-help-dialog-body { font-size: 0.9rem; line-height: 1.45; white-space: normal; }
.field-help-dialog-body p { margin: 0 0 0.5rem; }
.field-help-dialog-body ul { margin: 0; padding-left: 1.1rem; }
.field-help-dialog-body li { margin: 0.2rem 0; }

.print-only { display: none; }

.more-info {
    margin: 1rem 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.1rem 1rem;
}
.more-info summary {
    cursor: pointer;
    padding: 0.75rem 0;
    font-weight: bold;
    color: var(--brand);
}
.more-info[open] summary { border-bottom: 1px solid var(--border); margin-bottom: 0.5rem; }

.field-hint { color: var(--muted); font-size: 0.85rem; font-weight: normal; }

.order-actions { justify-content: flex-start; flex-wrap: wrap; }

.add-zone-row { display: flex; gap: 0.5rem; margin: 0.5rem 0; flex-wrap: wrap; }
.add-zone-row input[type="text"] { flex: 2; min-width: 140px; }
.add-zone-row input[type="number"] { flex: 1; min-width: 90px; }

/* A small, closed-by-default "what does this page do" note — visually distinct from .more-info
   (plain box for optional extra fields) via the tinted background + brand-colored left edge, so
   it reads as guidance rather than a form section, while staying out of the way until opened. */
.page-info {
    margin: 0.75rem 0 1.25rem;
    background: #fff6ee;
    border: 1px solid #f0d9c0;
    border-left: 3px solid var(--brand);
    border-radius: 6px;
    font-size: 0.85rem;
    max-width: 620px;
}
.page-info summary {
    cursor: pointer;
    padding: 0.55rem 0.9rem;
    font-weight: 600;
    color: var(--brand);
    list-style: none;
}
.page-info summary::-webkit-details-marker { display: none; }
.page-info summary::before { content: "▸ "; }
.page-info[open] summary::before { content: "▾ "; }
.page-info[open] summary { border-bottom: 1px solid #f0d9c0; }
.page-info-icon { margin-right: 0.15rem; }
.page-info-body {
    padding: 0.7rem 0.9rem 0.85rem;
    color: var(--ink);
    line-height: 1.6;
}
.page-info-body ul { margin: 0.2rem 0 0; padding-left: 1.2rem; }
.page-info-body li { margin: 0.3rem 0; }

.button.danger { background: var(--due); color: white; border-color: var(--due); }
.button.danger:hover { opacity: 0.9; }

.success-banner {
    background: #eaf7ef;
    border: 1px solid #a9dfc0;
    border-radius: 6px;
    padding: 0.75rem 1rem;
    margin: 0 0 1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.success-banner p { margin: 0; color: #1d7a3f; }
.success-banner button { margin: 0; background: transparent; color: #1d7a3f; border: none; font-size: 1.1rem; padding: 0 0.25rem; }
.fb-share-prompt-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
.fb-share-prompt-actions .button { background: var(--brand); color: white; border: 1px solid var(--brand); font-size: 1rem; padding: 0.4rem 1rem; }

/* Facebook's web Share Dialog is reliable on desktop, but mobile browsers and installed
   Facebook apps do not consistently complete the handoff. The project already treats
   641-1100px as its tablet/landscape-phone bridge, so keep every Facebook-specific action
   (including the post-save prompt and a modal opened before resizing) out of that range and
   below. The elements and their behavior remain intact for desktop widths. */
@media (max-width: 1100px) {
    .facebook-share-ui,
    .facebook-share-ui-modal,
    .fb-share-prompt { display: none !important; }
}

.empty-state {
    text-align: center;
    padding: 2.5rem 1rem;
    border: 1px dashed var(--border);
    border-radius: 8px;
    margin: 1rem 0;
}
.empty-state p { color: var(--muted); max-width: 420px; margin: 0 auto 1rem; }

.first-visit-hint {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem 1rem;
    background: var(--surface-muted);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 0.75rem 1rem;
    margin: 0 0 1rem;
}
.first-visit-hint p { margin: 0; flex: 1 1 240px; color: var(--ink); font-size: 0.92rem; }
.first-visit-hint-actions { display: flex; gap: 0.5rem; flex-shrink: 0; }
.first-visit-hint-actions .button { margin-top: 0; }

button, .button {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--brand);
    color: white;
    border: 1px solid var(--brand);
    border-radius: 4px;
    padding: 0.6rem 1.2rem;
    /* Browsers don't let form controls inherit the page font by default — <button> falls back
       to the OS UI font (Arial on this test machine) unless told otherwise, unlike <a>, which
       inherits normally. Arial can't render Bengali, so the browser silently substitutes a
       different fallback font per character than body's "Noto Sans Bengali" — different enough
       metrics to visibly shrink a button's box relative to a same-styled <a> next to it (found
       via the Dashboard's Facebook-share button rendering shorter/narrower than the adjacent
       ⚙️ settings <a>, both using the same .settings-card class). */
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.25;
    cursor: pointer;
    text-decoration: none;
    margin-top: 0.5rem;
    white-space: nowrap;
}
.button.secondary { background: white; color: var(--brand); border: 1px solid var(--brand); }
/* Outlined red — a "log out" or "cancel" action that's real but not the modal-confirmed,
   fully-committed danger .button.danger already means (solid red fill, e.g. an admin delete).
   Same recipe as .button.secondary, just the danger hue instead of the brand one. */
.button.secondary.danger { color: var(--due); border-color: var(--due); }
.button.small { padding: 0.3rem 0.7rem; font-size: 0.8rem; margin-top: 0; }
.row-actions { display: flex; gap: 0.4rem; flex-wrap: nowrap; align-items: center; }

.error { color: var(--due); font-weight: bold; }

/* Applied alongside .error on form-submission failure messages that can otherwise render far
   below the fold on a long form (e.g. many product lines) — a shopkeeper had no way to notice
   why "সংরক্ষণ করুন" did nothing without scrolling all the way back to the top. Fixed
   positioning means it's visible immediately, wherever they were scrolled to, with no JS
   scroll-into-view needed. Not applied to .error text that's part of a page's normal content
   flow (e.g. an inline empty-state message) — only to transient validation/failure feedback. */
.error-toast {
    position: fixed;
    top: var(--space-4);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2000;
    background: #fbeaea;
    border: 1px solid #f3c6c6;
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    box-shadow: 0 4px 16px rgba(0,0,0,0.18);
    max-width: min(92vw, 32rem);
    margin: 0;
}

/* Image-moderation "held for review" notice shown under an upload (Products/Edit, Settings
   logo, Onboarding logo) when the nudity detector saw a person and the photo is waiting for the
   platform admin — calm blue info style, inline (not a fixed toast): the upload DID succeed, this is context,
   not a failure the shopkeeper has to act on. See ImageModerationPolicy.OwnerMessage. */
.moderation-notice {
    background: #f4f9ff;
    border: 1px solid #cfe0f7;
    border-left: 3px solid #1a73e8;
    border-radius: 10px;
    padding: .55rem .8rem;
    margin: .6rem 0 0;
    color: #4c627a;
    font-size: .82rem;
    line-height: 1.5;
}

/* Same fixed-position fix as .error-toast above, green instead of red — for a SUCCESS message
   after an action taken far down a long/dynamic page (a variant table row, a voice-entry
   confirmation that resets the form back to blank once saved). ManageVariants.razor's
   savedMessage used this class with no matching rule at all before this — a plain unstyled <p>,
   invisible below the fold on a page with many variant rows. */
.success-toast {
    position: fixed;
    top: var(--space-4);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2000;
    color: #1d7a3f;
    background: #eaf7ef;
    border: 1px solid #a9dfc0;
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    box-shadow: 0 4px 16px rgba(0,0,0,0.18);
    max-width: min(92vw, 32rem);
    margin: 0;
}

/* Both toasts auto-dismiss: slide in, hold ~5s, fade out and stop taking clicks. Standard
   transient-toast behaviour — several pages (ManageVariants, Settings, the entry forms) set
   one of these once and never clear it, so a "saved" / error message otherwise sat pinned to
   the top of the screen for the rest of the session. Pages that navigate or reload after the
   action get the animation fresh on the new page; a page that stays put (ManageVariants) adds
   @key to its toast <p> so a repeat message remounts the node and replays this. transform in
   every keyframe keeps the translateX(-50%) centring the base rule sets. */
.error-toast,
.success-toast {
    animation: toast-autohide 6s ease forwards;
}
@keyframes toast-autohide {
    0%   { opacity: 0; transform: translate(-50%, -0.6rem); }
    6%   { opacity: 1; transform: translate(-50%, 0); }
    90%  { opacity: 1; transform: translate(-50%, 0); }
    100% { opacity: 0; transform: translate(-50%, -0.6rem); visibility: hidden; pointer-events: none; }
}
@media (prefers-reduced-motion: reduce) {
    .error-toast,
    .success-toast { animation: toast-autohide-plain 6s linear forwards; }
    @keyframes toast-autohide-plain {
        0%, 90% { opacity: 1; transform: translateX(-50%); }
        100%    { opacity: 0; transform: translateX(-50%); visibility: hidden; pointer-events: none; }
    }
}

/* Composable onto .success-banner (rather than replacing it everywhere) for the one case that
   needs it: Voice.razor's success banner appears after CompleteSuccessfully() resets the whole
   parsed-entry confirmation form back to blank, so the page can shrink out from under wherever
   the user was scrolled while reviewing/confirming a long voice-parsed order. Every OTHER
   .success-banner (Dashboard, Products/Purchases/Sales/Expenses list pages, ContactUs) appears
   right after a fresh page load/redirect, always already in view — those stay plain in-flow. */
.success-banner.toast-fixed {
    position: fixed;
    top: var(--space-4);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2000;
    box-shadow: 0 4px 16px rgba(0,0,0,0.18);
    max-width: min(92vw, 32rem);
}
.success { color: #26b050; font-weight: bold; }
.muted { color: var(--muted); }
.contact-line { margin: 0.25rem 0; }

/* table-layout: fixed + explicit per-column shares apply at EVERY width, not just the mobile
   breakpoint below — confirmed live at a mid-size (roughly tablet/small-window) width: browser
   auto-layout gave ধরন's <select> a computed column width narrower than the select's own
   intrinsic content, and the selected ধরন's text rendered fully invisible (not truncated —
   gone) instead of just tight. Fixed layout removes that guesswork at any viewport; the
   percentages themselves were tuned for a phone screen but scale up cleanly on a wider one
   (every column just gets more absolute pixels for the same share). */
.line-item-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    margin-top: 1rem;
    border: 1px solid var(--border);
}
/* The optional scan field above a line-item table (Sales/Purchases/Orders Create.razor) and its
   inline result message — kept plain and small since it sits above an already-full form. Only
   a USB/Bluetooth scanner (or hand-typing) can fill it; unlike দ্রুত বিক্রয়, there's no camera
   button here. Hidden on phones — the app's users are overwhelmingly on mobile, where a
   physical scanner is rare, and a "scan" field with nothing to scan with just reads as broken.
   Selecting the product from the dropdown below always works either way; this is a bonus
   shortcut for a shop's checkout PC with a scanner attached, not a replacement for it. */
/* ".entry-form-section > label" (further down this file) sets display/max-width on every
   direct-child label and, at (0,1,1), out-specifies a plain ".line-scan-field" class selector
   (0,1,0) — matching its own "section > label" shape here is what makes the override (and the
   mobile hide below) actually take effect, instead of silently losing to that rule. */
.entry-form-section > label.line-scan-field { max-width: 320px; margin-bottom: 0.75rem; }
.line-scan-field input { border: 2px solid var(--brand); }
@media (max-width: 640px) {
    .entry-form-section > label.line-scan-field { display: none; }
}
/* Every product barcode field (new product, product edit, variant rows, quick-create dialog):
   input + BarcodeCameraButton on one line, the camera preview wrapping onto its own line below.
   Lives here, globally, rather than in each page's scoped CSS: four scoped copies drifted apart
   (one missed an override and pushed the icon onto its own line), and a scoped selector can't
   reach an <InputText>'s rendered <input> without ::deep anyway.
   Flex, not position:absolute for the icon — absolute + top/bottom:0 stretched the button to the
   whole wrapper's height once the preview opened below the input, hiding the icon.
   !important on the input: the global input rule above ((0,5,1) via its :not() chain) sets
   width:100% (which as a flex basis claims the whole row and pushes the icon down), a 420px
   max-width and a top margin; a class selector can't out-rank it otherwise. */
.barcode-input-row { display: flex; flex-wrap: wrap; align-items: center; column-gap: 0; row-gap: 0.4rem; max-width: 420px; }
/* flex-basis 0, not auto: an <input>'s intrinsic width (~20 characters) is wider than a variant
   table's barcode cell, so an auto basis alone still wraps the icon below it there. */
.barcode-input-row > input { flex: 1 1 0; min-width: 0; width: auto !important; max-width: none !important; margin: 0 !important; }
.barcode-input-row > .barcode-camera-panel,
.barcode-input-row > .barcode-camera-message { flex-basis: 100%; }
/* Set by camera-scan.js while the press-and-hold scan button is held: the phone's long-press
   would otherwise select page text and pop up Copy / Select All / Share. */
html.ongsi-holding, html.ongsi-holding * {
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}
/* Scan accepted: the button turns green until the finger is lifted (one read per press). */
[data-scan-trigger].done { background: #2e9e4f !important; border-color: #fff !important; color: #fff !important; }
/* Brief green frame over the camera picture when a code is accepted (camera-scan.js flash()). */
.scan-flash::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    border: 5px solid #34c759;
    background: rgba(52, 199, 89, 0.22);
    pointer-events: none;
}
[data-scan-trigger] {
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
}
.pos-link-inline {
    display: inline;
    margin: 0 0 0 0.4rem;
    padding: 0;
    background: none;
    border: none;
    color: var(--brand);
    text-decoration: underline;
    font-size: inherit;
}
/* ManageVariants.razor's own management table (name/stock/price/status/on-off) was never part
   of the entry-form six-column shape the shares below are tuned for — it opts back out to its
   natural content-sized columns at every width, same as it already did under the old
   mobile-only version of this rule. */
.line-item-table.variant-manage-table { table-layout: auto; width: auto; }
/* The bare-<button> "✕" remove-line control was inheriting the base button, .button rule's
   full brand-orange fill/padding — far too heavy for a small per-row remove action. */
.line-item-table .remove-line-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    margin: 0;
    background: transparent;
    color: var(--muted);
    border: 0;
    border-radius: 6px;
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
}
.line-item-table .remove-line-btn:hover { color: var(--due); border-color: var(--due); background: #fdecec; }
/* ManageVariants.razor's per-row status pill (icon + "বিক্রি চালু/বন্ধ" wording). The wording
   is in a .vm-label span so a phone can drop it to just the icon (see the mobile block far
   below); the icon alone still reads because active is green and stopped is muted grey. */
.variant-manage-table .vm-status { display: inline-flex; align-items: center; gap: 0.3rem; }
.variant-manage-table .vm-status-on { color: var(--positive, #1d7a3f); }
.variant-manage-table .vm-status-off { color: var(--muted); }
/* Bands rows sharing the same primary (সাইজ/মডেল/...) value together, so a long two-axis list
   (L/কালো, L/সবুজ, L/সাদা, M/কালো, ...) reads as visible groups instead of one undifferentiated
   block — see the @{ } grouping logic in the markup for how groupAlt alternates only when the
   primary value actually changes. Applied .muted-safe: a deactivated row keeps its own .muted
   dimming regardless of which band it's in, so the two states never fight over one background. */
.variant-manage-table tr.vm-row-alt:not(.muted) td { background: var(--surface-muted); }
/* Fixes ManageVariants.razor's "সেভ" button rendering as missing/overflowing next to its price
   input, AT EVERY viewport width, not just mobile — this was never actually a table-width or
   media-query problem. The real cause: the base form-input rule up near the top of this file
   ("input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit])
   :not([type=button]):not([type=file])") chains five :not() pseudo-classes, which gives it
   specificity (0,0,5,1) — higher than ".inline-actions-nowrap input[type=number]"'s (0,0,2,1)
   ever was, so that rule's intended 6rem/100%-of-flex-item width has never actually won the
   cascade; the input was always rendered at the base rule's own width (up to 420px) instead,
   leaving no room for the সেভ button beside it and pushing it out of view. Matching that
   specificity (five class-level selectors here too) is what actually lets this win. */
.line-item-table .inline-actions-nowrap input[type="number"]:not([readonly]):not([disabled]):not([hidden]):not([multiple]) {
    width: 6rem;
    max-width: 6rem;
    flex-shrink: 0;
}
/* .button.small on its own already wins the cascade over a bare .add-line-btn (two classes vs
   one — specificity, not source order), which silently ate this margin on every line-item table
   (Sales/Purchases/Orders Create+Edit all use "button secondary small add-line-btn" together).
   Matching that specificity here is what actually makes the spacing apply. */
.button.small.add-line-btn { margin-top: 1rem; min-height: 2.5rem; font-weight: 600; }
.line-item-table th, .line-item-table td {
    text-align: left;
    /* Without this, a plain short value like "৳0" (মোট) middle-aligns by the browser's own
       table-cell default while every OTHER cell in the same row is stretched taller by an
       input plus a .field-hint line underneath (স্টক/ইউনিট) — the two ended up visibly
       floating at different heights across one row instead of reading as one aligned line,
       exactly the "boxes not in the same line" look. Top-aligning everything means every
       cell's real content (the select/input, or মোট's own text) starts flush at the same row
       position regardless of which neighboring cells happen to carry an extra hint line below. */
    vertical-align: top;
    padding: 0.5rem;
    border: 1px solid var(--border);
}
.line-item-table th {
    font-size: var(--text-sm);
    font-weight: 600;
    background: var(--surface-muted);
}
/* These six columns and their শতাংশ shares are the real shape Sales/Purchases/Orders'
   Create+Edit rows all share — পণ্য, ধরন, পরিমাণ, দাম, মোট, then the remove button — driven by
   what each actually holds: a product name/select (longest), a variant select, two number
   inputs that stay legible when narrow, a formatted total needing room for a comma-grouped
   ৳১৪,৫০,০০০-sized figure, and a small icon-only remove button last. Scales up proportionally on
   tables with fewer columns (the 3-column delivery-zone table) since only nth-child(1..3) ever
   match there. */
.line-item-table th:nth-child(1), .line-item-table td:nth-child(1) { width: 28%; }
.line-item-table th:nth-child(2), .line-item-table td:nth-child(2) { width: 14%; }
.line-item-table th:nth-child(3), .line-item-table td:nth-child(3) { width: 16%; }
.line-item-table th:nth-child(4), .line-item-table td:nth-child(4) { width: 16%; }
.line-item-table th:nth-child(5), .line-item-table td:nth-child(5) { width: 18%; }
.line-item-table th:nth-child(6), .line-item-table td:nth-child(6) { width: 8%; }
/* Most products in a real shop never have a ধরন at all — Sales/Purchases/Orders Create+Edit
   only add the ".no-variants" class to <table> when NONE of the currently-selected products in
   the line list actually have more than one active ধরন (AnyLineHasVariants), which is also the
   state a brand-new, nothing-picked-yet row starts in. Hiding the always-"—" column then, rather
   than always reserving 14% for it, is both less clutter and gives every other column real room
   back — redistributed below in roughly the same proportion the six-column shares already had
   to each other, so nothing looks arbitrarily stretched. Column stays in the DOM (display:none,
   not conditionally rendered) specifically so nth-child positions never shift underneath these
   same selectors depending on which state a given table happens to be in. */
.line-item-table.no-variants th:nth-child(2), .line-item-table.no-variants td:nth-child(2) { display: none; }
.line-item-table.no-variants th:nth-child(1), .line-item-table.no-variants td:nth-child(1) { width: 32%; }
.line-item-table.no-variants th:nth-child(3), .line-item-table.no-variants td:nth-child(3) { width: 19%; }
.line-item-table.no-variants th:nth-child(4), .line-item-table.no-variants td:nth-child(4) { width: 19%; }
.line-item-table.no-variants th:nth-child(5), .line-item-table.no-variants td:nth-child(5) { width: 21%; }
.line-item-table.no-variants th:nth-child(6), .line-item-table.no-variants td:nth-child(6) { width: 9%; }
/* Right-aligned so the digits line up down the মোট column, and overflow-wrap as a last resort:
   a total larger than budgeted breaks onto a second line inside its own cell instead of
   spilling into the one next to it or past the edge of the screen. */
.line-item-table th:nth-child(5), .line-item-table td:nth-child(5) {
    text-align: right;
    overflow-wrap: anywhere;
}
/* min-width: 0 is what actually lets a <select>/<input> honor its cell's fixed percentage
   width above instead of insisting on its own intrinsic content width — without it, a ধরন
   select whose selected option's text was wider than its 14% share either forced the column
   wider than budgeted or (confirmed live) rendered with the text invisible altogether. A
   slightly smaller font gives real variant labels ("লাল / মিডিয়াম") more room to actually fit
   before ever needing to truncate. */
.line-item-table select,
.line-item-table input {
    min-width: 0;
    font-size: 0.9rem;
}
/* select isn't affected by the specificity fight documented on the input rule below (a bare
   "select" in the base global rule is far lower specificity), so a plain class selector is
   enough here to win. The bigger find: the base select{} rule up near the top of this file
   reserves a flat 2.4rem (38px) on the right for its dropdown-arrow background-image, sized for
   an ordinary full-width form field — on a ধরন column's ~50px cell that alone was most of the
   available width, leaving room for maybe one character (confirmed live: at true phone width
   the select rendered with NO visible text at all, not just truncated). Shrinking the arrow
   itself and its reserved space to match this table's own compact scale is what actually frees
   up room for the selected ধরন's text to render at all. */
.line-item-table select {
    padding-left: 0.3rem;
    padding-right: 1.3rem;
    background-position: right 0.35rem center;
    background-size: 0.9rem;
}

/* .data-table: list-page table — full grid lines (row AND column), subtle header background,
   generalized row hover, numeric columns right-aligned via a manual .num class on the relevant
   <td>/<th>. Was originally a softer "no vertical borders" look; switched to a full grid on
   request, matching .line-item-table's (purchase/sale entry-form line items) grid look. */
.data-table {
    width: 100%;
    /* separate (not collapse) so the outer border-radius corners don't get squared off by the
       header cell's own background poking past them — collapse merges cell borders onto the
       table edge itself, which clips a rounded corner. */
    border-collapse: separate;
    border-spacing: 0;
    margin-top: var(--space-4);
    /* #e4e4e4: between --border (#ddd, used elsewhere for stat-cards/form-cards) and
       --border-subtle (#ececec, confirmed live as too faint to see against the page's cream
       background) — visible as a light grid without reading as heavy/boxed. */
    border: 1px solid #e4e4e4;
    border-radius: var(--radius-md);
    /* NOT overflow: hidden — that clipped every row's own RowActionMenu dropdown (position:
       absolute, meant to render below the row) along with the header background it was
       actually meant to clip (confirmed live: the "..." menu's items were rendering, just
       invisible, cut off by the table's own box). The corner cells round themselves instead,
       below — same visual result (no squared-off corner poking past the border-radius) without
       clipping anything that needs to overflow the table. */
}
.data-table th, .data-table td {
    text-align: left;
    padding: var(--space-3);
    border: none;
    border-bottom: 1px solid #e4e4e4;
    border-right: 1px solid #e4e4e4;
}
.data-table th:last-child, .data-table td:last-child { border-right: none; }
.data-table tr:last-child td { border-bottom: none; }
.data-table thead tr:first-child th:first-child { border-top-left-radius: var(--radius-md); }
.data-table thead tr:first-child th:last-child { border-top-right-radius: var(--radius-md); }
.data-table tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius-md); }
.data-table tbody tr:last-child td:last-child { border-bottom-right-radius: var(--radius-md); }
.data-table thead th {
    background: var(--surface-muted);
    font-size: var(--text-sm);
    font-weight: 600;
    border-bottom: 1px solid #e4e4e4;
}
.data-table th.sortable-th { cursor: pointer; user-select: none; }
.data-table th.sortable-th:hover { color: var(--brand); }
.data-table .sort-indicator { font-size: var(--text-xs); margin-left: var(--space-1); }
.data-table .filter-row-inline th { padding: 0.25rem var(--space-2); }
.data-table .filter-row-inline input {
    width: 100%;
    max-width: none;
    margin-top: 0;
    padding: 0.3rem var(--space-2);
    font-size: var(--text-sm);
    font-weight: normal;
}
/* #faf7f2: closer to --paper (#fdfaf6) than --surface-muted (#f5f2ee) was — barely a shade off
   the page background, just enough to show which row you're on. */
.data-table tbody tr:hover { background: #faf7f2; }
/* Keeps the triggering row visibly marked for as long as its "..." menu is open — the panel
   itself is position:fixed now (see .row-menu-panel) and can end up flipped well above the
   trigger on a tall menu, so proximity alone isn't always enough for a busy table to tell which
   row it belongs to. :has() is already relied on elsewhere in this file for the same "does this
   row currently contain an open row-menu" check (see .row-menu:has(.row-menu-panel)); no JS
   needed since the panel only exists in the DOM while RowActionMenu's isOpen is true. */
.data-table tbody tr:has(.row-menu-panel) { background: #f2ece2; }
.record-link { color: var(--ink); font-weight: 600; text-decoration: none; }
.record-link:hover { color: var(--brand); text-decoration: underline; }
.data-table tr.clickable-row { cursor: pointer; }
.data-table tr.inactive-row { opacity: 0.5; }

/* A ধরন (type) sub-row nested under its product's row in লাভ-ক্ষতি's product-profit table —
   slightly recessed so its "↳ Label" reads as a breakdown of the row above, not a sibling
   product. */
.data-table tr.report-variant-row { background: var(--surface-muted, #f7f3ee); font-size: var(--text-sm); }
.data-table tr.report-variant-row:hover { background: #faf7f2; }
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.due-amount { color: var(--due); font-weight: bold; }

/* When a .num cell also carries a trailing .status-badge (e.g. স্টক), text-align:right on the
   td would right-align the number+badge as one unit — shifting the digits left on rows that
   have a badge versus rows that don't, so the numbers stop lining up under the header. Stacking
   them in a column keeps the number on its own right-aligned line always, badge on the next. */
.num-with-badge { display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; }

.due-summary { margin: 0 0 var(--space-3); font-size: var(--text-sm); color: var(--ink); }
.due-summary strong { color: var(--due); }

/* Paid/due breakdown shown next to a বাকি/আংশিক status badge — a shop owner shouldn't have to
   infer one figure from the other when only one is displayed. */
.payment-breakdown { font-size: var(--text-xs); white-space: nowrap; }
.data-table .payment-breakdown { margin-top: 0.2rem; }

/* Status is a quiet dot and label throughout admin and storefront views. */
.status-badge {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: normal;
}
.status-badge::before {
    content: "";
    width: 0.48rem;
    height: 0.48rem;
    flex: 0 0 0.48rem;
    margin-top: 0.37em;
    border-radius: 50%;
    background: currentColor;
}
.status-badge:has(> .icon)::before { display: none; }
.status-badge-neutral { color: #355274; }
.status-badge-positive { color: #206d45; }
.status-badge-warning { color: var(--warning-text); }
.status-badge-danger { color: #a32933; }
.order-advance-badge { margin-top: .35rem; }

/* Compact row actions: pencil/eye/share as .row-icon-btn on wide screens (tooltip via
   title=), collapsing into a .row-menu "⋮" popover below 860px so crowded action cells don't
   overflow on tablet. Same open/catcher/Escape/outside-click mechanism as MoreMenu.razor's
   .nav-dropdown, reused here with distinct class names. */
.row-actions { display: flex; gap: var(--space-2); align-items: center; justify-content: flex-end; }
/* A flex <td> leaves the table grid, so its bottom border ends at a different point
   from the rest of the row. Keep action cells in table layout and align their contents. */
.data-table td.row-actions { display: table-cell; text-align: right; white-space: nowrap; }
.data-table td.row-actions > * + * { margin-left: var(--space-2); }
.row-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    margin: 0;
    /* Match the outlined secondary action beside it so the card action group reads as one. */
    background: transparent;
    color: var(--brand);
    border: 1px solid var(--brand);
    border-radius: var(--radius-sm);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
}
.row-icon-btn:hover { color: var(--brand); border-color: var(--brand); background: #f2ece5; }
.row-menu { position: relative; display: inline-block; }
.row-menu-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    margin: 0;
    background: transparent;
    color: var(--brand);
    border: 1px solid var(--brand);
    border-radius: var(--radius-sm);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.row-menu-trigger:hover { color: var(--brand); border-color: var(--brand); background: #fdf3ec; }
.row-menu-catcher { position: fixed; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: 900; background: transparent; }
/* position: fixed (not absolute) + row-menu-position.js: a table row near the bottom or right
   edge of the screen used to render this panel partly off-screen / clipped by the table's own
   overflow, because "absolute, top:100%, right:0" only ever opens downward and has no idea where
   the viewport edge is. row-menu-position.js measures the trigger + panel and flips it upward /
   shifts it sideways when there isn't room, the same collision-handling approach Floating UI /
   Radix / Bootstrap use for their dropdowns. Starts hidden and JS reveals it once positioned, so
   there's no visible jump from the old top-left corner to the real spot. */
.row-menu-panel {
    position: fixed;
    /* border-box: row-menu-position.js sets max-height to the exact gap it measured between the
       trigger and the chosen viewport edge — with the default content-box sizing that budget
       excluded this padding/border, so a long menu's real (rendered) bottom edge crept past
       where the script meant to stop it, right up against/over the trigger button. */
    box-sizing: border-box;
    margin: 0;
    background: var(--paper);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    min-width: 200px;
    max-width: min(280px, calc(100vw - 1rem));
    z-index: 901;
    padding: 0.35rem;
    display: flex;
    flex-direction: column;
    visibility: hidden;
}
.row-menu-panel.is-positioned { visibility: visible; }
.row-menu-item {
    display: block;
    width: 100%;
    box-sizing: border-box;
    text-align: left;
    background: none;
    color: var(--ink);
    font-size: var(--text-sm);
    text-decoration: none;
    padding: var(--space-2) var(--space-3);
    margin: 0;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    white-space: normal;
}
.row-menu-item:hover { background: #f2ece5; color: var(--brand); }
.row-menu-item-danger { color: var(--due); }
.row-menu-item-danger:hover { background: #fbeaea; color: var(--due); }
@media (max-width: 860px) {
    .row-icon-collapsible { display: none; }
}

/* Order actions row — unified Primary + Menu pattern on desktop and mobile */
.order-actions-row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    justify-content: flex-start;
}

.button.compact {
    height: 36px;
    padding: 0 11px;
    font-size: 15px;
    white-space: nowrap;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.row-menu-trigger.compact {
    width: 36px;
    height: 36px;
    padding: 0;
    font-size: 16px;
}

/* Compact page-title context help — "পণ্য ⓘ" pattern (ContextHelp.razor wrapping
   FieldHelp.razor) replacing PageInfoNote's permanent banner on list pages that have
   adopted the new toolbar system. */
.context-help .field-help-icon { font-size: 1.1rem; width: 1.4rem; height: 1.4rem; vertical-align: 0.05em; }

/* Standalone "ⓘ সাহায্য" placement for pages whose heading isn't a plain <h1> (e.g. Reports,
   whose title lives inside ReportHeader, a shared print/PDF-header component ContextHelp
   shouldn't be embedded in). */
.report-page-help { color: var(--muted); font-size: 0.85rem; margin: 0.25rem 0 0.25rem; }
.report-range-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-3) var(--space-4);
    align-items: end;
    padding: var(--space-4);
    margin: 0 0 var(--space-4);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--surface-muted);
}
.report-range-copy { display: flex; flex-direction: column; gap: 0.15rem; }
.report-range-label { color: var(--muted); font-size: var(--text-sm); }
.report-range-copy strong { font-size: 1.05rem; }
.report-period-presets { grid-column: 1 / -1; }
.report-custom-dates { display: flex; flex-wrap: wrap; gap: var(--space-3); grid-column: 1 / -1; }
.report-custom-dates label { display: flex; flex: 1 1 180px; flex-direction: column; gap: 0.35rem; margin: 0; font-size: var(--text-sm); }
.report-custom-summary { flex: 1 0 100%; margin: 0; color: var(--muted); font-size: var(--text-sm); }
.report-custom-summary strong { color: var(--ink); font-weight: 600; }
.report-range-export { justify-self: end; }

/* List-page toolbar: search + ফিল্টার toggle + এক্সপোর্ট, all one row, wraps on narrow
   widths instead of scrolling/overflowing. */
.list-toolbar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-2); }
.toolbar-search-wrap { position: relative; min-width: 220px; flex: 1 1 220px; }
.toolbar-search-wrap .icon { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 0.95em; }
/* !important needed here: the general input rule above (several :not() clauses) has higher
   specificity than a single class and would otherwise win back the default 0.75rem padding. */
.toolbar-search { width: 100%; height: var(--control-height); padding-left: 2.75rem !important; }
.filter-toggle.active { background: var(--surface-muted); border-color: var(--muted); color: var(--ink); }
/* Row layout with wrapping on tablet/laptop/desktop — a date-range filter with 2-4 fields
   should read as one glance-able line (or two at most), not one field per full-width row. Only
   mobile (see the 640px block below) goes back to a single stacked column, where a row would
   be too cramped. */
.filter-panel {
    background: var(--surface-muted);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin: var(--space-2) 0 var(--space-4);
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3) var(--space-4);
}
.filter-panel > label { flex: 1 1 180px; min-width: 160px; margin: 0; }
.filter-panel > label.checkbox-label { flex: 0 0 auto; }
.filter-panel-actions { display: flex; gap: var(--space-2); flex: 0 0 auto; align-items: center; }
.active-filter-bar { display: flex; align-items: center; gap: var(--space-3); margin: 0 0 var(--space-3); font-size: var(--text-sm); }

/* Export menu ("↓ এক্সপোর্ট ▾") — same dropdown mechanism as .nav-dropdown/.row-menu. */
.export-menu { position: relative; display: inline-block; }
.export-menu-catcher { position: fixed; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: 900; background: transparent; }
.export-menu-panel {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 0.25rem;
    background: var(--paper);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    min-width: 220px;
    z-index: 901;
    padding: 0.35rem;
    display: flex;
    flex-direction: column;
}
.export-menu-item {
    display: block;
    box-sizing: border-box;
    width: 100%;
    text-align: left;
    background: none;
    color: var(--ink);
    font-size: var(--text-sm);
    padding: var(--space-2) var(--space-3);
    margin: 0;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
}
.export-menu-item:hover { background: #f2ece5; color: var(--brand); }

/* Mobile card list (≤640px) — replaces the horizontally-scrolling table for a page. Both
   blocks always render server-side; the 640px media query toggles which is visible (same
   CSS-only approach already used for the admin bottom-nav/desktop-nav split). Every real
   usage carries BOTH "record-card-list" and "mobile-only-list" on the same element — the
   hiding rule below is keyed to that combined selector (specificity 0,2,0) specifically so it
   always beats the plain ".record-card-list { display:flex }" rule regardless of which is
   declared later in this file. A single-class ".mobile-only-list { display:none }" rule here
   previously lost that tie on desktop (identical 0,1,0 specificity, last-declared-wins), so
   both the desktop table AND the "mobile" card list rendered visibly at once above 640px on
   every page using this pattern (confirmed live: Orders/Sales/Purchases all affected). */
.record-card-list.mobile-only-list { display: none; }
/* The newer mobile "ledger" list (see the max-width:640px block, "Mobile ledger list") uses
   .record-list / .record-groups instead of .record-card-list - same hide-by-default rule so
   desktop and tablet never render the phone markup alongside the table. */
.record-list.mobile-only-list, .record-groups.mobile-only-list { display: none; }
/* Generic mobile record-card layout — used by Sales and Purchases (and any future list page
   that adopts a mobile card view instead of a scrolling table) so both stay visually
   identical rather than each page inventing its own. */
.record-card-list { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-4); }
.record-card { border-bottom: 1px solid var(--border-subtle); padding: var(--space-3) 0; }
.record-card.inactive-row { opacity: 0.5; }
.record-card-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); }
/* min-width: 0 is required for a flex child's text-overflow ellipsis to actually kick in —
   without it the title refuses to shrink below its content width and pushes the amount (the
   other thing that needs to stay visible at a glance) off the edge of the card instead. */
.record-card-title { font-weight: 600; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Products/Purchases Index.razor's mobile card uses the product name itself as
   .record-card-title (unlike Orders/Sales, where the product row is a separate .record-card-
   subtitle) — showing a thumbnail there means wrapping .record-card-title in .product-thumb-row
   instead of standing it directly in .record-card-top. This keeps that wrapper taking the same
   flexible share of the row .record-card-title always did (shrinks so .record-card-amount is
   never pushed off), with the ellipsis truncation still happening on the title text itself. */
.record-card-top > .product-thumb-row { flex: 1 1 auto; min-width: 0; }
.record-card-amount { font-weight: 600; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.record-card-subtitle { font-size: var(--text-sm); margin-top: 0.15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* "My Orders" (Storefront/MyOrders.razor) — user-approved layout (confirmed via mockup before
   building): a page header with a home link opposite the logout button, an account card below
   it, then shop-grouped order rows with a thumbnail, date, and color-coded status per row. */
.my-orders-page-header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
.my-orders-back-link { display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--text-sm); color: var(--brand); text-decoration: none; }
.my-orders-back-link:hover { text-decoration: underline; }
.my-orders-page-header h1 { margin: 0.3rem 0 0.15rem; }
.my-orders-account-card { background: white; border: 1px solid var(--border); border-radius: 8px; padding: var(--space-3) var(--space-4); display: flex; align-items: flex-start; gap: var(--space-3); }
.my-orders-account-avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--warning-bg); color: var(--warning-text); display: flex; align-items: center; justify-content: center; font-size: 1.3rem; flex: 0 0 auto; }
.my-orders-account-identity { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; flex: 1 1 auto; min-width: 0; }
.my-orders-account-identity strong { font-size: 1.05rem; }
.my-orders-account-identity .button.secondary.small { margin-top: var(--space-2); }
.my-orders-list-gap { margin-top: var(--space-5); }
/* "চলমান অর্ডার" / "অর্ডার ইতিহাস" tabs — the active tab reads as brand-colored and
   underlined, matching how a link already reads as "the thing you can act on" elsewhere on
   this page, rather than inventing a new selected-state visual language just for this pair. */
.my-orders-tabs { display: flex; gap: var(--space-4); border-bottom: 1px solid var(--border); }
.my-orders-tab { background: none; border: none; border-bottom: 2px solid transparent; margin: 0 0 -1px; padding: 0.5rem 0.1rem; font: inherit; font-weight: 600; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 0.4rem; }
.my-orders-tab.active { color: var(--brand); border-bottom-color: var(--brand); }
.my-orders-tab-count { background: var(--surface-muted, #f7f3ee); color: inherit; border-radius: 999px; padding: 0.05rem 0.5rem; font-size: var(--text-sm); font-weight: 600; }
.my-orders-tab.active .my-orders-tab-count { background: var(--warning-bg); color: var(--brand); }
/* The order row's own headline is now the product name(s), not "অর্ডার #১০" — a customer
   recognizes an order by what's in it. Unlike .record-card-title elsewhere, this deliberately
   wraps instead of truncating: hiding part of what someone ordered behind an ellipsis is worse
   here than a taller card. */
.my-order-row { display: flex; align-items: flex-start; gap: var(--space-3); flex-wrap: wrap; }
.my-order-thumb { width: 44px; height: 44px; border-radius: 8px; background: var(--surface-muted, #f7f3ee); color: var(--muted); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; flex: 0 0 auto; overflow: hidden; }
.my-order-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.my-order-info { flex: 1 1 auto; min-width: 160px; }
.my-order-title { margin: 0; font-weight: 600; }
.my-order-meta-line { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.3rem; font-size: var(--text-sm); color: var(--muted); }
.my-order-due { margin: 0; font-size: var(--text-sm); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.my-order-cancel-reason { margin: 0.3rem 0 0; }
.my-order-cancel-row { display: flex; align-items: center; gap: var(--space-2); margin-top: 0.5rem; }
/* margin-left: auto (not justify-content on the row) so the cancel button stays pinned to the
   right whether or not the status-check WhatsApp button is also present next to it. */
.my-order-cancel-btn { margin-left: auto; }
/* One group per shop on "My Orders" — the shop's own name/contact belongs to the shop once,
   with that shop's own orders listed underneath, rather than repeating it on every order row. */
/* Each shop is its own bordered, lightly-tinted container — a customer with orders from
   several shops should see at a glance which orders belong together, parent (shop) holding
   child (orders) rather than one flat list with only a thin rule between groups. */
.my-orders-shop-group { border: 1px solid var(--border); border-radius: 12px; background: var(--surface-muted, #f7f3ee); padding: var(--space-3) var(--space-4) var(--space-4); }
.my-orders-shop-group + .my-orders-shop-group { margin-top: var(--space-5); }
.my-orders-shop-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); padding-bottom: var(--space-2); border-bottom: 1px solid var(--border); margin-bottom: var(--space-3); }
.my-orders-shop-identity { display: flex; align-items: center; gap: var(--space-2); }
.my-orders-shop-identity .record-link { font-size: 1.1rem; }
.my-orders-shop-icon { width: 32px; height: 32px; border-radius: 50%; background: var(--warning-bg); color: var(--warning-text); display: flex; align-items: center; justify-content: center; font-size: 1rem; flex: 0 0 auto; }
.my-orders-shop-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* The child orders sit indented from the shop's own name, reinforcing the parent/child
   relationship visually, not just via the container's border. Each order card stays white so
   it still reads as a distinct object against the shop container's own tinted background. */
.my-orders-shop-group .record-card-list { margin-left: var(--space-4); }
.my-orders-shop-group .record-card { background: white; border: 1px solid var(--border); border-radius: 8px; padding: var(--space-3); }
.my-orders-edit-form { max-width: 28rem; margin-top: var(--space-2); padding: var(--space-3); border: 1px solid var(--border-subtle); border-radius: 8px; background: var(--surface-muted, #f7f3ee); }

/* Cart is deliberately a compact shopping surface: each store is a clear section, its products
   sit in a scannable grid, and the running total remains visible without hiding the items. */
.cart-page { max-width: 920px; }
.cart-page-heading { display: flex; align-items: end; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); }
.cart-page-heading h1 { margin: 0; display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.cart-page-kicker { display: flex; align-items: center; gap: 0.4rem; margin: 0 0 var(--space-1); color: var(--muted); font-size: var(--text-sm); }
.cart-page-kicker .icon { color: var(--brand); }
.cart-continue-link { display: inline-flex; align-items: center; gap: 0.35rem; padding-bottom: 0.2rem; font-size: var(--text-sm); font-weight: 600; text-decoration: none; white-space: nowrap; }
.cart-continue-link:hover { text-decoration: underline; }
/* Header item-count pill — the equivalent of the old favourites-count badge, but read directly
   off the page's own state rather than a separate JS-maintained DOM write. */
.cart-count-pill { display: inline-block; padding: 0.1rem 0.65rem; border-radius: 999px; background: var(--warning-bg); color: var(--brand); font-size: var(--text-sm); font-weight: 700; }
.empty-state-icon { display: block; margin: 0 auto 0.75rem; font-size: 2.25rem; color: var(--muted); }

/* Header divider — the reference design draws one rule under the whole heading block, not
   under each individual piece of it. */
.cart-page-heading { padding-bottom: var(--space-4); border-bottom: 1px solid var(--border); }

/* Two-column layout: items left, sticky order-summary sidebar right — single column on mobile,
   where the summary instead lives in the fixed .cart-checkout-bar at the bottom of the viewport.
   The sidebar and the bottom bar call the same OpenCheckout and read the same CheckoutNotice, so
   there is exactly one source of truth either way. */
.cart-layout { display: grid; grid-template-columns: 1fr; gap: var(--space-5); align-items: start; }
.cart-main { min-width: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.cart-summary-sidebar { display: none; }
/* Order-summary card — a WHITE card like every other one on this page (not a dark/inverted
   panel): the brand-rust accent already carries enough visual weight on its own via the total
   figure and the CTA button. */
.cart-summary-card { background: white; border: 1px solid var(--border); border-radius: 16px; padding: var(--space-4); box-shadow: 0 1px 2px rgba(43, 43, 43, 0.04); }
.cart-summary-card h2 { margin: 0 0 var(--space-3); font-size: 1.05rem; display: flex; align-items: center; gap: 0.5rem; }
.cart-summary-card-icon { width: 2rem; height: 2rem; border-radius: 8px; background: var(--warning-bg); color: var(--brand); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cart-summary-row { display: flex; justify-content: space-between; gap: var(--space-2); padding: 0.3rem 0; font-size: var(--text-sm); color: var(--muted); }
/* Stands in for the delivery-charge figure (CartBody.razor) while it's genuinely undecided —
   ৳০ there would read as "free delivery", the opposite of the truth, so this is a prompt, not
   a number. Brand-coloured and weighted like the price it replaces, so it draws the eye at the
   exact spot a scanning customer is looking for the charge, not just via the separate warning
   text below the checkout button. */
.cart-delivery-pending { color: var(--brand); font-weight: 600; }
.cart-delivery-free { color: #1d7a3f; font-weight: 600; }
.cart-summary-total { display: flex; align-items: baseline; justify-content: space-between; margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--border); }
.cart-summary-total strong { font-size: 1.6rem; color: var(--brand); }
.cart-summary-card .error.small { margin: var(--space-2) 0 0; }
.cart-summary-cta { width: 100%; margin-top: var(--space-3); min-height: 3rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; }
.cart-summary-note { margin: var(--space-3) 0 0; text-align: center; line-height: 1.4; }
.cart-checkout-bar-notice { margin: 0.2rem 0 0; }
@media (min-width: 992px) {
    .cart-page { max-width: 1100px; }
    .cart-layout { grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr); }
    /* Clears the sticky site header (SiteHeader Sticky="true", itself position:sticky; top:0 —
       see .site-header-sticky) rather than the "top-6" a page with no other sticky chrome could
       use; the header shrinks on scroll but never below roughly this height. */
    .cart-summary-sidebar { display: block; position: sticky; top: 5.25rem; }
}

/* Vendor card. */
.cart-shop-card { background: white; border: 1px solid var(--border); border-radius: 16px; overflow: hidden; box-shadow: 0 1px 2px rgba(43, 43, 43, 0.04); }
.cart-shop-card + .cart-shop-card { margin-top: 0; }
.cart-shop-card-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4); border-bottom: 1px solid var(--border-subtle); }
.cart-shop-card-identity { display: flex; align-items: center; gap: var(--space-3); }
.cart-shop-card-identity strong { font-size: 1rem; }
.cart-shop-card-identity p { margin: 0.1rem 0 0; }
.cart-shop-card-icon { width: 2.5rem; height: 2.5rem; border-radius: 10px; background: var(--warning-bg); color: var(--brand); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cart-shop-visit-link { display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--text-sm); font-weight: 600; color: var(--brand); text-decoration: none; white-space: nowrap; }
.cart-shop-visit-link:hover { text-decoration: underline; }
.cart-shop-visit-link .icon { width: 0.85em; height: 0.85em; }

/* align-items: center, not start — the price+qty column is short and fixed-height while the
   body column varies a lot (a plain line has just the name; one with size/color pickers is much
   taller). Top-aligning left price+qty pinned to the row's top with a big dead gap below them
   whenever the body was taller (the common case), and conversely left the name stranded at the
   top with empty space beneath it whenever the body was shorter than price+qty (e.g. no variant
   pickers). Centering keeps price+qty reading as one anchored unit regardless of which column
   ends up tallest. */
.cart-line { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; align-items: center; gap: var(--space-3); padding: var(--space-4); background: white; margin: 0; }
.cart-line + .cart-line { border-top: 1px solid var(--border-subtle); }
.cart-line-media { width: 72px; height: 72px; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-muted, #f7f3ee); color: var(--muted); display: flex; align-items: center; justify-content: center; font-size: 1.3rem; overflow: hidden; }
.cart-line-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cart-line-body { min-width: 0; padding-top: 0.1rem; }
.cart-line-name { display: inline-block; font-weight: 700; color: var(--ink); text-decoration: none; line-height: 1.35; }
.cart-line-name:hover { color: var(--brand); text-decoration: underline; }
.cart-line-meta, .cart-line-body .error.small { margin: 0.2rem 0 0; }
.cart-line-variant-picker { margin-top: 0.5rem; }
.cart-line-variant-picker label { display: block; }
.cart-line-variant-picker label + label { margin-top: 0.5rem; }
.cart-line-variant-picker select { display: block; width: min(100%, 19rem); margin-top: 0.25rem; background: var(--surface-muted, #f7f3ee); }
.cart-line-side { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-3); }
.cart-line-price { text-align: right; font-variant-numeric: tabular-nums; line-height: 1.4; }
.cart-line-price strong { display: block; font-size: 1rem; white-space: nowrap; }
.cart-line-actions { display: flex; align-items: center; gap: 0.5rem; }
.cart-line-qty { display: inline-grid; grid-template-columns: 2.25rem minmax(3.25rem, auto) 2.25rem; align-items: center; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; background: var(--surface-muted, #f7f3ee); }
.cart-line-qty .icon-button { width: 2.25rem; height: 2.25rem; border: 0; border-radius: 0; color: var(--brand); }
.cart-line-qty .icon-button:hover { background: #fff3e9; }
.cart-line-qty .icon-button:disabled { color: #b8b2ac; background: var(--surface-muted); cursor: not-allowed; }
.cart-line-qty input { width: 3.5rem; min-width: 0; height: 2.25rem; box-sizing: border-box; padding: 0; text-align: center; font: inherit; font-weight: 700; font-variant-numeric: tabular-nums; background: white; border: 0; border-right: 1px solid var(--border); border-left: 1px solid var(--border); outline-offset: -2px; }
.cart-line-remove { width: 2.25rem; height: 2.25rem; color: var(--muted); border-color: transparent; flex-shrink: 0; }
.cart-line-remove:hover { color: var(--due); background: #fff1f1; border-color: #f3d5d5; }

/* Per-shop footer: delivery-area selector on the left, a distinct bordered mini order-summary
   card on the right — two columns on a wide card, stacked full-width on mobile. */
.cart-shop-footer { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-4); background: var(--surface-muted, #f7f3ee); border-top: 1px solid var(--border-subtle); }
.cart-shop-delivery { flex: 1 1 16rem; min-width: 0; }
.cart-shop-delivery label { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.35rem; }
.cart-shop-delivery select { width: 100%; background: white; }
/* margin-left: auto keeps this pinned to the right edge even when it wraps onto its own row
   (a narrow left column with a long shop name, or a tablet-width viewport) — without it,
   flex-wrap alone left-aligns a wrapped item, same as any other left-to-right flex row. */
.cart-shop-total-box { flex: 0 0 auto; min-width: 14rem; margin-left: auto; background: white; border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-3); }
.cart-shop-total-box .cart-summary-row { padding: 0.15rem 0; }
.cart-shop-total-box-final { display: flex; justify-content: space-between; align-items: baseline; margin-top: 0.3rem; padding-top: 0.4rem; border-top: 1px solid var(--border-subtle); font-variant-numeric: tabular-nums; }
.cart-shop-total-box-final strong { color: var(--ink); font-size: 1.05rem; }

.cart-checkout-bar { position: sticky; bottom: var(--space-3); margin-top: var(--space-1); padding: var(--space-3) var(--space-4); background: white; border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: 0 8px 22px rgba(43, 43, 43, 0.12); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); z-index: 3; }
.cart-checkout-bar strong { display: inline-block; margin-top: 0.05rem; font-size: 1.25rem; font-variant-numeric: tabular-nums; }
.cart-checkout-bar .button { margin-top: 0; min-height: 2.75rem; padding-inline: 1.25rem; }
.cart-checkout-result { display: flex; align-items: flex-start; gap: 0.5rem; padding: var(--space-2) 0; border-bottom: 1px solid var(--border-subtle); }
.cart-checkout-result.ok { color: #2e7d32; }
.cart-checkout-result.fail { color: var(--due); }
/* Placed AFTER the base .cart-checkout-bar rule on purpose — a media-query-scoped override has
   no extra specificity over a plain rule, so an earlier "display: none" here was being beaten by
   the later unconditional "display: flex" above and the bar kept showing on desktop too. Source
   order is what actually decides the tie, so the override has to come after what it overrides. */
@media (min-width: 992px) {
    .cart-checkout-bar { display: none; }
}
@media (max-width: 640px) {
    .cart-shop-card-header { padding: var(--space-3); }
    .cart-line { grid-template-columns: 56px minmax(0, 1fr); padding: var(--space-3); }
    .cart-line-media { width: 56px; height: 56px; }
    .cart-line-side { grid-column: 1 / -1; flex-direction: row; align-items: center; justify-content: space-between; margin-top: 0.4rem; width: 100%; }
    .cart-line-price { text-align: left; }
    .cart-shop-footer { padding: var(--space-3); }
    .cart-shop-total-box { width: 100%; min-width: 0; margin-left: 0; box-sizing: border-box; }
}
.record-card-bottom { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-1); }
.record-card-bottom .status-badge { margin-left: auto; }
.record-card-action { margin-left: auto; }

.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
}

/* Shared record-detail hierarchy: identity and state first, one compact action group next,
   then the page's financial summary and content sections. */
.detail-identity { margin-bottom: var(--space-4); }
.detail-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.detail-title-copy { min-width: 0; }
.detail-title-line { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
.detail-title-line h1 { margin: 0; }
.detail-subtitle { margin-top: var(--space-1); color: var(--muted); font-size: var(--text-sm); line-height: 1.5; }
.detail-primary-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.detail-primary-actions .button { margin-top: 0; }
/* Products/Detail.razor groups its 3 header actions in this wrapper so they stay on one row
   (they'd otherwise wrap 2-then-1 under .detail-primary-actions' mobile grid). Scrolls
   sideways only if the labels genuinely can't fit the viewport. */
.detail-actions-inline { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.detail-actions-inline .button { margin-top: 0; }
.detail-section { border-top: 1px solid var(--border-subtle); padding: var(--space-4) 0; }
.detail-section-heading { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); }
.detail-section-heading h2 { margin: 0; }
.detail-key-values { margin: var(--space-2) 0 0; }
.detail-key-values > div { display: grid; grid-template-columns: minmax(8rem, 0.35fr) 1fr; gap: var(--space-3); padding: var(--space-1) 0; }
.detail-key-values dt { color: var(--muted); }
.detail-key-values dd { margin: 0; min-width: 0; }
/* One card per line item, laid out as a single row: description on the left, amount and the
   actions menu on the right. Previously .mobile-product-row was a plain block, so its two
   child divs stacked — the amount and ⋮ button landed on their own line, visually detached
   from the product they belong to. The product name and its meta line also ran together
   ("Three piece২ × ৳৩,০০০") because both are inline elements with no separator; stacking them
   in a column below fixes that without touching the markup, which three detail pages share.
   Card styling matches .stat-card so a list of purchased items reads like the rest of the app
   rather than as undifferentiated rows.
   display stays none here — the mobile media query switches it to flex, exactly as it used to
   switch it to block. Declaring flex at this level would show the list on desktop too, beside
   the full table it exists to replace. */
.mobile-product-list { display: none; flex-direction: column; gap: var(--space-2); }
.mobile-product-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3);
    background: white;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
/* min-width:0 lets a long product name shrink and ellipsize instead of pushing the amount off
   the card — flex items refuse to shrink below their content width without it. Was previously
   ".mobile-product-row > div:first-child" (a plain, unclassed div) — now scoped to
   .product-thumb-info explicitly since that first child is .product-thumb-row (thumb + this
   info block) on all three pages that share .mobile-product-row; see .product-thumb below. */
.product-thumb-info {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}
.product-thumb-info > span {
    color: var(--muted);
    font-size: var(--text-sm);
}
.product-thumb-info > strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mobile-product-row .row-actions { flex: 0 0 auto; }

/* Product photo thumbnail — every place product info is shown read-only (Orders/Sales/Purchases
   Detail's product tables, Customers/Detail's due-sale item lines), never inside a button-
   triggered popup (OrderProductsQuickView/SaleProductsQuickView keep their text-only summary by
   design). Mirrors MyOrders.razor's own .my-order-thumb pattern exactly (already proven,
   responsive) under a more generic name since this now shows up in admin contexts too, not just
   the customer-facing "my orders" page — kept as one shared class rather than a second copy of
   the same four rules. .small is for dense multi-item-per-card contexts (due-sale cards can list
   several items per sale, several sales per page) where a full 44px thumb per line would make
   the page unnecessarily tall. */
.product-thumb-row { display: flex; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.product-thumb { width: 44px; height: 44px; border-radius: 8px; background: var(--surface-muted, #f7f3ee); color: var(--muted); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; flex: 0 0 auto; overflow: hidden; }
.product-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product-thumb.small { width: 28px; height: 28px; font-size: 0.9rem; border-radius: 6px; }

/* Distinct from .button/.button.secondary on purpose — this always navigates to a separate
   report page rather than acting on the current one, so it shouldn't compete visually with
   the primary "+ নতুন..." action or look like another in-page control (ফিল্টার/এক্সপোর্ট). */
.page-report-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    text-decoration: none;
    color: var(--muted);
    font-size: var(--text-sm);
    white-space: nowrap;
}
.page-report-link:hover { color: var(--brand); }

.filter-pills { display: flex; gap: 0.4rem; }
.pill {
    background: white;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    font-size: 0.9rem;
    cursor: pointer;
    margin-top: 0;
}
.pill.active { background: var(--brand); color: white; border-color: var(--brand); }

.stat-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin: 1rem 0;
}
.stat-card {
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.5rem;
    min-width: 160px;
    text-decoration: none;
    color: var(--ink);
    display: block;
    transition: box-shadow 0.15s, border-color 0.15s;
}
a.stat-card:hover { border-color: var(--brand); box-shadow: 0 2px 8px rgba(184, 80, 42, 0.12); }
/* ConfirmOrderAction's "which customer details to keep" step: each card is a radio-style
   button — the whole card is the target, the picked one gets a brand border + a check badge.
   Reuses .stat-card's look; <button> defaults (font, text-align, cursor) are reset here. */
.conflict-option { position: relative; text-align: left; font: inherit; color: inherit; cursor: pointer; width: 100%; }
.conflict-option:hover:not(:disabled) { border-color: var(--brand); }
.conflict-option.selected { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(184, 80, 42, 0.18); background: #fff8f4; }
.conflict-option-check { position: absolute; top: 0.6rem; right: 0.6rem; width: 1.4rem; height: 1.4rem; border-radius: 50%; background: var(--brand); color: #fff; display: none; align-items: center; justify-content: center; }
.conflict-option-check .icon { width: 0.9rem; height: 0.9rem; }
.conflict-option.selected .conflict-option-check { display: inline-flex; }
.stat-card.stat-card-alert { background: var(--warning-bg); border-color: var(--warning-border); }
a.stat-card.stat-card-alert:hover { border-color: var(--brand); }
.stat-card .status-badge { margin-top: 0.5rem; }
/* The one number the লাভ-ক্ষতি page is really about (net profit) — outlined on desktop, and
   promoted to a full-width brand tile at the top of the grid on phones (see the 640px block). */
.stat-card-hero { border: 2px solid var(--brand); }
.stat-card-hero .stat-value { font-size: 2.1rem; }

.settings-section {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.settings-card {
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.5rem;
    min-width: 160px;
    /* A fixed width, not just min-width: <button> and <a> compute flex-item intrinsic sizing
       differently in at least Chromium — a <button> here refused to grow past min-width even
       once its text needed more room to wrap onto two lines (confirmed live: font-size and
       white-space were already made identical between the two, and the button still stayed
       narrower/taller than the <a> next to it). Pinning width explicitly sidesteps that
       element-type quirk entirely rather than chasing it further, and guarantees any future
       card added to this row lines up the same way regardless of whether it's a link or button.
       box-sizing: border-box turned out to be the actual root cause underneath all of this —
       <button> gets border-box for free from the browser's UA stylesheet (every form control
       does), <a> does not (content-box is the general CSS default), so the exact same
       padding+border was being included in the anchor's box but added on TOP of the button's,
       a fixed ~50px gap between them at every width tried until this was added explicitly. */
    box-sizing: border-box;
    width: 220px;
    /* The <a> and <button> variants stubbornly stayed different heights even with the width
       fix, font-family fix, and .settings-section's own default align-items: stretch all in
       place — confirmed live that a <button> here still resists being stretched to match its
       sibling <a>'s height by content alone. A fixed min-height sidesteps that flex quirk
       entirely instead of chasing it further: both variants now size the same way regardless of
       element type, the same reasoning as the width fix above. Sized for the worst case already
       in use (a one-line label over a two-line sub, e.g. "স্টোর শেয়ার" / "স্টোরের লিংক শেয়ার
       করুন") plus this box's own padding. align-self: stretch is kept alongside it as the
       standards-correct sizing for any row where the tallest card needs more than this. */
    min-height: 96px;
    align-self: stretch;
    text-decoration: none;
    color: var(--ink);
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: box-shadow 0.15s, border-color 0.15s;
    /* Pinned explicitly because this class renders as either <a> (settings link) or <button>
       (Facebook-share trigger) — the mobile media query's generic "button, .button { font-size:
       0.9rem }" rule (app.css, ~640px breakpoint) shrinks any <button>, and with no font-size
       of its own here to out-specificity it, that shrink was making the Facebook-share card
       visibly smaller than the settings <a> card next to it, which was never a button element
       and so never got shrunk. 1rem here always wins (class beats bare element selector).
       Same story for white-space: the base "button" rule sets nowrap (so a plain button's own
       label never breaks mid-word), which was forcing the Facebook-share card's whole
       label+sub onto one unbreakable line — the <a> variant never inherits that, since it is
       not a button. Reset back to normal so both variants wrap their sub text the same way and
       end up the same width. */
    font-size: 1rem;
    white-space: normal;
    /* Same button-vs-anchor reset as above: the base "button, .button" rule sets
       margin-top: 0.5rem for standalone buttons in normal document flow, which an <a> never
       gets — pushing the Facebook-share (FacebookPromoteAction) card down relative to its
       sibling <a> card in this flex row. Zeroed here, not in FacebookPromoteAction.razor
       itself, so its OTHER TriggerCssClass usages elsewhere (e.g. "button small") keep their
       normal margin — this only strips it for the .settings-card case specifically. */
    margin-top: 0;
}

.settings-card:hover { border-color: var(--brand); box-shadow: 0 2px 8px rgba(184, 80, 42, 0.12); }

.settings-icon {
    font-size: 1.5rem;
    flex-shrink: 0;
}

.settings-card > div {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    /* Flex items default to a minimum size of their content's min-content — a single long
       Bengali word/phrase with nowhere to break was enough to push the settings <a> wider than
       the fixed width set above, defeating it. This lets the label/sub actually wrap inside the
       fixed-width box instead of forcing the box wider to avoid wrapping. */
    min-width: 0;
}

.settings-label {
    font-weight: 600;
    color: var(--ink);
    display: block;
    overflow-wrap: anywhere;
    /* Explicit, not inherited — .settings-card renders as either <a> (line-height: normal,
       recalculated per element's own font-size) or <button> (line-height: 20px, a FIXED pixel
       value from the generic button/.button rule, applied as-is regardless of this element's
       own smaller font-size). That mismatch was the actual cause of the <a>/<button> card height
       difference (confirmed live: 152px vs 129px) — giving both variants their own relative
       line-height here sidesteps it regardless of which element type renders the card. */
    line-height: 1.3;
}

.settings-sub {
    font-size: 0.85rem;
    color: var(--muted);
    display: block;
    overflow-wrap: anywhere;
    line-height: 1.3;
}

.social-connections { display: flex; flex-wrap: wrap; gap: 1rem; margin: 1rem 0; }
.social-connection-card {
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.5rem;
    min-width: 200px;
}
.social-connection-card h2 { margin: 0 0 0.5rem; font-size: 1.1rem; }
.facebook-page-choices { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.5rem 0; }

.facebook-post-action { margin: 1rem 0; }
.facebook-preview-modal-backdrop {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    /* Above every menu/sheet/FAB tier (900-1002) so a confirmation dialog always wins,
       however deep in the DOM (and however low the z-index of the container that
       triggered it) it happens to be nested — see the shared "modal tier" note by
       .field-help-backdrop. */
    z-index: 1100;
    padding: 1rem;
    box-sizing: border-box;
}
.facebook-preview-modal {
    background: var(--paper);
    border-radius: 8px;
    padding: 1.5rem;
    max-width: 480px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    box-sizing: border-box;
    min-width: 0;
    max-height: calc(100vh - 2rem);
    max-height: calc(100dvh - 2rem);
    overflow-x: hidden;
    text-align: left;
    white-space: normal;
    overflow-wrap: break-word;
}
.facebook-preview-modal input,
.facebook-preview-modal select,
.facebook-preview-modal textarea { box-sizing: border-box; max-width: 100%; }
.facebook-preview-modal h2 { margin-top: 0; }
.facebook-preview-image { width: 100%; max-height: 240px; object-fit: cover; border-radius: 6px; margin-bottom: 0.75rem; }
.facebook-preview-modal textarea { width: 100%; }
.facebook-publish-success { text-align: center; }
.facebook-publish-success .success { font-size: 1.2rem; }

.variant-image-cell {
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: 6px;
    padding: 0;
    cursor: pointer;
    width: 2.75rem;
    height: 2.75rem;
    flex-shrink: 0;
}
.variant-image-thumb { width: 2.75rem; height: 2.75rem; object-fit: cover; border-radius: 5px; display: block; }
.variant-image-thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-size: 1.1rem;
}
.variant-image-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
    gap: 0.6rem;
    margin: 0.75rem 0;
}
.variant-image-picker-option {
    background: var(--paper);
    border: 2px solid var(--border);
    border-radius: 6px;
    padding: 0;
    cursor: pointer;
    aspect-ratio: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    color: var(--muted);
}
.variant-image-picker-option img { width: 100%; height: 100%; object-fit: cover; }
.variant-image-picker-option.selected { border-color: var(--accent, #2563eb); }
.variant-image-picker-upload { border-style: dashed; }
/* Same !important reasoning as .image-add-button input above — the native file control would
   otherwise render next to the "+ নতুন ছবি" label instead of staying fully hidden behind it. */
.variant-image-picker-upload input[type="file"] { display: none !important; }
.variant-image-picker-group-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    margin: 0.75rem 0;
}
.variant-image-picker-group-toggle input { width: auto; margin: 0; }

.small { font-size: 0.85rem; }

.icon-button {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--border);
    border-radius: 6px;
    width: 2.25rem;
    height: 2.25rem;
    line-height: 1;
    font-size: 1.05rem;
    padding: 0;
    margin-top: 0;
    cursor: pointer;
    flex-shrink: 0;
    /* Without this, the ✕ glyph sits off-center in the box (its own font metrics, not
       reliably centered by line-height alone) — same class of bug as the Facebook-share
       copy button fixed earlier. Applies everywhere .icon-button is used (order popup, product
       share modal, etc.) and to every screen size — no separate mobile override exists. */
    display: flex;
    align-items: center;
    justify-content: center;
}
.icon-button:hover { background: var(--paper); }

.fb-promote-modal {
    max-width: 420px;
    /* Same modal shadow already used elsewhere in this app — the previous flat rectangle sat
       on the dark backdrop with no border or lift of its own. */
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    border: 1px solid var(--border);
    /* Belt-and-suspenders alongside the textarea's own box-sizing fix above — nothing inside
       this modal should ever be able to force the horizontal scrollbar seen live again. */
    overflow-x: hidden;
}
.fb-promote-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin: -1.5rem -1.5rem 1rem;
    padding: .9rem 1.5rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--surface-muted);
}
.fb-promote-header h2 { margin: 0; font-size: 1.15rem; }
.fb-promote-header .icon-button { border: none; font-size: 1.2rem; }
.modal-title-with-help { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.modal-title-with-help h2 { min-width: 0; }

.fb-promote-field {
    display: block;
    margin-top: 0.9rem;
    color: var(--muted);
    font-size: 0.85rem;
}
.fb-promote-textarea-wrap { position: relative; margin-top: 0.35rem; }
.fb-promote-textarea-wrap textarea {
    /* box-sizing: border-box is required here — there is no global box-sizing reset in this
       codebase (textarea defaults to content-box), so width: 100% plus the padding-right below
       was adding 2.75rem on top of the wrap's own width and pushing the whole modal into
       horizontal overflow (the scrollbar seen live). */
    box-sizing: border-box;
    width: 100%;
    /* Room for the floating button so the caption's own last lines never run underneath it. */
    padding-right: 2.75rem;
    border-radius: var(--radius-sm);
    /* Smaller text and tighter line spacing so a typical composed caption (product/price/
       description/contact lines, each on its own paragraph with a blank line between — see
       SocialCaptionComposer) fits in the 5 visible rows without needing to scroll to read it. */
    font-size: 0.9rem;
    line-height: 1.35;
    /* The browser's own resize grip renders in the same bottom-right corner as the copy button
       below, and the two overlapping is what made that button read as off-center/unrecognizable.
       Removing native resize (this field doesn't need it — five rows fits the whole caption in
       the cases this component is used for) leaves that corner to the copy button alone. */
    resize: none;
}
/* A circular button sitting in the textarea's own corner, not a separate row: this is what
   replaces the old icon-button-plus-sentence pair below the field. Brand-colored and lifted
   with a small shadow so it reads as an action sitting ON the caption, not a stray control —
   the "more focused" ask — rather than the plain bordered square it was before. */
.fb-promote-copy-fab {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    border: none;
    background: var(--brand);
    color: white;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
    transition: transform 0.1s, background 0.15s;
    /* Centers the clipboard glyph itself — emoji glyphs sit off-center inside a box by their own
       font metrics unless the box explicitly centers them, which is why the icon looked
       off-center regardless of the resize-grip overlap above. */
    display: flex;
    align-items: center;
    justify-content: center;
}
.fb-promote-copy-fab:hover { transform: scale(1.06); }
.fb-promote-copy-fab.copied { background: #2e7d32; }

/* The link line as a distinct, quiet chip rather than plain paragraph text sitting loose in
   the modal — gives it the same "this is its own small section" separation the caption field
   already has via its label. */
.fb-promote-link-row {
    background: var(--surface-muted);
    border-radius: var(--radius-sm);
    padding: 0.6rem 0.75rem;
    margin: 0.9rem 0 0;
}
.fb-promote-link-inline {
    display: inline;
    background: none;
    color: var(--brand);
    border: none;
    border-bottom: 1px dashed var(--brand);
    border-radius: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    font-size: inherit;
    font-weight: 600;
    cursor: pointer;
}
.fb-promote-link-inline:hover { border-bottom-style: solid; }
/* box-sizing: border-box is required here — .button's own padding (app.css ~line 337) is
   content-box by default (no global reset in this codebase), so width: 100% plus that padding
   was pushing the button past the modal's right edge; .fb-promote-modal's overflow-x: hidden
   then clipped it exactly at that edge, which is what removed the right-side gap. Same root
   cause as the textarea fix above. */
.fb-promote-share-btn { display: block; width: 100%; box-sizing: border-box; text-align: center; justify-content: center; margin-top: 1rem; }

.pay-due-modal { max-width: 380px; }
.pay-due-summary { display: flex; flex-direction: column; gap: 0.35rem; background: var(--surface-muted); border-radius: 6px; padding: 0.75rem 1rem; margin-bottom: 0.75rem; }
.pay-due-summary div { display: flex; justify-content: space-between; align-items: baseline; }
.pay-due-summary strong { font-size: 1.1rem; }
.pay-due-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }
.pay-due-actions .button { min-width: 0; white-space: normal; text-align: center; }
@media (max-width: 480px) {
    .pay-due-actions .button { flex: 1 1 auto; }
}

.due-sale-card { border: 1px solid var(--border); border-radius: 8px; padding: 0.85rem 1rem; margin-bottom: 0.75rem; }
.due-sale-card-header { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; margin-bottom: 0.35rem; }
.due-sale-card-header a { font-weight: 600; }
.due-sale-card-items { font-size: 0.9rem; margin-bottom: 0.6rem; }
.due-sale-card-totals { display: flex; flex-wrap: wrap; gap: 1.25rem; margin-bottom: 0.7rem; }
.due-sale-card-totals div { display: flex; flex-direction: column; gap: 0.15rem; }
.due-sale-card-totals strong { font-size: 1.05rem; }
.due-sale-card.settled { opacity: 0.85; }
.due-sale-card-footer { display: flex; align-items: center; gap: 0.6rem; }

/* display:block + white-space:normal because a bare <button> otherwise shrink-to-fits its
   OWN preferred width from its unwrapped text — confirmed live: a long product name (made more
   likely to actually reach this length now that the label always appends "× quantity unit")
   ran the button clean past its card's right edge instead of wrapping, on both the desktop
   table cell and the mobile card. A block-level button takes its container's full width and
   wraps normally like any other block text, same as everything else in this table/card. */
.quick-view-trigger { display: block; width: 100%; white-space: normal; background: none; border: none; padding: 0; margin: 0; font: inherit; color: var(--brand); text-decoration: underline; cursor: pointer; text-align: left; }
.quick-view-modal { max-width: 420px; }
.quick-view-table tfoot td { border-top: 2px solid var(--border); padding-top: 0.5rem; }
.quick-view-return-link { background: none; border: none; padding: 0; margin-top: 0.2rem; font-size: 0.8rem; color: var(--due); text-decoration: underline; cursor: pointer; }
.quick-view-confirm { margin-top: 0.4rem; background: var(--surface-muted); border-radius: 6px; padding: 0.6rem 0.75rem; }
.quick-view-confirm p { margin: 0 0 0.3rem; }

.order-products-table tfoot td { border-top: 2px solid var(--border); padding-top: 0.6rem; }

/* One clear card per product for "কতটি ফেরত দিয়েছেন?" — replaces a cramped multi-column table
   with tiny inputs (explicit feedback: confusing, not touch-friendly on mobile). */
.return-item-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3);
    margin-bottom: var(--space-2);
    background: var(--surface-muted);
    border-radius: var(--radius-md);
}
.return-item-info { min-width: 0; }
.return-item-info .product-name { font-weight: 600; }
.return-item-kept { margin-top: 0.15rem; }
.return-item-qty {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.2rem;
    flex-shrink: 0;
}
.return-item-qty label { font-size: var(--text-xs); color: var(--muted); }
.return-item-qty input {
    width: 5rem;
    height: var(--control-height);
    font-size: var(--text-lg);
    text-align: center;
    padding: 0.25rem;
}
.dismissible-alert { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; border-radius: 6px; padding: 0.75rem 1rem; margin: 0 0 1rem; }
.dismissible-alert p { margin: 0; }
.dismissible-alert button { background: transparent; border: none; font-size: 1.1rem; padding: 0 0.25rem; margin: 0; cursor: pointer; line-height: 1; flex-shrink: 0; }
.dismissible-alert-success { background: #eaf7ef; border: 1px solid #a9dfc0; }
.dismissible-alert-success p, .dismissible-alert-success button { color: #1d7a3f; }
.dismissible-alert-error { background: #fbeaea; border: 1px solid #f3c8c8; }
.dismissible-alert-error p, .dismissible-alert-error button { color: var(--due); }
.dismissible-alert-warning { background: var(--warning-bg); border: 1px solid var(--warning-border); }
.dismissible-alert-warning p, .dismissible-alert-warning button { color: var(--warning-text); }
.dismissible-alert-info { background: var(--surface-muted); border: 1px solid var(--border); }
.dismissible-alert-info p, .dismissible-alert-info button { color: var(--ink); }

.stat-label { display: block; font-size: 0.85rem; color: var(--muted); }
.stat-value { display: block; font-size: 1.5rem; font-weight: bold; color: var(--ink); }
.stat-sub { display: block; font-size: 0.75rem; color: var(--muted); margin-top: 0.25rem; }

.dashboard-group { margin: 2rem 0 1rem 0; padding-top: 1.5rem; border-top: 1px solid var(--border); }
.dashboard-group:first-of-type { border-top: none; padding-top: 0; }
.dashboard-section-title { font-size: var(--text-lg); margin: 0 0 0.75rem 0; }
.quick-links { display: flex; gap: 0.75rem; flex-wrap: wrap; }

.inline-form { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.inline-form input { width: auto; }

.filter-row { display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap; margin-bottom: var(--space-4); }
.filter-row label { margin-bottom: 0; }

.back-link {
    display: inline-block;
    margin-bottom: 1rem;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.9rem;
}
.back-link:hover { color: var(--brand); }

.total-line { font-size: 1.25rem; }

.auth-page, .onboarding {
    max-width: 480px;
    margin: 2rem auto;
    background: white;
    padding: 2rem;
    border-radius: 8px;
    border: 1px solid var(--border);
}

.landing {
    max-width: 640px;
    margin: 1.5rem auto 2rem;
    text-align: center;
}
.cta-row { display: flex; gap: 1rem; justify-content: center; margin-top: 1.5rem; }
.landing-browse-link { margin-top: 1rem; }

/* ---- Public storefront (PROJECT_PLAN.md §21 Phase 5) ---- */

.site-header {
    max-width: 960px;
    margin: 0 auto;
    padding: 1rem 1rem 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.site-logo {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}
.site-logo-icon { width: 68px; height: 68px; flex-shrink: 0; object-fit: contain; }
.site-logo-text { font-weight: 700; font-size: 1.15rem; color: var(--brand); }

.site-header-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-wrap: wrap;
}
.site-header-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    text-decoration: none;
    color: var(--ink);
    padding: 0.5rem 0.6rem;
    border-radius: 6px;
    cursor: pointer;
    list-style: none;
}
.site-header-icon::-webkit-details-marker { display: none; }
.site-header-icon:hover { background: #f2ece5; }
/* Icon glyph is plain ink by default — .active (the current page) or .has-value (a filter is
   picked) switches it to brand orange. Tried brand-colored-always-with-a-fill-on-active first;
   reverted (see session notes) — with every icon already orange, the active one only differed
   by a subtle fill-vs-outline change that was easy to miss. Neutral-by-default so the color
   change alone reads clearly as "you are here", the standard tab-bar/nav pattern. */
.site-header-icon-glyph { font-size: 1.15rem; line-height: 1; }
.site-header-icon.active .site-header-icon-glyph,
.site-header-icon.has-value .site-header-icon-glyph {
    color: var(--brand);
}
.site-header-icon-label { font-size: 0.85rem; }
.site-header-icon .badge {
    background: var(--brand);
    color: white;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    border-radius: 999px;
}

.site-header-dropdown { position: relative; }
.site-header-dropdown-panel {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 10;
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    /* Sized to its widest item (not a fixed min-width) so a long label like "মোবাইল,
       কম্পিউটার ও ইলেকট্রনিক্স" never wraps to a second line — capped at 92vw as a safety
       net on very narrow phones only, never a normal constraint. */
    width: max-content;
    max-width: 92vw;
}
.site-header-dropdown-panel a {
    padding: 0.5rem 0.6rem;
    border-radius: 4px;
    text-decoration: none;
    color: var(--ink);
    font-size: 0.9rem;
    white-space: nowrap;
}
.site-header-dropdown-panel a:hover { background: #f2ece5; }
.site-header-dropdown-panel a.active { background: var(--brand); color: white; font-weight: 600; }
.site-header-dropdown-panel a.active:hover { background: var(--brand); }

/* Top matches .admin-main's 1.5rem — the two panels had no reason to differ. */
.storefront-page { max-width: 1120px; margin: 0 auto; padding: 1.25rem 1rem 3rem; }

.storefront-header { margin-bottom: 1.5rem; }
.storefront-header-brand { display: flex; align-items: center; gap: var(--space-3); }
.storefront-header-brand h1 { margin: 0; }
.storefront-logo { width: 56px; height: 56px; object-fit: contain; border: 1px solid var(--border); border-radius: 8px; background: #fff; padding: 4px; flex-shrink: 0; }
.storefront-shop-main { display: flex; align-items: center; gap: var(--space-3); }
.storefront-shop-identity h1 { margin: 0; }
.storefront-shop-identity .muted { margin: 0.35rem 0 0; }
.storefront-shop-page .storefront-search { width: 100%; max-width: none; }
#storefront-shop-product-search { flex: 1 1 auto; width: auto; min-width: 0; max-width: none; }

/* WhatsApp's own green, reserved exclusively for WhatsApp CTAs so it stays instantly
   recognizable (PROJECT_PLAN.md §18 design reference). */
.whatsapp-btn { background: #25D366; border-color: #25D366; color: white; }
.whatsapp-btn:hover { opacity: 0.92; }
.whatsapp-icon { vertical-align: -3px; }

.landing { max-width: 1120px; margin: 0 auto; padding: 2.15rem 1rem .5rem; }
.landing-hero { max-width: 720px; margin: 0 auto; text-align: center; }
.landing-kicker, .section-kicker { color: var(--brand); font-size: .84rem; font-weight: 700; letter-spacing: .02em; margin: 0 0 .45rem; }
.landing-hero h1 { margin: 0; font-size: clamp(1.8rem, 2vw, 2rem); line-height: 1.2; }
.landing-hero > p:last-child { margin: .7rem auto 0; max-width: 570px; color: var(--muted); font-size: 1rem; line-height: 1.45; }
.storefront-search { display: flex; gap: 0.5rem; margin: 1.35rem auto 0; padding: 0; max-width: 620px; }
.landing-search input { min-height: 3.5rem; font-size: 1.05rem; }
/* Shrinks only the "(বাংলা অথবা ইংরেজিতে)" hint text, not what the visitor actually types —
   the placeholder is the one thing on the page allowed to say the search accepts either
   language, so it has to fit on one line without competing with the real (larger) input
   font-size. */
.landing-search input::placeholder { font-size: 0.85rem; }
.landing-search button { min-height: 3.5rem; padding-inline: 1.35rem; }
.storefront-search input { margin: 0; }
.storefront-search button { margin: 0; }

/* Browse filters live under the search field on every viewport. */
/* position: relative lives here, not on the individual .browse-filter-dropdown anchors — the
   two pills aren't evenly spaced from the page center (their labels differ in width), so a
   panel centered under whichever one was clicked could still run past the screen edge on a
   narrow phone. Anchoring both panels to the shared, always page-centered row instead keeps
   their translateX(-50%) centering point (and therefore the max-width clamp below) safely
   inside the viewport regardless of which pill opened it. */
.browse-filter-pills { position: relative; display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.9rem; }
.browse-filter-pill {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.5rem 0.75rem; border: 1px solid var(--border); border-radius: 999px;
    background: #fff; font-size: 0.875rem; color: var(--ink); cursor: pointer; list-style: none;
}
.browse-filter-pill::-webkit-details-marker { display: none; }
.browse-filter-pill:hover { border-color: var(--brand); background: #fdf5ee; }
.browse-filter-pill.has-value { border-color: var(--brand); color: var(--brand); font-weight: 600; }
.browse-filter-pill svg { width: 16px; height: 16px; flex-shrink: 0; }
.browse-filter-dropdown-panel {
    top: calc(100% + 0.35rem); left: 50%; right: auto; transform: translateX(-50%);
    max-width: calc(100vw - 2rem); max-height: min(22rem, 60vh); overflow-y: auto;
}
/* A fixed width, not a percentage — the panel itself is sized to its widest item
   (.site-header-dropdown-panel's width: max-content), so a percentage here would be resolving
   against a container whose size depends on this element, which browsers don't handle
   predictably. align-self centers it within that content-sized panel instead. */
.browse-district-search {
    display: flex; align-items: center; gap: 0.4rem;
    align-self: center;
    margin: 0.55rem 0 0.4rem; padding: 0.4rem 0.65rem; box-sizing: border-box;
    width: 12.5rem; max-width: 100%;
    background: #f1f6fc; border: none; border-radius: 999px;
    transition: background-color 0.15s ease;
}
.browse-district-search:focus-within { background: #e8f0fe; }
.browse-district-search svg { width: 1rem; height: 1rem; flex-shrink: 0; color: var(--muted); }
.browse-district-search:focus-within svg { color: var(--brand); }
.browse-district-search input {
    flex: 1; min-width: 0; margin: 0; padding: 0; border: none;
    font-size: 0.9rem; background: transparent;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.browse-district-search input:focus { outline: none; }
/* Same reasoning as .landing-search input::placeholder above — the pill is only 12.5rem wide,
   so the "(বাংলা অথবা ইংরেজিতে)" hint needs to shrink further here to read as a full word
   instead of ellipsis-clipping after a couple of characters, without touching what's actually
   typed. */
.browse-district-search input::placeholder { font-size: 0.72rem; }
.browse-district-empty { margin: 0; padding: 0.75rem; color: var(--muted); font-size: 0.8rem; text-align: center; }

.browse-owner-bridge { margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--border); text-align: center; }
.browse-owner-bridge p { margin: 0 0 0.25rem; }
.browse-owner-bridge a { font-weight: 600; }

/* Home.razor — the owner-facing landing page. Sections below reuse .section-kicker (already
   shared with the storefront family above) for their eyebrow labels, and .cta-row/.button for
   every call-to-action, so only the layout scaffolding these sections actually need is new. */
.landing-page { max-width: 1120px; margin: 0 auto; padding: 3.5rem 1rem 4rem; }
.landing-hero-split { display: grid; grid-template-columns: 1.15fr 1fr; gap: 4rem; align-items: center; }
.landing-hero-copy h1 { margin: 0; font-size: 2.9rem; line-height: 1.15; letter-spacing: -0.01em; }
.landing-hero-sub { margin: 1.1rem 0 0; max-width: 520px; color: var(--muted); font-size: 1.1rem; line-height: 1.5; }
.landing-hero-cta { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; justify-content: flex-start; margin-top: 1.6rem; }
.landing-hero-cta .button { min-height: 3.2rem; padding-inline: 1.6rem; font-size: 1.05rem; }
/* Single filled CTA + a text login link (not two equal buttons — the primary action must be
   unambiguous). Reused by the closing CTA block via .landing-cta-center. */
.landing-hero-login { color: var(--muted); font-size: 0.95rem; text-decoration: none; margin-top: 0.5rem; }
.landing-hero-login strong { color: var(--brand); }
.landing-hero-login:hover strong { text-decoration: underline; }
.landing-cta-center { justify-content: center; }
.landing-trust { list-style: none; margin: 1.4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; color: var(--muted); font-size: 0.9rem; }
.landing-trust li { display: flex; align-items: center; gap: 0.5rem; }
.landing-trust .icon { color: var(--ok, #2f7d4f); width: 1.05em; height: 1.05em; }

/* Owner-facing marketing header (SiteHeader Landing="true"). Sticky on desktop only — the
   CTA stays reachable while reading down, the standard SaaS landing pattern; on a phone a
   sticky bar eats too much of the viewport, and the closing CTA section catches them. */
.site-header-landing {
    max-width: 1120px;
    padding: 0.6rem 1rem;
    flex-wrap: nowrap;
}
/* Shared sticky + shrink-on-scroll behaviour (SiteHeader Landing="true" OR Sticky="true").
   The bar needs an opaque ground once content slides under it. */
.site-header-sticky {
    background: var(--paper);
    border-bottom: 1px solid var(--border);
}
@media (min-width: 641px) {
    /* Full-bleed bar: the ground + border span the whole viewport (a 960px-wide floating strip
       with page showing either side looked broken), while the CONTENT stays aligned to the
       page column — the horizontal padding grows to absorb the extra width. --sticky-column is
       the column each variant aligns to (960px shopper page, 1120px landing).
       overflow-anchor: none — the browser must not "helpfully" re-anchor the scroll position to
       compensate for this bar changing height (that compensation is what fed the toggle loop). */
    .site-header-sticky {
        --sticky-column: 960px;
        position: sticky; top: 0; z-index: 500; overflow-anchor: none;
        max-width: none; width: 100%; box-sizing: border-box;
        padding: 0.6rem max(1rem, calc((100% - var(--sticky-column)) / 2));
        transition: padding var(--hdr-ease), box-shadow var(--hdr-ease);
    }
    .site-header-landing.site-header-sticky { --sticky-column: 1120px; }
    /* Once scrolled (site-header.js toggles .is-compact) the bar collapses to just its
       controls — ~42px on both variants — full spacing only while at the top of the page. */
    .site-header-sticky.is-compact { padding-top: 0.15rem; padding-bottom: 0.15rem; box-shadow: 0 2px 10px rgba(44, 32, 20, 0.08); }
    .site-header-sticky.is-compact .site-logo-icon { width: 36px; height: 36px; }
    .site-header-sticky.is-compact .site-header-icon { padding-block: 0.3rem; }
    .site-header-landing.is-compact .landing-nav-cta.button { min-height: 0; padding: 0.3rem 0.9rem; font-size: 0.88rem; line-height: 1.2; }
    .site-header-landing.is-compact .landing-nav a,
    .site-header-landing.is-compact .landing-nav-login { padding-block: 0.2rem; }
}
.site-header-landing .site-logo-icon { width: 52px; height: 52px; }
/* Every property the compact state changes is transitioned with ONE shared timing — the
   shrink previously animated only the bar's padding and logo while the links/CTA snapped,
   which read as a stutter. 320ms with a material "standard" curve: quick enough to feel
   responsive, long enough that the eye tracks the change instead of registering a jump. */
.site-header-sticky { --hdr-ease: 320ms cubic-bezier(0.4, 0, 0.2, 1); }
.site-header-sticky .site-logo-icon { transition: width var(--hdr-ease), height var(--hdr-ease); }
.site-header-sticky .site-header-icon { transition: padding var(--hdr-ease); }
.site-header-landing .landing-nav a, .site-header-landing .landing-nav-login { transition: padding var(--hdr-ease), background-color 0.15s ease; }
.site-header-landing .landing-nav-cta.button { transition: padding var(--hdr-ease), font-size var(--hdr-ease), min-height var(--hdr-ease); }
.landing-nav { display: flex; align-items: center; gap: 0.25rem; margin-left: 1rem; flex: 1; }
.landing-nav a, .landing-nav-login {
    color: var(--ink);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 500;
    padding: 0.45rem 0.7rem;
    border-radius: 6px;
}
.landing-nav-login { display: inline-flex; align-items: center; gap: 0.35rem; }
.landing-nav a:hover, .landing-nav-login:hover { background: #f2ece5; }
.landing-nav .landing-nav-browse { margin-left: auto; color: var(--ink); display: inline-flex; align-items: center; gap: 0.35rem; }
.landing-nav-browse .icon { width: 1.05em; height: 1.05em; }
.landing-nav-actions { display: flex; align-items: center; gap: 0.35rem; flex-shrink: 0; }
.landing-nav-cta.button {
    margin-top: 0;
    min-height: 0;
    padding: 0.45rem 0.7rem;
    border-color: transparent;
    background: transparent;
    background-image: none;
    box-shadow: none;
    color: var(--ink);
    font-size: 0.92rem;
    font-weight: 500;
}
.landing-nav-cta.button:hover { background: #f2ece5; }

/* Tablet and landscape-phone bridge. The phone layout ends at 640px, but both full desktop
   headers need substantially more room than that. Compact only the header controls in this
   middle range; page content, the landing hero and the established phone/desktop layouts stay
   untouched. */
@media (min-width: 641px) and (max-width: 1100px) {
    .site-header { flex-wrap: nowrap; }
    .site-header .site-logo-icon { width: 52px; height: 52px; }

    /* Shopper header: all destinations remain available as 44px icon targets. Their existing
       aria labels keep the icon-only controls accessible. */
    .site-header:not(.site-header-landing) .site-header-actions {
        margin-left: auto;
        min-width: 0;
        flex-wrap: nowrap;
        gap: 0;
    }
    .site-header:not(.site-header-landing) .site-header-icon-label { display: none; }
    .site-header:not(.site-header-landing) .site-header-icon {
        box-sizing: border-box;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        padding: 0.5rem;
    }
    .site-header:not(.site-header-landing) .site-header-dropdown-panel {
        right: auto;
        left: 50%;
        transform: translateX(-50%);
        max-width: calc(100vw - 2rem);
    }

    /* Landing header: remove only the three in-page section shortcuts. The buyer search and
       account actions stay visible, in full, on one line. */
    .site-header-landing .landing-nav {
        margin-left: auto;
        min-width: 0;
        flex: 0 1 auto;
        gap: 0;
    }
    .site-header-landing .landing-nav a:not(.landing-nav-browse) { display: none; }
    .site-header-landing .landing-nav .landing-nav-browse {
        margin-left: 0;
        padding-inline: 0.45rem;
        white-space: nowrap;
    }
    .site-header-landing .landing-nav-actions,
    .site-header-landing .landing-nav-login,
    .site-header-landing .landing-nav-cta.button { white-space: nowrap; }
}

/* Anchor links must land below the sticky bar, not under it. */
/* Sized to the COMPACT bar (the state the header is always in once an anchor has scrolled the page). */
.landing-section { scroll-margin-top: 60px; }
.landing-faq-more { margin: 1rem 0 0; font-size: 0.9rem; }
.landing-faq-more a { font-weight: 600; text-decoration: none; }
.landing-faq-more a:hover { text-decoration: underline; }

/* Home "দাম" summary — the price cards themselves reuse the /pricing page's .pricing-rate* styles. */
#pricing .landing-pricing-lead { margin: -1.4rem 0 1.5rem; color: var(--muted); font-size: 1rem; }
#pricing .landing-pricing-more { margin: 1.1rem 0 0; font-size: 0.95rem; }
#pricing .landing-pricing-more a { font-weight: 600; text-decoration: none; }
#pricing .landing-pricing-more a:hover { text-decoration: underline; }
@media (max-width: 760px) { #pricing .pricing-rates-grid { grid-template-columns: 1fr; } }

/* Hero phone mock (aria-hidden, illustrative) — "Option B" from the design canvas: the product
   is used on a phone, so the preview is one. Deliberately shows only what persuades (one big
   number, two rows, the voice action), not a whole dashboard; a full desktop-style mock read
   as clutter next to the headline. */
/* Depth, not gloss. Three quiet touches in the brand hue — a warm glow behind the phone, a
   top-light on the primary button, a sheen on the bezel — all low-alpha so the page still
   reads as the same flat, paper-warm brand as the app itself. */
.landing-hero-split { position: relative; isolation: isolate; overflow: hidden; }
.landing-hero-split::before {
    content: ""; position: absolute; z-index: -1; pointer-events: none;
    right: -6%; top: 50%; width: 640px; height: 640px; transform: translateY(-50%);
    background: radial-gradient(closest-side, rgba(184, 80, 42, 0.16), rgba(184, 80, 42, 0.05) 55%, transparent 100%);
}
.landing-page .button:not(.secondary) {
    background-image: linear-gradient(180deg, #c65c34 0%, var(--brand) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(44, 32, 20, 0.12);
}
.landing-phone { position: relative; }
.landing-phone::after {
    content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; border-radius: inherit; pointer-events: none;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0.06) 28%, transparent 46%);
}
.landing-phone-wrap { display: flex; justify-content: center; }
.landing-phone { width: 300px; height: 500px; background: #1f1a17; border-radius: 38px; padding: 11px; box-shadow: 0 30px 70px rgba(44, 32, 20, 0.22); flex-shrink: 0; }
.landing-phone-screen { width: 100%; height: 100%; background: var(--paper); border-radius: 28px; overflow: hidden; display: flex; flex-direction: column; box-sizing: border-box; }
.landing-phone-head { display: flex; align-items: center; gap: 0.6rem; padding: 1.5rem 1.25rem 0.8rem; font-weight: 700; font-size: 0.95rem; }
.landing-phone-head img { width: 26px; height: 26px; object-fit: contain; }
.landing-phone-stat { margin: 0 1rem; background: #fff; border: 1px solid var(--border-subtle, #ececec); border-radius: 8px; padding: 1rem 1.1rem; }
.landing-phone-stat .muted { font-size: 0.78rem; }
.landing-phone-stat-value { font-size: 2rem; font-weight: 800; line-height: 1.1; margin-top: 0.2rem; }
.landing-phone-stat-sub { display: flex; gap: 1rem; margin-top: 0.7rem; font-size: 0.78rem; }
.landing-phone-due { color: var(--due); }
.landing-phone-brand { color: var(--brand); }
/* Two stats side by side in the one card (today's sales · this month's profit) — smaller
   figure than the single-stat size so "৳ ১২,৩০০" never wraps in half the card's width. */
.landing-phone-stat-split { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; padding: 1rem 0.9rem; }
.landing-phone-stat-split .landing-phone-stat-value { font-size: 1.25rem; white-space: nowrap; }
.landing-phone-profit { color: #1d7a3f; }
.landing-phone-chips { display: flex; gap: 0.45rem; margin: 0.6rem 1rem 0; }
.landing-phone-chip { flex: 1; display: flex; align-items: center; gap: 0.35rem; background: #fff; border: 1px solid var(--border-subtle, #ececec); border-radius: 999px; padding: 0.4rem 0.7rem; font-size: 0.72rem; font-weight: 600; white-space: nowrap; }
.landing-phone-chip-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--brand); flex-shrink: 0; }
.landing-phone-chip-warn .landing-phone-chip-dot { background: #d99a1e; }
.landing-phone-row { margin: 0.6rem 1rem 0; background: #fff; border: 1px solid var(--border-subtle, #ececec); border-radius: 8px; padding: 0.75rem 0.9rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
.landing-phone-row-title { font-weight: 600; font-size: 0.85rem; }
.landing-phone-row .muted { font-size: 0.72rem; }
.landing-phone-row-amount { font-weight: 700; font-size: 0.85rem; white-space: nowrap; }
.landing-phone-voice { margin: auto 1rem 1.25rem; background: var(--brand); color: #fff; border-radius: 999px; padding: 0.8rem 1rem; display: flex; align-items: center; gap: 0.6rem; font-size: 0.8rem; font-weight: 600; }
.landing-phone-voice .icon { width: 1.3em; height: 1.3em; flex-shrink: 0; }

/* Buyer bridge — a slim divider-style line near the foot, not a boxed panel. */
.landing-bridge { margin-top: 4rem; padding: 1.5rem 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; font-size: 1rem; }
.landing-bridge-link { display: inline-flex; align-items: center; gap: 0.35rem; font-weight: 600; white-space: nowrap; text-decoration: none; }
.landing-bridge-link:hover { text-decoration: underline; }

.landing-section { margin-top: 5rem; }
.landing-section h2 { margin: 0 0 2.25rem; font-size: 1.85rem; line-height: 1.25; }

/* Features: icon-left rows in two columns, no card boxes — quieter than a grid of six cards. */
.landing-features { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem 4rem; }
.landing-feature { display: flex; gap: 1.1rem; align-items: flex-start; }
.landing-feature-icon { width: 44px; height: 44px; flex-shrink: 0; border-radius: 4px; background: var(--warning-bg, #fdf1e4); color: var(--brand); display: flex; align-items: center; justify-content: center; }
.landing-feature-icon .icon { width: 22px; height: 22px; }
.landing-feature h3 { margin: 0; font-size: 1.08rem; }
.landing-feature p { margin: 0.3rem 0 0; color: var(--muted); font-size: 0.95rem; line-height: 1.55; }

.landing-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem; }
.landing-step { display: flex; gap: 0.9rem; align-items: flex-start; }
.landing-step-number { width: 40px; height: 40px; border-radius: 999px; background: var(--brand); color: #fff; font-weight: 700; font-size: 1.1rem; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.landing-step-title { font-weight: 700; font-size: 1rem; }
.landing-step p { margin: 0.15rem 0 0; font-size: 0.875rem; line-height: 1.5; }

.landing-faq-list { max-width: 720px; }

.storefront-section { margin-top: 2.2rem; }
.storefront-section-heading { display: flex; align-items: end; justify-content: space-between; gap: 1rem; }
.storefront-section-heading h2 { margin: 0; }
.storefront-load-more { display: flex; justify-content: center; margin-top: 1.4rem; overflow-anchor: none; }

.storefront-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 1rem;
    margin-top: 1rem;
}

/* Shimmer placeholders shown while Browse.razor's product/shop queries are still running
   (StreamRendering sends this shell immediately, then swaps in the real cards) — same idea as
   Facebook/LinkedIn's loading cards: the page's shape is there right away, only the content
   fades in once it arrives. Sized to match .storefront-card/.storefront-shop-card exactly so
   nothing visibly jumps when the real content replaces it. */
@keyframes skeleton-shimmer {
    0% { background-position: -300px 0; }
    100% { background-position: 300px 0; }
}
.skeleton-block {
    background: #e7effb;
    background-image: linear-gradient(90deg, #e7effb 0px, #f5f9ff 40px, #e7effb 80px);
    background-size: 600px;
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .skeleton-block { animation: none; }
}
.skeleton-card { border: 1px solid var(--border); border-radius: 14px; overflow: hidden; background: white; }
.skeleton-card .skeleton-media { width: 100%; aspect-ratio: 1; }
.skeleton-card .skeleton-lines { padding: .8rem .9rem .85rem; display: flex; flex-direction: column; gap: .5rem; }
.skeleton-card .skeleton-line { height: 0.85rem; border-radius: 4px; }
.skeleton-card .skeleton-line.w-70 { width: 70%; }
.skeleton-card .skeleton-line.w-40 { width: 40%; }
.skeleton-card .skeleton-line.w-55 { width: 55%; }
.skeleton-shop-card {
    flex: 0 0 220px;
    min-height: 132px;
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.5rem 1rem 1rem;
    background: white;
    display: flex;
    flex-direction: column;
    gap: .6rem;
}
.skeleton-shop-card .skeleton-line { height: 0.9rem; border-radius: 4px; }

/* ---- Settings page: annotated sections. Each section is an intro column (icon, title, one
   line of "why") beside a white card holding the fields — the Shopify/GitHub settings pattern.
   Below 900px the intro stacks above its card; below 640px the field grid becomes one column
   and the save bar sticks just above the bottom nav. Onboarding/Business and the Products
   opening-stock/variant pages reuse .settings-field / .settings-location-label-row /
   .settings-save-bar, so those keep their plain (non-sticky) base look. ---- */
.settings-page-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.settings-page-heading h1 { margin: 0; }
.settings-page-heading .button { margin-top: 0; }
.settings-form { max-width: 1040px; }
.settings-group {
    display: grid;
    grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
    gap: var(--space-4) var(--space-6);
    padding: var(--space-5) 0;
    border-top: 1px solid var(--border-subtle);
    max-width: 1040px;
}
.settings-form > .settings-group:first-of-type { border-top: 0; padding-top: var(--space-2); }
.settings-group-intro { min-width: 0; }
.settings-group-icon {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 10px;
    background: var(--warning-bg);
    color: var(--brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    margin-bottom: var(--space-2);
}
.settings-group-intro h2 { font-size: var(--text-lg); margin: 0 0 var(--space-1); }
.settings-group-intro p { margin: 0; color: var(--muted); font-size: var(--text-sm); line-height: 1.5; }
/* One consistent tint + left accent for every settings card, not a different colour per
   section — with 6+ sections on this page (store, contact, address, delivery, payment, order
   settings, security) a rainbow would read as noisy rather than organised. Confirmed live as
   needed: the plain white card blended straight into the page background, and on mobile the
   icon+heading sits ABOVE the card with real vertical gap (see the mobile media query further
   down), so the visual link between an icon and "its" card was weak — a screenshot showed a
   shop owner unable to tell where one section's fields ended and the next began. Reuses the
   same --warning-bg/--brand pair .settings-group-icon already uses, so the icon's own tint and
   the card it belongs to read as one visual family instead of two separate color choices. */
.settings-group-card {
    min-width: 0;
    background: var(--warning-bg);
    border: 1px solid var(--warning-border);
    border-left: 4px solid var(--brand);
    border-radius: 14px;
    padding: var(--space-5);
}
.settings-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3) var(--space-4); }
.settings-fields > * { min-width: 0; }
.settings-fields .span-2 { grid-column: 1 / -1; }
.settings-fields label { margin: 0; }

/* সেটিংস hub (Settings/Index.razor) — one clickable row per category instead of one giant
   scrolling form. Reuses .settings-group-card's own tint/border-left treatment so a hub row
   and the page it links to read as the same visual family; row-specific bits (link reset,
   horizontal icon+text+chevron layout, hover/tap feedback) live here. */
.settings-hub-list { display: flex; flex-direction: column; gap: var(--space-3); max-width: 640px; }
.settings-hub-row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, background 0.15s;
}
.settings-hub-row:hover, .settings-hub-row:focus-visible { border-color: var(--brand); }
.settings-hub-row .settings-group-icon { margin-bottom: 0; flex-shrink: 0; }
.settings-hub-row-text { flex: 1 1 auto; min-width: 0; }
.settings-hub-row-text strong { display: block; font-size: var(--text-lg); }
.settings-hub-row-text span { display: block; color: var(--muted); font-size: var(--text-sm); margin-top: 0.15rem; }
.settings-hub-row-chevron { flex-shrink: 0; color: var(--muted); }
@media (max-width: 640px) {
    .settings-hub-row { padding: var(--space-4); border-radius: 12px; gap: var(--space-3); }
}
/* The base input rule caps text fields at 420px; inside a settings card the grid column is the
   width (this selector out-specifies the base one's six :not() attribute selectors). */
.settings-group-card input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]):not([type=file]),
.settings-group-card select, .settings-group-card textarea { max-width: none; background: white; }
.settings-fields textarea { min-height: 5.5rem; resize: vertical; }
.settings-field { min-width: 0; }
.settings-location-label-row { display: flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
.settings-location-label-row label { min-width: 0; margin: 0; }
.district-combobox { position: relative; }
.district-combobox > input { margin-bottom: 0; }
.district-combobox-results { position: absolute; z-index: 40; top: calc(100% + 0.25rem); left: 0; right: 0; max-height: min(19rem, 45vh); overflow-y: auto; padding: 0.3rem; border: 1px solid var(--border); border-radius: 0.65rem; background: #fff; box-shadow: 0 12px 28px rgba(27, 32, 43, 0.14); }
.district-combobox-results button { display: block; width: 100%; margin: 0; padding: 0.55rem 0.65rem; border: 0; border-radius: 0.4rem; background: transparent; color: var(--ink); text-align: left; font-weight: 400; }
.district-combobox-results button:hover, .district-combobox-results button:focus-visible, .district-combobox-results button.active { background: #fdf0e7; color: var(--brand); }
.district-combobox-results p { margin: 0; padding: 0.65rem; color: var(--muted); font-size: 0.82rem; text-align: center; }
.customer-combobox { position: relative; }
.customer-combobox > input { margin-bottom: 0; }
.customer-combobox-results { position: absolute; z-index: 40; top: calc(100% + 0.25rem); left: 0; right: 0; max-height: min(19rem, 45vh); overflow-y: auto; padding: 0.3rem; border: 1px solid var(--border); border-radius: 0.65rem; background: #fff; box-shadow: 0 12px 28px rgba(27, 32, 43, 0.14); }
.customer-combobox-results button { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; width: 100%; margin: 0; padding: 0.55rem 0.65rem; border: 0; border-radius: 0.4rem; background: transparent; color: var(--ink); text-align: left; font-weight: 400; }
.customer-combobox-results button:hover, .customer-combobox-results button:focus-visible, .customer-combobox-results button.active { background: #fdf0e7; color: var(--brand); }
.customer-combobox-results button.new-option { color: var(--brand); font-weight: 600; border-top: 1px solid var(--border-subtle); margin-top: 0.2rem; padding-top: 0.65rem; }
.customer-combobox-results p { margin: 0; padding: 0.65rem; color: var(--muted); font-size: 0.82rem; text-align: center; }
.product-combobox { position: relative; min-width: 0; }
.product-combobox:focus-within { z-index: 60; }
.product-combobox > input { box-sizing: border-box; width: 100%; margin: 0; }
.product-combobox-results {
    position: absolute;
    z-index: 60;
    top: calc(100% + .25rem);
    left: 0;
    min-width: min(18rem, calc(100vw - 3rem));
    max-width: min(24rem, calc(100vw - 3rem));
    max-height: min(18rem, 50vh);
    overflow-y: auto;
    padding: .3rem;
    border: 1px solid var(--border);
    border-radius: .65rem;
    background: #fff;
    box-shadow: 0 12px 28px rgba(27, 32, 43, .14);
}
.product-combobox-results button {
    display: block;
    width: 100%;
    margin: 0;
    padding: .6rem .7rem;
    border: 0;
    border-radius: .4rem;
    background: transparent;
    color: var(--ink);
    font-size: .85rem;
    font-weight: 400;
    text-align: left;
    white-space: normal;
    overflow-wrap: anywhere;
}
.product-combobox-results button:hover,
.product-combobox-results button:focus-visible,
.product-combobox-results button.active { background: #eef5ff; color: #155fc4; }
.product-combobox-results button.new-option { margin-top: .2rem; border-top: 1px solid var(--border-subtle); color: #155fc4; font-weight: 600; }
.product-combobox-results p { margin: 0; padding: .6rem .7rem; color: var(--muted); font-size: .8rem; }
.supplier-combobox { position: relative; min-width: 0; width: 100%; }
.supplier-combobox:focus-within { z-index: 60; }
.supplier-combobox > input { box-sizing: border-box; width: 100%; margin: 0; }
.supplier-combobox-results {
    position: absolute;
    z-index: 60;
    top: calc(100% + .25rem);
    left: 0;
    right: 0;
    max-height: min(18rem, 50vh);
    overflow-y: auto;
    padding: .3rem;
    border: 1px solid var(--border);
    border-radius: .65rem;
    background: #fff;
    box-shadow: 0 12px 28px rgba(27, 32, 43, .14);
}
.supplier-combobox-results button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: 100%;
    margin: 0;
    padding: .6rem .7rem;
    border: 0;
    border-radius: .4rem;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-weight: 400;
    text-align: left;
}
.supplier-combobox-results button:hover,
.supplier-combobox-results button:focus-visible,
.supplier-combobox-results button[aria-selected="true"] { background: #eef5ff; color: #155fc4; }
.supplier-combobox-results button.new-option { margin-top: .2rem; border-top: 1px solid var(--border-subtle); color: #155fc4; font-weight: 600; }
.supplier-combobox-results p { margin: 0; padding: .6rem .7rem; color: var(--muted); font-size: .8rem; }
/* Small grey explanation under a field — replaces the italic .field-help for this page. */
.settings-note { display: flex; align-items: flex-start; gap: 0.4rem; margin: 0.4rem 0 0; font-size: var(--text-xs); color: var(--muted); line-height: 1.45; }
.settings-note .icon { flex: 0 0 auto; margin-top: 0.15em; }
.settings-subheading { font-size: var(--text-sm); font-weight: 600; color: var(--ink); margin: var(--space-4) 0 var(--space-2); }
/* Checkbox settings read as a row: box, bold label, grey explanation — the whole row is the
   label, so tapping the text toggles it. */
.settings-toggle-list { display: grid; gap: var(--space-2); }
.settings-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin: 0;
    padding: 0.75rem 0.9rem;
    background: var(--surface-muted);
    border-radius: 10px;
    color: var(--ink);
    font-size: 0.95rem;
    cursor: pointer;
}
.settings-toggle > input { flex: 0 0 auto; width: 1.15rem; height: 1.15rem; margin: 0.2rem 0 0; accent-color: var(--brand); }
.settings-toggle > span { min-width: 0; }
.settings-toggle strong { display: block; font-weight: 600; line-height: 1.35; }
.settings-toggle .hint { display: block; color: var(--muted); font-size: var(--text-xs); line-height: 1.45; margin-top: 0.15rem; }
.settings-logo-row { display: flex; align-items: center; gap: var(--space-4); padding-bottom: var(--space-4); margin-bottom: var(--space-4); border-bottom: 1px solid var(--border-subtle); }
.settings-logo-row .onboarding-logo-preview { margin: 0; }
.settings-logo-row .image-add-button { flex: 0 0 auto; margin: 0; }
.settings-logo-copy { min-width: 0; }
.settings-logo-copy strong { display: block; }
.settings-logo-copy p { margin: 0.15rem 0 0; font-size: var(--text-sm); color: var(--muted); }
.settings-logo-copy .button { margin-top: var(--space-2); }
.settings-logo-copy .error, .settings-logo-copy .moderation-notice { margin-top: var(--space-2); }
.settings-zone-table { margin: 0 0 var(--space-2); }
.settings-zone-table td .button { margin: 0; }
.settings-card-actions { margin-top: var(--space-4); display: flex; justify-content: flex-end; }
.settings-card-actions .button { margin: 0; }
.settings-save-bar { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: .75rem; margin-top: var(--space-4); }
.settings-save-bar button { min-width: 13rem; }
/* The long form's save button stays reachable while scrolling. */
.settings-form .settings-save-bar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin-top: 0;
    padding: var(--space-3) 0;
    background: var(--paper);
    border-top: 1px solid var(--border-subtle);
}
.settings-form .settings-save-bar button { margin: 0; }
/* Pushes the button to stay flush right even once this appears — same green as .success-banner.
   A filled pill (not plain text) with a pop-in animation, since the sticky save bar alone wasn't
   enough to make a shopkeeper notice a save actually happened — plain colored text next to a
   button they were already looking at still went unread. */
.settings-save-confirm {
    margin-right: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #fff;
    background: #1d7a3f;
    font-weight: 600;
    font-size: 0.92rem;
    padding: 0.55rem 0.9rem;
    border-radius: 999px;
    animation: settings-save-confirm-pop 0.25s ease-out;
}
@keyframes settings-save-confirm-pop {
    from { opacity: 0; transform: scale(0.9); }
    to { opacity: 1; transform: scale(1); }
}
.settings-security { margin-top: var(--space-2); }

/* Payment methods and advance-policy read as two separate decisions if stacked one after
   another with no visual link — side by side, it's clear at a glance they're two halves of the
   same setting (how you'll be paid, and when payment is asked for). */
.settings-advance-columns { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-5); align-items: start; }

@media (max-width: 900px) {
    .settings-group { grid-template-columns: 1fr; gap: var(--space-3); padding: var(--space-4) 0; }
    .settings-group-intro { display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-3); align-items: center; }
    .settings-group-icon { grid-row: 1 / span 2; margin: 0; }
    .settings-group-intro h2 { margin: 0; }
    .settings-advance-columns { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
    .settings-page-heading .button { width: 100%; box-sizing: border-box; }
    .settings-group-card { padding: var(--space-4); border-radius: 12px; }
    .settings-fields { grid-template-columns: 1fr; }
    .settings-logo-row { align-items: flex-start; }
    .settings-form .settings-save-bar { bottom: calc(64px + env(safe-area-inset-bottom, 0)); }
    .settings-save-bar button, .settings-card-actions .button { width: 100%; box-sizing: border-box; }
    .settings-card-actions { display: block; }
    .add-zone-row button { width: 100%; box-sizing: border-box; }
}
.storefront-card-wrapper { position: relative; }
.storefront-card-wrapper { display: flex; }
.storefront-card {
    display: flex;
    flex-direction: column;
    width: 100%;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    background: white;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.storefront-card:hover { border-color: #e2c8b8; box-shadow: 0 4px 14px rgba(44, 32, 20, 0.09); }
/* Fixed-size media box regardless of whether the card has a real photo or the 📦 placeholder,
   and regardless of that photo's own aspect ratio — without this, a portrait photo (tall)
   sized itself differently than a landscape photo or the placeholder icon, so the title/price
   below started at a different height card-to-card in the same row. object-fit:contain
   letterboxes any source image inside the same fixed square instead. */
.storefront-card-media {
    width: 100%;
    aspect-ratio: 1;
    overflow: hidden;
    background: #f6f2ed;
}
.storefront-card-media img { width: 94%; height: 94%; margin: 3%; object-fit: contain; display: block; }
.storefront-card-noimage {
    width: 100%; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
    font-size: 2.5rem; background: #f2ece5; color: var(--muted);
}
.storefront-card-noimage.large { aspect-ratio: 4/3; font-size: 4rem; border-radius: 8px; }
.storefront-card-body { padding: .8rem .9rem .85rem; display: flex; flex-direction: column; flex: 1; min-height: 5.75rem; }
/* Keep names safely clamped, but don't reserve an empty second line. This makes the important
   name → price relationship compact like a marketplace card; equal media/grid sizing still
   keeps all cards aligned. */
.storefront-card-name {
    font-weight: 600;
    font-size: 1rem;
    margin-bottom: 0.3rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.3;
}
.storefront-card-price { color: var(--brand); font-weight: 700; font-size: 1rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.storefront-card-price.contact-price { font-size: .92rem; line-height: 1.3; }
.storefront-card-shop {
    font-size: 0.8rem;
    margin-top: auto;
    padding-top: 0.6rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cart-add-button {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    z-index: 2;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.9);
    color: var(--muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 7px rgba(0, 0, 0, 0.12);
}
.cart-add-button:hover { color: var(--brand); }
/* Brief green flash right after a quick-add from the grid (ProductCard's own button, or
   AddToCartAction's simple-product path) — cart.js/AddToCartAction toggle this class off again
   on their own timer, so it never needs a second click to clear. */
.cart-add-button.added, .cart-add-btn.added { color: #2e7d32; }

.storefront-detail-title-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}
.storefront-detail-title-row h1 { margin: 0; }

.storefront-shop-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1rem;
    margin-top: 1rem;
}
/* Carousel container with left/right nav buttons instead of a scrollbar. */
.storefront-shop-carousel {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.5rem;
    width: 100%;
    min-height: 160px;
}
/* A single scrollable row ("slider" without an auto-rotating carousel — plain horizontal
   scroll + snap, no JS needed to scroll, but buttons trigger the scroll). */
.storefront-shop-row {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0.6rem 0.25rem 0.75rem;
    scroll-snap-type: x proximity;
    /* Hide native scrollbar — carousel buttons replace it. */
    scrollbar-width: none;
    /* Let the row flex to fill available space, pushing buttons to edges. */
    flex: 1;
    min-width: 0;
}
.storefront-shop-row::-webkit-scrollbar { display: none; }

/* Left/right carousel navigation buttons. */
.carousel-btn {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    min-width: 40px;
    min-height: 40px;
    padding: 0;
    border: 1px solid var(--brand);
    border-radius: 50%;
    background: white;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--brand);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s;
    box-shadow: 0 1px 4px rgba(184, 80, 42, 0.15);
    z-index: 2;
}
.carousel-btn:hover {
    background: var(--brand);
    color: white;
    box-shadow: 0 2px 8px rgba(184, 80, 42, 0.3);
}
.carousel-btn:active { transform: scale(0.92); }
.storefront-shop-card {
    display: flex;
    flex-direction: column;
    position: relative;
    flex: 0 0 220px;
    scroll-snap-align: start;
    min-height: 132px;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.5rem 1rem 1rem;
    text-decoration: none;
    color: inherit;
    background: white;
}
.storefront-shop-card:hover { border-color: var(--brand); }
.storefront-shop-name {
    font-weight: 700;
    font-size: 1.05rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.storefront-shop-type { margin-top: 0.15rem; }
/* Solid pill badge overlapping the card's top border — deliberately opaque (not the previous
   plain muted/left-aligned text) so it reads as a clear location tag rather than blending in. */
.storefront-shop-location-badge {
    position: absolute;
    top: -0.65rem;
    left: 0.85rem;
    /* box-sizing: border-box is required here — without it, max-width caps only the content
       box, and this pill's own padding/border get added ON TOP of that cap, pushing the
       rendered edge past the card regardless of what the max-width number said. Left offset
       is 0.85rem; the right side is given extra clearance (1.15rem, not a matching 0.85rem) so
       a long, truncated address visibly stops short of the card's edge rather than just
       grazing it. */
    box-sizing: border-box;
    max-width: calc(100% - 2rem);
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    background: white;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.2rem 0.65rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--brand);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.storefront-shop-location-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.storefront-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 2rem;
    margin-top: 1rem;
}

.storefront-detail-image-button {
    width: 100%;
    aspect-ratio: 1;
    max-height: 500px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: linear-gradient(135deg, #f9f7f4 0%, #f2ece5 100%);
    overflow: hidden;
    cursor: zoom-in;
}
.storefront-detail-image-button:focus-visible,
.storefront-thumb-button:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; }
.storefront-detail-main-image {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    transform-origin: var(--zoom-x, 50%) var(--zoom-y, 50%);
    transition: transform 0.18s ease;
    pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
    .storefront-detail-image-button.is-zoomed .storefront-detail-main-image { transform: scale(2); }
}
.storefront-thumb-row {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 0.25rem;
    scroll-behavior: smooth;
}
.storefront-thumb-button {
    display: block;
    box-sizing: border-box;
    width: 64px;
    height: 64px;
    margin: 0;
    padding: 0;
    border-radius: 6px;
    border: 2px solid transparent;
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color 0.15s;
    background: #f9f7f4;
    overflow: hidden;
}
.storefront-thumb-button img { width: 100%; height: 100%; display: block; object-fit: contain; }
.storefront-thumb-button:hover { border-color: var(--muted); }
.storefront-thumb-button.active { border-color: var(--brand); }
@media (prefers-reduced-motion: reduce) {
    .storefront-detail-main-image { transition: none; }
}

/* Gallery modal styles */
.gallery-backdrop {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    animation: fadeIn 0.2s ease;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.gallery-modal {
    position: relative;
    background: black;
    width: 90vw;
    height: 85vh;
    max-width: 1000px;
    max-height: 700px;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: scaleIn 0.2s ease;
}

@keyframes scaleIn {
    from { opacity: 0; transform: scale(0.9); }
    to { opacity: 1; transform: scale(1); }
}

.gallery-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    width: 44px;
    height: 44px;
    background: rgba(0, 0, 0, 0.6);
    border: none;
    border-radius: 50%;
    color: white;
    font-size: 1.5rem;
    cursor: pointer;
    z-index: 1002;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
}

.gallery-close:hover { background: rgba(0, 0, 0, 0.8); }

.gallery-image-container {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    overflow: hidden;
    position: relative;
    touch-action: none;
}

.gallery-image {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    animation: imageIn 0.3s ease;
}

@keyframes imageIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.gallery-counter {
    position: absolute;
    top: 1rem;
    left: 1rem;
    background: rgba(0, 0, 0, 0.6);
    color: white;
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    font-size: 0.9rem;
    font-weight: 600;
}

.gallery-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 50px;
    height: 50px;
    background: rgba(0, 0, 0, 0.5);
    border: none;
    color: white;
    font-size: 1.8rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    z-index: 1002;
    transition: background 0.15s;
}

.gallery-nav:hover { background: rgba(0, 0, 0, 0.75); }

.gallery-prev { left: 1rem; }
.gallery-next { right: 1rem; }

.gallery-thumbs-container {
    display: flex;
    gap: 0.5rem;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.3);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
}

.gallery-thumb {
    width: 60px;
    height: 60px;
    border: 2px solid transparent;
    border-radius: 6px;
    padding: 0;
    background: none;
    cursor: pointer;
    flex-shrink: 0;
    transition: border-color 0.15s;
    overflow: hidden;
}

.gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.gallery-thumb.active {
    border-color: white;
    box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
}

.gallery-thumb:hover { border-color: rgba(255, 255, 255, 0.5); }

/* Mobile: hide arrows and optimize layout */
@media (max-width: 640px) {
    .gallery-modal { max-height: 100vh; }
    .gallery-image-container { min-height: 200px; }
    .gallery-nav { width: 40px; height: 40px; font-size: 1.5rem; }
    .gallery-counter { font-size: 0.85rem; }
    .gallery-close { width: 40px; height: 40px; font-size: 1.3rem; }
}
.storefront-detail-price { font-size: 1.4rem; color: var(--brand); font-weight: 700; margin: 0.5rem 0; }
.storefront-detail-description { line-height: 1.6; white-space: pre-wrap; }
.storefront-detail-full-description {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
}
.storefront-detail-full-description h2 { margin: 0 0 0.75rem; }
.storefront-cta-row { display: flex; gap: 0.75rem; flex-wrap: nowrap; margin: 1.25rem 0; }
.storefront-shop-page .storefront-share,
.storefront-product-page .storefront-share {
    margin-top: 1rem;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
}
.storefront-shop-page .storefront-share summary,
.storefront-product-page .storefront-share summary,
.storefront-shop-page .storefront-about summary,
.storefront-product-page .storefront-seller-card summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--brand);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem 1.1rem;
    list-style: none;
}
.storefront-shop-page .storefront-share summary::-webkit-details-marker,
.storefront-product-page .storefront-share summary::-webkit-details-marker,
.storefront-shop-page .storefront-about summary::-webkit-details-marker,
.storefront-product-page .storefront-seller-card summary::-webkit-details-marker { display: none; }
.storefront-shop-page .storefront-share summary::after,
.storefront-product-page .storefront-share summary::after,
.storefront-shop-page .storefront-about summary::after,
.storefront-product-page .storefront-seller-card summary::after {
    content: "";
    margin-left: auto;
    width: 0.45rem;
    height: 0.45rem;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg);
    transition: transform 0.2s ease;
}
.storefront-shop-page .storefront-share[open] summary::after,
.storefront-product-page .storefront-share[open] summary::after,
.storefront-shop-page .storefront-about[open] summary::after,
.storefront-product-page .storefront-seller-card[open] summary::after { transform: rotate(225deg); }
.storefront-shop-page .storefront-share-body,
.storefront-product-page .storefront-share-body { padding: 1rem 1.1rem; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.storefront-shop-page .storefront-share-body .button,
.storefront-product-page .storefront-share-body .button { margin: 0; font-size: 0.95rem; }
.storefront-shop-page .storefront-share-body .button:disabled,
.storefront-product-page .storefront-share-body .button:disabled { opacity: 0.65; cursor: default; }

.contact-for-price { font-size: 1.1rem !important; }

/* Public "অর্ডার করুন" modal — same backdrop/panel/Escape mechanism as MobileMoreSheet's nav
   sheet, but its own class names since that one is mobile-only-styled (bottom-anchored sheet
   inside a max-width:640px media query) and this needs to look right at every width: a
   centered, modest-width panel on desktop, comfortably full-width on small screens. */
.order-now-backdrop {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.order-now-panel {
    background: var(--paper);
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
    overflow-y: auto;
    border-radius: 10px;
    padding: 1.25rem;
}
/* Tightened specifically for this panel, not the base `label` rule everywhere else — the
   checkout form (name, address, note, terms) stacks enough fields that the generic 0.75rem
   label margin pushed the confirm button below the fold on a laptop, forcing an internal
   scroll to reach it (confirmed live: "সর্বমোট"/checkbox/button all sat past the visible
   90vh). Every rule below only fires inside .order-now-panel — no other form on the site is
   affected. */
.order-now-panel label { margin: 0.4rem 0; }
.order-now-panel input::placeholder, .order-now-panel textarea::placeholder { font-size: 0.85em; }
.order-now-panel textarea { min-height: 3.6rem; }
.order-now-panel .muted.small { margin: 0.25rem 0; line-height: 1.35; }
.order-now-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin: -1.25rem -1.25rem 1rem;
    padding: .9rem 1.25rem;
    border-bottom: 1px solid var(--border-subtle);
    background: var(--surface-muted);
}
.order-now-product-line { font-weight: 600; margin-bottom: 0.5rem; }
/* "আপনার নম্বর: ০১৭… · বদলান" line at the top of the order form once the device is trusted —
   the number is shown, not editable, so changing it is a deliberate step. Text left, link
   right, both on the text baseline so the <button> never sits lower than the label. */
.order-now-identity { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; margin: 0 0 0.75rem; }
.order-now-identity .inline-add-related { padding: 0; font: inherit; font-weight: 600; line-height: inherit; white-space: nowrap; }
/* Code step: "মোবাইল নম্বর" label left, "নম্বর পরিবর্তন করুন" text link right, above the
   (disabled) number. Mirrors the label's own font/margin so the row reads as the field's label. */
.order-now-field-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; margin: 0.75rem 0 0.25rem; font-size: 0.9rem; color: var(--muted); }
.order-now-field-head .inline-add-related { padding: 0; font: inherit; font-weight: 600; line-height: inherit; white-space: nowrap; }
.order-now-verify-btn { width: 100%; justify-content: center; min-height: 3rem; margin-top: 0.75rem; }
/* In-button spinner for the order dialog's three waits (send code / verify / submit) — the
   button is already disabled during the round trip; this makes the wait visible instead of
   looking like a dead click. Inherits currentColor so it works on filled and outlined buttons. */
.btn-spinner { display: inline-block; width: 1em; height: 1em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: btn-spin 0.7s linear infinite; vertical-align: -0.15em; }
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* Page-level "still loading" indicator — invisible for the first 300ms (opacity: 0, animation-
   delay), so a fast load never shows it at all; fades in only once a load is actually slow
   enough to notice. See DelayedLoadingIndicator.razor's own comment for why this is pure CSS. */
.delayed-spinner {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    opacity: 0;
    animation: delayed-spinner-fade-in 0.2s ease 300ms forwards;
}
.delayed-spinner-circle {
    width: 2rem;
    height: 2rem;
    border: 3px solid var(--border);
    border-right-color: var(--brand);
    border-radius: 50%;
    animation: btn-spin 0.7s linear infinite;
}
@keyframes delayed-spinner-fade-in { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .delayed-spinner { animation: none; opacity: 1; }
    .delayed-spinner-circle { animation: none; }
}
.order-now-panel .button:disabled { opacity: 0.85; cursor: progress; }
/* "আবার কোড পাঠান। কোড পাচ্ছেন না? …" under the code field — an inline text-link row. */
.order-now-otp-help { margin-top: 0.75rem; line-height: 1.6; }
.order-now-otp-help .inline-add-related { padding: 0; font-size: inherit; }
/* Admin order detail: the customer proved this number with a code before ordering. */
.order-phone-verified { display: inline-flex; align-items: center; gap: 0.2rem; margin-left: 0.4rem; color: #2f7d3a; font-size: 0.85rem; font-weight: 600; }
.order-now-total-line { margin: 0.6rem 0; padding-top: 0.5rem; border-top: 1px solid var(--border); line-height: 1.4; }
/* Checkout consent checkbox (OrderNowAction.razor, CartBody.razor) — sits right above the
   final "অর্ডার নিশ্চিত করুন" button. align-items: flex-start (not center, unlike the generic
   .checkbox-label) because this text wraps to 2-3 lines on a phone; centering would float the
   checkbox in the middle of the wrapped text instead of lining up with its first line. .small
   (0.85rem) keeps it legible while taking noticeably less vertical space than the surrounding
   form labels. */
.checkout-terms-agree {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.5rem 0;
    cursor: pointer;
}
.checkout-terms-agree input[type="checkbox"] { margin-top: 0.2rem; flex-shrink: 0; width: auto; }
.order-now-success { text-align: center; }
.order-now-success-check { color: #2f7d3a; font-size: 1.2rem; font-weight: 700; }

.storefront-availability { font-weight: 600; margin: 0.25rem 0 0.75rem; }
.storefront-availability.in-stock { color: #2f7d3a; }
.storefront-availability.out-of-stock { color: var(--due); }
.storefront-availability-tag { font-size: 0.78rem; font-weight: 600; margin-top: 0.15rem; }
.storefront-availability-tag.in-stock { color: #2f7d3a; }
.storefront-availability-tag.out-of-stock { color: var(--due); }

/* On-page ধরন picker (ProductDetail.razor) — plain links, not a popup, so a size/colour click
   is one navigation, not two (open modal, then pick). */
.storefront-variant-picker { margin: 0.5rem 0 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
.storefront-variant-axis-label { display: block; font-size: 0.85rem; color: var(--muted); margin-bottom: 0.35rem; }
.storefront-variant-axis-label strong { color: var(--ink); font-weight: 600; }
.storefront-variant-chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.storefront-variant-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.9rem;
    text-decoration: none;
    color: inherit;
    background: #fff;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.storefront-variant-chip:hover { border-color: var(--brand); }
.storefront-variant-chip.selected { background: var(--brand); border-color: var(--brand); color: #fff; }
.storefront-variant-chip.out-of-stock { color: var(--muted); text-decoration: line-through; opacity: 0.6; }
.storefront-variant-chip.out-of-stock.selected { color: #fff; opacity: 0.85; }
.storefront-variant-swatch { width: 1rem; height: 1rem; border-radius: 50%; flex: 0 0 auto; border: 1px solid rgba(0, 0, 0, 0.15); }
.storefront-variant-chip.with-image { padding: .25rem .5rem .25rem .25rem; border-radius: 8px; min-height: 3rem; }
.storefront-variant-chip.with-image.image-only { padding: .2rem; }
.storefront-variant-choice-image { width: 2.5rem; height: 2.5rem; object-fit: cover; border-radius: 5px; flex: 0 0 auto; }
.storefront-variant-chip.with-image.image-only .storefront-variant-choice-image { width: 3rem; height: 3rem; }
.storefront-variant-chip.with-image.out-of-stock { text-decoration: none; }
.storefront-variant-chip.has-price .storefront-variant-chip-copy { display: inline-flex; flex-direction: column; align-items: flex-start; gap: .12rem; line-height: 1.15; }
.storefront-variant-chip-price { font-size: .76rem; font-weight: 600; opacity: .78; white-space: nowrap; }
.storefront-variant-chip.selected .storefront-variant-chip-price { opacity: .95; }
.storefront-variant-chip.with-image.image-only.has-price { flex-direction: column; }
.storefront-variant-chip.with-image.image-only.has-price .storefront-variant-chip-copy { align-items: center; }

.storefront-shop-description { margin: 0.5rem 0 0; line-height: 1.5; }
.storefront-shop-count { font-size: 0.8rem; color: var(--muted); margin-top: auto; padding-top: 0.4rem; }

.storefront-pagination { display: flex; align-items: center; gap: 1rem; margin-top: 1.5rem; }

.storefront-shop-page .storefront-about,
.storefront-product-page .storefront-seller-card { margin-top: 1.25rem; background: #fff; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.storefront-shop-page .storefront-about-body,
.storefront-product-page .storefront-seller-body { padding: 0 1.1rem 1rem; border-top: 1px solid var(--border); }
.storefront-shop-page .storefront-about-body p { margin: 0.65rem 0 0; }
.storefront-product-page .storefront-seller-name { font-weight: 700; margin: 0.85rem 0 0.25rem; font-size: 1.05rem; }
.storefront-product-page .storefront-seller-body .button { margin-top: 0.75rem; margin-right: 0.5rem; font-size: 0.95rem; }

/* The visual refresh is desktop-only. Keeping it behind this breakpoint preserves the
   storefront's existing phone layout and the separate mobile sticky-action behavior. */
@media (min-width: 641px) {
    .storefront-shop-page .storefront-shop-hero {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 2rem;
        padding: 1.5rem;
        background: #fff;
        border: 1px solid var(--border);
        border-radius: 16px;
        box-shadow: 0 8px 24px rgba(57, 43, 31, 0.06);
    }
    .storefront-shop-page .storefront-shop-main { align-self: stretch; align-items: stretch; min-width: 0; }
    .storefront-shop-page .storefront-shop-main .storefront-logo {
        width: 108px;
        height: auto;
        min-height: 88px;
        align-self: stretch;
        object-fit: cover;
        box-sizing: border-box;
    }
    .storefront-shop-page .storefront-shop-identity { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
    .storefront-shop-page .storefront-shop-hero h1 { margin: 0; font-size: 1.9rem; }
    .storefront-shop-page .storefront-shop-hero .muted { margin: 0.4rem 0 0; font-size: 1.05rem; }
    .storefront-shop-page .storefront-shop-hero .storefront-cta-row { margin: 0; flex-shrink: 0; }

    .storefront-shop-page .storefront-search {
        width: 100%;
        max-width: none;
        margin: 1rem auto 2rem;
    }
    #storefront-shop-product-search {
        flex: 1 1 auto;
        width: auto;
        min-width: 0;
        max-width: none;
        min-height: 48px;
        font-size: 1.05rem;
    }
    .storefront-shop-page .storefront-search button { flex: 0 0 auto; min-height: 48px; padding-inline: 1.35rem; }

    .storefront-shop-page .storefront-section-title { margin: 0 0 1rem; font-size: 1.7rem; }
    .storefront-shop-page .storefront-section-title::after { content: ""; display: block; width: 2.25rem; height: 3px; margin-top: 0.4rem; border-radius: 999px; background: var(--brand); }
    .storefront-shop-page .storefront-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 245px)); gap: 1.1rem; }
    .storefront-shop-page .storefront-card-name { font-size: 1.15rem; }
    .storefront-shop-page .storefront-card-price { font-size: 1.1rem; }
    .storefront-shop-page .storefront-card-price.contact-price,
    .storefront-shop-page .storefront-availability-tag { font-size: 1rem; }
    .storefront-shop-page .storefront-about summary,
    .storefront-shop-page .storefront-share summary { font-size: 1.1rem; }
    .storefront-shop-page .storefront-about-body { font-size: 1.05rem; }

    .storefront-product-page .storefront-detail { gap: 1.5rem; align-items: start; margin-top: 0; }
    .storefront-product-page .storefront-detail-images {
        padding: 0.75rem;
        background: #fff;
        border: 1px solid var(--border);
        border-radius: 16px;
        box-shadow: 0 8px 24px rgba(57, 43, 31, 0.05);
    }
    .storefront-product-page .storefront-product-purchase-card {
        padding: 1.5rem;
        background: #fff;
        border: 1px solid var(--border);
        border-radius: 16px;
        box-shadow: 0 8px 24px rgba(57, 43, 31, 0.05);
    }
    .storefront-product-page .storefront-product-purchase-card .storefront-detail-title-row h1 { font-size: 2rem; }
    .storefront-product-page .storefront-product-purchase-card .storefront-detail-price { font-size: 1.75rem; margin-top: 0.65rem; }
    .storefront-product-page .storefront-product-purchase-card .storefront-availability { font-size: 1.05rem; }
    .storefront-product-page .storefront-product-purchase-card .storefront-cta-row { display: block; margin: 1.25rem 0 0; }
    .storefront-product-page .storefront-purchase-actions { display: grid; gap: 0.65rem; }
    .storefront-product-page .storefront-purchase-actions > .button,
    .storefront-product-page .storefront-contact-actions > .button { box-sizing: border-box; width: 100%; justify-content: center; min-height: 46px; }
    .storefront-product-page .storefront-contact-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.65rem; margin-top: 0.65rem; }
    .storefront-product-page .storefront-seller-card summary,
    .storefront-product-page .storefront-share summary { font-size: 1.1rem; }
    .storefront-product-page .storefront-detail-full-description {
        padding: 1.25rem;
        background: #fff;
        border: 1px solid var(--border);
        border-radius: 14px;
    }
}

/* Hidden on desktop — a compact always-visible contact bar only makes sense once buttons
   would otherwise scroll out of view on a small screen. */
.storefront-sticky-actions { display: none; }

.landing-search { max-width: 480px; margin-left: auto; margin-right: auto; }
.landing-cta-section {
    max-width: 640px; margin: 3rem auto 1rem; text-align: center;
    padding: 1.5rem; border-top: 1px solid var(--border);
}
.landing-cta-section .muted { margin: 0.35rem 0 1rem; }

/* Short public legal/help pages: deliberately quiet, readable and independent of the
   admin layout so visitors can understand the rules without signing in. */
.legal-page { max-width: 780px; margin: 0 auto; padding: 2.5rem 1rem 3rem; }
.legal-page > h1 { margin: 0; }
.legal-page > p { line-height: 1.7; }
.legal-page section { margin-top: 2rem; }
.legal-page h2 { font-size: 1.25rem; margin: 0 0 0.55rem; }
.legal-page section p, .legal-page li { line-height: 1.7; }
.legal-page ul { padding-left: 1.25rem; }
.legal-updated, .legal-intro { color: var(--muted); margin-top: 0.45rem; }
.faq-page details { border: 1px solid var(--border); border-radius: 6px; background: white; margin-top: 0.65rem; padding: 0.85rem 1rem; }

/* Public pricing: show the current free period separately from the two 2027 rates. */
.pricing-page { box-sizing: border-box; max-width: 1120px; margin: 0 auto; padding: 3rem 1.25rem 4.5rem; }
.pricing-page * { box-sizing: border-box; }
.pricing-page h1, .pricing-page h2, .pricing-page h3, .pricing-page p { margin-top: 0; }
.pricing-page a:focus-visible, .pricing-page summary:focus-visible { outline: 3px solid #ff9f40; outline-offset: 3px; }
.pricing-hero { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(250px, .75fr); gap: 2.5rem; align-items: center; position: relative; overflow: hidden; padding: clamp(2rem, 5vw, 3.75rem); border: 1px solid #cfe0f8; border-radius: 28px; background: radial-gradient(circle at 96% 0%, #dceaff 0, transparent 38%), linear-gradient(120deg, #f5f9ff 0%, #eaf3ff 100%); }
.pricing-hero::after { content: ""; position: absolute; width: 180px; height: 180px; right: -95px; bottom: -105px; border: 28px solid rgba(242, 140, 40, .16); border-radius: 50%; pointer-events: none; }
.pricing-hero-copy, .pricing-now { position: relative; z-index: 1; }
.pricing-hero .section-kicker { margin-bottom: .8rem; }
.pricing-hero h1 { max-width: 680px; margin-bottom: .9rem; color: #172c49; font-size: clamp(2rem, 4.3vw, 3.45rem); line-height: 1.28; letter-spacing: -.02em; }
.pricing-lead { max-width: 570px; margin-bottom: 0; color: #455b74; font-size: 1.08rem; line-height: 1.65; }
.pricing-hero-actions { display: flex; align-items: center; flex-wrap: wrap; gap: .85rem 1.1rem; margin-top: 1.65rem; }
.pricing-hero-actions > span { color: #536980; font-size: .87rem; line-height: 1.5; }
.pricing-primary-action.button { min-height: 48px; margin: 0; padding: .7rem 1.25rem; border-radius: 11px; font-weight: 700; justify-content: center; }
.pricing-primary-action .icon { width: 1.05em; height: 1.05em; }
.pricing-now { display: flex; flex-direction: column; align-items: flex-start; padding: 1.7rem; border: 1px solid #d2e2f6; border-radius: 20px; background: #fff; box-shadow: 0 18px 40px rgba(25, 81, 148, .08); }
.pricing-now-eyebrow { color: #496580; font-size: .9rem; font-weight: 700; }
.pricing-now-amount { margin: .55rem 0 .15rem; color: var(--brand); font-size: clamp(3.5rem, 5vw, 5rem); font-weight: 800; line-height: 1; }
.pricing-now strong { margin-top: .55rem; color: #203451; font-size: 1rem; }
.pricing-now > span:last-child { margin-top: .35rem; color: var(--muted); font-size: .86rem; }
.pricing-page > section { margin-top: 4.1rem; }
.pricing-section-heading { display: flex; align-items: end; justify-content: space-between; gap: 1rem; margin-bottom: 1.35rem; }
.pricing-section-heading .section-kicker { margin-bottom: .35rem; }
.pricing-section-heading h2 { margin: 0; color: #1c304a; font-size: clamp(1.55rem, 2.5vw, 2.1rem); line-height: 1.35; }
.pricing-section-heading > p { margin: 0 0 .15rem; color: var(--muted); font-size: .95rem; }
.pricing-rates-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem; }
.pricing-rate { min-width: 0; padding: 1.65rem; border: 1px solid #dce4ef; border-radius: 20px; background: #fff; box-shadow: 0 7px 24px rgba(29, 51, 79, .035); }
.pricing-rate-early { border-color: #9bc3f7; background: linear-gradient(145deg, #fff 20%, #f4f9ff 100%); box-shadow: 0 11px 32px rgba(26, 115, 232, .08); }
.pricing-rate-badge, .pricing-rate-overline { display: inline-flex; align-items: center; min-height: 27px; margin-bottom: 1rem; font-size: .8rem; font-weight: 700; }
.pricing-rate-badge { padding: .15rem .7rem; border-radius: 999px; background: #e7f1ff; color: #115fc2; }
.pricing-rate-overline { color: var(--muted); }
.pricing-rate h3 { min-height: 3.1em; margin-bottom: .7rem; color: #263952; font-size: 1rem; line-height: 1.55; }
.pricing-rate-amount { color: #172c49; font-size: clamp(2.2rem, 3.8vw, 3.1rem); font-weight: 800; line-height: 1.15; }
.pricing-rate-early .pricing-rate-amount { color: #1265d1; }
.pricing-rate-amount span { color: var(--muted); font-size: 1rem; font-weight: 500; }
.pricing-rate p { margin: .7rem 0 0; color: var(--muted); font-size: .94rem; line-height: 1.6; }
.pricing-feature-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .8rem; }
.pricing-feature { display: flex; align-items: flex-start; gap: .8rem; min-width: 0; padding: 1.2rem; border: 1px solid #e0e8f2; border-radius: 17px; background: #fff; }
.pricing-feature-icon { flex: 0 0 40px; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; border-radius: 12px; background: #eaf3ff; color: #1769d2; }
.pricing-feature-icon .icon { width: 21px; height: 21px; }
.pricing-feature h3 { margin: .05rem 0 .3rem; color: #21364f; font-size: 1rem; line-height: 1.45; }
.pricing-feature p { margin: 0; color: var(--muted); font-size: .88rem; line-height: 1.62; }
.pricing-browser-note { display: flex; align-items: flex-start; gap: .45rem; margin: 1rem 0 0; color: #4b627c; font-size: .9rem; line-height: 1.5; }
.pricing-browser-note .icon { flex: 0 0 auto; margin-top: .15rem; color: var(--brand); }
.pricing-detail-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .8rem; }
.pricing-detail { padding: 1.2rem; border: 1px solid #e0e8f2; border-radius: 17px; background: #fff; }
.pricing-detail h3 { margin-bottom: .55rem; color: #21364f; font-size: 1rem; }
.pricing-detail p { margin: 0; color: var(--muted); font-size: .9rem; line-height: 1.65; }
.pricing-detail small { display: block; margin-top: .65rem; color: #6b7d90; font-size: .76rem; line-height: 1.5; }
.pricing-page > .pricing-support { display: flex; align-items: center; justify-content: space-between; gap: 2rem; padding: 1.8rem 2rem; border-radius: 22px; background: linear-gradient(110deg, #173d75, #195da9); color: #fff; }
.pricing-support .section-kicker { color: #bcd9ff; }
.pricing-support h2 { margin-bottom: .5rem; color: #fff; font-size: 1.55rem; }
.pricing-support p:not(.section-kicker) { max-width: 620px; margin: 0; color: #e5efff; font-size: .94rem; line-height: 1.65; }
.pricing-support-contact { display: flex; flex: 0 0 auto; flex-direction: column; align-items: flex-start; gap: .3rem; padding: 1rem 1.25rem; border: 1px solid rgba(255,255,255,.25); border-radius: 14px; background: rgba(255,255,255,.1); }
.pricing-support-contact span { color: #d9eaff; font-size: .8rem; }
.pricing-support-contact > a:first-of-type { color: #fff; font-family: Arial, sans-serif; font-size: 1.45rem; font-weight: 700; text-decoration: none; }
.pricing-support-contact .pricing-support-link { margin-top: .35rem; color: #fff; font-size: .8rem; text-decoration: underline; text-underline-offset: .2em; }
.pricing-page > .pricing-fee-note { margin-top: 1.35rem; padding: 1rem 1.25rem; border: 1px solid #dce4ef; border-radius: 13px; background: #fff; }
.pricing-fee-note summary { color: #2b405a; cursor: pointer; font-weight: 700; }
.pricing-fee-note p { margin: .7rem 0 0; color: var(--muted); font-size: .9rem; line-height: 1.7; }
.pricing-bottom-cta { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; margin-top: 3.5rem; padding: 1.55rem 1.8rem; border: 1px solid #cfe0f8; border-radius: 19px; background: #eaf3ff; }
.pricing-bottom-cta h2 { margin: 0 0 .3rem; color: #1d3452; font-size: 1.4rem; }
.pricing-bottom-cta p { margin: 0; color: #536980; font-size: .9rem; }
.pricing-more-questions { margin: 1.3rem 0 0; color: var(--muted); font-size: .9rem; text-align: center; line-height: 1.65; }
.pricing-more-questions a { font-weight: 700; }
@media (max-width: 850px) {
    .pricing-hero { grid-template-columns: minmax(0, 1fr) minmax(220px, .7fr); gap: 1.3rem; }
    .pricing-feature-grid, .pricing-detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pricing-page > .pricing-support { align-items: flex-start; flex-direction: column; }
}
@media (max-width: 640px) {
    .pricing-page { padding: 1.2rem 1rem 3rem; }
    .pricing-hero { grid-template-columns: 1fr; gap: 1.4rem; padding: 1.45rem; border-radius: 20px; }
    .pricing-hero h1 { font-size: clamp(1.75rem, 7.3vw, 2.25rem); }
    .pricing-page .pricing-lead { font-size: 1.05rem; }
    .pricing-hero-actions { align-items: stretch; flex-direction: column; margin-top: 1.25rem; }
    .pricing-primary-action.button { width: 100%; }
    .pricing-now { padding: 1.2rem; border-radius: 16px; }
    .pricing-now-amount { font-size: 3.65rem; }
    .pricing-page > section { margin-top: 3rem; }
    .pricing-section-heading { align-items: flex-start; flex-direction: column; gap: .3rem; }
    .pricing-rates-grid, .pricing-feature-grid, .pricing-detail-grid { grid-template-columns: 1fr; }
    .pricing-rate { padding: 1.3rem; }
    .pricing-rate h3 { min-height: 0; }
    .pricing-page > .pricing-support { gap: 1.3rem; padding: 1.4rem; border-radius: 18px; }
    .pricing-support-contact { width: 100%; }
    .pricing-bottom-cta { align-items: stretch; flex-direction: column; padding: 1.35rem; margin-top: 2.6rem; }
}
.faq-page summary { color: var(--ink); cursor: pointer; font-weight: 700; }
.faq-page details p { margin: 0.75rem 0 0; line-height: 1.65; }
/* Landing-page FAQ only: plain rows on the paper ground — no boxes, no dividers — with the
   browser's native ▶/▼ marker kept (the user preferred it) in ink; only the open
   question's title takes the brand colour. /faq keeps its boxed style. */
.landing-faq-list details { border: 0; border-radius: 0; background: transparent; margin: 0; padding: 0.55rem 0; }
.landing-faq-list summary { font-size: 1.05rem; padding: 0.4rem 0; }
.landing-faq-list summary::marker { color: var(--ink); }
.landing-faq-list details[open] summary { color: var(--brand); }
.landing-faq-list details p { margin: 0.4rem 0 0.5rem 1.25rem; color: var(--muted); max-width: 640px; }
.landing-voice-demo { margin: 0.7rem 0 0.8rem 1.25rem; max-width: 680px; color: var(--muted); }
.landing-faq-list details .landing-voice-demo p,
.faq-page details .landing-voice-demo p { margin: 0; max-width: none; }
.landing-voice-lead { line-height: 1.6; }
.landing-voice-step { display: grid; grid-template-columns: 1.65rem minmax(0, 1fr); gap: 0.65rem; align-items: start; margin-top: 1rem; }
.landing-voice-step-number { display: inline-flex; align-items: center; justify-content: center; width: 1.65rem; height: 1.65rem; border-radius: 50%; background: #fdf2e7; color: var(--brand); font-size: 0.78rem; font-weight: 700; }
.landing-voice-step-body { min-width: 0; }
.landing-voice-step p + * { margin-top: 0.55rem; }
.landing-voice-control { pointer-events: none; user-select: none; cursor: default; }
.landing-voice-demo .voice-section-summary { margin-top: 0.55rem; cursor: default; }
.landing-voice-demo .voice-section-summary:hover { background: #fdf5ee; }
.landing-voice-preview { margin: 0.55rem 0 0; padding: 0.85rem; }
.landing-voice-text-sample { min-height: 3.25rem; background: white; color: #777; line-height: 1.45; }
.landing-voice-demo .voice-mic-btn:hover:not(:disabled) { background: white; color: var(--brand); }
.landing-voice-demo .voice-mic-btn.recording { background: var(--due); color: white; animation: none; }
.landing-voice-demo .voice-cancel-btn:hover { background: white; color: var(--muted); border-color: var(--border); }
.landing-voice-examples-static { margin-top: 0.65rem; }
.landing-voice-example-title { font-weight: 600; color: var(--muted); }
.landing-voice-examples-static .voice-examples { margin-bottom: 0.4rem; }
.landing-faq-list details .landing-voice-examples-static p,
.faq-page details .landing-voice-examples-static p { font-size: 0.82rem; }
.landing-voice-recording-sample { margin: 0.55rem 0; padding: 0.7rem; background: #fdfaf6; border: 1px solid #eddac4; border-radius: 12px; }
.landing-faq-list details .landing-voice-typing,
.faq-page details .landing-voice-typing { margin-top: 1rem; line-height: 1.55; }
.landing-voice-page-note { display: grid; grid-template-columns: 1.7rem minmax(0, 1fr); gap: 0.65rem; margin-top: 1rem; padding: 0.85rem; background: var(--surface-muted); border-radius: 10px; }
.landing-voice-page-note > .icon { color: var(--brand); font-size: 1.15rem; margin-top: 0.1rem; }
.landing-faq-list details .landing-voice-page-note p,
.faq-page details .landing-voice-page-note p { margin-top: 0.35rem; line-height: 1.5; }
.landing-voice-page-note a { display: inline-block; margin-top: 0.45rem; color: var(--brand); font-weight: 600; text-decoration: none; }
.landing-voice-page-note a:hover { text-decoration: underline; }
.landing-faq-list details .landing-voice-browser-note,
.faq-page details .landing-voice-browser-note { margin-top: 0.75rem; font-size: 0.82rem; }
@media (max-width: 700px) {
    .landing-voice-demo { margin-left: 0.6rem; }
    .landing-voice-preview { padding: 0.75rem; }
    .landing-voice-preview .voice-fill-btn { width: 100%; text-align: center; }
    .landing-voice-recording-sample { gap: 0.5rem; }
}

/* Public pages render <SiteHeader />, the page's own content and <SiteFooter /> as direct
   children of <body> (MainLayout is just @Body). On a short page (login, a 404) the footer
   used to sit mid-screen with empty paper below it. Flex column body + auto top margin on
   the footer: it pins to the bottom of the viewport when the
   content is short, and flows normally after it when long. Scoped with :has() so only pages
   that actually carry the public footer get the flex body — the admin shell has its own
   min-height column and is untouched. */
body:has(> .site-footer) { min-height: 100vh; display: flex; flex-direction: column; }
/* In a flex column, a child with "margin: 0 auto" (the header, the browse/landing wrappers)
   shrink-wraps to its content and centres instead of filling the row — confirmed live on a
   phone: the landing header collapsed to a narrow strip and the browse page overflowed.
   Explicit width restores block-like sizing; max-width + auto margins still centre as before. */
body:has(> .site-footer) > * { width: 100%; box-sizing: border-box; flex-shrink: 0; }
/* margin-top:auto on the FOOTER (not flex-grow on the content) — growing the content element
   stretched the login card into a tall empty box. The auto margin absorbs the spare space
   instead, so content keeps its natural size; the sibling rule keeps the 3rem gap the footer
   normally has when the page is long and the auto margin collapses to zero. */
body:has(> .site-footer) > .site-footer { margin-top: auto; }
/* :not(.order-now-backdrop): CartBody.razor closes its page wrapper BEFORE rendering the
   checkout modal (see that file), so while the modal is open this fixed, inset:0 backdrop is
   itself the direct-body-child-right-before-.site-footer this rule targets — margin-bottom on
   an absolutely-positioned box with both top AND bottom already pinned (inset:0) is not just
   extra space beside it, it shrinks the box itself by that amount, leaving the real page
   visible through a 3rem gap at the bottom of what should be a full-viewport backdrop
   (confirmed live via DevTools: this exact rule was the only one matching the backdrop
   element). Excluded by class rather than restructuring the markup, since every other page
   this rule exists for is unaffected either way. */
body:has(> .site-footer) > :has(+ .site-footer):not(.order-now-backdrop) { margin-bottom: 3rem; }
.site-footer {
    margin-top: 3rem;
    border-top: 1px solid var(--border);
    background: #f2ece5;
}
.site-footer-inner {
    max-width: 1120px;
    margin: 0 auto;
    padding: 2rem 1rem;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 1.5rem;
}
.site-footer-brand .site-logo { margin-bottom: 0.5rem; }
.site-footer-brand p { max-width: 320px; }
.site-footer-column h3 { font-size: 0.9rem; margin: 0 0 0.6rem; color: var(--muted); }
.site-footer-column { display: flex; flex-direction: column; gap: 0.5rem; }
.site-footer-column a { color: var(--ink); text-decoration: none; font-size: 0.9rem; }
.site-footer-column a:hover { color: var(--brand); text-decoration: underline; }
.site-footer-bottom {
    border-top: 1px solid var(--border);
    padding: 1rem;
    text-align: center;
}
.site-footer-bottom p { margin: 0; font-size: 0.8rem; color: var(--muted); }

@media (max-width: 640px) {
    /* Reduced padding/gap and a smaller logo — the desktop sizing (1rem header padding + a
       32px logo icon + six 44px-min icons) added up to ~446px, wider than a 375-414px phone
       viewport, and was pushing the row off both edges (confirmed live). */
    .site-header { flex-wrap: nowrap; padding: 0.6rem 0.5rem 0; gap: 0.4rem; }
    .site-logo { gap: 0.35rem; }
    /* Keep the brand mark clearly more prominent than an individual navigation icon while
       preserving enough room for all five compact mobile actions. */
    .site-logo-icon { width: 64px; height: 44px; }
    .site-logo-text { font-size: 1rem; }
    .site-header-actions { gap: 0; flex-shrink: 0; }
    .site-header-icon-label { display: none; }
    /* border-box so min-width IS the tap target (38px), not 38px + padding: seven icons plus
       the logo overflowed a 375px phone and clipped the last one (লগইন). */
    .site-header-icon { padding: 0.4rem; min-width: 38px; min-height: 38px; box-sizing: border-box; justify-content: center; }
    .site-header-icon-glyph { font-size: 1rem; }
    .site-header-dropdown-panel {
        right: auto;
        left: 50%;
        transform: translateX(-50%);
        max-width: calc(100vw - 2rem);
    }
    /* A little smaller than desktop so the longest category label ("মোবাইল, কম্পিউটার ও
       ইলেকট্রনিক্স") still fits on one line within a phone's narrower width. */
    .site-header-dropdown-panel a { font-size: 0.82rem; padding: 0.5rem 0.5rem; }
    /* Labels collapse on mobile to save space, so a filled dot is the only way to tell a
       filter is active without opening the dropdown — still satisfies "selected value is
       shown" without crowding the header. */
    .site-header-icon.has-value::after {
        content: "";
        position: absolute;
        top: 6px;
        right: 6px;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: var(--brand);
    }

    .cart-add-button { min-width: 44px; min-height: 44px; }
    .cart-page-heading { align-items: flex-start; margin-bottom: var(--space-4); }
    .cart-continue-link { padding-top: 0.4rem; }
    .cart-checkout-bar { bottom: var(--space-2); padding: var(--space-3); }
    .cart-checkout-bar .button { padding-inline: 0.9rem; }

    .landing { padding: 1.5rem 1rem .25rem; }
    .landing-hero { text-align: left; }
    .landing-hero h1 { font-size: 1.85rem; line-height: 1.22; }
    .landing-hero > p:last-child { margin-left: 0; }
    .storefront-search { margin-top: 1.1rem; }
    .landing-search input, .landing-search button { min-height: 3rem; }
    .landing-search input { font-size: 1rem; }
    .landing-search button { padding-inline: .95rem; }
    .storefront-page { padding-top: 1.5rem; }
    .storefront-section { margin-top: 2.1rem; }
    .storefront-section-heading h2 { font-size: 1.55rem; }

    /* Mobile product grid: two columns fit on a typical ~375px phone screen.
       minmax(0, 1fr), not bare 1fr — a bare 1fr track still respects its content's intrinsic
       min-width, and white-space:nowrap text (shop name, WhatsApp/কল করুন buttons) was forcing
       one column wider than the other (confirmed live: 172px vs 240px instead of an even
       split). minmax(0, ...) removes that floor so both columns are always exactly equal. */
    .storefront-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }

    .storefront-card-body { min-height: 7.35rem; padding: 0.65rem 0.7rem 0.75rem; }
    .storefront-card-price.contact-price { font-size: .86rem; }

    .storefront-shop-card { flex-basis: 180px; }

    .site-footer-inner { grid-template-columns: 1fr; }

    .browse-filter-pill { font-size: 0.8rem; padding: 0.45rem 0.65rem; }

    .landing-page { padding: 1.5rem 1rem 2.5rem; }
    .landing-hero-split { grid-template-columns: 1fr; gap: 1.75rem; }
    .landing-hero-copy h1 { font-size: 1.8rem; }
    .landing-hero-cta { flex-direction: column; align-items: stretch; gap: 0.6rem; }
    /* box-sizing: border-box — no global reset in this stylesheet, so width:100% plus the
       button's own 1.6rem side padding overflowed the column on a phone. */
    .landing-hero-cta .button { width: 100%; min-height: 48px; box-sizing: border-box; }
    .landing-hero-login { text-align: center; }

    /* Keep the full landing header on one row across phone widths. Its four labelled actions
       need tighter, fluid sizing than the shopper header; scope every reduction to this header
       so public-store and admin navigation retain their established tap targets. */
    .site-header-landing { padding: 0.45rem 0.35rem; gap: 0.1rem; flex-wrap: nowrap; }
    /* Matches the shopper header's mobile logo size (app.css ~line 3030) — was shrunk to 36x40
       here to fight for space, but the real space problem was the gap below, not the logo. */
    .site-header-landing .site-logo-icon { width: 64px; height: 44px; }
    /* Phone: the section anchors go, while the buyer search link keeps both its icon and text.
       Desktop's margin-left:auto on .landing-nav-browse is kept here on purpose — it groups the
       search link with ব্যবসা শুরু করুন/লগইন on the right, away from the logo, matching the
       intended right-aligned action cluster. */
    .site-header-landing .landing-nav { display: flex; margin-left: 0.1rem; flex: 1 1 auto; min-width: 0; gap: 0; overflow: hidden; }
    .landing-nav a:not(.landing-nav-browse) { display: none; }
    .site-header-landing .landing-nav .landing-nav-browse {
        padding: 0.3rem 0.12rem;
        gap: 0.25rem;
        font-size: clamp(0.72rem, 3.4vw, 0.9rem);
        white-space: nowrap;
        /* .landing-nav-browse span below still needs to shrink/truncate independently — this
           element itself is a flex row (icon + span), so overflow has to be set on the span,
           not here, or the icon would get clipped too. */
        min-width: 0;
        max-width: 100%;
    }
    .site-header-landing .landing-nav .landing-nav-browse span {
        overflow: hidden;
        text-overflow: ellipsis;
        min-width: 0;
    }
    .site-header-landing .landing-nav .landing-nav-browse .icon { flex-shrink: 0; }
    .site-header-landing .landing-nav .landing-nav-browse .icon { width: 1.05rem; height: 1.05rem; }
    .landing-nav .landing-nav-browse span { display: inline; }
    .site-header-landing .landing-nav-actions { gap: 0.1rem; flex-shrink: 0; }
    .site-header-landing .landing-nav-login {
        padding: 0.3rem 0.25rem;
        gap: 0.2rem;
        font-size: clamp(0.72rem, 3vw, 0.85rem);
    }
    .landing-nav-cta.button {
        min-height: 0;
        padding: 0.3rem 0.4rem;
        border-color: transparent;
        background: transparent;
        background-image: none;
        box-shadow: none;
        color: var(--ink);
        font-size: clamp(0.72rem, 3vw, 0.85rem);
        font-weight: 500;
        line-height: 1.1;
        gap: 0.2rem;
    }
    .landing-nav-cta.button:hover { background: #f2ece5; }
    .landing-steps { grid-template-columns: 1fr; }

    /* Bridge stacks on a phone; the link becomes a full-width outlined button. */
    .landing-bridge { flex-direction: column; align-items: stretch; gap: 0.9rem; padding: 1.25rem 0; margin-top: 3rem; }
    .landing-bridge-link { justify-content: center; border: 1px solid var(--brand); border-radius: 4px; padding: 0.65rem 1rem; }

    /* Phone mock below the copy, scaled down so it doesn't dominate a real phone's screen. */
    .landing-hero-split { gap: 2.5rem; }
    /* Glow sits behind the (now stacked, centred) phone rather than off to the right. */
    .landing-hero-split::before { right: 50%; top: auto; bottom: 0; width: 420px; height: 420px; transform: translate(50%, 10%); }
    .landing-phone { width: 240px; height: 470px; border-radius: 30px; padding: 9px; }
    .landing-phone-screen { border-radius: 22px; }
    .landing-phone-head { padding: 1.1rem 1rem 0.6rem; font-size: 0.85rem; }
    .landing-phone-stat { margin: 0 0.75rem; padding: 0.8rem 0.9rem; }
    .landing-phone-stat-value { font-size: 1.6rem; }
    .landing-phone-stat-split { padding: 0.75rem 0.7rem; }
    .landing-phone-stat-split .landing-phone-stat-value { font-size: 1.05rem; }
    .landing-phone-chips { margin: 0.5rem 0.75rem 0; gap: 0.35rem; }
    .landing-phone-chip { font-size: 0.64rem; padding: 0.3rem 0.5rem; }
    .landing-phone-row { margin: 0.5rem 0.75rem 0; padding: 0.6rem 0.75rem; }
    .landing-phone-voice { margin: auto 0.75rem 1rem; font-size: 0.72rem; padding: 0.65rem 0.85rem; }

    .landing-section { margin-top: 3.5rem; }
    .landing-section h2 { font-size: 1.5rem; margin-bottom: 1.5rem; }
    .landing-features { grid-template-columns: 1fr; gap: 1.5rem; }
    .landing-steps { grid-template-columns: 1fr; gap: 1.25rem; }

    .storefront-page { padding-bottom: 100px; }
    .storefront-detail { grid-template-columns: 1fr; gap: 1rem; }
    .storefront-detail-info { margin-bottom: 2rem; }
    /* Primary contact actions stay reachable without scrolling back up on mobile.
       box-sizing: border-box is required here — there's no global box-sizing reset in this
       file, so width:100% + padding would otherwise add the padding on top of 100% (content-box
       default) and push the bar past both edges of the viewport. */
    .storefront-sticky-actions {
        display: flex; gap: 0.5rem; position: sticky; bottom: 0; z-index: 5;
        padding: 0.75rem 1rem; background: var(--paper); border-top: 1px solid var(--border);
        width: 100%; box-sizing: border-box;
    }
    /* OrderNowAction's own confirmation dialog is a descendant of this sticky bar
       (position:sticky + z-index:5 traps it the same way — see the modal-tier note on
       .facebook-preview-modal-backdrop); escalate above the sticky site header (z-index
       500) while it's open. */
    .storefront-sticky-actions:has(.order-now-backdrop) { z-index: 1101; }
    /* Plain-class twin of the :has() rule above for browsers without :has() — set by
       js/overlay-escalation.js. Kept as a SEPARATE rule on purpose: one unknown selector in
       a comma list makes an old browser drop the entire rule, twin included. */
    .storefront-sticky-actions.has-open-overlay { z-index: 1101; }
    /* box-sizing: border-box is required here — same root cause as the storefront-share-body
       fix above: .button's default padding is content-box, so 4 flex:1 buttons (order, cart,
       call, WhatsApp — the longest Bengali labels among them) overflowed the viewport width.
       Tighter padding/gap/font-size keep every label on one line at the smallest supported
       screen width instead of wrapping or clipping. */
    .storefront-sticky-actions .button {
        flex: 1 1 0; box-sizing: border-box; text-align: center; justify-content: center;
        min-width: 0; min-height: 44px; padding: 0.5rem 0.2rem; gap: 0.15rem;
        font-size: 0.78rem; line-height: 1.15; white-space: normal;
    }

    /* Sharing is a set of peer actions, so on a phone each one gets the same target size
       regardless of its label length. A two-column grid also avoids the last, long label
       shrinking every other action into an uneven row. */
    .storefront-share-body {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: stretch;
        gap: 0.65rem;
    }
    .storefront-share-body .button {
        /* box-sizing: border-box is required here — <button> gets it for free from the browser's
           UA stylesheet (every form control does), <a> does not (content-box is the general CSS
           default), so the same width: 100% + min-height: 48px rendered the two <a> buttons
           (Facebook, WhatsApp) visibly larger than the two <button> ones (আরও, লিংক কপি করুন) —
           their padding was being added on top instead of included. Same root cause fixed
           several times elsewhere in this file (search "box-sizing: border-box is required"). */
        box-sizing: border-box;
        width: 100%;
        min-height: 48px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding-inline: 0.5rem;
        text-align: center;
    }

    /* The sticky bar below replaces these on mobile — avoids showing the same WhatsApp/Call
       actions twice on a small screen. */
    .storefront-header .storefront-cta-row, .storefront-detail-info .storefront-cta-row { display: none; }
}

@media (max-width: 380px) {
    .storefront-sticky-actions {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .storefront-sticky-actions .button { width: 100%; min-height: 42px; }

    /* 7 columns (6 primary + আরও) at this width leaves ~45-48px per label — enough for every
       label at the regular 0.7rem/1.2rem sizing except "ক্রয় ও স্টক", the one two-word label,
       which wraps and stretches the whole bar taller. Shrinking text/icon/gap a notch here
       (this breakpoint, not the 640px one above) buys back just enough width to keep it on one
       line on most phones in this range without touching the far more common ≥380px case. */
    .admin-bottom-nav-link { gap: 0.1rem; font-size: 0.62rem; padding: 0.3rem 0; }
    .admin-bottom-nav-link span:first-child { font-size: 1.05rem; }
}

.admin-shell { min-height: 100vh; display: flex; flex-direction: column; }
.admin-header {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 0.75rem var(--admin-gutter);
    /* Once the viewport is wider than the content column, grow the side padding so the
       header's contents sit inside that same column (full-bleed background, aligned content). */
    padding-inline: max(var(--admin-gutter), calc((100% - var(--admin-width)) / 2 + var(--admin-gutter)));
    background: white;
    border-bottom: 1px solid var(--border);
}
.admin-header .brand { display: inline-flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.brand-logo { width: 56px; height: 56px; object-fit: contain; }


/* Desktop only: the admin header sticks and shrinks on scroll, same behaviour as the public
   sticky headers (site-header.js toggles .is-compact on it too). Not on mobile — there the
   bottom tab bar is the persistent nav and the header is just a logo strip that scrolls away.
   z-index sits ABOVE the 900 click-catchers the "আরও"/account dropdowns use: sticky creates a
   stacking context, and the dropdown panel (901) lives inside the header, so anything lower
   here would trap the open panel underneath its own catcher. */
@media (min-width: 641px) {
    .admin-header {
        position: sticky; top: 0; z-index: 950; overflow-anchor: none;
        --hdr-ease: 320ms cubic-bezier(0.4, 0, 0.2, 1);
        transition: padding var(--hdr-ease), box-shadow var(--hdr-ease);
    }
    .admin-header .brand-logo { transition: width var(--hdr-ease), height var(--hdr-ease); }
    .admin-header .admin-nav-link, .admin-header .admin-action-link, .admin-header .nav-dropdown-trigger,
    .admin-header .admin-account-trigger, .admin-header .admin-shopview-btn { transition: padding var(--hdr-ease), background-color 0.15s ease, color 0.15s ease; }

    .admin-header.is-compact { padding-top: 0.15rem; padding-bottom: 0.15rem; box-shadow: 0 2px 10px rgba(44, 32, 20, 0.08); }
    .admin-header.is-compact .brand-logo { width: 36px; height: 36px; }
    .admin-header.is-compact .admin-nav-link, .admin-header.is-compact .admin-action-link,
    .admin-header.is-compact .nav-dropdown-trigger, .admin-header.is-compact .admin-account-trigger { padding-block: 0.25rem; }
    .admin-header.is-compact .admin-shopview-btn { padding-block: 0.2rem; }
}

.admin-nav-primary { display: flex; align-items: center; gap: 0.25rem; flex: 1; flex-wrap: wrap; }
.admin-nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.7rem;
    border-radius: 6px;
    text-decoration: none;
    color: var(--ink);
    font-size: 0.9rem;
    border-bottom: 2px solid transparent;
}
.admin-nav-link:hover { color: var(--brand); background: #f2ece5; }
.admin-nav-link.active { color: var(--brand); font-weight: 600; border-bottom-color: var(--brand); }

.admin-header-actions { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }
.admin-action-link {
    text-decoration: none;
    color: var(--ink);
    font-size: 0.9rem;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    white-space: nowrap;
}
.admin-action-link:hover, .admin-action-link.active { color: var(--brand); }

.admin-shopview-btn {
    text-decoration: none;
    color: var(--brand);
    border: 1px solid var(--brand);
    border-radius: 6px;
    padding: 0.35rem 0.7rem;
    font-size: 0.85rem;
    white-space: nowrap;
}
.admin-shopview-btn:hover { background: var(--brand); color: white; }

/* "আরও" and account dropdowns (NavDropdown.razor) */
.nav-dropdown { position: relative; }
.nav-dropdown-trigger, .admin-account-trigger {
    background: none;
    border: none;
    color: var(--ink);
    font-size: 0.9rem;
    cursor: pointer;
    padding: 0.4rem 0.7rem;
    border-radius: 6px;
    white-space: nowrap;
    margin-top: 0;
}
.nav-dropdown-trigger:hover, .admin-account-trigger:hover { color: var(--brand); background: #f2ece5; }
.admin-account-logo { width: 20px; height: 20px; object-fit: contain; border-radius: 4px; vertical-align: middle; margin-right: 0.35rem; }
.admin-header-tablet-icon { display: none; }
.nav-dropdown-catcher { position: fixed; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: 900; background: transparent; }
.nav-dropdown-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.25rem;
    background: var(--paper);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
    min-width: 190px;
    z-index: 901;
    padding: 0.35rem;
    display: flex;
    flex-direction: column;
}
.nav-dropdown-item {
    display: block;
    box-sizing: border-box;
    width: 100%;
    text-align: left;
    text-decoration: none;
    color: var(--ink);
    font-size: 0.9rem;
    padding: 0.5rem 0.6rem;
    margin: 0;
    border-radius: 6px;
    border: none;
    background: none;
    cursor: pointer;
}
.nav-dropdown-item:hover { background: #f2ece5; color: var(--brand); }
.nav-dropdown-item.active { color: var(--brand); font-weight: 600; }
.nav-dropdown-item.logout-form { padding: 0; }
.nav-dropdown-item.logout-form button {
    display: block;
    box-sizing: border-box;
    width: 100%;
    text-align: left;
    background: none;
    color: var(--ink);
    border: none;
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
    margin: 0;
    font-size: 0.9rem;
    cursor: pointer;
}
.nav-dropdown-item.logout-form button:hover { background: #f2ece5; color: var(--brand); }

/* Widened from 960px (which left a large dead gutter on any screen wider than that, unhelpful
   for a data-table-heavy admin tool — more width means fewer cramped columns, not something a
   narrow reading column improves the way it would for prose) and centered via margin:auto, so a
   very large/ultrawide monitor doesn't stretch a table absurdly wide either. Voice.razor is a
   deliberate exception — its own .voice-panel stays flush-left, unchanged, rather than centered
   inside this wider container. */
/* Bottom padding gets an extra 1rem beyond the gutter on every side — every admin add/edit form
   (Products, Customers, Suppliers, Purchases, …) ends inside this one shared wrapper, and a
   mobile browser's own chrome (Chrome's bottom URL bar, Safari's toolbar, an in-app WebView's
   controls) routinely covers roughly that much of the viewport's bottom edge without the app
   being able to detect it, leaving the last button partly hidden/hard to tap. This is on top of,
   not instead of, the mobile media query's own extra compensation for the app's fixed
   .admin-bottom-nav below. */
.admin-main { padding: var(--admin-gutter); padding-bottom: calc(var(--admin-gutter) + 1rem); max-width: var(--admin-width); margin: 0 auto; width: 100%; box-sizing: border-box; flex: 1; display: flex; flex-direction: column; }
/* .admin-main is a flex column with the default align-items: stretch, so any direct-child
   <button> — a lone submit button on a short form like Customers/Suppliers Create/Edit, not
   wrapped in an .entry-form-section like the longer admin forms are — stretches to the full
   column width instead of sizing to its own content, despite the button's own display:
   inline-flex (align-items on the flex PARENT governs the item's outer box regardless of what
   display the item declares for its own children). Scoped to a direct child so it never touches
   a button already nested inside .entry-form-section elsewhere. */
.admin-main > button.button { align-self: flex-start; }

/* Mobile bottom nav + sheet — hidden above the mobile breakpoint (see @media below). */
.admin-bottom-nav { display: none; }

/* Match the public header's tablet/landscape-phone bridge: preserve every admin destination,
   but use one compact icon row until the full text labels have enough room again. The existing
   <=640px bottom navigation remains the phone layout and is intentionally untouched. */
@media (min-width: 641px) and (max-width: 1100px) {
    .admin-header {
        flex-wrap: nowrap;
        gap: 0.4rem;
        padding: 0.45rem var(--admin-gutter);
    }
    .admin-header .brand-logo { width: 52px; height: 52px; }
    .admin-nav-primary {
        min-width: 0;
        flex-wrap: nowrap;
        gap: 0;
    }
    .admin-header-actions {
        margin-left: auto;
        min-width: 0;
        gap: 0;
    }
    .admin-header-label { display: none; }
    .admin-header-tablet-icon { display: inline-flex; }
    .admin-header .admin-nav-link,
    .admin-header .admin-action-link,
    .admin-header .nav-dropdown-trigger,
    .admin-header .admin-account-trigger,
    .admin-header .admin-shopview-btn {
        box-sizing: border-box;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 0.15rem;
        min-width: 44px;
        min-height: 44px;
        padding: 0.5rem;
    }
    .admin-header .admin-account-logo { margin-right: 0; }
    .admin-header .nav-dropdown-panel {
        max-width: calc(100vw - 2rem);
    }
}

.report-header {
    border-bottom: 3px solid var(--brand);
    padding-bottom: 0.75rem;
    margin-bottom: 0.5rem;
}
.report-header-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
}
.report-shop-name {
    color: var(--brand);
    margin: 0;
    font-size: 1.6rem;
}
.report-title {
    color: var(--ink);
    margin: 0.15rem 0 0;
    font-size: 1.1rem;
    font-weight: normal;
}
.report-generated-at {
    color: var(--muted);
    font-size: 0.8rem;
    white-space: nowrap;
}
.report-period {
    color: var(--muted);
    margin: 0.5rem 0 0;
    font-size: 0.95rem;
}
.report-footer {
    margin-top: auto;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
}
.report-footer p { margin: 0; }
.report-footer-logo { width: 20px; height: 20px; object-fit: contain; }

.voice-panel { max-width: 480px; }
.voice-intent-label { margin: 1rem 0 0.5rem; }
.voice-answer { font-size: 1.2rem; margin: 1rem 0; color: var(--brand); }
.voice-notice {
    background: #fdf3e0;
    border: 1px solid #e8c88a;
    border-radius: 6px;
    padding: 0.6rem 1rem;
    margin: 0 0 1rem;
    font-size: 0.9rem;
}
.voice-notice ul { margin: 0.25rem 0 0; padding-left: 1.25rem; }

.voice-help { max-width: 480px; margin-top: 1.5rem; font-size: 0.85rem; color: var(--muted); }
.voice-help summary { cursor: pointer; font-weight: 600; font-size: 0.85rem; }
.voice-examples { margin: 0.5rem 0 0; padding-left: 1.25rem; line-height: 1.6; }

/* Voice content on the dedicated page and inside the optional voice panel. */
.voice-section {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 1rem 0 1.25rem;
    padding: 1rem 1.15rem 1.1rem;
    background: linear-gradient(165deg, #fdf2e7 0%, #fdfaf6 65%);
    border: 1.5px solid #eddac4;
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(184, 80, 42, 0.06);
}
.voice-section .voice-help { max-width: none; margin-top: 0.6rem; }
.voice-section .voice-fill-summary { margin-bottom: 0; }

/* A compact, fixed trigger opens the optional voice workspace without moving the form. */
.voice-tool { position: relative; display: inline-flex; align-items: center; margin: .35rem 0 .85rem; }
.voice-tool-trigger,
.voice-tool-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 1px solid #cbdcf2;
    border-radius: 10px;
    background: #eef5ff;
    color: #155fc4;
    cursor: pointer;
}
.voice-tool-trigger:hover,
.voice-tool-trigger[aria-expanded="true"] { background: #dcecff; border-color: #9dc4f8; }
.voice-tool-trigger:focus-visible,
.voice-tool-close:focus-visible { outline: 3px solid #77aeff; outline-offset: 2px; }
.voice-tool-tooltip {
    position: absolute;
    z-index: 2;
    top: calc(100% + .35rem);
    right: 0;
    width: max-content;
    max-width: 15rem;
    padding: .35rem .55rem;
    border-radius: 6px;
    background: #203047;
    color: #fff;
    font-size: .75rem;
    line-height: 1.3;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .12s ease;
}
.voice-tool-trigger:hover + .voice-tool-tooltip,
.voice-tool-trigger:focus-visible + .voice-tool-tooltip { opacity: 1; visibility: visible; }
.voice-tool-backdrop { position: fixed; inset: 0; z-index: 1200; background: rgba(23, 37, 60, .36); }
.voice-tool-backdrop[hidden] { display: none; }
.voice-tool-panel {
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    width: min(28rem, 100%);
    height: 100%;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: #fff;
    box-shadow: -12px 0 36px rgba(23, 37, 60, .16);
}
.voice-tool-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid #dce5f0;
    background: var(--surface-muted);
}
.voice-tool-panel-title { display: flex; align-items: center; gap: .6rem; color: #1d3049; font-size: 1.1rem; }
.voice-tool-panel-title svg { color: #155fc4; }
.voice-tool-close { width: 2.25rem; height: 2.25rem; background: #fff; color: #52647c; }
.voice-tool-close:hover { background: #eef5ff; color: #155fc4; }
.voice-tool-panel .voice-section {
    flex: 1;
    margin: 0;
    padding: 1.25rem;
    border: 0;
    border-radius: 0;
    background: #fff;
    box-shadow: none;
}
.voice-section-summary {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    user-select: none;
    list-style: none;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--brand);
    padding: 0.45rem 0.85rem;
    background: #fdf5ee;
    border: 1px solid #eddac4;
    border-radius: 999px;
}
.voice-section-summary::-webkit-details-marker { display: none; }
.voice-section-summary::before {
    content: "▸";
    display: inline-block;
    font-size: 0.65em;
    transition: transform 0.15s ease;
}
.voice-section-summary:hover { background: #fdecdc; }

.voice-capture {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.voice-capture-row, .voice-text-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.voice-text-input {
    flex: 1 1 260px;
    min-width: 0;
    max-width: none;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.85rem;
    resize: vertical;
}
.voice-fill-btn { flex-shrink: 0; }
.voice-mic-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: white;
    color: var(--brand);
    border: 1.5px solid var(--brand);
    border-radius: 999px;
    padding: 0.5rem 1.1rem;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}
.voice-mic-btn:hover:not(:disabled) { background: var(--brand); color: white; }
.voice-mic-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.voice-mic-btn.recording {
    background: var(--due);
    border-color: var(--due);
    color: white;
    animation: voice-pulse 1.4s ease-in-out infinite;
}
.voice-cancel-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: white;
    color: var(--muted);
    border: 1.5px solid var(--border);
    border-radius: 999px;
    padding: 0.5rem 0.9rem;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.voice-cancel-btn:hover { background: #fdecec; color: var(--due); border-color: var(--due); }
.voice-mic-icon { font-size: 1.05rem; line-height: 1; }
.voice-live-caption { color: var(--muted); font-size: 0.9rem; }
.voice-live-caption.muted { font-style: italic; }
.voice-mic-error { margin: .7rem 0 0; font-size: 0.85rem; color: var(--muted); }
.voice-mic-error .error { margin: 0; }
.voice-mic-error p:not(.error) { margin: .45rem 0 0; }
.voice-fallback-mobile { display: none; }
.voice-mic-error details { margin-top: .45rem; }
.voice-mic-error summary { cursor: pointer; color: var(--brand); font-weight: 600; }
.voice-mic-error ul { margin: .4rem 0 0; padding-left: 1.15rem; }
.voice-mic-error li + li { margin-top: .25rem; }
@media (max-width: 700px) {
    .voice-fallback-desktop { display: none; }
    .voice-fallback-mobile { display: block; }
}

@keyframes voice-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(179, 33, 33, 0.35); }
    50% { box-shadow: 0 0 0 8px rgba(179, 33, 33, 0); }
}

.danger-zone { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.danger-zone p { margin: 0.5rem 0; }

.voice-fill-summary { margin: 0 0 1rem; }
.voice-fill-ok {
    background: #eaf7ef;
    border: 1px solid #a9dfc0;
    border-radius: 6px;
    padding: 0.6rem 1rem;
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
}
.voice-fill-ok ul { margin: 0.25rem 0 0; padding-left: 1.25rem; }

/* Applied to a voice-filled input/select right after a fill; fades out on its own after a
   couple of seconds so the highlight is a momentary cue, not a permanent visual state. */
.voice-filled { animation: voice-fill-fade 2.5s ease-out forwards; }
@keyframes voice-fill-fade {
    0% { background-color: #d9f2e2; }
    100% { background-color: transparent; }
}

@media (max-width: 640px) {
    .admin-header { padding: 0.6rem 1rem; }
    .brand-logo { width: 40px; height: 40px; }
    .admin-nav-primary, .admin-header-actions { display: none; }
    .admin-main { padding: 1rem; padding-bottom: calc(1rem + 64px + 1rem); }

    .admin-bottom-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        background: white;
        border-top: 1px solid var(--border);
        z-index: 800;
        padding-bottom: env(safe-area-inset-bottom, 0);
    }
    .admin-bottom-nav-link {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.15rem;
        min-height: 56px;
        text-decoration: none;
        color: var(--muted);
        font-size: 0.7rem;
        background: none;
        border: none;
        padding: 0.4rem 0;
        margin-top: 0;
        cursor: pointer;
    }
    .admin-bottom-nav-link span:first-child { font-size: 1.2rem; }
    /* Seven items on a 375px phone (hybrid shops get অর্ডার too): keep every label on one line. */
    .admin-bottom-nav-link span { white-space: nowrap; }
    .admin-bottom-nav-link { font-size: 0.66rem; padding-left: 0.1rem; padding-right: 0.1rem; min-width: 0; }
    .admin-bottom-nav-link.active { color: var(--brand); font-weight: 600; }

    .quick-links { flex-direction: column; gap: 0.5rem; }
    .quick-links a, .quick-links .button {
        text-align: center;
        margin-top: 0;
    }

    button, .button { padding: 0.5rem 1rem; font-size: 0.9rem; }

    /* Mobile lists use a consistent card anatomy: identity and amount first, supporting
       facts second, state third, then one full-width primary action plus More. This prevents
       a long primary label, status, and the ⋮ target fighting for the same narrow row. */
    .record-card-list { gap: 0.75rem; margin-top: 0.75rem; }
    .record-card {
        display: flex;
        flex-direction: column;
        gap: 0.55rem;
        padding: 1.1rem;
        border: 1px solid var(--border-subtle);
        border-radius: 12px;
        background: var(--paper);
        box-shadow: 0 2px 8px rgba(25, 35, 45, 0.035);
    }
    .record-card-top, .record-card-subtitle, .record-card-bottom { margin: 0; }
    .record-card-top { align-items: flex-start; gap: 0.75rem; }
    .record-card-title { white-space: normal; line-height: 1.25; }
    .record-card-amount { padding-top: 0.05rem; }
    .record-card-subtitle { white-space: normal; line-height: 1.35; }
    .record-card-meta {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.35rem 0.6rem;
        color: var(--muted);
        font-size: var(--text-sm);
        line-height: 1.3;
    }
    .record-card-meta > span + span::before {
        content: "•";
        margin-right: 0.6rem;
        color: var(--border);
    }
    .record-card-date {
        display: inline-flex;
        align-items: center;
        font-variant-numeric: tabular-nums;
    }
    .record-card-bottom { min-height: 22px; display: flex; align-items: center; }
    /* In a compact card, state should be a quiet label, not a separate rounded control.
       The dot preserves immediate color recognition without breaking the reading rhythm. */
    .record-card .status-badge {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
        font-size: var(--text-sm);
        font-weight: 500;
    }
    .record-card .status-badge::before {
        content: "";
        width: 0.48rem;
        height: 0.48rem;
        border-radius: 50%;
        background: currentColor;
        flex: 0 0 auto;
    }
    .record-card-actions {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 44px;
        align-items: stretch;
        gap: 0.6rem;
        margin-top: 0.35rem;
        padding-top: 0.75rem;
        border-top: 1px solid var(--border-subtle);
    }
    .record-card-primary {
        flex: 1 1 auto;
        width: auto;
        margin: 0;
        text-align: center;
        justify-content: center;
    }
    .record-card-actions .row-menu {
        display: flex;
        margin-left: 0;
        width: 44px;
        height: 100%;
    }
    /* The primary label may wrap. Let the More target grow with that same action bar instead
       of leaving a short square next to a taller button. */
    .record-card-actions .row-menu-trigger {
        flex: 1 1 auto;
        width: 44px;
        height: 100% !important;
        min-height: 44px;
    }

    .row-menu-item + .row-menu-item,
    .row-menu-item + button,
    button + .row-menu-item { margin-top: 0.5rem; }

    .mobile-sheet-backdrop {
        position: fixed;
        top: 0; right: 0; bottom: 0; left: 0;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 1100;
        display: flex;
        align-items: flex-end;
    }
    .mobile-sheet {
        background: var(--paper);
        width: 100%;
        max-height: 80vh;
        overflow-y: auto;
        border-radius: 14px 14px 0 0;
        padding: 1rem;
        padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0));
    }
    .mobile-sheet-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem; }
    .mobile-sheet-group-label {
        font-size: 0.75rem;
        color: var(--muted);
        text-transform: uppercase;
        letter-spacing: 0.03em;
        margin: 0.75rem 0 0.25rem;
        padding: 0 0.4rem;
    }
    /* justify-content: flex-start — same fix as .row-menu-item: this class is also used on a
       <button> (লগআউট) alongside plain <a> items, and the generic mobile "button {
       justify-content: center }" rule would otherwise center that one item's label only. */
    .mobile-sheet-item {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        text-decoration: none;
        color: var(--ink);
        font-size: 1rem;
        padding: 0.7rem 0.5rem;
        border-radius: 8px;
        min-height: 44px;
        box-sizing: border-box;
        width: 100%;
    }
    .mobile-sheet-item:hover, .mobile-sheet-item:active { background: #f2ece5; }
    .mobile-sheet-item.active { color: var(--brand); font-weight: 600; }
    .mobile-sheet-logout-form { margin: 0.75rem 0 0; border-top: 1px solid var(--border); padding-top: 0.5rem; }
    .mobile-sheet-logout-form button {
        display: flex;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
        text-align: left;
        background: none;
        border: none;
        color: var(--due);
        font-size: 1rem;
        padding: 0.7rem 0.5rem;
        border-radius: 8px;
        min-height: 44px;
        margin: 0;
        cursor: pointer;
    }
    .mobile-sheet-logout-form button:hover { background: #fbeaea; }

    .data-table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
        -webkit-overflow-scrolling: touch;
    }

    /* .line-item-table deliberately does NOT scroll horizontally like .data-table above — it is
       an entry form, not a list to read, and every field needs to stay on screen without
       sideways scrolling. The actual fixed-layout + per-column শতাংশ shares now live in the
       base (non-media-query) rule above, since a mid-size/tablet width had the exact same
       "column too narrow for its content" problem this was originally written to fix — only the
       mobile-specific compacting below (smaller text, tighter padding, no spinner arrows) is a
       phone-only concern. */
    .line-item-table { display: table; width: 100%; white-space: normal; }
    .line-item-table th, .line-item-table td { padding: 0.4rem 0.3rem; font-size: 0.8rem; }
    /* Headers are the tallest thing in the row ("প্রতিটির ক্রয়মূল্য (৳)" wraps to two lines at
       any width that leaves room for the fields), so they get their own smaller size rather
       than dictating how much space the inputs can have. */
    .line-item-table th { font-size: 0.72rem; line-height: 1.25; }
    /* Reclaims the width the native spinner arrows were eating — this table is always filled by
       direct typing (often straight off a numeric keypad on a phone), so the tap-to-increment
       arrows were pure overhead here, not a control anyone actually used. Phone-only: a desktop
       cell has room to spare, so the arrows are left alone there. */
    .line-item-table input[type="number"] { -moz-appearance: textfield; }
    .line-item-table input[type="number"]::-webkit-outer-spin-button,
    .line-item-table input[type="number"]::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }
    /* The unit hint under পরিমাণ (e.g. "কেজি") and the স্টক hint under পণ্য both use this same
       class — at the table's own already-reduced 0.8rem body size, .field-hint's base 0.85rem
       actually renders LARGER than the cell's other text and was the widest thing forcing this
       narrow column to wrap. */
    .line-item-table .field-hint { font-size: 0.68rem; line-height: 1.2; margin-top: 0.15rem; }
    /* The padding-reduction below (as plain ".line-item-table input") never actually applied —
       same specificity bug this file's own comment already documents for
       ".inline-actions-nowrap input[type=number]": the base rule near the top of this file
       ("input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit])
       :not([type=button]):not([type=file])") chains five :not() pseudo-classes for specificity
       (0,0,5,1), beating ".line-item-table input"'s mere (0,0,1,1). Confirmed live: a number
       input measured 12px/9.6px padding (the base rule's 0.75rem/0.6rem), not this rule's
       intended 0.35rem — on a ~40-50px-wide cell that's over a quarter of the width gone to
       padding alone before a single digit is drawn. Matching the same five :not()s here (as
       the .inline-actions-nowrap fix already does) is what actually wins the cascade. */
    .line-item-table input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]):not([type=file]) {
        padding-left: 0.3rem;
        padding-right: 0.3rem;
    }
    .line-item-table .remove-line-btn { width: 100%; min-width: 0; }

    /* ManageVariants.razor's variant table (.variant-manage-table) is a management view —
       one row per ধরন: name / stock / price / status / on-off. It stays a real table at
       every width: a shop owner scanning ten colourways wants them lined up, not stacked
       into ten cards. Below this breakpoint the row is kept to one line by dropping every
       button and the status wording down to its icon — the .vm-label spans hide, the <Icon>
       beside them carries the meaning, buttons become square tap targets, and the "আলাদা
       দাম" badge (which alone is wider than a phone column) is dropped since the filled
       price input already shows a custom price is set. Columns size to their content, not
       the entry-form nth-child percentages above, and .scroller absorbs whatever width is
       still left over on the narrowest phones. */
    /* No min-width: 100% — letting the table shrink to its own content is what stops the
       leftover width being handed to (and visibly bloating) the first column. Every column
       is then exactly as wide as it needs to be; if the sum still exceeds a very narrow
       phone, .scroller takes over. */
    .line-item-table.variant-manage-table {
        table-layout: auto;
        width: auto;
    }
    .line-item-table.variant-manage-table td {
        width: auto;
        text-align: left;
        overflow-wrap: normal;
        white-space: nowrap;
        padding: 0.4rem 0.3rem;
    }
    /* Headers may wrap to two lines so a column can be only as wide as its data ("৩০" + a
       square button), instead of the full "বর্তমান স্টক" / "বিক্রয় মূল্য (৳)" string. */
    .line-item-table.variant-manage-table th {
        white-space: normal;
        font-size: 0.7rem;
        line-height: 1.2;
        padding: 0.4rem 0.3rem;
        vertical-align: bottom;
    }
    .line-item-table.variant-manage-table .vm-label { display: none; }
    .line-item-table.variant-manage-table .status-badge { display: none; }
    .line-item-table.variant-manage-table .inline-actions,
    .line-item-table.variant-manage-table .inline-actions-nowrap {
        flex-wrap: nowrap;
        gap: 0.25rem;
    }
    .line-item-table.variant-manage-table .inline-actions .button,
    .line-item-table.variant-manage-table .inline-actions-nowrap .button,
    .line-item-table.variant-manage-table .inline-add-stock .button {
        padding: 0.35rem;
        min-width: 1.9rem;
        justify-content: center;
        flex: 0 0 auto;
    }
    /* Rename mode: the name <input> keeps a usable width and a small min-width so a colourway
       name is still editable in the narrow রঙ column, rather than collapsing to a sliver. */
    .line-item-table.variant-manage-table .inline-actions input[type="text"] {
        flex: 1 1 4rem;
        min-width: 4rem;
    }
    /* Keep the expanded "add stock" sub-form's সেভ/বাতিল as the same square icon buttons the
       rename row uses, sitting side by side rather than stacked, so the two edit states read
       as one design. min-width widens this cell only while the form is open (the collapsed
       "৩০ +" state is far narrower), giving the two icon buttons room to share a line. */
    .line-item-table.variant-manage-table .inline-add-stock {
        gap: 0.4rem 0.5rem;
        min-width: 8.5rem;
    }
    .line-item-table.variant-manage-table .inline-add-stock label { flex: 1 1 100%; }
    .line-item-table.variant-manage-table .inline-add-stock label input[type="number"] {
        width: 100%;
        max-width: none;
    }
    .line-item-table.variant-manage-table .icon-button {
        width: 1.7rem;
        height: 1.7rem;
        padding: 0;
        border: none;
        flex-shrink: 0;
    }
    /* Roomier than the old 4rem so a 6–7 digit amount (৩২৫০০০) isn't clipped, but still capped
       — the price column may be given extra width, and the input shouldn't eat all of it and
       shove the ✓ button and the on/off toggle off the side of the screen. */
    .line-item-table.variant-manage-table .inline-actions-nowrap input[type="number"]:not([readonly]):not([disabled]):not([hidden]):not([multiple]) {
        flex: 0 0 auto;
        width: 6rem;
        max-width: 6rem;
    }
    /* Drop the standalone অবস্থা column on a phone — the on/off toggle button in the last
       column already shows state (its icon + colour), and an inactive row is dimmed via
       tr.muted. Keeping a whole column just to repeat that is what pushed the row off-screen. */
    .line-item-table.variant-manage-table th:nth-child(4),
    .line-item-table.variant-manage-table td:nth-child(4) { display: none; }
    .line-item-table.variant-manage-table td:last-child .button.secondary { border-color: var(--muted); color: var(--ink); }
    .line-item-table.variant-manage-table tr:not(.muted) td:last-child .button.secondary { border-color: var(--due); color: var(--due); }

    .desktop-only-table { display: none; }
    /* Matches the combined-class specificity (0,2,0) of the base ".record-card-list.mobile-
       only-list { display:none }" rule above — a plain ".mobile-only-list" selector here
       (0,1,0) would lose that specificity tie and never show the card list at all on mobile,
       regardless of this media query being active (confirmed live: this exact mismatch was
       introduced while fixing the desktop-duplication bug, and briefly hid the mobile list
       entirely). */
    .record-card-list.mobile-only-list { display: flex; }

    .row-menu-trigger, .row-menu-trigger.compact { width: 44px; min-width: 44px; height: 44px; }
    .row-menu-panel {
        position: fixed;
        left: 0;
        right: 0;
        top: auto;
        bottom: 0;
        min-width: 0;
        width: 100%;
        max-width: none;
        border-radius: 14px 14px 0 0;
        padding: var(--space-3);
        padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0));
        z-index: 1001;
    }
    .row-menu-catcher { background: rgba(0, 0, 0, 0.45); z-index: 1000; }
    /* justify-content: flex-start beats the generic "button { justify-content: center }"
       mobile rule below (same specificity fight, .row-menu-item wins on the class vs tag
       selector) — without it, every *button*-based menu item (Cancel/Return/Void/Verify/
       Share/…) centered its label while the plain <a> items stayed left-aligned. */
    .row-menu-item { min-height: 48px; display: flex; align-items: center; justify-content: flex-start; padding: var(--space-3); font-size: 1rem; }

    .detail-title-row { align-items: flex-start; }
    .detail-title-line { align-items: flex-start; flex-direction: column; }
    .detail-primary-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
    .detail-primary-actions > :first-child { width: 100%; }
    /* box-sizing: border-box is required here — .button's own padding (content-box by default,
       no global reset in this codebase) was adding on top of the width: 100% above and pushing
       the button past the right edge of the screen. Same root cause fixed before in the Facebook
       share modal's textarea/button — see app.css comments there. Only surfaces when there is a
       single primary action (e.g. no due amount to pay, just "রসিদ দেখুন" alone), since with two
       actions the first child sits in its own narrower grid track instead. */
    .detail-primary-actions .button { min-width: 0; white-space: normal; text-align: center; box-sizing: border-box; }
    /* Detail page's 3 header actions: one line, compact, horizontal-scroll as the fallback. */
    .detail-actions-inline { flex-wrap: nowrap; gap: 0.3rem; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
    .detail-actions-inline .button { flex: 0 0 auto; white-space: nowrap; font-size: 0.72rem; padding: 0.45rem 0.5rem; line-height: 1.2; }
    .detail-key-values > div { grid-template-columns: 6rem minmax(0, 1fr); }
    .detail-table-desktop { display: none; }
    .mobile-product-list { display: flex; }

    .page-header, .filter-row, .list-toolbar, .inline-form, .quick-add-row, .cta-row {
        gap: 0.6rem;
    }

    .cta-row { flex-direction: column; }
    /* border-box is essential here, not cosmetic: this stylesheet is content-box throughout,
       so width:100% put the button's own 1rem side padding OUTSIDE the 327px column, making
       each button 360.7px and pushing the whole landing page 10px past the viewport. */
    .cta-row a, .cta-row .button { width: 100%; box-sizing: border-box; }

    .filter-panel { flex-direction: column; align-items: stretch; }
    .filter-panel > label, .filter-panel > label.checkbox-label { flex: 1 1 auto; min-width: 0; }

    .report-range-bar { grid-template-columns: 1fr; padding: var(--space-3); }
    /* One row, not a 2-column grid with a full-width last cell: that stacked five presets into
       three rows and pushed the actual report off the first screen. Tightened text and padding
       let all five fit across a 375px phone; overflow-x is the safety valve for anything
       narrower, so the row still reads as one line rather than reflowing. */
    .report-period-presets {
        display: flex;
        flex-wrap: nowrap;
        width: 100%;
        gap: 0.25rem;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .report-period-presets::-webkit-scrollbar { display: none; }
    .report-period-presets .pill {
        flex: 0 1 auto;
        white-space: nowrap;
        padding: 0.3rem 0.4rem;
        font-size: 0.72rem;
    }
    .report-custom-dates { flex-direction: column; }
    .report-custom-dates label { flex: 0 0 auto; width: 100%; }
    .report-range-export { justify-self: start; }
    /* Tighter on a phone, where the space between the period picker and the tabs cost most of
       the room the first report figures should have occupied. Only the bar's margin is set
       here: the base .report-tabs rule is declared further down the file, so a margin-top
       override at this point would lose to it on source order alone. */
    .report-range-bar { margin-bottom: var(--space-2); }

    .stat-cards { gap: 0.6rem; }
    .stat-card {
        flex: 1 1 calc(50% - 0.6rem);
        min-width: 0;
        padding: 0.85rem 1rem;
    }

    button, .button, .voice-mic-btn, .pill {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .auth-page, .onboarding {
        margin: 1rem auto;
        padding: 1.25rem;
        max-width: 100%;
    }
    .landing { margin: 2rem auto; }

    /* ================================================================================
       Mobile "ledger" list pattern (Design A) — one white container per list/group with
       hairline-divided rows. Anatomy of every row, on every admin list page:
         [thumb] [title / meta line] [amount / status] [chevron or ⋮]
       The whole row is the tap target (the title link is stretched over the row via ::after);
       only rows that genuinely need an action (new order, due payment) get a compact pill
       row underneath. Nothing here applies above 640px — the table stays as-is there.
       ================================================================================ */
    .record-list.mobile-only-list, .record-groups.mobile-only-list { display: block; }
    .record-list {
        margin-top: 0.75rem;
        background: white;
        border: 1px solid var(--border-subtle);
        border-radius: 14px;
        overflow: hidden;
    }
    .record-groups { margin-top: 0.25rem; }
    .record-group-title {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        padding: 0.9rem 0.35rem 0.4rem;
        font-size: var(--text-xs);
        font-weight: 600;
        color: var(--muted);
    }
    .record-group-title + .record-list { margin-top: 0; }
    .record-row {
        position: relative;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.25rem 0.75rem;
        padding: 0.7rem 0.55rem 0.7rem 0.85rem;
        min-height: 64px;
        box-sizing: border-box;
        border-top: 1px solid var(--border-subtle);
    }
    .record-row:first-child { border-top: 0; }
    .record-row.inactive-row { opacity: 0.55; }
    .record-row-thumb {
        width: 44px;
        height: 44px;
        border-radius: 10px;
        background: var(--surface-muted);
        color: #b5aca3;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 1.2rem;
        flex: 0 0 auto;
        overflow: hidden;
    }
    .record-row-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
    .record-row-thumb.round { border-radius: 50%; }
    .record-row-main { flex: 1 1 0; min-width: 0; }
    .record-row-title {
        display: block;
        font-weight: 600;
        font-size: 0.95rem;
        line-height: 1.25;
        color: var(--ink);
        text-decoration: none;
        /* Two lines max, then an ellipsis — a name like "অর্ডার #১ · সালমা আক্তার" must not be
           cut to "অর্ডার #১ · সা…" just because the amount column is next to it. */
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        overflow-wrap: anywhere;
    }
    /* Stretched link: the title's ::after covers the whole row, so tapping anywhere navigates.
       Anything else interactive inside the row sits above it via z-index below. */
    a.record-row-title::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; }
    .record-row-sub {
        font-size: var(--text-xs);
        color: var(--muted);
        margin-top: 0.15rem;
        line-height: 1.35;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .record-row-sub > span + span::before { content: "·"; margin: 0 0.35rem; color: #c9c1b8; }
    .record-row-sub .quick-view-trigger { display: inline; width: auto; text-decoration: none; color: var(--brand); font-weight: 600; }
    .record-row-sub button, .record-row-sub a, .record-row-sub .quick-view-trigger { position: relative; z-index: 2; }
    /* The quick-view trigger carries its own thumb+label pair; the row already shows the thumb,
       so inside the meta line only the label is kept, inline. */
    .record-row-sub .product-thumb-row { display: inline; }
    .record-row-sub .product-thumb-row .product-thumb { display: none; }
    .record-row-end { flex: 0 1 auto; text-align: right; max-width: 38%; }
    .record-row-amount { font-weight: 700; font-size: 0.95rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
    /* Only rendered for a non-today order (RowDateHint) — a quiet cue, above the amount. */
    .record-row-date { font-size: var(--text-xs); color: var(--muted); margin-bottom: 0.1rem; white-space: nowrap; }
    .record-row-amount.due-amount { color: var(--due); }
    .record-row-amount:empty { display: none; }
    /* State is a quiet dot + short word under the amount — no badge box in a dense row. */
    .record-row .status-badge {
        display: inline-flex;
        align-items: center;
        justify-content: flex-end;
        gap: 0.35rem;
        margin: 0.15rem 0 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
        font-size: var(--text-xs);
        font-weight: 500;
        line-height: 1.2;
        text-align: right;
        white-space: normal;
    }
    .record-row .status-badge::before {
        content: "";
        width: 0.45rem;
        height: 0.45rem;
        border-radius: 50%;
        background: currentColor;
        flex: 0 0 auto;
    }
    .record-row-chevron { display: flex; color: #c9c1b8; flex: 0 0 auto; margin-left: -0.35rem; }
    .record-row .row-menu { position: relative; z-index: 2; flex: 0 0 auto; margin-left: -0.35rem; }
    /* The open sheet (and any modal an item opens inside it) lives inside this stacking
       context, so while it is open the whole menu has to sit above the row's other z-index:2
       pieces (the action pills) — otherwise they paint through the backdrop. */
    .record-row .row-menu:has(.row-menu-panel) { z-index: 1002; }
    /* Plain-class twin for browsers without :has() — see js/overlay-escalation.js. */
    .record-row .row-menu.has-open-overlay { z-index: 1002; }
    /* Same "which row is this for" marker as .data-table tbody tr:has(...) above — the mobile
       sheet already covers most of the screen while open so this matters less here, but it
       still helps for the brief moment right as it opens. Pure :has(), no plain-class fallback:
       .record-row isn't one of overlay-escalation.js's TRAPS, and this is a cosmetic nicety, not
       the stacking-context fix those plain-class twins exist for — an old browser just won't
       show the tint. */
    .record-row:has(.row-menu-panel) { background: #f2ece2; }
    .record-row .row-menu-trigger, .record-row .row-menu-trigger.compact {
        width: 36px;
        min-width: 36px;
        height: 36px;
        min-height: 36px;
        padding: 0;
        box-sizing: border-box;
        border: 0;
        background: transparent;
        color: var(--muted);
        border-radius: 8px;
    }
    .record-row .row-menu-trigger:hover, .record-row .row-menu-trigger:active { background: var(--surface-muted); color: var(--brand); }
    .record-row-actions {
        position: relative;
        z-index: 2;
        flex: 0 0 100%;
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        padding: 0.3rem 0 0.1rem calc(44px + 0.75rem);
    }
    /* Same reasoning as .row-menu:has(.row-menu-panel) above — a primary action button
       (টাকা পেয়েছি, বিক্রি সম্পন্ন করুন, …) can open a confirmation dialog straight from
       here, not just from the ⋮ menu, and the dialog must not be capped at this row's
       own low z-index against the mobile FAB/bottom-nav. */
    .record-row-actions:has(.facebook-preview-modal-backdrop) { z-index: 1101; }
    /* Plain-class twin for browsers without :has() — see js/overlay-escalation.js. This is
       the one that showed up in the wild: on an old phone the :has() rule above is dropped,
       so the "টাকা পেয়েছেন?" dialog stayed capped at this row's z-index:2 and the next rows'
       "বিক্রি সম্পন্ন করুন" pills painted right over it. */
    .record-row-actions.has-open-overlay { z-index: 1101; }
    .record-list.no-thumb .record-row-actions { padding-left: 0; }
    .record-row-actions .button, .record-row-actions button {
        box-sizing: border-box;
        min-height: 36px;
        padding: 0.35rem 0.85rem;
        font-size: 0.8rem;
        font-weight: 600;
        border-radius: 8px;
        margin: 0;
        flex: 0 1 auto;
        white-space: nowrap;
    }
    .record-row-note {
        flex: 0 0 100%;
        font-size: var(--text-xs);
        color: var(--muted);
        padding-left: calc(44px + 0.75rem);
        margin-top: -0.1rem;
        line-height: 1.4;
        overflow-wrap: anywhere;
        box-sizing: border-box; /* the padding must not add to the 100% basis */
        min-width: 0;
    }
    /* Same content-box trap for the action row. */
    .record-row-actions { box-sizing: border-box; min-width: 0; }
    .record-list.no-thumb .record-row-note { padding-left: 0; }

    /* --- Toolbar: search fills the row; filter + download collapse to 42px icon buttons. --- */
    .list-toolbar { flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0; }
    .toolbar-search-wrap { flex: 1 1 0; min-width: 0; }
    .toolbar-search { height: 42px; border-radius: 12px; border-color: var(--border-subtle); background: white; box-sizing: border-box; }
    .list-toolbar .filter-toggle, .list-toolbar .export-menu > .button {
        width: 42px;
        min-width: 42px;
        height: 42px;
        min-height: 42px;
        padding: 0;
        margin: 0;
        box-sizing: border-box;
        border-radius: 12px;
        justify-content: center;
        position: relative;
        font-size: 1rem;
    }
    .filter-toggle-label, .export-menu-label { display: none; }
    .filter-toggle-count {
        position: absolute;
        top: -5px;
        right: -5px;
        min-width: 18px;
        height: 18px;
        padding: 0 4px;
        border-radius: 999px;
        background: var(--brand);
        color: white;
        font-size: 0.65rem;
        font-weight: 700;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
    }
    .filter-toggle.active { background: var(--warning-bg); border-color: var(--brand); color: var(--brand); }
    .list-toolbar .export-menu-panel { right: 0; left: auto; }
    /* Customers/Suppliers quick toggles become a chip row under the search. */
    .list-toolbar .filter-pills { order: 10; flex: 0 0 100%; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
    .list-toolbar .filter-pills::-webkit-scrollbar { display: none; }
    .list-toolbar .filter-pills .pill { min-height: 30px; padding: 0.15rem 0.85rem; font-size: 0.8rem; white-space: nowrap; flex: 0 0 auto; }
    .list-toolbar .toolbar-checkbox { order: 11; flex: 0 0 100%; font-size: var(--text-xs); white-space: normal; margin: 0.1rem 0 0; }
    .due-summary { margin: 0.5rem 0.25rem 0; font-size: var(--text-xs); }
    .filter-panel { margin-top: 0.5rem; }
    .active-filter-bar { margin-top: 0.5rem; }

    /* --- Page header: the primary "+ নতুন" button floats above the bottom nav; any secondary
           links (স্টক সমন্বয়, বিস্তারিত রিপোর্ট) shrink to a compact row. --- */
    .page-header { margin-bottom: 0.5rem; gap: 0.4rem; }
    .page-header > div { display: flex; flex-wrap: wrap; gap: 0.4rem; }
    /* A header holding nothing but the floating primary takes no room (display:none would also
       hide the fixed-position FAB inside it). */
    .page-header:not(:has(.button.secondary)):not(:has(.page-report-link)) { margin: 0; gap: 0; }
    .page-header .button.secondary { box-sizing: border-box; min-height: 34px; padding: 0.25rem 0.8rem; font-size: 0.8rem; border-radius: 999px; margin: 0; }
    .page-header .page-report-link { font-size: 0.8rem; }
    .page-header .mobile-fab {
        position: fixed;
        right: 1rem;
        bottom: calc(64px + env(safe-area-inset-bottom, 0) + 1rem);
        z-index: 700;
        margin: 0;
        box-sizing: border-box;
        min-height: 48px;
        padding: 0.6rem 1.15rem 0.6rem 1rem;
        border-radius: 999px;
        font-weight: 600;
        font-size: 0.9rem;
        box-shadow: 0 6px 16px rgba(184, 80, 42, 0.35);
        white-space: nowrap;
    }
    /* Keep the last row reachable above the floating button. */
    .record-list.mobile-only-list:last-child, .record-groups.mobile-only-list:last-child { margin-bottom: 64px; }

    /* --- Dashboard: compact 2-up stat tiles, then quick actions and management as tappable
           list rows in the same white container style as every list page. --- */
    .stat-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; margin: 0.5rem 0 0.25rem; }
    .stat-card { box-sizing: border-box; min-width: 0; padding: 0.75rem 0.85rem; border-radius: 12px; border-color: var(--border-subtle); }
    .stat-card .stat-label { font-size: var(--text-xs); line-height: 1.3; }
    .stat-card .stat-value { font-size: 1.2rem; margin-top: 0.1rem; }
    .stat-card .stat-sub { font-size: 0.7rem; }
    .stat-card-hero { grid-column: 1 / -1; order: -1; background: var(--brand); border-color: var(--brand); padding: 1rem 1.1rem; }
    .stat-card-hero .stat-label { color: rgba(255, 255, 255, 0.85); }
    .stat-card-hero .stat-value { color: white; font-size: 1.9rem; }
    /* Banners with a text + action buttons + dismiss: text and × share the first line, the
       action buttons wrap underneath instead of squeezing the message into a narrow column. */
    .success-banner { flex-wrap: wrap; gap: 0.5rem 0.75rem; }
    .success-banner > p { flex: 1 1 calc(100% - 3rem); order: -1; }
    .success-banner > button:not(.button) { order: -1; }
    .dashboard-group { margin: 1.25rem 0 0; padding-top: 0; border-top: 0; }
    .dashboard-section-title { font-size: var(--text-xs); font-weight: 600; color: var(--muted); margin: 0 0.35rem 0.4rem; }
    .quick-links, .settings-section {
        flex-direction: column;
        gap: 0;
        background: white;
        border: 1px solid var(--border-subtle);
        border-radius: 14px;
        overflow: hidden;
    }
    .quick-links .button, .quick-links a {
        display: flex;
        align-items: center;
        justify-content: space-between;
        text-align: left;
        min-height: 52px;
        padding: 0.7rem 1rem;
        margin: 0;
        border: 0;
        border-top: 1px solid var(--border-subtle);
        border-radius: 0;
        background: transparent;
        color: var(--ink);
        font-weight: 500;
        font-size: 0.95rem;
        box-sizing: border-box;
    }
    .quick-links .button:first-child, .quick-links a:first-child { border-top: 0; }
    .quick-links .button::after, .settings-section .settings-card::after {
        content: "";
        width: 0.5rem;
        height: 0.5rem;
        border-right: 2px solid #c9c1b8;
        border-bottom: 2px solid #c9c1b8;
        transform: rotate(-45deg);
        flex: 0 0 auto;
        margin-left: 0.75rem;
    }
    .settings-section .settings-card {
        width: 100%;
        box-sizing: border-box;
        border: 0;
        border-top: 1px solid var(--border-subtle);
        border-radius: 0;
        box-shadow: none;
        padding: 0.7rem 1rem;
        min-height: 52px;
        display: flex;
        align-items: center;
    }
    .settings-section .settings-card:first-child { border-top: 0; }
    .settings-section .settings-card > div { flex: 1 1 auto; min-width: 0; }
}


/* ---- Advance payment ------------------------------------------------------------------
   Customer side (/pay/{token}): one white card, phone-first. Owner side: the advance card on
   the order page and the claim block inside the "টাকা পেয়েছি" sheet. Same tokens and radii as
   the rest of the admin/storefront so nothing here reads as a different product. ---- */
.pay-page { max-width: 560px; margin: 0 auto; padding: var(--space-4) var(--space-4) var(--space-6); }
.pay-card { background: white; border: 1px solid var(--border-subtle); border-radius: 16px; padding: var(--space-5); }
.pay-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); }
.pay-card-head h1 { margin: 0; font-size: 1.3rem; }
.pay-kicker { margin: 0 0 0.15rem; color: var(--muted); font-size: var(--text-sm); }
.pay-amount-box { text-align: right; flex: 0 0 auto; }
.pay-amount-box span { display: block; font-size: var(--text-xs); }
.pay-amount-box strong { display: block; font-size: 1.6rem; color: var(--brand); line-height: 1.1; font-variant-numeric: tabular-nums; }
.pay-summary { display: flex; justify-content: space-between; gap: var(--space-3); margin: var(--space-3) 0 0; padding: 0.6rem 0.8rem; background: var(--surface-muted); border-radius: 10px; font-size: var(--text-sm); color: var(--muted); }
.pay-intro { margin: var(--space-4) 0 var(--space-3); font-size: 1rem; line-height: 1.5; }
.pay-methods { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: var(--space-3); }
.pay-methods .pill { min-height: 36px; padding: 0.3rem 1rem; font-size: 0.9rem; }
.pay-copy-rows { display: grid; gap: 0.5rem; }
.pay-copy-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 0.7rem 0.9rem; border: 1px solid var(--border-subtle); border-radius: 12px; }
.pay-copy-row > div { min-width: 0; }
.pay-copy-row .muted { display: block; font-size: var(--text-xs); }
.pay-number { display: block; font-size: 1.25rem; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }
.pay-copy-row .button { margin: 0; flex: 0 0 auto; white-space: nowrap; }
.pay-open-app { width: 100%; box-sizing: border-box; margin-top: var(--space-3); justify-content: center; }
.pay-open-hint { margin: var(--space-2) 0 0; line-height: 1.45; }
.pay-qr { text-align: center; }
.pay-qr img { width: min(100%, 260px); border: 1px solid var(--border-subtle); border-radius: 12px; padding: 0.5rem; background: white; }
.pay-qr p { margin: var(--space-2) 0 var(--space-3); line-height: 1.45; }
.pay-report { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px dashed var(--border); }
.pay-report-btn { width: 100%; box-sizing: border-box; justify-content: center; min-height: 48px; font-size: 1rem; font-weight: 600; }
.pay-report-title { margin: 0 0 var(--space-2); font-weight: 600; }
.pay-report label input { max-width: none; }
.pay-state { display: flex; align-items: flex-start; gap: 0.6rem; margin-top: var(--space-4); padding: 0.85rem 1rem; border-radius: 12px; line-height: 1.5; }
.pay-state .icon { flex: 0 0 auto; margin-top: 0.2em; font-size: 1.1rem; }
.pay-state-ok { background: #eaf7ef; color: #1d7a3f; }
.pay-state-wait { background: var(--warning-bg); color: var(--warning-text); }
.pay-state-wait .muted { display: block; margin-top: 0.15rem; font-size: var(--text-xs); }
.pay-state-warn { background: #fbeaea; color: var(--due); }
.pay-state-muted { background: var(--surface-muted); color: var(--muted); }
.pay-secondary-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: var(--space-3); }
.pay-secondary-actions .button { margin: 0; }
.pay-footer-links { margin: var(--space-4) 0 0; text-align: center; font-size: var(--text-sm); color: var(--muted); }
.pay-footer-links span { margin: 0 0.5rem; }
/* Checkout success screens: the one thing to do next, in its own soft box. */
.checkout-advance-cta { margin: var(--space-3) 0; padding: 0.85rem 1rem; background: var(--warning-bg); border: 1px solid var(--warning-border); border-radius: 12px; }
.checkout-advance-cta p { margin: 0 0 0.6rem; color: var(--warning-text); line-height: 1.45; }
.checkout-advance-cta .button { margin: 0; width: 100%; box-sizing: border-box; justify-content: center; }
/* আমার অর্ডার row: one line under the products. */
.my-order-advance { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-2); font-size: var(--text-sm); }
.my-order-advance-todo { padding: 0.5rem 0.75rem; background: var(--warning-bg); border-radius: 10px; color: var(--warning-text); }
.my-order-advance .button { margin: 0; flex: 0 0 auto; }
/* আমার অর্ডার: four-step progress line (অর্ডার → নেওয়া হয়েছে → কুরিয়ারে → ডেলিভারি) + courier info. */
.order-progress { display: flex; list-style: none; margin: var(--space-3) 0 0; padding: 0; gap: 0.25rem; }
.order-progress li { flex: 1 1 0; min-width: 0; text-align: center; font-size: 0.75rem; color: var(--muted); position: relative; padding-top: 1.1rem; line-height: 1.3; }
.order-progress li::before { content: ""; position: absolute; top: 0.2rem; left: 0; right: 0; height: 4px; border-radius: 2px; background: var(--border-subtle); }
.order-progress li.done { color: inherit; }
.order-progress li.done::before { background: var(--brand); }
.order-progress li.current { font-weight: 600; }
.my-order-shipment { margin-top: var(--space-2); padding: 0.5rem 0.75rem; background: var(--surface-muted); border-radius: 10px; font-size: var(--text-sm); display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.75rem; }
.my-order-shipment .button { margin: 0; }
/* Owner: courier picker in the ship dialog, and the shipment block on the order page. */
.ship-courier-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.4rem 0 0.6rem; }
/* Explicit colour: the global button style is white-on-brand, which made unselected chips invisible. */
.ship-courier-chip { padding: 0.55rem 1rem; border: 1px solid var(--border-subtle); border-radius: 999px; background: white; color: var(--ink); font: inherit; cursor: pointer; }
.ship-courier-chip:hover { background: var(--surface-muted); color: var(--ink); }
.ship-courier-chip.active, .ship-courier-chip.active:hover { border-color: var(--brand); background: var(--brand); color: white; font-weight: 600; }
.ship-courier-more { width: 100%; margin-bottom: 0.4rem; }
.ship-tracking-preview { margin: 0.25rem 0 0.5rem; word-break: break-all; }
/* The ID and its copy button sit on one line, vertically centred with the text. */
.my-order-shipment > span, .shipment-card p > span { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; }
.copy-tracking-btn { display: inline-flex; align-items: center; gap: 0.25rem; margin: 0; line-height: 1.2; padding: 0.15rem 0.55rem; border: 1px solid var(--border-subtle); border-radius: 999px; background: white; color: var(--ink); font: inherit; font-size: var(--text-sm); cursor: pointer; }
.copy-tracking-btn:hover { background: var(--surface-muted); color: var(--ink); }
.copy-tracking-btn svg { width: 0.95em; height: 0.95em; }
.shipment-tracking-id { font-variant-numeric: tabular-nums; user-select: all; word-break: break-all; }
/* Owner: the advance block on the order page, and the claim block in the verify sheet. */
.advance-card { margin: var(--space-3) 0; padding: var(--space-4); background: white; border: 1px solid var(--border-subtle); border-radius: 12px; }
.advance-card-reported { border-color: var(--warning-border); background: #fffaf3; }
.advance-card-head { display: flex; align-items: center; gap: 0.75rem; }
.advance-card-head strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.advance-card-claim { margin: var(--space-2) 0 0; }
.advance-card-refund { margin: var(--space-2) 0 0; color: var(--due); font-weight: 600; }
.advance-card-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: var(--space-3); }
.advance-card-actions .button { margin: 0; }
.advance-claim { display: flex; flex-direction: column; gap: 0.15rem; padding: 0.75rem 0.9rem; background: var(--surface-muted); border-radius: 10px; margin-bottom: var(--space-3); }
.advance-claim strong { font-size: 1.1rem; }
.advance-claim-meta { font-size: var(--text-sm); color: var(--muted); }
.share-message-preview { white-space: pre-wrap; font: inherit; font-size: var(--text-sm); line-height: 1.5; margin: 0 0 var(--space-3); padding: 0.75rem 0.9rem; background: var(--surface-muted); border-radius: 10px; word-break: break-word; }
textarea.share-message-preview { display: block; width: 100%; box-sizing: border-box; border: 1px solid var(--border); resize: vertical; }
.share-link-actions { display: flex; flex-direction: column; gap: 0.5rem; }
.table-cell-actions { display: flex; align-items: center; gap: 0.75rem; }
.share-link-actions .button { margin: 0; justify-content: center; }
/* Settings: a toggle row that also carries its own input (bKash/Nagad number, QR upload). */
.settings-toggle-field > span > input, .settings-toggle-field > span > .settings-qr-upload { margin-top: 0.5rem; }
.settings-toggle-field > span > input { max-width: 16rem; }
.settings-qr-upload { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.settings-qr-thumb { width: 72px; height: 72px; object-fit: contain; border: 1px solid var(--border-subtle); border-radius: 8px; background: white; }
.settings-file-button { position: relative; overflow: hidden; cursor: pointer; margin: 0; }
.settings-file-button input { position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; opacity: 0; cursor: pointer; }
.settings-radio-list input[type=radio] { accent-color: var(--brand); width: 1.1rem; height: 1.1rem; margin-top: 0.2rem; flex: 0 0 auto; }

@media print {
    .admin-header, .admin-bottom-nav, .no-print { display: none !important; }
    .print-only { display: block; }
    .admin-main { padding: 0; max-width: none; }
    .data-table .filter-row-inline, .data-table .sort-indicator { display: none; }
    .data-table th.sortable-th { cursor: default; }
    .report-footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        margin-top: 0;
        padding-bottom: 0.75rem;
        background: white;
    }
}

.onboarding-step { color: var(--muted); font-size: 0.85rem; margin: 0 0 0.25rem; }

.onboarding-actions { display: flex; gap: 0.75rem; align-items: center; margin-top: var(--space-4); }
.onboarding-actions button { margin-top: 0; }

.related-product-helper { color: var(--muted); font-size: .82rem; }
.inline-add-related { background: transparent; border: 0; color: var(--accent, #bd5128); padding: .35rem 0; font: inherit; font-size: .9rem; font-weight: 600; text-decoration: underline; cursor: pointer; }
.section-heading-action { display: block; }
.section-heading-action h2 { margin-bottom: .15rem; }
.section-heading-action .related-product-helper { display: inline; }
.section-heading-action .inline-add-related { display: inline; margin-left: .3rem; }

/* Create/edit forms follow one quiet, vertical reading flow: each task is grouped without
   turning the page into a dense multi-column dashboard. Tables remain untouched inside the
   product section, while customer, delivery and payment fields become easy to scan. */
.entry-form-section {
    background: #fffdfb;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: clamp(1rem, 2vw, 1.5rem);
    margin: 1rem 0;
}
.entry-form-section > h2,
.entry-form-section .section-heading-action h2 { margin-top: 0; }
.entry-form-section-action { margin: .2rem 0 .85rem; }
.entry-form-section-action .related-product-helper { display: inline; }
.entry-form-section-action .inline-add-related { display: inline; margin-left: .3rem; }
.entry-form-section > label { display: block; max-width: 42rem; margin: .9rem 0 0; }
.entry-form-section > label input,
.entry-form-section > label select,
.entry-form-section > label textarea { width: 100%; }

/* The two rules above are meant for a field label sitting above a full-width text/select/
   textarea input. A checkbox or radio label is the opposite shape — a small control inline
   with its own text — and was being caught by them: ".entry-form-section > label" (0,1,1)
   outranks ".radio-label" (0,1,0), so display:block replaced the flex row, and the input rule
   stretched the radio itself to width:100%. The result put the control on its own line, far
   from the words it belongs to. Restated here at matching specificity rather than adding
   :not() above, so the intent of each rule stays readable on its own. */
.entry-form-section > label.radio-label,
.entry-form-section > label.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0 0;
}
.entry-form-section > label.radio-label input,
.entry-form-section > label.checkbox-label input { width: auto; flex: 0 0 auto; }
.entry-form-section .related-party-create { margin-top: .5rem; }
.entry-form-section .total-line {
    margin: 1.25rem 0 .85rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
    font-size: 1.1rem;
}
.entry-form-section-final { background: #fffaf6; }
.bulk-edit-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin: 0.75rem 0 0;
}
.bulk-edit-row label { display: block; flex: 1 1 10rem; min-width: 8rem; margin: 0; }
.bulk-edit-row label input { width: 100%; }
.bulk-edit-row .button { flex: 0 0 auto; }

/* Both of these are "do something to every ধরন at once" action panels sitting in a page
   that's otherwise a plain table — without their own background they read as just more of the
   same flat page (confirmed from a screenshot: nothing visually separated them from the table
   above/below). A tint + a coloured left edge is enough to read as "a distinct zone" while
   scrolling past, without the weight of a full card shadow. Different accent colours from each
   other on purpose — this bar edits EXISTING ধরন (blue/"info"), the one below CREATES a new one
   (brand orange, the same color every other primary "add" action in this app already uses). */
.bulk-edit-bar {
    background: var(--info-bg);
    border-color: var(--info-border);
    border-left: 4px solid var(--info-accent);
}
.variant-add-section {
    background: var(--warning-bg);
    border-color: var(--warning-border);
    border-left: 4px solid var(--brand);
}
.bulk-edit-bar > h2,
.variant-add-section > h2 { display: flex; align-items: center; gap: 0.4rem; }
@media (max-width: 700px) {
    .entry-form-section { margin: .85rem 0; padding: 1rem; border-radius: .75rem; }
    .entry-form-section > label { max-width: none; }
    /* .bulk-edit-row's two inputs already wrap into their own two-column row at this width
       (flex-wrap on the 10rem-minimum labels) — the button was left at its own natural content
       width beside/below them, which looked fine while its label was long enough to span nearly
       the full row on its own, but shrinks to an oddly narrow, off-center box once that label
       is shortened. Full-width here matches every other primary mobile action in this app. */
    .bulk-edit-row .button { flex: 1 1 100%; width: 100%; }
    /* iOS Safari's native <input type="date"> (Blazor's InputDate, e.g. Purchases/Create.razor's
       "ক্রয়ের তারিখ") renders its day/month/year segments at their own intrinsic content width
       regardless of the input's CSS width — on a narrow mobile card that intrinsic width can
       exceed the input's box and spill past its rounded edge instead of shrinking to fit.
       min-width: 0 lets it actually honor the 100% it's already given (the flex/grid default of
       min-width: auto is what was overriding that), and a slightly smaller font gives the
       day/month/year text enough room to fit that 100% without needing to grow past it. */
    .entry-form-section input[type="date"] {
        width: 100%;
        max-width: 100%;
        min-width: 0;
        box-sizing: border-box;
        font-size: 0.9rem;
    }
}
/* Size/color chip picker (product variants wizard + manage-variants page): a row of toggle
   pills instead of a plain checkbox list, so a shop owner can scan and tap options quickly on
   a phone instead of reading a vertical list of checkboxes. */
.variant-chip-grid { display: flex; flex-wrap: wrap; gap: .5rem; margin: .5rem 0 1rem; }
.variant-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .45rem .9rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: pointer;
    font-size: .95rem;
    user-select: none;
    background: #fff;
    transition: background .15s, border-color .15s, color .15s;
}
.variant-chip input { margin: 0; width: auto; flex: 0 0 auto; }
.variant-chip.selected { background: var(--brand); border-color: var(--brand); color: #fff; }
.variant-chip-add {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin: .35rem 0 1rem;
}
.variant-chip-add input[type="text"] { max-width: 14rem; }

/* Small groups of an input plus one or more buttons on one line (rename a size/color, add
   quick stock, save a price) — the default button/icon-button rules only add vertical margin,
   never a horizontal gap, so adjacent controls sat flush against each other without this. */
.inline-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .35rem; }
.inline-actions input[type="text"], .inline-actions input[type="number"] { width: auto; max-width: 10rem; }
.inline-actions button, .inline-actions .button { margin-top: 0; }

/* ManageVariants.razor's স্টক/মূল্য cells specifically — a wide number input next to its own
   "সেভ"/"+ স্টক যোগ করুন" button was wrapping onto a second line inside the table cell even on
   a normal desktop width, because .line-item-table's own column-width rules were written for a
   different 5-column shape (Sales/Purchases/Orders' পণ্য/পরিমাণ/দাম/মোট layout) and squeezed
   this page's নরন/স্টক/মূল্য columns too narrow for their actual content. nowrap here plus a
   shorter input (matching .inline-add-stock's own 6rem) keeps every row on one line; .scroller
   (below) lets the table scroll horizontally instead if a viewport is ever too narrow for that. */
.inline-actions-nowrap { flex-wrap: nowrap; }
.inline-actions-nowrap input[type="number"] { width: 6rem; max-width: 6rem; flex-shrink: 0; }
.inline-actions-nowrap button, .inline-actions-nowrap .button { flex-shrink: 0; white-space: nowrap; }

/* Was applied to ManageVariants.razor's table wrapper with no actual rule behind it — a wide
   row (see .inline-actions-nowrap above) had nowhere to go but wrap or overflow invisibly.
   overflow-x here is the same escape hatch .data-table already uses on the list pages: scroll
   sideways rather than silently clipping or squeezing content unreadably. */
.scroller { overflow-x: auto; }

.inline-add-stock { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; margin-top: .5rem; }
.inline-add-stock label { display: flex; flex-direction: column; gap: .2rem; margin: 0; }
.inline-add-stock input[type="number"] { width: 6rem; }
.inline-add-stock button, .inline-add-stock .button { margin-top: 0; }

.related-create-modal { max-width: 42rem; max-height: min(90vh, 52rem); overflow: auto; }
.related-create-modal label { display: block; margin: .75rem 0; }
.related-stock { margin: 1rem 0; padding: .75rem 1rem; border: 1px solid #e7d7ca; border-radius: .65rem; }
@media (max-width: 700px) { .related-create-modal { width: 100%; height: 100%; max-width: none; max-height: none; border-radius: 0; } }

.mode-choices { display: flex; flex-direction: column; gap: 0.75rem; margin: 1.25rem 0; }
.mode-card {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 1rem 1.1rem;
    border: 2px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.mode-card:hover { border-color: var(--brand); }
.mode-card.selected { border-color: var(--brand); background: var(--warning-bg); }
/* The real <input> stays in the tab order and receives focus — visually hidden (not
   display:none, which would drop it from focus/keyboard handling) rather than styled away,
   so screen readers and keyboard nav still see a real radio input. */
.mode-card-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.mode-card-input:focus-visible ~ .mode-card-radio { outline: 2px solid var(--brand); outline-offset: 2px; }
.mode-card-radio {
    flex-shrink: 0;
    width: 1.35rem;
    height: 1.35rem;
    margin-top: 0.15rem;
    border: 2px solid var(--border);
    border-radius: 50%;
    box-sizing: border-box;
    position: relative;
}
.mode-card.selected .mode-card-radio { border-color: var(--brand); }
.mode-card.selected .mode-card-radio::after {
    content: "";
    position: absolute;
    top: 3px; right: 3px; bottom: 3px; left: 3px;
    inset: 3px;
    border-radius: 50%;
    background: var(--brand);
}
.mode-card-text strong { display: block; font-size: 1.05rem; margin-bottom: 0.2rem; }
.mode-card-text p { margin: 0; color: var(--muted); font-size: 0.9rem; }

.onboarding-note { color: var(--muted); font-size: 0.85rem; margin-top: 0.75rem; }
.onboarding-done-actions { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.5rem; }
/* Report tabs */
/* margin-top is deliberately modest: .report-range-bar above already contributes its own
   16px bottom margin, and the two do not collapse (the page wrapper is a flex column), so
   they add up. At 1.5rem that produced a 40px void between the period picker and the tabs. */
.report-tabs { display: flex; gap: 1rem; margin-top: var(--space-3); border-bottom: 1px solid var(--border); }
.tab-button { flex: 0 0 auto; padding: 0.75rem 1rem; background: transparent; border: none; cursor: pointer; font-weight: normal; color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px; transition: all 0.2s ease; border-radius: 4px 4px 0 0; }
.tab-button.active { font-weight: bold; color: white; background: var(--brand); border-bottom-color: var(--brand); }
.tab-button:hover:not(.active) { color: var(--ink); background: rgba(184, 80, 42, 0.1); }

/* Product profit table/card responsive layout */
@media (min-width: 768px) {
    #product-profit-table { display: table !important; width: 100%; }
    .data-card { display: none !important; }
}

@media (max-width: 767px) {
    #product-profit-table { display: none !important; }
    .data-card { display: block !important; }
}

/* Image Gallery Upload */
.image-gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
    align-items: center;
}

.image-thumbnail {
    position: relative;
    width: 75px;
    height: 75px;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: #f9f7f4;
    flex-shrink: 0;
}

.image-thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.image-delete-btn {
    position: absolute;
    top: 0;
    right: 0;
    width: 24px;
    height: 24px;
    background: rgba(0, 0, 0, 0.8);
    border: none;
    color: white;
    font-size: 1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease;
    line-height: 1;
    padding: 0;
    border-radius: 0 4px 0 3px;
}

.image-delete-btn:hover {
    background: rgba(179, 33, 33, 0.9);
}

/* Persistent "held for review" flag on a product/logo thumbnail (Products/Edit.razor,
   Settings.razor, Onboarding/Logo.razor) — deliberately always-on, not just a one-time toast:
   the moderation-notice paragraph shown right after upload disappears on the next action, but
   the photo can stay Pending for as long as it takes the platform admin to look at it, so the
   owner needs a way to tell at a glance which of their photos aren't public yet. */
.moderation-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(230, 145, 15, 0.92);
    color: #fff;
    font-size: 0.55rem;
    font-weight: 600;
    text-align: center;
    padding: 2px 1px;
    line-height: 1.2;
}

/* Rejected (not just pending) variant of .moderation-badge above — the underlying file is
   already deleted from disk by the time this renders (see /admin/media in Program.cs, which
   falls back to the "removed" placeholder graphic), so without this the owner sees a blank
   removed-image icon with no explanation at all. Red rather than amber to read as "this one
   needs action" (delete it), not "still waiting". */
.moderation-badge-rejected {
    background: rgba(179, 33, 33, 0.92);
}

/* Waiting for the automatic background check — neutral blue rather than amber, so "being
   checked, nothing for you to do" reads differently from "a person will review this". */
/* "Your photo is waiting for a person to review it" card (ModerationReviewNotice). Calm blue —
   it is information, not a warning — with a link to the policy section. */
.moderation-review-note {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    margin: .7rem 0;
    padding: .7rem .85rem;
    border: 1px solid #cfe0f7;
    border-left: 3px solid #1a73e8;
    border-radius: 10px;
    background: #f4f9ff;
    color: #1b3554;
}
.moderation-review-icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: #e1eeff;
    color: #1769d2;
}
.moderation-review-icon .icon { width: 17px; height: 17px; }
.moderation-review-body strong { display: block; margin-bottom: .1rem; font-size: .92rem; }
.moderation-review-body p { margin: 0 0 .3rem; color: #4c627a; font-size: .82rem; line-height: 1.5; }
.moderation-review-body a { display: inline-flex; align-items: center; gap: .25rem; color: #155fc4; font-size: .82rem; font-weight: 600; text-decoration: none; }
.moderation-review-body a:hover { text-decoration: underline; }
.moderation-review-body a .icon { width: 13px; height: 13px; }
#halal-shalinota { scroll-margin-top: 90px; }
/* Variant colour swatch (ManageVariants): a small round dot right after the variant name + pencil,
   on every screen size, no text. Standard colour names already get their dot automatically; this
   only changes the shade. !important because the global admin input rule forces a 2.65rem minimum
   height and a 9px radius on every input, which stretched the dot into a tall pill. */
.admin-shell .variant-manage-table .vm-swatch-dot {
    width: 1.5rem !important; height: 1.5rem !important; min-height: 0 !important; min-width: 0 !important;
    padding: 0 !important; margin: 0 .3rem 0 .25rem !important; flex: none;
    border: 1px solid #cfdcec !important; border-radius: 50% !important; background: none !important;
    cursor: pointer; overflow: hidden;
}
.admin-shell .variant-manage-table .vm-swatch-dot::-webkit-color-swatch-wrapper { padding: 0; }
.admin-shell .variant-manage-table .vm-swatch-dot::-webkit-color-swatch { border: 0; border-radius: 50%; }
.admin-shell .variant-manage-table .vm-swatch-dot::-moz-color-swatch { border: 0; border-radius: 50%; }
/* Floating "contact ongsi" bubble on the owner-facing pages (FloatingContact.razor).
   Written to work on old phones too (iPhone 6 / iOS 12 Safari): a plain div + <button> instead of
   <details>/<summary>; fixed pixel sizes; flex centring; margins instead of flex `gap` (not supported
   before iOS 14.5); and max-width: calc() instead of min(). "html body" beats the layout rule
   `body:has(> .site-footer) > *` that stretches direct children of the page on newer browsers. */
/* Pinned with an explicit LEFT (viewport width minus button width minus gap), not "left: auto; right: ...":
   iOS 12 Safari left the button at the page's left edge when it had to work the position out from ight. */
html body .floating-contact { position: fixed; top: auto; right: auto; left: calc(100% - 68px); bottom: 8px; width: 52px; height: 52px; margin: 0; z-index: 1000; }
.floating-contact-button {
    -webkit-appearance: none;
    appearance: none;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 52px;
    height: 52px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 26px;
    background: #1a73e8;
    color: #fff;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    box-shadow: 0 8px 22px rgba(26, 115, 232, .38);
    transition: transform .15s ease, box-shadow .15s ease;
}
.floating-contact-button:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(26, 115, 232, .45); }
.floating-contact-button .icon { display: block; width: 26px; height: 26px; }
.floating-contact-card {
    display: none;
    /* Pinned to the SCREEN with left + right margins (a phone-width sheet above the button), not placed
       relative to the 52px button container: old iPhone Safari put that version outside the window. */
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 70px;
    box-sizing: border-box;
    width: auto;
    max-width: 380px;
    max-height: 75vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 16px;
    border: 1px solid #d7e7fa;
    border-radius: 16px;
    background: #fff;
    color: #1b3554;
    box-shadow: 0 18px 44px rgba(27, 53, 84, .2);
}
.floating-contact.is-open .floating-contact-card { display: block; }
.floating-contact-card > strong { display: block; font-size: 1rem; }
.floating-contact-card > p { margin: 4px 0 12px; color: #61768d; font-size: .88rem; line-height: 1.55; }
.floating-contact-row {
    display: flex;
    align-items: center;
    padding: 9px 11px;
    margin-top: 6px;
    border: 1px solid #e0eaf6;
    border-radius: 12px;
    color: #1b3554;
    text-decoration: none;
    font-weight: 600;
    font-size: .92rem;
}
.floating-contact-row:hover { background: #f4f9ff; border-color: #a9c9f4; }
.floating-contact-row-text { display: block; min-width: 0; }
.floating-contact-row small { display: block; margin-top: 2px; color: #61768d; font-weight: 400; font-size: .82rem; }
.floating-contact-row-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 36px;
    height: 36px;
    margin-right: 12px;
    border-radius: 10px;
    background: #e8f2ff;
    color: #1769d2;
}
.floating-contact-row-icon .icon { width: 19px; height: 19px; }
@media (min-width: 641px) { .floating-contact-card { left: auto; right: 16px; bottom: 68px; width: 330px; } }
@media (max-width: 640px) { html body .floating-contact { left: calc(100% - 64px); bottom: 6px; } }
@media print { .floating-contact { display: none; } }
@media (prefers-reduced-motion: reduce) { .floating-contact-button { transition: none; } }
.moderation-badge-processing {
    background: rgba(41, 98, 168, 0.92);
}

.image-add-button {
    width: 75px;
    height: 75px;
    border: 2px dashed var(--border);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    background: #f9f7f4;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
}

/* !important needed here: input[type=file] (above) sets display:block at equal specificity,
   and ties go to whichever rule the cascade/build happens to serve last — not reliable enough
   to leave unforced, as confirmed live (the native "File No file chosen" control showing next
   to the dashed "+" box instead of being hidden). */
.image-add-button input {
    display: none !important;
}

.image-add-button:hover {
    border-color: var(--brand);
    background: rgba(184, 80, 42, 0.08);
}

/* Drag-and-drop photo zone (Products/Edit.razor): the same 75px square as a thumbnail, just a "+",
   no text — the hint lives in its tooltip. Unlike .image-add-button above, its file input is NOT
   hidden with display:none (a browser only accepts a drop on a file input that is rendered), so
   the input is stretched invisibly over the whole square: a click anywhere opens the picker.
   Dropped files are handed to that input by image-dropzone.js, which also adds .is-dragover while
   a file is being dragged over it. */
.image-dropzone {
    position: relative;
    flex: 0 0 75px;
    width: 75px;
    height: 75px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 0;
    border: 2px dashed var(--border);
    border-radius: 4px;
    background: #f9f7f4;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
}
.image-dropzone input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
    font-size: 0;
}
.image-dropzone:hover,
.image-dropzone.is-dragover {
    border-color: var(--brand);
    background: rgba(184, 80, 42, 0.08);
}
.image-dropzone.is-dragover { border-style: solid; }
.image-dropzone:focus-within { outline: 2px solid var(--brand); outline-offset: 2px; }
.image-dropzone-icon { font-size: 1.6rem; line-height: 1; font-weight: bold; color: var(--brand); pointer-events: none; }
.add-icon {
    font-size: 1.6rem;
    color: var(--brand);
    font-weight: bold;
    line-height: 1;
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Onboarding/Logo.razor's own preview — a bit bigger than a product thumbnail since it's the
   sole focus of that screen, not one of several images in a gallery. */
.onboarding-logo-preview { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-3) 0; }
.onboarding-logo-preview img { width: 96px; height: 96px; object-fit: contain; border: 1px solid var(--border); border-radius: 4px; background: #fff; padding: var(--space-2); }
/* Positioning anchor for .moderation-badge over the logo preview — see app.css's own comment
   on .moderation-badge for why this stays visible past the upload toast. */
.logo-preview-frame { position: relative; display: inline-block; }
.logo-preview-frame .moderation-badge { border-radius: 0 0 4px 4px; }

/* Admin visual refresh: one soft canvas, readable controls, and quieter data density.
   Keep these rules inside the admin shell so the public shop and checkout retain their styles. */
.admin-shell {
    --brand: #1a73e8;
    --accent: #1a73e8;
    --admin-primary: #1a73e8;
    --admin-primary-hover: #155fc4;
    --ink: #202b3a;
    --muted: #607084;
    --border: #d4deeb;
    --border-subtle: #e4eaf2;
    --paper: #fff;
    --surface-muted: #f2f6fc;
    --info-bg: #eef5ff;
    --info-border: #d3e4fb;
    --info-accent: #1a73e8;
    --radius-md: 12px;
    --control-height: 2.75rem;
    background: var(--paper);
    color: var(--ink);
}

.admin-shell .admin-header {
    border-bottom-color: var(--border-subtle);
    box-shadow: 0 1px 8px rgba(39, 55, 83, .035);
}
.admin-shell .admin-main {
    padding: clamp(1.25rem, 2.5vw, 2.5rem);
    padding-bottom: 3rem;
}
.admin-shell .admin-main > h1,
.admin-shell .admin-main > div > h1 {
    font-size: clamp(1.55rem, 2vw, 1.9rem);
    line-height: 1.35;
    letter-spacing: -.015em;
    margin-bottom: 1.25rem;
}
.admin-shell h2 { line-height: 1.4; }
.admin-shell .admin-nav-link.active {
    background: #e8f0fe;
    color: var(--brand);
    border-bottom-color: transparent;
}
.admin-shell .admin-nav-link:hover,
.admin-shell .nav-dropdown-trigger:hover,
.admin-shell .admin-account-trigger:hover { background: #eff5ff; }
.site-header .admin-account-trigger:hover,
.site-header .admin-account-trigger:focus-visible { background: #eff5ff; color: #1a73e8; }
.admin-shell .admin-shopview-btn { border-color: var(--border); background: #fff; color: var(--ink); }
.admin-shell .admin-shopview-btn:hover { border-color: #a9c9f4; background: #f1f6ff; color: var(--brand); }

.admin-shell .button:not(.danger),
.admin-shell button[type=submit]:not(.danger) {
    border-radius: 9px;
}
.admin-shell .button:not(.secondary):not(.danger),
.admin-shell button[type=submit]:not(.danger) {
    background: var(--admin-primary);
    border-color: var(--admin-primary);
    color: #fff;
}
.admin-shell .button:not(.secondary):not(.danger):hover,
.admin-shell button[type=submit]:not(.danger):hover {
    background: var(--admin-primary-hover);
    border-color: var(--admin-primary-hover);
}
.admin-shell .button.secondary:not(.danger) {
    border-color: var(--border);
    color: var(--ink);
    background: #fff;
}
.admin-shell .button.secondary:hover { background: #eef5ff; border-color: #a9c9f4; color: #155fc4; }
.admin-shell .button:focus-visible,
.admin-shell button:focus-visible,
.admin-shell a:focus-visible,
.admin-shell input:focus-visible,
.admin-shell select:focus-visible,
.admin-shell textarea:focus-visible { outline: 3px solid #a6b9f4; outline-offset: 2px; }

.admin-shell input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]):not([type=file]),
.admin-shell select,
.admin-shell textarea {
    background-color: #fff;
    border-color: #cbd8e8;
    border-radius: 9px;
    min-height: 2.65rem;
    box-shadow: 0 1px 2px rgba(40, 53, 75, .025);
}
.admin-shell textarea { min-height: 5.5rem; }
.admin-shell label { color: #41516a; font-weight: 500; }
.admin-shell .field-help { color: var(--muted); font-style: normal; font-size: .82rem; line-height: 1.5; }
@media (min-width: 900px) {
    .admin-shell .admin-main > form > label:not(.checkbox-label):not(.radio-label) { max-width: 36rem; }
    .admin-shell .admin-main > form > label:not(.checkbox-label):not(.radio-label) > input,
    .admin-shell .admin-main > form > label:not(.checkbox-label):not(.radio-label) > select,
    .admin-shell .admin-main > form > label:not(.checkbox-label):not(.radio-label) > textarea { max-width: none; }
}

.admin-shell .page-header { margin-bottom: 1.25rem; }
.admin-shell .page-header > div { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.admin-shell .page-header .button { margin-top: 0; min-height: 2.55rem; box-sizing: border-box; }
.admin-shell .list-toolbar { gap: .65rem; margin-bottom: 1.25rem; }
.admin-shell .toolbar-search-wrap { flex-grow: 0; flex-basis: clamp(16rem, 32vw, 26rem); }
.admin-shell .toolbar-search { max-width: none !important; margin-top: 0; }
.admin-shell .filter-panel,
.admin-shell .entry-form-section,
.admin-shell .create-options {
    background: #fff;
    border-color: var(--border-subtle);
    border-radius: 14px;
    box-shadow: 0 2px 12px rgba(41, 57, 84, .035);
}
.admin-shell .entry-form-section { padding: clamp(1.25rem, 2.3vw, 2rem); margin: 1rem 0 1.25rem; }
.admin-shell .entry-form-section-final { background: #fff; }
.admin-shell .first-visit-hint { background: #eef5ff; border-color: var(--info-border); }
.admin-shell .admin-info-note {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    box-sizing: border-box;
    margin: .75rem 0;
    padding: .7rem .85rem;
    border: 1px solid var(--info-border);
    border-left: 3px solid var(--info-accent);
    border-radius: 8px;
    background: var(--info-bg);
    color: var(--ink);
    font-size: .8rem;
    font-weight: 400;
    line-height: 1.5;
}
.admin-shell .admin-info-note .icon { flex: 0 0 auto; margin-top: .15em; color: var(--info-accent); }
.admin-shell .admin-info-note > span { min-width: 0; }
.admin-shell .settings-note {
    padding: .55rem .7rem;
    border: 1px solid var(--info-border);
    border-left: 3px solid var(--info-accent);
    border-radius: 8px;
    background: var(--info-bg);
    color: var(--ink);
}
.admin-shell .settings-note .icon { color: var(--info-accent); }
.admin-shell .page-info { background: var(--info-bg); border-color: var(--info-border); border-left-color: var(--info-accent); font-size: .8rem; }
.admin-shell .page-info[open] summary { border-bottom-color: var(--info-border); }
.admin-shell .admin-main .variant-add-info { font-size: .8rem; }

@media (min-width: 641px) {
    .admin-shell .data-table {
        margin-top: .75rem;
        border-color: var(--border-subtle);
        border-radius: 14px;
        background: #fff;
        box-shadow: 0 2px 12px rgba(41, 57, 84, .035);
    }
    .admin-shell .data-table th,
    .admin-shell .data-table td {
        padding: .85rem 1rem;
        border-right: 0;
        border-bottom-color: var(--border-subtle);
    }
    .admin-shell .data-table thead th { background: #e8f1fe; color: #344969; font-size: .82rem; border-bottom-color: #cbdcf6; }
    .admin-shell .data-table tbody tr:hover { background: #f6f9ff; }
    .admin-shell .data-table tbody tr:has(.row-menu-panel) { background: #eef5ff; }
}

@media (min-width: 641px) and (max-width: 1100px) {
    .admin-shell .admin-header { padding-inline: 1rem; }
    .admin-shell .admin-main { padding: 1.5rem; }
    .admin-shell .data-table th,
    .admin-shell .data-table td { padding: .7rem .6rem; }
}

@media (max-width: 640px) {
    .admin-shell .admin-main { padding: 1rem; padding-bottom: calc(5.5rem + env(safe-area-inset-bottom)); }
    .admin-shell .toolbar-search-wrap { flex: 1 1 100%; }
    .admin-shell .entry-form-section { padding: 1rem; }
}

/* Use the space according to the task: a comfortable reading column for forms, a wider
   workspace for records. These page signatures avoid changing storefront or POS layouts. */
@media (min-width: 641px) {
.admin-main:has(> form.product-editor) { max-width: 800px; }
.admin-main:has(> .bc-page-title) { max-width: 800px; }
    .admin-main:has(> form.stock-adjust-form) { max-width: 800px; }
    .admin-main:has(> .order-products-section) { max-width: 1100px; }
    .admin-main:has(> .transaction-form-heading) { max-width: 800px; }
    .admin-main:has(> .compact-form-heading) { max-width: 800px; }
    .admin-main:has(> .product-variant-form-heading),
    .admin-main:has(> .stock-add-section) { max-width: 800px; }
    .admin-shell .admin-main:has(> .detail-identity),
    .admin-shell .admin-main:has(> .bc-assign) { max-width: 800px; }
    .admin-main:has(> .stat-cards) { max-width: 1180px; }
    .admin-main:has(> .list-toolbar) { max-width: 1280px; }
    .admin-main:has(> .desktop-only-table) { max-width: 1280px; }
    .admin-main:has(> .bc-toolbar) { max-width: 800px; }
}

.admin-shell .admin-main > h1 { margin-bottom: .9rem; }
.admin-shell .admin-main > .back-link { margin-bottom: .4rem; }
.admin-shell .admin-main > .back-link + h1 { margin-bottom: .9rem; }
.admin-shell .page-header { margin-bottom: .9rem; }
.admin-shell .list-toolbar { margin-bottom: 1rem; }
.admin-shell .data-table { margin-top: .4rem; }

/* List pages need a compact heading and actions before the data, with export in a
   predictable place. Leave form and detail headings at their own reading scale. */
@media (min-width: 641px) {
    .admin-shell .admin-main:has(> .list-toolbar) { padding-top: clamp(1.25rem, 2vw, 1.75rem); }
    .admin-shell .admin-main:has(> .list-toolbar) > h1 {
        margin-bottom: .65rem;
        font-size: 1.6rem;
        line-height: 1.3;
    }
    .admin-shell .admin-main:has(> .list-toolbar) > .page-header { margin-bottom: .7rem; }
    .admin-shell .admin-main:has(> .list-toolbar) > .page-header .button {
        min-height: 2.5rem;
        padding: .45rem .85rem;
        font-size: .9rem;
    }
    .admin-shell .admin-main:has(> .list-toolbar) > .list-toolbar { margin-bottom: .8rem; }
}
.admin-shell .admin-main:has(> .list-toolbar) > .list-toolbar > .export-menu { margin-left: auto; }
.admin-shell .admin-main:has(> .list-toolbar) > .list-toolbar .export-menu-panel { right: 0; left: auto; }

/* The product editor was a narrow stack on an otherwise empty page. The form now reads as
   one centered task, with the optional variant area visually grouped inside it. */
.admin-shell form.product-editor,
.admin-shell form.stock-adjust-form {
    box-sizing: border-box;
    width: 100%;
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    padding: clamp(1.25rem, 3vw, 2.25rem);
    box-shadow: 0 3px 18px rgba(40, 55, 82, .045);
}
.admin-shell .admin-form-card {
    box-sizing: border-box;
    width: 100%;
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    padding: clamp(1.25rem, 3vw, 2.25rem);
    box-shadow: 0 3px 18px rgba(40, 55, 82, .045);
}
.admin-shell .admin-form-card > label:not(.checkbox-label):not(.radio-label) {
    display: block;
    width: 100%;
    max-width: none !important;
    margin: 0 0 1.1rem;
}
.admin-shell .admin-form-card > label:not(.checkbox-label):not(.radio-label) input,
.admin-shell .admin-form-card > label:not(.checkbox-label):not(.radio-label) select,
.admin-shell .admin-form-card > label:not(.checkbox-label):not(.radio-label) textarea {
    box-sizing: border-box;
    width: 100%;
    max-width: none !important;
}
.admin-shell .admin-ledger-payment-card { max-width: 800px; margin: 1.25rem auto; }
.admin-shell .admin-ledger-payment-card .admin-form-heading h2,
.admin-shell .admin-ledger-payment-card .admin-form-heading h3 { margin: 0; }
.admin-shell .admin-main:has(> .detail-identity) > .detail-section {
    box-sizing: border-box;
    width: 100%;
    margin: 0 0 1rem;
    padding: clamp(1.25rem, 3vw, 2rem);
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    background: #fff;
    box-shadow: 0 3px 18px rgba(40, 55, 82, .045);
}
.admin-shell .admin-main:has(> .detail-identity) > .detail-section > h2:first-child { margin-top: 0; }
.admin-shell .admin-main:has(> .detail-identity) > .product-manage-nav,
.admin-shell .admin-main:has(> .detail-identity) > details.more-info {
    box-sizing: border-box;
    width: 100%;
    margin: 0 0 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    background: #fff;
    box-shadow: 0 3px 18px rgba(40, 55, 82, .045);
}
.admin-shell .admin-main:has(> .detail-identity) > details.more-info { padding: 1rem 1.25rem; }
.admin-shell .admin-main:has(> .detail-identity) > .admin-ledger-payment-card { margin: 0 0 1rem; }
@media screen {
    .admin-shell .admin-main:has(> .detail-identity) .detail-table-desktop { display: none; }
    .admin-shell .admin-main:has(> .detail-identity) .mobile-product-list { display: flex; }
}
.admin-shell form.product-editor > label:not(.checkbox-label):not(.radio-label),
.admin-shell form.stock-adjust-form > label:not(.checkbox-label):not(.radio-label) {
    max-width: 100%;
    margin: 0 0 1.1rem;
}
.admin-shell form.product-editor > label:not(.checkbox-label):not(.radio-label) > input,
.admin-shell form.product-editor > label:not(.checkbox-label):not(.radio-label) > select,
.admin-shell form.product-editor > label:not(.checkbox-label):not(.radio-label) > textarea,
.admin-shell form.stock-adjust-form > label:not(.checkbox-label):not(.radio-label) > input,
.admin-shell form.stock-adjust-form > label:not(.checkbox-label):not(.radio-label) > select {
    max-width: 100%;
}
.admin-shell form.stock-adjust-form .stock-adjust-preview { width: 100%; max-width: none; }
.admin-shell form.product-editor .barcode-input-row { max-width: 100%; }
.admin-shell .product-editor-fields {
    display: block;
    margin-bottom: 1.1rem;
}
.admin-shell .product-editor-fields > label:not(.checkbox-label):not(.radio-label) {
    display: block;
    width: 100%;
    max-width: none;
    margin: 0 0 1.1rem;
}
.admin-shell form.product-editor .product-editor-fields > label > input:not([type=checkbox]),
.admin-shell form.product-editor .product-editor-fields > label > select,
.admin-shell form.product-editor .product-editor-fields > label > textarea { width: 100%; max-width: none !important; }
.admin-shell .product-editor-fields > label textarea { resize: vertical; }
.admin-shell .product-barcode-section {
    padding: 1.1rem 1.25rem;
    margin: .2rem 0 1.35rem;
    background: #f2f7ff;
    border: 1px solid #d8e6f7;
    border-radius: 12px;
}
.admin-shell .product-barcode-heading { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .75rem; }
.admin-shell .product-barcode-heading h2 { font-size: 1.05rem; margin: 0; }
.admin-shell .product-barcode-heading span { color: var(--muted); font-size: .8rem; }
.admin-shell .product-barcode-section > label { display: block; width: 100%; max-width: none; margin: 0; }
.admin-shell .product-barcode-section .barcode-input-row {
    width: 100%;
    max-width: none;
}
.admin-shell .product-barcode-section .barcode-input-row > input {
    min-height: 2.65rem;
}
.admin-shell .product-barcode-section .barcode-camera-btn { width: 2.7rem; }
/* Barcode text and camera are one connected field on product, variant and quick-create forms. */
.admin-shell .barcode-input-row > input {
    border-right: 0 !important;
    border-radius: 9px 0 0 9px !important;
    box-shadow: none;
}
.admin-shell .barcode-input-row > .barcode-camera-btn {
    box-sizing: border-box;
    background: #fff;
    border: 1px solid #cbd8e8;
    border-radius: 0 9px 9px 0;
}
.admin-shell .barcode-input-row > .barcode-camera-btn:hover { background: #eef5ff; }
.admin-shell .barcode-input-row > .barcode-camera-btn.active { background: var(--brand); color: #fff; }
.admin-shell .product-barcode-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .8rem; }
.admin-shell .product-barcode-actions .button { margin: 0; min-height: 2.4rem; padding: .4rem .75rem; font-size: .85rem; }
.admin-shell .product-barcode-actions .phone-pair-trigger {
    min-height: 2.4rem;
    margin: 0;
    padding: .4rem .75rem;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 9px;
    color: var(--ink);
    font-size: .85rem;
    text-decoration: none;
}
.admin-shell .product-barcode-actions .phone-pair-trigger:hover { background: #eef5ff; border-color: #a9c9f4; }
.admin-shell .product-barcode-actions .barcode-generate-note { margin: 0; }
.admin-shell .product-editor-fields > .product-barcode-field { margin: .4rem 0 1rem; }
/* Stock row under the price on the product form (create and edit). */
.admin-shell .product-editor-fields > .product-stock-block { margin: 0 0 1.1rem; }
.admin-shell .product-unit-line { display: block; margin: 0 0 1.1rem; }
.admin-shell form.product-editor .product-unit-line > select { width: 100%; max-width: none !important; }
/* Quantity (or current stock) and cost price share one line on desktop; they stack on phones. */
.admin-shell .product-stock-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem; align-items: end; }
@media (max-width: 640px) { .admin-shell .product-stock-row { grid-template-columns: 1fr; } }
.admin-shell .product-stock-row > label { display: block; margin: 0; }
/* A long hint must be clipped with "…" instead of running past the input's edge. */
.admin-shell .product-stock-row input::placeholder { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-shell .product-stock-row input { min-width: 0; text-overflow: ellipsis; }
.admin-shell form.product-editor .product-stock-row > label > input:not([type=checkbox]),
.admin-shell form.product-editor .product-stock-row > label > select { width: 100%; max-width: none !important; }
.admin-shell .product-stock-current { display: grid; gap: .15rem; padding: .55rem .85rem; border: 1px solid #d8e6f7; border-radius: 10px; background: #f5f9ff; }
.admin-shell .product-stock-current span { color: var(--muted); font-size: .85rem; }
.admin-shell .product-stock-current strong { color: #1b3554; font-size: 1.1rem; }
.admin-shell .product-stock-links { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .6rem; }
.admin-shell .product-stock-link { padding: .25rem .1rem; border: 0; background: transparent; color: #155fc4; font: inherit; text-decoration: underline; cursor: pointer; }
.admin-shell .product-stock-supplier { margin-top: .6rem; }
/* The stock/variants shortcuts on the edit page: taller and clearly clickable, not small grey chips. */
.admin-shell .product-stock-links .product-stock-action {
    min-height: 2.9rem;
    padding: .65rem 1.25rem;
    border: 1.5px solid #80b3f6;
    border-radius: 10px;
    background: #eef5ff;
    color: #104fa6;
    font-size: .95rem;
    font-weight: 700;
}
.admin-shell .product-stock-links .product-stock-action:hover { background: #dcecff; border-color: #1a73e8; }
.admin-shell .product-stock-supplier summary { color: #155fc4; cursor: pointer; }
.admin-shell .product-stock-supplier label { display: block; margin-top: .6rem; }
.admin-shell .product-variants-choice { display: flex; align-items: flex-start; gap: .7rem; margin: 1rem 0 0; padding: .9rem 1rem; border: 1px solid #d8e6f7; border-radius: 10px; background: #fff; cursor: pointer; }
.admin-shell .product-variants-choice:has(input:checked) { border-color: #80b3f6; background: #eef5ff; }
.admin-shell .product-variants-choice input { margin-top: .25rem; accent-color: #1a73e8; }
.admin-shell .product-variants-choice span { display: grid; gap: .2rem; }
.admin-shell .product-variants-choice small { color: var(--muted); font-weight: 400; line-height: 1.4; }
.admin-shell form.product-editor .create-options {
    margin-top: 1.5rem;
    padding: clamp(1rem, 2vw, 1.5rem);
    background: #f5f9ff;
    border-color: var(--border-subtle);
    box-shadow: none;
}
.admin-shell form.product-editor .create-options .button.secondary.create-action-button,
.admin-shell form.product-editor .create-options .variant-file-picker {
    background: #e8f1fe;
    border-color: #a9c9f4;
    color: #155fc4;
    font-weight: 600;
}
.admin-shell form.product-editor .create-options .button.secondary.create-action-button:hover,
.admin-shell form.product-editor .create-options .variant-file-picker:hover {
    background: #dcecff;
    border-color: #80b3f6;
    color: #104fa6;
}
.admin-shell form.product-editor .product-edit-save {
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-subtle);
    margin-top: 1.5rem;
    gap: .65rem;
}
.admin-shell form.stock-adjust-form > button[type=submit] { margin-top: 1.1rem; }
.admin-shell form.stock-adjust-form .stock-adjust-preview { margin: 1.25rem 0; }
.admin-main:has(> form.stock-adjust-form) > .field-help { max-width: 680px; margin-bottom: 1rem; }

/* Keep transaction sections in one reading column, with controls filling their card. */
.admin-shell .order-products-section,
.admin-shell .order-customer-section,
.admin-shell .order-delivery-section,
.admin-shell .order-payment-section { margin: 0 0 1rem; }
.admin-shell .order-products-section > h2,
.admin-shell .order-customer-section > h2,
.admin-shell .order-delivery-section > h2,
.admin-shell .order-payment-section > h2 { margin-bottom: .9rem; }
.admin-shell .order-product-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .65rem 1rem;
    padding-bottom: .9rem;
    border-bottom: 1px solid var(--border-subtle);
}
.admin-shell .order-product-heading h2 { margin: 0; }
.admin-shell .order-scan-tools { display: flex; align-items: end; flex-wrap: wrap; gap: .55rem .8rem; margin-top: .9rem; }
.admin-shell .order-scan-tools .line-scan-field { flex: 1 1 100%; min-width: 0; margin: 0; }
.admin-shell .order-scan-tools .line-scan-field input { box-sizing: border-box; width: 100%; max-width: none; border-width: 1px; }
.admin-shell .order-scan-tools .barcode-input-row { width: 100%; max-width: 100%; }
.admin-shell .order-scan-tools .phone-pair-trigger {
    min-height: 2.65rem;
    padding: .45rem .7rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: #fff;
    color: #155fc4;
    text-decoration: none;
}
.admin-shell .order-scan-tools .phone-pair-trigger:hover { background: #eef5ff; border-color: #a9c9f4; }
.admin-shell .order-products-section .line-item-table { margin-top: 1.15rem; }
.admin-shell .order-products-section .line-item-table th,
.admin-shell .order-products-section .line-item-table td { border-color: var(--border-subtle); }
.admin-shell .order-products-section .line-item-table th { background: #e8f1fe; }
.admin-shell .order-products-section .line-item-table select,
.admin-shell .order-products-section .line-item-table input { min-height: 2.5rem; }
.admin-shell .order-payment-section .total-line { margin: 1rem 0 .25rem; }
@media (max-width: 640px) {
    .admin-shell .order-scan-tools .line-scan-field { flex: 1 1 100%; }
}

.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) {
    width: 100%;
    max-width: none;
}
.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) input,
.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) select,
.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) textarea {
    box-sizing: border-box;
    width: 100%;
    max-width: none !important;
}
.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) .customer-combobox,
.admin-shell .admin-main:has(> .transaction-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) .district-combobox { width: 100%; }
.admin-shell .admin-main:has(> .product-variant-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) {
    width: 100%;
    max-width: none;
}
.admin-shell .admin-main:has(> .product-variant-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) input,
.admin-shell .admin-main:has(> .product-variant-form-heading) .entry-form-section > label:not(.radio-label):not(.checkbox-label) select {
    box-sizing: border-box;
    width: 100%;
    max-width: none !important;
}

/* The dashboard's six cards and action links now occupy a balanced grid rather than leaving
   one card on its own row and a large unused area to the right. */
@media (min-width: 900px) {
    .admin-main:has(> .stat-cards) .stat-cards {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: .9rem;
    }
    .admin-main:has(> .stat-cards) .quick-links {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: .7rem;
    }
    .admin-main:has(> .stat-cards) .quick-links .button { justify-content: flex-start; margin: 0; }
    .admin-main:has(> .stat-cards) .settings-section { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: .8rem; }
}
.admin-main:has(> .stat-cards) .stat-card {
    min-width: 0;
    border-color: var(--border-subtle);
    border-radius: 13px;
    padding: 1.15rem 1.25rem;
    box-shadow: 0 2px 10px rgba(40, 55, 82, .03);
}
.admin-main:has(> .stat-cards) .dashboard-group { margin: 1.5rem 0 0; padding-top: 1.35rem; border-color: var(--border-subtle); }
.admin-main:has(> .stat-cards) .dashboard-section-title { margin-bottom: .8rem; }
.admin-main:has(> .stat-cards) .settings-section .settings-card { width: 100%; min-width: 0; border-radius: 12px; justify-content: flex-start; }
.admin-main:has(> .stat-cards) .settings-section .settings-card:hover,
.admin-main:has(> .stat-cards) .stat-card:hover { border-color: #a9c9f4; background: #f3f8ff; box-shadow: 0 4px 12px rgba(40, 89, 155, .08); }
.admin-main:has(> .stat-cards) .stat-card-alert { background: #fff; border-left: 4px solid var(--brand); }
.admin-main:has(> .stat-cards) .quick-links .button.secondary { background: #fff; border-color: var(--border); color: var(--ink); }
.admin-main:has(> .stat-cards) .quick-links .button.secondary:hover { background: #eef5ff; border-color: #a9c9f4; }

@media (max-width: 640px) {
    .admin-shell form.product-editor,
    .admin-shell form.stock-adjust-form { padding: 1rem; box-shadow: none; }
    .admin-shell .product-editor-fields { display: block; }
}

@media (min-width: 641px) and (max-width: 899px) {
    .admin-shell .product-editor-fields { display: block; }
    .admin-shell .order-customer-section > label,
    .admin-shell .order-delivery-section > label,
    .admin-shell .order-payment-section > label { max-width: none; }
    .admin-shell .order-customer-section > label input,
    .admin-shell .order-customer-section > label textarea,
    .admin-shell .order-delivery-section > label input,
    .admin-shell .order-delivery-section > label textarea,
    .admin-shell .order-payment-section > label input { max-width: none; }
    .admin-shell .desktop-only-table { overflow-x: auto; }
    .admin-shell .desktop-only-table .data-table { min-width: 860px; }
}

@media print {
    .admin-shell { background: #fff; }
    .admin-shell .admin-main { padding: 0; max-width: none; }
    .admin-shell .data-table,
    .admin-shell .entry-form-section { box-shadow: none; }
}

/* Blue actions and a restrained sky tint tie the workspace together. Data remains on white
   surfaces; the stronger header tint separates column labels from both canvas and rows. */
.admin-shell .admin-main:has(> .variant-tools-grid) { max-width: 1240px; }
.admin-shell .admin-main:has(> .variant-tools-grid) > .scroller {
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    box-shadow: 0 2px 12px rgba(41, 57, 84, .035);
}
.admin-shell .variant-manage-table {
    width: 100%;
    min-width: 900px;
    margin: 0;
    border: 0;
}
.admin-shell .variant-manage-table th,
.admin-shell .variant-manage-table td { border-color: var(--border-subtle); }
.admin-shell .variant-manage-table th {
    background: #e8f1fe;
    color: #344969;
    border-bottom-color: #cbdcf6;
}
.admin-shell .variant-manage-table tr.vm-row-alt:not(.muted) td { background: #f8faff; }
.admin-shell .variant-manage-table tbody tr:hover td { background: #eef5ff; }
.admin-shell .variant-tools-grid .entry-form-section { margin: 0; }
.admin-shell .variant-tools-grid .variant-bulk-controls-price { grid-template-columns: 1fr; }
.admin-shell .variant-tools-grid .variant-bulk-controls .button { justify-self: start; }
.admin-shell .variant-redefine-action .button.secondary { color: var(--brand); border-color: #bcd4f5; }
.admin-shell .variant-redefine-action .button.secondary:hover { color: #155fc4; }
.admin-shell .entry-form-section .inline-add-related,
.admin-shell .inline-add-related { color: var(--brand); }
.admin-shell .entry-form-section .inline-add-related:hover,
.admin-shell .inline-add-related:hover { color: #155fc4; }
.admin-shell .line-item-table th { background: #e8f1fe; color: #344969; }
.admin-shell .product-barcode-section .phone-pair-trigger,
.admin-shell .variant-barcode-panel .phone-pair-trigger { color: var(--brand); }
@media (max-width: 640px) {
    .admin-shell .variant-manage-table { width: auto; min-width: 0; }
    .admin-shell .variant-tools-grid .variant-bulk-controls .button { width: 100%; }
}

/* Product browsing: let photography and names lead, with blue reserved for buying and
   selection. WhatsApp retains its familiar green as a separate contact action. */
body:has(.storefront-shop-page),
body:has(.storefront-product-page) { background: #f8faff; }
.storefront-shop-page,
.storefront-product-page {
    --brand: #1a73e8;
    --ink: #202b3a;
    --muted: #607084;
    --border: #dce4ef;
    color: var(--ink);
}
.storefront-shop-page .storefront-shop-hero,
.storefront-product-page .storefront-detail-images,
.storefront-product-page .storefront-product-purchase-card {
    box-shadow: 0 8px 26px rgba(36, 68, 112, .055);
}
.storefront-shop-page .storefront-card {
    border-radius: 14px;
    box-shadow: 0 2px 10px rgba(36, 68, 112, .035);
}
.storefront-shop-page .storefront-card:hover { border-color: #a9c9f4; box-shadow: 0 8px 22px rgba(36, 93, 171, .11); }
.storefront-shop-page .storefront-card-price { color: #202b3a; }
.storefront-shop-page .storefront-card-media,
.storefront-shop-page .storefront-card-noimage,
.storefront-product-page .storefront-card-noimage.large,
.storefront-product-page .storefront-detail-image-button { background: #f1f6fc; }
.storefront-product-page .storefront-card-noimage.large { color: #9bafc8; }
.storefront-product-page .storefront-detail-price { color: var(--ink); letter-spacing: -.015em; }
.storefront-product-page .storefront-availability {
    display: inline-flex;
    width: fit-content;
    align-items: center;
    min-height: 1.9rem;
    margin: .25rem 0 .4rem;
    padding: .15rem .65rem;
    border-radius: 999px;
    font-size: .9rem;
}
.storefront-product-page .storefront-availability.in-stock { background: #eaf7ee; color: #247348; }
.storefront-product-page .storefront-availability.out-of-stock { background: #fcecec; color: #a72d2d; }
.storefront-product-page .storefront-product-purchase-card .button:not(.secondary):not(.whatsapp-btn),
.storefront-product-sticky-actions .button:not(.secondary):not(.whatsapp-btn) {
    background: #1a73e8;
    border-color: #1a73e8;
    color: #fff;
}
.storefront-product-page .storefront-product-purchase-card .button:not(.secondary):not(.whatsapp-btn):hover,
.storefront-product-sticky-actions .button:not(.secondary):not(.whatsapp-btn):hover { background: #155fc4; border-color: #155fc4; }
.storefront-product-sticky-actions .button.secondary { background: #eef5ff; border-color: #bad3f7; color: #155fc4; }
.storefront-product-sticky-actions .button.whatsapp-btn { background: #25d366; border-color: #25d366; color: #fff; }
.storefront-product-sticky-actions { --paper: #fff; --border: #dce4ef; }
.storefront-product-page .storefront-purchase-actions .button.secondary { background: #eef5ff; border-color: #bad3f7; color: #155fc4; }
.storefront-product-page .storefront-purchase-actions .button.secondary:hover,
.storefront-product-page .storefront-contact-actions .button.secondary:hover { background: #e3efff; border-color: #91baf0; }
.storefront-product-page .storefront-variant-chip.selected { background: #e8f0fe; border-color: #7aaaf0; color: #155fc4; }
.storefront-product-page .storefront-variant-chip.selected .storefront-variant-chip-price { color: #155fc4; }
.storefront-product-page .storefront-variant-chip.out-of-stock.selected { color: #155fc4; }
.storefront-product-page .storefront-product-purchase-card .storefront-availability {
    display: inline-flex;
    align-items: baseline;
    gap: .4rem;
    min-height: 0;
    margin: .3rem 0 .75rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    font-size: .9rem;
    font-weight: 500;
    line-height: 1.4;
}
.storefront-product-page .storefront-availability.in-stock,
.storefront-product-page .storefront-availability.out-of-stock { background: transparent; }
.storefront-product-page .storefront-availability::before {
    content: "";
    width: .48rem;
    height: .48rem;
    flex: 0 0 .48rem;
    margin-top: .37em;
    border-radius: 50%;
    background: currentColor;
}
.storefront-product-page .storefront-variant-chip,
.storefront-product-page .storefront-variant-chip.with-image { max-width: 100%; box-sizing: border-box; border-radius: 5px; }
.storefront-product-page .storefront-variant-chip-price { white-space: normal; }
.storefront-product-page .storefront-contact-actions { padding-top: .75rem; border-top: 1px solid var(--border); }
.storefront-product-page .storefront-contact-actions .whatsapp-btn { background: #25d366; border-color: #25d366; color: #fff; }

/* Shared interaction states. The soft dashboard hover is the reference for actions in
   tables, popovers, product tabs, and optional tools throughout the admin area. */
.admin-shell .row-menu-panel { background: #fff; border-color: var(--border); }
.admin-shell .row-menu-trigger:hover,
.admin-shell .row-icon-btn:hover,
.admin-shell .export-menu-item:hover,
.admin-shell .nav-dropdown-item:hover,
.admin-shell .record-row .row-menu-trigger:hover,
.admin-shell .record-row .row-menu-trigger:active,
.admin-shell .mobile-sheet-item:hover,
.admin-shell .mobile-sheet-item:active { background: #eef5ff; border-color: #a9c9f4; color: #155fc4; }
.admin-shell .row-menu-item:hover,
.admin-shell .row-menu-item:focus-visible { background: #eef5ff; color: #155fc4; }
.admin-shell .row-menu-item-danger:hover,
.admin-shell .row-menu-item-danger:focus-visible { background: #eef5ff; color: var(--due); }
.admin-shell .record-row:has(.row-menu-panel) { background: #eef5ff; }
.admin-shell .admin-main .dashboard-group .quick-links > a.button.secondary {
    background: #fff;
    border-color: var(--border);
    color: var(--ink);
}
.admin-shell .admin-main .dashboard-group .quick-links > a.button.secondary:hover,
.admin-shell .admin-main .dashboard-group .quick-links > a.button.secondary:focus-visible {
    background: #eef5ff;
    border-color: #a9c9f4;
    color: #155fc4;
}
.admin-shell .admin-main .dashboard-group .quick-links > a.quick-sale-link.button.secondary {
    background: #eef5ff;
    border-color: #a9c9f4;
    color: #155fc4;
    font-weight: 600;
    text-decoration: none;
}
.admin-shell .admin-main .dashboard-group .quick-links > a.quick-sale-link.button.secondary:hover,
.admin-shell .admin-main .dashboard-group .quick-links > a.quick-sale-link.button.secondary:focus-visible {
    background: #dcecff;
    border-color: #80b3f6;
    color: #104fa6;
}
.admin-shell .voice-section-summary,
.admin-shell .landing-voice-demo .voice-section-summary {
    background: #f3f8ff;
    border-color: #d3e4fb;
    color: #155fc4;
}
.admin-shell .voice-section-summary:hover,
.admin-shell .landing-voice-demo .voice-section-summary:hover { background: #e8f0fe; border-color: #a9c9f4; }
.admin-shell .voice-section { background: #f5f9ff; border-color: #d3e4fb; box-shadow: none; }
.admin-shell .voice-tool-panel .voice-section { background: #fff; border: 0; box-shadow: none; }
.admin-shell .admin-form-heading {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: .6rem 1rem;
    margin: 0 0 1rem;
}
.admin-shell .admin-form-heading h1 {
    position: relative;
    top: .5rem;
    min-width: 0;
    margin: 0;
}
.admin-shell .admin-form-heading > .voice-tool { justify-self: end; margin: 0; }
@media (max-width: 640px) {
    .voice-tool-panel { width: 100%; }
    .voice-tool-panel-header { padding: .75rem 1rem; }
    .voice-tool-panel .voice-section { padding: 1rem; }
}
@media (max-width: 640px) {
    .admin-shell .admin-main .dashboard-group .quick-links { gap: .5rem; background: transparent; border: 0; overflow: visible; }
    .admin-shell .admin-main .dashboard-group .quick-links > a.button { border: 1px solid var(--admin-primary); border-radius: 9px; }
    .admin-shell .admin-main .dashboard-group .quick-links > a.button:not(.secondary) { background: var(--admin-primary); color: #fff; }
    .admin-shell .admin-main .dashboard-group .quick-links > a.button:not(.secondary)::after { border-color: #fff; }
    .admin-shell .admin-main .dashboard-group .quick-links > a.quick-sale-link.button.secondary { border-color: #a9c9f4; border-radius: 9px; }
    .admin-shell .admin-main .dashboard-group .quick-links > a.quick-sale-link.button.secondary::after { border-color: #155fc4; }
}
/* Public discovery and landing share the same neutral canvas as the product page. */
body:has(.browse-filter-pills) { background: #f8faff; }
body:has(.landing-page) { background: #fff; }
.site-footer { background: #f2f6fc; }
.site-header-sticky { background: #fff; }
.landing-nav a:hover,
.landing-nav-login:hover,
.landing-nav-cta.button:hover { background: #eef5ff; color: #155fc4; }
.landing-page .button:not(.secondary):hover,
.landing-search button:hover { background: #155fc4; border-color: #155fc4; }
.site-header-icon:hover,
.site-header-dropdown-panel a:hover,
.browse-filter-pill:hover,
.district-combobox-results button:hover,
.district-combobox-results button:focus-visible,
.customer-combobox-results button:hover,
.customer-combobox-results button:focus-visible { background: #eef5ff; }
.browse-filter-pill.has-value { background: #e8f0fe; }
.storefront-card { border-radius: 14px; box-shadow: 0 2px 10px rgba(36, 68, 112, .035); }
.storefront-card:hover { border-color: #a9c9f4; box-shadow: 0 8px 22px rgba(36, 93, 171, .11); }
.storefront-card-media,
.storefront-card-noimage { background: #f1f6fc; }
.storefront-card-price { color: var(--ink); }
.storefront-card-price.contact-price,
.storefront-shop-page .storefront-card-price.contact-price {
    display: block;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    -webkit-line-clamp: unset;
    font-size: .84rem;
    font-weight: 600;
    line-height: 1.4;
}
.storefront-card .storefront-availability-tag.out-of-stock {
    display: inline-flex;
    align-items: baseline;
    gap: .35rem;
    width: fit-content;
    margin-top: .45rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: #a32933;
    font-size: .76rem;
    line-height: 1.4;
}
.storefront-card .storefront-availability-tag.out-of-stock::before {
    content: "";
    width: .43rem;
    height: .43rem;
    flex: 0 0 .43rem;
    margin-top: .35em;
    border-radius: 50%;
    background: currentColor;
}
@media (max-width: 640px) {
    .storefront-card-price.contact-price,
    .storefront-shop-page .storefront-card-price.contact-price { font-size: .8rem; }
}
.storefront-shop-card { border-radius: 14px; box-shadow: 0 2px 10px rgba(36, 68, 112, .035); }
.storefront-shop-card:hover { border-color: #a9c9f4; box-shadow: 0 8px 22px rgba(36, 93, 171, .11); }
.landing-hero-split::before { background: radial-gradient(closest-side, rgba(26, 115, 232, .12), rgba(26, 115, 232, .035) 55%, transparent 100%); }
.landing-page .button:not(.secondary) { background-image: none; box-shadow: 0 2px 8px rgba(26, 115, 232, .12); }
.landing-phone { background: #24344a; box-shadow: 0 30px 70px rgba(36, 68, 112, .16); }
.landing-feature-icon { background: #e8f0fe; border-radius: 10px; }
.landing-voice-step-number { background: #e8f0fe; }
.landing-voice-recording-sample { background: #f3f8ff; border-color: #d3e4fb; }
.landing-voice-demo .voice-section-summary:hover { background: #eef5ff; }

/* Settings hub and category forms use a centered workspace, white cards, and the same
   sky accent as navigation. The old peach fill no longer competes with field labels. */
.admin-shell .admin-main:has(> .settings-page-heading) { max-width: 1120px; }
.admin-shell .settings-page-heading { margin-bottom: 1.4rem; }
.admin-shell .settings-page-heading h1 { font-size: clamp(1.65rem, 2.4vw, 2rem); line-height: 1.3; }
.admin-shell .settings-hub-intro { margin: .35rem 0 0; color: var(--muted); line-height: 1.5; }
.admin-shell .settings-hub-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    width: 100%;
    max-width: none;
}
.admin-shell .settings-hub-row {
    min-height: 8rem;
    box-sizing: border-box;
    padding: 1.3rem 1.45rem;
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    box-shadow: 0 2px 12px rgba(41, 57, 84, .035);
    gap: 1rem;
}
.admin-shell .settings-hub-row:hover,
.admin-shell .settings-hub-row:focus-visible {
    background: #f3f8ff;
    border-color: #a9c9f4;
    box-shadow: 0 6px 20px rgba(36, 93, 171, .08);
}
.admin-shell .settings-hub-row:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc((100% - 1rem) / 2);
    justify-self: center;
}
.admin-shell .settings-hub-row-text strong { font-size: 1.12rem; line-height: 1.35; }
.admin-shell .settings-hub-row-text span { line-height: 1.5; margin-top: .25rem; }
.admin-shell .settings-hub-row-chevron { color: #7890ad; }
.admin-shell .settings-group-icon {
    width: 2.8rem;
    height: 2.8rem;
    border-radius: 11px;
    background: #e8f0fe;
    color: #1a73e8;
}
.admin-shell .settings-form { width: 100%; max-width: none; margin-inline: auto; }
.admin-shell .settings-group { max-width: none; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: 1.5rem; padding: 1.5rem 0; }
.admin-shell .settings-group-card {
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    box-shadow: 0 2px 12px rgba(41, 57, 84, .035);
}
.admin-shell .settings-toggle { background: #f3f8ff; border: 1px solid #e1eafa; }
.admin-shell .settings-form .settings-save-bar { background: #f8faff; }
@media (max-width: 900px) {
    .admin-shell .settings-group { grid-template-columns: minmax(0, 1fr); gap: .8rem; }
}
@media (max-width: 720px) {
    .admin-shell .settings-hub-list { grid-template-columns: minmax(0, 1fr); gap: .75rem; }
    .admin-shell .settings-hub-row { min-height: 6.5rem; padding: 1rem; }
    .admin-shell .settings-hub-row:last-child:nth-child(odd) { grid-column: auto; width: 100%; }
}

/* Leave room for the status and separate advance line in the orders table. */
.admin-shell .order-list-table .data-table th:nth-child(6),
.admin-shell .order-list-table .data-table td:nth-child(6) { min-width: 10.5rem; }
.admin-shell .order-list-table .order-advance-badge { margin-top: .2rem; }
.admin-shell .order-list-table td:nth-child(6) .muted.small { font-size: .76rem; line-height: 1.4; }

/* Keep the aligned action slot compact so the menu remains visible at desktop widths. */
.admin-shell .order-list-table .data-table th:last-child,
.admin-shell .order-list-table .data-table td:last-child { width: 13rem; min-width: 13rem; }
.admin-shell .order-list-table .order-actions-row {
    justify-content: flex-end;
    align-items: center;
    gap: .35rem;
    white-space: nowrap;
}
.admin-shell .order-list-table .order-actions-row > .button {
    width: 10rem;
    flex: 0 0 10rem;
    height: 36px;
    box-sizing: border-box;
    margin: 0;
    padding-inline: .35rem;
    font-size: .86rem;
}
.admin-shell .order-list-table .order-actions-row > .row-menu {
    display: flex;
    align-items: center;
    flex: 0 0 36px;
    height: 36px;
    margin: 0;
}
.admin-shell .order-list-table .order-actions-row .row-menu-trigger.compact {
    width: 36px;
    min-width: 36px;
    height: 36px;
    margin: 0;
    box-sizing: border-box;
}

/* At desktop width, the six quick actions use one compact, equal-width row. */
@media (min-width: 1100px) {
    .admin-shell .admin-main:has(> .stat-cards) .quick-links {
        display: flex;
        flex-wrap: nowrap;
        gap: .6rem;
    }
    .admin-shell .admin-main:has(> .stat-cards) .quick-links > a.button {
        flex: 1 1 0;
        min-width: 0;
        min-height: 2.9rem;
        box-sizing: border-box;
        justify-content: center;
        margin: 0;
        padding: .45rem .35rem;
        font-size: .85rem;
        text-align: center;
        white-space: nowrap;
    }
}

/* Shared report styling; the profit summary uses the narrower form reading width below. */
.admin-shell .admin-main:has(> .report-header) { max-width: 1180px; }
.admin-shell .admin-main:has(> .report-profit-header) { max-width: 800px; }
.admin-shell .admin-main:has(> .report-header) .report-header {
    margin: .4rem 0 1rem;
    padding: 1.2rem 1.4rem;
    background: #fff;
    border: 1px solid #dce5f1;
    border-radius: 14px;
    box-shadow: 0 2px 12px rgba(31, 53, 84, .035);
}
.admin-shell .admin-main:has(> .report-header) .report-shop-name {
    color: #1f3554;
    font-size: clamp(1.2rem, 2vw, 1.5rem);
    line-height: 1.3;
}
.admin-shell .admin-main:has(> .report-header) .report-title {
    margin-top: .2rem;
    color: #344969;
    font-size: 1.05rem;
    font-weight: 600;
}
.admin-shell .admin-main:has(> .report-header) .report-period { color: #5d6d83; font-size: .85rem; }
.admin-shell .admin-main:has(> .report-header) .report-range-bar {
    background: #fff;
    border-color: #dce5f1;
    border-radius: 14px;
    box-shadow: 0 2px 12px rgba(31, 53, 84, .03);
}
.admin-shell .admin-main:has(> .report-header) .report-range-copy strong { color: #1f3554; }
.admin-shell .admin-main:has(> .report-header) .report-tabs {
    gap: .25rem;
    border-bottom-color: #dce5f1;
}
.admin-shell .admin-main:has(> .report-header) .tab-button {
    background: transparent;
    border-radius: 0;
    color: #5d6d83;
    font-weight: 500;
}
.admin-shell .admin-main:has(> .report-header) .tab-button:hover:not(.active) { background: #f3f7fc; color: #1f3554; }
.admin-shell .admin-main:has(> .report-header) .tab-button.active {
    background: transparent;
    border-bottom-color: #1a73e8;
    color: #155fc4;
    font-weight: 600;
}
.admin-shell .admin-main:has(> .report-header) .stat-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: .8rem;
    margin: 1rem 0 1.4rem;
}
.admin-shell .admin-main:has(> .report-header) .stat-card {
    min-width: 0;
    padding: 1rem 1.15rem;
    background: #fff;
    border: 1px solid #dce5f1;
    border-radius: 12px;
    box-shadow: 0 2px 10px rgba(31, 53, 84, .025);
}
.admin-shell .admin-main:has(> .report-header) .stat-card-hero {
    background: #edf5ff;
    border-color: #b8d3f6;
}
.admin-shell .admin-main:has(> .report-header) .stat-label { color: #5d6d83; line-height: 1.4; }
.admin-shell .admin-main:has(> .report-header) .stat-value { color: #1f3554; font-size: 1.4rem; line-height: 1.3; }
.admin-shell .admin-main:has(> .report-header) .stat-card-hero .stat-label,
.admin-shell .admin-main:has(> .report-header) .stat-card-hero .stat-value { color: #1f3554; }
.admin-shell .admin-main:has(> .report-header) .data-table thead th { background: #e8f0fe; color: #344969; }
.admin-shell .admin-main:has(> .report-header) .detail-section { border-top-color: #dce5f1; }
.admin-shell .admin-main:has(> .report-header) .detail-section h2 { color: #1f3554; }
@media screen {
    .admin-shell .admin-main:has(> .report-header) #product-profit-table { display: none !important; }
    .admin-shell .admin-main:has(> .report-header) #product-profit-cards .data-card { display: block !important; }
}

/* Customer pages share the landing page's white canvas. Neutral icon containers use
   a quiet sky fill; amber remains reserved for payments that need attention. */
body:has(.site-header):not(:has(.admin-shell)) { background: #fff; }
.storefront-page:has(.my-orders-page-header) .my-orders-account-avatar,
.storefront-page:has(.my-orders-page-header) .my-orders-shop-icon,
.cart-page .cart-summary-card-icon,
.cart-page .cart-shop-card-icon {
    background: #eaf2ff;
    color: #1a73e8;
}
.storefront-page:has(.my-orders-page-header) .my-orders-tab.active .my-orders-tab-count,
.cart-page .cart-count-pill { background: #eaf2ff; color: #155fc4; }

/* Give each order stage a recognisable colour in both owner and customer views. */
.status-badge-confirmed { color: #1a73e8; }
.status-badge-processing { color: #7051a3; }
.status-badge-shipped { color: #007f76; }

/* Customer orders read as a compact list within each shop, with one clear hierarchy. */
.storefront-page:has(.my-orders-page-header) .my-orders-account-card { border-radius: 12px; }
.storefront-page:has(.my-orders-page-header) .my-orders-shop-group {
    background: #f8fbff;
    border-color: #dce4ef;
    padding: 1rem;
}
.storefront-page:has(.my-orders-page-header) .my-orders-shop-group + .my-orders-shop-group { margin-top: 1rem; }
.storefront-page:has(.my-orders-page-header) .my-orders-shop-header { margin-bottom: .75rem; }
.storefront-page:has(.my-orders-page-header) .my-orders-shop-group .record-card-list { margin: 0; gap: .65rem; }
.storefront-page:has(.my-orders-page-header) .my-orders-shop-group .record-card {
    background: #fff;
    border-color: #dce4ef;
    border-radius: 12px;
    padding: .9rem 1rem;
}
.storefront-page:has(.my-orders-page-header) .my-order-row {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    align-items: start;
    gap: .75rem;
}
.storefront-page:has(.my-orders-page-header) .my-order-info { min-width: 0; }
.storefront-page:has(.my-orders-page-header) .my-order-due { color: #344969; }
.storefront-page:has(.my-orders-page-header) .my-order-meta-line { flex-wrap: wrap; gap: .2rem .5rem; line-height: 1.35; }
.storefront-page:has(.my-orders-page-header) .my-order-advance-todo {
    background: #f1f7ff;
    border: 1px solid #cfe1f8;
    color: #27496f;
    padding: .45rem .65rem;
}
.storefront-page:has(.my-orders-page-header) .order-progress { margin-top: .8rem; }
.storefront-page:has(.my-orders-page-header) .order-progress li { padding-top: .85rem; }
.storefront-page:has(.my-orders-page-header) .order-progress li::before { height: 3px; }
.storefront-page:has(.my-orders-page-header) .order-progress li.done::before { background: #a8c9f5; }
.storefront-page:has(.my-orders-page-header) .order-progress li.current::before { background: #1a73e8; }
.storefront-page:has(.my-orders-page-header) .my-order-shipment { background: #f3f7fc; }
@media (max-width: 640px) {
    .storefront-page:has(.my-orders-page-header) .my-order-row { grid-template-columns: 44px minmax(0, 1fr); }
    .storefront-page:has(.my-orders-page-header) .my-order-due { grid-column: 2; }
    .storefront-page:has(.my-orders-page-header) .my-orders-shop-group { padding: .75rem; }
}

/* Keep table labels and dates legible without hiding any column on tablet. */
@media (min-width: 641px) {
    .admin-shell .desktop-only-table { overflow-x: auto; }
    .admin-shell .desktop-only-table .data-table thead th { white-space: nowrap; }
    .admin-shell .sales-list-table .data-table,
    .admin-shell .order-list-table .data-table { min-width: 1050px; }
    .admin-shell .sales-list-table .data-table td:nth-child(7),
    .admin-shell .order-list-table .data-table td:nth-child(7) {
        white-space: nowrap;
        font-size: .82rem;
        font-variant-numeric: tabular-nums;
    }
}
@media (max-width: 640px) {
    .admin-shell .admin-main:has(> .report-header) .report-header { padding: 1rem; }
    .admin-shell .admin-main:has(> .report-header) .stat-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .admin-shell .admin-main:has(> .report-header) .stat-card-hero { grid-column: 1 / -1; }
}
@media print {
    .admin-shell .admin-main:has(> .report-header) { max-width: none; }
    .admin-shell .admin-main:has(> .report-header) #product-profit-table { display: table !important; }
    .admin-shell .admin-main:has(> .report-header) #product-profit-cards { display: none !important; }
    .admin-shell .admin-main:has(> .report-header) .report-header {
        margin: 0 0 1rem;
        padding: 0 0 .75rem;
        border: 0;
        border-bottom: 1px solid #dce5f1;
        border-radius: 0;
        box-shadow: none;
    }
    .admin-shell .admin-main:has(> .report-header) .stat-card { box-shadow: none; }
}

/* A variant is an editable record on a phone. Keep every field in view instead of
   shrinking seven table columns and hiding the price control. */
@media (max-width: 640px) {
    .admin-shell .admin-main:has(> .variant-tools-grid) > .scroller {
        overflow: visible;
        width: 100%;
        box-sizing: border-box;
        background: transparent;
        border: 0;
        box-shadow: none;
    }
    .admin-shell .line-item-table.variant-manage-table {
        display: block;
        width: 100%;
        min-width: 0;
    }
    .admin-shell .variant-manage-table thead { display: none; }
    .admin-shell .variant-manage-table tbody {
        display: grid;
        gap: .75rem;
    }
    .admin-shell .variant-manage-table tbody tr {
        display: grid;
        grid-template-columns: 3.25rem minmax(0, 1fr) auto;
        grid-template-areas:
            "image name name"
            "stock stock stock"
            "price price price"
            "barcode barcode barcode"
            "status status action";
        gap: .55rem .7rem;
        width: 100%;
        min-width: 0;
        padding: .85rem;
        box-sizing: border-box;
        background: #fff;
        border: 1px solid var(--border-subtle);
        border-radius: 12px;
        box-shadow: 0 2px 8px rgba(41, 57, 84, .035);
    }
    .admin-shell .variant-manage-table tbody td,
    .admin-shell .variant-manage-table tbody td:nth-child(4) {
        display: block;
        width: auto;
        min-width: 0;
        padding: 0;
        border: 0;
        background: transparent;
        white-space: normal;
        overflow-wrap: anywhere;
    }
    .admin-shell .variant-manage-table tbody tr:hover td,
    .admin-shell .variant-manage-table tbody tr.vm-row-alt:not(.muted) td { background: transparent; }
    .admin-shell .variant-manage-table td:nth-child(1) { grid-area: name; font-weight: 600; }
    .admin-shell .variant-manage-table td:nth-child(2) { grid-area: image; }
    .admin-shell .variant-manage-table td:nth-child(3) { grid-area: stock; display: flex !important; align-items: center; justify-content: space-between; gap: .5rem; }
    .admin-shell .variant-manage-table td:nth-child(4) { grid-area: price; }
    .admin-shell .variant-manage-table td:nth-child(5) { grid-area: barcode; }
    .admin-shell .variant-manage-table td:nth-child(6) { grid-area: status; align-self: center; }
    .admin-shell .variant-manage-table td:nth-child(7) { grid-area: action; text-align: right; }
    .admin-shell .variant-manage-table td:nth-child(3),
    .admin-shell .variant-manage-table td:nth-child(4),
    .admin-shell .variant-manage-table td:nth-child(5) {
        padding-top: .55rem;
        border-top: 1px solid var(--border-subtle);
    }
    .admin-shell .variant-manage-table td:nth-child(3)::before,
    .admin-shell .variant-manage-table td:nth-child(4)::before,
    .admin-shell .variant-manage-table td:nth-child(5)::before {
        content: attr(data-label);
        display: block;
        margin-bottom: .35rem;
        color: var(--muted);
        font-size: .78rem;
        font-weight: 600;
    }
    .admin-shell .variant-manage-table td:nth-child(3)::before { margin: 0; }
    .admin-shell .variant-manage-table .vm-label { display: inline; }
    .admin-shell .variant-manage-table .status-badge { display: none; }
    .admin-shell .variant-manage-table .inline-actions { flex-wrap: wrap; }
    .admin-shell .variant-manage-table td:nth-child(1) .inline-actions { margin-top: 0; align-items: center; }
    .admin-shell .variant-manage-table td:nth-child(1) input[type="text"] {
        width: 100%;
        max-width: none;
        flex: 1 1 100%;
    }
    .admin-shell .variant-manage-table td:nth-child(2) .inline-actions { margin-top: 0; }
    .admin-shell .variant-manage-table .vm-image-edit { display: none; }
    .admin-shell .variant-manage-table .variant-image-cell,
    .admin-shell .variant-manage-table .variant-image-thumb { width: 3.25rem; height: 3.25rem; }
    .admin-shell .variant-manage-table td:nth-child(3) .inline-actions { flex-wrap: nowrap; margin: 0; }
    .admin-shell .variant-manage-table td:nth-child(4) .inline-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem; margin-top: 0; }
    .admin-shell .variant-manage-table td:nth-child(4) input[type="number"]:not([readonly]):not([disabled]):not([hidden]):not([multiple]) {
        width: 100% !important;
        max-width: none !important;
        min-width: 0;
    }
    .admin-shell .variant-manage-table td:nth-child(4) .button { min-height: 2.75rem; }
    .admin-shell .variant-manage-table .variant-barcode-cell { min-width: 0; }
    .admin-shell .variant-manage-table .barcode-editor,
    .admin-shell .variant-manage-table .barcode-editor-add,
    .admin-shell .variant-manage-table .barcode-input-row { max-width: 100%; min-width: 0; }
    .admin-shell .variant-manage-table .barcode-chip { max-width: 100%; box-sizing: border-box; white-space: normal; }
    .admin-shell .variant-manage-table .barcode-chip-code { min-width: 0; overflow-wrap: anywhere; }
    .admin-shell .variant-manage-table td:nth-child(6) .vm-status { white-space: nowrap; }
    .admin-shell .variant-manage-table td:nth-child(7) .button { white-space: normal; }
}

/* Public landing page: a compact, consistent path from the first sale to pricing. */
.landing-page { max-width: 1200px; padding: 2rem 1.25rem 4rem; }
.landing-hero-split {
    min-height: 570px;
    grid-template-columns: minmax(0, 1.12fr) minmax(320px, .88fr);
    gap: clamp(1.5rem, 4vw, 4rem);
    padding: clamp(1.5rem, 4vw, 3.5rem);
    border: 1px solid #dce9fb;
    border-radius: 30px;
    background: linear-gradient(115deg, #f7fbff 0%, #edf5ff 100%);
}
.landing-hero-split::before { right: -14%; background: radial-gradient(closest-side, rgba(26, 115, 232, .14), transparent 70%); }
.landing-hero-copy { position: relative; z-index: 1; }
.landing-hero-eyebrow { display: inline-flex; align-items: center; gap: .55rem; margin-bottom: 1.15rem; color: #1459b3; font-size: .9rem; }
.landing-eyebrow-dot { width: 8px; height: 8px; border-radius: 50%; background: #f08b28; box-shadow: 0 0 0 5px #ffead6; }
.landing-hero-copy h1 { max-width: 710px; color: #162d4e; font-size: clamp(2.3rem, 4.25vw, 4.15rem); line-height: 1.17; letter-spacing: -.025em; }
.landing-hero-copy h1 span { color: #1769d2; }
.landing-hero-sub { max-width: 570px; margin-top: 1.25rem; color: #506781; font-size: clamp(1rem, 1.3vw, 1.15rem); line-height: 1.75; }
.landing-hero-cta { gap: 1rem; margin-top: 1.7rem; }
.landing-hero-cta .button { display: inline-flex; align-items: center; gap: .6rem; min-height: 52px; border-radius: 12px; box-shadow: 0 10px 22px rgba(26, 115, 232, .19) !important; }
.landing-hero-cta .button .icon { width: 1em; height: 1em; }
.landing-hero-login { margin: 0; }
.landing-hero-cta-main { display: flex; flex-direction: column; align-items: stretch; }
.landing-hero-note { margin-top: .45rem; text-align: center; color: var(--muted); font-size: .85rem; line-height: 1.4; }
.landing-trust { flex-direction: row; flex-wrap: wrap; gap: .55rem 1.1rem; margin-top: 1.7rem; font-size: .82rem; }
.landing-trust li { white-space: nowrap; }
.landing-trust .icon { color: #1673d8; }
.landing-phone-wrap { align-self: center; padding: 1.1rem 0; }
.landing-section { margin-top: clamp(3.5rem, 6vw, 5.5rem); }
.landing-section h2 { margin-bottom: 1.5rem; color: #172e4f; font-size: clamp(1.65rem, 2.7vw, 2.4rem); }
.landing-section-heading { display: flex; align-items: end; justify-content: space-between; gap: 2rem; margin-bottom: 1.45rem; }
.landing-section-heading h2 { margin-bottom: 0; }
.landing-section-heading > p { max-width: 340px; margin: 0 0 .15rem; color: #627890; font-size: .94rem; line-height: 1.6; }
.landing-features { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .9rem; }
.landing-feature { min-width: 0; min-height: 166px; gap: .9rem; padding: 1.3rem; border: 1px solid #e0e9f5; border-radius: 18px; background: #fff; box-shadow: 0 6px 22px rgba(27, 67, 115, .035); transition: transform .18s ease, box-shadow .18s ease; }
.landing-feature:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(27, 67, 115, .08); }
.landing-feature-icon { width: 42px; height: 42px; border-radius: 12px; }
.landing-feature h3 { color: #1b3554; font-size: 1.02rem; line-height: 1.45; }
.landing-feature p { margin-top: .45rem; color: #62748a; font-size: .9rem; line-height: 1.65; }
.landing-more { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: 1.1rem; }
.landing-more-label { color: #1b3554; font-weight: 600; font-size: .92rem; }
.landing-more-chip { padding: .3rem .8rem; border: 1px solid #d7e7fa; border-radius: 999px; background: #f4f9ff; color: #1b3554; font-size: .88rem; }
#how-it-works { padding: clamp(1.4rem, 3vw, 2.3rem); border: 1px solid #dce9fb; border-radius: 24px; background: #f5f9ff; }
#how-it-works h2 { margin-bottom: 1.7rem; }
.landing-steps { gap: 1rem; }
.landing-step { padding: 1.1rem; border: 1px solid #e0eaf6; border-radius: 16px; background: #fff; }
.landing-step-number { width: 36px; height: 36px; background: #e8f2ff; color: #1769d2; font-size: 1rem; }
.landing-step-title { color: #1b3554; }
.landing-step p { margin-top: .3rem; color: #61768d; line-height: 1.6; }
#pricing { scroll-margin-top: 90px; }
#benefits { scroll-margin-top: 90px; }
.landing-pricing-teaser { position: relative; overflow: hidden; display: block; padding: clamp(1.4rem, 3.4vw, 2.2rem); border: 0; border-radius: 22px; background: radial-gradient(circle at 100% 0%, #2f86e8 0, transparent 45%), linear-gradient(120deg, #123a73 0%, #1767c9 100%); color: #fff; }
.landing-pricing-teaser::after { content: ""; position: absolute; width: 190px; height: 190px; right: -90px; bottom: -110px; border: 30px solid rgba(255, 166, 64, .28); border-radius: 50%; pointer-events: none; }
.landing-pricing-teaser > * { position: relative; z-index: 1; }
.landing-pricing-kicker { display: inline-block; margin: 0 0 .8rem; padding: .2rem .8rem; border-radius: 999px; background: rgba(255, 255, 255, .16); color: #ffd9a8; font-size: .9rem; font-weight: 700; }
.landing-pricing-teaser h2 { margin: 0; color: #fff; font-size: clamp(1.6rem, 3.6vw, 2.6rem); line-height: 1.3; font-weight: 800; }
.landing-pricing-text { max-width: 760px; margin: 1rem 0 0; color: #e3efff; font-size: 1rem; line-height: 1.7; }
.landing-pricing-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 1.5rem; }
.landing-pricing-more { margin: .3rem 1rem .3rem 0; color: #cfe3ff; font-size: 1rem; text-decoration: underline; text-underline-offset: .2em; }
.landing-pricing-more:hover { color: #fff; }
.landing-pricing-link { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; min-height: 48px; padding: .55rem 1.5rem; border: 0; border-radius: 999px; background: #fff; color: #0f4fa8; font-weight: 700; text-decoration: none; white-space: nowrap; box-shadow: 0 8px 20px rgba(8, 31, 70, .25); }
.landing-pricing-link:hover { background: #fff3e2; }
.landing-pricing-link .icon { width: 1em; height: 1em; margin-left: .55rem; }
.landing-faq-list { max-width: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .65rem 1.5rem; align-items: start; }
.landing-faq-list details { min-width: 0; padding: .7rem 1rem; border: 1px solid #e1e9f4; border-radius: 12px; background: #fff; }
.landing-faq-list summary { color: #1d3653; font-weight: 700; }
.landing-faq-list details p { margin-left: .1rem; line-height: 1.7; }
.landing-cta-section { max-width: none; margin-top: 4rem; padding: 2.5rem 1.5rem; border: 0; border-radius: 23px; background: linear-gradient(110deg, #163d78, #1766c6); color: #fff; }
.landing-cta-section h2 { margin: 0; color: #fff; }
.landing-cta-section .muted { max-width: 700px; margin: .65rem auto 1.2rem; color: #dceaff; line-height: 1.7; }
.landing-cta-section .button { background: #fff !important; border-color: #fff !important; color: #145dbb !important; box-shadow: none !important; }
.landing-cta-section .landing-hero-login, .landing-cta-section .landing-hero-login strong { color: #fff; }
@media (max-width: 900px) {
    .landing-hero-split { min-height: 0; grid-template-columns: minmax(0, 1fr) 280px; gap: 1.5rem; }
    .landing-features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .landing-section-heading > p { max-width: 290px; }
}
@media (max-width: 640px) {
    .landing-page { padding: .85rem .85rem 2.5rem; }
    .landing-hero-split { grid-template-columns: 1fr; gap: .5rem; padding: 1.5rem 1.1rem; border-radius: 21px; }
    .landing-hero-copy h1 { font-size: clamp(2rem, 8vw, 2.55rem); line-height: 1.2; }
    .landing-hero-sub { margin-top: .9rem; font-size: 1rem; }
    .landing-hero-cta { gap: .8rem; }
    .landing-trust { gap: .35rem .8rem; margin-top: 1.25rem; font-size: .78rem; }
    .landing-trust li { white-space: normal; }
    .landing-phone-wrap { padding: 1.2rem 0 0; }
    .landing-phone { box-sizing: border-box; width: 100%; max-width: 290px; height: 470px; padding: 10px; border-radius: 34px; background: #24344a; box-shadow: 0 18px 38px rgba(36, 68, 112, .16); transform: none; }
    .landing-phone::after { display: none; }
    .landing-phone-screen { height: 100%; border: 0; border-radius: 25px; background: #f7f9fd; box-shadow: none; }
    .landing-phone-head { padding: 1.1rem 1rem .65rem; }
    .landing-phone-chips { margin-bottom: 0; }
    .landing-phone-row, .landing-phone-voice { display: flex; }
    .landing-phone-voice { margin: auto .75rem 1rem; }
    .landing-section-heading { display: block; }
    .landing-section-heading > p { max-width: none; margin-top: .55rem; }
    .landing-features { grid-template-columns: 1fr; gap: .7rem; }
    .landing-feature { min-height: 0; padding: 1rem; }
    .landing-step { padding: 1rem; }
    .landing-pricing-teaser { padding: 1.2rem; }
    .landing-pricing-more { flex: 0 0 100%; margin: 0 0 .9rem; font-size: .92rem; }
    .landing-pricing-link { width: 100%; box-sizing: border-box; }
    .landing-faq-list { grid-template-columns: 1fr; gap: .55rem; }
    .landing-cta-section { padding: 2rem 1.1rem; }
}
@media (prefers-reduced-motion: reduce) {
    .landing-feature { transition: none; }
}

/* Public account and contact forms use the same centered card treatment as admin forms. */
.auth-page.public-form-card,
.legal-page.contact-page.public-form-card {
    box-sizing: border-box;
    width: calc(100% - 2rem);
    max-width: 36rem;
    margin: clamp(1.5rem, 4vw, 3rem) auto 3rem;
    padding: clamp(1.25rem, 3vw, 2.25rem);
    background: #fff;
    border: 1px solid var(--border-subtle);
    border-radius: 16px;
    box-shadow: 0 3px 18px rgba(40, 55, 82, .045);
}
.legal-page.contact-page.public-form-card { max-width: 44rem; }
.public-form-card h1 { margin: 0 0 1.25rem; }
.public-form-card > p.muted { line-height: 1.6; }
.public-form-card form { max-width: none; }
.public-form-card form > label { color: var(--ink); font-weight: 600; }
.public-form-card form > label input,
.public-form-card form > label textarea {
    width: 100%;
    max-width: none;
    min-height: 2.9rem;
    border-radius: 10px;
    background: #fff;
    font-weight: 400;
}
.public-form-card form > label textarea { min-height: 8rem; }
.public-form-card form > button[type=submit] { margin-top: .75rem; }
.auth-page.public-form-card .field-help {
    box-sizing: border-box;
    max-width: none;
    padding: .75rem 1rem;
    border: 1px solid #d4e5fa;
    border-radius: 10px;
    background: #f2f7ff;
    color: var(--muted);
    font-size: .9rem;
    font-style: normal;
    line-height: 1.55;
}
@media (max-width: 640px) {
    .auth-page.public-form-card,
    .legal-page.contact-page.public-form-card {
        width: calc(100% - 1.5rem);
        margin: 1rem auto 2rem;
        padding: 1.25rem;
    }
    .public-form-card form > button[type=submit] { width: 100%; }
}

/* Keep a direct route to store and product browsing on the landing page. The remaining
   mobile links live in one compact menu; the full desktop navigation is unchanged. */
.landing-mobile-browse,
.landing-mobile-menu,
.landing-mobile-trust,
.landing-hero-sub-mobile { display: none; }
@media (max-width: 640px) {
    .site-header-landing { position: relative; z-index: 600; padding: .45rem .75rem; gap: .4rem; }
    .site-header-landing .site-logo-icon { width: 75px; height: 44px; }
    .site-header-landing .landing-nav,
    .site-header-landing .landing-nav-actions { display: none; }
    .site-header-landing .landing-mobile-browse {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: .35rem;
        min-height: 44px;
        margin-left: auto;
        padding: 0 .55rem;
        border-radius: 10px;
        color: var(--ink);
        font-size: .9rem;
        font-weight: 650;
        text-decoration: none;
        white-space: nowrap;
    }
    .site-header-landing .landing-mobile-browse:hover,
    .site-header-landing .landing-mobile-browse:focus-visible { background: #eef5ff; color: #155fc4; }
    .site-header-landing .landing-mobile-menu { display: block; position: relative; }
    .site-header-landing .landing-mobile-menu > summary {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
        min-width: 44px;
        padding: 0;
        border-radius: 10px;
        color: var(--ink);
        font-size: .9rem;
        font-weight: 650;
        list-style: none;
        cursor: pointer;
        white-space: nowrap;
    }
    .site-header-landing .landing-mobile-menu > summary::-webkit-details-marker { display: none; }
    .site-header-landing .landing-mobile-menu > summary:hover,
    .site-header-landing .landing-mobile-menu > summary:focus-visible,
    .site-header-landing .landing-mobile-menu[open] > summary { background: #eef5ff; color: #155fc4; }
    .site-header-landing .landing-mobile-menu nav {
        position: absolute;
        top: calc(100% + .45rem);
        right: 0;
        box-sizing: border-box;
        width: min(18rem, calc(100vw - 1.5rem));
        padding: .45rem;
        border: 1px solid var(--border);
        border-radius: 14px;
        background: #fff;
        box-shadow: 0 14px 32px rgba(27, 48, 78, .15);
    }
    .site-header-landing .landing-mobile-menu nav a {
        display: flex;
        align-items: center;
        min-height: 44px;
        padding: .3rem .85rem;
        border-radius: 9px;
        color: var(--ink);
        text-decoration: none;
    }
    .site-header-landing .landing-mobile-menu nav a:hover,
    .site-header-landing .landing-mobile-menu nav a:focus-visible { background: #eef5ff; color: #155fc4; }

    .landing-page { padding: .6rem 1rem 2.5rem; }
    .landing-page .landing-hero-split {
        display: flex;
        flex-direction: column;
        gap: 0;
        min-height: 0;
        padding: 1.45rem 0 0;
        border: 0;
        border-radius: 0;
        background: transparent;
    }
    .landing-page .landing-hero-split::before { display: none; }
    .landing-page .landing-hero-eyebrow { padding-left: .4rem; }
    .landing-page .landing-hero-copy h1 { font-size: clamp(2rem, 8vw, 2.55rem); }
    .landing-page .landing-hero-sub-desktop,
    .landing-page .landing-trust { display: none; }
    .landing-page .landing-hero-sub-mobile { display: inline; }
    .landing-page .landing-hero-cta { margin-top: 1.4rem; }
    .landing-page .landing-phone-wrap { width: 100%; padding: 1.55rem 0 0; }
    .landing-page .landing-phone { max-width: 290px; }
    .landing-page .landing-phone-screen { box-shadow: none; }
    .landing-page .landing-mobile-trust { display: block; margin: 1.1rem 0 0; color: var(--muted); font-size: .78rem; text-align: center; line-height: 1.5; }
    .landing-page .landing-section { margin-top: 2.7rem; }
}

/* ===== How-to videos (VideoCard / VideoLink / VideoGuideGrid / js/help-video.js) =====
   The thumbnail ("poster") is drawn here in CSS, in the app's own blue palette, so it is crisp at any
   size, costs no image download, and nothing is requested from YouTube until someone taps play.
   Written for old phones too: no aspect-ratio / flex-gap / min(). */
.hv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); grid-gap: 16px; gap: 16px; }
.hv-card {
    display: block;
    padding: 10px;
    border: 1px solid #e0eaf6;
    border-radius: 18px;
    background: #fff;
    color: #1b3554;
    text-decoration: none;
    box-shadow: 0 6px 22px rgba(27, 67, 115, .035);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
    -webkit-tap-highlight-color: transparent;
}
.hv-card:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(27, 67, 115, .09); border-color: #a9c9f4; }
.hv-card-text { display: block; padding: 0 4px 4px; }
.hv-card-title { display: block; margin-top: 10px; font-size: .98rem; font-weight: 700; line-height: 1.4; color: #1b3554; }
.hv-card-sub { display: block; margin-top: 4px; font-size: .85rem; line-height: 1.5; color: #61768d; }

.hv-poster {
    position: relative;
    display: block;
    width: 100%;
    padding-top: 56.25%;               /* 16:9 box without aspect-ratio */
    overflow: hidden;
    border-radius: 12px;
    color: #fff;
    background:
        radial-gradient(circle at 88% 18%, rgba(255, 255, 255, .24), rgba(255, 255, 255, 0) 38%),
        radial-gradient(circle at 6% 112%, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 42%),
        linear-gradient(135deg, #1769d2, #3b8cff);
}
.hv-poster-first-product { background:
        radial-gradient(circle at 88% 18%, rgba(255, 255, 255, .24), rgba(255, 255, 255, 0) 38%),
        radial-gradient(circle at 6% 112%, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 42%),
        linear-gradient(135deg, #0b7f86, #22b8a6); }
.hv-poster-product-benefits { background:
        radial-gradient(circle at 88% 18%, rgba(255, 255, 255, .24), rgba(255, 255, 255, 0) 38%),
        radial-gradient(circle at 6% 112%, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 42%),
        linear-gradient(135deg, #4338ca, #7c6cf0); }
.hv-poster-how-to-sell { background:
        radial-gradient(circle at 88% 18%, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 38%),
        radial-gradient(circle at 6% 112%, rgba(255, 255, 255, .14), rgba(255, 255, 255, 0) 42%),
        linear-gradient(135deg, #12315a, #1a73e8); }
.hv-poster > span { position: absolute; display: block; }
.hv-poster-kicker {
    top: 11px; left: 12px;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .2);
    font-size: .72rem; font-weight: 700; letter-spacing: .01em;
}
.hv-poster-tag {
    top: 11px; right: 12px;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .28);
    font-size: .72rem; font-weight: 700;
}
.hv-poster-tag svg { margin-right: 3px; }
.hv-card.is-watched .hv-poster-tag { display: none !important; }
/* The big centred play button with a soft halo — the unmistakable "this is a video" cue. */
.hv-play {
    left: 50%; top: 50%;
    width: 56px; height: 56px;
    margin: -34px 0 0 -28px;
    border-radius: 50%;
    background: #fff;
    color: #1769d2;
    box-shadow: 0 0 0 8px rgba(255, 255, 255, .25), 0 8px 22px rgba(0, 0, 0, .28);
    text-align: center;
    transition: transform .18s ease;
}
.hv-play svg { margin-top: 17px; margin-left: 4px; }
.hv-card:hover .hv-play { transform: scale(1.1); }
.hv-poster-headline {
    left: 12px; right: 12px; bottom: 13px;
    font-size: 1rem; font-weight: 800; line-height: 1.25;
    text-shadow: 0 1px 8px rgba(0, 0, 0, .28);
}
.hv-watched {
    display: none !important;
    top: 11px; right: 12px;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    color: #137333;
    font-size: .7rem; font-weight: 700;
}
.hv-card.is-watched .hv-watched { display: block !important; }
.hv-card-cta { display: block; margin-top: 8px; color: #1769d2; font-size: .85rem; font-weight: 700; }
.hv-card-cta .icon { width: 16px; height: 16px; margin-right: 5px; vertical-align: -3px; }

/* Compact: a video-icon tile on the left, text on the right (register page, empty-state panels). */
.hv-card-compact { display: flex; align-items: center; padding: 10px 14px; }
.hv-compact-icon {
    display: flex; align-items: center; justify-content: center;
    flex: none;
    width: 40px; height: 40px;
    margin-right: 14px;
    border-radius: 14px;
    background: #e8f2ff;
    color: #1769d2;
}
.hv-compact-icon .icon { width: 24px; height: 24px; }
.hv-card-compact .hv-card-text { flex: 1; min-width: 0; padding: 0; }
.hv-card-compact .hv-card-title { margin-top: 0; font-size: .92rem; font-weight: 600; line-height: 1.45; }

.hv-chip {
    display: inline-flex;
    align-items: center;
    padding: 5px 12px;
    border: 1px solid #cfe0f7;
    border-radius: 999px;
    background: #eef5ff;
    color: #155fc4;
    font-size: .85rem; font-weight: 600;
    text-decoration: none;
}
.hv-chip:hover { background: #dcecff; border-color: #a9c9f4; }
.hv-chip .icon { width: 18px; height: 18px; margin-right: 6px; }
.hv-chip-row { margin: 0 0 12px; }
.hv-inline { margin: 12px 0; }
.hv-empty-videos { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); grid-gap: 12px; gap: 12px; margin-top: 18px; text-align: left; }
.hv-channel { margin: 14px 0 0; color: #61768d; font-size: .92rem; }
.hv-channel a { font-weight: 600; text-decoration: none; }
.hv-channel a:hover { text-decoration: underline; }
.hv-channel .icon { width: 14px; height: 14px; }

/* The in-app player (built by js/help-video.js). */
html.hv-open, html.hv-open body { overflow: hidden; }
.hv-overlay {
    position: fixed; top: 0; right: 0; bottom: 0; left: 0;
    z-index: 4000;
    display: flex; align-items: center; justify-content: center;
    background: rgba(10, 20, 35, .84);
}
.hv-player { position: relative; max-width: 100%; }
.hv-player-frame { overflow: hidden; border-radius: 14px; background: #000; box-shadow: 0 24px 60px rgba(0, 0, 0, .5); }
.hv-player-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.hv-player-close {
    position: absolute; top: -44px; right: 0;
    display: flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; padding: 0;
    border: 0; border-radius: 18px;
    background: rgba(255, 255, 255, .2);
    color: #fff;
    cursor: pointer;
}
.hv-player-close:hover { background: rgba(255, 255, 255, .32); }
@media print { .hv-grid, .hv-card, .hv-chip, .hv-overlay { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .hv-card, .hv-card:hover { transition: none; transform: none; } }

/* Video helper banner (VideoHint): the first-visit-hint look plus a tappable video icon. Kept compact. */
.video-hint { justify-content: flex-start; padding: .55rem .75rem; }
.video-hint-icon {
    display: flex; align-items: center; justify-content: center;
    flex: none;
    width: 32px; height: 32px;
    border-radius: 10px;
    background: #dcecff;
    color: #1769d2;
    text-decoration: none;
    transition: background .15s ease, transform .15s ease;
    -webkit-tap-highlight-color: transparent;
}
.video-hint-icon:hover { background: #c6dffe; transform: scale(1.05); }
.video-hint-icon .icon { width: 18px; height: 18px; }
.video-hint p { flex: 1 1 220px; line-height: 1.4; font-size: .85rem; }
.video-hint .first-visit-hint-actions { margin-left: auto; }
.video-hint .first-visit-hint-actions .button { box-sizing: border-box; min-height: 34px !important; height: auto; padding: .2rem .8rem !important; line-height: 1.3 !important; font-size: .85rem !important; }
@media (max-width: 640px) {
    /* Phones: icon + sentence on the first row, two equal compact buttons on the second. */
    .video-hint { padding: .5rem .65rem; }
    .video-hint p { flex: 1 1 0; min-width: 0; font-size: .82rem; }
    .video-hint .first-visit-hint-actions { flex: 0 0 100%; margin-left: 0; }
    .video-hint .first-visit-hint-actions .button { flex: 1 1 0; justify-content: center; }
}
/* Social links: footer icon row and the video guide's "follow us" line. */
.site-footer-social { display: flex; margin-top: 12px; }
.site-footer-social a {
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 38px;
    margin-right: 10px;
    border: 1px solid #d7e7fa;
    border-radius: 50%;
    background: #fff;
    color: #1769d2;
    text-decoration: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.site-footer-social a:hover { background: #1a73e8; border-color: #1a73e8; color: #fff; text-decoration: none; }
.site-footer-social .icon { width: 19px; height: 19px; }
.hv-social { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; margin-left: 6px; border-radius: 50%; vertical-align: middle; transition: background .15s ease; }
.hv-social:hover { background: #e8f2ff; text-decoration: none; }
.hv-social .icon { width: 22px; height: 22px; margin: 0; }

/* Pricing page: 2026 free-year copy (rate checklists, feature notes, Q&A list). */
/* Hero text pair: the lead is the main line, the note beneath it is smaller and quieter. Prefixed with .pricing-page to beat ".pricing-page p { margin-top: 0 }". */
.pricing-page .pricing-lead { max-width: 600px; margin: 0; color: #2c415b; font-size: 1.2rem; font-weight: 600; line-height: 1.6; }
.pricing-page .pricing-subnote { max-width: 600px; margin: 1.1rem 0 0; color: #5a7089; font-size: .95rem; font-weight: 400; line-height: 1.7; }
@media (max-width: 640px) { .pricing-page .pricing-lead { font-size: 1.08rem; } .pricing-page .pricing-subnote { font-size: .9rem; } }
.pricing-trust { margin: 1.1rem 0 0; color: #536980; font-size: .87rem; line-height: 1.6; }
.pricing-now-amount span { color: var(--muted); font-size: 1.1rem; font-weight: 500; }
.pricing-section-sub { margin: .45rem 0 0; color: #455b74; font-size: 1.02rem; }
.pricing-rate-caption { margin: .3rem 0 0; color: #455b74; font-size: .95rem; font-weight: 600; }
.pricing-rate-list { list-style: none; margin: 1.1rem 0 0; padding: 0; }
.pricing-rate-list li { display: flex; align-items: flex-start; margin-top: .55rem; color: #33475f; font-size: .94rem; line-height: 1.55; }
.pricing-rate-list .icon { flex: 0 0 auto; width: 1.05em; height: 1.05em; margin: .3em .55rem 0 0; color: #1769d2; }
.pricing-rates-cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 1.4rem; padding: 1.2rem 1.5rem; border-radius: 16px; background: #eaf3ff; }
.pricing-rates-cta p { margin: .3rem 1rem .3rem 0; color: #1d3452; font-size: 1.05rem; font-weight: 700; }
.pricing-disclaimer { margin: 1rem 0 0; color: #6b7d90; font-size: .82rem; line-height: 1.6; }
.pricing-feature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pricing-feature p.pricing-feature-note { margin-top: .45rem; color: #33475f; font-weight: 600; }
.pricing-detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pricing-detail-grid .pricing-detail:last-child:nth-child(odd) { grid-column: 1 / -1; }
.pricing-page > .pricing-faq details { margin-top: .6rem; padding: 1rem 1.25rem; border: 1px solid #dce4ef; border-radius: 13px; background: #fff; }
.pricing-faq summary { color: #2b405a; cursor: pointer; font-weight: 700; }
.pricing-faq details p { margin: .7rem 0 0; color: var(--muted); font-size: .92rem; line-height: 1.7; }
.pricing-bottom-cta .pricing-bottom-strong { margin: 0 0 .3rem; color: #1d3452; font-size: 1rem; font-weight: 700; }
@media (max-width: 640px) {
    .pricing-feature-grid, .pricing-detail-grid { grid-template-columns: 1fr; }
    .pricing-rates-cta { display: block; padding: 1.1rem; }
    .pricing-rates-cta p { margin: 0 0 .9rem; }
    .pricing-rates-cta .button { width: 100%; }
}
