/*
 * getqatra.com
 *
 * The site runs on the app's own two grounds and adds nothing to them:
 *
 *   PAPER — warm parchment, dark ink, gold used once per screenful. Everything
 *           marketing is set here.
 *   NIGHT — the app's reading surface. It appears exactly where the page is
 *           showing the product reading, so the ground change carries meaning
 *           instead of just breaking up the scroll.
 *
 * Every colour, radius and face is lifted from apps/mobile/src/theme/tokens.ts.
 * Nothing is approximated: a gold a shade off makes the page read as a fan site.
 *
 * Structure is editorial rather than card-based. Sections are numbered in the
 * margin, separated by hairlines, and set on an asymmetric measure. Three equal
 * feature cards in a row is the shape every product page defaults to and it
 * tells the reader nothing about which claim matters.
 */

/* ------------------------------------------------------------------- faces */

@font-face {
  font-family: 'Fraunces';
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url('/fonts/fraunces-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Fraunces';
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url('/fonts/fraunces-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Fraunces';
  font-weight: 600;
  font-style: italic;
  font-display: swap;
  src: url('/fonts/fraunces-600-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Jakarta';
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/jakarta-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Jakarta';
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/jakarta-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Jakarta';
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/jakarta-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Jakarta';
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/jakarta-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Amiri';
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/amiri-400.woff2') format('woff2');
}
/* Arabic pages set their whole interface in naskh, and an interface has bold in
   it — labels, the strong in a legal clause, a plan name. Without a real bold
   the browser synthesises one by smearing the strokes, which on naskh reads as
   a rendering fault rather than as emphasis. */
@font-face {
  font-family: 'Amiri';
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/amiri-700.woff2') format('woff2');
}

/* ------------------------------------------------------------------ tokens */

:root {
  --night: #0b1210;
  --night-soft: #131e1a;
  --night-raised: #1c2a25;

  --paper: #fbf7f0;
  --paper-sunk: #f3ede2;
  --paper-deep: #efe6d5;
  --paper-raised: #ffffff;
  --line: #e7ddcc;
  --line-strong: #d8cbb4;

  --ink: #17211c;
  --ink-muted: #6b7a72;
  --ink-faint: #9ca9a1;

  --light: #f6f1e7;
  --light-muted: rgba(246, 241, 231, 0.64);
  --light-faint: rgba(246, 241, 231, 0.38);

  --sun: #f4c544;
  --sun-ink: #1a1508;

  --gold: #b8862b;
  --gold-deep: #8f6516;
  --gold-soft: #e2be79;
  --gold-wash: #f7eedc;
  --emerald: #1e6b52;
  --emerald-wash: #e4f0ea;

  /* Warm-tinted, as in the app: a neutral black shadow on parchment reads as
     grey dirt rather than as depth. */
  --shadow-card: 0 1px 2px rgba(59, 44, 20, 0.05), 0 6px 18px rgba(59, 44, 20, 0.06);
  --shadow-raised: 0 2px 4px rgba(59, 44, 20, 0.06), 0 14px 34px rgba(59, 44, 20, 0.11);
  --shadow-phone: 0 4px 8px rgba(59, 44, 20, 0.1), 0 30px 70px rgba(40, 30, 14, 0.22);

  --shell: 1180px;
  --gutter: clamp(20px, 5vw, 48px);

  /* One curve for the whole site. The app's own easing, not a browser default. */
  --ease: cubic-bezier(0.2, 0, 0, 1);
}

/* ------------------------------------------------------------------- reset */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Jakarta', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

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

p {
  margin: 0 0 1.05em;
  text-wrap: pretty;
}

p:last-child {
  margin-bottom: 0;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 400;
  text-wrap: balance;
}

ul,
ol {
  margin: 0 0 1.05em;
  padding-inline-start: 1.25em;
}

li {
  margin-bottom: 0.4em;
  text-wrap: pretty;
}

::selection {
  background: var(--gold-soft);
  color: var(--sun-ink);
}

:focus-visible {
  outline: 2px solid var(--gold-deep);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--ink);
  color: var(--paper);
  border-radius: 0 0 10px 0;
}

.skip:focus {
  inset-inline-start: 0;
}

/* -------------------------------------------------------------- primitives */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Section numbers, the small tracked labels, and every other piece of interface
   type. Uppercase and tracked so it recedes without going grey-on-grey. */
.overline {
  margin: 0;
  font-family: 'Jakarta', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.night .overline {
  color: var(--light-faint);
}

.ar {
  font-family: 'Amiri', 'Geeza Pro', serif;
  direction: rtl;
  unicode-bidi: isolate;
}

.num {
  font-variant-numeric: tabular-nums;
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(251, 247, 240, 0.82);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms var(--ease);
}

.site-header.scrolled {
  border-bottom-color: var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 72px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  flex-shrink: 0;
}

/* The icon tile. Radius and drop coverage match the shipped app icon. */
.mark {
  display: grid;
  place-items: center;
  width: var(--mark-size);
  height: var(--mark-size);
  border-radius: calc(var(--mark-size) * 0.2237);
  background: var(--sun);
  box-shadow: 0 1px 2px rgba(59, 44, 20, 0.14);
  flex-shrink: 0;
}

/* The size comes from a class and not from a style attribute on the element.
   The site is served under 'style-src self' with no 'unsafe-inline', so an
   inline style is dropped by the browser in production while working fine off
   a local file server — which makes it the one kind of bug that cannot be seen
   before it ships. Every size the markup asks for needs a rule here. */
.mark-26 { --mark-size: 26px; }
.mark-32 { --mark-size: 32px; }
.mark-38 { --mark-size: 38px; }
.mark-44 { --mark-size: 44px; }

/* The same reason, for the handful of one-off declarations the markup used to
   carry inline. */
.is-contents { display: contents; }
.link-inherit { color: inherit; text-decoration: underline; }
.faq-narrow { max-width: 760px; }
.split-media-flush { gap: 0; align-items: flex-end; }

.wordmark-names {
  display: flex;
  flex-direction: column;
  line-height: 1;
}

.wordmark-names .ar {
  font-size: calc(var(--mark-size) * 0.52);
  /* Amiri's ascenders and the fatha on قَطْ need headroom the default line box
     does not give them; without this the mark clips against the row above. */
  line-height: 1.5;
  color: var(--ink);
}

.wordmark-names .lat {
  font-family: 'Jakarta', sans-serif;
  font-size: calc(var(--mark-size) * 0.27);
  font-weight: 700;
  letter-spacing: 3.2px;
  color: var(--ink-faint);
}

.header-nav {
  display: flex;
  gap: 26px;
  margin-inline-start: auto;
  font-size: 15px;
  font-weight: 500;
}

.header-nav a {
  position: relative;
  color: var(--ink-muted);
  padding: 8px 0;
  transition: color 160ms var(--ease);
}

.header-nav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 220ms var(--ease);
}

.header-nav a:hover {
  color: var(--ink);
}

.header-nav a:hover::after {
  transform: scaleX(1);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 46px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  font-family: 'Jakarta', sans-serif;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.1px;
  cursor: pointer;
  transition:
    background-color 160ms var(--ease),
    color 160ms var(--ease),
    box-shadow 160ms var(--ease),
    transform 120ms var(--ease);
}

.btn:active {
  transform: scale(0.96);
}

.btn-ink {
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow-card);
}

.btn-ink:hover {
  background: #0f1814;
  box-shadow: var(--shadow-raised);
}

.btn-gold {
  background: var(--sun);
  color: var(--sun-ink);
  box-shadow: 0 1px 2px rgba(59, 44, 20, 0.12), 0 8px 20px rgba(184, 134, 43, 0.22);
}

.btn-gold:hover {
  background: #f7cf60;
}

.btn-quiet {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}

.btn-quiet:hover {
  box-shadow: inset 0 0 0 1px var(--ink-faint);
}

.night .btn-quiet,
.cta .btn-quiet {
  color: var(--light);
  box-shadow: inset 0 0 0 1px rgba(246, 241, 231, 0.22);
}

.night .btn-quiet:hover,
.cta .btn-quiet:hover {
  box-shadow: inset 0 0 0 1px rgba(246, 241, 231, 0.45);
}

.header-cta {
  min-height: 40px;
  padding: 0 18px;
  font-size: 14.5px;
}

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

.hero {
  position: relative;
  padding-top: clamp(48px, 7vw, 92px);
  padding-bottom: clamp(56px, 8vw, 110px);
  overflow: hidden;
}

/* The mihrab, at architectural size and cropped by the section. It sits behind
   the phone and is the whole of the decoration: no pattern, no glow, no mesh. */
.hero-arch {
  position: absolute;
  top: clamp(30px, 5vw, 78px);
  right: clamp(-90px, -2vw, -20px);
  width: min(560px, 50vw);
  pointer-events: none;
}

.hero-arch .arch {
  width: 100%;
  height: auto;
}

.hero-inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  align-items: center;
  gap: clamp(32px, 5vw, 72px);
}

