/* ==========================================================================
   SEZAR Gallery — Storefront
   --------------------------------------------------------------------------
   Values here are transcribed from the approved component bundle
   (reference/claude-design/_ds_bundle.js), not estimated from a screenshot.
   Where the bundle uses a literal — 62px logo, 34px heart, 14px card body
   padding — that literal is reproduced exactly and noted with its source
   component. Everything else is a token var().

   There are NO literal colour values in this file. A hex code appearing here
   is a drift from the approved palette and is findable with a grep.

   RTL-first: Arabic is the default storefront language, so logical properties
   are used throughout and English mirrors without a second stylesheet.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}
html[lang="ar"] body { font-family: var(--font-arabic); line-height: 1.7; }

img { max-width: 100%; display: block; }
a { color: var(--text-primary); text-decoration: none; }
a:hover { color: var(--text-link); }
button { font-family: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: 0;
}
html[lang="ar"] h1, html[lang="ar"] h2,
html[lang="ar"] h3, html[lang="ar"] h4 {
  font-family: var(--font-arabic); font-weight: var(--weight-medium);
}

:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-xs); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: absolute; inset-inline-start: var(--space-4); top: -100px;
  background: var(--surface-inverse); color: var(--text-on-inverse);
  padding: var(--space-3) var(--space-5); border-radius: var(--radius-sm);
  z-index: 100; transition: top var(--duration-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

/* Approved keyframes, from the prototype's inline <style>. */
@keyframes szFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes szDrop { from { opacity: 0; transform: translateY(-8px) } to { opacity: 1; transform: none } }
@keyframes szInR  { from { transform: translateX(100%) }  to { transform: none } }
@keyframes szInL  { from { transform: translateX(-100%) } to { transform: none } }
@keyframes szPop  { 0% { transform: scale(1) } 45% { transform: scale(1.28) } 100% { transform: scale(1) } }

/* ------------------------------------------------------------- LAYOUT -- */

.container { max-width: var(--container-max); margin-inline: auto; padding-inline: var(--container-pad); }
@media (min-width: 1024px) { .container { padding-inline: var(--container-pad-lg); } }

/* THEME HOOKS (Gate H5).
   Every one of these takes the approved value as its fallback, so a shop that
   has never opened the theme screen — or one whose theme failed its own
   contrast guard and emitted nothing — renders exactly what was signed off.

   PATCHED IN PLACE RATHER THAN APPENDED. The first version added a second
   `.section` rule at the end of the file, which sits after the desktop media
   query and therefore beat it: the responsive spacing step silently vanished at
   768px. A theme hook must not change the cascade it is hooking into.

   NOTHING HERE IS A LAYOUT PROPERTY. No width, no column count, no breakpoint,
   no position takes a theme value — which is what stops a theme setting from
   breaking the responsive design (§4). */
.section { padding-block: var(--section-space, var(--space-16)); }
/* The desktop step is a multiple of whichever preset is set, so the approved
   64px → 80px relationship holds for compact and generous too. */
@media (min-width: 768px) { .section { padding-block: calc(var(--section-space, var(--space-16)) * 1.25); } }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-8); flex-wrap: wrap;
  /* INERT BY DEFAULT, and it has to be exactly inert. A `1px solid
     transparent` border still occupies a pixel of layout and a fixed
     padding-block-end still adds twelve, so the first version moved every
     section head on the approved page by thirteen pixels while appearing to
     change nothing. Width and padding are both variables defaulting to zero,
     so the approved design is byte-identical until somebody turns the divider
     on. */
  border-block-end: var(--divider-width, 0) solid var(--divider-colour, transparent);
  padding-block-end: var(--divider-space, 0);
}
.section-title { font-size: var(--text-xl); color: var(--section-title-colour, var(--text-primary)); }
@media (min-width: 768px) { .section-title { font-size: var(--text-2xl); } }

.eyebrow {
  font-family: var(--font-body); font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: var(--eyebrow-transform, uppercase);
  color: var(--text-secondary); margin: 0 0 var(--space-2);
}

/* ------------------------------------------------- ANNOUNCEMENT BAR -- */
/* Header.jsx: padding 8px 32px, text-xs, text-secondary, 1px border-bottom. */

.announcement-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding: 8px 32px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-subtle);
  overflow: hidden;
  transition: max-height var(--duration-base) var(--ease-standard),
              opacity var(--duration-fast) var(--ease-standard),
              padding var(--duration-base) var(--ease-standard);
  max-height: 60px;
}
@media (max-width: 767px) { .announcement-bar { padding: 8px var(--space-4); } }

/* Fixed height and no wrapping. Messages differ in length, and letting a
   longer one wrap to a second line changed the bar height mid-rotation, which
   shifted the entire page under the reader — the exact layout shift the brief
   rules out, and enough to make a submit button un-clickable. */
.announcement-message {
  display: block;
  line-height: 1.4;
  height: 1.4em;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 auto;
}
.announcement-message > span { display: block; }
/* Rotation is opacity-only so the bar never changes height mid-cycle. */
.announcement-message > span {
  animation: szFade var(--duration-slow) var(--ease-out);
}

/* -------------------------------------------------------------- HEADER -- */
/* Header.jsx: main bar padding 14px 32px, gap 24, space-between. */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--surface-page);
  border-bottom: 1px solid var(--border-subtle);
}

.header-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
  padding: 14px 32px;
  transition: padding var(--duration-base) var(--ease-standard);
}
@media (max-width: 767px) { .header-bar { padding: 10px var(--space-4); gap: var(--space-3); } }

.brand { display: flex; align-items: center; flex: 0 0 auto; }
.brand img {
  height: 62px; width: auto;                      /* Header.jsx: height 62 */
  transition: height var(--duration-base) var(--ease-standard);
}
@media (max-width: 899px) { .brand img { height: 44px; } }

/* Compact-on-scroll. Collapses the announcement bar and tightens the header
   rather than hiding it, so the shopper never loses the cart or search. */
.site-header.is-compact .announcement-bar {
  max-height: 0; padding-block: 0; opacity: 0; border-bottom-color: transparent;
}
.site-header.is-compact .header-bar { padding-block: 8px; }
.site-header.is-compact .brand img { height: 44px; }
@media (max-width: 899px) { .site-header.is-compact .brand img { height: 36px; } }

/* Nav — Header.jsx: gap 28, text-sm, weight 500, nowrap. */
.main-nav { display: none; align-items: center; gap: 28px; }
@media (min-width: 900px) { .main-nav { display: flex; } }

.main-nav a {
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-primary); white-space: nowrap;
  padding-block: 4px; border-bottom: 1.5px solid transparent;
  transition: color var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}
.main-nav a:hover, .main-nav a[aria-current="page"] {
  color: var(--text-link); border-bottom-color: var(--border-strong);
}

/* Icon cluster — Header.jsx: gap 18; IconBtn 20x20 stroke 1.7. */
.header-actions { display: flex; align-items: center; gap: 18px; }
@media (max-width: 767px) { .header-actions { gap: var(--space-4); } }

.icon-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--text-primary);
  transition: color var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-spring);
}
.icon-btn:hover { color: var(--text-link); }
.icon-btn:active { transform: scale(0.92); }

