/* =============================================================================
   Riibat — editorial monochrome. Dark default, light toggle. The dot mark lives
   on the fixed canvas behind the hero.

   TYPE — two voices, deliberately:
     · TITLES  -> CY Grotesk Wide (var(--display)). Opt-in, listed explicitly.
     · BODY/UI/BUTTONS -> Helvetica (var(--sans)). Inherited from <body>.
     · ARABIC  -> Thmanyah Serif Display, auto-selected by unicode-range.
   CY ships a SINGLE weight (400) and no bold cut, so `font-synthesis: none`
   stops the browser faking one — a smeared wide grotesk reads worse than none.
   On TITLES, hierarchy therefore comes from size/tracking/colour, never weight.
   Helvetica and Thmanyah both have real bolds, so body copy can still go bold.
============================================================================= */

@font-face {
  font-family: 'CY Grotesk';
  src: url('../fonts/cy-grotesk-wide-400.woff2') format('woff2'),
       url('../fonts/cy-grotesk-wide-400.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
/* Russian — Madiffure. Scoped by unicode-range to CYRILLIC ONLY, because the font
   has NO digits and NO punctuation (158 glyphs, letters only). Gating it this way
   means every comma, dash and numeral automatically falls through to CY Grotesk
   instead of vanishing, and Latin brand names (Riibat, Aniis) stay on CY too. */
@font-face {
  font-family: 'Madiffure';
  src: url('../fonts/madiffure-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0400-04FF, U+0500-052F, U+2DE0-2DFF, U+A640-A69F;
}

/* Arabic — Thmanyah Serif Display. Unlike CY it HAS a real bold, and it only ever
   renders Arabic ranges, so weight works normally here. */
@font-face {
  font-family: 'Thmanyah';
  src: url('../fonts/thmanyah-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Thmanyah';
  src: url('../fonts/thmanyah-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

:root {
  --bg: #08080a;
  --bg-2: #0e0e11;
  --fg: #f4f3f1;
  --fg-strong: #ffffff;
  --muted: #9b9a96;
  --faint: #6a6965;
  --line: rgba(255,255,255,.12);
  --line-strong: rgba(255,255,255,.22);
  --accent: #22C9E8;          /* electric cyan-blue */
  --accent-deep: #0FA8C6;

  /* TWO voices. CY Grotesk is a wide DISPLAY face — it sets titles. Body copy,
     UI and buttons stay on Helvetica, which is narrower, has a real bold, and
     reads far better at small sizes. 'Thmanyah' is listed first everywhere so
     Arabic picks it up automatically via its unicode-range. */
  --display: 'Thmanyah', 'Madiffure', 'CY Grotesk', 'Helvetica Neue', Helvetica, sans-serif;
  --sans: 'Thmanyah', 'Helvetica Neue', Helvetica, 'Inter', system-ui, Arial, sans-serif;
  --serif: 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
  /* technical/instrument voice for micro-labels */
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, 'JetBrains Mono', Menlo, Consolas, monospace;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --shell: clamp(1.4rem, 5vw, 6rem);
  --radius-banner: 28px;      /* rounded curves — banners */
  --radius-card: 20px;        /* rounded curves — tiles */
}
:root[data-theme="light"] {
  --bg: #ffffff;              /* clean white, so the black type snaps */
  --bg-2: #f4f4f5;
  --fg: #0e0e10;
  --fg-strong: #000000;
  --muted: #55555c;
  --faint: #8b8b93;
  --line: rgba(0,0,0,.13);
  --line-strong: rgba(0,0,0,.26);
  --accent: #0E7490;          /* deep cyan, holds on white */
  --accent-deep: #0A5566;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; font-synthesis: none; }

/* ---- The display face is opt-IN, and only titles opt in. ------------------- */
.hl, .h2, .p-title, .cs-name, .blog-hero h1, .statement__line, .soon,
.worklist__name, .p-work__n, .p-posts__t, .postcard__title, .feature__title,
.posts__title, .cs-beat__text h2, .cs-close h2, .browser__view h3, .menu__nav a,
.foot__brandline {
  font-family: var(--display);
}
html {
  -webkit-text-size-adjust: 100%;
  /* The orb deliberately hangs off the edge of the viewport. `overflow-x: hidden`
     on <body> alone does not contain it — the ICB still grows, which in RTL shoved
     the whole page sideways. `clip` on <html> contains it without creating a scroll
     container (so position:sticky/fixed still behave). */
  overflow-x: clip;
}
body {
  background: var(--bg); color: var(--fg); font-family: var(--sans); font-weight: 400;
  line-height: 1.5; overflow-x: hidden; min-height: 100vh; -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility; transition: background .6s var(--ease), color .6s var(--ease);
}
/* ---- Theme change: soft, slow crossfade ----------------------------------
   Custom properties don't transition, so flipping --bg/--fg used to snap. While
   `is-theming` is on, every element eases its colours instead. It is added only
   for the ~900ms of the switch, so it never taxes normal interaction. */
html.is-theming, html.is-theming *, html.is-theming *::before, html.is-theming *::after {
  transition: background-color .9s var(--ease), color .9s var(--ease),
              border-color .9s var(--ease), fill .9s var(--ease), opacity .9s var(--ease) !important;
}
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .7s; }

::selection { background: var(--accent); color: #fff; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 3px; }

/* Fine grain over everything (editorial) */
body::after {
  content: ''; position: fixed; inset: 0; z-index: 60; pointer-events: none; opacity: .5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
:root[data-theme="light"] body::after { opacity: .35; }

.skip-link { position: fixed; top: 12px; left: 12px; z-index: 300; background: var(--accent); color: #fff; padding: .6rem 1rem; border-radius: 8px; font-weight: 600; transform: translateY(-160%); transition: transform .3s var(--ease); }
.skip-link:focus { transform: none; }

/* ---- Stage ---------------------------------------------------------------- */
.stage { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 0; display: block; background: var(--bg); }
html.webgl-loading body { overflow: hidden; }
html.webgl-loading .site, html.webgl-loading main, html.webgl-loading .foot { opacity: 0; }
html.is-ready .site, html.is-ready main, html.is-ready .foot { opacity: 1; transition: opacity 1.3s var(--ease); }

/* ---- Boot ----------------------------------------------------------------- */
.boot { position: fixed; inset: 0; z-index: 200; display: grid; place-content: center; gap: 1.4rem; justify-items: center; background: var(--bg); transition: opacity .8s var(--ease), visibility .8s var(--ease); }
html.is-ready .boot { opacity: 0; visibility: hidden; }
.boot__ring { width: 42px; height: 42px; border-radius: 50%; border: 1.5px solid var(--line-strong); border-top-color: var(--accent); animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.boot__word { font-size: .72rem; letter-spacing: .5em; text-transform: lowercase; color: var(--faint); padding-left: .5em; }
@media (prefers-reduced-motion: reduce) { .boot__ring { animation: none; } }

/* ---- Header --------------------------------------------------------------- */
.site {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;   /* ABOVE panels */
  display: flex; align-items: center; justify-content: space-between; gap: 2rem;
  padding: clamp(1rem, 2.2vw, 1.6rem) var(--shell);
  transition: transform .45s var(--ease), opacity .35s var(--ease);
}
/* hide on scroll-down, return on scroll-up (never hidden inside a panel).
   `html.is-ready .site` sets opacity:1 at higher specificity, so the tuck has to
   out-specify it or the bar would slide up but stay fully opaque. */
html .site.is-tucked { transform: translateY(-115%); opacity: 0; }
body.panel-open .site { transform: none; opacity: 1; }
/* The supplied logo is the full lockup (mark + wordmark), trimmed to its
   content box — ratio 3.715:1. Set a height; the width follows. */
.brandmark { display: inline-flex; align-items: center; }
.brandmark__img { height: clamp(26px, 2.4vw, 32px); width: auto; display: block; }
.brandmark__img--light { display: none; }
:root[data-theme="light"] .brandmark__img--dark { display: none; }
:root[data-theme="light"] .brandmark__img--light { display: block; }
.brandmark--foot .brandmark__img { height: 34px; }

.nav { display: flex; gap: clamp(1.2rem, 2.4vw, 2.4rem); }
/* mono so the scramble/dot swap can't shift layout (equal advance widths) */
.nav a { font-family: var(--mono); white-space: nowrap; }
.nav a { font-size: .8rem; letter-spacing: .02em; color: var(--fg); position: relative; padding: .3rem 0; opacity: .82; transition: opacity .3s var(--ease); }
.nav a::after { content: ''; position: absolute; left: 0; bottom: 0; width: 0; height: 1px; background: var(--accent); transition: width .35s var(--ease); }
.nav a:hover { opacity: 1; } .nav a:hover::after { width: 100%; }
@media (max-width: 860px) { .nav { display: none; } }

.site__tools { display: flex; align-items: center; gap: .7rem; }

/* Sun / moon switch (no toggle track) */
.theme-toggle {
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--line-strong);
  background: transparent; color: var(--fg); cursor: pointer;
  transition: border-color .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); transform: rotate(18deg); }
.theme-toggle svg { width: 16px; height: 16px; display: block; }
.theme-toggle .i-sun { display: block; }     /* dark mode -> offer the sun */
.theme-toggle .i-moon { display: none; }
:root[data-theme="light"] .theme-toggle .i-sun { display: none; }
:root[data-theme="light"] .theme-toggle .i-moon { display: block; }

/* Language switcher */
.lang { position: relative; }
.lang__btn {
  display: inline-flex; align-items: center; gap: .4rem;
  height: 34px; padding: 0 .7rem; border-radius: 40px;
  border: 1px solid var(--line-strong); background: transparent;
  color: var(--fg); font-family: var(--mono); font-size: .72rem; letter-spacing: .1em;
  cursor: pointer; transition: border-color .3s var(--ease);
}
.lang__btn:hover { border-color: var(--accent); }
.lang__list {
  position: absolute; top: calc(100% + .5rem); right: 0; z-index: 120;
  min-width: 11rem; padding: .4rem; border-radius: 12px;
  border: 1px solid var(--line-strong); background: var(--bg);
  display: flex; flex-direction: column; gap: .1rem;
  box-shadow: 0 20px 50px -20px rgba(0,0,0,.5);
  /* drops open, rather than snapping into existence */
  opacity: 0; visibility: hidden;
  transform: translateY(-8px) scaleY(.96);
  transform-origin: top center;
  transition: opacity .28s var(--ease), transform .34s var(--ease), visibility .34s var(--ease);
}
.lang.is-open .lang__list { opacity: 1; visibility: visible; transform: none; }
.lang__list button { opacity: 0; transform: translateY(-6px); transition: opacity .3s var(--ease), transform .3s var(--ease), background .2s var(--ease); }
.lang.is-open .lang__list button { opacity: 1; transform: none; }
.lang.is-open .lang__list button:nth-child(1) { transition-delay: .04s; }
.lang.is-open .lang__list button:nth-child(2) { transition-delay: .07s; }
.lang.is-open .lang__list button:nth-child(3) { transition-delay: .10s; }
.lang.is-open .lang__list button:nth-child(4) { transition-delay: .13s; }
.lang.is-open .lang__list button:nth-child(5) { transition-delay: .16s; }
.lang.is-open .lang__list button:nth-child(6) { transition-delay: .19s; }
.lang__list button {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .55rem .7rem; border: none; border-radius: 8px; background: transparent;
  color: var(--fg); font-family: var(--mono); font-size: .82rem; cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.lang__list button:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.lang__list button[aria-current="true"] { color: var(--accent); }
.lang__code { font-size: .62rem; color: var(--faint); letter-spacing: .12em; }
@media (max-width: 860px) { .lang { display: none; } }

/* =============================================================================
   FULL-SCREEN section panels. Each carries its own --tone.
   Light: a very pale wash of the tone. Dark: a very deep wash of the tone.
============================================================================= */
.panel {
  --tone: #22C9E8;
  position: fixed; inset: 0; z-index: 150;
  width: 100vw; height: 100dvh;
  background: color-mix(in srgb, var(--tone) 12%, #06070b);
  color: var(--fg);
  opacity: 0; visibility: hidden;
  transition: opacity .55s var(--ease), visibility .55s var(--ease);
  overflow-y: auto; overscroll-behavior: contain;
  /* top padding clears the fixed top bar, which stays visible inside panels */
  padding: clamp(10rem, 19vh, 13rem) clamp(1.4rem, 6vw, 6rem) 6rem;  /* clears top bar + panel nav */
}
:root[data-theme="light"] .panel {
  background: color-mix(in srgb, var(--tone) 7%, #ffffff);
  color: #0e0e10;
}
.panel.is-open { opacity: 1; visibility: visible; }

/* The panel itself carries NO mask any more. It is a plain opaque surface; the
   dot transition is done by a separate solid-black curtain (see .curtain below),
   which fully covers the screen so you never glimpse the page underneath. */

/* the panel's own mutated orb, pulsing behind the content */
.panel__orb {
  position: fixed; right: -6vw; top: 50%; transform: translateY(-50%);
  width: min(70vw, 90vh); aspect-ratio: 1; z-index: 0;
  pointer-events: none; opacity: .55;
}
:root[data-theme="light"] .panel__orb { opacity: .45; }
.panel__body { position: relative; z-index: 2; max-width: 1200px; margin: 0 auto; }

/* Panel nav: Back on the left, Close on the right. The top bar stays visible. */
/* Back / Close float ABOVE the panel, not in its flow. As a sticky flow item they
   were being resolved against the panel's own scrollport and landing ON TOP of the
   first line of copy. Fixed, with the panel padded to clear them, they simply cannot
   collide — and they stay put while the panel scrolls, which is what sticky was for. */
.panel__nav {
  position: fixed; top: 5.4rem; left: clamp(1.4rem, 6vw, 6rem); right: clamp(1.4rem, 6vw, 6rem);
  z-index: 160;
  display: flex; align-items: center; justify-content: space-between;
  pointer-events: none;                        /* only the buttons are clickable */
}
.panel__nav > * { pointer-events: auto; }
.panel__btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .55rem 1rem; border-radius: 40px;
  border: 1px solid currentColor; background: transparent; color: inherit;
  font-family: var(--mono); font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
  opacity: .6; transition: opacity .25s var(--ease), color .25s var(--ease), gap .25s var(--ease);
}
.panel__btn:hover { opacity: 1; color: var(--tone); }
.panel__btn--back:hover { gap: .9rem; }
.panel__btn[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .panel { transition: none; }
}

/* --- panel typography ----------------------------------------------------- */
.p-eyebrow {
  font-family: var(--mono); font-size: clamp(.8rem, 1.1vw, .95rem); font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--tone);
  margin: 2.6rem 0 1rem;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 50%, transparent 51%);
  mask-image: radial-gradient(circle at 50% 50%, #000 50%, transparent 51%);
  -webkit-mask-size: 3px 3px; mask-size: 3px 3px;
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
}
.p-eyebrow:first-child { margin-top: 0; }
.p-title { font-size: clamp(1.55rem, 3.3vw, 2.8rem); letter-spacing: -.035em; line-height: 1.05; max-width: 16ch; }
.p-lead { font-size: clamp(1rem, 1.5vw, 1.3rem); margin-top: 1.6rem; max-width: 38ch; opacity: .9; }
.p-lead--center { max-width: 40ch; margin-inline: auto; text-align: center; }
.p-body { font-size: clamp(1rem, 1.4vw, 1.15rem); opacity: .72; line-height: 1.7; }
.p-cols { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 4rem); margin-top: 2rem; }
.p-kicker { margin-top: 3.5rem; font-family: var(--mono); font-size: .8rem; letter-spacing: .2em; text-transform: uppercase; color: var(--tone); }
@media (max-width: 800px) { .p-cols { grid-template-columns: 1fr; } }

/* --- images / media ---------------------------------------------------------
   One shared shape language: banners are 16:9 with --radius-banner, tiles are
   square with --radius-card. Everything is capped so nothing ever runs long or
   wide across a big screen. Images fade up as they decode (no pop-in). ------ */
.p-figure { margin: 0; }
.p-figure img, .p-tile img, .p-banner img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.p-figure img.is-loaded, .p-tile img.is-loaded, .p-banner img.is-loaded { opacity: 1; }

/* Banner — the one big image per section. Capped so it never goes wide-screen. */
.p-banner {
  position: relative; margin: 2.2rem 0 0; max-width: 860px;
  aspect-ratio: 16 / 9; border-radius: var(--radius-banner); overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--tone) 26%, transparent);
  background: color-mix(in srgb, var(--tone) 8%, transparent);
  box-shadow: 0 30px 80px -40px rgba(0,0,0,.7);
}
.p-banner__cap {
  position: absolute; left: 1.2rem; bottom: 1.1rem; z-index: 2;
  padding: .45rem .85rem; border-radius: 40px;
  background: rgba(6,7,11,.55); backdrop-filter: blur(10px);
  color: #fff; font-family: var(--mono); font-size: .64rem;
  letter-spacing: .16em; text-transform: uppercase;
}

/* Tiles — small, square, consistent. Never more than 4 across. */
.p-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem;
  margin-top: 1.2rem; max-width: 860px;
}
.p-grid--3 { grid-template-columns: repeat(3, 1fr); }
.p-tile {
  position: relative; aspect-ratio: 1 / 1; border-radius: var(--radius-card); overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--tone) 22%, transparent);
  background: color-mix(in srgb, var(--tone) 8%, transparent);
  transition: transform .5s var(--ease), border-color .5s var(--ease);
}
.p-tile:hover { transform: translateY(-4px); border-color: var(--tone); }
.p-tile:hover img { transform: scale(1.05); }
/* --- Withheld projects: the thumb carries the riibat orb MARK --------------
   Projects 03/04/05 have no imagery, so instead of a blank wash their thumb
   shows the mark itself — the group standing in for the company that has not
   been named yet. One rule drives every withheld thumb on the site. --------- */
.p-tile--held,
.worklist__t--held,
.p-work__t:empty {
  position: relative;
  border-style: dashed;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: .72rem; letter-spacing: .18em; color: var(--tone);
}
.p-tile--held::after,
.worklist__t--held::after,
.p-work__t:empty::after {
  content: '';
  position: absolute; inset: 0;
  background: url('../brand/mark-white.png') center / 58% no-repeat;
  opacity: .30;
  transition: opacity .4s var(--ease);
}
:root[data-theme="light"] .p-tile--held::after,
:root[data-theme="light"] .worklist__t--held::after,
:root[data-theme="light"] .p-work__t:empty::after {
  background-image: url('../brand/mark-black.png');
  opacity: .34;
}
.worklist a:hover .worklist__t--held::after,
.p-work button:hover .p-work__t:empty::after { opacity: .62; }
.p-tile--held span { position: relative; z-index: 1; opacity: .7; }

/* A COMING SOON panel drops its reading column (see .panel__body:has(.soon)), so
   media inside one needs its own centred column back. */
.p-hold { max-width: 860px; margin-inline: auto; }
.p-hold .p-banner, .p-hold .p-grid { margin-inline: auto; }
.p-eyebrow--center { text-align: center; }
.p-body--center { max-width: 54ch; margin: 2.4rem auto 0; text-align: center; }
.p-kicker--center { text-align: center; }

@media (max-width: 800px) {
  .p-grid, .p-grid--3 { grid-template-columns: 1fr 1fr; }
  .p-banner { max-width: none; }
}

/* --- work list inside a panel --------------------------------------------- */
.p-work { list-style: none; margin-top: 2.5rem; }
.p-work button {
  width: 100%; display: grid; grid-template-columns: 2.4rem 64px 13rem 1fr auto; gap: 1.4rem; align-items: center;
  padding: 1.1rem 0; background: transparent; border: none; border-top: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  color: inherit; text-align: left; cursor: pointer; transition: color .3s var(--ease), padding-left .3s var(--ease);
}
.p-work li:last-child button { border-bottom: 1px solid color-mix(in srgb, currentColor 16%, transparent); }
.p-work button:hover { color: var(--tone); padding-left: .6rem; }
.p-work button:hover .p-work__t img { transform: scale(1.08); }
.p-work__i { font-family: var(--mono); font-size: .78rem; opacity: .5; }
/* 64px square thumb. The three withheld projects have no image yet, so they get
   a tone wash instead — same shape, so the row rhythm never breaks. */
.p-work__t {
  width: 64px; height: 64px; border-radius: 14px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--tone) 26%, transparent);
  background: color-mix(in srgb, var(--tone) 12%, transparent);
}
.p-work__t img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .6s var(--ease), transform .6s var(--ease); }
.p-work__t img.is-loaded { opacity: 1; }
.p-work__n { font-size: clamp(1.2rem, 2vw, 1.7rem); letter-spacing: -.02em; white-space: nowrap; }
.p-work__d { opacity: .6; font-size: .95rem; }
.p-work__s { font-family: var(--mono); font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; color: var(--tone); }
@media (max-width: 800px) {
  .p-work button { grid-template-columns: 48px 1fr auto; gap: 1rem; }
  .p-work__d, .p-work__i { display: none; }
  .p-work__t { width: 48px; height: 48px; border-radius: 12px; }
}

