/**
 * Component styles for the public site.
 *
 * Tailwind utilities handle layout in the templates; this file holds the few
 * repeated components and everything that needs a real selector - focus rings,
 * dropdown hover behaviour, and the logical properties that let the Arabic
 * layout mirror without a second stylesheet.
 *
 * Colours come from the CSS custom properties emitted by theme_service.php, so
 * changing a colour in the admin panel changes them here too.
 */

/* ------------------------------------------------------------ typography - */

body {
  font-family: Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .font-heading {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.015em;
}

/* Plus Jakarta Sans and Inter have no Arabic coverage, so Arabic falls back to a real
   Arabic face rather than rendering in a substituted one with mismatched
   metrics. Noto Kufi is geometric, which sits close to Plus Jakarta Sans in weight. */
html[lang="ar"] body,
html[lang="ar"] h1, html[lang="ar"] h2, html[lang="ar"] h3, html[lang="ar"] h4,
html[dir="rtl"] body,
html[dir="rtl"] h1, html[dir="rtl"] h2, html[dir="rtl"] h3, html[dir="rtl"] h4 {
  font-family: "Noto Kufi Arabic", "Segoe UI", Tahoma, system-ui, sans-serif;
}

/* Arabic headings do not want the negative tracking the Latin headings are given. */
html[lang="ar"] h1, html[lang="ar"] h2, html[lang="ar"] h3, html[lang="ar"] h4,
html[dir="rtl"] h1, html[dir="rtl"] h2, html[dir="rtl"] h3, html[dir="rtl"] h4 {
  letter-spacing: 0;
}

/* A section with no Arabic translation yet is shown in English and marked
   lang="en" dir="ltr" (rd_render_section). It keeps the Latin typefaces, so the
   page reads as English-in-an-Arabic-site rather than English set in Kufi. */
html[dir="rtl"] [lang="en"] {
  font-family: Inter, system-ui, sans-serif;
}

html[dir="rtl"] [lang="en"] :is(h1, h2, h3, h4, .font-heading, .stat-value) {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  letter-spacing: -0.015em;
}

/* ---------------------------------------------------------- skip link ---- */

/* Hidden by clipping, not by parking the box off-screen.
   `inset-inline-start: -9999px` resolves to LEFT in English and to RIGHT in
   Arabic, so the RTL pages carried a 163px-wide element sitting 10,000px past
   the right edge - harmless in Chrome today, real horizontal overflow the
   moment an engine accounts for it. Clipping is direction-agnostic and keeps
   the link focusable, which `display: none` would not. */
.skip-link {
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  z-index: 100;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--rd-primary);
  /* White, not ink: white on the purple fill is 8.0:1; dark ink on it is 2.2:1. */
  color: #fff;
  font-weight: 600;
}

.skip-link:focus {
  width: auto;
  height: auto;
  padding: 0.75rem 1.25rem;
  overflow: visible;
  clip-path: none;
}

/* -------------------------------------------------------------- header --- */

/* The header floats transparently over the banner. Once the page scrolls it
   becomes frosted glass: white at --rd-head-alpha (Admin -> Settings -> Website
   behaviour: solid, 25% or 50% see-through) over a blurred page.

   Why dark text stays readable at 50%: over the DARKEST band (#1B0B2E) the
   glass averages to about rgb(141,141,141), where ink is 5.4:1 and the
   secondary colour 5.0:1. Brand purple text would be 3.7:1 there, so the
   active link is ink with a purple underline rather than purple text. */

.site-head {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  transition: background-color 0.25s ease, box-shadow 0.25s ease;
}

.site-head.is-scrolled {
  background: rgb(255 255 255 / var(--rd-head-alpha, 1));
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  box-shadow: 0 6px 24px -16px rgb(var(--rd-ink-rgb) / 0.45);
}

.site-topbar {
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.85);
  overflow: hidden;
  max-height: 3rem;
  transition: max-height 0.25s ease, opacity 0.2s ease, border-color 0.25s ease;
}

/* Collapse the utility bar once scrolling starts, so the header stays compact. */
.site-head.is-scrolled .site-topbar {
  max-height: 0;
  opacity: 0;
  border-color: transparent;
}

.site-header {
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s ease;
}

.site-head.is-scrolled .site-header {
  border-bottom-color: rgb(255 255 255 / 0.5);
}

/* Logo swap: light over the banner, dark over white. */
.site-logo {
  display: block;
  width: auto;
  object-fit: contain;
}

.site-logo--dark {
  display: none;
}

.site-head.is-scrolled .site-logo--light {
  display: none;
}

.site-head.is-scrolled .site-logo--dark {
  display: block;
}

.nav-link {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.88);
  transition: color 0.15s ease, background-color 0.15s ease;
  white-space: nowrap;
}

.nav-link:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

.nav-link.is-active {
  color: var(--rd-on-dark);
}

.site-head.is-scrolled .nav-link {
  color: var(--rd-secondary);
}

