/* ==========================================================================
   BE REAL ESTATE — header, footer, hero, search
   Depends on be.css for tokens. Logical properties throughout.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
/* Translucent rather than solid, and with no bottom rule: the reference lets
   the page show faintly through the bar and separates it with a shadow only
   once the page has scrolled. A permanent 1px border also made the header
   65px against a measured 64. */
.be-header {
    position: sticky;
    inset-block-start: 0;
    z-index: 100;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    transition: box-shadow var(--be-transition), background var(--be-transition);
}
.be-header.is-stuck {
    background: rgba(255, 255, 255, 0.96);
    box-shadow: 0 1px 0 var(--be-line), 0 6px 20px -12px rgba(15, 23, 42, 0.22);
}

/* Blur is unavailable in some engines; fall back to an opaque bar there so the
   header never becomes unreadable over a photograph. */
@supports not (backdrop-filter: blur(4px)) {
    .be-header { background: #fff; box-shadow: 0 1px 0 var(--be-line); }
}

.be-header__inner {
    display: flex;
    align-items: center;
    gap: var(--be-6);
    block-size: var(--be-header-h);
    /* The containing block for the mega panel - see the mega menu block. */
    position: relative;
}

.be-logo { display: inline-flex; align-items: center; gap: var(--be-3); flex: none; }
/* The uploaded mark is 1774x887 with a wide white margin baked into the
   file, so a 40px box left the visible logo far smaller than its box and
   dwarfed by the navigation beside it. 48px in a 64px header keeps a sensible
   margin while giving the mark itself room to read.

   Sized by height with width:auto, so a differently-proportioned logo
   uploaded later still fits rather than being squashed to a fixed ratio. */
.be-logo img { block-size: 48px; inline-size: auto; max-inline-size: 190px; object-fit: contain; }

/* Between 992 and 1400 the header is full — logo, seven nav items and five
   actions — and 48px tipped it 3px past the viewport at 1200, which is one of
   the widths the responsive sweep checks. The mark stays large where there is
   room for it and steps down where there is not.

   The nav gutter tightens with it so this lands with actual headroom rather
   than sitting exactly on the boundary, where the next thing added to the
   header would push it over again. */
@media (max-width: 1399px) {
    .be-logo img { block-size: 42px; max-inline-size: 150px; }
    .be-nav { gap: 0; }
    .be-nav__link { padding-inline: var(--be-2); }
}

@media (max-width: 991px) {
    .be-logo img { block-size: 40px; max-inline-size: 150px; }
}
.be-logo__mark {
    inline-size: 40px;
    block-size: 40px;
    border-radius: 10px;
    background: var(--be-brand);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 15px;
    letter-spacing: 0.02em;
    flex: none;
}
.be-logo__text { display: flex; flex-direction: column; line-height: 1.15; }
.be-logo__name { font-size: 1rem; font-weight: 800; color: var(--be-ink); letter-spacing: -0.01em; }
.be-logo__tag { font-size: 0.6875rem; font-weight: 600; color: var(--be-brand); letter-spacing: 0.04em; }

.be-nav { display: flex; align-items: stretch; gap: 2px; flex: 1; justify-content: flex-end; }

/* Icon above label. The stack gives each destination a recognisable shape
   before the word is read - useful in a bilingual interface where the label
   length changes completely between locales. */
.be-nav__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: var(--be-2) var(--be-4);
    min-inline-size: 74px;
    block-size: var(--be-header-h);
    font-size: var(--be-text-sm);
    font-weight: 600;
    color: var(--be-ink-soft);
    line-height: 1.2;
    text-align: center;
    white-space: nowrap;
    position: relative;
    transition: color var(--be-transition);
}
.be-nav__link .be-icon { color: var(--be-navy-400); transition: color var(--be-transition); }
.be-nav__link:hover,
.be-nav__link:hover .be-icon { color: var(--be-brand); }
.be-nav__link.is-active { color: var(--be-brand-400); }
.be-nav__link.is-active .be-icon { color: var(--be-brand-400); }
.be-nav__link.is-active::after {
    content: '';
    position: absolute;
    inset-block-end: 0;
    inset-inline: var(--be-4);
    block-size: 3px;
    background: var(--be-brand-400);
    border-start-start-radius: 3px;
    border-start-end-radius: 3px;
}
.be-nav__label { display: block; }

.be-header__actions { display: flex; align-items: center; gap: var(--be-2); flex: none; }

.be-lang {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: var(--be-2);
    font-size: var(--be-text-sm);
    font-weight: 700;
    color: var(--be-ink-soft);
    border-radius: var(--be-r-sm);
}
.be-lang .be-icon { color: var(--be-brand); }
.be-lang:hover { color: var(--be-brand); background: var(--be-brand-50); }

.be-fav-count {
    position: absolute;
    inset-block-start: -4px;
    inset-inline-end: -4px;
    min-inline-size: 18px;
    block-size: 18px;
    padding-inline: 4px;
    border-radius: var(--be-r-pill);
    background: var(--be-brand);
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    display: grid;
    place-items: center;
}
/* The favourites control is a filled circle in the reference header - it is
   the one persistent piece of saved state, so it earns the emphasis. */
.be-icon-btn--fav {
    position: relative;
    background: var(--be-brand-50);
    border-color: transparent;
    color: var(--be-brand);
}
.be-icon-btn--fav:hover { background: var(--be-brand-100); color: var(--be-brand-700); }

.be-burger { display: none; }
@media (max-width: 1279px) {
    .be-nav__link { min-inline-size: 62px; padding-inline: var(--be-2); font-size: var(--be-text-xs); }
}
@media (max-width: 1099px) {
    .be-nav { display: none; }
    .be-burger { display: inline-flex; }
    .be-header__inner { gap: var(--be-3); justify-content: space-between; }
}
@media (max-width: 767px) {
    .be-header__actions .be-btn--cta span { display: none; }
    .be-header__actions .be-btn--cta { padding-inline: var(--be-3); }

    /* Logo at one end, controls grouped at the other.
       `justify-content: space-between` on three children spread the logo, the
       menu button and the CTA evenly across the bar, which read as three
       unrelated things rather than a logo and a toolbar. */
    .be-header__inner { justify-content: flex-start; gap: var(--be-2); }
    .be-header__actions { margin-inline-start: auto; }
    .be-burger { order: 1; }
}
@media (max-width: 575px) {
    .be-logo__text { display: none; }
}

/* Mega menu */