/* --- COMING SOON: full screen width, dot font, pulsing -------------------- */
/* let it escape the reading column and use the whole laptop screen */
.panel__body:has(.soon) { max-width: none; }
.soon {
  margin: 10vh 0 0; text-align: center;
  letter-spacing: -.02em; line-height: 1;
  font-size: clamp(1.7rem, 8.6vw, 10rem);        /* fills the screen width */
  white-space: nowrap; color: var(--tone);
  -webkit-text-stroke: .022em currentColor;      /* no bold cut — see dot-font note */
  paint-order: stroke fill;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 50%, transparent 51%);
  mask-image: radial-gradient(circle at 50% 50%, #000 50%, transparent 51%);
  -webkit-mask-size: 7px 7px; mask-size: 7px 7px;
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
  animation: soonPulse 3.4s ease-in-out infinite;
}
@keyframes soonPulse { 0%,100% { opacity: .38; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .soon { animation: none; opacity: .9; } }

/* --- Aniis showcase: browser + app ---------------------------------------- */
.browser {
  margin-top: 1.5rem; border-radius: 14px; overflow: hidden;
  border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  background: color-mix(in srgb, var(--tone) 10%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.browser__bar { display: flex; align-items: center; gap: .4rem; padding: .7rem 1rem; border-bottom: 1px solid color-mix(in srgb, currentColor 14%, transparent); }
.browser__bar i { width: 9px; height: 9px; border-radius: 50%; background: color-mix(in srgb, currentColor 28%, transparent); }
.browser__bar span { margin-left: 1rem; font-family: var(--mono); font-size: .7rem; opacity: .6; }
.browser__view { padding: clamp(2rem, 6vw, 5rem) 2rem; text-align: center; }
.browser__eyebrow { font-family: var(--mono); font-size: .7rem; letter-spacing: .2em; text-transform: uppercase; color: var(--tone); }
.browser__view h3 { font-size: clamp(1.7rem, 4vw, 3rem); font-weight: 800; letter-spacing: -.04em; margin: .8rem 0; }
.browser__view h3 span { color: var(--tone); }
.browser__view p { opacity: .7; }
.browser__cta { display: inline-block; margin-top: 1.4rem; padding: .7rem 1.4rem; border-radius: 40px; background: var(--tone); color: #10100f; font-weight: 600; font-size: .9rem; }

.p-app { display: grid; grid-template-columns: auto 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; margin-top: 1.5rem; }
.p-feat { list-style: none; display: grid; gap: 1.2rem; }
.p-feat li { display: grid; grid-template-columns: 2.2rem 1fr; gap: .2rem 1rem; padding-bottom: 1.2rem; border-bottom: 1px solid color-mix(in srgb, currentColor 14%, transparent); }
.p-feat b { grid-row: span 2; font-family: var(--mono); color: var(--tone); font-size: .9rem; }
.p-feat strong { font-size: 1.15rem; font-weight: 700; }
.p-feat span { opacity: .65; font-size: .95rem; }
@media (max-width: 860px) { .p-app { grid-template-columns: 1fr; } }

/* Contact: label on top, value stacked BELOW it */
.p-contact { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.5rem; margin-top: 2.5rem; }
.p-contact > div { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; }
.p-contact .p-eyebrow { margin: 0; }
.p-contact a, .p-contact span:not(.p-eyebrow) { font-size: clamp(1rem, 1.4vw, 1.2rem); line-height: 1.5; }
.p-contact a:hover { color: var(--tone); }
@media (max-width: 760px) { .p-contact { grid-template-columns: 1fr; } }

/* Contact form */
.p-form { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; margin-top: 1.5rem; max-width: 46rem; }
.p-form .full { grid-column: 1 / -1; }
.p-field { display: flex; flex-direction: column; gap: .5rem; }
.p-field label {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  opacity: .6;
}
.p-field input, .p-field textarea, .p-field select {
  width: 100%; padding: .9rem 1rem; border-radius: 10px;
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  background: color-mix(in srgb, var(--tone) 6%, transparent);
  color: inherit; font-family: var(--sans); font-size: 1rem;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
.p-field textarea { min-height: 8rem; resize: vertical; }
.p-field input:focus, .p-field textarea:focus, .p-field select:focus {
  outline: none; border-color: var(--tone);
  background: color-mix(in srgb, var(--tone) 12%, transparent);
}
.p-submit {
  justify-self: start; margin-top: .4rem;
  padding: .95rem 1.8rem; border-radius: 40px; border: none; cursor: pointer;
  background: var(--tone); color: #0b0b0d; font-weight: 700; font-size: .95rem;
  transition: transform .25s var(--ease), filter .25s var(--ease);
}
.p-submit:hover { transform: translateY(-2px); filter: brightness(1.08); }
.p-note {
  grid-column: 1 / -1; font-family: var(--mono); font-size: .72rem; letter-spacing: .06em;
  opacity: .55; margin-top: .2rem;
}
.p-note.is-sent { color: var(--tone); opacity: 1; }
@media (max-width: 760px) { .p-form { grid-template-columns: 1fr; } }

/* Blog inside a panel — each post carries a small 16:9 cover, same radius as
   the tiles so the shape language holds across every section. */
.p-posts { list-style: none; margin-top: 2.5rem; max-width: 860px; }
.p-posts li a {
  display: grid; grid-template-columns: 132px 5.5rem 1fr auto; gap: 1.4rem; align-items: center;
  padding: 1.1rem 0; border-top: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  transition: color .3s var(--ease), padding-left .3s var(--ease);
}
.p-posts li:last-child a { border-bottom: 1px solid color-mix(in srgb, currentColor 16%, transparent); }
.p-posts li a:hover { color: var(--tone); padding-left: .6rem; }
.p-posts li a:hover .p-posts__c img { transform: scale(1.06); }
.p-posts__c {
  width: 132px; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--tone) 24%, transparent);
  background: color-mix(in srgb, var(--tone) 10%, transparent);
}
.p-posts__c img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .6s var(--ease), transform .6s var(--ease); }
.p-posts__c img.is-loaded { opacity: 1; }
.p-posts__d { font-family: var(--mono); font-size: .72rem; opacity: .55; letter-spacing: .1em; }
.p-posts__t { font-size: clamp(1.05rem, 1.9vw, 1.45rem); letter-spacing: -.02em; }
.p-posts__k { font-family: var(--mono); font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; color: var(--tone); }
@media (max-width: 760px) {
  .p-posts li a { grid-template-columns: 92px 1fr; gap: .9rem 1rem; }
  .p-posts__c { width: 92px; }
  .p-posts__d, .p-posts__k { display: none; }
}
.menu-btn { display: none; flex-direction: column; gap: 4px; width: 30px; height: 30px; align-items: center; justify-content: center; background: transparent; border: none; cursor: pointer; }
.menu-btn i { width: 20px; height: 1.5px; background: var(--fg); }
@media (max-width: 860px) { .menu-btn { display: flex; } }

/* ---- Menu ----------------------------------------------------------------- */
.menu { margin: 0; padding: 0; border: none; width: 100vw; height: 100vh; max-width: 100vw; max-height: 100vh; background: var(--bg); color: var(--fg); }
.menu::backdrop { background: rgba(0,0,0,.5); }
.menu[open] { display: flex; flex-direction: column; padding: var(--shell); }
.menu__close { align-self: flex-end; background: none; border: 1px solid var(--line-strong); color: var(--fg); padding: .5rem 1rem; border-radius: 40px; font-size: .72rem; letter-spacing: .2em; text-transform: uppercase; cursor: pointer; }
.menu__nav { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 1rem; }
.menu__nav a { display: flex; align-items: baseline; gap: 1rem; font-size: clamp(1.7rem, 5.6vw, 2.8rem); letter-spacing: -.03em; }
.menu__nav a span { font-size: .8rem; color: var(--accent); font-weight: 400; }
.menu__foot { color: var(--faint); line-height: 1.7; }

/* ---- Hero (transparent — the knot shows through) -------------------------- */
.hero { position: relative; min-height: 100vh; display: flex; align-items: center; padding: 0 var(--shell); }
.hero__inner { position: relative; z-index: 2; max-width: 52rem; }
.eyebrow { font-size: .72rem; font-weight: 500; letter-spacing: .28em; text-transform: uppercase; color: var(--accent); margin-bottom: 1.6rem; }
.hl { font-size: clamp(2.1rem, 5.4vw, 5rem); font-weight: 800; letter-spacing: -.045em; line-height: .9; color: var(--fg-strong); }
.hero__sub { max-width: 34rem; margin-top: 1.8rem; color: var(--muted); font-size: clamp(1.05rem, 1.6vw, 1.35rem); line-height: 1.45; }
.btn { display: inline-flex; align-items: center; gap: .6rem; margin-top: 2.2rem; padding: .85rem 1.5rem; border-radius: 40px; border: 1px solid var(--line-strong); font-size: .85rem; letter-spacing: .02em; color: var(--fg); transition: gap .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease); }
.btn:hover { gap: 1rem; border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
/* ---- The floating halftone loop -------------------------------------------
   Transparent asset only. Never place a background plate behind it.
   Motion: ~21s rotation capped at 8deg, 14px vertical drift, 6px pointer
   parallax, ease-in-out, paused when the tab is hidden.
--------------------------------------------------------------------------- */
.loop {
  position: absolute; z-index: 1; pointer-events: none;
  right: 0; top: 50%;
  /* bigger again — the dot count was raised so the dots themselves stay small */
  width: min(92vw, 108vh, 1450px); aspect-ratio: 1;
  /* parallax lives here (JS sets --px/--py, capped at 6px) */
  transform: translate3d(var(--px, 0px), calc(-50% + var(--py, 0px)), 0);
  transition: transform .8s cubic-bezier(.4, 0, .2, 1);
}
/* The bead canvas. Rotation happens in 3D, so CSS only carries the drift. */
.loop__canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; display: none;
  animation: loopDrift 21s ease-in-out infinite;
  will-change: transform;
}
.loop.is-3d .loop__canvas { display: block; }
/* Flat fallback — ONLY when WebGL genuinely fails (.loop.is-flat, set by
   experience.js). It is hidden by default: it used to be display:block until boot()
   finished, which flashed the full lockup on every single page load.
   It is also the MARK, never the wordmark — the hero object is the mark. */
.loop__img { display: none; }
.loop.is-flat .loop__img--dark {
  display: block;
  width: 100%; height: 100%; object-fit: contain;
  animation: loopFloat 21s ease-in-out infinite;
  will-change: transform;
}
:root[data-theme="light"] .loop.is-flat .loop__img--dark { display: none; }
:root[data-theme="light"] .loop.is-flat .loop__img--light {
  display: block;
  width: 100%; height: 100%; object-fit: contain;
  animation: loopFloat 21s ease-in-out infinite;
}

@keyframes loopDrift {
  0%   { transform: translateY(-7px); }
  50%  { transform: translateY(7px); }
  100% { transform: translateY(-7px); }
}
@keyframes loopFloat {
  0%   { transform: rotate(-4deg) translateY(-7px); }
  50%  { transform: rotate(4deg)  translateY(7px); }
  100% { transform: rotate(-4deg) translateY(-7px); }
}
/* pause when the tab is hidden */
html.is-hidden .loop__img,
html.is-hidden .loop__canvas { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .loop { transition: none; transform: translate3d(0, -50%, 0); }
  .loop__img { animation: none; transform: rotate(-4deg); }  /* fixed three-quarter */
  .loop__canvas { animation: none; }
}
@media (max-width: 860px) {
  .hero { flex-direction: column; justify-content: center; padding: 18vh var(--shell) 8vh; }
  .loop { position: relative; right: auto; top: auto; transform: none; width: min(76vw, 400px); margin: 0 auto 2.5rem; order: 1; }
  .loop__img { animation-duration: 24s; }
  .hero__inner { order: 2; }
}

.hero__meta { position: absolute; display: flex; flex-direction: column; gap: .2rem; font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); z-index: 2; }
.hero__meta--tl { top: auto; bottom: 7vh; left: var(--shell); }
.hero__meta--br { bottom: 7vh; right: var(--shell); text-align: right; }
@media (max-width: 860px) { .hero__meta { display: none; } .hero { text-align: left; } }

