@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,500;0,600;1,400&family=Jost:wght@300;400;500;600&display=swap');

/* ==========================================================
   LIGHT LUXURY THEME
   --ivory now holds the primary INK color (#1A1A1A), not an
   ivory tone. Kept the variable name so every existing selector
   that already reads var(--ivory) for text picks up the new
   dark-on-cream color without a full find/replace across the
   file. Read it as "primary text", not literally ivory-colored.
   ========================================================== */
:root{
  --bg:            #FBF9F6;
  --surface:       #FCFAF6;
  --surface-2:     #F1ECE2;
  --line:          rgba(212,175,55,0.28);
  --gold:          #D4AF37;
  --gold-bright:   #B8902E;
  --gold-dim:      #C9A227;
  --ivory:         #1A1A1A;
  --muted:         #6B6258;
  --top-note:      #D4AF37;
  --heart-note:    #B8902E;
  --base-note:     #7A5F1E;
  --danger:        #A3573F;
  --footer-bg:     #2C2520;
  --footer-text:   #F5F0E6;
}

*{box-sizing:border-box;margin:0;padding:0;}
/* .nav is position:sticky;top:0 (below), so an in-page anchor link
   (Visit Us, Best Sellers, Our Craft, hero CTAs) technically scrolls
   to the right element, but without this the sticky nav then covers
   the top of it - looking like it scrolled to the wrong place. This
   compensates every anchor on the page at once, not just #visit.
   Value matches the nav's real rendered height (~82px desktop,
   ~56px mobile, +8px breathing room) rather than a guess. */
html{scroll-behavior:smooth;scroll-padding-top:90px;-webkit-text-size-adjust:100%;text-size-adjust:100%;}
@media (max-width:1300px){html{scroll-padding-top:64px;}}
/* text-size-adjust:100% above is the standard fix for mobile Chrome/Safari's
   automatic font-boosting text-autosizer: on narrow viewports these browsers
   can recompute a second, differently-scaled text layout pass over the one
   already painted, and the transient overlap between those two passes reads
   exactly like duplicated leading characters ("NewNew Arrivals"). This site
   already controls type scale explicitly via rem/clamp(), so the browser's
   own autosizing pass is never wanted here regardless of this specific bug. */
body{background:var(--bg);color:var(--ivory);font-family:'Jost',sans-serif;font-weight:300;line-height:1.6;-webkit-font-smoothing:antialiased;}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;}
h1,h2,h3,h4{font-family:'Cormorant Garamond',serif;font-weight:500;letter-spacing:0.01em;}
.eyebrow{font-size:0.72rem;letter-spacing:0.22em;text-transform:uppercase;color:var(--gold-bright);font-weight:400;}
.container{max-width:1240px;margin:0 auto;padding:0 clamp(1.2rem,4vw,3rem);}
:focus-visible{outline:1.5px solid var(--gold-bright);outline-offset:3px;}
@media (prefers-reduced-motion: reduce){*{animation:none !important;transition:none !important;scroll-behavior:auto !important;}}

/* ==========================================================
   PREMIUM MICRO-ANIMATIONS
   Shared keyframes used across nav, hero, product cards and the
   brand narrative band. Pure CSS, no JS hooks required: elements
   animate the moment they're painted, so this works identically
   whether markup is static (server HTML) or injected by app.js
   (innerHTML swaps still trigger a fresh paint).
   ========================================================== */
@keyframes luxuryGlare{
  0%{ transform:translateX(-160%) translateY(-160%) rotate(45deg); opacity:0; }
  12%{ opacity:1; }
  100%{ transform:translateX(160%) translateY(160%) rotate(45deg); opacity:0; }
}
@keyframes premiumFadeInUp{
  from{ opacity:0; transform:translateY(15px); }
  to{ opacity:1; transform:translateY(0); }
}
@keyframes navTrackingExpand{
  from{ letter-spacing:0.1em; }
  to{ letter-spacing:0.35em; }
}

/* ---------- NAV ---------- */
.nav{position:sticky;top:0;z-index:60;background:rgba(251,249,246,0.9);backdrop-filter:blur(10px);border-bottom:1px solid var(--line);}
.nav-row{position:relative;display:flex;align-items:center;justify-content:space-between;padding:0.75rem clamp(1.2rem,4vw,3rem);}
.nav-left{display:flex;align-items:center;gap:0.6rem;}
.logo-mark{display:flex;align-items:center;gap:0.6rem;}
.logo-mark img{height:38px;width:auto;}
/* position:static + flex:1 (not absolute+transform-centered on the
   row's geometric midpoint) so nav-center gets the real leftover
   space between .nav-left and .nav-actions and centers within THAT -
   the same fix already used at the mobile breakpoint below, and for
   the same reason: .nav-actions (search box) is heavier than
   .nav-left (logo), so the row's true midpoint isn't the free
   space's midpoint. Centering on the row's midpoint instead let
   .nav-links silently overlap the search box once it grew wide
   enough (8 items) to reach that heavier side. */
.nav-center{
  flex:1;
  min-width:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0.35rem;
}
.nav-brand-text{
  font-family:'Cormorant Garamond',serif;
  font-weight:600;
  font-size:1rem;
  letter-spacing:0.35em;
  text-transform:uppercase;
  color:var(--ivory);
  white-space:nowrap;
  animation:navTrackingExpand 1.5s cubic-bezier(0.16,1,0.3,1) both;
}
.nav-links{display:flex;gap:2rem;list-style:none;}
.nav-links a{font-size:0.78rem;letter-spacing:0.12em;text-transform:uppercase;color:var(--muted);transition:color 0.25s;position:relative;padding-bottom:2px;white-space:nowrap;}
.nav-links a::after{content:'';position:absolute;left:0;bottom:-2px;width:0;height:1px;background:var(--gold);transition:width 0.3s;}
.nav-links a:hover{color:var(--ivory);}
.nav-links a:hover::after{width:100%;}
.nav-actions{display:flex;align-items:center;gap:1.4rem;}
.icon-btn{position:relative;color:var(--ivory);padding:0.3rem;}
.icon-btn svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.3;}
.cart-badge{position:absolute;top:-4px;right:-6px;background:var(--gold);color:#fff;font-size:0.62rem;width:16px;height:16px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:600;}
.nav-hamburger{display:none;align-items:center;justify-content:center;width:34px;height:34px;color:var(--ivory);flex-shrink:0;}
.nav-hamburger svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.6;}
@media (max-width:1300px){.nav-links{display:none;}}

/* ---------- MOBILE NAV DRAWER ----------
   Independent of .nav-center (which is transform-centered and would
   otherwise become the containing block for any position:fixed
   descendant). These two live as siblings of .nav in the markup so
   they anchor to the real viewport, not to the transformed header. */
.mobile-nav-overlay{position:fixed;inset:0;background:rgba(26,26,26,0.45);z-index:150;opacity:0;pointer-events:none;transition:opacity 0.3s;}
.mobile-nav-overlay.open{opacity:1;pointer-events:auto;}
.mobile-nav-drawer{position:fixed;top:0;left:0;height:100%;width:min(300px,82vw);background:var(--surface);border-right:1px solid var(--line);z-index:160;transform:translateX(-100%);will-change:transform;transition:transform 0.35s cubic-bezier(0.16,1,0.3,1);display:flex;flex-direction:column;}
.mobile-nav-drawer.open{transform:translateX(0);}
.mobile-nav-head{display:flex;justify-content:space-between;align-items:center;padding:1.4rem 1.6rem;border-bottom:1px solid var(--line);}
.mobile-nav-title{font-family:'Cormorant Garamond',serif;font-size:1.15rem;letter-spacing:0.03em;color:var(--ivory);}
.mobile-nav-links{list-style:none;padding:1rem 0;overflow-y:auto;}
.mobile-nav-links li{border-bottom:1px solid var(--line);}
.mobile-nav-links a{display:block;padding:1rem 1.6rem;font-size:0.85rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);transition:color 0.2s;}
.mobile-nav-links a:hover{color:var(--gold-bright);}

