/* Fonts, served from this site rather than Google's.

   The stylesheet used to sit on fonts.googleapis.com and the files on
   fonts.gstatic.com — two DNS lookups and two TLS handshakes to hosts we do not
   control, before a single word could be drawn. They are here now, on a
   connection the browser has already opened.

   Both families are variable fonts: one file covers every weight. Google's own
   stylesheet downloads that same file once per weight and labels each copy with
   a single fixed weight, which is three times the bytes for the same glyphs.
   Declared as ranges instead, so one file answers for all of them.

   Latin only. Every non-ASCII character the site actually uses falls inside this
   range — the two that do not, the arrow and the star, fell back to a system
   font under Google's subsetting too, so nothing about them changed.

   swap: text draws immediately in the fallback face and reflows when these
   arrive, rather than leaving the page blank while they load. */

@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/cormorant-garamond-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/cormorant-garamond-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* The Arabic faces. Each is scoped to the Arabic unicode-range, which is what
   makes this safe to ship on every page: a browser only downloads a font whose
   range the page actually uses, so an English page never fetches a byte of
   these. That is also why they sit in the same family stacks rather than behind
   a [lang] switch — on a page mixing both scripts, every character is drawn by
   the face built for it, and "ADMA" or "QR 350" inside an Arabic sentence keeps
   the Latin typeface it was designed in.

   Amiri is a Naskh in the classical tradition, chosen to stand where Cormorant
   Garamond stands in English — a formal face with real calligraphic history.
   Tajawal is geometric and quiet, the counterpart to Jost. Both are OFL. */
@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/amiri-400.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/tajawal-300.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/tajawal-400.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/tajawal-500.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/jost-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   ADMA — Design System
   Two typefaces. Zero border-radius. One restrained accent.
   All colour, spacing, and type decisions live here as tokens.
   ========================================================================== */

/* --- 1. TOKENS ----------------------------------------------------------- */
:root {
  /* Core surfaces — warm-shifted blacks. Never pure #000 (reads cheap on OLED). */
  --ink:        #0F0E0C;
  --ink-2:      #171613;
  --ink-3:      #211F1B;
  --oud:        #2A211C;

  /* Light surfaces — warm, paper-like. Never pure #FFF. */
  --ivory:      #F5F2EC;
  --bone:       #E8E2D6;
  --linen:      #DED7C8;

  /* Text */
  --text-dark:      #14130F;
  --text-dark-soft: #55503F;
  --text-light:     #F5F2EC;
  --text-light-soft:#A9A093;

  /* Accents. Used as hairlines, labels, and hover states — never as large gold fills. */
  --amber:      #A9743F;   /* muted, earthy. NOT gold. Decorative use only. */
  --amber-lift: #C08E56;   /* on dark: 6.7:1 against --ink */
  --amber-deep: #8A5A2B;   /* on light: 5.3:1 against --ivory */
  --cypress:    #223229;
  --wine:       #4A1F26;

  /* Something went wrong, and something went right. Warm rather than the usual
     alarm red, so a mistyped digit still looks like it belongs to this shop —
     but far enough from the amber accent that it cannot be mistaken for one. */
  --error:      #8C2F2F;
  --error-bg:   rgba(140, 47, 47, 0.07);
  --error-lift: #D99A9A;   /* the same message on a dark surface */
  --ok:         #2F5D3A;
  --ok-bg:      rgba(47, 93, 58, 0.07);
  --ok-lift:    #8FC7A0;

  /* Context-aware accent. Dark surfaces override it below, so every label,
     placeholder, hover and focus ring stays above WCAG AA in both directions. */
  --accent-text: var(--amber-deep);
  --accent-fill: var(--amber-deep);   /* paired with --ivory text: 5.3:1 */

  /* Hairlines */
  --rule-light: rgba(245,242,236,.14);
  --rule-dark:  rgba(20,19,15,.13);

  /* Type */
  --font-display: "Cormorant Garamond", "Amiri", "Iowan Old Style", Georgia, serif;
  --font-ui:      "Jost", "Tajawal", "Avenir Next", "Segoe UI", system-ui, sans-serif;

  --fs-display: clamp(3.25rem, 9.5vw, 8rem);
  --fs-h1:      clamp(2.4rem, 6vw, 4.75rem);
  --fs-h2:      clamp(1.9rem, 4vw, 3.1rem);
  --fs-h3:      clamp(1.3rem, 2.2vw, 1.7rem);
  --fs-h4:      clamp(1.05rem, 1.4vw, 1.2rem);
  --fs-body:    clamp(0.95rem, 0.35vw + 0.86rem, 1.0625rem);
  --fs-sm:      0.875rem;
  --fs-xs:      0.8125rem;
  --fs-label:   0.6875rem;

  --tracking-label: 0.2em;
  --tracking-wide:  0.08em;

  /* Spacing — 4px base */
  --s1: 4px;   --s2: 8px;   --s3: 12px;  --s4: 16px;
  --s5: 24px;  --s6: 32px;  --s7: 48px;  --s8: 64px;
  --s9: 96px;  --s10: 128px; --s11: 160px; --s12: 200px;

  /* Layout */
  --maxw: 1440px;
  --maxw-text: 62ch;
  --gutter: clamp(20px, 5vw, 72px);
  --header-h: 68px;

  /* Motion */
  --ease: cubic-bezier(.22,.61,.36,1);
  --dur: 340ms;

  --z-header: 100;
  --z-drawer: 300;
  --z-overlay: 290;
}

/* --- 2. RESET ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
body {
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: 300;
  line-height: 1.65;
  color: var(--text-dark);
  background: var(--ivory);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
h1, h2, h3, h4 { font-weight: 300; line-height: 1.06; letter-spacing: -0.01em; }

/* Any dark surface flips the accent to its light-on-dark variant. */
.section--dark, .section--oud, .hero, .page-hero, .footer,
.mobile-menu, .collection, .pillar, .quote, .header--overlay, .announce {
  --accent-text: var(--amber-lift);
}

:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}
::selection { background: var(--accent-fill); color: var(--ivory); }

