/* =============================================================================
   VFincu Storefront Design System
   =============================================================================

   Loaded LAST in resources/views/frontend/layouts/style.blade.php so it wins the
   cascade without editing the three legacy stylesheets it sits on top of:
       public/syaanah/css/minimal.css
       public/asoug/css/minimal.css
       public/asoug/css/style.css
       public/asoug/css/footer.css

   Two rules keep this file from breaking the ~110 pages it did not redesign:

   1. Every token is prefixed --vf-. The legacy :root in public/asoug/css/style.css
      declares --primary, --secondary, --surface and ~25 more, and legacy CSS reads
      them. Redefining those names here would restyle the entire storefront by
      accident. We never touch them; we shadow nothing.

   2. Component classes are new names (.vf-*) or names this project already owns
      (.product-card, .price). We do not restyle bare Bootstrap element selectors.

   Brand colours are taken from the existing palette, not invented:
       --primary   #14003F  (public/asoug/css/style.css:21)
       --secondary #FFEB3B  (public/asoug/css/style.css:25)

   RTL: the storefront ships an Arabic-first layout (<html dir> is driven by
   session('lang_dir')). Every rule below uses logical properties — inline-start /
   inline-end — never left / right. See the LOGICAL PROPERTIES note before adding
   anything.
   ========================================================================== */


/* -----------------------------------------------------------------------------
   1. TOKENS
   -----------------------------------------------------------------------------
   Moved to public/assets/global/css/vf-tokens.css so the admin panel can share
   one palette rather than keeping a second copy of it that would drift. That
   file also carries the dark-mode ramp ([data-bs-theme="dark"]) and the
   self-hosted Roboto / IBM Plex Sans Arabic stacks.

   THIS FILE DEPENDS ON IT. vf-tokens.css must be linked BEFORE design-system.css
   — resources/views/frontend/layouts/style.blade.php does that. Every --vf-*
   name read below is defined there, and nothing here redefines one.
   -------------------------------------------------------------------------- */


/* -----------------------------------------------------------------------------
   2. LOGICAL PROPERTIES / RTL
   -----------------------------------------------------------------------------
   Everything below this line uses margin-inline-*, padding-inline-*, inset-inline-*
   and border-inline-*. Do not add left/right rules to this file. If you need a
   direction-specific override, use [dir="rtl"] explicitly and say why.
   -------------------------------------------------------------------------- */

[dir="rtl"] body,
[dir="rtl"] .vf-font-brand {
    font-family: var(--vf-font-arabic);
}

/* Direction-implying icons must mirror. Bootstrap Icons and FontAwesome both
   render chevrons as glyphs, so a transform is the only way to flip them. */
[dir="rtl"] .vf-flip-rtl,
[dir="rtl"] .vf-icon-next,
[dir="rtl"] .vf-icon-prev {
    transform: scaleX(-1);
}


/* -----------------------------------------------------------------------------
   3. BASE / TYPOGRAPHY
   -----------------------------------------------------------------------------
   Scoped to .vf-* wrappers and to elements inside redesigned pages rather than
   applied to bare `body`, so untouched legacy pages keep their current type.
   -------------------------------------------------------------------------- */

/* Both syaanah/css/minimal.css and asoug/css/minimal.css declare these two
   families, and asoug's copy points at ../fonts/amber/ -- a directory that
   does not exist under public/asoug/. Being the later of the two, the broken
   declaration was the one that won, so 'Ember RG' and 'Ember Bold' resolved to
   nothing site-wide while the .ttf files sat unreferenced in public/syaanah/.

   Restated here because /public/asoug is in .gitignore: a correction made in
   that folder lives on one machine and never reaches a deploy. This file loads
   last, so re-declaring the families is enough to take the working paths --
   the same source-order mechanism that caused the bug, pointed the other way. */
@font-face {
    font-family: 'Ember RG';
    src: url('../../../syaanah/fonts/amber/AmazonEmber_Regular.ttf');
    font-display: swap;
}

@font-face {
    font-family: 'Ember Bold';
    src: url('../../../syaanah/fonts/amber/AmazonEmber_Bold.ttf');
    font-display: swap;
}

.vf-scope {
    font-family: var(--vf-font-sans);
    font-size: var(--vf-text-base);
    line-height: var(--vf-leading-normal);
    color: var(--vf-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

[dir="rtl"] .vf-scope {
    font-family: var(--vf-font-arabic);
}

/* asoug/css/style.css:75-81 sets `h1,h2,...,h6 { font-family: var(--poppins) }`.
   A rule that targets the heading directly beats a font-family *inherited* from
   .vf-scope no matter how specific the ancestor selector is, so every heading on
   the storefront was asking for Poppins -- a Latin-only face with no Arabic
   glyphs. Arabic headings fell through to whatever the browser picked per
   glyph, which is why they never matched the body copy next to them. Restated
   here as a direct rule of our own so inheritance is no longer what decides it.

   RTL only: under LTR, Poppins has the glyphs it needs and swapping the
   storefront's heading face is a design change, not a bug fix. */
[dir="rtl"] .vf-scope :is(h1, h2, h3, h4, h5, h6) {
    font-family: var(--vf-font-arabic);
}

.vf-scope h1,
.vf-scope h2,
.vf-scope h3,
.vf-scope h4,
.vf-scope h5,
.vf-scope h6 {
    color: var(--vf-ink);
    line-height: var(--vf-leading-tight);
    font-weight: var(--vf-weight-bold);
    margin-block-end: var(--vf-space-3);
}

.vf-scope h1 { font-size: var(--vf-text-4xl); }
.vf-scope h2 { font-size: var(--vf-text-3xl); }
.vf-scope h3 { font-size: var(--vf-text-2xl); }
.vf-scope h4 { font-size: var(--vf-text-xl); }
.vf-scope h5 { font-size: var(--vf-text-lg); }
.vf-scope h6 { font-size: var(--vf-text-base); }

@media (max-width: 767.98px) {
    .vf-scope h1 { font-size: var(--vf-text-3xl); }
    .vf-scope h2 { font-size: var(--vf-text-2xl); }
    .vf-scope h3 { font-size: var(--vf-text-xl); }
}

.vf-scope a {
    color: var(--vf-accent);
    text-decoration: none;
    transition: color var(--vf-duration-fast) var(--vf-ease);
}

.vf-scope a:hover {
    color: var(--vf-primary-600);
    text-decoration: underline;
}

.vf-muted { color: var(--vf-muted) !important; }
.vf-ink { color: var(--vf-ink) !important; }

.vf-text-2xs { font-size: var(--vf-text-2xs); }
.vf-text-xs { font-size: var(--vf-text-xs); }
.vf-text-sm { font-size: var(--vf-text-sm); }
.vf-text-lg { font-size: var(--vf-text-lg); }

/* Line clamping — used by product titles and section blurbs. */
.vf-clamp-1,
.vf-clamp-2,
.vf-clamp-3 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.vf-clamp-1 { -webkit-line-clamp: 1; }
.vf-clamp-2 { -webkit-line-clamp: 2; }
.vf-clamp-3 { -webkit-line-clamp: 3; }

/* Visible to screen readers only — used for form hints and icon-only buttons. */
.vf-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}


/* -----------------------------------------------------------------------------
   4. FOCUS
   -----------------------------------------------------------------------------
   A visible focus ring on every interactive element. :focus-visible keeps it off
   mouse clicks. This is deliberately near the top of the file so later component
   rules can override the colour but not remove the ring.
   -------------------------------------------------------------------------- */

.vf-scope a:focus-visible,
.vf-scope button:focus-visible,
.vf-scope input:focus-visible,
.vf-scope select:focus-visible,
.vf-scope textarea:focus-visible,
.vf-scope [tabindex]:focus-visible,
.vf-btn:focus-visible,
.vf-product-card__link:focus-visible {
    outline: 2px solid var(--vf-primary-500);
    outline-offset: 2px;
    border-radius: var(--vf-radius-sm);
}

@media (prefers-reduced-motion: reduce) {
    .vf-scope *,
    .vf-scope *::before,
    .vf-scope *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}


/* -----------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */

.vf-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--vf-space-2);
    min-height: var(--vf-tap);
    padding: var(--vf-space-3) var(--vf-space-5);
    font-family: inherit;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--vf-radius-md);
    cursor: pointer;
    transition: background-color var(--vf-duration-fast) var(--vf-ease),
                border-color var(--vf-duration-fast) var(--vf-ease),
                color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease);
}

.vf-btn:disabled,
.vf-btn[aria-disabled="true"],
.vf-btn.is-loading {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
}

.vf-btn--block { width: 100%; }
.vf-btn--sm { min-height: 36px; padding: var(--vf-space-2) var(--vf-space-4); font-size: var(--vf-text-xs); }
.vf-btn--lg { min-height: 52px; padding: var(--vf-space-4) var(--vf-space-6); font-size: var(--vf-text-base); }

.vf-btn--primary {
    background-color: var(--vf-primary);
    border-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);  /* follows the brand: BrandPalette picks black or white by contrast */
}

.vf-btn--primary:hover,
.vf-btn--primary:focus {
    background-color: var(--vf-primary-600);
    border-color: var(--vf-primary-600);
    color: var(--vf-on-primary, #ffffff);
}

.vf-btn--secondary {
    background-color: var(--vf-secondary);
    border-color: var(--vf-secondary);
    color: var(--vf-on-secondary);  /* 15.61:1 — white here would be 1.22:1 */
}

.vf-btn--secondary:hover,
.vf-btn--secondary:focus {
    background-color: var(--vf-secondary-600);
    border-color: var(--vf-secondary-600);
    color: var(--vf-on-secondary);
}

.vf-btn--outline {
    background-color: transparent;
    border-color: var(--vf-border-strong);
    color: var(--vf-ink);
}

.vf-btn--outline:hover,
.vf-btn--outline:focus {
    background-color: var(--vf-n-50);
    border-color: var(--vf-primary-500);
    color: var(--vf-primary-600);
}

.vf-btn--ghost {
    background-color: transparent;
    border-color: transparent;
    color: var(--vf-accent);
}

.vf-btn--ghost:hover { background-color: var(--vf-primary-50); }

.vf-btn--danger {
    background-color: var(--vf-danger);
    border-color: var(--vf-danger);
    color: #ffffff;                 /* 5.62:1 */
}

/* Icon-only action, e.g. wishlist heart on a product card. Square, and never
   smaller than the tap floor even though the icon inside is 16px. */
.vf-btn--icon {
    min-width: var(--vf-tap);
    padding: 0;
    border-radius: var(--vf-radius-pill);
}

/* --- Social sign-in ---------------------------------------------------------
   Deliberately outline-styled so they read as secondary to the email/password
   submit. Brand colour lives on the mark, not the button fill — a wall of solid
   blue/red buttons out-shouts the primary action.
   Used by the auth pages in Workstream 3/4. */

.vf-btn-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--vf-space-3);
    width: 100%;
    min-height: var(--vf-tap);
    padding: var(--vf-space-3) var(--vf-space-4);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    background-color: var(--vf-surface);
    border: 1px solid var(--vf-border-strong);
    border-radius: var(--vf-radius-md);
    text-decoration: none;
    transition: background-color var(--vf-duration-fast) var(--vf-ease),
                border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease);
}

.vf-btn-social:hover,
.vf-btn-social:focus {
    background-color: var(--vf-n-50);
    border-color: var(--vf-n-400);
    color: var(--vf-ink);
    text-decoration: none;
    box-shadow: var(--vf-shadow-xs);
}

.vf-btn-social:focus-visible {
    outline: 2px solid var(--vf-primary-500);
    outline-offset: 2px;
}

.vf-btn-social__icon {
    display: inline-flex;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
}

.vf-btn-social__icon svg { width: 100%; height: 100%; }

.vf-btn-social--facebook .vf-btn-social__icon { color: #1877f2; }

/* "or" divider between the password form and the social buttons. Renders only
   when at least one provider is enabled — the Blade guards that, not the CSS. */
.vf-divider {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    margin-block: var(--vf-space-5);
    color: var(--vf-muted);
    font-size: var(--vf-text-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.vf-divider::before,
.vf-divider::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background-color: var(--vf-border);
}


/* -----------------------------------------------------------------------------
   6. FORM CONTROLS
   -------------------------------------------------------------------------- */

.vf-field { margin-block-end: var(--vf-space-5); }

.vf-label {
    display: block;
    margin-block-end: var(--vf-space-2);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-medium);
    color: var(--vf-ink);
}

/* The project already marks mandatory fields with class="required" on the label. */
.vf-label.required::after,
.vf-scope label.required::after {
    content: " *";
    color: var(--vf-danger);
}

.vf-input,
.vf-select,
.vf-textarea {
    display: block;
    width: 100%;
    min-height: var(--vf-tap);
    padding: var(--vf-space-3) var(--vf-space-4);
    font-family: inherit;
    font-size: var(--vf-text-base);   /* 16px stops iOS Safari zooming on focus */
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    background-color: var(--vf-surface);
    border: 1px solid var(--vf-border-strong);
    border-radius: var(--vf-radius-md);
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease);
}

.vf-input::placeholder,
.vf-textarea::placeholder {
    color: var(--vf-n-400);
}

.vf-input:focus,
.vf-select:focus,
.vf-textarea:focus {
    outline: none;
    border-color: var(--vf-primary-500);
    box-shadow: var(--vf-shadow-focus);
}

.vf-input[aria-invalid="true"],
.vf-select[aria-invalid="true"],
.vf-textarea[aria-invalid="true"],
.vf-input.is-invalid {
    border-color: var(--vf-danger);
}

.vf-input[aria-invalid="true"]:focus,
.vf-input.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(198, 35, 72, 0.25);
}

.vf-input:disabled,
.vf-select:disabled,
.vf-textarea:disabled {
    background-color: var(--vf-n-50);
    color: var(--vf-n-400);
    cursor: not-allowed;
}

.vf-help {
    display: block;
    margin-block-start: var(--vf-space-2);
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-error {
    display: block;
    margin-block-start: var(--vf-space-2);
    font-size: var(--vf-text-xs);
    color: var(--vf-danger);
}

.vf-error:empty { display: none; }

/* Password reveal toggle. Positioned with inset-inline-end so it lands on the
   correct side under RTL without a second rule. */
.vf-input-group { position: relative; }

.vf-input-group .vf-input { padding-inline-end: calc(var(--vf-tap) + var(--vf-space-1)); }

.vf-input-affix {
    position: absolute;
    inset-inline-end: 0;
    inset-block-start: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--vf-tap);
    height: 100%;
    padding: 0;
    background: none;
    border: 0;
    color: var(--vf-muted);
    cursor: pointer;
}

.vf-input-affix:hover { color: var(--vf-ink); }


/* -----------------------------------------------------------------------------
   7. SURFACES / SECTION HEADINGS
   -------------------------------------------------------------------------- */

