/* Omran Intelligence — landing. One stylesheet serves EN (LTR) and AR (RTL)
   via logical properties. Tokens per DESIGN.md. */

/* ---------- Fonts (self-hosted, ADR 0001: no third-party requests) ---------- */

@font-face {
  font-family: 'Cabinet Grotesk';
  src: url('../fonts/cabinet-grotesk.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('../fonts/switzer.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Martian Mono';
  src: url('../fonts/martian-mono.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Noto Kufi Arabic';
  src: url('../fonts/noto-kufi-arabic.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/ibm-plex-sans-arabic-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/ibm-plex-sans-arabic-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/ibm-plex-sans-arabic-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */

:root {
  --bg: oklch(0.11 0 0);
  --surface: oklch(0.15 0.006 160);
  --surface-2: oklch(0.175 0.008 160);
  --line: oklch(0.28 0.008 160);
  --line-soft: oklch(0.21 0.006 160);
  --ink: oklch(0.94 0.004 160);
  --muted: oklch(0.71 0.01 160);
  /* 0.60 clears WCAG AA (4.5:1) on --surface and --bg for the small labels */
  --faint: oklch(0.60 0.008 160);
  --primary: oklch(0.46 0.09 160);
  --primary-deep: oklch(0.32 0.06 160);
  --primary-bright: oklch(0.72 0.13 158);
  --accent: oklch(0.82 0.09 90);

  --font-display: 'Cabinet Grotesk', system-ui, -apple-system, sans-serif;
  --font-body: 'Switzer', system-ui, -apple-system, sans-serif;
  --font-mono: 'Martian Mono', ui-monospace, monospace;

  --radius: 2px;
  --container: 1280px;
  --pad-x: clamp(1.25rem, 4vw, 3rem);
  --section-gap: clamp(5rem, 12vh, 9rem);

  /* z-scale: content < nav < skip-link */
  --z-nav: 10;
  --z-skip: 20;
  /* brighter reading tone for long passages (ledes, body copy): lifts
     legibility above --muted while staying calm. AAA on --bg and --surface */
  --read: oklch(0.80 0.012 160);
}
/* phones read as a feed: tighter vertical rhythm */
@media (max-width: 640px) {
  :root { --section-gap: 4.25rem; }
}

/* Arabic page: family swap, no tracking, taller leading, +12% size */
:root[lang='ar'] {
  --font-display: 'Noto Kufi Arabic', 'IBM Plex Sans Arabic', sans-serif;
  --font-body: 'IBM Plex Sans Arabic', system-ui, sans-serif;
}

/* ---------- Reset / base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* keep anchored section headings clear of the 68px sticky nav */
  scroll-padding-block-start: 84px;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
:root[lang='ar'] body {
  font-size: 1.1875rem;
  line-height: 1.8;
  letter-spacing: 0;
}

/* film grain over the whole page: breaks the flat black, reads as print
   texture. Tile is generated feTurbulence noise; element opacity keeps it
   at a whisper. Excluded from print/headless (the print rule forces
   opacity 1 on everything, which would turn this into a black snowstorm). */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 30;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px;
  opacity: 0.045;
}
@media print {
  body::after { display: none; }
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0;
  text-wrap: balance;
}
:root[lang='ar'] h1,
:root[lang='ar'] h2,
:root[lang='ar'] h3,
:root[lang='ar'] h4 {
  letter-spacing: 0;
  line-height: 1.38;
  font-weight: 600;
}

p { margin: 0; }
a { color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }

img, svg { max-width: 100%; height: auto; display: block; }

::selection { background: var(--primary); color: oklch(0.97 0 0); }

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

/* absolute (not fixed) + clip while unfocused: invisible in normal flow AND
   in full-page screenshots (headless captures ignore transforms on fixed
   elements, which used to paint the link mid-page in renders) */
.skip-link {
  position: absolute;
  inset-block-start: 0.75rem;
  inset-inline-start: 0.75rem;
  z-index: var(--z-skip);
  background: var(--primary);
  color: oklch(0.97 0 0);
  padding: 0.6rem 1rem;
  border-radius: var(--radius);
  clip-path: inset(50%);
  white-space: nowrap;
  overflow: hidden;
}
.skip-link:focus { clip-path: none; overflow: visible; }

/* small supporting labels (former mono eyebrows, now quiet body-face text) */
.label-quiet {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--faint);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  padding: 0.95rem 1.5rem;
  border-radius: var(--radius);
  white-space: nowrap;
  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.18s, border-color 0.18s, box-shadow 0.18s;
}
.btn:active { transform: scale(0.98); }

.btn-primary {
  background: var(--primary);
  color: oklch(0.97 0.003 160);
  box-shadow: 0 14px 34px -14px oklch(0.46 0.09 160 / 0.55);
}
/* rest 6.2:1, hover 5.1:1 vs white text (WCAG AA, verified) */
.btn-primary:hover {
  background: oklch(0.50 0.095 160);
  transform: translateY(-1px);
  /* a machined lift, not a product glow: just above the rest shadow */
  box-shadow: 0 18px 36px -18px oklch(0.46 0.09 160 / 0.58);
}
.btn-ghost {
  /* one step lighter than --line: the hairline tone vanished on phones */
  border: 1px solid oklch(0.38 0.012 160);
  color: var(--ink);
  background: transparent;
}
.btn-ghost:hover {
  border-color: var(--muted);
  transform: translateY(-1px);
  background: color-mix(in oklab, var(--surface) 60%, transparent);
}

.btn .btn-arrow { transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1); }
.btn:hover .btn-arrow { transform: translateX(3px); }
:root[dir='rtl'] .btn:hover .btn-arrow { transform: translateX(-3px); }

a:focus-visible, button:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--primary-bright);
  outline-offset: 3px;
}

