/* ---------- Fonts, served from this site ----------
   Self-hosted so that opening a page contacts no third party. Only the Arabic
   and Latin subsets are kept; unicode-range lets the browser fetch just the
   subset a page actually uses. El Messiri is a variable font, so one file per
   subset covers 500-700. */
@font-face {
  font-family: 'El Messiri'; font-style: normal; font-weight: 500 700; font-display: swap;
  src: url('../fonts/el-messiri-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'El Messiri'; font-style: normal; font-weight: 500 700; font-display: swap;
  src: url('../fonts/el-messiri-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-400-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-500-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-600-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-700-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/ibm-plex-sans-arabic-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   رفيق السيلياك — Design System · «ليل الواحة» (Nocturne)
   Arabic-first, RTL-native, WCAG 2.2 AA oriented.

   The platform reads on a night-forest ground with cream bands cut into it.
   That is the design itself, not a dark *mode*: the tokens below are the only
   palette, and a cream band re-declares them locally through `.on-cream`, so
   every component keeps working inside either ground without knowing which
   one it is standing on.

   Status colours are NEVER the only signal: every status also carries an icon
   and a text label (see .status-badge).
   ========================================================================== */

:root {
  /* --- Night forest ground --- */
  --bg:            #10291d;
  --bg-alt:        #0c2117;   /* a deeper band, cut into the page */
  --bg-deep:       #0a1d14;   /* footer and the sources block */
  --surface:       #16321f;   /* a raised panel */
  --surface-sunk:  #13291b;   /* an inset well */

  /* --- Ink on the night ground (13.1:1 down to 7.9:1) --- */
  --ink:           #f2ebdd;
  --ink-strong:    #f7f2e8;
  --ink-soft:      #b9ccc0;
  --ink-muted:     #a9bfb2;

  /* --- Brand: gold, the single accent that carries interaction --- */
  --brand:         #d99a4e;   /* 6.4:1 on --bg */
  --brand-deep:    #f0bd7c;   /* links and hover — 9.1:1 on --bg */
  --brand-bright:  #d99a4e;   /* display-size only (≥24px), never body text */
  --brand-soft:    #1d3a27;
  --brand-line:    #4a6450;

  /* --- Primary button: gold on night, night on cream (see .on-cream) --- */
  --btn-bg:        #d99a4e;
  --btn-fg:        #16281b;
  --btn-bg-hover:  #f0bd7c;

  /* --- Secondary accents --- */
  --accent:        #e5a86a;
  --accent-soft:   #2a2416;
  --info:          #8fc4d8;   /* petrol blue — 8.2:1 on --bg */
  --info-soft:     #172b33;

  /* --- Status (all AA against both their soft background and --bg) --- */
  --safe:          #74cd9d;
  --safe-soft:     #14301f;
  --safe-line:     #2f5f42;

  --check:         #edb757;
  --check-soft:    #2e2611;
  --check-line:    #63491b;

  --unsafe:        #f08a7d;
  --unsafe-soft:   #331b18;
  --unsafe-line:   #6a322b;

  --cross:         #e0ab6d;
  --cross-soft:    #2c2213;
  --cross-line:    #5d4322;

  /* --- Lines & shadows --- */
  --line:          rgba(242,235,221,.13);
  --line-strong:   rgba(242,235,221,.28);
  --shadow-sm:     0 1px 2px rgba(0,0,0,.34);
  --shadow-md:     0 6px 20px rgba(0,0,0,.38);
  --shadow-lg:     0 14px 44px rgba(0,0,0,.45);

  /* --- Shape: soft corners throughout; the banner arch is the one big
         curve, and controls are fully rounded. --- */
  --r-sm: 10px;
  --r:    16px;
  --r-lg: 22px;
  --r-xl: 30px;
  --r-pill: 999px;
  --arch: 30px 235px 235px 30px;   /* the curved banner, RTL-facing */

  /* --- Rhythm --- */
  --sp-1: .4rem;
  --sp-2: .8rem;
  --sp-3: 1.2rem;
  --sp-4: 1.9rem;
  --sp-5: 3rem;
  --sp-6: 4.6rem;
  --sp-7: 6.4rem;

  /* Long-form reading rhythm. Separate from --sp-* because these are measured
     against the body line (~26px), not the layout grid. */
  --prose-gap: 1.5rem;   /* 24px — one line, so paragraphs read as separate */
  --prose-h3:  2.5rem;   /* 40px */
  --prose-h2:  clamp(4rem, 1.5rem + 5vw, 6rem);  /* 96px at 1440, 64px on phones */

  --wrap: 1240px;

  /* Two faces with two jobs: El Messiri carries the headings, and a UI face
     built for small sizes carries everything a reader actually reads —
     card copy, captions, filter chips, table cells, footnotes. */
  --font: "IBM Plex Sans Arabic", "Segoe UI", "Noto Sans Arabic", Tahoma, system-ui, sans-serif;
  --font-display: "El Messiri", "IBM Plex Sans Arabic", "Noto Sans Arabic", Tahoma, serif;
}

/* --------------------------------------------------------------------------
   A cream band cut into the night ground. Everything inside re-reads the same
   tokens, so cards, chips, callouts and status badges need no band-aware
   variants — they simply pick up the light values.
   -------------------------------------------------------------------------- */
.on-cream,
.detail-head,
.page-light,
.on-paper {
  --bg:            #f2ebdd;
  --bg-alt:        #e8dfcb;
  --bg-deep:       #e0d5bd;
  --surface:       #ffffff;
  --surface-sunk:  #f7f2e8;

  --ink:           #21281f;
  --ink-strong:    #10291d;
  --ink-soft:      #4b5348;
  --ink-muted:     #5b6357;   /* 5.2:1 on --bg, 4.6:1 on --bg-alt */

  --brand:         #8a5f20;   /* 4.7:1 on cream — the body-text gold */
  --brand-deep:    #6e4a17;
  --brand-bright:  #a8762c;   /* display-size only (3.4:1) */
  --brand-soft:    #f7edda;
  --brand-line:    #ddc79a;

  --btn-bg:        #10291d;
  --btn-fg:        #f2ebdd;
  --btn-bg-hover:  #16321f;

  --accent:        #a8552a;
  --accent-soft:   #fbeee3;
  --info:          #2c5c72;   /* 6.1:1 on cream, 7.3:1 on white */
  --info-soft:     #e5f0f4;

  --safe:          #1c6b46;
  --safe-soft:     #e4f3ea;
  --safe-line:     #b3ddc4;

  --check:         #8a5300;
  --check-soft:    #fdf0d9;
  --check-line:    #f0d09a;

  --unsafe:        #a92d21;
  --unsafe-soft:   #fbe9e7;
  --unsafe-line:   #f2c1bb;

  --cross:         #7a4b12;
  --cross-soft:    #fbf0e2;
  --cross-line:    #eccfa6;

  --line:          #ddd2bb;
  --line-strong:   #c5b699;
  --shadow-sm:     0 1px 2px rgba(28,36,32,.06), 0 2px 6px rgba(28,36,32,.05);
  --shadow-md:     0 4px 14px rgba(28,36,32,.08), 0 10px 30px rgba(28,36,32,.05);
  --shadow-lg:     0 10px 34px rgba(28,36,32,.11), 0 26px 60px rgba(28,36,32,.07);

  background: var(--bg);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Internal routes stand on white paper. The night ground is the home page's
   and the site chrome's; everything a reader settles into to actually read —
   an explorer, a guide, an article, a directory — is dark ink on white, with
   the cream banner and the cream detail slab cut into it for contrast.
   -------------------------------------------------------------------------- */
.page-light,
.on-paper {
  --bg:           #ffffff;
  --bg-alt:       #f7f3ea;
  --bg-deep:      #efe8da;
  --surface:      #fdfbf7;
  --surface-sunk: #f7f3ea;
  --line:         #e2dbcb;
  --line-strong:  #c8bca4;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

:root { --dir: 1; }            /* sign for direction-aware transforms: 1 RTL, -1 LTR */
:root[dir="ltr"] { --dir: -1; }
:root[lang="en"] body { line-height: 1.65; }
/* Latin headings wrap to even lines instead of leaving one word behind. */
:root[lang="en"] :is(h1, h2, h3) { text-wrap: balance; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: clamp(1rem, .96rem + .2vw, 1.075rem);
  line-height: 1.78;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;

  /* Sticky footer: on short pages the footer sits at the bottom instead of
     leaving page background under it. dvh tracks the mobile browser's
     collapsing URL bar, which vh does not. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }
.site-footer { flex-shrink: 0; }

h1, h2, h3, h4 { line-height: 1.4; margin: 0 0 var(--sp-3); font-weight: 700; letter-spacing: -.01em; }
h1 { font-size: clamp(1.85rem, 1.4rem + 2.1vw, 2.9rem); }
h2 { font-size: clamp(1.45rem, 1.2rem + 1.2vw, 2.05rem); }
h3 { font-size: clamp(1.18rem, 1.06rem + .55vw, 1.4rem); }
h4 { font-size: 1.06rem; }
p  { margin: 0 0 var(--sp-3); }
ul, ol { margin: 0 0 var(--sp-3); padding-inline-start: 1.35rem; }
li { margin-bottom: .55rem; }
img { max-width: 100%; height: auto; display: block; }
strong { font-weight: 600; }

a { color: var(--brand-deep); text-underline-offset: .22em; text-decoration-thickness: .07em; }
a:hover { color: var(--brand); }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; inset-inline-start: 1rem; top: -100px; z-index: 999;
  background: var(--brand); color: #16281b; padding: .7rem 1.15rem;
  border-radius: 0 0 var(--r-sm) var(--r-sm); font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: 0; color: #16281b; }

.wrap { width: min(100% - 2rem, var(--wrap)); margin-inline: auto; }
@media (min-width: 700px) { .wrap { width: min(100% - 3rem, var(--wrap)); } }

.muted { color: var(--ink-muted); }
.small { font-size: .875rem; }
.center { text-align: center; }
/* Boot placeholder, shown until the first route renders: the leaf of the
   logo draws itself, its stem grows, and a short bar slides beneath. It is a
   full screen tall so the footer starts below the fold: shorter, and the
   footer showed at the top and then jumped down when the page arrived, the
   site's largest layout shift. */
.loading {
  min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1.1rem; color: var(--brand);
}
.loading-leaf, .loading-stem { stroke-dasharray: 100; stroke-dashoffset: 100; }
.loading-leaf { animation: loading-draw 1.8s ease-in-out infinite; }
.loading-stem { animation: loading-draw 1.8s ease-in-out .35s infinite; }
@keyframes loading-draw {
  0%   { stroke-dashoffset: 100; opacity: .35; }
  45%  { stroke-dashoffset: 0;   opacity: 1; }
  75%  { stroke-dashoffset: 0;   opacity: 1; }
  100% { stroke-dashoffset: -100; opacity: .35; }
}
.loading-bar {
  position: relative; width: 120px; height: 3px; border-radius: 3px; overflow: hidden;
  background: color-mix(in srgb, var(--brand) 18%, transparent);
}
.loading-bar::after {
  content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: 40%; border-radius: 3px;
  background: var(--brand); animation: loading-slide 1.2s ease-in-out infinite;
}
/* Moved with a transform, not an offset, so the loop never counts as layout. */
@keyframes loading-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
@keyframes loading-slide-rtl {
  0%   { transform: translateX(100%); }
  100% { transform: translateX(-250%); }
}
[dir="rtl"] .loading-bar::after { animation-name: loading-slide-rtl; }
@media (prefers-reduced-motion: reduce) {
  .loading-leaf, .loading-stem { animation: none; stroke-dashoffset: 0; }
  .loading-bar::after { animation: none; inset-inline-start: 30%; }
}

/* ---------- Motion ----------
   One ease-out curve for everything that moves in (see bindMotion in app.js).
   The start states apply only under html.motion-on, which is never set under
   reduced motion, so without it every element simply sits in place. */
:root { --ease-out: cubic-bezier(.22, 1, .36, 1); }
@keyframes rise-in { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.motion-on .view-enter .pagehead-text > *,
.motion-on .view-enter .detail-head-text > *,
.motion-on .view-enter > .section > .breadcrumb {
  animation: rise-in 2s var(--ease-out) both;
}
.motion-on .view-enter .pagehead-text > :nth-child(2),
.motion-on .view-enter .detail-head-text > :nth-child(2) { animation-delay: .25s; }
.motion-on .view-enter .pagehead-text > :nth-child(3),
.motion-on .view-enter .detail-head-text > :nth-child(3) { animation-delay: .5s; }
.motion-on .view-enter .pagehead-text > :nth-child(n+4),
.motion-on .view-enter .detail-head-text > :nth-child(n+4) { animation-delay: .75s; }
/* The banner photo slides a short way in from the left to its place against
   the arch, slowing as it arrives — a slide only, no fade. It moves the
   figure, not the panel, so the medallion — which overhangs the panel —
   stays put and fades in once the photo has settled. */
@keyframes slide-ltr {
  from { transform: translateX(calc(-14% * var(--dir, 1))); }
  to   { transform: none; }
}
.motion-on .view-enter .pagehead-figure { animation: slide-ltr 2.8s var(--ease-out) .1s both; }
.motion-on .view-enter .pagehead-badge { animation: fade-in 1.2s var(--ease-out) 1.6s both; }
.motion-on .view-enter .detail-head-media { animation: fade-in 2.6s var(--ease-out) .15s both; }
.motion-on .view-enter .hero-video-media { animation: fade-in 3s var(--ease-out) both; }
.motion-on .view-enter .detail-head { animation: fade-in 1.5s var(--ease-out) both; }

.motion-on .reveal {
  opacity: 0; transform: translateY(32px);
  transition: opacity 1.8s var(--ease-out), transform 1.8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
}
.motion-on .reveal.is-in { opacity: 1; transform: none; }

/* Landing-page sections each enter their own way (data-reveal on the grid):
   drop — from above; zoom — small to full size from the centre; split — the
   cards left of centre from the left and the rest from the right, together
   (--from is set per card in bindMotion). */
.motion-on [data-reveal="drop"] > .reveal  { transform: translateY(-36px); }
.motion-on [data-reveal="zoom"] > .reveal  { transform: scale(.82); transform-origin: center; }
.motion-on [data-reveal="split"] > .reveal { transform: translateX(calc(var(--from, 1) * 70px)); }
.motion-on [data-reveal] > .reveal.is-in   { transform: none; }
/* Cards starting to the side must not widen the page on phones: the band
   clips sideways only, so shadows above and below are untouched. */
.motion-on .band { overflow-x: clip; }

/* A plate of naturally gluten-free food centred above «أدوات سريعة». It turns
   as the page scrolls (bindPlate in app.js); decorative, and still under
   reduced motion. */
.plate-deco { width: 280px; max-width: 100%; margin: 0 auto var(--sp-3); }
.band.band-plate { padding-top: 48px; }
.plate-deco img {
  display: block; width: 100%; height: auto;
  filter: drop-shadow(0 14px 22px rgba(40, 28, 10, .2));
  will-change: transform;
}

/* Hover or keyboard focus on a clickable card eases its photo in slightly.
   The photo's frame clips it, so the card itself keeps its size. */
.card-media, .video-thumb, .prod-photo-wrap { overflow: hidden; }
.card-media img, .video-thumb img, .prod-photo { transition: transform .9s cubic-bezier(.4, 0, .2, 1); }
/* Only where the photo is part of a link: a whole card that is an <a>, or a
   video's thumbnail. A card that only
   holds information never zooms, so the motion always means "this opens". */
a:is(.card, .entry-card):is(:hover, :focus-visible) :is(.card-media img, .prod-photo),
.video-thumb:is(:hover, :focus-visible) img { transform: scale(1.06); }
@media (prefers-reduced-motion: reduce) {
  .card-media img, .video-thumb img, .prod-photo { transition: none; }
  a:is(.card, .entry-card):is(:hover, :focus-visible) :is(.card-media img, .prod-photo),
    .video-thumb:is(:hover, :focus-visible) img { transform: none; }
}

/* The fade must not replace the hover zoom's transition on the same img —
   a lone `transition: opacity` made every lazy card photo snap on hover. */
.motion-on img.fade-img {
  opacity: 0;
  transition: opacity 1.8s var(--ease-out), transform .9s cubic-bezier(.4, 0, .2, 1);
}
.motion-on img.fade-img.is-loaded { opacity: 1; }

@media print {
  .motion-on .reveal, .motion-on img.fade-img { opacity: 1 !important; transform: none !important; }
}

/* ---------- Top strip ---------- */
.topstrip {
  background: var(--brand-deep);
  color: #eaf5ef;
  font-size: .82rem;
  line-height: 1.6;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .45rem 1rem;
  text-align: center;
}
.topstrip p { margin: 0; }
/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 210;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.header-inner {
  display: flex; align-items: center; gap: var(--sp-3);
  padding-block: 1rem;
}
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--brand); flex-shrink: 0; }
.brand-mark { display: block; line-height: 0; }
.brand-text { display: flex; flex-direction: column; line-height: 1.25; }
.brand-text strong { color: var(--ink); font-size: 1.05rem; }
.brand-text small { color: var(--ink-muted); font-size: .74rem; }
@media (max-width: 520px) { .brand-text small { display: none; } }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  font-family: inherit; font-size: .95rem; font-weight: 600; line-height: 1.4;
  padding: .82rem 1.55rem; border-radius: var(--r-pill); border: 1px solid transparent;
  cursor: pointer; text-decoration: none; transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-sm { padding: .58rem 1.1rem; font-size: .87rem; }
.btn-primary { background: var(--btn-bg); color: var(--btn-fg); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--btn-bg-hover); color: var(--btn-fg); box-shadow: var(--shadow-md); }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn-ghost:hover { border-color: var(--brand); color: var(--brand-deep); background: var(--brand-soft); }
.btn-soft { background: var(--brand-soft); color: var(--brand-deep); border-color: var(--brand-line); }
.btn-soft:hover { background: var(--surface); color: var(--brand-deep); }
.btn-block { width: 100%; }

/* ---------- Cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--sp-4);
  box-shadow: var(--shadow-sm);
}
.card-hover { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.card-hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--line-strong); }
a.card { text-decoration: none; color: inherit; display: block; }

/* On the light grounds a card's frame says what it does: a card that opens
   another page has the firmer #ccc5b6 line, a card that only holds content
   the faint #efece7. The night home page keeps its own lines. */
:is(.page-light, .on-cream) { --card-line: #efece7; --card-line-link: #ccc5b6; }
:is(.page-light, .on-cream) :is(.card, .entry-card, .myth-card, .plat-card) { border-color: var(--card-line); }
:is(.page-light, .on-cream) :is(a.card, a.entry-card, .venue-card) { border-color: var(--card-line-link); }
:is(.page-light, .on-cream) :is(a.card, a.entry-card, .venue-card):hover { border-color: var(--line-strong); }
.back-row { display: flex; margin-top: var(--sp-5); }

/* ---------- Clickable cards ----------
   A card that is a link ends in a small arrow chip at its end corner — the
   left in Arabic, pointing the way the reading goes — which fills in on hover
   and focus. A card that only holds information carries none, so the chip is
   the clue rather than the border, which both kinds share. Drawn in CSS with
   empty content, so a screen reader hears the link and not "arrow". Venue
   cards are exempt: only their top half is a link, and they already end in
   an explicit «التفاصيل» button.

   Switched off for now: the rules apply only under .card-arrows, which
   nothing sets. Add class="card-arrows" to <html> in index.html to bring the
   chip back. */
a.card { display: flex; flex-direction: column; }
a.card > .pill-count { align-self: flex-start; }
.card-arrows a.card > :last-child { padding-bottom: .75rem; }
.card-arrows a.card::after,
.card-arrows a.entry-card::after {
  content: "";
  align-self: flex-end;
  margin-top: auto;
  flex-shrink: 0;
  width: 2rem; height: 2rem; border-radius: 50%;
  border: none;
  background: var(--brand-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a5f20' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M11 6l-6 6 6 6'/%3E%3C/svg%3E") center / 1rem no-repeat;
  transition: background-color .16s ease;
}
[dir="ltr"] .card-arrows a.card::after,
[dir="ltr"] .card-arrows a.entry-card::after { transform: scaleX(-1); }
.card-arrows a.card:is(:hover, :focus-visible)::after,
.card-arrows a.entry-card:is(:hover, :focus-visible)::after {
  background-color: var(--brand);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M11 6l-6 6 6 6'/%3E%3C/svg%3E");
}

.grid { display: grid; gap: var(--sp-3); }
/* A grid has no bottom margin of its own, so whatever follows one inside a
   section would otherwise start flush against the last row of cards. */
:is(.section, .tabpanel) > .grid + *,
.wrap > .grid + * { margin-top: var(--sp-4); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(clamp(240px, 44%, 320px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fill, minmax(195px, 1fr)); }

/* ---------- Desktop: fixed card grids fill the page, cards stay equal ----------
   The ladders above are right for results and small screens, but on a desktop
   they left fixed grids short: auto-fill keeps empty tracks (3 cards in a 4-track
   grid-3 stopped three-quarters of the way across), and grid-2's 320px cap made
   it run 3 across, so 4 cards came out 3 + a lone 1.

   From 1200px a fixed grid lays out on 12 tracks and each card spans 12 / per-row
   — a card spanning 3 of 12 is exactly as wide as a real 4-column cell, so card
   widths and gaps are what a plain grid would give. The count picks the split,
   and every card in a grid is the same width:

     cards   grid-3 / grid-4        grid-2
       1          1                   1
       2          2                   2
       3          3                   3
       4          4                 2 + 2
       5        3 + 2·              3 + 2·
       6        3 + 3               3 + 3
       8        4 + 4             3 + 3 + 2·
       9      3 + 3 + 3           3 + 3 + 3
      14   4 + 4 + 4 + 2·         3 × 4 + 2·        · = last row short

   An even split wins where there is one; otherwise the last row is left short
   rather than widening its cards, so a grid never mixes card sizes. A grid that
   fits in one row does fill it — its cards are equal anyway. Nothing gets
   denser than it was: grid-2 holds the wide cards and stays at most 3 across,
   grid-3 and grid-4 at most 4.

   Two opt-outs. .grid-results: a directory re-renders on every filter, and
   fitting it by count would resize the cards as you filter — one search result
   would become a 1240px card, so it keeps the ladder above. .grid-thirds: a page
   of several grids that should share one column count (the symptom groups on
   /knowledge/symptoms, whose 2-card group sits as two thirds, not two halves).

   Each rule below is written to outrank the one before it: the count queries
   carry their :has() argument's specificity, so a mode switch beats the rule it
   replaces. */
@media (min-width: 1200px) {
  .grid-2:not(.grid-results, .grid-thirds),
  .grid-3:not(.grid-results, .grid-thirds),
  .grid-4:not(.grid-results, .grid-thirds) { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .grid-thirds { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* grid-3 / grid-4 — four across; one or two cards take the whole row. */
  :is(.grid-3, .grid-4):not(.grid-results, .grid-thirds) > * { grid-column: span 3; }
  :is(.grid-3, .grid-4):not(.grid-results, .grid-thirds) > :only-child { grid-column: span 12; }
  :is(.grid-3, .grid-4):not(.grid-results, .grid-thirds)
    > :is(:first-child:nth-last-child(2), :nth-child(2):last-child) { grid-column: span 6; }
  /* …three across when the count divides by 3 but not by 4 (3, 6, 9, 18), or when
     fours would strand one card and threes leave two (5, 17). */
  :is(.grid-3, .grid-4):not(.grid-results, .grid-thirds):is(
      :has(> :last-child:nth-child(3n)):not(:has(> :last-child:nth-child(4n))),
      :has(> :last-child:nth-child(12n+5))) > * { grid-column: span 4; }

  /* grid-2 — three across; two cards take the row as halves. */
  .grid-2:not(.grid-results, .grid-thirds) > * { grid-column: span 4; }
  .grid-2:not(.grid-results, .grid-thirds)
    > :is(:first-child:nth-last-child(2), :nth-child(2):last-child) { grid-column: span 6; }
  /* …two across when threes would strand one card (4, 10), and a single card
     takes the row. */
  .grid-2:not(.grid-results, .grid-thirds):has(> :last-child:nth-child(3n+1)) > * { grid-column: span 6; }
  .grid-2:not(.grid-results, .grid-thirds):has(> :last-child:nth-child(3n+1)) > :only-child { grid-column: span 12; }
}

.section { padding-block: var(--sp-6); }
.section + .section { border-top: 1px solid var(--line); }
.section-head { margin-bottom: var(--sp-4); max-width: 62ch; }
.section-head p { color: var(--ink-soft); margin-bottom: 0; }

/* Headings ship with no top margin, so a new section inside a .section used to
   get the same 19px a line break gets. Sibling margins collapse, so each gap
   below is the larger of the pair: 24 between paragraphs, 40 before an h3,
   64 before an h2 — and the heading binds to its own content at 12.
   Scoped to direct children: prose inside cards and accordions stays tight. */
:is(.section, .tabpanel) > p,
:is(.section, .tabpanel) > ul,
:is(.section, .tabpanel) > ol,
:is(.section, .tabpanel) > dl { margin-bottom: var(--prose-gap); }
:is(.section, .tabpanel) > * + h2 { margin-top: var(--prose-h2); }
/* The same break for the h2s the rule above cannot reach: the main column of a
   detail page (/food/*, /ingredient/*), and the grouped lists (/faq,
   /associations, /support, the symptom groups) where each h2 opens a nested
   <section>. The group's margin collapses with the previous group's, so groups
   end up exactly one break apart. Headings that open a box — steps, triad
   panels, cards — are their box's first child and are never matched. */
.detail-grid > div > * + h2,
:is(.section, .tabpanel) > section:has(> h2:first-child):not(:first-child) { margin-top: var(--prose-h2); }
:is(.section, .tabpanel) > * + h3 { margin-top: var(--prose-h3); }
:is(.section, .tabpanel) > h2 { margin-bottom: .75rem; }
:is(.section, .tabpanel) > h3 { margin-bottom: .6rem; }
:is(.section, .tabpanel) > :first-child { margin-top: 0; }
/* .grid + * is (0,2,0) and would outrank the heading breaks above, so a heading
   after a card grid needs its own rule at matching specificity. */
:is(.section, .tabpanel) > .grid + h2 { margin-top: var(--prose-h2); }
:is(.section, .tabpanel) > .grid + h3 { margin-top: var(--prose-h3); }
/* A callout introduced by a heading binds to it like any other content, instead
   of keeping the 30px it uses when it stands alone between paragraphs. */
:is(.section, .tabpanel) > h2 + .callout,
:is(.section, .tabpanel) > h3 + .callout { margin-top: .75rem; }
.eyebrow {
  display: inline-block; font-size: .78rem; font-weight: 700; letter-spacing: .04em;
  color: var(--brand); background: var(--brand-soft); border: 1px solid var(--brand-line);
  padding: .25rem .7rem; border-radius: var(--r-pill); margin-bottom: .8rem;
}

/* ---------- Status system (colour + icon + text, never colour alone) ---------- */
.status-badge {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .82rem; font-weight: 700; line-height: 1.3;
  padding: .38rem .85rem; border-radius: var(--r-pill); border: 1px solid;
  white-space: nowrap;
}
.status-badge .dot { font-size: .9em; }
.st-safe   { color: var(--safe);   background: var(--safe-soft);   border-color: var(--safe-line); }
.st-check  { color: var(--check);  background: var(--check-soft);  border-color: var(--check-line); }
.st-unsafe { color: var(--unsafe); background: var(--unsafe-soft); border-color: var(--unsafe-line); }
.st-cross  { color: var(--cross);  background: var(--cross-soft);  border-color: var(--cross-line); }


/* ---------- Callouts ---------- */
.callout {
  /* Tinted, with a side rule and no outer frame: warnings stand out from the
     text around them without reading as another box on the page. */
  border: 0;
  border-inline-start: 4px solid var(--brand);
  background: var(--brand-soft);
  border-radius: var(--r-sm);
  padding: var(--sp-3) var(--sp-4);
  /* Both margins, not just the bottom one: a callout that follows a grid or a
     card had nothing pushing it away, because neither of those carries a
     bottom margin, and the two ended flush. Sibling margins collapse, so two
     stacked callouts still sit one gap apart. */
  margin-block: var(--sp-4);
}
.callout > :last-child { margin-bottom: 0; }
.callout-title { display: flex; align-items: center; gap: .5rem; font-weight: 700; margin-bottom: .45rem; }
.callout-warn   { border-inline-start-color: var(--check);  background: var(--check-soft); }
.callout-danger { border-inline-start-color: var(--unsafe); background: var(--unsafe-soft); }
.callout-safe   { border-inline-start-color: var(--safe);   background: var(--safe-soft); }
.callout-info   { border-inline-start-color: var(--info); background: var(--info-soft); }

/* ---------- Hero ---------- */
.hero {
  position: relative; overflow: hidden;
  background:
    radial-gradient(1100px 460px at 88% -12%, var(--brand-soft), transparent 62%),
    radial-gradient(760px 380px at 6% 6%, var(--accent-soft), transparent 58%),
    var(--bg);
  border-bottom: 1px solid var(--line);
}
.hero-inner { padding-block: clamp(2.5rem, 1.4rem + 5vw, 5rem); }
.hero h1 { max-width: 17ch; margin-bottom: var(--sp-3); }
.hero-lead { font-size: clamp(1.03rem, .98rem + .35vw, 1.2rem); color: var(--ink-soft); max-width: 56ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: var(--sp-4); }

/* A grid item sizes to its widest child by default; the search input would
   otherwise push the text column past a phone screen. */
.pagehead-text { min-width: 0; }
.hero-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .85rem; }
.chip {
  font-size: .83rem; padding: .45rem .95rem; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink-soft); text-decoration: none; cursor: pointer;
  font-family: inherit;
}
.chip:hover { border-color: var(--brand); color: var(--brand-deep); background: var(--brand-soft); }
.chip[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: var(--btn-fg); font-weight: 600; }
/* A chip used as a label rather than a control: same shape, no affordance. */
.chip-static { cursor: default; align-self: flex-start; }
.chip-static:hover { border-color: var(--line-strong); color: var(--ink-soft); background: var(--surface); }

/* ---------- Status triad panels ---------- */
/* ---------- Risk guide (eating out) ----------
   One scale, low to high, read in the direction of the page: a bar shades
   from green to red over three columns. Each column names its level in words
   and emoji, lists the kinds of places, then the signs to watch for. */
.risk { margin-bottom: var(--sp-4); }
.risk-scale {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: .8rem; font-weight: 700; color: var(--ink-muted);
  padding-bottom: .9rem; margin-bottom: var(--sp-4); position: relative;
}
.risk-scale::after {
  content: ""; position: absolute; inset-inline: 0; bottom: 0; height: 8px; border-radius: 4px;
  background: linear-gradient(to left, var(--safe), var(--check), var(--unsafe));
}
/* Green always at the start of the reading line. */
[dir="ltr"] .risk-scale::after {
  background: linear-gradient(to right, var(--safe), var(--check), var(--unsafe));
}
.risk-col { display: flex; flex-direction: column; }
.risk { display: grid; gap: var(--sp-4) var(--sp-5); }
@media (min-width: 900px) {
  .risk { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .risk-scale { grid-column: 1 / -1; margin-bottom: 0; }
}
.risk-col h3 { display: flex; align-items: center; gap: .5rem; font-size: 1.35rem; margin-bottom: .7rem; }
.risk-low h3  { color: var(--safe); }
.risk-mid h3  { color: var(--check); }
.risk-high h3 { color: var(--unsafe); }
.risk-places { list-style: none; margin: 0 0 var(--sp-3); padding: 0; }
.risk-places li {
  position: relative; padding: .5rem 0; padding-inline-start: 1.1rem;
  border-bottom: 1px solid var(--line); font-size: .97rem;
}
.risk-places li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 1.05rem;
  width: .45rem; height: .45rem; border-radius: 50%; background: currentColor;
}
.risk-low  .risk-places li::before { color: var(--safe); }
.risk-mid  .risk-places li::before { color: var(--check); }
.risk-high .risk-places li::before { color: var(--unsafe); }
.risk-signs { margin-top: auto; border-radius: var(--r-sm); padding: .8rem 1rem; background: var(--safe-soft); }
.risk-mid  .risk-signs { background: var(--check-soft); }
.risk-high .risk-signs { background: var(--unsafe-soft); }
.risk-signs-title { font-weight: 700; margin: 0 0 .3rem; font-size: .92rem; color: var(--ink-strong); }
.risk-signs ul { margin: 0; padding-inline-start: 1.1rem; font-size: .92rem; }
.risk-signs li { margin-bottom: .2rem; }

/* ---------- Text block ----------
   Text that is not a link or a picture sits on the page with no frame. Side
   by side in a grid, each column is marked by a dot beside its title — gold,
   or green / amber / red for a status — and the same dots on its list items. Every status heading also says its status
   in words, so the colour never carries it alone. A heading that already
   opens with an emoji marker keeps that instead of the dot. */
.block { --block-c: var(--brand); }
.block-safe   { --block-c: var(--safe); }
.block-check  { --block-c: var(--check); }
.block-unsafe { --block-c: var(--unsafe); }
.grid:has(> .block) { column-gap: var(--sp-5); row-gap: var(--sp-4); }
.block > :last-child { margin-bottom: 0; }
.block-safe > h3   { color: var(--safe); }
.block-check > h3  { color: var(--check); }
.block-unsafe > h3 { color: var(--unsafe); }

.grid > .block > h3 { display: flex; align-items: center; gap: .55rem; font-size: 1.12rem; margin-bottom: .6rem; }
.grid > .block > h3:not(:has(> span[aria-hidden]))::before {
  content: ""; flex-shrink: 0; width: .7rem; height: .7rem; border-radius: 50%; background: var(--block-c);
}
.grid > .block > ul { list-style: none; padding: 0; }
.grid > .block > ul > li { position: relative; padding-inline-start: 1.05rem; margin-bottom: .4rem; }
.grid > .block > ul > li:last-child { margin-bottom: 0; }
.grid > .block > ul > li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: .72em;
  width: .38rem; height: .38rem; border-radius: 50%; background: var(--block-c); opacity: .75;
}

/* ---------- Journey / steps ---------- */
.steps { list-style: none; padding: 0; margin: 0; display: grid; }
.step {
  display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); align-items: start;
  padding-block: var(--sp-3); border-bottom: 1px solid var(--line);
}
.step:first-child { padding-top: 0; }
.step:last-child { border-bottom: 0; padding-bottom: 0; }
.step-num {
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: var(--brand-soft); color: var(--brand-deep);
  border: 1px solid var(--brand-line);
  display: grid; place-items: center; font-weight: 700; font-size: 1.05rem;
}
.step h3 { margin-bottom: .4rem; }
.step > div > :last-child { margin-bottom: 0; }

/* The newly-diagnosed stages: numbered accordions, one open at a time. */
.journey { list-style: none; padding: 0; margin: 0; display: grid; gap: .75rem; }
.journey summary { justify-content: flex-start; padding-block: .9rem; }
.journey .step-num { width: 2.2rem; height: 2.2rem; font-size: .95rem; flex-shrink: 0; }
.journey-title { flex: 1; font-size: 1.05rem; }

/* ---------- Diagnosis path: two phases of numbered steps ---------- */
.dx-path { display: grid; gap: var(--sp-4); margin-bottom: var(--sp-5); align-items: start; }
@media (min-width: 900px) { .dx-path { grid-template-columns: 3fr 2fr; column-gap: var(--sp-5); } }
.dx-phase-head {
  background: var(--safe-soft); border-radius: var(--r);
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
}
.dx-phase.is-gluten .dx-phase-head { background: var(--check-soft); }
.dx-phase-head > :last-child { margin-bottom: 0; }
.dx-phase-title { margin: 0 0 .35rem; font-size: 1.15rem; }
.dx-phase-note {
  display: flex; align-items: center; gap: .45rem; margin: 0;
  font-weight: 700; font-size: .95rem; color: var(--ink-strong);
}
.dx-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.dx-step { --dx-disc: 2.4rem; position: relative; display: grid; grid-template-columns: var(--dx-disc) 1fr; gap: .85rem; }
.dx-step:not(:last-child)::after {
  content: ""; position: absolute; inset-inline-start: calc(var(--dx-disc) / 2 - 1px);
  top: var(--dx-disc); bottom: -.75rem; width: 2px; background: var(--line-strong);
}
.dx-num {
  width: var(--dx-disc); height: var(--dx-disc); border-radius: 50%;
  display: grid; place-items: center; font-weight: 800; font-size: 1.05rem;
  background: var(--surface); color: var(--ink-strong); border: 2px solid var(--line-strong);
  position: relative; z-index: 1;
}
.dx-step.is-key .dx-num { background: var(--brand); border-color: var(--brand); color: #fff; }
.dx-body { padding-top: .35rem; padding-bottom: .25rem; }
.dx-title { margin: 0 0 .2rem; font-weight: 700; color: var(--ink-strong); font-size: 1.02rem; }
.dx-note { margin: 0; color: var(--ink-soft); font-size: .95rem; line-height: 1.7; }
@media (max-width: 599px) {
  .dx-step { --dx-disc: 2.1rem; gap: .6rem; }
}
.dx-tag {
  display: inline-block; margin-inline-start: .35rem; vertical-align: middle;
  background: var(--brand-soft); color: var(--brand-deep); border: 1px solid var(--brand-line);
  border-radius: var(--r-pill); padding: .05rem .55rem; font-size: .78rem; font-weight: 700;
}

/* ---------- Accordion ---------- */
.accordion { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--surface); }
.accordion + .accordion { margin-top: .75rem; }
.accordion summary {
  cursor: pointer; padding: 1.2rem var(--sp-4); font-weight: 600; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
}
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after { content: "＋"; color: var(--brand); font-weight: 700; flex-shrink: 0; }
.accordion[open] summary::after { content: "－"; }
.accordion summary:hover { background: var(--surface-sunk); }
.accordion-body { padding: 0 var(--sp-4) var(--sp-4); border-top: 1px solid var(--line); padding-top: var(--sp-3); }
.accordion-body > :last-child { margin-bottom: 0; }

/* ---------- Tables ---------- */
.table-scroll { overflow-x: auto; margin-bottom: var(--sp-4); border: 1px solid var(--line); border-radius: var(--r); }
table { width: 100%; border-collapse: collapse; font-size: .93rem; background: var(--surface); }
th, td { padding: 1rem 1.25rem; text-align: start; border-bottom: 1px solid var(--line); vertical-align: top; }
th { background: var(--surface-sunk); font-weight: 700; }
tbody tr:last-child td { border-bottom: 0; }

/* ---------- Filter bar ---------- */
.filterbar {
  display: flex; flex-wrap: wrap; gap: .55rem; align-items: center;
  margin-bottom: var(--sp-3);
}
.searchbox {
  display: flex; align-items: center; gap: .5rem; width: 100%;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-pill); padding: .4rem; padding-inline-start: 1.15rem; margin-bottom: var(--sp-4);
}
.searchbox:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.searchbox input {
  flex: 1; min-width: 0; border: 0; background: transparent; color: var(--ink);
  font-family: inherit; font-size: .98rem; padding: .6rem 0;
}
.searchbox input:focus { outline: none; }

/* ---------- Food / entry cards ---------- */
.entry-card {
  display: flex; flex-direction: column; gap: .55rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--sp-4);
  text-decoration: none; color: inherit;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.entry-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.entry-card h3 { margin: 0; font-size: 1.06rem; }
.entry-card .en { color: var(--ink-muted); font-size: .8rem; direction: ltr; text-align: start; }
.entry-card .en[lang="ar"] { direction: rtl; }
.entry-card p { margin: 0; font-size: .89rem; color: var(--ink-soft); }
.entry-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; }

/* Pictures live on cards; a guide's body stays text. A card image runs edge to
   edge across the card's top at one shared shape, so a row of cards keeps one
   top line whatever the source ratio (the square food and alternative pictures
   are centre-cropped to it). Only a recipe or article page opens on a picture,
   and a food page's head carries a square thumbnail. */
.entry-card.has-media, .card.has-media { padding-top: 0; overflow: hidden; }
.card-media { margin-inline: calc(var(--sp-4) * -1); margin-bottom: .35rem; }
.card-media img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
/* A .card is block layout, so the photo's own margin is the only gap above the
   title; .entry-card gets its spacing from the flex gap instead. */
.card.has-media > .card-media { margin-bottom: var(--sp-3); }
.entry-id { display: flex; align-items: center; gap: .75rem; min-width: 0; }
.thumb {
  flex-shrink: 0; object-fit: cover; background: var(--surface-sunk);
}

/* ---------- Market product cards ----------
   No licensed product photography exists for these entries, so the default is
   a monogram tile rather than a stock photo standing in for a real package.
   Drop a real path into `image` and .prod-photo renders instead. */
/* Video channel avatar, round as it is on YouTube. */
.channel-logo {
  width: 56px; height: 56px; flex: none; border-radius: 50%;
  border: 1px solid var(--line); object-fit: cover; background: #fff;
}
/* Venue logo from the venue's own site; the tile carries its own ground colour. */
.venue-logo {
  width: 44px; height: 44px; flex: none; border-radius: 10px;
  border: 1px solid var(--line); background: #fff; object-fit: cover;
}
.prod-card { padding-top: 0; overflow: hidden; }
.prod-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .3rem; aspect-ratio: 16 / 9; margin-inline: calc(var(--sp-4) * -1);
  margin-bottom: .35rem;
  background:
    radial-gradient(120% 120% at 50% 0%, var(--brand-soft), transparent 70%),
    var(--surface-sunk);
  border-bottom: 1px solid var(--line);
}
.prod-tile-icon { font-size: 2.1rem; line-height: 1; }
.prod-tile-brand {
  font-size: .78rem; font-weight: 700; letter-spacing: .04em;
  color: var(--brand-deep); text-transform: uppercase;
}
/* Brand logo stands in for a pack photo: white ground, since logos are drawn for it. */
.prod-tile-logo { background: #fff; padding: 1rem; }
.prod-tile-logo img { max-width: 60%; max-height: 100%; height: auto; object-fit: contain; }
/* max-width: none, or the site-wide img cap (100%) would stop the photo at
   the card's inner width while the negative margins still pulled it
   sideways — a pack sitting off-centre with an empty strip on one side. */
.prod-photo-wrap {
  width: calc(100% + var(--sp-4) * 2); max-width: none; margin-inline: calc(var(--sp-4) * -1);
  background: var(--surface-sunk); border-bottom: 1px solid var(--line); margin-bottom: .35rem;
}
.prod-photo { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: contain; }
/* Photo unavailable: hide it rather than show a broken-image glyph. */
.prod-photo-wrap:has(.prod-photo.is-broken) { display: none; }
.barcode {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 1.05rem; letter-spacing: .08em;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); padding: .15rem .5rem;
}

/* ---------- Video cards ----------
   Thumbnail only, never an embedded player: the image loads from YouTube's
   image CDN and nothing starts tracking the reader until they click through. */
.video-card { padding-top: 0; overflow: hidden; gap: .5rem; }
.video-thumb {
  position: relative; display: block; line-height: 0;
  margin-inline: calc(var(--sp-4) * -1); margin-bottom: .5rem;
  background: var(--surface-sunk); border-bottom: 1px solid var(--line);
}
.video-thumb img {
  width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block;
  transition: opacity .18s ease;
}
.video-thumb:hover img { opacity: .88; }
.video-play {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: center;
  font-size: 0; color: transparent;      /* the glyph is replaced by drawn shapes */
}
/* A solid round button with a drawn triangle: a text glyph rendered grey on a
   dark tile and flipped in right-to-left. direction is fixed so it never flips. */
.video-play::before {
  content: ""; position: absolute; width: 4.2rem; height: 4.2rem; border-radius: 50%;
  background: rgba(255, 255, 255, .94); box-shadow: 0 6px 22px rgba(0, 0, 0, .38);
  transition: background .18s ease, transform .18s ease;
}
.video-play::after {
  content: ""; position: absolute; width: 0; height: 0;
  border-block: .8rem solid transparent; border-inline-start: 1.3rem solid #6e4a17;
  border-inline-end: 0; transform: translateX(.12rem); direction: ltr;
}
html[dir="rtl"] .video-play::after { border-inline-start: 0; border-left: 1.3rem solid #6e4a17; transform: translateX(.12rem); }
html[dir="ltr"] .video-play::after { border-left: 1.3rem solid #6e4a17; border-inline-start: 0; }
.video-thumb:hover .video-play::before { background: #fff; transform: scale(1.08); }
/* Thumbnail unavailable (removed video, blocked CDN, offline): keep the frame
   and say what the reader is clicking, instead of a broken-image glyph. */
.video-fallback { display: none; }
.video-thumb.is-broken { aspect-ratio: 16 / 9; }
.video-thumb.is-broken img,
.video-thumb.is-broken .video-play { display: none; }
.video-thumb.is-broken .video-fallback {
  position: absolute; inset: 0; display: grid; place-items: center;
  gap: .35rem; padding: var(--sp-4); text-align: center; line-height: 1.5;
  font-size: .92rem; font-weight: 500; color: var(--ink-soft);
}
/* YouTube titles are the platform's own — often long and emoji-laden. They are
   stored verbatim and clamped for display, never rewritten to look tidier. */
.video-title {
  font-size: 1rem; line-height: 1.45; margin: 0;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}

/* ---------- Support programme cards ---------- */
/* ---------- Organisation cards (associations) ----------
   A fixed 64px square so marks of every shape line up down the column. Logos
   are fitted on white (their own ground); a body without one gets its initial
   in a circle, so it is plainly a placeholder and never mistaken for a mark. */
.org-head { display: flex; align-items: center; gap: .9rem; margin-bottom: .75rem; }
.org-head h3 { margin: 0 0 .15rem; }
.org-logo {
  flex: none; width: 64px; height: 64px; border-radius: var(--r-sm);
  background: #fff; border: 1px solid var(--line); object-fit: contain;
}
.org-initial {
  display: grid; place-items: center; border-radius: 50%;
  font-family: var(--font-display); font-weight: 700; font-size: 1.6rem; line-height: 1;
  color: var(--brand-deep); background: var(--brand-soft); border-color: var(--brand-line);
}

/* ---------- Support programmes ----------
   Reading on one side, the figures and actions on the other; programmes are
   split by a hairline rather than boxed. */
.prog-list > .prog + .prog { border-top: 1px solid var(--line-strong); }
.prog { display: grid; gap: var(--sp-3) var(--sp-5); padding-block: var(--sp-4); }
@media (min-width: 900px) { .prog { grid-template-columns: minmax(0, 1fr) 17rem; } }
.prog-list > .prog:first-child { padding-top: var(--sp-2); }
.prog-body { margin: 0 0 .2rem; font-size: .85rem; font-weight: 700; color: var(--brand-deep); }
.prog-main h3 { font-size: 1.3rem; margin-bottom: .5rem; }
.prog-main > :last-child { margin-bottom: 0; }
.prog-more { margin: .2rem 0 var(--sp-3); }
.prog-more > summary {
  cursor: pointer; display: inline-flex; align-items: center; gap: .4rem;
  font-weight: 700; color: var(--brand-deep); list-style: none;
}
.prog-more > summary::-webkit-details-marker { display: none; }
.prog-more > summary::after { content: "＋"; font-weight: 700; }
.prog-more[open] > summary::after { content: "－"; }
.prog-more-body { margin-top: .6rem; padding-inline-start: var(--sp-3); border-inline-start: 2px solid var(--brand-line); }
.prog-caution { margin: 0 0 .5rem; }
.prog-source { margin: 0; }
.prog-side { display: flex; flex-direction: column; align-items: flex-start; gap: .75rem; }
.prog-amount { margin: 0; font-size: 1rem; font-weight: 800; line-height: 1.35; color: var(--safe); }
.prog-links { display: flex; flex-direction: column; align-items: stretch; gap: .5rem; align-self: stretch; }
.prog-links .btn { justify-content: center; text-align: center; }

/* ---------- Venue cards ----------
   The card is a container, not a link, so the address and the map/phone
   actions stay independently clickable instead of nesting inside an <a>. */
.venue-card { gap: .5rem; }
.venue-card .status-badge { align-self: flex-start; }
.venue-card-main {
  display: flex; flex-direction: column; gap: .5rem;
  text-decoration: none; color: inherit;
}
.venue-card-main:hover h3 { color: var(--brand-deep); }
/* Where and how to reach it, as plain links: the address opens the map, the
   number dials it. The card's upper half already opens the details. */
.venue-contact {
  list-style: none; margin: auto 0 0; padding: .7rem 0 0;
  border-top: 1px solid var(--line); display: grid; gap: .45rem;
}
.venue-contact li { margin: 0; }
.venue-contact a {
  display: flex; align-items: flex-start; gap: .45rem;
  font-size: .9rem; line-height: 1.55; color: var(--brand-deep); text-decoration: none;
}
.venue-contact a:hover span:not([aria-hidden]),
.venue-contact a:focus-visible span:not([aria-hidden]) { text-decoration: underline; }
.venue-contact-icon { flex-shrink: 0; }
.venue-contact-out { font-size: .8rem; opacity: .8; }

/* ---------- Detail page ---------- */
.breadcrumb { font-size: .85rem; color: var(--ink-muted); margin-bottom: var(--sp-3); }
.breadcrumb a { color: var(--ink-muted); }
.detail-grid { display: grid; gap: var(--sp-5); }
@media (min-width: 900px) { .detail-grid { grid-template-columns: minmax(0,1fr) 320px; align-items: start; } }
.sidebar { display: grid; gap: var(--sp-4); position: sticky; top: 8rem; }

/* ---------- Source / governance block ---------- */
.governance {
  background: var(--surface-sunk); border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm); padding: var(--sp-3) var(--sp-4); font-size: .87rem;
  color: var(--ink-soft); margin-top: var(--sp-6);
}
/* The block usually closes a page that ends in a card grid, and `.grid + *` is
   (0,2,0) — it would drag the slab back to the 30px a grid gives any sibling.
   Matching specificity keeps the full break wherever the block lands. */
:is(.section, .tabpanel) > .grid + .governance,
.wrap > .grid + .governance { margin-top: var(--sp-6); }
.governance h2 { margin-bottom: .5rem; font-size: .95rem; color: var(--ink); font-family: var(--font); }
.governance h3 { margin: .8rem 0 .4rem; font-size: .9rem; color: var(--ink); font-family: var(--font); }
/* The reference list folds behind one line; the sentence above it stays visible. */
.gov-refs summary {
  cursor: pointer; font-weight: 600; font-size: .87rem; color: var(--brand-deep);
  padding-block: .15rem; width: fit-content;
}
.gov-refs[open] summary { margin-bottom: .5rem; }
.gov-refs ul { margin-bottom: .5rem; }
.governance ul { margin: 0; padding-inline-start: 1.2rem; }
.governance li { margin-bottom: .25rem; }
.review-pending { color: var(--check); font-weight: 600; }

.evidence-tag {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .74rem; font-weight: 700; padding: .2rem .6rem; border-radius: var(--r-pill);
  border: 1px solid; margin-bottom: .6rem;
}
.ev-medical   { color: var(--info); background: var(--info-soft); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.ev-lifestyle { color: var(--accent); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.ev-community { color: var(--ink-muted); background: var(--surface-sunk); border-color: var(--line-strong); }

/* ---------- Checklist ---------- */
.checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.checklist li {
  display: flex; gap: .75rem; align-items: flex-start; margin: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 1rem 1.2rem;
}
/* WCAG 2.2 SC 2.5.8 asks for 24x24; the row itself is the real target, so the
   label stretches to fill it and a tap anywhere on the line toggles. */
.checklist input[type="checkbox"] { width: 1.5rem; height: 1.5rem; margin-top: .16rem; accent-color: var(--brand); flex-shrink: 0; }
.checklist label { cursor: pointer; flex: 1; min-width: 0; padding-block: .15rem; }
.checklist li.done { background: var(--safe-soft); border-color: var(--safe-line); }
.checklist li.done label { text-decoration: line-through; opacity: .7; }
.checklist .note { display: block; font-size: .84rem; color: var(--ink-muted); margin-top: .2rem; }
.progress-wrap { display: flex; align-items: center; gap: .8rem; margin-bottom: var(--sp-3); }
.progress-bar { flex: 1; height: 10px; background: var(--bg-alt); border-radius: var(--r-pill); overflow: hidden; border: 1px solid var(--line); }
.progress-fill { height: 100%; background: var(--brand); transition: width .3s ease; }

/* ---------- Myth cards ---------- */
.myth-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.myth-head { background: var(--unsafe-soft); color: var(--unsafe); padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--unsafe-line); }
.myth-head .label { font-size: .78rem; font-weight: 700; display: block; margin-bottom: .2rem; }
.myth-head p { margin: 0; font-weight: 600; }
.myth-body { padding: var(--sp-3) var(--sp-4); }
.myth-body .label { font-size: .78rem; font-weight: 700; color: var(--safe); display: block; margin-bottom: .3rem; }
.myth-body > :last-child { margin-bottom: 0; }

/* ---------- Ask assistant ---------- */

/* ---------- Quick facts (myths page) ----------
   Light items on the page: a coloured dot beside each title and its kind in
   words (the tag) above it, so the colour only repeats what the tag says. */
.fact-grid { display: grid; gap: var(--sp-4) var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }
.fact { --fact-c: var(--safe); }
.fact.k-warn   { --fact-c: var(--check); }
.fact.k-info   { --fact-c: var(--info); }
.fact.k-danger { --fact-c: var(--unsafe); }
.fact-tag { display: block; font-size: .8rem; font-weight: 700; color: var(--fact-c); margin-bottom: .3rem; }
.fact h3 { display: flex; align-items: center; gap: .5rem; font-size: 1.1rem; margin: 0 0 .35rem; }
.fact h3::before {
  content: ""; flex-shrink: 0; width: .7rem; height: .7rem; border-radius: 50%; background: var(--fact-c);
}
.fact p { margin: 0; font-size: .95rem; color: var(--ink-soft); }

/* ---------- Symptom lists ----------
   A compact two- or three-column list: name, then one line of explanation,
   rows split by a hairline — scanned like an index, not read as cards. */
.sym-group { margin-bottom: var(--sp-5); }
.sym-head { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.sym-icon {
  width: 2.6rem; height: 2.6rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-soft); font-size: 1.3rem;
}
.sym-count {
  font-family: var(--font); font-size: .82rem; font-weight: 700; color: var(--ink-muted);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill); padding: .1rem .6rem;
}
.sym-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; column-gap: var(--sp-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
}
.sym-list li {
  position: relative; padding: .85rem 0 .85rem; padding-inline-start: 1.1rem;
  border-bottom: 1px solid var(--line);
}
.sym-list li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 1.35rem;
  width: .45rem; height: .45rem; border-radius: 50%; background: var(--brand);
}
.sym-list h3 { font-size: 1.02rem; margin: 0 0 .2rem; }
.sym-list p { margin: 0; font-size: .93rem; color: var(--ink-soft); line-height: 1.7; }

/* ---------- Certification ladder ---------- */
.cert-ladder { list-style: none; margin: 0 0 var(--sp-4); padding: 0; counter-reset: none; }
.cert-row {
  display: grid; gap: .6rem var(--sp-4); align-items: center;
  grid-template-columns: minmax(0, 1fr);
  padding: var(--sp-3) 0; border-bottom: 1px solid var(--line);
}
.cert-row:first-child { border-top: 1px solid var(--line); }
@media (min-width: 900px) {
  .cert-row { grid-template-columns: 15rem 17rem minmax(0, 1fr); }
}
.cert-id { display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; }
.cert-num { margin: 0 0 .35rem; display: flex; align-items: baseline; gap: .35rem; color: var(--ink-soft); font-size: .9rem; }
.cert-num b { font-size: 2rem; line-height: 1; color: var(--ink-strong); font-variant-numeric: tabular-nums; }
.cert-num b.is-word { font-size: 1.35rem; }
.cert-meter { display: block; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; max-width: 14rem; }
.cert-meter > span { display: block; height: 100%; background: var(--check); border-radius: 3px; }
.cert-note { font-size: .95rem; }
.cert-note a { display: inline-block; margin-top: .3rem; }

/* ---------- Product-category guides (labels page) ---------- */
.pg-list { display: grid; gap: var(--sp-5); }
.pg-head { display: flex; align-items: center; gap: .85rem; margin-bottom: var(--sp-3); }
.pg-icon {
  flex-shrink: 0; width: 3rem; height: 3rem; border-radius: 50%;
  display: grid; place-items: center; background: var(--brand-soft); font-size: 1.45rem;
}
.pg-cat { margin: 0; font-size: .82rem; font-weight: 700; color: var(--brand-deep); }
.pg-head h3 { margin: 0; font-size: 1.3rem; }
.pg-cols { display: grid; gap: var(--sp-3); }
@media (min-width: 760px) { .pg-cols { grid-template-columns: 1fr 1fr; } }
.pg-col { border-radius: var(--r); padding: var(--sp-3) var(--sp-4); background: var(--safe-soft); }
.pg-avoid { background: var(--unsafe-soft); }
.pg-col-title { margin: 0 0 .4rem; font-weight: 700; color: var(--safe); }
.pg-avoid .pg-col-title { color: var(--unsafe); }
.pg-col ul { margin: 0; padding-inline-start: 1.1rem; font-size: .95rem; }
.pg-col li { margin-bottom: .35rem; }
.pg-col li:last-child { margin-bottom: 0; }
.pg-note { margin: var(--sp-3) 0 0; font-size: .95rem; color: var(--ink-soft); }

/* Equal headings and text across a row of photo cards (travel page). */
.card-title { font-size: 1.15rem; margin-bottom: .6rem; }
.card-list { font-size: .95rem; padding-inline-start: 1.1rem; }
.card-list li { margin-bottom: .35rem; }

/* ---------- Store directory ---------- */
.store-group { display: flex; align-items: center; gap: .6rem; font-size: 1.25rem; margin: var(--sp-4) 0 .4rem; }
.store-list {
  list-style: none; margin: 0 0 var(--sp-4); padding: 0;
  display: grid; column-gap: var(--sp-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
}
.store { display: flex; gap: .85rem; align-items: flex-start; padding: .9rem 0; border-bottom: 1px solid var(--line); }
.store-icon {
  flex-shrink: 0; width: 2.4rem; height: 2.4rem; border-radius: 50%;
  display: grid; place-items: center; background: var(--brand-soft); font-size: 1.1rem;
}
.store-name { font-size: 1.05rem; margin: 0 0 .15rem; }
.store-name a { text-decoration: none; }
.store-name a:hover { text-decoration: underline; }
.store-type { margin: 0; font-size: .85rem; color: var(--ink-muted); }
.store-note { margin: .3rem 0 0; font-size: .93rem; color: var(--ink-soft); }

/* ---------- Recipe ---------- */
.recipe-meta { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: var(--sp-3); }
.meta-pill {
  font-size: .81rem; background: var(--surface-sunk); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: .28rem .75rem; color: var(--ink-soft);
}

/* ---------- Label simulator ---------- */
.label-sim {
  background: #fffef8; color: #1c2420; border: 2px solid #333; border-radius: 6px;
  padding: var(--sp-3) var(--sp-4); font-size: .9rem; line-height: 1.7; margin-bottom: var(--sp-3);
}
.label-sim h3 { margin: 0 0 .4rem; font-size: 1rem; color: #1c2420; font-family: var(--font); }
.label-sim .ing { border-top: 1px dashed #999; padding-top: .5rem; margin-top: .5rem; }
.label-sim mark { background: #ffe08a; padding: 0 .15em; border-radius: 3px; }

/* ---------- Empty state ---------- */
.empty {
  text-align: center; padding: var(--sp-6) var(--sp-4);
  border: 1px dashed var(--line-strong); border-radius: var(--r);
  background: var(--surface-sunk); color: var(--ink-muted);
}
.empty .big { font-size: 2rem; display: block; margin-bottom: .5rem; }
/* Keeps every child on the box's centre line even if something ever narrows
   it — a capped block would otherwise sit at the start edge, the right in RTL. */
.empty > * { margin-inline: auto; }

/* ---------- Footer ---------- */
.site-footer {
  margin-top: var(--sp-7);
  background: var(--bg-alt);
  border-top: 1px solid var(--line);
  padding-block: var(--sp-5) var(--sp-4);
  font-size: .92rem;
}
/* The same five sections as the menu (both come from data/sitemap.js), set
   tight: the footer is a map to scan, not a second copy of the menu to read. */
.footer-grid { display: grid; gap: var(--sp-4) var(--sp-5); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 860px) { .footer-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
/* On a phone each section's links wrap as a line rather than a column: the
   same map in a third of the height, with targets still well over 24px. */
@media (max-width: 859px) {
  .footer-grid { grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
  .footer-links { display: flex; flex-wrap: wrap; gap: 0 1.1rem; }
  .footer-links li { margin: 0; }
  .footer-links a { display: inline-block; padding-block: .2rem; line-height: 1.5; }
  .footer-title { margin-bottom: .2rem; }
}
.footer-title { font-size: 1rem; margin-bottom: .5rem; }
.footer-links { list-style: none; padding: 0; margin: 0; font-size: .88rem; }
.footer-links li { margin-bottom: .3rem; }
.footer-links a, #footer-about a { color: var(--ink-soft); text-decoration: none; }
.footer-links a:hover, #footer-about a:hover { color: var(--brand-deep); text-decoration: underline; }
/* The closing row: the brand's mark, name and line at the start, the two
   pages about the platform itself at the end. It stacks on phones. */
.footer-bottom {
  margin-top: var(--sp-4); padding-top: var(--sp-4);
  border-top: 1px solid var(--line); font-size: .82rem; color: var(--ink-muted);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3) var(--sp-5);
}
.footer-bottom p { margin: 0; }
.footer-brand { display: flex; align-items: center; gap: .75rem; min-width: 0; }
.footer-mark { color: var(--brand); line-height: 0; flex-shrink: 0; }
.footer-about { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.footer-about strong {
  font-family: var(--font-display); font-weight: 700; font-size: 1.05rem;
  color: var(--ink-strong); line-height: 1.3;
}
.footer-tagline { color: var(--ink-muted); line-height: 1.6; }
/* The two footer-only pages read as more of the site map: the same size, ink
   and hover as the section links above. */
.footer-meta { display: flex; flex-wrap: wrap; gap: .3rem 1.6rem; }
#footer-about a { white-space: nowrap; font-size: .88rem; padding-block: .2rem; }
@media (max-width: 859px) {
  .footer-bottom { flex-direction: column; align-items: flex-start; }
}

/* Phones: the footer clears the home-indicator area. */
.site-footer { padding-bottom: max(var(--sp-4), env(safe-area-inset-bottom)); }


/* ---------- Safety strip ----------
   A folded warning. The summary carries the sentence that must never be
   missed, so what folds away is the reasoning, never the claim. */
.safety {
  border: 1px solid var(--unsafe-line); border-radius: var(--r);
  background: var(--unsafe-soft); margin-bottom: var(--sp-4);
}
.safety > summary {
  display: flex; align-items: center; gap: .6rem; cursor: pointer;
  padding: .85rem 1.1rem; list-style: none;
  font-size: .88rem; font-weight: 600; color: var(--ink);
  border-radius: var(--r); min-height: 44px;
}
.safety > summary::-webkit-details-marker { display: none; }
.safety-icon { font-size: 1.05rem; line-height: 1; flex-shrink: 0; }
.safety-summary { flex: 1; min-width: 0; }
.safety-more {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: .3rem;
  font-size: .8rem; font-weight: 600; color: var(--brand);
  text-decoration: underline; text-underline-offset: 3px;
}
.safety-more::after { content: "⌄"; text-decoration: none; }
.safety[open] .safety-more::after { content: "⌃"; }
.safety > summary:hover .safety-more { color: var(--brand-bright); }
.safety-body {
  padding: 0 1.1rem 1.1rem; border-top: 1px solid var(--unsafe-line);
  padding-top: .9rem; margin-top: -.1rem;
}
.safety-body > :last-child { margin-bottom: 0; }

/* ---------- Directory controls ---------- */

/* ---------- Tabs (the FAQ categories) ----------
   A flat strip with an underline on the selected tab, so it reads as tabs and
   not as the pill-shaped filter chips the directories use. On a phone the strip
   scrolls sideways rather than wrapping into a block of buttons. */
/* The strip keeps every tab on one line. When they run out of room it
   scrolls sideways inside itself with no scrollbar showing; the side that has
   more tabs fades out, and that fade is the cue. */
.tabs-bar { margin-block: var(--sp-4) var(--sp-5); }
/* The page's own tabs stay in reach while its sections scroll: the strip
   sticks under the header (--header-h, measured in app.js). Its wrapper must
   not be only as tall as the strip, or there is nothing to stick within. */
.tabs-bar {
  position: sticky; top: var(--header-h, 0px); z-index: 150;
  background: var(--surface);
}
.tabs-bar.is-stuck { box-shadow: 0 8px 14px -12px rgba(0, 0, 0, .35); }
.js-faq-tabs { display: contents; }
@media print { .tabs-bar { position: static; } }
.tabs {
  display: flex; gap: .15rem;
  border-bottom: 1px solid var(--line-strong);
  overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs-bar.fade-left .tabs { mask-image: linear-gradient(to right, transparent, #000 3.5rem); }
.tabs-bar.fade-right .tabs { mask-image: linear-gradient(to left, transparent, #000 3.5rem); }
.tabs-bar.fade-left.fade-right .tabs {
  mask-image: linear-gradient(to right, transparent, #000 3.5rem, #000 calc(100% - 3.5rem), transparent);
}
.tab {
  flex: none; background: none; border: 0;
  border-bottom: 3px solid transparent; margin-bottom: -1px;
  padding: .7rem 1rem; font: inherit; font-weight: 600; font-size: .95rem;
  color: var(--ink-muted); cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--brand-deep); border-bottom-color: var(--brand); }
.tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; border-radius: var(--r-sm) var(--r-sm) 0 0; }
/* «كل الأسئلة» stacks every group with the usual section break; a single tab
   shows one group, whose heading only repeats the tab it sits under. */
.faq-panel:not(.is-single) > section + section { margin-top: var(--prose-h2); }
.faq-panel.is-single > section > h2 { display: none; }

/* How many came back, and the way out — in that order. Two stacked rows rather
   than one wrapping line: the count and the sort control belong together, and
   the active filters are a separate statement about what the reader has done. */
.resultsbar { margin-bottom: var(--sp-4); }
.resultsbar-top {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sp-2) var(--sp-3);
}
.resultsbar .pill-count { margin: 0; }
.active-filters {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin-top: var(--sp-3);
  padding-top: var(--sp-2); border-top: 1px dashed var(--line);
}
.active-filters-label { font-size: .8rem; font-weight: 600; color: var(--ink-soft); }
.chip-drop {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand-deep);
  min-height: 32px;
}
.chip-drop:hover { background: var(--surface); }
.chip-drop-x { font-size: 1.05rem; line-height: 1; opacity: .75; }

.sortbar { display: inline-flex; align-items: center; gap: .5rem; }
.sortbar label { font-size: .8rem; color: var(--ink-muted); }
.sortbar select {
  font-family: inherit; font-size: .83rem; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-pill); padding: .45rem .9rem; min-height: 36px; cursor: pointer;
}
.sortbar select:hover { border-color: var(--brand); }

/* Cards carry their own `display`, which outranks the UA rule behind the
   `hidden` attribute — without this the batch beyond the fold stays visible. */
.grid > [hidden] { display: none !important; }

.more-row { display: flex; justify-content: center; margin-top: var(--sp-4); }
.more-count { font-weight: 400; }

/* Appears only once the header has scrolled away. */
.to-top {
  position: fixed; inset-inline-start: 1.1rem; z-index: 80;
  bottom: calc(1.1rem + env(safe-area-inset-bottom));
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; font-size: 1.15rem; cursor: pointer;
  background: var(--btn-bg); color: var(--btn-fg); border: 1px solid var(--btn-bg);
  box-shadow: 0 6px 20px rgba(0,0,0,.28);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { background: var(--btn-bg-hover); border-color: var(--btn-bg-hover); }
@media (prefers-reduced-motion: reduce) {
  .to-top { transition: none; }
}
@media print { .to-top { display: none; } }

/* Shown beside a print button when the browser opened no print window. */
.print-help { margin-top: .6rem; color: var(--ink-soft); max-width: 60ch; }

/* ---------- Utilities ---------- */
.stack-sm > * + * { margin-top: var(--sp-2); }
.stack   > * + * { margin-top: var(--sp-3); }
.stack-lg > * + * { margin-top: var(--sp-4); }
.flex-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
/* .mt-3 was used in markup long before it existed here, which is why blocks
   after a grid sat flush against it. */
.mt-3 { margin-top: var(--sp-3) !important; }
.mt-4 { margin-top: var(--sp-4) !important; }
.mb-0 { margin-bottom: 0 !important; }
.pill-count { font-size: .8rem; color: var(--ink-muted); }
.divider { height: 1px; background: var(--line); border: 0; margin-block: var(--sp-4); }

/* ==========================================================================
   ليل الواحة — the Nocturne layer
   Typography, bands, ornaments and the curved banner. Everything below is
   shared by every route: a view only chooses which band it sits in.
   ========================================================================== */

/* ---------- Display typography ---------- */
h1, h2, h3, h4, .footer-title, .brand-text strong {
  font-family: var(--font-display);
  letter-spacing: 0;
}
h1, h2 { color: var(--ink-strong); }
body { font-weight: 400; }
strong, b, th { font-weight: 700; }

/* ---------- Patterns ----------
   Woven hairlines and a diamond lattice, drawn in the accent gold on the
   night ground and in the forest green on cream. Decorative only. */
.deco {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23d99a4e' stroke-opacity='.13' stroke-width='1'%3E%3Cpath d='M24 6 42 24 24 42 6 24z'/%3E%3Cpath d='M24 16 32 24l-8 8-8-8z'/%3E%3C/g%3E%3C/svg%3E");
}
.weave {
  background-image:
    repeating-linear-gradient(45deg,  rgba(217,154,78,.07) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(-45deg, rgba(217,154,78,.07) 0 1px, transparent 1px 12px);
}
.weavelight {
  background-image:
    repeating-linear-gradient(45deg,  rgba(16,41,29,.055) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(-45deg, rgba(16,41,29,.055) 0 1px, transparent 1px 12px);
}

/* ---------- Page shell ----------
   #view-root is full-bleed so a band can run edge to edge; anything a view
   returns that is not itself a band goes back inside the wrap. */
#view-root > :not(.pagehead):not(.band):not(.searchband) {
  width: min(100% - 2rem, var(--wrap));
  margin-inline: auto;
}
@media (min-width: 700px) {
  #view-root > :not(.pagehead):not(.band):not(.searchband) { width: min(100% - 3rem, var(--wrap)); }
}
.band { padding-block: var(--sp-7); }
.band-deep  { background: var(--bg-alt); }
.band-cream { background: var(--bg); }   /* pairs with .on-cream */
.band-paper { background: var(--bg); }   /* pairs with .on-paper */
/* Sections that carry a short list or a single row of cards need more room
   above and below them than a dense one does, or they read as cramped
   between their neighbours. */
.band.band-airy { padding-block: calc(var(--sp-7) * 1.4); }
/* Two bands on the same ground still need to read as two sections. The
   doubled class outranks the `.band + .band` reset below. */
.band.band-paper + .band.band-paper { border-top: 1px solid var(--line); }
.band + .band { border-top: 0; }

/* ---------- Ornament label ----------
   The eyebrow is drawn as a rule–diamond–text–diamond–rule ornament rather
   than a pill, which is the section marker throughout the design. */
.eyebrow {
  display: flex; align-items: center; justify-content: center; gap: .7rem;
  font-size: .78rem; font-weight: 400; letter-spacing: .26em; line-height: 1.6;
  color: var(--brand); background: none; border: 0; padding: 0;
  margin-bottom: .9rem;
}
.eyebrow::before, .eyebrow::after {
  content: ""; flex: 0 0 auto; width: 60px; height: 12px;
  /* Masked rather than drawn, so the diamond and the rule both inherit the
     ornament's own colour on either ground. */
  background-color: currentColor;
  opacity: .75;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 11px 11px, 42px 1px; mask-size: 11px 11px, 42px 1px;
  -webkit-mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4'%3E%3Cpath d='M12 3 21 12l-9 9-9-9z'/%3E%3C/svg%3E"),
    linear-gradient(#000, #000);
  mask-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4'%3E%3Cpath d='M12 3 21 12l-9 9-9-9z'/%3E%3C/svg%3E"),
    linear-gradient(#000, #000);
}
.eyebrow::before { -webkit-mask-position: 0 center, 100% center; mask-position: 0 center, 100% center; }
.eyebrow::after  { -webkit-mask-position: 100% center, 0 center; mask-position: 100% center, 0 center; }
@media (max-width: 560px) {
  .eyebrow::before, .eyebrow::after {
    width: 26px;
    -webkit-mask-size: 0 0, 22px 1px; mask-size: 0 0, 22px 1px;
  }
}

.section-head {
  text-align: center;
  max-width: 64ch;
  margin-inline: auto;
  margin-bottom: var(--sp-5);
}
.section-head h2 { margin-bottom: .6rem; }
.section-head p { color: var(--ink-soft); }

/* An ornament that opens a block from the start edge instead of the centre. */
.head-start { text-align: start; margin-inline: 0; }

/* ---------- Curved page banner ----------
   Every route opens on the same cream band. The photograph (or the woven
   panel where no photograph is honest) runs off the inline-end edge of the
   viewport — the left, in Arabic — and its inner side is cut as one large
   half-ellipse facing the text, with the gold medallion resting on that arc
   carrying a real count from the platform's own data. */
.pagehead {
  --pagehead-pad: clamp(2.6rem, 1.6rem + 4vw, 5.4rem);
  --pagehead-arc: clamp(110px, 15vw, 250px);
  /* The band's own gutter. A percentage inside the media's margin would
     resolve against its grid area, not the reading measure, and bleed far
     past the viewport edge — so the gutter is computed here, on the
     full-width band, and spent there. */
  --pagehead-gutter: max(1.5rem, calc((100vw - var(--wrap)) / 2));
  position: relative;
  padding-block: var(--pagehead-pad);
  /* The home banner stands at 700px on desktop (inner pages override this to
     400px under .page-light). Phones keep the stacked layout's
     own figure height — 815px there is the whole first screen with nothing
     under it.

     The column flex matters: min-height on the band alone leaves the inner
     grid sized to its text, so the photo stops short and the rest of the band
     is empty cream. Making the band a column and letting .pagehead-inner grow
     hands the spare height to the grid row, which the media then fills
     through its own align-self: stretch. */
  min-height: 700px;
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--line);
  /* The media bleeds by a viewport-width calculation, which counts the
     scrollbar; clip the couple of pixels rather than let them scroll. */
  overflow: hidden;
}
.pagehead-inner {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr);
  gap: clamp(1.75rem, 1rem + 3vw, 3.25rem);
  align-items: center;
}
.pagehead-text > :last-child { margin-bottom: 0; }
.pagehead h1 {
  font-size: clamp(2rem, 1.35rem + 2.9vw, 58px);
  line-height: 1.28;
  margin-bottom: var(--sp-3);
  max-width: 18ch;
}
.pagehead h1 .accent { color: var(--brand-bright); }
.pagehead-lead {
  font-size: clamp(1rem, .96rem + .3vw, 1.08rem);
  line-height: 1.85;
  color: var(--ink-soft);
  max-width: 58ch;
}
.pagehead-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: var(--sp-4); }
.pagehead .breadcrumb { margin-bottom: .9rem; }

.pagehead-media {
  position: relative;
  align-self: stretch;
  /* Out to the viewport edge on the end side, and over the band's own padding
     top and bottom, so the panel meets all three edges flush. */
  margin-inline-end: calc(var(--pagehead-gutter) * -1);
  margin-block: calc(var(--pagehead-pad) * -1);
}
/* <picture> exists only to offer the browser a WebP source; it must never become
   a layout box of its own. Left inline it would wrap the figure in a line box,
   and the figure would then size against that wrapper instead of the panel or
   grid cell it is meant to fill — the same class of bug as the oversized
   banners. display:contents removes the wrapper and leaves the <img> exactly
   the layout child it was before.

   It promotes *every* child, though, and <source> is not among the elements a
   browser hides by default — so without the second rule each <source> became
   an empty grid item of its own. In .split, an auto-fit grid, that turned two
   columns into three: text, photo, and a blank third of every home-page card.
   Hiding it does not affect which file loads; the browser selects a source by
   walking the DOM, not the box tree. */
picture { display: contents; }
picture > source { display: none; }

.pagehead-figure {
  /* Taken out of flow so the photo fills the row instead of defining it. In
     normal flow height:100% resolved to auto inside an auto-height grid row,
     so a square or portrait source set the band's height from its own ratio
     (560x560 -> 620px, 620x770 -> 770px) and .pagehead's min-height, which can
     only raise, never capped it. object-fit does the cropping either way. */
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  background: var(--surface-sunk);
  /* One half-ellipse on the side facing the text; flat against the edge. */
  border-start-start-radius: var(--pagehead-arc) 50%;
  border-end-start-radius: var(--pagehead-arc) 50%;
  border-start-end-radius: 0;
  border-end-end-radius: 0;
}
/* No photograph: the same shape, woven in the brand green instead of a stock
   image standing in for something the platform has not seen. */
.pagehead-figure.is-pattern {
  background-color: #10291d;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23d99a4e' stroke-opacity='.22' stroke-width='1'%3E%3Cpath d='M24 6 42 24 24 42 6 24z'/%3E%3Cpath d='M24 16 32 24l-8 8-8-8z'/%3E%3C/g%3E%3C/svg%3E");
}
.pagehead-badge {
  position: absolute; inset-inline-start: -58px; top: 62%;
  transform: translateY(-50%);
  width: 152px; height: 152px; border-radius: 50%;
  background: #d99a4e; border: 6px solid var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; text-align: center; padding-inline: .6rem;
}
/* Numerals are set in the text face, not the display one, everywhere they
   appear — the medallion count and the list counters included. */
.pagehead-badge b {
  font-family: var(--font); font-size: 2.3rem; font-weight: 700;
  line-height: 1; color: #16281b;
}
.pagehead-badge span { font-size: .71rem; line-height: 1.45; color: #3b2a12; font-weight: 400; }

@media (max-width: 899px) {
  /* Stacked: the panel spans the full width above the text and the arc moves
     to its bottom edge, where the reading now continues. */
  .pagehead { min-height: 0; }
  .pagehead-inner { grid-template-columns: 1fr; }
  .pagehead h1 { max-width: none; }
  .pagehead-media {
    order: -1;
    margin-inline: calc(var(--pagehead-gutter) * -1);
    margin-block: calc(var(--pagehead-pad) * -1) 2.6rem;
  }
  .pagehead-figure {
    /* Stacked, there is no fixed-height row to fill, so the figure goes back
       into flow and its own height sets the panel's. */
    position: static;
    height: clamp(200px, 46vw, 300px); min-height: 0;
    border-start-start-radius: 0;
    border-end-start-radius: 50% 46px;
    border-end-end-radius: 50% 46px;
  }
  .pagehead-badge {
    inset-inline-start: auto; inset-inline-end: 22px; top: auto; bottom: -30px;
    transform: none; width: 122px; height: 122px; border-width: 5px;
    padding-inline: .5rem;
  }
  .pagehead-badge b { font-size: 1.75rem; }
  .pagehead-badge span { font-size: .6rem; line-height: 1.4; }
}

/* ---------- Home video hero ----------
   The alternative home banner (HOME_HERO in views/home.js): the footage fills
   the whole band and the text sits over it. The film keeps its people on the
   left, so the text column is the inline start (the right, in Arabic), and a
   scrim darkens that side so white type reads over any frame. The dark ground
   colour is what shows before the poster paints, and what an automated
   contrast check sees behind the text. */
.pagehead.hero-video {
  --pagehead-pad: clamp(2.6rem, 1.6rem + 4vw, 5.4rem);
  min-height: 700px;
  background: #16130f;
  border-bottom: 0;
  isolation: isolate;
}
.hero-video-media {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 30% center;
  background: #16130f;
}
.hero-video-scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to left, rgba(16, 13, 10, .86) 0%, rgba(16, 13, 10, .72) 38%, rgba(16, 13, 10, .18) 70%, rgba(16, 13, 10, .05) 100%),
    linear-gradient(to top, rgba(16, 13, 10, .55), transparent 35%);
}
.hero-video .pagehead-inner { grid-template-columns: minmax(0, 36rem); justify-content: start; }
.hero-video h1 { color: #fff; text-shadow: 0 2px 18px rgba(0, 0, 0, .35); }
.hero-video h1 .accent { color: #e8b06a; }
/* Left to right, the text sits on the left of the video: the scrim darkens
   that side instead. */
[dir="ltr"] .hero-video-scrim {
  background:
    linear-gradient(to right, rgba(16, 13, 10, .86) 0%, rgba(16, 13, 10, .72) 38%, rgba(16, 13, 10, .18) 70%, rgba(16, 13, 10, .05) 100%),
    linear-gradient(to top, rgba(16, 13, 10, .55), transparent 35%);
}
/* «تبدأ بالمعرفة» writes itself in after the first line: revealed from the
   right, the way it reads, with a gold underline drawn beneath and then
   withdrawn, once, on arrival. Skipped under reduced motion. */
@keyframes accent-write { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes accent-line {
  0%   { transform: scaleX(0); opacity: 1; }
  55%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}
.motion-on .view-enter .pagehead h1 .accent {
  display: inline-block; position: relative;
  animation: accent-write 1.6s var(--ease-out) .55s both;
}
.motion-on .view-enter .pagehead h1 .accent::after {
  content: ""; position: absolute; inset-inline: 0; bottom: .02em; height: 3px; border-radius: 3px;
  background: currentColor; transform-origin: right center;
  animation: accent-line 2.4s var(--ease-out) 1.2s both;
}
/* English reads from the left: the accent writes in from the left and its
   underline draws from the left. */
@keyframes accent-write-ltr { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
[dir="ltr"].motion-on .view-enter .pagehead h1 .accent { animation-name: accent-write-ltr; }
[dir="ltr"].motion-on .view-enter .pagehead h1 .accent::after { transform-origin: left center; }
.hero-video .pagehead-lead { color: #efe7da; text-shadow: 0 1px 10px rgba(0, 0, 0, .4); }
.hero-video .btn-ghost {
  background: rgba(22, 19, 15, .35); color: #fff; border-color: rgba(255, 255, 255, .55);
}
.hero-video .btn-ghost:hover { background: rgba(22, 19, 15, .6); color: #fff; border-color: #fff; }
@media (max-width: 899px) {
  .pagehead.hero-video { min-height: 560px; }
  .hero-video-media { object-position: 25% center; }
  .hero-video-scrim, [dir="ltr"] .hero-video-scrim {
    background: linear-gradient(to top, rgba(16, 13, 10, .9) 0%, rgba(16, 13, 10, .72) 55%, rgba(16, 13, 10, .35) 100%);
  }
  .hero-video .pagehead-inner { grid-template-columns: 1fr; align-items: end; }
}

/* ---------- Compact banner on inner pages ----------
   The home page keeps the full 700px banner; every other route (#view-root gets
   .page-light) opens on a shorter, 400px one on desktop — same photo, title and
   lead — so the content starts about 300px sooner on every page. Stacked
   phones keep the 300px floor, which their photo and text already exceed. The photo still fills its
   panel with object-fit, so a 16:9 source simply crops a little top and bottom.
   The band is a minimum, not a cap: a long title or lead still gets the room it
   needs. */
.page-light .pagehead {
  --pagehead-pad: clamp(1.6rem, 1rem + 1.6vw, 2.5rem);
  --pagehead-arc: clamp(80px, 9vw, 160px);
  min-height: 300px;
}
@media (min-width: 900px) {
  .page-light .pagehead { min-height: 400px; }
}
.page-light .pagehead h1 {
  font-size: clamp(1.75rem, 1.3rem + 1.5vw, 2.8rem);
  line-height: 1.3; margin-bottom: var(--sp-2);
}
.page-light .pagehead-lead { font-size: 1rem; line-height: 1.75; }
.page-light .pagehead .breadcrumb { margin-bottom: .55rem; }
.page-light .pagehead-actions { margin-top: var(--sp-3); }
.page-light .pagehead-badge {
  width: 116px; height: 116px; border-width: 5px; inset-inline-start: -44px;
}
.page-light .pagehead-badge b { font-size: 1.7rem; }
.page-light .pagehead-badge span { font-size: .6rem; }
@media (max-width: 899px) {
  .page-light .pagehead-figure { height: clamp(150px, 36vw, 220px); }
  .page-light .pagehead-media { margin-block-end: 2rem; }
  .page-light .pagehead-badge { width: 100px; height: 100px; inset-inline-start: auto; bottom: -24px; }
  .page-light .pagehead-badge b { font-size: 1.45rem; }
  .page-light .pagehead-badge span { font-size: .55rem; }
}

/* ---------- Search band ----------
   The white strip directly under the banner, carrying the site search. */
.searchband { background: #ffffff; border-bottom: 1px solid var(--line); }
.searchband-inner {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4);
  padding-block: var(--sp-3);
}
.searchband form {
  flex: 1 1 320px; min-width: 0;
  display: flex; align-items: center; gap: .6rem;
  border: 1px solid var(--line-strong); background: #fff;
  border-radius: var(--r-pill);
  padding: .4rem;
  padding-inline-start: 1.25rem;
}
.searchband form:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.searchband input {
  flex: 1; min-width: 0; border: 0; background: transparent; color: var(--ink);
  font-family: inherit; font-size: .97rem; padding: .6rem 0;
}
.searchband input:focus { outline: none; }
.searchband-tries { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }

/* ---------- Dotted-leader menu ----------
   Lists read as a menu card rather than bullets: name, then a dotted rule
   running out to the edge of the column. */
.leader-list { list-style: none; padding: 0; margin: 0; }
/* The whole row is the link, and it ends in the same arrow the clickable
   cards use, pointing the way Arabic reads, so the rows read as destinations. */
.leader-list li { margin: 0; }
.leader-list a {
  display: flex; align-items: center; padding: .62rem 0;
  color: var(--ink); text-decoration: none; font-size: .97rem;
}
.leader-list a:hover, .leader-list a:focus-visible { color: var(--brand-deep); }
.leader-list .lead {
  flex-grow: 1; align-self: flex-end; margin: 0 .7rem 9px;
  border-bottom: 1px dotted color-mix(in srgb, var(--brand) 55%, transparent);
}
.leader-arrow {
  flex-shrink: 0; width: 1.75rem; height: 1.75rem; border-radius: 50%;
  background: var(--brand-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a5f20' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M11 6l-6 6 6 6'/%3E%3C/svg%3E") center / .9rem no-repeat;
  transition: background-color .16s ease, transform .16s ease;
}
.leader-list a:is(:hover, :focus-visible) .leader-arrow {
  background-color: var(--brand); transform: translateX(calc(-3px * var(--dir, 1))) scaleX(var(--dir, 1));
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M11 6l-6 6 6 6'/%3E%3C/svg%3E");
}
/* The arrow is drawn pointing left (forward in Arabic); it turns to point
   right in English, and its hover nudge moves forward with it. */
[dir="ltr"] .leader-arrow { transform: scaleX(-1); }
@media (prefers-reduced-motion: reduce) { .leader-list a:hover .leader-arrow { transform: scaleX(var(--dir, 1)); } }
.triad-menu { display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.triad-menu-col > h3 {
  display: flex; align-items: center; gap: .5rem;
  padding-bottom: .7rem; margin-bottom: .8rem; border-bottom: 2px solid currentColor;
  font-size: 1.35rem;
}
.triad-menu-col p { font-size: .94rem; color: var(--ink-soft); }
.triad-menu-safe   > h3 { color: var(--safe); }
.triad-menu-check  > h3 { color: var(--check); }
.triad-menu-unsafe > h3 { color: var(--unsafe); }

/* ---------- Numbered list (Arabic-Indic numerals) ---------- */
.numlist { display: grid; gap: 6px; }
.numlist a {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 1.45rem 1.8rem; display: flex; align-items: center; gap: 1.25rem;
  text-decoration: none; color: inherit;
}
.numlist a:hover { border-color: var(--brand); }
.numlist .n {
  font-family: var(--font); font-size: 1.05rem; font-weight: 700;
  color: var(--brand); flex-shrink: 0; font-variant-numeric: tabular-nums;
}
.numlist h3 { font-size: 1.02rem; font-weight: 400; margin: 0; color: var(--ink); font-family: var(--font); }

/* ---------- Photo tile card ---------- */
.tile {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden;
}
.tile:hover { border-color: var(--brand); }
.tile img { width: 100%; height: 210px; object-fit: cover; display: block; }
.tile-body { padding: 1.6rem 1.7rem 1.8rem; display: flex; flex-direction: column; gap: .55rem; }
.tile-kicker { font-size: .77rem; letter-spacing: .12em; color: var(--brand); }
.tile-body h3 { margin: 0; font-size: 1.18rem; }
.tile-body p { margin: 0; font-size: .9rem; line-height: 1.85; color: var(--ink-soft); }
.tile-meta { font-size: .84rem; color: var(--ink-muted); }

/* ---------- Split panel (photo beside a block of text) ---------- */
.split {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  border-radius: var(--r-lg); overflow: hidden;
}
.split img { width: 100%; height: 100%; min-height: 260px; object-fit: cover; display: block; }
.split-body {
  background: var(--surface); padding: clamp(2.1rem, 1.2rem + 2.9vw, 3.8rem);
  display: flex; flex-direction: column; justify-content: center; gap: 1rem;
}
.split-body > :last-child { margin-bottom: 0; }

/* ---------- Pull quote (myths) ---------- */
.quote {
  border-inline-start: 2px solid var(--brand);
  padding-inline-start: var(--sp-4);
}
.quote .said {
  font-family: var(--font-display); font-size: 1.2rem; line-height: 1.75;
  color: var(--ink-strong); margin-bottom: .7rem;
}
.quote .said::before { content: "» "; color: var(--brand); }
.quote .label {
  display: block; font-size: .76rem; letter-spacing: .14em;
  color: var(--unsafe); margin-bottom: .45rem;
}
.quote .answer { font-size: .95rem; line-height: 1.95; color: var(--ink-soft); margin: 0; }
.quote .answer-label {
  display: block; font-size: .76rem; letter-spacing: .14em;
  color: var(--safe); margin-bottom: .35rem;
}

/* ---------- Component retuning on the night ground ---------- */
.card { box-shadow: none; }
.card-hover:hover { transform: none; border-color: var(--brand); box-shadow: var(--shadow-md); }
.entry-card:hover { transform: none; border-color: var(--brand); box-shadow: var(--shadow-md); }
.btn:hover { transform: none; }
.governance { background: var(--surface-sunk); }
.progress-fill { background: var(--brand); }
.checklist input[type="checkbox"] { accent-color: var(--brand); }

/* ---------- Header ---------- */
.site-header { background: color-mix(in srgb, var(--bg) 92%, transparent); }
.brand { color: var(--brand); }
.brand-text strong { color: var(--ink-strong); font-size: 1.28rem; font-weight: 700; }
.topstrip { background: var(--bg-deep); color: var(--ink-soft); letter-spacing: .02em; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--bg-deep);
  border-top: 1px solid var(--line);
  margin-top: 0;
  padding-block: var(--sp-5) var(--sp-4);
}
.footer-title { color: var(--brand); font-size: .82rem; letter-spacing: .2em; font-weight: 400; }
.footer-links a:hover, #footer-about a:hover { color: var(--brand-deep); }
/* Phones: room under the footer's last line for the fixed back-to-top button. */
@media (max-width: 859px) {
  .site-footer { padding-bottom: calc(46px + 2.2rem + env(safe-area-inset-bottom)); }
}

/* A band that runs to the page edge must not leave the ground showing beneath
   the last one, so the footer is welded straight onto whatever precedes it. */
main { display: flex; flex-direction: column; }
#view-root { flex: 1 0 auto; }

/* ---------- Item page header ----------
   Item pages (a food, an ingredient, a product, a venue, an article, a
   recipe) open on a cream panel cut with the banner's arch, so a detail page
   reads as part of the sequence. It takes the cream tokens from the `.on-cream`
   rule, which it shares a selector with. The item's picture sits large on the
   end side (the left in Arabic), its outer corner following the arch. */
.detail-head {
  --dh-pad: clamp(1.4rem, 1rem + 1.6vw, 2.6rem);
  display: grid; gap: var(--sp-4); align-items: center;
  padding: var(--dh-pad);
  margin-bottom: var(--sp-5);
  border-radius: var(--r-lg);
  border-end-end-radius: 90px;
  background-color: var(--bg);
  background-image:
    repeating-linear-gradient(45deg,  rgba(16,41,29,.05) 0 1px, transparent 1px 12px),
    repeating-linear-gradient(-45deg, rgba(16,41,29,.05) 0 1px, transparent 1px 12px);
  color: var(--ink);
}
@media (min-width: 900px) {
  .detail-head.has-media { grid-template-columns: minmax(0, 1fr) minmax(0, 44%); }
}
.detail-head h1 { font-size: clamp(1.8rem, 1.3rem + 1.9vw, 2.8rem); margin-bottom: .35rem; }
.detail-head-lead { color: var(--ink-soft); font-size: 1.05rem; margin: 0; }
/* A secondary name in the other script keeps its own direction but sits on
   the page's reading edge. */
[dir="ltr"] .detail-head-lead[dir="rtl"] { text-align: left; }
[dir="rtl"] .detail-head-lead[dir="ltr"] { text-align: right; }
.detail-head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-top: var(--sp-3); }
.detail-head-media { align-self: stretch; display: flex; align-items: center; justify-content: center; }
.detail-figure {
  display: block; width: 100%; aspect-ratio: 4 / 3; max-height: 360px; object-fit: cover;
  border-radius: var(--r-lg); border-end-end-radius: 64px;
  background: var(--surface-sunk); box-shadow: var(--shadow-sm);
}
/* A pack photo is shown as itself — its own shape, no white panel around it. */
.detail-figure.is-contain {
  width: auto; max-width: 100%; height: auto; max-height: 360px; aspect-ratio: auto;
  object-fit: contain; background: none; padding: 0;
  border-radius: var(--r); box-shadow: var(--shadow-md);
}
.detail-logo {
  width: clamp(150px, 16vw, 220px); aspect-ratio: 1; display: grid; place-items: center;
  padding: 1.2rem; background: #fff; border-radius: 28px; box-shadow: var(--shadow-md);
}
.detail-logo img { width: 100%; height: 100%; object-fit: contain; }
.detail-logo.is-icon { font-size: 4rem; background: var(--surface); }
@media (max-width: 899px) {
  .detail-head { border-end-end-radius: 56px; }
  .detail-head-media { order: -1; }
  .detail-figure { aspect-ratio: 16 / 10; max-height: 260px; border-end-end-radius: 40px; }
  .detail-figure.is-contain { max-height: 280px; }
  .detail-logo { width: 132px; }
}

/* ==========================================================================
   Print
   The screen design is a night one, but two pages exist to be printed and
   handed over — the school guide and the checklists. On paper the whole
   palette is inverted to ink on white, the site chrome and banner imagery
   are dropped, and links are annotated with their destination.
   ========================================================================== */
@media print {
  :root,
  .on-cream,
  .detail-head,
  .page-light,
  .on-paper {
    --bg: #ffffff; --bg-alt: #ffffff; --bg-deep: #ffffff;
    --surface: #ffffff; --surface-sunk: #ffffff;
    --ink: #000000; --ink-strong: #000000; --ink-soft: #1a1a1a; --ink-muted: #333333;
    --brand: #000000; --brand-deep: #000000; --brand-bright: #000000;
    --brand-soft: #ffffff; --brand-line: #999999;
    --btn-bg: #ffffff; --btn-fg: #000000; --btn-bg-hover: #ffffff;
    --accent: #000000; --info: #000000;
    --safe: #000000; --safe-soft: #ffffff; --safe-line: #999999;
    --check: #000000; --check-soft: #ffffff; --check-line: #999999;
    --unsafe: #000000; --unsafe-soft: #ffffff; --unsafe-line: #999999;
    --cross: #000000; --cross-soft: #ffffff; --cross-line: #999999;
    --line: #bbbbbb; --line-strong: #888888;
    --shadow-sm: none; --shadow-md: none; --shadow-lg: none;
  }
  body { background: #fff; color: #000; font-weight: 400; min-height: 0; display: block; }
  main { display: block; flex: none; }
  .topstrip, .site-header, .site-footer, .skip-link,
  .pagehead-media, .searchband, .filterbar, .searchbox, .breadcrumb,
  .btn, .chip { display: none !important; }
  .deco, .weave, .weavelight, .detail-head { background-image: none !important; }
  /* A folded warning must still print in full. */
  .safety-body { display: block !important; }
  .safety-more { display: none !important; }
  .band, .pagehead, .section { padding-block: 0; border: 0; }
  .pagehead-inner { display: block; }
  .card, .callout, .checklist li, .accordion, .empty, .governance {
    box-shadow: none; border-color: #888;
    break-inside: avoid;
  }
  h1, h2, h3 { break-after: avoid; }
  /* Status still never relies on colour: the icon and label print with it. */
  .status-badge { border-color: #000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .78em; word-break: break-all; }

  @page { margin: 14mm 12mm; }
  /* The banner keeps its title and lead but not its screen height, or the
     page opens on a blank third of paper. */
  .pagehead, .page-light .pagehead { min-height: 0 !important; padding-block: 0 6mm !important; }
  .pagehead h1 { font-size: 22pt; }
  /* On-screen wayfinding has no meaning on paper. */
  .next-steps, .tabs-bar, .tabs, .to-top, .print-help, .progress-wrap,
  .reveal-more, .more-row, .no-print { display: none !important; }
  .table-scroll { overflow: visible !important; border: 0; border-radius: 0; }
  /* Ruled cells, so a printed form can be filled in by hand. */
  th, td { border: 1px solid #888 !important; padding: 2.5mm 3mm; }
  /* Trailing margins alone must not spill onto a blank last sheet. */
  .checklist, .section > :last-child { margin-bottom: 0; }
  .flex-row:not(:has(> :not(.btn))), body > .sr-only { display: none !important; }
  /* A checkbox prints as an empty box to tick by hand. */
  .checklist input[type="checkbox"] { -webkit-appearance: none; appearance: none;
    width: 14px; height: 14px; border: 1.5px solid #000; border-radius: 2px; background: #fff; }
  .checklist input[type="checkbox"]:checked { background: #000; }

  /* A print button prints only its target (set by bindPrint): everything in
     the view that neither is nor holds the target is dropped. */
  html.print-scope #view-root *:not(.print-target):not(.print-target *):not(:has(.print-target)) {
    display: none !important;
  }
  html.print-scope .print-target { border: 1px solid #888; padding: 7mm; margin: 0; max-width: none; font-size: 11pt; }
  html.print-scope .js-travel-card.print-target h3 { font-size: 18pt; }
  html.print-scope .js-travel-card.print-target p { font-size: 13pt; line-height: 1.8; }
}

/* ==========================================================================
   Header, menu overlay and search overlay
   One header row: the brand with the menu button beside it, the assistant,
   and the search icon. Neither the menu nor the search lives in the bar —
   both open as modal overlays, so the header stays the same shape at every
   width and the whole architecture arrives on one screen instead of hiding
   behind five hover targets.
   ========================================================================== */

.header-inner { gap: var(--sp-3); }
.header-end { display: flex; align-items: center; gap: .6rem; margin-inline-start: auto; }
@media (min-width: 1120px) {
  /* Three cells rather than flex: the nav is centred against the header, not
     against whatever space the brand and the controls happen to leave. */
  .header-inner { display: grid; grid-template-columns: auto 1fr auto; }
  .topnav { justify-self: center; }
  .header-end { margin-inline-start: 0; }
}

/* ---------- The parents, in the header ----------
   Each one opens the mega panel on its own section. They are the visible top
   level of the architecture; the single menu button below takes over where
   they no longer fit. */
.topnav { align-self: center; }
/* The items carry no margin: the site-wide list-item bottom margin made the
   row taller than its buttons and sat the labels 4px above the logo and the
   search. Each item is a flex box so the button alone sets its height. */
.topnav ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: .25rem;
}
.topnav li { display: flex; margin: 0; }
.topnav-btn {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .55rem .95rem; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--ink-soft); cursor: pointer;
  font-family: var(--font-display); font-size: 1.02rem; font-weight: 600; line-height: 1.4;
  white-space: nowrap;
}
.topnav-btn:hover { background: var(--brand-soft); color: var(--brand-deep); }
.topnav-btn[aria-expanded="true"] { background: var(--brand-soft); color: var(--brand-deep); font-weight: 600; }
/* The open route lives in this section. */
.topnav-btn.is-current {
  color: var(--brand-deep); background: var(--brand-soft);
  box-shadow: inset 0 0 0 1px var(--brand-line);
}


.menu-btn {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .62rem 1.1rem; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: none; color: var(--ink);
  font-family: inherit; font-size: .92rem; font-weight: 600; line-height: 1;
}
.menu-btn:hover { border-color: var(--brand); color: var(--brand-deep); }
.menu-btn[aria-expanded="true"] { background: var(--brand); border-color: var(--brand); color: var(--btn-fg); }

/* Three bars that fold into a cross while the menu is open. */
.menu-bars { display: grid; gap: 4px; width: 18px; }
.menu-bars span {
  display: block; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform .2s ease, opacity .2s ease;
}
.menu-btn[aria-expanded="true"] .menu-bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] .menu-bars span:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded="true"] .menu-bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Below the width where the parent labels fit, the single button returns and the
   panel falls back to showing every section at once. Declared after
   `.menu-btn` so it wins at equal specificity. */
@media (max-width: 1119px) { .topnav { display: none; } }
@media (min-width: 1120px) { .menu-btn { display: none; } }

.icon-btn {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line-strong); background: none; color: var(--ink);
  font-size: 1.05rem; line-height: 1;
}
.icon-btn:hover { border-color: var(--brand); color: var(--brand-deep); }
.icon-btn[aria-expanded="true"] { background: var(--brand); border-color: var(--brand); color: var(--btn-fg); }
.icon-btn .icon-x { display: none; }
.icon-btn[aria-expanded="true"] .icon-search { display: none; }
.icon-btn[aria-expanded="true"] .icon-x { display: block; }
.overlay-panel:focus-visible { outline: none; }

/* The language switch: the same page in the other language, labelled in that
   language. Same height and outline as the search button beside it. */
.lang-switch {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  min-height: 44px; padding: 0 1rem; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); color: var(--ink); text-decoration: none;
  font-size: .92rem; font-weight: 600; line-height: 1; white-space: nowrap;
}
.lang-switch:hover { border-color: var(--brand); color: var(--brand-deep); }
.lang-switch[hidden] { display: none; }
.lang-switch-short { display: none; }
/* Narrow phones: brand, menu, language and search share one row, so the
   gaps tighten, the round buttons drop to 40px and the name shrinks a step;
   below 350px the leaf mark gives way to the name. */
@media (max-width: 420px) {
  .header-inner { gap: .5rem; }
  .header-end { gap: .4rem; }
  .brand-text strong { font-size: 1.1rem; }
  .icon-btn, .lang-switch, .menu-btn { width: 40px; height: 40px; min-height: 40px; }
}
@media (max-width: 350px) {
  .brand-mark { display: none; }
}
@media (max-width: 639px) {
  .lang-switch { width: 44px; padding: 0; border-radius: 50%; }
  .lang-switch-short { display: inline; font-size: .95rem; }
  .lang-switch-long {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

@media (max-width: 639px) {
  .menu-btn { padding: .62rem; width: 44px; height: 44px; justify-content: center; }
  /* Hidden from view but not from the accessibility tree: `display: none`
     here left the button with nothing but its aria-hidden bars, and so with
     no accessible name. */
  .menu-btn-label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

/* ---------- Overlays ---------- */
/* Opens under the header, whose height JS measures at open time — the page
   is frozen while an overlay is up, so one measurement holds. */
.overlay { position: fixed; inset: 0; z-index: 200; padding-top: var(--overlay-top, 0px); }
/* With a panel welded beneath it, the header stops being translucent — page
   content showing faintly through it breaks the single-surface reading. */
.has-overlay .site-header { background: var(--bg); backdrop-filter: none; }
.overlay:not([hidden]) { display: flex; flex-direction: column; }
.overlay-panel {
  flex: 0 1 auto; min-height: 0; overflow-y: auto;
  background: var(--bg);
  border-bottom: 1px solid var(--brand-line);
  box-shadow: var(--shadow-lg);
  padding-block: var(--sp-4) var(--sp-5);
  animation: overlay-in .22s ease both;
}
#menu-overlay .overlay-panel {
  padding-block: var(--sp-5) var(--sp-4);
}
.overlay-scrim {
  flex: 1 1 auto; min-height: 0;
  background: rgba(4, 14, 9, .62);
  backdrop-filter: blur(2px);
  cursor: pointer;
}
@keyframes overlay-in { from { transform: translateY(-14px); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .overlay-panel { animation: none; } }

/* The page behind an open overlay must not scroll under it.
   The root only — never `body` as well. Giving body `overflow: hidden` makes
   it a scroll container, which takes the sticky header's containing block away
   from the viewport: open the menu after scrolling and the header rendered at
   its static position, far above the fold, leaving the panel floating over
   bare page content. */
.has-overlay { overflow: hidden; }

.overlay-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.overlay-title {
  margin: 0; font-size: .78rem; font-weight: 400;
  letter-spacing: .26em; color: var(--brand);
}

/* ---------- Menu overlay ---------- */
.menu-grid {
  display: grid; gap: var(--sp-4) var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* A parent opens its own section, laid out wide: the heading and its purpose
   on a rail, the links filling the rest. Switching parents swaps the section
   without closing the panel. Not the `hidden` attribute — `display: none`
   takes the inactive sections out of the accessibility tree and out of the
   focus trap just as cleanly, and survives the media query below. */
/* The photograph is decorative, like every other image in this design: it sets
   the section's tone and never stands in for a product, a place or a claim. */
.menu-col-image { display: none; }

@media (min-width: 1120px) {
  .menu-grid { grid-template-columns: minmax(0, 1fr); }
  .menu-col { display: none; }
  .menu-col.is-active {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 400px);
    grid-template-areas: "title image" "list image";
    grid-template-rows: auto 1fr;
    gap: .3rem var(--sp-5);
    align-items: start;
  }
  .menu-col.is-active > .menu-col-title { grid-area: title; }
  .menu-col.is-active > .menu-col-list  {
    grid-area: list; margin-top: .8rem;
    display: grid; gap: .35rem .6rem;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  /* Descendant, not child: the image sits inside a <picture> that offers a
     WebP source. That wrapper is display:contents so the image is still the
     grid item here, but selectors match the DOM tree, not the box tree. */
  .menu-col.is-active .menu-col-image {
    display: block; grid-area: image; align-self: start;
    width: 100%; aspect-ratio: 16 / 9;
    object-fit: cover; border-radius: var(--r);
  }
}
.menu-col-title {
  font-size: 1.12rem; margin: 0 0 .3rem;
  padding-bottom: .55rem; border-bottom: 1px solid var(--brand-line);
  color: var(--ink-strong);
}
.menu-col-list { list-style: none; margin: 0; padding: 0; }
.menu-col-list li { margin: 0; }
.menu-col-list a {
  display: block; padding: .35rem 0; border-radius: var(--r-sm);
  color: var(--ink-soft); text-decoration: none; font-size: .95rem;
}
.menu-col-list a:hover { color: var(--brand-deep); }
.menu-col-list a[aria-current="page"] { color: var(--brand-deep); font-weight: 600; }

/* ---------- Search overlay ---------- */
.bigsearch {
  display: flex; align-items: center; gap: .7rem;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  padding: .45rem; padding-inline-start: 1.3rem;
}
.bigsearch:focus-within { border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.bigsearch-icon { display: grid; place-items: center; color: var(--ink-muted); }
.bigsearch input {
  flex: 1; min-width: 0; border: 0; background: transparent; color: var(--ink);
  font-family: inherit; font-size: clamp(1rem, .95rem + .5vw, 1.25rem); padding: .75rem 0;
}
.bigsearch input:focus { outline: none; }
.overlay-search .hero-chips { margin-top: var(--sp-3); }

/* ==========================================================================
   Text width
   Body text takes the full width of whatever holds it — the section, a card,
   a callout, an accordion, the governance box. There is deliberately no
   reading-measure cap on content: a paragraph that stops part-way across a
   full-width box read as a misalignment. The only capped text is layout, not
   body copy: the banner heading and lead, and the centred section intros on
   the home page, which would otherwise run edge to edge.
   ========================================================================== */

/* Full-bleed elements a view may drop straight into a section. */
.section > .grid,
.section > .risk,
.section > .triad-menu,
.section > .table-scroll,
.section > .dx-path,
.section > .steps,
.section > .journey,
.section > .checklist,
.section > .numlist,
.section > .split,
.section > .accordion,
.section > .filterbar,
.section > .searchbox { max-width: none; }

/* ---------- Media: accounts and platforms ----------
   Grouped by what the account is for, one card each: a monogram, the name,
   where it is and what kind, the official site as the main action, and the
   social accounts as small pills beneath. Monograms are letters, never a
   drawn logo of the organisation. */
.plat-group + .plat-group { margin-top: var(--sp-5); }
.plat-group-head { display: flex; align-items: center; gap: .9rem; margin-bottom: var(--sp-3); padding-bottom: .8rem; border-bottom: 1px solid var(--line); }
.plat-group-head h3 { margin: 0; }
.plat-group-icon { display: grid; place-items: center; flex: none; width: 46px; height: 46px; border-radius: 14px; background: var(--brand-soft); font-size: 1.4rem; }
.plat-count { display: inline-block; margin-inline-start: .35rem; padding: .05rem .6rem; border-radius: 999px; background: var(--surface-sunk); font: 600 .8rem var(--font); color: var(--ink-soft); vertical-align: middle; }
.plat-grid { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr)); }
.plat-card { display: flex; flex-direction: column; gap: .85rem; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); }
.plat-top { display: flex; align-items: center; gap: .85rem; min-width: 0; }
.plat-mono { display: grid; place-items: center; flex: none; width: 54px; height: 54px; border-radius: 50%; background: var(--brand-soft); border: 1px solid var(--brand); color: var(--brand-deep); font: 700 1.5rem var(--font-display); }
.plat-id { min-width: 0; }
.plat-id h4 { margin: 0; font-size: 1.05rem; line-height: 1.35; }
.plat-meta { margin: .15rem 0 0; font-size: .84rem; color: var(--ink-muted); }
.plat-about { margin: 0; font-size: .93rem; line-height: 1.7; color: var(--ink-soft); }
.plat-menu { position: relative; margin-top: auto; }
.plat-menu summary {
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: .6rem; cursor: pointer;
  padding: .8rem 1.2rem; border-radius: 14px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); font: 600 1rem var(--font); user-select: none;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.plat-menu summary::-webkit-details-marker { display: none; }
.plat-menu summary:hover, .plat-menu[open] summary { border-color: var(--brand); color: var(--brand-deep); background: var(--brand-soft); }
.plat-menu summary svg { transition: transform .2s ease; transform: rotate(180deg); }
.plat-menu[open] summary svg { transform: none; }
.plat-menu-list {
  list-style: none; margin: .5rem 0 0; padding: .4rem; position: absolute; inset-inline: 0; top: 100%; z-index: 20;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 16px; box-shadow: var(--shadow-md);
}
.plat-menu-list a {
  display: flex; align-items: center; gap: .9rem; padding: .7rem .9rem; border-radius: 10px;
  color: var(--ink); text-decoration: none; font: 600 1rem var(--font);
}
.plat-menu-list a:hover, .plat-menu-list a:focus-visible { background: var(--brand-soft); color: var(--brand-deep); }
.plat-ico { display: grid; place-items: center; width: 26px; flex: none; color: var(--ink-soft); }
.plat-menu-list a:hover .plat-ico { color: var(--brand-deep); }

/* Arabic is a connected script: tracking pulls the letters of a word apart
   (worst in Safari, which breaks the joins). Letter-spacing is therefore
   switched off for every Arabic run; Latin text keeps its tracking. */
:lang(ar), :lang(ar) *, html[lang="ar"] body * { letter-spacing: 0 !important; }
