/* =============================================================================
   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.
   -------------------------------------------------------------------------- */

.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);
}

.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:not(.vf-btn) {
    color: var(--vf-accent);
    text-decoration: none;
    transition: color var(--vf-duration-fast) var(--vf-ease);
}

.vf-scope a:not(.vf-btn):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); }

/* Coupon chip on the order list foot -- one glance tells the seller/admin
   which orders used a coupon and how much came off. */
.vf-order__coupon {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px;
    border-radius: 999px;
    background: rgba(33, 161, 121, .10);
    color: #21a179;
    font-weight: 600;
    font-size: 12px;
    line-height: 1.6;
}
.vf-order__coupon i { font-size: 10px; }
.vf-order__coupon-amt { color: #21a179; font-weight: 700; margin-inline-start: 2px; }

@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;
}

/* 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: color-mix(in srgb, var(--vf-primary) 88%, #000);
    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; margin-inline-end: auto; }

.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;
}

/* The header CTAs. Reuses .vf-btn rather than growing a header-only button:
   the only thing the header needs to add is that they never wrap or shrink
   into two lines next to the account control. */
.vf-hdr__ctas {
    display: flex;
    align-items: center;
    gap: var(--vf-space-2);
    flex: 0 0 auto;
}

.vf-hdr__ctas .vf-btn { white-space: nowrap; }

.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-1);
    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; }

.vf-hdr__cart-badge {
    position: absolute;
    inset-block-start: -6px;
    inset-inline-end: -8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 18px;
    block-size: 18px;
    padding-inline: 4px;
    border-radius: var(--vf-radius-pill);
    /* Not --vf-secondary: the brand yellow is 1.22:1 on white and fails
       WCAG 1.4.11 as a UI-component boundary. */
    background-color: var(--vf-primary);
    color: var(--vf-on-primary);
    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: main navigation --------------------------------------------- */

.vf-hdr__nav { background-color: var(--vf-primary); }

.vf-hdr__nav-list { gap: var(--vf-space-1); }

/* .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__nav-list > li {
    flex-shrink: 0;
}

.vf-hdr__nav-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__nav-link:hover { color: var(--vf-on-primary); }

.vf-hdr__nav-link[aria-current="page"] {
    border-block-end-color: var(--vf-secondary);
    color: var(--vf-on-primary);
    font-weight: var(--vf-weight-semibold);
}

.vf-hdr__nav-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__logo img { max-height: 32px; }
}


/* -----------------------------------------------------------------------------
   8g-2. MOBILE OFFCANVAS  (layouts/mobile_canvas.blade.php)
   -----------------------------------------------------------------------------
   Below lg this panel IS the site navigation, so it gets the same treatment as
   the header rather than the bare stack of .text-dark anchors it replaces. Those
   anchors had no tap target of their own -- a 21px line box inside a flex column
   -- which is under half the 44px WCAG 2.5.8 asks for.

   Everything here is logical-property only: the offcanvas opens from the inline
   start, so under RTL it comes from the right and its rules must follow.
   -------------------------------------------------------------------------- */

.vf-offcanvas {
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-4);
}

.vf-offcanvas__ctas {
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-2);
}

.vf-offcanvas__nav {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.vf-offcanvas__link {
    display: flex;
    align-items: center;
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-2);
    border-radius: var(--vf-radius-sm);
    color: var(--vf-ink);
    font-size: var(--vf-text-base);
    text-decoration: none;
}

.vf-offcanvas__link:hover {
    background-color: var(--vf-primary-50);
    color: var(--vf-primary);
    text-decoration: none;
}

/* The current page, and the current language, are both marked -- aria-current
   page for one, aria-current true for the other -- so one rule covers both. */
.vf-offcanvas__link[aria-current] {
    background-color: var(--vf-primary-100);
    color: var(--vf-primary);
    font-weight: var(--vf-weight-semibold);
}

.vf-offcanvas__link:focus-visible {
    outline: 2px solid var(--vf-primary);
    outline-offset: -2px;
}

.vf-offcanvas__label {
    margin: 0;
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--vf-muted);
}

.vf-offcanvas__rule {
    margin: 0;
    border: 0;
    border-block-start: 1px solid var(--vf-border);
    opacity: 1;
}