/* .nav-center is flex:1 (real leftover space between .nav-left and
   .nav-actions, not the row's geometric midpoint - see its base rule
   above) at every width, desktop included. This breakpoint only
   switches its flex-direction from column (desktop: wordmark stacked
   above the nav-links row) to row (below 1300px: nav-links is hidden
   entirely, so the wordmark is the only visible child and there's
   nothing left to stack).

   1300px specifically: at 8 nav items (added "Track Order"), the
   links need ~830px unwrapped and un-clipped; measured real free
   space between .nav-left and .nav-actions falls below that
   somewhere around 1230-1250px viewport width, so 1300px gives a
   deliberate safety margin rather than sitting right at the edge of
   breaking again the next time a nav item is added. */
@media (max-width:1300px){
  .nav-hamburger{display:flex;}
  .nav-row{padding:0.65rem 0.9rem;gap:0.4rem;}
  .nav-left{gap:0.4rem;}
  .logo-mark img{height:26px;}
  .nav-center{flex-direction:row;}
  .nav-brand-text{
    font-size:0.64rem;
    letter-spacing:0.12em;
    max-width:100%;
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .nav-actions{gap:0.5rem;}
}
/* .nav-search / .search-suggestions mobile overrides live in the
   SEARCH section below, after their unconditional base rules -
   same specificity, so they must come later in the file to win. */

/* ---------- ANNOUNCEMENT ---------- */
.announce{background:var(--surface-2);border-bottom:1px solid var(--line);text-align:center;padding:0.55rem 1rem;font-size:0.72rem;letter-spacing:0.08em;line-height:1.6;color:var(--muted);}
.announce b{color:var(--gold-bright);font-weight:500;}
@media (max-width:600px){.announce{font-size:0.66rem;letter-spacing:0.04em;padding:0.6rem 0.8rem;}}

/* ---------- HERO ----------
   Repositioned to the upper-left quadrant of the background photo,
   where the reference image has clean, uniform sky/water rather
   than textured rocks. No dark scrim reintroduced, text-shadow
   alone carries legibility per the earlier "remove the overlay"
   instruction; this only fixes position, not contrast method. */
.hero{position:relative;min-height:88vh;min-height:88dvh;overflow:hidden;background:#0b0a08;}
.hero-track{display:flex;width:100%;height:100%;min-height:88vh;min-height:88dvh;transition:transform 0.7s cubic-bezier(0.25,1,0.5,1);will-change:transform;}
.hero-slide{position:relative;flex:0 0 100%;width:100%;min-height:88vh;min-height:88dvh;display:flex;align-items:flex-start;overflow:hidden;background-size:cover;background-position:center;}
.hero-slide::after{
  content:"";
  position:absolute;
  top:-60%;left:-60%;
  width:60%;height:220%;
  background:linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.35) 50%, transparent 100%);
  pointer-events:none;
  opacity:0;
  z-index:1;
}
.hero-slide:hover::after{ animation:luxuryGlare 0.8s ease-in-out; }
.hero-inner{position:relative;z-index:2;width:100%;padding-top:7rem;animation:premiumFadeInUp 0.6s cubic-bezier(0.16,1,0.3,1) both;}
.hero-inner > *{max-width:520px;}
.hero-eyebrow{margin-bottom:1.2rem;text-shadow:0px 2px 4px rgba(0,0,0,0.8),0px 4px 12px rgba(0,0,0,0.6),0px 10px 25px rgba(0,0,0,0.5);}
.hero h1{font-size:clamp(2.4rem,5.6vw,4.2rem);line-height:1.06;color:#fff;max-width:18ch;text-shadow:0px 2px 4px rgba(0,0,0,0.8),0px 4px 12px rgba(0,0,0,0.6),0px 10px 25px rgba(0,0,0,0.5);}
.hero h1 em{color:var(--gold-bright);font-style:italic;}
.hero h1 .highlight-white{color:#ffffff !important;font-weight:800;font-style:normal;}
.hero p{margin-top:1.4rem;max-width:42ch;color:#f2ede2;font-size:1rem;text-shadow:0px 2px 4px rgba(0,0,0,0.8),0px 4px 12px rgba(0,0,0,0.6),0px 10px 25px rgba(0,0,0,0.5);}
.hero-ctas{display:flex;gap:1rem;margin-top:2.2rem;flex-wrap:wrap;}
@media (max-width:600px){
  .hero-inner{padding-top:5.5rem;}
  .hero-inner > *{max-width:100%;}
  .hero h1{font-size:2.1rem;max-width:16ch;}
  .hero p{font-size:0.88rem;}
  .hero-ctas .btn{padding:0.8rem 1.4rem;font-size:0.72rem;}
}

/* ---------- HERO CAROUSEL CONTROLS ---------- */
.hero-nav{
  position:absolute;bottom:1.65rem;
  width:38px;height:38px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(26,26,26,0.35);border:1px solid rgba(255,255,255,0.4);
  color:#fff;opacity:0;transition:opacity 0.35s ease, background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
  z-index:5;
}
.hero:hover .hero-nav{opacity:1;}
.hero-nav:hover{background:rgba(26,26,26,0.6);border-color:var(--gold-bright);color:var(--gold-bright);}
.hero-nav:focus-visible{opacity:1;}
.hero-nav svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6;}
.hero-nav-prev{left:1.6rem;}
.hero-nav-next{right:1.6rem;}
@media (max-width:760px){.hero-nav{width:34px;height:34px;opacity:0.55;}}

.hero-dots{position:absolute;bottom:1.8rem;left:50%;transform:translateX(-50%);display:flex;gap:0.6rem;z-index:5;}
.hero-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.4);border:1px solid rgba(255,255,255,0.6);padding:0;transition:background-color 0.3s ease, transform 0.3s ease;}
.hero-dot:hover{background:rgba(255,255,255,0.7);}
.hero-dot.active{background:var(--gold-bright);border-color:var(--gold-bright);transform:scale(1.3);}
.btn{display:inline-flex;align-items:center;gap:0.5rem;padding:0.9rem 1.9rem;font-size:0.78rem;letter-spacing:0.14em;text-transform:uppercase;transition:all 0.25s;border-radius:2px;}
.btn:disabled{opacity:0.45;cursor:not-allowed;pointer-events:none;}
.btn-solid{background:var(--gold);color:#1a1408;}
.btn-solid:hover{background:var(--gold-bright);color:#fff;}
.btn-outline{border:1px solid rgba(255,255,255,0.55);color:#fff;}
.btn-outline:hover{border-color:var(--gold);color:var(--gold-bright);background:rgba(255,255,255,0.08);}
.btn-arrow{display:inline-flex;align-items:center;transition:transform 0.3s ease;}
.btn-arrow svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.6;}
.btn:hover .btn-arrow{transform:translateX(4px);}
/* btn-outline used outside the hero (on cream backgrounds) needs dark text/border instead of the white hero variant above */
.section .btn-outline,.footer .btn-outline{border-color:var(--line);color:var(--ivory);}
.section .btn-outline:hover,.footer .btn-outline:hover{border-color:var(--gold);color:var(--gold-bright);background:transparent;}

/* ---------- USP STRIP ---------- */
.usp-strip{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--surface-2);}
.usp-row{display:flex;justify-content:space-between;padding:1.5rem 0;overflow-x:auto;gap:2rem;}
.usp-item{display:flex;align-items:center;gap:0.7rem;white-space:nowrap;font-size:0.76rem;letter-spacing:0.05em;color:var(--muted);}
.usp-item svg{width:16px;height:16px;stroke:var(--gold-bright);fill:none;stroke-width:1.3;flex-shrink:0;}

/* ---------- SECTION HEADER ---------- */
/* Was 5.5rem: adjacent homepage sections share this class with no
   margin between them, so two boundary paddings compound (bottom of
   one + top of the next) into a much larger visual gap than either
   value alone suggests - 5.5rem+5.5rem read as ~176px of dead space
   at every section break. 4rem keeps the section breathing room but
   halves that compounded gap to a tighter ~128px. */
.section{padding:4rem 0;}
/* Same compounding problem as above, worse on mobile: 4rem+4rem still
   reads as ~128px of dead space between one section's CTA and the
   next section's header on a phone-height viewport. Tightened further
   here rather than in the base rule, so desktop keeps its fuller
   breathing room. 600px matches .horizontal-slider-track's own mobile
   breakpoint just below, the established "mobile" cutoff in this file. */
@media (max-width:600px){.section{padding:2rem 0;}}
.section-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:2.6rem;gap:1.5rem;flex-wrap:wrap;}
.section-head h2{font-size:clamp(1.9rem,3.4vw,2.6rem);color:var(--ivory);}
.section-head p{color:var(--muted);font-size:0.9rem;max-width:34ch;}
.section-cta{text-align:center;margin-top:2.6rem;}

