/* ============================================================
   QOBBAN — Precision Engineering design system
   Direction locked 2026-07-27. See WEBSITE/Website_Strategy.md
   All spacing uses CSS logical properties for RTL readiness.
   ============================================================ */

/* ---------- Tokens ---------- */
:root {
  /* Brand */
  --black:        #1A1A1A;
  --white:        #FFFFFF;
  --yellow:       #FFC220;

  /* Surfaces */
  --surface:       #111111;
  --surface-raised:#1A1A1A;
  --surface-line:  #2A2A2A;
  --surface-hover: #202020;

  /* Type */
  --text:        #FFFFFF;
  --text-body:   #D6D6D6;
  --text-muted:  #8A8A8A;

  /* Type scale */
  --f-display: clamp(2.5rem, 7vw, 4.5rem);
  --f-h1:      clamp(2rem, 5vw, 3.5rem);
  --f-h2:      clamp(1.5rem, 3.5vw, 2.25rem);
  --f-h3:      clamp(1.25rem, 2vw, 1.5rem);
  --f-body:    1.0625rem;
  --f-caption:  0.75rem;
  --f-cta:      0.9375rem;

  /* Space */
  --s-1: 0.5rem;  --s-2: 1rem;   --s-3: 1.5rem;
  --s-4: 2rem;    --s-5: 3rem;   --s-6: 4rem;
  --s-7: 6rem;    --s-8: 8rem;

  --wrap: 1280px;
  --gutter: clamp(1.25rem, 5vw, 4rem);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur: 0.7s;

  --font: "Montserrat", "Gotham", "Helvetica Neue", Arial, sans-serif;

  /* Base colour the page overlays are mixed from. Tokenised so light mode
     can flip the hero and header washes without rewriting every gradient. */
  --wash: 17, 17, 17;
  --header-bg: rgba(17, 17, 17, 0.92);
  --accent-text: var(--yellow);   /* yellow fails contrast on light — see below */
  --shadow: rgba(0, 0, 0, 0.45);
}

/* ---------- Light theme ----------
   The brand is dark-first (BRAND/Color_System.md); this is the documented
   inversion: white base, #1A1A1A type, yellow used more sparingly still.
   #FFC220 as *text* on a light background is ~1.6:1 and fails outright, so
   --accent-text darkens to an amber that clears AA while still reading as
   the brand colour. Yellow as a *fill* behind dark text is unchanged. */
[data-theme="light"] {
  --surface:        #F4F4F1;
  --surface-raised: #FFFFFF;
  --surface-line:   #DEDED8;
  --surface-hover:  #EDEDE7;

  --text:        #1A1A1A;
  --text-body:   #3C3C3C;
  --text-muted:  #6B6B6B;

  --wash: 244, 244, 241;
  --header-bg: rgba(244, 244, 241, 0.92);
  --accent-text: #8A5D00;
  --shadow: rgba(0, 0, 0, 0.16);

  color-scheme: light;
}
[data-theme="dark"] { color-scheme: dark; }

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-size: var(--f-body);
  line-height: 1.6;
  color: var(--text-body);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  /* Stops the mobile nav (translateX(100%)) causing horizontal scroll.
     Must be `clip`, not `hidden`: overflow-x:hidden forces overflow-y to
     auto, which makes BODY a scroll container — and position:sticky then
     resolves against body's scrollport instead of the viewport, so the
     process stage stack silently stops pinning. `clip` clips identically
     without creating a scroll container. */
  overflow-x: clip;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--yellow); color: var(--black); }

:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 3px;
}

/* ---------- Layout ---------- */
.wrap {
  width: 100%;
  max-inline-size: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: clamp(4rem, 10vw, 8rem); position: relative; }
.section--line { border-block-start: 1px solid var(--surface-line); }

/* Engineering grid overlay — the signature of the direction.
   Must sit BEHIND all content: it is texture, never foreground.
   z-index:0 here + z-index:1 on .wrap keeps it under text, buttons and cards. */
.gridlines {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--surface-line) 1px, transparent 1px);
  background-size: calc(100% / 6) 100%;
  opacity: 0.28;
  mask-image: linear-gradient(to bottom, transparent, #000 15%, #000 85%, transparent);
}

/* Every section's content sits above the grid. */
.section > .wrap { position: relative; z-index: 1; }

/* ---------- Type ---------- */
h1, h2, h3, h4 {
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text);
  line-height: 1.08;
  letter-spacing: -0.02em;
}
h1 { font-size: var(--f-h1); }
h2 { font-size: var(--f-h2); }
h3 { font-size: var(--f-h3); font-weight: 600; letter-spacing: 0; line-height: 1.2; }
p { max-inline-size: 68ch; }
strong { color: var(--text); font-weight: 600; }