.vf-card {
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    box-shadow: var(--vf-shadow-sm);
}

.vf-card__body { padding: var(--vf-space-5); }

.vf-section { padding-block: var(--vf-space-6); }

@media (min-width: 992px) {
    .vf-section { padding-block: var(--vf-space-7); }
}

.vf-section--sunken { background-color: var(--vf-surface-sunken); }

.vf-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--vf-space-4);
    margin-block-end: var(--vf-space-5);
}

.vf-section-head__title {
    margin: 0;
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    line-height: var(--vf-leading-tight);
}

.vf-section-head__sub {
    margin: var(--vf-space-1) 0 0;
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
}

.vf-section-head__link {
    flex: 0 0 auto;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-accent);
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .vf-section-head__title { font-size: var(--vf-text-xl); }
}


/* -----------------------------------------------------------------------------
   8. PRODUCT CARD
   -----------------------------------------------------------------------------
   Replaces the one-off .product-card-ex / .promotion-card-ex / .sale-badge-ex
   rules that lived in a <style> block inside welcome.blade.php. Those set a fixed
   `height: 170px` on the image and `transform: scale(1.05)` on hover — the first
   distorted non-square product photos, the second made cards overlap their
   neighbours in a tight grid. Both are fixed here: aspect-ratio + object-fit for
   the image, translateY for the hover.
   -------------------------------------------------------------------------- */

.vf-product-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    overflow: hidden;
    transition: box-shadow var(--vf-duration-base) var(--vf-ease),
                transform var(--vf-duration-base) var(--vf-ease),
                border-color var(--vf-duration-base) var(--vf-ease);
}

.vf-product-card:hover,
.vf-product-card:focus-within {
    border-color: var(--vf-border-strong);
    box-shadow: var(--vf-shadow-md);
    transform: translateY(-2px);
}

/* Fixed ratio box: the single biggest source of cumulative layout shift on a
   product grid is an <img> with no reserved space. */
.vf-product-card__media {
    position: relative;
    aspect-ratio: 1 / 1;
    background-color: var(--vf-n-50);
    overflow: hidden;
}

.vf-product-card__media img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: transform var(--vf-duration-slow) var(--vf-ease);
}

.vf-product-card:hover .vf-product-card__media img { transform: scale(1.04); }

.vf-product-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    gap: var(--vf-space-2);
    padding: var(--vf-space-4);
}

/* Stretched link: the whole card is clickable, but only one real <a> is in the
   tab order — the action buttons sit above it via z-index. */
.vf-product-card__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: var(--vf-z-base);
}

.vf-product-card__title {
    margin: 0;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-medium);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    min-height: calc(var(--vf-text-sm) * var(--vf-leading-snug) * 2);
}

/* It is a marketplace: who you are buying from is part of the offer. */
.vf-product-card__seller {
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-product-card__seller a {
    position: relative;
    z-index: calc(var(--vf-z-base) + 1);
    color: var(--vf-muted);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.vf-product-card__actions {
    position: relative;
    z-index: calc(var(--vf-z-base) + 1);
    display: flex;
    align-items: center;
    gap: var(--vf-space-2);
    margin-block-start: auto;
    padding-block-start: var(--vf-space-2);
}

.vf-product-card__wish {
    position: absolute;
    z-index: calc(var(--vf-z-base) + 1);
    inset-block-start: var(--vf-space-2);
    inset-inline-end: var(--vf-space-2);
    width: var(--vf-tap);
    height: var(--vf-tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-pill);
    color: var(--vf-n-500);
    cursor: pointer;
    transition: color var(--vf-duration-fast) var(--vf-ease),
                border-color var(--vf-duration-fast) var(--vf-ease);
}

.vf-product-card__wish:hover,
.vf-product-card__wish.is-active {
    color: var(--vf-sale);
    border-color: var(--vf-sale);
}


/* --- Price ------------------------------------------------------------------ */

.vf-price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
}

.vf-price__now {
    font-size: var(--vf-text-lg);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-price);
    line-height: 1.2;
}

.vf-price__was {
    font-size: var(--vf-text-xs);
    color: var(--vf-price-was);
    text-decoration: line-through;
}

.vf-price__off {
    font-size: var(--vf-text-xs);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-sale);
}

/* Prices are always LTR digits with the currency attached; forcing the direction
   stops "SAR 1,200" reordering into "1,200 SAR" inside an RTL paragraph. */
.vf-price__now,
.vf-price__was {
    direction: ltr;
    unicode-bidi: isolate;
}


/* --- Badges ----------------------------------------------------------------- */

.vf-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    padding: var(--vf-space-1) var(--vf-space-2);
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    line-height: 1.4;
    border-radius: var(--vf-radius-sm);
    white-space: nowrap;
}

.vf-badge--sale {
    position: absolute;
    z-index: calc(var(--vf-z-base) + 1);
    inset-block-start: var(--vf-space-2);
    inset-inline-start: var(--vf-space-2);
    background-color: var(--vf-sale-bg);
    color: var(--vf-on-sale);       /* 5.62:1 */
}

.vf-badge--new { background-color: var(--vf-info-bg); color: var(--vf-info); }
.vf-badge--success { background-color: var(--vf-success-bg); color: var(--vf-success); }
.vf-badge--warning { background-color: var(--vf-warning-bg); color: var(--vf-warning); }
.vf-badge--neutral { background-color: var(--vf-n-100); color: var(--vf-n-600); }


/* --- Rating ------------------------------------------------------------------
   The star glyphs are decoration; the count next to them is the accessible
   value. Never ship the stars without the adjacent text. */

.vf-rating {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-rating__stars {
    color: var(--vf-rating);        /* 3.19:1 — meets the 3:1 non-text minimum */
    letter-spacing: 1px;
    direction: ltr;
    unicode-bidi: isolate;          /* stars read left-to-right in both locales */
}


/* --- Stock -------------------------------------------------------------------- */

.vf-stock { font-size: var(--vf-text-xs); font-weight: var(--vf-weight-medium); }
.vf-stock--in { color: var(--vf-stock-in); }
.vf-stock--low { color: var(--vf-stock-low); }
.vf-stock--out { color: var(--vf-stock-out); }


/* -----------------------------------------------------------------------------
   8b. PROMO TILE
   -----------------------------------------------------------------------------
   Replaces .promotion-card-ex / .promotion-title-ex / .product-card-ex /
   .product-link-ex, which were declared in a <style> block inside
   welcome.blade.php. Three things are fixed in the move:

     - .promotion-card-ex hover was `translateY(-10px)` and .product-card-ex hover
       was `scale(1.05)`. Nested as they were -- a promo card containing a product
       tile -- hovering the card ran both, and the scaled child overlapped its
       neighbours in the grid. One subtle lift now, on the outer tile only.
     - `color: #000 !important` on both blocked every text colour downstream.
     - .sale-badge-ex pinned itself with `left: 10px`, which lands on the wrong
       side in Arabic. The system badge (.vf-badge--sale) uses inset-inline-start.
       .sale-badge-ex and .product-image-ex had no markup using them at all, so
       they were dropped rather than ported.
   -------------------------------------------------------------------------- */

.vf-promo {
    background-color: var(--vf-surface-sunken);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    transition: box-shadow var(--vf-duration-base) var(--vf-ease),
                transform var(--vf-duration-base) var(--vf-ease);
}

.vf-promo:hover,
.vf-promo:focus-within {
    transform: translateY(-3px);
    box-shadow: var(--vf-shadow-lg);
}

.vf-promo__title {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: var(--vf-leading-tight);
}

@media (max-width: 768px) {
    .vf-promo__title { font-size: var(--vf-text-lg); }
}

.vf-promo__desc {
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
    margin-block: var(--vf-space-2) 0;
}

/* Image tile inside a promo card. aspect-ratio reserves the box before the image
   arrives; the old rule let the <img> size itself and shifted the page on load. */
.vf-media-tile {
    position: relative;
    display: block;
    overflow: hidden;
    background-color: var(--vf-n-50);
    border-radius: var(--vf-radius-md);
}

.vf-media-tile__link {
    display: block;
    width: 100%;
    height: 100%;
    text-decoration: none;
}

.vf-media-tile img {
    display: block;
    width: 100%;
    height: auto;
    transition: transform var(--vf-duration-slow) var(--vf-ease);
}

.vf-media-tile:hover img { transform: scale(1.03); }


/* -----------------------------------------------------------------------------
   8c. STAT TILE
   -----------------------------------------------------------------------------
   Account-dashboard figures. The value carries the weight, the label sits under
   it small and muted, and the tone tints only the icon -- a wall of four
   fully-coloured panels makes none of them readable as more important than the
   others.
   -------------------------------------------------------------------------- */

.vf-stat {
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-1);
    height: 100%;
    padding: var(--vf-space-4);
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    text-decoration: none;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease);
}

.vf-stat:hover,
.vf-stat:focus-visible {
    border-color: var(--vf-border-strong);
    box-shadow: var(--vf-shadow-sm);
    text-decoration: none;
}

.vf-stat__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin-block-end: var(--vf-space-2);
    border-radius: var(--vf-radius-md);
    font-size: 15px;
    background-color: var(--vf-n-100);
    color: var(--vf-n-600);
}

.vf-stat__value {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    line-height: 1.15;
    color: var(--vf-ink);
    /* Figures and currency read left-to-right in both locales. */
    direction: ltr;
    unicode-bidi: isolate;
    align-self: flex-start;
}

.vf-stat__label {
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-stat--info .vf-stat__icon { background-color: var(--vf-info-bg); color: var(--vf-info); }
.vf-stat--success .vf-stat__icon { background-color: var(--vf-success-bg); color: var(--vf-success); }
.vf-stat--warning .vf-stat__icon { background-color: var(--vf-warning-bg); color: var(--vf-warning); }
.vf-stat--warning .vf-stat__value { color: var(--vf-warning); }

@media (max-width: 575.98px) {
    .vf-stat { padding: var(--vf-space-3); }
    .vf-stat__value { font-size: var(--vf-text-xl); }
}


/* -----------------------------------------------------------------------------
   8d. ORDER CARD
   -----------------------------------------------------------------------------
   Header (reference + date + status), body grouped by seller, footer with the
   money and the one real action.
   -------------------------------------------------------------------------- */

.vf-order__head,
.vf-order__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--vf-space-3);
    flex-wrap: wrap;
    padding: var(--vf-space-4);
}

.vf-order__head { border-block-end: 1px solid var(--vf-border); }

.vf-order__foot {
    border-block-start: 1px solid var(--vf-border);
    background-color: var(--vf-surface-sunken);
}

.vf-order__ref {
    margin: 0;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    direction: ltr;
    unicode-bidi: isolate;
}

.vf-order__date {
    margin: 0;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-order__body { padding: var(--vf-space-2) var(--vf-space-4); }

.vf-order__seller {
    display: flex;
    align-items: center;
    gap: var(--vf-space-2);
    padding-block: var(--vf-space-3);
}

.vf-order__seller-logo {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
    background-color: var(--vf-n-100);
}

.vf-order__seller-name {
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-order__item {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    padding-block: var(--vf-space-3);
    border-block-start: 1px solid var(--vf-n-100);
}

/* A ratio box rather than the old fixed 80x80, which squashed any product photo
   that was not square. */
.vf-order__thumb {
    flex: 0 0 auto;
    width: 64px;
    aspect-ratio: 1 / 1;
    border-radius: var(--vf-radius-md);
    overflow: hidden;
    background-color: var(--vf-n-50);
}

.vf-order__thumb img { width: 100%; height: 100%; object-fit: contain; }

.vf-order__item-main { flex: 1 1 auto; min-width: 0; }

.vf-order__item-name {
    margin: 0 0 var(--vf-space-1);
    font-size: var(--vf-text-sm);
    color: var(--vf-ink);
}

.vf-order__item-meta { margin: 0; font-size: var(--vf-text-xs); color: var(--vf-muted); }

.vf-order__item-total {
    flex: 0 0 auto;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    direction: ltr;
    unicode-bidi: isolate;
}

.vf-order__money {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-4);
    font-size: var(--vf-text-sm);
    color: var(--vf-body);
}

.vf-order__total strong { color: var(--vf-ink); }
.vf-order__due { color: var(--vf-warning); }
.vf-order__due strong { color: var(--vf-warning); }

@media (max-width: 575.98px) {
    .vf-order__thumb { width: 52px; }
    .vf-order__foot { align-items: flex-start; }
    .vf-order__foot .vf-btn { width: 100%; }
}


/* -----------------------------------------------------------------------------
   8e. ACCOUNT SIDE NAV
   -----------------------------------------------------------------------------
   One consistent list. Previously half the destinations were nav-pills with
   icons and the other half were bare <h6> elements styled identically to the
   group headings above them -- so My Wishlists, Queries and Help and Support
   read as section titles rather than links.
   -------------------------------------------------------------------------- */

.vf-side-nav { padding-block-end: var(--vf-space-5); }

.vf-side-nav__title {
    margin: var(--vf-space-5) 0 var(--vf-space-2);
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--vf-n-400);
}

.vf-side-nav__title:first-child { margin-block-start: 0; }

.vf-side-nav__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.vf-side-nav__list--foot {
    margin-block-start: var(--vf-space-4);
    padding-block-start: var(--vf-space-3);
    border-block-start: 1px solid var(--vf-border);
}

.vf-side-nav__link {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    min-height: var(--vf-tap);
    padding: var(--vf-space-2) var(--vf-space-3);
    border-radius: var(--vf-radius-md);
    font-size: var(--vf-text-sm);
    color: var(--vf-body);
    text-decoration: none;
    transition: background-color var(--vf-duration-fast) var(--vf-ease),
                color var(--vf-duration-fast) var(--vf-ease);
}

.vf-side-nav__link i {
    flex: 0 0 auto;
    width: 18px;
    font-size: 14px;
    text-align: center;
    color: var(--vf-n-400);
    transition: color var(--vf-duration-fast) var(--vf-ease);
}

.vf-side-nav__link:hover {
    background-color: var(--vf-n-50);
    color: var(--vf-ink);
    text-decoration: none;
}

.vf-side-nav__link:hover i { color: var(--vf-n-600); }

.vf-side-nav__link.is-active {
    background-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);
    font-weight: var(--vf-weight-semibold);
}

.vf-side-nav__link.is-active i { color: var(--vf-secondary); }

.vf-side-nav__link--danger { color: var(--vf-danger); }
.vf-side-nav__link--danger i { color: var(--vf-danger); }

.vf-side-nav__link--danger:hover {
    background-color: var(--vf-danger-bg);
    color: var(--vf-danger);
}

.vf-side-nav__link--danger:hover i { color: var(--vf-danger); }