/* ---------- CATEGORY TABS ---------- */
.tabs{display:flex;gap:0.4rem;border-bottom:1px solid var(--line);margin-bottom:2.6rem;flex-wrap:wrap;}
.tab-btn{padding:0.8rem 1.4rem;font-size:0.78rem;letter-spacing:0.1em;text-transform:uppercase;color:var(--muted);border-bottom:2px solid transparent;transition:all 0.25s;margin-bottom:-1px;}
.tab-btn:hover{color:var(--ivory);}
.tab-btn.active{color:var(--gold-bright);border-bottom-color:var(--gold);}

/* ---------- PRODUCT GRID
   Cards go transparent/near-invisible so the white product photo
   background dissolves into the cream page canvas: a floating
   boutique shelf rather than a boxed tile. ---------- */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:2rem;}
@media (max-width:960px){.grid{grid-template-columns:repeat(2,1fr);gap:1.4rem;}}
.card{background:transparent;border:1px solid transparent;border-radius:6px;transition:border-color 0.3s, transform 0.3s, box-shadow 0.3s;display:flex;flex-direction:column;animation:premiumFadeInUp 0.6s cubic-bezier(0.16,1,0.3,1) both;cursor:pointer;}
.card:hover{border-color:var(--line);transform:translateY(-3px);box-shadow:0 14px 28px -20px rgba(44,37,32,0.25);}
/* Staggered assembly: first row (and a bit of the second) fades in with
   an incremental delay; anything past nth-child(10) just uses the base
   0s delay above rather than growing indefinitely for 100+ SKU grids. */
.grid .card:nth-child(1){animation-delay:0s;}
.grid .card:nth-child(2){animation-delay:0.1s;}
.grid .card:nth-child(3){animation-delay:0.2s;}
.grid .card:nth-child(4){animation-delay:0.3s;}
.grid .card:nth-child(5){animation-delay:0.4s;}
.grid .card:nth-child(6){animation-delay:0.5s;}
.grid .card:nth-child(7){animation-delay:0.6s;}
.grid .card:nth-child(8){animation-delay:0.7s;}
.grid .card:nth-child(9){animation-delay:0.8s;}
.grid .card:nth-child(10){animation-delay:0.9s;}
.card-media{position:relative;aspect-ratio:1;display:flex;align-items:center;justify-content:center;background:transparent;overflow:hidden;}
.card-media .bottle-wrap{width:44%;}
.card-media::after{
  content:"";
  position:absolute;
  top:-60%;left:-60%;
  width:60%;height:220%;
  background:linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.55) 50%, transparent 100%);
  pointer-events:none;
  opacity:0;
  z-index:2;
}
.card:hover .card-media::after{ animation:luxuryGlare 0.8s ease-in-out; }
/* No CSS vignette/inset-shadow/gradient ever existed here to remove -
   .card-media and .card are both background:transparent already, and
   .card-photo has carried no filter/box-shadow since the earlier
   product-card shadow-removal pass. The soft corner darkening visible
   on product photos is baked into the source photography's own pixel
   data (studio lighting falloff), confirmed by sampling actual pixel
   values - CSS can blend an image against the page, but it cannot
   selectively brighten only an image's corners. mix-blend-mode:multiply
   is added per luxury-ecommerce convention and is safe here (this
   site's cream bg, rgb(251,249,246), sits close enough to pure white
   that multiply is a near no-op), but it will NOT eliminate the
   vignette - only re-edited photography with a flatter, truly-white
   background can do that. object-fit stays "contain" (not "cover"):
   switching would crop bottle/jar photography, regressing an earlier
   deliberate fix. */
.card-photo{
  position:relative;z-index:1;width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply;
  transition:opacity 0.3s cubic-bezier(0.25,0.46,0.45,0.94),transform 0.3s cubic-bezier(0.25,0.46,0.45,0.94);
}
.modal-media .card-photo{width:82%;height:auto;max-height:70vh;}

/* ---------- NOTES HOVER/TOUCH REVEAL ----------
   Perfume cards only (getProductNotesImage() in app.js returns null,
   and cardMarkup skips rendering this element entirely, for any
   product without a distinct per-family notes shot - Attar/Bakhour/
   Our Creation all use one fixed or single real photo with nothing
   to swap to). Desktop uses the CSS :hover below; touch devices have
   no hover state, so app.js's touchstart/touchend toggle the same
   .reveal-notes class the touch media query can't reach on its own. */
