/* Campaign popups live in their own file: one self-contained block of rules
   with no overlap with the page layout, and long enough to be worth finding on
   its own. Vite inlines the import at build time — the site still ships one
   stylesheet. */
@import "./popup.css";

/*
   woff2 first, truetype only as a fallback for browsers that cannot read it.

   These shipped as bare TTF, which is the raw font with no web compression at
   all: 222 KB for the Arabic face alone, on a body font every page needs before
   it can paint text. The same outlines as woff2 are 68 KB. Nothing about the
   rendering changes — it is the identical font, 69% smaller on the wire.
 */
@font-face {
  font-family: "IBM Plex Sans Arabic";
  src:
    url("/assets/IBMPlexSansArabic-Regular.woff2") format("woff2"),
    url("/assets/IBMPlexSansArabic-Regular.ttf") format("truetype");
  font-weight: 300 500;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src:
    url("/assets/IBMPlexSans-Bold.woff2") format("woff2"),
    url("/assets/IBMPlexSans-Bold.ttf") format("truetype");
  font-weight: 600 800;
  font-display: swap;
}

:root {
  --black: #000;
  --ink: #070707;
  --gold: #b89a58;
  --gold-bright: #ceb36f;
  --text: #c6c2bd;
  --muted: #8d8984;
  --line: rgba(184, 154, 88, 0.24);
  --paper: #f0ece4;
  --max: 1180px;
  --header: 110px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--black);
  color: var(--text);
  font-family: "IBM Plex Sans Arabic", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.85;
  -webkit-font-smoothing: antialiased;
}

/*
 * Reserve the scrollbar gutter permanently.
 *
 * `.is-locked` below takes the scrollbar away whenever a popup or the side
 * panel opens. Without a reserved gutter the content area silently grows by the
 * scrollbar's width at that moment and every element on the page moves — a
 * single 0.22 layout shift, which is most of a CLS budget spent on opening a
 * dialog. Reserving the gutter for the whole session means locking the scroll
 * changes nothing about the layout.
 */
html {
  scrollbar-gutter: stable;
}

body.is-locked {
  overflow: hidden;
}

::selection {
  background: var(--gold);
  color: #000;
}

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

/* Every responsive image is wrapped in a <picture> so it can offer WebP. The
   wrapper must not become a box of its own: 57 rules in this file size the img
   against its container (`.leader-photo img { height: 100% }` and friends), and
   an inline picture between them would collapse the lot. display:contents takes
   it out of the layout entirely, so the img stays the child the CSS expects. */
picture {
  display: contents;
}

/*
 * ...and its <source> elements must not become boxes either.
 *
 * `display: contents` promotes a picture's *children* into the parent's layout,
 * and that includes the `<source>` tags, not just the `<img>`. In a flex or
 * grid container they are real items: zero-width, but each one takes a cell.
 *
 * The floor-plan panel is where this showed. Two plans in a two-column grid put
 * both drawings in the same column with the other half empty, because the
 * sources had claimed the first cells — measured sitting at x=1018 with the
 * images pushed beneath them.
 *
 * Safe to hide: a `<source>` is metadata. Which candidate the browser picks is
 * decided by the image selection algorithm from the element's attributes, not
 * by layout, so removing its box changes nothing about which file loads.
 */
picture > source {
  display: none;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
textarea,
select {
  font: inherit;
  /* type="tel" and type="email" default to LTR, which flips their placeholder
     to the wrong edge on an RTL page. */
  direction: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

h1,
h2,
h3,
h4,
p {
  margin-top: 0;
}

h1,
h2,
h3,
h4 {
  color: var(--gold);
  font-weight: 400;
  line-height: 1.35;
}

.container {
  width: min(calc(100% - 48px), var(--max));
  margin-inline: auto;
}

.section {
  position: relative;
  padding: 112px 0;
}

.section--tight {
  padding: 72px 0;
}

.section-kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  color: var(--gold);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.section-kicker::before {
  width: 36px;
  height: 1px;
  background: currentColor;
  content: "";
}

.section-title {
  max-width: 760px;
  margin-bottom: 28px;
  font-size: clamp(32px, 4vw, 56px);
}

.section-copy {
  max-width: 700px;
  color: #b7b3ae;
}

.lined {
  background-image: url("/assets/line-pattern.png");
  background-position: center;
  background-size: cover;
}

.gold-frame {
  border: 1px solid var(--line);
}

/* Buttons fill with a gold wipe that grows up from the bottom edge, rather
   than swapping background colour. Matches the live site's timing curve. */
.btn,
.hero-search__submit {
  display: inline-flex;
  min-height: 52px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 30px;
  border: 1px solid var(--gold);
  background-color: transparent;
  background-image: linear-gradient(0deg, var(--gold) 0, var(--gold) 100%);
  background-position: 100% calc(100% + 2px);
  background-repeat: no-repeat;
  background-size: 100% 0;
  color: var(--gold-bright);
  cursor: pointer;
  font-size: 14px;
  /* A button label is one line. Without this the longer English strings broke
     across two inside the same box — "GROUP SUBSIDIARIES" in the footer, where
     the column is narrower than the words. Every label the site uses fits on
     one line well inside the narrowest breakpoint. */
  white-space: nowrap;
  transition: background-size 0.64s cubic-bezier(0.33, 0.02, 0, 0.93),
    color 0.25s ease-out, border-color 0.25s ease-out;
}

.btn:hover,
.btn:focus-visible,
.hero-search__submit:hover,
.hero-search__submit:focus-visible {
  background-size: 100% calc(100% + 4px);
  color: #000;
  outline: none;
}

/* The glyph beside a button label — download, globe, pin, play.
   `currentColor` so it inverts with the label when the fill wipes up; a fixed
   fill would leave a gold icon on a gold background. `flex: none` because the
   button is a flex row and a long Arabic label would otherwise squeeze the
   icon narrower than it is tall. */
.btn-icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  fill: currentColor;
}

/* Filled buttons start full and empty out on hover — the inverse wipe. */
.btn--fill {
  background-size: 100% calc(100% + 4px);
  color: #fff;
  transition-delay: 0s, 0.05s, 0s;
}

.btn--fill:hover,
.btn--fill:focus-visible {
  background-size: 100% 0;
  color: #fff;
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--gold);
  font-size: 14px;
}

.text-link::after {
  content: "\2190";
  transition: transform 0.25s ease;
}

[dir="ltr"] .text-link::after {
  content: "\2192";
}

.text-link:hover::after {
  transform: translateX(-5px);
}

[dir="ltr"] .text-link:hover::after {
  transform: translateX(5px);
}

.skip-link {
  position: fixed;
  z-index: 300;
  top: 8px;
  inset-inline-start: 8px;
  padding: 8px 14px;
  background: #fff;
  color: #000;
  transform: translateY(-150%);
}

.skip-link:focus {
  transform: translateY(0);
}

/* Header */
.site-header {
  position: relative;
  z-index: 100;
  height: var(--header);
  border-bottom: 1px solid #483f30;
  background: #000;
}

@media (min-width: 1101px) {
  /* The header overlays the page instead of sitting in the flow, and #main
     reserves its height once. Shrinking it on scroll then costs no reflow, so
     the page never jumps the moment .is-fixed lands. */
  .site-header {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    transition:
      height 0.25s ease,
      background-color 0.25s ease;
  }

  #main {
    padding-top: var(--header);
  }

  /* Anchor jumps would otherwise land underneath the overlaying header. */
  html {
    scroll-padding-top: 70px;
  }

  .site-logo,
  .site-logo img,
  .nav-list a,
  .lang-toggle {
    transition:
      width 0.25s ease,
      height 0.25s ease;
  }

  .site-header.is-fixed {
    height: 70px;
    background: rgba(0, 0, 0, 0.98);
  }

  .site-header.is-fixed .site-logo,
  .site-header.is-fixed .site-logo img {
    width: 45px;
    height: 60px;
  }

  .site-header.is-fixed .nav-list a,
  .site-header.is-fixed .lang-toggle {
    height: 69px;
  }

  .site-header.is-fixed .nav-list a::after {
    bottom: 12px;
  }
}

.header-inner {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: space-between;
  padding: 0 40px;
  margin-inline: auto;
}

.site-logo {
  display: grid;
  width: 67px;
  height: 90px;
  place-items: center;
}

.site-logo img {
  width: 67px;
  height: 90px;
  object-fit: contain;
}

.nav-wrap,
.main-nav,
.nav-list {
  display: flex;
  align-items: center;
}

.nav-wrap {
  margin-inline-end: 38px;
}

.nav-list {
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-list li {
  position: relative;
  margin: 0 25px;
}

.nav-list li:first-child {
  margin-inline-start: 25px;
  margin-inline-end: 0;
}

.nav-list li::after,
.lang-toggle::after {
  position: absolute;
  top: 50%;
  left: -20px;
  width: 1px;
  height: 24px;
  background: #473c30;
  content: "";
  transform: translateY(-50%);
}

.nav-list li:first-child::after {
  left: -11px;
}

.nav-list a {
  position: relative;
  display: flex;
  height: calc(var(--header) - 1px);
  align-items: center;
  padding: 0;
  color: #b5985a;
  font-size: 16px;
  line-height: 18px;
  white-space: nowrap;
}

.nav-list a::after {
  position: absolute;
  right: 0;
  bottom: 33px;
  width: 32px;
  height: 1px;
  background: #b5985a;
  content: "";
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.25s ease;
}

.nav-list a:hover::after,
.nav-list a[aria-current="page"]::after {
  transform: scaleX(1);
}

.lang-toggle,
.menu-toggle {
  border: 0;
  background: transparent;
  color: var(--gold);
  cursor: pointer;
}

.lang-toggle {
  position: relative;
  display: flex;
  height: calc(var(--header) - 1px);
  align-items: center;
  margin-inline-end: 25px;
  padding: 0;
  color: #b5985a;
  font-family: inherit;
  font-size: 16px;
  line-height: 18px;
}

.header-glyph {
  display: grid;
  width: 42px;
  height: 27px;
  padding: 0;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--gold);
  cursor: pointer;
  margin: 0;
}

.header-glyph:focus,
.desktop-side-panel__close:focus {
  outline: none;
}

.header-glyph svg {
  width: 42px;
  height: 24px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  shape-rendering: crispEdges;
}

@keyframes qode-draw-vertical {
  0%,
  100% {
    clip-path: inset(-2px -2px);
  }

  42% {
    clip-path: inset(-2px -2px 100% -2px);
  }

  43% {
    clip-path: inset(100% -2px -2px -2px);
  }
}

@keyframes qode-draw {
  0%,
  100% {
    clip-path: inset(-2px -2px);
  }

  42% {
    clip-path: inset(-2px -2px -2px 100%);
  }

  43% {
    clip-path: inset(-2px 100% -3px -2px);
  }
}

@media (hover: hover) {
  .header-glyph:hover path {
    animation: qode-draw-vertical 0.9s cubic-bezier(0.57, 0.39, 0, 0.86) 1 forwards;
  }

  .header-glyph:hover path:nth-of-type(2),
  .header-glyph:hover path:nth-of-type(5) {
    animation-delay: 0.1s;
  }

  .header-glyph:hover path:nth-of-type(3),
  .header-glyph:hover path:nth-of-type(6) {
    animation-delay: 0.2s;
  }
}

.menu-toggle {
  display: none;
  width: 44px;
  height: 44px;
  padding: 9px;
}

.menu-toggle span {
  display: block;
  height: 1px;
  margin: 6px 0;
  background: currentColor;
  transition: 0.3s ease;
}

.menu-toggle.is-open span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.menu-toggle.is-open span:nth-child(2) {
  opacity: 0;
}

.menu-toggle.is-open span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Page heading */
.page-hero {
  display: grid;
  min-height: 220px;
  place-items: center;
  border-bottom: 1px solid var(--line);
  text-align: center;
}

/* Live keeps this at a flat 36px at every width it is shown at — it does not
   scale up on wide screens. */
.page-hero h1 {
  margin-bottom: 8px;
  font-size: 36px;
  line-height: 46px;
}

/* And below 768px the whole title band is hidden, breadcrumbs included. */
@media (max-width: 768px) {
  .page-hero {
    display: none;
  }
}

.breadcrumbs {
  color: #b9b4af;
  font-size: 18px;
  font-weight: 300;
  line-height: 25px;
}

.breadcrumbs a:hover {
  color: var(--gold);
}

/* Home video hero */
/* The live hero video is exactly 100vh; we run it slightly shorter by choice so
   it sits more comfortably above the fold. #main reserves the header's height
   above this, so subtract it and add live's 31px top offset back. */
.home-hero {
  position: relative;
  height: calc(92svh - var(--header) + 31px);
  overflow: hidden;
  background: #0a0a0a;
}

.home-hero::after {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.24));
  content: "";
  pointer-events: none;
}

.home-hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  filter: brightness(0.76) saturate(0.82);
}

.hero-search {
  position: absolute;
  z-index: 2;
  right: 50%;
  bottom: 134px;
  display: grid;
  width: min(901px, calc(100% - 40px));
  height: 107px;
  grid-template-columns: 170px 207px 170px 170px 144px;
  align-items: center;
  padding: 20px;
  background: #111;
  gap: 0;
  transform: translateX(50%);
}

.hero-search__field {
  display: block;
}

.hero-search select {
  width: 100%;
  height: 35px;
  padding: 4px 0;
  border: 0;
  border-bottom: 1px solid #5b5b5b;
  appearance: none;
  background: transparent;
  color: #ccc;
  cursor: pointer;
  font-size: 15px;
}

.hero-search select:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 4px;
}

.hero-search option {
  background: #111;
  color: #ccc;
}

.hero-search__submit {
  width: 144px;
  height: 47px;
  min-height: 0;
  padding: 0;
  color: var(--gold);
  font-size: 12px;
  letter-spacing: 0.05em;
}

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

.hero-scroll {
  position: absolute;
  z-index: 2;
  bottom: 60px;
  left: 7%;
  width: 40px;
  height: 20px;
}

.hero-scroll span {
  display: block;
  width: 40px;
  height: 2px;
  background: #fff;
}

/* Home feature grid */
.feature-grid {
  display: grid;
  padding-bottom: 51px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.feature-card {
  position: relative;
  min-height: 250px;
  overflow: hidden;
  border-inline-end: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  isolation: isolate;
}

.feature-card:nth-child(2n) {
  border-inline-end: 0;
}


.feature-image {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.06) translateX(0);
  transition: transform 0.5s cubic-bezier(0.61, 1, 0.88, 1);
}

.feature-card::after {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: #000;
  content: "";
  opacity: 1;
  transition: opacity 0.5s ease, visibility 0.5s ease;
  visibility: visible;
}

.feature-card:hover .feature-image,
.feature-card:focus-within .feature-image {
  transform: scale(1.06) translateX(6px);
}

.feature-card:hover::after,
.feature-card:focus-within::after {
  opacity: 0;
  visibility: hidden;
}

.feature-number {
  position: absolute;
  z-index: 2;
  right: auto;
  bottom: -50px;
  left: 67px;
  color: #211e19;
  font-family: "IBM Plex Sans Arabic", Arial, sans-serif;
  font-size: clamp(145px, 14vw, 200px);
  font-weight: 100;
  line-height: 1;
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.35s ease, transform 0.5s cubic-bezier(0.61, 1, 0.88, 1);
}


.feature-card h2 {
  position: absolute;
  z-index: 2;
  top: 38px;
  right: auto;
  left: 60px;
  margin: 0;
  font-size: 22px;
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.35s ease, transform 0.5s cubic-bezier(0.61, 1, 0.88, 1);
}


.feature-card h2 span {
  opacity: 0.8;
}

.feature-card:hover .feature-number,
.feature-card:hover h2,
.feature-card:focus-within .feature-number,
.feature-card:focus-within h2 {
  opacity: 0;
  transform: translateX(18px);
}

/* Intro block used by about.html (the home has its own .intro-band) */
.home-intro {
  display: grid;
  min-height: 680px;
  grid-template-columns: 0.92fr 1.08fr;
  align-items: center;
  gap: 70px;
}

.home-intro__visual {
  position: relative;
  display: grid;
  min-height: 520px;
  place-items: center;
}

.home-intro__visual::before,
.home-intro__visual::after {
  position: absolute;
  width: 66%;
  height: 70%;
  border: 1px solid var(--line);
  content: "";
}

.home-intro__visual::after {
  transform: rotate(45deg) scale(0.7);
}

.home-intro__visual img {
  position: relative;
  z-index: 1;
  width: 66%;
  max-height: 400px;
  object-fit: contain;
  filter: sepia(0.35) saturate(0.8);
}

.home-intro h1 {
  font-size: clamp(38px, 5vw, 64px);
}

.home-intro p {
  margin-bottom: 34px;
  color: #bbb6b1;
  font-size: 17px;
}

/* Home intro band — two equal columns of the capped content grid below */
.intro-band {
  display: grid;
  height: 488px;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  padding: 25px 0;
}

.intro-band__visual {
  display: flex;
  height: 100%;
  align-items: center;
}

.intro-band__visual img {
  width: 100%;
  filter: sepia(0.35) saturate(0.8);
}

.intro-band__copy {
  padding-inline-end: 13px;
}

/* The intro is the one band that genuinely mirrors between languages: the copy
   always sits on the inline-start side, the artwork opposite. Auto-placement
   handles that, since the copy comes first in the markup. */
[dir="ltr"] .intro-band__copy {
  padding-inline-end: 0;
}