/* Deliberately NOT position: relative.

   Centred on its own nav item, the panel escaped the viewport: it is ~1020px
   wide and the items sit near the ends of the bar, so the leftmost menu opened
   10px past the edge at 1200px and 47px past it at 1100px - a horizontal
   scrollbar on the homepage, caused by a panel that is not even visible.

   It resolves against .be-header__inner instead, so it is centred on the page
   container and cannot overflow by construction. The vertical anchor is
   unaffected: .be-nav__link is already block-size: var(--be-header-h), so the
   item bottom and the container bottom are the same edge, and the 10px gap the
   pointer crosses on the way to the panel is exactly what it was. */
.be-nav__item { position: static; }
.be-mega {
    position: absolute;
    inset-block-start: calc(100% + 10px);
    inset-inline-start: 50%;
    transform: translateX(-50%) translateY(-6px);
    inline-size: min(940px, 94vw);
    background: #fff;
    border: 1px solid var(--be-line);
    border-radius: var(--be-r-xl);
    /* A deeper, cooler shadow than the shared token: the panel floats over a
       photographic hero, and the generic card shadow disappeared against it. */
    box-shadow: 0 24px 60px -12px rgba(10, 32, 80, 0.28), 0 0 0 1px rgba(10, 32, 80, 0.04);
    padding: 0;
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--be-transition), transform var(--be-transition), visibility var(--be-transition);
    z-index: 110;
}
[dir="rtl"] .be-mega { transform: translateX(50%) translateY(-6px); }
.be-nav__item:hover .be-mega,
.be-nav__item:focus-within .be-mega { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
[dir="rtl"] .be-nav__item:hover .be-mega,
[dir="rtl"] .be-nav__item:focus-within .be-mega { transform: translateX(50%) translateY(0); }

/* A tinted head so the panel opens with its own name rather than starting
   cold on three column headings. */
.be-mega__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--be-4);
    padding: var(--be-4) var(--be-6);
    background: linear-gradient(180deg, var(--be-brand-50), #fff);
    border-block-end: 1px solid var(--be-line);
}

.be-mega__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--be-2);
    font-size: var(--be-text-sm);
    font-weight: 800;
    color: var(--be-navy);
}
.be-mega__eyebrow .be-icon { color: var(--be-brand); }

.be-mega__all {
    display: inline-flex;
    align-items: center;
    gap: var(--be-1);
    font-size: var(--be-text-sm);
    font-weight: 700;
    color: var(--be-brand);
}
.be-mega__all .be-icon { transition: transform var(--be-transition); }
.be-mega__all:hover .be-icon { transform: translateX(-3px); }
[dir="ltr"] .be-mega__all:hover .be-icon { transform: translateX(3px); }

/* Lists on one side, one real record on the other. A panel of nothing but
   text links asks the visitor to already know what they want. */
.be-mega__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 232px;
    gap: 0;
}

.be-mega__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    padding: var(--be-5) var(--be-4);
    min-inline-size: 0;
}

/* The feature card. Its own tinted panel so it reads as a destination rather
   than a fourth column of links. */
.be-mega__feature {
    display: flex;
    flex-direction: column;
    border-inline-start: 1px solid var(--be-line);
    background: linear-gradient(180deg, var(--be-brand-50), #fff);
    color: inherit;
    transition: background var(--be-transition);
}
.be-mega__feature:hover { background: var(--be-brand-50); color: inherit; }

.be-mega__feature-media {
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--be-line-soft);
}
.be-mega__feature-media img { inline-size: 100%; block-size: 100%; object-fit: cover; transition: transform 400ms ease; }
.be-mega__feature:hover .be-mega__feature-media img { transform: scale(1.04); }

.be-mega__feature-body { display: grid; gap: 4px; padding: var(--be-4); }

.be-mega__feature-eyebrow {
    font-size: var(--be-text-xs);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--be-brand);
}

.be-mega__feature-title {
    font-size: var(--be-text-base);
    font-weight: 800;
    color: var(--be-navy);
    line-height: var(--be-leading-tight);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.be-mega__feature-meta { display: flex; flex-wrap: wrap; gap: var(--be-1) var(--be-3); font-size: var(--be-text-xs); color: var(--be-muted); font-weight: 600; }

/* Below the widest desktops the feature would squeeze the lists, so the
   columns keep the space and the card steps aside. */
@media (max-width: 1279px) {
    .be-mega__body { grid-template-columns: minmax(0, 1fr); }
    .be-mega__feature { display: none; }
}

/* Hairlines between the columns rather than a gutter of nothing — it groups
   each list without adding a box around it. */
.be-mega__col { padding-inline: var(--be-3); }
.be-mega__col + .be-mega__col { border-inline-start: 1px solid var(--be-line-soft); }

.be-mega__title {
    display: flex;
    align-items: center;
    gap: var(--be-2);
    font-size: var(--be-text-xs);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--be-navy);
    margin-block-end: var(--be-3);
}
/* A short accent rule reads as a heading marker without shouting like an
   all-caps label did. */
.be-mega__title::after {
    content: '';
    flex: 1;
    block-size: 1px;
    background: var(--be-line);
}

.be-mega__list { display: grid; gap: 2px; }

.be-mega__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--be-2);
    padding: var(--be-2) var(--be-3);
    border-radius: var(--be-r-sm);
    font-size: var(--be-text-base);
    color: var(--be-ink);
    transition: background var(--be-transition), color var(--be-transition);
}