/* ---- The site-wide dot substrate (one nervous system) ---------------------- */
.field {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  z-index: 0; display: block; pointer-events: none;
  /* The hero already has the orb — keep the substrate out of it. */
  opacity: 0; transition: opacity .9s var(--ease);
}
body.past-hero .field { opacity: 1; }

/* ---- Statement (replaces the analytics row) ------------------------------- */
.statement {
  position: relative; z-index: 2;
  min-height: 92vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: 2rem; padding: clamp(4rem, 10vh, 8rem) var(--shell);
  border-top: 1px solid var(--line);
}
.statement__line {
  font-size: clamp(1.25rem, 2.4vw, 2.1rem);
  font-weight: 700; letter-spacing: -.03em; line-height: 1.2;
  color: var(--fg-strong);
  max-width: none; white-space: nowrap;      /* exactly two lines */
}
@media (max-width: 760px) { .statement__line { white-space: normal; font-size: clamp(1.4rem, 6vw, 2rem); } }
.statement__k { color: var(--accent); font-variant-numeric: tabular-nums; }

/* ---- Sections (transparent — the substrate breathes through) --------------- */
.section { position: relative; z-index: 2; background: transparent; border-top: 1px solid var(--line); padding: clamp(4.5rem, 12vh, 9rem) var(--shell); }
.section__head { display: flex; align-items: baseline; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-bottom: clamp(2.5rem, 6vh, 4.5rem); }
.label { font-size: .68rem; font-weight: 500; letter-spacing: .26em; text-transform: uppercase; color: var(--accent); }
.section__note { color: var(--muted); max-width: 26rem; font-size: .95rem; }
.h2 { font-size: clamp(1.5rem, 2.9vw, 2.25rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.04; color: var(--fg-strong); }

/* About */
.about__grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(2rem, 5vw, 5rem); align-items: start; }
.about__body p { color: var(--muted); font-size: clamp(1rem, 1.4vw, 1.15rem); line-height: 1.7; max-width: 34rem; }
.about__body p + p { margin-top: 1.2rem; }
.about__body [lang="ar"] { color: var(--accent); font-size: 1.15em; }
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; margin-top: clamp(3rem, 7vh, 5rem); border-top: 1px solid var(--line); padding-top: 2.4rem; }
.stat-row div { display: flex; flex-direction: column; gap: .4rem; }
.stat-row strong { font-size: clamp(1.8rem, 3.5vw, 2.8rem); font-weight: 700; letter-spacing: -.03em; color: var(--fg-strong); }
.stat-row span { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
@media (max-width: 760px) { .about__grid { grid-template-columns: 1fr; } .stat-row { grid-template-columns: 1fr 1fr; } }

/* Work list */
.worklist { list-style: none; display: flex; flex-direction: column; }
.worklist a { display: grid; grid-template-columns: 2.4rem 72px 13.5rem 1fr auto auto; align-items: center; gap: 1.4rem; padding: 1.1rem 0; border-top: 1px solid var(--line); position: relative; transition: color .3s var(--ease); }
.worklist li:last-child a { border-bottom: 1px solid var(--line); }
.worklist a::before { content: ''; position: absolute; left: -.6rem; top: 50%; transform: translateY(-50%); width: 0; height: 8px; border-radius: 4px; background: var(--brand); box-shadow: 0 0 12px var(--brand); transition: width .35s var(--ease); }
.worklist a:hover { color: var(--fg-strong); }
.worklist a:hover::before { width: 8px; }
.worklist__idx { font-size: .72rem; color: var(--faint); letter-spacing: .1em; }
/* Same 1:1 rounded thumb as the panel work list — one shape language throughout. */
.worklist__t {
  width: 72px; height: 72px; border-radius: 16px; overflow: hidden;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--brand) 12%, transparent);
  transition: border-color .35s var(--ease);
}
.worklist__t img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .6s var(--ease), transform .6s var(--ease); }
.worklist__t img.is-loaded { opacity: 1; }
.worklist__t--held { border-style: dashed; }
.worklist a:hover .worklist__t { border-color: var(--brand); }
.worklist a:hover .worklist__t img { transform: scale(1.07); }
.worklist__name { font-size: clamp(1.3rem, 2.2vw, 1.8rem); letter-spacing: -.02em; color: var(--fg-strong); white-space: nowrap; }
.worklist__desc { color: var(--muted); font-size: .95rem; }
.worklist__status { font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; color: var(--brand); }
.worklist__go { font-size: .78rem; color: var(--faint); opacity: 0; transform: translateX(-8px); transition: opacity .3s var(--ease), transform .3s var(--ease); }
.worklist a:hover .worklist__go { opacity: 1; transform: none; }
@media (max-width: 860px) {
  .worklist a { grid-template-columns: 56px 1fr auto; gap: 1rem; }
  .worklist__idx, .worklist__desc, .worklist__go { display: none; }
  .worklist__t { width: 56px; height: 56px; border-radius: 14px; }
}
@media (max-width: 860px) { .worklist a { grid-template-columns: 2rem 1fr auto; gap: 1rem; } .worklist__desc, .worklist__go { display: none; } }

