/**
 * design.md -> CSS custom properties. This file is the ONLY place a visual value from
 * design.md is written as a literal. Every component consumes var(--...) exclusively
 * (design-tokens skill). Section order mirrors design.md so the two never drift apart.
 */

:root {
  /* ============================= Color: primitive scale ============================= */
  --blue-50: #eef3ff;
  --blue-100: #d9e4ff;
  --blue-200: #b3c8ff;
  --blue-300: #7fa2ff;
  --blue-400: #4a7cff;
  --blue-500: #1e5eff;
  --blue-600: #1a4fd6;
  --blue-700: #153e90;
  --blue-800: #10306e;
  --blue-900: #0b1d3f;

  --gold-50: #fff7e6;
  --gold-100: #ffecbf;
  --gold-200: #ffdd8c;
  --gold-300: #ffce5c;
  --gold-400: #ffc12e;
  --gold-500: #ffb400;
  --gold-600: #e09e00;
  --gold-700: #b37e00;

  --white: #ffffff;
  --gray-50: #f7f9fc;
  --gray-100: #eef1f6;
  --gray-200: #e2e7ef;
  --gray-300: #cbd3e0;
  --gray-400: #9aa6bc;
  --gray-500: #6b7891;
  --gray-600: #4c566b;
  --gray-700: #333b4d;
  --gray-800: #1f2532;
  --gray-900: #0e1320;

  --green-50: #e4f6ec;
  --green-500: #22a05a;
  --green-600: #1b834a;
  --amber-50: #fff4e0;
  --amber-500: #e08a00;
  --amber-600: #b87200;
  --red-50: #fdecec;
  --red-500: #e23d3d;
  --red-600: #c42b2b;

  /* ============================= Color: semantic tokens ============================= */
  --color-primary: var(--blue-500);
  --color-primary-hover: var(--blue-600);
  --color-primary-active: var(--blue-700);
  --color-primary-soft: var(--blue-50);
  --color-secondary: var(--blue-700);
  --color-link: var(--blue-700);
  --color-accent: var(--gold-500);
  --color-accent-hover: var(--gold-600);
  --color-accent-soft: var(--gold-50);
  --color-text-on-accent: var(--gray-900);

  --color-navy: var(--blue-900);

  --color-text: var(--gray-900);
  --color-text-muted: var(--gray-500);
  --color-text-subtle: var(--gray-400);
  --color-text-inverse: #ffffff;

  --color-bg: #ffffff;
  --color-surface: var(--gray-50);
  --color-surface-2: var(--gray-100);
  --color-card: #ffffff;
  --color-border: var(--gray-200);
  --color-border-strong: var(--gray-300);

  --color-success: var(--green-600);
  --color-success-soft: var(--green-50);
  --color-warning: var(--amber-600);
  --color-warning-soft: var(--amber-50);
  --color-danger: var(--red-600);
  --color-danger-soft: var(--red-50);
  --color-info: var(--blue-600);
  --color-info-soft: var(--blue-50);

  --color-focus-ring: var(--blue-500);
  --color-overlay: rgba(11, 29, 63, 0.55);
  --color-scrim: rgba(11, 29, 63, 0.6);
  --color-watermark: rgba(255, 255, 255, 0.7);
  --color-watermark-ink: rgba(11, 29, 63, 0.35);

  /* ---- Domain status aliases ---- */
  --status-approved: var(--color-success);
  --status-approved-soft: var(--color-success-soft);
  --status-pending: var(--color-warning);
  --status-pending-soft: var(--color-warning-soft);
  --status-rejected: var(--color-danger);
  --status-rejected-soft: var(--color-danger-soft);
  --lead-new: var(--color-info);
  --lead-new-soft: var(--color-info-soft);
  --lead-contacted: var(--gray-600);
  --lead-contacted-soft: var(--gray-100);
  --lead-viewing: var(--color-warning);
  --lead-viewing-soft: var(--color-warning-soft);
  --lead-closed: var(--color-success);
  --lead-closed-soft: var(--color-success-soft);
  --lead-quiet: var(--color-danger);
  --lead-quiet-soft: var(--color-danger-soft);
  --source-admin: var(--color-primary);
  --source-lister: var(--gray-600);

  /* ---- Hero panel / filter-bar surface (Direction A: near-solid, blur as progressive
     enhancement). IT12: this is now the filter BAR's shell — design.md "filter-bar-bg:
     hero-panel-bg (UNCHANGED value)" / "filter-bar-blur: hero-panel-blur (8px)". ---- */
  --hero-panel-bg: rgba(255, 255, 255, 0.92);
  --hero-panel-blur: 8px;
  --hero-panel-stack-gap: var(--space-5); /* filter-bar-stack-gap: toggle row <-> field row */

  /* ---- Hero copy scrim (IT12, design.md Color "hero-scrim-copy") — the AA guarantee for the
     inverse copy over a moving background. Same navy as --color-overlay, documented alphas
     only — no new hue. Block-direction only, so it never needs an RTL mirror rule. ---- */
  --hero-scrim-copy: linear-gradient(
    to bottom,
    rgba(11, 29, 63, 0.3) 0%,
    rgba(11, 29, 63, 0.3) 55%,
    rgba(11, 29, 63, 0) 85%
  );

  /* ---- Hero band (S1) composition — IT12 (design.md Layout "Hero band (S1) composition -
     IT12"): statement copy anchored at the band's block-start, a full-width filter BAR
     anchored at its block-end. Supersedes IT7's two-zone side-card grid — --hero-grid-lg /
     --hero-zone-gap-lg / --hero-panel-max-inline-lg are retired (the bar is no longer a
     capped side column; it spans the container like everything else). ---- */
  /* IT12-R1 (review cycle 1, H1 ruling): was 720px on a char-average model that under-predicted
     the EN mobile break (4 real lines, not the predicted 2-3) and, at the shortened EN string,
     left desktop line 1 98.5% full with a one-word orphan. Re-derived per-glyph on the FINAL
     strings (design.md splice pack §3.4-R1): EN "Your next property, one / trusted contact"
     530px(83%)/351px, AR unchanged 552px(86%)/408px — both clean 2-line breaks at 640px. */
  --hero-copy-max-inline-lg: 640px;
  --hero-copy-bar-gap-lg: var(--space-12); /* row-gap between the copy block and the bar */
  --hero-min-block-lg: 580px; /* CHANGED from 440px (IT7) — measured floor, see design.md */
  --hero-bar-margin-base: var(--space-8); /* margin above the bar in the <bp-lg stacked flow */

  /* ---- Media framing (IT12-R3, design.md Layout "Media framing (IT12-R3)") — hero-media-*.
     MUST be applied to BOTH the poster <img> and the <video> at every breakpoint (parity rule:
     a mismatch makes the poster -> video handoff visibly jump). See HeroMedia.module.css. ---- */
  --hero-media-object-position-lg: 50% 55%; /* >= bp-lg: slight downward bias so the 692px band
    keeps skyline/waterline in frame instead of empty sky. Do not exceed 60%. */
  --hero-media-object-position-base: 50% 50%; /* < bp-lg: vertical is inert (portrait crop shows
    100% of frame height) — only horizontal matters. The one per-asset value an orchestrator may
    retune if a future clip's subject sits off-centre; re-check both breakpoints together. */

  /* ============================= Type ============================= */
  --font-latin: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-arabic: 'Cairo', 'Tajawal', system-ui, sans-serif;
  --font-body: var(--font-latin);
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Courier New', monospace;

  --text-xs: 12px;
  --leading-xs: 1.5;
  --text-sm: 14px;
  --leading-sm: 1.5;
  --text-base: 16px;
  --leading-base: 1.6;
  --text-lg: 20px;
  --leading-lg: 1.4;
  --text-xl: 24px;
  --leading-xl: 1.35;
  --text-2xl: 30px;
  --leading-2xl: 1.25;
  --text-3xl: 38px;
  --leading-3xl: 1.2;
  --text-4xl: 48px;
  --leading-4xl: 1.1;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* letter-spacing-default (0) needs no custom property — nothing sets a non-zero value to
     override. letter-spacing-caps is the ONE tracking value in the product (design.md Type),
     first consumed at IT12 by the hero eyebrow — the product's first and only uppercase
     micro-label, English-only (see HeroSearchPanel.module.css). */
  --letter-spacing-caps: 0.04em;

  /* ============================= Spacing (4px base) ============================= */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;

  /* ============================= Radii ============================= */
  --radius-xs: 8px;
  --radius-chip: 12px;
  --radius-input: 14px;
  --radius-card: 18px;
  --radius-lg: 24px;
  --radius-full: 9999px;

  /* ============================= Shadows ============================= */
  /* docs/10-iteration-5-audit.md D8: --shadow-xs pruned (dead — zero box-shadow consumers). */
  --shadow-sm: 0 2px 6px rgba(15, 19, 32, 0.08);
  --shadow-card: 0 6px 20px rgba(15, 19, 32, 0.08);
  --shadow-md: 0 10px 30px rgba(15, 19, 32, 0.1);
  --shadow-lg: 0 20px 48px rgba(15, 19, 32, 0.14);
  --shadow-sidebar: 0 0 24px rgba(11, 29, 63, 0.2);
  --shadow-focus: 0 0 0 3px color-mix(in srgb, var(--color-focus-ring) 35%, transparent);

  /* ============================= Motion ============================= */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --easing-standard: cubic-bezier(0.2, 0, 0, 1);
  --easing-decelerate: cubic-bezier(0, 0, 0, 1);
  --easing-accelerate: cubic-bezier(0.3, 0, 1, 1);

  /* ---- Structural motion tokens (IT10 site-wide motion system + gallery/card-pager slide) ----
     Distances/durations/budgets only — no color, no brand identity (design.md Motion). The
     "motion-content-visible-cap" (150ms) budget is enforced BY CONSTRUCTION (gating logic in
     AppLayout.tsx / useScrollReveal.ts), not a CSS value, so it has no custom property here. */
  --motion-rise: 8px;
  --motion-slide-duration: var(--duration-base);
  --motion-slide-easing: var(--easing-standard);
  --motion-page-enter-duration: var(--duration-base);
  --motion-page-enter-easing: var(--easing-decelerate);
  --motion-reveal-duration: var(--duration-base);
  --motion-reveal-easing: var(--easing-decelerate);
  --motion-reveal-stagger: 60ms;
  --motion-swipe-commit: 40px;

  /* ---- Perceived-speed tokens (IT11; design.md "Loading & perceived speed") ----
     Same class as the motion-* budgets above — a threshold, not a color/type/identity value.
     "preload-max-inflight" (3) is a JS concurrency ceiling (imagePrefetchQueue.ts), not a CSS
     value, so it has no custom property here — mirroring the motion-content-visible-cap note
     just above. "perceived-affordance-delay" IS consumed directly as a CSS `animation-delay`
     (ImagePager.module.css's shimmer), so it gets one. */
  --perceived-affordance-delay: 150ms;

  /* ============================= Z-index ============================= */
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 100;
  --z-header: 150;
  --z-drawer: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-popover: 450;
  --z-toast: 500;

  /* ============================= Layout ============================= */
  --container-max: 1200px;
  --container-pad-inline: var(--space-4);
  --reading-measure: 72ch;
  --header-height: 64px;
  --grid-gutter: var(--space-6);

  /* ---- Footer separation (main->footer gap) — IT7: the SINGLE gap, was an ad-hoc space-16 ---- */
  --footer-margin-block-start: var(--space-12);

  /* ---- Admin (design.md Layout "Admin") ---- */
  --admin-sidebar-width: 264px;
  --admin-sidebar-collapsed: 72px;
  --admin-topbar-height: 64px;
  --admin-content-max: 1440px;

  /* ---- Account page (S-ACC, design.md Layout "Account page") — IT10 ---- */
  --account-content-max: 640px;

  /* ============================= Components ============================= */
  --touch-min: 44px;

  --btn-height-sm: 36px;
  --btn-height-md: 44px;
  --btn-height-lg: 52px;
  --btn-pad-inline: var(--space-5);
  --btn-pad-inline-sm: var(--space-4);
  --btn-radius: var(--radius-input);

  --input-height: 48px;
  --input-radius: var(--radius-input);
  --input-pad-inline: var(--space-4);
  --input-border: 1px solid var(--color-border-strong);
  --input-bg: var(--white);
  --textarea-min-height: 120px;

  /* ---- Combobox (searchable select) — NEW (IT7) ---- */
  --combobox-popover-offset: var(--space-1);
  --combobox-popover-maxh: min(320px, 40vh);
  --combobox-option-minh: var(--touch-min);
  /* design.md Touch-target rules: "the chip removable-x AND the combobox clear-x are 24px
     glyph hit-areas" — a documented exception value, not derived from another token. */
  --combobox-clear-size: 24px;

  /* ---- Mobile contact bar (S4, < bp-lg) — REWORKED (IT7): fixed, self-hiding ---- */
  --mcbar-pad-block: var(--space-3);
  --mcbar-safe-area-block-end: max(var(--space-3), env(safe-area-inset-bottom));

  --chip-height: 34px;
  --chip-radius: var(--radius-chip);
  --chip-pad-inline: var(--space-3);

  --card-radius: var(--radius-card);
  --card-pad: var(--space-4);
  --card-bg: var(--color-card);
  --card-border: 1px solid var(--color-border);
  --card-shadow: var(--shadow-card);

  /* ---- Listing list-row (S2 list view) — design.md Components "Listing list-row" (IT9 spec,
     shipped IT9-FE) — the two thumbnail widths the row's @container tiers switch between.
     The 320px/560px tier BOUNDARIES themselves stay literal pixels inside
     ListingListRow.module.css's own `@container` rules (same constraint as the breakpoints
     note below: `@container`, like `@media`, cannot read a custom property in its condition). */
  --listrow-thumb-compact: 112px;
  --listrow-thumb-comfortable: 148px;

  --badge-height: 24px;
  --badge-radius: var(--radius-full);
  --badge-pad-inline: var(--space-2);

  --tab-height: 44px;

  /* ---- Data table (admin) — design.md Components "Data table (admin)" ---- */
  --table-row-height: 56px;

  --modal-radius: var(--radius-lg);
  --modal-max-width: 560px;
  --modal-pad: var(--space-6);
  --modal-shadow: var(--shadow-lg);
  /* IT10-FE wave-2 fix, found via this slice's own AR render evidence (the confirm-deletion
     modal's scrim rendered fully transparent): design.md Modals "modal-scrim: color-scrim - the
     single scrim value, shared with drawers/overlays" was never actually added here — Dialog.tsx/
     Dialog.module.css already referenced `var(--modal-scrim)`, but with no definition anywhere in
     this file the declaration silently resolved to nothing (an invalid custom-property reference
     with no fallback is simply dropped, not an error), so every Dialog (this one, S16's
     reject-reason modal, S10's delete-confirm) has been opening with an invisible scrim since
     Dialog.tsx was first built. A direct alias of the existing --color-scrim primitive — no new
     visual value invented. */
  --modal-scrim: var(--color-scrim);

  --toast-max-width: 360px;
  --toast-radius: var(--radius-input);
  --toast-shadow: var(--shadow-md);
  --toast-pad: var(--space-4);

  --avatar-sm: 32px;
  --avatar-md: 40px;
  --avatar-lg: 48px;

  --skeleton-base: var(--color-surface-2);
  --skeleton-shimmer: var(--gray-300);

  --spinner-size-sm: 20px;
  --spinner-size-md: 24px;
  --spinner-size-lg: 40px;
  --spinner-track: color-mix(in srgb, currentColor 25%, transparent);

  /* ============================= Product-specific ============================= */
  --watermark-color: var(--color-watermark);
  --watermark-ink: var(--color-watermark-ink);
  --watermark-inset: var(--space-3);

  /* docs/10-iteration-5-audit.md D8: --map-approx-fill/-stroke/-radius-m pruned (dead — the
     old Leaflet dashed-circle overlay; the Google embed + MapLibre replaced it in IT4). */

  --shield-bg: var(--color-info-soft);
  --shield-border-width: 3px;
  --shield-radius: var(--radius-input);

  --private-panel-bg: var(--color-warning-soft);
  --private-panel-radius: var(--radius-input);

  /* ============================= Iconography ============================= */
  --icon-size-sm: 16px;
  --icon-size-default: 20px;
  --icon-size-lg: 24px;
  --icon-stroke: 1.75px;
}