/* ---------- Nav ---------- */

/* the bar reads seamless over the hero (transparent) and materializes into a
   solid, elevated header the moment the page scrolls, so nothing ghosts
   through it. State toggled by JS (.is-stuck); the transition is the motion. */
.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: var(--bg);
  border-block-end: 1px solid var(--line-soft);
  box-shadow: 0 14px 34px -22px oklch(0 0 0 / 0.9);
}
/* the state transition is gated behind a JS-added class so the first paint (the
   solid default, before deferred JS runs) snaps to .at-top without a 0.3s
   border+shadow flicker over the hero. Scroll-driven toggles still animate. */
.nav.is-ready {
  transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
/* JS marks the very top of the page: there the bar goes seamless over the hero.
   Default (and the no-JS state) is the solid, elevated bar, so page content can
   never ghost through it. */
.nav.at-top {
  background: transparent;
  border-block-end-color: transparent;
  box-shadow: none;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  height: 68px;
}
.wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.65rem;
  text-decoration: none;
  color: var(--ink);
}
/* the cadastral mark: a parcel plan with one located plot (the datapoint) */
.logo-mark { align-self: center; color: var(--ink); flex: none; }
.logo-mark .lm-lines { stroke: currentColor; stroke-width: 2.5; }
.logo-mark .lm-cell { fill: var(--accent); }
.wordmark-latin {
  font-family: 'Cabinet Grotesk', sans-serif;
  font-weight: 800;
  font-size: 1.18rem;
  letter-spacing: 0.05em;
}
.wordmark-arabic {
  font-family: 'Noto Kufi Arabic', sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--accent);
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 2rem;
  font-size: 0.9375rem;
  color: var(--muted);
}
.nav-links a {
  position: relative;
  text-decoration: none;
  transition: color 0.15s;
}
/* underline grows from the reading edge on hover, mirrored for RTL */
.nav-links a::after {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: -5px;
  inline-size: 100%;
  block-size: 1px;
  background: var(--primary-bright);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
:root[dir='rtl'] .nav-links a::after { transform-origin: right center; }
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after,
.nav-links a:focus-visible::after { transform: scaleX(1); }
.nav-cta { display: flex; align-items: center; gap: 1.25rem; }
.lang-switch {
  font-size: 0.9375rem;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid var(--line-soft);
  padding: 0.45rem 0.8rem;
  border-radius: var(--radius);
  transition: color 0.15s, border-color 0.15s;
}
.lang-switch:hover { color: var(--ink); border-color: var(--line); }
/* the switch label is in the *other* script */
.lang-switch.to-ar { font-family: 'Noto Kufi Arabic', sans-serif; }
.lang-switch.to-en { font-family: 'Cabinet Grotesk', sans-serif; }

.nav .btn { padding: 0.62rem 1.05rem; font-size: 0.875rem; }

/* mobile disclosure menu (no JS needed) */
.nav-menu { display: none; position: relative; }
.nav-menu summary {
  list-style: none;
  cursor: pointer;
  font-size: 0.9375rem;
  color: var(--muted);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 0.45rem 0.8rem;
}
.nav-menu summary::-webkit-details-marker { display: none; }
.nav-menu[open] summary { color: var(--ink); border-color: var(--line); }
.nav-menu-panel {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: calc(100% + 0.6rem);
  min-width: 13rem;
  display: grid;
  gap: 0.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.6rem;
  box-shadow: 0 18px 40px oklch(0 0 0 / 0.45);
}
.nav-menu-panel a {
  text-decoration: none;
  color: var(--ink);
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius);
}
.nav-menu-panel a:hover { background: var(--surface-2); }

@media (max-width: 900px) {
  .nav-links { display: none; }
  .nav-menu { display: block; }
}
/* the Arabic switch stays reachable on phones; only the nav CTA folds
   into the menu (the hero CTA is one scroll away) */
@media (max-width: 560px) {
  .nav .btn-primary { display: none; }
  .nav-inner { gap: 1rem; }
}

/* ---------- Hero ---------- */

.hero {
  min-height: calc(100dvh - 68px);
  display: flex;
  align-items: center;
  /* lighter top, heavier bottom: keeps the composition anchored under the nav */
  padding-block: clamp(1.5rem, 3vh, 2.5rem) clamp(4.5rem, 10vh, 7rem);
  position: relative;
  overflow: hidden;
}
/* a soft green field glow behind the map side; the only light in the room */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(58rem 38rem at 70% 44%, oklch(0.19 0.045 160 / 0.5), transparent 62%);
  pointer-events: none;
}
:root[dir='rtl'] .hero::before {
  background: radial-gradient(58rem 38rem at 30% 44%, oklch(0.19 0.045 160 / 0.5), transparent 62%);
}
/* the cadastral field: faint parcel lines drifting behind the hero, the
   logo's land-registry grid blown up to landscape scale. Pure texture;
   fades out before it can compete with the headline. */