.be-mega__label { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.be-mega__link:hover { background: var(--be-brand-50); color: var(--be-brand); }

/* The count is a pill, so the eye can rank the rows at a glance instead of
   reading a number floating at the end of each line. */
.be-mega__count {
    flex: none;
    min-inline-size: 34px;
    text-align: center;
    padding: 1px var(--be-2);
    border-radius: var(--be-r-pill);
    background: var(--be-line-soft);
    color: var(--be-muted);
    font-size: var(--be-text-xs);
    font-weight: 700;
    transition: background var(--be-transition), color var(--be-transition);
}
.be-mega__link:hover .be-mega__count { background: var(--be-brand); color: #fff; }

@media (max-width: 1100px) {
    .be-mega__grid { padding: var(--be-4) var(--be-3); }
    .be-mega__col { padding-inline: var(--be-2); }
}

/* Mobile drawer nav */
.be-drawer__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--be-4) var(--be-5);
    border-block-end: 1px solid var(--be-line);
}
.be-drawer__nav { padding: var(--be-4) var(--be-3); display: grid; gap: var(--be-1); }
.be-drawer__link {
    padding: var(--be-3) var(--be-4);
    border-radius: var(--be-r-sm);
    font-size: var(--be-text-md);
    font-weight: 600;
    color: var(--be-ink);
}
.be-drawer__link:hover, .be-drawer__link.is-active { background: var(--be-brand-50); color: var(--be-navy); }
.be-drawer__foot { margin-block-start: auto; padding: var(--be-5); border-block-start: 1px solid var(--be-line); display: grid; gap: var(--be-3); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.be-hero {
    position: relative;
    isolation: isolate;
    color: #fff;
    overflow: hidden;
    /* Height tracks the viewport so the band keeps roughly the shape of the
       photographs behind it.

       At a fixed 560px a 1900px-wide screen made the band 3.4:1 while the
       images are about 2:1 — a third of every frame cropped away, which is
       what "the hero does not contain the picture" meant. Scaling with vw
       holds the ratio near 2.5:1 across the range, and the clamp stops it
       becoming a full-screen slab on very wide monitors. */
    min-block-size: clamp(560px, 40vw, 760px);
    display: grid;
    align-items: center;
    /* The hero used to stand 942px tall while the pictures behind it are
       roughly 2:1 — so most of each frame was cropped away and what survived
       was sky. Tightening the block rhythm brings the band close to the shape
       of the photographs, which is what stops them looking like arbitrary
       crops.

       The bottom padding is 112px rather than a token step because the search
       card is pulled 76px up into the hero; anything less and the card lands
       on the call to action, which is exactly what a first attempt at this
       did. */
    padding-block: var(--be-12) 7rem;
}

/* Slides occupy one grid cell and cross-fade. Keeping them in flow (rather
   than absolutely positioned) means the hero reserves its own height and the
   section never jumps as the slideshow advances. */
.be-hero__slides { position: absolute; inset: 0; z-index: -2; display: grid; }
.be-hero__slide {
    grid-area: 1 / 1;
    opacity: 0;
    transition: opacity 900ms ease;
}
.be-hero__slide.is-active { opacity: 1; }
.be-hero__slide img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    /* The focal point of a compound photograph is its buildings and landscaping,
       which sit below the horizon. Anchoring the crop there keeps the subject in
       frame instead of filling the hero with sky. */
    object-position: center 45%;
    display: block;

    /* Was brightness(0.78) saturate(0.92) *on top of* a scrim that already runs
       to 0.88 black. The two together crushed the photograph into a dark
       smudge — and the source is only 1188x792, so it is being upscaled about
       2.7x on a retina screen and had no contrast left to spare. The image now
       carries no filter of its own; legibility is the scrim's job alone, and a
       touch of saturation puts back what the upscale washes out. */
    filter: saturate(1.06) contrast(1.04);

    /* "Gently": the first paint used to snap in at full opacity. Each slide
       fades up once its own file has decoded, so the hero resolves rather than
       flashes. */
    opacity: 0;
    transition: opacity 700ms ease;
}

/* Set by the script once the image reports complete; the fallback keeps the
   hero visible if the load event was missed. */
.be-hero__slide img.is-loaded,
.no-js .be-hero__slide img { opacity: 1; }

/* The overlay has to carry white text over an unknown photograph, so it is a
   two-stop scrim - heavier at the bottom where the search card meets it. */
.be-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    /* Lighter, and weighted where the text actually is.

       The old scrim was near-opaque across the whole frame — 0.72 at the top
       and 0.88 at the bottom, plus a radial on top of that — so it darkened
       the photograph everywhere rather than only behind the copy. The headline
       sits in the upper middle and the search card meets the bottom edge, so
       those are the two places that need cover; the rest can show the picture.
       White text over this measures well past 4.5:1. */
    /* Two linear passes across the whole band, never a shape inside it.

       The previous version put a radial gradient on a pseudo-element sized to
       the copy. On a wide screen that ellipse reached its transparent stop
       while still inside its own box and drew a visible dark rectangle over
       the photograph — the "black square". A linear gradient spanning the
       full element has no edge to show, so the protection reads as light
       falling across the frame.

       The horizontal pass is strongest on the side the copy sits on, which is
       the inline-start — the right in Arabic, mirrored for English below. */
    background:
        linear-gradient(180deg, rgba(11, 18, 32, 0.52) 0%, rgba(11, 18, 32, 0.22) 44%, rgba(11, 18, 32, 0.72) 100%),
        linear-gradient(270deg, rgba(8, 15, 28, 0.68) 0%, rgba(8, 15, 28, 0.44) 38%, rgba(8, 15, 28, 0.10) 68%, rgba(8, 15, 28, 0) 88%);
    pointer-events: none;
}

/* Composed rather than centred.
   --------------------------------------------------------------------------
   Everything used to be stacked down the middle: headline, paragraph, four
   boxes, a button and a row of dots, all on one axis. Nothing led, the boxes
   competed with the headline, and the photograph had no room anywhere.

   Anchoring the copy to the inline-start gives the picture a side of its own
   and gives the block a reading order. */
[dir="ltr"] .be-hero::after {
    background:
        linear-gradient(180deg, rgba(11, 18, 32, 0.52) 0%, rgba(11, 18, 32, 0.22) 44%, rgba(11, 18, 32, 0.72) 100%),
        linear-gradient(90deg, rgba(8, 15, 28, 0.68) 0%, rgba(8, 15, 28, 0.44) 38%, rgba(8, 15, 28, 0.10) 68%, rgba(8, 15, 28, 0) 88%);
}

.be-hero__inner {
    position: relative;
    z-index: 2;
    text-align: start;
}

/* The measure goes on the children, not on the wrapper.

   `.be-hero__inner` carries `.be-container` too, and a container centres
   itself with `margin-inline: auto`. Capping the wrapper therefore produced a
   620px container centred in the viewport — the copy ended up floating in the
   middle rather than sitting at the start of a full-width container, which is
   where anchoring it was supposed to put it.

   Capping each child instead keeps the container full width, and
   `margin-inline-end: auto` on a block child pushes it to the inline-start —
   the right-hand side in Arabic. */
.be-hero__inner > * {
    max-inline-size: 620px;
    margin-inline-end: auto;
}


.be-hero__title {
    color: #fff;
    font-size: clamp(2rem, 4.2vw, 3.375rem);
    font-weight: 700;
    line-height: 1.2;
    margin: 0 0 var(--be-3);
    text-shadow: 0 2px 24px rgba(15, 23, 42, 0.45);
}
.be-hero__title em { color: var(--be-gold); font-style: normal; display: block; }

