/*
Theme Name: 3orod
Theme URI: https://3orod.net/
Description: Parent theme for 3orod.net — Arabic supermarket offers & coupons. RTL-first, built with CSS logical properties so the same styles work LTR (e.g. French Morocco). Country-agnostic: country specifics live in child themes (3orod-sa, 3orod-ma). No build step.
Version: 0.1.0
Author: 3orod.net
Text Domain: 3orod
Requires at least: 6.3
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

/* ==========================================================================
   3orod.net — Stylesheet
   Pure CSS. Tokens mirror DESIGN.md. Uses logical properties so the same
   sheet works for RTL (Arabic) and LTR (e.g. French Morocco) with no fork.
   When ported to WordPress, this file becomes the theme stylesheet largely
   unchanged — :root tokens stay, selectors map to theme markup.
   ========================================================================== */

/* ---------- Design Tokens (from DESIGN.md) ---------- */
:root {
  /* Color — surfaces */
  --color-background: #f9f9f9;        /* Mist — global canvas */
  --color-surface: #f9f9f9;
  --color-surface-card: #ffffff;      /* Snow — clean shelf for cards */
  --color-surface-container-low: #f3f3f4;
  --color-surface-container: #eeeeee;
  --color-surface-container-high: #e8e8e8;

  /* Color — text */
  --color-on-background: #1a1c1c;     /* Ink Black */
  --color-on-surface: #1a1c1c;
  --color-secondary: #5f5e5e;
  --color-muted: #6b6b6b;

  /* Color — brand */
  --color-primary: #8f000d;           /* Firebrick */
  --color-primary-container: #b22222;
  --color-on-primary: #ffffff;

  /* Color — lines & accents */
  --color-outline-variant: #e2beba;
  --color-hairline: rgba(26, 26, 26, 0.08);

  /* Color — footer */
  --color-footer-bg: #1a1a1a;
  --color-footer-text: #a3a3a3;

  /* Color — coupon / badge tints */
  --color-badge-bg: #fef3e2;
  --color-badge-text: #b45309;

  /* Typography */
  --font-ui: "Cairo", "Segoe UI", Tahoma, sans-serif;
  --font-price: "Plus Jakarta Sans", "Cairo", sans-serif;

  /* Radius (component-level, per DESIGN.md "Shapes") */
  --radius-sm: 4px;    /* tags, checkboxes */
  --radius-md: 6px;    /* buttons, inputs */
  --radius-lg: 10px;   /* cards, media, modals */
  --radius-full: 9999px;

  /* Spacing — 4px grid */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --gutter: 16px;
  --margin-desktop: 48px;

  /* Layout */
  --container-max: 1280px;

  /* Elevation (DESIGN.md ambient shadows) */
  --shadow-card: 0 4px 12px rgba(26, 26, 26, 0.05);
  --shadow-card-hover: 0 8px 20px rgba(26, 26, 26, 0.1);

  /* Motion */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --dur: 180ms;
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Also clip horizontal overflow at the root — this catches position:fixed
     overflow that `body`'s clip can't (fixed elements are clipped by the
     viewport, not by body). A Google Auto Ads anchor unit can render a few px
     wider than the viewport on mobile and, being fixed, would otherwise force a
     sideways page shift. `clip` doesn't create a scroll container, so the
     sticky header still works. */
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 24px;
  color: var(--color-on-background);
  background: var(--color-background);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Kill any horizontal overflow (e.g. a responsive AdSense unit that sizes
     wider than the viewport on mobile) so the page never scrolls sideways.
     `clip` — not `hidden` — so it doesn't become a scroll container and break
     the sticky header. It also lets responsive ads measure the true viewport
     width, so they render at the correct size instead of overflowing. */
  overflow-x: clip;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  cursor: pointer;
}

h1,
h2,
h3,
p,
ul {
  margin: 0;
}

ul {
  list-style: none;
  padding: 0;
}

/* ---------- Helpers ---------- */
.container {
  width: 100%;
  max-inline-size: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.icon {
  inline-size: 24px;
  block-size: 24px;
  display: block;
}
.icon--sm {
  inline-size: 16px;
  block-size: 16px;
}

.skip-link {
  position: absolute;
  inset-block-start: -100px;
  inset-inline-start: var(--space-md);
  z-index: 100;
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  transition: inset-block-start var(--dur) var(--ease);
}
.skip-link:focus {
  inset-block-start: var(--space-md);
}

/* Text for screen readers only — it must never be on screen.
   Four <label>s use this class and NOTHING defined it: header.php:95,
   404.php:131, search.php:180 and the product search in 3orod-core.php:3122.
   They are direct children of .ps-form, which is display:flex, so each one was
   a plain flex item and the words "ابحث في الموقع" showed inside the search row
   on every page of every edition. Verified live: 0 rules for this class in
   style.css, home-v2.css or any child theme.
   No :focus escape hatch on purpose — all four uses are <label>s, which cannot
   take focus, and .skip-link above already handles the one focusable case. */
.screen-reader-text {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- 1. Header ---------- */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 40;
  background: var(--color-primary);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  /* Compact bar — the static fallback for browsers without scroll-driven
     animations (e.g. current iOS Safari) and the end state of the shrink. */
  --header-bar-h: 72px;
  --header-logo-h: 55px;
}

/* Shrink-on-scroll — PURE CSS, no JS. The header starts tall with a big logo and
   collapses to the compact bar over the first 90px of scroll. The size is a
   smooth function of scroll offset (not a class toggled at a threshold), so
   there's no flicker/feedback loop. Browsers without `scroll()` timelines just
   keep the compact fallback above. The vars are @property-registered so they
   interpolate (plain custom properties would jump at 50%). */
@property --header-bar-h {
  syntax: "<length>";
  inherits: true;
  initial-value: 72px;
}
@property --header-logo-h {
  syntax: "<length>";
  inherits: true;
  initial-value: 55px;
}
@supports (animation-timeline: scroll()) {
  /* The header resize must not nudge the scroll position, or the snap would
     fight the browser's scroll-anchoring and flicker. Disabling anchoring on the
     root scroller keeps the two-step snap rock-steady. */
  html {
    overflow-anchor: none;
  }
  .site-header {
    --header-bar-h: 100px;
    --header-logo-h: 88px; /* almost fills the 100px bar */
    animation: threeorod-header-shrink linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 90px;
  }
  /* Two discrete steps (cleaner than a gradual shrink): hold the tall bar, then
     snap to compact at ~35% of the range (~31px scrolled). */
  @keyframes threeorod-header-shrink {
    0%,
    35% {
      --header-bar-h: 100px;
      --header-logo-h: 88px;
    }
    35%,
    100% {
      --header-bar-h: 72px;
      --header-logo-h: 55px;
    }
  }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  block-size: var(--header-bar-h);
}

.site-logo {
  font-family: var(--font-price);
  font-weight: 800;
  font-size: 26px;
  letter-spacing: -0.01em;
  color: var(--color-on-primary);
}
.site-logo--dark {
  color: var(--color-primary);
}
/* Custom logo (Customizer → Logo): height tracks the header var, width
   auto-scales to keep the aspect ratio. Use a white/transparent logo — the
   header bar is firebrick. */
.custom-logo-link {
  display: inline-flex;
  align-items: center;
}
.custom-logo {
  block-size: var(--header-logo-h);
  inline-size: auto;
  max-inline-size: 300px;
  object-fit: contain;
  display: block;
}

/* Mobile: gentler heights so the tall state isn't overbearing on a phone. */
@media (max-width: 767px) {
  .site-header { /* fallback (no scroll-timeline) */
    --header-bar-h: 58px;
    --header-logo-h: 40px;
  }
  @supports (animation-timeline: scroll()) {
    .site-header {
      --header-bar-h: 80px;
      --header-logo-h: 68px; /* almost fills the 80px mobile bar */
      animation-name: threeorod-header-shrink-m;
    }
    @keyframes threeorod-header-shrink-m {
      0%,
      35% {
        --header-bar-h: 80px;
        --header-logo-h: 68px;
      }
      35%,
      100% {
        --header-bar-h: 58px;
        --header-logo-h: 40px;
      }
    }
  }
}

/* Reduced motion: no scroll-linked resize — pin the compact bar. */
@media (prefers-reduced-motion: reduce) {
  .site-header {
    animation: none;
    --header-bar-h: 72px;
    --header-logo-h: 55px;
  }
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: rgba(255, 255, 255, 0.85);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.icon-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
.icon-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ---------- Country switcher ---------- */
.country-switcher {
  position: relative;
}
.country-switcher__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  block-size: 40px;
  padding-inline: 10px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.9);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.country-switcher__toggle:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
.country-switcher__toggle:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.country-switcher__flag {
  inline-size: 20px;
  block-size: 20px;
  border-radius: var(--radius-full);
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
  flex: none;
}
.country-switcher__name {
  white-space: nowrap;
}
.country-switcher__caret {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
  transition: transform var(--dur) var(--ease);
}
.country-switcher.is-open .country-switcher__caret {
  transform: rotate(180deg);
}

/* Dropdown panel (desktop): absolute, anchored to the toggle's inline-end. */
.country-switcher__menu {
  position: absolute;
  inset-block-start: calc(100% + 8px);
  inset-inline-end: 0;
  z-index: 60;
  min-inline-size: 200px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-hover);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
    visibility var(--dur) var(--ease);
}
.country-switcher.is-open .country-switcher__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.country-switcher__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 8px 10px;
  border-radius: var(--radius-md);
  font-size: 14px;
  color: var(--color-on-surface);
  text-decoration: none;
}
.country-switcher__item:hover {
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
.country-switcher__item.is-current {
  font-weight: 700;
}
.country-switcher__item.is-current::after {
  content: "✓";
  margin-inline-start: auto;
  color: var(--color-primary);
}

/* Drawer context: dark-on-light toggle, static expanding list (no overlay).
   ⚠️ The city picker reuses .country-switcher's markup but carries
   `town-switcher--drawer`, NOT `country-switcher--drawer` — so it matched none
   of this and kept the RED-header palette inside the white drawer: white text
   and a white border on white. The city control was invisible in the mobile
   menu on /sa and /ae. Every selector here lists both modifiers for that
   reason; adding a new switcher means adding it here too. */
.country-switcher--drawer,
.town-switcher--drawer {
  inline-size: 100%;
}
.country-switcher--drawer .country-switcher__toggle,
.town-switcher--drawer .country-switcher__toggle {
  inline-size: 100%;
  color: var(--color-on-surface);
  background: var(--color-background);
  border-color: var(--color-hairline);
}
.country-switcher--drawer .country-switcher__caret,
.town-switcher--drawer .country-switcher__caret {
  margin-inline-start: auto;
}
.country-switcher--drawer .country-switcher__menu,
.town-switcher--drawer .country-switcher__menu {
  position: static;
  min-inline-size: 0;
  margin-block-start: var(--space-xs);
  padding-inline: 0;
  border: 0;
  box-shadow: none;
  opacity: 1;
  visibility: visible;
  transform: none;
  display: none;
}
.country-switcher--drawer.is-open .country-switcher__menu,
.town-switcher--drawer.is-open .country-switcher__menu {
  display: block;
}

/* Language switcher (Polylang, e.g. /ma AR↔FR) — compact pill toggle, no
   dropdown/JS. Two plain links; the active language is the filled pill. */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  block-size: 40px;
  padding: 3px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-full);
}
.lang-switch__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  block-size: 32px;
  padding-inline: 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  color: rgba(255, 255, 255, 0.9);
  text-decoration: none;
  border-radius: var(--radius-full);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.lang-switch__item:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
.lang-switch__item.is-current {
  background: #fff;
  color: var(--color-primary, #8f000d);
}
.lang-switch__item:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
/* Drawer: full-width row inside the mobile menu. */
.drawer__lang {
  margin-block-start: var(--space-md);
}
.drawer__lang-label {
  display: block;
  margin-block-end: var(--space-xs);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-on-background, #1a1c1c);
}
.lang-switch--drawer {
  display: flex;
  inline-size: 100%;
  border-color: var(--color-hairline);
}
/* ⚠️ The colours above this block are tuned for the RED header bar (white text,
   white hairline, white pill for the current language). Inside the drawer the
   background is --color-surface-card (white), so the inherited white made the
   NON-current language invisible — «Français» / "English" simply could not be
   seen in the mobile menu on /ma and /ae. Repaint dark-on-light here, the same
   way .country-switcher--drawer does, and fill the current pill with the brand
   colour so "which language am I on" still reads at a glance. */
.lang-switch--drawer .lang-switch__item {
  flex: 1 1 0;
  color: var(--color-on-surface);
}
.lang-switch--drawer .lang-switch__item:hover {
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
  color: var(--color-primary);
}
.lang-switch--drawer .lang-switch__item.is-current {
  background: var(--color-primary);
  color: #fff;
}
.lang-switch--drawer .lang-switch__item:focus-visible {
  outline-color: var(--color-primary);
}

/* Hamburger only on small screens */
.nav-toggle {
  display: none;
}

/* ---------- 2. Primary Nav (inline in the red header bar) ---------- */
.main-nav {
  min-inline-size: 0; /* allow the flex item to shrink instead of overflowing */
  position: relative; /* containing block for the mega panel — sits OUTSIDE the
                         overflow-x scroll list below, so the panel isn't clipped */
}

.main-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  overflow-x: auto;
  scrollbar-width: none;
}
.main-nav__list::-webkit-scrollbar {
  display: none;
}

.main-nav__link {
  display: block;
  white-space: nowrap;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.82);
  transition: color var(--dur) var(--ease);
}
.main-nav__link:hover {
  color: #fff;
}
.main-nav__link.is-active {
  color: #fff;
}

/* ---------- Mobile Drawer ---------- */
.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(26, 26, 26, 0.5);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.drawer-backdrop.is-open {
  opacity: 1;
}

.drawer {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0; /* slides from the right for RTL, auto-flips for LTR */
  z-index: 60;
  inline-size: min(320px, 85vw);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card-hover);
  transform: translateX(100%);
  transition: transform 240ms var(--ease);
  display: flex;
  flex-direction: column;
  padding: var(--space-md);
  overflow-y: auto; /* let the menu scroll when it's taller than the viewport */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
/* In LTR the drawer sits on the left, so flip the hidden transform */
:dir(ltr) .drawer {
  transform: translateX(-100%);
}
.drawer.is-open {
  transform: translateX(0);
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block-end: var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
}
.drawer__close {
  color: var(--color-on-surface);
}
.drawer__close:hover {
  background: var(--color-surface-container);
  color: var(--color-on-surface);
}

.drawer__country {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-block: var(--space-md);
}
.drawer__country-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-secondary);
}
.drawer__country-select {
  font: inherit;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background: var(--color-background);
  color: var(--color-on-surface);
}

.drawer__list {
  display: flex;
  flex-direction: column;
}
.drawer__list a {
  display: block;
  padding: var(--space-md) var(--space-sm);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-on-surface);
  border-radius: var(--radius-md);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.drawer__list a:hover {
  background: var(--color-surface-container-low);
}
.drawer__list a.is-active {
  color: var(--color-primary);
}

body.no-scroll {
  overflow: hidden;
}

/* The [hidden] attribute must win over the display rules above */
.drawer[hidden],
.drawer-backdrop[hidden] {
  display: none;
}