.hero h1 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(2.4rem, 4.9vw, 3.95rem);
  line-height: 1.08;
  letter-spacing: -0.028em;
  margin-bottom: 24px;
}

/* One accented phrase per headline, in gold italic. It goes on the phrase that
   carries the claim, and it is the only decoration the type gets. */
.hero h1 em,
.claim em,
.sec-head h2 em {
  font-style: italic;
  font-weight: 600;
  color: var(--gold-deep);
}

.hero-sub {
  max-width: 34ch;
  font-size: clamp(1.02rem, 1.3vw, 1.18rem);
  line-height: 1.6;
  color: var(--ink-muted);
  margin-bottom: 32px;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
}

.hero-fine {
  font-size: 13.5px;
  color: var(--ink-faint);
}

.hero-fine strong {
  font-weight: 600;
  color: var(--ink-muted);
}

@media (min-width: 1001px) {
  /* Lift the whole hero toward the header so more of the phone sits above the
     fold. The arch is positioned against the section rather than the grid, so
     it takes the same lift and stays put behind the device. */
  .hero {
    --hero-lift: clamp(20px, 2.8vw, 40px);
    padding-top: calc(clamp(48px, 7vw, 92px) - var(--hero-lift));
  }

  .hero-arch {
    top: calc(clamp(30px, 5vw, 78px) - var(--hero-lift));
  }

  .hero-copy {
    translate: 0 -34px;
  }
}

/* --------------------------------------------------------------- the phone */

.stage {
  position: relative;
  display: flex;
  justify-content: center;
}

/*
 * The device shell. The screen radius is 12.5% of the shell width, which is what
 * the hardware does; the bezel is a fixed 10px, so the outer radius is the inner
 * radius plus the bezel and the two corners stay concentric. Getting that wrong
 * is what makes a mocked-up phone look pinched at the corners.
 */