.be-hero__lead {
    color: rgba(255, 255, 255, 0.88);
    font-size: var(--be-text-lg);
    /* Not `margin: 0 auto`.

       The shorthand set BOTH inline margins to auto, which beat the
       `margin-inline-end: auto` that .be-hero__inner > * uses to push each
       child to the inline-start edge. The result was the one centred line in
       an otherwise right-aligned column: every sibling ended at the same x,
       and the lead floated 314px short of it.

       The 60ch cap goes with it - it computed to 604.8px against the 620px
       every sibling uses, so the column had two ragged edges 15px apart. */
    margin-block: 0 var(--be-8);
    margin-inline: 0 auto;
    text-shadow: 0 1px 12px rgba(15, 23, 42, 0.4);
}

/* Four inventory pills, 2x2 on the widest screens down to a single column on
   a phone. Each is a link: the number is a promise the user can act on. */
/* One strip, three figures, hairlines between them.

   Four filled boxes in a 2x2 grid read as chrome and drew the eye before the
   headline did. A single line of figures separated by rules states the same
   thing and stops competing. */
.be-hero__stats {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0;
    /* 12px, not 20: the aside below is the tail of this strip, not a separate
       block. It used to sit equidistant between the strip and the caption and
       so belonged to neither. */
    margin-block-end: var(--be-3);
}

.be-hero__stat {
    display: flex;
    align-items: baseline;
    gap: var(--be-2);
    padding-inline: var(--be-5);
    color: #fff;
    /* Same shadow as .be-hero__lead. These figures sit directly on the
       photograph and were the only near-white text in the hero without one. */
    text-shadow: 0 1px 12px rgba(15, 23, 42, 0.4);
    transition: color var(--be-transition);
}
.be-hero__stat:first-child { padding-inline-start: 0; }
.be-hero__stat + .be-hero__stat { border-inline-start: 1px solid rgba(255, 255, 255, 0.22); }
.be-hero__stat:hover { color: var(--be-gold); }
.be-hero__stat b { font-size: var(--be-text-2xl); font-weight: 800; letter-spacing: -0.01em; }
.be-hero__stat span { font-size: var(--be-text-sm); color: rgba(255, 255, 255, 0.76); }

/* The one entry that never had a number. */
.be-hero__aside {
    /* flex, not inline-flex.

       As an inline box it sat in an anonymous line box carrying the Arabic
       prose leading (`html[lang^="ar"] body.be { line-height: 1.85 }`), which
       added ~3px of half-leading above it - the declared 20px gap measured 23.
       Being inline also made `margin-inline-end: auto` from `.be-hero__inner >
       *` compute to zero, so this was the one child in the column not held in
       place by the same mechanism as its siblings.

       fit-content is load-bearing: a block-level flex box would inherit the
       620px cap from that same rule and become a 620px hit target and focus
       ring for a 150px link. */
    display: flex;
    inline-size: fit-content;
    align-items: center;
    gap: var(--be-2);
    /* The gap below now belongs to .be-hero__feature, which owns the only real
       group boundary in this column. */
    margin-block-end: 0;
    font-size: var(--be-text-sm);
    /* 600/0.80 puts this in the same register as `.be-hero__stat span` so it
       reads as the strip's tail rather than as a second kicker stacked over
       the caption's own eyebrow. */
    font-weight: 600;
    color: rgba(255, 255, 255, 0.80);
    text-shadow: 0 1px 12px rgba(15, 23, 42, 0.4);
}
.be-hero__aside:hover { color: var(--be-gold); }
.be-hero__aside .be-icon { transition: transform var(--be-transition); }
.be-hero__aside:hover .be-icon { transform: translateX(-4px); }

/* The shared `arrow` glyph is authored pointing physically left, which is
   forward in Arabic and backward in English. Scoped to the hero's two forward
   arrows - a global flip would reverse the appbar back button and cancel
   `.be-rail__flip`. */
[dir="ltr"] .be-hero__aside .be-icon,
[dir="ltr"] .be-hero__cta .be-btn .be-icon { transform: scaleX(-1); }
/* Order is load-bearing: `translateX(4px) scaleX(-1)` translates in the
   parent's frame and moves the glyph 4px right on screen. The other way round
   it translates inside the mirrored frame and moves 4px left. */
[dir="ltr"] .be-hero__aside:hover .be-icon { transform: translateX(4px) scaleX(-1); }

/* 32px is this column's only real group boundary: static furniture above,
   cross-fading slide caption below. Inert at <=991px, where this element is
   display:none, so it cannot strand air on a phone. */
.be-hero__feature {
    margin-block-start: var(--be-8);
    display: grid;
    justify-items: start;
    /* No min-block-size. Every caption shares cell 1/1 and the inactive ones
       are `visibility: hidden`, not `display: none`, so the row is already as
       tall as the tallest caption and never changes between slides. The old
       108px floor sat ~9px above the real content and that slack leaked
       downward, turning the declared dots gap into a measured 25px.

       align-items: end bottom-anchors every caption, so the button and the
       dots stay put as the slideshow advances even when one name wraps. */
    align-items: end;
}
.be-hero__cta {
    grid-area: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* 16px: name -> button was the block's tightest real gap at 12px, under a
       name that is now 24-28px. */
    gap: var(--be-4);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* `visibility` was never in the transition list, so the outgoing caption
       was cut to hidden in frame 1 while the incoming one faded up over 500ms
       - the caption area went blank mid-swap. Hold it visible for exactly its
       own fade, then hide. */
    transition: opacity 220ms ease, visibility 0s linear 220ms;
}
.be-hero__cta-text { display: flex; flex-direction: column; gap: var(--be-1); }
.be-hero__cta-eyebrow {
    /* 14px in white, not 12px in gold. --be-gold is a light blue and the
       caption scrim lets ~23% of the photograph through, so gold on a bright
       frame measures ~4.2:1 - under AA for text this size, and it drops to
       11px on a phone. White is independent of both the photograph and of
       whatever accent colour the operator sets in the admin.

       The eyebrow declared no line-height and so inherited 1.85 from the
       Arabic prose rule: paragraph leading on a UI label, which is why the
       declared 2px gap to the name measured ~9px. And no letter-spacing:
       positive tracking breaks Arabic joins, a rule this stylesheet already
       states for headings. */
    font-size: var(--be-text-sm);
    line-height: var(--be-leading-snug);
    font-weight: 700;
    color: rgba(255, 255, 255, 0.92);
    text-shadow: 0 1px 8px rgba(15, 23, 42, 0.5);
}
.be-hero__cta-dot { opacity: 0.75; margin-inline: 2px; }
.be-hero__cta.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    /* Out, then in - never both. The captions share one grid cell, and
       overlapping two Arabic names at partial opacity merges joined strokes
       into mush. The incoming caption stays hidden (neither painted nor
       hit-testable) for the 220ms the outgoing one takes to clear, then turns
       visible exactly as its own opacity starts to rise. 220 + 280 = the same
       500ms envelope as before, still inside the photo's 900ms fade. */
    transition: opacity 280ms ease 220ms, visibility 0s linear 220ms;
}