/* ---------- Main-menu mega panels (supermarkets + coupons) ----------
   Desktop: hover/focus panel anchored to .main-nav (escapes the nav list's
   overflow clipping). Drawer: a tap-to-expand accordion of the same markup.
   `.has-mega` is auto-added to any item carrying a mega-* panel class
   (mega-supermarkets/appliances/mobile/electronics or mega-coupons). */

/* The flagged menu item gets a caret to signal the panel — points DOWN by
   default, flips UP when the panel opens (like the country switcher). Physical
   borders (not logical) so the chevron stays vertical under RTL. */
.main-nav__list .has-mega > .main-nav__link::after {
  content: "";
  display: inline-block;
  inline-size: 7px;
  block-size: 7px;
  margin-inline-start: 6px;
  vertical-align: 2px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg); /* down */
  opacity: 0.85;
  transition: transform var(--dur) var(--ease);
}
.main-nav .has-mega:hover > .main-nav__link::after,
.main-nav .has-mega:focus-within > .main-nav__link::after,
.main-nav .has-mega.is-open > .main-nav__link::after {
  transform: rotate(225deg); /* up */
}

/* ----- Desktop panel ----- */
.store-mega--desktop {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  inline-size: min(760px, 92vw);
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: 0 16px 44px rgba(26, 26, 26, 0.18);
  padding: var(--space-lg);
  z-index: 60;
  /* hidden until hover/focus */
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.18s var(--ease), transform 0.18s var(--ease),
    visibility 0.18s var(--ease);
}
.main-nav .has-mega:hover > .store-mega--desktop,
.main-nav .has-mega:focus-within > .store-mega--desktop,
.main-nav .has-mega.is-open > .store-mega--desktop {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.store-mega__heading {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--color-secondary);
  margin-block-end: var(--space-sm);
}
.store-mega__featured {
  margin-block-end: var(--space-md);
  padding-block-end: var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
}
.store-mega__row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--space-sm);
}
.store-mega__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-xs) var(--space-sm);
}

/* One store cell */
.store-mega__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 6px 8px;
  border-radius: var(--radius-md);
  color: var(--color-on-surface);
  min-block-size: 44px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.store-mega__item:hover {
  background: var(--color-surface-container-low);
  color: var(--color-primary);
}
/* Featured cells: stacked, boxed, logo bigger */
.store-mega__item.is-featured {
  flex-direction: column;
  gap: 6px;
  text-align: center;
  padding: var(--space-sm);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
}
.store-mega__logo {
  inline-size: 30px;
  block-size: 30px;
  object-fit: contain;
  border-radius: 6px;
  flex-shrink: 0;
}
.store-mega__item.is-featured .store-mega__logo {
  inline-size: 46px;
  block-size: 46px;
}
.store-mega__logo--initial {
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
  font-weight: 700;
  font-size: 14px;
}
.store-mega__item.is-featured .store-mega__logo--initial {
  font-size: 18px;
}
.store-mega__name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.25;
}

/* ----- Coupon-category row (coupons mega only) ----- */
.store-mega__cats {
  margin-block-end: var(--space-md);
  padding-block-end: var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
}
.store-mega__catrow {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-sm);
}
.store-mega__item--cat {
  flex-direction: column;
  gap: 6px;
  text-align: center;
}
.store-mega__icon {
  display: grid;
  place-items: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: var(--radius-full);
  background: var(--color-surface-container-low);
  /* duotone palette derived from the brand colour (matches the homepage tiles) */
  --icon-fg: var(--color-primary);
  --icon-tint: #eccac6;
  --icon-tint: color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.store-mega__item--cat:hover .store-mega__icon {
  background: #fdecec;
  --icon-tint: color-mix(in srgb, var(--color-primary) 24%, transparent);
}
.store-mega__icon svg {
  inline-size: 24px;
  block-size: 24px;
  display: block;
}
.store-mega__icon .duo-tint {
  fill: var(--icon-tint);
}
.store-mega__icon .duo-fg {
  fill: var(--icon-fg);
}
.store-mega__icon .duo-stroke {
  fill: none;
  stroke: var(--icon-fg);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ----- Drawer accordion (mobile) ----- */
.store-mega--drawer {
  display: none;
  padding-block: var(--space-sm);
  padding-inline-start: var(--space-sm);
}
.drawer__list .has-mega.is-open .store-mega--drawer {
  display: block;
}
.store-mega--drawer .store-mega__row,
.store-mega--drawer .store-mega__grid {
  grid-template-columns: repeat(2, 1fr);
}
.store-mega--drawer .store-mega__catrow {
  grid-template-columns: repeat(3, 1fr);
}
.store-mega--drawer .store-mega__icon {
  inline-size: 34px;
  block-size: 34px;
}
.store-mega--drawer .store-mega__featured {
  margin-block-end: var(--space-sm);
  padding-block-end: var(--space-sm);
}
.store-mega--drawer .store-mega__item.is-featured {
  flex-direction: row;
  text-align: start;
  border: 0;
  padding: 6px 8px;
}
.store-mega--drawer .store-mega__item.is-featured .store-mega__logo {
  inline-size: 30px;
  block-size: 30px;
}
.store-mega--drawer .store-mega__name {
  color: var(--color-on-surface);
}
/* Caret on the drawer parent, rotates when open */
.drawer__list .has-mega > a {
  position: relative;
}
.drawer__list .has-mega > a::after {
  content: "";
  position: absolute;
  inset-inline-end: 4px;
  inset-block-start: 50%;
  inline-size: 8px;
  block-size: 8px;
  margin-block-start: -6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg); /* down */
  transition: transform var(--dur) var(--ease);
}
.drawer__list .has-mega.is-open > a::after {
  transform: rotate(225deg); /* up */
}

/* ----- Homepage store + section sliders (admin preview) -----
   These reuse the coupon slider chrome verbatim (.coupon-slider / .coupon-track /
   .slider-arrow / .coupon-slide / .swipe-hint + initCouponSlider). Only the card
   face is bespoke, and each track just overrides how many cards show per view. */
.home-stores .coupon-track,
.section-tiles .coupon-track {
  --visible: 3.2;
}
@media (min-width: 640px) {
  .home-stores .coupon-track,
  .section-tiles .coupon-track {
    --visible: 5;
  }
}
@media (min-width: 1024px) {
  .home-stores .coupon-track {
    --visible: 7;
  }
  .section-tiles .coupon-track {
    --visible: 6;
  }
}
/* Store card face (logo + name), same surface/elevation as a coupon card. */
.store-scard {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  block-size: 100%;
  min-block-size: 132px;
  padding: var(--space-md) var(--space-sm);
  background: var(--color-surface-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  color: var(--color-on-surface);
  text-align: center;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease),
    color var(--dur) var(--ease);
}
.store-scard:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
  color: var(--color-primary);
}
.store-scard__media {
  display: grid;
  place-items: center;
  inline-size: 64px;
  block-size: 64px;
}
.store-scard__logo {
  max-inline-size: 100%;
  max-block-size: 100%;
  object-fit: contain;
  border-radius: 8px;
}
.store-scard__logo--initial {
  inline-size: 100%;
  block-size: 100%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
  font-weight: 700;
  font-size: 22px;
}
.store-scard__name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
}
/* Section card: illustrated icon (WebP) + label, centered. */
.store-scard--section {
  min-block-size: 116px;
}
.store-scard--section .store-scard__name {
  font-size: 14px;
}
.store-scard__img {
  display: block;
  block-size: 60px;
  inline-size: auto;
  max-inline-size: 100%;
  object-fit: contain;
}
.store-scard__icon {
  display: grid;
  place-items: center;
  inline-size: 48px;
  block-size: 48px;
  border-radius: var(--radius-full);
  background: var(--color-surface-container-low);
  /* Duotone palette from the brand colour (fallback hex before color-mix). */
  --icon-fg: var(--color-primary);
  --icon-tint: #eccac6;
  --icon-tint: color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.store-scard:hover .store-scard__icon {
  background: #fdecec;
  --icon-tint: color-mix(in srgb, var(--color-primary) 24%, transparent);
}
.store-scard__icon svg {
  inline-size: 28px;
  block-size: 28px;
  display: block;
}
.store-scard__icon .duo-tint {
  fill: var(--icon-tint);
}
.store-scard__icon .duo-fg {
  fill: var(--icon-fg);
}
.store-scard__icon .duo-stroke {
  fill: none;
  stroke: var(--icon-fg);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Ad slots ---------- */
.ad-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-block: var(--space-lg);
  /* Never let an ad wrapper exceed the column it sits in. */
  max-inline-size: 100%;
  /* Backstop for AdSense's mobile full-width breakout, which mis-offsets on RTL
     and pushes the unit off the left viewport edge: clip anything that still
     escapes the column instead of letting it bleed off-screen. */
  overflow-x: clip;
}
.ad-wrap--center {
  margin-block: var(--space-xl);
}
/* In-article ads use the full viewport width on phones. The page gutter is 16px a side,
   so cancelling it symmetrically makes the unit exactly viewport-wide — 380px → 412px on a
   412px screen (+8%). Symmetric by construction, so it cannot mis-offset in RTL the way
   AdSense's own full-width breakout did. box-sizing is border-box globally, so no overflow. */
@media (max-width: 599px) {
  .ad-wrap--bleed {
    margin-inline: calc(var(--gutter) * -1);
    /* .ad-wrap caps every wrapper at max-inline-size:100% of its column. Without
       releasing that cap here the negative margin cannot WIDEN the element — it only
       SHIFTS it, which lands it flush against the inline-start edge and leaves the
       whole 32px gap on the other side (measured 380px at left=32/right=0 on a 412px
       screen). That is the asymmetry this change exists to avoid, so the cap must go. */
    max-inline-size: none;
  }
}
/* No "إعلان" label. The helper printed it BEFORE it could know whether the unit
   would fill, so on a low-fill page most labels sat over empty space (22 labels
   on one live Carrefour flyer). AdSense requires ads to be DISTINGUISHABLE from
   content — which Google's own frame + AdChoices marker already do — not
   labelled. Do not re-add. */
.ad-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-container-high);
  /* border: 1px solid var(--color-outline-variant); */
  border-radius: var(--radius-md);
  color: var(--color-secondary);
  font-size: 13px;
  /* fixed dimensions reserve space => no layout shift (good CWV + AdSense) */
}
.ad-slot--leaderboard {
  inline-size: 100%;
  max-inline-size: 728px;
  block-size: 90px;
}
.ad-slot--rectangle {
  inline-size: 300px;
  block-size: 250px;
}
.ad-slot--large {
  inline-size: 336px;
  block-size: 280px;
}

/* Live AdSense <ins> units: responsive, with a reserved min-height so the page
   doesn't shift when the ad paints (good CWV). Width fills the wrap; max keeps
   it sane on wide screens. The fixed-size .ad-slot--* boxes above are only the
   staging/local placeholders. */
.ad-unit {
  display: block;
  inline-size: 100%;
  max-inline-size: 100%;
  margin-inline: auto;
}
/* Top banner: data-ad-format="horizontal" + full-width-responsive="false", so AdSense
   picks from the banner sizes that fit the container (320×50, 320×100, 468×60, 728×90).
   One fixed CSS size only ever let ONE size bid — measured 23.70% fill, the worst unit on
   the account. The max-block-size below is a guard, not the ad size: every horizontal
   creative is 50-100px tall, so it should never clip. "auto" is deliberately NOT used —
   it built a near-full-screen creative on mobile (see functions.php).
   ⚠️ 100px AT EVERY WIDTH ON PURPOSE — DO NOT RE-ADD A 90px CAP ABOVE 800px. A 728×90
   ad in a 100px box just carries 10px of invisible slack, but a 320×100 served on a
   wide screen would be clipped by exactly 10px. The tighter cap bought nothing and was
   the only known way this unit could cut off a creative. */
.ad-unit--leaderboard {
  display: block;
  inline-size: 100%;
  max-inline-size: 728px;
  max-block-size: 100px;
}
.ad-unit--rectangle,
.ad-unit--large {
  min-block-size: 250px;
  max-inline-size: 336px;
}
.ad-unit--large {
  min-block-size: 280px;
}
/* In-grid in-feed ad: span the full grid row so the card rhythm isn't broken. */
.ad-wrap--cell {
  grid-column: 1 / -1;
}
/* .ad-wrap sets display:flex, which beats the UA's [hidden]{display:none}
   (same specificity, author sheet wins). The coupon JS collapses a dead ad box
   with wrap.hidden = true, so it needs this rule to actually disappear. */
.ad-wrap[hidden] {
  display: none;
}

/* Google AUTO ads (not our slots) drop in-page ads INSIDE the offer grids.
   Trigger: Google's own Auto-ads experiment "Banner ads" (2026-09-11 → 09-19,
   +10% revenue, auto-applied to every visitor on 09-19). As a plain grid item
   each ad took ONE card cell: half the row on a phone (182px), too narrow for
   most ads. Measured on the EG homepage 2026-09-19: 7 of the first grid's 19
   items were auto ads; the empty ones left blank holes and the rest showed
   Google's "اكتشاف المزيد" topics squeezed into half a column.
   1) Span the full row, like our own .ad-wrap--cell. The grid is
      `row dense`, so the cards backfill and no hole is left, and the ad is
      requested at full width (380px on a phone), which fills better.
   2) Hide it ONLY when AdSense reports "unfilled" — Google's own documented
      rule (support.google.com/adsense/answer/10762946). NOT "unfill-*":
      "unfill-optimized" means the "Fill empty in-page ads" setting filled the
      box with Google's topic panel, which AdSense counts as impressions
      (format "Unfilled fallback term"). Hiding it would serve counted Google
      content into an invisible box. At full width it renders as a tidy panel.
      To remove those panels, turn that setting off in AdSense: they then come
      back "unfilled" and this rule hides them. */
.grid > .google-auto-placed {
  grid-column: 1 / -1;
}
.grid > .google-auto-placed:has(> ins.adsbygoogle[data-ad-status="unfilled"]) {
  display: none !important;
}

/* ---------- Coupon card shown when an ad slot came back unfilled ----------
   Deliberately NOT named ad-*: it renders as a SIBLING of .ad-wrap so an
   ad-blocking reader — who by definition sees empty inventory — still gets the
   coupon. Every value below is an existing token; no new colour, radius,
   shadow or font. The site has NO dark mode — there is not one colour-scheme
   media query in this file. Do not add the only dark block in the codebase.
   (Wording kept free of the literal query name so a grep for it still
   answers "none" honestly.) */