.phone {
  --phone-w: 336px;
  --bezel: 10px;
  --screen-radius: 42px;
  position: relative;
  width: var(--phone-w);
  padding: var(--bezel);
  border-radius: calc(var(--screen-radius) + var(--bezel));
  background: linear-gradient(160deg, #2b3531 0%, #101815 42%, #232c29 100%);
  box-shadow: var(--shadow-phone), inset 0 0 0 1px rgba(255, 255, 255, 0.09);
}

.phone img {
  width: 100%;
  height: auto;
  border-radius: var(--screen-radius);
  /* Pure black at low opacity, never a tinted neutral: a warm outline picks up
     the parchment behind it and reads as dirt along the screen edge. */
  outline: 1px solid rgba(0, 0, 0, 0.12);
  outline-offset: -1px;
}

/* Smaller in a split than in the hero: beside a three-line paragraph, a
   full-height phone is not a bigger argument, it is a bigger hole. */
.split .phone {
  --phone-w: 292px;
  --screen-radius: 37px;
}

.phone-sm {
  --phone-w: 250px;
  --screen-radius: 32px;
  --bezel: 8px;
}

.phone-tilt-l {
  transform: rotate(-2.5deg);
}

.phone-tilt-r {
  transform: rotate(2.5deg);
}

/* The notification, lifted out of the lock screen and enlarged. Drawn rather
   than cropped from the screenshot so the type stays sharp at any size. */
.notif {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: min(330px, 84vw);
  padding: 13px 15px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: var(--shadow-raised), inset 0 0 0 1px rgba(255, 255, 255, 0.7);
  text-align: start;
}

.notif .icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 9px;
  background: var(--sun);
  flex-shrink: 0;
}

.notif .body {
  flex: 1;
  min-width: 0;
}

.notif .meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 2px;
}

.notif .app-name {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: rgba(23, 33, 28, 0.62);
}

.notif .when {
  font-size: 11.5px;
  color: rgba(23, 33, 28, 0.45);
  font-variant-numeric: tabular-nums;
}

.notif .line {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 15px;
  line-height: 1.35;
  color: var(--ink);
}

.notif .line-ar {
  font-family: 'Amiri', serif;
  direction: rtl;
  font-size: 14.5px;
  line-height: 1.7;
  color: rgba(23, 33, 28, 0.6);
  text-align: right;
}

/* The three reminders, stacked as they arrive: one under the other, down the
   day. Side by side they read as three products rather than three moments. */
.notif-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  max-width: 400px;
}

.notif-stack .notif {
  width: 100%;
}

.notif-float {
  position: absolute;
  /* Hang into the column gutter and no further. A viewport-based offset kept
     growing past the gap on wide screens and slid the card over the hero's
     fine print; tying it to the same clamp the grid gap uses means it always
     stops exactly where the text column ends. */
  inset-inline-start: calc(-1 * clamp(32px, 5vw, 72px));
  bottom: 14%;
  z-index: 2;
}

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

.sec {
  position: relative;
  padding-block: clamp(64px, 8vw, 112px);
}

.sec + .sec {
  border-top: 1px solid var(--line);
}

.night {
  background: var(--night);
  color: var(--light);
  border-top: 0 !important;
}

.night + .sec {
  border-top: 0;
}

.sunk {
  background: var(--paper-sunk);
  border-top: 0 !important;
}

/* Section headers carry a number in the margin. It is a print idiom rather than
   a web one, and it gives the eye a fixed left edge to travel down. */
.sec-head {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  align-items: start;
  gap: 0 12px;
  margin-bottom: clamp(32px, 4vw, 54px);
}

.sec-num {
  font-family: 'Jakarta', sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--gold);
  padding-top: 0.75em;
  font-variant-numeric: tabular-nums;
}

.night .sec-num {
  color: var(--gold-soft);
}

.sec-head h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.95rem, 3.4vw, 2.9rem);
  line-height: 1.12;
  letter-spacing: -0.022em;
  max-width: 18ch;
}

/* `> p:not(.sec-num)` and not `p`: the section number is a paragraph too, and
   the bare selector put it in the content column and dropped the heading into
   the 56px margin. */
.sec-head > p:not(.sec-num) {
  grid-column: 2;
  max-width: 46ch;
  margin-top: 16px;
  color: var(--ink-muted);
  font-size: 1.03rem;
}

.night .sec-head > p:not(.sec-num) {
  color: var(--light-muted);
}

/* ------------------------------------------------------ the claim (night) */

/*
 * The product, shown rather than described: one real reflection, set exactly as
 * the app sets it — the reader's language in Fraunces, the Arabic beneath it in
 * Amiri. The honest limitation goes directly underneath, because it is the thing
 * a careful reader most wants to know before installing.
 */
.claim {
  max-width: min(660px, 92%);
  margin-inline: auto;
  text-align: center;
}

.claim .en {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.75rem, 3.6vw, 2.85rem);
  line-height: 1.32;
  letter-spacing: -0.018em;
  color: var(--light);
}

.claim .ar {
  display: block;
  margin-top: 26px;
  font-size: clamp(1.5rem, 3vw, 2.3rem);
  line-height: 1.85;
  color: var(--light-muted);
}

.claim-rule {
  width: 40px;
  height: 1px;
  margin: 46px auto 24px;
  background: rgba(246, 241, 231, 0.24);
}