/* Count badge — IconBtn: top -8, right -10, 16x16, gold, 10px/700. */
.icon-badge {
  position: absolute; top: -8px; inset-inline-end: -10px;
  background: var(--accent-gold); color: var(--text-on-gold);
  font-size: 10px; font-weight: 700; font-family: var(--font-body);
  border-radius: var(--radius-circle);
  width: 16px; height: 16px;
  display: flex; align-items: center; justify-content: center;
  animation: szPop var(--duration-base) var(--ease-spring);
}

/* Language switch — LangSwitch.jsx: pill pair, 6px 12px, text-xs/600. */
.lang-switch { display: inline-flex; align-items: center; gap: 2px; }
.lang-switch button {
  display: inline-flex; align-items: center; gap: 5px;
  border: none; cursor: pointer;
  padding: 6px 12px; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-secondary);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard);
}
.lang-switch button[aria-pressed="true"] { background: var(--accent-gold); color: var(--text-on-gold); }
.lang-switch button[lang="ar"] { font-family: var(--font-arabic); }
.lang-switch button[lang="en"] { font-family: var(--font-body); }

/* Mobile menu toggle */
.menu-toggle { display: inline-flex; }
@media (min-width: 900px) { .menu-toggle { display: none; } }

/* A class-level `display` beats the user-agent rule for [hidden], so the
   attribute alone would not hide this. Without the line below the menu covers
   the whole page at every breakpoint. */
.mobile-menu[hidden] { display: none; }

.mobile-menu {
  position: fixed; inset: 0; z-index: 80;
  background: var(--surface-page);
  padding: var(--space-6) var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
  animation: szInL var(--duration-base) var(--ease-out);
  overflow-y: auto;
}
html[dir="rtl"] .mobile-menu { animation-name: szInR; }
.mobile-menu a {
  font-size: var(--text-md); padding: var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--border-subtle);
}

/* ------------------------------------------------------ MOBILE BOTTOM NAV -- */
/* MobileNav.jsx: space-around, surface-card, 1px top border, 10px 0 14px. */

.mobile-nav { display: none; }
@media (max-width: 899px) {
  .mobile-nav {
    display: flex; justify-content: space-around;
    position: sticky; bottom: 0; z-index: 40;
    background: var(--surface-card);
    border-top: 1px solid var(--border-subtle);
    padding: 10px 0 14px;
    font-family: var(--font-body);
  }
  body { padding-bottom: 0; }
}
.mobile-nav a {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  min-width: 44px;                                  /* MobileNav.jsx: minWidth 44 */
  color: var(--text-secondary);
  transition: color var(--duration-fast) var(--ease-standard);
}
.mobile-nav a[aria-current="page"] { color: var(--accent-gold-hover); }
.mobile-nav span { font-size: 10px; font-weight: var(--weight-medium); }
.mobile-nav .icon-badge { top: -4px; inset-inline-end: 2px; }

/* --------------------------------------------------------------- HERO -- */

.hero { position: relative; background: var(--surface-page-alt); overflow: hidden; }
.hero-grid { display: grid; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 1fr 1fr; } }

.hero-copy {
  padding: var(--space-12) var(--container-pad);
  display: flex; flex-direction: column; justify-content: center; gap: var(--space-5);
}
@media (min-width: 900px) { .hero-copy { padding: var(--space-24) var(--container-pad-lg); } }

.hero-title { font-size: var(--text-2xl); }
@media (min-width: 768px)  { .hero-title { font-size: var(--text-3xl); } }
@media (min-width: 1200px) { .hero-title { font-size: var(--text-4xl); } }

.hero-lede { color: var(--text-secondary); font-size: var(--text-base); max-width: 46ch; margin: 0; }
.hero-media { min-height: 320px; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 900px) { .hero-media { min-height: 560px; } }

/* ------------------------------------------------------------ BUTTONS -- */
/* Button.jsx: pill, weight 600, tracking-wide, uppercase; md = 12px 26px. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--font-body); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  border-radius: var(--radius-button, var(--radius-pill));
  padding: 12px 26px; font-size: var(--text-sm);
  border: 1px solid transparent; cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-standard), color var(--duration-base) var(--ease-standard), border-color var(--duration-base) var(--ease-standard), transform var(--duration-base) var(--ease-standard), box-shadow var(--duration-base) var(--ease-standard);
}
.btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn-sm { padding: 8px 18px; font-size: var(--text-xs); }
.btn-lg { padding: 16px 34px; font-size: var(--text-base); }

.btn-primary { background: var(--accent-gold); color: var(--text-on-gold); border-color: var(--accent-gold); }
.btn-primary:hover:not(:disabled) { background: var(--accent-gold-hover); }
.btn-dark { background: var(--surface-inverse); color: var(--text-on-inverse); border-color: var(--surface-inverse); }
.btn-dark:hover:not(:disabled) { background: var(--color-espresso-700); }
.btn-outline { background: transparent; color: var(--text-primary); border-color: var(--border-subtle); }
.btn-outline:hover:not(:disabled) { background: var(--surface-page-alt); }
.btn-ghost { background: transparent; color: var(--text-primary); }

.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
.btn-block { width: 100%; }

/* ------------------------------------------------------- PRODUCT CARD -- */
/* ProductCard.jsx, transcribed. */

/* Explicit column counts, not auto-fill. auto-fill lays out as many tracks as
   fit and leaves the surplus empty, so a three-item band at 1440px bunched
   into half the width with dead space beside it. */
.product-grid {
  display: grid; gap: var(--space-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px)  { .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); } }
@media (min-width: 1200px) { .product-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Bands that hold only one or two items must not leave empty columns. */
/* Short bands must not leave a row of empty tracks. */
@media (min-width: 768px) {
  .product-grid[data-count="1"] { grid-template-columns: minmax(0, 340px); }
  .product-grid[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 720px; }
  .product-grid[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Product carousel (Gate H3).
   The only component the Content Studio adds, and it is deliberately the
   smallest possible one: a scroll-snapping row of the same product cards the
   grid uses. No JavaScript, no arrows, no autoplay — an auto-advancing carousel
   is an accessibility problem and a layout-shift source, and §2 asks for the
   approved performance to be preserved.
   Every value below is an existing token. Nothing here introduces a colour, a
   typeface or a spacing step that was not already in the frozen set. */
.product-scroller {
  display: flex; gap: var(--space-5);
  overflow-x: auto; overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  /* Bleeds to the viewport edge, then restores the container gutter at both
     ends so the first and last cards line up with everything else. */
  padding-inline: var(--container-pad); padding-block-end: var(--space-3);
  scrollbar-width: thin;
}
.product-scroller-item { flex: 0 0 68%; scroll-snap-align: start; }
@media (min-width: 768px)  { .product-scroller-item { flex-basis: 30%; } }
@media (min-width: 1200px) { .product-scroller-item { flex-basis: 22%; } }
/* Above the container width the row stops bleeding and aligns with the grid. */
@media (min-width: 1360px) {
  .product-scroller { max-width: var(--container-max); margin-inline: auto; }
}

.product-card {
  position: relative;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);                  /* 14px, not 22px */
  overflow: hidden;
  /* --shadow-xs is the approved value and stays the fallback; the theme's
     "soft shadow on cards" toggle is the only thing that changes it. */
  box-shadow: var(--shadow-card, var(--shadow-xs));
  display: flex; flex-direction: column;
  transition: box-shadow var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-standard);
}
.product-card:hover, .product-card:focus-within {
  box-shadow: var(--shadow-md);
  transform: translateY(-4px);                      /* ProductCard.jsx: -4 */
}

/* BUG-089. THE CARD FRAME IS A FRAME, NOT A CROP. `object-fit: cover` filled
   the square by enlarging the photograph until its short edge matched and
   throwing away everything past the long one — so a tall vase lost its rim and
   its base, and a wide runner lost both ends. The grid keeps its square cells,
   because a listing page of mismatched heights reads as broken; what changes is
   that the product is now fitted INSIDE the cell and centred, with the cell's
   own sand tone behind it as breathing room, rather than the cell being packed
   with the middle of the product. Aspect ratio is never altered — `contain`
   cannot distort, only letterbox. */
.product-card-media {
  position: relative; aspect-ratio: 1 / 1;
  background: var(--surface-page-alt); overflow: hidden;
}
/* THE PHOTOGRAPH FILLS THE CELL. `contain` with padding was the first answer
   to BUG-089 and it overcorrected: it stopped the crop and left every card a
   small picture floating in a cream box, which on a grid of twenty-four reads
   as a page that failed to load.

   `cover` on a square cell whose photographs are mostly 4:5 trims a little top
   and bottom and nothing else — and it cannot distort, it can only crop. The
   destructive version of this was the PRODUCT PAGE forcing 1:1 on the master;
   that stays fixed, and the gallery below still adapts to the real shape.
   `object-position: center` is stated rather than left to the default so a
   focal-point value can be set per image later without moving this rule. */
.product-card-media img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  transition: transform var(--duration-slow) var(--ease-standard);
}
.product-card:hover .product-card-media img { transform: scale(1.05); }
.product-card.is-soldout .product-card-media img { filter: grayscale(0.5) opacity(0.7); }

