/* Blackhorse Real Estate — design tokens as CSS custom properties.

   GENERATED by site/tools/build-tokens.mjs from assets/tokens.json.
   Do not edit this file. Edit assets/tokens.json and rerun the script.

   Source version 1.0.0, updated 2026-08-20.

   The one rule that breaks this brand fastest: gold #C9A14C on white measures
   2.4:1 and fails every threshold. Gold is for dark backgrounds, large
   type and non-text elements. Small gold-toned text on light uses --bh-accent-on-light.
*/

:root {
  /* The palette is a light one. Without this, a phone in dark mode
     re-tints the whole page and the native controls come from the other set. */
  color-scheme: light;
  /* ---- Core palette ---- */
  --bh-black: #1A1A1A;
  --bh-gold: #C9A14C;
  --bh-bronze: #A67C2E;
  --bh-cream: #F7F1E3;

  /* ---- Extended ---- */
  --bh-ink: #0F0F0F;
  --bh-gold-deep: #8B6A24;  /* small text / links on LIGHT bg — 5.0:1 */
  --bh-gold-light: #E0C078;  /* hover on dark */
  --bh-gold-tint: #F5EBD6;  /* row highlight, soft fill */
  --bh-graphite: #3A3A3A;
  --bh-slate: #6E6E6E;
  --bh-hairline: #DCD6C8;  /* rules on light */
  --bh-hairline-dk: #2E2E2E;  /* rules on dark */
  --bh-white: #FFFFFF;

  /* ---- Semantic ---- */
  --bh-positive: #2E7D5B;
  --bh-negative: #B3261E;
  --bh-warning: #B7791F;
  --bh-info: #2C5F7C;

  /* ---- Charts ---- */
  --bh-chart-1: #C9A14C;
  --bh-chart-2: #3A3A3A;
  --bh-chart-3: #A67C2E;
  --bh-chart-4: #E0C078;
  --bh-chart-5: #6E6E6E;
  --bh-gridline: #DCD6C8;

  /* ---- Surfaces & roles ---- */
  --bh-surface: var(--bh-white);
  --bh-surface-muted: var(--bh-cream);
  --bh-surface-dark: var(--bh-black);
  --bh-surface-sunk: var(--bh-gold-tint);
  --bh-text: var(--bh-black);  /* on white 17.4:1 */
  --bh-text-secondary: var(--bh-graphite);
  --bh-text-muted: var(--bh-slate);
  --bh-text-on-dark: var(--bh-cream);
  --bh-accent-on-dark: var(--bh-gold);  /* 7.2:1 — gold's only correct home */
  --bh-accent-on-light: var(--bh-gold-deep);  /* 5:1 — AA */
  --bh-border: var(--bh-hairline);
  --bh-border-strong: var(--bh-slate);
  --bh-border-dark: var(--bh-hairline-dk);
  --bh-link: var(--bh-gold-deep);  /* never --bh-gold: gold on white is 2.4:1 */
  --bh-focus: var(--bh-gold-deep);
  --bh-on-accent: var(--bh-black);  /* gold buttons take BLACK text; white on gold is 2.2:1 */

  /* ---- Site-scoped — not from tokens.json ---- */
  --bh-print-ink: #000000;  /* pure black on paper — never --bh-black, which prints grey */
  --bh-print-rule: #999999;  /* rules on paper — non-text only, 2.9:1 */
  --bh-print-muted: #444444;  /* print secondary text — 9.7:1 on paper */
  --bh-ghost-border-dk: #5A5A5A;  /* ghost button on dark — lighter than --bh-border-strong on purpose (2.5:1 vs 2.0:1) */
  --bh-ghost-hover-dk: #262626;  /* its hover fill */
  --bh-text-blurb-dk: #B9B9B9;  /* footer blurb on black — 8.9:1 */
  /* One duration and one curve for the mobile menu, so the panel, the links
     and the icon cannot drift out of step with each other. */
  --bh-menu-ms: 280ms;
  --bh-menu-ease: cubic-bezier(0.4, 0, 0.2, 1);

  --bh-fs-badge: 10px;  /* the shortlist count only; one step below --bh-fs-micro */

  /* ---- Type families ---- */
  --bh-font-latin: Inter, 'Inter Fallback', 'Helvetica Neue', Arial, sans-serif;
  --bh-font-ar: 'IBM Plex Sans Arabic', 'Plex Arabic Fallback', 'Noto Sans Arabic', Tahoma, sans-serif;
  --bh-font-mono: 'SF Mono', ui-monospace, Menlo, monospace;
  --bh-font: var(--bh-font-latin);  /* flipped to the Arabic stack under [dir="rtl"] */

  /* ---- Type scale ---- */
  --bh-fs-display: 40px;
  --bh-fs-h1: 30px;
  --bh-fs-h2: 22px;
  --bh-fs-h3: 17px;
  --bh-fs-body-lg: 16px;
  --bh-fs-body: 14.5px;
  --bh-fs-small: 13px;
  --bh-fs-micro: 11px;

  /* ---- Weights, leading, tracking ---- */
  --bh-fw-regular: 400;
  --bh-fw-semibold: 600;
  --bh-fw-bold: 700;
  --bh-lh-heading: 1.25;
  --bh-lh-body: 1.5;
  --bh-lh-arabic: 1.35;
  --bh-lh-arabic-prose: 1.8;  /* BRAND.md floors Arabic at 1.35; running prose wants 1.7-1.9 */
  --bh-ls-caps: 0.08em;  /* Latin all-caps labels ONLY — never Arabic */
  --bh-fs-body-ar: 15.5px;  /* Arabic reads smaller at the same px */

  /* ---- Spacing (8px base) ---- */
  --bh-space-1: 4px;
  --bh-space-2: 8px;
  --bh-space-3: 12px;
  --bh-space-4: 16px;
  --bh-space-5: 20px;  /* form rhythm: 16 is tight under a label, 24 is loose */
  --bh-space-6: 24px;
  --bh-space-8: 32px;
  --bh-space-12: 48px;
  --bh-space-16: 64px;
  --bh-space-24: 96px;

  /* ---- Radius & elevation ---- */
  --bh-radius-none: 0;
  --bh-radius-sm: 4px;
  --bh-radius-md: 8px;
  --bh-radius-full: 999px;
  --bh-shadow: 0 1px 3px rgba(26,26,26,0.10);  /* the only permitted elevation */

  /* ---- Logo ---- */
  --bh-logo-aspect: 2.5497;  /* 923x362 measured from assets/logo-trimmed.png — NOT tokens.json's 1.207 */
  --bh-logo-min-w: 120px;
  --bh-logo-clear: calc(var(--bh-logo-h, 32px) * 0.125);
}

/* Dark sections. Gold becomes usable as text here (7.2:1). */
.bh-dark, .section--dark, .footer {
  --bh-surface: var(--bh-black);
  --bh-surface-muted: #232323;
  --bh-surface-sunk: #232323;
  --bh-text: var(--bh-cream);
  --bh-text-secondary: #C4C4C4;
  --bh-text-muted: #9A9A9A;
  --bh-border: var(--bh-hairline-dk);
  --bh-border-strong: #4A4A4A;
  --bh-link: var(--bh-gold);
  --bh-focus: var(--bh-gold);
  --bh-accent-on-light: var(--bh-gold);
  color: var(--bh-text);
  background: var(--bh-surface);
}

/* Arabic. Set once on <html dir="rtl">; every logical property does the rest. */
[dir="rtl"] {
  --bh-font: var(--bh-font-ar);
  --bh-fs-body: var(--bh-fs-body-ar);
  --bh-lh-body: var(--bh-lh-arabic-prose);
}


/* Blackhorse — self-hosted web fonts.
   Generated by site/tools/fetch-fonts.mjs. Do not edit by hand.
   Subsets come straight from Google Fonts' per-unicode-range woff2 files, so
   an Arabic page never downloads Latin glyphs it will not draw, and vice versa.
   Total 172.3 KB across 5 files. No CDN at runtime. */

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/plex-ar-arabic-400.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/plex-ar-latin-400.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/plex-ar-arabic-600.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/plex-ar-latin-600.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: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-latin-var.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;
}