.vf-side-nav__toggle {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    width: 100%;
    min-height: var(--vf-tap);
    padding: var(--vf-space-3) var(--vf-space-4);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    background-color: var(--vf-surface);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    cursor: pointer;
}

.vf-side-nav__toggle[aria-expanded="true"] { background-color: var(--vf-n-50); }


/* -----------------------------------------------------------------------------
   8f. TABLE
   -----------------------------------------------------------------------------
   The account list screens are all Bootstrap tables. This restyles them without
   touching .table itself, so nothing outside the account area shifts.
   -------------------------------------------------------------------------- */

.vf-table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.vf-table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    font-size: var(--vf-text-sm);
}

.vf-table th {
    padding: var(--vf-space-3) var(--vf-space-4);
    text-align: start;                  /* start, not left -- mirrors under RTL */
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--vf-muted);
    background-color: var(--vf-surface-sunken);
    border-block-end: 1px solid var(--vf-border);
    white-space: nowrap;
}

.vf-table td {
    padding: var(--vf-space-4);
    vertical-align: middle;
    color: var(--vf-body);
    border-block-end: 1px solid var(--vf-n-100);
}

.vf-table tbody tr:last-child td { border-block-end: 0; }

.vf-table tbody tr:hover { background-color: var(--vf-n-25); }

.vf-table__actions {
    display: flex;
    gap: var(--vf-space-2);
    justify-content: flex-end;
    flex-wrap: wrap;
}

.vf-table__num {
    width: 1%;
    color: var(--vf-muted);
    font-variant-numeric: tabular-nums;
}

/* Product cell: thumbnail plus name, used by the wishlist. */
.vf-table__product {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    min-width: 220px;
}

.vf-table__thumb {
    flex: 0 0 auto;
    width: 48px;
    aspect-ratio: 1 / 1;
    border-radius: var(--vf-radius-md);
    overflow: hidden;
    background-color: var(--vf-n-50);
}

.vf-table__thumb img { width: 100%; height: 100%; object-fit: contain; }

.vf-table__name {
    font-weight: var(--vf-weight-medium);
    color: var(--vf-ink);
    text-decoration: none;
}

.vf-table__name:hover { color: var(--vf-accent); text-decoration: underline; }


/* -----------------------------------------------------------------------------
   8g. STOREFRONT HEADER
   -----------------------------------------------------------------------------
   A rewrite, not a correction this time -- the previous pass patched the old
   markup's colours and spacing, but the markup itself still put seven elements
   at equal weight on one row, hid the account menu and language switcher from
   keyboard and touch users entirely (display:none + :hover, no :focus-within),
   and copied Amazon's exact palette (#131921 / #232f3e). All of that is gone
   from layouts/header.blade.php now; this is its replacement component layer.

   Three bands:
     .vf-hdr__utility  dark, secondary links + delivery + language. Collapses
                        on scroll-down via .vf-hdr--condensed (storefront.js).
     .vf-hdr__main     light, so the search field -- not the logo, not the
                        account menu -- is the loudest thing in the header.
     .vf-hdr__dept     dark, actual shopping departments. nav-bar / mobile-nav /
                        scroll-left-btn / scroll-right-btn are kept ALONGSIDE
                        the vf-hdr__dept* classes because the RTL-aware overflow
                        scroller in layouts/script.blade.php binds to those
                        three names -- do not rename them without updating it.

   #header-section keeps its id: minimal.css:166-171 uses it (!important) to
   neutralise asoug/css/style.css's `header { height: 150px !important }`.
   -------------------------------------------------------------------------- */

#header-section.vf-hdr {
    /* Higher specificity than the bare #header-section rule above, so this
       wins regardless of stylesheet order. minimal.css sets position:
       relative at the same #header-section selector -- sticky replaces it. */
    position: sticky;
    inset-block-start: 0;
    z-index: var(--vf-z-header);
    height: auto;

    /* Header-local brand purple. The global --vf-primary (#14003f) is a
       near-black navy chosen for text contrast; the storefront header is
       meant to read as vibrant purple (the Aqasat look). These vars are
       scoped to the header only, so nothing else on the site shifts hue. */
    --vf-hdr-purple: #6d28d9;
    --vf-hdr-purple-600: #5b21b6;
    --vf-hdr-purple-700: #4c1d95;
}

/* WCAG 2.4.12: a sticky header must never cover the element that just
   received focus. Reserve roughly the header's own height -- this file loads
   only on pages that render the header, so no :has() guard is needed. */
html {
    scroll-padding-block-start: 124px;
}

/* ---- Band 1: utility --------------------------------------------------- */

.vf-hdr__utility {
    background-color: var(--vf-hdr-purple);
    transition: max-block-size var(--vf-duration-base) var(--vf-ease),
        opacity var(--vf-duration-base) var(--vf-ease);
    max-block-size: 44px;
}

/* Only the collapsed state clips -- the language/currency dropdown
   (.vf-hdr__menu-panel) is an absolutely-positioned descendant that must be
   able to pop out below this band's own 44px box while it is open.
   overflow: hidden on the base rule clipped that panel to invisibility and
   made every link inside it unclickable (hit-testing fell through to the
   search bar in Band 2 underneath), which is what "language switch doesn't
   work" actually was. */
.vf-hdr--condensed .vf-hdr__utility {
    max-block-size: 0;
    opacity: 0;
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .vf-hdr__utility { transition: none; }
}

.vf-hdr__utility-inner {
    display: flex;
    align-items: center;
    min-block-size: 40px;
    gap: var(--vf-space-4);
}

.vf-hdr__utility-links {
    display: flex;
    align-items: center;
    gap: var(--vf-space-5);
    margin: 0;
    padding: 0;
    list-style: none;
}

.vf-hdr__utility-right {
    display: flex;
    align-items: center;
    gap: var(--vf-space-4);
    /* Pushes this group to the line-end edge even when .vf-hdr__utility-links
       is hidden below lg -- see the d-lg-flex on it in the blade. */
    margin-inline-start: auto;
}

.vf-hdr__utility-link {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-1);
    background: none;
    border: 0;
    color: rgba(255, 255, 255, 0.82);
    font-size: var(--vf-text-xs);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.vf-hdr__utility-link:hover { color: var(--vf-on-primary); }

.vf-hdr__utility-link:focus-visible {
    outline: 2px solid var(--vf-secondary);
    outline-offset: -2px;
    border-radius: var(--vf-radius-sm);
}

.vf-hdr__deliver-label { color: rgba(255, 255, 255, 0.7); }
.vf-hdr__deliver-value { color: var(--vf-on-primary); font-weight: var(--vf-weight-semibold); }

/* "Deliver to" collapses to just the icon and the value on very small
   screens -- there is no room for three words next to the flag selector. */
@media (max-width: 399.98px) {
    .vf-hdr__deliver-label { display: none; }
}

.vf-hdr__flag { border-radius: var(--vf-radius-sm); }

.vf-hdr__lang-caret { font-size: 0.625rem; color: rgba(255, 255, 255, 0.7); }

/* .vf-hdr__lang-toggle reuses .vf-hdr__action's layout (flex column, tap
   size) but sits on the dark utility bar, not the light main bar -- .vf-hdr__
   action's own color: var(--vf-ink) and its focus ring would both be a dark
   colour on dark navy, which is close to invisible. Overridden here rather
   than splitting the layout into a second class.

   Selectors are doubled up (.vf-hdr__action.vf-hdr__lang-toggle) so this
   beats .vf-hdr__action's own rules under Band 2 below on specificity, not on
   source order -- a single-class override here would lose that fight, since
   .vf-hdr__action:focus-visible appears later in the file. */
.vf-hdr__action.vf-hdr__lang-toggle {
    flex-direction: row;
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-2);
    color: rgba(255, 255, 255, 0.82);
}

.vf-hdr__action.vf-hdr__lang-toggle:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: var(--vf-on-primary);
}

.vf-hdr__action.vf-hdr__lang-toggle:focus-visible {
    outline: 2px solid var(--vf-secondary);
    outline-offset: -2px;
}

/* ---- Band 2: main -------------------------------------------------------
   Light -- the direction Amazon and Walmart have themselves moved toward --
   so contrast is spent on the search field instead of the whole bar. */

.vf-hdr__main {
    background-color: var(--vf-surface);
    border-block-end: 1px solid var(--vf-border);
}

.vf-hdr__main-inner {
    display: flex;
    align-items: center;
    gap: var(--vf-space-4);
    padding-block: var(--vf-space-3);
}

.vf-hdr__menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--vf-tap);
    block-size: var(--vf-tap);
    background: none;
    border: 0;
    border-radius: var(--vf-radius-sm);
    color: var(--vf-ink);
    font-size: var(--vf-text-lg);
    cursor: pointer;
}

.vf-hdr__logo { flex: 0 0 auto; display: inline-flex; }

.vf-hdr__logo img {
    /* Was 120px wide with no height floor, so a tall narrow logo shrank to a
       smear. */
    max-height: 40px;
    max-width: 140px;
    width: auto;
    object-fit: contain;
}

.vf-hdr__search {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 0;
    min-inline-size: 200px;
    max-inline-size: 640px;
}

.vf-hdr__search-input {
    inline-size: 100%;
    /* Leading room for the magnifier + separator now living on the inline-start
       edge, matching the reference where the icon sits before the text. */
    min-block-size: 52px;
    padding-inline: calc(var(--vf-tap) + var(--vf-space-3)) var(--vf-space-4);
    border: 1.5px solid var(--vf-hdr-purple);
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-surface);
    color: var(--vf-ink);
    font-size: var(--vf-text-base);
}

.vf-hdr__search-input::placeholder { color: var(--vf-n-400); }

.vf-hdr__search-input:focus {
    outline: none;
    border-color: var(--vf-hdr-purple);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vf-hdr-purple) 20%, transparent);
}

/* The submit control now reads as a leading icon: transparent, sitting on the
   inline-start edge with a hairline separator after it (the vertical bar in
   the reference). It remains a real submit button for keyboard/mouse. */
.vf-hdr__search-btn {
    position: absolute;
    inset-block: 8px;
    inset-inline-start: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 40px;
    border: 0;
    border-inline-end: 1px solid var(--vf-border);
    border-radius: 0;
    background-color: transparent;
    color: var(--vf-hdr-purple);
    font-size: var(--vf-text-lg);
}

.vf-hdr__search-btn:hover { color: var(--vf-hdr-purple-600); background-color: transparent; }

.vf-hdr__search-btn:focus-visible,
.vf-hdr__menu-toggle:focus-visible,
.vf-hdr__logo:focus-visible {
    outline: 2px solid var(--vf-primary);
    outline-offset: 2px;
}

.vf-hdr__actions {
    display: flex;
    align-items: center;
    gap: var(--vf-space-2);
    flex: 0 0 auto;
}

.vf-hdr__menu { position: relative; }

.vf-hdr__action {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-3);
    background: none;
    border: 0;
    border-radius: var(--vf-radius-sm);
    color: var(--vf-ink);
    text-decoration: none;
    line-height: var(--vf-leading-tight);
    cursor: pointer;
}

.vf-hdr__action:hover { background-color: var(--vf-n-50); color: var(--vf-ink); }

.vf-hdr__action:focus-visible {
    outline: 2px solid var(--vf-primary);
    outline-offset: 2px;
}

.vf-hdr__action-icon { font-size: var(--vf-text-lg); }
.vf-hdr__action-label { font-size: var(--vf-text-2xs); font-weight: var(--vf-weight-medium); white-space: nowrap; }

.vf-hdr__cart-icon { position: relative; display: inline-flex; }

/* The account (user), orders and cart actions all read as filled purple
   square buttons (the icon tiles in the reference) rather than the stacked
   icon+label the markup ships with. Each label is kept for screen readers but
   visually folded away so the tile stays square.
     - .vf-hdr__menu > .vf-hdr__action ......... the account toggle button
     - .vf-hdr__actions > a...:not(.vf-hdr__cart) the Orders link
     - .vf-hdr__cart.vf-hdr__action ............ the Cart link

   :not(.vf-hdr__lang-toggle) is load-bearing. .vf-hdr__menu is not unique to
   the account button in Band 2 -- Band 1's language switcher uses the same
   wrapper, because both need a positioned ancestor for their .vf-hdr__menu-panel
   dropdown to anchor to. Without the exclusion this rule also caught the
   language toggle and, being later in the file at equal (0,2,0) specificity,
   beat the .vf-hdr__action.vf-hdr__lang-toggle rule above on source order --
   the exact fight its comment anticipated. Three things broke at once: the
   toggle was forced to a 48px square inside a band whose max-block-size is
   44px, so 4px of an 8px-radius corner spilled onto the white band below and
   read as a stray purple tab; it was painted --vf-hdr-purple, invisible against
   the identical band behind it and visible only where it spilled; and the label
   rule below folded its text away, leaving a bare squashed flag. */
.vf-hdr__cart.vf-hdr__action,
.vf-hdr__menu > .vf-hdr__action:not(.vf-hdr__lang-toggle),
.vf-hdr__actions > a.vf-hdr__action:not(.vf-hdr__cart) {
    inline-size: 48px;
    block-size: 48px;
    padding-inline: 0;
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-hdr-purple);
    color: var(--vf-on-primary);
}

.vf-hdr__cart.vf-hdr__action:hover,
.vf-hdr__menu > .vf-hdr__action:not(.vf-hdr__lang-toggle):hover,
.vf-hdr__actions > a.vf-hdr__action:not(.vf-hdr__cart):hover {
    background-color: var(--vf-hdr-purple-600);
    color: var(--vf-on-primary);
}

.vf-hdr__cart.vf-hdr__action .vf-hdr__action-icon,
.vf-hdr__menu > .vf-hdr__action:not(.vf-hdr__lang-toggle) .vf-hdr__action-icon,
.vf-hdr__actions > a.vf-hdr__action:not(.vf-hdr__cart) .vf-hdr__action-icon {
    font-size: var(--vf-text-xl);
}

.vf-hdr__cart.vf-hdr__action .vf-hdr__action-label,
.vf-hdr__menu > .vf-hdr__action:not(.vf-hdr__lang-toggle) .vf-hdr__action-label,
.vf-hdr__actions > a.vf-hdr__action:not(.vf-hdr__cart) .vf-hdr__action-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.vf-hdr__cart-badge {
    position: absolute;
    inset-block-start: -10px;
    inset-inline-end: -12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 20px;
    block-size: 20px;
    padding-inline: 5px;
    border-radius: var(--vf-radius-pill);
    /* Red, to match the reference badge (and --vf-danger passes contrast). */
    background-color: var(--vf-danger);
    color: #fff;
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    box-shadow: 0 0 0 2px var(--vf-surface);
}