/* Contact */
.contact__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: end; }
.contact__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; }
.contact__cols > div { display: flex; flex-direction: column; gap: .6rem; }
.contact__cols a, .contact__cols span:not(.label) { font-size: 1.05rem; color: var(--fg); }
.contact__cols a:hover { color: var(--accent); }
@media (max-width: 760px) { .contact__grid { grid-template-columns: 1fr; } }

/* ---- Footer ----------------------------------------------------------------
   Directory-style: brand + reach on the left, three link columns, socials, then
   a newsletter row. (Partners block deliberately omitted.) ------------------ */
.foot {
  position: relative; z-index: 2; background: var(--bg-2);
  border-top: 1px solid var(--line);
  padding: clamp(3.5rem, 8vh, 6rem) var(--shell) 2rem;
}
.foot__grid {
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: clamp(2rem, 4vw, 4rem);
  max-width: 1320px; margin: 0 auto; align-items: start;
}
.brandmark--foot .brandmark__img { height: 34px; }

.foot__brand { display: flex; flex-direction: column; gap: .55rem; }
.foot__blurb { color: var(--muted); font-size: .9rem; line-height: 1.6; max-width: 28ch; margin-top: 1rem; }
.foot__line { font-size: .9rem; color: var(--muted); margin-top: .1rem; }
.foot__line a { transition: color .3s var(--ease); }
.foot__line a:hover { color: var(--accent); }
.foot__line--addr { max-width: 24ch; line-height: 1.5; }
.foot__sublabel { margin-top: 1.6rem; }
.foot__cov { font-size: .85rem; color: var(--muted); }
.foot__cov b { color: var(--fg); font-weight: 400; }
.foot__cov span { color: var(--faint); }