/* ---- Metric-matched fallbacks ------------------------------------------
   font-display: swap paints text in the fallback face first, then swaps.
   Without these, the swap reflows the page (the Arabic hero reflowed twice on
   4G in the audit's waterfall). Overriding the fallback's vertical metrics to
   the webfont's makes the swap near shift-free. Values are read from the
   shipped woff2 files by tools/fetch-fonts.mjs, not typed in.

   size-adjust is left at 100% for the Arabic fallback: the widths of Noto
   Naskh Arabic UI (Android's default) were not measurable here. Vertical
   metrics are what move the page. */

@font-face {
  font-family: 'Plex Arabic Fallback';
  src: local('Noto Naskh Arabic UI'), local('Noto Naskh Arabic'), local('Geeza Pro'), local('Tahoma');
  ascent-override: 108.50%;
  descent-override: 41.50%;
  line-gap-override: 0.00%;
}

@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial'), local('Roboto'), local('Helvetica Neue');
  ascent-override: 96.88%;
  descent-override: 24.12%;
  line-gap-override: 0.00%;
  size-adjust: 107%;
}


/* Blackhorse Real Estate — the stylesheet.

   Companions: tokens.css (generated from assets/tokens.json — every colour and
   metric comes from there) and fonts.css (generated by tools/fetch-fonts.mjs).

   One sheet serves both directions. Every horizontal property here is logical
   — margin-inline-start, padding-inline, inset-inline-end, text-align: start.
   There is no [dir="rtl"] override for layout anywhere below, and there should
   never need to be. The [dir="rtl"] rules that DO exist are the handful of
   things logical properties cannot express: which glyphs mirror, and the
   typographic habits Arabic does not share with Latin.
*/

/* ===================================================================== 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: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--bh-font);
  font-size: var(--bh-fs-body);
  line-height: var(--bh-lh-body);
  color: var(--bh-text);
  background: var(--bh-surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

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

/* The UA stylesheet gives [hidden] display:none at the lowest specificity, so
   any component that sets its own display silently ignores it. The filters hide
   cards with the attribute, so this has to win. */
[hidden] { display: none !important; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }

table { border-collapse: collapse; width: 100%; }

/* ================================================================ typography */

h1, h2, h3, h4 {
  line-height: var(--bh-lh-heading);
  font-weight: var(--bh-fw-semibold);
  text-wrap: balance;
}
h1 { font-size: clamp(26px, 5.2vw, var(--bh-fs-h1)); }
h2 { font-size: clamp(20px, 4.2vw, var(--bh-fs-h2)); }
h3 { font-size: var(--bh-fs-h3); }
h4 { font-size: var(--bh-fs-body-lg); }

p { text-wrap: pretty; }
p + p { margin-block-start: var(--bh-space-4); }

a { color: var(--bh-link); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

strong, b { font-weight: var(--bh-fw-semibold); }   /* minimal bold — never 700 in prose */

:focus-visible {
  outline: 2px solid var(--bh-focus);
  outline-offset: 2px;
  border-radius: 2px;
}

::selection { background: var(--bh-gold-tint); color: var(--bh-black); }

/* Numbers align in tables and price columns everywhere, both languages. */
table, .num, [data-numeric] { font-variant-numeric: tabular-nums; }

/* Latin all-caps micro-labels. The Arabic override below is not cosmetic:
   letter-spacing severs the joins in an Arabic word and uppercase is
   meaningless in a script that has no case. */
.eyebrow {
  font-size: var(--bh-fs-micro);
  font-weight: var(--bh-fw-semibold);
  letter-spacing: var(--bh-ls-caps);
  text-transform: uppercase;
  color: var(--bh-text-muted);
  margin-block-end: var(--bh-space-2);
}
.bh-dark .eyebrow { color: var(--bh-accent-on-dark); }

.lede { font-size: var(--bh-fs-body-lg); color: var(--bh-text-secondary); }

/* Mixed Arabic/Latin runs — a ref like BH-0142 or a phone number inside an
   Arabic sentence — need isolation or the punctuation jumps sides. */
bdi, .iso { unicode-bidi: isolate; }
.ltr { direction: ltr; unicode-bidi: isolate; }

/* ==================================================================== layout */

.wrap {
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: var(--bh-space-4);
}
@media (min-width: 720px) { .wrap { padding-inline: var(--bh-space-8); } }

.section { padding-block: var(--bh-space-12); }
.section--tight { padding-block: var(--bh-space-8); }
@media (min-width: 720px) { .section { padding-block: var(--bh-space-16); } }

.section--muted { background: var(--bh-surface-muted); }

/* Gold Deep measures 5.0:1 on white but only 4.46:1 on cream — under AA by a
   hair. Rather than invent a darker gold, which BRAND.md forbids, links on a
   cream surface are ink and carry a permanent underline so they still read as
   links without relying on colour alone. The gold accent stays in the rules,
   pills and borders where it is not text. */
.section--muted, .panel, .filters, .plan, .cta, .card__photo--empty {
  --bh-link: var(--bh-black);
}
.section--muted a:not(.btn):not(.listing-card__link):not(.area-card),
.panel a:not(.btn), .plan a:not(.btn), .cta a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--bh-bronze);
}
.section--dark { background: var(--bh-black); }

.rule { border: 0; border-block-start: 1px solid var(--bh-border); margin-block: var(--bh-space-8); }

.stack > * + * { margin-block-start: var(--bh-space-4); }
.stack-6 > * + * { margin-block-start: var(--bh-space-6); }
.stack-8 > * + * { margin-block-start: var(--bh-space-8); }

.grid { display: grid; gap: var(--bh-space-6); }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 640px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 860px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

.cluster { display: flex; flex-wrap: wrap; gap: var(--bh-space-3); align-items: center; }
.between { display: flex; flex-wrap: wrap; gap: var(--bh-space-4); align-items: center; justify-content: space-between; }

.prose { max-width: 68ch; }
.prose h2 { margin-block: var(--bh-space-8) var(--bh-space-3); }
.prose h3 { margin-block: var(--bh-space-6) var(--bh-space-2); }
.prose ul { margin-block: var(--bh-space-4); }
.prose li { padding-inline-start: var(--bh-space-6); position: relative; margin-block-end: var(--bh-space-2); }
.prose li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: .62em;
  width: 6px; height: 1px;
  background: var(--bh-accent-on-light);
}

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

.skip-link {
  position: absolute;
  inset-block-start: -100%;
  inset-inline-start: var(--bh-space-4);
  z-index: 100;
  background: var(--bh-black);
  color: var(--bh-white);
  padding: var(--bh-space-3) var(--bh-space-4);
  border-radius: 0 0 var(--bh-radius-sm) var(--bh-radius-sm);
}
.skip-link:focus { inset-block-start: 0; }

/* =================================================================== buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--bh-space-2);
  min-height: 44px;                       /* touch target */
  padding: var(--bh-space-3) var(--bh-space-6);
  border: 1px solid transparent;
  border-radius: var(--bh-radius-sm);
  font-weight: var(--bh-fw-semibold);
  font-size: var(--bh-fs-body);
  text-align: center;
  text-decoration: none;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn:hover { text-decoration: none; }

.btn--primary { background: var(--bh-black); color: var(--bh-white); }
.btn--primary:hover { background: var(--bh-ink); }

/* Black text on gold. White on gold is 2.2:1 and unreadable. */
.btn--accent { background: var(--bh-gold); color: var(--bh-on-accent); }
.btn--accent:hover { background: var(--bh-gold-light); }

.btn--ghost { color: var(--bh-text); border-color: var(--bh-border-strong); }
.btn--ghost:hover { background: var(--bh-surface-muted); }
.bh-dark .btn--ghost, .section--dark .btn--ghost { color: var(--bh-cream); border-color: var(--bh-ghost-border-dk); }
.bh-dark .btn--ghost:hover, .section--dark .btn--ghost:hover { background: var(--bh-ghost-hover-dk); }

.btn--wide { width: 100%; }
.btn--sm { min-height: 36px; padding: var(--bh-space-2) var(--bh-space-4); font-size: var(--bh-fs-small); }
.btn[disabled], .btn[aria-disabled="true"] { background: var(--bh-hairline); color: var(--bh-slate); cursor: not-allowed; }

/* WhatsApp is the primary CTA in this market, so it earns a colour that is not
   in the brand palette — recognising the app at a glance is the point.

   NOT WhatsApp's own #128C7E: white on it measures 4.14:1 and fails AA. This is
   the same hue darkened until it passes (5.22:1), which reads as WhatsApp and
   is legible. Verified by tools/check.mjs, which fails the build if it drifts. */