/* Account / language disclosure panels -----------------------------------
   Replaces .dropdown-hover / .dropdown-hover-menu (minimal.css:56-83), which
   was display:none + :hover with no :focus-within and no JS -- display:none
   removes its children from the tab order, so the account menu's Orders,
   Wishlist, Support, Profile and Logout links were unreachable by keyboard
   or touch. storefront.js drives [data-vf-disclosure] / [hidden] instead. */

.vf-hdr__menu-panel {
    position: absolute;
    inset-block-start: calc(100% + var(--vf-space-2));
    inset-inline-end: 0;
    z-index: var(--vf-z-dropdown);
    min-inline-size: 240px;
    padding: var(--vf-space-4);
    background-color: var(--vf-surface);
    border-radius: var(--vf-radius-md);
    box-shadow: var(--vf-shadow-lg);
}

.vf-hdr__menu-panel--end { min-inline-size: 200px; }

.vf-hdr__menu-title {
    margin-block-end: var(--vf-space-2);
    color: var(--vf-muted);
    font-size: var(--vf-text-xs);
    font-weight: var(--vf-weight-semibold);
    text-transform: uppercase;
}

.vf-hdr__menu-list { margin: 0; padding: 0; list-style: none; }

.vf-hdr__menu-list a {
    display: flex;
    align-items: center;
    min-block-size: var(--vf-tap);
    color: var(--vf-body);
    text-decoration: none;
}

.vf-hdr__menu-list a:hover { color: var(--vf-accent); }
.vf-hdr__menu-list a[aria-current="true"] { color: var(--vf-primary); font-weight: var(--vf-weight-semibold); }

.vf-hdr__menu-divider { margin-block: var(--vf-space-3); border-color: var(--vf-border); }

.vf-hdr__menu-foot { margin-block: var(--vf-space-3) 0; text-align: center; font-size: var(--vf-text-xs); }

/* ---- Band 3: departments ------------------------------------------------- */

.vf-hdr__dept { background-color: var(--vf-hdr-purple); }

.vf-hdr__dept-list { gap: var(--vf-space-1); }

/* The two scroll arrows (minimal.css:237-260) are 35px circles positioned
   absolutely over each end of this strip. layouts/script.blade.php adds
   .has-scroll-arrows to the .nav-bar wrapper only while the strip actually
   overflows, which is the only time they are on screen. Padding the scroller
   itself rather than the wrapper keeps the reserved space inside the scroll
   range, so the end items come to rest clear of the arrows instead of under
   them -- on a phone that link was 27% covered and its tap target clipped. */
.nav-bar.has-scroll-arrows .vf-hdr__dept-list {
    padding-inline: 40px;
}

/* .mobile-nav's own item rule (minimal.css) is scoped to .nav-item, a class
   the rewritten markup no longer carries. Without flex-shrink: 0 the items
   would compress instead of overflowing, and layouts/script.blade.php only
   reveals the scroll arrows when there IS an overflow to scroll. */
.vf-hdr__dept-list > li {
    flex-shrink: 0;
}

.vf-hdr__dept-link {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-3);
    border-block-end: 3px solid transparent;
    color: rgba(255, 255, 255, 0.92);
    font-size: var(--vf-text-sm);
    text-decoration: none;
    white-space: nowrap;
}

.vf-hdr__dept-link:hover { color: var(--vf-on-primary); }

.vf-hdr__dept-link[aria-current="page"] {
    border-block-end-color: var(--vf-secondary);
    color: var(--vf-on-primary);
    font-weight: var(--vf-weight-semibold);
}

.vf-hdr__dept-link:focus-visible {
    outline: 2px solid var(--vf-secondary);
    outline-offset: -2px;
    border-radius: var(--vf-radius-sm);
}

@media (min-width: 992px) {
    .vf-hdr__main-inner { gap: var(--vf-space-5); }
}

/* Below lg there is no room for hamburger + logo + a meaningfully wide search
   field + actions on one line -- eBay's spec and Baymard's mobile findings
   both put search on its own full-width row near the top instead. Mirrors
   the order: 10; flex: 0 0 100% pattern minimal.css used on the old
   .main-search-box-area for the same reason. */
@media (max-width: 991.98px) {
    .vf-hdr__main-inner { flex-wrap: wrap; row-gap: var(--vf-space-2); }

    .vf-hdr__search {
        order: 10;
        flex: 0 0 100%;
        min-inline-size: 0;
        max-inline-size: none;
    }

    .vf-hdr__logo img { max-height: 32px; }
}


/* -----------------------------------------------------------------------------
   8h. CATEGORY TILES + HERO FALLBACK
   -------------------------------------------------------------------------- */

.vf-cat-grid {
    display: grid;
    gap: var(--vf-space-3);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 576px) { .vf-cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 768px) { .vf-cat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 992px) { .vf-cat-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.vf-cat-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--vf-space-2);
    padding: var(--vf-space-3);
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    text-decoration: none;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease),
                transform var(--vf-duration-fast) var(--vf-ease);
}

.vf-cat-tile:hover,
.vf-cat-tile:focus-visible {
    border-color: var(--vf-primary-500);
    box-shadow: var(--vf-shadow-md);
    transform: translateY(-2px);
    text-decoration: none;
}

/* A ratio box, so a grid of mixed-shape category photos still lines up. */
.vf-cat-tile__media {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--vf-radius-md);
    overflow: hidden;
    background-color: var(--vf-n-50);
}

.vf-cat-tile__media img { width: 100%; height: 100%; object-fit: cover; }

.vf-cat-tile__name {
    font-size: var(--vf-text-xs);
    font-weight: var(--vf-weight-medium);
    color: var(--vf-ink);
    text-align: center;
    line-height: var(--vf-leading-snug);
    /* Two lines maximum: a long category name must not make one tile taller than
       the rest of its row. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Stands in for the hero slider when no slider rows exist, so the top of the
   homepage is never an empty rectangle. */
.vf-hero-fallback {
    display: flex;
    align-items: center;
    aspect-ratio: 1200 / 416;
    padding: var(--vf-space-6);
    border-radius: var(--vf-radius-lg);
    background: linear-gradient(135deg,
        var(--vf-primary) 0%,
        color-mix(in srgb, var(--vf-primary) 70%, #000) 100%);
}

/* .vf-scope h2 is (0,1,1) and outranked the bare class, so every title
   meant to sit on a dark brand panel was painted ink-dark on it. */
.vf-scope .vf-hero-fallback__title,
.vf-hero-fallback__title {
    font-size: var(--vf-text-3xl);
    font-weight: var(--vf-weight-bold);
    line-height: var(--vf-leading-tight);
    color: var(--vf-on-primary, #ffffff);
    margin: 0 0 var(--vf-space-2);
}

.vf-scope .vf-hero-fallback__text,
.vf-hero-fallback__text {
    font-size: var(--vf-text-base);
    color: color-mix(in srgb, var(--vf-on-primary, #ffffff) 85%, transparent);
    margin: 0 0 var(--vf-space-5);
    max-width: 46ch;
}

@media (max-width: 575.98px) {
    .vf-hero-fallback {
        aspect-ratio: auto;
        padding: var(--vf-space-5) var(--vf-space-4);
    }

    .vf-hero-fallback__title { font-size: var(--vf-text-xl); }
    .vf-hero-fallback__text { font-size: var(--vf-text-sm); }
}


/* -----------------------------------------------------------------------------
   8i. CONTACT PAGE
   -------------------------------------------------------------------------- */

.vf-contact-hero { margin-block-end: var(--vf-space-6); max-width: 62ch; }

.vf-contact-hero__title {
    font-size: var(--vf-text-4xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    line-height: var(--vf-leading-tight);
    margin: 0 0 var(--vf-space-2);
}

.vf-contact-hero__text {
    font-size: var(--vf-text-base);
    color: var(--vf-muted);
    margin: 0;
}

@media (max-width: 575.98px) {
    .vf-contact-hero__title { font-size: var(--vf-text-2xl); }
}

.vf-contact-list {
    list-style: none;
    margin: 0 0 var(--vf-space-5);
    padding: 0;
    display: grid;
    gap: var(--vf-space-4);
}

.vf-contact-list li {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
}

.vf-contact-list__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-primary-50);
    color: var(--vf-primary-500);
    font-size: 15px;
}

.vf-contact-list__label {
    display: block;
    font-size: var(--vf-text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--vf-muted);
}

.vf-contact-list__value {
    display: block;
    font-size: var(--vf-text-sm);
    color: var(--vf-ink);
    /* Phone numbers and email addresses read left-to-right even in Arabic. */
    unicode-bidi: isolate;
}

a.vf-contact-list__value { color: var(--vf-accent); text-decoration: none; }
a.vf-contact-list__value:hover { text-decoration: underline; }

.vf-contact-sub {
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    margin: 0 0 var(--vf-space-3);
}

.vf-social {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    margin: 0;
    padding: 0;
}

.vf-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Full tap target: these were bare icons at roughly 16px. */
    width: var(--vf-tap);
    height: var(--vf-tap);
    border-radius: var(--vf-radius-md);
    border: 1px solid var(--vf-border);
    color: var(--vf-n-600);
    text-decoration: none;
    transition: background-color var(--vf-duration-fast) var(--vf-ease),
                color var(--vf-duration-fast) var(--vf-ease),
                border-color var(--vf-duration-fast) var(--vf-ease);
}

.vf-social a:hover,
.vf-social a:focus-visible {
    background-color: var(--vf-primary);
    border-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);
}

/* Deflection links: the alternative routes offered beside the form. */
.vf-quick-link {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
    padding: var(--vf-space-3);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    text-decoration: none;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                background-color var(--vf-duration-fast) var(--vf-ease);
}

.vf-quick-link:hover,
.vf-quick-link:focus-visible {
    border-color: var(--vf-primary-500);
    background-color: var(--vf-primary-50);
    text-decoration: none;
}

.vf-quick-link__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-n-100);
    color: var(--vf-n-600);
    font-size: 14px;
}

.vf-quick-link__title {
    display: block;
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-quick-link__text {
    display: block;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

/* Honeypot. Off-screen rather than display:none, because some bots skip hidden
   fields but not positioned ones. aria-hidden and tabindex keep it away from
   assistive tech and the keyboard. */
.vf-hp {
    position: absolute;
    inset-inline-start: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}


/* -----------------------------------------------------------------------------
   8j. SERVICES + ABOUT
   -------------------------------------------------------------------------- */

.vf-service-grid {
    display: grid;
    gap: var(--vf-space-4);
    grid-template-columns: repeat(1, minmax(0, 1fr));
}

@media (min-width: 576px) { .vf-service-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px) { .vf-service-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .vf-service-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.vf-service-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    overflow: hidden;
    /* Required for Bootstrap's .stretched-link on the CTA -- makes the whole
       card clickable while keeping the button as the visible affordance. */
    position: relative;
    transition: box-shadow var(--vf-duration-base) var(--vf-ease),
                transform var(--vf-duration-base) var(--vf-ease),
                border-color var(--vf-duration-base) var(--vf-ease);
}

/* Every card whose CTA carries .stretched-link is a link surface, so pointer
   feedback should follow. */
.vf-service-card:has(.stretched-link) { cursor: pointer; }

.vf-service-card:hover,
.vf-service-card:focus-within {
    border-color: var(--vf-border-strong);
    box-shadow: var(--vf-shadow-md);
    transform: translateY(-2px);
}

/* The old cards let the <img> size itself, so a grid of differently shaped
   service photos produced rows of different heights. */
.vf-service-card__media {
    aspect-ratio: 16 / 10;
    background-color: var(--vf-n-50);
    overflow: hidden;
}

.vf-service-card__media img { width: 100%; height: 100%; object-fit: cover; }

.vf-service-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    gap: var(--vf-space-2);
    padding: var(--vf-space-4);
}

.vf-service-card__title {
    margin: 0;
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    line-height: var(--vf-leading-snug);
}

.vf-service-card__text {
    margin: 0;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
    line-height: var(--vf-leading-normal);
}

/* margin-block-start:auto pins the button to the bottom, so buttons line up
   across a row whatever the description length. */
.vf-service-card__cta { margin-block-start: auto; align-self: flex-start; }

.vf-about-media {
    border-radius: var(--vf-radius-lg);
    overflow: hidden;
    background-color: var(--vf-n-50);
    aspect-ratio: 4 / 3;
}

.vf-about-media img { width: 100%; height: 100%; object-fit: cover; }

.vf-scope .vf-about-lead {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-primary-500);
    margin: 0 0 var(--vf-space-2);
}

.vf-about-text {
    font-size: var(--vf-text-base);
    color: var(--vf-body);
    line-height: var(--vf-leading-relaxed);
    margin: 0;
}

.vf-about-banner {
    position: relative;
    background-size: cover;
    background-position: center;
    padding-block: var(--vf-space-8);
    isolation: isolate;
}

/* The scrim. Without it the white copy sat directly on the photograph and its
   legibility depended entirely on what was behind it. Angled from the inline
   start so it mirrors under RTL, where the text also sits. */
.vf-about-banner::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(to inline-end,
        rgba(0, 0, 0, 0.78) 0%,
        rgba(0, 0, 0, 0.55) 55%,
        rgba(0, 0, 0, 0.25) 100%);
}

.vf-about-banner__inner {
    /* Was border-left, which put the rule on the wrong edge in Arabic. */
    border-inline-start: 3px solid var(--vf-secondary);
    padding-inline-start: var(--vf-space-4);
}

.vf-scope .vf-about-banner__title {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: #ffffff;
    margin: 0 0 var(--vf-space-2);
}

.vf-about-banner__text {
    font-size: var(--vf-text-base);
    /* 90% white on a 0.78 black scrim clears AA comfortably. */
    color: rgba(255, 255, 255, 0.9);
    line-height: var(--vf-leading-relaxed);
    margin: 0;
    max-width: 60ch;
}

@media (max-width: 575.98px) {
    .vf-about-banner { padding-block: var(--vf-space-6); }
    .vf-scope .vf-about-banner__title { font-size: var(--vf-text-xl); }
    .vf-about-banner__text { font-size: var(--vf-text-sm); }
}


/* -----------------------------------------------------------------------------
   9. CHIP
   -------------------------------------------------------------------------- */

.vf-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-2);
    min-height: 36px;
    padding: var(--vf-space-2) var(--vf-space-4);
    font-size: var(--vf-text-sm);
    color: var(--vf-body);
    background-color: var(--vf-n-50);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-pill);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color var(--vf-duration-fast) var(--vf-ease),
                border-color var(--vf-duration-fast) var(--vf-ease),
                color var(--vf-duration-fast) var(--vf-ease);
}

.vf-chip:hover { border-color: var(--vf-border-strong); }

.vf-chip.is-active,
.vf-chip[aria-pressed="true"] {
    background-color: var(--vf-primary);
    border-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);
}


/* -----------------------------------------------------------------------------
   10. SKELETON
   -----------------------------------------------------------------------------
   Skeletons, not spinners, for product grids: they hold the layout so nothing
   jumps when the data lands.
   -------------------------------------------------------------------------- */