/* ---------------------------------------------------------------
   Extended content grid
   The intro and projects bands sit in a capped column pinned to the
   inline-start side, so the projects carousel can bleed off the
   opposite edge. These calc() breakpoints mirror the live site's.
   --------------------------------------------------------------- */
/*
   Logical, not physical.

   These were `padding-left`, with an RTL override in the ≥1441px block only.
   So between 1025px and 1440px an Arabic page put its whole gutter on the far
   side and the copy sat flush against the viewport edge — measured at 1424px,
   the width the client reported, as 0px of gap where 1500px gives 100px. Below
   1025px the padding is symmetric, which is why the fault had a window rather
   than a threshold.

   `padding-inline-start` is the same rule in both directions, so the override
   is deleted rather than duplicated.
 */
.intro-band,
.projects-shell {
  /*
     Viewport units, not percentages.
     A custom property stores the expression, not the result, so `50%` would be
     re-resolved against whatever box reads it — the foot below sits inside the
     already-padded shell, and got 81px where the heading got 162px. `50vw` is
     the same number wherever it is read.
   */
  --shell-inset: calc(50vw - 550px);

  padding-inline-start: var(--shell-inset);
}

@media (max-width: 1200px) {
  .intro-band,
  .projects-shell {
    --shell-inset: calc(50vw - 480px);
  }
}

@media (max-width: 1024px) {
  .intro-band,
  .projects-shell {
    /* Symmetric here, so nothing below needs to add its own inset back. */
    --shell-inset: 0px;

    padding-inline: 7%;
  }
}

@media (min-width: 1441px) {
  .intro-band,
  .projects-shell {
    --shell-inset: calc(50vw - 650px);

    padding-inline-end: 0;
  }
}

/*
   The carousel's foot is inset on both sides; only the track bleeds.

   The shell pads the start side and leaves the end at zero on purpose, so the
   photographs can run off the opposite edge. But `.carousel__foot` is a
   `space-between` row across that same full width, which put the arrows 6px
   from the viewport edge — clipped, and sitting behind the floating contact
   bar. Reusing `--shell-inset` rather than repeating the calc keeps the foot
   aligned with the heading at every breakpoint instead of drifting from it.
 */
.projects-shell .carousel__foot {
  padding-inline-end: var(--shell-inset);
}

.intro-band h1 {
  margin-bottom: 12px;
  font-size: 38px;
  line-height: 1.1;
}

.intro-band p {
  margin-bottom: 20px;
  color: #ccc;
  font-size: 18px;
  line-height: 1.6;
}

.intro-band .btn {
  width: 159px;
}

/* Leadership */
.leader-section {
  min-height: 523px;
  overflow: hidden;
  padding: 20px 90px;
}

/* The live site keeps the portrait on the same physical side in both
   languages, so these grids are laid out in physical order and the text
   direction is restored on the copy. */
.leader-grid {
  display: grid;
  height: 100%;
  grid-template-columns: 1fr 343px;
  align-items: center;
  gap: 70px;
  direction: ltr;
}

.leader-grid .leader-photo {
  grid-row: 1;
  grid-column: 2;
}

.leader-grid .leader-copy {
  grid-row: 1;
  grid-column: 1;
}

.leader-grid--reverse {
  grid-template-columns: 343px 1fr;
}

.leader-grid--reverse .leader-photo {
  grid-row: 1;
  grid-column: 1;
}

.leader-grid--reverse .leader-copy {
  grid-row: 1;
  grid-column: 2;
}

[dir="rtl"] .leader-copy {
  direction: rtl;
}

.leader-photo {
  height: 482px;
  overflow: hidden;
  padding: 6px;
  border: 1px solid var(--line);
}

.leader-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.65) contrast(1.05);
}

.leader-copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-inline-start: 10px;
}

.leader-copy h2 {
  margin-bottom: 20px;
  font-size: 32px;
}

.leader-copy h3 {
  margin-bottom: 20px;
  color: #fff;
  font-size: 20px;
  font-weight: 400;
}

.leader-copy p {
  margin-bottom: 16px;
  color: #ccc;
  font-size: 18px;
  line-height: 1.6;
}

.leader-copy p:last-child {
  margin-bottom: 0;
}

.showcase-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  margin-bottom: 50px;
}

.showcase-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
}

.project-card,
.article-card {
  position: relative;
}

.project-card__image,
.article-card__image {
  position: relative;
  display: block;
  overflow: hidden;
  background: #111;
}

.project-card__image {
  aspect-ratio: 0.84;
}

.article-card__image {
  aspect-ratio: 1.48;
}

.project-card__image::after,
.article-card__image::after {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.65), transparent 58%);
  content: "";
}

.project-card img,
.article-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.7) sepia(0.08);
  transition: 0.7s var(--ease);
}

.project-card:hover img,
.article-card:hover img {
  filter: saturate(0.95);
  transform: scale(1.045);
}

.project-card__content {
  position: absolute;
  z-index: 2;
  right: 0;
  bottom: 0;
  left: 0;
  padding: 24px;
}

.project-card__content h3 {
  margin: 6px 0 4px;
  color: #fff;
  font-size: 23px;
}

.project-card__tag {
  color: var(--gold-bright);
  font-size: 12px;
  letter-spacing: 0.08em;
}

.project-card__meta {
  color: #d3d0cb;
  font-size: 13px;
}

.stats-band {
  padding: 74px 0;
  background: var(--gold);
  color: #fff;
}

.stats-title {
  margin-bottom: 45px;
  color: #fff;
  text-align: center;
  font-size: 34px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 38px 24px;
}

.stat {
  text-align: center;
}

.stat strong {
  display: block;
  margin-bottom: 4px;
  color: rgba(64, 52, 38, 0.75);
  font-family: "IBM Plex Sans Arabic", Arial, sans-serif;
  font-size: clamp(48px, 6vw, 76px);
  font-weight: 300;
  line-height: 1;
}

.stat span {
  font-size: 15px;
}

/* Home figures band */
.figures-band {
  height: 375px;
  padding: 20px 30px 30px;
  background: rgb(181, 152, 90);
}

.figures-band__title {
  margin: 0 0 30px;
  color: #fff;
  text-align: center;
  font-size: 32px;
  font-weight: 400;
  line-height: 1.1;
}

.figures-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.figure {
  height: 120px;
  text-align: center;
}

/*
   One ink for the whole band, and it is dark enough to read.

   The numbers were #756049 on this gold — 2.16:1, against the 3:1 that large
   text needs — and the labels were white at 16px, 2.76:1 against 4.5:1. Both
   failed, and the label failed by more relative to its threshold even though
   only the number was reported. #362b1e is 5.00:1, which clears both with room.

   Darkening the ink rather than the band: white would need the gold taken down
   to a luminance of 0.18 against its current 0.33, which is a different colour
   rather than a corrected one.
 */
.figure strong {
  display: block;
  color: #362b1e;
  font-family: "IBM Plex Sans Arabic", Arial, sans-serif;
  font-size: 80px;
  font-weight: 300;
  line-height: 80px;
}

.figure span {
  display: block;
  color: #362b1e;
  font-size: 16px;
  font-weight: 600;
  line-height: 40px;
}

/* Home buttons are shorter and smaller than the site default */
.intro-band .btn,
.projects-section__link,
.contact-form__actions .btn {
  min-height: 47px;
  height: 47px;
  padding: 0;
  font-size: 12px;
  letter-spacing: 0.05em;
}

/* Shared band heading */
.band-title {
  margin: 0;
  color: var(--gold);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.1;
}

/* Home projects carousel */
.projects-section {
  padding: 25px 0 24px;
}


.projects-section .band-title {
  margin-bottom: 20px;
  text-align: start;
}

.carousel__viewport {
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.carousel.is-dragging .carousel__viewport {
  cursor: grabbing;
}

/* Stop the browser's own image drag from hijacking the gesture. */
.carousel__viewport img,
.carousel__viewport a {
  -webkit-user-drag: none;
  user-select: none;
}

.carousel__track {
  --carousel-gap: 19px;

  display: flex;
  gap: var(--carousel-gap);
  transition: transform 0.6s var(--ease);
}

.project-slide {
  position: relative;
  flex: 0 0 303px;
  height: 303px;
  overflow: hidden;
  background: #111;
}

.project-slide a {
  display: block;
  height: 100%;
}

/*
   The card clears itself on hover, which is the whole of this interaction.

   At rest a flat 40% black wash covers the photograph with the title centred on
   it. Pointing at a card takes all of that away: the wash fades out, the title
   slides 15px down and fades with it, and the still grows slightly — so what
   remains under the cursor is the photograph, unobstructed.

   Ours used to do none of it. The scrim was a permanent gradient, the title was
   permanent, and hover only saturated and scaled the image — which is why the
   section read as a different component from the published one rather than as
   the same one styled differently.

   Every number here is the published theme's own, read out of tadao-core:
   `rgba(0,0,0,.4)` and `opacity .5s ease-out` for the wash, `translateY(15px)`
   with `opacity .37s ease-out, transform .5s cubic-bezier(.43,.76,.33,1)` for
   the caption, and `scale(1.01)` to `scale(1.038)` about a 70%/80% origin,
   easing in over .5s and out over .9s. They are asymmetric on purpose: the
   caption leaves faster than it returns.

   Scoped away from `--wide` throughout. That variant puts its caption *below*
   the image in a shorter anchor, so a wash measured from the slide would cover
   the title and the category and make both look switched off.
 */
.project-slide:not(.project-slide--wide) > a {
  position: relative;
}

.project-slide:not(.project-slide--wide) > a::after {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  content: "";
  pointer-events: none;
  transition: opacity 0.5s ease-out;
}

.project-slide:not(.project-slide--wide):hover > a::after {
  opacity: 0;
}

.project-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-slide:not(.project-slide--wide) img {
  transform: scale(1.01);
  transform-origin: 70% 80%;
  transition: transform 0.5s cubic-bezier(0.27, 0.48, 0.45, 0.94);
}

.project-slide:not(.project-slide--wide):hover img {
  transform: scale(1.038);
  transition-duration: 0.9s;
}

/* The wide variant keeps the treatment it was designed with — it is a different
   layout, with its caption below the image, and was not part of this. */
.project-slide--wide img {
  filter: saturate(0.75);
  transition: 0.7s var(--ease);
}

.project-slide--wide:hover img {
  filter: saturate(1);
  transform: scale(1.05);
}

/*
   Centred by flex, as the published card is, rather than by `top: 50%` and a
   `translateY(-50%)`. The transform has to be free to carry the hover shift,
   and it cannot do that while it is also holding the title in place.

   The text-shadow is ours and stays: white on a 40% wash is legible over most
   photographs but not all of them, and it costs nothing on the ones where the
   wash was already enough.
 */
.project-slide:not(.project-slide--wide) h3 {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 43px 50px;
  color: #fff;
  text-align: center;
  font-size: 20px;
  font-weight: 400;
  line-height: 1.25;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6);
  transition:
    opacity 0.37s ease-out,
    transform 0.5s cubic-bezier(0.43, 0.76, 0.33, 1);
}

.project-slide:not(.project-slide--wide):hover h3 {
  opacity: 0;
  transform: translateY(15px);
}

.carousel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 30px;
  margin-top: 15px;
}

/* Physical margin on purpose: this container is forced to `direction: ltr` so
   the two arrows keep their left/right order, which would make a logical
   margin resolve against the wrong edge. */
/*
   No `direction: ltr` here.

   It pinned the pair to Latin order, so in Arabic "previous" sat on the left
   and drew a left-pointing head while the track scrolls right-to-left — both
   the order and the glyphs were the mirror of what the carousel actually does.
   Letting the row inherit the page direction puts them the right way round, and
   the SVGs are flipped below so each head points the way its button moves.
 */
.carousel__arrows {
  display: flex;
  order: 2;
  gap: 12px;
  margin-inline-start: 60px;
}

[dir="rtl"] .carousel__arrow svg {
  transform: scaleX(-1);
}

.carousel__arrow {
  display: grid;
  width: 65px;
  height: 30px;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--gold);
  cursor: pointer;
  transition: opacity 0.25s ease;
}

.carousel__arrow[disabled] {
  cursor: default;
  opacity: 0.35;
}

.carousel__arrow svg {
  width: 65px;
  height: 10px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}

.carousel__progress {
  display: flex;
  order: 1;
  align-items: center;
  height: 5px;
  gap: 0;
}

.carousel__progress span {
  width: 40px;
  height: 1px;
  background: rgba(178, 150, 83, 0.3);
  transition: height 0.3s ease, background 0.3s ease;
}

.carousel__progress span.is-active {
  height: 2px;
  background: var(--gold);
}

.projects-section__link {
  display: block;
  width: 161px;
  height: 47px;
  padding: 0;
  margin-top: 43px;
  text-align: center;
  line-height: 45px;
}

/* Partners */
/*
   The group page: eight companies as a family tree, not a list.
 *
 * Three columns. The holding company sits alone at the top of the middle one
 * with a line descending from it to the flagship, and the six operating
 * companies sit either side. That is the published arrangement and it is the
 * point of the page — it says who owns whom — which is exactly what was lost
 * when the import stripped the Elementor columns and left one long column with
 * every caption stranded away from its logo.
 *
 * Measured off the published page at 1440: three columns of equal width with
 * their logos on a shared baseline, 18px white taglines under them, and 20px
 * for the holding company's. Logos are capped by height rather than width
 * because they are wildly different shapes — 121x64 for Offices Zone against
 * 141x370 for the holding mark — and a width cap would have shrunk the wide
 * ones to nothing while leaving the tall ones towering.
 */
.subsidiaries {
  padding: 96px 0;
}

.subsidiaries .band-title {
  margin-bottom: 64px;
  text-align: center;
}

.subsidiaries__grid {
  display: grid;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 24px;
  /* Every column gets the tallest one's height, which is what lets the rows
     line up across them — see the columns below. */
  align-items: stretch;
}

/*
   Spread, not stacked.

   The middle column is much the tallest — the holding mark alone is 370px — so
   left to pack from the top the side columns finished a row and a half above
   the flagship, and the bottom of the page read as three unrelated lists. With
   the columns stretched to a common height and their items spread through it,
   the last row lands level across all three, as it does on the published page.
   The gap stays as the floor, so a short column still breathes.
 */
.subsidiaries__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 72px;
}

/* The middle column's spacing is the line's job: it grows to fill whatever is
   left between the holding company and the flagship, so the descent is as long
   as the tree is tall rather than a fixed stub. */
.subsidiaries__col--center {
  gap: 0;
}

.subsidiary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  text-align: center;
}

.subsidiary__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 106px;
}

.subsidiary__logo img {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 106px;
  object-fit: contain;
}

/* The holding mark is the tall one and the page's anchor: it is printed larger
   than the rest on the published page, and shrinking it to their cap would have
   made the parent company the smallest thing on its own family tree. */
.subsidiary--lead .subsidiary__logo {
  min-height: 370px;
}

.subsidiary--lead .subsidiary__logo img {
  max-height: 370px;
}

.subsidiary__tagline {
  margin: 0;
  max-width: 30ch;
  color: #fff;
  font-size: 18px;
  font-weight: 400;
  line-height: 1.6;
}

.subsidiary--lead .subsidiary__tagline {
  font-size: 20px;
}

/* Descent, not decoration: it exists only with a company at each end. */
.subsidiaries__line {
  flex: 1 1 auto;
  width: 1px;
  min-height: 90px;
  margin: 34px 0;
  background: var(--line);
}

.subsidiary__logo img {
  transition: opacity 0.3s ease-out;
}

.subsidiary__logo:hover img {
  opacity: 0.75;
}

@media (max-width: 900px) {
  /*
     One column below the tree's width.

     The centre column's order matters here: read top to bottom the holding
     company should still come first, so it leads rather than sitting between
     the two side columns as the source order would put it.
   */
  .subsidiaries__grid {
    grid-template-columns: 1fr;
    gap: 64px;
  }

  .subsidiaries__col--center {
    order: -1;
    gap: 64px;
  }

  .subsidiaries__line {
    display: none;
  }

  .subsidiary--lead .subsidiary__logo,
  .subsidiary--lead .subsidiary__logo img {
    max-height: 260px;
    min-height: 0;
  }
}

.partners {
  padding: 50px 0;
  overflow: hidden;
}

.partners .band-title {
  margin-bottom: 20px;
  text-align: center;
}

.carousel--partners .carousel__track {
  gap: 0;
}

.partner {
  display: grid;
  flex: 0 0 20%;
  height: 128px;
  place-items: center;
}

.partner img {
  max-width: 122px;
  max-height: 122px;
  object-fit: contain;
  filter: grayscale(1) brightness(3);
}

/* Videos */
.videos-section {
  padding: 50px 0 60px;
}

.videos-section .band-title {
  margin-bottom: 30px;
  text-align: center;
}

.videos-grid {
  display: grid;
  padding: 0 10px;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #111;
}

.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The click-to-load facade that stands in for the player until it is asked for. */
.video-frame__poster {
  position: absolute;
  display: block;
  inset: 0;
  cursor: pointer;
}

.video-frame__poster picture,
.video-frame__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-frame__play {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  display: grid;
  width: 58px;
  height: 58px;
  place-items: center;
  border: 1px solid var(--gold-bright);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.52);
  color: #fff;
  transform: translate(-50%, -50%);
  transition: background 0.2s ease, transform 0.2s ease;
}

.video-frame__poster:hover .video-frame__play,
.video-frame__poster:focus-visible .video-frame__play {
  background: rgba(0, 0, 0, 0.75);
  transform: translate(-50%, -50%) scale(1.08);
}