.card-photo-notes{
  position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply;
  opacity:0;pointer-events:none;
  transition:opacity 0.3s cubic-bezier(0.25,0.46,0.45,0.94),transform 0.3s cubic-bezier(0.25,0.46,0.45,0.94);
}
@media (hover:hover) and (pointer:fine){
  .card-media.has-notes:hover .card-photo{opacity:0;transform:scale(0.97);}
  .card-media.has-notes:hover .card-photo-notes{opacity:1;transform:scale(1);pointer-events:auto;}
}
.card-media.has-notes.reveal-notes .card-photo{opacity:0;transform:scale(0.97);}
.card-media.has-notes.reveal-notes .card-photo-notes{opacity:1;transform:scale(1);pointer-events:auto;}
.card-family{position:absolute;top:0.8rem;left:0.8rem;font-size:0.62rem;letter-spacing:0.14em;text-transform:uppercase;color:var(--gold-bright);}
.card-sale{position:absolute;top:0.8rem;right:0.8rem;background:var(--danger);color:#fff;font-size:0.62rem;letter-spacing:0.06em;padding:0.2rem 0.5rem;border-radius:2px;}
.card-body{padding:1.6rem 0.4rem 1.8rem;flex:1;display:flex;flex-direction:column;}
.card-type{font-size:0.66rem;color:var(--muted);letter-spacing:0.14em;text-transform:uppercase;}
.card-title{font-size:1.3rem;margin:0.4rem 0 0.7rem;color:var(--ivory);letter-spacing:0.01em;}

.pyramid-mini{display:flex;height:4px;width:100%;border-radius:2px;overflow:hidden;margin-bottom:0.8rem;opacity:0.85;}
.pyramid-mini span{display:block;height:100%;}
.pyramid-mini .top{background:var(--top-note);}
.pyramid-mini .heart{background:var(--heart-note);}
.pyramid-mini .base{background:var(--base-note);}
.card-notes{font-size:0.74rem;color:var(--muted);margin-bottom:0.9rem;min-height:1.2em;letter-spacing:0.02em;}

.size-toggle{display:flex;gap:0.5rem;margin-bottom:1rem;}
.size-pill{padding:0.34rem 0.8rem;font-size:0.68rem;letter-spacing:0.06em;border:1px solid var(--line);color:var(--muted);border-radius:2px;transform-origin:center;transition:border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease, transform 0.25s cubic-bezier(0.34,1.56,0.64,1);}
.size-pill.active{border-color:var(--gold);color:var(--gold-bright);background:rgba(212,175,55,0.08);transform:scale(1.08);}
.size-single{font-size:0.74rem;color:var(--muted);margin-bottom:1rem;}

.card-price-row{display:flex;align-items:baseline;gap:0.6rem;margin-top:auto;margin-bottom:1.1rem;}
.price{font-size:1.08rem;color:var(--ivory);font-weight:500;}
.price-compare{font-size:0.85rem;color:var(--muted);text-decoration:line-through;}
.card-actions{display:flex;gap:0.6rem;}
.card-actions .btn{flex:1;justify-content:center;padding:0.75rem;font-size:0.72rem;}
.card-actions .btn-ghost{border:1px solid var(--line);color:var(--muted);}
.card-actions .btn-ghost:hover{color:var(--gold-bright);border-color:var(--gold-dim);}
/* ---------- MOBILE PRODUCT GRID (<=600px)
   Premium 2-column layout (Ajmal/luxury-storefront pattern) instead
   of single huge full-width cards. Tighter gap/paddings and scaled-down
   type throughout the card so two columns of the same card still read
   as intentional, not cramped; card-actions stacks vertically since
   two side-by-side buttons don't fit a ~155px-wide column legibly. */
@media (max-width:600px){
  .grid{grid-template-columns:repeat(2,1fr);gap:0.75rem;}
  .card-body{padding:0.9rem 0.15rem 1.1rem;}
  /* card-family inherits body's line-height:1.6, which pads its text box to
     ~1.6x the glyph height. On the narrower media squares here that padded
     box's bottom edge sits low enough to dip into .card-photo's own top
     clearance (it's centered at 84% height inside .card-media, leaving a
     fixed percentage of headroom that shrinks in absolute px as the square
     itself shrinks) - line-height:1 tightens the tag to its actual glyph
     height, and the padding-top on .card-media below adds a further margin
     of safety so the two can never visually touch. */
  .card-family{font-size:0.56rem;top:0.5rem;left:0.5rem;line-height:1;}
  .card-sale{font-size:0.56rem;padding:0.15rem 0.4rem;top:0.5rem;right:0.5rem;}
  .card-media{padding-top:0.65rem;}
  .card-type{font-size:0.6rem;}
  .card-title{font-size:0.98rem;margin:0.3rem 0 0.5rem;line-height:1.25;}
  .pyramid-mini{margin-bottom:0.6rem;}
  .card-notes{font-size:0.64rem;margin-bottom:0.7rem;}
  .size-toggle{gap:0.35rem;margin-bottom:0.75rem;flex-wrap:wrap;}
  .size-pill{padding:0.5rem 0.7rem;font-size:0.7rem;}
  .card-price-row{gap:0.4rem;margin-bottom:0.85rem;}
  .price{font-size:0.92rem;}
  .price-compare{font-size:0.72rem;}
  .card-actions{flex-direction:column;gap:0.45rem;}
  .card-actions .btn{padding:0.75rem 0.5rem;font-size:0.68rem;letter-spacing:0.05em;}
}

/* ---------- HOMEPAGE HORIZONTAL SLIDER
   Shared by every homepage product shelf (Best Sellers, For Him, For
   Her, Attars, Our Creations, Bakhour) - none of them use .grid on
   index.html anymore, all six scroll sideways the same way. Native
   overflow-x:auto + scroll-snap does all the scrolling, so touch
   swipe on mobile needs zero JS. The scrollbar is kept visible
   (styled thin, in the gold theme) rather than hidden, since there
   are no prev/next arrow buttons here to otherwise hint that desktop
   users can drag/wheel-scroll this row. ---------- */
.horizontal-slider-track{
  display:flex;
  gap:1.6rem;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;
  padding:0.4rem 0.2rem 1.2rem;
  scrollbar-width:thin;
  scrollbar-color:var(--gold-dim) transparent;
}
.horizontal-slider-track::-webkit-scrollbar{height:5px;}
.horizontal-slider-track::-webkit-scrollbar-track{background:transparent;}
.horizontal-slider-track::-webkit-scrollbar-thumb{background:var(--gold-dim);border-radius:3px;}
.horizontal-slider-track .card{flex:0 0 240px;scroll-snap-align:start;}
@media (max-width:600px){
  .horizontal-slider-track{gap:0.8rem;padding:0.2rem 0.1rem 1rem;}
  .horizontal-slider-track .card{flex:0 0 62vw;}
}

/* ---------- bottle silhouette (fallback art, unused now that real photos exist, kept for safety) ---------- */
.bottle-wrap{position:relative;}
.bottle-cap{width:34%;height:9%;margin:0 auto;background:linear-gradient(180deg,var(--gold-bright),var(--gold-dim));border-radius:2px 2px 0 0;}
.bottle-neck{width:14%;height:5%;margin:0 auto;background:var(--surface-2);}
.bottle-body{width:100%;aspect-ratio:0.62;background:linear-gradient(160deg, rgba(212,175,55,0.1), rgba(241,236,226,0.9) 55%);border:1px solid var(--line);border-radius:6px 6px 26px 26px;position:relative;}
.bottle-liquid{position:absolute;left:8%;right:8%;bottom:6%;top:38%;background:linear-gradient(180deg, rgba(212,175,55,0.5), rgba(122,95,30,0.7));border-radius:2px 2px 20px 20px;}

/* ---------- QUICK VIEW MODAL ---------- */
.overlay{position:fixed;inset:0;background:rgba(26,26,26,0.45);z-index:100;display:none;align-items:center;justify-content:center;padding:1.5rem;}
.overlay.open{display:flex;}
.modal{background:var(--surface);border:1px solid var(--line);border-radius:6px;max-width:820px;width:100%;max-height:88vh;overflow-y:auto;display:grid;grid-template-columns:0.9fr 1.1fr;box-shadow:0 30px 60px -20px rgba(26,26,26,0.35);}
@media (max-width:720px){.modal{grid-template-columns:1fr;}}
.modal-media{background:var(--surface-2);display:flex;align-items:center;justify-content:center;padding:2.4rem;border-right:1px solid var(--line);}
@media (max-width:720px){.modal-media{border-right:none;border-bottom:1px solid var(--line);}}
.modal-media .bottle-wrap{width:70%;}

/* ---------- QUICK VIEW GALLERY ----------
   Same overflow-x:auto + scroll-snap technique as .horizontal-slider-
   track elsewhere on the site - native scroll handles touch swipe with
   zero JS, app.js only listens to sync the dots and to support a dot
   click jumping the scroll position. Only rendered when a product has
   a real second (notes) image; single-image products keep the plain
   .modal-media <img> untouched, no empty slide/dots markup at all. */
.quickview-gallery{flex-direction:column;padding:1.6rem 1.6rem 1.2rem;gap:1rem;}
.quickview-track{
  display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;width:100%;border-radius:4px;
}
.quickview-track::-webkit-scrollbar{display:none;}
.quickview-slide{flex:0 0 100%;scroll-snap-align:start;display:flex;align-items:center;justify-content:center;}
.quickview-slide .card-photo{width:82%;height:auto;max-height:60vh;}
.quickview-dots{display:flex;justify-content:center;gap:0.5rem;}
.qv-dot{width:6px;height:6px;border-radius:50%;background:var(--line);transition:background-color 0.2s,transform 0.2s;cursor:pointer;}
.qv-dot.active{background:var(--gold-bright);transform:scale(1.3);}

.modal-body{padding:2.2rem;position:relative;}
.modal-close{position:absolute;top:1.2rem;right:1.2rem;color:var(--muted);font-size:1.4rem;line-height:1;}
.modal-close:hover{color:var(--gold-bright);}

/* ---------- PRODUCT DETAIL PAGE ----------
   Same 0.9fr/1.1fr ratio and 720px collapse as .modal, so the PDP
   reads as the same design language as the (now-removed) Quick View
   it replaces - it's a full page section, not a dialog, so no
   max-width/max-height/overlay chrome. .pdp-media reuses
   .quickview-gallery/.quickview-track/.quickview-slide/.quickview-dots
   wholesale (same classes, new home) instead of duplicating that CSS. */
.pdp-layout{display:grid;grid-template-columns:0.9fr 1.1fr;gap:2.4rem;}
@media (max-width:720px){.pdp-layout{grid-template-columns:1fr;}}
.pdp-media{background:var(--surface-2);display:flex;align-items:center;justify-content:center;padding:2.4rem;border-radius:6px;}
.pdp-media .card-photo{width:82%;height:auto;max-height:60vh;}
.pdp-body{position:relative;}
.pdp-body h1{font-size:clamp(1.7rem,3vw,2.3rem);color:var(--ivory);margin:0.3rem 0 0.9rem;}

.pdp-breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:0.5rem;font-size:0.78rem;color:var(--muted);margin-bottom:1.8rem;}
.pdp-breadcrumb a{color:var(--muted);transition:color 0.2s;}
.pdp-breadcrumb a:hover{color:var(--gold-bright);}
.pdp-breadcrumb .pdp-crumb-sep{color:var(--line);}
.pdp-breadcrumb .pdp-crumb-current{color:var(--ivory);}

