/* ==========================================================================
   Al Ayn — storefront consistency layer
   Created 2026-08-24. Track 4: global consistency on the pages already live
   (header / shop / product / category).

   WHY THIS FILE EXISTS
   Track 1 shipped the token layer (assets/css/storefront-tokens.css) and
   proved zero visual change. This file is the first consumer of those tokens
   on the live storefront. It holds two kinds of rule and nothing else:

     FIX .........  something measured as broken (contrast below 4.5:1,
                    content clipped, an image that does not fill its frame).
                    Every FIX carries its before/after measurement.
     UNIFY .......  the same component rendering differently on two pages.
                    Every UNIFY names both pages and says which one moved.

   It deliberately contains NO taste changes. Anything that is a preference
   belongs in the previewable homepage version, not on live browse pages.

   LOAD ORDER
   base.php: storefront-tokens.css -> app-storefront.css (prebuilt Tailwind)
             -> storefront-polish-2026.css -> THIS FILE -> $additionalHead.
   Loading last among the stylesheets means these rules win ties without
   needing !important. !important appears below only where it is overriding
   an existing !important, and each such case is marked.

   NOTE ON PREBUILT TAILWIND
   assets/dist/css/app-storefront.css is a build artefact. An arbitrary
   utility that is not already in it compiles to nothing. Nothing in this
   file depends on a utility class; it is all real CSS.
   ========================================================================== */


/* ==========================================================================
   1. FIX — product images on category pages did not fill their frame
   --------------------------------------------------------------------------
   views/components/ui/product-card-modern.php renders the media box as
   `.pc-media.relative.aspect-[3/4]`, and on category pages only it wraps the
   <img> in an extra `.img-skeleton.absolute.inset-0` shimmer element.

   The prebuilt bundle defines `.img-skeleton{position:relative;...}`. That
   has the same specificity (0,1,0) as Tailwind's `.absolute{position:absolute}`
   and is emitted later, so the class wins and the wrapper stays in flow.
   In flow it sizes to its content — the image's intrinsic 400x500 — instead
   of stretching to the 3:4 frame, and `inset:0` does nothing useful on it.

   MEASURED on /category/women and /category/tops:
     1440px : .pc-media 284x378.7, <img> 284x355.0  -> 23.7px of bare
              #f3f4f6 (gray-100) across the bottom of every product image
      390px : .pc-media 171x228.0, <img> 171x213.8  -> 14.2px band
     The same component on /product/... has no skeleton wrapper and fills
     the frame exactly (0px gap), so the two pages cropped differently.

   Scoped to `.pc-media >` so other `.img-skeleton` users are untouched.
   Specificity (0,2,0) beats the bundle's (0,1,0) without !important.
   AFTER: image 284x378.7 at 1440, 171x228 at 390 — gap 0px, matches
   /product exactly.
   ========================================================================== */
.pc-media > .img-skeleton {
    position: absolute;
    inset: 0;
}


/* ==========================================================================
   2. FIX + UNIFY — "Sale" used the error red, and failed contrast
   --------------------------------------------------------------------------
   The brief recorded the Sale nav item as #dc2626. Measured, it is #ef4444
   — which is --al-danger, the colour this site uses for errors and
   destructive actions. So "this product is discounted" and "something went
   wrong" were literally the same colour.

   DECISION: sale-red stays a real semantic colour rather than folding into
   the gold accent. Urgency is a different message from brand identity, the
   store is discount-and-COD driven, and a discount badge that reads as
   "brand" reads as decoration. Track 1 already reserved --al-sale (#dc2626)
   for exactly this and kept it separate from --al-danger. This change simply
   makes the storefront use it.

   It is also a contrast fix, and #dc2626 was ALREADY this site's sale-red —
   the bundle used it for the :hover state, i.e. the hover was accessible and
   the resting state was not.

   MEASURED, 13.5px/600 on #ffffff:
     before  #ef4444  3.76:1   FAILS AA (needs 4.5:1)
     after   #dc2626  4.83:1   passes
   And for the solid discount badges, white on the fill:
     before  #fff on #ef4444   3.76:1   FAILS
     after   #fff on #dc2626   4.83:1   passes
   Hover moves down a step to red-700 #b91c1c (6.47:1) so hover stays darker
   than rest, which is the direction it already travelled.
   ========================================================================== */
.sh-nav__link--sale,
.mega-panel__qlink--sale,
.mm-quick__pill--sale,
.mm-quick__pill--sale svg {
    color: var(--al-sale);
}

.sh-nav__link--sale:hover,
.sh-nav__link--sale:focus-visible,
.mega-panel__qlink--sale:hover,
.mega-panel__qlink--sale:focus-visible,
.mm-quick__pill--sale:hover,
.mm-quick__pill--sale:focus-visible {
    color: #b91c1c;
}

.sh-nav__link--sale.active::after {
    background: var(--al-sale);
}

.mega-panel__qlink--sale:hover {
    background: rgba(220, 38, 38, .05);
}

.mm-quick__pill--sale {
    background: rgba(220, 38, 38, .06);
    border-color: rgba(220, 38, 38, .2);
}

.mm-quick__pill--sale:hover,
.mm-quick__pill--sale:focus-visible {
    background: rgba(220, 38, 38, .1);
    border-color: var(--al-sale);
}