.vf-skeleton {
    background-color: var(--vf-n-100);
    background-image: linear-gradient(
        90deg,
        var(--vf-n-100) 0%,
        var(--vf-n-50) 50%,
        var(--vf-n-100) 100%
    );
    background-size: 200% 100%;
    border-radius: var(--vf-radius-sm);
    animation: vf-shimmer 1.4s var(--vf-ease) infinite;
}

.vf-skeleton--text { height: 0.75rem; margin-block-end: var(--vf-space-2); }
.vf-skeleton--title { height: 1rem; width: 70%; }
.vf-skeleton--media { aspect-ratio: 1 / 1; width: 100%; border-radius: 0; }

@keyframes vf-shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

/* The shimmer runs left-to-right; under RTL it should sweep the other way. */
[dir="rtl"] .vf-skeleton { animation-direction: reverse; }

@media (prefers-reduced-motion: reduce) {
    .vf-skeleton { animation: none; }
}


/* -----------------------------------------------------------------------------
   11. EMPTY STATE
   -------------------------------------------------------------------------- */

.vf-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--vf-space-3);
    padding: var(--vf-space-7) var(--vf-space-4);
    text-align: center;
    color: var(--vf-muted);
}

.vf-empty__icon {
    font-size: var(--vf-text-4xl);
    color: var(--vf-n-300);
    line-height: 1;
}

.vf-empty__title {
    margin: 0;
    font-size: var(--vf-text-lg);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-empty__text { margin: 0; font-size: var(--vf-text-sm); max-width: 42ch; }


/* -----------------------------------------------------------------------------
   11b. AUTH SHELL
   -----------------------------------------------------------------------------
   A card that sits between the storefront header and footer, not a full-viewport
   takeover. The auth screens extend frontend.layouts.app, so the site's own
   navigation, search, cart and language switcher stay available while someone is
   signing in -- being thrown out of the site chrome to log in is disorienting,
   and it hides the cart the visitor was in the middle of filling.

   Split into a brand panel and a form panel above 992px, one column below.
   Column order is set by grid placement rather than by floating either side, so
   the whole thing mirrors under RTL on its own.
   -------------------------------------------------------------------------- */

.vf-auth {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    margin-block: var(--vf-space-6);
    background-color: var(--vf-surface);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-xl);
    box-shadow: var(--vf-shadow-sm);
    /* Clips the brand panel's background to the rounded corners. */
    overflow: hidden;
}

.vf-auth__brand {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--vf-space-5);
    padding: var(--vf-space-6) var(--vf-space-5);
    background-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);
}

.vf-auth__brand-logo img {
    max-height: 44px;
    width: auto;
}

.vf-scope .vf-auth__brand-title,
.vf-auth__brand-title {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    line-height: var(--vf-leading-tight);
    color: var(--vf-on-primary, #ffffff);
    margin: 0;
}

.vf-scope .vf-auth__brand-text,
.vf-auth__brand-text {
    font-size: var(--vf-text-sm);
    line-height: var(--vf-leading-relaxed);
    /* 85% white on #14003F is still ~14:1 -- comfortably past AA. */
    color: rgba(255, 255, 255, 0.85);
    margin: 0;
    max-width: 46ch;
}

.vf-auth__points {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--vf-space-3);
}

.vf-auth__points li {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
    font-size: var(--vf-text-sm);
    color: rgba(255, 255, 255, 0.85);
}

.vf-auth__points i {
    color: var(--vf-secondary);      /* yellow on deep violet — 15.61:1 */
    margin-block-start: 2px;
}

.vf-auth__panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    flex: 1 1 auto;
    padding: var(--vf-space-5) var(--vf-space-4);
}

.vf-auth__inner {
    width: 100%;
    max-width: 440px;
    margin-inline: auto;
}

.vf-auth__title {
    font-size: var(--vf-text-3xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    line-height: var(--vf-leading-tight);
    margin: 0 0 var(--vf-space-2);
}

.vf-auth__sub {
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
    margin: 0 0 var(--vf-space-6);
}

.vf-auth__foot {
    margin-block-start: var(--vf-space-5);
    text-align: center;
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
}

.vf-auth__alt {
    margin-block-start: var(--vf-space-3);
    text-align: center;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

@media (min-width: 992px) {
    .vf-auth {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    }

    .vf-auth__brand {
        padding: var(--vf-space-7) var(--vf-space-6);
        gap: var(--vf-space-6);
    }

    .vf-auth__brand-title { font-size: var(--vf-text-3xl); }

    .vf-auth__panel { padding: var(--vf-space-7); }
}

/* On a phone the brand panel is a short strip above the form rather than a
   screenful the visitor has to scroll past to reach the fields. */
@media (max-width: 991.98px) {
    .vf-auth__points { display: none; }

    .vf-auth__brand {
        gap: var(--vf-space-3);
        padding: var(--vf-space-5) var(--vf-space-4);
    }

    .vf-auth__brand-logo { display: none; }
}

/* A banner for the server's own error/status messages, above the fields. Hidden
   until something fills it -- :empty would not work because the markup carries an
   icon, so JS toggles [hidden] instead. */
.vf-alert {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
    padding: var(--vf-space-3) var(--vf-space-4);
    margin-block-end: var(--vf-space-5);
    font-size: var(--vf-text-sm);
    border-radius: var(--vf-radius-md);
    border: 1px solid transparent;
}

.vf-alert[hidden] { display: none; }

.vf-alert--danger {
    background-color: var(--vf-danger-bg);
    border-color: var(--vf-danger);
    color: var(--vf-danger);
}

.vf-alert--success {
    background-color: var(--vf-success-bg);
    border-color: var(--vf-success);
    color: var(--vf-success);
}

.vf-alert--info {
    background-color: var(--vf-info-bg);
    border-color: var(--vf-info);
    color: var(--vf-info);
}

/* Password strength meter — four segments, filled as the score rises. */
.vf-strength { margin-block-start: var(--vf-space-2); }

.vf-strength__track {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--vf-space-1);
}

.vf-strength__seg {
    height: 4px;
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-n-200);
    transition: background-color var(--vf-duration-fast) var(--vf-ease);
}

.vf-strength__seg.is-1 { background-color: var(--vf-danger); }
.vf-strength__seg.is-2 { background-color: var(--vf-warning-fill); }
.vf-strength__seg.is-3 { background-color: var(--vf-info); }
.vf-strength__seg.is-4 { background-color: var(--vf-success); }

.vf-strength__label {
    display: block;
    margin-block-start: var(--vf-space-1);
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

/* Stepper — splits a long registration form into panels. The indicator is a list
   so it still reads as an ordered sequence with CSS off. */

.vf-steps {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-2);
    list-style: none;
    margin: 0 0 var(--vf-space-6);
    padding: 0;
    counter-reset: vf-step;
}

.vf-steps__item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--vf-space-2);
    position: relative;
    text-align: center;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-steps__dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: var(--vf-n-100);
    color: var(--vf-n-600);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    border: 1px solid var(--vf-border);
}

/* The connector runs toward the previous item, so inset-inline-end plus a
   translate keeps it between the dots in both directions. */
.vf-steps__item + .vf-steps__item::before {
    content: "";
    position: absolute;
    inset-block-start: 16px;
    inset-inline-end: 50%;
    width: 100%;
    height: 2px;
    background-color: var(--vf-border);
}

.vf-steps__item.is-active .vf-steps__dot,
.vf-steps__item.is-done .vf-steps__dot {
    background-color: var(--vf-primary);
    border-color: var(--vf-primary);
    color: var(--vf-on-primary, #ffffff);
}

.vf-steps__item.is-active,
.vf-steps__item.is-done {
    color: var(--vf-ink);
    font-weight: var(--vf-weight-semibold);
}

.vf-steps__item.is-done + .vf-steps__item::before,
.vf-steps__item.is-active + .vf-steps__item::before {
    background-color: var(--vf-primary);
}

.vf-step[hidden] { display: none; }

.vf-step__actions {
    display: flex;
    gap: var(--vf-space-3);
    margin-block-start: var(--vf-space-5);
}

.vf-step__actions .vf-btn { flex: 1 1 auto; }


/* Role picker on the registration screens — RegisterController validates
   Rule::in(['buyer','supplier','both']), so the choice has to be explicit. */
.vf-choice {
    display: grid;
    gap: var(--vf-space-3);
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

.vf-choice__item { position: relative; }

.vf-choice__item input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}

.vf-choice__box {
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-1);
    height: 100%;
    padding: var(--vf-space-4);
    border: 1px solid var(--vf-border-strong);
    border-radius: var(--vf-radius-md);
    cursor: pointer;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                background-color var(--vf-duration-fast) var(--vf-ease);
}

.vf-choice__item input:checked + .vf-choice__box {
    border-color: var(--vf-primary-500);
    background-color: var(--vf-primary-50);
    box-shadow: inset 0 0 0 1px var(--vf-primary-500);
}

.vf-choice__item input:focus-visible + .vf-choice__box {
    outline: 2px solid var(--vf-primary-500);
    outline-offset: 2px;
}

.vf-choice__title {
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-choice__desc { font-size: var(--vf-text-xs); color: var(--vf-muted); }


/* -----------------------------------------------------------------------------
   12. LAYOUT HELPERS
   -------------------------------------------------------------------------- */

/* Responsive product grid without Bootstrap's column soup. Auto-fills to the
   available width, so it needs no per-breakpoint column classes. */
.vf-grid {
    display: grid;
    gap: var(--vf-space-4);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 576px) { .vf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 992px) { .vf-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .vf-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.vf-grid--wide { grid-template-columns: repeat(1, minmax(0, 1fr)); }
@media (min-width: 576px) { .vf-grid--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px) { .vf-grid--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Horizontal scroller for mobile carousels — snap points, no JS. */
.vf-scroller {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(150px, 1fr);
    gap: var(--vf-space-4);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    padding-block-end: var(--vf-space-2);
}

.vf-scroller > * { scroll-snap-align: start; }

@media (min-width: 768px) {
    .vf-scroller { grid-auto-columns: minmax(200px, 1fr); }
}

/* Any wide child (table, code block, diagram) scrolls inside itself rather than
   scrolling the page sideways. The storefront must never scroll horizontally. */
.vf-overflow-x {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.vf-stack > * + * { margin-block-start: var(--vf-space-4); }

/* Reserve space for media before it loads. */
.vf-ratio-16x9 { aspect-ratio: 16 / 9; }
.vf-ratio-4x3 { aspect-ratio: 4 / 3; }
.vf-ratio-1x1 { aspect-ratio: 1 / 1; }
.vf-ratio-16x9 > img,
.vf-ratio-4x3 > img,
.vf-ratio-1x1 > img { width: 100%; height: 100%; object-fit: cover; }


/* -----------------------------------------------------------------------------
   8k. CATEGORY DIRECTORY  (/list/categories)
   --------------------------------------------------------------------------
   The all-categories page was a `.row` of `col-md-3` cells, one per ROOT
   category, each holding a `<ul style="list-style: none">` of its direct
   children.

   That shape does not fit this catalogue. There are exactly three roots
   (Vegetables, Leafy Vegetables, Fruits) and 172 categories in total, arranged
   three levels deep -- 81 at level two and 88 at level three. So the old page
   filled three of four cells in one row, left the fourth empty, rendered
   "Fruits" as a single 38-item column running far past the other two, and
   showed nothing at all below level two: 88 of the 172 categories it counted in
   its own header had no representation on the page.

   A directory is the right shape: one panel per root, its level-two categories
   flowed into CSS columns, each with its own level-three links beneath it. That
   is what a catalogue index looks like on every marketplace that has one, and
   it degrades to a single readable column on a phone without a media query per
   count.

   `break-inside: avoid` is what makes it work -- without it a level-two group
   and its leaves split across a column boundary and the heading ends up
   orphaned from its own children.
   -------------------------------------------------------------------------- */

.vf-catdir-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-3);
    margin-block-end: var(--vf-space-5);
}

.vf-catdir-search {
    position: relative;
    flex: 1 1 18rem;
    min-width: 0;
}

.vf-catdir-search .vf-input {
    padding-inline-start: calc(var(--vf-space-4) + 1.25rem);
}

.vf-catdir-search__icon {
    position: absolute;
    inset-inline-start: var(--vf-space-4);
    top: 50%;
    transform: translateY(-50%);
    color: var(--vf-n-400);
    pointer-events: none;
}

/* Jump links to each root panel. Cheap with three roots, and it is the only way
   to reach "Fruits" on a phone without scrolling past 80 links. */
.vf-catdir-jump {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
}

.vf-catdir {
    margin-block-end: var(--vf-space-5);
    /* Anchor targets sit under the sticky storefront header otherwise. */
    scroll-margin-block-start: var(--vf-space-8);
}

.vf-catdir__head {
    display: flex;
    align-items: center;
    gap: var(--vf-space-4);
    padding-block-end: var(--vf-space-4);
    margin-block-end: var(--vf-space-4);
    border-block-end: 1px solid var(--vf-border);
}

.vf-catdir__thumb {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: var(--vf-radius-md);
    overflow: hidden;
    background-color: var(--vf-n-50);
}

.vf-catdir__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.vf-catdir__titles {
    min-width: 0;
}

.vf-catdir__title {
    margin: 0;
    font-size: var(--vf-text-lg);
    font-weight: var(--vf-weight-bold);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
}

.vf-catdir__title a { color: inherit; text-decoration: none; }
.vf-catdir__title a:hover { color: var(--vf-primary); }

.vf-catdir__meta {
    margin: var(--vf-space-1) 0 0;
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
}

/* One column on a phone, then two, then three. Fixed counts rather than
   `column-width`, because the groups vary from 1 to 15 leaves and an automatic
   count produces a different layout every breakpoint pixel. */
.vf-catdir__groups {
    columns: 1;
    column-gap: var(--vf-space-6);
}

@media (min-width: 576px) { .vf-catdir__groups { columns: 2; } }
@media (min-width: 992px) { .vf-catdir__groups { columns: 3; } }

.vf-catdir__group {
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
    margin-block-end: var(--vf-space-5);
}

.vf-catdir__group-title {
    display: block;
    margin-block-end: var(--vf-space-2);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    text-decoration: none;
}

.vf-catdir__group-title:hover {
    color: var(--vf-primary);
    text-decoration: underline;
}

.vf-catdir__group-title .vf-catdir__n {
    font-weight: var(--vf-weight-normal);
    color: var(--vf-muted);
}

.vf-catdir__leaves {
    list-style: none;
    margin: 0;
    padding: 0;
}

.vf-catdir__leaves li + li { margin-block-start: var(--vf-space-1); }

.vf-catdir__leaves a {
    display: block;
    font-size: var(--vf-text-sm);
    line-height: var(--vf-leading-snug);
    color: var(--vf-body);
    text-decoration: none;
}

.vf-catdir__leaves a:hover {
    color: var(--vf-primary);
    text-decoration: underline;
}

/* Set by the filter script on a group whose name and leaves both miss the
   query. Display, not removal, so no reflow cost and no DOM churn per keypress. */
.vf-catdir__group[hidden],
.vf-catdir__leaves li[hidden],
.vf-catdir[hidden] {
    display: none !important;
}

/* Shown by the filter script when every group in every panel is hidden. */
.vf-catdir-noresults[hidden] { display: none; }


/* -----------------------------------------------------------------------------
   8l. SUPPLIER DIRECTORY  (/suppliers)
   --------------------------------------------------------------------------
   The supplier card was styled entirely by class names that are not defined in
   any stylesheet this site loads: `box-3`, `hov-shadow-md`, `has-transition`,
   `fw-600`, `rating-sm`, plus the Bootstrap 4 spellings `no-gutters`,
   `border-left` and `text-left`, which Bootstrap 5 renamed to `g-0`,
   `border-start` and `text-start`. Grepping every .css file under public/ for
   any of them returns nothing. So the "card" was an unstyled two-column row
   with a border that never drew and a shadow that never appeared -- which is
   why the page reads as a list of logos rather than as a directory.

   The page's own styling was a 47-line <style> block sitting inside
   @section('meta_tags'), giving the search bar a #b4c1ce slab, a #9C27B0 round
   button and a #ff6347 hover. None of those three colours appears anywhere else
   on the storefront, and none went through the contrast checks the rest of the
   palette did. It is the design system's own .vf-input-group now.

   What a supplier card has to answer, for a B2B directory, is "who are they and
   should I talk to them" -- so business type, main products and catalogue size
   are on the card. Every one of those columns was already on `companies` and
   none of them was rendered.
   -------------------------------------------------------------------------- */

.vf-supplier-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    overflow: hidden;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease),
                transform var(--vf-duration-fast) var(--vf-ease);
}