.site-head.is-scrolled .nav-link:hover {
  color: var(--rd-ink);
  background: rgb(255 255 255 / 0.6);
}

.site-head.is-scrolled .nav-link.is-active {
  color: var(--rd-ink);
  box-shadow: inset 0 -2px 0 var(--rd-primary);
  border-radius: 0.5rem 0.5rem 0 0;
}

/* Language button and mobile toggle follow the same two states. */
.lang-button,
.menu-toggle {
  border-color: rgba(255, 255, 255, 0.35);
  color: rgba(255, 255, 255, 0.9);
}

.lang-button:hover,
.menu-toggle:hover {
  border-color: #fff;
  color: #fff;
}

.site-head.is-scrolled .lang-button,
.site-head.is-scrolled .menu-toggle {
  border-color: var(--rd-border);
  color: var(--rd-secondary);
}

.site-head.is-scrolled .lang-button:hover,
.site-head.is-scrolled .menu-toggle:hover {
  border-color: var(--rd-ink);
  color: var(--rd-ink);
}

/* The mobile menu is a white panel, so its controls always use dark ink. */
.mobile-menu .menu-toggle {
  border-color: var(--rd-border);
  color: var(--rd-secondary);
}

/* --------------------------------------------------------- dropdowns ----- */

.nav-dropdown {
  position: relative;
}

.nav-dropdown-panel {
  position: absolute;
  inset-inline-start: 0;
  top: calc(100% + 0.25rem);
  z-index: 60;
  min-width: 15rem;
  padding: 0.5rem;
  border: 1px solid var(--rd-border);
  border-radius: 0.75rem;
  background: #fff;
  box-shadow: 0 18px 40px -22px rgb(var(--rd-ink-rgb) / 0.5);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

.nav-dropdown-panel--right {
  inset-inline-start: auto;
  inset-inline-end: 0;
}

.nav-dropdown:hover .nav-dropdown-panel,
.nav-dropdown:focus-within .nav-dropdown-panel,
.nav-dropdown-panel.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.nav-dropdown-link {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--rd-secondary);
}

.nav-dropdown-link:hover {
  background: var(--rd-surface-alt);
  color: var(--rd-primary-dark);
}

.nav-dropdown-link.is-active {
  background: var(--rd-primary);
  color: #fff;
}

/* Structure only. Colour belongs to the header's two states, set above and in
   the .is-scrolled rules - this block used to re-declare `color` and
   `border-color` here, and being later in the file it silently overrode the
   white treatment, leaving "EN" dark on the transparent header. Same trap as
   .menu-toggle vs xl:hidden. */
.lang-button {
  padding: 0.45rem 0.7rem;
  border-width: 1px;
  border-style: solid;
  border-radius: 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
}

.site-head.is-scrolled .lang-button:hover {
  border-color: var(--rd-primary-dark);
  color: var(--rd-primary-dark);
}

/* ------------------------------------------------------- mobile menu ----- */

/* STRUCTURE ONLY - the same trap as .lang-button above, and this block fell
   into it twice. `display` is omitted because at equal specificity a
   `display: inline-flex` here beat Tailwind's `xl:hidden` (media queries add
   no specificity) and the hamburger stayed visible beside the desktop nav.
   `color` and `border-color` are omitted because this block sits AFTER the
   header's state rules and silently overrode them: the hero slider's
   prev/next buttons reuse .menu-toggle and came out navy-on-navy, i.e. two
   empty boxes. Colour belongs to the state rules and to the markup. */
.menu-toggle {
  width: 2.75rem;
  height: 2.75rem;
  border-width: 1px;
  border-style: solid;
  border-radius: 0.5rem;
}

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 80;
  overflow-y: auto;
  background: #fff;
}

.mobile-menu[hidden] {
  display: none;
}

.mobile-link {
  display: block;
  padding: 0.7rem 0.9rem;
  border-radius: 0.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--rd-secondary);
}

.mobile-link:hover {
  background: var(--rd-surface-alt);
  color: var(--rd-primary-dark);
}

.mobile-link.is-active {
  background: var(--rd-primary);
  color: #fff;
}

.mobile-link--child {
  margin-inline-start: 1rem;
  font-size: 0.875rem;
  font-weight: 500;
}

/* ------------------------------------------------------------ buttons ---- */

/* STRUCTURE ONLY - no `display`. site.css loads after tailwind.css, so at
   equal specificity a `display: inline-flex` here beat Tailwind's `.hidden`
   and the header's desktop-only CTA stayed on screen at phone width, pushing
   the page wider than the viewport. Display lives in the markup. */