/* --------------------------------------------------------------------------
   2b. UNIFY — the discount badge was two different badges
   The "-NN%" badge over a product thumbnail in the header menus:
     .mm-prod__sale   (mobile menu)  white on #ef4444, radius 999px, 10px/700
     .mega-prod__sale (desktop mega) white on #1f2937, radius 6px,  12px/600
   Same data, same position, same component role, two unrelated designs —
   one red, one charcoal. Unified onto the sale token and the pill shape,
   which is the one that reads as a discount rather than as a spec chip.
   The desktop badge is the one that moved.
   -------------------------------------------------------------------------- */
.mm-prod__sale,
.mega-prod__sale {
    background: var(--al-sale);
    color: var(--al-surface);
    border-radius: var(--al-radius-pill);
    font-weight: 700;
}


/* ==========================================================================
   3. FIX — body text measured below 4.5:1
   --------------------------------------------------------------------------
   Each of these is functional copy a shopper needs to read, not decoration.
   Measured against the painted background, not the declared one.
   ========================================================================== */

/* /shop filter drawer: the price-range hint and the "Clear All Filters"
   action. Both inherit --pro-gray-muted.
   before #999999 on #ffffff at 12px/400 = 2.85:1  FAILS
   after  --al-text-subtle #6b7280        = 4.83:1  passes
   "Clear All Filters" is an interactive control, so it takes the darker
   --al-text-muted #4b5563 = 7.56:1 to sit above the static hint.

   ROOT CAUSE, NOT FIXED HERE: these two inherit from `--pro-gray-muted:#999`,
   defined in the prebuilt bundle. That is a FIFTH partial token system
   (`--pro-*`) on top of the four Track 1 catalogued, and #999 fails AA on
   white everywhere it lands. It has 17 consumers:
     text  .pro-breadcrumb__sep .pro-price__original .pro-shop__breadcrumb
           .pro-shop__count .pro-filters__input::placeholder
           .pro-filters__price-separator .pro-filters__hint
           .pro-filters__clear .pro-sort-dropdown__label
           .pro-product-card__original-price .pro-shop__empty p
           .pro-shop__pagination-page
     NOT text  .pro-filters__checkbox-box (border) .pro-sort-dropdown__chevron
           .pro-gallery__mobile .swiper-pagination-bullet (fill)
           .pro-shop__empty-icon svg (icon)
   Re-pointing it in one line — `:root{--pro-gray-muted:var(--al-text-subtle)}`
   — would fix all twelve text consumers at once, but it also darkens the four
   non-text ones, which is a visible change that deserves its own before/after
   proof. Left for a follow-up rather than smuggled in here. */
.pro-filters__hint {
    color: var(--al-text-subtle);
}

.pro-filters__clear {
    color: var(--al-text-muted);
}


/* ==========================================================================
   4. UNIFY — category subcategory chips == shop quick chips
   --------------------------------------------------------------------------
   The same control — a horizontally scrolling row of sibling-category links
   — shipped as two unrelated components:

     /shop      .shop-quick-chip        999px pill, 12px/500, #4b5563 on #fff,
                                        1px #e5e7eb, gap 8px, right fade mask
     /category  .alayn-category-subcats a
                                        12px radius, 14px/600, #8a641d on
                                        rgba(255,255,255,.7), 1px
                                        rgba(181,138,44,.24), gap 16px, NO mask

   Three of those colours — #8a641d, #5f4312 (hover), #b58a2c (border) —
   exist nowhere else on the storefront. They were invented by the page-private
   <style id="category-hero-glass-polish"> block in views/category.php, which
   this file replaces.

   The category row also had no scroll affordance. MEASURED at 390px:
   scrollWidth 569 vs clientWidth 358 — 211px of the row is off-screen and
   the last chip is hard-clipped mid-word with nothing to indicate more.
   /shop solves this with a right-edge fade; category simply clipped.

   Category is the page that moved, onto /shop's treatment, because /shop's
   uses palette colours that already exist in the token file and carries the
   affordance. Everything below mirrors .shop-quick-chip exactly.
   ========================================================================== */
#main-content.category-page .alayn-category-subcats .reveal-stagger {
    gap: .5rem;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* matches .shop-quick-chips exactly */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
}

#main-content.category-page .alayn-category-subcats .reveal-stagger::-webkit-scrollbar {
    display: none;
}

/* !important here overrides the equally-specific !important the deleted
   inline block used; without it the bundle's own link colour would win. */
#main-content.category-page .alayn-category-subcats a {
    flex: 0 0 auto;
    min-height: 44px;
    padding: .625rem .875rem;
    border-radius: var(--al-radius-pill) !important;
    border: 1px solid var(--al-line) !important;
    background: var(--al-surface) !important;
    box-shadow: none;
    color: var(--al-text-muted) !important;
    font-size: .75rem;
    font-weight: 500;
    white-space: nowrap;
    transition: border-color .2s ease, background-color .2s ease, color .2s ease;
}

#main-content.category-page .alayn-category-subcats a:hover,
#main-content.category-page .alayn-category-subcats a:focus-visible {
    background: var(--al-surface-subtle) !important;
    border-color: var(--al-line-strong) !important;
    color: var(--al-text) !important;
}

/* The chip for the category currently being viewed, matching
   .shop-quick-chip--active (dark fill), if the markup marks one. */