.foot__col { display: flex; flex-direction: column; gap: .75rem; }
.foot__col .label { margin-bottom: .4rem; }
.foot__col a { font-size: .9rem; color: var(--muted); transition: color .3s var(--ease); width: fit-content; }
.foot__col a:hover { color: var(--accent); }

.foot__social { list-style: none; display: flex; gap: 1rem; margin-top: 1.8rem; }
.foot__social a { display: grid; place-items: center; width: 22px; height: 22px; color: var(--muted); }
.foot__social a:hover { color: var(--accent); }
.foot__social svg { width: 20px; height: 20px; }
.foot__handle { margin-top: .9rem; font-family: var(--mono); font-size: .78rem; letter-spacing: .08em; color: var(--faint); }

/* newsletter */
.foot__news {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 4rem); align-items: start;
  max-width: 1320px; margin: clamp(3rem, 7vh, 5rem) auto 0;
  padding-top: clamp(2rem, 4vh, 3rem); border-top: 1px solid var(--line);
}
.foot__brandline { font-size: 1.15rem; letter-spacing: -.01em; color: var(--fg-strong); }
.foot__news .foot__blurb { margin-top: .5rem; }
.foot__sub-row { display: flex; gap: .7rem; }
.foot__sub input[type="email"] {
  flex: 1; padding: .85rem 1.2rem; border-radius: 40px;
  border: 1px solid var(--line-strong); background: transparent; color: inherit;
  font-family: var(--sans); font-size: .9rem;
  transition: border-color .25s var(--ease);
}
.foot__sub input[type="email"]:focus { outline: none; border-color: var(--accent); }
.foot__sub-btn {
  padding: .85rem 1.6rem; border-radius: 40px; border: none; cursor: pointer;
  background: var(--fg); color: var(--bg); font-size: .9rem; white-space: nowrap;
  transition: filter .25s var(--ease), transform .25s var(--ease);
}
.foot__sub-btn:hover { transform: translateY(-1px); filter: brightness(.9); }
.foot__consent { display: flex; gap: .6rem; margin-top: 1rem; font-size: .78rem; color: var(--faint); line-height: 1.5; }
.foot__consent input { margin-top: .18rem; accent-color: var(--accent); }
.foot__consent a { text-decoration: underline; }
.foot__note { margin-top: .7rem; font-family: var(--mono); font-size: .72rem; color: var(--accent); }

.foot__base {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem;
  max-width: 1320px; margin: clamp(2.5rem, 6vh, 4rem) auto 0;
  padding-top: 1.6rem; border-top: 1px solid var(--line);
  font-size: .72rem; letter-spacing: .06em; color: var(--faint);
}

@media (max-width: 1040px) {
  .foot__grid { grid-template-columns: 1fr 1fr; row-gap: 3rem; }
  .foot__brand { grid-column: 1 / -1; }
}
@media (max-width: 700px) {
  .foot__grid { grid-template-columns: 1fr; }
  .foot__news { grid-template-columns: 1fr; }
  .foot__sub-row { flex-direction: column; }
  .foot__sub-btn { width: 100%; }
}

/* ---- No-WebGL ------------------------------------------------------------- */
html.no-webgl .stage { background: radial-gradient(50% 55% at 62% 42%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 70%), var(--bg); }
html.no-webgl .boot { display: none; }

/* ---- Instrument voice: micro-labels go mono (reads technical, not agency) -- */
.eyebrow, .label, .hero__meta, .worklist__idx, .worklist__status,
.foot__base, .posts__date, .posts__tag, .cs-endorse, .cs-status,
.cs-statelist, .stat-row span, .meta, .chrome__status, .future-meta {
  font-family: var(--mono);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.eyebrow, .label { letter-spacing: .22em; }
.worklist__status, .posts__tag, .cs-status { letter-spacing: .14em; }

/* ---- The dot font. Renders the SAME word as a dot matrix (Nothing-style) —
       the text stays readable, it is never replaced by dots.

       The mask punches a dot grid out of the glyphs, so it needs FAT strokes to
       bite into — thin ones shatter into unreadable crumbs. We used to get that
       fat from font-weight: 700/800. CY Grotesk has no bold cut, so we grow the
       stroke outward with -webkit-text-stroke instead; being in `em` it scales
       with the type. This is the only reason text-stroke appears in this file.
------------------------------------------------------------------------- */
.dot-font,
.label, .eyebrow {
  -webkit-text-stroke: .042em currentColor;
  paint-order: stroke fill;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 53%);
  mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 53%);
  -webkit-mask-size: 3px 3px;
  mask-size: 3px 3px;
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
}
.label, .eyebrow {
  font-size: clamp(.95rem, 1.5vw, 1.15rem);
  letter-spacing: .18em;
  color: var(--accent);
}
/* ---- THE CURTAIN --------------------------------------------------------
   ONE transition, TWO modes:

     .curtain             FADE — between sections. A quiet dip to the page colour.
     .curtain--dots       ARRIVAL — going home, and changing language.

   The arrival used to fill the whole screen with a dot grid, which was too much to
   look at. It is now CLEAN SPACE — just the page colour — with the mark standing
   large in the middle, breathing. The mark is itself made of halftone dots, so the
   dot language is still there; it just isn't shouting.

   Opacity/transform only. An animated mask is what made the very first version
   stutter, and it must not come back.
------------------------------------------------------------------------- */
.curtain {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center;
  background: var(--bg);                        /* clean: white in light, ink in dark */
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .45s var(--ease), visibility .45s var(--ease);
  will-change: opacity;
}
.curtain.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

/* The mark — the whole of the arrival screen.
   It does not rotate, it does not scale, it does not move. It sits still in the
   middle and simply resolves. The wrapper is kept only so the sizing lives in one
   place (and so nothing is ever tempted to put two transform animations on one
   element again — the last one silently wins). */
.curtain__orb {
  position: relative; z-index: 1;
  display: none;
  width: clamp(88px, 11vw, 150px);              /* small, quiet */
}
.curtain--dots .curtain__orb { display: block; }

.curtain__mark {
  display: block; width: 100%; height: auto;
  opacity: 0;
  will-change: opacity;
}
.curtain--dots.is-on .curtain__mark {
  animation: orbIn .45s var(--ease) forwards;   /* fade only — no transform at all */
}

@keyframes orbIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* the mark is white artwork; on the light surface it has to invert */
:root[data-theme="light"] .curtain__mark { filter: invert(1); }

/* A single soft ring of light behind it, so the empty screen has a centre of
   gravity. Cheap: one gradient, no mask, no repaint. */
.curtain__dots {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 50%,
              color-mix(in srgb, var(--fg) 7%, transparent) 0%,
              transparent 42%);
  opacity: 0;
  transition: opacity .45s var(--ease);
}
.curtain--dots.is-on .curtain__dots { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .curtain { transition: none; }
  .curtain--dots.is-on .curtain__mark { animation: none; opacity: 1; }
}

/* ---- Section to section: the copy DISSOLVES, nothing else moves -------------
   Moving between siblings used to raise the whole curtain, which was far more than
   the moment deserved. Now the outgoing copy dissolves, the new copy is swapped in
   underneath, and it pulls back up into place. The panel, the orb and the top bar
   never flinch. */
.panel__body { transition: opacity .26s var(--ease), transform .26s var(--ease); }
.panel__body.is-leaving {
  opacity: 0;
  transform: translateY(-10px);
}
/* the children must not run their entry animation while the body is on its way out */
.panel__body.is-leaving > * { animation: none !important; }

/* Incoming panel copy pulls up into place. */
@keyframes pullIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
.panel__body > * { animation: pullIn .75s var(--ease) both; }
.panel__body > *:nth-child(1) { animation-delay: .02s; }
.panel__body > *:nth-child(2) { animation-delay: .08s; }
.panel__body > *:nth-child(3) { animation-delay: .14s; }
.panel__body > *:nth-child(4) { animation-delay: .20s; }
.panel__body > *:nth-child(5) { animation-delay: .26s; }
.panel__body > *:nth-child(6) { animation-delay: .32s; }
.panel__body > *:nth-child(n+7) { animation-delay: .38s; }

