/* =============================================================
   Theme — every colour in this file comes from a variable.

   The values below are only the fallback for a fresh install: the page
   <head> re-emits the admin-configurable ones from the settings table
   (Admin → Site Settings → Brand colours), so changing a colour there
   changes it everywhere on the storefront. Never hard-code a hex here —
   add a variable instead, or the admin's choice won't reach it.

   Built on Bootstrap 5.3 (overrides its CSS variables).
   ============================================================= */

:root {
    /* Type — Plus Jakarta Sans carries the Latin/UI glyphs, Anek Bangla the
       Bangla ones; the browser falls back per glyph, so a mixed line uses
       both without any markup. Both are variable fonts (400–800). */
    --font-sans: "Plus Jakarta Sans", "Anek Bangla", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-display: var(--font-sans);

    /* ---- Admin-configurable brand palette ----
       The -d variants are darkened automatically; the -rgb triplets exist so
       translucent shades (rgba) follow the chosen colour too. */
    --brand-navy: #002B7F;
    /* primary — navbar, buttons, links */
    --brand-navy-d: #001f5c;
    --brand-navy-rgb: 0, 43, 127;

    --brand-orange: #FF5A00;
    /* accent — CTAs, sale badges */
    --brand-orange-d: #e65100;
    --brand-orange-rgb: 255, 90, 0;

    --brand-yellow: #FFC400;
    /* highlight — stars, footer rules */
    --brand-yellow-rgb: 255, 196, 0;

    --brand-heading: #0b1a3a;
    /* section titles */
    --brand-heading-rgb: 11, 26, 58;

    --brand-body: #1f2937;
    /* body copy */
    --brand-gray: #515151;
    /* secondary copy */
    --brand-muted: #64748b;
    /* small print, table headers */

    --brand-light: #f6f8fc;
    /* soft section background */
    --brand-surface: #f4f6fa;
    /* image plates, inert panels */
    --brand-border: #eef0f4;
    /* card, table and input borders */

    --brand-success: #15803d;
    --brand-danger: #dc2626;

    /* ---- Hero & header background ----
       The deep green plate the masthead and the hero share. Admin-configurable
       (Site Settings → Brand colours → "Hero background"); the glow and the
       edge shading are derived from it, so one colour moves the whole panel. */
    --hero-bg: #0e4033;
    --hero-bg-rgb: 14, 64, 51;
    --hero-sticky: #135745;
    --hero-glow: #24a685;
    --hero-glow-rgb: 36, 166, 133;

    /* No picture unless the shop chooses one. "none" is a real background
       layer, so the rules below can list it unconditionally and get the
       painted plate whenever it is not set. @see layouts/header.php */
    --hero-image: none;
    --hero-scrim: none;

    /* ---- Footer ----
       Background and text are two separate settings (Site Settings → Brand
       colours), so a shop can run a pale footer with dark type just as easily
       as the dark one it ships with. Everything else down there — headings,
       icons, the social buttons, the copyright line — is derived from those
       two, so the pair can never end up unreadable against each other. */
    --footer-bg: #002B7F;
    --footer-text: #c7d2e6;
    --footer-text-rgb: 199, 210, 230;
    --footer-heading: #ffffff;

    --brand-border-strong: #dfe4ee;
    /* borders that need to read clearly */

    /* ---- Fixed accents (deliberately not admin-configurable) ----
       Status tints and third-party brand colours. Changing these from the
       admin would mostly break meaning (red = error, WhatsApp green), so they
       stay put — but they are still variables, not literals. */
    --c-success-soft: #86efac;
    --c-success-bg: #dcfce7;
    --c-success-bg-soft: #f0fdf4;
    --c-success-d: #14532d;

    --c-danger-soft: #fecaca;
    --c-danger-bg: #fee2e2;
    --c-danger-bg-soft: #fef2f2;
    --c-danger-d: #991b1b;
    --c-danger-l: #fca5a5;

    --c-warning-bg: #fef3c7;
    /* "pending" order status */
    --c-warning-d: #92400e;

    --c-slate: #475569;
    --c-slate-d: #334155;
    --c-slate-l: #94a3b8;
    --c-faint: #9aa3af;

    --c-on-navy: #c7d2e6;
    /* footer copy on the primary colour */
    --c-on-navy-dim: #9fb0cf;
    --c-on-dark: #d4d9e2;

    --c-border-mid: #cbd5e1;
    --c-border-btn: #dee2e6;
    --c-divider: #cdd8ee;
    /* dashed separators */

    --c-hero-btn: #f8f9fa;
    /* off-white CTA on the hero */
    --c-hero-btn-d: #e9ecef;
    --c-teal: #0d9488;
    --c-teal-d: #0b7d73;
    --c-whatsapp: #25D366;
    /* WhatsApp's own brand green */
    --c-whatsapp-d: #1da851;

    /* The searchable dropdown. Its three colours were only ever the fallbacks
       inside var() — nothing anywhere set them — so the control kept the
       shipped blue and grey however the shop repainted the rest of the page.
       Pointed at the brand here, which is all they ever wanted to be. */
    --combo-accent: var(--brand-navy);
    --combo-border: var(--c-border-mid);
    --combo-ring: rgba(var(--brand-navy-rgb), .12);

    /* Retint Bootstrap to the brand */
    --bs-primary: var(--brand-navy);
    --bs-primary-rgb: var(--brand-navy-rgb);
    --bs-link-color: var(--brand-navy);
    --bs-link-hover-color: var(--brand-orange);
}

body {
    font-family: var(--font-sans);
    color: var(--brand-body);
    font-optical-sizing: auto;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Proportional lining figures — keeps prices and quantities even. */
    font-variant-numeric: lining-nums;

    /* Sticky footer: on short pages (order tracking, policies, 404) <main>
       grows to fill the viewport so the footer stays at the bottom instead of
       riding up into the middle of the screen. The fixed-position widgets
       (cart FAB, back-to-top, toast) are out of flow and unaffected. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.site-main {
    flex: 1 0 auto;
}

/* The browser hides [hidden] with `display: none`, but that comes from the user
   agent sheet — the weakest source there is. Any rule here that sets a display
   of its own outranks it, so an element the page had switched off stayed on
   screen: `.summary-totals p { display: flex }` kept the discount row visible
   with no discount in it. One !important settles it for every toggle on the
   storefront rather than each one guessing. */
[hidden] {
    display: none !important;
}

.site-footer {
    flex-shrink: 0;
}

/* =============================================================
   Links
   -------------------------------------------------------------
   No stylesheet rule existed for a bare <a>, so every link that
   wasn't part of a styled component fell back to the browser's
   underline — a hard line under breadcrumbs, prose links, alerts
   and notes alike, cutting through the descenders of Bangla
   letters as it went.

   No underline at all now, resting or hovered. Links are carried
   by colour and weight, and the colour shifts to the accent when
   you point at one.
   ============================================================= */
a {
    text-decoration: none;
}

a:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Links inside body copy — the ones a reader has to be able to spot. */
.site-main p a,
.site-main li a,
.about-prose a,
.policy-prose a,
.form-text a,
.alert a {
    color: var(--brand-navy);
    font-weight: 600;
    transition: color .15s ease;
}

.site-main p a:hover,
.site-main li a:hover,
.about-prose a:hover,
.policy-prose a:hover,
.form-text a:hover,
.alert a:hover {
    color: var(--brand-orange);
}

/* Breadcrumbs are navigation, not prose — lighter weight suits them. */
.breadcrumb a {
    font-weight: 500;
}

/* Headings sit tighter and heavier than body copy — the usual premium cue. */
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
.display-1,
.display-2,
.display-3,
.display-4,
.display-5,
.display-6 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -.015em;
}

.btn,
.navbar,
.form-label,
.badge {
    font-family: var(--font-sans);
}

.btn {
    font-weight: 600;
    letter-spacing: -.005em;
}

/* Prices/totals read best with slightly tightened, tabular-ish figures. */
.price,
.price-old,
.summary-item__total,
.summary-totals,
.cart-totals,
.cart-grand {
    font-feature-settings: "tnum" 1;
}

/* ---- Buttons ---- */
.btn-primary {
    --bs-btn-bg: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-hover-bg: var(--brand-navy-d);
    --bs-btn-hover-border-color: var(--brand-navy-d);
    --bs-btn-active-bg: var(--brand-navy-d);
    --bs-btn-active-border-color: var(--brand-navy-d);
}

/* Solid CTA button. Navy rather than the accent colour — the orange is kept
   for small highlights (and the floating cart), not for full buttons. */
.btn-accent {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-navy-d);
    --bs-btn-hover-border-color: var(--brand-navy-d);
    --bs-btn-active-bg: var(--brand-navy-d);
}

.btn-outline-primary {
    --bs-btn-color: var(--brand-navy);
    --bs-btn-border-color: var(--brand-navy);
    --bs-btn-hover-bg: var(--brand-navy);
    --bs-btn-hover-border-color: var(--brand-navy);
    --bs-btn-active-bg: var(--brand-navy);
}

/* Hero CTAs — soft off-white on the navy hero, with a little extra top
   padding so the Bangla text sits visually centred. */
/* ---- Hero call-to-action pair ----
   Two buttons that used to look identical, so neither looked like the main
   one. Now the first is solid and the second is outlined: same size, clear
   hierarchy. Both are built here rather than on Bootstrap's .btn, so the
   height and the label sit exactly where they should whatever the text. */
.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
}

.btn-hero {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55rem;
    min-height: 52px;
    padding: 0 1.7rem;
    border: 1.5px solid transparent;
    border-radius: 10px;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease,
        background-color .18s ease, border-color .18s ease, color .18s ease;
}

.btn-hero i {
    font-size: 1.05rem;
    transition: transform .18s ease;
}

/* The action we actually want: solid, and it carries the arrow. */
.btn-hero--solid {
    background: var(--hero-glow);
    border-color: var(--hero-glow);
    color: var(--footer-heading);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .22);
}

.btn-hero--solid:hover,
.btn-hero--solid:focus-visible {
    background: #fff;
    color: var(--brand-navy);
    transform: translateY(-2px);
    box-shadow: 0 14px 30px rgba(0, 0, 0, .28);
}

.btn-hero--solid:hover i {
    transform: translateX(3px);
}

/* The alternative: outlined, so it reads as secondary without disappearing. */
.btn-hero--ghost {
    background: rgba(255, 255, 255, .08);
    border-color: rgba(255, 255, 255, .55);
    color: #fff;
    backdrop-filter: blur(2px);
}

.btn-hero--ghost:hover,
.btn-hero--ghost:focus-visible {
    background: rgba(255, 255, 255, .18);
    border-color: #fff;
    color: #fff;
    transform: translateY(-2px);
}

.btn-hero:active {
    transform: translateY(0);
}

.btn-hero:focus-visible {
    outline: 3px solid rgba(var(--brand-yellow-rgb), .5);
    outline-offset: 2px;
}

@media (max-width: 991.98px) {

    /* The column is centred below lg, so the pair should be too. */
    .hero-actions {
        justify-content: center;
    }
}

@media (max-width: 400px) {

    /* Two buttons side by side get cramped on the narrowest phones. */
    .btn-hero {
        flex: 1 1 100%;
    }
}

@media (prefers-reduced-motion: reduce) {

    .btn-hero,
    .btn-hero i {
        transition: none;
    }

    .btn-hero:hover {
        transform: none;
    }
}

.text-primary {
    color: var(--brand-navy) !important;
}

.text-accent {
    color: var(--brand-orange) !important;
}

.bg-primary {
    background-color: var(--brand-navy) !important;
}

.bg-accent {
    background-color: var(--brand-orange) !important;
}

/* ---- Header / Navbar (navy) ---- */
/* The masthead sits on the same plate as the hero, with only a hairline
   between them, so on the homepage the two read as one panel. */
.site-nav {
    background-color: var(--hero-bg);
    /* Scrim over picture, and nothing at all when there is no picture. */
    background-image: var(--hero-scrim), var(--hero-image);
    background-size: cover;
    background-position: top center;
    background-repeat: no-repeat;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
    box-shadow: none;
    transition: padding .28s ease, background-color .28s ease, box-shadow .28s ease, backdrop-filter .28s ease;
}

/* Sticky scroll effect: compact, a shade lighter, deeper shadow.

   Solid rather than the translucent plate it used to be. Once the masthead
   lifts off the hero it spends most of its life over white product pages,
   where a see-through green picks up whatever is sliding underneath and the
   logo has to fight it. One flat colour reads the same on every page. */
.site-nav.scrolled {
    padding-top: .4rem !important;
    padding-bottom: .4rem !important;
    background: var(--hero-sticky);
    box-shadow: 0 8px 26px rgba(0, 0, 0, .32);
}

.brand-logo {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    text-decoration: none;
    width: 100%;
}

.brand-logo .brand-mark {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: #fff;
    color: var(--brand-navy);
    font-size: 1.15rem;
    box-shadow: inset 0 -3px 0 var(--brand-orange);
    transition: width .28s ease, height .28s ease, font-size .28s ease;
}

.site-nav.scrolled .brand-mark {
    width: 32px;
    height: 32px;
    font-size: 1rem;
}