.btn--whatsapp { background: #0F7A6D; color: var(--bh-white); }
.btn--whatsapp:hover { background: #0B5F55; }

.btn__icon { width: 18px; height: 18px; flex: none; fill: currentColor; }

/* ===================================================================== forms */

.field { display: block; }
.field + .field { margin-block-start: var(--bh-space-4); }

/* A form lays out on ONE rhythm, set by the form itself.

   The sibling margin above only fires between two adjacent .field elements, so
   every row that followed something else — the Type/Size grid, the
   Selling/Renting toggle, a note — got no space at all and sat flush against
   the control before it. Six of the eleven rows in the valuation form had a
   zero gap; a reader saw a label welded to the field above it.

   A grid with a gap spaces every child the same way whatever it is, so this
   cannot drift again as rows are added. The children's own margins are zeroed
   because .field + .field would otherwise add 16px on top of the gap. */
form[data-form] { display: grid; gap: var(--bh-space-5); align-content: start; }
/* The two notes under the form explain the button, not the field above them,
   so they sit closer to each other than the 20px rhythm. A negative margin is
   the only way to tighten one gap inside a grid, since gap applies to all. */
form[data-form] > .form-note { margin-block-start: -8px; }
form[data-form] > .form-note + .form-note { margin-block-start: -12px; }
/* ...but not when the fields are laid out by a grid or a flex row. There the
   container's own gap does the spacing, and the sibling margin pushed the
   second field down by an extra 16px — which is why Bedrooms sat below Type
   instead of level with it. */
.grid > .field + .field,
.cluster > .field + .field,
.filters__grid > .field + .field,
/* A form is a grid too — and this selector has to be listed HERE rather than
   left to a `form[data-form] > *` reset further down, because that reset is
   specificity (0,1,1) and loses to `.field + .field` at (0,2,0). Adding the
   form to this list makes it (0,2,1), which wins. */
form[data-form] > .field + .field { margin-block-start: 0; }
.field__label {
  display: block;
  font-size: var(--bh-fs-small);
  font-weight: var(--bh-fw-semibold);
  margin-block-end: var(--bh-space-1);
}
.field__hint { display: block; font-size: var(--bh-fs-micro); color: var(--bh-text-muted); margin-block-start: var(--bh-space-1); }
.field__error { display: block; font-size: var(--bh-fs-small); color: var(--bh-negative); margin-block-start: var(--bh-space-1); }

.input, .select, .textarea {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: var(--bh-space-3);
  border: 1px solid var(--bh-border);
  border-radius: var(--bh-radius-sm);
  background: var(--bh-surface);
  color: var(--bh-text);
  text-align: start;
}
.textarea { min-height: 110px; resize: vertical; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--bh-bronze); }
.input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--bh-negative); }

/* Native select arrow sits on the correct side automatically; the only thing
   to fix is the padding we add for it. */
.select {
  appearance: none;
  padding-inline-end: var(--bh-space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%236E6E6E' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--bh-space-3) center;
  background-size: 12px 8px;
}
[dir="rtl"] .select { background-position: left var(--bh-space-3) center; }

/* ===================================================================== cards */

.card {
  background: var(--bh-surface);
  border: 1px solid var(--bh-border);
  border-radius: var(--bh-radius-md);
  overflow: hidden;
}
.card__body { padding: var(--bh-space-4); }
@media (min-width: 720px) { .card__body { padding: var(--bh-space-6); } }

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--bh-space-1);
  padding: 3px var(--bh-space-3);
  border-radius: var(--bh-radius-full);
  font-size: var(--bh-fs-micro);
  font-weight: var(--bh-fw-semibold);
  background: var(--bh-surface-sunk);
  color: var(--bh-graphite);
  white-space: nowrap;
}
/* A pill you can tap is a control and needs a control's target size; the
   status pills on cards are labels and stay as they are. */
a.pill { min-height: 36px; padding-block: var(--bh-space-2); }
.pill--sale   { background: var(--bh-black); color: var(--bh-cream); }
.pill--rent   { background: var(--bh-gold); color: var(--bh-on-accent); }
.pill--closed { background: var(--bh-graphite); color: var(--bh-cream); }

/* ==================================================================== header */

.masthead {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
  background: var(--bh-surface);
  border-block-end: 1px solid var(--bh-border);
}
.masthead__bar {
  display: flex;
  align-items: center;
  gap: var(--bh-space-4);
  min-height: 64px;
}
/* Karim, 8 September 2026: the navigation is centred.

   Three grid columns rather than a flex row, because centring inside a flex
   row only ever centres the nav in the space the logo and the controls leave
   over — it drifts as either changes width, and it drifted differently in
   Arabic. With 1fr auto 1fr the nav column is exactly its own width and the
   two side columns take equal halves of the rest, so the middle of the nav is
   the middle of the page whatever sits beside it.

   Only above 960px, which is the width the nav appears at; below that the bar
   stays the flex row of logo and controls. `1fr` columns can shrink below
   their content, so min-width: 0 on the sides keeps a long Arabic label from
   pushing the nav off centre instead of wrapping. */
@media (min-width: 960px) {
  .masthead__bar {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
  }
  .masthead__bar > .logo { justify-self: start; min-width: 0; }
  .masthead__bar > .nav { justify-self: center; }
  .masthead__bar > .masthead__end { justify-self: end; min-width: 0; }
}

/* The logo is 2.55:1 (923x362 measured). Height is set; width follows from the
   aspect token. Anything sized from tokens.json's 1.207 comes out twice as
   tall as the artwork actually is. */
.logo { display: inline-flex; align-items: center; flex: none; }
/* BRAND.md:41 sets a 120px floor on screen — "below that REAL ESTATE becomes
   unreadable". Sized from the width so the floor is explicit and the height
   follows the measured 2.5497 aspect, rather than the other way round where a
   height tweak silently drops the width under the floor again. */
.logo img {
  width: 120px;
  height: calc(120px / var(--bh-logo-aspect));
}
@media (min-width: 720px) { .logo img { width: 132px; height: calc(132px / var(--bh-logo-aspect)); } }

/* The wordmark is black artwork with no light-on-dark variant, so it only ever
   sits on a light surface. On the dark footer it gets a cream plate. */
.logo--plated {
  background: var(--bh-cream);
  padding: var(--bh-space-2) var(--bh-space-3);
  border-radius: var(--bh-radius-sm);
}

.nav { display: none; }
@media (min-width: 960px) {
  /* margin-inline-start is gone: it was what held the nav beside the logo, and
     it is exactly what would stop the grid centring it. */
  .nav { display: flex; gap: var(--bh-space-6); }
  .nav a {
    color: var(--bh-text);
    font-size: var(--bh-fs-small);
    font-weight: var(--bh-fw-semibold);
    padding-block: var(--bh-space-2);
    border-block-end: 2px solid transparent;
  }
  .nav a:hover { text-decoration: none; border-block-end-color: var(--bh-gold); }
  .nav a[aria-current="page"] { border-block-end-color: var(--bh-black); }
}

/* margin-inline-start: auto still does the work below 960px, where the bar is
   a flex row; inside the grid above it is overridden by justify-self. */
.masthead__end { display: flex; align-items: center; gap: var(--bh-space-2); margin-inline-start: auto; }

.lang-toggle {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding-inline: var(--bh-space-3);
  border: 1px solid var(--bh-border-strong);
  border-radius: var(--bh-radius-sm);
  font-size: var(--bh-fs-small);
  font-weight: var(--bh-fw-semibold);
  color: var(--bh-text);
  white-space: nowrap;
}
.lang-toggle:hover { background: var(--bh-surface-muted); text-decoration: none; }

.menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--bh-border-strong);
  border-radius: var(--bh-radius-sm);
}
@media (min-width: 960px) { .menu-btn { display: none; } }
.menu-btn svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.6; }

/* The menu opens by growing a grid row from 0fr to 1fr. That is the one way
   to animate to a height nobody has measured — max-height needs a guess, and
   a guess that overshoots spends the back half of the transition doing
   nothing visible. The row can only size ONE child, which is what
   .drawer__inner is for.

   display stays grid at every state: display cannot be transitioned, so the
   closed drawer is hidden by a zero row plus visibility, and visibility is
   delayed by the length of the animation so the links do not vanish halfway
   through closing. visibility:hidden also takes them out of the tab order,
   which display:none used to do. */