.offer-coupon {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-block: var(--space-lg);
  max-inline-size: 100%;
}
.offer-coupon[hidden] {
  display: none;
}
/* ---------- §2d — the store-top coupon: a ticket, in the shop's colour ----------
   Redesigned 2026-09-19 on the owner's pick (mockup "JHY66 Ticket Card"): the
   shop's brand colour as the ground, one short headline, and a white ticket -
   edge notches, a dashed tear line, a «انسخ الكود» stub - in which the CODE is
   the largest thing on the card.
   Colours are per store through the --tk-* properties. The default is the
   3orod red; a store opts into its own palette with one
   `.store-coupon[data-store="..."]` block (noon is the first).
   ⚠ Every rule is scoped `.store-coupon .x` (0,2,0) ON PURPOSE. The card is
   injected INTO `.offer__content`, whose `p { margin-block:16px }` and
   `img { inline-size:100%; margin-block:16px }` are (0,1,1) - a single-class
   rule loses to them, which is how a logo got stretched across a card twice.
   Line-heights are explicit because the body sets 28px.
   ⚠ The button keeps the shared `.coupon-code` class (initCouponCopy and the
   coupon analytics bind on it), so it also receives the global `.coupon-code`,
   `.coupon-code:hover` and `.coupon-code.is-copied` rules, which sit LATER in
   this file. Rest state is therefore (0,2,0) and hover/copied (0,3,0) - do not
   flatten them or the global dashed pink box comes back.
   ⚠ The stub's LABEL is vertical; the stub BOX is not. A border on a
   vertical-writing element maps its inline sides to top/bottom, which drew the
   tear line sideways in the first mockup - so the line lives on __main.
   ⚠ No class here may contain "ad": cosmetic ad-block lists match those
   letters, and a blocked reader is the best audience this card has. */
.store-coupon {
  --tk-bg: var(--color-primary-container);
  --tk-ink: #fff;
  --tk-sub: rgba(255, 255, 255, 0.88);
  --tk-code: var(--color-primary);
  --tk-tag-bg: #fff;
  --tk-tag-ink: var(--color-primary);
  --tk-chip: #fff;
  --tk-dash: rgba(143, 0, 13, 0.35);
  margin: var(--space-md) auto var(--space-lg);
  max-inline-size: 620px;
}
/* Noon: the card takes the logo file's own yellow (#fce818, sampled from
   Noon_Featured.jpg), so the logo sits on it with no box around it. */
.store-coupon[data-store="noon"] {
  --tk-bg: #fce818;
  --tk-ink: #1c1d1f;
  --tk-sub: #4a4520;
  --tk-code: #1c1d1f;
  --tk-tag-bg: #1c1d1f;
  --tk-tag-ink: #fce818;
  --tk-chip: transparent;
  --tk-dash: rgba(28, 29, 31, 0.4);
}
.store-coupon .store-coupon__card {
  background: var(--tk-bg);
  color: var(--tk-ink);
  border-radius: 16px;
  padding: 14px var(--space-md) var(--space-md);
}
.store-coupon .store-coupon__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-block-size: 36px;
}
.store-coupon .store-coupon__chip {
  display: flex;
  align-items: center;
  background: var(--tk-chip);
  border-radius: 8px;
  padding: 3px 6px;
}
.store-coupon .store-coupon__logo {
  display: block;
  inline-size: auto;
  block-size: 40px;
  max-inline-size: 120px;
  object-fit: contain;
  margin: 0;
  border-radius: 0;
}
.store-coupon .store-coupon__name {
  font-weight: 800;
  font-size: 20px;
  line-height: 1.2;
  color: var(--tk-ink);
}
.store-coupon .store-coupon__tag {
  background: var(--tk-tag-bg);
  color: var(--tk-tag-ink);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
  padding: 4px 11px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.store-coupon .store-coupon__deal {
  font-size: 22px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--tk-ink);
  margin: 10px 0 0;
  text-wrap: balance; /* 320px phones: «رصيد مسترجع / حتى 50 ﷼», not a lone «ريال» */
}
.store-coupon .store-coupon__deal b {
  font-weight: 800;
  color: inherit;
}
.store-coupon .store-coupon__sub {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--tk-sub);
  margin: 2px 0 0;
}
/* The ticket - rest state (0,2,0) beats the global `.coupon-code` (0,1,0). */
.store-coupon .store-coupon__ticket {
  position: relative;
  display: grid;
  grid-template-columns: 54px 1fr;
  gap: 0;
  align-items: stretch;
  inline-size: 100%;
  min-block-size: 84px;
  margin: 14px 0 0;
  padding: 0;
  background: #fff;
  border: 0;
  border-radius: 12px;
  color: var(--tk-code);
  font: inherit;
  cursor: pointer;
}
.store-coupon .store-coupon__ticket:hover {
  background: #fafafa;
}
/* Edge notches, cut in the card's own ground colour. Physical left/right on
   purpose: they are symmetric, so direction does not matter. */
.store-coupon .store-coupon__ticket::before,
.store-coupon .store-coupon__ticket::after {
  content: "";
  position: absolute;
  top: 50%;
  inline-size: 18px;
  block-size: 18px;
  background: var(--tk-bg);
  border-radius: 50%;
  transform: translateY(-50%);
}
.store-coupon .store-coupon__ticket::before {
  left: -9px;
}
.store-coupon .store-coupon__ticket::after {
  right: -9px;
}
/* Tear-line notches, centred on the stub/code seam 54px from the start edge.
   inset + negative margin (both logical) centres them in RTL and LTR alike -
   /ma/fr/ is LTR. */
.store-coupon .store-coupon__tn {
  position: absolute;
  inset-inline-start: 54px;
  margin-inline-start: -7px;
  inline-size: 14px;
  block-size: 14px;
  background: var(--tk-bg);
  border-radius: 50%;
}
.store-coupon .store-coupon__tn--t {
  top: -7px;
}
.store-coupon .store-coupon__tn--b {
  bottom: -7px;
}
.store-coupon .store-coupon__stub {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 800;
  line-height: 1.2;
}
.store-coupon .store-coupon__idle,
.store-coupon .store-coupon__done {
  writing-mode: vertical-rl;
}
.store-coupon .store-coupon__done {
  display: none;
}
.store-coupon .store-coupon__main {
  display: flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 0;
  padding: 10px 14px;
  border-inline-start: 2px dashed var(--tk-dash);
}
.store-coupon .store-coupon__code {
  font-family: var(--font-price);
  font-size: 44px;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1;
  direction: ltr;
  unicode-bidi: isolate;
  white-space: nowrap;
  text-align: center;
}
/* Length steps, set in PHP - the FALLBACK for browsers without container
   units (see the @supports block at the end of this section). Sized for a
   360px phone: code area ~214px, ~0.95em per character. */
.store-coupon .store-coupon__code--m {
  font-size: 32px;
}
.store-coupon .store-coupon__code--l {
  font-size: 24px;
}
.store-coupon .store-coupon__code--xl {
  font-size: 18px;
}
.store-coupon .store-coupon__code--xxl {
  font-size: 16px;
  white-space: normal;
  overflow-wrap: anywhere;
}
/* Copied - (0,3,0) beats the global `.coupon-code.is-copied` (0,2,0). */
.store-coupon .store-coupon__ticket.is-copied {
  background: #eaf8ee;
  border: 0;
  color: #1b7f3b;
}
.store-coupon .store-coupon__ticket.is-copied .store-coupon__idle {
  display: none;
}
.store-coupon .store-coupon__ticket.is-copied .store-coupon__done {
  display: block;
}
.store-coupon .store-coupon__ticket:focus-visible {
  outline: 3px solid #2563eb;
  outline-offset: 3px;
}
@media (min-width: 600px) {
  .store-coupon .store-coupon__deal {
    font-size: 26px;
  }
  .store-coupon .store-coupon__code {
    font-size: 52px;
  }
  .store-coupon .store-coupon__code--m {
    font-size: 44px;
  }
  .store-coupon .store-coupon__code--l {
    font-size: 36px;
  }
  .store-coupon .store-coupon__code--xl {
    font-size: 30px;
  }
  .store-coupon .store-coupon__code--xxl {
    font-size: 24px;
  }
}
@media (prefers-reduced-motion: no-preference) {
  .store-coupon .store-coupon__ticket {
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
  }
}
/* Fit the code to the ticket's REAL width, so it is never cut or split on any
   phone: 100cqi = the code area's width, --len = characters (set in PHP),
   0.95em = measured width per character incl. letter-spacing. Capped at the
   design size (44px phone / 52px wide), floored at 14px. Must stay LAST in the
   section: same specificity as the length steps above, so order decides. */
@supports (width: 1cqi) {
  .store-coupon .store-coupon__main {
    container-type: inline-size;
  }
  .store-coupon .store-coupon__code {
    font-size: clamp(14px, calc(100cqi / (var(--len, 5) * 0.95)), 44px);
  }
  @media (min-width: 600px) {
    .store-coupon .store-coupon__code {
      font-size: clamp(14px, calc(100cqi / (var(--len, 5) * 0.95)), 52px);
    }
  }
}
/* The horizontal ticket: logo · text · code. Capped so it reads as a card and
   not a full-width banner — it was sprawling across the whole content column
   on desktop with very little in it. */
.offer-coupon__card {
  inline-size: 100%;
  max-inline-size: 560px;
  margin-inline: auto;
  background: var(--color-surface-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-sm);
  display: grid;
  grid-template-columns: 92px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
}
/* A coupon with no featured image: drop the logo track, or the text would be
   squeezed into it. */
.offer-coupon__card--bare {
  grid-template-columns: 1fr auto;
}
.offer-coupon__logo {
  aspect-ratio: 2 / 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-card);
  padding: 4px;
}
/* contain, NEVER cover. cover cropped the noon wordmark — a brand mark must be
   shown whole or not at all.
   ⚠ Double-scoped for the SAME reason as the text rules below: `.offer__content
   img` is (0,1,1), sits later in this file, and was overriding a single-class
   rule with `block-size: auto` + `margin-block: 16px`. That let a 200×200
   square logo render 84×84 inside the 92×46 box and get clipped by
   `overflow: hidden` — i.e. still visibly cropped, by CSS this time, even after
   the file itself was fixed. Reset margin and radius here too. */
.offer-coupon .offer-coupon__logo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  margin: 0;
  border-radius: 0;
}
/* ⚠ These three are scoped under .offer-coupon ON PURPOSE — the card is
   injected INTO the article body, so it inherits `.offer__content` typography:
   `line-height: 28px` and `.offer__content p { margin-block: 16px }`. That rule
   is (0,1,1) and beat a plain `.offer-coupon__offer` (0,1,0), so the card
   measured 157px tall at 412px with 12px terms text on 28px leading. Two
   classes (0,2,0) win it back. Every line-height is explicit for the same
   reason — do not drop them and do not lower this specificity. */
.offer-coupon .offer-coupon__kick {
  display: block;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--color-primary);
  margin: 0;
}
.offer-coupon .offer-coupon__offer {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--color-primary-container);
  margin: 2px 0 0;
}
.offer-coupon .offer-coupon__terms {
  font-size: 12px;
  line-height: 1.4;
  color: var(--color-muted);
  margin: 2px 0 0;
}
/* The code column IS the ticket stub: a dashed tear line instead of the shared
   component's full dashed box, and sized to its content rather than the 100%
   width it uses inside a stacked coupon card. Higher specificity than the base
   `.coupon-code` rules, so it wins wherever they conflict; `.is-copied` and
   `:hover` tie on specificity and come later in this file, so the green copied
   state still overrides it. display:flex also neutralises the base component's
   `grid-column` placements on the value/icon. */
.offer-coupon .coupon-code {
  display: flex;
  align-items: center;
  gap: 6px;
  inline-size: auto;
  margin-block-start: 0;
  padding: var(--space-xs) var(--space-md);
  background: transparent;
  border: 0;
  border-inline-start: 1px dashed var(--color-primary-container);
  border-radius: 0;
}
/* Under 400px the terms line is the first thing to go — dropping a line beats
   shrinking the type on the smallest phones (360px is the most common). */
@media (max-width: 399px) {
  .offer-coupon__card {
    grid-template-columns: 68px 1fr auto;
  }
  .offer-coupon__terms {
    display: none;
  }
  .offer-coupon .coupon-code {
    padding-inline: var(--space-sm);
  }
}
.ad-unit--infeed,
.ad-unit--in_article {
  min-block-size: 120px;
}
/* Placeholder boxes for the in-feed / in-article units (staging/local). */
.ad-slot--infeed,
.ad-slot--in_article {
  inline-size: 100%;
  max-inline-size: 728px;
  block-size: 120px;
}

/* ---------- Main / page intro ---------- */
.site-main {
  padding-block-end: var(--margin-desktop);
}

.block {
  margin-block-start: var(--space-xl);
}

.page-intro {
  margin-block-start: var(--space-lg);
}
.breadcrumb {
  font-size: 14px;
  color: var(--color-secondary);
  margin-block-end: var(--space-md);
}
.breadcrumb a:hover {
  color: var(--color-primary);
}
.breadcrumb__sep {
  margin-inline: var(--space-xs);
}
.page-title {
  font-size: 24px;
  font-weight: 700;
  line-height: 32px;
  margin-block-end: var(--space-sm);
}
.page-lead {
  color: var(--color-muted);
  font-size: 16px;
  line-height: 26px;
  max-inline-size: 70ch;
}

.section-title {
  font-size: 28px;
  font-weight: 700;
  line-height: 36px;
  color: var(--color-primary-container);
  margin-block-end: var(--space-lg);
}

/* ---------- Grids ---------- */
.grid {
  display: grid;
  gap: var(--gutter);
  /* A full-width in-feed ad (.ad-wrap--cell, grid-column:1/-1) can land mid-row
     when the ad position (after card 4) isn't a multiple of the current column
     count — e.g. at the 3-col breakpoint it leaves 2 empty cells before the ad.
     `dense` backfills those cells with the following cards, so no gaps at any
     breakpoint. No effect on uniform grids (only reflows around the spanning ad);
     DOM/reading order is unchanged. */
  grid-auto-flow: row dense;
}
.grid--2 {
  grid-template-columns: 1fr;
}
.grid--3 {
  grid-template-columns: 1fr;
}
/* Offers grid: A4-portrait cards, so 2-up even on phones (a full-width
   single column would be ~1.4× the screen tall). 2 → 3 → 4 across. */