/* -----------------------------------------------------------------------------
   8g-3. STOREFRONT FOOTER  (layouts/footer.blade.php)
   -----------------------------------------------------------------------------
   Here rather than in a @push('head_tags') inside the footer blade, which is
   where it started and where it silently did nothing: layouts/app.blade.php
   renders @stack('head_tags') from layouts/style.blade.php at line 12, inside
   <head>, and includes the footer at line 27. The stack is already flushed by
   then, so the push arrived too late and the footer rendered unstyled.

   Sections get away with @push because @yield('content') is evaluated before
   the layout renders. Anything included BY the layout -- header, footer,
   offcanvas -- has to put its CSS here instead.

   A new class rather than an override of .footer-section: the legacy rules in
   syaanah/css/footer.css are shared and carry !important, and this file must
   not have to out-specify declarations written for a different design.
   -------------------------------------------------------------------------- */

/* The legacy .footer-section rules live in syaanah/css/footer.css, which
   is shared and must not be edited. This is a new class rather than an
   override of that one, so nothing here has to out-specify !important
   declarations written for a different design. */
.vf-footer {
    background-color: var(--vf-primary);
    color: rgba(255, 255, 255, 0.82);
    padding-block: var(--vf-space-8) var(--vf-space-5);
}

.vf-footer__top {
    display: grid;
    gap: var(--vf-space-6);
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .vf-footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
    /* The brand column carries the intro and contact details, so it gets
       roughly double the width of a link column. */
    .vf-footer__top { grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr)); }
}

.vf-footer__brand { display: flex; flex-direction: column; gap: var(--vf-space-3); }

.vf-footer__logo img {
    max-height: 48px;
    max-width: 190px;
    width: auto;
    object-fit: contain;
}

.vf-footer__intro {
    margin: 0;
    max-width: 46ch;
    font-size: var(--vf-text-sm);
    line-height: var(--vf-leading-relaxed);
    color: rgba(255, 255, 255, 0.78);
}

.vf-footer__contact {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-2);
    font-size: var(--vf-text-sm);
}

.vf-footer__contact li { display: flex; align-items: flex-start; gap: var(--vf-space-2); }
.vf-footer__contact i { margin-block-start: 4px; opacity: 0.8; }

.vf-footer__heading {
    margin: 0 0 var(--vf-space-3);
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--vf-on-primary);
}

.vf-footer__links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

/* 44px tap target. The old list gave each link a 0.2rem-padded line box,
   roughly 24px, which is well under WCAG 2.5.8. */
.vf-footer a {
    color: rgba(255, 255, 255, 0.82);
    text-decoration: none;
}

.vf-footer__links a {
    display: flex;
    align-items: center;
    min-block-size: var(--vf-tap);
    font-size: var(--vf-text-sm);
}

.vf-footer a:hover,
.vf-footer a:focus-visible {
    color: var(--vf-on-primary);
    text-decoration: underline;
}

/* Focus has to be visible against the brand, so it is the secondary
   rather than the primary -- 7.14:1 on --vf-primary. */
.vf-footer a:focus-visible {
    outline: 2px solid var(--vf-secondary);
    outline-offset: 2px;
    border-radius: var(--vf-radius-sm);
}

.vf-footer__social { display: flex; flex-wrap: wrap; gap: var(--vf-space-2); }

.vf-footer__social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--vf-tap);
    height: var(--vf-tap);
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--vf-radius-pill);
    font-size: var(--vf-text-base);
}

.vf-footer__social a:hover {
    background-color: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.5);
}

.vf-footer__apps { display: flex; flex-wrap: wrap; gap: var(--vf-space-2); }

.vf-footer__app {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-2);
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-4);
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--vf-radius-md);
    font-size: var(--vf-text-sm);
}

.vf-footer__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--vf-space-3);
    margin-block-start: var(--vf-space-6);
    padding-block-start: var(--vf-space-5);
    border-block-start: 1px solid rgba(255, 255, 255, 0.18);
    font-size: var(--vf-text-sm);
}

.vf-footer__legal {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-4);
}