.skip-link {
  position: absolute; inset-inline-start: var(--s4); inset-block-start: -100px;
  z-index: 999; background: var(--ink); color: var(--ivory);
  padding: var(--s3) var(--s5); font-size: var(--fs-sm);
  transition: inset-block-start 200ms var(--ease);
}
.skip-link:focus { inset-block-start: var(--s4); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- 3. LAYOUT PRIMITIVES ------------------------------------------------ */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--narrow { max-width: 920px; }
.section { padding-block: clamp(64px, 9vw, 140px); }
.section--tight { padding-block: clamp(48px, 6vw, 88px); }
.section--dark { background: var(--ink); color: var(--text-light); }
.section--oud  { background: var(--oud); color: var(--text-light); }
.section--bone { background: var(--bone); }
.stack > * + * { margin-block-start: var(--s4); }

/* --- 4. TYPE UTILITIES --------------------------------------------------- */
.display {
  font-family: var(--font-display); font-weight: 300;
  font-size: var(--fs-display); line-height: 0.95; letter-spacing: -0.02em;
}
.h1 { font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 300; line-height: 1.02; }
.h2 { font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 300; line-height: 1.08; }
.h3 { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 400; line-height: 1.2; }
.h4 { font-family: var(--font-ui); font-size: var(--fs-h4); font-weight: 400; letter-spacing: 0.01em; }

.label {
  font-family: var(--font-ui); font-size: var(--fs-label); font-weight: 400;
  text-transform: uppercase; letter-spacing: var(--tracking-label);
  color: var(--accent-text);
}
.label--muted { color: var(--text-dark-soft); }
.section--dark .label--muted, .section--oud .label--muted { color: var(--text-light-soft); }

.lead { font-size: clamp(1.05rem, 1.4vw, 1.3rem); line-height: 1.6; font-weight: 300; }
.muted { color: var(--text-dark-soft); }
.section--dark .muted, .section--oud .muted { color: var(--text-light-soft); }
.measure { max-width: var(--maxw-text); }

/* Placeholder tokens — deliberately visible so nothing ships unfilled. */
.ph {
  font-family: var(--font-ui); font-size: 0.8em; font-weight: 400;
  letter-spacing: 0.04em; color: var(--accent-text);
  border-block-end: 1px dashed currentColor; padding-block-end: 1px;
}

/* Section heading block */
.section-head { display: flex; flex-direction: column; gap: var(--s3); margin-block-end: var(--s7); }
.section-head--row { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: var(--s5); flex-wrap: wrap; }
.section-head .h2 { max-width: 20ch; }

/* --- 5. BUTTONS ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 52px; padding-inline: clamp(20px, 4vw, 48px); padding-block: var(--s3);
  font-family: var(--font-ui); font-size: var(--fs-label); font-weight: 400;
  text-transform: uppercase; letter-spacing: var(--tracking-label);
  border: 1px solid transparent; border-radius: 0; cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
  text-align: center;
}
.btn--primary { background: var(--ivory); color: var(--text-dark); border-color: var(--ivory); }
.btn--primary:hover:not([disabled]) { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--ivory); }

.btn--dark { background: var(--ink); color: var(--ivory); border-color: var(--ink); }
.btn--dark:hover:not([disabled]) { background: var(--accent-fill); border-color: var(--accent-fill); }

.btn--ghost { background: transparent; color: currentColor; border-color: currentColor; opacity: .85; }
.btn--ghost:hover { opacity: 1; background: currentColor; }
.section--dark .btn--ghost:hover, .section--oud .btn--ghost:hover { color: var(--ink); }
.btn--ghost:not(.section--dark .btn--ghost):hover { color: var(--ivory); }

.btn--block { width: 100%; }
/* Inert, and looking it. A sold-out button used to still animate to the
   accent on hover — telling the customer it works, a moment before refusing.
   With single-digit stock this is the shop's most common state. */
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn[disabled]:hover { background: inherit; }

/* Text link with underline reveal */
.link-u {
  display: inline-block; font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-label); padding-block-end: 3px;
  border-block-end: 1px solid currentColor;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.link-u:hover { color: var(--accent-text); }

/* --- 6. HEADER ----------------------------------------------------------- */
.announce {
  background: var(--oud); color: var(--text-light);
  font-size: var(--fs-xs); letter-spacing: var(--tracking-wide);
  text-align: center; position: relative;
}
.announce__inner { padding: 9px var(--s8) 9px var(--s5); }
.announce__close {
  position: absolute; inset-inline-end: 6px; inset-block-start: 50%; translate: 0 -50%;
  width: 34px; height: 34px; display: grid; place-items: center; opacity: .6;
}
.announce__close:hover { opacity: 1; }
.announce[hidden] { display: none; }

.header {
  position: sticky; inset-block-start: 0; z-index: var(--z-header);
  background: var(--ivory); color: var(--text-dark);
  border-block-end: 1px solid var(--rule-dark);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
/* Transparent over a dark hero, solidifies on scroll (JS toggles .is-solid).
   Stays sticky so it still works underneath the announcement bar. */
.header--overlay { background: transparent; color: var(--text-light); border-color: transparent; }
.header--overlay.is-solid { background: var(--ink); border-color: var(--rule-light); }
/* Pull the hero up so it sits *behind* the transparent header. */
main > .hero:first-child { margin-block-start: calc(var(--header-h) * -1); }

.header__inner {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--s5); min-height: var(--header-h);
}
.brand { display: flex; align-items: baseline; gap: var(--s2); }
.brand__mark {
  font-family: var(--font-display); font-size: 1.6rem; font-weight: 400;
  letter-spacing: 0.34em; text-indent: 0.34em; line-height: 1;
}

/* The real ADMA wordmark, painted as a mask so one greyscale file works on both
   dark and light surfaces — it takes its colour from `currentColor`. The <span>
   still contains the word "ADMA": if masking is unsupported the type shows
   instead, so the brand is never invisible. */
@supports ((-webkit-mask-image: url("../img/adma-wordmark.png")) or (mask-image: url("../img/adma-wordmark.png"))) {
  .brand__mark {
    display: block;
    width: 6.5rem; aspect-ratio: 320 / 152;
    text-indent: -9999px; overflow: hidden;
    background-color: currentColor;
    -webkit-mask-image: url("../img/adma-wordmark.png");
            mask-image: url("../img/adma-wordmark.png");
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center;  mask-position: center;
    -webkit-mask-size: contain;     mask-size: contain;
    -webkit-mask-mode: luminance;   mask-mode: luminance;
  }
  /* Baseline alignment no longer applies once the mark is a block image. */
  .brand { align-items: center; }
}
.brand__sub {
  font-size: 0.5625rem; letter-spacing: 0.3em; text-transform: uppercase;
  opacity: .55; display: none;
}
@media (min-width: 900px) { .brand__sub { display: block; } }

.nav { display: none; justify-content: center; }
@media (min-width: 1024px) { .nav { display: flex; } }
.nav__list { display: flex; gap: clamp(18px, 2.2vw, 38px); }
.nav__link {
  font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-label);
  padding-block: var(--s3); position: relative; white-space: nowrap;
}
.nav__link::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-end: 8px; height: 1px;
  background: currentColor; scale: 0 1; transform-origin: left;
  transition: scale var(--dur) var(--ease);
}
.nav__link:hover::after, .nav__link[aria-current="page"]::after { scale: 1 1; }

.header__actions { display: flex; align-items: center; gap: var(--s1); justify-self: end; }
.icon-btn {
  width: 44px; height: 44px; display: grid; place-items: center; position: relative;
  transition: color var(--dur) var(--ease);
}
.icon-btn:hover { color: var(--accent-text); }
.icon-btn svg { width: 19px; height: 19px; }
@media (min-width: 1024px) { .icon-btn--menu { display: none; } }

.cart-count {
  position: absolute; inset-block-start: 6px; inset-inline-end: 5px;
  min-width: 16px; height: 16px; padding-inline: 4px;
  background: var(--accent-fill); color: var(--ivory);
  font-size: 10px; line-height: 16px; text-align: center; font-weight: 500;
}
.cart-count[data-empty="true"] { display: none; }