.display {
  font-size: var(--f-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 1.02;
  color: var(--text);
}
.accent { color: var(--accent-text); }

/* Spec caption — the "spec sheet" voice */
.spec {
  font-size: var(--f-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.spec::before {
  content: "";
  inline-size: 28px;
  block-size: 1px;
  background: var(--yellow);
  flex: none;
}
.spec--plain::before { display: none; }

.lede { font-size: clamp(1.0625rem, 1.6vw, 1.25rem); color: var(--text-body); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.9rem 1.75rem;
  font-size: var(--f-cta);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease), transform .25s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn--primary { background: var(--yellow); color: var(--black); }
.btn--primary:hover { background: #ffcf4d; }
.btn--ghost { border-color: var(--surface-line); color: var(--text); }
.btn--ghost:hover { border-color: var(--yellow); color: var(--yellow); }
.btn__arrow { transition: transform .25s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }
[dir="rtl"] .btn:hover .btn__arrow { transform: translateX(-4px); }

/* ---------- Header ---------- */
.header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 100;
  transition: background .35s var(--ease), border-color .35s var(--ease);
  border-block-end: 1px solid transparent;
}
.header.is-stuck {
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  border-block-end-color: var(--surface-line);
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  block-size: 76px;
}
.logo { display: flex; align-items: center; gap: 0.7rem; flex: none; color: var(--text); }
.logo__mark { inline-size: 42px; block-size: auto; }
.logo__text { display: flex; flex-direction: column; line-height: 1; }
.logo__ar { font-size: 0.7rem; color: var(--text-muted); }
.logo__en {
  font-size: 1.05rem; font-weight: 700; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--text);
}
.nav { display: flex; align-items: center; gap: var(--s-4); }
.nav__link {
  font-size: 0.8125rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--text-body);
  padding-block: 0.5rem; position: relative; transition: color .25s;
}
.nav__link::after {
  content: ""; position: absolute; inset-block-end: 0; inset-inline-start: 0;
  inline-size: 0; block-size: 2px; background: var(--yellow);
  transition: inline-size .3s var(--ease);
}
.nav__link:hover, .nav__link[aria-current="page"] { color: var(--text); }
.nav__link:hover::after, .nav__link[aria-current="page"]::after { inline-size: 100%; }

/* ---------- Header controls: theme + language ----------
   Two small icon buttons. Deliberately quiet — they are utilities, not
   calls to action, so they never take yellow. */
.controls { display: flex; align-items: center; gap: 0.35rem; flex: none; }
.ctrl {
  display: grid;
  place-content: center;
  inline-size: 38px;
  block-size: 38px;
  padding: 0;
  background: none;
  border: 1px solid var(--surface-line);
  border-radius: 3px;
  color: var(--text-muted);
  cursor: pointer;
  transition: color .25s var(--ease), border-color .25s var(--ease),
              background .25s var(--ease);
}
.ctrl:hover { color: var(--text); border-color: var(--text-muted); }
.ctrl__lang {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1;
}

/* Only one icon shows at a time; the other is hidden per theme. */
.ctrl__sun, .ctrl__moon { display: none; }
[data-theme="dark"] .ctrl__sun { display: block; }
[data-theme="light"] .ctrl__moon { display: block; }

.burger {
  display: none; background: none; border: 0; cursor: pointer;
  inline-size: 44px; block-size: 44px; padding: 10px;
}
.burger span {
  display: block; block-size: 2px; background: var(--text);
  margin-block: 5px; transition: transform .3s var(--ease), opacity .2s;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 960px) {
  .burger { display: block; }
  .nav {
    /* .header carries backdrop-filter when stuck, and backdrop-filter makes
       an ancestor the containing block for fixed descendants. So `inset: 76px 0 0`
       resolved against the 76px-tall header and the panel collapsed to zero
       height. Set the height explicitly instead of relying on the bottom inset.
       100dvh (not vh) so mobile browser chrome doesn't clip the last link. */
    position: fixed;
    inset-block-start: 76px;
    inset-inline: 0;
    block-size: calc(100vh - 76px);
    block-size: calc(100dvh - 76px);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface);
    flex-direction: column; justify-content: center; gap: var(--s-4);
    transform: translateX(100%); transition: transform .4s var(--ease);
  }
  [dir="rtl"] .nav { transform: translateX(-100%); }
  .nav.is-open { transform: translateX(0); }
  .nav__link { font-size: 1.25rem; }
}