.vf-footer__copy { margin: 0; color: rgba(255, 255, 255, 0.72); }


/* -----------------------------------------------------------------------------
   8o. CMS PAGE  (website/webpage.blade.php)
   -----------------------------------------------------------------------------
   Fourteen pages in two languages render through one template, so this is the
   most-used layout on the site after the homepage.

   .vf-prose is deliberately general: it styles editor-authored HTML -- the tags
   a rich-text editor emits and nothing else -- so the blog, articles and product
   descriptions can adopt it later without a second copy of the same rules.
   Everything is logical-property only; the primary audience reads right to left.
   -------------------------------------------------------------------------- */

.vf-page-hero {
    background-color: var(--vf-primary-50);
    border-block-end: 1px solid var(--vf-primary-100);
    padding-block: var(--vf-space-7);
}

.vf-page-hero__crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-2);
    margin-block-end: var(--vf-space-3);
    font-size: var(--vf-text-xs);
    color: var(--vf-muted);
}

.vf-page-hero__crumbs a { color: var(--vf-primary-500); text-decoration: none; }
.vf-page-hero__crumbs a:hover { text-decoration: underline; }
.vf-page-hero__crumbs span[aria-hidden] { color: var(--vf-border-strong); }

.vf-page-hero__title {
    margin: 0;
    font-size: var(--vf-text-4xl);
    line-height: var(--vf-leading-tight);
    font-weight: var(--vf-weight-bold);
    color: var(--vf-ink);
    text-wrap: balance;
}

.vf-page-hero__lede {
    margin-block: var(--vf-space-3) 0;
    max-width: 68ch;
    font-size: var(--vf-text-lg);
    line-height: var(--vf-leading-relaxed);
    color: var(--vf-body);
}

.vf-page-hero__actions { margin-block-start: var(--vf-space-5); }


/* --- Grouped content ------------------------------------------------------ */

.vf-page-groups {
    display: grid;
    gap: var(--vf-space-4);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    margin-block-start: var(--vf-space-6);
}

.vf-page-group {
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-3);
    height: 100%;
    padding: var(--vf-space-5);
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
}

/* The group that is really a form spec carries the page action, so it is marked
   out rather than reading as one more list of features. */
.vf-page-group--action {
    background-color: var(--vf-primary-50);
    border-color: var(--vf-primary-100);
}

.vf-page-group__head {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-3);
}

.vf-page-group__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    min-inline-size: 30px;
    block-size: 30px;
    padding-inline: var(--vf-space-2);
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-primary);
    color: var(--vf-on-primary);
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
}

.vf-page-group__title {
    margin: 0;
    font-size: var(--vf-text-lg);
    line-height: var(--vf-leading-snug);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-page-group__action { align-self: flex-start; margin-block-start: auto; }


/* --- Prose ----------------------------------------------------------------
   Editor HTML. Resets the browser defaults the storefront never set, and gives
   lists a marker that belongs to the brand rather than a black disc. */

.vf-prose { color: var(--vf-body); font-size: var(--vf-text-base); line-height: var(--vf-leading-relaxed); }

.vf-prose > *:first-child { margin-block-start: 0; }
.vf-prose > *:last-child { margin-block-end: 0; }

.vf-prose p { margin-block: 0 var(--vf-space-3); }

.vf-prose h2,
.vf-prose h3,
.vf-prose h4 {
    margin-block: var(--vf-space-5) var(--vf-space-2);
    color: var(--vf-ink);
    font-weight: var(--vf-weight-semibold);
    line-height: var(--vf-leading-snug);
}

.vf-prose h2 { font-size: var(--vf-text-2xl); }
.vf-prose h3 { font-size: var(--vf-text-xl); }
.vf-prose h4 { font-size: var(--vf-text-lg); }

.vf-prose a { color: var(--vf-primary-500); text-decoration: underline; }
.vf-prose strong { color: var(--vf-ink); font-weight: var(--vf-weight-semibold); }

.vf-prose ul,
.vf-prose ol {
    margin-block: 0 var(--vf-space-3);
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-2);
}

.vf-prose li {
    position: relative;
    padding-inline-start: var(--vf-space-5);
}