.brand-logo .brand-text {
    font-weight: 800;
    font-size: 1.25rem;
    color: #fff;
    letter-spacing: -.5px;
}

/* Uploaded logo image (used instead of the icon+text mark when configured) */
.brand-logo .brand-img {
    height: 44px;
    width: auto;
    max-width: 220px;
    object-fit: contain;
    display: block;
    transition: height .28s ease;
    margin: 0 auto 15px;
}

.site-nav.scrolled .brand-logo .brand-img {
    height: 36px;
}

.site-nav .nav-link {
    font-weight: 600;
    color: rgba(255, 255, 255, .82);
}

.site-nav .nav-link:hover,
.site-nav .nav-link.active {
    color: var(--brand-orange);
}

/* The desktop search box, used everywhere — a translucent field on the navy
   bar. The phone gets the same thing, only full width, so the header looks
   the same whatever the screen. The magnifier sits inside it on the right. */
.nav-search {
    position: relative;
    margin: 0;
}

.nav-search .form-control {
    width: 340px;
    /* Right padding leaves room for the icon button. */
    padding: .4rem 2.6rem .4rem 1rem;
    border-radius: 8px;
    font-size: .98rem;
    background: rgba(255, 255, 255, .14);
    border-color: rgba(255, 255, 255, .25);
    color: #fff;
}

.nav-search .form-control::placeholder {
    color: rgba(255, 255, 255, .7);
}

.nav-search .form-control:focus {
    background: rgba(255, 255, 255, .22);
    color: #fff;
    box-shadow: 0 0 0 .2rem rgba(var(--brand-yellow-rgb), .25);
}

/* A real submit button, so Enter and the tap do the same thing. Kept quiet —
   it belongs to the field rather than sitting on top of it. */
.nav-search button {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 2.6rem;
    display: grid;
    place-items: center;
    border: none;
    background: none;
    color: rgba(255, 255, 255, .75);
    font-size: 1rem;
    cursor: pointer;
    transition: color .15s ease;
}

.nav-search button:hover,
.nav-search .form-control:focus+button {
    color: #fff;
}

/* Mobile: the box is the header, so it takes the space the logo gave up. */
.nav-search--wide {
    flex: 1 1 auto;
    min-width: 0;
}

.nav-search--wide .form-control {
    width: 100%;
}

/* On phones the header stacks into two rows: the logo centred on top, the
   search bar full-width beneath it. (On desktop the logo sits inline at the
   left as usual — this only applies below the lg breakpoint.) */
@media (max-width: 991.98px) {
    .site-nav .container {
        row-gap: .65rem;
    }

    .site-nav .brand-logo {
        display: flex;
        flex: 0 0 100%;
        justify-content: center;
        margin: 0;
    }

    .site-nav .nav-search--wide {
        flex: 0 0 100%;
    }
}

@media only screen and (min-width: 992px) {
    .brand-logo {
        width: auto;
    }
}

.account-btn {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: #fff;
    border: 2px solid var(--brand-light);
    background: transparent;
    font-size: 1.2rem;
}

.account-btn:hover {
    background: #fff;
    color: var(--brand-navy);
}

/* ---- Hero ---- */
/* A flat plate. It used to carry three soft glows and a vignette over the
   top — the blurred-foliage look — but a shop that sets its own hero colour
   got a panel that was never quite the colour it picked, and a shop that sets
   a background picture had the glows sitting on it. One colour, or one
   picture, and nothing painted over either. */
.hero {
    position: relative;
    background-color: var(--hero-bg);
    /* Scrim over picture; both are "none" until a picture is chosen. */
    background-image: var(--hero-scrim), var(--hero-image);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: #fff;
    padding: 4.75rem 0;
    overflow: hidden;
}

/* The slides sit above the plate. */
.hero > * { position: relative; z-index: 1; }

.hero h1 {
    font-weight: 800;
    letter-spacing: -1px;
    color: #fff;
}

/* Bootstrap's .lead is 1.25rem — too heavy next to the display heading, and
   it pushed the buttons below the fold on a phone. This is the supporting
   line, so it reads a step quieter than the body text around it. */
.hero .lead {
    color: rgba(255, 255, 255, .82);
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1.65;
    /* Capped for readability, but flush left with the heading and the
       buttons — centring the box here indented the paragraph away from
       everything else in the column. */
    max-width: 52ch;
    margin-inline: 0;
}

/* Below lg the whole column is centred, so the capped box must be too. */
@media (max-width: 991.98px) {
    .hero .lead {
        margin-inline: auto;
    }
}

@media (max-width: 575.98px) {
    .hero .lead {
        font-size: .92rem;
    }
}

.hero-img {
    width: 100%;
    aspect-ratio: 4/3;
    object-fit: cover;
    border-radius: 1.25rem;
}

/* ---- Hero carousel (full two-column slides) ---- */
.hero .carousel-item {
    padding-bottom: 1.5rem;
}

/* room for indicators */

/* Smooth crossfade between slides (content + image fade together) */
.hero .carousel-fade .carousel-item {
    transition: opacity .8s ease;
}

.hero .carousel-indicators {
    margin-bottom: 0;
}

.hero .carousel-indicators [data-bs-target] {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    border: 0;
    opacity: .5;
}

.hero .carousel-indicators .active {
    background: var(--brand-orange);
    opacity: 1;
}

.hero .carousel-control-prev,
.hero .carousel-control-next {
    width: 4rem;
    opacity: .85;
}

.hero .carousel-control-prev-icon,
.hero .carousel-control-next-icon {
    background-color: rgba(255, 255, 255, .16);
    border-radius: 50%;
    padding: 1.1rem;
    background-size: 42%;
}

@media (max-width: 991px) {

    .hero .carousel-control-prev,
    .hero .carousel-control-next {
        display: none;
    }
}

/* ---- Shop / products page ---- */
.shop-head {
    background: var(--brand-light);
    border-bottom: 1px solid var(--brand-border);
}

.shop-head .breadcrumb {
    font-size: .85rem;
}

.shop-head .breadcrumb a {
    color: var(--brand-navy);
    text-decoration: none;
}

.shop-head .breadcrumb a:hover {
    color: var(--brand-orange);
}

/* =============================================================
   Catalogue filters
   -------------------------------------------------------------
   One toolbar: category pills, then a compact bar with the count
   on the left and price / sort / apply on the right, then chips
   for whatever is currently active. The old design asked for the
   category twice — once in a select, once in a pill row.
   ============================================================= */

/* The whole block sits in one outlined panel, so the pills, the bar and the
   active chips read as a single tool rather than three loose rows floating
   above the grid. */
.shop-filter {
    display: flex;
    flex-direction: column;
    gap: .85rem;
    padding: 1rem 1.15rem;
    border: 1px solid var(--brand-border);
    border-radius: 16px;
    background: #fff;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .05);
}

/* Thin rules between the three rows — cheaper on the eye than boxing each
   one, and they only appear when the row above them exists. */
.shop-filter>*+* {
    padding-top: .85rem;
    border-top: 1px solid var(--brand-border);
}

/* ---- Category pills ---- */
.filter-pills {
    display: flex;
    gap: .5rem;
    /* Sideways scroll beats wrapping into five rows on a phone. */
    overflow-x: auto;
    padding-bottom: .25rem;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.filter-pills::-webkit-scrollbar {
    height: 4px;
}

.filter-pills::-webkit-scrollbar-thumb {
    background: var(--brand-border);
    border-radius: 4px;
}

.filter-pill {
    flex: 0 0 auto;
    padding: .5rem 1.05rem;
    border: 1px solid var(--brand-border);
    border-radius: 999px;
    background: #fff;
    color: var(--brand-body);
    font-size: .92rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.filter-pill:hover {
    border-color: var(--brand-navy);
    color: var(--brand-navy);
}

.filter-pill.is-active {
    background: var(--brand-navy);
    border-color: var(--brand-navy);
    color: #fff;
}

/* ---- The bar ----
   No border of its own: the panel around it already provides one, and a box
   inside a box makes the whole thing look busier than it is. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1rem;
    margin: 0;
}

.filter-bar__count {
    margin: 0;
    color: var(--c-slate-l);
    font-size: .95rem;
}

.filter-bar__count strong {
    color: var(--brand-navy);
    font-size: 1.1rem;
    font-weight: 800;
}


.filter-bar__group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
}

/* Label and control on one line — a stacked label would double the height
   of a bar that only holds two controls. */
.filter-field {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
}

.filter-field__label {
    color: var(--c-slate-l);
    font-size: .85rem;
    font-weight: 600;
    white-space: nowrap;
}

.filter-field select,
.price-range {
    height: 40px;
    border: 1px solid var(--brand-border);
    border-radius: 9px;
    background: var(--brand-surface);
    color: var(--brand-body);
    font-size: .92rem;
    font-weight: 600;
}

.filter-field select {
    padding: 0 2rem 0 .75rem;
    /* Own chevron, so the control matches the price box exactly. */
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2364748b'%3E%3Cpath d='M8 11 3 6h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .6rem center;
    background-size: 12px;
    cursor: pointer;
}

.price-range {
    display: inline-flex;
    align-items: center;
    padding: 0 .5rem;
}

.price-range input {
    width: 74px;
    height: 100%;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: center;
    /* The spinners eat half the field at this width. */
    -moz-appearance: textfield;
    appearance: textfield;
}

.price-range input::-webkit-outer-spin-button,
.price-range input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.price-range input:focus {
    outline: none;
}

.price-range__dash {
    color: var(--c-faint);
    padding: 0 .1rem;
}

.filter-field select:focus,
.price-range:focus-within {
    border-color: var(--brand-navy);
    box-shadow: 0 0 0 .2rem rgba(var(--brand-navy-rgb), .12);
    outline: none;
}

.filter-apply {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    height: 40px;
    padding: 0 1.1rem;
    border: none;
    border-radius: 9px;
    background: var(--brand-navy);
    color: #fff;
    font-size: .92rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease;
}

.filter-apply:hover {
    background: var(--brand-navy-d);
}

/* ---- Active filter chips ---- */
.filter-active {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.filter-active__label {
    color: var(--c-slate-l);
    font-size: .85rem;
    font-weight: 600;
}

/* Each chip removes its own filter — clearer than hunting for the control
   that set it and putting it back to "any". */
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .32rem .7rem .32rem .85rem;
    border-radius: 999px;
    background: rgba(var(--brand-navy-rgb), .07);
    color: var(--brand-navy);
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color .15s ease;
}

.filter-chip i {
    font-size: .7rem;
    opacity: .6;
}

.filter-chip:hover {
    background: rgba(var(--brand-navy-rgb), .14);
    color: var(--brand-navy);
}

.filter-chip:hover i {
    opacity: 1;
}

/* "Clear all" — quiet until pointed at, when it turns to the danger colour. */
.filter-active__clear {
    color: var(--c-slate-l);
    font-size: .85rem;
    font-weight: 600;
    transition: color .15s ease;
}

.filter-active__clear:hover {
    color: var(--brand-danger, #dc2626);
}

/* ---- Nothing matched ---- */
.shop-empty {
    padding: 3.5rem 1.5rem;
    border: 1px dashed var(--brand-border);
    border-radius: 16px;
    background: var(--brand-surface);
    text-align: center;
}

.shop-empty__icon {
    width: 66px;
    height: 66px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: #fff;
    border: 1px solid var(--brand-border);
    color: var(--c-faint);
    font-size: 1.6rem;
}

@media (max-width: 575.98px) {

    /* Count above, controls below — side by side they squeeze the price box
       down to about three characters. */
    .shop-filter {
        padding: .85rem .9rem;
    }

    .filter-bar__group {
        width: 100%;
    }

    .filter-field {
        flex: 1 1 100%;
        justify-content: space-between;
    }

    .price-range input {
        width: 100%;
    }

    .price-range {
        flex: 1;
    }

    .filter-field select {
        flex: 1;
    }

    .filter-apply {
        width: 100%;
        justify-content: center;
    }
}

/* Fade-in for cards appended by the "Load more" button */
.product-appear {
    animation: productAppear .5s ease both;
}

@keyframes productAppear {
    from {
        opacity: 0;
        transform: translateY(18px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .product-appear {
        animation: none;
    }
}

/* ---- Product detail ---- */
/* Thumbnail strip on the left, main image on the right. The thumbs column is
   a grid item with min-height:0 + overflow, so however many images a product
   has, the row stays exactly as tall as the main image — the info column
   beside it never gets pushed down. */
.pd-gallery {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr);
    gap: .75rem;
    align-items: stretch;
}

.pd-gallery--single {
    grid-template-columns: minmax(0, 1fr);
}

.pd-main-wrap {
    position: relative;
}

.pd-main {
    width: 100%;
    aspect-ratio: 1/1;
    /* The whole product, never a crop of it — this is the picture the buying
       decision is made from. @see .product-card .card-img-top */
    object-fit: contain;
    border: 1px solid var(--brand-border);
    border-radius: 1rem;
    background: var(--brand-surface);
}

/* The thumbnail column: capped, scrollable, with its own buttons.
   --------------------------------------------------------------------------
   It used to simply grow. Seven photos made this column 646px tall next to a
   484px picture, so the extra 162px of empty space to the right of the image
   became part of the page — the column was setting the height of the row it
   was supposed to sit inside. Now the picture decides the height (JS measures
   it into --pd-main-h) and anything past that scrolls. */
.pd-thumbs-wrap {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    min-height: 0;
    max-height: var(--pd-main-h, none);
}

.pd-thumbs {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin: 0;
    min-height: 0;
    overflow-y: auto;
    scroll-behavior: smooth;
    scrollbar-width: thin;
    /* Reaching the end of the strip should not then drag the page with it. */
    overscroll-behavior-y: contain;
}

/* Hidden until there is something out of view — the buttons are added by the
   markup either way, and JS puts .is-scrollable on the wrapper when the
   pictures genuinely overflow. */
.pd-thumbs__nav {
    display: none;
    flex: 0 0 auto;
    padding: .15rem 0;
    border: 1px solid var(--brand-border);
    border-radius: .5rem;
    background: var(--brand-surface, #f4f6fa);
    color: var(--brand-navy);
    line-height: 1;
    font-size: .9rem;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, opacity .15s ease;
}

.pd-thumbs-wrap.is-scrollable .pd-thumbs__nav {
    display: block;
}

.pd-thumbs__nav:hover:not(:disabled) {
    background: var(--brand-navy);
    color: #fff;
}

/* Kept in place rather than removed, so the column does not jump by 26px the
   moment you reach either end. */
.pd-thumbs__nav:disabled {
    opacity: .35;
    cursor: default;
}

@media (prefers-reduced-motion: reduce) {
    .pd-thumbs {
        scroll-behavior: auto;
    }
}

.pd-thumb {
    width: 100%;
    aspect-ratio: 1/1;
    flex: 0 0 auto;
    /* Matches the main image above, so a thumbnail is a small version of what
       opens rather than a differently-cropped one. */
    object-fit: contain;
    background: var(--brand-surface);
    border-radius: .6rem;
    border: 2px solid var(--brand-border);
    cursor: pointer;
    transition: border-color .15s ease;
}

/* Phones: back under the image as a horizontal, swipeable strip. */
@media (max-width: 575.98px) {
    .pd-gallery {
        grid-template-columns: minmax(0, 1fr);
    }

    .pd-main-wrap {
        order: 1;
    }

    .pd-thumbs-wrap {
        order: 2;
        /* The cap is for a column beside the picture; underneath it there is
           nothing to line up with. */
        max-height: none;
    }

    .pd-thumbs {
        flex-direction: row;
        overflow-x: auto;
        overflow-y: hidden;
        padding-bottom: .25rem;
        overscroll-behavior-x: contain;
    }

    .pd-thumb {
        width: 68px;
    }

    /* No buttons here: a thumb is a finger-width away and the strip is
       swipeable, and up/down chevrons would point the wrong way anyway. */
    .pd-thumbs-wrap.is-scrollable .pd-thumbs__nav {
        display: none;
    }
}

.pd-thumb:hover {
    border-color: var(--c-border-mid);
}

.pd-thumb.is-active {
    border-color: var(--brand-navy);
}

.stars {
    color: var(--brand-yellow);
    letter-spacing: 1px;
}

/* Brand line above the product name.
   Quiet on purpose: it sits directly above an h1 and must label it, not
   compete with it — so small caps-ish spacing and the muted ink, with the
   logo (when the brand has one) kept to the height of the text beside it. */
.pd-brand {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .9rem;
}

.pd-brand__item {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}

.pd-brand__logo {
    height: 22px;
    width: auto;
    max-width: 96px;
    object-fit: contain;
}

.pd-brand__name {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--brand-muted, #64748b);
}

.pd-price .price {
    color: var(--brand-navy);
    font-weight: 800;
}

/* Action buttons — each a distinct colour */
.pd-qty {
    width: 88px;
    flex: 0 0 88px;
    font-weight: 700;
}

.btn-buy {
    /* Buy now — orange, so it stands apart from the navy "add to cart". */
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--brand-orange);
    --bs-btn-border-color: var(--brand-orange);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-orange-d);
    --bs-btn-hover-border-color: var(--brand-orange-d);
    --bs-btn-active-bg: var(--brand-orange-d);
    font-weight: 600;
}

.btn-whatsapp {
    /* WhatsApp — green */
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--c-whatsapp);
    --bs-btn-border-color: var(--c-whatsapp);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--c-whatsapp-d);
    --bs-btn-hover-border-color: var(--c-whatsapp-d);
    --bs-btn-active-bg: var(--c-whatsapp-d);
    font-weight: 600;
}

.btn-call {
    /* Call — teal */
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--c-teal);
    --bs-btn-border-color: var(--c-teal);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--c-teal-d);
    --bs-btn-hover-border-color: var(--c-teal-d);
    --bs-btn-active-bg: var(--c-teal-d);
    font-weight: 600;
}