@media (prefers-reduced-motion: reduce) {
  .curtain, .curtain__dots, .curtain__mark { transition: none; }
  .panel__body > * { animation: none; }
}

/* ---- Buttons go DOTTED on hover ------------------------------------------
   Masking a button's whole box would eat its border and background too, so the
   dot matrix is applied to the LABEL only, via a wrapper span the JS injects.
   Buttons stay on Helvetica (never the display face) — the founder's call. --- */
.btn, .p-submit, .panel__btn, .browser__cta, .menu__close, .lang__btn, .cs-back, .foot__sub-btn, .foot__totop {
  font-family: var(--sans);
}
.btn-dots {
  display: inline-block;
  transition: -webkit-mask-size .35s var(--ease);
}
/* HOVER ONLY. `:focus-visible` was leaving a button dotted after it had been
   clicked, with the pointer nowhere near it — the focus ring is the affordance for
   keyboard users, not the dot font. */
:is(.btn, .p-submit, .panel__btn, .browser__cta, .menu__close, .cs-back, .foot__sub-btn, .foot__totop):hover .btn-dots {
  /* Button labels are small (~13px, cap height ~10px). A 3px dot grid left barely
     three dots per stroke, which read as mush. A 2px grid with a fatter fill and a
     heavier stroke keeps the WORD legible while still reading as dots. */
  -webkit-text-stroke: .07em currentColor;
  paint-order: stroke fill;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 62%, transparent 63%);
  mask-image: radial-gradient(circle at 50% 50%, #000 62%, transparent 63%);
  -webkit-mask-size: 2px 2px; mask-size: 2px 2px;
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
}
@media (prefers-reduced-motion: reduce) {
  .btn-dots { -webkit-mask-image: none !important; mask-image: none !important; }
}

/* Set by dotHover() once it has measured the word — a pinned box that a mid-shuffle
   glyph can never grow out of, so hovering fast can never push text to a 2nd line. */
.dot-lock {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  vertical-align: bottom;
}
/* Big words carry a proportionally heavier stroke so the grid stays visible */
.worklist__name.dot-font, .hl.dot-font, .p-title.dot-font { -webkit-text-stroke: .03em currentColor; }
/* Keep everything legible if the browser can't do masks */
@supports not (mask-size: 3px 3px) {
  .dot-font, .label, .eyebrow { -webkit-mask-image: none; mask-image: none; }
}

/* ---- Reveal (JS adds .is-lit) --------------------------------------------- */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 1s var(--ease), transform 1.1s var(--ease); }
.reveal.is-lit { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1 !important; transform: none !important; } * { animation-duration: .001ms !important; } }

/* =============================================================================
   Work — case-study pages (brand-tinted, no fixed canvas)
============================================================================= */
body.work {
  background:
    radial-gradient(58% 48% at 74% 16%, color-mix(in srgb, var(--brand) 16%, transparent), transparent 60%),
    var(--bg);
}
.work-hero { position: relative; min-height: 86vh; display: flex; align-items: center; padding: 18vh var(--shell) 8vh; }
.work-hero__inner { max-width: 54rem; }
.cs-endorse { display: inline-flex; align-items: center; gap: .5rem; margin-bottom: 1.8rem; padding: .5rem 1rem; border-radius: 40px; border: 1px solid var(--line-strong); font-size: .64rem; letter-spacing: .22em; text-transform: uppercase; color: var(--accent); }
.cs-endorse i { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 10px var(--brand); }
.cs-name { font-size: clamp(2.2rem, 7vw, 5.2rem); font-weight: 800; letter-spacing: -.045em; line-height: .9; color: var(--fg-strong); }
.cs-name span { color: var(--brand); }
.cs-sub { max-width: 34rem; margin-top: 1.6rem; font-size: clamp(1.05rem, 1.7vw, 1.4rem); color: var(--muted); line-height: 1.45; }
.cs-status { display: inline-flex; align-items: center; gap: .5rem; margin-top: 1.8rem; padding: .5rem 1.05rem; border-radius: 40px; border: 1px solid color-mix(in srgb, var(--brand) 45%, transparent); font-size: .66rem; letter-spacing: .2em; text-transform: uppercase; color: var(--brand); }
.cs-status i { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 10px var(--brand); }

.cs-beat { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; padding: clamp(3.5rem, 9vh, 7rem) var(--shell); border-top: 1px solid var(--line); }
.cs-beat--flip .cs-beat__text { order: 2; }
.cs-beat__text .label { color: var(--brand); }
.cs-beat__text h2 { font-size: clamp(1.45rem, 2.7vw, 2.05rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.05; margin-top: 1rem; color: var(--fg-strong); }
.cs-beat__text p { margin-top: 1.1rem; color: var(--muted); line-height: 1.65; max-width: 32rem; }
.cs-tile { margin: 0; aspect-ratio: 4/3; border-radius: var(--radius-card); border: 1px solid var(--line); background: var(--bg-2); display: grid; place-items: center; position: relative; overflow: hidden; transition: border-color .5s var(--ease); }
/* The tone wash only shows where there is no photo behind it. */
.cs-tile:not(:has(img))::before { content: ''; position: absolute; inset: 0; background: radial-gradient(85% 70% at 28% 18%, color-mix(in srgb, var(--brand) 24%, transparent), transparent 62%); }
.cs-tile span { position: relative; font-size: .7rem; letter-spacing: .22em; text-transform: uppercase; color: color-mix(in srgb, var(--brand) 72%, var(--fg)); }
.cs-tile img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .8s var(--ease), transform .8s var(--ease); }
.cs-tile img.is-loaded { opacity: 1; }
.cs-beat:hover .cs-tile { border-color: color-mix(in srgb, var(--brand) 55%, transparent); }
.cs-beat:hover .cs-tile img { transform: scale(1.04); }

/* --- Case-study banner + gallery — same radii as the rest of the site ------ */
.cs-banner {
  position: relative; margin: 2rem 0 0; max-width: 980px;
  aspect-ratio: 16 / 9; border-radius: var(--radius-banner); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-2);
  box-shadow: 0 30px 80px -40px rgba(0,0,0,.7);
}
.cs-banner img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .8s var(--ease); }
.cs-banner img.is-loaded { opacity: 1; }

.cs-gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(.9rem, 1.6vw, 1.3rem); margin-top: 2.4rem; max-width: 980px; }
.cs-shot {
  margin: 0; aspect-ratio: 1 / 1; border-radius: var(--radius-card); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-2);
  transition: transform .5s var(--ease), border-color .5s var(--ease);
}
.cs-shot:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--brand) 55%, transparent); }
.cs-shot img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .8s var(--ease), transform .6s var(--ease); }
.cs-shot img.is-loaded { opacity: 1; }
.cs-shot:hover img { transform: scale(1.06); }
@media (max-width: 760px) { .cs-gallery { grid-template-columns: 1fr 1fr; } }
@media (max-width: 820px) { .cs-beat { grid-template-columns: 1fr; } .cs-beat--flip .cs-beat__text { order: 0; } }