.drawer {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  opacity: 0;
  /* Width, not colour. A 1px transparent border still occupies 1px of layout,
     and so does the inner padding — measured: the closed drawer was still
     33px tall and pushing the page down. Both collapse to nothing here and
     grow back with the row. */
  border-block-start: 0 solid var(--bh-border);
  transition:
    grid-template-rows var(--bh-menu-ms) var(--bh-menu-ease),
    opacity calc(var(--bh-menu-ms) * 0.6) ease,
    border-block-start-width var(--bh-menu-ms) var(--bh-menu-ease),
    visibility 0s linear var(--bh-menu-ms);
}
.drawer[data-open="true"] {
  grid-template-rows: 1fr;
  visibility: visible;
  opacity: 1;
  border-block-start-width: 1px;
  transition:
    grid-template-rows var(--bh-menu-ms) var(--bh-menu-ease),
    opacity calc(var(--bh-menu-ms) * 0.5) ease,
    border-block-start-width var(--bh-menu-ms) var(--bh-menu-ease),
    visibility 0s;
}
/* min-height:0 lets the row collapse — a grid item refuses to go below its
   content height without it. The padding has to travel too: min-height only
   frees the content box, so 16px top and bottom would survive a 0fr row. */
.drawer__inner {
  min-height: 0;
  overflow: hidden;
  padding-block: 0;
  transition: padding-block var(--bh-menu-ms) var(--bh-menu-ease);
}
.drawer[data-open="true"] .drawer__inner { padding-block: var(--bh-space-4); }
@media (min-width: 960px) { .drawer { display: none !important; } }

.drawer a {
  display: block;
  padding-block: var(--bh-space-3);
  color: var(--bh-text);
  font-weight: var(--bh-fw-semibold);
  border-block-end: 1px solid var(--bh-border);
  /* vertical only, so this reads the same in Arabic */
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 200ms ease, transform 240ms var(--bh-menu-ease);
}
/* The links arrive just behind the panel that carries them, one after the
   next, so the eye follows the list down instead of meeting all of it at
   once. Eight links, and the last is still in under a third of a second. */
.drawer[data-open="true"] a { opacity: 1; transform: none; }
.drawer[data-open="true"] a:nth-child(1) { transition-delay: 40ms; }
.drawer[data-open="true"] a:nth-child(2) { transition-delay: 68ms; }
.drawer[data-open="true"] a:nth-child(3) { transition-delay: 96ms; }
.drawer[data-open="true"] a:nth-child(4) { transition-delay: 124ms; }
.drawer[data-open="true"] a:nth-child(5) { transition-delay: 152ms; }
.drawer[data-open="true"] a:nth-child(6) { transition-delay: 180ms; }
.drawer[data-open="true"] a:nth-child(7) { transition-delay: 208ms; }
.drawer[data-open="true"] a:nth-child(8) { transition-delay: 236ms; }
/* Closing runs the other way with no stagger — a menu should get out of the
   way immediately, and eight delays on the way out feels like lag. */
.drawer a:hover { text-decoration: none; color: var(--bh-accent-on-light); }

/* The three bars fold into a cross. Each rotation happens about the centre of
   the icon, so the two outer bars are first translated onto that centre —
   CSS applies these right to left, so translateY runs first, then rotate. */
.menu-btn svg line {
  transform-box: view-box;
  transform-origin: 12px 12px;
  transition: transform var(--bh-menu-ms) var(--bh-menu-ease),
              opacity calc(var(--bh-menu-ms) * 0.4) ease;
}
.menu-btn[aria-expanded="true"] .menu-btn__t { transform: rotate(45deg) translateY(6px); }
.menu-btn[aria-expanded="true"] .menu-btn__b { transform: rotate(-45deg) translateY(-6px); }
.menu-btn[aria-expanded="true"] .menu-btn__m { opacity: 0; transform: scaleX(0.1); }
.menu-btn { transition: background-color 160ms ease; }
.menu-btn[aria-expanded="true"] { background: var(--bh-surface-muted); }

/* A visitor who has asked for less movement gets the same menu, instantly.
   Nothing here is decorative-only, so the states still change — they just
   stop travelling. */
@media (prefers-reduced-motion: reduce) {
  .drawer, .drawer__inner, .drawer a, .menu-btn svg line, .menu-btn {
    transition-duration: 1ms !important;
    transition-delay: 0s !important;
  }
  .drawer a { transform: none; }
}

/* ==================================================================== footer */

/* D2 proof. Two of the three figures are computed at build time from data/,
   so a visitor can check them against the site they are on. The third comes
   from Karim's tracker and does not render unless it is supplied. */