/* RTL: swap the body font stack; Arabic gets its own leading/tracking (design.md Type). */
[dir='rtl'] {
  --font-body: var(--font-arabic);
}

/* Breakpoints (design.md): bp-sm 640 / bp-md 768 / bp-lg 1024 / bp-xl 1280.
   CSS custom properties cannot be used inside @media conditions, so these values are
   duplicated as literals in each component's @media queries and mirrored in
   src/lib/breakpoints.ts for the rare JS media check (filter drawer vs. rail). Keep both
   in sync with design.md if it ever changes. */


/**
 * Server-rendered blog stylesheet — design.md "Blog (server-rendered)" section, ADR 013 D5.
 * Concatenated with tokens.css (and NOTHING else — global.css is NOT part of this bundle) into
 * `dist/blog.css` by `scripts/build-blog-css.mjs`, linked by the server templates as
 * `/blog.css?v={BUILD_ID}`. ONE token source: every color/size/radius/shadow/duration below is a
 * `var(--*)` from tokens.css — the only literals are @media breakpoint px values (a documented
 * CSS custom-property limitation) and the two `ch` measures.
 *
 * These pages have NO client JS (ADR 013 D5) — no skeleton, no scroll-reveal, no
 * IntersectionObserver, no `.container`/`.skeleton`/`.icon-directional` (unused here).
 */