/* Shared polish for the product-detail action buttons */
.btn-accent,
.btn-buy,
.btn-whatsapp,
.btn-call {
    box-shadow: 0 .35rem .9rem rgba(0, 0, 0, .12);
}

/* ---- "Buy now" attention nudge ----
   A short wiggle plus a ring that spreads out, then a brief rest before it
   repeats. Continuous movement reads as a broken page and makes the button
   harder to hit; a repeating one is noticed and then forgotten about.

   2.5s cycle: the wiggle takes the first 30% (~0.75s), leaving ~1.75s still.
   To change the rhythm, adjust the duration — the percentages keep the wiggle
   proportional to it.

   Only transform and box-shadow animate, so nothing around it reflows, and it
   stops the moment the pointer is over the button — nobody wants to chase a
   moving target. */
.btn-nudge {
    animation: btnNudge 2.5s ease-in-out 1.5s infinite;
}

.btn-nudge:hover,
.btn-nudge:focus-visible,
.btn-nudge:active {
    animation: none;
}

@keyframes btnNudge {

    /* Still from 30% to the end of the cycle. */
    0%,
    30% {
        transform: none;
        box-shadow: 0 .35rem .9rem rgba(0, 0, 0, .12);
    }

    6% {
        transform: scale(1.035);
        box-shadow: 0 .35rem .9rem rgba(0, 0, 0, .12), 0 0 0 0 rgba(var(--brand-orange-rgb), .55);
    }

    12% {
        transform: scale(1.02) rotate(-.7deg);
    }

    18% {
        transform: scale(1.02) rotate(.7deg);
    }

    24% {
        transform: scale(1.02) rotate(-.5deg);
    }

    29% {
        transform: scale(1.01) rotate(0);
        /* Ring finishes spreading and fades as it goes. */
        box-shadow: 0 .35rem .9rem rgba(0, 0, 0, .12), 0 0 0 .9rem rgba(var(--brand-orange-rgb), 0);
    }
}

/* Movement is a preference, not a requirement — honour the system setting. */
@media (prefers-reduced-motion: reduce) {
    .btn-nudge {
        animation: none;
    }
}

.btn-accent:hover,
.btn-buy:hover,
.btn-whatsapp:hover,
.btn-call:hover {
    box-shadow: 0 .5rem 1.2rem rgba(0, 0, 0, .18);
}

/* Rating stars on the product card */
.card-rating {
    display: flex;
    align-items: center;
    gap: .3rem;
    line-height: 1;
}

.card-rating .stars {
    font-size: .82rem;
}

/* Reassurance boxes (2×2 grid) */
.pd-trust__box {
    display: flex;
    align-items: center;
    gap: .6rem;
    height: 100%;
    border: 1px solid var(--brand-border);
    border-radius: .75rem;
    padding: .8rem .9rem;
    background: #fff;
    font-size: .86rem;
    font-weight: 600;
    color: var(--brand-gray);
    line-height: 1.3;
}

.pd-trust__box i {
    color: var(--brand-navy);
    font-size: 1.3rem;
    flex-shrink: 0;
}

/* Level the info column with the (square) image on large screens */
@media (min-width: 992px) {
    .pd-info {
        display: flex;
        flex-direction: column;
    }

    .pd-info .pd-trust {
        margin-top: auto;
    }
}

/* Tabs (pill buttons) */
.product-tabs .nav-link {
    color: var(--brand-gray);
    font-weight: 700;
    border: 1px solid var(--brand-border);
    padding: .5rem 1.25rem;
    background: #fff;
}

.product-tabs .nav-link:hover {
    border-color: var(--brand-navy);
    color: var(--brand-navy);
}

.product-tabs .nav-link.active {
    background: var(--brand-navy);
    border-color: var(--brand-navy);
    color: #fff;
}

.pd-tab-content {
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: 1rem;
    padding: 1.75rem;
}

/* Review summary + items */
.review-summary {
    background: var(--brand-light);
    border-radius: 1rem;
    padding: 1.5rem;
}

.review-summary__avg {
    font-size: 2.75rem;
    font-weight: 800;
    color: var(--brand-navy);
    line-height: 1;
}

.review-item {
    border-bottom: 1px solid var(--brand-border);
    padding: 1rem 0;
}

.review-item:first-child {
    padding-top: 0;
}

.review-item:last-child {
    border-bottom: 0;
}

/* Clickable star rating input */
.star-input {
    display: inline-flex;
    flex-direction: row-reverse;
    gap: .15rem;
    /* Anchors the visually-hidden radios below. */
    position: relative;
}

/* The radios are hidden from sight but NOT from the browser.
   display:none on a `required` control is a trap: the browser cannot focus it
   to show "please choose one", so it refuses to submit the form and logs
   "An invalid form control with name='rating' is not focusable" — the review
   button simply did nothing until a star was clicked, with no explanation. */
.star-input input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
}

.star-input label {
    color: var(--c-on-dark);
    font-size: 1.6rem;
    cursor: pointer;
    transition: color .12s ease;
}

.star-input label:hover,
.star-input label:hover~label,
.star-input input:checked~label {
    color: var(--brand-yellow);
}

/* Keyboard users get a visible focus ring on the star being chosen. */
.star-input input:focus-visible+label {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ---- Feature strip ---- */
.feature {
    display: flex;
    align-items: center;
    gap: .85rem;
}

.feature .icon {
    width: 46px;
    height: 46px;
    border-radius: 12px;
    display: grid;
    place-items: center;
    background: var(--brand-light);
    color: var(--brand-navy);
    font-size: 1.35rem;
}

/* ---- Product cards ---- */
.section-title {
    font-weight: 800;
    letter-spacing: -.5px;
    color: var(--brand-heading);
}

.section-title::after {
    content: "";
    display: block;
    width: 54px;
    height: 4px;
    border-radius: 4px;
    background: var(--brand-orange);
    margin-top: .5rem;
}

/* ---- Related products: horizontal slider ---- */
.related-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.related-nav {
    display: flex;
    gap: .4rem;
}

.related-nav__btn {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--brand-border);
    background: #fff;
    color: var(--brand-navy, #002b7f);
    display: grid;
    place-items: center;
    cursor: pointer;
    font-size: 1.05rem;
    line-height: 1;
    transition: background .15s ease, color .15s ease, opacity .15s ease;
}

.related-nav__btn:hover {
    background: var(--brand-navy, #002b7f);
    color: #fff;
    border: none;
}

.related-nav__btn:disabled {
    opacity: .35;
    cursor: default;
}

.related-slider {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    cursor: grab;
    /* overflow-x:auto makes the box clip vertically too, so the card's hover
       lift and its drop shadow would be cut off at the edges. This padding
       gives them room; the negative margin keeps the gap to the next section
       looking the same as before. */
    padding: 10px 3px 26px;
    margin-bottom: -18px;
    /* The arrows do the navigating — hide the native scrollbar in every
       browser so no grey bar sits under the row. */
    scrollbar-width: none;
    /* Firefox */
    -ms-overflow-style: none;
    /* old Edge/IE */
}

.related-slider::-webkit-scrollbar {
    display: none;
}

/* While dragging with the mouse: grabbing cursor, no text/image select, and —
   the key bit — no scroll-snap and no smooth easing, so the row follows the
   hand exactly instead of fighting it back to a snap point. */
.related-slider.is-dragging {
    cursor: grabbing;
    scroll-behavior: auto;
    scroll-snap-type: none;
    user-select: none;
}

.related-slider.is-dragging img {
    pointer-events: none;
}

/* Chrome, Safari */
/* Each product-card cell becomes a fixed-width slide instead of a grid column.
   ~4 show on desktop; on a phone the next one peeks to hint that it scrolls. */
.related-slider>[class*="col-"] {
    flex: 0 0 auto;
    width: calc((100% - 3rem) / 4);
    min-width: 210px;
    max-width: 78%;
    padding: 0;
    scroll-snap-align: start;
}

.related-slider>[class*="col-"] .product-card {
    height: 100%;
}

@media (max-width: 575.98px) {
    .related-slider>[class*="col-"] {
        min-width: 150px;
        width: 62%;
    }
}

.product-card {
    border: 1px solid var(--brand-border);
    transition: transform .18s ease, box-shadow .18s ease;
}

.product-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 .75rem 2rem rgba(var(--brand-heading-rgb), .10) !important;
}

/* The square tile every product sits in.
   Filled edge to edge, and still showing the whole photo: a blown-up blurred
   copy does the filling, the real picture sits on top of it uncropped.
   "cover" alone cut the top off anything tall; "contain" alone left grey bars
   down the sides and made the product look small in its own tile. */
.product-card__media {
    position: relative;
    display: block;
    aspect-ratio: 1/1;
    overflow: hidden;
    background: var(--brand-surface);
}

.product-card__wash {
    position: absolute;
    /* Bled past every edge, so the blur has no soft border of its own. */
    inset: -10%;
    width: 120%;
    height: 120%;
    object-fit: cover;
    filter: blur(18px) saturate(1.15);
    opacity: .5;
    transform: scale(1.05);
    /* hides the transparent rim blur leaves */
}

.product-card .card-img-top {
    position: relative;
    /* above the wash */
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: none;
    /* the wash is the backdrop now */
}

.product-title {
    font-size: .95rem;
    font-weight: 700;
    color: var(--brand-body);
}

.product-title:hover {
    color: var(--brand-navy);
}

/* Sale price and the original always share a line — on a half-width card the
   two amounts used to wrap and read as two unrelated prices. Baseline
   alignment keeps the small struck-through figure sitting on the big one. */
.price-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: baseline;
    gap: .4rem;
    min-width: 0;
}