/* inset-inline-start, not left: under RTL the marker has to sit to the right of
   the text, which a physical property would not do. */
.vf-prose ul > li::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0.6em;
    inline-size: 6px;
    block-size: 6px;
    border-radius: 50%;
    background-color: var(--vf-primary-500);
}

.vf-prose ol { counter-reset: vf-prose-count; }

.vf-prose ol > li { counter-increment: vf-prose-count; }

.vf-prose ol > li::before {
    content: counter(vf-prose-count) ".";
    position: absolute;
    inset-inline-start: 0;
    color: var(--vf-primary-500);
    font-weight: var(--vf-weight-semibold);
    font-size: var(--vf-text-sm);
}

/* Pasted tables have no width limit of their own and would scroll the page
   sideways on a phone. */
.vf-prose table { display: block; max-width: 100%; overflow-x: auto; }

.vf-prose img { max-width: 100%; height: auto; border-radius: var(--vf-radius-md); }

.vf-prose blockquote {
    margin: 0 0 var(--vf-space-3);
    padding-inline-start: var(--vf-space-4);
    border-inline-start: 3px solid var(--vf-primary-100);
    color: var(--vf-muted);
}

.vf-prose--lede {
    max-width: 72ch;
    font-size: var(--vf-text-lg);
    color: var(--vf-body);
}


/* --- Stub + closing action ------------------------------------------------ */

.vf-page-stub {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--vf-space-3);
    max-width: 52ch;
    margin-inline: auto;
    padding: var(--vf-space-7) var(--vf-space-5);
    background-color: var(--vf-surface-sunken);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-lg);
    text-align: center;
}

.vf-page-stub__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 48px;
    block-size: 48px;
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-primary-100);
    color: var(--vf-primary);
    font-size: var(--vf-text-xl);
}

.vf-page-stub__title { margin: 0; font-size: var(--vf-text-lg); font-weight: var(--vf-weight-semibold); color: var(--vf-ink); }
.vf-page-stub__text { margin: 0; font-size: var(--vf-text-sm); color: var(--vf-muted); }

.vf-page-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--vf-space-4);
    padding: var(--vf-space-6);
    background-color: var(--vf-primary);
    color: var(--vf-on-primary);
    border-radius: var(--vf-radius-xl);
}

.vf-page-cta__title {
    margin: 0 0 var(--vf-space-1);
    font-size: var(--vf-text-xl);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-on-primary);
}

/* 85% white on the brand #673091 is 6.78:1 -- comfortably past AA. */
.vf-page-cta__text { margin: 0; font-size: var(--vf-text-sm); color: rgba(255, 255, 255, 0.85); max-width: 56ch; }

@media (max-width: 575.98px) {
    .vf-page-hero { padding-block: var(--vf-space-6); }
    .vf-page-hero__title { font-size: var(--vf-text-3xl); }
}

/* -----------------------------------------------------------------------------
   8p. PUBLIC APPLICATION FORM  (frontend/partner/apply.blade.php)
   -----------------------------------------------------------------------------
   The field primitives -- .vf-field, .vf-label, .vf-input, .vf-select,
   .vf-textarea, .vf-help, .vf-error -- already exist further up this file and
   are reused unchanged. Only the page-level furniture is new: the panel the
   form sits in, its two-column grid, the summary shown when validation fails,
   and the confirmation shown after a successful submit.

   Named .vf-apply-grid, not .vf-form-grid: that name is already taken further
   down by the form-plus-aside layout on the contact page, and reusing it here
   would have given every field a 1.6fr/1fr split.
   -------------------------------------------------------------------------- */

.vf-form-panel {
    max-width: 56rem;
    margin-inline: auto;
    padding: clamp(var(--vf-space-5), 4vw, var(--vf-space-7));
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-xl);
}

.vf-apply-grid {
    display: grid;
    gap: 0 var(--vf-space-5);
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 768px) {
    .vf-apply-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Email, the free-text fields and the notes read across the full measure;
       the short identity fields pair up. */
    .vf-apply-grid > .vf-field--wide { grid-column: 1 / -1; }
}

/* Thirteen inputs in one run reads as a tax return, so the quote form groups
   them. A real <fieldset>/<legend>, not a styled div: it is what tells a screen
   reader which questions belong together, and the border is reset because the
   browser default cuts through the legend. */