/* Marquee ticker */
.ticker {
  overflow: hidden;
  padding: 26px 0 30px;
  border-top: 1px solid #483f30;
  border-bottom: 1px solid #483f30;
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker 34s linear infinite;
}

.ticker__group {
  display: flex;
  align-items: center;
  gap: 0;
}

.ticker__group span {
  display: flex;
  align-items: center;
  color: var(--gold);
  font-size: 16px;
  line-height: 30px;
  white-space: nowrap;
}

.ticker__group span::after {
  width: 5px;
  height: 5px;
  margin: 0 30px;
  background: var(--gold);
  content: "";
}

@keyframes ticker {
  to {
    transform: translateX(50%);
  }
}

[dir="ltr"] .ticker__track {
  animation-name: ticker-ltr;
}

@keyframes ticker-ltr {
  to {
    transform: translateX(-50%);
  }
}

/* Home contact */
.home-contact {
  display: grid;
  /* min-height, not height: the band keeps live's 616px at rest but grows if
     validation tips appear rather than clipping them. */
  min-height: 616px;
  grid-template-columns: 52% 48%;
  align-items: center;
  overflow: hidden;
  padding: 50px 0;
  direction: ltr;
}

.home-contact__image {
  grid-row: 1;
  grid-column: 1;
}

.home-contact__form {
  grid-row: 1;
  grid-column: 2;
  padding: 0 120px 0 50px;
}

[dir="rtl"] .home-contact__form {
  direction: rtl;
}

.home-contact__form .band-title {
  margin-bottom: 32px;
}

.home-contact__image {
  display: flex;
  height: 100%;
  align-items: center;
}

.home-contact__image img {
  width: 749px;
  max-width: none;
  height: auto;
}

[dir="ltr"] .home-contact__image img {
  transform: scaleX(-1);
}

.contact-form p {
  margin: 0 0 40px;
}

.contact-form__row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 39px;
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  padding: 6px 0;
  border: 0;
  border-bottom: 1px solid #483f30;
  background: transparent;
  color: #ccc;
  font-size: 15px;
}

.contact-form textarea {
  height: 124px;
  resize: vertical;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: #ccc;
  opacity: 1;
}

.contact-form input:focus,
.contact-form textarea:focus {
  border-bottom-color: var(--gold);
  outline: 0;
}

.contact-form__actions {
  margin-bottom: 0;
  text-align: right;
}

.contact-form__actions .btn {
  width: 148px;
  height: 47px;
  padding: 0;
  line-height: 45px;
}

/* Map — the band is 700 tall but the map itself is 600, inset 50px top and
   bottom, so it does not run edge to edge like the other full-bleed sections. */
.map-section {
  height: 700px;
  padding: 50px 0;
  margin-bottom: 30px;
}

.map-section iframe {
  display: block;
  width: 100%;
  height: 600px;
  border: 0;
}

.contact-info h2 {
  font-size: 42px;
}

.contact-list {
  margin: 36px 0 0;
  padding: 0;
  list-style: none;
}

.contact-list li {
  padding: 18px 0;
  border-top: 1px solid var(--line);
}

.contact-list small {
  display: block;
  color: var(--gold);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.field {
  position: relative;
}

.field--full {
  grid-column: 1 / -1;
}

.field label {
  display: block;
  margin-bottom: 6px;
  color: #a9a39d;
  font-size: 13px;
}

.field input,
.field textarea,
.field select {
  width: 100%;
  min-height: 50px;
  padding: 10px 0;
  border: 0;
  border-bottom: 1px solid #47433e;
  border-radius: 0;
  background: transparent;
  color: #eee;
  outline: none;
}

.field textarea {
  min-height: 130px;
  resize: vertical;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--gold);
}

/* Projects */
.projects-page-section {
  padding: 74px 0 92px;
}

.projects-page-section .container {
  max-width: 1140px;
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  margin-bottom: 25px;
}

.filter-btn {
  min-height: 58px;
  padding: 20px 25px;
  border: 0;
  background: transparent;
  color: #c9c5c1;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: 0.15em;
}

.filter-btn:hover,
.filter-btn.is-active {
  color: var(--gold);
}

.projects-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 30px;
}

.projects-grid .project-card[hidden] {
  display: none;
}

.project-list-card .project-card__image {
  height: 240px;
  aspect-ratio: auto;
  background: #000;
  text-align: center;
}

.project-list-card {
  overflow: hidden;
  border: 1px solid #8e7861;
  border-radius: 3px;
  background: #000;
}

.project-list-card .project-card__image::after {
  display: none;
}

/* Fill the cell, crop what does not fit.

   `width: auto` with a fixed height sized each image by its own aspect ratio,
   so a portrait or logo-shaped hero came out a narrow strip centred in a 358px
   cell with black either side — two of the eight cards on the first page, which
   is what reads as the listing being misaligned. */
.project-list-card .project-card__image img {
  width: 100%;
  height: 240px;
  object-fit: cover;
  object-position: center;
  filter: none;
  transform: none;
}

.project-list-card:hover .project-card__image img {
  filter: none;
  transform: none;
}

.project-list-card .project-card__content {
  position: static;
  display: block;
  min-height: 0;
  padding: 0;
  background: none;
}

.project-list-card .project-card__content h3 {
  display: flex;
  min-height: 61px;
  align-items: center;
  margin: 0;
  padding: 13px 10px 11px;
  border-bottom: 1px solid #483f30;
  color: #fff;
  font-size: 22px;
  font-weight: 600;
  line-height: 22px;
  text-transform: uppercase;
}

.project-data {
  display: grid;
  gap: 0;
  margin-inline-start: 10px;
  margin-inline-end: 0;
  padding: 0;
  color: #fff;
  font-size: 18px;
  line-height: 23px;
  list-style: none;
}

.project-data li {
  display: grid;
  min-height: 53px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 6px;
  padding: 15px 0;
  border-bottom: 1px solid #483f30;
}

.project-data li:last-child {
  border-bottom: 0;
}

.project-data b {
  color: #b29653;
  font-size: 15px;
  font-weight: 700;
  line-height: 18px;
  text-align: start;
}

.project-data span {
  color: #fff;
  font-size: 18px;
  line-height: 23px;
  text-align: start;
}

.projects-subtitle {
  margin-top: 90px;
}

/* Project detail */
.project-intro {
  display: grid;
  grid-template-columns: 0.78fr 1.22fr;
  align-items: center;
  gap: 80px;
}

.project-intro__image {
  position: relative;
}

.project-intro__image::before {
  position: absolute;
  top: -22px;
  right: -22px;
  bottom: 22px;
  left: 22px;
  border: 1px solid var(--line);
  content: "";
}

.project-intro__image img {
  position: relative;
  width: 100%;
  max-height: 720px;
  object-fit: cover;
}

.project-intro__copy h2 {
  font-size: clamp(34px, 4.2vw, 55px);
}

.project-logo {
  width: 118px;
  margin-bottom: 28px;
}

.facts {
  margin: 38px 0 0;
}

.fact {
  display: grid;
  grid-template-columns: 0.65fr 1.35fr;
  gap: 20px;
  padding: 15px 0;
  border-top: 1px solid var(--line);
}

.fact dt {
  color: var(--gold);
  font-size: 13px;
  text-transform: uppercase;
}

.fact dd {
  margin: 0;
  color: #e1ded9;
}

.location-grid {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: 80px;
}

.location-copy h2 {
  font-size: 38px;
}

.distances {
  display: grid;
  gap: 20px;
}

.distance-head {
  display: flex;
  justify-content: space-between;
  margin-bottom: 7px;
  color: #e6e2dd;
  font-size: 13px;
}

.distance-head span:last-child {
  color: var(--gold);
}

.distance-bar {
  height: 3px;
  background: #2a2826;
}

.distance-bar i {
  display: block;
  width: var(--progress);
  height: 100%;
  background: var(--gold);
}

.floor-grid,
.luxury-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 70px;
}

.floor-plan {
  padding: 42px;
  background: #f0ede6;
}

.floor-plan img {
  width: 100%;
  max-height: 620px;
  object-fit: contain;
}

.floor-models {
  display: grid;
  gap: 40px;
}

.floor-model {
  display: grid;
  grid-template-columns: 0.72fr 1.28fr;
  align-items: center;
  gap: 50px;
  padding: 34px;
  border: 1px solid var(--line);
}

.floor-model:nth-child(even) .floor-model__image {
  order: 2;
}

.floor-model__image {
  padding: 28px;
  background: #f0ede6;
}

.floor-model__image img {
  width: 100%;
  max-height: 520px;
  object-fit: contain;
}

.floor-model h3 {
  margin-bottom: 14px;
  font-size: clamp(26px, 3vw, 38px);
}

.luxury-image {
  display: grid;
  min-height: 520px;
  place-items: center;
}

.luxury-image img {
  max-width: 420px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.gallery-item {
  position: relative;
  min-height: 330px;
  overflow: hidden;
  border: 0;
  background: #111;
  cursor: zoom-in;
}

/*
 * A gallery slide has to say how wide it is.
 *
 * `.gallery-item` was written for `.gallery-grid`, where the grid column
 * decides the width and the item never needs an opinion. `x-gallery` then put
 * the same class inside `.carousel__track`, which is flex — and there nothing
 * decides it: the item defaults to `flex: 0 1 auto`, its only child is an image
 * at `width: 100%` with no definite parent width to resolve against, so every
 * slide collapsed to **12.6px** and a sixteen-photograph album rendered as a
 * row of vertical stripes.
 *
 * Three across, which is what the grid it replaced showed, with the two gaps
 * subtracted so the third slide ends flush against the viewport instead of
 * being pushed a gap's width past it. Scoped to the track, so the grid usage —
 * where a width here would fight the column — is untouched.
 */
.carousel__track > .gallery-item {
  flex: 0 0 calc((100% - 2 * var(--carousel-gap)) / 3);
}

@media (max-width: 900px) {
  .carousel__track > .gallery-item {
    flex-basis: calc((100% - var(--carousel-gap)) / 2);
  }
}

@media (max-width: 600px) {
  .carousel__track > .gallery-item {
    flex-basis: 100%;
  }
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: 0.5s var(--ease);
}

.gallery-item:hover img {
  transform: scale(1.06);
}

.map-placeholder {
  position: relative;
  min-height: 460px;
  overflow: hidden;
  border: 1px solid var(--line);
  background-color: #14110c;
  background-image:
    linear-gradient(30deg, transparent 48%, rgba(184, 154, 88, 0.13) 49%, rgba(184, 154, 88, 0.13) 51%, transparent 52%),
    linear-gradient(120deg, transparent 48%, rgba(184, 154, 88, 0.13) 49%, rgba(184, 154, 88, 0.13) 51%, transparent 52%);
  background-size: 130px 130px;
}

.map-frame {
  width: 100%;
  min-height: 520px;
  border: 0;
  filter: grayscale(1) sepia(0.35) brightness(0.72) contrast(1.05);
}

.map-placeholder::before,
.map-placeholder::after {
  position: absolute;
  border: 1px solid rgba(184, 154, 88, 0.25);
  border-radius: 46% 54% 39% 61%;
  content: "";
}

.map-placeholder::before {
  inset: 12% 8%;
  transform: rotate(-8deg);
}

.map-placeholder::after {
  inset: 25% 20%;
  transform: rotate(17deg);
}

.map-pin {
  position: absolute;
  z-index: 2;
  top: 48%;
  left: 50%;
  display: grid;
  width: 54px;
  height: 54px;
  place-items: center;
  border: 1px solid var(--gold);
  border-radius: 50% 50% 50% 0;
  background: var(--gold);
  color: #000;
  transform: translate(-50%, -50%) rotate(-45deg);
}

.map-pin span {
  transform: rotate(45deg);
}

.register-bar {
  display: flex;
  min-height: 120px;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  padding: 30px 48px;
  border: 1px solid var(--line);
}

.register-bar h2 {
  margin: 0;
  font-size: 30px;
}

/* Project detail - matched to the original single project template */
[data-page="project"] .page-hero {
  min-height: 220px;
}

[data-page="project"] .page-hero h1 {
  margin-bottom: 4px;
  font-size: 36px;
  line-height: 46px;
}

[data-page="project"] .breadcrumbs {
  font-size: 18px;
  line-height: 25px;
}

[data-page="project"] .nav-list a::after {
  display: none;
}

/*
   The photograph a project page opens with, above the logo.

   Held to the same measure as the rest of the page rather than bled to the
   viewport edge — the published site sets it inside the content column, and a
   full-bleed image here fights the title band directly above it, which is
   inset. `aspect-ratio` with `object-fit: cover` so a portrait source cannot
   push the logo a screen and a half down the page.
 */
.project-cover-section {
  padding: 40px 0 0;
}

.project-cover img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 620px;
  object-fit: cover;
}

.project-logo-stage {
  display: grid;
  min-height: 0;
  place-items: center;
  padding: 10px 24px;
}

.project-logo-stage img {
  width: 300px;
  height: auto;
  max-height: 300px;
  object-fit: contain;
}

.project-overview-section {
  padding: 30px 0 40px;
}

[data-page="project"] .project-intro {
  width: min(1140px, calc(100% - 48px));
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Centred against the artwork, not hung from its top edge. The fact list is
     always shorter than the image, so `start` left it stranded at the top with
     a growing well of empty space beneath it. */
  align-items: center;
  gap: 20px;
  padding-inline: 10px;
}

/* One column when the band has no artwork, so the copy takes the width instead
   of sitting in half of it beside a dead column. Two projects turn the overview
   image off, and both read as a half-empty band without this. */
.project-intro:not(:has(.project-intro__media)),
[data-page="project"] .project-intro:not(:has(.project-intro__media)) {
  grid-template-columns: minmax(0, 1fr);
}

[data-page="project"] .project-intro__image::before {
  display: none;
}

[data-page="project"] .project-intro__image img {
  width: 100%;
  height: auto;
  max-height: none;
  object-fit: cover;
}

[data-page="project"] .project-intro__image--portrait {
  display: grid;
  place-items: center;
}

[data-page="project"] .project-intro__image--portrait img {
  width: auto;
  max-width: 250px;
  max-height: 500px;
  object-fit: contain;
}

[data-page="project"] .project-intro__copy {
  padding-top: 0;
}

/* Flex column so the title and the fact list shrink to their own width and sit
   centred in the half they are given. Stretched to the full column, the fact
   rows right-align their values against a 550px measure and leave a ~300px
   well of dead space on the outer edge, which reads as the band being hung off
   to one side.

   Only when there is artwork to sit beside. The two projects that turn the
   overview image off give the copy the whole 1120px row (see the `:not(:has())`
   rule above), and centring a short list in a measure that wide strands it in
   the middle of the band, away from the paragraph it belongs to. */
[data-page="project"] .project-intro:has(.project-intro__media) .project-intro__copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Centring makes the list shrink-to-fit, and a shrink-wrapped `0.8fr 1.2fr`
   resolves the label track below its own max-content — every multi-word label
   ("وصف المشروع:", "Project Description:") wrapped onto a second line.

   Each `.fact` was its own two-column grid, so the tracks were sized per row
   and could not be widened to a shared measure without hard-coding one. Lift
   the grid to the list and let the rows pass through, so all five rows share
   one pair of tracks: `max-content` on the labels means no label wraps in
   either language, and the list still shrinks to its own content so the flex
   centring above has something to centre. `minmax(0, …)` on the values lets
   them wrap under real pressure rather than overflow the column. */
[data-page="project"] .project-intro:has(.project-intro__media) .project-intro__copy .facts {
  display: grid;
  grid-template-columns: max-content minmax(0, max-content);
  max-width: 100%;
  column-gap: 14px;
  /* Rows are no longer boxes, so their `padding: 3px 0` has to be rebuilt from
     the list: 6px between rows, and 3px at each end for the padding the first
     and last rows used to contribute. Keeps the band the same height as the
     Blade original. */
  padding-block: 3px;
  row-gap: 6px;
}

[data-page="project"] .project-intro:has(.project-intro__media) .project-intro__copy .fact {
  display: contents;
}

/* Prose keeps the full measure. `align-items: center` shrink-wraps every child,
   which is what the fact list wants but not a paragraph — on the projects that
   carry an overview blurb it pulled the heading into a 227px block floating
   above a flush-left paragraph. Only the list is meant to centre. */
[data-page="project"] .project-intro:has(.project-intro__media) .project-intro__copy > .project-intro__body,
[data-page="project"] .project-intro:has(.project-intro__media) .project-intro__copy > p {
  align-self: stretch;
}

[data-page="project"] .project-intro__copy h2,
[data-page="project"] .location-copy h2 {
  margin-bottom: 18px;
  color: var(--project-accent, var(--gold));
  font-size: 22px;
}

[data-page="project"] .project-intro__copy p,
[data-page="project"] .location-copy p {
  color: #ddd9d4;
  font-size: 15px;
  line-height: 1.8;
}

[data-page="project"] .facts {
  margin-top: 26px;
}

[data-page="project"] .fact {
  grid-template-columns: 0.8fr 1.2fr;
  gap: 14px;
  padding: 3px 0;
  border: 0;
}

[data-page="project"] .fact dt,
[data-page="project"] .fact dd {
  font-size: 18px;
  line-height: 23px;
}

[data-page="project"] .fact dt {
  color: var(--project-accent, var(--gold));
}

.project-location-section {
  min-height: 617px;
  padding: 56px 0 70px;
}

[data-page="project"] .location-grid {
  width: min(1140px, calc(100% - 48px));
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 20px;
  padding-inline: 10px;
}

.project-location-link {
  min-width: 104px;
  min-height: 44px;
  margin-top: 18px;
  padding: 8px 24px;
}