#main-content.category-page .alayn-category-subcats a[aria-current],
#main-content.category-page .alayn-category-subcats a.active {
    background: var(--al-text) !important;
    border-color: var(--al-text) !important;
    color: var(--al-surface) !important;
}


/* ==========================================================================
   5. MOVED VERBATIM — was <style id="category-hero-glass-polish"> inside
      views/category.php's $additionalHead.
   --------------------------------------------------------------------------
   One of eight page-private <style> blocks across shop/product/category.
   Every declaration below is byte-identical to what that block shipped; only
   its location changed, from a per-page inline block to this shared file.
   The chip rules from that block are NOT reproduced here — section 4 above
   replaces them, and that is the one deliberate difference.

   Kept as-is rather than rewritten: this is the category hero's identity and
   changing it is a taste call, which is out of scope for this track.
   ========================================================================== */
#main-content.category-page .alayn-category-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: linear-gradient(135deg, rgba(248, 250, 249, .98), rgba(255, 250, 236, .88)) !important;
    color: var(--al-ink) !important;
    border-bottom: 1px solid rgba(17, 24, 39, .08);
}

#main-content.category-page .alayn-category-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        linear-gradient(90deg, rgba(17, 24, 39, .045) 1px, transparent 1px),
        linear-gradient(180deg, rgba(22, 139, 139, .055) 1px, transparent 1px);
    background-size: 3.25rem 3.25rem;
    -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, .52), rgba(0, 0, 0, .06));
    mask-image: linear-gradient(180deg, rgba(0, 0, 0, .52), rgba(0, 0, 0, .06));
}

#main-content.category-page .alayn-category-hero > * {
    position: relative;
    z-index: 1;
}

#main-content.category-page .alayn-category-hero h1,
#main-content.category-page .alayn-category-hero .oc-cat-hero__title {
    color: var(--al-ink) !important;
    text-wrap: balance;
}

#main-content.category-page .alayn-category-hero p,
#main-content.category-page .alayn-category-hero .oc-cat-hero__desc,
#main-content.category-page .alayn-category-hero .oc-cat-hero__count {
    color: rgba(55, 65, 81, .84) !important;
}

#main-content.category-page .alayn-category-subcats {
    background: linear-gradient(135deg, rgba(255, 255, 255, .92), rgba(248, 250, 249, .78)) !important;
    border-top: 1px solid rgba(181, 138, 44, .14);
    border-bottom: 1px solid rgba(17, 24, 39, .08);
    box-shadow: 0 14px 38px rgba(17, 24, 39, .06), inset 0 1px rgba(255, 255, 255, .84);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
}

@media (prefers-reduced-transparency: reduce) {
    #main-content.category-page .alayn-category-hero::before {
        display: none !important;
    }

    #main-content.category-page .alayn-category-hero {
        background: var(--al-surface-cream) !important;
    }

    #main-content.category-page .alayn-category-subcats {
        background: rgba(255, 255, 255, .98) !important;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        box-shadow: 0 10px 24px rgba(17, 24, 39, .07);
    }

    #main-content.category-page .alayn-category-subcats a {
        background: var(--al-surface) !important;
    }
}


/* ==========================================================================
   6. FIX — contrast pass 2026-08-26 (five reviewed specs, merged)
   --------------------------------------------------------------------------
   Every rule below is a measured AA failure (WCAG 1.4.3, 4.5:1 for normal
   text) or a 1.4.11 non-text failure (3:1). Each carries its before/after
   ratio against the backdrop it ACTUALLY renders on — composited, not the
   nearest opaque ancestor, which is what the QA harness reported and what
   made several of these numbers look better than they were.

   TWO RULES THIS SECTION KEEPS TO:
     - Brand gold #D4A537 (--brand-gold / --al-accent) stays as FILL, border,
       ring and tint everywhere. Only text inks move.
     - Gold-as-text lands on gold.ink #8A6B24, which already ships as
       --gold-ink in the bundle's :root (src/css/app.css:16, safelisted at
       tailwind.config.cjs:17 as .text-gold-ink). No new token is declared —
       a second custom property holding the same hex is exactly the
       fragmentation this file exists to undo. Call sites use
       var(--gold-ink, #8A6B24) so a missing var cannot fall through to black.

   SCOPE WARNING FOR WHOEVER VERIFIES THIS
   views/layouts/base-v2.php (Ocean Silk) does NOT link this stylesheet — it
   loads storefront-tokens.css, app-storefront.css and theme-ocean.min.css
   only. Everything below therefore applies to the classic shell (base.php)
   and is inert on any page routed through the Ocean gate. The mm-* rules in
   6b are the ones this actually costs: views/components/v2/header.php renders
   the same markup and keeps the failing colours until the same declarations
   are mirrored into src/css/app.css + assets/dist/css/app.css. Filed, not
   fixed here — it is a src/dist edit, not a consistency-layer edit.

   No !important anywhere in this section. This file is the last <link> in
   base.php (:163), so an equal-specificity rule wins on source order. Where a
   shipped rule is more specific (the expanded-parent count chip, the
   :hover pairs) the selector below is restated at the same specificity.
   ========================================================================== */