/* ---------- Hero ---------- */
.hero {
  min-block-size: 100svh;
  display: grid;
  align-items: center;
  position: relative;
  padding-block-start: 76px;
  overflow: hidden;
}
.hero__media {
  position: absolute; inset: 0; z-index: -2;
  background: var(--black) center/cover no-repeat;
}
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(var(--wash),.96) 0%, rgba(var(--wash),.75) 45%, rgba(var(--wash),.35) 100%);
}
[dir="rtl"] .hero__media::after { transform: scaleX(-1); }
.hero__content { position: relative; max-inline-size: 46rem; }
.hero .display { margin-block: var(--s-3) var(--s-4); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-block-start: var(--s-5); }

/* Level bubble — the load animation, mirrors the logo */
.level {
  inline-size: min(340px, 80%);
  block-size: 54px;
  border: 2px solid var(--white);
  border-radius: 4px;
  position: relative;
  display: flex;
  align-items: center;
  padding-inline: 6px;
  margin-block-end: var(--s-4);
}
.level__vial {
  position: relative; inline-size: 100%; block-size: 30px;
  background: var(--yellow); border-radius: 2px; overflow: hidden;
}
.level__bubble {
  position: absolute; inset-block-start: 50%; inset-inline-start: 12%;
  inline-size: 46px; block-size: 20px;
  background: var(--white); border-radius: 10px;
  transform: translate(-50%, -50%);
  animation: settle 2.6s var(--ease) forwards;
}
.level__tick {
  position: absolute; inset-block: 0; inline-size: 2px;
  background: rgba(26,26,26,.55);
}
.level__tick--a { inset-inline-start: 42%; }
.level__tick--b { inset-inline-start: 58%; }
@keyframes settle {
  0%   { inset-inline-start: 12%; }
  35%  { inset-inline-start: 82%; }
  62%  { inset-inline-start: 36%; }
  82%  { inset-inline-start: 55%; }
  100% { inset-inline-start: 50%; }
}

/* ============================================================
   LOADING SCREEN — first visit only.
   The brand idea is the progress indicator: the bubble
   oscillates while loading and settles dead centre when ready,
   then the two panels open like a frame.
   `html.is-loaded` is set instantly by an inline head script on
   repeat visits, so returning users never see a flash.
   ============================================================ */
.loader {
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
}
html.is-loaded .loader { display: none; }

.loader__panel {
  position: absolute;
  inset-inline: 0;
  block-size: 50%;
  background: var(--surface);
  transition: transform 0.9s var(--ease);
}
.loader__panel--top { inset-block-start: 0; }
.loader__panel--bottom { inset-block-end: 0; }
.loader.is-done .loader__panel--top { transform: translateY(-100%); }
.loader.is-done .loader__panel--bottom { transform: translateY(100%); }

.loader__inner {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  transition: opacity .4s var(--ease);
}
.loader.is-done .loader__inner { opacity: 0; }