/* Mobile menu */
.mobile-menu {
  position: fixed; inset: 0; z-index: var(--z-drawer);
  background: var(--ink); color: var(--text-light);
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.mobile-menu.is-open { opacity: 1; visibility: visible; }
.mobile-menu__top { display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); }
.mobile-menu__body { flex: 1; overflow-y: auto; padding-block: var(--s6) var(--s8); }
.mobile-menu__list { display: flex; flex-direction: column; }
.mobile-menu__link {
  font-family: var(--font-display); font-size: clamp(2rem, 9vw, 3rem); font-weight: 300;
  padding-block: var(--s3); border-block-end: 1px solid var(--rule-light);
  display: flex; align-items: center; justify-content: space-between;
}
.mobile-menu__link:hover { color: var(--amber-lift); }
.mobile-menu__foot { padding-block: var(--s6); display: flex; flex-direction: column; gap: var(--s4); }

/* --- 7. HERO ------------------------------------------------------------- */
.hero {
  position: relative; min-height: 100svh; display: flex; align-items: flex-end;
  background: var(--ink); color: var(--text-light); overflow: hidden;
  padding-block-start: calc(var(--header-h) + var(--s7));
}
/* Base atmosphere is pure CSS — it can never distort at any viewport size. */
.hero__bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(78% 62% at 74% 32%, rgba(169,116,63,.20), transparent 62%),
    linear-gradient(158deg, #241C17 0%, #14120F 56%, #0B0A09 100%);
}
/* The flacon is a separate, size-controlled element — never a stretched cover image. */
.hero__flacon {
  position: absolute; inset-block-end: 7%; inset-inline-end: 7%;
  height: clamp(260px, 52vh, 540px); width: auto;
}
@media (max-width: 900px) {
  .hero__flacon { inset-inline-end: 4%; inset-block-end: 46%; height: clamp(190px, 27vh, 280px); opacity: .55; }
}
/* Legibility scrim, painted above the flacon. */
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(15,14,12,.50) 0%, rgba(15,14,12,.10) 38%, rgba(15,14,12,.92) 100%);
}
.hero__inner {
  position: relative; width: 100%; max-width: var(--maxw); margin-inline: auto;
  /* Bottom padding clears the fixed WhatsApp button so CTAs stay tappable. */
  padding-inline: var(--gutter); padding-block-end: 120px;
}
@media (min-width: 900px) { .hero__inner { padding-block-end: clamp(72px, 8vw, 112px); } }
.hero__eyebrow { margin-block-end: var(--s5); color: var(--amber-lift); }
.hero__title { max-width: 15ch; margin-block-end: var(--s5); }
.hero__title em { font-style: italic; color: var(--amber-lift); }
.hero__text { max-width: 46ch; color: var(--text-light-soft); margin-block-end: var(--s7); }
.hero__ctas { display: flex; flex-wrap: wrap; gap: var(--s3); }
.hero__ctas .btn { flex: 1 1 auto; min-width: 190px; }
@media (min-width: 640px) { .hero__ctas .btn { flex: 0 0 auto; } }

.hero__scroll {
  display: none; position: absolute; inset-inline-end: var(--gutter);
  inset-block-end: clamp(48px, 8vw, 112px);
  writing-mode: vertical-rl; font-size: var(--fs-label);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--text-light-soft);
}
@media (min-width: 900px) { .hero__scroll { display: block; } }

/* Page hero (interior pages) */
.page-hero { background: var(--ink); color: var(--text-light); padding-block: clamp(72px, 11vw, 150px) clamp(48px, 7vw, 96px); }
.page-hero__title { max-width: 18ch; margin-block: var(--s4) var(--s4); }
.page-hero__text { max-width: 52ch; color: var(--text-light-soft); }

/* --- 8. TRUST STRIP ------------------------------------------------------ */

/* --- 9. PRODUCT CARD ----------------------------------------------------- */
.product-grid {
  display: grid; gap: var(--s5) var(--s4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 860px)  { .product-grid { grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--s6) var(--s5); } }
@media (min-width: 1180px) { .product-grid { grid-template-columns: repeat(4, minmax(0,1fr)); } }
.product-grid--3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 900px) { .product-grid--3 { grid-template-columns: repeat(3, minmax(0,1fr)); } }

/* Mobile: horizontal rail for featured rows */
.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 68%;
  gap: var(--s4); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-inline: var(--gutter); margin-inline: calc(var(--gutter) * -1);
  padding-block-end: var(--s4);
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; }
@media (min-width: 720px) {
  .rail {
    grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0,1fr));
    overflow: visible; padding-inline: 0; margin-inline: 0; gap: var(--s6) var(--s5);
  }
}
@media (min-width: 1024px) { .rail { grid-template-columns: repeat(4, minmax(0,1fr)); } }

.card { position: relative; display: flex; flex-direction: column; }
.card__media {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  background: var(--bone); display: grid; place-items: center;
}
.section--dark .card__media, .section--oud .card__media { background: var(--ink-3); }
.card__media svg, .card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: scale 600ms var(--ease);
}
.card:hover .card__media svg, .card:hover .card__media img { scale: 1.04; }

.card__flag {
  position: absolute; inset-block-start: var(--s3); inset-inline-start: var(--s3);
  background: var(--ink); color: var(--ivory);
  font-size: 10px; letter-spacing: var(--tracking-label); text-transform: uppercase;
  padding: 5px var(--s3); z-index: 2;
}
.card__flag--out { background: var(--ink); color: var(--ivory); }

/* A sold-out card should read as sold out before anyone gets to the badge.
   The badge alone is a 10px label in one corner of a large dark image — easy to
   scan straight past, which is exactly what happened. Draining the colour out
   of the bottle says "not available" at a glance and at any size, and the badge
   then confirms what the eye already suspected.

   Deliberately not hidden or faded to near-nothing: a sold-out fragrance is
   still part of the house, still worth reading about, and still the page
   somebody lands on when it comes back. It is unavailable, not gone. */
.card--out .card__media {
  filter: grayscale(0.85);
  opacity: 0.62;
  transition: filter var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.card--out:hover .card__media { opacity: 0.78; }
.card--out .card__price { color: var(--text-dark-faint); }

.card__quick {
  position: absolute; inset-inline: var(--s3); inset-block-end: var(--s3); z-index: 2;
  opacity: 0; translate: 0 8px;
  transition: opacity var(--dur) var(--ease), translate var(--dur) var(--ease);
  min-height: 44px; padding-inline: var(--s4);
}
.card:hover .card__quick, .card:focus-within .card__quick { opacity: 1; translate: 0 0; }
@media (hover: none) { .card__quick { opacity: 1; translate: 0 0; } }

.card__body { padding-block-start: var(--s4); display: flex; flex-direction: column; gap: 5px; }
.card__family { font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-dark-soft); }
.section--dark .card__family { color: var(--text-light-soft); }
.card__name { font-family: var(--font-display); font-size: 1.32rem; font-weight: 400; line-height: 1.2; }
.card__name a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.card__meta { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; font-size: var(--fs-sm); }
.card__price { letter-spacing: 0.02em; }
.card__size { color: var(--text-dark-soft); font-size: var(--fs-xs); }
.section--dark .card__size { color: var(--text-light-soft); }