.price {
    color: var(--brand-navy);
    font-weight: 800;
    white-space: nowrap;
}

.price-old {
    color: var(--c-faint);
    font-weight: 400;
    font-size: .85rem;
    text-decoration: line-through;
    white-space: nowrap;
    /* Six-figure prices on a 320px screen are the one case that still can't
       fit: trim the older figure rather than push it out of the card. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* "৳500 সাশ্রয়" under the price — the amount kept, next to the % on the image. */
.price-saving {
    color: var(--brand-success, #15803d);
    font-size: .78rem;
    font-weight: 700;
    line-height: 1.2;
}

/* Percentage chip beside the price on the product page. */
.price-off {
    background: rgba(var(--brand-orange-rgb, 255, 90, 0), .12);
    color: var(--brand-orange);
    font-size: .78rem;
    font-weight: 700;
    padding: .1rem .45rem;
    border-radius: 999px;
    white-space: nowrap;
}

/* ---- Product cards on a phone ----
   Two per row leaves roughly 130px of content width, which everything here
   has to live inside. The pieces are trimmed rather than rearranged, so a
   card still reads the same as it does on a laptop. */
@media (max-width: 575.98px) {

    .product-card .card-body {
        padding: .7rem .65rem .8rem;
    }

    /* Two lines, then ellipsis — long Bangla names used to make one card
       twice the height of the one beside it. */
    .product-title {
        font-size: .88rem;
        line-height: 1.4;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* Two cards per row leave ~130px, which is not enough for two amounts
       side by side once either runs to five figures. On a phone the original
       price goes on its own line under the sale price, where it has room to
       be read properly. Desktop keeps them side by side. */
    .product-card .price-row {
        flex-direction: column;
        align-items: flex-start;
        gap: .1rem;
    }

    .product-card .price {
        font-size: 1.05rem;
    }

    .product-card .price-old {
        font-size: .85rem;
    }

    /* The discount badge shares the image with the wishlist heart. */
    .badge-sale {
        top: .4rem;
        left: .4rem;
        font-size: .7rem;
        padding: .2rem .45rem;
    }

    .card-rating {
        font-size: .78rem;
    }

    /* "কার্টে যোগ করুন" plus an icon overflows at this width — drop the icon
       and tighten the label instead of letting the button wrap. */
    .product-card .btn {
        padding: .5rem .4rem;
        font-size: .82rem;
        white-space: nowrap;
    }

    .product-card .btn i {
        display: none;
    }
}

/* The narrowest phones still in use (320px) leave ~115px per card. */
@media (max-width: 400px) {
    .product-card .price {
        font-size: .98rem;
    }

    .product-card .price-old {
        font-size: .8rem;
    }

    .product-card .card-body {
        padding: .6rem .55rem .7rem;
    }
}

.badge-sale {
    position: absolute;
    top: .6rem;
    left: .6rem;
    /* Above the tile's two images, which are positioned and come later in the
       markup — without this the discount hides behind the photo. The wishlist
       button next to it has always carried the same 2. */
    z-index: 2;
    background: var(--brand-navy);
    /* Holds an amount ("৳500 সাশ্রয়"), so keep it on one line and make sure
       it can never grow wider than the card image it sits on. */
    font-size: .78rem;
    font-weight: 700;
    white-space: nowrap;
    max-width: calc(100% - 1.2rem);
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}

/* =============================================================
   Wishlist heart
   ============================================================= */

.wish-form {
    margin: 0;
}

.wish-btn {
    display: inline-grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--brand-border);
    border-radius: 50%;
    background: #fff;
    color: var(--c-faint);
    font-size: 1.05rem;
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease, transform .15s ease;
}

.wish-btn:hover {
    color: var(--brand-danger);
    border-color: var(--c-danger-soft);
}

.wish-btn.is-saved {
    color: var(--brand-danger);
    border-color: var(--c-danger-soft);
    background: var(--c-danger-bg-soft);
}

.wish-btn.is-busy {
    opacity: .6;
    pointer-events: none;
}

/* Floating over a product card image */
.wish-btn--float {
    position: absolute;
    top: .6rem;
    right: .6rem;
    z-index: 2;
    width: 38px;
    height: 38px;
    font-size: .95rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
}

/* Full-width row on the product detail page — a modern outline button that
   fills with a soft red on hover / when saved, with the heart standing out. */
.wish-btn--wide {
    width: 100%;
    height: 52px;
    border-radius: .85rem;
    gap: 1rem;
    /* generous space between heart and text */
    grid-auto-flow: column;
    margin-bottom: .6rem;
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: .2px;
    border: 1.5px solid var(--brand-border);
    color: var(--brand-body);
    transition: color .18s ease, background-color .18s ease,
        border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}

.wish-btn--wide i {
    font-size: 1.25rem;
    color: var(--brand-danger);
    transition: transform .18s ease;
}

.wish-btn--wide:hover {
    background: var(--c-danger-bg-soft);
    border-color: var(--brand-danger);
    color: var(--brand-danger);
    transform: translateY(-1px);
    box-shadow: 0 8px 18px rgba(220, 38, 38, .14);
}

.wish-btn--wide:hover i {
    transform: scale(1.18);
}

.wish-btn--wide.is-saved {
    background: var(--c-danger-bg-soft);
    border-color: var(--brand-danger);
    color: var(--brand-danger);
}

.wish-btn--wide::after {
    content: "উইশলিস্টে রাখুন";
    font-size: .98rem;
}

.wish-btn--wide.is-saved::after {
    content: "উইশলিস্টে আছে";
}

.wish-btn.is-popped {
    animation: heartPop .4s ease;
}

@keyframes heartPop {
    35% {
        transform: scale(1.25);
    }

    70% {
        transform: scale(.92);
    }

    100% {
        transform: scale(1);
    }
}

@media (prefers-reduced-motion: reduce) {

    .wish-btn,
    .wish-btn.is-popped {
        transition: none;
        animation: none;
    }
}

/* =============================================================
   Newsletter (footer)
   ============================================================= */

/* The heading and blurb are styled by .footer-news__copy now — the form
   itself is all that is shared, so only its rules live here. */
.newsletter__form {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}

.newsletter__form input {
    flex: 1 1 200px;
    min-width: 0;
    padding: .6rem .9rem;
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: .5rem;
    background: rgba(255, 255, 255, .12);
    color: #fff;
    font: inherit;
}

.newsletter__form input::placeholder {
    color: rgba(255, 255, 255, .6);
}

.newsletter__form input:focus {
    outline: 0;
    background: rgba(255, 255, 255, .2);
    border-color: var(--brand-yellow);
}

.newsletter__form button {
    padding: .6rem 1.2rem;
    border: 0;
    border-radius: .5rem;
    background: var(--brand-orange);
    color: #fff;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.newsletter__form button:hover {
    background: var(--brand-orange-d);
}

.newsletter__msg {
    margin: .6rem 0 0;
    font-size: .9rem;
    font-weight: 600;
}

.newsletter__msg.is-ok {
    color: var(--c-success-soft);
}

.newsletter__msg.is-error {
    color: var(--c-danger-l);
}

/* =============================================================
   Cart page
   The item list is a CSS grid rather than a <table> so it can be
   re-flowed on small screens without horizontal scrolling.
   ============================================================= */

.cart-head,
.cart-row {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr) 116px 136px 116px 40px;
    align-items: center;
    gap: 1rem;
}

.cart-head {
    padding: .85rem 1.25rem;
    background: var(--brand-light);
    border-bottom: 1px solid var(--brand-border);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--brand-muted);
}

.cart-row {
    padding: 1.1rem 1.25rem;
    border-bottom: 1px solid var(--brand-border);
    transition: background-color .15s ease;
}

.cart-row:last-of-type {
    border-bottom: 0;
}

.cart-row:hover {
    background: var(--brand-surface);
}

.cart-row__media img {
    width: 92px;
    height: 92px;
    object-fit: contain;
    background: var(--brand-surface);
    border-radius: .75rem;
    background: var(--brand-surface);
    border: 1px solid var(--brand-border);
}

.cart-row__info {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
}

.cart-row__name {
    font-weight: 700;
    color: var(--brand-body);
    text-decoration: none;
    line-height: 1.35;
}

.cart-row__name:hover {
    color: var(--brand-navy);
}

.cart-row__variant {
    align-self: flex-start;
    background: var(--brand-light);
    color: var(--brand-gray);
    border-radius: 999px;
    padding: .1rem .6rem;
    font-size: .78rem;
}

.cart-row__unit {
    font-weight: 700;
    color: var(--brand-navy);
}

.cart-row__stock {
    font-size: .8rem;
    font-weight: 600;
}

.cart-row__stock--low {
    color: var(--brand-orange);
}

.cart-row__stock--out {
    color: var(--brand-danger);
}

.cart-row__total {
    font-weight: 800;
    color: var(--brand-navy);
    text-align: right;
}

/* Quantity stepper */
.qty-stepper {
    position: relative;
    /* contains the hidden Enter-catcher button */
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--brand-border);
    border-radius: 999px;
    overflow: hidden;
    background: #fff;
}

.qty-stepper button {
    width: 36px;
    height: 38px;
    border: 0;
    background: transparent;
    color: var(--brand-navy);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

.qty-stepper button:hover:not(:disabled) {
    background: var(--brand-light);
}

.qty-stepper button:disabled {
    opacity: .3;
    cursor: not-allowed;
}

/* Invisible catcher for Enter-key submits — see the note in cart.php */
.qty-stepper__default {
    position: absolute;
    width: 0;
    height: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
}

.qty-stepper input {
    width: 46px;
    height: 38px;
    border: 0;
    border-inline: 1px solid var(--brand-border);
    text-align: center;
    font-weight: 700;
    color: var(--brand-body);
    -moz-appearance: textfield;
    appearance: textfield;
}

.qty-stepper input:focus {
    outline: 0;
    background: var(--brand-light);
}

.qty-stepper input::-webkit-outer-spin-button,
.qty-stepper input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.cart-row__remove button {
    width: 38px;
    height: 38px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--c-faint);
    cursor: pointer;
}

.cart-row__remove button:hover {
    background: var(--c-danger-bg);
    color: var(--brand-danger);
}

/* Summary card */
.cart-summary-card {
    position: sticky;
    top: 96px;
}

.coupon-applied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    background: var(--c-success-bg-soft);
    border: 1px dashed var(--c-success-soft);
    border-radius: .6rem;
    padding: .6rem .85rem;
    color: var(--brand-success);
}

/* Delivery-area picker on checkout */
.delivery-options {
    display: grid;
    gap: .6rem;
}

.delivery-option {
    display: flex;
    align-items: center;
    gap: .6rem;
    border: 1px solid var(--brand-border-strong);
    border-radius: .6rem;
    padding: .7rem .9rem;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.delivery-option:hover {
    border-color: var(--brand-navy, var(--brand-navy));
}

.delivery-option:has(input:checked) {
    border-color: var(--brand-navy, var(--brand-navy));
    background: var(--brand-surface);
}

.delivery-option input {
    accent-color: var(--brand-navy, var(--brand-navy));
}

.delivery-option__name {
    flex: 1 1 auto;
    font-weight: 600;
}

.delivery-option__cost {
    font-weight: 700;
    white-space: nowrap;
}

/* Available (public) coupons listed on the cart */
.offer-chip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    background: var(--brand-surface);
    border: 1px dashed var(--brand-navy, var(--brand-navy));
    border-radius: .6rem;
    padding: .5rem .75rem;
    margin-bottom: .5rem;
}

.offer-chip__info strong {
    letter-spacing: .3px;
}

.offer-chip__apply {
    font-weight: 600;
    white-space: nowrap;
}

.cart-totals {
    display: grid;
    grid-template-columns: 1fr auto;
    row-gap: .6rem;
    column-gap: 1rem;
    margin: 0;
}

.cart-totals dt {
    font-weight: 500;
    color: var(--brand-gray);
}

.cart-totals dd {
    margin: 0;
    text-align: right;
    font-weight: 600;
}