[data-page="project"] .distances {
  gap: 15px;
}

[data-page="project"] .distance-head {
  margin-bottom: 4px;
  color: #f2f0ed;
  font-size: 14px;
  /* Place names read as labels rather than as body copy. */
  font-weight: 700;
}

[data-page="project"] .distance-head span:last-child {
  display: none;
}

[data-page="project"] .distance-bar {
  position: relative;
  height: 20px;
  overflow: hidden;
  background: #b0a9a9;
}

/*
   The duration sits at the filled end of the bar, not the far end.
 *
   The bar grows from the inline start, and the row is clipped, so a label
   pinned to `flex-end` sat at the boundary where the fill runs out. On a narrow
   viewport a short trip — two or three minutes — left almost no bar to hold it
   and the number was cut in half. Anchored to the start it has the whole filled
   length behind it at every width.

   White rather than black: the number reads as a value on the accent, the same
   way the place name above it reads on the page.
 */
[data-page="project"] .distance-bar i {
  position: relative;
  display: flex;
  height: 100%;
  align-items: center;
  justify-content: flex-start;
  padding-inline-start: 8px;
  background: var(--project-accent, #b89a58);
  color: #fff;
  font-style: normal;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.project-floor-section {
  padding: 0 0 20px;
}

.project-floor-section .section-title {
  margin: 0 auto 36px;
  font-size: 22px;
  text-align: center;
}

.floor-stack {
  display: grid;
  max-width: 1120px;
  gap: 56px;
  margin-inline: auto;
}

.floor-stack figure {
  margin: 0;
  overflow: hidden;
  background: #f1eee8;
}

.floor-stack img {
  width: 100%;
  aspect-ratio: 1300 / 919;
  object-fit: cover;
}

.project-luxury-section {
  min-height: 440px;
  padding: 20px 0;
}

[data-page="project"] .luxury-grid {
  width: min(1140px, calc(100% - 48px));
  min-height: 400px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  padding-inline: 10px;
}

[data-page="project"] .luxury-grid--single {
  min-height: 0;
  grid-template-columns: minmax(0, 1fr);
}

[data-page="project"] .luxury-grid--single > div {
  max-width: 840px;
  margin-inline: auto;
}

/* Bare anchors the import left at the top of a project body — brochure and
   plan links — dressed as the buttons they were. `:not(.btn)` because a real
   button is already one: re-dressing it would repaint its label gold, and on a
   filled button that is gold on gold. */
[data-page="project"] .article-prose > a:not(.btn) {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  margin: 0 0 18px 10px;
  padding: 8px 24px;
  border: 1px solid var(--gold);
  color: var(--gold);
}

.project-luxury-section .section-title {
  margin-bottom: 18px;
  font-size: 22px;
}

.project-luxury-section p {
  max-width: 540px;
  margin-bottom: 0;
  color: #ddd9d4;
  font-size: 15px;
  line-height: 1.8;
}

.project-brochure {
  min-height: 44px;
  margin-top: 24px;
  padding: 8px 24px;
}

[data-page="project"] .luxury-image {
  min-height: 400px;
}

[data-page="project"] .luxury-image img {
  width: 400px;
  max-width: 100%;
}

.project-gallery-section {
  padding: 23px 0 13px;
}

/*
   The project gallery is a contained carousel with its arrows on the sides.
 *
 * It was running the full 1440 — the strip bleeding off both edges — with the
 * two arrows dropped into the bottom-left corner under it. The published page
 * keeps the tiles inside the same column the rest of the page uses and puts a
 * chevron either side of them, level with the middle of the pictures.
 *
 * Scoped to `.project-gallery-section`, so the post-gallery use of the same
 * `x-gallery` component — three across inside an article's prose — is
 * untouched. This is the shape every project page gets.
 */
.project-gallery-section .carousel {
  position: relative;
  width: min(calc(100% - 340px), 1100px);
  margin-inline: auto;
}

/*
   The foot becomes an overlay rail rather than a row beneath.

   Stretched 56px past each edge so the chevrons sit outside the pictures
   instead of on top of them, and `pointer-events: none` so the rail itself
   never swallows a click meant for a tile — only the buttons take one back.
 */
.project-gallery-section .carousel__foot {
  position: absolute;
  z-index: 2;
  /* Stretched to the carousel rather than given a height. With the foot taken
     out of flow the carousel is exactly as tall as its viewport, so this
     centres on the pictures whichever tile height the variant uses — 240px on
     the compact layout, 350px elsewhere. A hardcoded 240 left the arrows 55px
     high on every page that is not compact. */
  inset-block: 0;
  inset-inline: -56px;
  /* `height: auto` on purpose: the base `.carousel__foot` sets `height: 30px`,
     and an explicit height beats a pair of insets — so without this the rail
     was a 30px strip pinned to the top and both chevrons sat above the
     pictures instead of level with them. */
  height: auto;
  margin: 0;
  pointer-events: none;
}

.project-gallery-section .carousel__arrows {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: space-between;
  /* The base rule gives this row a 60px inline-start margin, which in Arabic is
     a margin on the *right* — it dragged the leading chevron 60px in from the
     rail and sat it on top of the last picture while the other stayed clear. */
  margin: 0;
}

.project-gallery-section .carousel__arrow {
  pointer-events: auto;
}

/*
   The published page's arrow: a bare gold chevron, not the site's long line.

   Measured on it — 32x32, `rgb(178,150,70)`, no background and no border, sat
   just outside the pictures. The site's own carousels keep their line-with-a-
   head; this variant exists because the project gallery is the one place that
   draws them differently.
 */
.carousel__arrow--chevron,
.project-gallery-section .carousel__arrow--chevron {
  width: 32px;
  height: 32px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  /* The published page's own gold. Stated on both selectors because the plain
     class alone lost to the generic arrow styling and the chevron came out
     grey. */
  color: #b29646;
}

.carousel__arrow--chevron svg {
  width: 100%;
  height: 100%;
}

.carousel__arrow--chevron:hover,
.carousel__arrow--chevron:focus-visible {
  background: none;
  color: var(--gold-bright);
}

/* The published gallery has no progress rule under it — the arrows are the
   whole control. */
.project-gallery-section .carousel__progress {
  display: none;
}

@media (max-width: 1100px) {
  /* No room outside the tiles at this width, so the rail sits over them. */
  .project-gallery-section .carousel {
    width: calc(100% - 80px);
  }

  .project-gallery-section .carousel__foot {
    inset-inline: 8px;
  }
}

.project-body-gallery-section {
  padding: 23px 0 30px;
}

[data-page="project"] .project-body-gallery-section .gallery-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

[data-page="project"] .project-body-gallery-section .gallery-item {
  min-height: 350px;
  height: 350px;
}

[data-page="project"] .gallery-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}

[data-page="project"] .gallery-item {
  min-height: 350px;
  height: 350px;
}

[data-page="project"] .gallery-item:hover img {
  transform: none;
}

.project-map-section {
  height: 450px;
}

[data-page="project"] .project-map-section .map-frame {
  width: 100%;
  height: 450px;
  min-height: 450px;
  filter: grayscale(1) sepia(0.25) brightness(0.62) contrast(1.1);
}

.project-post-nav {
  min-height: 113px;
  padding: 24px 0;
}

.project-post-nav__inner {
  display: grid;
  min-height: 65px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  text-align: center;
}

.project-post-nav a {
  color: var(--gold);
  font-size: 13px;
  line-height: 1.5;
}

.project-post-nav a:first-child {
  text-align: right;
}

.project-post-nav a:last-child {
  text-align: left;
}

.project-post-nav span,
.project-post-nav strong {
  display: block;
}

.project-post-nav strong {
  color: #ddd9d4;
  font-weight: 400;
}

.project-share {
  position: relative;
}

.project-share::after {
  display: block;
  width: 1px;
  height: 38px;
  margin: 10px auto 0;
  background: var(--line);
  content: "";
}

/* Sticky action bar
   -----------------
   Replaces the project-only interest dock. The height is a custom property
   because two other things have to know it: the page reserves that much space
   at the bottom so the bar stops overlaying the last of the footer, and the
   back-to-top arrow lifts clear of it. Both were wrong before — nothing
   reserved the dock's 70px, and on mobile the arrow sat inside it. */
:root {
  /* Two variables, and they must stay two. The bar's own floor is fixed; the
     reservation is whatever the bar measured, which site.js writes. Pointing
     the bar's min-height at the value JS writes makes a feedback loop — the bar
     grows to its own measurement and never shrinks back. */
  --action-bar-min-height: 70px;
  --action-bar-height: 70px;
}

.action-bar {
  position: fixed;
  z-index: 95;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  min-height: var(--action-bar-min-height);
  align-items: center;
  border-top: 1px solid var(--project-accent, var(--gold));
  background: rgba(0, 0, 0, 0.96);
}

/* Device is the one targeting rule the server cannot answer, so the browser
   takes the bar away when it does not belong here. Hiding by default and
   showing on script would have meant no bar at all with scripting off. */
.action-bar.is-hidden {
  display: none;
}

.action-bar__inner {
  display: flex;
  width: 100%;
  max-width: var(--max);
  align-items: center;
  justify-content: center;
  padding: 10px 20px;
  margin-inline: auto;
  gap: 16px;
  flex-wrap: wrap;
}

.action-bar__message {
  margin: 0;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.action-bar__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.action-bar .btn {
  min-width: 284px;
  min-height: 47px;
  padding: 8px 24px;
  border-color: var(--project-accent, var(--gold));
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
}

/* The accent is the text colour on an outline button and the fill colour on a
   filled one — never both at once. The old dock could set `color: accent` on
   every .btn because it only ever drew one outline button; doing that here put
   gold text on a gold fill and made the label unreadable. */
.action-bar .btn:not(.btn--fill) {
  color: var(--project-accent, var(--gold));
}

.action-bar .btn:not(.btn--fill):hover,
.action-bar .btn:not(.btn--fill):focus-visible {
  color: #000;
}

.action-bar .btn--fill {
  background-image: linear-gradient(
    0deg,
    var(--project-accent, var(--gold)) 0,
    var(--project-accent, var(--gold)) 100%
  );
  color: #fff;
}

/* The 284px minimum is wider than a small phone. With two or three buttons it
   was wider than the screen even before this bar could hold more than one. */
@media (max-width: 767px) {
  .action-bar .btn {
    min-width: 0;
    flex: 1 1 auto;
    padding: 8px 14px;
  }

  .action-bar__inner {
    padding: 8px 12px;
    gap: 10px;
  }

  .action-bar__message {
    width: 100%;
    text-align: center;
  }
}

/* Nothing reserved the old dock's height, so it covered the last 70px of the
   footer on every project page. The class is on <body> from the server, so the
   space is reserved before any script runs; site.js then corrects the height to
   what the bar actually measures, which on a narrow screen is more than one row.
   A page with no bar never gets the class and keeps its full height. */
body.has-action-bar {
  padding-bottom: var(--action-bar-height);
}

body.has-action-bar .back-to-top {
  bottom: calc(var(--action-bar-height) + 16px);
}

/* Removed by the device rule: the space goes back with it. */
body.has-action-bar.action-bar-hidden {
  padding-bottom: 0;
}

body.has-action-bar.action-bar-hidden .back-to-top {
  bottom: 56px;
}

@media (max-width: 767px) {
  body.has-action-bar.action-bar-hidden .back-to-top {
    bottom: 20px;
  }
}

/* Articles */
.articles-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 56px 26px;
}

/* The news listing runs two-up on the live site, unlike articles and media,
   with a correspondingly wider image crop. */
.articles-grid--wide {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.articles-grid--wide .article-card__image {
  aspect-ratio: 1.98;
}

.article-card__body {
  min-height: 168px;
  padding: 22px 6px 0;
}

.article-card h2,
.article-card h3 {
  margin-bottom: 10px;
  color: #d6d1cc;
  font-size: 22px;
}

.article-card__meta {
  margin-bottom: 10px;
  color: #8f8a85;
  font-size: 13px;
}

/* Media library featured player — 800x450 above the thumbnail grid, as on the
   live page's YouTube playlist widget. */
.media-player {
  margin: 0 auto 30px;
  width: min(800px, 100%);
}

.media-player__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #111;
}

.media-player__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Tiles past the reveal step. Hidden rather than unrendered so "show more" is
   a class toggle and not a request. The tile's own styling is further down. */
.media-grid .article-card[hidden] {
  display: none;
}

/*
   The in-article contact pair.

   Inside .article-prose, so it needs its own vertical rhythm rather than the
   paragraph margins around it. Wraps on a narrow screen instead of shrinking
   the labels, which in Arabic are long enough to break mid-word otherwise.
 */
.contact-cta {
  display: flex;
  flex-wrap: wrap;
  margin: 38px 0;
  gap: 16px;
}

.contact-cta .btn {
  flex: 1 1 260px;
  max-width: 420px;
}

@media (max-width: 600px) {
  .contact-cta .btn {
    flex-basis: 100%;
    max-width: none;
  }
}

/* The reveal button, centred under the grid. Hidden until the script decides
   there is something left to reveal. */
.media-more {
  display: flex;
  justify-content: center;
  margin-top: 50px;
}

.media-more[hidden] {
  display: none;
}

/*
 * A video tile is not an article card, and the difference is three rules.
 *
 * This block previously said the opposite: overrides were removed here in
 * favour of "the title below the still at the same size as every other card".
 * The client has asked for the published site's treatment, and measuring it
 * settles why — an article card reserves 168px below the image for a title, a
 * date and an excerpt, and a video has only a title, so ours came out 422px
 * tall against the published page's 261 with a field of black under every
 * caption.
 *
 * 16/9 is the shape of the picture. The still itself now comes from
 * `maxresdefault`, which is 1280x720 and has no bars to hide — see
 * Video::thumbnailUrl(). The ratio still earns its place twice over: it is what
 * makes the row of tiles agree in height, and if a video without a maxres still
 * falls back to the 4:3 `sddefault`, `object-fit: cover` scales by width and
 * crops exactly the 60px of letterbox off each edge.
 *
 * One case neither fixes: a video shot portrait or square is padded at the
 * sides in every size YouTube offers, and no crop takes side bars off without
 * eating the picture. That one wants a landscape thumbnail uploaded against the
 * video, which the dashboard already accepts.
 */
.media-grid .article-card__image {
  aspect-ratio: 16 / 9;
}

/* No date and no excerpt, so there is nothing to reserve room for. */
.media-grid .article-card__body {
  min-height: 0;
  padding: 14px 6px 0;
}

.media-grid .article-card h2 {
  margin-bottom: 0;
  color: #fff;
  font-size: 14px;
  line-height: 1.6;
}

/* The blog grid's 56px row gap is spaced for cards with an excerpt under the
   title. Under a two-line caption it read as a hole; the published page runs
   32px between a caption and the next still, so that is what this uses. */
.media-grid {
  row-gap: 32px;
}


.media-thumb {
  cursor: pointer;
}

.media-thumb span {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  display: grid;
  width: 58px;
  height: 58px;
  place-items: center;
  border: 1px solid var(--gold-bright);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.52);
  color: #fff;
  transform: translate(-50%, -50%);
}

.pagination {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-top: 70px;
  color: var(--gold);
}

.pagination a,
.pagination span {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
}

.pagination .current {
  border: 1px solid var(--gold);
}

.article-detail {
  width: min(calc(100% - 48px), 1040px);
  margin-inline: auto;
  padding: 70px 0 110px;
}

.article-cover {
  width: 100%;
  max-height: 690px;
  margin-bottom: 52px;
  object-fit: cover;
}

.article-prose {
  color: #aaa6a1;
  font-size: 17px;
}

.article-prose h2 {
  margin-top: 48px;
  margin-bottom: 18px;
  font-size: clamp(28px, 3vw, 40px);
}

.article-prose h3 {
  margin-top: 32px;
  color: var(--gold-bright);
  font-size: 26px;
}

.article-prose p,
.article-prose li {
  margin-bottom: 12px;
}

/*
 * Body links, not buttons.
 *
 * Without the `:not(.btn)` this rule claims every anchor in an article, and it
 * is specific enough to win: `.article-prose a` is (0,1,1) against
 * `.btn--fill`'s (0,1,0). So a filled button inside an article lost its white
 * label to gold — gold text on the gold fill, which is a button with no writing
 * on it, and that is exactly how the in-article contact pair rendered.
 *
 * The rule below for `.article-actions` is the same bug patched once for one
 * container, back when that was the only pair of buttons a body could contain.
 * Blocks can be dropped anywhere in a body now, so the fix belongs here where
 * the overreach is, rather than being re-patched per container forever.
 */
.article-prose a:not(.btn) {
  color: var(--gold);
  text-decoration: underline;
}

.article-actions {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
  margin: 42px 0;
}

.article-prose .article-actions .btn {
  color: #fff;
  text-decoration: none;
}

/* These are all filled buttons, so hovering empties the gold away and the
   label has to stay light — black would land on the dark page background. */
.article-prose .article-actions .btn:hover,
.article-prose .article-actions .btn:focus-visible {
  color: #fff;
}

/* Share row and post navigation, matching the live article layout: both are
   centred, ungoverned by rules, and the share icons are plain gold glyphs. */
.article-share {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: 60px;
}

.article-share > span {
  color: var(--gold);
  font-size: 20px;
  line-height: 1.25;
}

.share-icons {
  display: flex;
  align-items: center;
  gap: 4px;
}

.share-icons a {
  display: grid;
  width: 17px;
  height: 19px;
  place-items: center;
  color: var(--gold);
  text-decoration: none;
  transition: color 0.25s ease;
}

.share-icons a:hover {
  color: var(--gold-bright);
}