.pdp-not-found{text-align:center;padding:4.5rem 1.5rem;}
.pdp-not-found h2{color:var(--ivory);margin-bottom:0.6rem;font-size:1.6rem;}
.pdp-not-found p{color:var(--muted);margin-bottom:1.8rem;}
.modal-body .card-type{margin-bottom:0.2rem;}
.modal-body h3{font-size:1.7rem;color:var(--ivory);margin-bottom:0.7rem;}
.modal-desc{font-size:0.88rem;color:var(--muted);margin-bottom:1.5rem;}
.pyramid-full{margin-bottom:1.6rem;}
.pdp-description{color:var(--ivory);font-size:0.95rem;line-height:1.7;margin-bottom:1.3rem;}
.pyramid-full-label{font-size:0.68rem;letter-spacing:0.1em;text-transform:uppercase;color:var(--muted);margin-bottom:0.8rem;}
.pyramid-tier{display:flex;align-items:center;gap:0.8rem;margin-bottom:0.7rem;}
.pyramid-tier .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.pyramid-tier .top-dot{background:var(--top-note);}
.pyramid-tier .heart-dot{background:var(--heart-note);}
.pyramid-tier .base-dot{background:var(--base-note);}
.pyramid-tier .tier-name{font-size:0.68rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);width:64px;flex-shrink:0;}
.pyramid-tier .tier-notes{font-size:0.86rem;color:var(--ivory);}
.modal-price-row{display:flex;align-items:baseline;gap:0.7rem;margin-bottom:1.3rem;}
.modal-price-row .price{font-size:1.5rem;}
.qty-row{display:flex;align-items:center;gap:1rem;margin-bottom:1.4rem;}
.qty-control{display:flex;align-items:center;border:1px solid var(--line);border-radius:2px;}
.qty-control button{width:34px;height:34px;color:var(--ivory);}
.qty-control button:hover{color:var(--gold-bright);}
.qty-control span{width:34px;text-align:center;font-size:0.9rem;}

/* ---------- VISIT CARD ---------- */
.visit-card{border:1px solid var(--line);background:var(--surface);border-radius:6px;display:grid;grid-template-columns:1fr 1fr 1fr;gap:0;}
@media (max-width:760px){.visit-card{grid-template-columns:1fr;}}
.visit-block{padding:2.2rem;border-right:1px solid var(--line);}
.visit-block:last-child{border-right:none;}
@media (max-width:760px){.visit-block{border-right:none;border-bottom:1px solid var(--line);}.visit-block:last-child{border-bottom:none;}}
.visit-block h4{
  font-size:0.72rem;letter-spacing:0.12em;text-transform:uppercase;color:var(--gold-bright);
  margin-bottom:0.9rem;font-family:'Jost',sans-serif;font-weight:500;
  position:relative;isolation:isolate;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
/* Address/hours span multiple real lines via <br>, so no white-space:nowrap here -
   that would truncate genuine content instead of just containing a rendering
   artifact. overflow-wrap keeps a long single line from overflowing its column,
   and isolation still gives it its own stacking context. */
.visit-block p{font-size:0.92rem;color:var(--ivory);line-height:1.7;position:relative;isolation:isolate;overflow-wrap:break-word;}
.visit-block a{
  color:var(--gold-bright);display:inline-block;max-width:100%;
  position:relative;isolation:isolate;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}

/* ---------- SEARCH
   Matches the always-visible inline nav search bar markup:
   #navSearchWrap > svg.nav-search-icon + #perfumeSearch + #searchSuggestions ---------- */
.nav-search{position:relative;display:flex;align-items:center;gap:0.5rem;background:var(--surface-2);border:1px solid var(--line);border-radius:20px;padding:0.45rem 0.9rem;width:220px;transition:width 0.25s, border-color 0.25s;}
.nav-search:focus-within{width:280px;border-color:var(--gold-dim);}
@media (max-width:1300px){
  .nav-search{width:104px;padding:0.4rem 0.65rem;}
  .nav-search:focus-within{width:min(200px,52vw);}
}
.nav-search-icon{width:15px;height:15px;stroke:var(--muted);fill:none;stroke-width:1.6;flex-shrink:0;}
.nav-search-input{flex:1;background:transparent;border:none;color:var(--ivory);font-size:0.8rem;font-family:inherit;min-width:0;}
.nav-search-input:focus{outline:none;}
.nav-search-input::placeholder{color:var(--muted);}
@media (max-width:1300px){.nav-search-input{font-size:0.76rem;}}
/* position:absolute takes this fully out of flow, so it can never
   push/squish the nav row's own dimensions regardless of how much
   content it holds - z-index:9999 just settles paint order against
   other overlays (cart/mobile-nav drawers, modals), it doesn't
   affect layout. */
.search-suggestions{
  position:absolute;top:calc(100% + 10px);left:0;right:0;min-width:320px;
  background:#F9F6F0;border:1px solid var(--gold-dim);border-radius:6px;
  max-height:350px;overflow-y:auto;z-index:9999;display:none;
  box-shadow:0 10px 30px rgba(0,0,0,0.08);
  scrollbar-width:thin;scrollbar-color:var(--gold-dim) transparent;
}
.search-suggestions::-webkit-scrollbar{width:5px;}
.search-suggestions::-webkit-scrollbar-track{background:transparent;}
.search-suggestions::-webkit-scrollbar-thumb{background:var(--gold-dim);border-radius:3px;}
.search-suggestions.open{display:block;}
@media (max-width:1300px){
  .search-suggestions{left:auto;right:-0.4rem;min-width:0;width:max(240px,calc(100vw - 2.2rem));}
}
.suggestion-item{
  padding:0.65rem 1rem;font-size:0.83rem;color:var(--ivory);cursor:pointer;
  border-bottom:1px solid var(--line);display:flex;align-items:center;gap:0.8rem;
}
.suggestion-item:last-child{border-bottom:none;}
.suggestion-item:hover{background:rgba(212,175,55,0.08);}
.suggestion-thumb{width:40px;height:40px;flex-shrink:0;background:var(--surface-2);border-radius:4px;display:flex;align-items:center;justify-content:center;overflow:hidden;}
.suggestion-thumb img{width:75%;height:75%;object-fit:contain;}
.suggestion-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:0.22rem;}
.suggestion-name{font-family:'Cormorant Garamond',serif;font-size:0.92rem;color:var(--ivory);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.suggestion-badge{font-size:0.6rem;letter-spacing:0.1em;text-transform:uppercase;color:var(--gold-bright);}
.suggestion-price{color:var(--muted);font-size:0.76rem;white-space:nowrap;flex-shrink:0;}
.suggestion-empty{padding:0.9rem 1rem;font-size:0.82rem;color:var(--muted);}
@keyframes searchHighlightPulse{
  0%, 100% { box-shadow:0 0 0 2px rgba(212,175,55,0.3); }
  50% { box-shadow:0 0 0 6px rgba(212,175,55,0.15), 0 0 24px 4px rgba(212,175,55,0.35); }
}
.card.search-highlight{border-color:var(--gold);animation:searchHighlightPulse 1s ease-in-out 2;}
/* Mobile .nav-search sizing (width, focus-within expansion, dropdown
   anchoring) lives in the single @media(max-width:1300px) NAV-section block in the
   NAV section above, consolidated there instead of duplicated here. */

/* ---------- CHECKOUT MODAL
   Binds to the static form already in index.html/perfumes.html
   (#checkoutModal > .checkout-body > #checkoutSummary, #checkoutForm,
   #checkoutTotal), app.js populates rather than injects it. ---------- */
.checkout-modal{grid-template-columns:1fr;max-width:520px;}
.checkout-body{padding:2.2rem;position:relative;}
.checkout-body h3{font-size:1.6rem;color:var(--ivory);margin-bottom:0.5rem;}
.checkout-summary{color:var(--muted);font-size:0.85rem;margin-bottom:1.6rem;}
.checkout-form label{display:block;font-size:0.7rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--gold-bright);margin-bottom:0.5rem;margin-top:1.1rem;}
.checkout-form label:first-of-type{margin-top:0;}
.checkout-form input,.checkout-form textarea{
  width:100%;background:var(--surface-2);border:1px solid var(--line);color:var(--ivory);
  padding:0.75rem 0.9rem;font-size:0.88rem;font-family:inherit;border-radius:3px;margin-top:0.1rem;
}
.checkout-form input:focus,.checkout-form textarea:focus{outline:none;border-color:var(--gold-dim);}
.checkout-form textarea{resize:vertical;min-height:80px;}
.checkout-total-row{display:flex;justify-content:space-between;align-items:baseline;padding:1rem 0;border-top:1px solid var(--line);margin:1.3rem 0 1.4rem;}
.checkout-total-row span:last-child{font-size:1.3rem;color:var(--ivory);font-weight:500;}