/* The global reduced-motion rule only covers skeletons, and the script
   suppresses the autoplay timer but not the dot-click path - without this a
   reduced-motion visitor waits out the sequence on every click. */
@media (prefers-reduced-motion: reduce) {
    .be-hero__cta,
    .be-hero__cta.is-active { transition: none; }
}
.be-hero__cta-name {
    /* Not var(--be-text-xl): --be-text-lg and --be-text-xl are defined as the
       same 1.125rem, so the slide's identity computed to exactly the 18px of
       the lead paragraph and 4px UNDER the stat figures - the label out-weighed
       the thing it labelled. Scoped here rather than fixing the token, which is
       also h3 and eight other call sites.

       1.4, not 1.25: below Cairo's content area the descenders of a wrapped
       two-line Arabic name collide. */
    font-size: clamp(1.5rem, 1.5vw, 1.75rem);
    font-weight: 800;
    color: #fff;
    line-height: 1.4;
    text-wrap: balance;
    text-shadow: 0 1px 12px rgba(15, 23, 42, 0.55);
}

.be-hero__dots {
    display: flex;
    justify-content: flex-start;
    /* 16px: with the 24px hit areas below, 10 + 16 = 26px centre to centre, so
       adjacent targets clear each other. */
    gap: var(--be-4);
    /* 24px, stated. It was 16px plus ~9px of slack inherited from the deleted
       min-block-size, so the largest gap in the block sat between the button
       and the dots that drive it. Now narrower than the 32px boundary above. */
    margin-block-start: var(--be-6);
}
.be-hero__dots button {
    position: relative;
    inline-size: 10px;
    block-size: 10px;
    box-shadow: 0 1px 4px rgba(8, 15, 28, 0.45);
    padding: 0;
    border: 0;
    border-radius: var(--be-r-pill);
    background: rgba(255, 255, 255, 0.55);
    cursor: pointer;
    transition: inline-size var(--be-transition), background var(--be-transition);
}
.be-hero__dots button[aria-selected="true"] { inline-size: 30px; background: var(--be-gold); }

/* The target, not the dot. Absolutely positioned so it adds no height to the
   row and does not push the first dot off the column's inline-start edge; a
   pseudo-element hit-tests as its own button. 7 + 10 + 7 = the 24px minimum. */
.be-hero__dots button::after {
    content: '';
    position: absolute;
    inset-block: -7px;
    inset-inline: -7px;
}

/* Keyboard focus is invisible in this block otherwise: the global ring is a
   20%-alpha brand blue, drawn here over a dark photograph. Scoped to .be-hero
   so the global token, tuned for white cards, is left alone. The white 2px
   rule is sandwiched between a dark 6px spread and the element, so it survives
   over a blown sky and over a dark facade alike. */
.be-hero :focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
    box-shadow: 0 0 0 6px rgba(8, 15, 28, 0.80);
}
.be-hero__dots button:focus-visible {
    box-shadow: 0 1px 4px rgba(8, 15, 28, 0.45), 0 0 0 6px rgba(8, 15, 28, 0.80);
}
@media (forced-colors: active) {
    .be-hero :focus-visible { outline-color: Highlight; box-shadow: none; }
}

@media (max-width: 767px) {
    .be-hero { min-block-size: 480px; padding-block: var(--be-12) var(--be-16); }
    /* Kept 2x2 on a phone rather than dropping to one column. Stacked, four
       full-width pills pushed the search panel and everything under it below
       two screens of scrolling before the visitor saw a single listing. */
    .be-hero__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); max-inline-size: 420px; gap: var(--be-2); }
    .be-hero__stat { padding: var(--be-3); }
    .be-hero__stat b { font-size: var(--be-text-lg); }
}

.be-searchwrap { position: relative; z-index: 5; margin-block-start: -76px; }

.be-search {
    background: #fff;
    border-radius: var(--be-r-xl);
    box-shadow: 0 18px 48px rgba(15, 23, 42, 0.18);
    padding: var(--be-5);
    color: var(--be-ink);
}

@media (max-width: 767px) {
    .be-searchwrap { margin-block-start: -48px; }
    .be-search { padding: var(--be-4); }
}
.be-search__tabs { display: flex; gap: var(--be-1); border-block-end: 1px solid var(--be-line); margin-block-end: var(--be-5); }
.be-search__tab {
    padding: var(--be-3) var(--be-5);
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: var(--be-text-base);
    font-weight: 700;
    color: var(--be-muted);
    cursor: pointer;
    position: relative;
    white-space: nowrap;
}
.be-search__tab[aria-selected="true"] { color: var(--be-navy); }
.be-search__tab[aria-selected="true"]::after {
    content: '';
    position: absolute;
    inset-inline: var(--be-3);
    inset-block-end: -1px;
    block-size: 2.5px;
    background: var(--be-brand);
    border-radius: 2px 2px 0 0;
}

.be-search__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--be-4);
    margin-block-end: var(--be-4);
    flex-wrap: wrap;
}
.be-search__help {
    display: inline-flex;
    align-items: center;
    gap: var(--be-2);
    margin: 0;
    font-size: var(--be-text-sm);
    color: var(--be-muted);
}
.be-search__help .be-icon { color: var(--be-brand); }

/* One search row rather than a grid of captioned fields.
   The labels still exist for assistive technology (be-sr-only); visually the
   row reads as a single bar, which is what stops the controls from stacking
   at different heights depending on whether they happen to carry a caption. */
.be-search__row {
    display: flex;
    align-items: stretch;
    gap: var(--be-2);
}

.be-search__cell {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 0;
    min-inline-size: 0;
    background: var(--be-surface);
    border: 1px solid var(--be-line);
    border-radius: var(--be-r-md);
    transition: border-color var(--be-transition), box-shadow var(--be-transition);
}
.be-search__cell--grow { flex: 2 1 0; }
.be-search__cell:focus-within { border-color: var(--be-brand); box-shadow: 0 0 0 3px var(--be-brand-50); }