/* ---- Base layer restated from global.css (NOT concatenated into dist/blog.css) — copied
   verbatim, not re-derived (design.md instruction). ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  -webkit-font-smoothing: antialiased;
}

html[lang='ar'] body {
  line-height: 1.7;
  letter-spacing: 0;
}
html[lang='ar'] h1,
html[lang='ar'] h2,
html[lang='ar'] h3 {
  line-height: 1.4;
}

h1,
h2,
h3,
p,
figure,
blockquote {
  margin: 0;
}

img {
  display: block;
  max-inline-size: 100%;
}

a {
  color: var(--color-link);
}

:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-xs);
}

bdi[dir='ltr'] {
  unicode-bidi: isolate;
  font-variant-numeric: tabular-nums;
}

.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
a.sr-only:focus-visible {
  position: fixed;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  inline-size: auto;
  block-size: auto;
  padding: var(--space-2) var(--space-4);
  clip: auto;
  overflow: visible;
  white-space: normal;
  background: var(--color-bg);
  color: var(--color-text);
  border-radius: var(--radius-input);
  box-shadow: var(--shadow-focus);
  z-index: var(--z-toast);
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- Fonts (BUILD DEPENDENCY — build-blog-css.mjs copies these woff2 files into dist/fonts/
   from the @fontsource packages already used by the SPA; same families/weights/swap policy). If
   the copy step is ever skipped, the substitution stack below (Inter -> system-ui; Cairo ->
   Tajawal, system-ui) applies and every layout stays stable — all sizing is token-driven. ---- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-latin-400-normal.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/inter-latin-600-normal.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/inter-latin-700-normal.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/cairo-arabic-400-normal.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1, U+08E3-08FF, U+FB50-FDFF,
    U+FE70-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EFD-10EFF, U+1EC70-1ECB4, U+1ED00-1ED3D,
    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: 'Cairo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/cairo-arabic-600-normal.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC;
}
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/cairo-arabic-700-normal.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFC;
}

/* ---- Long-form type ladder (both languages) — design.md table, reuses existing roles ---- */
.title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  margin-block-end: var(--space-3);
}
html[lang='ar'] .title {
  line-height: 1.4;
}