/* --------------------------------------------------------------------------
   6a. FIX — homepage product rails (pc-*)
   --------------------------------------------------------------------------
   SCOPE, corrected from the original spec: renderModernProductCard() emits
   pc-* markup ONLY in its `$layout === 'homepage'` branch
   (views/components/ui/product-card-modern.php:282-285). That is
   views/home.php:390-391, views/home-editorial26.php:118-119 and
   views/components/homepage-2026-renderer.php:187. /shop renders
   .pro-product-card__*, and /category, /deals, /search, /404 render
   .pcx-* — NONE of the selectors below exist on those pages. Do not open
   /shop to verify this; open the homepage.

   Card face is #ffffff (.product-card--light, src/css/app.css:3101), so the
   measured and declared backdrops agree for all four.
   -------------------------------------------------------------------------- */

/* Struck-through original price: --warm-400 #E8D5A0 is a cream *background*
   ramp step used as text. 10px/400 (12px >=640px) on #ffffff.
     before  1.45:1  FAIL      after  4.83:1  pass
   --al-text-faint #9ca3af was rejected at 2.54:1. The live price stays
   --brand-charcoal at 14.68:1, so the hierarchy still reads — 3.04:1 apart,
   plus smaller size, lighter weight and the line-through.
   The token itself must NOT move: --warm-400 is also a border-color
   (app.css:2576, 3676, 12357) and a ::placeholder (2517, 3434, 3682, 12359). */
.pc-price__original {
    color: var(--al-text-subtle);
}

/* "Save Tk700": --success #0D9488 (teal-600) as 10-11px/600 text on #ffffff.
     before  3.74:1  FAIL      after  5.47:1  pass
   One step down the same ramp (teal-700), so the hue does not move.
   --al-success #059669 also fails at 3.77:1. The token must NOT move —
   --success's other consumers are all fills (app.css:3639, 3860, 9258). */
.pc-price__save {
    color: var(--al-teal-deep);
}

/* Category kicker: --brand-gold-dark #B8891A as 10-11px/600 uppercase on #fff.
     before  3.17:1  FAIL      after  4.99:1  pass
   Same gold family, text-safe step. --brand-gold-dark must NOT move: six of
   its uses are fills or hover backgrounds (2320, 2413, 2452, 3449, 3826,
   12305, 12440, 12539) that have to stay bright. */