/* BUG-088. A range is two figures and a dash and must stay on one line at card
   width, so it steps down a little rather than wrapping mid-price. */
.price-range .price { white-space: nowrap; font-size: var(--text-sm); }
.price-range-dash { opacity: 0.7; }

/* Chip.jsx: 10px/700, .06em, uppercase, 4px 9px, pill; positioned top 10 left 10. */
.chip {
  display: inline-block; padding: 4px 9px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body); font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap;
}
.chip-sale { background: var(--badge-sale-bg); color: var(--badge-sale-text); }
.chip-new  { background: var(--badge-new-bg);  color: var(--badge-new-text); }
.chip-best { background: var(--badge-best-bg); color: var(--badge-best-text); }
.chip-out  { background: var(--state-out-of-stock); color: var(--color-white); }
/* Buyable inside a set, or not sold singly to this shopper — never "sold out"
   when there is stock (2026-09-25). */
.chip-set  { background: var(--surface-gold); color: var(--text-on-gold); }
.card-set-link { color: var(--text-link); text-decoration: underline; font-size: var(--text-sm); }
.card-set-link:hover { color: var(--text-link-hover); }

.card-chips { position: absolute; top: 10px; inset-inline-start: 10px; display: flex; flex-direction: column; gap: 6px; z-index: 2; }

/* HeartBtn.jsx: 34px circle, rgba white .85, top 6 right 6. */
.card-heart { position: absolute; top: 6px; inset-inline-end: 6px; z-index: 3; }

.heart-btn {
  width: 34px; height: 34px; border-radius: var(--radius-circle);
  background: rgba(255, 255, 255, 0.85); border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-espresso-700);
  transition: transform var(--duration-fast) var(--ease-spring),
              background var(--duration-fast) var(--ease-standard);
}
.heart-btn:hover { transform: scale(1.08); }
.heart-btn.is-active { color: var(--accent-gold); }
.heart-btn.is-active svg { fill: var(--accent-gold); animation: szPop var(--duration-base) var(--ease-spring); }
.heart-btn svg { fill: none; stroke: currentColor; stroke-width: 1.8; }

.heart-btn-lg { width: 46px; height: 46px; background: var(--surface-card); border: 1px solid var(--border-subtle); }

/* Body — ProductCard.jsx: padding 14px 14px 16px. */
.product-card-body { padding: 14px 14px 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }

.product-card-name {
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  line-height: var(--leading-snug); color: var(--text-primary);
  margin: 0;
}
html[lang="ar"] .product-card-name { font-family: var(--font-arabic); }

.product-card-category { font-size: var(--text-xs); color: var(--text-muted); }
.product-card-footer { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }

/* Quick add — ProductCard.jsx: 34px circle, gold on card hover. */
.quick-add {
  width: 34px; height: 34px; border-radius: var(--radius-circle);
  border: 1px solid var(--border-subtle); background: transparent;
  color: var(--text-primary); cursor: pointer;
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
  transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard);
}
.product-card:hover .quick-add { background: var(--accent-gold); color: var(--text-on-gold); border-color: var(--accent-gold); }
.quick-add:active { transform: scale(0.9); }
/* Touch devices have no hover, so the affordance must always be visible. */
@media (hover: none) { .quick-add { background: var(--accent-gold); color: var(--text-on-gold); border-color: var(--accent-gold); } }

/* --------------------------------------------------------------- PRICE -- */
/* PriceTag.jsx: text-md/600; state-error when discounted; compare text-sm muted. */

.price-tag { display: inline-flex; align-items: baseline; gap: 8px; font-family: var(--font-body); }
.price { font-size: var(--text-md); font-weight: var(--weight-semibold); color: var(--text-primary); }
.price.is-sale { color: var(--state-error); }
.price-compare { font-size: var(--text-sm); color: var(--text-muted); text-decoration: line-through; }
.product-card .price-compare { font-size: var(--text-xs); }

/* ------------------------------------------------------- PRODUCT PAGE -- */

.product-layout { display: grid; gap: var(--space-8); }
@media (min-width: 900px) { .product-layout { grid-template-columns: 1.05fr 1fr; gap: var(--space-16); } }

/* BUG-089. THE PRODUCT PAGE SHOWS THE PHOTOGRAPH, AT THE SHAPE IT WAS TAKEN.
   `aspect-ratio: 1/1` with `cover` forced every image into a square and cut
   whatever did not fit — on a portrait vase shot that is the top and the
   bottom of the vase, which is most of the product. The frame is now driven by
   the image: the element sizes to its own intrinsic ratio (the `width`/`height`
   attributes carry it, so the space is reserved before the bytes arrive and the
   page does not jump), bounded by a sensible share of the viewport so a very
   tall photograph cannot push the buy button off the screen.

   `contain` rather than `cover` for the same reason as the card, and no
   `aspect-ratio` at all so portrait, landscape and square each get their own
   height instead of the tallest one deciding for the rest. */
/* A BIG PHOTOGRAPH, AT ITS OWN SHAPE, WITH NOTHING AROUND IT.

   The previous rule centred the image inside a bordered box with a background
   and a viewport-height ceiling, so a portrait shot sat in the middle of a
   cream frame with bands down both sides — the empty canvas this was meant to
   avoid, in a different place.

   The container now takes the image's own aspect ratio (`aspect-ratio` is set
   from the `width`/`height` attributes by the browser, since the image is the
   only thing in it and fills it), so the box IS the photograph: portrait,
   landscape and square each get their own height and none of them is cropped
   or letterboxed. No border, no inner padding, no background showing.

   The rounded corner stays and `overflow: hidden` keeps the picture inside it. */