.proof {
  display: flex; flex-wrap: wrap; gap: var(--bh-space-8);
  list-style: none; margin: var(--bh-space-6) 0 0; padding: 0;
}
.proof li { flex: 1 1 12rem; }
.proof__n {
  display: block;
  font-size: var(--bh-fs-display); font-weight: var(--bh-fw-bold);
  line-height: 1.05; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.proof__l { display: block; color: var(--bh-text-muted); font-size: var(--bh-fs-small); margin-block-start: var(--bh-space-1); }
.proof__note { color: var(--bh-text-muted); font-size: var(--bh-fs-small); margin-block-start: var(--bh-space-4); }

/* The coverage page is a directory of 36 compounds. Compact cards drop the
   description and the "read more" line and carry what a visitor is actually
   looking for — who built it and what we have there — so the page reads as a
   list rather than 36 paragraphs. */
.area-card--compact .card__body { padding-block: var(--bh-space-4); }
.area-card--compact h3 { font-size: var(--bh-fs-h3); margin: 0; }
.area-card--compact .area-card__dev { margin-block: var(--bh-space-1) 0; }
.area-card__stock {
  margin-block-start: var(--bh-space-2);
  font-size: var(--bh-fs-small);
  color: var(--bh-text-muted);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 640px) { .area-grid--compact { gap: var(--bh-space-4); } }

.footer { background: var(--bh-black); padding-block: var(--bh-space-12) var(--bh-space-8); }
.footer a { color: var(--bh-cream); }
.footer a:hover { color: var(--bh-gold); }
.footer h2 {
  font-size: var(--bh-fs-micro);
  letter-spacing: var(--bh-ls-caps);
  text-transform: uppercase;
  color: var(--bh-gold);
  margin-block-end: var(--bh-space-3);
}
.footer li { margin-block-end: var(--bh-space-2); font-size: var(--bh-fs-small); }
.footer__base {
  margin-block-start: var(--bh-space-8);
  padding-block-start: var(--bh-space-6);
  border-block-start: 1px solid var(--bh-hairline-dk);
  font-size: var(--bh-fs-micro);
  color: var(--bh-text-muted);
}

/* ===================================================== direction-only rules */

/* Everything below exists because a logical property cannot express it. */

/* Arrows and chevrons point along the reading direction, so they flip.
   Logos, phone numbers, Latin brand names and numerals never do. */
[dir="rtl"] .flip { transform: scaleX(-1); }

/* Latin typographic habits that are wrong in Arabic: letter-spacing severs the
   joins between letters, and there is no upper case to transform to. */
[dir="rtl"] .eyebrow,
[dir="rtl"] .footer h2 {
  letter-spacing: 0;
  text-transform: none;
  font-size: var(--bh-fs-small);
}

/* Arabic is never justified — CSS justification opens word gaps rather than
   stretching letterforms the way real kashida typesetting would. */
[dir="rtl"] p, [dir="rtl"] li, [dir="rtl"] td, [dir="rtl"] th { text-align: start; }

/* Headings carry a little more leading in Arabic; ascenders and the dots below
   ba/ya collide at Latin metrics. */
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4 { line-height: 1.45; }

/* Arabic at the same px reads smaller. Nudge the headline scale, not the body
   (the body comes from --bh-fs-body-ar in tokens.css). */
[dir="rtl"] h1 { font-size: clamp(27px, 5.4vw, 32px); }
[dir="rtl"] h2 { font-size: clamp(21px, 4.4vw, 24px); }

/* ===================================================================== print */

@media print {
  .masthead, .footer, .drawer, .no-print { display: none !important; }
  body { font-size: 10.5pt; line-height: 1.45; color: var(--bh-print-ink); background: var(--bh-white); }
  a { color: var(--bh-print-ink); text-decoration: none; }
  .section { padding-block: 0; }
  .card { border: 1px solid var(--bh-print-rule); break-inside: avoid; }
}

/* ====================================================================== hero */

.hero { padding-block: var(--bh-space-8) var(--bh-space-12); background: var(--bh-surface); }
@media (min-width: 860px) { .hero { padding-block: var(--bh-space-16); } }

/* E4, reversed on 8 September 2026.

   The audit put the search panel first on a phone, because what the hero
   carried then was a long argument aimed at owners and a visitor met a wall of
   text before anything they could use. The hero now carries the firm's line —
   three words as the headline and two sentences under it — and Karim asked for
   that line to be the main title. A title a phone cannot see until it has
   scrolled past a form is not the main title, so the copy goes back on top.
   The search panel is directly beneath it and still above the fold on a
   390px screen. Order only: the DOM has always been copy-then-panel, which is
   the right reading order for a screen reader and the right source order for a
   crawler, and above 860px the two sit side by side either way. */
.hero__grid { display: grid; gap: var(--bh-space-8); align-items: start; }
@media (min-width: 860px) {
  .hero__grid { grid-template-columns: 1.15fr .85fr; gap: var(--bh-space-16); }
}

.hero__copy .lede { margin-block-start: var(--bh-space-4); max-width: 54ch; }
.hero__cta { margin-block-start: var(--bh-space-6); }
/* Once the two hero buttons stack, their right edges no longer line up —
   "Message on WhatsApp" is half as wide again as "View all properties", and a
   ragged pair of blocks is the first thing a phone sees. Below 560px they take
   the full column, so the edges agree with the headline above them. Side by
   side above that, where the ragged edge is what a row of buttons is. */
@media (max-width: 559px) {
  .hero__cta { display: grid; gap: var(--bh-space-3); }
  .hero__cta > .btn { width: 100%; }
}
.hero__search-title { font-size: var(--bh-fs-h3); margin-block-end: var(--bh-space-2); }
.hero__search { box-shadow: var(--bh-shadow); }

.segmented { display: flex; border: 1px solid var(--bh-border); border-radius: var(--bh-radius-sm); overflow: hidden; padding: 0; margin: 0; }
.segmented label { flex: 1; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block;
  padding-block: var(--bh-space-3);
  text-align: center;
  font-size: var(--bh-fs-small);
  font-weight: var(--bh-fw-semibold);
  cursor: pointer;
}
.segmented label + label span { border-inline-start: 1px solid var(--bh-border); }
.segmented input:checked + span { background: var(--bh-black); color: var(--bh-white); }
.segmented input:focus-visible + span { outline: 2px solid var(--bh-focus); outline-offset: -2px; }

/* ================================================================ home bits */

.area-card { display: block; color: inherit; transition: border-color .15s ease; }
.area-card:hover { text-decoration: none; border-color: var(--bh-gold); }
.area-card h3 { margin-block-end: var(--bh-space-2); }
.area-card p { color: var(--bh-text-secondary); }
.area-card__more {
  display: inline-flex;
  gap: var(--bh-space-2);
  margin-block-start: var(--bh-space-4);
  font-size: var(--bh-fs-small);
  font-weight: var(--bh-fw-semibold);
  color: var(--bh-accent-on-light);
}
.area-card:hover .area-card__more { text-decoration: underline; text-underline-offset: 3px; }

.pitch { padding-block-start: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.pitch h3 { margin-block-end: var(--bh-space-2); font-size: var(--bh-fs-body-lg); }
.pitch p { color: var(--bh-text-secondary); font-size: var(--bh-fs-body); }

.cta__inner { display: grid; gap: var(--bh-space-6); align-items: center; }
@media (min-width: 860px) { .cta__inner { grid-template-columns: 1.4fr auto; gap: var(--bh-space-12); } }
.cta { background: var(--bh-surface-sunk); }
.cta .lede { margin-block-start: var(--bh-space-2); max-width: 56ch; }

.footer__blurb { margin-block-start: var(--bh-space-4); font-size: var(--bh-fs-small); color: var(--bh-text-blurb-dk); max-width: 34ch; }
.footer .logo img { width: 120px; height: calc(120px / var(--bh-logo-aspect)); }

/* A region the build script fills. Visible on purpose: a silently empty strip
   on a live page is worse than an obvious note on a page nobody has built yet. */
.placeholder-note {
  margin-block-start: var(--bh-space-6);
  padding: var(--bh-space-4);
  border: 1px dashed var(--bh-border-strong);
  border-radius: var(--bh-radius-sm);
  font-size: var(--bh-fs-small);
  color: var(--bh-text-muted);
}

/* =============================================================== utilities */
/* A short, closed set — enough to keep inline style attributes out of the
   markup so the Content-Security-Policy can forbid them outright. */
.gap-3   { gap: var(--bh-space-3); }
.mt-8    { margin-block-start: var(--bh-space-8); }
.mt-6    { margin-block-start: var(--bh-space-6); }
.measure { max-width: 60ch; }

/* ============================================================ listing card */

.listing-card { display: flex; flex-direction: column; }
.listing-card__link { display: flex; flex-direction: column; flex: 1; color: inherit; }
.listing-card__link:hover { text-decoration: none; }
.listing-card__link:hover .listing-card__title { text-decoration: underline; text-underline-offset: 3px; }

.listing-card__media { position: relative; }

.card__photo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--bh-surface-muted);
}

/* No photograph yet. The panel holds the exact box the image will, so nothing
   on the page moves when real photos arrive. */
.card__photo--empty {
  display: grid;
  place-items: center;
  background: var(--bh-surface-muted);
  border-block-end: 1px solid var(--bh-border);
  color: var(--bh-text-muted);
  font-size: var(--bh-fs-small);
  text-align: center;
  padding: var(--bh-space-4);
}

.listing-card__status {
  position: absolute;
  inset-block-start: var(--bh-space-3);
  inset-inline-start: var(--bh-space-3);
}

.listing-card__body { padding: var(--bh-space-4); flex: 1; display: flex; flex-direction: column; }
/* Two lines, so every card in a row breaks at the same place and the price
   below it lands on one line. */
.listing-card__title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.listing-card__place {
  font-size: var(--bh-fs-micro);
  color: var(--bh-text-muted);
  margin-block-end: var(--bh-space-1);
}
.listing-card__title {
  font-size: var(--bh-fs-body-lg);
  font-weight: var(--bh-fw-semibold);
  margin-block-end: var(--bh-space-2);
}
.listing-card__price {
  font-size: var(--bh-fs-body-lg);
  font-weight: var(--bh-fw-semibold);
  color: var(--bh-text);
}
.listing-card__specs { font-size: var(--bh-fs-small); color: var(--bh-text-secondary); margin-block-start: var(--bh-space-1); }

.listing-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bh-space-3);
  padding: var(--bh-space-3) var(--bh-space-4);
  border-block-start: 1px solid var(--bh-border);
}
.listing-card__ref { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); font-variant-numeric: tabular-nums; }

.save-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--bh-space-2);
  min-height: 36px;
  padding-inline: var(--bh-space-2);
  font-size: var(--bh-fs-small);
  font-weight: var(--bh-fw-semibold);
  color: var(--bh-text-secondary);
  border-radius: var(--bh-radius-sm);
}
.save-btn svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.save-btn:hover { color: var(--bh-accent-on-light); }
.save-btn[aria-pressed="true"] { color: var(--bh-accent-on-light); }
.save-btn[aria-pressed="true"] svg { fill: currentColor; }

/* ============================================================ closed strip */