.share-icons svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.post-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  margin-top: 40px;
}

.post-nav a {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--gold);
  font-size: 15px;
  text-decoration: none;
}

.post-nav__arrow {
  width: 26px;
  height: 26px;
  flex: none;
  fill: currentColor;
}

.post-nav__arrow--flip {
  transform: scaleX(-1);
}

/* Static detail-page variants used by the remaining cards */
.variant-project-visual {
  padding-top: 72px;
}

.variant-project-visual img {
  width: 100%;
  height: min(68vw, 680px);
  object-fit: cover;
}

.variant-project-summary {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 80px;
  padding-top: 82px;
  padding-bottom: 90px;
}

.variant-project-summary h2,
.variant-project-copy h2 {
  margin-bottom: 20px;
  font-size: clamp(28px, 3.2vw, 44px);
}

.variant-project-summary p,
.variant-project-copy p {
  color: #c9c5c0;
  line-height: 1.95;
}

.variant-project-summary .facts {
  margin-top: 0;
}

.variant-project-summary .fact {
  padding: 13px 0;
  border-top: 1px solid var(--line);
}

.variant-project-copy {
  padding: 90px 0;
}

.variant-project-copy .container {
  max-width: 880px;
  text-align: center;
}

.simple-article-meta {
  margin: -30px 0 42px;
  color: var(--gold);
  font-size: 14px;
}

.simple-article-lead {
  color: #d7d3ce;
  font-size: 20px;
  line-height: 1.9;
}

/* About and contact */
.story-grid,
.contact-page-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  gap: 80px;
}

.story-image {
  position: relative;
  min-height: 580px;
}

.story-image img {
  width: 100%;
  height: 100%;
  min-height: 580px;
  object-fit: cover;
}

.story-image::after {
  position: absolute;
  top: 24px;
  right: 24px;
  bottom: -24px;
  left: -24px;
  border: 1px solid var(--line);
  content: "";
}

.values-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-inline-start: 1px solid var(--line);
}

.values-grid--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.values-grid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.values-grid--two .value-card,
.values-grid--three .value-card {
  min-height: 360px;
}

.services-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.value-card {
  min-height: 300px;
  padding: 38px 30px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.value-card strong {
  display: block;
  margin-bottom: 66px;
  color: rgba(184, 154, 88, 0.28);
  font-family: Arial, sans-serif;
  font-size: 64px;
  font-weight: 300;
}

.value-card h3 {
  font-size: 24px;
}

.office-card {
  padding: 44px;
  border: 1px solid var(--line);
}

.office-card h2 {
  font-size: 36px;
}

.contact-map {
  margin-top: 70px;
}

/* Footer */
.site-footer {
  border-top: 0;
}

.footer-pattern {
  padding: 41px 0 40px;
  background-image: url("/assets/line-pattern.png");
  background-position: center;
  background-size: cover;
}

.footer-shell {
  width: min(calc(100% - 48px), 1292px);
  margin-inline: auto;
}

.footer-main {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 30px;
  min-height: 302px;
}

.footer-col {
  padding: 0;
  font-size: 15px;
  line-height: 1.67;
}

.footer-col h3 {
  margin-bottom: 11px;
  font-size: 28px;
  line-height: 1.1111;
}

.footer-col h4 {
  margin-bottom: 20px;
  font-size: 20px;
  line-height: 1.2;
}

.footer-col ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Text links only — the social tiles are already gold, so tinting their glyph
   gold on hover would make it vanish into its own background. */
.footer-col a:hover {
  color: var(--gold);
}

.footer-col .socials a:hover {
  color: #fff;
  background: var(--gold-bright);
}

.footer-contact {
  padding-inline-end: 15%;
}

.footer-contact p {
  margin-bottom: 14px;
  font-size: 16px;
  line-height: 1.2;
}

.footer-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px;
  font-size: 16px;
}

.footer-links li {
  line-height: 25px;
}

.footer-office p {
  margin-bottom: 0;
}

.footer-office .btn {
  width: 216px;
  min-height: 46px;
  margin-top: 35px;
  font-size: 15px;
}

.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 59px;
}

.socials a {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border-radius: 1px;
  background: #b3975a;
  color: #fff;
}

.socials svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

.footer-bottom {
  min-height: 193px;
  padding-top: 20px;
  color: #8e8a86;
  font-size: 15px;
}

.footer-bottom__inner {
  display: grid;
  min-height: 173px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
}

.footer-brand {
  justify-self: start;
  margin-inline-start: 16px;
}

.footer-brand img {
  width: 300px;
  height: 115px;
  object-fit: contain;
}

.footer-copyright {
  justify-self: end;
  line-height: 25px;
}

.footer-copyright strong {
  color: #bbb7b2;
  font-weight: 600;
}

/* Desktop side panel */
.desktop-side-cover {
  position: fixed;
  z-index: 1002;
  inset: 0;
  background: transparent;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
}

.desktop-side-panel {
  position: fixed;
  z-index: 9999;
  top: 0;
  right: -500px;
  width: 500px;
  height: 100vh;
  min-height: 100%;
  padding: 146px 80px 35px;
  border-left: 1px solid #b29653;
  background: #000;
  color: #fff;
  overflow-y: auto;
  text-align: center;
  visibility: hidden;
  transition: right 0.6s cubic-bezier(0.77, 0, 0.175, 1), visibility 0.6s cubic-bezier(0.77, 0, 0.175, 1);
}