/* --- 10. COLLECTION TILES ------------------------------------------------ */
.collections { display: grid; gap: var(--s2); grid-template-columns: 1fr; }
@media (min-width: 860px) { .collections { grid-template-columns: repeat(3, 1fr); } }
.collection {
  position: relative; min-height: clamp(340px, 46vw, 560px);
  display: flex; align-items: flex-end; overflow: hidden;
  color: var(--text-light); padding: var(--s6);
  background: var(--ink);
}
.collection__art { position: absolute; inset: 0; transition: scale 700ms var(--ease); }
.collection:hover .collection__art { scale: 1.05; }
.collection::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(15,14,12,.15) 40%, rgba(15,14,12,.88) 100%);
}
.collection__body { position: relative; z-index: 1; }
.collection__name { font-family: var(--font-display); font-size: clamp(1.75rem,3vw,2.4rem); font-weight: 300; margin-block: var(--s2) var(--s3); }
.collection__text { font-size: var(--fs-sm); color: var(--text-light-soft); max-width: 34ch; margin-block-end: var(--s4); }

@media (min-width: 860px) {
  /* The three tiles sit side by side and their text is anchored to the bottom
     edge, so a card whose intro runs one line shorter starts one line lower —
     its tagline and year sit below its neighbours' while the Explore links
     still line up. Reserving the height of the longest intro makes all three
     blocks the same height, which lines up both ends.

     The count differs by language because the same paragraph does not wrap the
     same way twice: four lines in English, three in Arabic, measured rather
     than guessed. Only above 860px — below it the tiles stack, there is nothing
     to line up with, and reserved height would just be a gap.

     If this copy is ever edited long enough to add a line, _aligntest.html
     reports it rather than leaving it to be noticed. */
  .collection__text { min-height: 6.6em; min-height: 4lh; }
  [lang="ar"] .collection__text { min-height: 5.6em; min-height: 3lh; }
}

/* --- 11. SPLIT / EDITORIAL ----------------------------------------------- */
.split { display: grid; gap: clamp(32px, 5vw, 80px); align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; } }
.split--reverse .split__media { order: -1; }
@media (min-width: 900px) { .split--reverse .split__media { order: 2; } }
.split__media { position: relative; aspect-ratio: 3/2; background: var(--ink-2); overflow: hidden; }
@media (min-width: 900px) { .split__media { aspect-ratio: 4/5; } }
.split__media > svg, .split__media > img { width: 100%; height: 100%; object-fit: cover; }

/* Marks an image slot that still needs real photography. Delete with the note. */
.media-note {
  position: absolute; inset-block-end: 12px; inset-inline-start: 12px;
  font-family: var(--font-ui); font-size: 0.625rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--amber-lift); border: 1px dashed currentColor;
  padding: 5px 9px; background: rgba(15,14,12,.55);
}

/* --- 12. PILLARS --------------------------------------------------------- */
.pillars { display: grid; gap: 1px; background: var(--rule-light); }
@media (min-width: 700px) { .pillars { grid-template-columns: repeat(2,1fr); } }
@media (min-width: 1100px){ .pillars { grid-template-columns: repeat(4,1fr); } }
/* Three-up variant — the year narratives, which come in threes, not fours. */
@media (min-width: 700px) { .pillars--three { grid-template-columns: repeat(3,1fr); } }
.pillar { background: var(--ink); padding: var(--s6) var(--s5) var(--s7); display: flex; flex-direction: column; gap: var(--s3); }
.pillar__num { font-family: var(--font-display); font-size: 2rem; color: var(--accent-text); line-height: 1; }
.pillar__title { font-family: var(--font-display); font-size: 1.35rem; font-weight: 400; }
.pillar__text { font-size: var(--fs-sm); color: var(--text-light-soft); line-height: 1.6; }

/* --- 13. FRAGRANCE FINDER ------------------------------------------------ */
.quotes { display: grid; gap: var(--s5); }
@media (min-width: 860px) { .quotes { grid-template-columns: repeat(3,1fr); gap: var(--s6); } }
.quote { border-block-start: 1px solid var(--rule-light); padding-block-start: var(--s5); display: flex; flex-direction: column; gap: var(--s4); }
.quote__stars { display: flex; gap: 3px; color: var(--accent-text); }
.quote__stars svg { width: 14px; height: 14px; }
.quote__text { font-family: var(--font-display); font-size: 1.3rem; font-weight: 300; line-height: 1.45; }
.quote__by { font-size: var(--fs-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-light-soft); margin-block-start: auto; }

/* --- 15. NEWSLETTER ------------------------------------------------------ */
.newsletter__form { display: flex; flex-wrap: wrap; gap: var(--s2); max-width: 520px; margin-block-start: var(--s5); }
.newsletter__form .field { flex: 1 1 240px; }
.newsletter__note { font-size: var(--fs-xs); color: var(--text-dark-soft); margin-block-start: var(--s3); }

/* --- 16. FORMS ----------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
  font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--text-dark-soft);
}
.section--dark .field label, .section--oud .field label { color: var(--text-light-soft); }
.input, .textarea, .select {
  width: 100%; min-height: 52px; padding: var(--s3) var(--s4);
  background: transparent; color: inherit;
  border: 1px solid var(--rule-dark); border-radius: 0;
  font-size: var(--fs-body); font-weight: 300;
  transition: border-color var(--dur) var(--ease);
}
.section--dark .input, .section--dark .textarea, .section--dark .select,
.section--oud .input, .section--oud .textarea, .section--oud .select { border-color: var(--rule-light); }
/* Placeholders, set rather than left to the browser. The default resolves to a
   grey that is neither the brand's nor reliably legible — measured at 4.03:1 on
   ivory, under the 4.5:1 that body-sized text needs. This tone reads as a hint
   and still passes. */