.gallery { position: relative; }

.gallery-main {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-page-alt);
}
.gallery-main img {
  display: block;
  width: 100%;
  height: auto;
  transition: opacity var(--duration-fast) var(--ease-standard);
}
/* Alpine hides the inactive slides; without this they occupy layout for the
   instant before it boots and the page jumps by four image heights. */
.gallery-main img[x-cloak] { display: none; }

/* Arrows sit ON the photograph, and only where there is a pointer to use them.
   On a touch screen the swipe is the gesture and a pair of buttons over the
   picture is just something covering it. */
.gallery-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; display: none;
  align-items: center; justify-content: center;
  border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border-subtle);
  background: color-mix(in srgb, var(--surface-page) 88%, transparent);
  color: var(--text-primary);
  transition: background var(--duration-fast) var(--ease-standard);
}
.gallery-arrow:hover { background: var(--surface-page); }
.gallery-arrow-prev { inset-inline-start: var(--space-3); }
.gallery-arrow-next { inset-inline-end: var(--space-3); }
@media (hover: hover) and (min-width: 900px) {
  .gallery-arrow { display: flex; }
}
/* The chevron is the only part that cares which way is forward. The buttons
   are already placed by logical inset properties, so the icon is what would
   otherwise point the wrong way under RTL. */
[dir="rtl"] .gallery-arrow svg { transform: scaleX(-1); }

/* Where you are in the set, for a thumb nowhere near the thumbnails. */
.gallery-dots {
  position: absolute; inset-inline: 0; bottom: var(--space-3);
  display: flex; gap: 6px; justify-content: center;
}
.gallery-dots span {
  width: 6px; height: 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--text-primary) 28%, transparent);
  transition: background var(--duration-fast) var(--ease-standard);
}
.gallery-dots span.is-on { background: var(--text-primary); }

.gallery:focus-visible { outline: 2px solid var(--border-strong); outline-offset: 4px; }

.gallery-thumbs { display: flex; gap: var(--space-3); margin-top: var(--space-3); flex-wrap: wrap; }
.gallery-thumbs button {
  width: 72px; height: 72px; padding: 0; cursor: pointer;
  border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--border-subtle); background: var(--surface-page-alt);
  transition: border-color var(--duration-fast) var(--ease-standard);
}
.gallery-thumbs button[aria-current="true"] { border-color: var(--border-strong); }
/* Thumbnails fill their square too. A 72px navigational tile is not where
   anybody judges composition, and a fitted image inside it is mostly border. */
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }

.product-detail { display: flex; flex-direction: column; gap: var(--space-5); }
.product-title { font-size: var(--text-2xl); }
@media (min-width: 768px) { .product-title { font-size: var(--text-3xl); } }

.product-price-row { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.product-price-row .price { font-size: var(--text-xl); }

.stock-line { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); margin: 0; }
.stock-dot { width: 9px; height: 9px; border-radius: var(--radius-circle); flex: 0 0 auto; }
.stock-in  { color: var(--state-success); } .stock-in  .stock-dot { background: var(--state-success); }
.stock-low { color: var(--accent-gold-active); } .stock-low .stock-dot { background: var(--accent-gold); }
.stock-out { color: var(--text-muted); } .stock-out .stock-dot { background: var(--state-out-of-stock); }

.buy-row { display: flex; gap: var(--space-3); align-items: stretch; flex-wrap: wrap; }
.buy-row .btn { flex: 1 1 200px; }

/* QuantityStepper.jsx: 34px buttons. */
.qty-stepper {
  display: inline-flex; align-items: center;
  border: 1px solid var(--border-subtle); border-radius: var(--radius-pill);
  background: var(--surface-card); overflow: hidden;
}
.qty-stepper button {
  width: 34px; height: 34px; border: none; background: transparent;
  font-size: 16px; cursor: pointer; color: var(--text-primary);
  display: flex; align-items: center; justify-content: center;
  transition: background var(--duration-fast) var(--ease-standard);
}
.qty-stepper button:hover:not(:disabled) { background: var(--surface-page-alt); }
.qty-stepper button:disabled { opacity: 0.35; cursor: not-allowed; }
.qty-stepper output { min-width: 34px; text-align: center; font-size: var(--text-sm); font-weight: var(--weight-medium); }

/* BUG-097. The quantity is typed now, not only stepped.
   Sized so three digits fit without the field growing as somebody types —
   a control that changes width mid-entry moves the Add button under the
   thumb that is about to press it. No spinners: they are 12px browser
   arrows next to 34px buttons that do the same thing, and on a phone they
   are unhittable. Logical properties throughout, so RTL needs no override. */
.qty-stepper .qty-input {
  width: 3.5rem; min-width: 3.5rem; text-align: center;
  border: none; background: transparent; color: var(--text-primary);
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--weight-medium);
  padding-block: var(--space-1); padding-inline: 0;
  -moz-appearance: textfield; appearance: textfield;
}
.qty-stepper .qty-input::-webkit-outer-spin-button,
.qty-stepper .qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Visible focus, because this is now a keyboard stop between two buttons. */
.qty-stepper .qty-input:focus-visible {
  outline: 2px solid var(--border-strong); outline-offset: -2px; border-radius: var(--radius-sm);
}

.delivery-note {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--surface-page-alt); border-radius: var(--radius-md);
  padding: var(--space-4); font-size: var(--text-sm); color: var(--text-secondary);
}

.spec-list { border-top: 1px solid var(--border-subtle); padding-top: var(--space-5); display: grid; gap: var(--space-3); margin: 0; }
.spec-row { display: flex; justify-content: space-between; gap: var(--space-4); font-size: var(--text-sm); }
.spec-row dt { color: var(--text-secondary); }
.spec-row dd { margin: 0; color: var(--text-primary); text-align: end; }

/* Accordion.jsx: 1px dividers, chevron rotate. */
.accordion { border-top: 1px solid var(--border-subtle); }
.accordion-item { border-bottom: 1px solid var(--border-subtle); }
.accordion-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); padding: var(--space-4) 0;
  background: none; border: none; cursor: pointer; text-align: start;
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.accordion-head svg { transition: transform var(--duration-base) var(--ease-standard); flex: 0 0 auto; }
.accordion-item[open] .accordion-head svg { transform: rotate(180deg); }
.accordion-body { padding-bottom: var(--space-4); font-size: var(--text-sm); color: var(--text-secondary); }

.trust-strip {
  display: grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  padding: var(--space-8) 0; border-top: 1px solid var(--border-subtle);
  border-bottom: 1px solid var(--border-subtle); margin-top: var(--space-12);
}
.trust-item { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--text-sm); color: var(--text-secondary); }
.trust-item strong { display: block; color: var(--text-primary); font-weight: var(--weight-medium); }

/* ------------------------------------------------------- CART DRAWER -- */

.drawer-scrim {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(46, 33, 21, 0.42);
  animation: szFade var(--duration-base) var(--ease-out);
}

.drawer {
  position: fixed; inset-block: 0; inset-inline-end: 0; z-index: 91;
  width: min(420px, 100%);
  background: var(--surface-page);
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg);
  animation: szInR var(--duration-base) var(--ease-out);
}
html[dir="rtl"] .drawer { animation-name: szInL; }

.drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-5); border-bottom: 1px solid var(--border-subtle);
}
.drawer-title { font-size: var(--text-lg); }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-5); }
.drawer-foot { border-top: 1px solid var(--border-subtle); padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); background: var(--surface-card); }

.cart-line { display: grid; grid-template-columns: 78px 1fr; gap: var(--space-4); }
.cart-line img { width: 78px; height: 78px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-page-alt); }
.cart-line-name { font-size: var(--text-sm); font-weight: var(--weight-medium); margin: 0 0 2px; }
.cart-line-sku { font-size: var(--text-xs); color: var(--text-muted); }
.cart-line-controls { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-2); }

.link-button {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: var(--text-xs); color: var(--text-muted);
  text-decoration: underline; text-underline-offset: 2px;
}
.link-button:hover { color: var(--state-error); }

.summary-row { display: flex; justify-content: space-between; align-items: baseline; font-size: var(--text-sm); }
.summary-row.is-total { font-size: var(--text-md); font-weight: var(--weight-semibold); }

.price-changed { font-size: var(--text-xs); color: var(--accent-gold-active); }

/* ----------------------------------------------------- SEARCH OVERLAY -- */

.search-overlay {
  position: fixed; inset: 0; z-index: 95;
  background: var(--surface-page);
  display: flex; flex-direction: column;
  animation: szFade var(--duration-fast) var(--ease-out);
}
.search-head {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-5) var(--container-pad);
  border-bottom: 1px solid var(--border-subtle);
  animation: szDrop var(--duration-base) var(--ease-out);
}
.search-input {
  flex: 1; border: none; background: transparent;
  font-family: var(--font-display); font-size: var(--text-xl);
  color: var(--text-primary); padding: var(--space-2) 0;
}
html[lang="ar"] .search-input { font-family: var(--font-arabic); }
.search-input:focus { outline: none; }
.search-input::placeholder { color: var(--text-muted); }

.search-results { flex: 1; overflow-y: auto; padding: var(--space-6) var(--container-pad) var(--space-16); }
.search-result {
  display: grid; grid-template-columns: 64px 1fr auto; gap: var(--space-4);
  align-items: center; padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-subtle);
}
.search-result img { width: 64px; height: 64px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-page-alt); }
.search-result:hover { background: var(--surface-page-alt); }

/* Skeleton — animates opacity only, never layout dimensions. */
.skeleton-row { display: grid; grid-template-columns: 64px 1fr; gap: var(--space-4); padding: var(--space-3) 0; }
.skeleton-box { background: var(--surface-sunken); border-radius: var(--radius-sm); animation: szPulse 1.2s var(--ease-standard) infinite; }
@keyframes szPulse { 0%, 100% { opacity: 1 } 50% { opacity: 0.55 } }

/* ------------------------------------------------------------- TOAST -- */

.toast-stack { position: fixed; inset-block-end: var(--space-6); inset-inline: 0; z-index: 99; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); pointer-events: none; }
@media (max-width: 899px) { .toast-stack { inset-block-end: 84px; } }
.toast {
  pointer-events: auto;
  background: var(--surface-inverse); color: var(--text-on-inverse);
  padding: var(--space-3) var(--space-6); border-radius: var(--radius-pill);
  font-size: var(--text-sm); box-shadow: var(--shadow-md);
  animation: szDrop var(--duration-base) var(--ease-spring);
}
.toast.is-error { background: var(--state-error); }

/* -------------------------------------------------------------- FORMS -- */

.form-grid { display: grid; gap: var(--space-5); }
@media (min-width: 768px) { .form-grid.is-two-up { grid-template-columns: 1fr 1fr; } }

.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field label { font-size: var(--text-sm); color: var(--text-secondary); }
.field .required { color: var(--state-error); }

.input, .select, .textarea {
  font-family: inherit; font-size: var(--text-base); color: var(--text-primary);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  transition: border-color var(--duration-fast) var(--ease-standard),
              box-shadow var(--duration-fast) var(--ease-standard);
}
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--focus-ring); }
.input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--state-error); }
.textarea { min-height: 96px; resize: vertical; }

.field-error { font-size: var(--text-xs); color: var(--state-error); }

.alert { padding: var(--space-4); border-radius: var(--radius-md); font-size: var(--text-sm); }
.alert-error { background: var(--color-blush-200); color: var(--color-terracotta-500); }
.alert-success { background: var(--surface-page-alt); color: var(--state-success); }

.panel { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); padding: var(--space-6); }
@media (min-width: 768px) { .panel { padding: var(--space-8); } }

.checkout-layout { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 900px) { .checkout-layout { grid-template-columns: 1.4fr 1fr; gap: var(--space-12); } }
@media (min-width: 900px) { .checkout-summary { position: sticky; top: 120px; } }

.account-layout { display: grid; gap: var(--space-8); align-items: start; }
@media (min-width: 900px) { .account-layout { grid-template-columns: 240px 1fr; gap: var(--space-12); } }
.account-nav { display: flex; flex-direction: column; gap: var(--space-1); }
.account-nav a { padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); font-size: var(--text-sm); }
.account-nav a[aria-current="page"] { background: var(--surface-sunken); color: var(--text-primary); font-weight: var(--weight-medium); }

.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.data-table th { text-align: start; font-weight: var(--weight-medium); color: var(--text-secondary); padding: var(--space-3); border-bottom: 1px solid var(--border-subtle); }
.data-table td { padding: var(--space-3); border-bottom: 1px solid var(--border-subtle); }

.status-pill { display: inline-block; padding: 3px 10px; border-radius: var(--radius-pill); font-size: var(--text-xs); background: var(--surface-sunken); color: var(--text-secondary); }

/* ------------------------------------------------------------ PAGINATION -- */

/* Laravel's default pagination view is Tailwind's, and this stylesheet is not
   Tailwind. Its chevrons carry `w-5 h-5`, which styled nothing here, so the
   SVGs fell back to filling their container and the shop page ended with two
   chevrons several hundred pixels tall. The view is ours now
   (`resources/views/vendor/pagination/sezar.blade.php`) and the arrows carry
   width and height as HTML attributes as well, so they stay small even with no
   stylesheet at all. */

.pagination { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }

.pagination-list {
  display: flex; align-items: center; gap: var(--space-2);
  list-style: none; margin: 0; padding: 0; flex-wrap: wrap; justify-content: center;
}

.pagination-link {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 40px; min-height: 40px; padding: 0 var(--space-3);
  font-family: var(--font-body); font-size: var(--text-sm); line-height: 1;
  color: var(--text-primary); text-decoration: none;
  border: 1px solid var(--border-subtle); border-radius: var(--radius-pill);
  background: transparent;
  transition: background var(--duration-base) var(--ease-standard),
              border-color var(--duration-base) var(--ease-standard),
              color var(--duration-base) var(--ease-standard);
}

a.pagination-link:hover { background: var(--surface-page-alt); border-color: var(--border-strong, var(--border-subtle)); }

.pagination-link.is-current {
  background: var(--surface-inverse); color: var(--text-on-inverse);
  border-color: var(--surface-inverse); font-weight: var(--weight-semibold);
}

/* Not a link and not clickable — dimmed, and never picking up hover. */
.pagination-link.is-disabled { opacity: 0.4; cursor: not-allowed; }