.vf-supplier-card:hover,
.vf-supplier-card:focus-within {
    border-color: var(--vf-primary-500);
    box-shadow: var(--vf-shadow-md);
    transform: translateY(-2px);
}

.vf-supplier-card__head {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
    padding: var(--vf-space-4);
    padding-block-end: var(--vf-space-3);
}

/* Fixed box with `contain`, not `cover`: these are logos. Cropping a wordmark
   to fill a square -- which is what the old `img-fluid` on a 100x100 did on any
   non-square file -- cuts the company's name in half. */
.vf-supplier-card__logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    padding: var(--vf-space-2);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-surface);
}

.vf-supplier-card__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.vf-supplier-card__titles { min-width: 0; flex: 1 1 auto; }

.vf-supplier-card__name {
    margin: 0;
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-semibold);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    /* Two lines, then ellipsis. The old card used .text-truncate, which is one
       line -- and most of these names do not fit on one line at this width. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.vf-supplier-card__name a { color: inherit; text-decoration: none; }
.vf-supplier-card__name a:hover { color: var(--vf-primary); }

.vf-supplier-card__body {
    flex: 1 1 auto;
    padding: 0 var(--vf-space-4) var(--vf-space-3);
}

/* Label / value pairs. A definition list rather than a table so it collapses to
   one column below `sm` without a second set of rules. */
.vf-supplier-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--vf-space-1) var(--vf-space-3);
    margin: 0;
    font-size: var(--vf-text-sm);
}

.vf-supplier-facts dt {
    font-weight: var(--vf-weight-normal);
    color: var(--vf-muted);
    white-space: nowrap;
}

.vf-supplier-facts dd {
    margin: 0;
    color: var(--vf-body);
    min-width: 0;
    overflow-wrap: anywhere;
}

.vf-supplier-card__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    padding: var(--vf-space-3) var(--vf-space-4);
    border-block-start: 1px solid var(--vf-border);
    background-color: var(--vf-surface-sunken);
}

.vf-supplier-card__foot .vf-btn { flex: 1 1 8rem; justify-content: center; }

/* --- Toolbar ------------------------------------------------------------- */

.vf-supplier-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-3);
    margin-block-end: var(--vf-space-5);
}

.vf-supplier-toolbar form {
    flex: 1 1 22rem;
    min-width: 0;
    margin: 0;
}


/* -----------------------------------------------------------------------------
   8m. CONTACT SUPPLIER + PRODUCT PAGE
   --------------------------------------------------------------------------
   The contact form was a single `col-md-8 mx-auto` inside a bare card: a
   one-line "Your Query" text box, a 10-row textarea and a Send button, with no
   indication anywhere on the page of WHO the message was going to beyond the
   banner at the top, and -- for a signed-out visitor -- two unstyled sentences
   where a call to action belongs.

   It also never rendered the success flash. CustomerQueryController::store()
   ends with `redirect()->back()->with("success", ...)` and no frontend layout
   renders `session('success')`, so sending a query returned the visitor to an
   identical empty form. There was no way to tell whether it had worked.

   .vf-aside-card is the "who you are talking to" panel, shared with the product
   page's seller box: the same information, the same shape, in both places.
   -------------------------------------------------------------------------- */

.vf-form-grid {
    display: grid;
    gap: var(--vf-space-5);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 992px) {
    .vf-form-grid {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }
}

/* The supporting panel comes second on a phone: the form is why the page was
   opened. */
@media (max-width: 991.98px) {
    .vf-form-grid > .vf-form-grid__aside { order: 2; }
    .vf-form-grid > .vf-form-grid__main { order: 1; }
}

.vf-aside-card__head {
    display: flex;
    align-items: center;
    gap: var(--vf-space-3);
    padding-block-end: var(--vf-space-4);
    margin-block-end: var(--vf-space-4);
    border-block-end: 1px solid var(--vf-border);
}

.vf-aside-card__logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    padding: var(--vf-space-2);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-surface);
}

.vf-aside-card__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.vf-aside-card__name {
    margin: 0;
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-semibold);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    overflow-wrap: anywhere;
}

.vf-aside-card__name a { color: inherit; text-decoration: none; }
.vf-aside-card__name a:hover { color: var(--vf-primary); }

/* Label / value rows, one column throughout: this panel is narrow at every
   breakpoint. */
.vf-aside-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--vf-space-2) var(--vf-space-3);
    margin: 0;
    font-size: var(--vf-text-sm);
}

.vf-aside-facts dt { color: var(--vf-muted); white-space: nowrap; }
.vf-aside-facts dd { margin: 0; color: var(--vf-body); overflow-wrap: anywhere; }

.vf-aside-card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    margin-block-start: var(--vf-space-4);
}

.vf-aside-card__actions .vf-btn { flex: 1 1 8rem; justify-content: center; }


/* --- Product page ---------------------------------------------------------

   The buy column ran from the title to the wishlist button as one undivided
   stack of `d-flex` rows and `split-line-thin` rules -- price, variations,
   quantity, country of origin, shipping, three buttons -- so nothing separated
   "what this is" from "what it costs" from "how to buy it". The blocks below
   are the same content, grouped.
   -------------------------------------------------------------------------- */

.vf-pdp {
    display: grid;
    gap: var(--vf-space-5);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

/* Gallery and buy box side by side from md, the seller panel joining them on a
   third column only at xl -- below that it sits under the buy box, which is
   where it belongs once the two columns are already narrow. */
@media (min-width: 768px) {
    .vf-pdp { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

@media (min-width: 1200px) {
    .vf-pdp { grid-template-columns: minmax(0, 4fr) minmax(0, 5fr) minmax(0, 3fr); }
}

@media (max-width: 1199.98px) {
    .vf-pdp__aside { grid-column: 1 / -1; }
}

/* A titled block inside the buy column. */
.vf-buy-block + .vf-buy-block {
    margin-block-start: var(--vf-space-4);
    padding-block-start: var(--vf-space-4);
    border-block-start: 1px solid var(--vf-border);
}

.vf-buy-label {
    display: block;
    margin-block-end: var(--vf-space-2);
    font-size: var(--vf-text-xs);
    font-weight: var(--vf-weight-semibold);
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--vf-muted);
}

.vf-pdp-title {
    font-size: var(--vf-text-xl);
    font-weight: var(--vf-weight-bold);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    margin: 0 0 var(--vf-space-2);
    overflow-wrap: anywhere;
}

@media (min-width: 992px) {
    .vf-pdp-title { font-size: var(--vf-text-2xl); }
}

/* Rating / review count / order count, wrapping instead of overflowing -- these
   sat in one `d-flex` with no wrap, so on a phone the order count ran off. */
.vf-pdp-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-2) var(--vf-space-4);
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
}

.vf-pdp-price {
    font-family: var(--vf-font-numeric, inherit);
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-price);
    line-height: 1.2;
}

.vf-pdp-price__was {
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-normal);
    color: var(--vf-price-was);
    text-decoration: line-through;
    margin-inline-start: var(--vf-space-2);
}

/* Bulk tiers: a row of quantity/price steps that wraps, rather than Bootstrap
   `.col`s that squeeze to unreadable widths once there are more than three. */
.vf-tiers {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-3);
}

.vf-tier {
    flex: 1 1 7rem;
    padding: var(--vf-space-3);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    background-color: var(--vf-surface);
}

.vf-tier.is-active {
    border-color: var(--vf-primary);
    box-shadow: 0 0 0 1px var(--vf-primary);
}

.vf-tier__price {
    display: block;
    font-size: var(--vf-text-lg);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
}

.vf-tier.is-active .vf-tier__price { color: var(--vf-primary); }

.vf-tier__qty {
    display: block;
    margin-block-start: .15rem;
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

/* The three buy actions. They were `d-flex` with `<span class="mx-1">` spacers
   and no wrap, so on a phone "Add to Cart", "Order Now" and the wishlist button
   were squeezed onto one line. */
.vf-buy-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
}

.vf-buy-actions > .btn,
.vf-buy-actions > .vf-btn {
    flex: 1 1 10rem;
}

.vf-buy-actions > .wishlist-btn {
    flex: 0 0 auto;
}

/* Facts under the actions: origin, ships-to, shipping estimate. */
.vf-pdp-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--vf-space-2) var(--vf-space-3);
    margin: 0;
    font-size: var(--vf-text-sm);
}

.vf-pdp-facts dt { color: var(--vf-muted); white-space: nowrap; }
.vf-pdp-facts dd { margin: 0; color: var(--vf-body); overflow-wrap: anywhere; }


/* --- Breadcrumbs ----------------------------------------------------------
   The product page built its trail from a `d-flex` of links with
   `<span class="mx-1">/</span>` between them and a final `<a href="#">` for the
   product itself -- a link to nowhere for the page you are already on. It also
   could not wrap, so a three-level category path plus a long product name ran
   off the side of a phone.
   -------------------------------------------------------------------------- */

.vf-crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-1) var(--vf-space-2);
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
}

.vf-crumbs li { display: inline-flex; align-items: center; gap: var(--vf-space-2); }

/* The separator is generated, so it is never read out as content and never
   ends up orphaned on a line of its own. */
.vf-crumbs li + li::before {
    content: "/";
    color: var(--vf-n-300);
}

.vf-crumbs a { color: var(--vf-body); text-decoration: none; }
.vf-crumbs a:hover { color: var(--vf-primary); text-decoration: underline; }

.vf-crumbs li[aria-current="page"] {
    color: var(--vf-muted);
    /* Long product names truncate rather than pushing the trail to three lines. */
    max-width: 22rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- A control that reads as a link ---------------------------------------
   Several places used `<a href="#">` for something that only ever ran a click
   handler: opening the reviews tab, opening the ship-to modal, clearing a
   variation. Without JS they jump to the top of the page, and they are
   announced as links to somewhere. A button, styled as a link.
   -------------------------------------------------------------------------- */

.vf-link-button {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--vf-primary);
    text-decoration: none;
    cursor: pointer;
}

.vf-link-button:hover { text-decoration: underline; }

.vf-link-button:focus-visible {
    outline: 2px solid var(--vf-primary-500);
    outline-offset: 2px;
    border-radius: var(--vf-radius-sm);
}


/* -----------------------------------------------------------------------------
   8n. SUPPLIER PROFILE  (/supplier-details/{slug})
   --------------------------------------------------------------------------
   The profile was a `col-md-4` holding an `img-fluid m-3` logo beside a
   `col-md-8` holding a `.table-borderless` of seven label/value rows. Three
   problems with that shape, on top of the "null" the rows printed:

     - the logo had no bound, so a square file rendered around 325px tall and
       was the largest thing on the page -- and it is the SECOND copy of that
       logo, the banner above it already shows one.
     - a <table> for what is a list of label/value pairs, which then needed
       `.table-responsive` around it to survive a phone, where it became a
       horizontal scroll rather than stacking.
     - every row rendered whether or not it had a value, so a supplier who had
       filled in two fields showed five empty ones.
   -------------------------------------------------------------------------- */

.vf-profile {
    display: grid;
    gap: var(--vf-space-5);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 768px) {
    .vf-profile { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); }
}

.vf-profile__media {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* Bounded, and `contain` rather than `cover`: a wordmark cropped to fill a
   square loses the company's name. */
.vf-profile__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 13rem;
    aspect-ratio: 1 / 1;
    padding: var(--vf-space-4);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    background-color: var(--vf-surface);
}

.vf-profile__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.vf-profile__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--vf-space-2);
    margin-block-start: var(--vf-space-4);
    width: 100%;
    max-width: 13rem;
}

.vf-profile__actions .vf-btn { flex: 1 1 100%; justify-content: center; }

/* Wider than the card version of this list, so long values -- a main-products
   line naming a dozen items -- get room before they wrap. */
.vf-profile__facts {
    font-size: var(--vf-text-base);
    gap: var(--vf-space-3) var(--vf-space-5);
    grid-template-columns: minmax(8rem, auto) minmax(0, 1fr);
}

@media (max-width: 575.98px) {
    .vf-profile__facts {
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
    }

    .vf-profile__facts dt { margin-block-start: var(--vf-space-3); }
    .vf-profile__facts dt:first-child { margin-block-start: 0; }
}

.vf-profile__about {
    margin-block-start: var(--vf-space-5);
    padding-block-start: var(--vf-space-5);
    border-block-start: 1px solid var(--vf-border);
}

/* --- Seller-authored rich text -------------------------------------------
   The storefront renders company and product descriptions with {!! !!}. Without
   a container an oversized <img> or a wide <table> inside one pushes the whole
   card past the viewport, and the storefront must never scroll sideways.
   -------------------------------------------------------------------------- */

.vf-prose {
    font-size: var(--vf-text-base);
    line-height: var(--vf-leading-relaxed);
    color: var(--vf-body);
    overflow-wrap: anywhere;
}