.btn-primary,
.btn-secondary,
.btn-ghost {
  align-items: center;
  justify-content: center;
  /* "Get a Callback" was breaking across two lines in the header. A button
     label is a single unit; let the button grow instead of the text wrapping. */
  white-space: nowrap;
  gap: 0.5rem;
  padding: 0.7rem 1.35rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.2;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

/* Purple carries WHITE text (8.0:1); dark ink on it is 2.2:1 and fails. */
.btn-primary {
  background: var(--rd-primary);
  color: #fff;
}

.btn-primary:hover {
  background: var(--rd-primary-dark);
  color: #fff;
  transform: translateY(-1px);
}

/* Gold carries DARK text (10.3:1). White on gold is 1.7:1 - never do it.
   The hover tone is the deep gold, which does take white (6.2:1). */
.btn-secondary {
  background: var(--rd-accent);
  color: var(--rd-ink);
}

.btn-secondary:hover {
  background: var(--rd-accent-dark);
  color: #fff;
  transform: translateY(-1px);
}

.btn-ghost {
  border: 1px solid rgba(255, 255, 255, 0.6);
  color: #fff;
}

.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.12);
}

.btn-outline {
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--rd-border);
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--rd-secondary);
  transition: border-color 0.15s ease, color 0.15s ease;
}

.btn-outline:hover {
  border-color: var(--rd-primary-dark);
  color: var(--rd-primary-dark);
}

/* Arrow glyphs inside buttons must point the other way in RTL. :dir() rather
   than html[dir="rtl"]: an untranslated section on an Arabic page is marked
   dir="ltr", and its arrows must keep pointing forward. */
.btn-primary svg:dir(rtl),
.btn-secondary svg:dir(rtl),
.btn-outline svg:dir(rtl),
.link-arrow svg:dir(rtl) {
  transform: scaleX(-1);
}

/* ----------------------------------------------------------- sections ---- */

.section {
  padding-block: 4rem;
}

@media (min-width: 768px) {
  .section {
    padding-block: 5.5rem;
  }
}

.section-kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rd-primary-dark);
}

.section-kicker--light {
  color: var(--rd-on-dark);
}

/* The "01 / OUR SERVICES" counter that runs down the page.
   NOT --rd-accent: bright amber is 1.75:1 on white, and at ~17px bold this
   sits under the large-text threshold so it needs the full 4.5:1. */
.section-number {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--rd-accent-dark);
}

.section-number-divider {
  margin-inline: 0.15rem 0.35rem;
  /* Was --rd-border, a divider-line grey: 1.30:1 on white, so the slash between
     "01" and the kicker was invisible. This is the muted text token. */
  color: var(--rd-muted);
  font-weight: 400;
}

/* Hero video fades in once it can actually play, so a slow connection shows
   the poster image rather than a black rectangle. */
video[data-hero-video].is-ready {
  opacity: 1;
}

.section-title {
  margin-top: 0.75rem;
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  font-weight: 700;
  line-height: 1.15;
  color: var(--rd-ink);
}

.section-title--light {
  color: #fff;
}

/* The About block is set noticeably larger than the rest of the page, as on
   the reference site, so it reads as the site's statement of who we are. */
.section-title--xl {
  font-size: clamp(2.1rem, 4.4vw, 3.5rem);
  line-height: 1.06;
  letter-spacing: -0.01em;
}

.section-lead {
  margin-top: 1rem;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--rd-body);
}

.section-lead--xl {
  font-size: 1.0625rem;
  line-height: 1.8;
}

@media (min-width: 1024px) {
  .section-lead--xl {
    font-size: 1.15rem;
  }
}

.section-lead--light {
  color: rgba(255, 255, 255, 0.82);
}

/* Accent rule under headings, mirrored in RTL. A graphic, so the 3:1 bar
   applies - amber was 1.75:1 on white and effectively invisible. */
.title-rule::after {
  content: "";
  display: block;
  width: 3.5rem;
  height: 3px;
  margin-top: 1rem;
  border-radius: 2px;
  background: var(--rd-primary);
}

/* -------------------------------------------------------------- cards ---- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border: 1px solid var(--rd-border);
  border-radius: 1.25rem;
  background: #fff;
  box-shadow: 0 1px 2px rgb(var(--rd-ink-rgb) / 0.04);
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

/* A purple-to-gold line that draws across the top edge on hover. */
.card::after {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  z-index: 2;
  height: 3px;
  background: linear-gradient(90deg, var(--rd-primary), var(--rd-accent));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s ease;
}

.card:dir(rtl)::after {
  transform-origin: right;
}

.card:hover {
  transform: translateY(-4px);
  border-color: transparent;
  box-shadow: 0 22px 44px -26px rgb(var(--rd-overlay-rgb) / 0.55);
}

.card:hover::after {
  transform: scaleX(1);
}

.card-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: flex-start;
  padding: 1.75rem;
}

/* Edge-to-edge photograph at the top of a card. */
.card-media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--rd-surface-alt);
}

.card-media-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s ease;
}

.card:hover .card-media-img {
  transform: scale(1.05);
}

/* Under a photo the badge overlaps the picture's lower edge; the ring is the
   card's own background, so the badge looks cut into the photo. */
.card--media .card-body {
  padding-top: 0;
}