.meta {
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  line-height: 1.5;
  color: var(--color-text-muted);
  margin-block-end: var(--space-6);
}

.prose {
  overflow-wrap: anywhere;
}
.prose p {
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
  line-height: 1.6;
  color: var(--color-text);
  margin-block-end: var(--space-4);
}
html[lang='ar'] .prose p {
  line-height: 1.7;
}
.prose h2 {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: 1.35;
  color: var(--color-text);
  margin-block-start: var(--space-8);
  margin-block-end: var(--space-3);
}
.prose h3 {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: 1.4;
  color: var(--color-text);
  margin-block-start: var(--space-6);
  margin-block-end: var(--space-2);
}
html[lang='ar'] .prose h2,
html[lang='ar'] .prose h3 {
  line-height: 1.4;
}
.prose ul,
.prose ol {
  font-size: var(--text-base);
  line-height: 1.6;
  margin-block-end: var(--space-4);
  padding-inline-start: var(--space-6);
}
html[lang='ar'] .prose ul,
html[lang='ar'] .prose ol {
  line-height: 1.7;
}
.prose ul {
  list-style: disc;
}
.prose ol {
  list-style: decimal;
}
.prose li {
  margin-block-end: var(--space-2);
}
.prose blockquote {
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-text-muted);
  margin-block: var(--space-6);
  border-inline-start: 3px solid var(--color-border-strong);
  padding-inline-start: var(--space-4);
}
html[lang='ar'] .prose blockquote {
  line-height: 1.7;
}
.prose a {
  color: var(--color-link);
  text-decoration: underline;
}
.prose a:hover {
  color: var(--color-primary-hover);
}
.prose strong {
  font-weight: var(--weight-semibold);
}
.prose em {
  font-style: italic;
}
/* Cairo has no true italic — a synthetic oblique distorts joining. Arabic emphasis is weight,
   never italic (design.md). */