.pagination-gap { display: inline-flex; align-items: center; padding: 0 4px; color: var(--text-muted); }

/* Belt and braces against the bug this section exists for. */
.pagination-chevron { width: 14px; height: 14px; flex: none; }

/* "Previous" points right in Arabic. */
html[dir="rtl"] .pagination-chevron { transform: scaleX(-1); }

.pagination-count { font-size: var(--text-xs); color: var(--text-muted); margin: 0; }

/* On a phone the word labels go and the arrows carry the meaning, so eighteen
   products do not wrap the control onto three lines. */
@media (max-width: 520px) {
  .pagination-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .pagination-link { min-width: 36px; min-height: 36px; padding: 0 var(--space-2); }
}

/* ---------------------------------------------------------- EMPTY/MISC -- */

.empty-state { text-align: center; padding-block: var(--space-20); color: var(--text-secondary); display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.breadcrumbs { font-size: var(--text-xs); color: var(--text-muted); padding-block: var(--space-5); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.breadcrumbs a { color: var(--text-muted); }
.breadcrumbs a:hover { color: var(--text-link); }
.breadcrumbs [aria-current="page"] { color: var(--text-primary); }

.filter-bar { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-8); }
.filter-chip {
  padding: 8px 18px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle); background: var(--surface-card);
  font-size: var(--text-sm); color: var(--text-primary);
  transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard), opacity var(--duration-fast) var(--ease-standard);
}
.filter-chip:hover { border-color: var(--border-strong); }
.filter-chip[aria-current="true"] { background: var(--surface-inverse); color: var(--text-on-inverse); border-color: var(--surface-inverse); }

/* ------------------------------------------------------------- FOOTER -- */