.claim-note {
  max-width: min(560px, 92%);
  margin-inline: auto;
  text-align: center;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--light-muted);
}

.claim-note strong {
  font-weight: 600;
  color: var(--light);
}

/* ------------------------------------------------------------- split rows */

/* The workhorse: text one side, product the other, alternating. Columns are
   deliberately unequal — a 50/50 split makes the eye stop in the middle. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(36px, 6vw, 84px);
}

.split.reverse .split-media {
  order: -1;
}

.split-media {
  display: flex;
  justify-content: center;
  align-items: center;
}

.split-copy h3 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.6rem, 2.6vw, 2.15rem);
  line-height: 1.16;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}

.split-copy p {
  color: var(--ink-muted);
  max-width: 42ch;
}

.night .split-copy p {
  color: var(--light-muted);
}

/* --------------------------------------------------------------- fact list */

/* Numbers, set large. Every one is read out of the code, so the list is a spec
   sheet rather than a set of adjectives. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  margin-top: 40px;
  background: var(--line);
  border-block: 1px solid var(--line);
}

.night .facts {
  background: rgba(246, 241, 231, 0.14);
  border-color: rgba(246, 241, 231, 0.14);
}

.fact {
  padding: 24px 20px 26px;
  background: var(--paper);
}

.sunk .fact {
  background: var(--paper-sunk);
}

.night .fact {
  background: var(--night);
}

.fact dt .unit {
  font-size: 0.5em;
  margin-inline-start: 0.28em;
}

.fact dt {
  font-family: 'Fraunces', Georgia, serif;
  white-space: nowrap;
  font-size: clamp(1.9rem, 3vw, 2.6rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}

.fact dd {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-muted);
}

.night .fact dd {
  color: var(--light-muted);
}

/* ------------------------------------------------------------- theme strip */

/*
 * The backdrops, at the tile proportions the app uses, in one row that scrolls
 * sideways on a narrow screen rather than reflowing into a grid — the app's own
 * theme picker scrolls, and a wrapped grid would imply a different screen.
 */
.themes-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 178px;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 8px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.themes-rail::-webkit-scrollbar {
  display: none;
}

.theme-tile {
  position: relative;
  aspect-ratio: 400 / 520;
  border-radius: 20px;
  overflow: hidden;
  scroll-snap-align: start;
  box-shadow: var(--shadow-card);
  isolation: isolate;
}

.theme-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.theme-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.55) 100%);
}

.theme-tile .glyph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 1;
  font-family: 'Amiri', serif;
  direction: rtl;
  font-size: 27px;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.4);
}

.theme-tile .label {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 13px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
}

/* Marks the eight themes that are video in the app, not a decoration. */
.theme-tile .living {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.82);
}

.theme-tile .living::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: var(--sun);
}


/* ------------------------------------------------------------- the wall */

/*
 * Two rows of cards travelling in opposite directions. The opposition is the
 * point: two rows moving the same way read as one block sliding, and the eye
 * follows it off the screen instead of settling on a card.
 *
 * The track holds the list twice and translates by exactly -50%, so the second
 * copy is under the cursor at the moment the first runs out and the loop has no
 * seam. Duplicating by any other amount, or animating `left`, shows a jump.
 * `width: max-content` keeps the cards at their natural size instead of being
 * squeezed to the row.
 */