html[lang='ar'] .prose em {
  font-style: normal;
  font-weight: var(--weight-semibold);
}

.cover {
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  border-radius: var(--radius-card);
  inline-size: 100%;
  margin-block-end: var(--space-6);
}

.disclaimer {
  background: var(--color-info-soft);
  border-inline-start: 3px solid var(--color-info);
  border-radius: var(--radius-input);
  font-size: var(--text-sm);
  padding: var(--space-4);
  margin-block-start: var(--space-8);
}

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  block-size: var(--btn-height-md);
  padding-inline: var(--btn-pad-inline);
  border-radius: var(--btn-radius);
  background: var(--color-primary);
  color: var(--color-text-inverse);
  text-decoration: none;
  white-space: nowrap;
  margin-block-start: var(--space-6);
}

.ctaSecondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  block-size: var(--btn-height-md);
  padding-inline: var(--btn-pad-inline);
  border-radius: var(--btn-radius);
  background: #fff;
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  text-decoration: none;
  white-space: nowrap;
}

/* ---- Breadcrumb ---- */
.breadcrumb {
  display: flex;
  align-items: center;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-block-end: var(--space-4);
}
.breadcrumb a {
  color: var(--color-link);
}
.breadcrumbSep {
  color: var(--color-text-subtle);
  margin-inline: var(--space-2);
}