.closed-strip { display: grid; gap: var(--bh-space-4); }
@media (min-width: 640px) { .closed-strip { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .closed-strip { grid-template-columns: repeat(3, 1fr); } }

.closed-card { padding-block: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.closed-card__title { font-size: var(--bh-fs-body); margin-block: var(--bh-space-2) var(--bh-space-1); }
.closed-card__specs { font-size: var(--bh-fs-small); color: var(--bh-text-secondary); }
.closed-card__date { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); margin-block-start: var(--bh-space-1); }

.empty-note { margin-block-start: var(--bh-space-6); color: var(--bh-text-muted); }

/* =========================================================== listing page */

.listing-page { padding-block: var(--bh-space-6) var(--bh-space-12); }

.crumbs { display: flex; flex-wrap: wrap; gap: var(--bh-space-2); font-size: var(--bh-fs-small); color: var(--bh-text-muted); margin-block-end: var(--bh-space-6); }
.crumbs a { color: var(--bh-text-secondary); }

.listing-page__grid { display: grid; gap: var(--bh-space-8); align-items: start; }
/* The summary — h1, price, WhatsApp — is first in the source so a reader meets
   the property before its sections, and so the reading order matches what a
   phone shows. On a wide screen it belongs in the right-hand column, which is
   placement, not order. */
@media (min-width: 960px) {
  .listing-page__grid { grid-template-columns: 1fr 340px; gap: var(--bh-space-10); }
  .listing-page__aside { grid-column: 2; grid-row: 1; }
  .listing-page__main  { grid-column: 1; grid-row: 1; }
}

/* One photo at a time on a scroll-snap rail: swipe on a phone, arrows on a
   desktop, and with no JavaScript still a horizontal strip that scrolls. The
   rail is the scroller, so nothing here depends on direction — RTL works
   because the browser lays the strip out the other way round by itself. */
.gallery { position: relative; margin: 0; }
.gallery__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: var(--bh-space-2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  border-radius: var(--bh-radius-md);
  scrollbar-width: none;
}
.gallery__rail::-webkit-scrollbar { display: none; }
.gallery__rail:focus-visible { outline: 2px solid var(--bh-focus); outline-offset: 3px; }
.gallery__img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--bh-radius-md);
  scroll-snap-align: center;
  scroll-snap-stop: always;
  /* A photo that has not arrived yet shows this rather than a white hole —
     the frame keeps its shape and the eye has nothing to jump to. */
  background: var(--bh-surface-muted);
}
.gallery__nav {
  position: absolute; inset-block-start: 50%; transform: translateY(-50%);
  display: grid; place-items: center;
  inline-size: 44px; block-size: 44px; padding: 0;
  border: 1px solid var(--bh-border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--bh-surface) 88%, transparent);
  color: var(--bh-text);
  cursor: pointer;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.16);
}
.gallery__nav svg { inline-size: 22px; block-size: 22px; }
/* Logical insets, so the arrows swap sides in Arabic without a second rule. */
.gallery__nav--prev { inset-inline-start: var(--bh-space-3); }
.gallery__nav--next { inset-inline-end: var(--bh-space-3); }
/* The chevrons are drawn pointing left and right; in RTL "previous" is on the
   right, so the glyph has to turn with the button. */
[dir="rtl"] .gallery__nav svg { transform: scaleX(-1); }
.gallery__nav:hover { background: var(--bh-surface); }
.gallery__nav:focus-visible { outline: 2px solid var(--bh-focus); outline-offset: 2px; }
.gallery__nav[aria-disabled="true"] { opacity: 0.35; cursor: default; }
.gallery__count {
  position: absolute; inset-block-end: var(--bh-space-3); inset-inline-end: var(--bh-space-3);
  margin: 0; padding: 2px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bh-black) 72%, transparent);
  color: var(--bh-cream);
  font-size: var(--bh-fs-small);
  font-variant-numeric: tabular-nums;
}
.gallery__empty {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  background: var(--bh-surface-muted);
  border: 1px solid var(--bh-border);
  border-radius: var(--bh-radius-md);
  color: var(--bh-text-muted);
}

.listing-desc { margin-block-start: var(--bh-space-8); max-width: 68ch; }
.listing-desc p + p { margin-block-start: var(--bh-space-4); }

.specs { margin-block-start: var(--bh-space-12); }
.specs h2 { margin-block-end: var(--bh-space-4); }
.specs__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; margin: 0; }
@media (min-width: 720px) { .specs__grid { grid-template-columns: repeat(3, 1fr); } }
.spec { padding-block: var(--bh-space-3); border-block-start: 1px solid var(--bh-border); }
.spec dt { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); }
.spec dd { margin: 0; font-weight: var(--bh-fw-semibold); }

/* -------- summary card, sticky on desktop -------- */

.listing-summary { position: static; }
@media (min-width: 960px) { .listing-summary { position: sticky; inset-block-start: 88px; } }
.listing-summary__place { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); margin-block: var(--bh-space-3) var(--bh-space-1); }
.listing-summary__title { font-size: var(--bh-fs-h3); margin-block-end: var(--bh-space-3); }
.listing-summary__price { font-size: var(--bh-fs-h2); font-weight: var(--bh-fw-semibold); }
.listing-summary__spec {
  margin-block: var(--bh-space-1) 0;
  color: var(--bh-text-muted);
  font-size: var(--bh-fs-small);
  font-variant-numeric: tabular-nums;
}
.listing-summary__ref { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); margin-block-end: var(--bh-space-6); }
.listing-summary__cta > * + * { margin-block-start: var(--bh-space-3); }
.listing-summary__minor { gap: var(--bh-space-2); }
.listing-summary__agent { margin-block-start: var(--bh-space-6); padding-block-start: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.listing-summary__agent-name { font-weight: var(--bh-fw-semibold); }
.listing-summary__agent-role { font-size: var(--bh-fs-small); color: var(--bh-text-muted); }
.listing-summary__agent-link { font-size: var(--bh-fs-small); }

.back-link { margin-block-start: var(--bh-space-12); }

/* ------------------------------------------------- payment calculator */

.plan { margin-block-start: var(--bh-space-12); padding: var(--bh-space-6); background: var(--bh-surface-muted); border-radius: var(--bh-radius-md); }
.plan h2 { margin-block-end: var(--bh-space-4); }
.plan__controls { display: grid; gap: var(--bh-space-4); }
@media (min-width: 640px) { .plan__controls { grid-template-columns: repeat(2, 1fr); gap: var(--bh-space-6); } }
.plan__range { width: 100%; accent-color: var(--bh-bronze); min-height: 44px; }
.plan__out { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--bh-space-3); margin-block-start: var(--bh-space-6); }
.plan__out div { padding-block-start: var(--bh-space-3); border-block-start: 1px solid var(--bh-border); }
.plan__out dt { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); }
.plan__out dd { margin: 0; font-size: var(--bh-fs-body-lg); font-weight: var(--bh-fw-semibold); }
.plan__note { margin-block-start: var(--bh-space-4); font-size: var(--bh-fs-micro); color: var(--bh-text-muted); }

/* A toast for the copy actions — the only floating element on the site. */
.toast {
  position: fixed;
  inset-block-end: var(--bh-space-6);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  background: var(--bh-black);
  color: var(--bh-cream);
  padding: var(--bh-space-3) var(--bh-space-6);
  border-radius: var(--bh-radius-sm);
  box-shadow: var(--bh-shadow);
  font-size: var(--bh-fs-small);
  z-index: 90;
}

/* ==================================================== print — one A4 sheet */

@media print {
  @page { size: A4; margin: 16mm 14mm 18mm; }

  .crumbs, .back-link, .listing-summary__cta, .gallery__empty,
  .listing-page__grid > .listing-page__aside .listing-summary__agent-link,
  .plan__controls, .toast, .skip-link { display: none !important; }

  .listing-page__grid { display: block; }
  .listing-page__aside { margin-block-end: 8mm; }
  .listing-summary { position: static; border: 0; }
  .listing-summary .card__body { padding: 0; }
  .listing-summary__title { font-size: 16pt; }
  .listing-summary__price { font-size: 14pt; }

  .gallery { grid-template-columns: repeat(2, 1fr); }
  .gallery__img { aspect-ratio: 4 / 3; border-radius: 0; }
  .gallery__img:nth-child(n+3) { display: none; }

  .specs { margin-block-start: 6mm; }
  .specs__grid { grid-template-columns: repeat(3, 1fr); }
  .plan { background: none; padding: 0; margin-block-start: 6mm; }

  /* The similar-properties row is for browsing, not for a sheet in someone's hand. */
  .listing-page section[aria-labelledby="similar-h"] { display: none !important; }

  /* Everything a client needs to call us, on the paper. */
  .listing-page .wrap::after {
    content: "Blackhorse Real Estate · New Cairo · info@blackhorse.properties · +20 103 466 6676";
    display: block;
    margin-block-start: 8mm;
    padding-block-start: 3mm;
    border-block-start: 1px solid var(--bh-print-rule);
    font-size: 8pt;
    color: var(--bh-print-muted);
  }
}

/* ================================================================= filters */

.page-head { margin-block-end: var(--bh-space-8); }
.page-head .lede { margin-block-start: var(--bh-space-3); }

.filters {
  padding: var(--bh-space-4);
  background: var(--bh-surface-muted);
  border-radius: var(--bh-radius-md);
  margin-block-end: var(--bh-space-6);
}
@media (min-width: 720px) { .filters { padding: var(--bh-space-6); } }