.be-search__cell-icon {
    display: inline-flex;
    flex: none;
    color: var(--be-navy-400);
    padding-inline-start: var(--be-3);
}

.be-search__cell input,
.be-search__cell select {
    flex: 1;
    min-inline-size: 0;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: var(--be-text-base);
    color: var(--be-ink);
    padding: 0.8125rem var(--be-3);
    outline: none;
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    text-overflow: ellipsis;
}
.be-search__cell input { cursor: text; }
.be-search__cell input::placeholder { color: var(--be-navy-400); }

/* Native select arrow is removed above; this draws one on the inline end and
   stays on the correct side in both scripts. */
.be-search__cell select {
    padding-inline-end: var(--be-8);
    background-image: linear-gradient(45deg, transparent 50%, var(--be-navy-400) 50%),
                      linear-gradient(135deg, var(--be-navy-400) 50%, transparent 50%);
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    background-position: right 1.25rem center, right calc(1.25rem + 5px) center;
}
[dir="rtl"] .be-search__cell select {
    background-position: left 1.25rem center, left calc(1.25rem + 5px) center;
}

.be-search__more {
    flex: none;
    inline-size: 48px;
    display: grid;
    place-items: center;
    border: 1px solid var(--be-line);
    border-radius: var(--be-r-md);
    background: var(--be-surface);
    color: var(--be-ink-soft);
    cursor: pointer;
    transition: border-color var(--be-transition), color var(--be-transition), background var(--be-transition);
}
.be-search__more:hover { border-color: var(--be-brand); color: var(--be-brand); background: var(--be-brand-50); }

.be-search__go { flex: none; padding-inline: var(--be-6); block-size: 50px; align-self: center; }

@media (max-width: 991px) {
    .be-search__row { flex-wrap: wrap; }
    .be-search__cell { flex: 1 1 46%; }
    .be-search__cell--grow { flex: 1 1 100%; }
    .be-search__go { flex: 1 1 100%; }
}
@media (max-width: 575px) {
    .be-search__cell { flex: 1 1 100%; }
    .be-search__more { inline-size: 100%; block-size: 46px; }
}

.be-search__footer { display: flex; align-items: center; gap: var(--be-3); flex-wrap: wrap; margin-block-start: var(--be-5); }
.be-search__footer-label { display: inline-flex; align-items: center; gap: var(--be-2); font-size: var(--be-text-sm); color: var(--be-muted); font-weight: 600; flex: none; }
.be-search__footer-label .be-icon { color: var(--be-brand); }

/* --------------------------------------------------------------------------
   Property-type tiles
   -------------------------------------------------------------------------- */
.be-type {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--be-3);
    padding: var(--be-5) var(--be-3);
    background: #fff;
    border: 1px solid var(--be-line);
    border-radius: var(--be-r-lg);
    text-align: center;
    transition: all var(--be-transition);
}
.be-type:hover { border-color: var(--be-brand-100); background: var(--be-brand-50); transform: translateY(-2px); }
.be-type__icon {
    inline-size: 48px;
    block-size: 48px;
    display: grid;
    place-items: center;
    border-radius: var(--be-r);
    background: var(--be-brand-50);
    color: var(--be-brand);
    transition: background var(--be-transition);
}
.be-type:hover .be-type__icon { background: #fff; }
.be-type__icon svg { inline-size: 24px; block-size: 24px; }
.be-type__name { font-size: var(--be-text-sm); font-weight: 700; color: var(--be-navy); }
.be-type__count { font-size: var(--be-text-xs); font-weight: 700; color: var(--be-brand); }

/* --------------------------------------------------------------------------
   Spotlight (editorial featured project)
   -------------------------------------------------------------------------- */
.be-spotlight {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 0;
    border-radius: var(--be-r-xl);
    overflow: hidden;
    border: 1px solid var(--be-line);
    background: #fff;
}
@media (max-width: 991px) { .be-spotlight { grid-template-columns: minmax(0, 1fr); } }
.be-spotlight__media { position: relative; min-block-size: 380px; background: var(--be-canvas); }
.be-spotlight__media img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.be-spotlight__body { padding: var(--be-10); display: flex; flex-direction: column; gap: var(--be-4); justify-content: center; }
@media (max-width: 767px) { .be-spotlight__body { padding: var(--be-6); } .be-spotlight__media { min-block-size: 240px; } }
.be-spotlight__title { font-size: var(--be-text-2xl); }
.be-spotlight__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--be-4); padding-block: var(--be-4); border-block: 1px solid var(--be-line); }
.be-spotlight__fact dt { font-size: var(--be-text-xs); color: var(--be-muted); font-weight: 600; margin-block-end: 2px; }
.be-spotlight__fact dd { margin: 0; font-size: var(--be-text-md); font-weight: 800; color: var(--be-navy); }

/* --------------------------------------------------------------------------
   Stats band
   -------------------------------------------------------------------------- */
.be-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--be-6);
    padding: var(--be-10);
    border-radius: var(--be-r-xl);
    background: linear-gradient(135deg, var(--be-navy), var(--be-brand));
    color: #fff;
    text-align: center;
}
@media (max-width: 767px) { .be-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: var(--be-6); gap: var(--be-5); } }
.be-stats__value { font-size: var(--be-text-3xl); font-weight: 800; line-height: 1.15; color: #fff; }
.be-stats__label { font-size: var(--be-text-sm); color: rgba(255, 255, 255, 0.76); margin-block-start: var(--be-1); }

/* --------------------------------------------------------------------------
   How it works / benefits
   -------------------------------------------------------------------------- */

.be-benefit__icon svg { inline-size: 22px; block-size: 22px; }

/* --------------------------------------------------------------------------
   Lead CTA
   -------------------------------------------------------------------------- */
.be-cta {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--be-12);
    align-items: center;
    padding: var(--be-12);
    border-radius: var(--be-r-xl);
    background: var(--be-brand-50);
    border: 1px solid var(--be-brand-100);
}
@media (max-width: 991px) { .be-cta { grid-template-columns: minmax(0, 1fr); gap: var(--be-8); padding: var(--be-8) var(--be-6); } }
.be-cta__title { font-size: var(--be-text-2xl); margin-block-end: var(--be-3); }
.be-cta__text { color: var(--be-muted); margin-block-end: var(--be-6); }
.be-cta__form { background: #fff; padding: var(--be-6); border-radius: var(--be-r-lg); box-shadow: var(--be-shadow-sm); display: grid; gap: var(--be-4); }
.be-cta__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--be-4); }
@media (max-width: 575px) { .be-cta__row { grid-template-columns: minmax(0, 1fr); } }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.be-footer { background: #0b2547; color: rgba(255, 255, 255, 0.72); padding-block: var(--be-16) 0; margin-block-start: var(--be-20); }
.be-footer a { color: rgba(255, 255, 255, 0.72); }
.be-footer a:hover { color: #fff; }
.be-footer__grid { display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(4, minmax(0, 1fr)); gap: var(--be-8); }
@media (max-width: 991px) { .be-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--be-6); } }
@media (max-width: 575px) { .be-footer__grid { grid-template-columns: minmax(0, 1fr); } }