.site-footer { background: var(--surface-inverse); color: var(--text-on-inverse); padding-block: var(--space-16); margin-top: var(--space-20); }
.footer-grid { display: grid; gap: var(--space-10); grid-template-columns: 1fr; }
@media (min-width: 768px) { .footer-grid { grid-template-columns: 2fr 1fr 1fr; gap: var(--space-16); } }
.site-footer h3 { font-size: var(--text-sm); letter-spacing: var(--tracking-wider); text-transform: uppercase; font-family: var(--font-body); margin-bottom: var(--space-4); color: var(--color-gold-300); }
.site-footer a { color: var(--text-on-inverse); font-size: var(--text-sm); }
.site-footer a:hover { color: var(--color-gold-300); }
.site-footer p { color: var(--color-sand-300); font-size: var(--text-sm); }
.footer-links { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.footer-bottom { border-top: 1px solid rgba(255, 255, 255, 0.12); margin-top: var(--space-12); padding-top: var(--space-6); font-size: var(--text-xs); color: var(--color-sand-300); display: flex; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }

/* Durations already collapse to 0ms via the token file under reduced motion;
   this additionally stops the keyframe animations and the hover lift. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; }
  .product-card:hover, .btn:hover:not(:disabled) { transform: none; }
  .product-card:hover .product-card-media img { transform: none; }
}

/* ------------------------------------------------------ VIDEO BAND (I19) -- */
/* A shape reserved before anything loads, so the page never jumps when the
   poster or the player resolves. `aspect-ratio` is set inline from the band's
   own setting — it is a SHAPE, not a layout: it cannot express a width, a
   column count or a breakpoint, so it does not reopen the door §4 closed. */

.video-band {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-ink-900, #2E2115);
}

.video-band__media {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

.video-band__lede {
  max-width: 60ch;
  color: var(--text-secondary);
  margin: 0 0 var(--space-6);
}

.video-band__facade { position: absolute; inset: 0; cursor: pointer; }

/* The play button is a real <button>, centred over the poster, and large
   enough to be a comfortable touch target on a phone (44px is the floor; this
   is 64). Colour is never the only signal — it carries an accessible name. */
.video-band__play {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%;
  transform: translate(50%, -50%);
  width: 64px; height: 64px;
  border: none; border-radius: 50%;
  background: var(--color-gold-400, #C9A15A);
  color: var(--color-ink-900, #2E2115);
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow: var(--shadow-md, 0 6px 20px rgba(0, 0, 0, 0.28));
  transition: transform var(--duration-base) var(--ease-standard);
}
/* RTL puts the button back on centre: `translate(50%)` is correct under
   `dir="rtl"` because `inset-inline-start` resolves to the right edge. Under
   LTR it must go the other way. */
[dir="ltr"] .video-band__play { transform: translate(-50%, -50%); }

.video-band__play:hover { transform: translate(50%, -50%) scale(1.06); }
[dir="ltr"] .video-band__play:hover { transform: translate(-50%, -50%) scale(1.06); }

.video-band__play:focus-visible {
  outline: 2px solid var(--color-gold-300, #DCC08A);
  outline-offset: 4px;
}

.video-band__play-icon { font-size: 22px; line-height: 1; margin-inline-start: 3px; }

.video-band__noscript {
  position: absolute; inset-block-end: var(--space-4); inset-inline-start: 50%;
  transform: translateX(50%);
  color: var(--text-on-inverse, #fff);
  font-size: var(--text-sm);
}
[dir="ltr"] .video-band__noscript { transform: translateX(-50%); }

/* The iframe the facade is replaced with. */
.video-band iframe { width: 100%; height: 100%; border: 0; display: block; }

@media (prefers-reduced-motion: reduce) {
  .video-band__play:hover { transform: translate(50%, -50%); }
  [dir="ltr"] .video-band__play:hover { transform: translate(-50%, -50%); }
}

/* -------------------------------------------- OVERLAY / GALLERY / STRIP -- */
/* Gate I19. Three expressive bands, none of which adds a way to express a
   layout: every choice below is a named option with a fixed set of values, and
   every one of them collapses to a single readable column on a phone. */

/* --- image with the words on it ----------------------------------------- */

.overlay-band {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  display: grid;
}

.overlay-band__image { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ON A PHONE THE COPY GOES UNDERNEATH, always, whatever position is chosen.
   White text over a busy photograph at 390px is unreadable however dark the
   scrim, and an editor cannot be given a setting whose only safe value is one
   of three. */
.overlay-band__copy {
  padding: var(--space-6) 0 0;
  display: grid; gap: var(--space-3); justify-items: start;
}
.overlay-band__title { font-size: var(--text-xl); margin: 0; color: var(--text-primary); }
.overlay-band__lede { margin: 0; color: var(--text-secondary); max-width: 52ch; }

@media (min-width: 768px) {
  .overlay-band > picture { grid-area: 1 / 1; }
  .overlay-band__copy {
    grid-area: 1 / 1;
    align-self: center;
    padding: var(--space-10);
    max-width: 46ch;
    color: var(--text-on-inverse, #fff);
    position: relative; z-index: 1;
  }
  .overlay-band__title,
  .overlay-band__lede,
  .overlay-band__eyebrow { color: inherit; }

  .overlay-band--start .overlay-band__copy { justify-self: start; }
  .overlay-band--centre .overlay-band__copy { justify-self: center; text-align: center; justify-items: center; }
  .overlay-band--end .overlay-band__copy { justify-self: end; }

  /* The scrim. Contrast against a photograph cannot be computed the way the
     theme guard computes it against a palette, because the image changes —
     so these two values are the ones that keep the body colour legible over a
     mid-tone and a bright image, and `none` is for a photograph already dark
     enough not to need one. */
  .overlay-band--shade-soft::after,
  .overlay-band--shade-strong::after {
    content: ""; position: absolute; inset: 0; grid-area: 1 / 1;
    pointer-events: none;
  }
  .overlay-band--shade-soft::after { background: rgba(46, 33, 21, 0.35); }
  .overlay-band--shade-strong::after { background: rgba(46, 33, 21, 0.58); }
}

/* --- the gallery -------------------------------------------------------- */

/* `auto-fit` with a minimum means the chosen column count is a MAXIMUM. Four
   is four on a desktop, two on a tablet and one on a phone, and no setting can
   force four onto a 390px screen. That is the difference between offering a
   choice and offering a way to break the design. */
/* EXPLICIT COUNTS AT EVERY STEP, not `auto-fit`.
   `auto-fit` fills the row with as many tracks as fit and leaves the spare ones
   empty: four items on a 1265px row produced FIVE tracks, so the last cell was
   a gap and the row read as misaligned. Found by measuring the rendered page,
   not by reading the rule. One column, then two, then whatever the editor
   chose — each an exact number, so a track can never be empty. */
.gallery-band {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 600px) {
  .gallery-band { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  .gallery-band {
    grid-template-columns: repeat(var(--gallery-columns, 3), minmax(0, 1fr));
  }
}

.gallery-band__item { margin: 0; display: grid; gap: var(--space-2); }
.gallery-band__image {
  width: 100%; height: auto; aspect-ratio: 1 / 1;
  object-fit: cover; display: block;
  border-radius: var(--radius-md);
}
.gallery-band__caption {
  font-size: var(--text-sm); color: var(--text-secondary); margin: 0;
}

/* --- the feature strip -------------------------------------------------- */

/* FLEX, NOT GRID, and the reason is the same defect the gallery had.
   A grid with `auto-fit` gave four points five tracks on a wide row, so the
   strip sat off-centre with an empty cell at the end. Flex only ever creates
   as many items as there are, wraps when they no longer fit, and centres what
   is left on the final row — which is exactly the behaviour a row of one to
   four reassurances wants. */
.feature-strip {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--space-6);
  text-align: center;
}
.feature-strip__item {
  display: grid; gap: var(--space-2);
  padding-inline: var(--space-2);
  /* Grows to share the row, never past a comfortable measure. */
  flex: 1 1 200px;
  max-width: 320px;
}
.feature-strip__label {
  margin: 0;
  font-family: var(--font-display, var(--font-body));
  font-size: var(--text-base);
  color: var(--text-primary);
}
.feature-strip__detail {
  margin: 0; font-size: var(--text-sm); color: var(--text-secondary);
}


/* ==========================================================================
   THE LISTING PAGE
   --------------------------------------------------------------------------
   A banner, a filter panel and a grid. The panel had been a row of twenty-eight
   category pills — every category in the catalogue, two rows deep, with no
   price, no availability, no sale and no sort.

   LOGICAL PROPERTIES THROUGHOUT. The panel sits at the INLINE START, which puts
   it on the right in Arabic and the left in English without a second rule.
   ========================================================================== */

.listing-banner {
  position: relative;
  overflow: hidden;
  background: var(--surface-page-alt);
  border-block-end: 1px solid var(--border-subtle);
}

/* A LITTLE WARMTH BEHIND THE TITLE AND NOTHING ELSE. A flat tinted band is
   what a listing page has when nobody looked at it; a photograph here would
   compete with the products, which are the point. This is a soft rise in the
   sand behind the words — visible, and not something anybody has to notice. */
.listing-banner::before {
  content: '';
  position: absolute;
  inset-block-start: -60%;
  inset-inline-start: 50%;
  inline-size: 680px;
  block-size: 680px;
  translate: -50% 0;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(196 155 90 / 12%) 0%, transparent 68%);
  pointer-events: none;
}

.listing-banner-inner {
  position: relative;
  padding-block: var(--space-10);
  text-align: center;
}

.listing-banner-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-3);
OLD_MARKER
  font-family: var(--font-body);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--accent-gold);
}

.listing-banner-eyebrow::before,
.listing-banner-eyebrow::after {
  content: '';
  inline-size: var(--space-6);
  block-size: 1px;
  background: currentColor;
  opacity: 0.5;
}

.listing-banner-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  color: var(--text-primary);
}

.listing-banner-note {
  margin: var(--space-3) auto 0;
  max-inline-size: 46ch;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

@media (min-width: 768px) {
  .listing-banner-inner { padding-block: var(--space-14); }
  .listing-banner-title { font-size: var(--text-4xl); }
}

/* -------------------------------------------------------------- THE LAYOUT */

.listing {
  display: grid;
  gap: var(--space-6);
  padding-block-end: var(--space-16);
}

@media (min-width: 1024px) {
  /* 260px is wide enough for a category name and its count on one line, and
     narrow enough to leave four product columns beside it. */
  .listing { grid-template-columns: 260px minmax(0, 1fr); gap: var(--space-10); align-items: start; }
}

/* --------------------------------------------------------------- THE PANEL */

/* THE SWITCH IS FOCUSABLE AND INVISIBLE. `display: none` would take it out of
   the tab order and the label with it; this keeps the control reachable by
   keyboard while the label carries the appearance. */
.listing-switch {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.listing-panel {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
}

/* Below the breakpoint the panel is a disclosure and starts closed, so the
   products are the first thing on the page. */
.listing-panel-body { display: none; }
.listing-switch:checked ~ .listing-panel .listing-panel-body { display: flex; }
.listing-switch:focus-visible ~ .listing-panel .listing-panel-summary {
  outline: 2px solid var(--accent-gold);
  outline-offset: 2px;
}
.listing-switch:checked ~ .listing-panel .listing-panel-summary::after { transform: rotate(-135deg); }

.listing-panel-summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  cursor: pointer;
  list-style: none;
}

/* It was a `<summary>`; it is a `<label>` now, and neither should show a
   marker. */
.listing-panel-summary::-webkit-details-marker { display: none; }

/* The chevron, drawn rather than a glyph so it turns with the panel. */
.listing-panel-summary::after {
  content: '';
  inline-size: 8px;
  block-size: 8px;
  margin-inline-start: auto;
  /* PHYSICAL BORDERS, DELIBERATELY. A chevron that means "this opens
     downwards" points down in both directions; logical borders turned it into
     a left-pointing arrow in Arabic, which reads as "go back". */
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--duration-fast) var(--ease-standard);
}


.listing-panel-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 20px;
  block-size: 20px;
  padding-inline: 6px;
  border-radius: var(--radius-pill);
  background: var(--accent-gold);
  color: var(--text-on-gold);
  font-size: 11px;
  font-weight: var(--weight-bold);
}

/* NO `display` HERE. It is set by the two state rules above — closed by default
   on a phone, open above the breakpoint — and re-declaring it in this later
   block quietly won, which is why the panel came up expanded on a phone with
   the products pushed off the screen. */
.listing-panel-body {
  padding: 0 var(--space-5) var(--space-5);
  flex-direction: column;
  gap: var(--space-6);
}

/* ON A DESKTOP IT IS NOT A DISCLOSURE AT ALL. `<details>` is the phone
   behaviour; above 1024px the panel is simply a column, always open, with no
   summary to click. One element, two jobs, no JavaScript deciding which. */
/* ABOVE THE BREAKPOINT THERE IS NO DISCLOSURE AT ALL. The label is gone and the
   body is simply the column's content — one piece of markup, two behaviours,
   and no JavaScript deciding between them. */
@media (min-width: 1024px) {
  .listing-panel { position: sticky; inset-block-start: var(--space-6); }
  .listing-panel-summary { display: none; }
  .listing-panel-body,
  .listing-switch:checked ~ .listing-panel .listing-panel-body {
    display: flex;
    padding-block-start: var(--space-5);
  }
}

.listing-clear {
  align-self: flex-start;
  font-size: var(--text-xs);
  color: var(--text-link);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.listing-group { display: flex; flex-direction: column; gap: var(--space-2); }

.listing-group-title {
  margin: 0 0 var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ------------------------------------------------------------- THE TOGGLES */

.listing-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  transition: color var(--duration-fast) var(--ease-standard);
}

.listing-toggle-box {
  inline-size: 18px;
  block-size: 18px;
  flex: none;
  border: 1.5px solid var(--border-strong);
  /* A SQUARE, NOT A CIRCLE. `--radius-sm` rounded it to a disc, and a disc is
     a radio button — one of a set, choose exactly one. These two are
     independent and both can be on. */
  border-radius: 4px;
  position: relative;
OLD_MARKER
  transition: background var(--duration-fast) var(--ease-standard),
              border-color var(--duration-fast) var(--ease-standard);
}

.listing-toggle:hover { color: var(--text-primary); }
.listing-toggle:hover .listing-toggle-box { border-color: var(--accent-gold); }

.listing-toggle.is-on { color: var(--text-primary); font-weight: var(--weight-medium); }
.listing-toggle.is-on .listing-toggle-box { background: var(--accent-gold); border-color: var(--accent-gold); }

/* The tick, drawn in the box rather than shipped as an icon. */
.listing-toggle.is-on .listing-toggle-box::after {
  content: '';
  position: absolute;
  inset-inline-start: 5px;
  inset-block-start: 1px;
  inline-size: 5px;
  block-size: 10px;
  border-inline-end: 2px solid var(--text-on-gold);
  border-block-end: 2px solid var(--text-on-gold);
  transform: rotate(45deg);
}

/* --------------------------------------------------------------- THE PRICE */

.listing-price { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); align-items: end; }

.listing-price-field { display: flex; flex-direction: column; gap: 4px; font-size: var(--text-xs); color: var(--text-muted); }

.listing-price-field input {
  inline-size: 100%;
  min-block-size: var(--space-10);
  padding-inline: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-page);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-primary);
}