.filters__row { display: grid; gap: var(--bh-space-4); }
@media (min-width: 720px) {
  /* minmax(0,1fr) not 1fr: a grid track's default min is auto, so the search
     field's intrinsic width would otherwise push the segmented control down to
     nothing. max-content on the second track keeps all three segments legible. */
  .filters__row { grid-template-columns: minmax(0, 1fr) max-content; align-items: end; }
}
.filters__search .input { min-width: 0; }
.filters__status { align-self: end; }
.filters__status span { padding-inline: var(--bh-space-4); white-space: nowrap; }

.filters__grid {
  display: grid;
  gap: var(--bh-space-3);
  grid-template-columns: repeat(2, 1fr);
  margin-block-start: var(--bh-space-4);
}
@media (min-width: 720px) { .filters__grid { grid-template-columns: repeat(4, 1fr); } }

.filters__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--bh-space-3);
  margin-block-start: var(--bh-space-4);
  padding-block-start: var(--bh-space-4);
  border-block-start: 1px solid var(--bh-border);
}
.filters__count { font-size: var(--bh-fs-small); font-weight: var(--bh-fw-semibold); }

/* The count and the cards both update live; the region tells a screen reader
   the result changed without moving focus. */
.filters [aria-live] { min-height: 1.5em; }

/* ============================================================ area guides */

.area-hero { padding-block: var(--bh-space-8) var(--bh-space-6); }
.area-hero .lede { margin-block-start: var(--bh-space-4); max-width: 62ch; }
.area-facts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--bh-space-4);
  margin-block-start: var(--bh-space-8);
  padding-block-start: var(--bh-space-6);
  border-block-start: 1px solid var(--bh-border);
}
@media (min-width: 720px) { .area-facts { grid-template-columns: repeat(4, 1fr); } }
.area-facts dt { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); }
.area-facts dd { margin: 0; font-weight: var(--bh-fw-semibold); }

.area-body { max-width: 70ch; }
.area-section { margin-block-start: var(--bh-space-12); }
.area-section h2 { margin-block-end: var(--bh-space-4); }
.area-section p + p { margin-block-start: var(--bh-space-4); }

.faq__list { margin-block-start: var(--bh-space-4); }
.faq__item { padding-block: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.faq__item dt { font-weight: var(--bh-fw-semibold); margin-block-end: var(--bh-space-2); }
.faq__item dd { margin: 0; color: var(--bh-text-secondary); }

.area-aside { margin-block-start: var(--bh-space-12); }
@media (min-width: 960px) {
  .area-layout { display: grid; grid-template-columns: 1fr 300px; gap: var(--bh-space-16); align-items: start; }
  .area-aside { margin-block-start: 0; position: sticky; inset-block-start: 88px; }
}

/* ================================================== generic content pages */

.steps { counter-reset: step; margin-block-start: var(--bh-space-6); }
.step {
  position: relative;
  padding-inline-start: var(--bh-space-12);
  padding-block: var(--bh-space-4);
  border-block-start: 1px solid var(--bh-border);
}
.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: var(--bh-space-4);
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: var(--bh-radius-full);
  background: var(--bh-black);
  color: var(--bh-cream);
  font-size: var(--bh-fs-micro);
  font-weight: var(--bh-fw-semibold);
  font-variant-numeric: tabular-nums;
}
.step h3 { font-size: var(--bh-fs-body-lg); margin-block-end: var(--bh-space-1); }
.step p { color: var(--bh-text-secondary); }

.split { display: grid; gap: var(--bh-space-8); align-items: start; }
@media (min-width: 960px) { .split { grid-template-columns: 1fr 380px; gap: var(--bh-space-16); } }

/* Stacking these pages was worse, not better. Making the column single and
   narrow left 604px of the 1180px wrap empty on the right for the page's whole
   height — more dead space than the side-by-side ever had, just turned ninety
   degrees. Side by side uses the width; the cost is some empty column under
   the shorter side, which reads as ordinary page furniture rather than a hole.
   Measured, both ways, before choosing.

   The form is sticky so it stays in reach while the prose scrolls past, which
   is what turns that leftover column into somewhere the form sits. */
@media (min-width: 960px) {
  .split > aside { position: sticky; inset-block-start: 88px; }
}


.panel {
  padding: var(--bh-space-6);
  background: var(--bh-surface-muted);
  border-radius: var(--bh-radius-md);
}
.panel h2, .panel h3 { margin-block-end: var(--bh-space-3); }

.contact-list { margin-block-start: var(--bh-space-4); }
.contact-list div { padding-block: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.contact-list dt { font-size: var(--bh-fs-micro); color: var(--bh-text-muted); margin-block-end: var(--bh-space-1); }
.contact-list dd { margin: 0; font-weight: var(--bh-fw-semibold); }

/* Opening hours. Two columns that hug the left, not a row stretched edge to edge.

   It used to be a flex row with space-between, which reads as a schedule when
   there are five rows of days and times. With the single row the firm actually
   has — Every day / 24 hours — it threw "24 hours" to the far side of a 640px
   column with nothing near it, and the pair no longer read as one fact.

   A grid sized to its content keeps the days in one column and the times in
   the next, aligned with each other and starting where the rest of the page
   starts, whether there is one row or six. */
.hours { margin-block-start: var(--bh-space-4); }
.hours div {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  column-gap: var(--bh-space-8);
  padding-block: var(--bh-space-2);
}
.hours dt { color: var(--bh-text-secondary); }
.hours dd { margin: 0; font-variant-numeric: tabular-nums; }

/* ==================================================================== team */

/* A labelled list. The label is a term on its own line, not the first three
   words of a sentence set in bold — BRAND.md §7. */
.deflist { margin-block-start: var(--bh-space-4); }
.deflist > div { padding-block: var(--bh-space-4); border-block-start: 1px solid var(--bh-border); }
.deflist dt {
  font-size: var(--bh-fs-micro);
  letter-spacing: var(--bh-ls-caps);
  text-transform: uppercase;
  color: var(--bh-text-muted);
  margin-block-end: var(--bh-space-1);
}
[dir="rtl"] .deflist dt { letter-spacing: 0; text-transform: none; font-size: var(--bh-fs-small); }
.deflist dd { margin: 0; color: var(--bh-text-secondary); }

/* A prose page has no sidebar, so the measure would otherwise sit against one
   edge of a 1180px container with nothing beside it. */
.area-body:only-child { margin-inline: auto; }

.role-card { padding-block: var(--bh-space-6); border-block-start: 1px solid var(--bh-border); }
.role-card h3 { margin-block-end: var(--bh-space-2); }
.role-card p { color: var(--bh-text-secondary); }

/* ================================================================== forms */

.form-status {
  margin-block-start: var(--bh-space-4);
  padding: var(--bh-space-3) var(--bh-space-4);
  border-radius: var(--bh-radius-sm);
  font-size: var(--bh-fs-small);
  border-inline-start: 3px solid var(--bh-info);
  background: var(--bh-surface-muted);
}
.form-status--ok { border-inline-start-color: var(--bh-positive); }
.form-status--info { border-inline-start-color: var(--bh-warning); }

.form-note { margin-block-start: var(--bh-space-3); font-size: var(--bh-fs-micro); color: var(--bh-text-muted); }
.form-wa { margin-block-start: var(--bh-space-3); }

/* ============================================================== shortlist */

.shortlist-actions {
  display: flex; flex-wrap: wrap; gap: var(--bh-space-3);
  margin-block-end: var(--bh-space-8);
  padding-block-end: var(--bh-space-6);
  border-block-end: 1px solid var(--bh-border);
}

/* A count on the header link, once anything is saved. */
.shortlist-count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px;
  margin-inline-start: var(--bh-space-1);
  padding-inline: 5px;
  border-radius: var(--bh-radius-full);
  background: var(--bh-gold);
  color: var(--bh-on-accent);
  font-size: var(--bh-fs-badge);
  font-weight: var(--bh-fw-bold);
  font-variant-numeric: tabular-nums;
}

/* ==================================================================== 404 */

.notfound { padding-block: var(--bh-space-16); text-align: center; }
.notfound .cluster { justify-content: center; margin-block-start: var(--bh-space-6); }

/* A shortlist link in the masthead, with a live count. The label collapses on
   small screens; the icon and the count carry it. */
.lang-toggle__icon { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; }
/* Hidden from sight, not from a screen reader: display:none took the link's
   only name away on a phone. */