.input::placeholder, .textarea::placeholder { color: #6E6558; opacity: 1; }
.section--dark .input::placeholder, .section--oud .input::placeholder,
.section--dark .textarea::placeholder, .section--oud .textarea::placeholder { color: #9A9082; }

.input:hover, .textarea:hover, .select:hover { border-color: var(--text-dark-soft); }
.input:focus, .textarea:focus, .select:focus { border-color: var(--accent-text); outline: none; }
.textarea { min-height: 150px; resize: vertical; padding-block: var(--s4); }
.select {
  appearance: none; padding-inline-end: var(--s7);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2355503F' stroke-width='1.2'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--s4) center; background-size: 11px;
}
.form-grid { display: grid; gap: var(--s4); }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }
.form-note { font-size: var(--fs-xs); color: var(--text-dark-soft); }
.form-status { font-size: var(--fs-sm); padding: var(--s3) var(--s4); border: 1px solid var(--accent-text); margin-block-start: var(--s4); }
.form-status[hidden] { display: none; }

/* The message never relies on colour alone — it always says what is wrong in
   words. The colour is there to be seen before the words are read. */
.form-status--error { border-color: var(--error); color: var(--error); background: var(--error-bg); }
.form-status--ok    { border-color: var(--ok);    color: var(--ok);    background: var(--ok-bg); }
.section--dark .form-status--error, .section--oud .form-status--error { color: var(--error-lift); border-color: var(--error-lift); }
.section--dark .form-status--ok,    .section--oud .form-status--ok    { color: var(--ok-lift);    border-color: var(--ok-lift); }

/* The field itself, so the message and the box that caused it are connected.
   Two pixels rather than one: on a form of identical outlines, a colour change
   alone is easy to miss. */
.input.is-invalid, .textarea.is-invalid, .select.is-invalid,
.input.is-invalid:hover, .textarea.is-invalid:hover, .select.is-invalid:hover,
.input.is-invalid:focus, .textarea.is-invalid:focus, .select.is-invalid:focus {
  border-color: var(--error);
  box-shadow: inset 0 0 0 1px var(--error);
}

/* --- 17. SHOP TOOLBAR + FILTERS ------------------------------------------ */
.empty { text-align: center; padding-block: var(--s9); border: 1px dashed var(--rule-dark); }
.empty .h3 { margin-block: var(--s3); }

/* --- 18. PRODUCT PAGE ---------------------------------------------------- */
.pdp { display: grid; gap: var(--s6); align-items: start; }
@media (min-width: 900px) { .pdp { grid-template-columns: 1.15fr 1fr; gap: clamp(40px, 5vw, 88px); } }

.gallery { display: flex; flex-direction: column-reverse; gap: var(--s3); }
/* Tablet: stop a single-column gallery from becoming a wall of image. */
@media (min-width: 620px) and (max-width: 899px) { .gallery { max-width: 460px; margin-inline: auto; } }
@media (min-width: 900px) { .gallery { flex-direction: row; gap: var(--s3); position: sticky; inset-block-start: calc(var(--header-h) + var(--s4)); } }
.gallery__thumbs { display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none; }
.gallery__thumbs::-webkit-scrollbar { display: none; }
@media (min-width: 900px) { .gallery__thumbs { flex-direction: column; overflow: visible; flex: none; width: 72px; } }
.gallery__thumb {
  width: 64px; height: 80px; flex: none; background: var(--bone);
  border: 1px solid transparent; padding: 0; overflow: hidden;
  transition: border-color var(--dur) var(--ease);
}
@media (min-width: 900px) { .gallery__thumb { width: 72px; height: 90px; } }
.gallery__thumb[aria-current="true"] { border-color: var(--ink); }
.gallery__thumb > * { width: 100%; height: 100%; object-fit: cover; }
.gallery__main { flex: 1; aspect-ratio: 4/5; background: var(--bone); overflow: hidden; }
.gallery__main > * { width: 100%; height: 100%; object-fit: cover; }

.pdp__family { margin-block-end: var(--s3); }
.pdp__title { margin-block-end: var(--s3); }
.pdp__price { font-size: 1.4rem; letter-spacing: 0.02em; margin-block-end: var(--s2); }
.pdp__stock { display: inline-flex; align-items: center; gap: var(--s2); font-size: var(--fs-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-dark-soft); }
.pdp__stock::before { content: ""; width: 6px; height: 6px; background: #4E7A52; }
.pdp__stock[data-stock="out"]::before { background: #9B5B5B; }
/* Running low. Amber rather than the green of "in stock" or the red of "gone",
   because it is neither — the bottle is there, and it might not be tomorrow.
   The dot carries it; the words stay the same size as every other line, since a
   shop that shouts about scarcity stops sounding like this one. */
.pdp__stock[data-stock="low"] { color: var(--amber-deep); }
.pdp__stock[data-stock="low"]::before { background: var(--amber-deep); }
.pdp__desc { margin-block: var(--s5); color: var(--text-dark-soft); }
.pdp__rule { border: 0; border-block-start: 1px solid var(--rule-dark); margin-block: var(--s5); }

.swatches { display: flex; flex-wrap: wrap; gap: var(--s2); }
.swatch {
  min-height: 48px; padding: var(--s2) var(--s5); border: 1px solid var(--rule-dark);
  font-size: var(--fs-sm); letter-spacing: var(--tracking-wide);
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.swatch[aria-pressed="true"] { border-color: var(--ink); background: var(--ink); color: var(--ivory); }

.qty { display: inline-flex; align-items: center; border: 1px solid var(--rule-dark); }
.qty button { width: 48px; height: 52px; display: grid; place-items: center; font-size: 1.1rem; }
.qty button:hover { color: var(--accent-text); }
.qty input { width: 48px; height: 52px; text-align: center; border: 0; background: transparent; font-size: var(--fs-sm); -moz-appearance: textfield; }
.qty input::-webkit-outer-spin-button, .qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.buy-row { display: flex; gap: var(--s3); align-items: stretch; margin-block: var(--s5); }
.buy-row .btn { flex: 1; }

/* Notes pyramid */
.notes { display: grid; gap: var(--s4); }
.note-row { display: grid; grid-template-columns: 92px 1fr; gap: var(--s4); align-items: baseline; padding-block: var(--s3); border-block-start: 1px solid var(--rule-dark); }
.note-row__label { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--accent-text); }
.note-row__value { font-size: var(--fs-sm); line-height: 1.6; }

/* Accordion */
.acc__item { border-block-end: 1px solid var(--rule-dark); }
.acc__btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding-block: var(--s4); text-align: start; min-height: 56px;
  font-size: var(--fs-sm); letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.acc__btn:hover { color: var(--accent-text); }
.acc__icon { position: relative; width: 12px; height: 12px; flex: none; }
.acc__icon::before, .acc__icon::after {
  content: ""; position: absolute; background: currentColor; inset-block-start: 50%; inset-inline-start: 0;
  width: 12px; height: 1px; translate: 0 -50%;
  transition: rotate var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.acc__icon::after { rotate: 90deg; }
.acc__btn[aria-expanded="true"] .acc__icon::after { rotate: 0deg; opacity: 0; }
.acc__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur) var(--ease); }
.acc__panel > div { overflow: hidden; }
.acc__btn[aria-expanded="true"] + .acc__panel { grid-template-rows: 1fr; }
.acc__body { padding-block-end: var(--s5); font-size: var(--fs-sm); color: var(--text-dark-soft); line-height: 1.7; }
.section--dark .acc__item { border-color: var(--rule-light); }
.section--dark .acc__body { color: var(--text-light-soft); }

/* Sticky mobile buy bar */
.buy-bar {
  position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 90;
  background: var(--ivory); border-block-start: 1px solid var(--rule-dark);
  padding: var(--s3) var(--gutter); padding-block-end: calc(var(--s3) + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: var(--s4);
  translate: 0 100%; transition: translate var(--dur) var(--ease);
}
.buy-bar.is-visible { translate: 0 0; }
@media (min-width: 900px) { .buy-bar { display: none; } }
.buy-bar__info { min-width: 0; }
.buy-bar__name { font-family: var(--font-display); font-size: 1.05rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.buy-bar__price { font-size: var(--fs-xs); color: var(--text-dark-soft); }
.buy-bar .btn { margin-inline-start: auto; padding-inline: var(--s5); flex: none; }

/* --- 19. CART DRAWER ----------------------------------------------------- */
.overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay); background: rgba(15,14,12,.55);
  opacity: 0; visibility: hidden; transition: opacity var(--dur) var(--ease), visibility var(--dur);
  backdrop-filter: blur(2px);
}
.overlay.is-open { opacity: 1; visibility: visible; }

.drawer {
  position: fixed; inset-block: 0; inset-inline-end: 0; z-index: var(--z-drawer);
  width: min(440px, 100%); background: var(--ivory);
  display: flex; flex-direction: column;
  /* Hidden by sliding out through the edge it is anchored to. `translate` is
     physical and has no logical equivalent, so the direction lives in a
     variable and is flipped for Arabic — otherwise the drawer slides in from
     the wrong side and sits over the page instead of leaving it. The edge line
     is a border rather than a box-shadow so that it mirrors on its own;
     box-sizing is border-box, so it costs no width. */
  --drawer-hidden: 100%;
  translate: var(--drawer-hidden) 0; transition: translate var(--dur) var(--ease);
  border-inline-start: 1px solid var(--rule-dark);
}
[dir="rtl"] .drawer { --drawer-hidden: -100%; }
.drawer.is-open { translate: 0 0; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; padding: var(--s4) var(--s5); border-block-end: 1px solid var(--rule-dark); min-height: var(--header-h); }
.drawer__title { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.drawer__body { flex: 1; overflow-y: auto; padding: var(--s5); }
.drawer__foot { border-block-start: 1px solid var(--rule-dark); padding: var(--s5); padding-block-end: calc(var(--s5) + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: var(--s4); }
.drawer__totals { display: flex; justify-content: space-between; align-items: baseline; }
.drawer__totals span:last-child { font-size: 1.2rem; }

.line { display: grid; grid-template-columns: 68px 1fr auto; gap: var(--s4); padding-block: var(--s4); border-block-end: 1px solid var(--rule-dark); }
.line:first-child { padding-block-start: 0; }
.line__media { width: 68px; aspect-ratio: 4/5; background: var(--bone); overflow: hidden; }
.line__media > * { width: 100%; height: 100%; object-fit: cover; }
.line__name { font-family: var(--font-display); font-size: 1.1rem; line-height: 1.2; }
.line__meta { font-size: var(--fs-xs); color: var(--text-dark-soft); margin-block-start: 3px; }
.line__qty { display: inline-flex; align-items: center; gap: var(--s3); margin-block-start: var(--s3); font-size: var(--fs-sm); }
.line__qty button { width: 30px; height: 30px; border: 1px solid var(--rule-dark); display: grid; place-items: center; }
.line__qty button:hover { border-color: var(--ink); }
.line__price { font-size: var(--fs-sm); text-align: end; }
.line__remove { font-size: var(--fs-xs); color: var(--text-dark-soft); text-decoration: underline; margin-block-start: auto; }
.line__remove:hover { color: var(--wine); }

/* --- 20. FOOTER ---------------------------------------------------------- */
.footer { background: var(--ink); color: var(--text-light); padding-block: clamp(56px, 7vw, 96px) var(--s6); }
.footer__grid { display: grid; gap: var(--s7); }
@media (min-width: 780px)  { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1080px) { .footer__grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; } }
.footer__brand .brand__mark { font-size: 1.8rem; }
@supports ((-webkit-mask-image: url("../img/adma-wordmark.png")) or (mask-image: url("../img/adma-wordmark.png"))) {
  .footer__brand .brand__mark { width: 7.5rem; }
}
.footer__blurb { font-size: var(--fs-sm); color: var(--text-light-soft); max-width: 34ch; margin-block-start: var(--s4); }
.footer__title { font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--text-light-soft); margin-block-end: var(--s4); }
.footer__list { display: flex; flex-direction: column; gap: var(--s1); }
.footer__list a { font-size: var(--fs-sm); padding-block: 7px; display: inline-block; transition: color var(--dur) var(--ease); }
.footer__list a:hover { color: var(--accent-text); }
.socials { display: flex; gap: var(--s2); margin-block-start: var(--s5); }
.socials a { width: 42px; height: 42px; border: 1px solid var(--rule-light); display: grid; place-items: center; transition: all var(--dur) var(--ease); }
.socials a:hover { border-color: var(--accent-text); color: var(--accent-text); }
.socials svg { width: 17px; height: 17px; }
.footer__bottom {
  margin-block-start: var(--s8); padding-block-start: var(--s5);
  border-block-start: 1px solid var(--rule-light);
  display: flex; flex-wrap: wrap; gap: var(--s4); justify-content: space-between;
  font-size: var(--fs-xs); color: var(--text-light-soft);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--s5); }

/* The line that hands the customer their own year. Set apart from the scent
   description because it is not about the scent — it is the one place the
   brand's architecture is offered to the reader rather than explained at them. */
.pdp__yours {
  margin-block-start: var(--s3);
  padding-inline-start: var(--s3);
  border-inline-start: 1px solid var(--amber);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--text-dark-soft);
  max-width: 46ch;
}