.be-footer__about p { font-size: var(--be-text-base); line-height: var(--be-leading-normal); max-inline-size: 42ch; }
.be-footer .be-logo__name { color: #fff; }
.be-footer__title { font-size: var(--be-text-base); font-weight: 700; color: #fff; margin-block-end: var(--be-4); }
.be-footer__list { display: grid; gap: var(--be-2); font-size: var(--be-text-base); }
.be-footer__contact { display: grid; gap: var(--be-3); font-size: var(--be-text-base); }
.be-footer__contact li { display: flex; align-items: flex-start; gap: var(--be-2); }
.be-footer__contact svg { inline-size: 17px; block-size: 17px; margin-block-start: 4px; flex: none; color: var(--be-gold); }

.be-footer__social { display: flex; gap: var(--be-2); margin-block-start: var(--be-5); }
.be-footer__social a {
    inline-size: 38px; block-size: 38px;
    display: grid; place-items: center;
    border-radius: var(--be-r-sm);
    background: rgba(255, 255, 255, 0.08);
    transition: background var(--be-transition);
}
.be-footer__social a:hover { background: var(--be-brand); }
.be-footer__social svg { inline-size: 18px; block-size: 18px; }

.be-footer__bar {
    margin-block-start: var(--be-12);
    padding-block: var(--be-5);
    border-block-start: 1px solid rgba(255, 255, 255, 0.1);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--be-4);
    flex-wrap: wrap;
    font-size: var(--be-text-sm);
}
.be-footer__legal { display: flex; gap: var(--be-5); flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Mobile sticky action bar (detail pages)
   -------------------------------------------------------------------------- */
.be-sticky-actions {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 90;
    display: none;
    gap: var(--be-2);
    padding: var(--be-3) var(--be-4);
    padding-block-end: max(var(--be-3), env(safe-area-inset-bottom));
    background: #fff;
    border-block-start: 1px solid var(--be-line);
    box-shadow: 0 -4px 16px rgba(23, 32, 51, 0.08);
}
.be-sticky-actions .be-btn { flex: 1; }
@media (max-width: 991px) { .be-sticky-actions { display: flex; } body.be-has-sticky { padding-block-end: 76px; } }

/* The fourth hero pill carries a phrase, not a figure, so it centres its own
   single line instead of leaving a gap where the number would be. */
.be-hero__stat--plain { justify-content: center; }
.be-hero__stat--plain span { font-size: var(--be-text-base); font-weight: 700; color: #fff; }

/* ==========================================================================
   Phone app shell
   ==========================================================================
   On a phone the site behaves like an installed app rather than a website:
   the destinations live in a bottom tab bar within thumb reach instead of
   behind a hamburger, and with the manifest in place "Add to Home Screen"
   launches it full-screen with no browser chrome.

   Everything here is scoped to the phone breakpoint. Above it the tab bar is
   removed from the layout entirely, not just hidden.
   ========================================================================== */
.be-tabbar { display: none; }

@media (max-width: 991px) {
    .be-tabbar {
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: 90;
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 1fr;
        gap: 2px;
        padding-block: 6px;
        /* The home indicator on a notched phone sits over the last ~34px.
           Without this the tabs are half-covered by it. */
        padding-block-end: max(6px, env(safe-area-inset-bottom));
        background: color-mix(in srgb, var(--be-surface) 92%, transparent);
        -webkit-backdrop-filter: saturate(180%) blur(14px);
        backdrop-filter: saturate(180%) blur(14px);
        border-block-start: 1px solid var(--be-line);
    }

    .be-tabbar__item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        /* 48px is the smallest reliable thumb target. */
        min-block-size: 48px;
        padding-block: 4px;
        color: var(--be-muted);
        text-decoration: none;
        -webkit-tap-highlight-color: transparent;
    }

    .be-tabbar__icon { position: relative; display: inline-flex; }
    .be-tabbar__icon .be-icon { display: block; }

    .be-tabbar__label {
        font-size: 10.5px;
        font-weight: 600;
        line-height: 1.2;
        text-align: center;
        /* Arabic tab labels are longer than English ones and must not wrap
           into a second line that shifts the icons. */
        max-inline-size: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .be-tabbar__item.is-active { color: var(--be-brand); }
    .be-tabbar__item.is-active .be-tabbar__label { font-weight: 700; }

    .be-tabbar__badge {
        position: absolute;
        inset-block-start: -5px;
        inset-inline-end: -8px;
        min-inline-size: 16px;
        padding-inline: 4px;
        border-radius: 999px;
        background: var(--be-brand);
        color: #fff;
        font-size: 10px;
        font-weight: 700;
        line-height: 16px;
        text-align: center;
    }

    /* Content must clear the bar. Anything pinned to the bottom - the sticky
       contact actions on a listing - has to sit above it, not under it. */
    /* 62px, not 58: the bar measures 61px (6px padding + a 48px target + 6px).
       Reserving less left the last few pixels of the footer under it. */
    body.be { padding-block-end: calc(62px + env(safe-area-inset-bottom)); }
    .be-sticky-actions { inset-block-end: calc(62px + env(safe-area-inset-bottom)); }

    /* The header keeps the logo and search; the tab bar carries the rest, so
       duplicating them in a cramped top bar only crowds it. */
    .be-header__actions .be-lang,
    .be-header__actions .be-icon-btn--fav,
    .be-header__signin,
    .be-header__register { display: none; }
}

/* Standalone (installed) mode: there is no browser chrome to scroll away, so
   the header can be flush to the status bar. */
@media (display-mode: standalone) {
    .be-header { padding-block-start: env(safe-area-inset-top); }
}

/* --------------------------------------------------------------------------
   App bar (phone)
   --------------------------------------------------------------------------
   Replaces the website header on a phone. On home it carries the logo and the
   two entry points; on every other screen it carries back + the page title,
   which is what tells someone where they are inside an app.
   -------------------------------------------------------------------------- */
.be-appbar { display: none; }

@media (max-width: 991px) {
    /* The desktop header is removed from the layout, not merely hidden, so it
       cannot leave a gap above the app bar. */
    .be-header { display: none; }

    .be-appbar {
        position: sticky;
        inset-block-start: 0;
        z-index: 80;
        display: flex;
        align-items: center;
        gap: var(--be-2);
        min-block-size: 52px;
        padding-inline: var(--be-3);
        padding-block-start: env(safe-area-inset-top);
        background: color-mix(in srgb, var(--be-surface) 92%, transparent);
        -webkit-backdrop-filter: saturate(180%) blur(14px);
        backdrop-filter: saturate(180%) blur(14px);
        border-block-end: 1px solid var(--be-line);
    }

    .be-appbar__action {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: none;
        inline-size: 40px;
        block-size: 40px;
        border: 0;
        border-radius: var(--be-r-sm);
        background: none;
        color: var(--be-navy);
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }
    .be-appbar__action:active { background: var(--be-line-soft); }

    /* The chevron points back along the reading direction. */
    [dir="rtl"] .be-appbar [data-be-back] .be-icon { transform: scaleX(-1); }

    .be-appbar__title {
        flex: 1;
        min-inline-size: 0;
        margin: 0;
        font-size: var(--be-text-md);
        font-weight: 700;
        line-height: 1.3;
        color: var(--be-navy);
        text-align: center;
        /* One line. A title that wraps changes the bar's height between
           screens, which reads as the layout jumping. */
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Home: logo takes the space, actions sit at the far end. */
    .be-appbar--home .be-logo { margin-inline-end: auto; }
    /* 38px in a 52px bar, not 30.

       The uploaded mark is 1774x887 with a wide white margin baked into the
       file, so the visible wordmark is a fraction of its box - at 30px the
       Arabic strapline under "BE REAL ESTATE" was unreadable and the whole
       lockup read as a small grey smudge. 38px leaves 7px of clearance top and
       bottom and does not grow the bar.

       The real fix is a horizontal logo file trimmed to its own edges; until
       one is supplied this is as large as the bar allows. */
    .be-appbar--home .be-logo img { block-size: 38px; }

    /* --------------------------------------------------------------------
       An app has no link footer
       --------------------------------------------------------------------
       Every destination in it is already one tap away in the tab bar, and a
       six-column sitemap at the end of every screen is the single clearest
       tell that you are looking at a website. Only the legal line survives.
       -------------------------------------------------------------------- */
    .be-footer__grid,
    .be-footer__about { display: none; }
    .be-footer { padding-block: var(--be-5); }

    /* Sheets are already handled in be.css: below 768px .be-dialog is a bottom
       sheet, and .be-dialog--top is deliberately a *top* sheet so the search
       panel drops from the field it belongs to. Redefining either here would
       be a second declaration of the same component in a second file, which is
       the pattern that has broken this stylesheet before.
       Only the grab handle is new. */
    .be-dialog__head { position: relative; padding-block-start: var(--be-5); }

    .be-dialog:not(.be-dialog--top) .be-dialog__head::before {
        content: '';
        position: absolute;
        inset-block-start: 8px;
        inset-inline-start: 50%;
        transform: translateX(-50%);
        inline-size: 38px;
        block-size: 4px;
        border-radius: 999px;
        background: var(--be-line);
    }

    /* A sheet must clear the home indicator. */
    .be-dialog { padding-block-end: env(safe-area-inset-bottom); }

    /* Touch behaviour: no 300ms grey flash, no accidental text selection when
       dragging a rail, and momentum scrolling inside them. */
    .be-tabbar__item,
    .be-appbar__action,
    .be-btn,
    .be-chip { -webkit-tap-highlight-color: transparent; }

    .be-appbar__title,
    .be-tabbar__label { -webkit-user-select: none; user-select: none; }

    [data-be-rail] { -webkit-overflow-scrolling: touch; scroll-snap-type: inline mandatory; }
    [data-be-rail] > * { scroll-snap-align: start; }
}

/* Menu rows you can see, not only read
   --------------------------------------------------------------------------
   Areas, compounds and developers all have a picture on file. A drop-down of
   plain text asked the visitor to recognise a name; a thumbnail lets them
   recognise the place, which is the whole point of a mega menu over a plain
   list. */
.be-mega__link--thumb { padding-block: 5px; }

.be-mega__thumb {
    flex: none;
    inline-size: 34px;
    block-size: 34px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--be-line-soft);
    display: block;
}
.be-mega__thumb img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }

/* A ring on hover rather than a scale, so the row does not jump. */
.be-mega__link--thumb .be-mega__thumb { box-shadow: 0 0 0 1px rgba(10, 32, 80, 0.06); transition: box-shadow var(--be-transition); }
.be-mega__link--thumb:hover .be-mega__thumb { box-shadow: 0 0 0 2px var(--be-brand); }

/* With thumbnails the rows are taller, so the panel needs the room back. */
.be-mega { inline-size: min(1020px, 95vw); }
.be-mega__list { gap: 1px; }


/* The feature fills its column instead of floating in white.

   With the thin third column gone the panel is two lists and a card. The card
   stretches to whatever height the lists set and its picture takes up the
   slack, so the panel has no pocket of empty white under it — which is what
   made it look broken. */
.be-mega__feature { block-size: 100%; }
.be-mega__feature-media { flex: 1; min-block-size: 150px; aspect-ratio: auto; }

/* Quick links across the foot, where the thin column used to be. */
.be-mega__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--be-2);
    padding: var(--be-3) var(--be-6) var(--be-4);
    border-block-start: 1px solid var(--be-line);
    background: var(--be-canvas);
}

.be-mega__quick {
    padding: 5px var(--be-4);
    border-radius: var(--be-r-pill);
    border: 1px solid var(--be-line);
    background: #fff;
    font-size: var(--be-text-sm);
    font-weight: 700;
    color: var(--be-ink-soft);
    transition: border-color var(--be-transition), color var(--be-transition), background var(--be-transition);
}
.be-mega__quick:hover { border-color: var(--be-brand); background: var(--be-brand-50); color: var(--be-brand); }

/* Making room in the header
   --------------------------------------------------------------------------
   Between 992 and 1400 the header is full: logo, seven nav items and six
   actions, with about 33px to spare at 1200. An eighth nav section overflows
   it by 55px.

   The room comes from the sign-in control, which costs 158px of that band
   purely for its label. Below 1400 it becomes the icon it already carries —
   the action is unchanged and still reachable, and the button keeps an
   explicit aria-label so hiding the text does not leave an unnamed link. */