.side-panel-open .desktop-side-cover {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

body.side-panel-open {
  overflow: hidden;
}

.side-panel-open .desktop-side-panel {
  right: 0;
  visibility: visible;
}

.desktop-side-panel__close {
  position: absolute;
  z-index: 2;
  top: 42px;
  right: 69px;
  display: grid;
  width: 28px;
  height: 27px;
  padding: 0;
  place-items: center;
  border: 0;
  background: transparent;
  color: #b29653;
  cursor: pointer;
}

.desktop-side-panel__close svg {
  width: 27.33px;
  height: 24.5px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}

@media (hover: hover) {
  .desktop-side-panel__close:hover path {
    animation: qode-draw 0.8s cubic-bezier(0.57, 0.39, 0, 0.86) 1 forwards;
  }

  .desktop-side-panel__close:hover path:nth-of-type(2) {
    animation-delay: 0.2s;
  }
}

.desktop-side-panel__inner {
  width: 100%;
}

.desktop-side-panel__logo {
  display: block;
  width: 75px;
  height: 75px;
  margin-inline: auto;
}

.desktop-side-panel__logo img {
  width: 75px;
  height: 75px;
  object-fit: contain;
}

.desktop-side-panel__socials {
  display: flex;
  justify-content: center;
  gap: 5px;
  margin-top: 30px;
  direction: ltr;
}

.desktop-side-panel__socials a {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border-radius: 1px;
  background: #b3975a;
  color: #fff;
  transition: background-color 0.25s ease, color 0.25s ease;
}

.desktop-side-panel__socials a:hover,
.desktop-side-panel__socials a:focus-visible {
  background: #c1a68a;
  color: #000;
  outline: none;
}

.desktop-side-panel__socials svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

.desktop-side-panel__details {
  margin-top: 63px;
  font-size: 15px;
  line-height: 25px;
}

.desktop-side-panel__details p {
  margin-bottom: 12px;
}

.desktop-side-panel__details a:hover {
  color: var(--gold);
}

/* Floating contact */
.floating-contact {
  position: fixed;
  z-index: 90;
  top: 50%;
  left: 0;
  width: 53px;
  transform: translateY(-50%);
}

[dir="ltr"] .floating-contact {
  right: 0;
  left: auto;
}

.floating-contact__toggle,
.floating-contact__action {
  display: grid;
  width: 53px;
  place-items: center;
  border: 0;
  color: #fff;
  cursor: pointer;
}

.floating-contact__toggle {
  height: 32px;
  background-color: #000;
  background-image: repeating-linear-gradient(90deg, transparent 0 7px, rgba(184, 154, 88, 0.2) 7px 8px);
}

.floating-contact__toggle svg {
  width: 19px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.5;
  transition: transform 0.3s ease;
}

.floating-contact__actions {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.floating-contact__action {
  height: 53px;
  border-bottom: 2px solid #050505;
  background: #b29353;
  transition: background-color 0.25s ease;
}

.floating-contact__action:hover,
.floating-contact__action:focus-visible {
  background: var(--gold-bright);
  outline: none;
}

.floating-contact__action svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

.floating-contact__action .icon-whatsapp,
.floating-contact__action .icon-phone {
  fill: currentColor;
  stroke: none;
}

.floating-contact.is-collapsed .floating-contact__toggle svg {
  transform: rotate(180deg);
}

/* The strip sits on the right in LTR, so the collapse arrow has to point the
   other way — outwards, towards the edge it tucks into. */
[dir="ltr"] .floating-contact__toggle svg {
  transform: scaleX(-1);
}

[dir="ltr"] .floating-contact.is-collapsed .floating-contact__toggle svg {
  transform: scaleX(-1) rotate(180deg);
}

.floating-contact.is-collapsed .floating-contact__actions {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-100%);
}

.contact-drawer {
  position: fixed;
  z-index: 210;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(100%, 430px);
  padding: 52px 42px;
  background: #fff;
  color: #222;
  transform: translateX(-105%);
  transition: transform 0.45s var(--ease);
}

[dir="ltr"] .contact-drawer {
  right: 0;
  left: auto;
  transform: translateX(105%);
}

.contact-drawer.is-open {
  transform: translateX(0);
}

.contact-drawer h2 {
  color: #8f7136;
  font-size: 34px;
}

.contact-drawer .field input,
.contact-drawer .field textarea {
  color: #222;
}

.drawer-close,
.modal-close {
  position: absolute;
  top: 18px;
  right: 20px;
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 25px;
}

.drawer-overlay,
.modal-overlay {
  position: fixed;
  z-index: 200;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.drawer-overlay.is-open,
.modal-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.media-modal {
  position: fixed;
  z-index: 220;
  inset: 0;
  display: grid;
  padding: 44px;
  place-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.media-modal.is-open {
  opacity: 1;
  pointer-events: auto;
}

.media-modal__box {
  position: relative;
  z-index: 1;
  display: grid;
  width: min(100%, 980px);
  min-height: 420px;
  place-items: center;
  padding: 52px;
  border: 1px solid var(--line);
  background: #060606;
}

.media-modal img {
  width: 100%;
  max-height: 78vh;
  object-fit: contain;
}

.modal-message {
  max-width: 620px;
  text-align: center;
}

.modal-message h2 {
  font-size: 40px;
}

.toast {
  position: fixed;
  z-index: 400;
  right: 22px;
  bottom: 22px;
  max-width: 360px;
  padding: 16px 22px;
  border: 1px solid var(--gold);
  background: #0b0b0b;
  color: #ddd;
  opacity: 0;
  transform: translateY(20px);
  transition: 0.35s ease;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Motion */
.reveal {
  opacity: 1;
  transform: none;
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

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

@media (max-width: 1100px) {
  :root {
    --header: 82px;
  }

  .site-header {
    position: sticky;
    top: 0;
    background: rgba(0, 0, 0, 0.98);
  }

  .header-inner {
    width: min(calc(100% - 48px), 1360px);
    padding: 0;
  }

  .site-logo,
  .site-logo img {
    width: 48px;
    height: 64px;
  }

  .menu-toggle {
    position: relative;
    z-index: 102;
    display: block;
  }

  .nav-wrap {
    position: fixed;
    z-index: 101;
    top: var(--header);
    right: 0;
    bottom: 0;
    left: 0;
    display: block;
    margin-inline-end: 0;
    overflow-y: auto;
    padding: 42px 24px max(42px, env(safe-area-inset-bottom));
    background: #050505;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-12px);
    transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s ease;
  }

  .nav-wrap.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }

  .main-nav,
  .nav-list {
    display: block;
  }

  .nav-list li + li::before {
    display: none;
  }

  .nav-list li,
  .nav-list li:first-child {
    margin: 0;
  }

  .nav-list li::after,
  .lang-toggle::after {
    display: none;
  }

  .nav-list a {
    height: auto;
    padding: 13px 0;
    border-bottom: 0;
    font-size: 18px;
  }

  .nav-list a::after {
    display: none;
    bottom: 8px;
  }

  [data-page] .nav-list a[aria-current="page"]::after {
    display: block;
    transform: scaleX(1);
  }

  .lang-toggle {
    display: inline-block;
    height: auto;
    margin-inline-end: 0;
    margin-top: 20px;
    padding-inline: 0;
    border: 0;
  }

  .header-glyph {
    display: none;
  }

  .desktop-side-panel,
  .desktop-side-cover {
    display: none;
  }

  .footer-col {
    padding: 0;
  }

  .showcase-grid,
  .projects-grid,
  .articles-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .values-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 850px) {
  .container {
    width: min(calc(100% - 32px), var(--max));
  }

  .section {
    padding: 78px 0;
  }

  .floor-model,
  .floor-model:nth-child(even) {
    grid-template-columns: 1fr;
  }

  .floor-model:nth-child(even) .floor-model__image {
    order: 0;
  }

  .projects-grid {
    grid-template-columns: 1fr;
  }

  .feature-card {
    min-height: 290px;
  }

  .hero-search {
    width: min(700px, calc(100% - 40px));
    grid-template-columns: repeat(2, 1fr);
    gap: 14px 20px;
    padding: 24px;
  }

  .hero-search .hero-search__submit {
    grid-column: 1 / -1;
    margin-inline-start: 0;
  }

  .home-intro,
  .leader-grid,
  .leader-grid--reverse,
  .contact-split,
  .project-intro,
  .location-grid,
  .floor-grid,
  .luxury-grid,
  .story-grid,
  .contact-page-grid,
  .variant-project-summary {
    grid-template-columns: 1fr;
    gap: 48px;
  }

  /* The overview and the location band are separated by the sum of two
     paddings. That sum is a fixed pixel figure, so on a phone it takes a far
     larger share of the screen than it does on a desktop and reads as a hole
     between the two sections rather than as breathing room. Cut on the small
     breakpoint only; the desktop rhythm is unchanged. */
  .project-overview-section {
    padding-bottom: 28px;
  }

  .project-location-section {
    padding-top: 40px;
  }

  .home-contact {
    grid-template-columns: 1fr;
  }

  .home-contact__image {
    min-height: 440px;
    order: -1;
  }

  .leader-grid--reverse .leader-photo {
    order: -1;
  }

  .leader-photo,
  .leader-copy {
    min-height: 480px;
  }

  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .footer-main {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .footer-col {
    padding: 44px 0;
    border-bottom: 1px solid var(--line);
  }

  .footer-contact {
    padding-inline-end: 0;
  }

  .footer-bottom {
    min-height: 0;
    padding-top: 0;
  }

  .footer-bottom__inner {
    min-height: 0;
    grid-template-columns: 1fr;
    gap: 20px;
    padding: 28px 0;
  }

  .footer-brand,
  .footer-copyright {
    justify-self: center;
  }

  .footer-brand {
    margin-inline-start: 0;
  }

  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .register-bar {
    align-items: flex-start;
    flex-direction: column;
  }
}

@media (max-width: 620px) {
  body {
    font-size: 15px;
  }

  .section {
    padding: 62px 0;
  }

  .feature-grid,
  .showcase-grid,
  .projects-grid,
  .articles-grid,
  .values-grid,
  .form-grid,
  .article-actions {
    grid-template-columns: 1fr;
  }

  .feature-card {
    min-height: 260px;
    border-inline-end: 0;
    border-bottom: 1px solid var(--line) !important;
  }

  .home-hero {
    height: calc(100svh - var(--header));
    min-height: 560px;
  }

  .home-hero__video {
    object-position: 50% center;
  }

  .hero-search {
    bottom: 8%;
    width: calc(100% - 32px);
    grid-template-columns: 1fr 1fr;
    gap: 10px 14px;
    padding: 18px;
  }

  .hero-search a {
    padding: 10px 6px;
    font-size: 12px;
  }

  .hero-scroll {
    display: none;
  }

  .feature-number {
    left: 27px;
    font-size: 120px;
  }

  [dir="ltr"] .feature-number {
    right: 27px;
  }

  .feature-card h2 {
    top: 30px;
    left: 27px;
  }

  [dir="ltr"] .feature-card h2 {
    right: 27px;
  }

  .home-contact__form {
    padding: 62px 22px;
  }

  .home-contact__image {
    min-height: 320px;
  }

  .home-intro__visual {
    min-height: 390px;
  }

  .home-intro__visual img {
    width: 78%;
  }

  .showcase-head,
  .article-share,
  .post-nav {
    align-items: flex-start;
    flex-direction: column;
  }

  .project-card__image {
    aspect-ratio: 1 / 1.12;
  }

  .leader-photo,
  .leader-copy {
    min-height: auto;
  }

  .leader-photo img {
    max-height: 540px;
  }

  .leader-copy {
    padding: 50px 24px;
  }

  .stats-grid {
    grid-template-columns: 1fr 1fr;
  }

  .stat strong {
    font-size: 48px;
  }

  .page-hero {
    min-height: 190px;
  }

  .filter-bar {
    justify-content: flex-start;
    overflow-x: auto;
    flex-wrap: nowrap;
    padding-bottom: 10px;
  }

  .filter-btn {
    flex: none;
  }

  .gallery-grid {
    grid-template-columns: 1fr;
  }

  .gallery-item {
    min-height: 360px;
  }

  .footer-col {
    padding: 36px 0;
  }

  .contact-drawer {
    padding: 52px 26px;
  }

  .media-modal {
    padding: 18px;
  }

  .media-modal__box {
    min-height: 320px;
    padding: 40px 18px;
  }

  .article-detail {
    width: min(calc(100% - 32px), 1040px);
    padding-top: 38px;
  }
}

/* ---------------------------------------------------------------
   English home
   Structurally the same page as the Arabic one; it differs in that every
   heading is set in caps, the feature grid loses its bottom padding, and
   the contact band is taller.
   --------------------------------------------------------------- */
[lang="en"] h1,
[lang="en"] h2,
[lang="en"] h3,
[lang="en"] h4,
[lang="en"] .band-title,
[lang="en"] .figures-band__title,
[lang="en"] .btn,
[lang="en"] .nav-list a,
[lang="en"] .hero-search__submit,
[lang="en"] .accordion__title button,
[lang="en"] .text-link {
  text-transform: uppercase;
}

/* Arabic has no case, so the published site distinguishes these headings by
   weight in English only. Scoped to the language for exactly that reason. */
[lang="en"] .accordion__title button,
[lang="en"] .text-link {
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* Desktop only. Unscoped, this also removed the 51px that separates the feature
   cards from the intro band on a phone, so the English home page had the two
   sections touching while the Arabic one did not. */
@media (min-width: 768px) {
  [lang="en"] .feature-grid {
    padding-bottom: 0;
  }
}

[dir="ltr"] .feature-number {
  right: 41px;
  left: auto;
}

/* Not `--row`: that variant is one row of six and sizes itself at 210px below.
   Without the :not() this selector is one class more specific and wins, which
   left the About page's band 353px tall around 120px of content — 183px of
   empty gold, in English only. */
[lang="en"] .figures-band:not(.figures-band--row) {
  height: 353px;
}

[lang="en"] .ticker__group span {
  line-height: 16px;
}

[lang="en"] .home-contact {
  min-height: 716px;
  padding: 100px 0;
}

[lang="en"] .projects-section__link {
  width: 213px;
  margin-top: 42px;
}

/* ---------------------------------------------------------------
   Home page — tablet and below
   The desktop bands above are pinned to the live site's 1440px
   geometry, so they all need unwinding once the columns collapse.
   --------------------------------------------------------------- */
@media (max-width: 1024px) {
  .leader-section {
    padding: 20px 40px;
  }

  .leader-grid,
  .leader-grid--reverse {
    gap: 40px;
  }

  .home-contact__form {
    padding: 0 40px;
  }

  .home-contact__image img {
    width: 100%;
  }
}

@media (max-width: 767px) {
  .home-hero {
    height: auto;
  }

  .home-hero__video {
    height: 100svh;
  }

  .hero-search {
    position: static;
    display: grid;
    width: 100%;
    height: auto;
    grid-template-columns: 1fr;
    gap: 20px;
    padding: 20px;
    transform: none;
  }

  .hero-search__submit {
    width: 100%;
  }

  .hero-scroll {
    display: none;
  }

  .feature-grid {
    grid-template-columns: 1fr;
  }

  .feature-card {
    height: 250px;
    min-height: 0;
    border-inline-end: 0;
  }

  .partners,
  .videos-section {
    padding-bottom: 0;
  }

  .partner {
    height: 74px;
  }

  .carousel__arrows {
    margin-inline-end: 0;
  }

  .carousel__progress span {
    width: 24px;
  }

  .intro-band {
    display: block;
    height: auto;
    padding: 10px 20px 50px;
  }

  .intro-band__copy,
  [dir="ltr"] .intro-band__copy {
    padding: 0;
  }

  .intro-band__visual {
    padding: 0;
    margin-top: 30px;
  }

  .intro-band__visual img {
    width: 100%;
  }

  .leader-section {
    min-height: 0;
    padding: 10px;
  }

  .leader-grid,
  .leader-grid--reverse {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  .leader-grid .leader-photo,
  .leader-grid .leader-copy,
  .leader-grid--reverse .leader-photo,
  .leader-grid--reverse .leader-copy {
    grid-row: auto;
    grid-column: 1;
  }

  .leader-photo {
    height: auto;
  }

  .leader-copy {
    padding: 0 20px 20px;
  }

  .figures-band {
    height: auto;
    padding: 50px 30px;
  }

  .figures-grid {
    grid-template-columns: 1fr;
  }

  .videos-grid {
    grid-template-columns: 1fr;
  }

  .home-contact {
    display: block;
    height: auto;
    padding: 0 30px;
  }

  .home-contact__form,
  .home-contact__image {
    grid-column: auto;
    padding: 60px 0 125px;
  }

  .home-contact__image {
    padding: 0 0 40px;
  }

  .contact-form__row {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .contact-form p {
    margin-bottom: 30px;
  }

  .map-section {
    height: 700px;
  }
}

@media (max-width: 767px) {
  [lang="en"] .home-contact,
  [lang="en"] .figures-band {
    height: auto;
  }
}

/* ---------------------------------------------------------------
   About page
   Geometry taken from the live page at 1440px.
   --------------------------------------------------------------- */
.about-hero {
  height: 410px;
  margin-top: 30px;
  overflow: hidden;
}

.about-hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-intro {
  display: grid;
  /* 1400px, as the published page has it — two 700px columns, so the copy
     measures 520px once the 180px inner gutter is taken off. At 1100 the same
     gutter left only 370px and the band sat noticeably inset from the page. */
  width: min(calc(100% - 80px), 1400px);
  /* No min-height. There was a 626px one here, taken off the published page —
     but this is a grid, so the single row stretched to fill it and left 244px
     of empty black between the accordion and the band below. The design sizes
     the band to its content. */
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: 0;
  padding: 0 0 40px;
  margin-inline: auto;
}

.about-intro__copy {
  /* Logical, not physical. As `padding-left` this was the gutter between the
     two columns in Arabic — where the copy sits on the right — but in English
     the copy moves to the left and the same 180px landed on the outside,
     squeezing the text into a noticeably narrower column than the published
     page has. */
  padding: 30px 0 0;
  padding-inline-end: 180px;
  color: #ccc;
  font-size: 18px;
  line-height: 28px;
}

.about-intro__copy .band-title {
  margin-bottom: 12px;
  font-size: 28px;
  line-height: 31px;
}

.about-intro__copy p {
  margin: 0;
  color: #ccc;
  font-size: 18px;
  line-height: 28px;
}

.about-intro__accordion {
  padding-top: 30px;
}

.accordion__title {
  margin: 0;
  border-bottom: 1px solid var(--line);
}

.accordion__title button {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  padding: 30px 0 10px;
  border: 0;
  background: transparent;
  color: var(--gold);
  cursor: pointer;
  font-size: 16px;
  line-height: 20px;
  text-align: start;
}

.about-intro .accordion__panel + .accordion__title {
  margin-top: 18px;
}

.about-intro .accordion__panel-inner {
  padding-inline-end: 15%;
  color: #ccc;
  font-size: 15px;
  line-height: 25px;
}

.about-intro .accordion__panel.is-open > .accordion__panel-inner {
  padding-top: 0;
  padding-bottom: 62px;
}

.accordion__mark {
  position: relative;
  width: 14px;
  height: 14px;
  flex: none;
}

.accordion__mark::before,
.accordion__mark::after {
  position: absolute;
  top: 50%;
  left: 0;
  width: 14px;
  height: 1px;
  background: currentColor;
  content: "";
  transition: transform 0.3s ease;
}

.accordion__mark::after {
  transform: rotate(90deg);
}

.accordion__title button[aria-expanded="true"] .accordion__mark::after {
  transform: rotate(0deg);
}

.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.35s var(--ease);
}

.accordion__panel.is-open {
  grid-template-rows: 1fr;
}

.accordion__panel-inner {
  min-height: 0;
  overflow: hidden;
  margin: 0;
  color: #ccc;
  font-size: 18px;
  line-height: 1.6;
}

.accordion__panel.is-open > .accordion__panel-inner {
  padding: 18px 0;
}

/* Live draws this as a long line-arrow rather than a glyph. */
.about-intro__link {
  margin-top: 34px;
  gap: 12px;
  font-size: 12px;
}

/* This link draws its arrow as an svg, so the shared glyph is switched off.
   Both directions: `[dir="ltr"] .text-link::after` is a class more specific
   than this rule, so without the second selector English rendered the glyph and
   the svg — two arrows — while Arabic rendered neither. */
.about-intro__link::after,
[dir="ltr"] .about-intro__link::after {
  content: none;
}

.about-intro__link svg {
  width: 40px;
  height: 8px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}

/* Drawn pointing right; Arabic reads the other way. */
[dir="rtl"] .about-intro__link svg {
  transform: scaleX(-1);
}

.about-profile,
.about-more {
  display: flex;
  justify-content: center;
  padding: 10px 0;
}

.about-profile .btn {
  width: 248px;
  height: 47px;
  min-height: 47px;
  padding: 0;
  font-size: 14px;
}

.about-more .btn {
  width: 105px;
  height: 40px;
  min-height: 40px;
  padding: 0;
  font-size: 16px;
}

.about-projects {
  padding: 10px 0 0;
}

/* `start` is the right edge in RTL and the left in LTR. The published heading
   remains on its 1400px content grid while the media band below is full width. */
.about-projects .band-title {
  width: min(calc(100% - 40px), 1400px);
  margin: 0 auto 25px;
  padding: 0 10px;
  font-size: 28px;
  line-height: 31px;
  text-align: start;
}

/* The about page uses the live site's "info below" portfolio layout: two
   slides in view, image on top, title and category underneath — unlike the
   home page, where the title is overlaid on the image. */
.carousel--wide .carousel__track {
  gap: 20px;
}

/* The published page runs this band almost edge to edge: a 20px page inset,
   two equal columns, and a 20px inner gutter on the carousel side. */
.about-projects__grid {
  display: grid;
  width: calc(100% - 40px);
  grid-template-columns: 50% 50%;
  align-items: start;
  gap: 0;
  padding: 0;
  margin-inline: auto;
}

.about-projects__feature {
  grid-row: 1;
  grid-column: 2;
  height: 479px;
}

.about-projects__feature img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.carousel--wide {
  grid-row: 1;
  grid-column: 1;
  height: 479px;
  min-width: 0;
  padding-inline-end: 20px;
}

.project-slide--wide {
  flex: 0 0 calc(50% - 10px);
  height: 479px;
  background: transparent;
}

.project-slide--wide .project-slide__media {
  display: block;
  width: min(400px, 100%);
  height: auto;
  margin-inline-end: auto;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #111;
}

.project-slide--wide .project-slide__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-slide--wide .project-slide__content {
  padding: 16px 0 0;
  text-align: start;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.project-slide--wide.is-active .project-slide__content {
  opacity: 1;
  transition-delay: 0.6s;
}

.project-slide--wide h3 {
  position: static;
  margin: 0;
  color: var(--gold);
  font-size: 18px;
  font-weight: 400;
  line-height: 30px;
  text-align: start;
  transform: none;
  text-shadow: none;
}

.project-slide--wide .project-slide__cats {
  margin: 0;
  color: #ccc;
  font-size: 15px;
  line-height: 25px;
}

.about-projects .carousel__foot {
  display: flex;
}

.about-projects .carousel__arrows {
  display: none;
}

.about-goals {
  padding: 110px 70px 120px;
  text-align: center;
}

.about-goals .container {
  width: min(100%, 1140px);
}

.about-goals .section-title {
  max-width: none;
  margin: 0 0 30px;
  font-size: 28px;
  font-weight: 400;
  line-height: 28px;
  text-align: center;
}

.about-goals .article-prose,
.about-goals p {
  margin: 0 auto;
  max-width: none;
  color: #fff;
  font-size: 18px;
  line-height: 40px;
  text-align: center;
}

.about-split {
  display: grid;
  min-height: 279px;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  direction: ltr;
}

.about-split__copy {
  grid-row: 1;
  grid-column: 1;
  padding: 50px;
  color: #fff;
  font-size: 18px;
  line-height: 25px;
}

/*
   The image fills the band; it does not set its height.

   It used to. With `height: 100%` unable to resolve against a centred grid
   item, each picture fell back to its own aspect ratio at 720px wide — so the
   Mission band came out 393px tall, the Vision band 536px, and the pair looked
   mismatched rather than designed. The 279px min-height below had been sitting
   there unreachable the whole time.

   Taking the image out of flow lets the row be what it was meant to be: the
   copy, or 279px, whichever is taller. `object-fit: cover` then crops rather
   than letterboxes, so both bands read as one band.
 */
.about-split__media {
  position: relative;
  align-self: stretch;
  grid-row: 1;
  grid-column: 2;
  min-height: 279px;
}

.about-split__media img {
  position: absolute;
  width: 100%;
  height: 100%;
  inset: 0;
  object-fit: cover;
  object-position: center;
}

.about-split--reverse,
.about-split--reverse .about-split__media {
  min-height: 279px;
}

.about-split--reverse .about-split__copy {
  grid-column: 2;
}

.about-split--reverse .about-split__media {
  grid-column: 1;
}

[dir="rtl"] .about-split__copy {
  direction: rtl;
}

.about-split__copy .band-title {
  margin-bottom: 12px;
  font-size: 28px;
  line-height: 31px;
}

.about-split__copy p {
  margin: 0;
  color: #fff;
  font-size: 18px;
  line-height: 25px;
}

.about-services {
  padding: 40px 0 10px;
}

.about-services .band-title {
  margin-bottom: 27px;
  font-size: 28px;
  line-height: 28px;
  text-align: center;
}

.services-grid {
  display: grid;
  width: min(calc(100% - 140px), 1140px);
  padding: 10px 0 0;
  margin-inline: auto;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

/*
   The card fills gold under the cursor and lifts.

   Measured on the published page: the background goes from black to
   `rgb(181,152,90)` while the border stays the same gold, and the card rises
   5px. The icon and the title are already white, so they need no change — the
   card simply becomes the colour its outline was drawn in.

   Timings are the published ones too: the fill at .3s and the lift at .4s, so
   the colour lands slightly before the movement settles.
 */
.service-card {
  display: flex;
  height: 146px;
  flex-direction: column;
  justify-content: center;
  padding: 25px;
  border: 1px solid #b5985a;
  background-color: transparent;
  text-align: start;
  transition:
    background-color 0.3s ease-out,
    transform 0.4s ease-out;
}

.service-card:hover,
.service-card:focus-within {
  background-color: #b5985a;
  transform: translateY(-5px);
}

.service-card__icon {
  display: block;
  width: 50px;
  height: 50px;
  align-self: flex-start;
  color: #fff;
}

.service-card__icon svg,
.service-card__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.service-card h3 {
  margin: 14px 0 0;
  color: #fff;
  font-size: 28px;
  font-weight: 400;
  line-height: 31px;
}

/*
   The services page's detail band: one row per service, photograph on one side
   and the copy on the other, swapping sides down the page.

   Measured off the published page at 1440: rows are 550x250 with the picture
   filling exactly half the 1100px content column, stacked flush with no gap
   between them, so the six read as one alternating ribbon rather than six
   separate bands. The copy sits in a 500px column inside its half, titled 20px
   gold with 15px/25px body.

   The alternation is `:nth-child(even)`, so inserting a service re-staggers the
   rows below it instead of leaving two photographs side by side.
 */
/*
   The projects band as a grid rather than a carousel, which is how the services
   page closes on the published site: six tiles in two rows of three.

   `.project-slide` keeps its own 303px basis for the carousel, so the width has
   to be overridden here — a flex basis means nothing to a grid item, but the
   `flex: 0 0 303px` shorthand also sets a width the grid column would have to
   fight.
 */
/*
   Centred, unlike the carousel it borrows its tiles from.

   `.projects-shell` deliberately bleeds off one edge — that is the carousel's
   design, the strip running out of the viewport to say there is more of it. A
   grid has no more of it, so the same inset left this band flush to one side
   and 170px from the other. Reset to the page's own gutters.
 */
.projects-section--grid .projects-shell {
  width: min(calc(100% - 340px), 1100px);
  padding-inline: 0;
  margin-inline: auto;
}

.projects-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 19px;
}

.projects-grid .project-slide {
  flex: initial;
  width: auto;
  height: 303px;
}

.projects-section--grid {
  padding-bottom: 40px;
}

@media (max-width: 900px) {
  .projects-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .projects-grid {
    grid-template-columns: 1fr;
  }
}

.services-detail {
  width: min(calc(100% - 140px), 1100px);
  margin: 60px auto 0;
}

.services-detail__row {
  display: grid;
  min-height: 250px;
  grid-template-columns: 1fr 1fr;
  align-items: center;
}

.services-detail__media {
  position: relative;
  height: 250px;
  overflow: hidden;
  background: #111;
}

.services-detail__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
   The photograph leads the row in the markup, so it takes the first column —
   the reader's side, right in Arabic and left in English. Every other row sends
   it to the second column instead, and that is the whole of the stagger.

   `order: 1`, not `-1`: the media is already the first child, so pulling it
   further forward is a no-op and every row came out identical. It has to be
   pushed past the copy.
 */
.services-detail__row:nth-child(even) .services-detail__media {
  order: 1;
}

/*
   Hovering a row fills its copy with gold and turns the writing white.

   At rest the panel is the page's own black with a gold title over grey body
   copy; under the cursor the whole cell becomes the gold and every line of it
   goes white. Measured on the published page: the title moves from
   `rgb(178,150,83)` to `rgb(255,255,255)` and the body from `rgb(204,204,204)`
   to the same white, together.

   The whole row is the trigger, not just the copy — the photograph is half of
   what the reader is pointing at, and lighting up only one half of a pair reads
   as a mistake.
 */
.services-detail__copy {
  display: flex;
  height: 100%;
  flex-direction: column;
  justify-content: center;
  padding: 25px;
  background-color: transparent;
  transition: background-color 0.4s ease-out;
}

.services-detail__row:hover .services-detail__copy {
  background-color: var(--gold);
}

.services-detail__copy h3 {
  margin: 0 0 10px;
  color: var(--gold);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.4;
  transition: color 0.4s ease-out;
}

.services-detail__copy p {
  margin: 0;
  color: #ccc;
  font-size: 15px;
  line-height: 25px;
  transition: color 0.4s ease-out;
}

.services-detail__row:hover .services-detail__copy h3,
.services-detail__row:hover .services-detail__copy p {
  color: #fff;
}

@media (max-width: 900px) {
  /* One column: the photograph above its own copy, which keeps a service's
     picture and its words together — an alternating ribbon squeezed into one
     column pairs each photograph with the wrong text half the time. */
  .services-detail__row,
  .services-detail__row:nth-child(even) {
    grid-template-columns: 1fr;
  }

  .services-detail__row:nth-child(even) .services-detail__media {
    order: 0;
  }

  .services-detail__copy {
    padding: 20px 0 40px;
  }
}

/* The about page's figures band has no heading and runs six across. */
.figures-band--row {
  height: 210px;
  padding: 50px 70px 40px;
}

.figures-band--row .figures-grid {
  grid-template-columns: repeat(6, 1fr);
  gap: 0;
}

.figures-band--row .figure strong {
  font-size: 56px;
  line-height: 76px;
}

.figures-band--row .figure span {
  font-size: 14px;
  line-height: 22px;
}

@media (max-width: 1024px) {
  .about-intro {
    width: auto;
    height: auto;
    min-height: 0;
    padding: 0 40px 40px;
    margin: 0;
  }

  .about-intro__copy {
    padding: 30px 0 0;
  }

  .about-goals {
    padding: 60px 40px;
  }

  .services-grid {
    width: auto;
    padding: 0 40px;
    margin: 0;
  }

  .about-projects__grid {
    grid-template-columns: 1fr;
  }

  .about-projects__feature {
    display: none;
  }

  .carousel--wide {
    grid-column: 1;
    padding-inline-end: 0;
  }

  .figures-band--row {
    height: auto;
    padding: 40px;
  }

  .figures-band--row .figures-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
  }
}

@media (max-width: 767px) {
  .about-hero {
    height: 240px;
  }

  .about-intro {
    grid-template-columns: 1fr;
    padding: 0 20px 40px;
  }

  .project-slide--wide {
    flex: 0 0 calc(100vw - 40px);
    height: auto;
    aspect-ratio: 680 / 479;
  }

  .about-split {
    grid-template-columns: 1fr;
  }

  .about-split__copy,
  .about-split__media,
  .about-split--reverse .about-split__copy,
  .about-split--reverse .about-split__media {
    grid-row: auto;
    grid-column: 1;
  }

  /* The reverse variant too: its own 279px rule carries two classes and would
     otherwise outrank this one, leaving the two stacked bands 59px apart. */
  .about-split__media,
  .about-split--reverse .about-split__media {
    min-height: 220px;
  }

  .services-grid {
    padding: 0 20px;
    grid-template-columns: 1fr;
  }

  .figures-band--row .figures-grid {
    grid-template-columns: 1fr;
  }
}

/* The About page gives partner marks enough room to remain recognizable. */
.about-partners .band-title {
  margin-bottom: 20px;
  font-size: 28px;
  line-height: 31px;
}

.about-partners .partner {
  height: 190px;
}

.about-partners .partner img {
  max-width: 184px;
  max-height: 184px;
}

/* Live leaves a 30px gap before the footer when the ticker ends the page. */
#main > .ticker:last-child {
  margin-bottom: 30px;
}

/* Back-to-top arrow — fixed bottom-right, grows slightly on hover. */
/* The arrow is anchored to the bottom of its box so the hover growth extends
   upwards, in the direction it points, rather than from the centre out. */
.back-to-top {
  position: fixed;
  right: 56px;
  bottom: 56px;
  z-index: 60;
  display: grid;
  width: 20px;
  height: 56px;
  align-items: end;
  justify-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.back-to-top svg {
  width: 10px;
  height: 41px;
  overflow: visible;
  transition: height 0.3s var(--ease);
}

.back-to-top:hover svg {
  height: 56px;
}

.back-to-top__stem {
  stroke: var(--gold);
  stroke-width: 1.5;
}

.back-to-top__head {
  fill: var(--gold);
}

@media (max-width: 767px) {
  .back-to-top {
    right: 20px;
    bottom: 20px;
  }
}

/* Form validation — matches Contact Form 7's inline tip and summary. */
.field-error {
  display: block;
  margin-top: 8px;
  color: #dc3232;
  font-size: 15px;
  line-height: 1.5;
}

.contact-form input.is-invalid,
.contact-form textarea.is-invalid {
  border-bottom-color: #dc3232;
}

.demo-form .field input.is-invalid,
.demo-form .field textarea.is-invalid {
  border-color: #dc3232;
}

.form-response {
  margin: 18px 0 0;
  font-size: 15px;
  line-height: 1.5;
}

.form-response:empty {
  display: none;
}

.form-response.is-error {
  color: #dc3232;
}

.form-response.is-sent {
  color: var(--gold-bright);
}

/* Each paired field owns a cell so its error tip stacks underneath it rather
   than becoming a sibling grid item and breaking the two-column row. */
.contact-form__cell {
  display: block;
  min-width: 0;
}

/* Progress indicator under the about-page carousel. */
.carousel--wide .carousel__progress {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 5px;
  margin-top: 3px;
}

@media (max-width: 767px) {
  .about-projects__grid {
    width: 100%;
    grid-template-columns: 1fr;
    padding: 0;
    margin: 0;
  }

  .about-projects__feature {
    grid-row: auto;
    grid-column: 1;
    height: 240px;
  }

  .carousel--wide {
    grid-row: auto;
    grid-column: 1;
    height: auto;
  }

  .project-slide--wide .project-slide__media {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
  }
}

/* ==========================================================================
   Application additions

   The approved design is a static demo; these are the few classes a real,
   data-driven site needs that it never had to express. Everything here uses
   the design's own tokens — no new colours, no radii, no shadows.
   ========================================================================== */

/* Honeypot.
   Hidden by clipping, not by an off-screen offset. `left: -9999px` is the usual
   trick but it is direction-unsafe: in an RTL document it pushes the page 9999px
   wide, and because RTL anchors the scroll position to the right edge, every
   Arabic page carrying a form rendered as empty background.
   Clipping in place keeps it invisible to people and still fillable by a bot,
   which is the whole point — display:none would be skipped. */
.field--trap {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

/* Result counts beside a project filter. */
.filter-btn__count {
  margin-inline-start: 4px;
  font-size: 12px;
  opacity: 0.65;
}

/* ---------------------------------------------------------------- filters --
 * The projects listing filter and sort panel. Every control inside it is an
 * anchor, so the whole panel works with JavaScript off and every state it can
 * reach has a URL. Logical properties throughout: the same rules lay the panel
 * out right-to-left in Arabic without a mirrored copy.
 */
.project-filters {
  margin-bottom: 40px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 22px 0 18px;
  /* Every filter link targets this panel by id. The header is fixed, so without
     the margin the browser would park the first row of chips underneath it. */
  scroll-margin-top: calc(var(--header) + 24px);
}

/* While a filtered result set is being fetched in place. Dimmed rather than
   blanked, so the page does not jump between what is there and what replaces
   it — and no spinner, because the swap is one small request. */
#projects-results[aria-busy="true"] {
  opacity: 0.45;
  transition: opacity 0.15s var(--ease);
}

/*
 * Arriving at the panel is a jump, not a journey.
 *
 * The site scrolls smoothly by default, which is right for "back to top" and
 * for the hero's scroll cue. Applied to a filter click it animates the whole
 * page past the hero on every choice, which reads as the page moving rather
 * than the results changing. Scoped with :has so only this landing is instant —
 * the smooth behaviour everywhere else, including on this page, is untouched.
 */
html:has(.project-filters:target) {
  scroll-behavior: auto;
}

/*
   The quick bar, and the advanced trigger sitting at the end of it.

   The published listing led with five plain text presets and no chrome — no
   borders, no counts — and the forty-chip panel this replaced is what the client
   was reacting to. The chips are all still there, one summary away.

   A wrapping flex row with the <details> as its last item: closed, it is sized
   by its summary and reads as one more tab; open, it takes a full row so the
   panel underneath has the width to lay out four dimensions.
 */
.filters-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  /* Tight enough that the presets and the trigger stay on one row at desktop
     widths — the bar is built from the taxonomy now, so it can be seven items
     rather than the published site's five. */
  gap: 12px 30px;
}

.filters-head__tab {
  color: #fff;
  font-size: 16px;
  line-height: 28px;
  transition: color 0.25s ease;
}

.filters-head__tab:hover,
.filters-head__tab:focus-visible {
  color: var(--gold-bright);
  outline: none;
}

.filters-head__tab.is-active {
  color: var(--gold);
}

/* The trigger reads as a tab but is not a destination, so it is set apart by
   weight and a marker rather than by colour, which is carrying "selected". */
.filters-head__tab--advanced {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 0;
  background: none;
  color: var(--gold);
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.filters-head__tab--advanced::after {
  display: inline-block;
  border-top: 5px solid currentColor;
  border-inline: 4px solid transparent;
  content: "";
  transition: transform 0.25s ease;
}

.filters-head__tab--advanced[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

/* Open: its own full-width row under the presets, so the panel is not squeezed
   into the width of the word that opened it. */
.filters-head__count {
  display: inline-grid;
  min-width: 19px;
  height: 19px;
  flex: none;
  align-self: center;
  padding: 0 5px;
  border-radius: 10px;
  background: var(--gold);
  color: #000;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  place-items: center;
}

/* A sibling of the row, so opening it pushes the listing down instead of
   rearranging the row that opened it. */
.filters-head__panel {
  padding-top: 22px;
}

/* Collapsed by a class on <body> rather than the `hidden` attribute: the panel
   element is replaced on every filter click, so its own attributes cannot hold
   state. Absent the class — scripting off — the filters are simply all there. */
body.filters-collapsed .filters-head__panel {
  display: none;
}

.project-filters__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 18px;
}

.project-filters__count {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  letter-spacing: 0.08em;
}

.sort-menu {
  position: relative;
}

.sort-menu__trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  padding: 10px 18px;
  color: var(--text);
  cursor: pointer;
  font-size: 14px;
  list-style: none;
  white-space: nowrap;
}

/* Safari still paints its own triangle without this. */
.sort-menu__trigger::-webkit-details-marker {
  display: none;
}

.sort-menu__trigger:hover,
.sort-menu[open] .sort-menu__trigger {
  border-color: var(--gold);
}

.sort-menu__label {
  color: var(--muted);
}

.sort-menu__current {
  color: var(--gold);
  font-weight: 700;
}

.sort-menu__current::after {
  content: "";
  display: inline-block;
  margin-inline-start: 8px;
  border-top: 5px solid currentColor;
  border-inline: 4px solid transparent;
  vertical-align: middle;
}

.sort-menu__list {
  position: absolute;
  inset-inline-end: 0;
  z-index: 5;
  min-width: 200px;
  margin: 6px 0 0;
  border: 1px solid var(--line);
  padding: 6px 0;
  background: var(--ink);
  list-style: none;
}

.sort-menu__option {
  display: block;
  padding: 9px 18px;
  color: var(--text);
  font-size: 14px;
  text-decoration: none;
}

.sort-menu__option:hover,
.sort-menu__option.is-active {
  background: rgba(184, 154, 88, 0.1);
  color: var(--gold);
}

/* A grid, not a flex row: the label keeps its own column, so a dimension whose
   chips wrap to a second line still reads on the same line as its label. */
.filter-group {
  display: grid;
  grid-template-columns: 130px 1fr;
  align-items: baseline;
  gap: 10px 16px;
  padding: 8px 0;
}

.filter-group__label {
  color: var(--muted);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.filter-group__options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.filter-chip {
  border: 1px solid var(--line);
  padding: 7px 16px;
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  text-decoration: none;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}

.filter-chip:hover {
  border-color: var(--gold);
  color: var(--gold);
}

.filter-chip.is-active {
  border-color: var(--gold);
  background: var(--gold);
  color: #000;
  font-weight: 700;
}

.filter-chip__count {
  margin-inline-start: 6px;
  font-size: 12px;
  opacity: 0.65;
}

.project-filters__active {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

.project-filters__active-label {
  color: var(--muted);
  font-size: 13px;
  letter-spacing: 0.12em;
}

.active-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--gold);
  padding: 5px 12px;
  color: var(--gold);
  font-size: 13px;
  text-decoration: none;
}

.active-chip:hover {
  background: rgba(184, 154, 88, 0.12);
}

.active-chip__remove {
  font-size: 15px;
  line-height: 1;
}

.project-filters__clear {
  margin-inline-start: auto;
  color: var(--muted);
  font-size: 13px;
  text-decoration: underline;
}

.project-filters__clear:hover {
  color: var(--gold);
}

@media (max-width: 768px) {
  .filter-group {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .filter-group__options {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 6px;
  }

  .filter-chip {
    flex: none;
  }

  .project-filters__clear {
    margin-inline-start: 0;
  }
}

/* Shown when a filter combination has no matches, and on error pages. */
.empty-state {
  padding: 80px 0;
  text-align: center;
  color: #b7b3ae;
}

.empty-state h2 {
  margin: 0 0 12px;
  font-size: clamp(28px, 3.2vw, 44px);
}

.empty-state p {
  margin: 0 auto 28px;
  max-width: 46ch;
}

.error-page {
  padding: 90px 0 120px;
  text-align: center;
  color: #c6c2bd;
}

.error-page p {
  margin: 0 auto 32px;
  max-width: 52ch;
}

/* "Read more" on an article card. */
.article-card__more {
  display: inline-block;
  margin-top: 10px;
  color: var(--gold);
  font-size: 13px;
  letter-spacing: 0.08em;
}

/* The language switcher when the current page has no counterpart: the link
   still works but goes to that locale's home, so it is marked as a weaker
   destination rather than presented as a direct translation. */
.lang-toggle--home {
  opacity: 0.7;
}

.home-contact__media img {
  display: block;
  width: 100%;
  height: auto;
}

/* Pagination gets a little breathing room under a grid. */
.pagination {
  margin-top: 56px;
}

/* --------------------------------------------------------------------------
   Article & news single — refinements

   The design's share row was a tight cluster of bare glyphs; these give each
   icon its own square and let the row breathe. Everything stays inside the
   design language: 1px gold hairlines, square corners, no shadows.
   -------------------------------------------------------------------------- */

.share-icons {
  gap: 10px;
}

.share-icons a {
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  transition: color 0.25s ease, border-color 0.25s ease, background-color 0.25s ease;
}

.share-icons a svg {
  width: 15px;
  height: 15px;
}

.share-icons a:hover {
  border-color: var(--gold);
  background: rgba(184, 154, 88, 0.13);
}

/* Images inside imported article bodies. WordPress left these inline and
   left-aligned; centring them stops a portrait still sitting off to one side
   of an otherwise centred column.

   Scoped with :not() so it cannot reach a gallery tile: those images are sized
   by their tile and need height:100%, which a blanket height:auto here would
   silently beat on equal specificity. */
/* A picture in body copy needs air under it. With `margin-inline` alone the
   next heading started at exactly the image's bottom edge — measured 0px — so
   the caption read as part of the photograph. */
.article-prose img:not(.gallery-item img) {
  display: block;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  margin-block: 24px;
}

.article-prose figure {
  margin-inline: auto;
  text-align: center;
}

/* Previous / next sat almost against the footer. Give the row room above and
   below, and a hairline above it so it reads as its own band rather than as
   body copy running into the footer. */
.post-nav {
  margin-top: 64px;
  margin-bottom: 96px;
  padding-top: 34px;
  border-top: 1px solid var(--line);
}

@media (max-width: 767px) {
  .post-nav {
    margin-top: 44px;
    margin-bottom: 64px;
  }
}

/* Project guarantees
   ------------------
   Restores the block that WordPress rendered from [elementor-template id=17888].
   Follows the .stat rhythm — a large light figure over a small caption — because
   that is the pattern this design already uses for a number with a subject. */
.guarantees-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 34px 24px;
  margin: 40px 0 48px;
}

.guarantee {
  text-align: center;
}

.guarantee__years {
  display: block;
  margin-bottom: 4px;
  color: var(--gold);
  font-family: "IBM Plex Sans Arabic", Arial, sans-serif;
  font-size: clamp(40px, 5vw, 62px);
  font-weight: 300;
  line-height: 1;
}

.guarantee__label {
  display: block;
  font-size: 15px;
  line-height: 1.45;
}

/* An album inside body copy: the project gallery's grid at a smaller scale so
   it does not overpower the text column it sits in.

   A fixed ratio rather than a min-height, because the tile's height has to be
   definite for the image's height:100% to resolve against it. Left indefinite,
   photographs of differing proportions each set their own height and the rows
   come out ragged. */
.article-prose .gallery-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin: 32px 0;
}

.article-prose .gallery-item {
  aspect-ratio: 4 / 3;
}

@media (max-width: 900px) {
  .guarantees-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .guarantees-grid,
  .article-prose .gallery-grid {
    grid-template-columns: 1fr;
  }
}


/* Home hero slideshow
   -------------------
   The live site cross-fades three project stills here. Slides stack in the same
   box and only opacity animates, so the browser never re-lays-out the largest
   element on the page mid-transition. */
.home-hero__slides {
  position: absolute;
  inset: 0;
}

.home-hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s ease-in-out;
}

.home-hero__slide.is-active {
  opacity: 1;
}

/* Respect a reader who has asked for less motion: they get the first frame and
   no cross-fade at all. */
@media (prefers-reduced-motion: reduce) {
  .home-hero__slide {
    transition: none;
  }
}

/* Project floor plans
   -------------------
   One villa model at a time, its floors as tabs. Seventeen plans stacked in a
   single column is not a page anyone reads. */
.floor-plans__tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 28px;
  margin-bottom: 30px;
}

/* These name the unit being shown, so they are the label a visitor reads to
   choose between plans — not secondary chrome. At 15px regular in the muted
   grey they sat quieter than the plan drawing beneath them. */
.floor-plans__tab {
  padding: 6px 2px;
  border: 0;
  border-bottom: 1px solid transparent;
  background: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 17px;
  font-weight: 700;
  cursor: pointer;
  transition: color 0.25s ease, border-color 0.25s ease;
}

.floor-plans__tab:hover {
  color: var(--gold);
}

.floor-plans__tab[aria-selected="true"] {
  border-bottom-color: var(--gold);
  color: var(--gold);
}

.floor-plans__panel img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  background: #f1eee8;
}

.floor-plans__panel:not([hidden]) {
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
  gap: 10px;
}

/* Two plans in a panel sit side by side, one fills the width.
   Both spellings are needed: a responsive image is wrapped in a <picture>, so
   the siblings are pictures rather than imgs. display:contents fixes the
   layout but not the selector — :has() matches the DOM, not the boxes. */
.floor-plans__panel:not([hidden]):has(img + img),
.floor-plans__panel:not([hidden]):has(picture + picture) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.project-editorial-section,
.project-features-section,
.project-guarantees-section {
  padding: 45px 0;
}

.project-editorial-content {
  width: min(1140px, calc(100% - 48px));
  color: #ddd9d4;
  font-size: 15px;
  line-height: 25px;
}

.project-editorial-content > img {
  margin-block: 25px;
}

/*
   `margin-inline: auto`, or these are not centred at all.

   `.section-title` is a 760px box inside an 1180px container. `text-align:
   center` centres the words *within that box* — and with no auto inline margins
   the box itself sits flush against the inline start, so both headings landed
   about 210px right of the page's centre. The floor section already carries
   `margin: 0 auto`; these two were the ones that did not.
 */
.project-features-section .section-title,
.project-guarantees-section .section-title {
  margin-inline: auto;
  margin-bottom: 38px;
  color: var(--project-accent, var(--gold));
  text-align: center;
  font-size: 22px;
}

.project-features-grid,
.project-guarantees-grid {
  display: grid;
  gap: 24px;
  align-items: start;
}

.project-features-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}

.project-guarantees-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 38px 30px;
}