/* --------------------------------------------------------------- THE SHOP
   Three chapters stacked, each headed by its year at a size that finally
   matches what the year means to this house. Replaced a filter sidebar and
   toolbar that existed to narrow six products. */
.shop-all { margin-block-end: var(--s5); }
.shop-year + .shop-year { margin-block-start: var(--s8); }
.shop-year__head {
  display: grid; gap: var(--s2);
  margin-block-end: var(--s5);
  padding-block-end: var(--s4);
  border-block-end: 1px solid var(--rule-dark);
}
.shop-year__num {
  font-family: var(--font-display); font-weight: 300;
  font-size: clamp(3.5rem, 9vw, 6.5rem); line-height: .88;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--year-accent, var(--amber));
  margin: 0;
}
.shop-year__tag {
  font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--text-dark-soft);
}
.shop-year__intro { font-size: var(--fs-sm); line-height: 1.7; color: var(--text-dark-soft); max-width: 60ch; }
[lang="ar"] .shop-year__tag { text-transform: none; letter-spacing: 0; }

/* --------------------------------------------------------- THE THREE YEARS
   Replaces the fragrance finder. Three columns, one per chapter, each carrying
   its own accent — the only place on the site where the per-year colours in
   data.js are actually used at strength rather than buried in a gradient.

   Hairline gaps rather than borders, matching the pillars and the footer: one
   background showing through 1px gaps is how every grid on this site is built. */
.compare__grid {
  display: grid; gap: 1px; background: var(--rule-dark);
  grid-template-columns: 1fr;
}
@media (min-width: 800px) { .compare__grid { grid-template-columns: repeat(3, 1fr); } }

.compare__col {
  display: flex; flex-direction: column; gap: var(--s3);
  background: var(--ivory); padding: var(--s6) var(--s5);
  text-decoration: none; color: inherit;
  border-block-start: 2px solid var(--year-accent, var(--amber));
  transition: background var(--dur) var(--ease);
}
.compare__col:hover { background: var(--bone); }