.hero-field {
  position: absolute;
  inset: -100px;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='640'%3E%3Cg fill='none' stroke='rgb(203,224,214)' stroke-opacity='0.5'%3E%3Cpath d='M0 .5h640M.5 0v640M400.5 0v320M0 320.5h640M180.5 320v320M400 180.5h240M560.5 320v152M400 472.5h160'/%3E%3C/g%3E%3Crect x='470' y='210' width='22' height='16' fill='rgb(226,204,141)' fill-opacity='0.4'/%3E%3C/svg%3E");
  background-size: 640px;
  opacity: 0.05;
  mask-image: linear-gradient(180deg, transparent 0%, black 22%, black 74%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, black 22%, black 74%, transparent 100%);
  animation: field-drift 90s linear infinite alternate;
}
@keyframes field-drift {
  to { transform: translate3d(-70px, -45px, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-field { animation: none; }
}
.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 6.5fr) minmax(0, 5.5fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  width: 100%;
}
.hero h1 {
  font-size: clamp(2.35rem, 4.6vw, 3.9rem);
  max-width: 24ch;
}
:root[lang='ar'] .hero h1 { font-size: clamp(2.2rem, 4.7vw, 3.7rem); max-width: 19ch; }
.hero-sub {
  margin-block-start: 1.5rem;
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  line-height: 1.65;
  color: var(--read);
  max-width: 46ch;
}
.hero-ctas {
  margin-block-start: 2.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
}
/* phones: the two CTAs share one width instead of a ragged step */
@media (max-width: 640px) {
  .hero-ctas { flex-direction: column; align-items: stretch; }
  .hero-ctas .btn { justify-content: center; }
}
.hero-map { position: relative; }

@media (max-width: 900px) {
  .hero { min-height: 0; }
  .hero-grid { grid-template-columns: 1fr; }
  .hero-map { max-width: 560px; }
}

/* ---------- Coverage map (SVG) ---------- */

.coverage-map { width: 100%; height: auto; }
/* context countries: geographic framing only, no coverage claim */
.map-context {
  fill: oklch(0.128 0.002 160);
  stroke: oklch(0.20 0.006 160);
  stroke-width: 1;
}
/* covered GCC zone beyond KSA */
.map-neighbor {
  fill: oklch(0.15 0.006 160);
  stroke: oklch(0.30 0.018 160);
  stroke-width: 1;
}
.map-country-label {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.18em;
  fill: oklch(0.48 0.012 160);
}
:root[lang='ar'] .map-country-label {
  font-family: 'IBM Plex Sans Arabic', sans-serif;
  font-size: 17px;
  letter-spacing: 0;
}
.map-region {
  fill: oklch(0.185 0.016 160);
  stroke: oklch(0.42 0.045 160);
  stroke-width: 1;
  transition: fill 0.3s;
}
.map-region:hover { fill: oklch(0.22 0.028 160); }
.map-dot { fill: var(--accent); }
.map-city.major .map-dot {
  filter: drop-shadow(0 0 5px oklch(0.82 0.09 90 / 0.5));
}
.map-dot-halo {
  fill: none;
  stroke: var(--accent);
  stroke-opacity: 0.4;
  stroke-width: 1.25;
}
/* once the intro finishes (JS adds .is-live) the live markets keep a slow
   heartbeat: the base is maintained every day, the map says so */
.coverage-map.is-live .map-city.major .map-dot-halo {
  transform-box: fill-box;
  transform-origin: center;
  animation: dot-pulse 4.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
.coverage-map.is-live .map-city[data-city='jeddah'] .map-dot-halo { animation-delay: 0.9s; }
.coverage-map.is-live .map-city[data-city='madinah'] .map-dot-halo { animation-delay: 1.8s; }
.coverage-map.is-live .map-city[data-city='dammam'] .map-dot-halo { animation-delay: 2.7s; }
.coverage-map.is-live .map-city[data-city='dubai'] .map-dot-halo { animation-delay: 3.4s; }
@keyframes dot-pulse {
  0% { transform: scale(0.5); stroke-opacity: 0.55; }
  70%, 100% { transform: scale(1.55); stroke-opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .coverage-map.is-live .map-city.major .map-dot-halo { animation: none; }
}
/* on-request markets: hollow dot, quieter halo */
.map-city.remote .map-dot {
  fill: var(--bg);
  stroke: var(--accent);
  stroke-width: 1.5;
}
.map-city.remote .map-dot-halo { stroke-opacity: 0.18; }
.map-city.remote .map-label { fill: var(--faint); }
/* pointer devices: bring a city forward on hover (labels stay legible on the
   quieter dots too). Touch gets none of this, by design. */
@media (hover: hover) {
  .map-city:hover .map-dot { filter: drop-shadow(0 0 6px oklch(0.82 0.09 90 / 0.85)); }
  .map-city:hover .map-label { fill: var(--ink); }
  .map-city.remote:hover .map-dot { filter: drop-shadow(0 0 5px oklch(0.82 0.09 90 / 0.6)); }
}

.map-legend {
  margin-block-start: 1.1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--muted);
  text-align: center;
}
:root[lang='ar'] .map-legend { font-size: 0.875rem; }
.map-legend .legend-live { color: var(--accent); }
.map-legend .legend-remote { color: var(--accent); opacity: 0.75; }
.map-legend .legend-gap { display: inline-block; inline-size: 1.5rem; }
/* sizes are in SVG user units: the 940px viewBox renders around 55% scale,
   so 17px here reads as ~9.5px on screen */
.map-label {
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 450;
  fill: var(--muted);
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 5px;
  stroke-linejoin: round;
}
:root[lang='ar'] .map-label {
  font-family: 'IBM Plex Sans Arabic', sans-serif;
  font-size: 19px;
  /* neutralize the RTL document direction inside the SVG so text-anchor
     start/end keep the same geometry as the EN map (offsets are shared) */
  direction: ltr;
}
.map-city.major .map-label { fill: var(--ink); font-weight: 550; font-size: 19px; }
:root[lang='ar'] .map-city.major .map-label { font-size: 21px; }
@media (max-width: 640px) {
  .map-city:not(.major) .map-label { display: none; }
}

/* ---------- Sources band ---------- */

.sources {
  border-block-start: 1px solid var(--line-soft);
  padding-block: clamp(3.5rem, 8vh, 5.5rem);
}
.sources h2 {
  font-size: clamp(1.8rem, 3.1vw, 2.55rem);
}
.sources-lede {
  margin-block-start: 1.2rem;
  color: var(--read);
  font-size: 1.125rem;
  max-width: 56ch;
  text-wrap: pretty;
}
.source-wall {
  margin-block-start: 2.5rem;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* every row the same height: one uneven cell must not break the band */
  grid-auto-rows: 1fr;
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.source-plate {
  background: var(--bg);
  padding: 1.15rem 1.3rem 1.05rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 0.3rem;
  min-height: 6.5rem;
  transition: background-color 0.25s;
}
.source-plate:hover { background: var(--surface); }
.source-en {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  color: var(--ink);
}
:root[lang='ar'] .source-en { font-family: var(--font-body); font-weight: 600; }
.source-ar {
  font-family: 'Noto Kufi Arabic', sans-serif;
  font-size: 0.82rem;
  color: var(--faint);
}
.source-sub {
  font-size: 0.82rem;
  color: var(--faint);
}
/* plates with a real mark: the mark carries both scripts, text goes to AT only.
   Every mark is centered on both axes and optically size-tuned per logo, so
   the wall reads as one aligned system instead of eight ragged crops. */
.source-plate.has-logo { justify-content: center; align-items: center; }
.source-logo {
  height: 32px;
  width: auto;
  max-width: min(78%, 168px);
  object-fit: contain;
  /* normalize brand colors to a single institutional white */
  filter: brightness(0) invert(1);
  opacity: 0.85;
  transition: opacity 0.25s;
}
.source-plate.has-logo:hover .source-logo { opacity: 1; }
/* raster marks arrive pre-whitened (no filter needed) */
.source-logo-flat { filter: none; }
/* optical normalization, mark by mark (wordmark-heavy logos sit lower,
   portrait emblems taller); selectors match both en/ and ar/ paths */
.source-logo[src*='rega'] { height: 36px; }
.source-logo[src*='wafi'] { height: 40px; }
.source-logo[src*='sakani'] { height: 26px; }
.source-logo[src*='saudi-exchange'] { height: 38px; }
.source-logo[src*='dld'] { height: 36px; }
.source-logo[src*='adrec'] { height: 34px; }
/* the MOJ plate is the one emblem-only mark: it keeps a visible caption so
   the source stays nameable, and the solid crest is dimmed toward the
   optical weight of the line-drawn lockups around it */
.source-plate-cap { gap: 0.55rem; }
.source-plate-cap .source-logo { height: 38px; opacity: 0.72; }
.source-plate-cap:hover .source-logo { opacity: 0.9; }
/* must out-rank the .source-plate.has-logo .source-en hider below */
.source-plate.has-logo.source-plate-cap .source-en {
  position: static;
  width: auto; height: auto;
  margin: 0; padding: 0;
  clip-path: none;
  overflow: visible;
  white-space: normal;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--faint);
}
/* the field plate speaks at logo volume, not headline volume */
.source-plate-field .source-en {
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 600;
  font-family: var(--font-body);
}
.source-plate.has-logo .source-en,
.source-plate.has-logo .source-ar {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.source-note {
  margin-block-start: 0.9rem;
  font-size: 0.8125rem;
  color: var(--faint);
}

/* capture: how each figure is taken in, as a stepped hairline list
   (deliberately not the boxed method triad, so the page has two distinct 3-part shapes) */
.capture {
  margin-block: 2.5rem 3.25rem;
  display: grid;
}
.capture-item {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: 1.25rem 2rem;
  padding-block: 1.5rem;
  border-block-start: 1px solid var(--line-soft);
  align-items: start;
}
.capture-item:last-child { border-block-end: 1px solid var(--line-soft); }
.capture-tag {
  justify-self: start;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--primary-bright);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.3rem 0.55rem;
  direction: ltr;
  unicode-bidi: isolate;
}
.capture-body h3 { font-size: 1.2rem; }
.capture-body p {
  margin-block-start: 0.5rem;
  color: var(--read);
  font-size: 1rem;
  line-height: 1.62;
  max-width: 62ch;
}
@media (max-width: 720px) {
  .capture-item { grid-template-columns: 1fr; gap: 0.7rem; padding-block: 1.3rem; }
}
@media (max-width: 900px) {
  .source-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Sections (shared) ---------- */

.section { padding-block: var(--section-gap); }
.section + .section { padding-block-start: 0; }

.section-head { max-width: 64ch; }
/* headlines carry the section: larger, tighter, and given real air before the
   lede so the title lands first and the lede reads as support, not a rival */
.section-head h2 { font-size: clamp(2.1rem, 4.3vw, 3.6rem); line-height: 1.02; }
.section-head .lede {
  margin-block-start: 1.4rem;
  color: var(--read);
  font-size: 1.125rem;
  line-height: 1.6;
  max-width: 48ch;
  text-wrap: pretty;
}

.rule { border: 0; border-block-start: 1px solid var(--line-soft); margin: 0; }

/* ---------- Manifesto (problem) ---------- */

.manifesto { border-block: 1px solid var(--line-soft); background: var(--surface); }
.manifesto-inner { padding-block: clamp(4rem, 9vh, 6.5rem); }
.manifesto h2 {
  font-size: clamp(2.1rem, 4.4vw, 3.5rem);
  max-width: 20ch;
}
.manifesto-points {
  margin-block-start: 2.75rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2.5rem;
}
.manifesto-points > div {
  position: relative;
  border-block-start: 1px solid var(--line);
  padding-block-start: 1.4rem;
}
/* a short green tick over the start of each rule: anchors the three problems
   as a set and gives the mobile stack a visual spine instead of bare text */
.manifesto-points > div::before {
  content: '';
  position: absolute;
  inset-block-start: -1px;
  inset-inline-start: 0;
  inline-size: 2.5rem;
  block-size: 2px;
  background: var(--primary-bright);
}
.manifesto-points p { color: var(--read); font-size: 1.02rem; }
.manifesto-points strong { color: var(--ink); font-weight: 600; display: block; margin-block-end: 0.4rem; }
.manifesto-pivot {
  margin-block-start: 3rem;
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  max-width: 44ch;
  color: var(--ink);
}
:root[lang='ar'] .manifesto-pivot { letter-spacing: 0; }
.manifesto-pivot .pivot-mark { color: var(--primary-bright); }

@media (max-width: 820px) {
  .manifesto-points { grid-template-columns: 1fr; gap: 1.5rem; }
}

/* ---------- Coverage: dataset catalogue ---------- */

.catalog {
  margin-block-start: 3rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
  overflow-x: auto;
  /* the catalogue is the product shot: a low green light lifts it off the page */
  box-shadow: 0 28px 70px -36px oklch(0.35 0.07 160 / 0.5);
}
.catalog-table tbody tr { transition: background-color 0.2s; }
.catalog-table tbody tr:hover { background: var(--surface-2); }
.catalog:focus-visible { outline: 2px solid var(--primary-bright); outline-offset: 3px; }
.catalog-table {
  width: 100%;
  min-width: 720px;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.catalog-table th, .catalog-table td {
  text-align: start;
  padding: 1.05rem 1.4rem;
  border-block-end: 1px solid var(--line-soft);
  vertical-align: top;
}
.catalog-table thead th {
  font-weight: 500;
  font-size: 0.8125rem;
  color: var(--faint);
  padding-block: 0.8rem;
}
.catalog-table tbody tr:last-child th,
.catalog-table tbody tr:last-child td { border-block-end: 0; }
.catalog-table td { color: var(--read); }
.catalog-table .cat-name {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 700;
  font-size: 1.02rem;
  white-space: nowrap;
}
:root[lang='ar'] .catalog-table .cat-name { font-family: var(--font-body); font-weight: 600; }
.catalog-asof {
  margin-block-start: 0.9rem;
  font-size: 0.8125rem;
  color: var(--faint);
}

/* phones: the catalogue table becomes a stack of dataset cards, no
   horizontal scrolling, nothing clipped */
@media (max-width: 720px) {
  .catalog { border: 0; background: none; overflow: visible; }
  .catalog-table { min-width: 0; display: block; font-size: 1rem; }
  .catalog-table thead { display: none; }
  .catalog-table tbody { display: grid; gap: 0.8rem; }
  .catalog-table tr {
    display: block;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    padding: 1.05rem 1.15rem;
  }
  .catalog-table td { display: block; padding: 0; border: 0; }
  .catalog-table .cat-name { white-space: normal; margin-block-end: 0.3rem; }
}

.coverage-note {
  margin-block-start: 1.75rem;
  color: var(--read);
  max-width: 52ch;
}
.coverage-note em { color: var(--ink); font-style: normal; font-weight: 500; }

/* ---------- Time-depth: the trend trail ----------
   A single project's life as the base holds it, from launch to today. The
   green line draws across (GSAP scaleX from the reading edge); each stage is
   marked by the same small sand cell used elsewhere. */

.time-depth .section-head h2 { max-width: 22ch; }
.trail { margin-block-start: clamp(2.6rem, 6vh, 3.6rem); }
/* the connector spans the first marker to the last (Today) instead of running
   on to the container edge; markers sit at the left of five equal columns, so
   the last one lands at 80% + 0.8x the 1.5rem gap */
.trail-track { position: relative; block-size: 1px; background: var(--line-soft); inline-size: calc(80% + 1.2rem + 5px); }
.trail-line {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  block-size: 1px;
  inline-size: 100%;
  background: var(--primary-bright);
}
.trail-steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0 1.5rem;
  margin-block-start: 1.1rem;
}
.trail-steps li { position: relative; }
.trail-steps li::before {
  content: '';
  position: absolute;
  inset-block-start: -1.1rem;
  inset-inline-start: 0;
  inline-size: 8px;
  block-size: 8px;
  background: var(--accent);
}
.trail-stage {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.08rem;
  color: var(--ink);
}
:root[lang='ar'] .trail-stage { font-family: var(--font-body); font-weight: 600; }
.trail-note {
  display: block;
  margin-block-start: 0.45rem;
  font-size: 0.9rem;
  color: var(--read);
  max-width: 22ch;
  text-wrap: pretty;
}
/* mobile + tablet: a horizontal line over stacked stages reads as broken, so
   the trail becomes a vertical timeline — one line down the side, a sand cell
   at every stage. Logical properties mirror the whole thing for the AR page. */
@media (max-width: 820px) {
  .time-depth .trail-track { display: none; }
  .trail { margin-block-start: clamp(1.8rem, 4.5vh, 2.4rem); }
  .trail-steps {
    grid-template-columns: 1fr;
    gap: 1.85rem;
    position: relative;
    padding-inline-start: 1.7rem;
  }
  /* the continuous line, brightest at the launch end and fading toward today */
  .trail-steps::before {
    content: '';
    position: absolute;
    inset-block: 0.5rem 0.4rem;
    inset-inline-start: 3.5px;
    inline-size: 1px;
    background: linear-gradient(var(--primary-bright), var(--line-soft));
  }
  .trail-steps li::before {
    display: block;
    inset-block-start: 0.42em;
    inset-inline-start: -1.7rem;
  }
  .trail-stage { font-size: 1.12rem; }
  .trail-note { max-width: 40ch; margin-block-start: 0.35rem; }
}

/* ---------- Field divider (full-bleed photograph) ---------- */

.field-divider {
  position: relative;
  overflow: hidden;
  block-size: clamp(320px, 48vh, 470px);
  border-block: 1px solid var(--line-soft);
}
.field-divider img {
  position: absolute;
  inset-inline: 0;
  inset-block-start: -12%;
  width: 100%;
  height: 124%;
  object-fit: cover;
  filter: saturate(0.58) brightness(0.72) contrast(1.05);
}
.field-divider-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--bg) 0%, oklch(0.11 0 0 / 0.25) 30%, oklch(0.11 0 0 / 0.30) 68%, oklch(0.11 0 0 / 0.86) 100%);
}
.field-divider-line {
  position: absolute;
  inset-block-end: clamp(1.6rem, 5vh, 2.8rem);
  inset-inline: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.2rem, 2.4vw, 1.7rem);
  letter-spacing: -0.01em;
  color: var(--ink);
}
:root[lang='ar'] .field-divider-line { letter-spacing: 0; }