/* ---- Article measure ---- */
.article {
  max-inline-size: min(72ch, 100%);
  margin-inline: auto;
}
html[lang='ar'] .article {
  max-inline-size: min(65ch, 100%);
}

/* ---- Index page ---- */
.indexHeading {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  margin-block-end: var(--space-3);
}
html[lang='ar'] .indexHeading {
  line-height: 1.4;
}
.indexIntro {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  line-height: 1.6;
  margin-block-end: var(--space-8);
}
html[lang='ar'] .indexIntro {
  line-height: 1.7;
}

.indexContainer {
  max-inline-size: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}
@media (min-width: 1024px) {
  .indexContainer {
    padding-inline: var(--space-8);
  }
}

.cardGrid {
  display: grid;
  gap: var(--grid-gutter);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .cardGrid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .cardGrid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-decoration: none;
  color: inherit;
  block-size: 100%;
  background: var(--card-bg);
  border: var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--card-pad);
  box-shadow: var(--card-shadow);
}
@media (hover: hover) {
  .card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
    transition:
      box-shadow var(--duration-fast) var(--easing-standard),
      transform var(--duration-fast) var(--easing-standard);
  }
}

.cardTitle {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: 1.4;
  color: var(--color-text);
  margin-block-end: var(--space-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cardExcerpt {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: 1.5;
  margin-block-end: var(--space-3);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cardDate {
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  margin-block-start: auto;
}

/* ---- Pagination ---- */
.pagination {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-block-start: var(--space-8);
}
.paginationLink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  block-size: var(--btn-height-md);
  padding-inline: var(--btn-pad-inline);
  border-radius: var(--btn-radius);
  background: #fff;
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  text-decoration: none;
}
.paginationStatus {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ---- Reduced header ---- */
.header {
  min-block-size: 64px;
  background: var(--color-bg);
  border-block-end: 1px solid var(--color-border);
}
.headerInner {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-block: var(--space-2);
  padding-inline: var(--space-4);
  max-inline-size: 1200px;
  margin-inline: auto;
}
@media (min-width: 1024px) {
  .headerInner {
    padding-inline: var(--space-8);
  }
}
.wordmark {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--color-primary);
  text-decoration: none;
}
.headerNav {
  display: flex;
  gap: var(--space-4);
  margin-inline-start: auto;
  flex-wrap: wrap;
}
.headerNavLink {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--touch-min);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  text-decoration: none;
}
.headerNavLink:hover,
.headerNavLink[aria-current='page'] {
  color: var(--color-primary);
}
.langToggle {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--touch-min);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  text-decoration: none;
  /* Review finding #9 nit (cycle 1): `.headerInner` is `flex-wrap: wrap`, and only `.headerNav`
     (the sibling BEFORE this one) had `margin-inline-start: auto`. On a wide line that pushes
     both `.headerNav` and `.langToggle` flush to the far end together (fine at 1280px) — but once
     `.headerInner` wraps at narrow widths (390px), `.langToggle` can land on its OWN flex line,
     where the PREVIOUS sibling's auto-margin no longer applies (each wrapped line resolves
     `margin:auto` independently) — it fell back to the line's start edge, orphaned. Giving
     `.langToggle` its own `margin-inline-start: auto` keeps it flush to the far end of whichever
     line it ends up on, wrapped or not. */
  margin-inline-start: auto;
}