.wall {
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Full-bleed out of `.shell`: a marquee that stops at the text measure reads
     as a carousel with broken arrows. */
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

.wall-row {
  overflow: hidden;
  /* Fade both ends so cards enter and leave rather than being cut by an edge. */
  mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}

.wall-track {
  display: flex;
  gap: 16px;
  width: max-content;
  animation: wall-left 82s linear infinite;
}

.wall-row.reverse .wall-track {
  animation-name: wall-right;
}

/* Stop under the pointer, so a card that catches the eye can be read. */
.wall-row:hover .wall-track,
.wall-row:focus-within .wall-track {
  animation-play-state: paused;
}

@keyframes wall-left {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@keyframes wall-right {
  from { transform: translateX(-50%); }
  to { transform: translateX(0); }
}

.tcard {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 356px;
  flex-shrink: 0;
  padding: 24px;
  border-radius: 22px;
  background: var(--paper-raised);
  box-shadow: var(--shadow-card);
}

.tcard .who {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* A monogram, not a stock portrait. There is no photograph of these people to
   use, and inventing one would be a second fiction on top of the quote. */
.tcard .avatar {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 999px;
  background: var(--gold-wash);
  box-shadow: inset 0 0 0 1px rgba(184, 134, 43, 0.18);
  font-family: 'Jakarta', sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: var(--gold-deep);
}

.tcard .name {
  font-family: 'Jakarta', sans-serif;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
}

.tcard .meta {
  font-size: 13px;
  line-height: 1.3;
  color: var(--ink-faint);
}

.tcard .quote {
  margin: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-size: 16.5px;
  line-height: 1.52;
  letter-spacing: -0.005em;
  color: var(--ink);
}

/* Arabic gets the app's own treatment: a real naskh, right to left, and the
   looser leading the face needs. */
.tcard.rtl {
  direction: rtl;
}

.tcard.rtl .quote {
  font-family: 'Amiri', serif;
  font-size: 18px;
  line-height: 1.95;
}

@media (max-width: 720px) {
  .tcard {
    width: 290px;
    padding: 20px;
  }

  .wall-track {
    animation-duration: 58s;
  }
}

/* Motion off: the rows stop and become ordinary scrollable rails, so every
   card is still reachable rather than frozen half out of frame. */
@media (prefers-reduced-motion: reduce) {
  .wall-row {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .wall-row::-webkit-scrollbar {
    display: none;
  }

  .wall-track {
    animation: none;
  }
}

/* ------------------------------------------------------------------ prices */

.plans {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  gap: clamp(16px, 2.4vw, 26px);
  align-items: start;
}

.plan {
  padding: clamp(26px, 3vw, 36px);
  border-radius: 26px;
  background: var(--paper-raised);
  box-shadow: var(--shadow-card);
}

.plan.premium {
  background: var(--night);
  color: var(--light);
  box-shadow: var(--shadow-raised);
}

.plan h3 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.55rem;
  letter-spacing: -0.02em;
  margin-bottom: 4px;
}

.plan .price {
  font-size: 14px;
  color: var(--ink-muted);
  margin-bottom: 22px;
}

.plan.premium .price {
  color: var(--light-muted);
}

.plan ul {
  list-style: none;
  margin: 0 0 26px;
  padding: 0;
  font-size: 15.3px;
}

.plan li {
  display: flex;
  gap: 11px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
  color: var(--ink-muted);
}

.plan.premium li {
  border-top-color: rgba(246, 241, 231, 0.13);
  color: var(--light-muted);
}

.plan li:first-child {
  border-top: 0;
}

.plan li .tick {
  flex-shrink: 0;
  margin-top: 6px;
  color: var(--gold);
}

.plan.premium li .tick {
  color: var(--gold-soft);
}

.plan-badge {
  display: inline-block;
  margin-bottom: 14px;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--gold-wash);
  color: var(--gold-deep);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
}

.plan.premium .plan-badge {
  background: rgba(226, 190, 121, 0.16);
  color: var(--gold-soft);
}

.plan-fine {
  margin-top: 18px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-faint);
}

.plan.premium .plan-fine {
  color: var(--light-faint);
}

/* --------------------------------------------------------------------- faq */

.faq {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 0 clamp(36px, 5vw, 72px);
}

.faq-item {
  padding: 24px 0;
  border-top: 1px solid var(--line);
}

.faq-item h3 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.2rem;
  line-height: 1.3;
  letter-spacing: -0.012em;
  margin-bottom: 9px;
}

.faq-item p {
  font-size: 15.5px;
  color: var(--ink-muted);
}

/* ---------------------------------------------------------------- languages */

.langs {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: clamp(20px, 4vw, 56px);
  padding-block: 8px;
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.7rem, 4vw, 3rem);
  letter-spacing: -0.02em;
  color: var(--ink);
}

.langs .ar {
  font-family: 'Amiri', serif;
  font-size: clamp(2rem, 4.6vw, 3.5rem);
}

/* Inline in a split column, where there is half the width to play with. */
.langs-inline {
  justify-content: flex-start;
  gap: 18px;
  margin-top: 22px;
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
}

.langs-inline .ar {
  font-size: clamp(1.4rem, 2vw, 1.75rem);
}

.langs .dot {
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: var(--gold);
  transform: translateY(-0.5em);
}

/* -------------------------------------------------------------------- cta */

.cta {
  position: relative;
  overflow: hidden;
  background: var(--night);
  color: var(--light);
  text-align: center;
}

.cta-arch {
  position: absolute;
  left: 50%;
  top: clamp(34px, 5vw, 70px);
  translate: -50% 0;
  width: min(660px, 88vw);
  opacity: 0.62;
  pointer-events: none;
}

.cta-arch .arch {
  width: 100%;
  height: auto;
}

.cta-inner {
  position: relative;
}

.cta h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(2.1rem, 4.4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.026em;
  max-width: 15ch;
  margin-inline: auto;
  margin-bottom: 18px;
}

.cta h2 em {
  font-style: italic;
  font-weight: 600;
  color: var(--gold-soft);
}

.cta p {
  max-width: 42ch;
  margin-inline: auto;
  margin-bottom: 30px;
  color: var(--light-muted);
}

.cta-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-bottom: 18px;
}

.cta-fine {
  font-size: 13px;
  color: var(--light-faint);
}

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

.site-footer {
  background: var(--paper-sunk);
  border-top: 1px solid var(--line);
  padding-top: clamp(48px, 6vw, 72px);
}

.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 48px);
  padding-bottom: 48px;
}

.footer-brand .footer-line {
  max-width: 30ch;
  margin-top: 20px;
  margin-bottom: 10px;
  font-size: 15px;
  color: var(--ink-muted);
}

.footer-note {
  max-width: 32ch;
  font-size: 13.5px;
  color: var(--ink-faint);
}

.footer-col h2 {
  font-family: 'Jakarta', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 16px;
}

.footer-col a {
  display: block;
  padding: 5px 0;
  font-size: 14.5px;
  color: var(--ink-muted);
  transition: color 150ms var(--ease);
}

.footer-col a:hover {
  color: var(--ink);
}

.footer-address {
  margin-top: 16px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-faint);
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  padding-block: 20px 26px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-faint);
}

.footer-base p {
  margin: 0;
}

/* --------------------------------------------------------------- documents */

.doc-head {
  padding-top: clamp(44px, 6vw, 76px);
  padding-bottom: clamp(30px, 3.5vw, 44px);
  border-bottom: 1px solid var(--line);
}