.project-feature,
.project-guarantee {
  display: grid;
  justify-items: center;
  gap: 10px;
  color: #f2f0ed;
  text-align: center;
  font-size: 15px;
  line-height: 1.45;
}

.project-feature img {
  width: 100px;
  height: 100px;
  object-fit: contain;
}

.project-guarantee img {
  width: 105px;
  height: 109px;
  object-fit: contain;
}

.project-guarantee strong {
  color: var(--project-accent, var(--gold));
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
}

.project-guarantee span {
  font-size: 14px;
  line-height: 14px;
}

.project-features-section--concept {
  min-height: 635px;
  padding: 0;
}

.project-features-section--concept > .container {
  width: min(1400px, calc(100% - 40px));
  max-width: 1400px;
}

.project-features-layout {
  display: block;
}

.project-features-section--concept .project-features-layout {
  display: grid;
  grid-template-columns: 48% 52%;
  align-items: stretch;
}

.project-features-section--concept .project-features-copy {
  align-self: center;
  padding: 55px 30px;
}

/*
 * Only while the copy actually sits beside the concept image.
 *
 * The column is a fixed 48% share, but its content — a kicker, a title and
 * five short labels — needs a fraction of that. With every block left at full
 * width and aligned to `start`, all the slack collected on the inner edge and
 * opened a ~530px void between the image and the text. Shrinking each block to
 * its own content and parking it on the inline-end edge closes that gap; a
 * column flex container's cross axis follows `direction`, so this holds in
 * both RTL and LTR without a direction-specific rule.
 *
 * Below 900px the layout collapses to a single stacked column and there is no
 * image to hug — inline-end then means the wrong edge outright (the Arabic
 * list pinned left with 240px of space to its right). Hence the min-width,
 * paired to the max-width:900px rule that does the collapsing.
 */