/* ---- Reduced footer ---- */
.footer {
  margin-block-start: var(--space-12);
  border-block-start: 1px solid var(--color-border);
  padding-block: var(--space-8);
  padding-inline: var(--space-4);
}
@media (min-width: 1024px) {
  .footer {
    padding-inline: var(--space-8);
  }
}
.footerInner {
  max-inline-size: 1200px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
@media (min-width: 768px) {
  .footerInner {
    flex-direction: row;
    justify-content: space-between;
  }
}
.footerCopyright {
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
}
.footerLinks {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.footerLink {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--touch-min);
  font-size: var(--text-sm);
  color: var(--color-link);
  text-decoration: none;
}

/* ---- Empty / error / not-found centered block (states) ---- */
.stateBlock {
  max-inline-size: min(72ch, 100%);
  margin-inline: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--space-12) var(--space-6);
  text-align: center;
}
.stateIcon {
  color: var(--color-text-subtle);
  margin-inline: auto;
  margin-block-end: var(--space-4);
}
.stateTitle {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
}
.stateBody {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  margin-block-start: var(--space-2);
}
.stateActions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
  margin-block-start: var(--space-6);
}

/* ---- <main> block padding (both pages) ---- */
.main {
  padding-block-start: var(--space-8);
  padding-block-end: var(--space-12);
  padding-inline: var(--space-4);
}
@media (min-width: 1024px) {
  .main {
    padding-inline: var(--space-8);
  }
}