/* ---------- Method: split with record extract ---------- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.split.flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
@media (max-width: 900px) {
  .split, .split.flip { grid-template-columns: 1fr; }
}

/* the method check list, marked with the small green cell */
.history-list { margin-block-start: 2.2rem; display: grid; gap: 1.1rem; }
.history-list li {
  color: var(--read);
  padding-inline-start: 1.35rem;
  position: relative;
}
.history-list li strong { color: var(--ink); font-weight: 600; }
/* same marker language as the edge grid: the small green cell */
.history-list li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.42em;
  width: 8px;
  height: 8px;
  background: var(--primary-bright);
}

/* method: the three questions, presented as schema fields made human */
.triad {
  margin-block-start: 2.75rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.triad-item { background: var(--surface); padding: 1.6rem 1.5rem 1.5rem; }
.triad-tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--accent);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.3rem 0.55rem;
  direction: ltr;
  unicode-bidi: isolate;
}
.triad-item h3 { margin-block-start: 1rem; font-size: 1.2rem; }
.triad-item p { margin-block-start: 0.5rem; color: var(--read); font-size: 0.97rem; }
@media (max-width: 820px) {
  .triad { grid-template-columns: 1fr; }
  .triad-item { padding: 1.3rem 1.25rem; }
}

/* method: the compressed check pipeline beside the single record extract */
.method-split { margin-block-start: clamp(3rem, 7vh, 4.5rem); }
.method-side h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); }
.method-side .history-list { margin-block-start: 1.8rem; }
.method-delivery {
  margin-block-start: 2.2rem;
  padding-block-start: 1.4rem;
  border-block-start: 1px solid var(--line-soft);
  color: var(--muted);
  font-size: 0.98rem;
  max-width: 46ch;
}