.grid--4 {
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) {
  .grid--2 {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid--3 {
    grid-template-columns: repeat(2, 1fr);
  }
  .grid--4 {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 900px) {
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .grid--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ---------- Offers vertical grid (homepage sections) ----------
   ~90% of traffic is mobile and users mostly browse the homepage, so the offer
   sections are a VERTICAL grid (no horizontal swipe): 2-up on phones → 3 → 4
   across, reusing .grid.grid--4 (layout lives there — no second grid system).
   Each section shows its first 12 cards; the rest come in via the per-section
   "load more" button below (.btn-load-more). The container also carries
   .offers-grid / .js-offers-grid as append hooks for the load-more JS. */

/* Per-section "load more" (§4). */
.section-more {
  display: flex;
  justify-content: center;
  margin-block-start: var(--space-lg);
}
.btn-load-more {
  position: relative; /* anchor for the loading spinner overlay */
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  color: var(--color-primary);
  background: var(--color-surface-card);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-lg); /* match the offer cards */
  padding: 0.7em 2em;
  min-block-size: 44px; /* comfortable tap target */
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}
.btn-load-more:hover {
  background: var(--color-primary);
  color: #fff;
}
.btn-load-more:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.btn-load-more[aria-busy="true"] {
  opacity: 0.7;
  cursor: progress;
}
.btn-load-more--error {
  color: var(--color-primary);
  border-color: var(--color-primary);
}

/* Loading state: keep the label in flow but invisible so the button width
   never changes, and overlay a pure-CSS spinner centred over it. */
.btn-load-more[aria-busy="true"] .btn-load-more__label {
  visibility: hidden;
}
.btn-load-more__spinner {
  display: none;
}
.btn-load-more[aria-busy="true"] .btn-load-more__spinner {
  display: block;
  position: absolute;
  inset: 0;
  margin: auto; /* inset:0 + margin:auto + fixed size = perfect centre, RTL/LTR alike */
  inline-size: 1.1em;
  block-size: 1.1em;
  border: 2px solid currentColor;
  border-block-start-color: transparent; /* the gap that reveals the spin */
  border-radius: 50%;
  animation: btn-load-more-spin 0.6s linear infinite;
}
@keyframes btn-load-more-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .btn-load-more[aria-busy="true"] .btn-load-more__spinner {
    animation: none; /* static ring — still a clear "busy" cue */
  }
}

/* ---------- Offer card ---------- */
.offer-card {
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  /* No overflow:hidden here — the town/region picker dropdown must escape the
     card bounds on mobile. The image is clipped independently by
     .offer-card__media (its own radius + overflow:hidden, inset by the link
     padding), so the card's rounded corners don't need a card-level clip. */
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.offer-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.offer-card__link {
  display: flex;
  flex-direction: column;
  block-size: 100%;
  padding: var(--space-sm) var(--space-sm) var(--space-md);
}
.offer-card__media {
  position: relative; /* anchor for the "منتهي" expired badge */
  aspect-ratio: 210 / 297; /* A4 portrait — matches flyer feature images, no crop */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-container-low);
  margin-block-end: var(--space-sm);
}
.offer-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
/* Expired offer (within the grace window) — badge + dimmed image. */
.offer-card__badge {
  position: absolute;
  inset-block-start: var(--space-xs);
  inset-inline-start: var(--space-xs);
  z-index: 1;
  background: var(--color-primary);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  padding: 5px 9px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
}
/* Pinned "مجلة العروض" badge — the store's full catalogue flyer, leading its hub.
   Same component as the expired badge, opposite intent: the amber highlight tint
   rather than the Firebrick alarm. Only one of the two ever renders. */
.offer-card__badge--pinned {
  background: var(--color-badge-bg);
  color: var(--color-badge-text);
}
.offer-card--expired .offer-card__media img {
  opacity: 0.65;
}
.offer-card__meta--expired {
  color: var(--color-primary);
  font-weight: 600;
}
.offer-card__title {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--color-primary-container);
  margin-block-end: var(--space-xs);
}
/* Branch/scope suffix on the card title (TOWN-OFFERS-PHASE3, §B/§E) — the town's
   branches on a town page, or the store-hub scope label. Reads as secondary. */
.offer-card__scope {
  font-weight: 500;
  font-size: 0.92em;
  color: var(--color-secondary, #6a6a6a);
}
.offer-card__meta {
  margin-block-start: auto;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--color-secondary);
  font-size: 14px;
  padding-block-start: var(--space-sm);
}

/* ---------- Grouped multi-region offer card ----------
   One store's regional editions in a single card + a region picker. overflow is
   visible so the picker dropdown can escape the card bounds. */
.offer-card--group {
  position: relative;
  overflow: visible;
}
/* While its picker is open, lift the whole card above the grid cards below it
   (set by initRegionPicker on the closest .offer-card) so the dropdown — which
   overflows the card downward into the next row — paints ON TOP of those cards
   instead of behind them. Sibling cards paint in DOM order otherwise, so the
   next row would clip the panel's tail. */
.offer-card.is-picker-open {
  z-index: 5;
}
.offer-card__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 100%;
  block-size: 100%;
  font-size: 48px;
  font-weight: 700;
  color: var(--color-primary-container);
  background: var(--color-surface-container-low);
}
/* The single red toggle sits top-start (the leading corner) and IS the affordance:
   "اختر المنطقة" + a caret that flips when the region list is open. */
.region-picker {
  position: absolute;
  inset-block-start: calc(var(--space-sm) + var(--space-xs));
  inset-inline-end: calc(var(--space-sm) + var(--space-xs));
  z-index: 3;
}
.region-picker__toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--color-primary);
  color: #fff;
  border: 0;
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-card);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1;
  padding: 7px 11px;
  min-block-size: 32px;
  cursor: pointer;
}
.region-picker__caret {
  inline-size: 13px;
  block-size: 13px;
  transition: transform var(--dur) var(--ease);
}
.region-picker.is-open .region-picker__toggle {
  background: var(--color-primary-container);
}
.region-picker.is-open .region-picker__caret {
  transform: rotate(180deg);
}
.region-picker__menu {
  position: absolute;
  inset-block-start: calc(100% + 6px);
  inset-inline-end: 0;
  /* Match the toggle button's width: .region-picker shrink-wraps the toggle (the
     menu is out-of-flow, so it doesn't widen the wrapper), so 100% here IS the
     button width. The panel sits directly under the button, same width — and,
     being that narrow, is always within the viewport on any screen, so it needs
     no viewport cap. A long town list scrolls inside a capped height instead of
     running down the page (mirrors the header town picker). */
  inline-size: 100%;
  max-block-size: min(60vh, 360px);
  overflow-y: auto;
  overscroll-behavior: contain;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-hover);
}
.region-picker__menu[hidden] {
  display: none;
}
.region-picker__menu li {
  margin: 0;
}
.region-picker__menu a {
  display: flex;
  /* The menu is only as wide as the toggle button, so a region row (name + a
     nowrap dates chunk) may not fit on one line — let it wrap to a second line
     instead of overflowing. Town rows (name only) never wrap. */
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  color: var(--color-on-surface);
  text-decoration: none;
  font-size: 14px;
}
.region-picker__menu a:hover,
.region-picker__menu a:focus {
  background: var(--color-surface-container-low);
}
.region-picker__name {
  font-weight: 600;
}
.region-picker__dates {
  color: var(--color-secondary);
  font-size: 12.5px;
  white-space: nowrap;
}

/* ---------- Single offer ---------- */
.offer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  margin-block-start: var(--space-sm);
  color: var(--color-secondary);
  font-size: 14px;
}
.offer__store,
.offer__valid {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}
.offer__store {
  font-weight: 700;
  color: var(--color-primary);
}
.offer__store:hover {
  color: var(--color-primary-container);
}

/* Single-offer branch labels (TOWN-OFFERS): "متوفر في:" + the offer's covered
   branches as plain grey chips — NOT links (the "browse all branches" button
   below is the link). Sits between the store/validity meta line and the CTA. */
.offer-branches {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs) var(--space-sm);
  margin-block-start: var(--space-sm);
}
.offer-branches__label {
  flex: none;
  color: var(--color-secondary);
  font-size: 14px;
  font-weight: 700;
}
.offer-branches-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}
.offer-branches-tags__item {
  padding: 3px 10px;
  background: color-mix(in srgb, var(--color-on-surface) 7%, transparent);
  color: var(--color-secondary);
  border-radius: var(--radius-sm);
  font-size: 13px;
  line-height: 1.6;
  white-space: nowrap;
}

/* Store hub: neutral "store not available in your city" info notice, shown only
   on the out-of-scope fallback path above the (all-offers) grid. Info, not error. */
.store-scope-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs) var(--space-md);
  margin-block: 0 var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: color-mix(in srgb, var(--color-on-surface) 5%, transparent);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  color: var(--color-on-surface);
  font-size: 14px;
}
.store-scope-notice__cta {
  color: var(--color-primary);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.store-scope-notice__cta:hover,
.store-scope-notice__cta:focus-visible {
  text-decoration: underline;
}

.offer-expired {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-block: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-badge-bg);
  color: var(--color-badge-text);
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: 600;
}
.offer-expired a {
  color: var(--color-primary);
  text-decoration: underline;
}
/* Expired offer -> the ESCAPE CARD (2026-08-20). ~2,360 people a day open an
   offer that has already ended, 93% of them from Google/Discover/shared links.
   The plain .offer-expired above stays the no-card fallback (a store with
   nothing valid right now); .offer-expired--has-card is the real answer: the
   store's biggest CURRENT offer, above the hero, so it is on screen without
   scrolling. The old text link sat here alone while the picture-card block lived
   after the whole flyer - up to 47 images down, where only ~25% of readers go. */
.offer-expired--has-card {
  display: block;
  background: var(--color-surface-container-low);
  color: var(--color-on-surface);
  border: 1px solid var(--color-hairline);
  padding: var(--space-md);
}
.offer-expired__note {
  margin: 0;
  font-weight: 700;
}
.offer-expired--has-card .offer-expired__note {
  margin-block-end: var(--space-sm);
}
/* Beats the `.offer-expired a` underline above on class count (0,2,0 > 0,1,1) -
   the card is a block, not a text link, and must not be underlined. */
.offer-expired .offer-expired__card {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  color: inherit;
  text-decoration: none;
}
.offer-expired__thumb {
  flex: 0 0 110px;
  inline-size: 110px;
  block-size: 110px;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-surface-container-low);
}
.offer-expired__thumb img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  /* Flyer page 1 is tall portrait; its TOP carries the logo and the dates, so a
     square crop anchors there rather than to the middle of the shelf photos. */
  object-fit: cover;
  object-position: center top;
}
.offer-expired__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-inline-size: 0;
}
.offer-expired__title {
  font-size: 15px;
  font-weight: 700;
  line-height: 22px;
}
.offer-expired__dates {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-muted);
}
.offer-expired__button {
  align-self: flex-start;
  margin-block-start: var(--space-xs);
  padding: 8px 14px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: 14px;
  font-weight: 700;
}
.offer-expired__card:hover .offer-expired__button,
.offer-expired__card:focus-visible .offer-expired__button {
  filter: brightness(1.12);
}
@media (min-width: 701px) {
  .offer-expired__thumb {
    flex-basis: 150px;
    inline-size: 150px;
    block-size: 150px;
  }
  .offer-expired__title {
    font-size: 17px;
    line-height: 25px;
  }
}

.offer__hero {
  margin-block: var(--space-lg);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface-container-low);
  box-shadow: var(--shadow-card);
}
.offer__hero img {
  inline-size: 100%;
  block-size: auto;
}

.offer__content {
  font-size: 16px;
  line-height: 28px;
}
.offer__content p {
  margin-block: var(--space-md);
}
/* Editorial offer bodies (e.g. mobile-network promos) are heading + list heavy,
   not just catalogue scans, so they need a section rhythm the flyer bodies never
   did. Without these, h2/ul/li fell back to UA margins + the global list reset
   (no bullets, cramped rows, uneven gaps between sections). */
.offer__content h2,
.offer__content h3 {
  margin-block: var(--space-lg) var(--space-sm);
  line-height: 1.4;
}
.offer__content h2 {
  font-size: 22px;
}
.offer__content h3 {
  font-size: 19px;
}
.offer__content ul,
.offer__content ol {
  margin-block: var(--space-sm) var(--space-md);
  padding-inline-start: 1.6em;
}
.offer__content ul {
  list-style: disc;
}
.offer__content ol {
  list-style: decimal;
}
.offer__content li {
  margin-block: var(--space-xs);
}
.offer__content a {
  color: var(--color-primary);
  text-decoration: underline;
}
/* Catalogue scans inside the body — full width, rounded, spaced. */
.offer__content img {
  inline-size: 100%;
  block-size: auto;
  border-radius: var(--radius-md);
  margin-block: var(--space-md);
}

/* Centered emphasis line used inside offer bodies (e.g. "تصفّح بالأسفل ↓"). */
.offer__content .offer-note {
  text-align: center;
  font-weight: 700;
  color: var(--color-primary);
  margin-block: var(--space-lg) var(--space-sm);
}

/* "Follow us" row — inline-SVG social buttons (no Font Awesome, no requests). */
.offer-follow {
  display: flex;
  justify-content: center;
  gap: var(--space-sm);
  margin-block: var(--space-sm) var(--space-xl);
}
.offer-follow a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: var(--radius-full);
  color: #fff;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.offer-follow a:hover {
  transform: translateY(-2px);
  opacity: 0.92;
}
.offer-follow svg {
  inline-size: 20px;
  block-size: 20px;
  fill: currentColor;
}
.offer-follow__fb {
  background: #1877f2;
}
.offer-follow__x {
  background: #000;
}
.offer-follow__tg {
  background: #229ed9;
}
.offer-follow__wa {
  background: #25d366;
}

/* Catalogue page links (wp_link_pages) */
.offer-pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-block: var(--space-lg);
  font-size: 14px;
}
.offer-pages__label {
  color: var(--color-secondary);
  font-weight: 600;
}
.offer-pages a .offer-pages__num,
.offer-pages > .offer-pages__num {
  display: inline-grid;
  place-items: center;
  min-inline-size: 36px;
  min-block-size: 36px;
  padding-inline: var(--space-sm);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  font-weight: 700;
}
.offer-pages a:hover .offer-pages__num {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
/* current page (wp_link_pages outputs it as a bare span, not a link) */
.offer-pages > .offer-pages__num {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}

/* ---------- Coupon card ---------- */
.coupon-card {
  position: relative;
  background: var(--color-surface-card);
  /* border: 1px solid var(--color-outline-variant); */
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.coupon-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.badge {
  position: absolute;
  inset-block-start: var(--space-md);
  inset-inline-end: var(--space-md);
  z-index: 2;
  background: var(--color-badge-bg);
  color: var(--color-badge-text);
  font-size: 11px;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
}
.coupon-card__media {
  aspect-ratio: 2 / 1;     /* matches 400×200 */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-container);
}
.coupon-card__media-link {
  display: block;
  block-size: 100%;
}
.coupon-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: center;
}
.coupon-card__title {
  font-size: 20px;
  font-weight: 600;
  line-height: 28px;
  text-align: center;
  color: var(--color-primary-container);
}
.coupon-card__title a {
  color: inherit;
}
.coupon-card__title a:hover {
  color: var(--color-primary);
}
.coupon-code {
  margin-block-start: auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-sm);
  inline-size: 100%;
  background: #fff;
  border: 1px dashed var(--color-primary-container);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  color: var(--color-primary-container);
  transition: background var(--dur) var(--ease);
}
.coupon-code:hover {
  background: #fff5f5;
}
.coupon-code__value {
  grid-column: 2;
  text-align: center;
  font-family: var(--font-price);
  font-weight: 800;
  letter-spacing: 0.15em;
  font-size: 16px;
}
.coupon-code__icon {
  grid-column: 3;
  justify-self: end;
}
.coupon-code__icon .icon {
  inline-size: 18px;
  block-size: 18px;
}
.coupon-code.is-copied {
  border-style: solid;
  border-color: #1b7f3b;
  color: #1b7f3b;
  background: #f0fbf3;
}

/* ---------- Section head (title + see-all + slider controls) ---------- */
.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-block-end: var(--space-lg);
}
.section-head .section-title {
  margin-block-end: 0;
}
.section-head__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.see-all {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-primary);
  white-space: nowrap;
}
.see-all:hover {
  color: var(--color-primary-container);
}
/* Chevron points toward the reading-forward direction: left on RTL (default),
   flipped to point right on LTR (French) so "Tout voir ›" reads correctly. */
.see-all .icon--sm {
  inline-size: 18px;
  block-size: 18px;
}
:dir(ltr) .see-all .icon--sm {
  transform: scaleX(-1);
}