/* Live preview phone */
.preview { text-align: center; padding: clamp(4rem, 10vh, 8rem) var(--shell); border-top: 1px solid var(--line); }
.phone { position: relative; width: min(300px, 76vw); aspect-ratio: 300/620; margin: 2.4rem auto 0; border-radius: 42px; padding: 12px; background: linear-gradient(160deg, #26242c, #0c0b10); box-shadow: 0 40px 120px -44px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.14); }
.phone__screen { height: 100%; border-radius: 32px; overflow: hidden; background: radial-gradient(120% 80% at 50% 0%, color-mix(in srgb, var(--brand) 26%, #14121a), #100e15 70%); color: #f4f3f1; display: flex; flex-direction: column; padding: 1.4rem 1.15rem; gap: .9rem; text-align: left; }
.phone__bar { display: flex; justify-content: space-between; font-size: .6rem; letter-spacing: .1em; color: #9b9a96; }
.phone__hi { font-size: .82rem; color: #9b9a96; }
.phone__q { font-size: 1.5rem; font-weight: 600; letter-spacing: -.02em; color: #fff; line-height: 1.05; }
.phone__mood { display: flex; gap: .4rem; }
.phone__mood span { flex: 1; text-align: center; font-size: .6rem; padding: .5rem .2rem; border-radius: 10px; border: 1px solid rgba(255,255,255,.08); color: #9b9a96; }
.phone__mood .on { background: color-mix(in srgb, var(--brand) 30%, transparent); border-color: color-mix(in srgb, var(--brand) 60%, transparent); color: #fff; }
.phone__card { margin-top: auto; padding: .9rem 1rem; border-radius: 16px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08); }
.phone__card small { font-size: .58rem; letter-spacing: .12em; text-transform: uppercase; color: #9b9a96; }
.phone__card strong { display: block; font-size: .95rem; color: #fff; margin-top: .25rem; font-weight: 500; }
.phone__barline { margin-top: .6rem; height: 5px; border-radius: 4px; background: rgba(255,255,255,.1); overflow: hidden; }
.phone__barline i { display: block; height: 100%; width: 66%; background: var(--brand); box-shadow: 0 0 12px var(--brand); }
.phone__nav { display: flex; justify-content: space-around; margin-top: .8rem; font-size: .9rem; color: var(--faint); }
.phone__nav b { color: var(--brand); }
.captions { list-style: none; display: grid; gap: .55rem; max-width: 28rem; margin: 2.2rem auto 0; text-align: left; }
.captions li { display: flex; gap: .7rem; color: var(--muted); font-size: .95rem; }
.captions li b { color: var(--brand); font-weight: 600; }

/* Closing + back */
.cs-close { text-align: center; padding: clamp(5rem, 13vh, 10rem) var(--shell); border-top: 1px solid var(--line); }
.cs-close h2 { font-size: clamp(1.6rem, 3.8vw, 2.5rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.05; color: var(--fg-strong); }
.cs-close h2 em { font-style: normal; color: var(--brand); }
.cs-back { display: inline-flex; align-items: center; gap: .5rem; margin-top: 2rem; color: var(--accent); border-bottom: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); padding-bottom: .3rem; transition: gap .3s var(--ease); }
.cs-back:hover { gap: 1rem; }
.cs-statelist { display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem 2rem; margin: 2rem 0; font-size: .66rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); }
.cs-statelist span { display: inline-flex; align-items: center; gap: .5rem; }
.cs-statelist i { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 10px var(--brand); }

/* =============================================================================
   Blog
============================================================================= */
/* Hero, feature and archive must share ONE column, or their left edges disagree. */
.blog-hero { padding: 18vh var(--shell) 4vh; max-width: 1180px; margin: 0 auto; }
.blog-hero h1 { font-size: clamp(1.9rem, 4.3vw, 3.5rem); font-weight: 800; letter-spacing: -.04em; line-height: .92; color: var(--fg-strong); }
.blog-hero p { color: var(--muted); margin-top: 1.4rem; max-width: 34rem; }
.posts { list-style: none; padding: 0 var(--shell) clamp(4rem, 10vh, 8rem); max-width: 1180px; margin: 0 auto; }
.posts li a { display: grid; grid-template-columns: 8rem 1fr auto; gap: 1.5rem; align-items: baseline; padding: 2rem 0; border-top: 1px solid var(--line); transition: color .3s var(--ease); }
.posts li:last-child a { border-bottom: 1px solid var(--line); }
.posts__date { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.posts__title { font-size: clamp(1.1rem, 2vw, 1.6rem); font-weight: 600; letter-spacing: -.02em; color: var(--fg-strong); }
.posts__tag { font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); }
.posts li a:hover .posts__title { color: var(--accent); }
@media (max-width: 700px) { .posts li a { grid-template-columns: 1fr; gap: .4rem; } }

/* --- Featured post: one wide 16:9 banner, text beside it ------------------- */
.feature { padding: 2vh var(--shell) 0; max-width: 1180px; margin: 0 auto; }
.feature__link {
  display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(1.5rem, 3vw, 3rem); align-items: center;
  padding: clamp(1.4rem, 2.4vw, 2rem); border-radius: var(--radius-banner);
  border: 1px solid var(--line); background: color-mix(in srgb, var(--accent) 4%, transparent);
  transition: border-color .4s var(--ease), background .4s var(--ease);
}
.feature__link:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); background: color-mix(in srgb, var(--accent) 7%, transparent); }
.feature__link:hover .feature__media img { transform: scale(1.04); }
.feature__link:hover .feature__go { color: var(--accent); gap: 1rem; }
.feature__media {
  margin: 0; aspect-ratio: 16 / 9; border-radius: var(--radius-card); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-2);
}
.feature__media img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .7s var(--ease), transform .7s var(--ease); }
.feature__media img.is-loaded { opacity: 1; }
.feature__title { font-size: clamp(1.5rem, 2.8vw, 2.3rem); letter-spacing: -.03em; line-height: 1.1; color: var(--fg-strong); margin: .8rem 0 0; }
.feature__excerpt { color: var(--muted); margin-top: 1rem; font-size: 1rem; line-height: 1.6; max-width: 44ch; }
.feature__go { display: inline-flex; gap: .5rem; margin-top: 1.6rem; font-size: .8rem; color: var(--faint); transition: color .3s var(--ease), gap .3s var(--ease); }
@media (max-width: 860px) { .feature__link { grid-template-columns: 1fr; } }

/* --- Archive grid: same 16:9 cover + card radius as everything else -------- */
.postgrid-wrap { padding: clamp(4rem, 9vh, 7rem) var(--shell) clamp(4rem, 10vh, 8rem); max-width: 1180px; margin: 0 auto; }
.postgrid { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.4rem, 2.6vw, 2.4rem); margin-top: 2.6rem; }
.postcard a { display: flex; flex-direction: column; gap: .7rem; height: 100%; }
.postcard__media {
  margin: 0 0 .5rem; aspect-ratio: 16 / 9; border-radius: var(--radius-card); overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-2);
  transition: border-color .4s var(--ease);
}
.postcard__media img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .7s var(--ease), transform .7s var(--ease); }
.postcard__media img.is-loaded { opacity: 1; }
.postcard a:hover .postcard__media { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
.postcard a:hover .postcard__media img { transform: scale(1.05); }
.postcard a:hover .postcard__title { color: var(--accent); }
.postcard__title { font-size: 1.15rem; letter-spacing: -.02em; line-height: 1.25; color: var(--fg-strong); transition: color .3s var(--ease); }
.postcard__excerpt { color: var(--muted); font-size: .9rem; line-height: 1.6; flex: 1; }
.postcard .posts__tag { margin-top: .2rem; }
@media (max-width: 980px) { .postgrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .postgrid { grid-template-columns: 1fr; } }

/* =============================================================================
   INTERNATIONALISATION
   The layout must hold in six languages. Two of them break Latin assumptions:

   ARABIC is cursive and RTL. Letter-spacing is FATAL here — it severs the joins
   between letters and turns words into rubble — so all our tracked labels and
   tight display tracking are reset to zero. Direction-anchored positions
   (hero meta, panel orb, list markers) are mirrored.

   CHINESE has no spaces and no ascenders/descenders to speak of; negative
   tracking closes glyphs into each other, so tracking is reset there too, and a
   proper CJK stack is supplied since CY Grotesk has no CJK coverage.
============================================================================= */

/* ---- Arabic ---------------------------------------------------------------- */
[lang="ar"] .eyebrow, [lang="ar"] .label, [lang="ar"] .p-eyebrow,
[lang="ar"] .worklist__status, [lang="ar"] .posts__tag, [lang="ar"] .cs-status,
[lang="ar"] .p-work__s, [lang="ar"] .p-posts__k, [lang="ar"] .foot__base,
[lang="ar"] .hl, [lang="ar"] .h2, [lang="ar"] .p-title, [lang="ar"] .cs-name,
[lang="ar"] .soon, [lang="ar"] .statement__line, [lang="ar"] .blog-hero h1,
[lang="ar"] .panel__btn, [lang="ar"] .btn, [lang="ar"] .worklist__name {
  letter-spacing: 0 !important;      /* cursive script: tracking destroys the joins */
}
[lang="ar"] { line-height: 1.7; }    /* Arabic needs more leading than Latin */
[lang="ar"] .hl, [lang="ar"] .cs-name, [lang="ar"] .p-title { line-height: 1.25; }
[lang="ar"] .soon { line-height: 1.2; }

/* mirror everything that was anchored to a physical side */
[dir="rtl"] .hero__meta--tl { left: auto; right: var(--shell); }
[dir="rtl"] .hero__meta--br { right: auto; left: var(--shell); text-align: left; }
[dir="rtl"] .panel__orb { right: auto; left: -6vw; }
[dir="rtl"] .worklist a::before { left: auto; right: -.6rem; }
[dir="rtl"] .worklist a:hover { padding-left: 0; padding-right: .6rem; }
[dir="rtl"] .p-work button:hover, [dir="rtl"] .p-posts li a:hover { padding-left: 0; padding-right: .6rem; }
[dir="rtl"] .foot__consent input { margin-right: 0; }
[dir="rtl"] .lang__list { left: 0; right: auto; }
/* the loop/orb sits opposite the copy, so it flips with the text */
[dir="rtl"] .loop { right: auto; left: -8vw; }

/* ---- Chinese --------------------------------------------------------------- */
[lang="zh"] {
  font-family: 'PingFang SC', 'Hiragino Sans GB', 'Noto Sans SC', 'Microsoft YaHei', var(--sans);
}
[lang="zh"] .hl, [lang="zh"] .h2, [lang="zh"] .p-title, [lang="zh"] .cs-name,
[lang="zh"] .soon, [lang="zh"] .statement__line, [lang="zh"] .blog-hero h1,
[lang="zh"] .worklist__name, [lang="zh"] .p-work__n, [lang="zh"] .feature__title,
[lang="zh"] .postcard__title, [lang="zh"] .posts__title, [lang="zh"] .browser__view h3 {
  font-family: 'PingFang SC', 'Hiragino Sans GB', 'Noto Sans SC', 'Microsoft YaHei', var(--display);
  letter-spacing: 0 !important;      /* negative tracking jams CJK glyphs together */
}
[lang="zh"] .eyebrow, [lang="zh"] .label, [lang="zh"] .p-eyebrow { letter-spacing: .08em; }
[lang="zh"] .hl { line-height: 1.2; }

/* ---- Long-running languages (ru / es / fr) --------------------------------
   These run 20-40% longer than English. The headline clamps are tuned to a wide
   display face, so give the long ones a little more room before they wrap. */
[lang="es"] .hl, [lang="fr"] .hl { font-size: clamp(1.9rem, 4.6vw, 4.2rem); }
/* Madiffure is narrower than CY, so Russian can hold more size before it wraps */
[lang="ru"] .hl { font-size: clamp(2.1rem, 5.4vw, 4.9rem); letter-spacing: -.02em; }
[lang="ru"] .cta__title, [lang="ru"] .p-title { letter-spacing: -.02em; }
[lang="ru"] .soon, [lang="es"] .soon, [lang="fr"] .soon { font-size: clamp(1.5rem, 7.4vw, 8.5rem); }
[lang="ru"] .statement__line, [lang="es"] .statement__line, [lang="fr"] .statement__line {
  white-space: normal;               /* nowrap would run these off the shell */
}

/* =============================================================================
   Hero actions · section markers · the closing CTA · back-to-top · 404
============================================================================= */

/* Two CTAs side by side. They live in their own row so they can never ride over
   the copy above or the corner meta below — that was the overlap. */
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2.2rem; }
.hero__actions .btn { margin-top: 0; }
.btn--solid {
  background: var(--fg); color: var(--bg); border-color: var(--fg);
}
.btn--solid:hover {
  background: var(--fg-strong); border-color: var(--fg-strong); color: var(--bg);
  filter: none;
}

/* The corner marker the hero had — now on every section, so the numbering runs
   the length of the page instead of stopping at 01. */
.section, .statement, .cta { position: relative; }
.section__meta {
  position: absolute; bottom: clamp(1.2rem, 3vh, 2.2rem); right: var(--shell);
  font-family: var(--mono); font-size: .62rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--faint);
  pointer-events: none; z-index: 2;
}
[dir="rtl"] .section__meta { right: auto; left: var(--shell); }
@media (max-width: 860px) { .section__meta { display: none; } }

/* ---- The closing CTA — the last thing before the footer -------------------- */
.cta {
  z-index: 2; text-align: center;
  padding: clamp(5rem, 14vh, 9rem) var(--shell);
  border-top: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center;
}
.cta__title {
  font-family: var(--display);
  font-size: clamp(1.9rem, 4.4vw, 3.4rem);
  letter-spacing: -.035em; line-height: 1.05;
  color: var(--fg-strong); margin-top: .4rem;
}
.cta__lead {
  margin-top: 1.4rem; max-width: 52ch;
  color: var(--muted); font-size: clamp(.98rem, 1.3vw, 1.1rem); line-height: 1.65;
}
.cta__actions { margin-top: 2.4rem; }
.cta__actions .btn { margin-top: 0; cursor: pointer; }

/* ---- Back to top: rides the dot transition instead of scrolling ------------ */
.foot__top-row { max-width: 1320px; margin: clamp(2.5rem, 6vh, 4rem) auto 0; display: flex; justify-content: flex-end; }
.foot__totop {
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .7rem 1.3rem; border-radius: 40px;
  border: 1px solid var(--line-strong); background: transparent; color: var(--fg);
  font-size: .8rem; cursor: pointer;
  transition: border-color .3s var(--ease), gap .3s var(--ease), background .3s var(--ease);
}
.foot__totop:hover { border-color: var(--accent); gap: .9rem; background: color-mix(in srgb, var(--accent) 10%, transparent); }
[dir="rtl"] .foot__top-row { justify-content: flex-start; }

/* ---- 404 — the dot font, filling the screen -------------------------------- */
.notfound {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 0 var(--shell); position: relative; z-index: 2;
}
.notfound__code {
  font-family: var(--display);
  font-size: clamp(6rem, 34vw, 30rem);      /* fills the screen */
  line-height: .9; letter-spacing: -.03em; white-space: nowrap;
  color: var(--fg-strong);
  -webkit-text-stroke: .018em currentColor;  /* no bold cut — fatten for the dots */
  paint-order: stroke fill;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 53%);
  mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 53%);
  -webkit-mask-size: 9px 9px; mask-size: 9px 9px;
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
  animation: soonPulse 3.4s ease-in-out infinite;
}
.notfound__lead { margin-top: 1.4rem; max-width: 44ch; color: var(--muted); line-height: 1.65; }
.notfound__actions { margin-top: 2.4rem; }
.notfound__actions .btn { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .notfound__code { animation: none; } }