.vf-prose :is(img, video, iframe) {
    max-width: 100%;
    height: auto;
}

.vf-prose table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
}

.vf-prose > :last-child { margin-bottom: 0; }


/* --- Unsubscribe -----------------------------------------------------------
   A single-purpose page reached from a link in an email, so it is narrow and
   centred: there is one decision on it and nothing else.
   -------------------------------------------------------------------------- */

.vf-unsubscribe {
    max-width: 34rem;
    margin-inline: auto;
}


/* ==========================================================================
   .vf-rtable -- a table that becomes a stack of cards below `md`
   ==========================================================================

   Moved here from admin.css. It was only ever defined there, and admin.css is
   loaded by the admin and supplier shells but NOT by the buyer shell -- while
   four of the five screens that use this class extend getLayout(), which
   returns the buyer layout for a buyer. So the Address Book, the campaign
   report, the product detail and the order detail all rendered this class
   undefined for buyers: a plain six-column table at 390px, scrolling the page
   sideways with the Edit link of every row off-screen.

   One definition, in the sheet all three shells load.
   ========================================================================== */

.vf-rtable {
    width: 100%;
    margin: 0;
}

.vf-rtable th,
.vf-rtable td {
    padding: .6rem .75rem;
    vertical-align: middle;
    border-bottom: 1px solid var(--vf-border);
}

.vf-rtable thead th {
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--vf-muted);
    white-space: nowrap;
    border-bottom: 1px solid var(--vf-border-strong);
}

.vf-rtable tbody tr:last-child td {
    border-bottom: 0;
}

/* Money and quantity columns: tabular figures so digits line up down the
   column, and end-aligned. --vf-font-numeric is the face the dashboard
   figures already use. */
.vf-rtable .vf-num {
    font-family: var(--vf-font-numeric);
    font-variant-numeric: tabular-nums;
    text-align: end;
    white-space: nowrap;
}

@media (max-width: 767.98px) {
    .vf-rtable thead {
        /* Not display:none -- that removes it from the accessibility tree too.
           The per-cell data-label below carries the same information visually. */
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .vf-rtable,
    .vf-rtable tbody,
    .vf-rtable tr,
    .vf-rtable td {
        display: block;
        width: auto;
    }

    .vf-rtable tr {
        border: 1px solid var(--vf-border);
        border-radius: var(--vf-radius-md);
        padding: var(--vf-space-2) var(--vf-space-3);
        margin-bottom: var(--vf-space-3);
    }

    .vf-rtable tr:last-child {
        margin-bottom: 0;
    }

    .vf-rtable td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: var(--vf-space-3);
        padding: .3rem 0;
        border-bottom: 0;
        text-align: start;
    }

    .vf-rtable td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: var(--vf-text-2xs);
        font-weight: var(--vf-weight-semibold);
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--vf-muted);
    }

    /* A cell with no data-label (the row lead cell, the actions cell) spans
       the card on its own rather than pretending to be a label/value pair. */
    .vf-rtable td:not([data-label]) {
        display: block;
    }

    .vf-rtable .vf-num {
        text-align: end;
    }
}


/* ==========================================================================
   16px floor on text controls
   ==========================================================================

   iOS Safari zooms the viewport when a text control smaller than 16px receives
   focus, and does not zoom back out on blur -- the visitor is left on a zoomed,
   horizontally-pannable page for the rest of the session. The storefront
   viewport meta carries no maximum-scale, so nothing suppresses it.

   public/asoug/css/style.css:72 sets `html, body { font-size: 15px }`, and
   --vf-text-base is 1rem, so every control declaring it rendered at 15px --
   including the comment four hundred lines up that says 16px stops the zoom.
   Measured on /, /login and /list/products: html computes 15px and 6 of the 8
   visible text controls on /login sit under the threshold, on the checkout
   path.

   A floor rather than a fixed size, and deliberately so. This file now loads in
   the back office too, where the root is 17px; `font-size: 16px` would shrink
   every admin form control by a pixel as a side effect of a storefront fix.
   max() raises what is too small and leaves everything else alone.

   Not fixed by raising the root from 15px to 16px: Bootstrap 5.0.2 is rem-sized
   throughout, so that re-lays out every storefront page by 6.67%. vf-tokens.css
   warns against exactly that, and it is a separate change with its own visual
   regression pass. The scale is still wrong underneath this -- --vf-text-sm
   renders 13.13px where it documents 14px -- and that remains open.
   ========================================================================== */

.vf-input,
.vf-select,
.vf-textarea,
.form-control,
.form-select {
    font-size: max(16px, var(--vf-text-base));
}

/* ---------------------------------------------------------------------------
   DISCOUNT / COUPON CARDS
   Shared by the homepage discount strip and the full /coupons listing, so the
   card renders identically on both. Driven by global Coupons an admin creates.
   Three brand-aligned gradients cycle by index so a row is not one flat colour.
--------------------------------------------------------------------------- */
.vf-deal-strip {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

.vf-deal-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 22px 24px;
    border-radius: 14px;
    overflow: hidden;
    color: #fff;
    min-height: 150px;
}