.loader__vial {
  inline-size: min(260px, 60vw);
  block-size: 26px;
  background: var(--yellow);
  border-radius: 3px;
  position: relative;
  overflow: hidden;
}
.loader__bubble {
  position: absolute;
  inset-block-start: 50%;
  inline-size: 40px;
  block-size: 18px;
  background: var(--white);
  border-radius: 9px;
  transform: translate(-50%, -50%);
  animation: loaderSeek 1.1s ease-in-out infinite alternate;
}
.loader.is-done .loader__bubble {
  animation: none;
  inset-inline-start: 50%;
  transition: inset-inline-start .5s var(--ease);
}
@keyframes loaderSeek {
  from { inset-inline-start: 22%; }
  to   { inset-inline-start: 78%; }
}
.loader__word {
  font-size: var(--f-caption);
  font-weight: 700;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ============================================================
   INTERACTIVE SPIRIT LEVEL — hero device.
   Charcoal body, yellow vial, white bubble: the logo's own
   construction. Cursor-driven on desktop, gyroscope on mobile.
   ============================================================ */
.levelbar {
  position: relative;
  block-size: clamp(62px, 8.5vw, 96px);
  background: var(--surface-raised);
  border: 2px solid var(--surface-line);
  display: flex;
  align-items: center;
  padding-inline: clamp(28px, 5vw, 72px);
  cursor: ew-resize;
  touch-action: none;
  transition: border-color .4s var(--ease);
  user-select: none;
}
.levelbar.is-level { border-color: var(--yellow); }

/* The vial is a recessed window in a charcoal body — the logo's
   construction. Keep it well inside the frame or the whole bar
   reads as a solid yellow slab and blows the colour budget. */
.levelbar__vial {
  position: relative;
  inline-size: 100%;
  block-size: 34%;
  background: var(--yellow);
  border-radius: 3px;
  overflow: hidden;
  box-shadow: inset 0 2px 7px rgba(0,0,0,.5);
  transition: box-shadow .4s var(--ease);
}
.levelbar.is-level .levelbar__vial {
  box-shadow: inset 0 2px 7px rgba(0,0,0,.5), 0 0 24px rgba(255,194,32,.5);
}

.levelbar__bubble {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: clamp(38px, 5vw, 58px);
  block-size: 72%;
  background: var(--white);
  border-radius: 999px;
  transform: translate(-50%, -50%);
  will-change: inset-inline-start;
}
.levelbar__tick {
  position: absolute;
  inset-block: 0;
  inline-size: 2px;
  background: rgba(26,26,26,.5);
}
.levelbar__tick--a { inset-inline-start: 43%; }
.levelbar__tick--b { inset-inline-start: 57%; }

/* End caps — reads as a physical instrument, not a progress bar */
.levelbar::before, .levelbar::after {
  content: "";
  position: absolute;
  inset-block: 22%;
  inline-size: 3px;
  background: var(--surface-line);
}
.levelbar::before { inset-inline-start: 6px; }
.levelbar::after  { inset-inline-end: 6px; }

.levelbar__hint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  margin-block-start: var(--s-2);
  font-size: var(--f-caption);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.levelbar__state { color: var(--yellow); opacity: 0; transition: opacity .3s var(--ease); }
.levelbar__state.is-on { opacity: 1; }

/* ---------- Hero card ---------- */
.herocard {
  position: relative;
  margin-block-start: var(--s-4);
  border: 1px solid rgba(255,194,32,.5);
  background: var(--surface-raised);
  overflow: hidden;
  display: grid;
  align-items: center;
  min-block-size: min(66vh, 640px);
}
.herocard__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--black) center/cover no-repeat;
}
.herocard__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(var(--wash),.96) 0%, rgba(var(--wash),.82) 42%, rgba(var(--wash),.4) 100%);
}
[dir="rtl"] .herocard__media::after { transform: scaleX(-1); }
.herocard__body {
  position: relative;
  z-index: 1;
  max-inline-size: 44rem;
  padding: clamp(1.75rem, 4.5vw, 4rem);
}
.herocard__body .display { margin-block: var(--s-3) var(--s-4); }

/* Corner registration marks — the Precision Engineering signature */
.herocard__corner {
  position: absolute;
  z-index: 1;
  inline-size: 18px;
  block-size: 18px;
  border: 2px solid var(--yellow);
  pointer-events: none;
}
.herocard__corner--tl { inset-block-start: 12px; inset-inline-start: 12px; border-inline-end: 0; border-block-end: 0; }
.herocard__corner--tr { inset-block-start: 12px; inset-inline-end: 12px; border-inline-start: 0; border-block-end: 0; }
.herocard__corner--bl { inset-block-end: 12px; inset-inline-start: 12px; border-inline-end: 0; border-block-start: 0; }
.herocard__corner--br { inset-block-end: 12px; inset-inline-end: 12px; border-inline-start: 0; border-block-start: 0; }

/* ---------- Scroll reveal ---------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .08s; }
.reveal[data-delay="2"] { transition-delay: .16s; }
.reveal[data-delay="3"] { transition-delay: .24s; }
.reveal[data-delay="4"] { transition-delay: .32s; }
.reveal[data-delay="5"] { transition-delay: .40s; }

/* ---------- Section heading ---------- */
.head { max-inline-size: 46rem; margin-block-end: var(--s-6); }
.head .spec { margin-block-end: var(--s-3); }
.head h2 { margin-block-end: var(--s-3); }

/* ---------- Pillars ---------- */
.pillars { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.pillar { padding-block-start: var(--s-3); border-block-start: 2px solid var(--yellow); }
.pillar h3 { margin-block-end: var(--s-2); }
.pillar__num {
  font-size: var(--f-caption); font-weight: 700; letter-spacing: 0.14em;
  color: var(--yellow); display: block; margin-block-end: var(--s-1);
}

/* ---------- Service cards ---------- */
.cards { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); background: var(--surface-line); border: 1px solid var(--surface-line); }
.card {
  background: var(--surface-raised);
  padding: var(--s-4);
  display: flex; flex-direction: column; gap: var(--s-2);
  min-block-size: 260px;
  transition: background .3s var(--ease);
  position: relative; overflow: hidden;
}
.card:hover { background: var(--surface-hover); }
.card::after {
  content: ""; position: absolute; inset-block-end: 0; inset-inline-start: 0;
  inline-size: 0; block-size: 3px; background: var(--yellow);
  transition: inline-size .4s var(--ease);
}
.card:hover::after { inline-size: 100%; }
.card__icon { color: var(--yellow); margin-block-end: var(--s-1); }
.card h3 { margin-block-end: 0; }
.card p { font-size: 0.9375rem; color: var(--text-muted); flex: 1; }
.card__more {
  font-size: var(--f-caption); font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--yellow);
  display: inline-flex; align-items: center; gap: 0.5rem;
}