.vf-fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 var(--vf-space-5);
}

.vf-fieldset__legend {
    padding: 0;
    margin-block-end: var(--vf-space-4);
    font-size: var(--vf-text-2xs);
    font-weight: var(--vf-weight-semibold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--vf-primary);
}

.vf-fieldset + .vf-fieldset {
    padding-block-start: var(--vf-space-5);
    border-block-start: 1px solid var(--vf-border);
}

.vf-fieldset-note {
    margin: 0;
    padding: var(--vf-space-3) var(--vf-space-4);
    background-color: var(--vf-primary-50);
    border-radius: var(--vf-radius-md);
    font-size: var(--vf-text-sm);
    color: var(--vf-body);
}

.vf-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-3);
    margin-block-start: var(--vf-space-3);
}

/* --- Validation summary ---------------------------------------------------
   A summary as well as the per-field messages: a long form scrolled past the
   first error otherwise submits and looks like nothing happened. */

.vf-form-errors {
    margin-block-end: var(--vf-space-5);
    padding: var(--vf-space-4) var(--vf-space-5);
    background-color: var(--vf-danger-bg);
    border: 1px solid var(--vf-danger);
    border-radius: var(--vf-radius-md);
    color: var(--vf-danger);
}

.vf-form-errors__title {
    margin: 0 0 var(--vf-space-2);
    font-weight: var(--vf-weight-semibold);
}

.vf-form-errors ul {
    margin: 0;
    padding-inline-start: var(--vf-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--vf-space-1);
    font-size: var(--vf-text-sm);
}

/* --- Confirmation --------------------------------------------------------- */

.vf-applied {
    display: flex;
    align-items: flex-start;
    gap: var(--vf-space-4);
    margin-block-end: var(--vf-space-6);
    padding: var(--vf-space-5);
    background-color: var(--vf-success-bg);
    border: 1px solid var(--vf-success);
    border-radius: var(--vf-radius-lg);
}

.vf-applied__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    inline-size: 40px;
    block-size: 40px;
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-success);
    color: var(--vf-n-0);
    font-size: var(--vf-text-base);
}

.vf-applied__title {
    margin: 0 0 var(--vf-space-1);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-success);
}

.vf-applied__text { margin: 0; font-size: var(--vf-text-sm); color: var(--vf-body); }

/* -----------------------------------------------------------------------------
   8q. RESTAURANT OFFERS  (frontend/offers/index.blade.php)
   -----------------------------------------------------------------------------
   The offer cards themselves are .vf-product-card, unchanged -- this is the
   furniture around them: the hero search, the category chip rail, the results
   bar, and the two empty states.

   Everything is logical-property only. The chip rail in particular scrolls
   horizontally on a phone, and under RTL it has to start from the right, which
   padding-inline and scroll-padding-inline handle and their physical
   counterparts would not.
   -------------------------------------------------------------------------- */

.vf-offer-search {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    margin-block-start: var(--vf-space-5);
    max-width: 44rem;
}

.vf-offer-search__input {
    flex: 1 1 16rem;
    min-inline-size: 0;
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-4);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-surface);
    color: var(--vf-ink);
    font-size: var(--vf-text-base);
}

.vf-offer-search__input::placeholder { color: var(--vf-n-400); }

.vf-offer-search__input:focus {
    outline: none;
    border-color: var(--vf-primary);
    box-shadow: var(--vf-shadow-focus);
}

/* --- Category chips ------------------------------------------------------- */

.vf-cat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--vf-space-2);
    margin: 0;
    padding: 0;
}

.vf-cat-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-2);
    min-block-size: var(--vf-tap);
    padding-inline: var(--vf-space-4);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-surface-raised);
    color: var(--vf-body);
    font-size: var(--vf-text-sm);
    text-decoration: none;
    white-space: nowrap;
}

.vf-cat-chip i { color: var(--vf-primary-500); }

.vf-cat-chip:hover {
    border-color: var(--vf-primary-500);
    color: var(--vf-primary);
    text-decoration: none;
}