.lang-toggle .shortlist-label {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
@media (min-width: 560px) {
  .lang-toggle .shortlist-label {
    position: static; width: auto; height: auto; margin: 0 0 0 var(--bh-space-2);
    margin-inline-start: var(--bh-space-2); overflow: visible; clip-path: none;
  }
}
@media (min-width: 560px) { .lang-toggle .shortlist-label { display: inline; } }

.area-card__dev {
  font-size: var(--bh-fs-micro);
  color: var(--bh-text-muted);
  margin-block-end: var(--bh-space-2);
}

.field__optional { font-weight: var(--bh-fw-regular); color: var(--bh-text-muted); }

/* ============================================================ careers band */

/* Aimed at a different reader from everything above it — a working broker, not
   a buyer — so it is visually separated rather than blended in. */
.careers-band__inner { display: grid; gap: var(--bh-space-6); align-items: center; }
@media (min-width: 860px) { .careers-band__inner { grid-template-columns: 1.5fr auto; gap: var(--bh-space-12); } }
.careers-band .lede { margin-block-start: var(--bh-space-3); max-width: 62ch; }

/* A quiet line where working brokers actually are: the listings index.
   Small and set behind a hairline, but NOT muted — muted small type in that
   position reads as a disclaimer and gets skipped, which defeats the point. */
.broker-note {
  margin-block-start: var(--bh-space-12);
  padding-block-start: var(--bh-space-6);
  border-block-start: 1px solid var(--bh-border);
  font-size: var(--bh-fs-small);
  color: var(--bh-text-secondary);
}
.broker-note a { font-weight: var(--bh-fw-semibold); }

/* ======================================================= audit fixes, CSS */

/* .card has overflow:hidden, which clipped the focus ring on every listing
   card link — keyboard users saw nothing move. Draw the ring inside the card
   instead, on the card itself, when anything inside it has focus. */
.listing-card:focus-within { outline: 2px solid var(--bh-focus); outline-offset: 2px; }
.listing-card__link:focus-visible { outline: none; }
.area-card:focus-visible { outline: 2px solid var(--bh-focus); outline-offset: 2px; }

/* The drawer sits inside the sticky masthead. Eleven links on a short phone
   overflowed the viewport with no way to scroll to the last ones. */
.drawer[data-open="true"] { max-height: calc(100dvh - 64px); overflow-y: auto; overscroll-behavior: contain; }

/* Listing page on a phone: one column in source order, which is now the
   summary, then the gallery and the detail. */
@media (max-width: 959px) {
  .listing-page__grid { display: flex; flex-direction: column; }
}

/* A sticky WhatsApp + call bar on phones, so the primary action is one thumb
   away wherever the reader is on the page. Hidden once the real CTA block is
   on screen (app.js toggles [hidden] with an IntersectionObserver), and in print. */
.sticky-cta {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: 40;
  display: flex;
  gap: var(--bh-space-2);
  padding: var(--bh-space-2) var(--bh-space-4) calc(var(--bh-space-2) + env(safe-area-inset-bottom));
  background: var(--bh-surface);
  border-block-start: 1px solid var(--bh-border);
  box-shadow: 0 -1px 3px rgba(26, 26, 26, 0.10);
}
.sticky-cta .btn { flex: 1; min-height: 44px; }
@media (min-width: 960px) { .sticky-cta { display: none; } }
@media print { .sticky-cta { display: none !important; } }
.has-sticky-cta { padding-block-end: 72px; }
@media (min-width: 960px) { .has-sticky-cta { padding-block-end: 0; } }

/* Landing pages: the "elsewhere" list is pills that are links. */
a.pill { color: var(--bh-graphite); }
a.pill:hover { background: var(--bh-gold-tint); text-decoration: none; }
.area-list li a { display: inline-block; padding: 4px var(--bh-space-3); border: 1px solid var(--bh-border); border-radius: var(--bh-radius-full); font-size: var(--bh-fs-small); color: var(--bh-text); }
.area-list li a:hover { border-color: var(--bh-gold); text-decoration: none; }

/* ============================================================ audit mediums */

/* Toast: the one physical transform in the sheet put it a full width off-centre
   in RTL. Symmetric insets centre it in either direction. */
.toast { inset-inline: var(--bh-space-4); transform: none; width: max-content; max-width: 100%; margin-inline: auto; }

/* Tabbing backwards under a sticky masthead landed the focused element behind it. */
html { scroll-padding-block-start: 80px; }
#main { scroll-margin-block-start: 80px; }

/* A pressed state for generic buttons used as toggles (the property-page Save). */
.btn[aria-pressed="true"] { background: var(--bh-gold-tint); border-color: var(--bh-bronze); }

/* Honeypot: off-screen, not display:none, so bots that check visibility fill it. */
.hp { position: absolute; inset-inline-start: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Agent tools on the listing summary: one primary action, the rest quiet. */
.listing-summary__tools { display: flex; flex-wrap: wrap; gap: var(--bh-space-3); margin-block-start: var(--bh-space-3); font-size: var(--bh-fs-small); }
.listing-summary__tools button { color: var(--bh-text-secondary); text-decoration: underline; text-underline-offset: 3px; }
.listing-summary__tools button:hover { color: var(--bh-accent-on-light); }

/* Print-only contact line, rendered from site.json rather than CSS content. */
.print-only { display: none; }
@media print { .print-only { display: block; margin-block-start: 8mm; padding-block-start: 3mm; border-block-start: 1px solid var(--bh-print-rule); font-size: 8pt; color: var(--bh-print-muted); } .listing-page .wrap::after { content: none; } }

/* A linked place line on cards and the summary. */
.listing-card__place a, .listing-summary__place a { color: inherit; }

/* The slogan is the headline, in the closest gold a white hero can carry.

   Karim tried the dark hero and did not want it, so the ground is white again
   and the brand's own contrast rule applies: docs/BRAND.md, "Gold on white is
   2.4:1 — never body text." #C9A14C fails even the 3:1 bar that large text is
   allowed, so it cannot be used here at any size.

   Bronze #A67C2E is 3.79:1 against white — it passes for a heading at this
   size and is the warmest, most gold-looking shade in the palette that does.
   GoldDeep #8B6A24 is safer at 5.02:1 but reads brown, which is the note
   Karim gave on it. Bronze is the compromise that looks like the brand.

   The real #C9A14C is available only on a dark ground, where it is 7.2:1.
   That was the dark hero, and it was rejected. */
/* The hero slogan carries the whole hero on its own. Karim, 9 Sep, after
   seeing an 80-word paragraph under it: "remove that paragraph and just write
   the slogan in a nice big font to fill the space."

   Three sentences, one per line — the break is in the markup, because the
   column is wide enough that natural wrapping puts "Speed. Trust. The" on one
   line and orphans "Direction." on the next, which reads as an accident.

   The site-wide h1 tops out at 30px and the RTL override sets line-height
   1.45; both are wrong for a display line, so both are restated here. 1.06 is
   tight enough to read as one block and still clears the Arabic descenders,
   which is why Arabic gets a slightly looser value of its own. */
.hero__copy h1 {
  color: var(--bh-bronze);
  /* 64px leaves only 12px between "The Right Direction." and the column edge.
     The face is self-hosted so the metrics are fixed, but a failed font load
     would push that line to a fourth. 62px keeps ~30px of slack. */
  font-size: clamp(34px, 5.4vw, 62px);
  line-height: 1.06;
  letter-spacing: -0.015em;
  /* No text-wrap: balance here. The three lines are already chosen in the
     markup, and balance re-wraps the longest of them to even the ragged edge —
     it split "The Right Direction." across two lines and made the slogan four
     lines instead of three. Measured; not guessed. */
}
/* Arabic gets its own, larger value. The same px reads smaller in Arabic —
   the reason tokens.css already carries --bh-fs-body-ar at 15.5px against
   14.5px — and "الاتجاه الصحيح." is a shorter line than "The Right
   Direction.", so it has the room the English does not. */
[dir="rtl"] .hero__copy h1 { font-size: clamp(34px, 6.2vw, 80px); line-height: 1.2; letter-spacing: normal; }
/* If the hero is ever put on a dark band again, plain Gold is the right shade
   there and Bronze drops to 1.9:1. Each is named only where it passes. */
.bh-dark .hero__copy h1,
.section--dark .hero__copy h1 { color: var(--bh-gold); }