.cart-grand {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 2px solid var(--brand-border);
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--brand-navy);
}

.cart-assurance li {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .3rem 0;
    font-size: .88rem;
    color: var(--brand-gray);
}

.cart-assurance i {
    color: var(--brand-orange);
    font-size: 1.05rem;
}

/* Empty state */
.cart-empty__icon {
    width: 92px;
    height: 92px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--brand-light);
    color: var(--brand-navy);
    font-size: 2.5rem;
}

/* Mobile: image spans two rows, quantity and line total sit underneath */
@media (max-width: 767.98px) {
    .cart-row {
        grid-template-columns: 76px minmax(0, 1fr) 38px;
        grid-template-areas:
            "media info   remove"
            "media qty    total";
        row-gap: .85rem;
        column-gap: .85rem;
        padding: 1rem;
    }

    .cart-row__media {
        grid-area: media;
        align-self: start;
    }

    .cart-row__info {
        grid-area: info;
    }

    .cart-row__qty {
        grid-area: qty;
    }

    .cart-row__total {
        grid-area: total;
    }

    .cart-row__remove {
        grid-area: remove;
        justify-self: end;
    }

    .cart-row__media img {
        width: 76px;
        height: 76px;
    }

    .cart-summary-card {
        position: static;
    }
}

/* ---- Footer ---- */
.site-footer {
    background: var(--footer-bg);
    color: var(--footer-text);
    font-size: 1.05rem;
    line-height: 1.8;
}

.site-footer h5 {
    color: var(--footer-heading);
    font-weight: 700;
    font-size: 1.35rem;
    margin-bottom: 1rem;
}

/* Short rule under every footer heading — drawn in the heading colour, so the
   footer reads as one calm block rather than a panel with orange stitching. */
.site-footer h5::after {
    content: "";
    display: block;
    width: 40px;
    height: 3px;
    background: var(--footer-heading);
    border-radius: 3px;
    margin-top: .5rem;
}

.site-footer a {
    color: var(--footer-text);
    text-decoration: none;
}

.site-footer a:hover {
    color: var(--brand-orange);
}

.footer-text {
    font-size: 1.05rem;
    line-height: 1.9;
}

.footer-top {
    border-bottom: 1px solid rgba(var(--footer-text-rgb), .18);
}

.footer-top .footer-text {
    max-width: 46rem;
}

/* ---- Newsletter band ---- */
.footer-news {
    border-bottom: 1px solid rgba(var(--footer-text-rgb), .18);
}

.footer-news__inner {
    display: grid;
    grid-template-columns: 1fr minmax(300px, 460px);
    align-items: center;
    gap: 1.25rem 2.5rem;
    padding: 1.6rem 0;
}

.footer-news__copy h5 {
    margin-bottom: .2rem;
    font-size: 1.25rem;
}

.footer-news__copy h5::after {
    display: none;
}

.footer-news__copy p {
    margin: 0;
    font-size: .98rem;
    color: var(--footer-text);
}

/* ---- Three-column grid ---- */
.footer-grid {
    display: grid;
    grid-template-columns: 1.8fr 1fr 1.3fr;
    gap: 2rem 2.5rem;
    padding: 2.5rem 0 2rem;
}

.footer-col h5 {
    font-size: 1.1rem;
    margin-bottom: .9rem;
}

.footer-about {
    font-size: .98rem;
    line-height: 1.85;
    max-width: 34rem;
    margin-bottom: 1.1rem;
}

.footer-links,
.footer-contact {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .98rem;
    line-height: 1.75;
}

.footer-links li {
    margin-bottom: .45rem;
}

.footer-links a {
    position: relative;
    display: inline-block;
    transition: transform .15s ease, color .15s ease;
}

/* Nudges right on hover — cheaper than an underline and reads as "go here" */
.footer-links a:hover {
    transform: translateX(3px);
}

.footer-contact li {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    margin-bottom: .6rem;
}

.footer-contact i {
    flex-shrink: 0;
    margin-top: .35rem;
    color: var(--footer-heading);
}

.footer-social {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}

.footer-brand .brand-mark {
    background: var(--footer-heading);
    color: var(--footer-bg);
    box-shadow: inset 0 -3px 0 var(--brand-orange);
}

.footer-brand .brand-text {
    color: var(--footer-heading);
    font-size: 1.6rem;
}

.footer-brand .brand-img {
    height: 44px;
    max-width: 260px;
}

.social-ic {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(var(--footer-text-rgb), .10);
    border: 1px solid rgba(var(--footer-text-rgb), .16);
    color: var(--footer-heading);
    font-size: 1.05rem;
    transition: background-color .15s ease, transform .15s ease;
}

/* Scoped under .site-footer so its white icon colour outranks the generic
   ".site-footer a:hover { color: orange }" rule — otherwise the icon turns
   orange on an orange background and vanishes. */
.site-footer .social-ic:hover {
    background: var(--brand-orange);
    border-color: var(--brand-orange);
    color: #fff;
    transform: translateY(-2px);
}

/* Copyright strip — no band of its own, just a hairline above it. */
.footer-bottom {
    background: transparent;
    border-top: 1px solid rgba(var(--footer-text-rgb), .18);
    color: rgba(var(--footer-text-rgb));
    font-size: .9rem;
}

.footer-bottom__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .35rem 1rem;
    padding: .6rem 0;
}

.footer-bottom .footer-credit {
    opacity: .85;
}

.footer-bottom a {
    color: var(--brand-yellow);
}

/* Tablet: three columns become two */
@media (max-width: 991.98px) {
    .footer-grid {
        grid-template-columns: 1fr 1fr;
        gap: 1.75rem 2rem;
        padding: 2rem 0 1.5rem;
    }

    .footer-col--brand {
        grid-column: 1 / -1;
    }

    .footer-news__inner {
        grid-template-columns: 1fr;
        gap: .9rem;
    }
}

/* Phone: one column, centred, and the whole footer sits above the sticky
   bottom bar rather than behind it. */
@media (max-width: 575.98px) {
    .footer-grid {
        grid-template-columns: 1fr;
        text-align: center;
        gap: 1.6rem;
    }

    .site-footer h5::after {
        margin-inline: auto;
    }

    .footer-about {
        margin-inline: auto;
    }

    .footer-social {
        justify-content: center;
    }

    .footer-brand .brand-logo {
        justify-content: center;
    }

    .footer-contact li {
        justify-content: center;
        text-align: left;
    }

    .footer-bottom__inner {
        justify-content: center;
        text-align: center;
    }
}

.place-items-center {
    place-items: center;
}

/* =============================================================
   Policy pages (privacy / terms / returns)
   ============================================================= */

.policy {
    font-size: 1.02rem;
    line-height: 1.9;
}

.policy__head {
    background: var(--brand-light);
    border: 1px solid var(--brand-border);
    border-radius: 1rem;
    padding: 1.75rem;
}

.policy__intro {
    color: var(--brand-gray);
    max-width: 68ch;
}

/* Sections */
.policy__section {
    scroll-margin-top: 96px;
    margin-bottom: 2.25rem;
}

.policy__section-title {
    display: flex;
    align-items: center;
    gap: .65rem;
    font-size: 1.2rem;
    margin-bottom: .75rem;
}

.policy__num {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--brand-navy);
    color: #fff;
    font-size: .85rem;
    font-weight: 700;
}

.policy__section p {
    color: var(--brand-gray);
    max-width: 72ch;
}

.policy__list {
    list-style: none;
    padding: 0;
    margin: 0 0 0 .15rem;
    max-width: 72ch;
}

.policy__list li {
    position: relative;
    padding-left: 1.6rem;
    margin-bottom: .5rem;
    color: var(--brand-gray);
}

/* Check mark drawn in CSS — no dependency on an icon-font codepoint */
.policy__list li::before {
    content: "";
    position: absolute;
    left: .3rem;
    top: .68rem;
    width: .4rem;
    height: .72rem;
    border: solid var(--brand-orange);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* Contact block */
.policy__contact {
    border: 1px solid var(--brand-border);
    border-left: 4px solid var(--brand-orange);
    border-radius: 1rem;
    background: var(--brand-light);
    padding: 1.5rem;
    margin-top: 2.5rem;
}

.policy__contact-list li {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .35rem;
}

.policy__contact-list i {
    color: var(--brand-navy);
}

.policy__contact-list a {
    color: var(--brand-navy);
    text-decoration: none;
}

.policy__contact-list a:hover {
    color: var(--brand-orange);
}

.policy__related {
    font-size: .92rem;
    color: var(--brand-gray);
}

/* =============================================================
   About us
   ============================================================= */

.about-section {
    padding: 4.5rem 0;
}

.about-section--tint {
    background: var(--brand-light);
}

/* Shared section header block */
.about-head {
    max-width: 44rem;
}

.about-head--center {
    margin-inline: auto;
    text-align: center;
}

.about-head h2 {
    font-size: clamp(1.65rem, 2.6vw, 2.15rem);
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--brand-heading);
    margin: 0 0 .75rem;
}

.about-head p {
    color: var(--brand-muted);
    font-size: 1.08rem;
    line-height: 1.8;
    margin: 0;
}

/* ---- Hero ---- */
.about-hero {
    background: var(--brand-navy);
    background-image: radial-gradient(circle at 82% 15%, rgba(255, 255, 255, .10), transparent 45%),
        radial-gradient(circle at 0% 100%, rgba(var(--brand-orange-rgb), .18), transparent 50%);
    color: #fff;
    padding: 2.25rem 0 7rem;
    /* extra room: the stats card overlaps the bottom */
}

/* No stats card to overlap — don't leave a gap under the hero. */
.about-hero--plain {
    padding-bottom: 4.5rem;
}

.about-hero .breadcrumb-item a {
    color: rgba(255, 255, 255, .75);
    text-decoration: none;
}

.about-hero .breadcrumb-item a:hover {
    color: var(--brand-yellow);
}

.about-hero .breadcrumb-item.active {
    color: rgba(255, 255, 255, .55);
}

.about-hero .breadcrumb-item+.breadcrumb-item::before {
    color: rgba(255, 255, 255, .35);
}

.about-hero__title {
    font-size: clamp(2rem, 4.2vw, 3.1rem);
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: 1.25;
    color: #fff;
    margin: 0 0 1rem;
}

.about-hero__lead {
    font-size: 1.15rem;
    line-height: 1.9;
    color: rgba(255, 255, 255, .82);
    max-width: 34rem;
    margin: 0;
}

/* ---- Framed images (hero + story) ---- */
.about-figure {
    position: relative;
    isolation: isolate;
}

/* Offset accent block behind the photo — the "designed" bit. */
.about-figure::before {
    content: "";
    position: absolute;
    z-index: -1;
    width: 62%;
    height: 62%;
    border-radius: 1.5rem;
}

.about-figure--hero::before {
    right: -1.1rem;
    bottom: -1.1rem;
    opacity: .9;
}

.about-figure--story::before {
    left: -1.1rem;
    top: -1.1rem;
    background: rgba(var(--brand-navy-rgb), .10);
}

.about-figure__img {
    display: block;
    width: 100%;
    aspect-ratio: 5/4;
    object-fit: cover;
    border-radius: 1.5rem;
    box-shadow: 0 24px 55px rgba(var(--brand-heading-rgb), .28);
}

.about-figure--story .about-figure__img {
    box-shadow: 0 18px 45px rgba(var(--brand-heading-rgb), .14);
}

/* Badge pinned to the story photo */
.about-badge {
    position: absolute;
    right: 1rem;
    bottom: -1.25rem;
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    max-width: 15rem;
    padding: .8rem 1.1rem;
    border-radius: 1rem;
    border: 4px solid #fff;
    background: var(--brand-navy);
    color: #fff;
    font-weight: 700;
    line-height: 1.35;
    box-shadow: 0 14px 30px rgba(var(--brand-navy-rgb), .28);
}

.about-badge i {
    color: var(--brand-yellow);
    font-size: 1.25rem;
}

/* ---- Numbers card, floating over the hero ---- */
.about-stats {
    position: relative;
    z-index: 2;
    margin-top: -4.5rem;
}

.about-stats__card {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: 1.5rem;
    padding: 1.75rem 1rem;
    box-shadow: 0 22px 50px rgba(var(--brand-heading-rgb), .12);
}

.about-stat {
    padding: .35rem 1.25rem;
    text-align: center;
}

.about-stat+.about-stat {
    border-left: 1px solid var(--brand-border);
}

.about-stat__value {
    display: block;
    font-size: 2.15rem;
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: 1.2;
    color: var(--brand-navy);
}

.about-stat__label {
    display: block;
    margin-top: .15rem;
    font-size: 1rem;
    color: var(--brand-muted);
}

/* ---- Story copy ---- */
.about-prose {
    font-size: 1.08rem;
    line-height: 1.95;
    color: var(--c-slate);
}

.about-prose p {
    margin-bottom: 1.1rem;
}

.about-prose p:last-child {
    margin-bottom: 0;
}

/* ---- Value cards ---- */
.about-value {
    position: relative;
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: 1.25rem;
    padding: 1.85rem 1.5rem;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

/* Brand hairline that reveals on hover */
.about-value::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--brand-navy), var(--brand-orange));
    opacity: 0;
    transition: opacity .18s ease;
}