.compare__year {
  font-family: var(--font-display); font-weight: 300;
  font-size: clamp(3.5rem, 7vw, 5rem); line-height: .9;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--year-accent, var(--amber));
}
.compare__tag {
  font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--text-dark-soft);
}
.compare__intro { font-size: var(--fs-sm); line-height: 1.65; color: var(--text-dark-soft); }

/* The facts, price and link sit as one block on the bottom edge, so they line
   up across all three columns however long each chapter's intro runs. Anchoring
   the whole group beats reserving a height for the prose: the intros are
   different lengths in both languages and always will be. */
.compare__facts {
  display: flex; flex-direction: column; gap: var(--s2);
  margin-block-start: auto;
  padding-block-start: var(--s4); border-block-start: 1px solid var(--rule-dark);
}
.compare__fact { display: flex; justify-content: space-between; gap: var(--s3); font-size: var(--fs-sm); }
.compare__fact b {
  font-weight: 400; font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--text-dark-faint);
}
.compare__price { font-family: var(--font-display); font-size: 1.35rem; }
.compare__go { align-self: flex-start; font-size: var(--fs-label);
               text-transform: uppercase; letter-spacing: var(--tracking-label); }

[lang="ar"] .compare__tag,
[lang="ar"] .compare__fact b,
[lang="ar"] .compare__go { text-transform: none; letter-spacing: 0; }

/* The add-to-bag confirmation. The button holds its own size while the word
   changes, so the layout does not jump; the amber is the same accent used for
   every other "this worked" moment on the site. */
.btn.is-added {
  background: var(--amber);
  border-color: var(--amber);
  color: var(--ink);
}
.btn.is-added:hover { background: var(--amber); border-color: var(--amber); }

/* ------------------------------------------------------------------ THE YEAR
   ADMA's whole identity is three numbers, and until now the site never let a
   number be larger than a heading. Set enormous behind the product, cropped by
   its own container, at an opacity that reads as watermark rather than content
   — it should be felt before it is read. Not a decoration: it is the one mark
   that is identical in English and Arabic, because digits do not translate. */
.year-mark {
  position: absolute; inset-block-start: -0.16em; inset-inline-start: -0.22em;
  font-family: var(--font-display);
  font-size: clamp(9rem, 26vw, 22rem);
  line-height: 0.78;
  font-weight: 300;
  font-variant-numeric: lining-nums tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  opacity: 0.045;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.section--dark .year-mark, .hero .year-mark { color: var(--ivory); opacity: 0.05; }
/* Everything the mark sits behind has to out-rank it. */
.has-year-mark { position: relative; }
.has-year-mark > *:not(.year-mark) { position: relative; z-index: 1; }

/* ------------------------------------------------------------------ ARABIC
   Latin display type is set very tight here — 0.95 on the hero — because
   Cormorant Garamond's capitals leave room above and below at that size.
   Arabic does not work that way: the script stacks marks above the letters and
   drops tails below them, so the same line-height collides one line into the
   next. These are the same headings with enough room to sit in, applied only
   where the page is Arabic so nothing about the English site moves.

   Arabic also has no capitals, which makes the uppercase-and-track treatment
   used on labels meaningless: letter-spacing pulls the joined letterforms
   apart into something close to unreadable. Both are switched off. */
[lang="ar"] .display { line-height: 1.35; letter-spacing: 0; }
[lang="ar"] .h1 { line-height: 1.4; }
[lang="ar"] .h2 { line-height: 1.45; }
[lang="ar"] .h3,
[lang="ar"] .card__name { line-height: 1.5; }
[lang="ar"] .lead,
[lang="ar"] body { line-height: 1.85; }

/* Arabic has no italic. Asking for one gets a synthetic slant: the browser
   shears the glyphs, which breaks the joins between letters and pushes the
   punctuation after it out of place. The emphasis is carried by the colour
   alone, which was doing most of the work in English anyway. */
[lang="ar"] .hero__title em,
[lang="ar"] em { font-style: normal; }

/* The language switch is a word, not an icon, so it needs a readable size in
   a slot built for 20px glyphs. Kept to the icon row's width rules so the
   header spacing does not shift when it appears. */
.lang-switch {
  font-family: var(--font-ui); font-size: var(--fs-label);
  letter-spacing: 0.02em; width: auto; padding-inline: var(--s2);
  text-decoration: none;
}
.lang-switch:hover { color: var(--accent-text); }
[lang="ar"] .lang-switch { font-family: var(--font-ui); letter-spacing: 0; }

/* Phone numbers read left to right in any language — "+974 7079 3333" is one
   token, not a sentence. Inside a right-to-left line the bidi algorithm treats
   the plus sign and the digit groups as separate runs and reorders them, so
   the number came out backwards: "3333 7079 974+". Isolating the element pins
   its internal direction without moving it from where the layout put it. */
[dir="rtl"] [data-c="phoneDisplay"],
[dir="rtl"] a[href^="tel:"] {
  direction: ltr;
  unicode-bidi: isolate;
}

[lang="ar"] .label,
[lang="ar"] .btn,
[lang="ar"] .nav__link,
[lang="ar"] .footer__title,
[lang="ar"] .drawer__title {
  text-transform: none;
  letter-spacing: 0;
}

/* The commercial registration number. Set in lining figures so the digits line
   up, and spaced a little, because it is a reference someone may read aloud or
   copy down rather than prose to skim past. */
.footer__cr {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* --- 21. WHATSAPP FAB ---------------------------------------------------- */
.wa-fab {
  position: fixed; inset-block-end: var(--s5); inset-inline-end: var(--s5); z-index: 80;
  width: 52px; height: 52px; display: grid; place-items: center;
  background: var(--oud); color: var(--ivory);
  border: 1px solid var(--rule-light);
  transition: background-color var(--dur) var(--ease), scale var(--dur) var(--ease);
}
.wa-fab:hover { background: var(--accent-fill); scale: 1.05; }
.wa-fab svg { width: 24px; height: 24px; }
body.has-buy-bar .wa-fab { inset-block-end: calc(var(--s5) + 76px); }
body.has-buy-bar { padding-block-end: 76px; }
@media (min-width: 900px) {
  body.has-buy-bar .wa-fab { inset-block-end: var(--s5); }
  body.has-buy-bar { padding-block-end: 0; }
}

/* --- 22. REVEAL ON SCROLL ------------------------------------------------ */
.reveal { opacity: 0; translate: 0 18px; transition: opacity 700ms var(--ease), translate 700ms var(--ease); }
.reveal.is-in { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; translate: 0 0; } }

/* --- 23. BREADCRUMB + MISC ----------------------------------------------- */
.crumbs { display: flex; flex-wrap: wrap; gap: var(--s2); font-size: var(--fs-xs); color: var(--text-dark-soft); padding-block: var(--s4); }
.crumbs a:hover { color: var(--accent-text); }
.crumbs span { opacity: .5; }
.prose p + p { margin-block-start: var(--s4); }
.prose h3 { margin-block: var(--s6) var(--s3); }
/* ============================================================ CHECKOUT PAGE */
.checkout { display: grid; gap: var(--s6); align-items: start; }

/* On one column the summary comes FIRST. Source order puts the form before it,
   which is right on a desktop where both are visible at once — but on a phone it
   put the total, the delivery fee and the items below the Place order button, so
   the last thing before paying was the button and the numbers were a scroll
   away. What you are about to pay belongs above the button that pays it. */
@media (max-width: 899px) {
  .checkout__summary { order: -1; }
}
@media (min-width: 900px) {
  .checkout { grid-template-columns: 1fr 22rem; gap: var(--s7); }
  /* The summary follows you down the form, so the total is never out of sight. */
  .checkout__summary { position: sticky; inset-block-start: var(--s6); }

  /* The summary is a bordered card and carries padding; the form is not and
     does not. Left alone, the two column headings — "Delivery" and "Your
     order" — sit 25px apart at the top of the page, which is the first thing
     the eye checks and the first thing it finds wrong. Matching the card's
     padding here puts them on the same line. Inside the media query only: in
     one column there is no second heading to align to, and the space would be
     a gap for nothing. */
  .checkout__form { padding-block-start: var(--s5); }
}
.checkout__summary {
  background: var(--bone);
  padding: var(--s5);
  border: 1px solid var(--rule-dark);
}
.checkout__summary .label { margin-block-end: var(--s4); }

.co-line {
  display: grid; grid-template-columns: 1fr auto; gap: 2px var(--s3);
  padding-block: var(--s3);
  border-block-start: 1px solid var(--rule-dark);
  font-size: var(--fs-sm);
}
.co-line:first-of-type { border-block-start: 0; padding-block-start: 0; }
.co-line__name { font-weight: 400; }
.co-line__meta { grid-column: 1; color: var(--text-dark-soft); font-size: 0.8125rem; }
.co-line__price { grid-row: 1; grid-column: 2; font-variant-numeric: tabular-nums; }

.totals {
  margin: 0; padding-block-start: var(--s4);
  border-block-start: 1px solid var(--rule-dark);
  display: grid; grid-template-columns: 1fr auto; gap: var(--s2) var(--s3);
  font-size: var(--fs-sm);
}
.totals dt { color: var(--text-dark-soft); }
.totals dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; }
.totals .is-total { font-size: 1.0625rem; padding-block-start: var(--s2); }
.totals .is-total dt, .totals dt.is-total { color: var(--text-dark); }