.pc-category {
    color: var(--gold-ink, #8A6B24);
}

/* "Buy Now": white label on the gold fill.
     before  #ffffff on #D4A537  2.27:1  FAIL
     after   #1F2937 on #D4A537  6.46:1  pass   (11px <640px, 12px >=640px, 600)
   THE FILL IS NOT TOUCHED. An earlier draft darkened the background to
   gold.ink instead; that was rejected — gold.ink is declared text-only in
   src/css/app.css:14-15 and tailwind.config.cjs:14-17, and darkening the fill
   also cost the button its edge separation on dark product photography
   (.pc-actions has no background of its own, src/css/app.css:3187).
   Darkening the LABEL is the codebase's own convention for gold fills:
   _alaynBtnClass() maps 'gold' => 'bg-gold text-charcoal'.
   Hover deliberately left alone: #1F2937 on --brand-gold-dark #B8891A is
   4.64:1, still passing, and hover keeps travelling the correct direction.
   The focus ring (2px solid var(--brand-gold)) is unchanged. */
.pc-actions__buy {
    color: var(--brand-charcoal, #1F2937);
}


/* --------------------------------------------------------------------------
   6b. FIX — fullscreen mobile menu (mm-*)
   --------------------------------------------------------------------------
   CLASSIC SHELL ONLY — see the scope warning at the top of section 6.

   BACKDROP NOTE: .mm-section__more, .mm-cat-sec and .mm-cat--all sit directly
   on the drawer ground, which is .mobile-menu{background:rgba(255,255,255,.96)}
   (src/css/app.css:12840) over .mobile-menu-overlay{bg-black/50}. That
   composites to ~#FAFAFA, not #ffffff, so gold.ink is 4.78:1 there rather
   than the 4.99:1 it gets on paper. Still clears 4.5:1, but the headroom is
   ~0.28 — if anyone counter-proposes a lighter gold for these, measure it on
   #FAFAFA, not on white. .mm-prod__price and .mm-cat__count sit on opaque
   fills (#fff card, #f3f4f6 pill) and are unaffected by this.
   -------------------------------------------------------------------------- */

/* "View all" section link. #d4a537 hard-coded at src/css/app.css:1317.
     before  2.27:1  FAIL      after  4.78:1  pass  (12px/600)
   The inline chevron is stroke="currentColor", so it darkens with the label
   and clears the 3:1 non-text floor it was also failing.
   Hover ground (rgba(212,165,55,.08) over the drawer) measures 4.71:1 — no
   separate hover rule needed. */
.mm-section__more {
    color: var(--gold-ink, #8A6B24);
}

/* MEN / WOMEN section labels. #B0873A (src/css/app.css:13111) wins over an
   earlier #B8891A (:13050); one rule here supersedes both.
     before  3.30:1  FAIL      after  4.78:1  pass  (10.5px/700 — below the
   18.66px-bold large-text threshold, so the bar is 4.5:1, not 3:1)
   VISIBLE CHANGE: at 700 weight and 0.2em tracking these read bronze rather
   than gold. Unavoidable — #B0873A tops out at 3.30:1 and gold.dark #B8891A
   at 3.17:1, so gold.ink is the only step on the ramp that clears 4.5:1. */
.mm-cat-sec {
    color: var(--gold-ink, #8A6B24);
}

/* "View all in X" child row — same drawer, same gold, promised by the spec's
   prose but missing from its rules. Without it the open drawer renders two
   different golds side by side.
     before  2.27:1 rest / 3.17:1 hover  FAIL      after  4.78:1 both  pass
   The :hover pair is restated because the shipped hover rule
   (.mm-cat--all:hover{color:#b8891a}) is (0,2,0) and a bare (0,1,0) override
   does not reach it. */
.mm-cat--all,
.mm-cat--all:hover {
    color: var(--gold-ink, #8A6B24);
}

/* Product-strip price, #d4a537 on the opaque white .mm-prod card.
     before  2.27:1  FAIL      after  4.99:1  pass  (11px/600) */
.mm-prod__price {
    color: var(--gold-ink, #8A6B24);
}

/* Compare-at price inside that same <p>. Its own rule is (0,1,1) and sets
   #9CA3AF, so the recolour above does not reach it.
     before  2.54:1  FAIL      after  4.83:1  pass  (11px/400 on #ffffff)
   Same landing value as .pc-price__original above, deliberately. */
.mm-prod__price del {
    color: var(--al-text-subtle);
}

/* Category count chip, #9CA3AF on the opaque #f3f4f6 pill.
     before  2.31:1  FAIL      after  6.87:1  pass  (11px/600)
   --al-text-subtle #6b7280 is NOT enough here — 4.39:1 on #f3f4f6, itself a
   logged failure. --al-text-muted is the first token that clears the bar.
   The pill background is unchanged. */
.mm-cat__count {
    color: var(--al-text-muted);
}

/* Same chip in the expanded-parent state, (0,3,0), so the rule above does not
   reach it. Its ground is TWO stacked gold tints: rgba(212,165,55,.15) on the
   chip over rgba(212,165,55,.07) on the parent row (src/css/app.css:13106,
   which overrides the .06 at :1374) over white = ~#F6ECD5.
     before  #b8891a  2.70:1  FAIL      after  #4b5563  6.43:1  pass
   The gold TINT background is kept — only the text moves. */
.mm-cat--parent[aria-expanded="true"] .mm-cat__count {
    color: var(--al-text-muted);
}

/* Secondary rows ("Track Order", "Contact us"), #9CA3AF at 14px on the
   composited drawer ground ~rgb(250,250,250).
     before  2.43:1  FAIL      after  7.23:1  pass
   --al-text-subtle #6b7280 was considered and withdrawn: 4.63:1 on a
   translucent, backdrop-blurred ground whose composite shifts with whatever
   page is behind it is not a defensible margin. The existing
   .mm-link--secondary:hover{color:#374151} (0,2,0) still wins on hover at
   9.86:1 and is untouched. */
.mm-link--secondary {
    color: var(--al-text-muted);
}

/* The 18px truck / message SVGs beside those rows — stroke="currentColor" at
   #9CA3AF = 2.43:1, below the 3:1 floor for non-text UI (WCAG 1.4.11).
     before  2.43:1  FAIL      after  4.63:1  pass
   Stopped at gray-500 rather than gray-600 so the icon stays lighter than the
   new link text. BLAST RADIUS, named precisely: this matches the three
   .mm-link__icon SVGs in views/components/header.php:700 (Blog), 705 (Track
   Order) and 709 (Contact us) — the Blog row is the one non-secondary row it
   touches, and its icon currently sits at #9CA3AF beside #374151 text, so
   this narrows a hierarchy inversion rather than creating one.
   The gold active state is preserved: .mm-link--active .mm-link__icon
   {color:#d4a537} is (0,2,0) and still wins. */
.mm-link__icon {
    color: var(--al-text-subtle);
}


/* --------------------------------------------------------------------------
   6c. FIX — homepage category quick-nav pills (views/home.php:292-300)
   --------------------------------------------------------------------------
   GROUND CORRECTION: the harness reported all of these "on rgb(255,255,255)"
   because it resolves a translucent element to its nearest OPAQUE ancestor.
   The real grounds are composited gold washes:
     pill        bg-gold/10 over white          = rgb(251,246,235)
     pill:hover  bg-gold/20 over white          = rgb(246,237,215)
     chip        bg-gold/15 over the pill's /10 = rgb(245,234,208)
   Anything sized against the reported 3.17:1 falls short of AA on all three.

   NOT PROMOTED TO A BARE `.text-gold-dark` RULE, though it was tempting: that
   utility has ~30 storefront consumers on white / bg-gold/5 / bg-gold/10
   grounds (views/account/*, views/creator/*, views/checkout.php,
   views/product.php, src/helpers.php:5236 …), several of them lucideIcon()
   SVG fills rather than text, and a bare rest-state rule would still leave
   this pill's hover at 4.28:1 — a shipped AA failure that an automated
   re-scan would mark green. Scoped rules only, until that inventory is
   re-measured against each element's own painted backdrop.
   -------------------------------------------------------------------------- */

/* Root-category pill label ("Men"), text-gold-dark #B8891A at 12/14px/600.
     rest   before 2.94:1  FAIL      after #8A6B24  4.63:1  pass
   (0,2,1) beats the utility's (0,1,0). Only views/home.php:292 matches —
   the other snap-start pills carry no text-gold-dark. */
a.snap-start.text-gold-dark {
    color: var(--gold-ink, #8A6B24);
}

/* …and the hover ground darkens to bg-gold/20, where gold.ink drops to
   4.28:1 and FAILS. Step the label down the same ramp rather than weakening
   the brand hover tint.
     hover  before 2.72:1  FAIL      after #4D380B (gold.900)  9.56:1  pass
   Note the pill's transition list omits `color`, so this snaps rather than
   eases — cosmetic, and adding `color` would be a non-colour change. */
a.snap-start.text-gold-dark:hover {
    color: #4D380B; /* tailwind.config.cjs gold.900 */
}

/* Count chip inside that pill. It declares NO colour of its own — it inherits
   the pill's — and its ground is darker than the pill's, so fixing the parent
   alone reaches only 4.17:1 at 10px. It needs its own declaration.
     before 2.65:1  FAIL      after #4D380B  9.30:1  pass
   The gold tint background is kept. */
a.snap-start.text-gold-dark > .bg-gold\/15 {
    color: #4D380B; /* tailwind.config.cjs gold.900 */
}

/* Sub-category pill count chip: text-gray-500 #6B7280 on the opaque
   bg-gray-100 #F3F4F6 — the one element in this group the harness measured
   correctly, and it is 0.11 short.
     before 4.39:1  FAIL      after 6.87:1  pass  (10px/600)
   The chip declares its own colour, so the pill's hover:text-gold never
   reaches it, and its ground is opaque, so hover:bg-gold/5 never tints it.
   Also matches the identical chip in views/home-v2.php:239 and
   views/components/homepage-2026-renderer.php:315 — harmless, and inert on
   home-v2 anyway, which renders through base-v2.php. */
a.snap-start .bg-gray-100.text-gray-500 {
    color: var(--al-text-muted);
}


/* --------------------------------------------------------------------------
   6d. FIX — white labels on the gold gradient buttons
   --------------------------------------------------------------------------
   assets/css/storefront-polish-2026.css:257-261 repaints every Tailwind
   `bg-gold` + `text-white` control with
   linear-gradient(135deg, #D4A537, #E8BE5A). A white label on that is:
     2.27:1 on the dark stop, 1.76:1 on the light stop #E8BE5A,
     2.73:1 on the hover gradient (#C49530 -> #D4A537)
   at 14px/600, which needs 4.5:1. This is ~40 markup sites — views/cart.php,
   deals.php, product.php, checkout.php, order-confirmation.php,
   track-order.php, blog/*, creator/*, size-guide.php, 404.php,
   unsubscribe.php, views/components/header.php:801 (the cart-drawer
   "browse collection" CTA that surfaced it).

     after  #1F2937 on #D4A537  6.46:1
            #1F2937 on #E8BE5A  8.35:1
            #1F2937 on #C49530  5.37:1  (worst case)   all pass

   THE GRADIENT IS NOT TOUCHED. Same ink as .pc-actions__buy above and as
   .pro-btn--primary (app.css:422), which already does ink-on-gold correctly —
   this unifies the Tailwind buttons with the two components that got it
   right, rather than inventing a colour.

   `~=` (whole-class token), NOT the polish file's `*=`: `*=` also matches
   `hover:bg-gold`, and the back-to-top button is
   `bg-charcoal/80 hover:bg-gold text-white` — a charcoal circle that must
   keep a white icon. `~=` misses it, and misses `bg-gold/90` and `bg-gold-50`
   too. Verified on / and /shop: `*=` catches 5 elements, `~=` catches the 4
   whose computed background-color really is rgb(212,165,55).
   Specificity (0,2,0) beats Tailwind's .text-white (0,1,0).

   VISIBLE CHANGE: gold buttons stop reading white-on-gold and start reading
   ink-on-gold. Deliberate unification — eyeball one before ship.
   -------------------------------------------------------------------------- */
[class~="bg-gold"][class~="text-white"] {
    color: var(--brand-charcoal, #1F2937);
}


/* --------------------------------------------------------------------------
   6e. FIX — --warm-400 used as text in the checkout flow
   --------------------------------------------------------------------------
   Same defect class as .pc-price__original in 6a: a cream background ramp
   step (#E8D5A0) used as a text colour. Both of these ship in
   assets/dist/css/app-storefront.css and both pages render through base.php.

     .checkout-step__number  #E8D5A0 on --warm-100 #FFF8E7  1.37:1  FAIL
                             -> #6b7280 on #FFF8E7          4.57:1  pass
     .order-summary__item-qty #E8D5A0 on #ffffff            1.45:1  FAIL
                             -> #6b7280 on #ffffff          4.83:1  pass

   Only the INACTIVE step numeral moves. `.checkout-step.active
   .checkout-step__number` and `.checkout-step.completed .checkout-step__number`
   are (0,2,0) and keep their own fills and white labels — those two are a
   separate, real failure (white on --success #0D9488 = 3.74:1) that needs its
   own before/after and is NOT addressed here.

   Two more --warm-400-as-text rules exist in src/css/app.css (.trust-bar__desc
   :2941, .category-card__count :3045) but are absent from the shipped
   bundles — src and dist are out of sync — so they are deliberately omitted
   rather than shipped as no-ops.
   -------------------------------------------------------------------------- */
.checkout-step__number,
.order-summary__item-qty {
    color: var(--al-text-subtle);
}


/* --------------------------------------------------------------------------
   6f. FIX — "jump to reviews" link on the product page
   --------------------------------------------------------------------------
   The shipped RESTING rule is the failure, not the hover one an earlier draft
   targeted: .jump-to-reviews{font-size:12px;color:var(--brand-gold)}.
     rest   before  #D4A537  2.27:1  FAIL   after  #8A6B24  4.99:1  pass
     hover  before  #B8891A  3.17:1  FAIL   after  #4D380B  11.13:1 pass
   Patching only :hover would have left the state shoppers actually read — and
   the only state that exists on touch, which is most of this storefront's
   traffic — at 2.27:1, while making an automated re-scan report it fixed.
   The :hover pair is restated at (0,2,0) to beat the shipped hover rule; its
   underline is untouched. */
.jump-to-reviews {
    color: var(--gold-ink, #8A6B24);
}

.jump-to-reviews:hover {
    color: #4D380B; /* tailwind.config.cjs gold.900 */
}


/* ==========================================================================
   7. FIX — footer touch targets (WCAG 2.2 SC 2.5.5, 44x44)
   --------------------------------------------------------------------------
   FRAMING, because it decides how much layout cost is worth paying: every
   item the harness flagged in the footer already passes SC 2.5.8 Target Size
   (Minimum), which is the Level AA criterion — 24x24 with a spacing
   exception. Footer nav links are 51.42x32 on a 33.27px pitch, social chips
   are 40x40, the wordmark is 149x36. The 44x44 bar the harness enforces is
   SC 2.5.5 Target Size (Enhanced), Level AAA / platform convention. So the
   two rules below are polish, and anything that would cost visible layout was
   left out — see the notes at the end of this section.

   Both rules are prefixed .site-footer--modern (0,2,1) to beat the base
   (0,1,0) declarations without !important. Ocean Silk pages do not load this
   file, so they keep the current geometry.
   -------------------------------------------------------------------------- */

/* Wordmark: 36px tall at >=1280px, which is where the harness flags it
   (1280/1440/1920/2560 — below 1280 it already carries a ::after hit area and
   never fails). font-size clamps to 2.25rem = 36px from 1200px up, so
   4px of padding-block lands it at exactly 44 with no overshoot.
     before 149.02x36      after 149.02x44
   The equal negative margin keeps the MARGIN box — which is what the
   surrounding line box measures — at its original height, so nothing moves:
   verified at 1280/1920 that footerH, mainGridH, brandBlockH, brandDescTop,
   socialsTop and bottomRailTop are all byte-identical before and after.

   Gated to >=1280 on purpose. Below that, src/css/app.css:13441-13458 gives
   .footer-wordmark `position:relative` and a ::after hit area at
   inset-block:-6px (retightened to -10px on coarse pointers), and padding on
   the element grows that absolutely-positioned pseudo-box too — at -10px the
   invisible hit area would start overlapping .footer-brand-description, whose
   margin-top is 16px. At >=1280 neither `position:relative` nor `content` is
   set, so no pseudo-box exists and there is nothing to collide with.

   MAINTENANCE: this depends on .footer-wordmark being display:inline-block.
   If it ever becomes display:block, or .footer-brand-block becomes a flex or
   grid container, the negative margins start actually pulling layout.
   Side effect: :focus-visible (2px outline, 5px offset) now traces the 44px
   box, so the keyboard ring around AL AYN is 4px taller. */
@media (min-width: 1280px) {
    .site-footer--modern .footer-wordmark {
        padding-block: 4px;
        margin-block: -4px;
    }
}

/* Social chips: 40x40 on mouse desktops. The 44px version already ships at
   <=767px (src/css/app.css:13472) and on coarse pointers (:13528) — this
   retires the viewport gate so every breakpoint agrees.
     before 40x40      after 44x44
   MEASURED COST: a flat +4.00px of footer height at 768/1024/1280/1920; the
   contact list and bottom rail shift down 4px. The 16x16 glyph is set
   independently (src/css/app.css:1924) and does not change, so the icon sits
   slightly more inset. border-radius stays 12px, which reads a hair squarer
   at 44px than at 40px — a taste call, not an a11y one. */
.site-footer--modern .footer-social {
    width: 44px;
    height: 44px;
    min-width: 44px;
    min-height: 44px;
}

/* ==========================================================================
   7. UNIFIED PRODUCT CARD (.hp26-c)
   --------------------------------------------------------------------------
   MOVED here from assets/css/homepage-refresh26.css so one file serves every
   storefront page. This sheet is already linked on every classic page by
   views/layouts/base.php and its mtime already feeds $cacheVersion, so a change
   here busts the CDN on its own.

   Do NOT move these rules into assets/dist/css/app*.css. base.php regenerates
   app-storefront.css from dist/app.css through a full replace
   (src/storefront-css-split.php), so anything unique to the derived file is
   destroyed on the next storefront pageview.

   Reversible: delete from this banner to EOF.
   ========================================================================== */
.hp26-c {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #FFFDF9;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(31, 41, 55, .05), 0 10px 26px -14px rgba(31, 41, 55, .28);
    transition: transform .25s cubic-bezier(.16,.84,.44,1), box-shadow .25s ease;
}
@media (hover: hover) {
    .hp26-c:hover { transform: translateY(-3px); box-shadow: 0 2px 4px rgba(31,41,55,.06), 0 18px 36px -16px rgba(31,41,55,.34); }
    .hp26-c:hover .hp26-c__media img { transform: scale(1.045); }
}
.hp26-c:focus-within { outline: 2px solid var(--brand-gold, #D4A537); outline-offset: 2px; }

.hp26-c__media {
    display: block;
    aspect-ratio: 3 / 4;
    background: linear-gradient(158deg, #FBF6EC 0%, #F3EBDD 100%);
    overflow: hidden;
}
.hp26-c__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 18%;   /* portraits crop at the hem, never the neckline */
    transition: transform .5s cubic-bezier(.16,.84,.44,1);
}

/* One badge, never two. Discount outranks "new". */
.hp26-c__badge {
    position: absolute;
    top: .55rem;
    left: .55rem;
    z-index: 2;
    padding: .25rem .5rem;
    border-radius: 999px;
    background: var(--brand-gold, #D4A537);
    color: #1F2937;                       /* 6.46:1 on gold */
    font-size: .6875rem;
    font-weight: 700;
    line-height: 1.35;
    box-shadow: 0 2px 6px rgba(31, 41, 55, .18);
}
.hp26-c__badge--new { background: #1F2937; color: #fff; }
@media (max-width: 24rem) { .hp26-c__badgeWord { display: none; } }

.hp26-c__wish {
    position: absolute;
    top: .45rem;
    right: .45rem;
    z-index: 2;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .88);
    color: #1F2937;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(31, 41, 55, .14);
}
@supports (backdrop-filter: blur(4px)) { .hp26-c__wish { backdrop-filter: blur(4px); } }
.hp26-c__wish[aria-pressed="true"] { background: #C2553A; color: #fff; }

.hp26-c__body {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    padding: .7rem .7rem .8rem;
}
.hp26-c__kicker {
    margin: 0;
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #8A6B24;                       /* 4.99:1 on the card */
}
.hp26-c__name {
    margin: 0;
    font-family: inherit;
    font-size: .8125rem;
    font-weight: 500;
    line-height: 1.32;
    color: #1F2937;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.64em;                   /* two lines always, so prices align */
}
.hp26-c__link { color: inherit; text-decoration: none; }
/* The whole card is tappable, but only the title is a real link, so the
   accessible name and tab order stay honest. The action row sits above this
   overlay on z-index 2 and was verified live: tapping "add to bag" fires
   cart/add, not the link. (When add-to-cart lands on a product that needs a
   size or colour the API returns needs_variant and product-actions.js sends
   the shopper to the picker — that redirect is intended, not a stray tap.) */
.hp26-c__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }

.hp26-c__price {
    margin: .15rem 0 .45rem;
    display: flex;
    align-items: baseline;
    gap: .4rem;
    font-variant-numeric: tabular-nums;
}
.hp26-c__now { font-size: 1rem; font-weight: 700; color: #1F2937; }
.hp26-c__was { font-size: .75rem; color: #6B7280; text-decoration: line-through; }

/* Actions live BELOW the photograph. Nothing covers the garment. */
.hp26-c__actions { position: relative; z-index: 2; display: flex; gap: .4rem; }
.hp26-c__buy {
    flex: 1 1 auto;
    min-height: 44px;
    border: 0;
    border-radius: 10px;
    background: var(--brand-gold, #D4A537);
    color: #1F2937;
    font: inherit;
    font-size: .8125rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease;
}
.hp26-c__buy:hover { background: #B8891A; }
.hp26-c__add {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    background: #fff;
    color: #1F2937;
    cursor: pointer;
    transition: border-color .15s ease;
}
.hp26-c__add:hover { border-color: var(--brand-gold, #D4A537); }

@media (prefers-reduced-motion: reduce) {
    .hp26-c, .hp26-c__media img { transition: none; }
    .hp26-c:hover { transform: none; }
    .hp26-c:hover .hp26-c__media img { transform: none; }
}


/* --- corrections applied when the card was promoted site-wide -------------- */

/* The 44px hit target was inherited from an unscoped button{min-height:44px}
   in the bundle. State it here so the card owns its own target size. */
.hp26-c__wish { min-width: 44px; min-height: 44px; }

/* Saved state: the bundle paints the glyph gold, which measures 1.98:1 on the
   coral ground and fails WCAG 1.4.11 (3:1 for non-text). White measures 4.51:1.
   Specificity ties the bundle rule and wins on load order. */
.hp26-c__wish[aria-pressed="true"] svg { fill: none; stroke: #fff; color: #fff; }

/* The Bengali buy label ("এখনই কিনুন") had 1.2px of slack at a 280px viewport
   and was relying on user-agent button padding to fit. */
.hp26-c__buy { min-width: 0; padding: 0 .35rem; }

/* Checkout viewport repair: critical form content must stay visible and use
   document scrolling when validation focuses a field. */
.checkout-page .checkout-layout > * {
    min-width: 0;
}

.checkout-page .checkout-step {
    overflow: clip;
}

.checkout-page .checkout-step.active {
    overflow: visible;
}

.checkout-page .checkout-step__header {
    border-radius: inherit;
}

.checkout-page .checkout-step.active .checkout-step__body {
    max-height: none;
    overflow: visible;
    transition: opacity .3s ease, padding .3s ease;
}

.checkout-page .checkout-layout .reveal {
    opacity: 1;
    transform: none;
    filter: none;
    will-change: auto;
}

@media (max-width: 767px) {
    .checkout-page .checkout-layout {
        align-items: stretch;
    }
}