/* ---------- Slider arrows (overlaid on the sides) ---------- */
.coupon-slider {
  position: relative;
}
.slider-arrow {
  position: absolute;
  inset-block-start: calc(50% - 6px); /* offset for the track's -6px margin */
  transform: translateY(-50%);
  z-index: 3;
  inline-size: 40px;
  block-size: 40px;
  display: none; /* shown ≥560px; mobile uses swipe */
  place-items: center;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-full);
  background: var(--color-surface-card);
  color: var(--color-on-surface);
  box-shadow: 0 4px 14px rgba(26, 26, 26, 0.16);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease), opacity var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
@media (min-width: 560px) {
  .slider-arrow {
    display: grid;
  }
}
/* prev → start side (right in RTL, left in LTR); next → end side */
.slider-arrow--prev {
  inset-inline-start: -8px;
}
.slider-arrow--next {
  inset-inline-end: -8px;
}
.slider-arrow .icon {
  inline-size: 22px;
  block-size: 22px;
}
.slider-arrow:hover {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
  transform: translateY(-50%) scale(1.06);
}
.slider-arrow:disabled {
  opacity: 0.35;
  cursor: default;
  box-shadow: 0 2px 6px rgba(26, 26, 26, 0.1);
  pointer-events: none;
}
/* Chevrons are authored for LTR; flip under RTL so each points the right way. */
[dir="rtl"] .slider-arrow .icon {
  transform: scaleX(-1);
}

/* ---------- Mobile swipe hint (coupon slider + category strip) ----------
   A small chevron that nudges toward the scroll direction to signal "swipe for
   more". Shown only where touch-scrolling replaces the arrows (< 560px).
   Decorative + pointer-events:none so it never blocks the swipe; script.js
   removes it after the first scroll or when there's nothing to scroll. */
.swipe-hint {
  display: none;
}
@media (max-width: 559.98px) {
  .swipe-hint {
    --swipe-dir: -1; /* RTL: more content lies toward the left (inline-end) */
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 6px;
    z-index: 3;
    display: grid;
    place-items: center;
    inline-size: 34px;
    block-size: 34px;
    margin-block-start: -17px; /* pull up by half its height to center */
    border-radius: var(--radius-full);
    background: var(--color-surface-card);
    color: var(--color-primary);
    box-shadow: 0 3px 12px rgba(26, 26, 26, 0.22);
    pointer-events: none; /* let swipes pass straight through */
    opacity: 0.95;
    animation: swipe-nudge 1.4s ease-in-out infinite;
  }
  :dir(ltr) .swipe-hint {
    --swipe-dir: 1; /* LTR: more content toward the right */
  }
  .swipe-hint .icon {
    inline-size: 20px;
    block-size: 20px;
  }
  /* chevron authored pointing right (›); flip under RTL so it points the swipe way */
  [dir="rtl"] .swipe-hint .icon {
    transform: scaleX(-1);
  }
  .swipe-hint.is-hidden {
    display: none;
  }
}
@keyframes swipe-nudge {
  0%,
  100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(calc(var(--swipe-dir) * 6px));
  }
}
@media (prefers-reduced-motion: reduce) {
  .swipe-hint {
    animation: none;
  }
}

/* ---------- Coupon slider ---------- */
.coupon-track {
  /* visible cards per view — overridden per breakpoint */
  --visible: 2.15;
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  /* room so card shadows aren't clipped by the scroll box */
  padding-block: 6px;
  margin-block: -6px;
  scrollbar-width: none; /* Firefox */
}
.coupon-track::-webkit-scrollbar {
  display: none; /* WebKit */
}
.coupon-track:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}
.coupon-slide {
  flex: 0 0
    calc((100% - (var(--visible) - 1) * var(--gutter)) / var(--visible));
  scroll-snap-align: start;
}
@media (min-width: 640px) {
  .coupon-track {
    --visible: 3;
  }
}
@media (min-width: 1024px) {
  .coupon-track {
    --visible: 5;
  }
}

/* Compact coupon card — only inside the slider, so the base .coupon-card stays
   reusable at full size on a dedicated coupons page later. */
.coupon-track .coupon-card {
  block-size: 100%;
  padding: var(--space-sm);
  gap: var(--space-xs);
}
.coupon-track .badge {
  inset-block-start: var(--space-sm);
  inset-inline-end: var(--space-sm);
  font-size: 10px;
  padding: 3px 6px;
}
.coupon-track .coupon-card__media {
  aspect-ratio: 2 / 1;     /* inherits the ratio, no fixed height needed */
}

.coupon-track .coupon-card__title {
  font-size: 15px;
  line-height: 22px;
  /* clamp to two lines so cards stay even height */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.coupon-track .coupon-code {
  padding: 6px var(--space-sm);
  gap: var(--space-xs);
}
.coupon-track .coupon-code__value {
  font-size: 13px;
  letter-spacing: 0.06em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.coupon-track .coupon-code__icon .icon {
  inline-size: 15px;
  block-size: 15px;
  flex-shrink: 0;
}

/* ---------- Coupon archive: filter bar ---------- */
.coupon-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-md);
  margin-block-start: var(--space-lg);
  padding: var(--space-md);
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.coupon-filters__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  flex: 1 1 180px;
  min-inline-size: 0;
}
.coupon-filters__field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-on-surface);
}
.coupon-filters select {
  inline-size: 100%;
  font: inherit;
  color: var(--color-on-surface);
  cursor: pointer;
  /* Custom chevron so we control its spacing (the native arrow can't be padded).
     RTL-first: arrow sits on the left; :dir(ltr) flips it right for Morocco. */
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--color-background);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235f5e5e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 16px;
  background-position: left var(--space-md) center;
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  padding-block: 10px;
  padding-inline: var(--space-md);
  padding-inline-end: calc(var(--space-md) + 24px); /* room for the chevron */
}
.coupon-filters select:dir(ltr) {
  background-position: right var(--space-md) center;
}
.coupon-filters select:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}
.coupon-filters__submit {
  flex: 0 0 auto;
  padding: 10px var(--space-lg);
  font: inherit;
  font-weight: 700;
  color: var(--color-on-primary);
  background: var(--color-primary);
  border: 0;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.coupon-filters__submit:hover {
  background: var(--color-primary-container);
}
.coupon-filters__reset {
  flex: 0 0 auto;
  align-self: flex-end;
  padding-block: 10px;          /* match the submit button's height/baseline */
  font-size: 14px;
  font-weight: 600;
  color: var(--color-secondary);
  text-decoration: underline;
}
.coupon-filters__reset:hover {
  color: var(--color-primary);
}

/* ---------- Coupon archive: grid ----------
   Mirrors the slider's per-view counts (2 / 3 / 5). Cards reuse the slider's
   compact treatment so a 5-up grid stays even and tidy. */
.coupon-grid {
  display: grid;
  gap: var(--gutter);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) {
  .coupon-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 1024px) {
  .coupon-grid {
    grid-template-columns: repeat(5, 1fr);
  }
}
.coupon-grid .coupon-card {
  block-size: 100%;
  padding: var(--space-sm);
  gap: var(--space-xs);
}
.coupon-grid .coupon-card__title {
  font-size: 15px;
  line-height: 22px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.coupon-grid .coupon-card__media {
  aspect-ratio: 2 / 1;
}
.coupon-grid .coupon-code {
  padding: 6px var(--space-sm);
  gap: var(--space-xs);
}
.coupon-grid .coupon-code__value {
  font-size: 13px;
  letter-spacing: 0.06em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.empty-state {
  text-align: center;
  padding-block: var(--space-xl);
}

/* ---------- Pagination (the_posts_pagination) ---------- */
.pagination {
  margin-block-start: var(--space-xl);
}
.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
}
.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 40px;
  block-size: 40px;
  padding-inline: var(--space-sm);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background: var(--color-surface-card);
  font-weight: 700;
  color: var(--color-on-surface);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pagination a.page-numbers:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.pagination .page-numbers.current {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}
.pagination .page-numbers.dots {
  border-color: transparent;
  background: transparent;
}

/* ---------- Article byline ---------- */
.article-byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-block: var(--space-sm);
  font-size: 14px;
  color: var(--color-secondary);
}
.article-byline__author {
  font-weight: 600;
  color: var(--color-on-surface);
}
.article-byline__sep {
  color: var(--color-outline-variant);
}

/* ---------- Article card ---------- */
.article-card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.article-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.article-card__link {
  display: block;
  color: inherit;
}
.article-card__media {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--color-surface-container-low);
}
.article-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.article-card__title {
  padding: var(--space-sm) var(--space-md) 0;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-primary-container);
}
.article-card__link:hover .article-card__title {
  color: var(--color-primary);
}
.article-card .article-byline {
  margin-block: var(--space-xs) 0;
  padding-inline: var(--space-md);
}
.article-card__excerpt {
  padding: var(--space-xs) var(--space-md) var(--space-md);
  font-size: 14px;
  line-height: 22px;
  color: var(--color-secondary);
}

/* ---------- Article featured (archive hero) ---------- */
.article-featured {
  display: grid;
  grid-template-columns: 1fr;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  margin-block-end: var(--space-xl);
}
@media (min-width: 768px) {
  .article-featured {
    grid-template-columns: 1.4fr 1fr;
    align-items: center;
  }
}
.article-featured__media {
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--color-surface-container-low);
}
.article-featured__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.article-featured__body {
  padding: var(--space-lg);
}
.article-featured__title {
  font-size: 24px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--color-primary-container);
}
.article-featured__title a {
  color: inherit;
}
.article-featured__title a:hover {
  color: var(--color-primary);
}
.article-featured__excerpt {
  margin-block: var(--space-sm);
  font-size: 15px;
  line-height: 26px;
  color: var(--color-secondary);
}
.article-featured__more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 700;
  color: var(--color-primary);
}
.article-featured__more:hover {
  text-decoration: underline;
}

/* ---------- Author box (single article) ---------- */
.author-box {
  display: flex;
  gap: var(--space-md);
  align-items: flex-start;
  margin-block: var(--space-xl);
  padding: var(--space-lg);
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.author-box__avatar {
  flex: 0 0 auto;
}
.author-box__img {
  display: block;
  border-radius: var(--radius-full);
}
.author-box__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.author-box__label {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-secondary);
}
.author-box__name {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-on-surface);
}
.author-box__bio {
  margin-block-start: var(--space-xs);
  font-size: 14px;
  line-height: 22px;
  color: var(--color-secondary);
}

/* ---------- Coupon category tiles ----------
   Mobile/tablet: horizontal scroll-snap strip (RTL-aware via logical props).
   Desktop (>=900px): a single row of ten. */
.cat-strip {
  position: relative; /* anchor for the mobile .swipe-hint */
}
.cat-grid {
  display: flex;
  gap: var(--space-sm);
  margin-block-start: var(--space-lg);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  /* keep snapped tiles clear of the leading edge (logical = RTL-correct) */
  scroll-padding-inline-start: var(--space-md);
  /* vertical breathing room so card shadow/hover-lift isn't clipped by overflow */
  padding-block: 2px var(--space-xs);
  scrollbar-width: none;            /* Firefox */
  -ms-overflow-style: none;         /* old Edge */
}
.cat-grid::-webkit-scrollbar {
  display: none;                    /* WebKit/Blink */
}
@media (min-width: 900px) {
  .cat-grid {
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    gap: var(--space-sm);
    overflow: visible;             /* drop the scroller on desktop */
  }
}
.cat-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  /* strip mode: fixed-width tiles so long Arabic labels wrap consistently */
  flex: 0 0 auto;
  inline-size: 92px;
  scroll-snap-align: start;
  padding: var(--space-md) var(--space-sm);
  min-block-size: 48px;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  text-align: center;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
/* Desktop: let each tile fill its 1fr grid column instead of the fixed strip
   width. Placed AFTER the base .cat-tile rule so it wins on equal specificity. */
@media (min-width: 900px) {
  .cat-tile {
    inline-size: auto;
  }
}
.cat-tile:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
  border-color: var(--color-outline-variant);
}
.cat-tile__icon {
  display: grid;
  place-items: center;
  inline-size: 48px;
  block-size: 48px;
  border-radius: var(--radius-full);
  background: var(--color-surface-container-low);
  /* Duotone palette — derived from the brand colour so it stays themeable.
     Fallback hex first for engines without color-mix(). */
  --icon-fg: var(--color-primary);
  --icon-tint: #eccac6;
  --icon-tint: color-mix(in srgb, var(--color-primary) 16%, transparent);
}
.cat-tile:hover .cat-tile__icon {
  background: #fdecec;
  --icon-tint: #e6b8b3;
  --icon-tint: color-mix(in srgb, var(--color-primary) 24%, transparent);
}
.cat-tile__icon svg {
  inline-size: 28px;
  block-size: 28px;
  display: block;
}
.cat-tile__icon .duo-tint {
  fill: var(--icon-tint);
}
.cat-tile__icon .duo-fg {
  fill: var(--icon-fg);
}
.cat-tile__icon .duo-stroke {
  fill: none;
  stroke: var(--icon-fg);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cat-tile__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-on-surface);
  line-height: 1.2;
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--color-footer-bg);
  color: #fff;
  margin-block-start: var(--space-xl);
  padding-block-start: 48px;
  border-block-start: 3px solid var(--color-primary); /* firebrick brand accent */
}
/* One-line footer: brand · nav · social, then a centred bottom bar. */
.site-footer__main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block-end: var(--space-lg);
  border-block-end: 1px solid rgba(255, 255, 255, 0.1);
}
.site-footer__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-xs);
}
.site-footer__logo {
  block-size: 88px;
  inline-size: auto;
  max-inline-size: 220px;
  object-fit: contain;
}
.site-footer__tagline {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-footer-text);
  max-inline-size: 340px;
}
.site-footer__nav .site-footer__list {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm) var(--space-lg);
  font-size: 15px;
  font-weight: 600;
  color: var(--color-footer-text);
}
.site-footer__nav .site-footer__list a:hover {
  color: #fff;
}
.site-footer__social {
  display: flex;
  gap: var(--space-md);
}
/* Mobile: stack the row and centre everything. */
@media (max-width: 767.98px) {
  .site-footer__main {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-md);
  }
  .site-footer__brand {
    align-items: center;
  }
  .site-footer__tagline {
    max-inline-size: 360px;
  }
}
.social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  transition: background var(--dur) var(--ease);
}
.social-btn:hover {
  background: var(--color-primary);
}

/* Share row — single offer / coupon / article (Facebook / X / WhatsApp / Telegram) */
.share {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-block-start: var(--space-lg);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--color-hairline);
}
.share__label {
  font-weight: 700;
  color: var(--color-on-background);
}
.share__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: var(--radius-full);
  background: var(--color-surface-container-low);
  color: var(--color-on-background);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.share-btn:hover,
.share-btn:focus-visible {
  color: #fff;
}
.share-btn--facebook:hover,
.share-btn--facebook:focus-visible {
  background: #1877f2;
}
.share-btn--x:hover,
.share-btn--x:focus-visible {
  background: #000;
}
.share-btn--whatsapp:hover,
.share-btn--whatsapp:focus-visible {
  background: #25d366;
}
.share-btn--telegram:hover,
.share-btn--telegram:focus-visible {
  background: #229ed9;
}
.site-footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  align-items: center;
  text-align: center;
  padding-block: var(--space-lg);
  font-size: 14px;
  color: var(--color-footer-text);
}
.site-footer__legal {
  display: flex;
  gap: var(--space-md);
}
.site-footer__legal a:hover {
  color: #fff;
}