/* ---------- Figure with dimension marks ---------- */
.figure { position: relative; background: var(--surface-raised); overflow: hidden; }
.figure img { inline-size: 100%; transition: transform .8s var(--ease); }
.figure:hover img { transform: scale(1.04); }
.figure__dim {
  position: absolute; inset-inline: 12px; inset-block-end: 12px;
  display: flex; align-items: center; gap: 8px;
  font-size: 0.625rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--yellow);
  pointer-events: none;
}
.figure__dim::before, .figure__dim::after {
  content: ""; block-size: 1px; background: var(--yellow); flex: 1; opacity: .6;
}
.figure__ph {
  aspect-ratio: 4 / 3;
  display: grid; place-content: center; gap: var(--s-1);
  text-align: center; padding: var(--s-4);
  border: 1px dashed var(--surface-line);
  color: var(--text-muted);
}
.figure__ph .spec { justify-content: center; }

/* ---------- Projects grid ---------- */
.projects { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.project__meta { display: flex; justify-content: space-between; gap: var(--s-2); padding-block-start: var(--s-2); }
.project__meta h3 { font-size: 1.0625rem; }
.project__meta span { font-size: var(--f-caption); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); }

.filters { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-block-end: var(--s-5); }
.filter {
  background: none; border: 1px solid var(--surface-line); cursor: pointer;
  padding: 0.55rem 1.1rem; font-size: var(--f-caption); font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted);
  transition: all .25s var(--ease);
}
.filter:hover { color: var(--text); border-color: var(--text-muted); }
.filter.is-active { background: var(--yellow); border-color: var(--yellow); color: var(--black); }

/* ---------- Process steps ---------- */
.steps { display: grid; gap: 1px; background: var(--surface-line); border: 1px solid var(--surface-line); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.step { background: var(--surface-raised); padding: var(--s-4); }
.step__n {
  font-size: 2.5rem; font-weight: 700; color: var(--surface-line);
  line-height: 1; margin-block-end: var(--s-2); transition: color .3s var(--ease);
}
.step:hover .step__n { color: var(--yellow); }
.step h3 { margin-block-end: var(--s-1); }
.step p { font-size: 0.9375rem; color: var(--text-muted); }

/* ============================================================
   PROCESS STAGE STACK
   Each stage pins under the header at an increasing offset, so earlier
   stages stay visible as later ones arrive — the reader accumulates the
   process instead of scrolling past it. No pin maths, no scroll listener,
   no dependency: the runway comes from the cards' own height.

   Requires `body { overflow-x: clip }` — see the note on body above.
   ============================================================ */
.stagestack {
  --header: 76px;
  --step: 16px;              /* visible sliver of each earlier card */
  display: grid;
  gap: clamp(2rem, 6vw, 5rem);
  /* Knob: raise to ~12vh if you want stage 05 to pin for a beat before
     the page moves on. Costs that much empty space below it. */
  padding-block-end: 0;
}

.stage {
  position: sticky;
  inset-block-start: calc(var(--header) + var(--i) * var(--step));
  background: var(--surface-raised);
  border: 1px solid var(--surface-line);
  border-radius: 3px;
  padding: clamp(1.5rem, 4vw, 3rem);
  transform-origin: top center;
  /* Opaque + own shadow so stacked cards read as separate objects */
  box-shadow: 0 -1px 0 var(--surface-line), 0 18px 40px var(--shadow);
}

.stage__grid { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
@media (min-width: 900px) {
  .stage__grid { grid-template-columns: 1fr 1fr; }
  .stage--flip .stage__grid > :first-child { order: 2; }
}

.stage__n {
  font-size: var(--f-caption);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--yellow);
}
.stage h2 { margin-block: var(--s-2) var(--s-3); }

.stage__corner {
  position: absolute;
  inline-size: 14px;
  block-size: 14px;
  border: 2px solid var(--yellow);
  pointer-events: none;
  opacity: .5;
}
.stage__corner--tl { inset-block-start: 8px; inset-inline-start: 8px; border-inline-end: 0; border-block-end: 0; }
.stage__corner--br { inset-block-end: 8px; inset-inline-end: 8px; border-inline-start: 0; border-block-start: 0; }

/* Enhancement only: recede as a card is overtaken. Unsupported browsers
   get the plain sticky stack, which is the point of doing it this way. */
@supports (animation-timeline: view()) {
  @media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
    .stage {
      animation: stageRecede linear both;
      animation-timeline: view();
      animation-range: exit-crossing 0% exit-crossing 100%;
    }
    @keyframes stageRecede {
      to { transform: scale(0.94); filter: brightness(0.72); }
    }
  }
}