.card--media .card-body > .card-icon {
  position: relative;
  z-index: 1;
  margin-top: -1.75rem;
  box-shadow: 0 0 0 5px var(--card-ring, #fff), 0 12px 24px -12px rgb(var(--rd-primary-rgb) / 0.7);
}

.card--media .card-body > .card-title:first-child {
  margin-top: 1.4rem;
}

.card-icon {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 1rem;
  background-color: var(--rd-primary);
  background-image: linear-gradient(135deg, var(--rd-primary) 0%, var(--rd-primary-dark) 100%);
  /* White on the purple gradient: 8.0:1 at its lightest. */
  color: #fff;
  box-shadow: 0 12px 24px -12px rgb(var(--rd-primary-rgb) / 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  transition: transform 0.25s ease;
}

.card:hover .card-icon {
  transform: translateY(-2px) rotate(-5deg);
}

.card-title {
  margin-top: 1.25rem;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--rd-ink);
}

.card-text {
  margin-top: 0.6rem;
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--rd-body);
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--rd-primary-dark);
}

.link-arrow:hover {
  color: var(--rd-ink);
}

/* ---------------------------------------------------------------- hero --- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* The colour behind the video while it loads, and if it fails to play.
     Must be a DARK band tone, never --rd-primary or --rd-primary-dark: a
     slow connection would then show a red block under white hero text at
     4.79:1, which is fine for a button and wrong for a headline. */
  background: var(--rd-band-navy, #1b0b2e);
}

.hero-slide {
  position: absolute;
  inset: 0;
  transition: opacity 0.8s ease;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgb(var(--rd-overlay-rgb) / 0.92) 0%, rgb(var(--rd-band-navy-rgb) / 0.78) 45%, rgb(var(--rd-secondary-rgb) / 0.42) 100%);
}

/* :dir(), not html[dir]: the dark side must follow the TEXT, and an untranslated
   hero on an Arabic page keeps its English, left-aligned text. */
.hero-overlay:dir(rtl) {
  background: linear-gradient(260deg, rgb(var(--rd-overlay-rgb) / 0.92) 0%, rgb(var(--rd-band-navy-rgb) / 0.78) 45%, rgb(var(--rd-secondary-rgb) / 0.42) 100%);
}

/* -------------------------------------------- hero video overlay --------- *
 * The reference site darkens its hero video with a single layer at
 * opacity .37. These are pitched around that: enough contrast under white
 * text on the left, light enough that the footage still reads on the right.
 *
 * Written here rather than as Tailwind gradient utilities because the opacity
 * values needed (.16-.72) are not on Tailwind's opacity scale, so
 * `to-navy-900/28` and friends were silently never generated.
 */
.hero-video-overlay {
  position: absolute;
  inset: 0;
  /* Weighted to the text column rather than raised everywhere. The footage is
     a bright daytime aerial - white cloud and glass - where the old even
     overlay left the heading at 2.8:1 on its brightest pixels. The right-hand
     side stays light so the picture still reads. */
  background:
    linear-gradient(to bottom, rgb(var(--rd-overlay-rgb) / 0.55) 0%, rgb(var(--rd-overlay-rgb) / 0) 22%),
    linear-gradient(
      100deg,
      rgb(var(--rd-overlay-rgb) / 0.72) 0%,
      rgb(var(--rd-overlay-rgb) / 0.62) 38%,
      rgb(var(--rd-overlay-rgb) / 0.34) 72%,
      rgb(var(--rd-overlay-rgb) / 0.22) 100%
    );
}

.hero-video-overlay--light {
  background:
    linear-gradient(to bottom, rgb(var(--rd-overlay-rgb) / 0.4) 0%, rgb(var(--rd-overlay-rgb) / 0) 22%),
    linear-gradient(
      100deg,
      rgb(var(--rd-overlay-rgb) / 0.55) 0%,
      rgb(var(--rd-overlay-rgb) / 0.44) 38%,
      rgb(var(--rd-overlay-rgb) / 0.22) 72%,
      rgb(var(--rd-overlay-rgb) / 0.14) 100%
    );
}

.hero-video-overlay--dark {
  background:
    linear-gradient(to bottom, rgb(var(--rd-overlay-rgb) / 0.6) 0%, rgb(var(--rd-overlay-rgb) / 0) 22%),
    linear-gradient(
      100deg,
      rgb(var(--rd-overlay-rgb) / 0.85) 0%,
      rgb(var(--rd-overlay-rgb) / 0.74) 38%,
      rgb(var(--rd-overlay-rgb) / 0.5) 72%,
      rgb(var(--rd-overlay-rgb) / 0.36) 100%
    );
}

.hero-video-overlay:dir(rtl),
.hero-video-overlay--light:dir(rtl),
.hero-video-overlay--dark:dir(rtl) {
  background-image: linear-gradient(
    260deg,
    var(--rd-hero-a) 0%,
    var(--rd-hero-b) 45%,
    var(--rd-hero-c) 100%
  );
}