/* record extract table */
.record {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  box-shadow: 0 24px 60px -34px oklch(0.35 0.07 160 / 0.45);
}
.record-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.6rem 2rem;
  flex-wrap: wrap;
  padding: 0.85rem 1.25rem;
  border-block-end: 1px solid var(--line-soft);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--faint);
}
.record table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: 0.8rem;
}
.record th, .record td {
  text-align: start;
  padding: 0.72rem 1.25rem;
  border-block-end: 1px solid var(--line-soft);
  vertical-align: top;
}
.record tr:last-child td { border-block-end: 0; }
.record th {
  color: var(--faint);
  font-weight: 400;
  width: 34%;
}
.record td { color: var(--ink); }
.record .val-src { color: var(--muted); }
.record .val-conf { color: var(--primary-bright); }
.record .val-na { color: var(--accent); }
/* masked values: real underneath, delivered under licence */
.record .redact { color: var(--accent); letter-spacing: 0.04em; }
:root[lang='ar'] .record th { font-family: 'IBM Plex Sans Arabic', sans-serif; font-size: 0.88rem; }
/* Arabic values leave the mono stack (fallback Arabic mono spaced badly);
   Latin tokens inside them keep it via .ltr */
:root[lang='ar'] .record td { font-family: 'IBM Plex Sans Arabic', sans-serif; font-size: 0.88rem; }
:root[lang='ar'] .record td .ltr { font-family: var(--font-mono); font-size: 0.8rem; }
/* global LTR isolation for latin tokens inside RTL copy (record values,
   format names, API mentions) */