.about-value:hover {
    transform: translateY(-5px);
    border-color: var(--brand-border);
    box-shadow: 0 .9rem 2.2rem rgba(var(--brand-heading-rgb), .10);
}

.about-value:hover::before {
    opacity: 1;
}

.about-value__icon {
    width: 58px;
    height: 58px;
    border-radius: 18px;
    display: grid;
    place-items: center;
    margin-bottom: 1.15rem;
    background: linear-gradient(135deg, rgba(var(--brand-navy-rgb), .09), rgba(var(--brand-orange-rgb), .12));
    color: var(--brand-navy);
    font-size: 1.6rem;
}

.about-value__title {
    font-size: 1.18rem;
    font-weight: 700;
    color: var(--brand-heading);
    margin-bottom: .5rem;
}

.about-value__text {
    font-size: 1rem;
    line-height: 1.75;
    color: var(--brand-muted);
}

/* ---- Team ---- */
.about-member {
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: 1.25rem;
    padding: 2rem 1.5rem 1.75rem;
    text-align: center;
    transition: transform .18s ease, box-shadow .18s ease;
}

.about-member:hover {
    transform: translateY(-5px);
    box-shadow: 0 .9rem 2.2rem rgba(var(--brand-heading-rgb), .10);
}

.about-member__photo {
    width: 118px;
    height: 118px;
    display: block;
    margin: 0 auto 1.1rem;
    border-radius: 50%;
    object-fit: cover;
    border: 5px solid #fff;
    box-shadow: 0 12px 28px rgba(var(--brand-heading-rgb), .16);
    background: var(--brand-light);
}

/* No photo uploaded yet — show the initial instead of a broken image. */
.about-member__photo--blank {
    display: grid;
    place-items: center;
    background: var(--brand-navy);
    color: #fff;
    font-size: 2.4rem;
    font-weight: 700;
}

.about-member__name {
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--brand-heading);
}

.about-member__role {
    font-size: 1rem;
    color: var(--brand-muted);
}

/* ---- Closing panel ---- */
.about-band {
    background: var(--brand-navy);
    background-image: radial-gradient(circle at 88% 12%, rgba(255, 255, 255, .10), transparent 45%),
        radial-gradient(circle at 5% 100%, rgba(var(--brand-orange-rgb), .22), transparent 55%);
    color: #fff;
    border-radius: 1.75rem;
    padding: 3.5rem 2rem;
    text-align: center;
    box-shadow: 0 22px 50px rgba(var(--brand-navy-rgb), .18);
}

.about-band h2 {
    color: #fff;
    font-weight: 800;
    font-size: clamp(1.6rem, 2.6vw, 2.1rem);
    letter-spacing: -.02em;
    margin-bottom: .85rem;
}

.about-band p {
    color: rgba(255, 255, 255, .82);
    font-size: 1.1rem;
    line-height: 1.8;
    max-width: 42rem;
    margin: 0 auto;
}

@media (max-width: 991.98px) {
    .about-section {
        padding: 3.25rem 0;
    }

    .about-hero {
        padding-bottom: 6rem;
    }

    .about-figure {
        margin-top: 1.5rem;
    }

    /* The body copy is sized for a wide column. On a phone the same sizes
       give ~30 characters a line, so the page turns into a long ribbon of
       short lines — step every paragraph down and tighten the leading. */
    .about-hero__lead {
        font-size: 1rem;
        line-height: 1.75;
    }

    .about-prose {
        font-size: .98rem;
        line-height: 1.8;
    }

    .about-head p,
    .about-band p {
        font-size: .98rem;
        line-height: 1.75;
    }

    .about-value__text {
        font-size: .94rem;
        line-height: 1.7;
    }

    /* ---- Stats card ----
       auto-fit was choosing three columns at tablet widths, which left a
       lone fourth figure on its own row still carrying the divider meant to
       sit between neighbours. Fixed at two columns below lg, it is always a
       tidy grid however many figures the shop enters. */
    .about-stats {
        margin-top: -3rem;
    }

    .about-stats__card {
        grid-template-columns: repeat(2, 1fr);
        gap: 0;
        padding: .5rem;
        border-radius: 1.1rem;
        box-shadow: 0 14px 34px rgba(var(--brand-heading-rgb), .10);
    }

    .about-stat {
        padding: .95rem .5rem;
        /* Long values would otherwise widen the column and squeeze its pair. */
        min-width: 0;
    }

    /* Rules drawn as a grid: down the middle, and under the first row. */
    .about-stat+.about-stat {
        border-left: 0;
    }

    .about-stat:nth-child(even) {
        border-left: 1px solid var(--brand-border);
    }

    .about-stat:nth-child(n+3) {
        border-top: 1px solid var(--brand-border);
    }

    .about-stat__value {
        font-size: 1.55rem;
    }

    .about-stat__label {
        font-size: .85rem;
        line-height: 1.4;
    }
}

@media (max-width: 575.98px) {

    /* One more step down on the narrowest screens. */
    .about-hero__lead,
    .about-prose,
    .about-head p,
    .about-band p {
        font-size: .93rem;
    }

    .about-value__text {
        font-size: .9rem;
    }

    /* Smallest screens: one more step down so "১০,০০০+" never wraps. */
    .about-stat__value {
        font-size: 1.35rem;
    }

    .about-stat__label {
        font-size: .78rem;
    }

    .about-stat {
        padding: .8rem .35rem;
    }

    .about-badge {
        right: .5rem;
        font-size: .95rem;
    }
}

/* ---- Back to top ---- */
/* =============================================================
   Floating cart — a link to the cart page carrying the live count
   and total. No drawer, no modal.
   ============================================================= */

.cart-fab {
    position: fixed;
    right: 1.25rem;
    bottom: 5rem;
    /* clears the back-to-top button */
    z-index: 1035;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    text-decoration: none;
}

.cart-fab__icon {
    position: relative;
    width: 58px;
    height: 58px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--brand-orange);
    color: #fff;
    font-size: 1.45rem;
    box-shadow: 0 10px 26px rgba(var(--brand-orange-rgb), .38);
    transition: transform .18s ease, background-color .18s ease;
}

.cart-fab:hover .cart-fab__icon {
    background: var(--brand-orange-d);
    transform: translateY(-2px);
}

.cart-fab__count {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 24px;
    height: 24px;
    padding: 0 .35rem;
    border-radius: 999px;
    background: var(--brand-navy);
    color: #fff;
    font-size: .78rem;
    font-weight: 700;
    line-height: 24px;
    text-align: center;
    box-shadow: 0 0 0 2px #fff;
}

/* Total sits directly under the icon */
.cart-fab__total {
    padding: .15rem .6rem;
    border-radius: 999px;
    background: var(--brand-navy);
    color: #fff;
    font-size: .8rem;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(var(--brand-navy-rgb), .3);
}

/* Empty cart: keep the icon as a shortcut, drop the noise around it */
.cart-fab.is-empty .cart-fab__count,
.cart-fab.is-empty .cart-fab__total {
    display: none;
}

/* Pops once whenever the count changes */
.cart-fab.is-bumped .cart-fab__icon {
    animation: cartBump .45s ease;
}

@keyframes cartBump {
    30% {
        transform: scale(1.16);
    }

    60% {
        transform: scale(.95);
    }

    100% {
        transform: scale(1);
    }
}

/* Toast */
.cart-toast {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    transform: translate(-50%, 1.5rem);
    z-index: 1090;
    max-width: min(420px, 92vw);
    padding: .7rem 1.15rem;
    border-radius: 999px;
    background: var(--c-success-d);
    color: #fff;
    font-weight: 600;
    font-size: .92rem;
    box-shadow: 0 12px 30px rgba(0, 0, 0, .25);
    opacity: 0;
    visibility: hidden;
    transition: opacity .22s ease, transform .22s ease, visibility .22s;
}

.cart-toast.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

.cart-toast.is-error {
    background: var(--c-danger-d);
}

/* Add-to-cart button while its request is in flight */
.is-busy {
    opacity: .65;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {

    .cart-fab,
    .cart-toast {
        transition: none;
    }
}

#toTop {
    position: fixed;
    right: 1.5rem;
    bottom: 1.25rem;
    display: none;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    z-index: 1030;
    background: var(--brand-navy);
    color: #fff;
    border: none;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .9), 0 6px 16px rgba(0, 0, 0, .25);
}

#toTop:hover {
    background: var(--brand-navy-d);
}

/* =============================================================
   Checkout
   ============================================================= */

.checkout {
    font-size: 1.08rem;
    line-height: 1.7;
}

/* ---- Cards ---- */
.checkout-card {
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: 1rem;
    padding: 1.5rem;
    margin-bottom: 1.25rem;
    box-shadow: 0 1px 2px rgba(var(--brand-heading-rgb), .04);
}

.checkout-card__title {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--brand-heading);
    margin-bottom: 1.25rem;
    padding-bottom: .85rem;
    border-bottom: 1px solid var(--brand-border);
}

.checkout-card__title i {
    color: var(--brand-orange);
}

.checkout-card__title .optional {
    font-size: 1rem;
    font-weight: 400;
    color: var(--c-slate-l);
}

.checkout .form-label {
    font-weight: 600;
    font-size: 1.08rem;
    color: var(--c-slate-d);
    margin-bottom: .35rem;
}

.checkout .req {
    color: var(--brand-orange);
}

.checkout .form-text {
    font-size: .95rem;
}

.checkout .form-check-label {
    font-size: 1.05rem;
}

.checkout .form-control {
    border-radius: .6rem;
    border-color: var(--brand-border-strong);
    padding: .7rem .95rem;
    font-size: 1.08rem;
}

.checkout .form-control:focus {
    border-color: var(--brand-navy);
    box-shadow: 0 0 0 .2rem rgba(var(--brand-navy-rgb), .12);
}

/* ---- Payment options ---- */
.pay-options {
    display: grid;
    gap: .75rem;
}

.pay-option {
    position: relative;
    display: block;
    cursor: pointer;
}

.pay-option input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.pay-option__body {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: .9rem 1rem;
    border: 2px solid var(--brand-border-strong);
    border-radius: .75rem;
    transition: border-color .15s ease, background-color .15s ease;
}

.pay-option:hover .pay-option__body {
    border-color: var(--c-on-navy);
}

.pay-option input:checked+.pay-option__body {
    border-color: var(--brand-navy);
    background: var(--brand-surface);
}

.pay-option input:focus-visible+.pay-option__body {
    box-shadow: 0 0 0 .2rem rgba(var(--brand-yellow-rgb), .35);
}

.pay-option__icon {
    width: 46px;
    height: 46px;
    flex: 0 0 auto;
    border-radius: .6rem;
    display: grid;
    place-items: center;
    background: var(--brand-light);
    color: var(--brand-navy);
    font-size: 1.35rem;
}

.pay-option input:checked+.pay-option__body .pay-option__icon {
    background: var(--brand-navy);
    color: #fff;
}

.pay-option__label {
    display: block;
    font-weight: 700;
    font-size: 1.12rem;
    color: var(--brand-body);
}

.pay-option__note {
    display: block;
    font-size: .98rem;
    color: var(--brand-muted);
}

/* ---- Thank-you page ---- */
.order-done__icon {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--c-success-bg);
    color: var(--brand-success);
    font-size: 2.1rem;
}

.order-done__number {
    display: inline-block;
    padding: .55rem 1.1rem;
    border-radius: .6rem;
    background: var(--brand-light);
    font-size: 1.08rem;
}

/* ---- Manual payment instructions (bKash / Nagad / Rocket / bank) ----
   Hidden until its own radio is selected, so the panel needs no JavaScript. */
.pay-detail {
    display: none;
    margin: -2px 0 0;
    /* sit flush on the option's own border */
    padding: 1.1rem 1.15rem;
    border: 2px solid var(--brand-navy);
    border-top: 0;
    border-radius: 0 0 .75rem .75rem;
    background: var(--brand-surface);
}

.pay-option input:checked~.pay-detail {
    display: block;
}

/* Same panel outside a radio group (thank-you page) — always visible. */
.pay-detail--static {
    display: block;
    margin: 0;
    border-top: 2px solid var(--brand-navy);
    border-radius: .75rem;
}

/* Square off the option body where the panel joins it. */
.pay-option input:checked~.pay-option__body:has(+ .pay-detail) {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.pay-detail__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.pay-detail__label {
    display: block;
    font-size: .95rem;
    color: var(--brand-muted);
}

.pay-detail__account {
    display: block;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: .01em;
    color: var(--brand-navy);
    user-select: all;
    /* easy to select on a phone */
}

.pay-detail__copy {
    border: 1px solid var(--brand-navy);
    background: #fff;
    color: var(--brand-navy);
    border-radius: .55rem;
    padding: .45rem .9rem;
    font: inherit;
    font-size: .98rem;
    font-weight: 600;
    cursor: pointer;
}

.pay-detail__copy:hover {
    background: var(--brand-navy);
    color: #fff;
}

.pay-detail__amount {
    display: block;
    margin-top: .6rem;
    font-size: 1.02rem;
    color: var(--c-slate-d);
}

.pay-detail__amount strong {
    color: var(--brand-orange);
}

.pay-detail__list {
    display: block;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px dashed var(--c-divider);
}

/* One instruction per row, with a CSS bullet so the text can wrap without the
   marker dragging along. */
.pay-detail__list span {
    display: block;
    position: relative;
    padding-left: 1.1rem;
    font-size: 1rem;
    line-height: 1.75;
    color: var(--c-slate);
    overflow-wrap: anywhere;
}

.pay-detail__list span::before {
    content: "";
    position: absolute;
    left: 0;
    top: .72em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--brand-orange);
}