/* =============================================================================
   ARABIC — corrections after review
============================================================================= */

/* ---- The wordmark ----------------------------------------------------------
   The supplied logo is a LATIN lockup ("riibat"), so on an Arabic page it cannot
   act as the wordmark — the brand would still be announcing itself in English.
   Arabic therefore gets the MARK ALONE plus the name set in Thmanyah. */
.brandmark__mark, .brandmark__ar { display: none; }
.brandmark__mark { height: clamp(26px, 2.4vw, 32px); width: auto; }
.brandmark__ar {
  font-family: 'Thmanyah', var(--display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  line-height: 1; color: var(--fg-strong);
  letter-spacing: 0;                       /* cursive: never track Arabic */
}
[lang="ar"] .brandmark { gap: .6rem; }
[lang="ar"] .brandmark__img { display: none !important; }
[lang="ar"] .brandmark__mark--dark { display: block; }
:root[data-theme="light"][lang="ar"] .brandmark__mark--dark,
[lang="ar"]:root[data-theme="light"] .brandmark__mark--dark { display: none; }
:root[data-theme="light"][lang="ar"] .brandmark__mark--light,
[lang="ar"]:root[data-theme="light"] .brandmark__mark--light { display: block; }
[lang="ar"] .brandmark__ar { display: inline-block; }
/* the footer lockup stays Latin — it sits beside the legal name */
[lang="ar"] .brandmark--foot .brandmark__img { display: block !important; }
[lang="ar"] .brandmark--foot .brandmark__mark,
[lang="ar"] .brandmark--foot .brandmark__ar { display: none; }

/* ---- Arabic reads SMALL for its word count, so give it more size -----------
   Arabic says the same thing in fewer, denser words. At the Latin scale the
   headlines looked underweight next to the English. */
[lang="ar"] .hl          { font-size: clamp(2.4rem, 6.2vw, 5.6rem); }
[lang="ar"] .h2          { font-size: clamp(1.75rem, 3.5vw, 2.8rem); }
[lang="ar"] .p-title     { font-size: clamp(1.8rem, 3.9vw, 3.2rem); }
[lang="ar"] .cta__title  { font-size: clamp(2.1rem, 4.9vw, 3.8rem); }
[lang="ar"] .cs-name     { font-size: clamp(2.6rem, 8vw, 5.8rem); }
[lang="ar"] .blog-hero h1{ font-size: clamp(2.2rem, 5vw, 4rem); }
[lang="ar"] .soon        { font-size: clamp(2.4rem, 12vw, 13rem); }
[lang="ar"] .statement__line { font-size: clamp(1.5rem, 2.9vw, 2.5rem); }
[lang="ar"] .hero__sub, [lang="ar"] .p-lead, [lang="ar"] .cta__lead { font-size: clamp(1.05rem, 1.6vw, 1.35rem); }
[lang="ar"] .nav a { font-size: .95rem; }
[lang="ar"] .worklist__name, [lang="ar"] .p-work__n { font-size: clamp(1.4rem, 2.4vw, 2rem); }

/* ---- The dot font does NOT work on small Arabic ----------------------------
   The dot matrix punches a grid through the glyphs. Arabic is cursive: the strokes
   are thin, they join, and they carry dots and diacritics of their own. At label
   size the mask shreds the word into unreadable confetti. So small Arabic labels
   keep the colour and tracking of the dot font but drop the mask. The big display
   pieces (COMING SOON, the 404) are large enough to survive it and keep it. */
[lang="ar"] .label,
[lang="ar"] .eyebrow,
[lang="ar"] .p-eyebrow,
[lang="ar"] .dot-font,
[lang="ar"] .btn-dots {
  -webkit-mask-image: none !important;
  mask-image: none !important;
  -webkit-text-stroke: 0 !important;
  letter-spacing: 0 !important;
}
[lang="ar"] .label, [lang="ar"] .eyebrow, [lang="ar"] .p-eyebrow { font-size: clamp(.85rem, 1.2vw, 1rem); }

/* The "instrument voice" micro-labels (nav, corner meta, eyebrows, statuses) are
   set in a MONOSPACE face. Monospacing Arabic is wrong: it forces every glyph to
   an identical advance, which pulls a cursive script apart and is exactly why the
   top bar looked broken. Redefining --mono for Arabic re-points every one of those
   selectors at the Arabic face in a single line. */
[lang="ar"] {
  --mono: 'Thmanyah', 'Helvetica Neue', Helvetica, sans-serif;
}
[lang="ar"] .nav a,
[lang="ar"] .hero__meta,
[lang="ar"] .section__meta,
[lang="ar"] .worklist__status,
[lang="ar"] .p-work__s,
[lang="ar"] .foot__base,
[lang="ar"] .panel__btn,
[lang="ar"] .cs-status,
[lang="ar"] .cs-endorse,
[lang="ar"] .posts__tag,
[lang="ar"] .p-posts__k,
[lang="ar"] .p-kicker {
  letter-spacing: 0 !important;
  text-transform: none;              /* Arabic has no case; uppercasing is a no-op */
}
[lang="ar"] .nav a { font-size: 1rem; }

/* ---- Contact: the classic one ---------------------------------------------
   Every other section has a product tone. Contact is where an investor, a corporate
   or a government actually transacts, so it gets none: a neutral platinum, a plain
   white surface in light mode, and no orb behind it. The form carries the section. */
/* Muted + a dot mask on top left these almost invisible. The dot font is already
   a big contrast cost; the colour must not add to it. */
.panel--neutral .p-eyebrow { color: var(--fg); opacity: .85; }
.panel--neutral .p-kicker { color: var(--muted); }
.panel--neutral .p-submit { background: var(--fg); color: var(--bg); }
.panel--neutral .p-field input:focus,
.panel--neutral .p-field textarea:focus,
.panel--neutral .p-field select:focus { border-color: var(--fg); background: transparent; }
.panel--neutral .p-contact a:hover { color: var(--fg-strong); }