.ltr { direction: ltr; unicode-bidi: isolate; }
/* phones: the record extract is the heaviest single block. Fix the field
   column narrow, let the value take the rest, and tighten the type so most
   rows fall back to one or two lines instead of wrapping to three or four. */
@media (max-width: 640px) {
  .record table { table-layout: fixed; font-size: 0.74rem; }
  .record th, .record td {
    padding: 0.62rem 0.85rem;
    overflow-wrap: break-word;
  }
  .record th { width: 38%; white-space: normal; }
  .record-head { padding: 0.75rem 0.85rem; }
  :root[lang='ar'] .record th,
  :root[lang='ar'] .record td { font-size: 0.82rem; }
}
/* keeps a short phrase on one line (heading break control) */
.nb { white-space: nowrap; }

/* ---------- Case studies: featured cases + expandable ledger ----------
   Two briefs with a real, shippable exhibit become full cases (prose + a
   redacted record panel, the Method component reused); the other four stay a
   scannable ledger that expands on demand (native <details>, no JS). The four
   beats use Omran's own words: the brief, who asked, what we assembled, what
   shipped, the edge. (Rebuild 2026-07-11 evening: show the work.) */

/* shared beat styles (featured + expanded ledger) */
.brief-work { color: var(--read); font-size: 1rem; max-width: 56ch; }
.brief-shipped { color: var(--read); font-size: 0.98rem; }
.brief-k { font-size: 0.8125rem; font-weight: 600; color: var(--faint); margin-inline-end: 0.3rem; }
.brief-edge {
  position: relative;
  padding-inline-start: 1.35rem;
  color: var(--ink);
  font-weight: 500;
  max-width: 54ch;
}
/* the located datapoint: the sand cell marks the line that carries the edge */
.brief-edge::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.5em;
  inline-size: 8px;
  block-size: 8px;
  background: var(--accent);
}