/* The redirect notice for an online gateway needs no bullet, just its icon. */
.pay-detail--online .pay-detail__list {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.pay-detail--online .pay-detail__list span {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding-left: 0;
}

.pay-detail--online .pay-detail__list span::before {
    content: none;
}

.pay-detail--online i {
    color: var(--brand-success);
    font-size: 1.15rem;
    line-height: 1.6;
}

/* ---- Order summary ---- */
.checkout-summary {
    position: sticky;
    top: 6rem;
}

.summary-items {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
    max-height: 22rem;
    overflow-y: auto;
}

.summary-item {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .75rem 0;
    border-bottom: 1px dashed var(--brand-border);
}

.summary-item:first-child {
    padding-top: 0;
}

.summary-item__thumb {
    position: relative;
    flex: 0 0 auto;
}

.summary-item__thumb img {
    width: 64px;
    height: 64px;
    object-fit: contain;
    background: var(--brand-surface);
    border-radius: .6rem;
    border: 1px solid var(--brand-border);
    background: var(--brand-surface);
}

.summary-item__qty {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 22px;
    height: 22px;
    padding: 0 .3rem;
    border-radius: 999px;
    display: grid;
    place-items: center;
    background: var(--brand-navy);
    color: #fff;
    font-size: .75rem;
    font-weight: 700;
}

.summary-item__info {
    flex: 1;
    min-width: 0;
}

.summary-item__name {
    display: block;
    font-weight: 600;
    font-size: 1.06rem;
    color: var(--brand-body);
    text-decoration: none;
    line-height: 1.45;
}

.summary-item__name:hover {
    color: var(--brand-navy);
}

.summary-item__variant,
.summary-item__unit {
    display: block;
    font-size: .95rem;
    color: var(--c-slate-l);
}

.summary-item__total {
    font-weight: 700;
    font-size: 1.06rem;
    color: var(--brand-navy);
    white-space: nowrap;
}

/* Room above the sums. The coupon box sits directly on top of them, and with
   no gap "সাবটোটাল" read as part of that form rather than as the first line of
   the bill. */
.summary-totals {
    margin-top: 1.1rem;
}

.summary-totals p {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin: 0 0 .5rem;
    font-size: 1.08rem;
    color: var(--c-slate);
}

.summary-totals__grand {
    margin: .75rem 0 0 !important;
    padding-top: .75rem;
    border-top: 1px solid var(--brand-border);
    font-size: 1.35rem !important;
    font-weight: 800;
    color: var(--brand-navy) !important;
}

.checkout .btn-lg {
    font-size: 1.15rem;
    font-weight: 700;
    padding: .8rem 1rem;
}

.summary-back {
    display: block;
    text-align: center;
    margin-top: .75rem;
    font-size: 1.02rem;
    color: var(--brand-muted);
    text-decoration: none;
}

.summary-back:hover {
    color: var(--brand-navy);
}

.summary-trust {
    list-style: none;
    padding: 1rem 0 0;
    margin: 1rem 0 0;
    border-top: 1px solid var(--brand-border);
    display: grid;
    gap: .5rem;
}

.summary-trust li {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: 1rem;
    color: var(--brand-muted);
}

.summary-trust i {
    color: var(--brand-success);
}

@media (max-width: 991.98px) {
    .checkout-summary {
        position: static;
    }

    .checkout-card {
        padding: 1.15rem;
    }
}

/* Bot trap: a field only a script would fill in. Kept out of the layout and
   out of the tab order — never shown to, or reachable by, a real visitor. */
.spam-trap {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

/* ==========================================================================
   Breadcrumbs — one rule for every page
   ==========================================================================
   Bootstrap underlines links by default, which on a breadcrumb turns a quiet
   trail into a row of shouting blue links. Only .shop-head and .about-hero
   used to override it, so the product, policy and wishlist pages showed the
   underline. This styles the component itself, so any breadcrumb added later
   inherits it too.                                                          */

.breadcrumb {
    font-size: .85rem;
    margin-bottom: .75rem;
    align-items: center;
}

.breadcrumb a {
    color: var(--brand-gray);
    text-decoration: none;
    border-radius: 4px;
    padding: .05rem .15rem;
    transition: color .15s ease;
}

.breadcrumb a:hover,
.breadcrumb a:focus-visible {
    color: var(--brand-orange);
    text-decoration: none;
}

.breadcrumb a:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
}

/* The page you are on: readable, but clearly not a link. */
.breadcrumb .breadcrumb-item.active {
    color: var(--brand-heading);
    font-weight: 600;
}

/* A softer separator than Bootstrap's default slash. */
.breadcrumb .breadcrumb-item+.breadcrumb-item::before {
    content: "\203A";
    /* › */
    color: var(--brand-muted);
    padding-inline: .1rem;
}

/* ==========================================================================
   Auth pages (login / register / forgot / reset)
   ========================================================================== */

.auth-intro {
    text-align: center;
    color: var(--brand-muted);
    font-size: .93rem;
    margin: -.35rem 0 1.5rem;
}

.auth-hint {
    display: block;
    margin-top: .3rem;
    font-size: .82rem;
    font-weight: 400;
    color: var(--brand-muted);
}

/* No underlines here either — a coloured, weighted word reads as a link
   without the ruled line under every one of them. */
.auth-page a,
.auth-alt a,
.auth-forgot a {
    color: var(--brand-navy);
    font-weight: 600;
    text-decoration: none;
    transition: color .15s ease;
}

.auth-page a:hover,
.auth-page a:focus-visible {
    color: var(--brand-orange);
    text-decoration: none;
}

.auth-page a:focus-visible {
    outline: 2px solid var(--brand-orange);
    outline-offset: 2px;
    border-radius: 4px;
}

/* "Forgot your password?" is secondary — keep it quiet until hovered. */
.auth-forgot a {
    color: var(--brand-muted);
    font-weight: 500;
}

/* =============================================================
   Mobile shell — search-only header + sticky bottom bar
   -------------------------------------------------------------
   On a phone the top of the screen is the worst place for
   navigation and the best place for search, so they swap: the
   header keeps only the search box, and Home / Support / Cart /
   Account / Menu move to a thumb-height bar pinned to the bottom.
   ============================================================= */

/* ---- The bar itself ---- */
.tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1040;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    align-items: center;
    background: var(--brand-navy);
    /* Sits above the iOS home indicator instead of under it. */
    padding-bottom: env(safe-area-inset-bottom, 0);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .18);
}

.tabbar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .15rem;
    padding: .5rem .25rem .55rem;
    background: none;
    border: none;
    color: rgba(255, 255, 255, .82);
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    /* Comfortably tappable whatever the label length. */
    min-height: 56px;
}

.tabbar__item i {
    font-size: 1.25rem;
    line-height: 1;
}

.tabbar__item:hover,
.tabbar__item:focus-visible {
    color: #fff;
}

/* Active tab, and "মেনু" while the menu it opens is showing — Bootstrap sets
   aria-expanded on the toggle, so the state needs no JavaScript of ours. */
.tabbar__item.is-active,
.tabbar__item[aria-expanded="true"] {
    color: var(--brand-yellow);
}

/* The middle cell is empty — the cart button is positioned over it. */
.tabbar__gap {
    display: block;
}

@media (max-width: 991.98px) {

    /* Room for the fixed bar, made by the footer rather than by padding the
       body. Body padding sits outside the footer, so the page background
       showed through as a white strip between the navy footer and the bar;
       growing the footer instead means the space behind and around the bar is
       always the footer's own colour. */
    body {
        padding-bottom: 0;
    }

    .site-footer {
        padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    }

    /* The floating cart becomes the bar's raised middle button. */
    .cart-fab {
        right: auto;
        left: 50%;
        bottom: 14px;
        transform: translateX(-50%);
        z-index: 1045;
    }

    .cart-fab__icon {
        width: 54px;
        height: 54px;
        font-size: 1.35rem;
        /* Ring in the bar's colour, so the button reads as part of it. */
        box-shadow: 0 0 0 5px var(--brand-navy), 0 8px 18px rgba(0, 0, 0, .28);
    }

    .cart-fab:hover .cart-fab__icon {
        transform: none;
    }

    /* No room for the total pill beside four labels — the count is enough. */
    .cart-fab__total {
        display: none;
    }

    /* Keep the helpers clear of the bar. The ring matters now that the button
       can sit against the navy footer — without it the navy circle vanishes. */
    #toTop {
        bottom: calc(70px + env(safe-area-inset-bottom, 0px));
        box-shadow: 0 0 0 2px rgba(255, 255, 255, .9), 0 6px 16px rgba(0, 0, 0, .25);
    }

    .cart-toast {
        bottom: calc(78px + env(safe-area-inset-bottom, 0px));
    }

    /* The collapsed menu opens from the bar; give it room to breathe. */
    .site-nav .navbar-collapse {
        padding-bottom: .5rem;
    }
}

/* =============================================================
   Editable basket inside the checkout summary
   -------------------------------------------------------------
   The cart page is gone: quantities, removal and coupons all
   happen in the summary column, so each row carries its own
   controls under the product name.
   ============================================================= */

.summary-item__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-top: .45rem;
}

/* Compact stepper — the summary column is narrower than the old cart table. */
.qty-stepper--sm button {
    width: 30px;
    height: 32px;
    font-size: 1rem;
}

.qty-stepper--sm input {
    width: 38px;
    height: 32px;
    font-size: .92rem;
}

.summary-item__remove button {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 1px solid var(--brand-border);
    border-radius: 50%;
    background: #fff;
    color: var(--c-slate-l);
    font-size: .95rem;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}

.summary-item__remove button:hover {
    color: var(--brand-danger, #dc2626);
    border-color: currentColor;
    background: rgba(220, 38, 38, .06);
}

/* The list grows with the basket now that it is the only place to edit it. */
.summary-items {
    max-height: none;
    overflow: visible;
}

/* Struck-through original price sits beside the unit price, not under it. */
.summary-item__unit .price-old {
    margin-left: .35rem;
    font-size: .82rem;
}

/* Count next to the summary heading ("৩টি পণ্য"). */
.checkout-card__title .optional {
    margin-left: auto;
    font-size: .85rem;
    font-weight: 500;
    color: var(--c-slate-l);
}

/* =============================================================
   Responsive clean-up
   ============================================================= */

/* Wide tables scroll inside their own box instead of stretching the page. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table-scroll>table {
    min-width: 520px;
}

@media (max-width: 991.98px) {

    /* The summary is the basket — it belongs above the address form on a
       phone, where the customer expects to check the order first. */
    .checkout-summary {
        position: static;
    }

    .row>.checkout-summary,
    .row>div>.checkout-summary {
        margin-bottom: 0;
    }
}

@media (max-width: 575.98px) {

    /* Row parts shrink so name, controls and line total still fit. */
    .summary-item__thumb img {
        width: 54px;
        height: 54px;
    }

    .summary-item__name {
        font-size: .95rem;
    }

    .summary-item__variant,
    .summary-item__unit {
        font-size: .85rem;
    }

    .summary-item__total {
        font-size: .95rem;
    }

    .summary-totals p {
        font-size: 1rem;
    }

    .summary-totals__grand {
        font-size: 1.15rem !important;
    }

    .checkout-card {
        padding: 1rem;
    }

    .checkout .btn-lg {
        font-size: 1.02rem;
    }

    /* Long Bangla headings were pushing the page sideways. */
    .section-title,
    .checkout-card__title {
        overflow-wrap: anywhere;
    }
}

/* ==========================================================================
   Vertically centred pages
   ==========================================================================
   For short pages — contact, order tracking — whose content otherwise sits
   pinned under the header with a lot of empty space beneath it.

   <main> already stretches to fill the viewport (see the sticky-footer rules
   on body), so centring is just a matter of how it lays its children out.
   justify-content on a column flex is safe here: main's flex-basis is auto,
   so a page whose content is taller than the screen simply makes main taller
   and nothing is ever pushed off the top.                                   */

.site-main--center {
    display: flex;
    flex-direction: column;
    justify-content: center;

    /* Generous breathing room above and below. The footer on this theme is
       tall, so justify-content on its own barely moves anything — main has
       little spare height left to centre within. This padding is what
       actually lifts the content off the header and drops it into the middle
       of the screen. clamp() keeps it proportional: never less than 3rem,
       never so much that a laptop has to scroll to reach the form. */
    padding-block: clamp(3rem, 9vh, 7rem);
}

/* On a phone the header, the form and the on-screen keyboard already fill the
   screen; centring there just adds scrolling, so it only applies from tablet up. */
@media (max-width: 767.98px) {
    .site-main--center {
        display: block;
        padding-block: 2rem;
    }
}