.hero-video-overlay {
  --rd-hero-a: rgb(var(--rd-overlay-rgb) / 0.55);
  --rd-hero-b: rgb(var(--rd-overlay-rgb) / 0.4);
  --rd-hero-c: rgb(var(--rd-overlay-rgb) / 0.28);
}

.hero-video-overlay--light {
  --rd-hero-a: rgb(var(--rd-overlay-rgb) / 0.4);
  --rd-hero-b: rgb(var(--rd-overlay-rgb) / 0.26);
  --rd-hero-c: rgb(var(--rd-overlay-rgb) / 0.16);
}

.hero-video-overlay--dark {
  --rd-hero-a: rgb(var(--rd-overlay-rgb) / 0.72);
  --rd-hero-b: rgb(var(--rd-overlay-rgb) / 0.58);
  --rd-hero-c: rgb(var(--rd-overlay-rgb) / 0.44);
}

.hero-dot {
  width: 2.25rem;
  height: 0.25rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.4);
  transition: background-color 0.2s ease;
}

.hero-dot.is-active {
  background: var(--rd-primary);
}

/* --------------------------------------------------------------- stats --- */

.stat-value {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  /* Capped at 2.5rem rather than 3rem: with white-space:nowrap a value like
     "60 min" overflowed its column in the four-across grid and collided
     with its neighbour. */
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  font-weight: 700;
  line-height: 1;
  /* Primary dark, 12.0:1 on white. The accent here would be 1.7:1 - a 48px number nobody could
     read. On a dark band the .rd-bg--* rules swap this for --rd-on-dark. */
  color: var(--rd-primary-dark);
  /* "60 min" and "7 days" were breaking across two lines in a four-column
     grid; a counter is one token. */
  white-space: nowrap;
}

/* Banner shading darkest behind the text: on the left in English, on the
   right in Arabic. Tailwind's bg-gradient-to-r is fixed to the left, which put
   Arabic banner headings on the LIGHTEST part of the shade. */
.bg-gradient-to-r.shade-follows-text:dir(rtl) {
  background-image: linear-gradient(to left, var(--tw-gradient-stops));
}

/* Phone numbers and email addresses are left-to-right in every language, but
   on an Arabic page they line up with the right-hand edge like the labels. */
html[dir="rtl"] .field-input[dir="ltr"] {
  text-align: right;
}

/* A counter that is words rather than a number ("Door to door"). */
.stat-value--words {
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  line-height: 1.15;
  white-space: normal;
}

/* The caption under a counter. A class, not a utility, because the section can
   be moved onto a dark band from the admin panel and text-slateink-500 cannot
   be corrected for that - it dropped to 3.23:1 the moment the homepage intro
   was switched to the navy band. */
.stat-label {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.375;
  color: var(--rd-muted);
}

.rd-bg--brand .stat-label,
.rd-bg--dark .stat-label,
.rd-bg--image .stat-label {
  color: rgba(255, 255, 255, 0.78);
}

/* ------------------------------------------------------------------ FAQ --- */

/* Built on <details>, so it opens, closes, takes keyboard focus and is
   announced correctly with no JavaScript at all. */
.faq-item {
  /* The panel's own square corners show through the rounded border without
     this. */
  overflow: hidden;
}

/* Browsers draw a default disclosure triangle; the markup supplies its own
   chevron, and both at once reads as a mistake. */
.faq-item > summary {
  list-style: none;
}

.faq-item > summary::-webkit-details-marker {
  display: none;
}

.faq-item > summary::marker {
  content: "";
}

.faq-item[open] {
  border-color: var(--rd-primary);
}

/* ----------------------------------------------------------- rich text --- */

.prose-rd {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--rd-body);
}

.prose-rd h2,
.prose-rd h3,
.prose-rd h4 {
  margin-top: 2rem;
  margin-bottom: 0.75rem;
  color: var(--rd-ink);
  font-weight: 700;
}

.prose-rd h2 { font-size: 1.5rem; }
.prose-rd h3 { font-size: 1.25rem; }
.prose-rd h4 { font-size: 1.05rem; }

.prose-rd p { margin-bottom: 1rem; }

.prose-rd ul,
.prose-rd ol {
  margin-bottom: 1rem;
  padding-inline-start: 1.4rem;
}

.prose-rd ul { list-style: disc; }
.prose-rd ol { list-style: decimal; }
.prose-rd li { margin-bottom: 0.4rem; }