.doc-head h1 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(2.1rem, 4.4vw, 3.3rem);
  line-height: 1.08;
  letter-spacing: -0.026em;
  margin-top: 14px;
  max-width: 20ch;
}

.doc-intro {
  max-width: 56ch;
  margin-top: 20px;
  font-size: 1.05rem;
  color: var(--ink-muted);
}

.doc-date {
  margin-top: 18px;
  font-size: 13px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.doc-body {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  padding-block: clamp(36px, 5vw, 64px) clamp(56px, 7vw, 96px);
}

.doc-toc {
  position: sticky;
  top: 100px;
  align-self: start;
}

.doc-toc h2 {
  font-family: 'Jakarta', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 14px;
}

.doc-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

.doc-toc li {
  margin: 0;
}

.doc-toc a {
  display: flex;
  gap: 10px;
  padding: 6px 0;
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink-muted);
  transition: color 150ms var(--ease);
}

.doc-toc a:hover {
  color: var(--ink);
}

.doc-toc .num {
  color: var(--gold);
  font-weight: 700;
  font-size: 11.5px;
  padding-top: 2px;
}

.doc-prose {
  max-width: 68ch;
}

.doc-prose section + section {
  margin-top: 46px;
}

.doc-prose h2 {
  display: flex;
  gap: 14px;
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(1.35rem, 2.2vw, 1.72rem);
  line-height: 1.2;
  letter-spacing: -0.018em;
  margin-bottom: 16px;
}

.doc-prose h2 .num {
  font-family: 'Jakarta', sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--gold);
  padding-top: 0.62em;
  flex-shrink: 0;
}

.doc-prose h3 {
  font-family: 'Jakarta', sans-serif;
  font-size: 15.5px;
  font-weight: 700;
  margin: 28px 0 8px;
}

.doc-prose p,
.doc-prose li {
  color: var(--ink-muted);
  font-size: 16px;
}

.doc-prose strong {
  font-weight: 600;
  color: var(--ink);
}

.doc-prose a {
  color: var(--gold-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

.doc-prose table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.05em;
  font-size: 14.5px;
}

.doc-prose th,
.doc-prose td {
  padding-block: 11px;
  padding-inline: 0 14px;
  text-align: start;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
  color: var(--ink-muted);
}

.doc-prose th {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.doc-prose td:first-child {
  color: var(--ink);
  font-weight: 500;
  width: 34%;
}

.doc-callout {
  padding: 20px 22px;
  border-radius: 18px;
  background: var(--gold-wash);
  box-shadow: inset 0 0 0 1px rgba(184, 134, 43, 0.14);
  margin-bottom: 1.05em;
}

.doc-callout p {
  color: var(--gold-deep);
  font-size: 15px;
}

/* ---------------------------------------------------------------- support */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 20px;
  overflow: hidden;
  margin-bottom: 1.05em;
}

.contact-cell {
  padding: 22px;
  background: var(--paper);
}

.contact-cell h3 {
  font-family: 'Jakarta', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 8px;
}

.contact-cell a,
.contact-cell p {
  font-size: 15px;
  color: var(--ink);
}

/* --------------------------------------------------------------- reveal */

/*
 * One restrained entrance, once, on first scroll into view. It is 12px of
 * travel and 500ms — enough to register as arrival, not enough to make the page
 * feel like it is assembling itself. Anything animated on a repeating
 * interaction is left alone.
 */
@media (prefers-reduced-motion: no-preference) {
  .reveal {
    opacity: 0;
    transform: translateY(12px);
    transition:
      opacity 500ms var(--ease),
      transform 500ms var(--ease);
  }

  .reveal.in {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------------- responsive */

@media (max-width: 1000px) {
  .hero-inner {
    grid-template-columns: minmax(0, 1fr);
    text-align: start;
  }

  .hero-arch {
    right: -22%;
    width: 78vw;
    opacity: 0.75;
  }

  .hero-sub {
    max-width: 46ch;
  }

  .stage {
    margin-top: 16px;
  }

  /* The three reminders, stacked as they arrive: one under the other, down the
   day. Side by side they read as three products rather than three moments. */
.notif-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  max-width: 400px;
}

.notif-stack .notif {
  width: 100%;
}

.notif-float {
    inset-inline-start: auto;
    inset-inline-end: clamp(-40px, -3vw, -12px);
    bottom: 6%;
    width: 260px;
  }

  .notif {
    width: 260px;
  }

  .split,
  .plans {
    grid-template-columns: minmax(0, 1fr);
  }

  .split.reverse .split-media {
    order: 0;
  }

  .doc-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .doc-toc {
    position: static;
    padding-bottom: 26px;
    border-bottom: 1px solid var(--line);
  }

  .doc-toc ol {
    columns: 2;
    column-gap: 28px;
  }

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

  .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 720px) {
  .header-nav {
    display: none;
  }

  .header-cta {
    margin-inline-start: auto;
  }

  .sec-head {
    grid-template-columns: minmax(0, 1fr);
  }

  .sec-num {
    padding-top: 0;
    margin-bottom: 12px;
  }

  /* Must match the specificity of the desktop `.sec-head > p:not(.sec-num)`
     rule, or that one keeps winning and its `grid-column: 2` conjures an
     implicit second column here — which collapses the heading's own column to
     0px and drops the sub-heading on top of it. */
  .sec-head > p:not(.sec-num),
  .sec-head h2 {
    grid-column: 1;
  }

  .phone {
    --phone-w: min(300px, 78vw);
  }

  /* The mihrab needs width to read as architecture. Cropped to a 195px strip it
     is just a vertical seam running down the hero, so it comes out entirely
     rather than being shown badly. */
  .hero-arch {
    display: none;
  }

  /* Full-width buttons: stacked at their own natural widths they read as a
     ragged column, and a 46px pill is a small target next to a thumb. */
  .hero-actions,
  .cta-actions {
    flex-direction: column;
    align-items: stretch;
  }

  /* Taking the notification out of `position: absolute` turns it into a flex
     item of `.stage`, which puts it *beside* the phone rather than under it. */
  .stage {
    flex-direction: column;
    align-items: center;
  }

  /* The three reminders, stacked as they arrive: one under the other, down the
   day. Side by side they read as three products rather than three moments. */
.notif-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  max-width: 400px;
}

.notif-stack .notif {
  width: 100%;
}

.notif-float {
    position: static;
    width: 100%;
    margin-top: 22px;
  }

  .notif {
    width: 100%;
  }

  .doc-toc ol {
    columns: 1;
  }

  .footer-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------------- language selector */

/*
 * A <details> and three links. It opens, closes and navigates with the
 * stylesheet and the markup alone; site.js only closes it on Escape and on a
 * click outside, and writes the choice down.
 *
 * It appears twice — once in the header, where a visitor looks for it, and
 * again in the footer, where a visitor who has scrolled a legal document to the
 * end is standing. On a narrow screen the header copy stands down and the
 * footer copy is the whole of it.
 */
.lang {
  position: relative;
  flex-shrink: 0;
}

.lang summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 11px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-muted);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition:
    color 160ms var(--ease),
    background-color 160ms var(--ease);
}