/* =============================================================
   Searchable select (.combo)
   -------------------------------------------------------------
   A <select data-combo> is replaced on screen by a button and a
   drop-down with a search box. The real <select> is still in the
   form — hidden, not removed — so the page keeps working with
   JavaScript off and posts exactly the same value.
   ============================================================= */
.combo {
    position: relative;
    display: block;
}

.combo select.combo__native {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.combo__field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: 100%;
    padding: .6rem .75rem;
    border: 1px solid var(--combo-border, #cbd5e1);
    border-radius: 10px;
    background: #fff;
    font: inherit;
    text-align: left;
    color: inherit;
    cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.combo__field.is-empty {
    color: var(--c-faint);
}

.combo__field:hover {
    border-color: var(--combo-accent, #002b7f);
}

.combo.is-open .combo__field,
.combo__field:focus-visible {
    outline: 0;
    border-color: var(--combo-accent, #002b7f);
    box-shadow: 0 0 0 3px var(--combo-ring, rgba(0, 43, 127, .12));
}

.combo__value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.combo__caret {
    flex: 0 0 auto;
    font-size: .8rem;
    opacity: .6;
    transition: transform .15s ease;
}

.combo.is-open .combo__caret {
    transform: rotate(180deg);
}

.combo__panel {
    position: absolute;
    z-index: 60;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: #fff;
    border: 1px solid var(--combo-border, #cbd5e1);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .16);
    overflow: hidden;
}

.combo__search {
    display: block;
    width: 100%;
    padding: .6rem .75rem;
    border: 0;
    border-bottom: 1px solid var(--combo-border, #cbd5e1);
    font: inherit;
    outline: 0;
}

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

.combo__group {
    padding: .45rem .6rem .2rem;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--c-slate-l);
}

.combo__option {
    padding: .5rem .6rem;
    border-radius: 7px;
    cursor: pointer;
    font-size: .93rem;
}

.combo__option:hover {
    background: var(--brand-light);
}

.combo__option.is-selected {
    background: var(--hero-sticky);
    color: #fff;
    font-weight: 600;
}

.combo__none {
    padding: .85rem .75rem;
    color: var(--c-slate-l);
    font-size: .88rem;
    text-align: center;
}

/* A required combo the customer skipped. */
.combo.is-invalid .combo__field {
    border-color: var(--brand-danger);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .12);
}

/* =====================================================================
   Tracking consent bar
   ---------------------------------------------------------------------
   Shown only to a visitor the shop has to ask — outside Bangladesh, and
   not yet answered. Fixed to the bottom rather than covering the page:
   a shopper who wants to keep reading can, and the shop is not holding
   its own catalogue hostage for an answer.
   ===================================================================== */
.consent {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1080;
    background: var(--brand-heading);
    color: var(--c-on-navy);
    box-shadow: 0 -8px 30px rgba(6, 14, 33, .35);
    animation: consentIn .28s ease both;
}

@keyframes consentIn {
    from {
        transform: translateY(100%);
    }

    to {
        transform: none;
    }
}

.consent__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: .95rem 1.1rem;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.consent__text {
    flex: 1 1 22rem;
    display: flex;
    gap: .7rem;
    margin: 0;
    font-size: .87rem;
    line-height: 1.55;
}

.consent__icon {
    font-size: 1.1rem;
    color: var(--brand-yellow, #FFC400);
    margin-top: .1rem;
}

.consent__text strong {
    display: block;
    color: #fff;
    margin-bottom: .15rem;
}

.consent__text a {
    color: #fff;
    text-decoration: underline;
}

.consent__buttons {
    display: flex;
    gap: .6rem;
    margin-left: auto;
}

.consent__buttons form {
    margin: 0;
}

/* Both the same size: the safe answer must not be the harder one to press. */
.consent__btn {
    min-width: 8.5rem;
    padding: .6rem 1.2rem;
    border-radius: 8px;
    border: 1px solid transparent;
    font: inherit;
    font-size: .88rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
}

.consent__btn--no {
    background: transparent;
    border-color: rgba(255, 255, 255, .35);
    color: #fff;
}

.consent__btn--no:hover {
    background: rgba(255, 255, 255, .1);
}

.consent__btn--yes {
    background: var(--brand-orange, #FF5A00);
    color: #fff;
}

.consent__btn--yes:hover {
    filter: brightness(1.08);
}

@media (max-width: 640px) {
    .consent__inner {
        padding: .85rem .9rem;
        gap: .8rem;
    }

    .consent__buttons {
        margin-left: 0;
        width: 100%;
    }

    .consent__btn {
        flex: 1;
        min-width: 0;
    }
}

/* The bar sits over the sticky bottom bar on phones, so lift that clear. */
@media (max-width: 991.98px) {
    body:has(.consent) .tabbar {
        bottom: auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .consent {
        animation: none;
    }
}

/* ==========================================================================
   Product gallery: video slides
   ==========================================================================
   A video sits in the thumbnail strip beside the photos. It is a <button>
   rather than an <img> — pressing it swaps the frame for a player instead of
   swapping one picture for another — so it needs the picture's own dimensions
   putting back, which a button does not inherit.                             */

.pd-thumb--video {
    position: relative;
    padding: 0;
    border: 1px solid var(--brand-border);
    background: var(--brand-heading);
    overflow: hidden;
    cursor: pointer;
}

.pd-thumb--video img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Vimeo and Facebook give no thumbnail, so the tile shows through. */
    opacity: .75;
}

/* The play mark, centred over whatever is behind it. */
.pd-thumb__play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 1.6rem;
    text-shadow: 0 1px 6px rgba(0, 0, 0, .55);
    pointer-events: none;
}

.pd-thumb--video:hover .pd-thumb__play,
.pd-thumb--video.is-active .pd-thumb__play {
    color: var(--brand-orange);
}

/* The player takes the space the main picture had, at the same aspect ratio,
   so nothing on the page jumps when the two swap. */
/* Exactly the picture's frame — same ratio, same border, same corners.
   Anything else and the page jumps as the shopper moves between a photo and
   the video. A 16:9 clip is letterboxed inside it, which is the price of the
   frame holding still. @see .pd-main */
.pd-main-video {
    width: 100%;
    aspect-ratio: 1/1;
    background: #000;
    border: 1px solid var(--brand-border);
    border-radius: 1rem;
    overflow: hidden;
}

/* contain, not cover: a product video cropped to a square would cut the
   product out of its own picture. */
.pd-main-video video {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
    background: #000;
}



/* A video thumbnail showing its own first frame — same fit as a photo tile. */
.pd-thumb--video video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    pointer-events: none;
}

/* ==========================================================================
   Hero picture: a light that travels round the edge
   ==========================================================================
   A conic gradient is painted behind the picture and slowly rotated; the
   picture sits on top and covers everything but a few pixels of rim, so what
   shows is a bright point running around the border.

   Done this way rather than with an animated border-image because a gradient
   border cannot be animated directly — border-image takes no transition, and
   @property (which would let a gradient angle animate) is still missing from
   enough browsers to matter for a shop.                                      */

.hero-frame {
    /* The one number that sets how thick the travelling rim looks. The image's
       own corner radius is derived from it below, so changing it here keeps
       the two curves concentric instead of leaving a pale sliver. */
    --hero-frame-w: 5px;
    position: relative;
    padding: var(--hero-frame-w);
    border-radius: 1.4rem;
    overflow: hidden;
    /* The rim is only visible against the frame's own backdrop, so give it
       one — otherwise the gradient shows through the corners' rounding. */
    background: var(--hero-bg);
    isolation: isolate;
}

.hero-frame::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    /* Square and generously larger than the frame, so a rotating gradient
       still covers the corners of a wide picture. */
    width: 200%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    background: conic-gradient(from 0deg,
            transparent 0deg 200deg,
            rgba(var(--brand-orange-rgb), .35) 250deg,
            var(--brand-orange) 300deg,
            #fff 330deg,
            var(--brand-orange) 345deg,
            transparent 360deg);
    animation: hero-frame-spin 5s linear infinite;
}

/* Above the gradient — this is what leaves only the rim showing. */
.hero-frame>.hero-img {
    position: relative;
    display: block;
    border-radius: calc(1.4rem - var(--hero-frame-w));
}

/* Thinner on a phone: the same 7px around a much smaller picture reads as a
   heavy border rather than a light travelling round it. */
@media (max-width: 575.98px) {
    .hero-frame {
        --hero-frame-w: 5px;
    }
}

@keyframes hero-frame-spin {
    to {
        transform: translate(-50%, -50%) rotate(1turn);
    }
}

/* A moving light in the corner of the eye is exactly what this setting is
   for. The rim stays, it simply stops travelling. */
@media (prefers-reduced-motion: reduce) {
    .hero-frame::before {
        animation: none;
    }
}

/* ===== Homepage category rail =====
   One row of picture tiles that scrolls sideways. A rail, not a grid: a shop
   with twenty categories should not push its products a screen and a half
   down the page, and sideways is the gesture a phone reaches for anyway.
   A tile is one <a>, so picture and name are the same tap target rather than
   two near misses. */
.cat-section {
    background: var(--brand-light);
}

.cat-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}

.cat-head__tools {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.cat-arrows {
    display: flex;
    gap: .4rem;
}

.cat-arrow {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: #fff;
    color: var(--brand-navy);
    border: 1px solid var(--brand-border);
    border-radius: 50%;
    line-height: 1;
    transition: background .18s ease, color .18s ease, border-color .18s ease, opacity .18s ease;
}

.cat-arrow:hover:not(:disabled) {
    background: var(--brand-navy);
    border-color: var(--brand-navy);
    color: #fff;
}

.cat-arrow:disabled {
    opacity: .35;
    cursor: default;
}

/* ---- the rail itself ---- */
.cat-rail {
    /* How many tiles fill the width, and the space between them. Every card
       width below is derived from these two, so a breakpoint only has to
       change the count. */
    --cat-per: 6;
    --cat-gap: .85rem;

    display: flex;
    gap: var(--cat-gap);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    /* Room for the lift on hover, which the scroll container would otherwise
       clip, and for the shadow under it. */
    padding: .35rem .25rem 1rem;
    margin: 0 -.25rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* the arrows and dragging are the controls */
    cursor: grab;
}

.cat-rail::-webkit-scrollbar {
    display: none;
}

/* While a drag is in progress: the closed hand, no snapping and no smooth
   easing, so the row follows the hand exactly instead of being pulled back.
   Same shape as .related-slider, which does this on the product page. */
.cat-rail.is-dragging {
    cursor: grabbing;
    scroll-behavior: auto;
    scroll-snap-type: none;
    user-select: none;
}

/* Images only — putting the whole rail behind pointer-events:none is what
   stopped a plain click ever reaching a tile. */
.cat-rail.is-dragging img {
    pointer-events: none;
}

/* ---- the tile ----
   A white card on the section's tinted ground, so each category is a discrete
   object rather than a photo floating loose. The border is what carries the
   hover — a shadow alone reads as "raised", a colour reads as "this one". */
.cat-card {
    flex: 0 0 calc((100% - (var(--cat-per) - 1) * var(--cat-gap)) / var(--cat-per));
    scroll-snap-align: start;
    display: block;
    padding: .4rem .4rem .1rem;
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: .9rem;
    text-decoration: none;
    color: inherit;
    transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease;
}

.cat-card:hover,
.cat-card:focus-visible {
    transform: translateY(-3px);
    border-color: rgba(var(--brand-orange-rgb), .5);
    box-shadow: 0 .7rem 1.4rem rgba(var(--brand-navy-rgb), .13);
    color: inherit;
}

/* ---- the picture ---- */
.cat-card__art {
    position: relative;
    display: grid;
    place-items: center;
    /* Not square. Category pictures are nearly always wide — a banner, a
       shelf, a flat-lay — and cropping one to a square throws away most of it. */
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: .6rem;
    background: linear-gradient(135deg, var(--brand-navy), var(--brand-orange));
}

.cat-card__art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.cat-card__letter {
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1;
    color: #fff;
}

.cat-card__name {
    display: block;
    padding: .5rem .25rem .55rem;
    font-size: .88rem;
    font-weight: 600;
    text-align: center;
    color: var(--brand-heading);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color .18s ease;
}

.cat-card:hover .cat-card__name {
    color: var(--brand-orange);
}

/* ---- how many fit ----
   Fractions on the narrower sizes on purpose: the sliver of the next tile is
   what tells a thumb there is more to the right, and it does the job of the
   scrollbar the rail deliberately hides. */
@media (max-width: 1199.98px) {
    .cat-rail {
        --cat-per: 5;
    }
}

@media (max-width: 991.98px) {
    .cat-rail {
        --cat-per: 4.4;
    }
}

@media (max-width: 767.98px) {
    .cat-rail {
        --cat-per: 3.4;
    }
}

@media (max-width: 575.98px) {
    .cat-rail {
        --cat-per: 2.6;
        --cat-gap: .6rem;
    }

    .cat-card__name {
        font-size: .8rem;
    }

    .cat-card__letter {
        font-size: 1.5rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .cat-card {
        transition: none;
    }

    .cat-card:hover {
        transform: none;
    }
}