/* Expand all — a visually-hidden checkbox drives this, so it needs no
   JavaScript, can't be blocked by the CSP, and can't desync from the DOM. */
.viewtoggle { display: flex; justify-content: flex-end; margin-block-end: var(--s-3); }
.viewtoggle__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border: 1px solid var(--surface-line);
  border-radius: 3px;
  cursor: pointer;
  font-size: var(--f-caption);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.viewtoggle__btn:hover { color: var(--text); border-color: var(--text-muted); }
.viewtoggle__input:focus-visible + .viewtoggle .viewtoggle__btn {
  outline: 2px solid var(--yellow);
  outline-offset: 3px;
}
.viewtoggle__off { display: none; }
.viewtoggle__input:checked + .viewtoggle .viewtoggle__off { display: inline; }
.viewtoggle__input:checked + .viewtoggle .viewtoggle__on { display: none; }
.viewtoggle__input:checked ~ .stagestack .stage {
  position: static;
  box-shadow: none;
  animation: none;
  transform: none;
  filter: none;
}

@media (max-width: 768px) {
  /* Five pinned cards on a phone viewport is a scroll trap. Already flat,
     so the toggle would be a no-op — hide it rather than lie. */
  .stage { position: static; box-shadow: none; }
  .viewtoggle, .viewtoggle__input { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .stage { position: static; animation: none; transform: none; filter: none; }
  .viewtoggle, .viewtoggle__input { display: none; }
}

/* ---------- Stats ---------- */
.stats { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.stat { border-inline-start: 2px solid var(--yellow); padding-inline-start: var(--s-3); }
.stat__n { font-size: clamp(2.25rem, 5vw, 3.25rem); font-weight: 700; color: var(--text); line-height: 1; }
.stat__l { font-size: var(--f-caption); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); margin-block-start: var(--s-1); }

/* ---------- Split ---------- */
.split { display: grid; gap: clamp(2rem, 6vw, 5rem); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; } }
.split--reverse > :first-child { order: 2; }
@media (max-width: 899px) { .split--reverse > :first-child { order: 0; } }

/* ---------- Accordion (FAQ) ---------- */
.acc { border-block-start: 1px solid var(--surface-line); }
.acc__item { border-block-end: 1px solid var(--surface-line); }
.acc__btn {
  inline-size: 100%; background: none; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding-block: var(--s-3); text-align: start;
  font-weight: 600; font-size: 1.0625rem; color: var(--text);
}
.acc__btn:hover { color: var(--yellow); }
.acc__ico { color: var(--yellow); flex: none; transition: transform .3s var(--ease); }
.acc__btn[aria-expanded="true"] .acc__ico { transform: rotate(45deg); }
.acc__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .35s var(--ease); }
.acc__panel.is-open { grid-template-rows: 1fr; }
.acc__panel > div { overflow: hidden; }
.acc__panel p { padding-block-end: var(--s-3); color: var(--text-muted); }