/* Tier 1: featured cases */
.brief-cases { margin-block-start: 3rem; display: grid; }
.brief-case {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4rem);
  /* the prose is now three short beats: centered against the exhibit it reads
     as a caption beside the product shot instead of a stub above a void */
  align-items: center;
  padding-block: clamp(2.4rem, 5.5vh, 3.4rem);
}
.brief-case + .brief-case { border-block-start: 1px solid var(--line-soft); }
.brief-case-body h3 { font-size: clamp(1.35rem, 2.4vw, 1.72rem); max-width: 22ch; }
.brief-who { margin-block-start: 1rem; color: var(--ink); font-size: 1.05rem; max-width: 52ch; }
.brief-case-body .brief-shipped { margin-block-start: 0.9rem; }
.brief-case-body .brief-edge { margin-block-start: 1.15rem; }
.brief-record { align-self: start; }
@media (max-width: 860px) {
  .brief-case { grid-template-columns: 1fr; gap: 1.8rem; }
}

/* Tier 2: the remaining briefs, expandable rows */
.brief-rows { display: grid; }
.brief-ledger { margin-block-start: 2.75rem; border-block-start: 1px solid var(--line-soft); }
.brief-row { border-block-end: 1px solid var(--line-soft); }
.brief-row > summary {
  position: relative;
  list-style: none;
  cursor: pointer;
  display: block;
  padding-block: 1.5rem;
  padding-inline: 1.4rem 2.6rem;
  transition: background-color 0.25s;
}
.brief-row > summary::-webkit-details-marker { display: none; }
.brief-row > summary:hover { background: color-mix(in oklab, var(--surface) 55%, transparent); }
/* the located datapoint marker, kept from the old ledger */
.brief-row > summary::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 1.95rem;
  inline-size: 8px;
  block-size: 8px;
  background: var(--accent);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.25s, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.brief-row[open] > summary::before,
.brief-row > summary:hover::before { opacity: 1; transform: none; }
/* expand chevron: a vertical down-caret. Placement stays logical (sits on the
   correct side in RTL) but the borders are PHYSICAL so the caret always points
   down, in both LTR and RTL (logical borders would mirror it to a side-caret). */