/* Safari draws its own disclosure triangle and ignores `list-style`. */
.lang summary::-webkit-details-marker {
  display: none;
}

.lang summary:hover {
  color: var(--ink);
  background: var(--paper-sunk);
}

.lang[open] summary {
  color: var(--ink);
  background: var(--paper-sunk);
}

.lang .globe {
  opacity: 0.7;
}

.lang-caret {
  opacity: 0.55;
  transition: transform 200ms var(--ease);
}

.lang[open] .lang-caret {
  transform: rotate(180deg);
}

.lang-list {
  position: absolute;
  z-index: 60;
  inset-inline-end: 0;
  min-width: 176px;
  margin: 6px 0 0;
  padding: 6px;
  list-style: none;
  background: var(--paper-raised);
  border-radius: 16px;
  box-shadow: var(--shadow-raised), inset 0 0 0 1px var(--line);
}

.lang-list li {
  margin: 0;
}

.lang-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 11px;
  font-size: 14.5px;
  color: var(--ink-muted);
  transition:
    color 140ms var(--ease),
    background-color 140ms var(--ease);
}

.lang-list a:hover {
  color: var(--ink);
  background: var(--paper-sunk);
}

.lang-list a[aria-current] {
  color: var(--ink);
  font-weight: 600;
}

.lang-check {
  color: var(--gold-deep);
  flex-shrink: 0;
}

/* Arabic is the one entry that has to be set in its own face wherever it is
   listed, including on an English page. */
.lang-list a[lang='ar'] span {
  font-family: 'Amiri', 'Geeza Pro', serif;
  font-size: 16px;
}

/* The footer copy opens upward: it sits on the last line of the page and a menu
   dropping below it would open off the bottom of the document. It also hangs
   from its leading edge rather than its trailing one, because the footer
   selector sits mid-row rather than against the far side of the page — anchored
   the other way it opens off the edge of a phone. */
.footer-lang {
  display: flex;
  align-items: center;
  gap: 10px;
}

.footer-lang-label {
  font-size: 13px;
  color: var(--ink-faint);
}

.lang-footer .lang-list {
  top: auto;
  bottom: 100%;
  inset-inline-start: 0;
  inset-inline-end: auto;
  margin: 0 0 6px;
}

/* -------------------------------------------------- first-run language screen */

/*
 * Shown once, to a visitor who has never chosen. lang.js marks <html> in the
 * head when nothing is stored, so this is up before the first paint and never
 * appears over a page the reader had already begun; with no JavaScript the
 * class never arrives and the screen never exists.
 */
.lang-gate {
  display: none;
}

html.needs-lang {
  overflow: hidden;
}

html.needs-lang .lang-gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgba(23, 33, 28, 0.44);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.lang-gate-card {
  width: min(420px, 100%);
  padding: clamp(28px, 5vw, 38px);
  border-radius: 26px;
  background: var(--paper);
  box-shadow: var(--shadow-raised);
  text-align: center;
}

.lang-gate-card .mark {
  margin-inline: auto;
  margin-bottom: 18px;
}

.lang-gate-card h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.6rem;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}

.lang-gate-card p {
  font-size: 14.5px;
  color: var(--ink-muted);
  margin-bottom: 22px;
}

.lang-gate-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Each option is set in its own script at its own size, because the whole point
   of this screen is that the reader recognises their language on sight. */
.lang-gate-options a[lang='ar'] {
  font-family: 'Amiri', 'Geeza Pro', serif;
  font-size: 19px;
}