.prose-rd a {
  color: var(--rd-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.prose-rd blockquote {
  margin: 1.25rem 0;
  padding-inline-start: 1rem;
  border-inline-start: 3px solid var(--rd-accent);
  color: var(--rd-ink);
  font-style: italic;
}

.prose-rd img {
  max-width: 100%;
  height: auto;
  border-radius: 0.75rem;
}

.prose-rd table {
  width: 100%;
  margin-bottom: 1rem;
  border-collapse: collapse;
}

.prose-rd th,
.prose-rd td {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--rd-border);
  text-align: start;
}

.prose-rd th {
  background: var(--rd-surface-alt);
  font-weight: 600;
  color: var(--rd-ink);
}

/* ------------------------------------------------------------- process --- */

/* The step number: large, faint, tucked into the card's top corner. It is
   aria-hidden decoration (the <ol> carries the order), so it may be faint. */
.step-number {
  position: absolute;
  top: 0.75rem;
  inset-inline-end: 1.25rem;
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 3.25rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: rgb(var(--rd-primary-rgb) / 0.12);
  pointer-events: none;
  transition: color 0.25s ease;
}

.card:hover .step-number {
  color: rgb(var(--rd-primary-rgb) / 0.22);
}

/* Numbers in the mission list. */
.list-number {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-top: 0.1rem;
  border-radius: 0.8rem;
  /* Solid fill under the gradient: what a checker (and an old browser) reads. */
  background-color: var(--rd-primary);
  background-image: linear-gradient(135deg, var(--rd-primary) 0%, var(--rd-primary-dark) 100%);
  color: #fff;
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  box-shadow: 0 10px 20px -12px rgb(var(--rd-primary-rgb) / 0.7);
}

/* --------------------------------------------------------------- forms --- */

.field-label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--rd-ink);
}

.field-input,
.field-select,
.field-textarea {
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--rd-border);
  border-radius: 0.5rem;
  background: #fff;
  font-size: 0.95rem;
  color: var(--rd-ink);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field-input:focus,
.field-select:focus,
.field-textarea:focus {
  outline: none;
  border-color: var(--rd-primary-dark);
  box-shadow: 0 0 0 3px rgb(var(--rd-primary-rgb) / 0.15);
}

/* --------------------------------------------------------------- misc ---- */

/* --------------------------------------------------------------- footer --- */

/* Slate rather than the brand green. A full-width green slab competed with the
   gold that now leads the palette, and green-on-green was what made the
   headings unreadable in the first place. */
.site-footer {
  background: var(--rd-band-slate);
  color: rgba(255, 255, 255, 0.82);
}

.footer-link {
  color: rgba(255, 255, 255, 0.78);
  transition: color 0.15s ease;
}

.footer-link:hover {
  color: #fff;
}

.footer-heading {
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--rd-on-dark);
}

.whatsapp-fab {
  position: fixed;
  inset-inline-end: 1.25rem;
  bottom: 1.25rem;
  z-index: 70;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 999px;
  background: #25d366;
  color: #fff;
  box-shadow: 0 12px 28px -10px rgba(37, 211, 102, 0.7);
  transition: transform 0.15s ease;
}

.whatsapp-fab:hover {
  transform: scale(1.06);
}

:focus-visible {
  outline: 2px solid var(--rd-primary);
  outline-offset: 2px;
}

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

/* ---------------------------------------------------- section backgrounds ---
 * Set per section from the admin panel (Appearance > Section background).
 * rd_render_section() wraps the section in .rd-bg--<style>; clearing the inner
 * section's own background is what lets one setting restyle all section types
 * without every partial having to know about it.
 */
.rd-bg > section {
  background-color: transparent !important;
  background-image: none !important;
}