.brief-row > summary::after {
  content: '';
  position: absolute;
  inset-inline-end: 0.5rem;
  inset-block-start: 1.85rem;
  inline-size: 10px;
  block-size: 10px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg);
  transition: transform 0.25s;
}
.brief-row[open] > summary::after { transform: rotate(-135deg); inset-block-start: 2.05rem; }
.brief-q {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.16rem;
  line-height: 1.3;
  color: var(--ink);
}
:root[lang='ar'] .brief-q { font-family: var(--font-body); font-weight: 600; line-height: 1.5; }
.brief-lead { display: block; margin-block-start: 0.4rem; color: var(--read); font-size: 0.99rem; max-width: 72ch; }
.brief-more {
  padding-inline: 1.4rem 2.6rem;
  padding-block-end: 1.7rem;
  display: grid;
  gap: 0.7rem;
  max-width: 76ch;
}
@media (max-width: 640px) {
  .brief-row > summary { padding-inline: 1.4rem 2.4rem; }
  .brief-more { padding-inline: 1.4rem 1rem; }
}

/* ---------- Engagement ---------- */

.tiers {
  margin-block-start: 3rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2.5rem;
}
.tier { border-block-start: 2px solid var(--line); padding-block-start: 1.4rem; transition: border-color 0.3s; }
.tier:hover { border-block-start-color: var(--muted); }
.tier.tier-lead { border-block-start-color: var(--primary-bright); }
.tier.tier-lead:hover { border-block-start-color: var(--primary-bright); }
.tier h3 { font-size: 1.22rem; margin-block-end: 0.7rem; }
.tier p { color: var(--read); font-size: 0.99rem; }
.tier .tier-hint {
  margin-block-start: 1.1rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
}
@media (max-width: 820px) {
  .tiers { grid-template-columns: 1fr; gap: 2rem; }
}

/* ---------- Final CTA ---------- */

.closer {
  position: relative;
  overflow: hidden;
  border-block-start: 1px solid var(--line-soft);
  background: var(--bg);
}
/* photographic depth under the final ask: Makkah at night, heavily scrimmed */
.closer-bg {
  position: absolute;
  inset: 0;
  background-image: url('../img/makkah-tower.webp');
  background-size: cover;
  background-position: center 30%;
  filter: saturate(0.55) brightness(0.75);
  opacity: 0.32;
}
.closer-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(90rem 30rem at 50% 120%, oklch(0.20 0.045 160 / 0.55), transparent 60%),
    linear-gradient(180deg, var(--bg) 0%, oklch(0.11 0 0 / 0.66) 30%, oklch(0.11 0 0 / 0.82) 100%);
}
.closer-inner {
  position: relative;
  padding-block: clamp(5rem, 14vh, 9rem);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.closer h2 { font-size: clamp(2.1rem, 4.4vw, 3.4rem); max-width: 18ch; }
.closer p {
  margin-block-start: 1.25rem;
  color: var(--ink);
  max-width: 52ch;
  font-size: 1.08rem;
}
.closer .hero-ctas { justify-content: center; }

.closer-conf {
  margin-block-start: 0.9rem;
  font-size: 0.9rem;
}
.closer-conf { color: var(--muted); }

/* ---------- Contact form ---------- */

.contact-form {
  margin-block-start: 3rem;
  width: min(100%, 620px);
  text-align: start;
}
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
  margin-block-end: 1.25rem;
}
@media (max-width: 620px) {
  .form-grid { grid-template-columns: 1fr; }
}
.field { margin-block-end: 1.25rem; }
.form-grid .field { margin-block-end: 0; }
.field label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
  margin-block-end: 0.45rem;
}
.field label .opt { color: var(--faint); font-weight: 400; }
.field input, .field textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 0.8rem 0.95rem;
  transition: border-color 0.15s;
}
.field textarea { resize: vertical; min-height: 7rem; }
@media (max-width: 640px) {
  /* the desktop resize grip is noise on touch screens */
  .field textarea { resize: none; }
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); opacity: 1; }
.field input:hover, .field textarea:hover { border-color: var(--muted); }
.field input:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--primary-bright);
  outline-offset: 1px;
  border-color: transparent;
}
/* honeypot: off-screen, still focus-skipped and hidden from AT */
.hp-field {
  position: absolute;
  inset-inline-start: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}
.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
}
.form-foot .btn { border: 0; cursor: pointer; }
.form-foot .btn[disabled] { opacity: 0.55; cursor: default; transform: none; }
.form-status { margin-block-start: 1rem; font-size: 0.95rem; color: var(--primary-bright); min-height: 1.4em; }
.form-status.error { color: oklch(0.78 0.12 25); }

/* visually hidden, available to assistive tech */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Footer ---------- */

.footer { border-block-start: 1px solid var(--line-soft); }
.footer-inner {
  padding-block: 2.75rem 2.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.75rem 3rem;
  color: var(--faint);
  font-size: 0.875rem;
}
.footer a { color: var(--muted); text-decoration: none; }
.footer a:hover { color: var(--ink); }
.footer .wordmark-latin { font-size: 0.95rem; }
.footer .wordmark-arabic { font-size: 0.88rem; }
.footer-brand { display: grid; gap: 0.8rem; }
.footer-tag { max-width: 34ch; text-wrap: pretty; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 0.9rem 1.75rem; padding-block-start: 0.2rem; }
.footer-side {
  display: grid;
  gap: 0.7rem;
  /* all three lines share the page's end grid line (mirrors on ar/) */
  justify-items: end;
  text-align: end;
}
.credits-link { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Motion helpers ----------
   Reveals are additive: content is fully visible without JS; GSAP sets
   from-states at runtime only. No CSS hides anything by default. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* print / headless: neutralize any JS-set reveal states */
@media print {
  * { opacity: 1 !important; transform: none !important; }
}