/* ---------- Toast ---------- */
.toast {
  position: fixed;
  inset-block-end: var(--space-lg);
  inset-inline: 0;
  margin-inline: auto;
  inline-size: max-content;
  max-inline-size: 90vw;
  z-index: 80;
  background: var(--color-on-background);
  color: #fff;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-full);
  font-size: 14px;
  box-shadow: var(--shadow-card-hover);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Responsive: show hamburger, hide inline nav ---------- */
@media (max-width: 767px) {
  .nav-toggle {
    display: inline-flex;
  }
  .main-nav {
    display: none;
  }
  /* Header pills are tight: /ae carries logo + search + language + city +
     country + hamburger on one line. 4px between them buys 16px back. */
  .site-header__actions {
    gap: 4px;
  }
  /* Country switcher and city picker stay VISIBLE in the mobile header bar (a
     Discover visitor landing on the wrong edition must see a way out without
     opening the drawer). Compact pill: icon + caret only — the name renders but
     is hidden on the toggle; the dropdown items keep icon + full name. The
     drawer copies stay (harmless redundancy). ≥44px tap targets per mobile
     a11y. The city name was the single widest item in the bar («اختر مدينتك»
     = 129px of a 360px phone), which is what pushed the hamburger off-screen
     on /sa and /ae. */
  .country-switcher--desktop > .country-switcher__toggle,
  .town-switcher--desktop > .country-switcher__toggle {
    block-size: 44px;
    min-inline-size: 44px;
    padding-inline: 8px;
    justify-content: center;
  }
  .country-switcher--desktop > .country-switcher__toggle .country-switcher__name,
  .town-switcher--desktop > .country-switcher__toggle .country-switcher__name {
    display: none;
  }
  .country-switcher--desktop .country-switcher__item {
    min-block-size: 44px;
  }
  /* Language pills carry a 2-letter code on the header (see
     threeorod_language_short_code) — tighten the padding to match. The code is
     narrow, so buy the tap area back on the axis that is free: 44px group,
     matching the country/city toggles beside it (they were 44 vs the pill's 40,
     so the row lines up better too). The drawer switcher keeps full names and
     its own full-width sizing. */
  .lang-switch--desktop {
    block-size: 44px;
  }
  .lang-switch--desktop .lang-switch__item {
    padding-inline: 9px;
    min-inline-size: 36px;
    block-size: 38px;
  }
  .site-logo {
    font-size: 22px;
  }
  .section-title {
    font-size: 22px;
    line-height: 30px;
  }
}

/* Narrow phones (360/375/390/393px): one edition — /ae — carries BOTH a
   language switcher and a city picker, and even fully compacted the six
   controls need ~394px. Below that the city picker leaves the header bar; it is
   still reachable from the drawer AND from the first-visit city popup, whereas
   the language switcher and the country switcher have no second entry point on
   the page. `:has()` keeps this surgical: /sa has a city picker but no language
   switcher, so it keeps its pill at every width. A browser without `:has()`
   support simply behaves as it does today. */
@media (max-width: 400px) {
  .site-header__actions:has(.lang-switch) .town-switcher--desktop {
    display: none;
  }
}

/* ---------- 404 ---------- */
.error-404 {
  text-align: center;
}
.error-404__code {
  font-size: clamp(64px, 18vw, 140px);
  font-weight: 800;
  line-height: 1;
  margin: 0 0 var(--space-xs);
  color: color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.error-404__search {
  max-inline-size: 480px;
  margin: var(--space-md) auto 0;
}
.error-404__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  justify-content: center;
}
.error-404__link {
  display: inline-flex;
  align-items: center;
  padding: 10px 18px;
  font-weight: 600;
  text-decoration: none;
  color: var(--color-primary);
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-full);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
}
.error-404__link:hover {
  color: var(--color-on-primary);
  background: var(--color-primary);
  border-color: var(--color-primary);
}

/* 404 launchpad — prominent search, big CTA, store shortcuts (see 404.php) */
.error-404__lead {
  max-inline-size: 640px;
  margin-inline: auto;
}
.error-404__search {
  /* Widen past the shared .error-404 rule above — the search is the hero element.
     Flows in normal document flow (.ps-results just grows below), so no shift. */
  max-inline-size: 620px;
  text-align: start;
}
.e404-actions {
  margin-block-start: var(--space-md);
  text-align: center;
}
.e404-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 14px 28px;
  min-block-size: 48px;
  font-weight: 700;
  text-decoration: none;
  color: var(--color-on-primary);
  background: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-full);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.e404-cta:hover {
  background: var(--color-primary-container);
  border-color: var(--color-primary-container);
}
.e404-cta:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
/* Store shortcuts: responsive auto-fill grid of the shared .store-mega__item cells. */
.e404-stores {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-xs) var(--space-sm);
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ---------- Single coupon — redemption card ---------- */
.coupon-redeem {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  inline-size: 100%;
  max-inline-size: 400px;
  margin-block: var(--space-lg);
  padding: var(--space-lg);
  text-align: center;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  margin-inline: auto;   /* ← add this line to center the card */
}
.coupon-redeem__media {
  inline-size: 100%;           /* fill the card width */
  aspect-ratio: 2 / 1;         /* matches 400×200 */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-container-low);
}
.coupon-redeem__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: center;
}
/* visible code box on the single page — larger than the slider version */
.coupon-redeem .coupon-code {
  inline-size: 100%;
  margin-block-start: 0;
}
.coupon-redeem .coupon-code__value {
  font-size: 20px;
  letter-spacing: 0.18em;
}
.coupon-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  inline-size: 100%;
  min-block-size: 48px;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-radius: var(--radius-md);
  font-weight: 700;
  font-size: 16px;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.coupon-cta:hover {
  background: var(--color-primary-container);
  transform: translateY(-1px);
  color: var(--color-on-primary);
}
/* arrow points the right way under RTL */
[dir="rtl"] .coupon-cta .icon {
  transform: scaleX(-1);
}

/* ===== Store hub hero (logo + name + description) ===== */
.store-hero {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-block-start: var(--space-sm);
}
.store-hero__logo {
  flex-shrink: 0;
  inline-size: 96px;
  block-size: 96px;
  display: grid;
  place-items: center;
  padding: 10px;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.store-hero__logo img {
  max-inline-size: 100%;
  max-block-size: 100%;
  inline-size: auto;
  block-size: auto;
  object-fit: contain;
}
.store-hero__initial {
  inline-size: 100%;
  block-size: 100%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
  font-weight: 700;
  font-size: 36px;
}
.store-hero__text {
  min-inline-size: 0;
}
.store-hero__text .page-title {
  margin-block: 0 6px;
}
.store-hero__text .page-lead {
  margin-block: 0;
}
@media (max-width: 560px) {
  /* Stack + center: logo above a centered title + description */
  .store-hero {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-sm);
  }
  .store-hero__logo {
    inline-size: 72px;
    block-size: 72px;
    padding: 8px;
  }
  .store-hero__initial {
    font-size: 28px;
  }
}

/* ---------- Store-hub footprint — the national coverage one-liner ----------
   Originally (TOWN-OFFERS-PHASE2 §D) this was a town/region CHIP SELECTOR. The
   chips were retired in PHASE4 §B in favour of the per-store branches page, and
   the last markup using them (the single-offer scope row) went with
   threeorod_render_offer_scope() on 2026-08-05.

   ⚠️ ALL FOUR rules below are emitted TOGETHER by one element —
   taxonomy-store.php:116 — and none is optional:
       <p class="store-footprint store-footprint--national store-footprint--compact">
   Note the last selector is the COMPOUND `--compact.store-footprint--national`
   (both classes on the same element), not a descendant rule. The `__label`,
   `__list` and `__chip` rules, and the `--compact` DESCENDANT rules that styled
   them, were deleted with the chips — do not reinstate them without markup that
   emits those classes. */