/* ---------- DISCOVERY SET MODAL
   #discoveryOverlay/.discovery-modal reuse .overlay/.modal wholesale
   (same dark scrim + centered card + close-button mechanics as
   quick-view/checkout/coming-soon) - a frosted-glass blur layered on
   top of the scrim is the one deliberately distinct touch for this
   feature, scoped to this overlay only so the other three modals'
   backdrop is untouched. ---------- */
#discoveryOverlay{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);}
.discovery-modal{grid-template-columns:1fr;max-width:640px;max-height:88vh;}
.discovery-body{padding:2.2rem;position:relative;}
.discovery-body .modal-header h2{font-size:1.6rem;color:var(--ivory);margin-bottom:0.5rem;}
.discovery-body .subtitle{color:var(--muted);font-size:0.85rem;margin-bottom:1.8rem;}
.discovery-slots-wrapper{display:grid;grid-template-columns:1fr 1fr;gap:1rem 1.2rem;margin-bottom:1.6rem;}
.discovery-slot label{display:block;font-size:0.66rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--gold-bright);margin-bottom:0.4rem;}
.discovery-slot select{
  width:100%;background:var(--surface-2);border:1px solid var(--line);color:var(--ivory);
  padding:0.65rem 0.8rem;font-size:0.84rem;font-family:inherit;border-radius:3px;
}
.discovery-slot select:focus{outline:none;border-color:var(--gold-dim);}
.discovery-footer{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding-top:1.4rem;border-top:1px solid var(--line);flex-wrap:wrap;}
.selection-counter{font-size:0.85rem;color:var(--muted);}
.selection-counter span{color:var(--ivory);font-weight:500;}
.cart-thumb-bundle{font-family:'Cormorant Garamond',serif;font-size:1.3rem;color:var(--gold-bright);}
@media (max-width:600px){
  .discovery-slots-wrapper{grid-template-columns:1fr;}
  .discovery-footer{flex-direction:column;align-items:stretch;}
}

/* ---------- COMING SOON MODAL (Attars / Home Fragrance) ---------- */
.coming-soon-modal{max-width:440px;grid-template-columns:1fr;text-align:center;padding:2.6rem 2.2rem;}
.coming-soon-modal .eyebrow{display:block;margin-bottom:1rem;}
.coming-soon-modal h3{font-size:1.6rem;color:var(--ivory);margin-bottom:1rem;}
.coming-soon-modal p{color:var(--muted);font-size:0.92rem;line-height:1.7;margin-bottom:1.8rem;}
.coming-soon-modal .modal-close{position:absolute;top:1.2rem;right:1.2rem;}

/* ---------- STORY BAND ---------- */
.story-band{background:var(--surface-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line);}
/* padding-top/padding-bottom only (not the "padding" shorthand) - this element
   also carries .container for its left/right cushion via clamp(); .container
   is declared earlier in this file, so a padding SHORTHAND here would win the
   cascade on all four sides and silently zero out that horizontal padding,
   flushing the story copy/media edge-to-edge on narrow viewports. */
.story-grid{display:grid;grid-template-columns:1fr 1fr;gap:3rem;align-items:center;padding-top:4rem;padding-bottom:4rem;}
@media (max-width:840px){.story-grid{grid-template-columns:1fr;}}
.story-media{aspect-ratio:4/3;border:1px solid var(--line);border-radius:6px;overflow:hidden;animation:premiumFadeInUp 0.6s cubic-bezier(0.16,1,0.3,1) both;}
.story-media img{width:100%;height:100%;object-fit:cover;}
.story-copy{animation:premiumFadeInUp 0.6s cubic-bezier(0.16,1,0.3,1) 0.15s both;}
.story-copy h2{font-size:clamp(1.8rem,3vw,2.4rem);margin-bottom:1.1rem;}
.story-copy p{color:var(--muted);font-size:0.94rem;margin-bottom:1.6rem;max-width:42ch;}

/* ---------- FOOTER
   Kept as a deep, grounded dark band rather than forcing it cream
   too: Jo Malone/Byredo-style light sites commonly close on a dark
   footer for contrast. Three-line change to make it match --bg
   exactly if that's not wanted. ---------- */
.footer{background:var(--footer-bg);border-top:1px solid var(--line);color:var(--footer-text);}
/* padding-top/padding-bottom only (not the "padding" shorthand) - this element
   also carries .container for its left/right cushion via clamp(); .container
   is declared earlier in this file, so a padding SHORTHAND here would win the
   cascade on all four sides and silently zero out that horizontal padding,
   flushing every footer column's text to the screen edge on narrow viewports. */
.footer-top{padding-top:4.5rem;padding-bottom:3rem;display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr;gap:2.5rem;}
@media (max-width:900px){.footer-top{grid-template-columns:1fr 1fr;}}
@media (max-width:560px){.footer-top{grid-template-columns:1fr;}}
.footer-brand .logo-mark{margin-bottom:1rem;}
.footer-brand .logo-mark img{filter:brightness(0) invert(1);}
.footer-brand p{color:rgba(245,240,230,0.65);font-size:0.85rem;max-width:32ch;margin-bottom:1.4rem;}
.newsletter-form{display:flex;border:1px solid rgba(245,240,230,0.25);max-width:340px;border-radius:2px;}
.newsletter-form input{flex:1;background:transparent;border:none;padding:0.8rem 1rem;color:var(--footer-text);font-size:0.85rem;font-family:inherit;}
.newsletter-form input::placeholder{color:rgba(245,240,230,0.5);}
.newsletter-form input:focus{outline:none;}
.newsletter-form button{padding:0.8rem 1.1rem;color:var(--gold-bright);font-size:0.76rem;letter-spacing:0.08em;text-transform:uppercase;}
/* Containment below (overflow:hidden + white-space:nowrap + text-overflow:ellipsis
   + an isolated stacking context) is defensive hardening against third-party DOM
   mutation - mobile auto-translate widgets, reader/accessibility overlays,
   extensions - that can leave a stray duplicated text fragment layered over the
   original if they process an element while it's mid-render. It's restricted to
   genuinely single-line labels/links here; the multi-line address/hours text in
   .visit-block below intentionally does NOT get white-space:nowrap, since that
   would truncate real content instead of just containing a rendering artifact.
   text-transform is left as uppercase on h4 (it's the actual visual design, not
   part of the bug's causal chain) and left at its already-default "none" on a,
   included below only for explicitness. */