.listing-price-field input:focus-visible { outline: 2px solid var(--accent-gold); outline-offset: 1px; border-color: var(--accent-gold); }

.listing-price .btn { grid-column: 1 / -1; }

/* ---------------------------------------------------------------- THE LIST */

.listing-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.listing-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  transition: color var(--duration-fast) var(--ease-standard);
}

.listing-link:hover { color: var(--text-primary); }
.listing-link.is-on { color: var(--accent-gold); font-weight: var(--weight-medium); }

.listing-count { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- THE TOOLBAR */

.listing-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-block-end: var(--space-5);
  margin-block-end: var(--space-6);
  border-block-end: 1px solid var(--border-subtle);
}

.listing-total { margin: 0; font-size: var(--text-sm); color: var(--text-secondary); }

.listing-sort { display: flex; align-items: center; gap: var(--space-2); }

.listing-sort label { font-size: var(--text-xs); color: var(--text-muted); }

.listing-sort select {
  min-block-size: var(--space-10);
  padding-inline: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-page);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-primary);
  cursor: pointer;
}

.listing-sort select:focus-visible { outline: 2px solid var(--accent-gold); outline-offset: 1px; }

.listing-pagination { margin-block-start: var(--space-12); }

/* ------------------------------------------------- A CARD WITH NO PICTURE -- */

/* 115 of 195 published products have no photograph, so most of a page of the
   shop was empty boxes — which reads as broken rather than as unphotographed. */
.product-card-blank {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--accent-gold);
  opacity: 0.45;
}

.product-card-blank svg { inline-size: 34px; block-size: 34px; }

.product-card-blank span {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .listing-panel-summary::after,
  .listing-toggle,
  .listing-toggle-box,
  .listing-link { transition: none; }
}

/* ---------------------------------------------------------------------------
   Order confirmation: the tick, and the gift (BUG-098).

   CSS ONLY. No library, nothing to download, and one media query to switch off.
   Durations come from the frozen tokens, which already collapse to 0ms under
   `prefers-reduced-motion` — so the reduced-motion block below is belt to that
   braces rather than the only thing honouring the preference.
--------------------------------------------------------------------------- */
.order-done-tick {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: sezar-tick var(--duration-page) var(--ease-standard) forwards;
}

@keyframes sezar-tick {
  to { stroke-dashoffset: 0; }
}

.referral-gift {
  animation: sezar-gift-in var(--duration-slow) var(--ease-standard) both;
  /* A short delay so it arrives after the tick rather than with it — the
     thanks first, the offer second. */
  animation-delay: var(--duration-base);
}

@keyframes sezar-gift-in {
  from { opacity: 0; transform: translateY(var(--space-3)); }
  to   { opacity: 1; transform: none; }
}

/* The code itself: large, spaced, selectable, and always LTR. A discount code
   is not language, and mirroring it in Arabic makes it unreadable. */
.referral-code {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  letter-spacing: 0.18em;
  color: var(--text-primary);
  background: var(--surface-page-alt);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  user-select: all;
}

@media (prefers-reduced-motion: reduce) {
  /* Not "faster" — none. The tick is simply drawn and the panel is simply
     there, which is the correct end state of both animations. */
  .order-done-tick { animation: none; stroke-dashoffset: 0; }
  .referral-gift { animation: none; opacity: 1; transform: none; }
}

/* ------------------------------------------- EASE OF ORDERING (QA 2026-10-12) -- */
/* Larger tap areas (44px), instant add-to-cart feedback, a visible help strip.
   Sizes and contrast come from the tokens (--text-xs/-sm/-muted). */
:root { --tap: 44px; }
.icon-btn { min-width: var(--tap); min-height: var(--tap); }
.header-actions { gap: var(--space-1); }
.lang-switch button { min-height: var(--tap); padding-inline: var(--space-3); }
.site-footer a { display: inline-flex; align-items: center; min-height: var(--tap); }
.footer-links { gap: 0; }
.btn { min-height: 52px; font-size: var(--text-base); }
.icon-badge { width: 20px; height: 20px; font-size: 12px; top: 2px; inset-inline-end: 0; }
/* Instant feedback on the add-to-cart button itself (class set by JS on tap) */
.btn.is-added { background: var(--color-gold-700); color: var(--color-cream-50); border-color: var(--color-gold-700); }
.help-strip { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; padding: var(--space-4); background: var(--surface-page-alt); border-radius: var(--radius-md, 12px); font-size: var(--text-base); }
.help-strip a { display: inline-flex; align-items: center; min-height: var(--tap); padding-inline: var(--space-4); border-radius: var(--radius-pill); border: 1px solid var(--border-strong); color: var(--text-primary); font-weight: var(--weight-semibold); }
[x-cloak] { display: none !important; }