.vf-deal-card--0 { background: linear-gradient(135deg, var(--vf-primary-700), var(--vf-primary-600)); }
.vf-deal-card--1 { background: linear-gradient(135deg, #d99e00, var(--vf-secondary-600)); color: var(--vf-on-secondary); }
.vf-deal-card--2 { background: linear-gradient(135deg, #1565c0, #1e88e5); }

.vf-deal-card__value {
    font-size: clamp(30px, 5vw, 46px);
    font-weight: 800;
    line-height: 1;
}

.vf-deal-card__name {
    font-size: 14px;
    font-weight: 600;
    opacity: .95;
}

.vf-deal-card__meta {
    font-size: 12px;
    opacity: .85;
}

.vf-deal-card__code {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    margin-top: auto;
    padding: 6px 12px;
    border-radius: 8px;
    background: rgba(255, 255, 255, .22);
    border: 1px dashed rgba(255, 255, 255, .7);
    font-weight: 700;
    letter-spacing: .5px;
}

.vf-deal-card--1 .vf-deal-card__code {
    background: rgba(20, 0, 63, .12);
    border-color: rgba(20, 0, 63, .45);
}

.vf-deal-card__link {
    position: absolute;
    inset-block-start: 16px;
    inset-inline-end: 18px;
    font-size: 12px;
    font-weight: 600;
    color: inherit;
    text-decoration: underline;
}

@media only screen and (max-width: 991.98px) {
    .vf-deal-strip { grid-template-columns: repeat(2, 1fr); }
}

@media only screen and (max-width: 575.98px) {
    .vf-deal-strip { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   PRODUCT LISTING (PLP) -- toolbar, card grid and sidebar filters.
   Shared by /list/products and /list/featured-products so both render the same.
--------------------------------------------------------------------------- */
.vf-plp-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    background: #fff;
    border: 1px solid var(--vf-border, #e6e8ee);
    border-radius: 12px;
    padding: 14px 18px;
    margin-bottom: 16px;
}

.vf-plp-toolbar__title { margin: 0; font-size: 18px; font-weight: 700; color: var(--vf-ink); }
.vf-plp-toolbar__count { margin: 2px 0 0; font-size: 13px; color: var(--vf-muted); }
.vf-plp-toolbar__sort { display: flex; align-items: center; gap: 10px; }
.vf-plp-toolbar__sort label { margin: 0; font-size: 13px; color: var(--vf-muted); white-space: nowrap; }

.vf-plp-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 16px;
}

@media (max-width: 1199.98px) { .vf-plp-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 991.98px)  { .vf-plp-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 767.98px)  { .vf-plp-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 400px)     { .vf-plp-grid { grid-template-columns: 1fr; } }

.vf-plp-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid var(--vf-border, #e6e8ee);
    border-radius: 12px;
    overflow: hidden;
    transition: box-shadow .2s, border-color .2s;
}

.vf-plp-card:hover {
    border-color: var(--vf-primary-500);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .08);
}

.vf-plp-card__media {
    position: relative;
    display: block;
    padding: 18px;
    aspect-ratio: 1 / 1;
    background: #fff;
}

.vf-plp-card__media img { width: 100%; height: 100%; object-fit: contain; }

.vf-plp-card__badge {
    position: absolute;
    inset-block-start: 10px;
    inset-inline-start: 10px;
    background: #ffe3e3;
    color: #e03131;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 6px;
    z-index: 2;
}

.vf-plp-card__cart {
    position: absolute;
    inset-block-end: 10px;
    inset-inline-end: 10px;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: #2f6bff;
    color: #fff;
    box-shadow: 0 4px 10px rgba(47, 107, 255, .35);
    z-index: 2;
    cursor: pointer;
}

.vf-plp-card__cart:hover { background: #1b56e0; }

.vf-plp-card__wish {
    position: absolute;
    inset-block-start: 10px;
    inset-inline-end: 10px;
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: #fff;
    color: #444;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
    z-index: 2;
    cursor: pointer;
    text-decoration: none;
    transition: color .15s ease, background .15s ease;
}

.vf-plp-card__wish:hover,
.vf-plp-card__wish.is-active { color: #e03131; }

.vf-plp-card__body { display: flex; flex-direction: column; gap: 4px; padding: 0 14px 14px; }
.vf-plp-card__price { font-size: 17px; font-weight: 800; color: var(--vf-primary-600); }
.vf-plp-card__facility { font-size: 11px; color: var(--vf-muted); }
.vf-plp-card__sep { margin: 8px 0; border: 0; border-top: 1px solid var(--vf-border, #eef0f4); }
.vf-plp-card__brand { font-size: 12px; font-weight: 600; color: var(--vf-accent); text-decoration: none; }

.vf-plp-card__title {
    font-size: 13px;
    line-height: 1.4;
    color: var(--vf-ink);
    text-decoration: none;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.vf-plp-card__title:hover { color: var(--vf-primary-600); }

.vf-plp-card__quote {
    display: inline-block;
    margin-top: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--vf-accent);
    text-decoration: none;
}

/* Sidebar -- each filter group is its own white card. */
.vf-filter-card {
    background: #fff;
    border: 1px solid var(--vf-border, #e6e8ee);
    border-radius: 12px;
    padding: 18px;
    margin-bottom: 16px;
}

.vf-filter-block__title { margin-bottom: 14px; font-size: 15px; font-weight: 700; color: var(--vf-ink); }

/* Categories header (label + current category) */
.vf-filter-cat-head {
    padding-bottom: 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--vf-border, #eef0f4);
}

.vf-filter-cat-head__label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--vf-primary-600);
    font-weight: 600;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .4px;
}

.vf-filter-cat-head__current { margin: 8px 0 0; font-size: 22px; font-weight: 800; color: var(--vf-ink); }

/* Clean category list -- no grey boxes, no bulky icons, subtle purple accents. */
.filter-category .accordion,
.filter-category .accordion-item { background: transparent !important; border: 0 !important; }
.filter-category .accordion-item { border-bottom: 1px solid var(--vf-border, #f0f1f5) !important; }
.filter-category .accordion-item:last-child { border-bottom: 0 !important; }

.filter-category .accordion-button {
    background: transparent !important;
    box-shadow: none !important;
    padding: 12px 2px !important;
    font-size: 14px;
    font-weight: 500;
    color: var(--vf-ink) !important;
}

.filter-category .accordion-button:not(.collapsed) { color: var(--vf-primary-600) !important; font-weight: 700; }
.filter-category .accordion-button::after { width: 1rem; height: 1rem; background-size: 1rem; }

.filter-category .accordion-button .bi-folder,
.filter-category .accordion-body .bi,
.filter-category h6 .bi { display: none !important; }

.filter-category .accordion-body { padding: 2px 0 10px !important; }

.filter-category .accordion-body a,
.filter-category h6.accordion-header a,
.filter-category ul li a {
    display: block;
    padding: 8px 12px !important;
    border-radius: 8px;
    font-size: 13px;
    color: var(--vf-muted) !important;
    background: transparent !important;
    text-decoration: none;
    transition: background .15s, color .15s;
}

.filter-category ul { list-style: none; padding: 0; margin: 0; }

.filter-category .accordion-body a:hover,
.filter-category h6.accordion-header a:hover,
.filter-category ul li a:hover {
    background: var(--vf-primary-50) !important;
    color: var(--vf-primary-600) !important;
}

.filter-category .accordion-body a.fw-bold,
.filter-category .accordion-body a.text-primary,
.filter-category h6.accordion-header a.fw-bold { background: var(--vf-primary-50) !important; color: var(--vf-primary-600) !important; font-weight: 700; }


/* -----------------------------------------------------------------------------
   8m. STOREFRONT FOOTER
   -----------------------------------------------------------------------------
   The legacy footer.css `.footer-section { background:#232F3E }` rule is in a
   sheet that no longer loads (public/asoug/css/footer.css is a 404), so the
   footer was rendering white headings on the page's own light background. This
   restyles it to the reference: a near-black panel, white column headings,
   muted-grey body copy and links, purple accent icons, and circular purple
   social buttons. Header-local purple is reused via the same value.
   -------------------------------------------------------------------------- */

.footer-section {
    --vf-foot-purple: #6d28d9;
    --vf-foot-purple-600: #5b21b6;
    background-color: #171717;
    color: #9a9a9a;
    padding-block: 3.5rem 2rem;
}

/* Column headings: white and bold, matching "About Company" / "Services" etc. */
.footer-section h4 {
    color: #ffffff;
    font-weight: 700;
    font-size: 1.125rem;
    margin-bottom: 1.25rem;
}

.footer-section p { color: #9a9a9a; }

/* Links: muted grey, brightening to white on hover. !important because the
   markup tags every footer link .text-white, whose Bootstrap rule is itself
   !important and would otherwise pin them all to solid white. The legacy sheet
   also slid links 10px sideways on hover; a colour shift is quieter and does
   not reflow the column. */
.footer-section a,
.footer-section li a,
.footer-section a.text-white {
    color: #b3b3b3 !important;
    text-decoration: none;
    transition: color var(--vf-duration-fast, .15s) var(--vf-ease, ease);
}

.footer-section a:hover,
.footer-section li:hover a,
.footer-section a.text-white:hover {
    color: #ffffff !important;
    padding-inline-start: 0; /* cancel legacy footer.css hover indent */
}

/* Social icons keep their white glyph on the purple fill -- exempt them from
   the muted-grey link colour above. */
.vf-foot-social a,
.vf-foot-social a:hover { color: #ffffff !important; }

.footer-section ul { list-style: none; padding: 0; margin: 0; }
.footer-section li { padding-block: 0.35rem; }

/* Accent icons (phone / help) in the brand purple, sized down from the
   legacy 50px so they read as an inline accent rather than a block.
   !important overrides the .text-white the icon markup also carries. */
.footer-section .icon-phone.text-white,
.footer-section .icon-phone,
.footer-section [class^="icon-"].h4 {
    color: var(--vf-foot-purple) !important;
    font-size: 1.75rem;
}

.footer-section .phone { color: #ffffff; font-size: 1rem; }

/* Divider before the copyright row. */
.footer-section hr {
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    margin-block: 2rem;
    opacity: 1;
}

/* ---- Social buttons -----------------------------------------------------
   The markup ships each link as an icon plus a text label. Here each becomes
   a filled purple circle showing only the icon; the label is kept in the DOM
   for screen readers but folded away visually. */
.vf-foot-social {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 0.25rem;
}

/* The bare <span class="mx-1"> spacers between links collapse under the flex
   gap above. */
.vf-foot-social > span { display: none; }

.vf-foot-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 44px;
    block-size: 44px;
    border-radius: 999px;
    background-color: var(--vf-foot-purple);
    color: #ffffff;
}

.vf-foot-social a:hover { background-color: var(--vf-foot-purple-600); }

/* Icon stays white on the purple fill; the .text-white on it already forces
   that, this just sizes it. */
.vf-foot-social a i { font-size: 1.125rem; margin: 0; }

/* Hide the "Facebook" / "Twitter" text labels visually, keep for a11y. */
.vf-foot-social a span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Copyright row. */
.footer-section > .container > .d-flex p { color: #9a9a9a; margin-bottom: 0; }
.footer-section > .container > .d-flex a { color: #b3b3b3; }
.footer-section > .container > .d-flex a:hover { color: #ffffff; }


/* -----------------------------------------------------------------------------
   8n. BREADCRUMBS
   -----------------------------------------------------------------------------
   Every storefront breadcrumb uses Bootstrap's .breadcrumb / .breadcrumb-item.
   The reference wants a light "»" double-chevron separator (not Bootstrap's
   "/"), muted-grey trail links, and a slightly darker current page. Styling
   the Bootstrap classes here covers every page at once.
   -------------------------------------------------------------------------- */

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    padding: 0;
    margin-block-end: 1rem;
    font-size: 0.875rem;
    background: transparent;
    list-style: none;
}

.breadcrumb-item,
.breadcrumb-item a {
    color: #8a8a8a;
    text-decoration: none;
    transition: color var(--vf-duration-fast, .15s) var(--vf-ease, ease);
}

.breadcrumb-item a:hover { color: var(--vf-hdr-purple, #6d28d9); }

/* The current page -- Bootstrap's .active. Kept a touch darker than the trail
   so it reads as "you are here" without shouting. */
.breadcrumb-item.active { color: #5f5f5f; }

/* Replace Bootstrap's "/" divider with the "»" chevron. Overriding the
   generated ::before content directly (rather than the --bs-breadcrumb-divider
   variable) so it works against the 5.0.2 bootstrap.css that hardcodes "/". */
.breadcrumb-item + .breadcrumb-item {
    padding-inline-start: 0;
}

.breadcrumb-item + .breadcrumb-item::before {
    content: "»";
    color: #b8b8b8;
    padding-inline: 0.5rem;
    float: none;
}

/* RTL: the chevron must point the other way. */
[dir="rtl"] .breadcrumb-item + .breadcrumb-item::before {
    content: "«";
}


/* -----------------------------------------------------------------------------
   8o. PRODUCT DETAIL (PDP2)
   -----------------------------------------------------------------------------
   The Aqasat product page: gallery + buy column, facilities + payment-option
   cards, a pill tab strip with a specification table, a compact related-product
   aside, and a related-product grid. CTAs use a blue accent (the mockup leads
   with blue action buttons) while price and brand accents stay purple.
   -------------------------------------------------------------------------- */

.vf-pdp2-page {
    --vf-pdp-purple: #6d28d9;
    --vf-pdp-blue: #2f6bff;
    --vf-pdp-blue-600: #1e54e0;
    --vf-pdp-red: #e5342b;
    --vf-pdp-card-radius: 12px;
}

/* ---- hero grid: gallery + buy column ----------------------------------- */
.vf-pdp2 {
    display: grid;
    gap: var(--vf-space-6);
    grid-template-columns: 1fr;
    align-items: start;
    margin-block-end: var(--vf-space-6);
}

@media (min-width: 768px) {
    .vf-pdp2 { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

.vf-pdp2__gallery {
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-pdp-card-radius);
    padding: var(--vf-space-4);
    background: var(--vf-surface);
}

.vf-pdp2__gallery img { max-width: 100%; height: auto; }

.vf-pdp2__title {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    line-height: var(--vf-leading-snug);
    color: var(--vf-ink);
    margin: 0 0 var(--vf-space-3);
}

.vf-pdp2__price {
    font-size: var(--vf-text-2xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-pdp-purple);
    margin-block-end: var(--vf-space-4);
}

.vf-pdp2__price-was {
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-medium);
    color: var(--vf-muted);
    margin-inline-start: var(--vf-space-2);
}

/* ---- facilities row ---------------------------------------------------- */
.vf-facilities { margin-block-end: var(--vf-space-4); }

.vf-facilities__label { display: block; margin-block-end: var(--vf-space-2); }

.vf-facilities__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--vf-space-3);
}

@media (min-width: 576px) {
    .vf-facilities__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.vf-facility {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--vf-space-1);
    font-size: var(--vf-text-2xs);
    color: var(--vf-muted);
}

.vf-facility i {
    font-size: 1.05rem;
    color: var(--vf-pdp-purple);
}

/* ---- payment option cards --------------------------------------------- */
.vf-payopt { margin-block-end: var(--vf-space-4); }
.vf-payopt .vf-buy-label { display: block; margin-block-end: var(--vf-space-2); }

.vf-payopt__cards {
    display: grid;
    gap: var(--vf-space-3);
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.vf-payopt__card {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-2);
    padding: var(--vf-space-3);
    border: 1.5px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    cursor: pointer;
    margin: 0;
    transition: border-color var(--vf-duration-fast) var(--vf-ease),
                box-shadow var(--vf-duration-fast) var(--vf-ease);
}

.vf-payopt__card input { margin-block-start: 3px; accent-color: var(--vf-pdp-blue); }

/* :has() keeps the visual selection in sync with the real radio; .is-active is
   the initial server-rendered state. */
.vf-payopt__card:has(input:checked),
.vf-payopt__card.is-active {
    border-color: var(--vf-pdp-blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--vf-pdp-blue) 15%, transparent);
}

.vf-payopt__body { display: flex; flex-direction: column; gap: 2px; }
.vf-payopt__amt { font-weight: var(--vf-weight-bold); color: var(--vf-ink); }
.vf-payopt__amt--emi { color: var(--vf-pdp-purple); }
.vf-payopt__amt small { font-weight: var(--vf-weight-medium); color: var(--vf-muted); }
.vf-payopt__note { font-size: var(--vf-text-2xs); color: var(--vf-muted); }

/* ---- quantity + buy now ----------------------------------------------- */
.vf-buyrow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--vf-space-3);
    margin-block-end: var(--vf-space-3);
}

.vf-buyrow--secondary { margin-block-start: calc(-1 * var(--vf-space-1)); }

.vf-qty {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-pill);
    overflow: hidden;
}

.vf-qty button {
    inline-size: 40px;
    block-size: 40px;
    border: 0;
    background: var(--vf-surface);
    color: var(--vf-ink);
    font-size: var(--vf-text-lg);
    cursor: pointer;
}

.vf-qty button:hover { background: var(--vf-n-50); }

.vf-qty input {
    inline-size: 44px;
    block-size: 40px;
    border: 0;
    border-inline: 1px solid var(--vf-border);
    text-align: center;
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    background: var(--vf-surface);
}

.vf-buynow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--vf-space-2);
    min-block-size: 44px;
    padding-inline: var(--vf-space-6);
    border: 0;
    border-radius: var(--vf-radius-md);
    background: var(--vf-pdp-blue);
    color: #fff;
    font-weight: var(--vf-weight-semibold);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--vf-duration-fast) var(--vf-ease);
}

.vf-buynow:hover { background: var(--vf-pdp-blue-600); color: #fff; }
.vf-buynow:disabled { opacity: .6; cursor: default; }

.vf-wish2 {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-1);
    min-block-size: 44px;
    padding-inline: var(--vf-space-3);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    background: var(--vf-surface);
    color: var(--vf-body);
    cursor: pointer;
}

.vf-wish2 .text-red { color: var(--vf-pdp-red); }

.vf-pdp2__note {
    margin-block: var(--vf-space-4) 0;
    font-size: var(--vf-text-sm);
    color: var(--vf-muted);
    line-height: var(--vf-leading-normal);
}

.vf-pdp2__note-label { color: var(--vf-pdp-red); font-weight: var(--vf-weight-semibold); }

/* ---- lower: tabs + aside ---------------------------------------------- */
.vf-pdp2-lower {
    display: grid;
    gap: var(--vf-space-6);
    grid-template-columns: 1fr;
    align-items: start;
    margin-block-end: var(--vf-space-7);
}

@media (min-width: 992px) {
    .vf-pdp2-lower { grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); }
}

.vf-tabs2 {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    margin-block-end: var(--vf-space-4);
}

.vf-tab2 {
    padding: var(--vf-space-2) var(--vf-space-4);
    border: 1px solid var(--vf-pdp-blue);
    border-radius: var(--vf-radius-md);
    background: var(--vf-surface);
    color: var(--vf-pdp-blue);
    font-size: var(--vf-text-sm);
    font-weight: var(--vf-weight-medium);
    cursor: pointer;
    transition: background var(--vf-duration-fast) var(--vf-ease),
                color var(--vf-duration-fast) var(--vf-ease);
}

.vf-tab2:hover { background: color-mix(in srgb, var(--vf-pdp-blue) 8%, transparent); }
.vf-tab2.is-active { background: var(--vf-pdp-blue); color: #fff; }

.vf-tabpanel {
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-pdp-card-radius);
    padding: var(--vf-space-5);
    background: var(--vf-surface);
}

.vf-tabpanel__title {
    font-size: var(--vf-text-xl);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    margin: 0 0 var(--vf-space-4);
}

/* specification table */
.vf-spec__head {
    background: color-mix(in srgb, var(--vf-pdp-blue) 8%, var(--vf-surface));
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-md);
    padding: var(--vf-space-3) var(--vf-space-4);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
    margin-block-end: var(--vf-space-3);
}

.vf-spec__table { width: 100%; border-collapse: collapse; }

.vf-spec__table th,
.vf-spec__table td {
    padding: var(--vf-space-3) var(--vf-space-2);
    border-block-end: 1px solid var(--vf-border);
    vertical-align: top;
    text-align: start;
    font-size: var(--vf-text-sm);
}

.vf-spec__table th {
    inline-size: 34%;
    font-weight: var(--vf-weight-medium);
    color: var(--vf-muted);
}

.vf-spec__table td { color: var(--vf-body); }
.vf-spec__empty { color: var(--vf-muted); margin: 0; }

.vf-rte { color: var(--vf-body); line-height: var(--vf-leading-relaxed); }
.vf-rte :where(img) { max-width: 100%; height: auto; }

/* ---- related aside (compact list) ------------------------------------- */
.vf-pdp2-aside {
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-pdp-card-radius);
    padding: var(--vf-space-4);
    background: var(--vf-surface);
}

.vf-pdp2-aside__title,
.vf-pdp2-related__title {
    font-size: var(--vf-text-base);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    margin: 0 0 var(--vf-space-3);
}

.vf-related-mini {
    display: flex;
    gap: var(--vf-space-3);
    padding-block: var(--vf-space-3);
    border-block-end: 1px solid var(--vf-border);
    text-decoration: none;
}

.vf-related-mini:last-child { border-block-end: 0; }

.vf-related-mini__media {
    position: relative;
    flex: 0 0 auto;
    inline-size: 56px;
    block-size: 56px;
    border-radius: var(--vf-radius-sm);
    overflow: hidden;
    background: var(--vf-n-50);
}

.vf-related-mini__media img { width: 100%; height: 100%; object-fit: cover; }

.vf-related-mini__badge {
    position: absolute;
    inset-block-start: 2px;
    inset-inline-start: 2px;
    padding: 1px 4px;
    border-radius: var(--vf-radius-sm);
    background: var(--vf-pdp-red);
    color: #fff;
    font-size: 9px;
    font-weight: var(--vf-weight-semibold);
}

.vf-related-mini__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.vf-related-mini__name {
    font-size: var(--vf-text-xs);
    color: var(--vf-body);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.vf-related-mini__price { font-size: var(--vf-text-sm); font-weight: var(--vf-weight-bold); color: var(--vf-pdp-purple); }
.vf-related-mini__price del { color: var(--vf-muted); font-weight: var(--vf-weight-normal); font-size: var(--vf-text-2xs); margin-inline-start: 4px; }

/* ---- related grid ----------------------------------------------------- */
.vf-pdp2-related { margin-block-end: var(--vf-space-6); }

.vf-pdp2-related__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--vf-space-3);
    margin-block-end: var(--vf-space-4);
}

.vf-pdp2-related__title { margin: 0; font-size: var(--vf-text-lg); }
.vf-pdp2-related__sub { margin: 2px 0 0; font-size: var(--vf-text-xs); color: var(--vf-muted); }
.vf-pdp2-related__all { font-size: var(--vf-text-sm); color: var(--vf-pdp-blue); text-decoration: none; white-space: nowrap; }
.vf-pdp2-related__all:hover { text-decoration: underline; }

.vf-pdp2-related__badge {
    position: absolute;
    inset-block-start: var(--vf-space-2);
    inset-inline-start: var(--vf-space-2);
    z-index: 1;
    padding: 2px 6px;
    border-radius: var(--vf-radius-sm);
    background: var(--vf-pdp-red);
    color: #fff;
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
}

.vf-pdp2-related__price { font-size: var(--vf-text-base); font-weight: var(--vf-weight-bold); color: var(--vf-pdp-purple); }
.vf-pdp2-related__facil { font-size: 10px; color: var(--vf-muted); margin: 2px 0 var(--vf-space-1); }
.vf-pdp2-related__cat { font-size: var(--vf-text-2xs); color: var(--vf-pdp-blue); margin: 0 0 2px; }

/* the floating cart chip on each grid card */
.vf-pdp2-related .vf-product-card { position: relative; }

.vf-pdp2-related__cart {
    position: absolute;
    inset-block-end: var(--vf-space-3);
    inset-inline-end: var(--vf-space-3);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 34px;
    block-size: 34px;
    border-radius: var(--vf-radius-pill);
    background: var(--vf-n-100);
    color: var(--vf-muted);
    font-size: var(--vf-text-sm);
}

.vf-pdp2-related .vf-product-card:hover .vf-pdp2-related__cart {
    background: var(--vf-pdp-blue);
    color: #fff;
}