.footer-col h4{
  font-family:'Jost',sans-serif;font-weight:500;font-size:0.76rem;letter-spacing:0.12em;
  text-transform:uppercase;color:var(--footer-text);margin-bottom:1.2rem;
  position:relative;isolation:isolate;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.footer-col ul{list-style:none;}
.footer-col li{margin-bottom:0.7rem;}
.footer-col a{
  color:rgba(245,240,230,0.65);font-size:0.86rem;transition:color 0.25s;
  text-transform:none;display:block;position:relative;isolation:isolate;
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.footer-col a:hover{color:var(--gold-bright);}
/* footerVisit column (Visit Us copy inside .footer-col) - same containment
   treatment as .visit-block above, previously done via inline styles in
   app.js's renderStoreDetails(); moved here so it's one rule instead of a
   duplicated style string, and so it gets the same hardening. */
.footer-visit-text{color:var(--muted);font-size:0.86rem;line-height:1.7;margin-bottom:0.8rem;position:relative;isolation:isolate;overflow-wrap:break-word;}
.footer-visit-phone{font-size:0.86rem;color:var(--gold-bright);display:inline-block;max-width:100%;position:relative;isolation:isolate;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
/* Same padding-top/padding-bottom-only fix as .footer-top above - this element
   also carries .container, and a padding shorthand here would zero out its
   horizontal cushion too, flushing the copyright line and social icons edge-to-edge. */
.footer-bottom{border-top:1px solid rgba(245,240,230,0.15);padding-top:1.6rem;padding-bottom:1.6rem;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem;}
.footer-bottom p{color:rgba(245,240,230,0.55);font-size:0.76rem;}
.social-row{display:flex;gap:1rem;}
.social-row a{color:rgba(245,240,230,0.65);}
.social-row a:hover{color:var(--gold-bright);}
.social-row svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.3;}

/* ---------- CART DRAWER ---------- */
.drawer-overlay{position:fixed;inset:0;background:rgba(26,26,26,0.45);z-index:110;opacity:0;pointer-events:none;transition:opacity 0.3s;}
.drawer-overlay.open{opacity:1;pointer-events:auto;}
.cart-drawer{position:fixed;top:0;right:0;height:100%;width:min(420px,92vw);background:var(--surface);border-left:1px solid var(--line);z-index:120;transform:translateX(100%);will-change:transform;transition:transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);display:flex;flex-direction:column;}
.cart-drawer.open{transform:translateX(0);}
.cart-head{display:flex;justify-content:space-between;align-items:center;padding:1.4rem 1.6rem;border-bottom:1px solid var(--line);}
.cart-head h3{font-size:1.15rem;letter-spacing:0.03em;}
.cart-items{flex:1;overflow-y:auto;padding:1rem 1.6rem;}
.cart-empty{color:var(--muted);font-size:0.88rem;text-align:center;padding:3rem 0;}
.cart-line{display:flex;gap:1rem;padding:1rem 0;border-bottom:1px solid var(--line);}
.cart-thumb{width:56px;height:56px;background:var(--surface-2);flex-shrink:0;display:flex;align-items:center;justify-content:center;border-radius:4px;}
.cart-thumb .bottle-wrap{width:70%;}
.cart-line-info{flex:1;}
.cart-line-info .name{font-size:0.9rem;color:var(--ivory);}
.cart-line-info .meta{font-size:0.74rem;color:var(--muted);margin:0.2rem 0 0.5rem;}
.cart-line-actions{display:flex;align-items:center;justify-content:space-between;}
.cart-remove{font-size:0.72rem;color:var(--muted);text-decoration:underline;}
.cart-remove:hover{color:var(--danger);}
.cart-foot{border-top:1px solid var(--line);padding:1.4rem 1.6rem;}
.cart-subtotal{display:flex;justify-content:space-between;font-size:0.95rem;margin-bottom:1rem;}
.cart-note{font-size:0.72rem;color:var(--muted);margin-bottom:1rem;}

/* ---------- PRICE BREAKDOWN (cart drawer + checkout modal) ----------
   Same markup/classes power both #cartTotalsBreakdown and
   #checkoutTotalsBreakdown - one totalsBreakdownHtml() generator in
   app.js, so the two can never show different numbers for the same cart. */
.totals-row{display:flex;justify-content:space-between;font-size:0.88rem;color:var(--muted);padding:0.3rem 0;}
.totals-row .value{color:var(--ivory);}
.totals-row.discount .value{color:var(--gold-bright);}
.totals-row.free-shipping .value{color:var(--gold-bright);text-transform:uppercase;font-size:0.76rem;letter-spacing:0.06em;}
.totals-row.grand-total{border-top:1px solid var(--line);margin-top:0.5rem;padding-top:0.9rem;font-size:1.05rem;}
.totals-row.grand-total .label,.totals-row.grand-total .value{color:var(--ivory);font-weight:500;}

/* ---------- ORDER TRACKING DRAWER ----------
   #trackingDrawer/#trackingOverlay are .cart-drawer/.drawer-overlay
   themselves (see the HTML), so the slide/mask mechanics above are
   inherited for free. Everything below is only the form + result
   panel content unique to this drawer. Its .btn-outline needs its
   own light-background override (same fix used for .category-hero),
   since the drawer sits on var(--surface), not the dark hero photo
   .btn-outline was originally styled for. ---------- */
.tracking-form .tracking-error{color:var(--danger);font-size:0.82rem;margin-top:0.9rem;}
#trackingBody .btn-outline{border-color:var(--line);color:var(--ivory);}
#trackingBody .btn-outline:hover{border-color:var(--gold);color:var(--gold-bright);background:transparent;}

.tracking-timeline{position:relative;display:flex;justify-content:space-between;margin:0.4rem 0 2rem;padding-top:0.4rem;}
.tracking-timeline::before{content:"";position:absolute;top:0.65rem;left:0;right:0;height:2px;background:var(--line);}
.tracking-timeline .tt-progress{position:absolute;top:0.65rem;left:0;height:2px;background:var(--gold);transition:width 0.4s ease;}
.tt-step{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;flex:1;text-align:center;}
.tt-dot{width:12px;height:12px;border-radius:50%;background:var(--surface);border:2px solid var(--line);margin-bottom:0.6rem;}
.tt-step.tt-done .tt-dot,.tt-step.tt-current .tt-dot{background:var(--gold);border-color:var(--gold);}
.tt-label{font-size:0.6rem;letter-spacing:0.05em;text-transform:uppercase;color:var(--muted);padding:0 0.2rem;}
.tt-step.tt-done .tt-label,.tt-step.tt-current .tt-label{color:var(--ivory);}

.tracking-meta{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:1.1rem 0;margin-bottom:1.4rem;}
.tracking-meta-row{display:flex;justify-content:space-between;align-items:baseline;font-size:0.85rem;padding:0.35rem 0;gap:1rem;}
.tracking-meta-row span:first-child{color:var(--muted);}
.tracking-meta-row span:last-child{color:var(--ivory);text-align:right;}
.tracking-meta-row a{color:var(--gold-bright);text-decoration:underline;font-size:0.85rem;}
.tracking-items h4{font-size:0.72rem;letter-spacing:0.1em;text-transform:uppercase;color:var(--muted);margin-bottom:0.6rem;}
.tracking-items .cart-line:last-child{border-bottom:none;}
.tracking-reset{margin-top:1.6rem;}

@media (max-width:600px){
  .tt-label{font-size:0.54rem;letter-spacing:0.02em;}
  .tracking-timeline{gap:0.2rem;}
}

.toast{position:fixed;bottom:1.6rem;right:1.6rem;background:var(--ivory);color:#fff;padding:0.85rem 1.3rem;font-size:0.82rem;z-index:130;border-radius:3px;transform:translateY(20px);opacity:0;transition:all 0.3s;pointer-events:none;}
.toast.show{transform:translateY(0);opacity:1;}

/* ==========================================================
   CATEGORY HERO BANNER
   Shared across perfumes.html / attars.html / bakhour.html /
   our-creation.html, sitting flush below .nav (which is
   position:sticky, not fixed, so it needs no manual top offset
   to clear). Copy/CTA values are hand-written per page in the
   markup, not rendered by app.js, so editing them directly is
   safe and won't be overwritten by any script.

   Real photography (assets/images/banners/) now backs this
   section via .category-hero-picture, a full-bleed absolute
   layer behind .category-hero-inner. This replaces an earlier
   CSS-illustrated stone-plinth/bottle mock and a hand-built SVG
   frond-shadow texture that stood in for real photography before
   it existed - both are gone now, along with the 2-column
   copy|visual grid split that made room for that mock. The real
   photos are shot with their own built-in negative space (left
   side on desktop, top on mobile) specifically for this text
   overlay, so .category-hero-copy sits directly over the photo
   instead of sharing a grid column with a synthetic visual.
   ========================================================== */
.category-hero{position:relative;overflow:hidden;background:var(--surface-2);min-height:480px;}
.category-hero-picture{position:absolute;inset:0;z-index:0;}
.category-hero-picture img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;}
.category-hero-inner{position:relative;z-index:1;padding-top:5.5rem;padding-bottom:4.5rem;}
.category-hero-copy{max-width:480px;}
/* .category-hero-copy .eyebrow is scoped (not the bare .eyebrow class)
   so this shadow only reaches the hero's own subtitle, not the many
   other .eyebrow labels used elsewhere on light backgrounds (section
   heads, product shelf titles) that never asked for one. */
.category-hero-copy .eyebrow{text-shadow:0px 2px 10px rgba(0,0,0,0.4),0px 1px 3px rgba(0,0,0,0.2);}
.category-hero-title{font-size:clamp(3rem,6vw,5.2rem);color:var(--ivory);line-height:1.02;margin:0.6rem 0 1.3rem;text-shadow:0px 2px 10px rgba(0,0,0,0.4),0px 1px 3px rgba(0,0,0,0.2);}
.category-hero-rule{display:block;width:64px;height:2px;background:var(--gold);margin-bottom:1.3rem;}
.category-hero-desc{color:var(--muted);font-size:1rem;line-height:1.7;max-width:38ch;margin-bottom:2rem;text-shadow:0px 2px 10px rgba(0,0,0,0.4),0px 1px 3px rgba(0,0,0,0.2);}
.category-hero .btn-outline{border-color:var(--line);color:var(--ivory);}
.category-hero .btn-outline:hover{border-color:var(--gold);color:var(--gold-bright);background:transparent;}

.category-hero-promo{position:absolute;top:2rem;right:clamp(1.2rem,4vw,3rem);max-width:220px;text-align:right;font-size:0.72rem;line-height:1.6;color:var(--muted);z-index:1;}
.category-hero-promo strong{color:var(--ivory);}

.category-anchor{display:flex;align-items:center;gap:1.2rem;max-width:360px;margin:2.6rem auto 0;padding:0 1.5rem;}
.category-anchor-rule{flex:1;height:1px;background:var(--line);}
.category-anchor-label{font-size:0.7rem;letter-spacing:0.26em;color:var(--gold-bright);white-space:nowrap;}

@media (max-width:600px){
  /* padding-left/right pinned to 0.9rem to match .nav-row's own mobile
     padding exactly (see the @media (max-width:1300px) .nav-row rule) -
     .container's clamp(1.2rem,4vw,3rem) resolves to a different value
     at this width, which would leave the hero text out of step with
     where the hamburger/logo actually sit. */
  .category-hero{min-height:460px;}
  .category-hero-inner{padding-top:3rem;padding-bottom:2rem;padding-left:0.9rem;padding-right:0.9rem;}
  /* Capped so the copy sits inside the photo's own built-in empty
     zone (top-left on every mobile banner shot) instead of extending
     into the product bottles composed into the bottom-right of frame. */
  .category-hero-copy{max-width:62%;}
  .category-hero-title{font-size:clamp(2.1rem,9vw,2.6rem);margin:0.5rem 0 1rem;}
  .category-hero-rule{margin-bottom:1rem;}
  .category-hero-desc{font-size:0.86rem;max-width:none;margin-bottom:1.5rem;}
  .category-hero-cta{padding:0.75rem 1.2rem;font-size:0.66rem;letter-spacing:0.08em;white-space:nowrap;}
  /* Redundant with the global .announce bar at the very top of
     every page on a screen with no room to spare - hidden here
     rather than repeated twice above the fold. */
  .category-hero-promo{display:none;}
  .category-anchor{margin-top:1.8rem;}
}

/* ==========================================================
   PERFORMANCE: SKELETON LOADERS
   Rendered into the grid/shelf containers the instant the page
   parses, before loadProducts() resolves, so the layout's real
   dimensions exist immediately (zero CLS when real cards replace
   them) instead of a plain "Loading..." string collapsing the
   section to near-zero height. Mirrors .card/.card-media's own
   box model (same aspect-ratio:1 media block) so the swap-in
   causes no shift at all. ========================================================== */
@keyframes skeletonShimmer{
  0%{background-position:-200% 0;}
  100%{background-position:200% 0;}
}
.card-skeleton{border:1px solid transparent;border-radius:6px;display:flex;flex-direction:column;pointer-events:none;}
.card-skeleton .card-media{background:transparent;}
.skel-shimmer{
  background:linear-gradient(90deg, var(--surface-2) 25%, rgba(255,255,255,0.5) 50%, var(--surface-2) 75%);
  background-size:200% 100%;
  animation:skeletonShimmer 1.4s ease-in-out infinite;
  border-radius:4px;
}
.card-skeleton .card-media.skel-shimmer{border-radius:6px;}
.card-skeleton .card-body{padding-top:0.9rem;display:flex;flex-direction:column;gap:0.6rem;}
.card-skeleton .skel-line{height:0.7rem;width:100%;}
.card-skeleton .skel-line.skel-title{height:0.95rem;width:78%;}
.card-skeleton .skel-line.skel-notes{width:55%;}
.card-skeleton .skel-line.skel-price{width:35%;margin-top:0.2rem;}

/* ==========================================================
   PERFORMANCE: OFF-SCREEN RENDER COST
   content-visibility:auto lets the browser skip layout/paint work
   for these sections until they near the viewport. Scoped to
   homepage shelves/sections below the hero+Best Sellers fold only
   - the hero, usp strip and Best Sellers shelf stay untouched so
   nothing that actually paints on first view is deferred.
   contain-intrinsic-size approximates each section's real rendered
   height so the scrollbar/anchor positions don't jump once the
   browser swaps in real layout. ========================================================== */
#himSection, #herSection, #unisexSection, #attarSection,
#creationsSection, #bakhourSection{
  content-visibility:auto;
  contain-intrinsic-size:auto 640px;
}
#story, #visit{
  content-visibility:auto;
  contain-intrinsic-size:auto 420px;
}
.footer{
  content-visibility:auto;
  contain-intrinsic-size:auto 380px;
}

/* ==========================================================
   PERFORMANCE: TOUCH RESPONSIVENESS
   touch-action:manipulation tells the browser these controls never
   need pinch-zoom/double-tap-zoom gesture detection, which removes
   the ~300ms delay browsers otherwise insert between a tap and its
   click event on touch devices. ========================================================== */
.btn, .icon-btn, .size-pill, .hero-nav, .hero-dot, .modal-close,
.nav-hamburger, .card, .card-actions a, .nav-links a, .mobile-nav-links a{
  touch-action:manipulation;
}