.vf-cat-chip.is-active {
    background-color: var(--vf-primary);
    border-color: var(--vf-primary);
    color: var(--vf-on-primary);
    font-weight: var(--vf-weight-medium);
}

.vf-cat-chip.is-active i { color: var(--vf-on-primary); }

.vf-cat-chip:focus-visible {
    outline: 2px solid var(--vf-primary);
    outline-offset: 2px;
}

/* --- Results bar ---------------------------------------------------------- */

.vf-offer-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--vf-space-4);
    margin-block-end: var(--vf-space-5);
}

.vf-offer-bar__count { font-size: var(--vf-text-sm); color: var(--vf-muted); }

.vf-offer-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vf-space-3);
}

.vf-offer-controls__sort { inline-size: auto; min-inline-size: 12rem; }

.vf-offer-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--vf-space-2);
    min-block-size: var(--vf-tap);
    font-size: var(--vf-text-sm);
    color: var(--vf-body);
    cursor: pointer;
}

.vf-offer-toggle input { inline-size: 18px; block-size: 18px; accent-color: var(--vf-primary); }

/* --- Grid + pager --------------------------------------------------------- */

.vf-offer-grid {
    display: grid;
    gap: var(--vf-space-4);
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

.vf-offer-pager {
    display: flex;
    justify-content: center;
    margin-block-start: var(--vf-space-6);
}

/* --- Empty states --------------------------------------------------------- */

.vf-offer-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--vf-space-3);
    max-width: 56ch;
    margin-inline: auto;
    padding: var(--vf-space-8) var(--vf-space-5);
    background-color: var(--vf-surface-raised);
    border: 1px solid var(--vf-border);
    border-radius: var(--vf-radius-xl);
    text-align: center;
}

.vf-offer-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 56px;
    block-size: 56px;
    border-radius: var(--vf-radius-pill);
    background-color: var(--vf-primary-100);
    color: var(--vf-primary);
    font-size: var(--vf-text-2xl);
}

.vf-offer-empty__title {
    margin: 0;
    font-size: var(--vf-text-xl);
    font-weight: var(--vf-weight-semibold);
    color: var(--vf-ink);
}

.vf-offer-empty__text {
    margin: 0;
    font-size: var(--vf-text-base);
    line-height: var(--vf-leading-relaxed);
    color: var(--vf-muted);
}

.vf-offer-empty__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--vf-space-3);
    margin-block-start: var(--vf-space-2);
}

/* -----------------------------------------------------------------------------
   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;
    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-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 the brand #673091 is 6.78: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));
}

/* =====================================================================
   Homepage — Flash Deals · Featured Suppliers · Discounted Products
   ===================================================================== */

/* ---------- Flash deals ---------- */
.vf-flash-grid {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.vf-flash-card {
    --vf-flash-bg: linear-gradient(135deg, #5b2a86 0%, #a03fbf 100%);
    --vf-flash-fg: #ffffff;
    display: flex;
    flex-direction: column;
    background: var(--vf-flash-bg);
    color: var(--vf-flash-fg);
    border-radius: 14px;
    overflow: hidden;
    text-decoration: none;
    box-shadow: 0 6px 18px rgba(24, 20, 44, .08);
    transition: transform .18s ease, box-shadow .18s ease;
}
.vf-flash-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 32px rgba(24, 20, 44, .18);
    color: var(--vf-flash-fg);
    text-decoration: none;
}
.vf-flash-card__media {
    position: relative;
    aspect-ratio: 16 / 9;
    background: rgba(0, 0, 0, .1);
    overflow: hidden;
}
.vf-flash-card__media img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.vf-flash-card__glyph {
    display: flex;
    align-items: center; justify-content: center;
    width: 100%; height: 100%;
    font-size: 48px;
    opacity: .6;
}
.vf-flash-card__pill {
    position: absolute;
    top: 10px; inset-inline-start: 10px;
    background: rgba(0, 0, 0, .35);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 999px;
    backdrop-filter: blur(6px);
}
.vf-flash-card__body { padding: 14px 16px 16px; }
.vf-flash-card__title {
    font-size: 16px;
    font-weight: 700;
    margin: 0 0 6px;
    line-height: 1.3;
}
.vf-flash-card__meta {
    font-size: 12px;
    opacity: .85;
    margin: 0 0 10px;
}
.vf-flash-card__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
}
.vf-flash-card__cta i { transition: transform .18s ease; }
.vf-flash-card:hover .vf-flash-card__cta i { transform: translateX(3px); }