.rd-bg--white  { background-color: var(--rd-surface, #fff); }
.rd-bg--light  { background-color: var(--rd-surface-alt, #f7f4fa); }

/* Deliberately NOT --rd-primary/--rd-secondary: those are brand roles that can
   be swapped from the admin panel, and a full-width band in gold would be
   unreadable. These two are fixed deep tones. */
.rd-bg--brand  { background-color: var(--rd-band-navy, #1b0b2e); }
.rd-bg--dark   { background-color: var(--rd-band-slate, #241337); }

.rd-bg--image {
  position: relative;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* The overlay sits between the photo and the content. */
.rd-bg--image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(var(--rd-band-navy-rgb) / 0.55);
}

/* ---------------------------------------------- feathered photo edges ---- *
 * A photograph that stops dead against the next section reads as pasted on.
 * These fade the band into the page background over its top and bottom edges,
 * so the picture dissolves instead of ending on a ruled line.
 *
 * Deliberately NOT `mask-image` on the section: a mask applies to the whole
 * element including its children, so the headline and cards would fade out
 * near the edges too. Two gradient overlays affect only what is behind them.
 *
 * The fade colour is the page background, so a blended section wants light
 * neighbours - which is how the homepage is ordered.
 */
.rd-bg--blend > .rd-bg-feather-top,
.rd-bg--blend > .rd-bg-feather-bottom {
  content: "";
  position: absolute;
  inset-inline: 0;
  height: 5.5rem;
  pointer-events: none;
  z-index: 1;
}

.rd-bg--blend > .rd-bg-feather-top {
  top: 0;
  background: linear-gradient(to bottom, var(--rd-surface, #fff) 0%, rgba(255, 255, 255, 0) 100%);
}

.rd-bg--blend > .rd-bg-feather-bottom {
  bottom: 0;
  background: linear-gradient(to top, var(--rd-surface, #fff) 0%, rgba(255, 255, 255, 0) 100%);
}

/* The section's own content must sit above the feathers. */
.rd-bg--blend > section {
  position: relative;
  z-index: 2;
}


.rd-bg--overlay-none::before  { background: transparent; }
.rd-bg--overlay-light::before { background: rgb(var(--rd-band-navy-rgb) / 0.35); }
/* Same value as the default above, stated explicitly so the class is not a
   no-op that only works by relying on the base rule. */
.rd-bg--overlay-medium::before { background: rgb(var(--rd-band-navy-rgb) / 0.55); }
.rd-bg--overlay-heavy::before { background: rgb(var(--rd-band-navy-rgb) / 0.75); }

.rd-bg--image > section {
  position: relative;
  z-index: 1;
}

/* On a dark ground the section's own text colours would be unreadable, so they
 * are overridden here rather than in each of the 18 partials. */
.rd-bg--brand,
.rd-bg--dark,
.rd-bg--image {
  color: #fff;
}

/* Text colour on a dark band is handled by ordinary inheritance from the
   container above, NOT by forcing `color: inherit` onto every tag.
   That earlier approach outranked utility classes like `text-white/80` and,
   worse, whitened the labels of the enquiry form - which sits on a white card
   inside the dark band, so they became white on white.

   The model instead is: the band sets white, and any explicitly light surface
   inside it resets to ink. */
.rd-bg--brand :is(.bg-white, .bg-slateink-100, .bg-brand-50),
.rd-bg--dark :is(.bg-white, .bg-slateink-100, .bg-brand-50),
.rd-bg--image :is(.bg-white, .bg-slateink-100, .bg-brand-50) {
  color: var(--rd-ink);
}

/* Components that hardcode a dark colour still need telling. Scoped away from
   light cards for the same reason as above. */
.rd-bg--brand .card:not(.card--photo) .card-title,
.rd-bg--dark .card:not(.card--photo) .card-title,
.rd-bg--image .card:not(.card--photo) .card-title {
  color: #fff;
}

.rd-bg--brand .card:not(.card--photo) .card-text,
.rd-bg--dark .card:not(.card--photo) .card-text,
.rd-bg--image .card:not(.card--photo) .card-text {
  color: rgba(255, 255, 255, 0.82);
}

/* The blanket `color: inherit` above flattens everything on a dark band to
   white, including the details that carry the accent. These put the accent
   back, in the light gold that actually reads on a dark ground. Declared after
   the inherit rule so they win at equal specificity. */
.rd-bg--brand :is(.section-number, .section-kicker, .stat-value, .link-arrow),
.rd-bg--dark :is(.section-number, .section-kicker, .stat-value, .link-arrow),
.rd-bg--image :is(.section-number, .section-kicker, .stat-value, .link-arrow) {
  color: var(--rd-on-dark);
}

/* The "/" divider and any small print keep their own colour, so the band's
   blanket `color: inherit` never reaches them - both were --rd-muted at
   2.55:1 on the dark band. White at 70% is 7.4:1 there. */
.rd-bg--brand :is(.section-number-divider, .section-footnote),
.rd-bg--dark :is(.section-number-divider, .section-footnote),
.rd-bg--image :is(.section-number-divider, .section-footnote) {
  color: rgba(255, 255, 255, 0.7);
}

/* Small print under a section: a repeated pattern, so it gets a class rather
   than a utility. A utility (text-slateink-500) cannot be corrected for the
   dark band, which is how it ended up at 2.55:1 there. */
.section-footnote {
  margin-top: 2rem;
  font-size: 0.875rem;
  color: var(--rd-muted);
}

/* The short rule under a heading is a fill, not text. */
.rd-bg--brand .btn-outline,
.rd-bg--dark .btn-outline,
.rd-bg--image .btn-outline {
  border-color: rgba(255, 255, 255, 0.55);
  color: #fff;
}

.rd-bg--brand .title-rule::after,
.rd-bg--dark .title-rule::after,
.rd-bg--image .title-rule::after {
  background: var(--rd-primary);
}

/* Supporting copy on a dark band. Full-strength white is harsh over a
   paragraph, so the lead steps back a little. */
.rd-bg--brand .section-lead,
.rd-bg--dark .section-lead,
.rd-bg--image .section-lead {
  color: rgba(255, 255, 255, 0.78);
}

/* A section placed on a dark band from the admin panel does not know to pass
   the template's "light" flag, so these make the dark treatment automatic. */
.rd-bg--brand .section-title,
.rd-bg--dark .section-title,
.rd-bg--image .section-title {
  color: #fff;
}

/* Cards on a dark band. The first version used rgba(255,255,255,.08) over a
   background photo and the cards were effectively invisible - no readable edge,
   no separation from the picture behind them. Darkening instead of lightening,
   with a real border and a blur, gives them their shape back. */
.rd-bg--brand :is(.card, .stat-card, .quote-card):not(.card--photo),
.rd-bg--dark :is(.card, .stat-card, .quote-card):not(.card--photo),
.rd-bg--image :is(.card, .stat-card, .quote-card):not(.card--photo) {
  background: rgb(var(--rd-overlay-rgb) / 0.62);
  border-color: rgba(255, 255, 255, 0.28);
  backdrop-filter: blur(3px);
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.85);
}

.rd-bg--brand .card:not(.card--photo):hover,
.rd-bg--dark .card:not(.card--photo):hover,
.rd-bg--image .card:not(.card--photo):hover {
  background: rgb(var(--rd-overlay-rgb) / 0.74);
  border-color: rgba(255, 255, 255, 0.45);
}

/* On a dark band the badge turns gold, so it lifts off the darkened card
   rather than blending into it. Plum on gold is 10.6:1. */
.rd-bg--brand .card-icon,
.rd-bg--dark .card-icon,
.rd-bg--image .card-icon {
  background: linear-gradient(135deg, var(--rd-on-dark) 0%, var(--rd-accent) 100%);
  color: var(--rd-band-navy);
  box-shadow: 0 12px 24px -12px rgb(var(--rd-accent-rgb) / 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.rd-bg--brand .card,
.rd-bg--dark .card,
.rd-bg--image .card {
  --card-ring: var(--rd-band-navy);
}

.rd-bg--brand .step-number,
.rd-bg--dark .step-number,
.rd-bg--image .step-number {
  color: rgba(255, 255, 255, 0.1);
}

.rd-bg--brand .card:hover .step-number,
.rd-bg--dark .card:hover .step-number,
.rd-bg--image .card:hover .step-number {
  color: rgba(255, 255, 255, 0.18);
}

/* ------------------------------------------------ cards with a photo ----- *
 * Each card carries its own background image. The scrim is what keeps the
 * text readable regardless of how busy the photograph is, and it deepens on
 * hover so the card still responds to the pointer.
 */
.card--photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--rd-band-navy, #1b0b2e);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-color: rgba(255, 255, 255, 0.3);
}

.card--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgb(var(--rd-overlay-rgb) / 0.62) 0%,
    rgb(var(--rd-overlay-rgb) / 0.82) 100%
  );
  transition: background 0.2s ease;
}

.card--photo:hover::before {
  background: linear-gradient(
    180deg,
    rgb(var(--rd-overlay-rgb) / 0.72) 0%,
    rgb(var(--rd-overlay-rgb) / 0.9) 100%
  );
}

.card--photo .card-title,
.card--photo .card-text,
.card--photo .link-arrow {
  color: #fff;
}

.card--photo .card-text {
  color: rgba(255, 255, 255, 0.86);
}

.card--photo .card-icon {
  background: linear-gradient(135deg, var(--rd-on-dark) 0%, var(--rd-accent) 100%);
  color: var(--rd-band-navy);
}

.card--photo {
  --card-ring: rgb(var(--rd-overlay-rgb));
}



/* Hero text sits over moving footage, so individual frames can put a white
   cloud directly behind a letter. A soft shadow costs nothing and keeps the
   worst frames legible without darkening the whole picture. */
.hero h1,
.hero .section-kicker,
.hero p {
  text-shadow: 0 1px 12px rgb(var(--rd-overlay-rgb) / 0.55);
}

/* ------------------------------------------------- content protection ---- *
 * Client request: discourage casual copying and image saving.
 *
 * This is a deterrent, not a control. Selection can be re-enabled from
 * devtools in one line, and the page source is downloaded before any of this
 * runs. See the matching note in static/js/site.js.
 *
 * The exemptions below are not optional niceties - without them the enquiry
 * forms cannot be filled in, and a customer cannot copy the phone number the
 * page is asking them to ring.
 *
 * Every rule is scoped to body[data-protect-content], which the layout sets
 * only while Admin -> Settings -> Website behaviour has protection on.
 */

body[data-protect-content] {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  /* Stops the iOS "save image / copy" sheet on a long press. */
  -webkit-touch-callout: none;
}

/* Anything a visitor has to type into, or legitimately needs to copy. */
body[data-protect-content] :is(
  input,
  textarea,
  select,
  [contenteditable="true"],
  address,
  a[href^="tel:"],
  a[href^="mailto:"],
  .allow-copy,
  [data-allow-copy]
) {
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* Images: no drag-to-desktop, no long-press menu. */
body[data-protect-content] :is(img, video) {
  -webkit-user-drag: none;
  -khtml-user-drag: none;
  -moz-user-drag: none;
  -o-user-drag: none;
  user-drag: none;
  -webkit-touch-callout: none;
}

/* Selection must stay visible where it is allowed, or fields look broken. */
input::selection,
textarea::selection,
.allow-copy ::selection {
  background: rgb(var(--rd-accent-rgb) / 0.28);
}

/* Keyboard users still need to see where they are. Never remove this: the
   protection rules above must not cost the site its focus indicators. */
:focus-visible {
  outline: 2px solid var(--rd-primary, #7030a0);
  outline-offset: 2px;
}