@media (min-width: 901px) {
  .project-features-section--concept .project-features-copy {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
  }
}

.project-features-kicker {
  margin: 0 0 18px;
  color: #fff;
  font-size: 25px;
  line-height: 1.2;
}

.project-features-section--concept .section-title {
  margin: 0 0 34px;
  text-align: start;
  font-size: 32px;
}

.project-features-section--concept .project-features-grid {
  grid-template-columns: 1fr;
  gap: 18px;
}

.project-features-section--concept .project-feature {
  display: block;
  color: #fff;
  text-align: start;
  font-size: 15px;
}

.project-features-concept-image,
.project-features-concept-image img {
  width: 100%;
  height: 100%;
  min-height: 635px;
}

.project-features-concept-image img {
  object-fit: contain;
}

.project-intro-special-actions {
  margin-top: 24px;
}

.project-luxury-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

/*
   The row's buttons are the same height as each other.

   `.project-brochure` carries `margin-top: 24px` from when that button stood
   alone under the copy. In this flex row the line stretches items to the
   tallest, and a top margin comes out of that height — so the brochure rendered
   46px tall and sat 24px lower than its 70px neighbour, bottom-aligned with it,
   which is the mismatched pair on screen. The margin belongs to the standalone
   case, not to a row.
 */
.project-luxury-actions .btn {
  flex: 0 0 auto;
  margin-top: 0;
  min-height: 41px;
  padding: 8px 20px;
  border-color: var(--project-accent, var(--gold));
  color: var(--project-accent, var(--gold));
  font-size: 15px;
  font-weight: 500;
}

.project-inline-interest {
  min-height: 423px;
  padding: 10px 0;
  scroll-margin-top: 70px;
}

.project-inline-interest > .container {
  width: min(1380px, calc(100% - 40px));
  max-width: 1380px;
}

.project-inline-interest h2 {
  margin: 0 0 20px;
  color: var(--gold);
  font-size: 32px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.project-inline-interest__form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 40px;
}

.project-inline-interest__form .field {
  margin: 0;
}

.project-inline-interest__form .field--phone,
.project-inline-interest__form .field--message,
.project-inline-interest__form .field--submit {
  grid-column: 1 / -1;
}

.project-inline-interest__form input,
.project-inline-interest__form textarea {
  width: 100%;
  padding: 4.5px 0;
  border: 0;
  border-bottom: 1px solid #5b5b5b;
  border-radius: 0;
  background: transparent;
  color: #fff;
  font: inherit;
  font-size: 15px;
  line-height: 25px;
}

.project-inline-interest__form input {
  height: 35px;
  min-height: 35px;
}

.project-inline-interest__form textarea {
  height: 124px;
  min-height: 124px;
  resize: none;
}

.project-inline-interest__form .field--submit {
  margin-top: -10px;
}

.project-inline-interest__form .btn {
  width: 219px;
  min-height: 47px;
  border-color: var(--gold);
  color: var(--gold);
  font-size: 12px;
  font-weight: 700;
}

.project-video-dialog {
  width: min(1120px, calc(100% - 48px));
  padding: 0;
  border: 1px solid var(--project-accent, var(--gold));
  background: #050505;
  color: #fff;
}

.project-video-dialog::backdrop {
  background: rgba(0, 0, 0, 0.92);
}

.project-video-dialog iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
}

.project-video-dialog__close {
  position: absolute;
  z-index: 1;
  top: 8px;
  right: 8px;
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  cursor: pointer;
  font-size: 28px;
}

/* `.btn` included: the arrows and the share row already took the project's own
   colour while every button on the page stayed gold, which is the mismatch the
   client reported. The outline button borrows it for its border too. */
/*
   `:not(.carousel__arrow--chevron)` on the arrows.

   The accent tint here is deliberate and stays — it is what the client asked
   for when the arrows and share row took the project's colour while the buttons
   stayed gold. The gallery's chevron is the exception: the published page draws
   it in the site's own gold whatever the project's accent is, and on a project
   whose accent is a slate grey the chevron came out grey against gold arrows
   everywhere else on the page.
 */
[data-page="project"] .project-floor-section .section-title,
[data-page="project"] .floor-plans__tab,
[data-page="project"] .carousel__arrow:not(.carousel__arrow--chevron),
[data-page="project"] .project-post-nav a,
[data-page="project"] .project-share,
[data-page="project"] .btn:not(.btn--fill) {
  color: var(--project-accent, var(--gold));
}

/*
   The label on hover, restated because the rule above outranks it.

   `.btn:hover` turns the label black so it reads against the fill wiping up
   behind it. That is two class-level selectors; the accent rule above is three,
   so on a project page it kept winning and the label stayed the accent colour —
   the same colour the fill had just become. Every outline button on a project
   went blank on hover, which is what a visitor sees as the text disappearing.

   The action bar carries the identical pair for the identical reason.
 */
[data-page="project"] .btn:not(.btn--fill):hover,
[data-page="project"] .btn:not(.btn--fill):focus-visible {
  color: #000;
}

/*
   The border and the wipe, for both button variants.

   `background-image` and not `background`: a button's fill is a gradient that
   grows from `background-size: 100% 0` to full on hover, and the shorthand
   would take the size, position and repeat with it — the animation would stop
   working and the filled variant would lose its hover inverse.

   `.btn--fill` keeps its white label: on that variant the accent is the fill,
   so the text has to contrast with it rather than match it.
 */
[data-page="project"] .btn {
  border-color: var(--project-accent, var(--gold));
  background-image: linear-gradient(
    0deg,
    var(--project-accent, var(--gold)) 0,
    var(--project-accent, var(--gold)) 100%
  );
}

[data-page="project"] .floor-plans__tab[aria-selected="true"] {
  border-bottom-color: var(--project-accent, var(--gold));
  color: var(--project-accent, var(--gold));
}

body[data-project="first-projects-sky"] .fact dt,
body[data-project="first-projects-sky"] .fact dd {
  font-size: 15px;
  line-height: 25px;
}

body[data-project="aurora-villas"] .project-intro__copy h2 {
  font-size: 28px;
  line-height: 1.11;
}

@media (max-width: 900px) {
  .project-features-grid,
  .project-guarantees-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .project-features-section--concept .project-features-layout,
  .project-inline-interest__form {
    grid-template-columns: 1fr;
  }

  .project-inline-interest__form .field {
    grid-column: 1;
  }
}

@media (max-width: 600px) {
  .project-features-grid,
  .project-guarantees-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* The gallery carousel reuses the shared carousel; only the slide width is
   project-specific. */
[data-page="project"] .project-gallery-section .carousel__track > * {
  flex: 0 0 33.3333%;
  min-height: 350px;
}

.project-gallery-open {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}

.project-gallery-dialog {
  width: 100vw;
  max-width: none;
  height: 100vh;
  max-height: none;
  padding: 0;
  border: 0;
  background: rgba(0, 0, 0, 0.96);
  color: #fff;
}

.project-gallery-dialog::backdrop {
  background: #000;
}

.project-gallery-dialog figure {
  display: grid;
  width: 100%;
  height: 100%;
  margin: 0;
  place-items: center;
}

.project-gallery-dialog figure img {
  max-width: calc(100vw - 150px);
  max-height: calc(100vh - 110px);
  object-fit: contain;
  transition: transform 0.25s ease;
}

.project-gallery-dialog.is-zoomed figure img {
  cursor: zoom-out;
  transform: scale(1.5);
}

.project-gallery-dialog figcaption {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
}

.project-gallery-dialog__toolbar {
  position: absolute;
  z-index: 2;
  top: 16px;
  right: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.project-gallery-dialog__toolbar button,
.project-gallery-dialog__arrow {
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border: 0;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  cursor: pointer;
  font-size: 25px;
}

.project-gallery-dialog__arrow {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  font-size: 42px;
}

/* Logical, not `left`/`right`.

   Pinned physically, "previous" stayed on the left in Arabic while the glyphs
   `‹` and `›` — both Bidi_Mirrored characters — were flipped by the RTL
   paragraph around them. The pair ended up pointing inwards at each other, and
   the left arrow stepped backwards although in Arabic the reading runs that
   way. Resolved against the inline axis, "previous" sits on the right in
   Arabic and the mirroring lands each head pointing outwards, which is also
   what the arrow keys already do: ArrowLeft advances under `dir="rtl"`. */
.project-gallery-dialog__arrow--prev {
  inset-inline-start: 18px;
}

.project-gallery-dialog__arrow--next {
  inset-inline-end: 18px;
}

/* Projects without structured distance, plan or materials bands follow the
   compact published composition. The section sizes come from their content and
   original media aspect ratios, so this works for every matching project. */
[data-page="project"] .page-hero--published-compact {
  min-height: 250px;
}

[data-page="project"] .project-logo-stage--published-compact {
  min-height: 0;
  padding: 10px 24px;
}

[data-page="project"] .project-logo-stage--published-compact img {
  width: 300px;
  height: auto;
  max-height: 300px;
}

[data-page="project"] .project-overview-section--published-compact {
  padding-bottom: 0;
}

[data-page="project"] .project-intro--published-compact {
  width: min(1100px, calc(100% - 48px));
  min-height: 0;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Same reason as the rule above: level with the middle of the image. */
  align-items: center;
  gap: 0;
  padding: 50px 0 33px;
}

[data-page="project"] .project-intro--published-compact.project-intro--with-prose {
  min-height: 540px;
}

[data-page="project"] .project-intro--published-compact .project-intro__media,
[data-page="project"] .project-intro--published-compact .project-intro__copy {
  min-width: 0;
  padding-inline: 10px;
}

[data-page="project"] .project-intro--published-compact .project-intro__image img {
  width: 100%;
  height: auto;
  max-height: none;
  object-fit: cover;
}

[data-page="project"] .project-intro--published-compact .project-intro__copy {
  padding-top: 0;
}

[data-page="project"] .project-intro--published-compact .project-intro__body {
  color: #ddd9d4;
  font-size: 15px;
  line-height: 1.65;
}

[data-page="project"] .project-intro--published-compact .project-intro__body h3 {
  margin: 0 0 4px;
  color: #f2f0ed;
  font-size: 22px;
  font-weight: 700;
}

[data-page="project"] .project-intro--published-compact .project-intro__body p {
  max-width: none;
  margin: 0;
  color: inherit;
  line-height: inherit;
}

[data-page="project"] .project-intro--published-compact .facts {
  margin-top: 18px;
}

[data-page="project"] .project-overview-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 30px;
}

[data-page="project"] .project-overview-actions .btn {
  min-width: 100px;
  min-height: 40px;
  padding: 7px 16px;
  font-size: 13px;
}

[data-page="project"] .project-overview-action--brochure {
  order: 1;
}

[data-page="project"] .project-overview-action--document {
  order: 2;
}

[data-page="project"] .project-overview-action--map {
  order: 3;
}

[data-page="project"] .project-overview-action--external {
  order: 4;
}

[data-page="project"] .project-compact-features {
  padding: 24px 0;
}

[data-page="project"] .project-compact-features__inner {
  display: flex;
  min-height: 30px;
  align-items: center;
  justify-content: center;
  gap: 18px 52px;
  color: #ddd9d4;
  font-size: 15px;
  font-weight: 600;
  text-align: center;
}

[data-page="project"] .project-gallery-section--published-compact {
  padding: 13px 0;
}

/* 300px, not 240: measured against the published gallery, whose tiles are
   roughly as tall as they are wide rather than the letterbox this was. */
[data-page="project"] .project-gallery-section--published-compact .gallery-item,
[data-page="project"] .project-gallery-section--published-compact .carousel__track > * {
  min-height: 300px;
  height: 300px;
}

[data-page="project"] .project-map-section--published-compact,
[data-page="project"] .project-map-section--published-compact .map-frame {
  height: 470px;
  min-height: 470px;
}

[data-page="project"] .project-map-section--published-compact .map-frame {
  filter: none;
}

[data-page="project"] .project-post-nav .project-share {
  border: 0;
  background: transparent;
  color: var(--gold);
  font: inherit;
  cursor: pointer;
}

@media (max-width: 900px) {
  [data-page="project"] .project-body-gallery-section .gallery-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  [data-page="project"] .project-gallery-section .carousel__track > * {
    flex-basis: 50%;
  }

  [data-page="project"] .project-intro--published-compact {
    min-height: 0;
    grid-template-columns: 1fr;
    gap: 36px;
  }

  [data-page="project"] .project-intro--published-compact.project-intro--with-prose {
    min-height: 0;
  }
}

@media (max-width: 600px) {
  [data-page="project"] .project-body-gallery-section .gallery-grid {
    grid-template-columns: 1fr;
  }

  .floor-plans__tabs {
    gap: 6px 16px;
  }

  [data-page="project"] .project-gallery-section .carousel__track > * {
    flex-basis: 100%;
  }

  [data-page="project"] .project-overview-actions {
    flex-wrap: wrap;
  }

  [data-page="project"] .project-overview-actions .btn {
    flex: 1 1 140px;
  }
}