.store-footprint {
  margin-block: var(--space-md);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-sm);
}
.store-footprint--national {
  color: var(--color-ink-soft, #555);
  font-size: 0.95rem;
}
/* §E: demote the footprint line — the offers are the main event, this is a
   secondary coverage/AEO signal. Smaller, muted, tighter. */
.store-footprint--compact {
  margin-block: var(--space-sm);
  gap: var(--space-xs);
}
.store-footprint--compact.store-footprint--national {
  font-size: 0.85rem;
}

/* Quiet crawl-path links from EG store hubs to their sibling editions. */
.store-cross-edition {
  margin-block: var(--space-sm);
  color: var(--color-ink-soft, #555);
  font-size: 0.85rem;
  line-height: 1.8;
}
.store-cross-edition a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.store-cross-edition a + a {
  margin-inline-start: var(--space-sm);
}

/* =========================================================================
   Per-store branches page (/store-branches/{slug}/) + the entry-point CTA.
   ====================================================================== */

/* "تصفّح فروع {store}" button — store hub + single offer. */
.store-branches-cta {
  margin-block: var(--space-md) 0;
}
.store-branches-cta__link {
  display: inline-block;
  padding: 8px 18px;
  border: 1px solid var(--color-primary, #8f000d);
  border-radius: var(--radius-md);
  color: var(--color-primary, #8f000d);
  background: var(--color-snow, #fff);
  font-weight: 700;
  font-size: 0.95rem;
  text-decoration: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.store-branches-cta__link:hover,
.store-branches-cta__link:focus-visible {
  background: var(--color-primary, #8f000d);
  color: #fff;
}

/* Branch groups (one per town) */
.branches {
  margin-block: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}
.branches-group__title {
  margin: 0 0 var(--space-md);
  font-size: 1.25rem;
  font-weight: 700;
  padding-block-end: var(--space-xs);
  border-block-end: 2px solid color-mix(in srgb, var(--color-primary, #8f000d) 20%, #fff);
}
.branches-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}
@media (min-width: 640px) {
  .branches-list {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 960px) {
  .branches-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

.branch-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  background: var(--color-snow, #fff);
  border: 1px solid var(--color-border, #e0e0e0);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.branch-card__name {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-on-background);
}
.branch-card__address {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-ink-soft, #555);
  line-height: 1.5;
}
.branch-card__map {
  margin-block-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-block-start: var(--space-xs);
  color: var(--color-primary, #8f000d);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}
.branch-card__map:hover,
.branch-card__map:focus-visible {
  text-decoration: underline;
}
.branch-card__map .icon {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
}

.branches-back {
  margin-block: var(--space-lg);
  font-weight: 700;
}
.branches-back a {
  color: var(--color-primary, #8f000d);
  text-decoration: none;
}
.branches-back a:hover,
.branches-back a:focus-visible {
  text-decoration: underline;
}

/* Town picker (§F): the location-pin reuses .country-switcher__flag for sizing,
   but must NOT inherit the flag's circular ring/shadow — it's a line icon. */
.town-switcher__pin {
  inline-size: 18px;
  block-size: 18px;
  border-radius: 0;
  box-shadow: none;
  color: inherit;
}
/* The town list carries up to 50 cities — cap the dropdown height and let it
   scroll internally. `overscroll-behavior: contain` stops the wheel/touch from
   chaining to the page behind it once the list hits its top/bottom. Applies to
   both the desktop (absolute) dropdown and the drawer (static) list. */
.town-switcher .country-switcher__menu {
  max-block-size: min(60vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* Towns grouped under their region. Each group is a container <li>; its header
   is either a link to the region archive (/region/<slug>/) or a plain label
   (the "مدن أخرى" fallback), with the town items nested in a reset <ul>. */
.town-switcher__group {
  margin-block-start: 4px;
  padding-block-start: 4px;
  border-block-start: 1px solid var(--color-hairline);
}
.town-switcher__towns {
  margin: 0;
  padding: 0;
  list-style: none;
}
.town-switcher__region {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--color-muted);
  text-decoration: none;
  border-radius: var(--radius-md);
}
a.town-switcher__region:hover,
a.town-switcher__region:focus-visible {
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 8%, transparent);
}
.town-switcher__region-arrow {
  flex: none;
  opacity: 0.7;
  transition: transform var(--dur) var(--ease);
}
a.town-switcher__region:hover .town-switcher__region-arrow,
a.town-switcher__region:focus-visible .town-switcher__region-arrow {
  transform: translateX(-2px); /* nudge toward the leading edge (RTL) */
}
/* Indent the town rows so they read as children of the region header. */
.town-switcher__towns .country-switcher__item {
  padding-inline-start: 20px;
}

/* ---------- Offer products table enhancements ----------
   The table markup + its base styles ship from the publisher as raw HTML in the
   post content (.orod-offers-acc / .orod-offers-table, green theme). These rules
   only style the JS-injected search field and sticky fold button
   (initOfferProducts in script.js), matching the table's existing green. */
.orod-offers-search {
  padding: 12px 14px;
  background: #f7faf8;
  border-block-end: 1px solid #eceff1;
}
.orod-offers-search__input {
  inline-size: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  font: inherit;
  font-size: 14px;
  color: #1a1c1c;
  background: #fff;
  border: 1px solid #cfe3d6;
  border-radius: 8px;
  outline: none;
}
.orod-offers-search__input:focus {
  border-color: #0f9d58;
  box-shadow: 0 0 0 3px rgba(15, 157, 88, 0.15);
}
.orod-offers-empty td {
  text-align: center !important;
  color: #9aa0a6;
  padding: 18px 14px;
  font-size: 14px;
}

/* Floats pinned to the bottom of the viewport (the visible part of the table)
   the whole time the table is scrolled; toggled via .is-visible from JS. */
.orod-offers-fold {
  position: fixed;
  inset-block-end: 20px;
  /* physical left + translateX so it's truly centred in both RTL and LTR
     (inset-inline-start flips sides in RTL and threw it off-centre) */
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  background: #0f9d58;
  border: none;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(15, 94, 32, 0.4);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s, background 0.15s, transform 0.15s;
}
.orod-offers-fold.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.orod-offers-fold:hover {
  background: #0b7c44;
}
.orod-offers-fold:active {
  transform: translateX(-50%) translateY(1px);
}
@media (prefers-reduced-motion: reduce) {
  .orod-offers-fold {
    transition: opacity 0.18s;
  }
}

/* ==========================================================================
   Site search — header overlay + product type-ahead (.js-product-search)
   Shared by the header magnifier overlay and the [threeorod_product_search]
   shortcode (the shortcode skips the overlay chrome, just .ps-form/.ps-results).
   ========================================================================== */
.site-search {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;          /* center the panel horizontally */
  justify-content: flex-start;  /* anchor it near the top */
  padding-block-start: 88px;    /* drop below the header bar */
  padding-inline: var(--space-md);
}
/* Author display:flex above overrides the UA `[hidden]{display:none}` rule
   (equal specificity, author wins), which left the overlay covering the page
   and eating clicks while "closed". Re-assert hidden explicitly. */
.site-search[hidden] {
  display: none;
}
.site-search__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(26, 28, 28, 0.55);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.site-search__panel {
  position: relative;
  inline-size: min(680px, 100%);   /* a centered box, not a full-bleed cover */
  background: var(--color-surface-card);
  box-shadow: 0 8px 28px rgba(26, 26, 26, 0.18);
  border-radius: var(--radius-lg);
  transform: translateY(-12px);
  opacity: 0;
  transition: transform 0.22s ease, opacity 0.22s ease;
  padding-block: var(--space-md);
  max-block-size: calc(100dvh - 120px);
  overflow-y: auto;
}
.site-search.is-open .site-search__backdrop {
  opacity: 1;
}
.site-search.is-open .site-search__panel {
  transform: translateY(0);
  opacity: 1;
}

.site-search__inner {
  display: block;
}

/* Search input row (overlay + shortcode share .ps-form) */
.ps-form {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.ps-form__icon {
  display: inline-flex;
  color: var(--color-muted);
  flex: 0 0 auto;
}
.ps-form__icon .icon {
  inline-size: 22px;
  block-size: 22px;
}
.ps-input {
  flex: 1 1 auto;
  min-inline-size: 0;
  box-sizing: border-box;
  padding: 12px 14px;
  font: inherit;
  font-size: 16px; /* ≥16px avoids iOS zoom-on-focus */
  color: var(--color-on-surface);
  background: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  outline: none;
}
.ps-input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(143, 0, 13, 0.12);
}
.ps-submit {
  flex: 0 0 auto;
  padding: 12px 20px;
  font: inherit;
  font-weight: 700;
  color: var(--color-on-primary);
  background: var(--color-primary);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background 0.15s;
}
.ps-submit:hover {
  background: var(--color-primary-container);
}
.site-search__close {
  flex: 0 0 auto;
}

/* Results */
.ps-results {
  margin-block-start: var(--space-md);
}
.ps-status,
.ps-empty {
  margin: 0;
  padding-block: var(--space-md);
  color: var(--color-muted);
  font-size: 14px;
}
.ps-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-block-start: 1px solid var(--color-hairline);
}
.ps-item > a {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px var(--space-sm);
  padding: 12px 4px;
  text-decoration: none;
  color: var(--color-on-surface);
  border-block-end: 1px solid var(--color-hairline);
  transition: background 0.12s;
}
.ps-item > a:hover {
  background: var(--color-surface-container-low);
}
/* Per-product crop thumbnail in the live type-ahead dropdown. */
.ps-thumb {
  flex: 0 0 auto;
  align-self: center;
  inline-size: 40px;
  block-size: 40px;
  object-fit: cover;
  border-radius: 6px;
  background: var(--color-surface-container-low);
}
.ps-name {
  font-weight: 600;
}
.ps-price {
  color: var(--color-primary);
  font-weight: 700;
  white-space: nowrap;
}
.ps-old {
  margin-inline-start: 4px;
  color: var(--color-muted);
  font-weight: 400;
  font-size: 0.85em;
}
.ps-meta {
  flex-basis: 100%;
  color: var(--color-muted);
  font-size: 13px;
}
.ps-all {
  display: inline-block;
  margin-block-start: var(--space-md);
  font-weight: 700;
  color: var(--color-primary);
  text-decoration: none;
}
.ps-all:hover {
  text-decoration: underline;
}
/* "هل تقصد …؟" — Layer-2 fuzzy suggestion line in the type-ahead dropdown. */
.ps-suggest {
  margin: 0;
  padding-block: 10px;
  color: var(--color-muted);
  font-size: 14px;
}
.ps-suggest__btn {
  margin-inline-start: 4px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 700;
  color: var(--color-primary);
  cursor: pointer;
}
.ps-suggest__btn:hover {
  text-decoration: underline;
}

@media (max-width: 560px) {
  .ps-submit {
    padding-inline: 14px;
  }
  .site-search {
    padding-block-start: 72px;
  }
  .site-search__panel {
    max-block-size: calc(100dvh - 92px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .site-search__backdrop,
  .site-search__panel {
    transition: opacity 0.18s ease;
    transform: none;
  }
}

/* Search results page (search.php) */
.search-term {
  color: var(--color-primary);
}
/* "هل تقصد …؟" / "نتائج عن … — ابحث بدلاً عن …" (Layer-2 fuzzy suggestion). */
.search-suggest {
  margin-block: calc(-1 * var(--space-sm)) var(--space-md);
  color: var(--color-muted);
  font-size: 15px;
}
.search-suggest__term {
  color: var(--color-primary);
}
.search-suggest__link {
  font-weight: 700;
  color: var(--color-primary);
}
.search-suggest__exact {
  margin-inline-start: var(--space-sm);
  color: var(--color-muted);
  text-decoration: underline;
}
/* "تعرض نتائج مدينة … — عرض نتائج كل المدن" (?town= scope indicator). */
.search-scope {
  margin-block: calc(-1 * var(--space-sm)) var(--space-md);
  color: var(--color-muted);
  font-size: 15px;
}
.search-scope__town {
  color: var(--color-primary);
}
.search-scope__all {
  margin-inline-start: var(--space-sm);
  color: var(--color-muted);
  text-decoration: underline;
}
.section-count {
  color: var(--color-muted);
  font-weight: 400;
  font-size: 0.8em;
}
.search-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.search-list__item {
  padding-block: var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
}
.search-list__item > a {
  font-weight: 700;
  color: var(--color-on-surface);
  text-decoration: none;
}
.search-list__item > a:hover {
  color: var(--color-primary);
}
.search-list__excerpt {
  margin: 4px 0 0;
  color: var(--color-muted);
  font-size: 14px;
}

/* Flyer-page anchors (#offer-page-N): keep the landing spot clear of the header
   for the native jump, the in-content "jump to page" links, and the JS re-anchor. */
[id^="offer-page-"] {
  scroll-margin-top: 84px;
}

/* Re-search form on the results page (reuses .ps-form). */
.search-page-form {
  max-inline-size: 560px;
  margin-block-start: var(--space-md);
}

/* Center the title + re-search form on the results page. */
.page-intro--search .page-title {
  text-align: center;
}
.page-intro--search .search-page-form {
  margin-inline: auto;
}

/* ── Search: product results table ─────────────────────────────────────
   Spreadsheet on desktop; each row reflows into a stacked card ≤640px so
   the price columns are never pushed off-screen on mobile (data-label
   pseudo-elements carry the column names). One markup, CSS-driven. */
.ps-table-wrap {
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.ps-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}
.ps-table thead th {
  text-align: start;
  font-weight: 700;
  font-size: 13px;
  color: var(--color-muted);
  background: var(--color-surface-container-low);
  padding: 12px var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
  white-space: nowrap;
}
.ps-table td {
  padding: 12px var(--space-md);
  border-block-end: 1px solid var(--color-hairline);
  vertical-align: middle;
}
.ps-table tbody tr:last-child td {
  border-block-end: 0;
}
.ps-table tbody tr:hover {
  background: color-mix(in srgb, var(--color-primary) 4%, transparent);
}
.ps-table__name a {
  font-weight: 700;
  color: var(--color-on-surface);
  text-decoration: none;
}
.ps-table__name a:hover {
  color: var(--color-primary);
}
/* Per-product crop thumbnail in the name cell (search page table). */
.ps-table__namelink {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.ps-table__thumb {
  flex: 0 0 auto;
  inline-size: 48px;
  block-size: 48px;
  object-fit: cover;
  border-radius: 6px;
  background: var(--color-surface-container-low);
}
.ps-table .num {
  font-family: var(--font-price);
  font-weight: 700;
}
.ps-table__price {
  white-space: nowrap;
}
.ps-table__price--old .num {
  color: var(--color-muted);
  font-weight: 400;
  text-decoration: line-through;
}
.ps-table__price--new .num {
  color: var(--color-primary);
  font-size: 1.05em;
}
.ps-table__cur {
  font-size: 0.8em;
  color: var(--color-muted);
}
.ps-table__store,
.ps-table__valid {
  color: var(--color-muted);
  white-space: nowrap;
}
.ps-table__store a {
  /* Grey pill button (not a dotted-underline link) — clearer tap target. */
  display: inline-block;
  padding: 5px 12px;
  border-radius: var(--radius-md);
  background: var(--color-surface-container-low);
  border: 1px solid var(--color-hairline);
  color: var(--color-on-surface);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.ps-table__store a:hover,
.ps-table__store a:focus-visible {
  background: var(--color-surface-container);
  border-color: var(--color-outline-variant);
  color: var(--color-primary);
  text-decoration: none;
}
.ps-table__dash {
  color: var(--color-muted);
}
.ps-table__action {
  text-align: end;
}
.ps-table__btn {
  display: inline-block;
  padding: 8px 14px;
  border-radius: var(--radius-md);
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  min-height: 36px;
}
.ps-table__btn:hover {
  background: var(--color-primary-container);
}

@media (max-width: 640px) {
  .ps-table-wrap {
    border: 0;
    background: transparent;
    box-shadow: none;
    overflow: visible;
  }
  .ps-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    border: 0;
  }
  .ps-table,
  .ps-table tbody,
  .ps-table__row,
  .ps-table td {
    display: block;
  }
  .ps-table__row {
    background: var(--color-surface-card);
    border: 1px solid var(--color-hairline);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    padding: var(--space-md);
    margin-block-end: var(--space-md);
  }
  .ps-table__row td {
    padding: 4px 0;
    border: 0;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-md);
  }
  .ps-table__row td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    font-size: 13px;
    font-weight: 700;
    color: var(--color-muted);
  }
  .ps-table td.ps-table__name {
    display: block;
    border-block-end: 1px solid var(--color-hairline);
    padding-block-end: 8px;
    margin-block-end: 4px;
  }
  .ps-table__name a {
    font-size: 16px;
  }
  .ps-table td.ps-table__action {
    display: block;
    text-align: start;
    padding-block-start: 10px;
  }
  .ps-table__btn {
    display: block;
    text-align: center;
  }
}


/* =========================================================================
   Browse-by-sections — /section/<slug>/  (SECTIONS-CORE-THEME-SPEC.md)
   Controls bar (sort + store filter), compact product-card grid, load-more.
   Logical properties throughout (RTL-first, LTR-safe). HIDDEN launch: the
   page is noindex + unlinked; these styles are inert everywhere else.
   ====================================================================== */

.section-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  padding: 12px 16px;
  margin-block-end: 20px;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
}
.section-controls__label {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-muted);
  margin-inline-end: 6px;
}
.section-controls__select {
  font: inherit;
  font-size: 14px;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-card);
  color: var(--color-on-surface);
  min-block-size: 40px;
  cursor: pointer;
  /* Custom chevron so we control its spacing (native arrow can't be padded).
     RTL-first: arrow on the left with a proper gap; :dir(ltr) flips it right. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235f5e5e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 16px;
  background-position: left 14px center;
  padding-block: 8px;
  padding-inline: 12px;
  padding-inline-end: calc(12px + 24px);
}
.section-controls__select:dir(ltr) {
  background-position: right 14px center;
}
.section-controls__stores {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  border: 0;
  padding: 0;
  margin: 0;
  min-inline-size: 0;
}
.section-controls__stores legend {
  float: inline-start; /* keep the legend inline with the checkboxes */
  padding: 0;
}
.section-controls__store {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  cursor: pointer;
  min-block-size: 40px;
}
.section-controls__store input {
  accent-color: var(--color-primary);
  inline-size: 16px;
  block-size: 16px;
}
.section-controls__count {
  color: var(--color-muted);
  font-size: 12px;
}
.section-controls__total {
  margin: 0;
  margin-inline-start: auto;
  font-size: 13px;
  color: var(--color-muted);
}

/* Subcategory filter chips — own full-width row atop the controls (the flex
   parent wraps; flex-basis:100% forces the break). Pill buttons matching the
   controls, RTL via logical props, single-select active state. */
.section-controls__subs {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-block-end: 12px;
  margin-block-end: 4px;
  border-block-end: 1px solid var(--color-hairline);
}
.section-sub {
  font: inherit;
  font-size: 13px;
  line-height: 1.2;
  padding: 8px 14px;
  min-block-size: 36px;
  border: 1px solid var(--color-hairline);
  border-radius: 999px;
  background: var(--color-surface-card);
  color: var(--color-on-surface);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.section-sub:hover {
  border-color: var(--color-primary);
}
.section-sub.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.section-sub__count {
  color: var(--color-muted);
  font-size: 12px;
}
.section-sub.is-active .section-sub__count {
  color: rgba(255, 255, 255, 0.8);
}

/* Product-card grid: compact cards, 2-up on phones → 6-up on wide desktop. */
.sec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
}
.sec-grid[aria-busy="true"] {
  opacity: 0.55;
}
/* JS-hidden cards must collapse — grid children can beat the UA [hidden] rule. */
.sec-grid .sec-card[hidden] {
  display: none !important;
}
.section-empty {
  grid-column: 1 / -1;
  margin: 0;
  padding: 24px 0;
  color: var(--color-muted);
  text-align: center;
}

.sec-card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: var(--color-on-surface);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.sec-card:hover,
.sec-card:focus-visible {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}
.sec-card__media {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  background: var(--color-surface-container-low);
}
.sec-card__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}
/* No per-product crop: keep the media box from reading as a broken image —
   center a padded store logo, or a neutral product glyph as a last resort. */
.sec-card__media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
}
.sec-card__ph-logo {
  inline-size: 62%;
  block-size: 62%;
  object-fit: contain;
  opacity: 0.85;
}
.sec-card__ph {
  display: inline-flex;
  color: var(--color-muted);
  opacity: 0.6;
}
.sec-card__badge {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-start: 8px;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  direction: ltr; /* keep "-30%" reading order intact in RTL */
}
.sec-card__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px 12px;
}
.sec-card__name {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.sec-card__prices {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}
.sec-card__new {
  color: var(--color-primary);
  font-size: 15px;
  font-weight: 800;
}
.sec-card__cur {
  font-size: 11px;
  font-weight: 600;
}
.sec-card__old {
  color: var(--color-muted);
  font-size: 12px;
}
.sec-card__store {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: flex-start;
  max-inline-size: 100%;
  margin-block-start: 2px;
  font-size: 11px;
  font-weight: 600;
  color: var(--color-secondary);
  background: var(--color-surface-container-low);
  padding: 3px 8px;
  border-radius: var(--radius-full);
}
.sec-card__logo {
  inline-size: 18px;
  block-size: 18px;
  flex: 0 0 auto;
  border-radius: var(--radius-full);
  object-fit: contain;
  background: #fff;
}
.sec-card__logo--letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  background: var(--color-primary);
}
.sec-card__store-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-inline-size: 0;
}
.sec-card__branch {
  color: var(--color-muted);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-inline-size: 0;
}

/* First-visit town popup (SA) — SA-TOWN-POPUP-AND-BRANCH-CARDS-SPEC §1. A
   full-screen dimmed modal; markup always in the (cached) DOM, JS toggles
   visibility from the localStorage town. */
.town-popup {
  position: fixed;
  inset: 0;
  /* Above EVERYTHING, incl. the plugin geo banner (z 99999) — a modal that asks
     a question must not have a banner painted over it. */
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.town-popup[hidden] {
  display: none;
}
.town-popup__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(26, 26, 26, 0.6);
}
.town-popup__dialog {
  position: relative;
  z-index: 1;
  inline-size: min(560px, 100%);
  max-block-size: min(85vh, 720px);
  display: flex;
  flex-direction: column;
  padding: 24px;
  overflow: hidden;
  background: var(--color-surface-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-hover);
}
.town-popup__dialog:focus {
  outline: none; /* programmatic focus target on open — no ring on the panel */
}
.town-popup__close {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-end: 12px;
  padding: 4px 8px;
  font-size: 26px;
  line-height: 1;
  color: var(--color-muted);
  background: none;
  border: 0;
  outline: none; /* kill any UA/global frame; keyboard ring restored below */
  cursor: pointer;
}
.town-popup__close:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-md, 6px);
}
.town-popup__title {
  margin: 0 24px 16px 0;
  font-size: 20px;
  font-weight: 700;
  color: var(--color-on-background);
}
.town-popup__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.town-popup__group {
  margin-block-end: 16px;
}
.town-popup__region {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-primary);
}
.town-popup__cities {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.town-popup__city {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  color: var(--color-on-background);
  background: var(--color-surface-container-low);
  border-radius: var(--radius-full);
  transition: background 0.15s, color 0.15s;
}
.town-popup__city:hover,
.town-popup__city:focus-visible {
  color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
}
.town-popup__foot {
  margin-block-start: 16px;
  padding-block-start: 16px;
  border-block-start: 1px solid var(--color-surface-container);
  text-align: center;
}
.town-popup__all {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  min-block-size: 44px;
  padding: 10px 24px;
  color: #fff;
  background: var(--color-primary);
  border: 0;
  border-radius: var(--radius-md, 6px);
  cursor: pointer;
}
.town-popup__all:hover,
.town-popup__all:focus-visible {
  background: var(--color-primary-container);
}
@media (max-width: 560px) {
  .town-popup__dialog {
    padding: 20px 16px;
    max-block-size: 90vh;
  }
  .town-popup__title {
    font-size: 18px;
  }
}

.section-more {
  margin: 24px 0 0;
  text-align: center;
}
.section-more[hidden] {
  display: none;
}
.section-more__btn {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--color-primary);
  background: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  padding: 10px 32px;
  min-block-size: 48px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.section-more__btn:hover:not(:disabled) {
  background: var(--color-surface-container-low);
}
.section-more__btn:disabled {
  cursor: default;
  opacity: 0.7;
}

/* Homepage section tiles (entry point — renders only once sections launch). */
.section-tiles__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.section-tiles__link {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  padding: 8px 16px;
  background: var(--color-surface-card);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-full);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-on-surface);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.section-tiles__link:hover,
.section-tiles__link:focus-visible {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

@media (max-width: 559px) {
  .section-controls {
    align-items: stretch;
    flex-direction: column;
    gap: 10px;
  }
  .section-controls__total {
    margin-inline-start: 0;
  }
  .sec-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ── Contact form (shortcode: threeorod_contact) ───────────────────────────
   Controls mirror .ps-input / .ps-submit (above) so the contact form and the
   product-search box read as ONE component. Logical properties throughout, so
   the same rules serve RTL (/ , /sa, /ma) and LTR (/ma/fr). */
.threeorod-contact {
  max-inline-size: 640px;
  margin-inline: auto;
}

.threeorod-contact .tc-notice {
  padding: 12px 16px;
  margin-block-end: 20px;
  font-weight: 600;
  border-radius: var(--radius-md);
}
.threeorod-contact .tc-notice--ok {
  color: #16653a;
  background: #e7f6ec;
}
.threeorod-contact .tc-notice--err {
  color: var(--color-primary);
  background: #fdeaea;
}

.threeorod-contact .tc-field {
  margin-block-end: 16px;
}
.threeorod-contact .tc-field label {
  display: block;
  margin-block-end: 6px;
  font-weight: 600;
  color: var(--color-on-surface);
}

/* Mirrors .ps-input so both forms on the site feel like one component. */
.threeorod-contact .tc-field input,
.threeorod-contact .tc-field textarea {
  box-sizing: border-box;
  inline-size: 100%;
  padding: 12px 14px;
  font: inherit;
  font-size: 16px; /* ≥16px avoids iOS zoom-on-focus */
  color: var(--color-on-surface);
  background: var(--color-surface-card);
  border: 1px solid var(--color-outline-variant);
  border-radius: var(--radius-md);
  outline: none;
}
.threeorod-contact .tc-field input:focus,
.threeorod-contact .tc-field textarea:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(143, 0, 13, 0.12);
}
.threeorod-contact .tc-field textarea {
  min-block-size: 140px;
  resize: vertical;
}

/* Mirrors .ps-submit, hover included — one hover treatment, not two. */
.threeorod-contact .tc-submit {
  padding: 12px 32px;
  font: inherit;
  font-weight: 700;
  color: var(--color-on-primary);
  background: var(--color-primary);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background 0.15s;
}
.threeorod-contact .tc-submit:hover {
  background: var(--color-primary-container);
}

/* Honeypot: off-screen, NOT display:none — many bots skip display:none fields. */
.threeorod-contact .tc-hp {
  position: absolute;
  inset-inline-start: -9999px;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
}

.threeorod-contact .tc-direct {
  margin-block-start: 22px;
  color: var(--color-muted);
}
.threeorod-contact .tc-direct a {
  font-weight: 600;
  color: var(--color-primary);
}


/* ==========================================================================
   Web push: the bell + the store picker (PWA phase 2)
   ========================================================================== */

/* The bell sits ABOVE the AdSense anchor ad on purpose. A fixed offset, not a
   measured one: Google injects the anchor iframe on its own schedule, so any JS
   measurement races it and can read 0. Overlapping an ad breaks AdSense policy,
   while floating a little high when no anchor is present costs nothing. */
.push-bell {
  position: fixed;
  right: 16px;
  bottom: 110px;
  z-index: 90;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px) scale(.9);
  pointer-events: none;
  /* `bottom` is set by JS, which keeps the bell clear of the AdSense anchor ad
     (see placeBell in script.js). The transition makes it glide when the ad opens
     or is closed instead of jumping. */
  transition: opacity .25s ease, transform .25s ease, bottom .18s ease;
}
.push-bell.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.push-bell svg {
  width: 26px;
  height: 26px;
  fill: currentColor;
}
/* Already subscribed: the bell has done its job, so it steps back. It stays
   reachable (it is now the settings button for changing stores or switching off)
   but it stops competing with the flyers for attention. Touching it brings it
   back to full strength. */
.push-bell.is-visible.is-on {
  opacity: .38;
  transform: scale(.92);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.push-bell.is-visible.is-on:hover,
.push-bell.is-visible.is-on:focus-visible,
.push-bell.is-visible.is-on:active {
  opacity: 1;
  transform: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
}
/* The bell announces itself ONCE when it first appears: this label slides out,
   and the ring below pings three times. Then both stop for good - see announce()
   in script.js for why it is not a loop.

   Positioned ABSOLUTELY on purpose. The bell is the only thing on the page that
   moves, and a fixed element that changes its own size can register as layout
   shift; taking the label out of flow and animating only transform + opacity
   keeps the whole effect on the compositor, where it cannot cost us Core Web
   Vitals. `right: 64px` puts it just clear of the 56px circle, and the text runs
   leftwards from there, which is the natural direction in Arabic. */
.push-bell__label {
  position: absolute;
  right: 64px;
  top: 50%;
  padding: 9px 14px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  /* ⚠ `width: max-content` is LOAD-BEARING, do not drop it.
     The label is absolutely positioned inside the 56px bell button, so its
     containing block is 56px wide and `right: 64px` leaves it NEGATIVE room.
     Without an explicit width it shrink-wraps to the longest single WORD and
     stacks one word per line - which is exactly what shipped for 20 minutes on
     2026-08-23 when `white-space: nowrap` was removed to allow wrapping.
     max-content sizes it to the whole sentence on ONE line.

     max-width is then what permits a second line, and only on a screen too
     narrow to hold the sentence: the label starts 64px in from the right edge,
     so a long wording would otherwise run off the LEFT. Two tidy centred lines
     beat half a sentence - this is the only text that tells a reader what the
     bell does. First declaration is the fallback for browsers without min(). */
  width: max-content;
  max-width: 15rem;
  max-width: min(15rem, calc(100vw - 88px));
  box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
  opacity: 0;
  transform: translateY(-50%) translateX(10px);
  transition: opacity .3s ease, transform .3s ease;
  pointer-events: none;
}
.push-bell.is-labelled .push-bell__label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
  pointer-events: auto;   /* a wider tap target while it is showing */
}

.push-bell.is-pinging::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid var(--color-primary);
  pointer-events: none;
  animation: push-bell-ping 1.4s ease-out 3;
}
@keyframes push-bell-ping {
  0%   { transform: scale(1);   opacity: .6; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* Anyone who has asked their phone to stop animating things means it. */
@media (prefers-reduced-motion: reduce) {
  .push-bell.is-pinging::after { animation: none; }
  .push-bell__label { transition: none; }
}

.push-bell__dot {
  position: absolute;
  top: 8px;
  right: 8px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: #fff;
  color: var(--color-primary);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.push-panel {
  position: fixed;
  inset: 0;
  z-index: 100001;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, .5);
}
@media (min-width: 640px) {
  .push-panel { align-items: center; }
}
body.push-open { overflow: hidden; }

.push-panel__box {
  position: relative;
  width: 100%;
  max-width: 420px;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  padding: 20px 18px 16px;
  border-radius: var(--radius-lg);
  background: #fff;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
}
.push-panel__x {
  position: absolute;
  top: 6px;
  left: 10px;
  padding: 4px 8px;
  border: 0;
  background: none;
  font-size: 26px;
  line-height: 1;
  color: #6b7280;
  cursor: pointer;
}
.push-panel__title {
  margin: 0 0 6px;
  font-size: 18px;
  line-height: 1.4;
  color: var(--color-primary);
}
.push-panel__sub {
  margin: 0 0 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #4b5563;
}
.push-panel__list {
  flex: 1 1 auto;
  /* Hold a sensible height from the first frame. The stores are embedded in the
     page so they are there immediately, but for the one frame before the picker
     renders - and on the fallback fetch path - the box would otherwise open tiny
     and then jump to full height, which by itself makes people close things. */
  min-height: 40vh;
  overflow-y: auto;
  margin: 0 -4px 10px;
  padding: 0 4px;
  -webkit-overflow-scrolling: touch;
}
.push-store {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 4px;
  border-bottom: 1px solid #f0f0f0;
  font-size: 15px;
  cursor: pointer;
}
.push-store:last-child { border-bottom: 0; }
.push-store input {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: var(--color-primary);
}
.push-panel__msg {
  margin: 0 0 10px;
  min-height: 20px;
  font-size: 14px;
  color: #4b5563;
}
.push-panel__actions {
  display: flex;
  gap: 10px;
  align-items: center;
}
.push-panel__save {
  flex: 1 1 auto;
  padding: 12px 16px;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-primary);
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
/* Disabled until the store list is on screen - see openPanel() in script.js.
   Without the grey it looks broken rather than "not yet". */
.push-panel__save:disabled {
  opacity: .5;
  cursor: default;
}
.push-panel__off {
  padding: 12px 14px;
  border: 1px solid #d1d5db;
  border-radius: var(--radius-md);
  background: #fff;
  color: #6b7280;
  font-size: 14px;
  cursor: pointer;
}

/* ---------- One-tap push ask on an expired offer ----------
   Sits BETWEEN the hero and .offer__content, so unlike the install card it is not
   a descendant of the article container and inherits none of its image/paragraph
   rules. Nothing here needs the two-class defence the install card carries. */
.offer-ask {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-block: var(--space-lg);
  padding: 13px 14px;
  border: 1.5px solid var(--color-primary);
  border-radius: var(--radius-md);
  background: #fdf6f6;
}
.offer-ask__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  inline-size: 34px;
  block-size: 34px;
  border-radius: 50%;
  background: var(--color-primary);
}
.offer-ask__icon svg { inline-size: 18px; block-size: 18px; fill: #fff; }
.offer-ask__text {
  flex: 1 1 auto;
  min-inline-size: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.6;
  color: var(--color-primary);
}
.offer-ask__go {
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--radius-md);
  padding: 10px 18px;
  background: var(--color-primary);
  color: #fff;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.offer-ask__go:disabled { opacity: .6; cursor: default; }

/* After the answer — success or refusal — it stops shouting and becomes a note. */
.offer-ask--done { border-color: #d8d2cd; background: #f6f4f2; }
.offer-ask--done .offer-ask__icon { background: #a49b94; }
.offer-ask--done .offer-ask__text { color: #4b443f; font-weight: 600; }

/* Under ~360px the button and a full sentence cannot share a line without the
   text collapsing to one word per line — the exact fault the bell label hit. */
@media (max-width: 360px) {
  .offer-ask { flex-wrap: wrap; }
  .offer-ask__text { flex: 1 1 100%; order: 2; }
  .offer-ask__go { order: 3; inline-size: 100%; }
}

/* ---------- Install card (PWA), inside the article ----------
   ⚠ Every `img`/`p` rule below is written as `.offer__content .install-card X`
   ON PURPOSE. The article container styles its descendants —
   `.offer__content img { inline-size: 100% }` in particular — and an injected card
   inherits all of it. That has broken the injected coupon card TWICE. A bare
   `.install-card img` ties on specificity and would depend on source order; the
   two-class form wins outright and cannot be undone by a later edit upstream. */
.install-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-block: var(--space-lg);
  padding: 14px;
  border: 1.5px solid var(--color-primary);
  border-radius: var(--radius-md);
  background: #fdf6f6;
}
.install-card__row { display: flex; align-items: center; gap: 11px; }
.install-card__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  inline-size: 52px;
  block-size: 52px;
  border-radius: 12px;
  background: #fff;
  border: 1px solid #ecd9da;
  box-shadow: 0 1px 4px rgba(143, 0, 13, .10);
}
.offer__content .install-card__icon img {
  inline-size: 42px;
  block-size: auto;
  margin-block: 0;
  border-radius: 0;
  display: block;
}
.install-card__text { display: flex; flex-direction: column; gap: 3px; min-inline-size: 0; }
.install-card__text b {
  font-size: 15px;
  font-weight: 800;
  line-height: 1.45;
  color: var(--color-primary);
}
.install-card__text span { font-size: 13px; line-height: 1.6; color: #4b443f; }
.install-card__actions { display: flex; gap: 9px; }
.install-card__go,
.install-card__later {
  font-family: inherit;
  cursor: pointer;
  border-radius: var(--radius-md);
  padding: 11px 16px;
}
.install-card__go {
  flex: 1 1 auto;
  border: 0;
  background: var(--color-primary);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
}
.install-card__later {
  border: 1px solid #d1cbc6;
  background: #fff;
  color: #6b6560;
  font-size: 14px;
}

/* Section heading inside the picker (سوبر ماركت / المستلزمات المنزلية / ...).
   The labels and the grouping both come from the site's own taxonomies, so this
   is pure presentation - see loadStores() in script.js. */
.push-section {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 14px 0 2px;
  padding: 6px 4px 5px;
  background: #fff;
  border-bottom: 2px solid var(--color-primary);
  color: var(--color-primary);
  font-size: 13px;
  font-weight: 700;
}
.push-section:first-child { margin-top: 4px; }

/* "Select all" - separated from the list so it does not read as a store. */
.push-store--all {
  margin-bottom: 4px;
  padding: 12px 4px;
  border-bottom: 1px solid #e5e7eb;
  font-weight: 700;
}