/* Payment options. Sharp edges and hairlines, like everything else. */
.pay { display: flex; flex-direction: column; gap: var(--s2); }
.pay__opt {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s3) var(--s4);
  border: 1px solid var(--rule-dark);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease);
}
.pay__opt:hover { border-color: var(--accent-text); }
.pay__opt input { margin-block-start: 4px; accent-color: var(--accent-text); }
.pay__opt strong { display: block; font-weight: 400; }
.pay__opt em {
  display: block; font-style: normal; font-size: var(--fs-sm);
  color: var(--text-dark-soft); margin-block-start: 2px;
}
.pay__opt.is-disabled { opacity: 0.5; cursor: not-allowed; }
.pay__opt.is-disabled:hover { border-color: var(--rule-dark); }

.field__hint { font-size: 0.8125rem; color: var(--text-dark-soft); margin-block-start: 6px; }
/* The reason, under the field it belongs to. Same size as the hint it sits
   beside — it needs to be noticed, not shouted. */
.field__error { font-size: 0.8125rem; color: var(--error); margin-block-start: 6px; font-weight: 400; }

/* The order number on the thank-you page. Boxed and monospaced because it gets
   read down a phone and copied into a message — the alphabet already avoids
   I, L, O and U so nothing can be misheard. */
/* A short message that appears near the bag and goes on its own. Not a dialog:
   nothing here is important enough to stop what the customer is doing, it just
   explains why a number would not go any higher. */
.toast {
  /* Centred with auto margins rather than the usual half-its-own-width nudge.
     That nudge is a physical translate, and paired with a logical inset it
     lands the toast off to one side in Arabic. This way the only movement
     left is vertical, which reads the same in either direction. */
  position: fixed; inset-block-end: 24px; inset-inline: 0;
  margin-inline: auto; width: fit-content;
  transform: translateY(12px);
  z-index: 400; max-width: min(92vw, 420px);
  background: var(--ink); color: var(--text-light);
  padding: var(--s3) var(--s5); font-size: var(--fs-sm); line-height: 1.5;
  text-align: center; opacity: 0; pointer-events: none;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}
.toast.is-in { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .toast { transition: opacity 200ms var(--ease); } }

/* Where a card payment reports itself while it is still being confirmed.
   Amber while waiting, because it is neither good news nor bad yet. */
.pay-state { margin-block-start: var(--s5); padding: var(--s4) var(--s5);
             border: 1px solid var(--amber-deep); color: var(--amber-deep);
             max-width: 46ch; margin-inline: auto; font-size: var(--fs-sm); }
.pay-state[hidden] { display: none; }
.pay-state[data-state="paid"]   { border-color: var(--ok);    color: var(--ok); }
.pay-state[data-state="failed"] { border-color: var(--error); color: var(--error); }
.pay-state[data-state="slow"]   { border-color: var(--rule-dark); color: var(--text-dark-soft); }
.pay-state p { margin: 0; }

.thanks__order { display: inline-block; border: 1px solid var(--rule-dark);
                 padding: var(--s4) var(--s6); margin-block-start: var(--s6); }
.thanks__number { font-family: ui-monospace, Menlo, monospace; font-size: 1.15rem;
                  letter-spacing: 0.08em; margin: 0; user-select: all; }
.field__error::before { content: "\2715"; margin-inline-end: 6px; font-size: 0.9em; }
/* Quieter than the label it sits beside, so a scan down the form reads the
   field names and only notices "optional" on the one that is. */
.field__optional { color: var(--text-dark-soft); text-transform: none; letter-spacing: 0; }

/* Dialling code beside the number. The code is sized to its content so the
   number — the part being typed — keeps the room. They read as one field
   because they are one answer. */
.phone { display: flex; gap: var(--s2); }
/* Capped, or the select grows to its widest option and squeezes the number —
   which is the part being typed and the part that must stay readable. */
.phone__code { flex: 0 1 auto; width: auto; min-width: 6.5rem; max-width: 10.5rem; }
.phone__number { flex: 1 1 9ch; min-width: 0; }
@media (max-width: 420px) {
  /* Narrow enough that the country name truncates behind the code. That is the
     right thing to lose: the code is the answer, and the country was chosen
     from the dropdown a moment ago. */
  .phone__code { min-width: 0; flex: 0 1 8.5rem; }
}

.prose ul { display: flex; flex-direction: column; gap: var(--s2); margin-block-start: var(--s3); }
/* `p + p` does not cover a paragraph that follows a list, which left the closing
   line of the craft section sitting flush against the last bullet. */
.prose ul + p { margin-block-start: var(--s4); }
.prose li { padding-inline-start: var(--s4); position: relative; font-size: var(--fs-sm); }
.prose li::before { content: ""; position: absolute; inset-inline-start: 0; inset-block-start: 0.65em; width: 5px; height: 1px; background: var(--accent-text); }

body.no-scroll { overflow: hidden; }