@media (prefers-reduced-motion: no-preference) {
  html.needs-lang .lang-gate {
    animation: gate-in 240ms var(--ease) both;
  }

  .lang-gate-card {
    animation: gate-card 320ms var(--ease) both;
  }
}

@keyframes gate-in {
  from {
    opacity: 0;
  }
}

@keyframes gate-card {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
}

/* ---------------------------------------------------------- right to left */

/*
 * Everything above is written in logical properties, so this is only the
 * handful of places where a physical side is the correct answer: artwork that
 * hangs off one edge of the hero, and an underline that has to grow from the
 * side the text starts on.
 */
[dir='rtl'] .header-nav a::after {
  transform-origin: right;
}

/*
 * The marquee has to travel the other way.
 *
 * The track is a flex row, so in RTL it is laid out from the right edge of the
 * row and extends leftwards — everything past the first screenful is already
 * off to the left. Both LTR keyframes translate within [-50%, 0], which drags
 * it further that way, and the wall renders blank. The duplicate copy still
 * lands exactly on the original half a track along, so the mirror is the same
 * hop with the sign flipped.
 */
[dir='rtl'] .wall-track {
  animation-name: wall-start-rtl;
}

[dir='rtl'] .wall-row.reverse .wall-track {
  animation-name: wall-end-rtl;
}

/* Same 50% hop, the other way. The track is flush with the *right* edge of the
   row here, so the only translations that keep it on screen are positive ones. */
@keyframes wall-start-rtl {
  from { transform: translateX(0); }
  to { transform: translateX(50%); }
}

@keyframes wall-end-rtl {
  from { transform: translateX(50%); }
  to { transform: translateX(0); }
}

[dir='rtl'] .hero-arch {
  right: auto;
  left: clamp(-90px, -2vw, -20px);
}

[dir='rtl'] .skip {
  border-radius: 0 0 0 10px;
}

/* The tilt on the phones leans into the page from whichever side the phone is
   on, so it flips with the layout. */
[dir='rtl'] .phone-tilt-l {
  transform: rotate(2.5deg);
}

[dir='rtl'] .phone-tilt-r {
  transform: rotate(-2.5deg);
}

/* -------------------------------------------------------------- arabic type */

/*
 * `:lang(ar)` rather than `[lang='ar'] *`: the testimonial wall carries English
 * and French cards inside the Arabic page, and they must keep their own faces.
 * `:lang()` matches an element's computed language, so a card marked lang="en"
 * inside an Arabic document is correctly left alone.
 *
 * Each rule below carries the same selector as the one it overrides, plus the
 * pseudo-class — anything less specific loses to the class-based rule it is
 * meant to replace, silently, which is how a page ends up half in naskh.
 */
body:lang(ar) {
  font-family: 'Amiri', 'Geeza Pro', serif;
  font-size: 18px;
  line-height: 1.85;
}

.overline:lang(ar),
.btn:lang(ar),
.sec-num:lang(ar),
.tcard .avatar:lang(ar),
.tcard .name:lang(ar),
.footer-col h2:lang(ar),
.doc-toc h2:lang(ar),
.doc-prose h3:lang(ar),
.contact-cell h3:lang(ar),
.hero h1:lang(ar),
.notif .line:lang(ar),
.sec-head h2:lang(ar),
.claim .en:lang(ar),
.split-copy h3:lang(ar),
.fact dt:lang(ar),
.tcard .quote:lang(ar),
.plan h3:lang(ar),
.faq-item h3:lang(ar),
.cta h2:lang(ar),
.doc-head h1:lang(ar),
.doc-prose h2:lang(ar),
.lang-gate-card h2:lang(ar) {
  font-family: 'Amiri', 'Geeza Pro', serif;
}

/* Naskh has no italic, and a synthesised oblique on it is a slant applied to a
   script with no such convention — it reads as a fault. The gold stays; it was
   always the part carrying the emphasis. */
.hero h1 em:lang(ar),
.claim em:lang(ar),
.sec-head h2 em:lang(ar),
.cta h2 em:lang(ar) {
  font-style: normal;
}

/* Uppercase and letter-spacing do nothing to Arabic but break the joins between
   letters, so the small tracked labels lose both and keep only their size. */
.overline:lang(ar),
.sec-num:lang(ar),
.footer-col h2:lang(ar),
.doc-toc h2:lang(ar),
.contact-cell h3:lang(ar),
.notif .app-name:lang(ar),
.theme-tile .living:lang(ar),
.plan-badge:lang(ar),
.doc-prose th:lang(ar) {
  text-transform: none;
  letter-spacing: 0;
}

/* Amiri sits small on the line next to Jakarta at the same pixel size. */
.doc-prose p:lang(ar),
.doc-prose li:lang(ar),
.doc-prose td:lang(ar) {
  font-size: 17px;
  line-height: 1.9;
}

/*
 * Three facts in a grid that has room for two leaves a fourth cell, and because
 * the hairlines between the facts are the container showing through a 1px gap,
 * that empty cell reads as a fourth tile with nothing in it. Below the width
 * where three fit — the container falls under 450px at about 500px of viewport —
 * the row is pinned to two columns and the odd one out takes the full width.
 */
@media (max-width: 520px) {
  .facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .fact:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

/* ----------------------------------------------- selector, narrow screens */

@media (max-width: 560px) {
  /* The header keeps the wordmark and the one button at this width; the footer
     picker is the one that stays reachable, which is why it is there. */
  .lang-header {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