/* ---------- Featured suppliers strip ---------- */
.vf-supplier-strip {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.vf-supplier-chip {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: #fff;
    border: 1px solid #ececf2;
    border-radius: 12px;
    text-decoration: none;
    color: #2a2a3a;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.vf-supplier-chip:hover {
    border-color: #5b2a86;
    box-shadow: 0 8px 20px rgba(91, 42, 134, .10);
    transform: translateY(-2px);
    color: #2a2a3a;
    text-decoration: none;
}
.vf-supplier-chip__logo {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    border-radius: 10px;
    background: #f5f5f7;
    display: inline-flex;
    align-items: center; justify-content: center;
    overflow: hidden;
}
.vf-supplier-chip__logo img {
    width: 100%; height: 100%;
    object-fit: contain;
    display: block;
}
.vf-supplier-chip__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}
.vf-supplier-chip__name {
    font-weight: 700;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.vf-supplier-chip__meta {
    font-size: 12px;
    color: #6b6b7b;
    margin-top: 2px;
}

/* ---------- Discounted products ---------- */
.vf-discount-grid {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.vf-discount-card {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #ececf2;
    border-radius: 14px;
    overflow: hidden;
    text-decoration: none;
    color: #2a2a3a;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.vf-discount-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 28px rgba(0, 0, 0, .08);
    border-color: transparent;
    text-decoration: none;
    color: #2a2a3a;
}
.vf-discount-card__media {
    position: relative;
    aspect-ratio: 1 / 1;
    background: #f7f7fa;
    overflow: hidden;
}
.vf-discount-card__media img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .3s ease;
}
.vf-discount-card:hover .vf-discount-card__media img { transform: scale(1.04); }
.vf-discount-card__badge {
    position: absolute;
    top: 10px; inset-inline-start: 10px;
    background: #e53935;
    color: #fff;
    font-size: 12px;
    font-weight: 800;
    padding: 4px 10px;
    border-radius: 999px;
    box-shadow: 0 4px 12px rgba(229, 57, 53, .35);
}
.vf-discount-card__body { padding: 12px 14px 14px; }
.vf-discount-card__name {
    font-size: 14px;
    font-weight: 700;
    margin: 0 0 4px;
    line-height: 1.35;
    min-height: 2.7em;
}
.vf-discount-card__vendor {
    font-size: 12px;
    color: #6b6b7b;
    margin: 0 0 8px;
    display: flex;
    align-items: center;
    gap: 4px;
}
.vf-discount-card__price {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0;
}
.vf-discount-card__now {
    font-size: 16px;
    font-weight: 800;
    color: #5b2a86;
}
.vf-discount-card__was {
    font-size: 13px;
    color: #a0a0b0;
    text-decoration: line-through;
}

/* ==========================================================================
   Global Site Banner (Dark Breadcrumb Hero matching /about-us)
   ========================================================================== */
.vf-site-banner {
    position: relative;
    min-height: 260px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: #ffffff;
    background: #2b1a4a center/cover no-repeat;
}
.vf-site-banner__inner {
    padding: 36px 16px;
}
.vf-site-banner__eyebrow {
    display: block;
    color: #ffb84d;
    letter-spacing: .18em;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 8px;
    text-transform: uppercase;
}
.vf-site-banner__title {
    font-size: clamp(1.6rem, 3.4vw, 2.4rem);
    font-weight: 700;
    letter-spacing: .08em;
    margin: 0;
    color: #ffffff;
    text-transform: uppercase;
}
.vf-site-banner__rule {
    width: 220px;
    max-width: 60%;
    height: 2px;
    margin: 18px auto 0;
    background: rgba(255, 255, 255, .55);
    position: relative;
}
.vf-site-banner__rule::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #ffb84d;
    transform: translate(-50%, -50%);
}
@media (max-width: 575.98px) {
    .vf-site-banner {
        min-height: 200px;
    }
}