/* ---------- CTA band ---------- */
.cta {
  background: var(--yellow); color: var(--black);
  padding-block: clamp(3rem, 8vw, 5rem);
}
.cta h2 { color: var(--black); }
.cta p { color: rgba(26,26,26,.8); }
.cta .btn--primary { background: var(--black); color: var(--yellow); }
.cta .btn--primary:hover { background: #000; }

/* ---------- Forms / quote flow ---------- */
.form { max-inline-size: 44rem; }
.field { margin-block-end: var(--s-3); }
.field label {
  display: block; font-size: var(--f-caption); font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted);
  margin-block-end: var(--s-1);
}
.field input, .field textarea, .field select {
  inline-size: 100%; background: var(--surface-raised);
  border: 1px solid var(--surface-line); color: var(--text);
  padding: 0.9rem 1rem; transition: border-color .25s;
}
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--yellow); outline: none;
}
.field textarea { min-block-size: 120px; resize: vertical; }
.field__hint { font-size: 0.8125rem; color: var(--text-muted); margin-block-start: var(--s-1); }
.field__error { font-size: 0.8125rem; color: #ff6b6b; margin-block-start: var(--s-1); display: none; }
.field.has-error input, .field.has-error select { border-color: #ff6b6b; }
.field.has-error .field__error { display: block; }

.choices { display: grid; gap: var(--s-2); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.choice { position: relative; }
.choice input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.choice span {
  display: block; padding: var(--s-3); border: 1px solid var(--surface-line);
  background: var(--surface-raised); cursor: pointer;
  font-weight: 600; transition: all .25s var(--ease);
}
.choice input:checked + span { border-color: var(--yellow); background: var(--surface-hover); color: var(--yellow); }
.choice input:focus-visible + span { outline: 2px solid var(--yellow); outline-offset: 2px; }

.progress { display: flex; gap: 6px; margin-block-end: var(--s-5); }
.progress__seg { block-size: 3px; flex: 1; background: var(--surface-line); transition: background .4s var(--ease); }
.progress__seg.is-done { background: var(--yellow); }
.stepper__step { display: none; }
.stepper__step.is-active { display: block; animation: stepIn .45s var(--ease); }
@keyframes stepIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }
.stepper__nav { display: flex; gap: var(--s-2); margin-block-start: var(--s-4); }

/* ---------- WhatsApp float ---------- */
.wa {
  position: fixed; inset-block-end: 24px; inset-inline-end: 24px; z-index: 90;
  inline-size: 56px; block-size: 56px; border-radius: 50%;
  background: var(--yellow); color: var(--black);
  display: grid; place-content: center;
  box-shadow: 0 8px 28px var(--shadow);
  transition: transform .3s var(--ease);
}
.wa:hover { transform: scale(1.08); }

/* ---------- Footer ---------- */
.footer { background: var(--black); border-block-start: 1px solid var(--surface-line); padding-block: var(--s-6) var(--s-4); }
.footer__grid { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin-block-end: var(--s-5); }
.footer h4 { font-size: var(--f-caption); letter-spacing: 0.14em; color: var(--text-muted); margin-block-end: var(--s-2); }
.footer ul { list-style: none; padding: 0; display: grid; gap: 0.5rem; }
.footer a:hover { color: var(--yellow); }
.footer__bottom {
  border-block-start: 1px solid var(--surface-line); padding-block-start: var(--s-3);
  display: flex; flex-wrap: wrap; gap: var(--s-2); justify-content: space-between;
  font-size: 0.8125rem; color: var(--text-muted);
}

/* ---------- Utilities ---------- */
.stack > * + * { margin-block-start: var(--s-3); }
.muted { color: var(--text-muted); }
.center { text-align: center; margin-inline: auto; }
.sr {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.skip {
  position: absolute; inset-block-start: -100px; inset-inline-start: var(--s-2); z-index: 200;
  background: var(--yellow); color: var(--black); padding: 0.75rem 1.25rem; font-weight: 700;
}
.skip:focus { inset-block-start: var(--s-2); }

/* ============================================================
   PAGE TRANSITIONS
   Native cross-document View Transitions — one declaration, no JS,
   no library. Unsupported browsers simply navigate as normal, so
   this is pure progressive enhancement.

   Kept short (260ms) and quiet: a cross-fade with the incoming page
   drifting up a few pixels. Anything longer starts to feel like
   latency rather than polish on the Home → Quote path.
   ============================================================ */
@view-transition { navigation: auto; }

/* The plane the cards sit on. Scaling a page down reveals this behind it,
   which is what sells "the page became an object". */
html { background: #070707; }
[data-theme="light"] { background: #DCDCD6; }

/* Incoming page rides above the outgoing one. */
::view-transition-new(root) { z-index: 1; }
::view-transition-old(root) { z-index: 0; }

::view-transition-old(root) {
  animation: cardOut 0.26s cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: cardIn 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Forward: current page shrinks to a card and leaves left; next page
   arrives from the right as a card and grows to fill. Exit is 62% of
   the enter duration so the whole thing feels responsive, not draggy. */
@keyframes cardOut {
  from { transform: none; border-radius: 0; opacity: 1; }
  to   { transform: translateX(-12%) scale(0.9); border-radius: 16px; opacity: 0; }
}
@keyframes cardIn {
  from { transform: translateX(24%) scale(0.88); border-radius: 16px; opacity: 0; }
  to   { transform: none; border-radius: 0; opacity: 1; }
}

/* Moving to a page earlier in the running order reverses the slide, so the
   geography stays consistent whichever way you travel — including browser
   back, which resolves to the same comparison. Set by boot.js. */
html[data-nav="back"]::view-transition-old(root) { animation-name: cardOutBack; }
html[data-nav="back"]::view-transition-new(root) { animation-name: cardInBack; }
@keyframes cardOutBack {
  from { transform: none; border-radius: 0; opacity: 1; }
  to   { transform: translateX(12%) scale(0.9); border-radius: 16px; opacity: 0; }
}
@keyframes cardInBack {
  from { transform: translateX(-24%) scale(0.88); border-radius: 16px; opacity: 0; }
  to   { transform: none; border-radius: 0; opacity: 1; }
}

/* Depth, not distance: a service page lives *under* Services, so entering
   one moves toward the viewer instead of sideways. Leaving reverses it.
   Pure scale — no lateral travel — so the two axes never read the same. */
html[data-nav="in"]::view-transition-old(root)  { animation-name: depthOutIn; }
html[data-nav="in"]::view-transition-new(root)  { animation-name: depthInIn; }
html[data-nav="out"]::view-transition-old(root) { animation-name: depthOutUp; }
html[data-nav="out"]::view-transition-new(root) { animation-name: depthInDown; }

@keyframes depthOutIn {   /* parent recedes */
  from { transform: none; border-radius: 0; opacity: 1; }
  to   { transform: scale(0.94); border-radius: 16px; opacity: 0; }
}
@keyframes depthInIn {    /* child rises toward you */
  from { transform: scale(1.06); border-radius: 16px; opacity: 0; }
  to   { transform: none; border-radius: 0; opacity: 1; }
}
@keyframes depthOutUp {   /* child passes the viewer on the way out */
  from { transform: none; border-radius: 0; opacity: 1; }
  to   { transform: scale(1.06); border-radius: 16px; opacity: 0; }
}
@keyframes depthInDown {  /* parent returns from behind */
  from { transform: scale(0.94); border-radius: 16px; opacity: 0; }
  to   { transform: none; border-radius: 0; opacity: 1; }
}

/* RTL reads right-to-left, so the lateral pair swaps. Depth is unaffected. */
[dir="rtl"][data-nav="forward"]::view-transition-old(root) { animation-name: cardOutBack; }
[dir="rtl"][data-nav="forward"]::view-transition-new(root) { animation-name: cardInBack; }
[dir="rtl"][data-nav="back"]::view-transition-old(root) { animation-name: cardOut; }
[dir="rtl"][data-nav="back"]::view-transition-new(root) { animation-name: cardIn; }

/* The header is visually continuous between pages — hold it still so it
   reads as one persistent frame while the content card swaps beneath. */
.header { view-transition-name: site-header; }
::view-transition-group(site-header) { animation-duration: 0.01s; }

/* ============================================================
   ARABIC / RTL
   Layout already flips for free — every spacing rule in this file
   uses logical properties. What Arabic actually needs is type
   handling, and one rule that is not optional:

   letter-spacing BREAKS Arabic. The script is cursive; adding
   tracking pulls the joined letterforms apart into gibberish.
   Every tracked style in this file must reset to normal.
   ============================================================ */
/* IBM Plex Sans Arabic is the brand Arabic face (BRAND/Typography.md).
   It ships in the same Google Fonts request as Montserrat — no extra
   connection — and unicode-range subsetting means the Arabic file only
   downloads on pages that actually contain Arabic glyphs. */
:root { --font-ar: "IBM Plex Sans Arabic", "Segoe UI", Tahoma, sans-serif; }

[lang="ar"] body,
[dir="rtl"] body { font-family: var(--font-ar); }

/* The bilingual wordmark renders in Arabic on every page, English or not,
   so it takes the brand Arabic face rather than a system fallback. */
.logo__ar,
:lang(ar) { font-family: var(--font-ar); }
/* Applies to the marked element AND everything inside it. Listing individual
   components missed the case where the Arabic element is itself the one
   carrying dir/lang — e.g. a single Arabic heading on an English page — and
   that element kept the Latin tracking. */
[dir="rtl"], [dir="rtl"] *,
[lang="ar"], [lang="ar"] * {
  letter-spacing: normal;
  /* Arabic has no letter case, so uppercase is a no-op that only risks an
     odd font fallback. */
  text-transform: none;
}
/* Arabic headlines need a touch more leading than the tight Latin setting */
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] .display { line-height: 1.25; }
/* Directional glyphs have to turn around with the layout */
[dir="rtl"] .btn__arrow { transform: scaleX(-1); }
[dir="rtl"] .btn:hover .btn__arrow { transform: scaleX(-1) translateX(4px); }
/* A phone number is not Arabic text. The leading "+" is bidi-neutral, so in
   an RTL paragraph the algorithm flips the whole string and +973 3994 9004
   renders as 9004 3994 973+. Isolating it pins the digits to LTR order.
   Selector is not scoped to [dir="rtl"] — it should hold wherever a number
   lands, including a future Arabic page. */
a[href^="tel:"] { direction: ltr; unicode-bidi: isolate; }

/* ---------- Motion preference ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .level__bubble { inset-inline-start: 50%; }
  /* Level sits centred and still; loader opens instantly rather than animating. */
  .levelbar__bubble { inset-inline-start: 50% !important; }
  .levelbar { cursor: default; }
  .loader__bubble { animation: none; inset-inline-start: 50%; }
  .loader.is-done { display: none; }
  /* Page transitions off entirely — a cross-fade is still motion. */
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
