/* ============================================================
   One block per section, in page order.
   ============================================================ */

/* =============================================================== navbar === */

.nav {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 60;
  padding: 0.7rem var(--gutter);
  display: flex;
  align-items: center;
  gap: 1.25rem;
  transition: background 400ms ease, backdrop-filter 400ms ease, box-shadow 400ms ease,
              translate 460ms cubic-bezier(.2,.8,.2,1);
}
/* Reading down the page tucks the bar away so each section gets the whole
   screen. Any scroll up, or keyboard focus, brings it back (initNav). */
.nav.is-hidden { translate: 0 calc(-100% - 1.5rem); }
.nav.is-stuck {
  background: color-mix(in srgb, var(--paper) 72%, transparent);
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  box-shadow: 0 1px 0 var(--ink-12);
}
/* The home page bar (data-on-tone) never changes its logo or ink: always the
   white of the first screen. Its glass takes the tint of the block below
   (--nav-glass, --nav-mix from initNav). project.html keeps the paper bar. */
.nav[data-on-tone] { --nav-ink: #fff; --nav-cta-fg: var(--ink); }
.nav[data-on-tone].is-stuck {
  background: color-mix(in srgb, var(--nav-glass, #0b0b12) var(--nav-mix, 62%), transparent);
  box-shadow: 0 1px 0 #ffffff1f;
}
@media (max-width: 900px) {
  .nav[data-on-tone] .nav__links {
    background: color-mix(in srgb, var(--nav-glass, #0b0b12) 92%, #000);
  }
  .nav[data-on-tone] .nav__links a { color: #fff; }
}

.nav__logo { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; }
.nav__logo img { height: 2.1rem; width: auto; }

.nav__links {
  list-style: none;
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.5vw, 1.6rem);
  margin: 0 auto 0 0;
  padding: 0;
}
.nav__links a {
  position: relative;
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
  padding: 0.35rem 0.1rem;
  color: var(--nav-ink, var(--ink));
  transition: color 300ms ease;
}
.nav__links a::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 0.05rem;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: inline-end;
  transition: transform 240ms cubic-bezier(.2,.7,.3,1);
}
.nav__links a:hover::after,
.nav__links a[aria-current='true']::after { transform: scaleX(1); transform-origin: inline-start; }

.nav__cta { flex: none; --btn-bg: var(--nav-ink, var(--ink)); --btn-fg: var(--nav-cta-fg, var(--paper)); }
.nav__burger {
  display: none;
  flex: none;
  width: 2.75rem; height: 2.75rem;
  border: var(--hair) solid currentColor;
  border-radius: 999px;
  background: transparent;
  color: var(--nav-ink, var(--ink));
  cursor: pointer;
  align-items: center; justify-content: center;
}
.nav__burger span { display: block; width: 1.05rem; height: 2px; background: currentColor; box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor; }

/* Wide screens: a floating capsule instead of a full width bar. It covers
   only what it holds, and the page runs edge to edge around it. */
@media (min-width: 901px) {
  .nav {
    inset-block-start: 0.75rem;
    margin-inline: auto;
    width: fit-content;
    max-width: calc(100% - var(--gutter) * 2);
    padding: 0.3rem;
    padding-inline-start: 1.1rem;
    gap: clamp(0.75rem, 2vw, 1.5rem);
    border-radius: 999px;
  }
  /* before any scroll: a faint frost, so it still reads as one object */
  .nav[data-on-tone]:not(.is-stuck) {
    background: #ffffff14;
    box-shadow: inset 0 0 0 1px #ffffff29;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }
  .nav.is-stuck { box-shadow: 0 0 0 1px var(--ink-12), 0 14px 34px -22px #0007; }
  .nav[data-on-tone].is-stuck { box-shadow: inset 0 0 0 1px #ffffff1f, 0 14px 34px -22px #000a; }

  .nav__logo img { height: 1.75rem; }
  .nav__links { margin: 0; gap: 0.15rem; }
  .nav__links a {
    padding: 0.4rem 0.8rem;
    border-radius: 999px;
    transition: color 300ms ease, background 200ms ease;
  }
  .nav__links a::after { content: none; }
  .nav__links a:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
  .nav__links a[aria-current='true'] { background: color-mix(in srgb, currentColor 17%, transparent); }
  .nav__menuonly { display: none; }
  .nav__cta { padding: 0.5em 1.2em; font-size: 0.9375rem; }
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: background 200ms ease, opacity 200ms ease; }
  .nav.is-hidden { translate: none; opacity: 0; pointer-events: none; }
}

@media (max-width: 900px) {
  .nav__links {
    position: fixed;
    inset: 0 0 auto;
    padding: 5.25rem var(--gutter) 2rem;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
    background: var(--paper);
    color: var(--ink);
    box-shadow: 0 24px 60px -30px #0006;
    transform: translateY(-102%);
    transition: transform 380ms cubic-bezier(.2,.7,.3,1);
  }
  .nav__links a { color: var(--ink); font-size: 1.35rem; font-family: var(--display); font-weight: 700; }
  .nav.is-open .nav__links { transform: none; }
  /* above the open panel, so the burger that opened it can close it */
  .nav__logo, .nav__burger { position: relative; z-index: 1; }
  /* far side of the bar from the logo */
  .nav__burger { display: inline-flex; margin-inline-start: auto; }
  .nav__cta { display: none; }
}

/* ---- the أعمالنا shelf (js/navworks.js) ----
   Six covers, not six labels: the art is what tells the works apart,
   so nothing here needs a bullet or a tag to carry colour. A popover
   in the top layer, so its glass blurs the page and not the bar.
   --o is its spring, 0 to 1: the panel grows out of the link and the
   blur arrives with it. */
.navworks {
  position: fixed;
  inset: var(--y, 4rem) auto auto var(--x, 50%);
  margin: 0;
  translate: -50% 0;
  width: max-content;
  padding: 0.7rem 0.75rem 0.8rem;
  border: 0;
  border-radius: 1.5rem;
  overflow: visible;
  color: #fff;
  background: color-mix(in srgb, var(--nav-glass, #0b0b12) 78%, transparent);
  box-shadow: inset 0 0 0 1px #ffffff1f, 0 28px 54px -26px #000d;
  -webkit-backdrop-filter: blur(calc(var(--o, 0) * 24px)) saturate(calc(1 + var(--o, 0) * 0.8));
  backdrop-filter: blur(calc(var(--o, 0) * 24px)) saturate(calc(1 + var(--o, 0) * 0.8));
  opacity: var(--o, 0);
  transform-origin: var(--ox, 50%) 0;
  transform: translateY(calc((1 - var(--o, 0)) * -0.5rem)) scale(calc(0.95 + var(--o, 0) * 0.05));
}
/* covers the gap under the link, so the pointer never leaves both */
.navworks::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 100%;
  height: var(--gap, 0.75rem);
}
/* the house decoration, one copy, sunk into the far corner. The clip is
   on this wrapper and not on the panel, so the bridge above survives. */
.navworks__deco {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.navworks__cloud {
  --cloud-color: #fff;
  width: 15rem;
  inset-block-start: -2.6rem;
  inset-inline-end: -3rem;
  opacity: 0.12;
  animation: nw-drift 26s ease-in-out infinite;
}
@keyframes nw-drift {
  50% { transform: translate3d(-14px, 6px, 0) rotate(-2deg); }
}

/* the studio's line, and beside it the latin title of whichever cover
   is under the pointer */
.navworks__head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  margin: 0;
  padding: 0.1rem 0.5rem 0.6rem;
}
.navworks__head b {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
  line-height: 1;
}
.navworks__head i {
  direction: ltr;
  font-style: normal;
  font-family: var(--body);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;        /* latin marginalia only */
  opacity: 0.5;
  animation: nw-latin 260ms cubic-bezier(.2,.7,.3,1);
}
@keyframes nw-latin { from { opacity: 0; translate: 8px 0; } }

.navworks ul {
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 0.2rem;
}
/* Each cover takes its own slice of the panel's spring, so they land
   one after another along the row instead of all at once. */
.navworks li {
  --p: clamp(0, calc((var(--o, 0) - var(--i) * 0.055) / 0.7), 1);
  opacity: var(--p);
  transform: translateY(calc((1 - var(--p)) * 16px)) scale(calc(0.94 + var(--p) * 0.06));
}

/* .nav__links a styles every link in the bar, so these reach past them */
.nav__links .navworks a {
  display: grid;
  justify-items: center;
  width: 6.2rem;
  padding: 0.4rem 0.3rem 0.5rem;
  border-radius: 1rem;
  color: #fff;
  font-family: var(--body);
  transition: background 200ms ease, opacity 260ms ease;
}
.nav__links .navworks a::after,
.nav__links .navworks a::before { content: none; }
.nav__links .navworks a b {
  margin-block-start: 0.3rem;
  /* two lines' room whether a name takes one or two, so every role in
     the row sits on the same line */
  min-block-size: 2.3em;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
}
.nav__links .navworks a small {
  font-size: 0.625rem;
  font-weight: 400;
  opacity: 0.52;
}

/* the cover itself: its own art, its own baked shadow, no frame */
.navworks__art {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 900 / 1333;
  transform-origin: 50% 90%;
  translate: 0 0;
  scale: 1;
  rotate: 0deg;
  transition: translate 320ms cubic-bezier(.2,.7,.3,1),
              scale 320ms cubic-bezier(.2,.7,.3,1),
              rotate 320ms cubic-bezier(.2,.7,.3,1);
}
.navworks__art img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain; }
/* the work's own colour pools behind it as it lifts, the way a lifted
   card pools into the sky in أعمالنا */
.navworks__art::after {
  content: '';
  position: absolute;
  inset: 16% 6% 8%;
  border-radius: 1rem;
  background: var(--accent);
  filter: blur(16px);
  opacity: 0;
  transition: opacity 280ms ease;
}

/* one cover forward, the rest a step back: the shelf answers the pointer
   as a whole */
.navworks ul:has(a:hover) a:not(:hover),
.navworks ul:has(a:focus-visible) a:not(:focus-visible) { opacity: 0.42; }
.nav__links .navworks a:hover .navworks__art,
.nav__links .navworks a:focus-visible .navworks__art { translate: 0 -8px; scale: 1.07; rotate: -2.5deg; }
.navworks li:nth-child(even) a:hover .navworks__art,
.navworks li:nth-child(even) a:focus-visible .navworks__art { rotate: 2.5deg; }
.nav__links .navworks a:hover .navworks__art::after,
.nav__links .navworks a:focus-visible .navworks__art::after { opacity: 0.55; }
/* feedback lands on the press */
.nav__links .navworks a:active .navworks__art {
  translate: 0 -2px;
  scale: 0.98;
  transition-duration: 110ms;
}
.nav__links .navworks a[aria-current='page'] { background: #ffffff17; }
.nav__links .navworks a[aria-current='page'] small { opacity: 0.85; }
.nav__links .navworks a:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }

/* a phone that reports hover (a mouse on a small window) still fits */
@media (max-width: 1100px) {
  .nav__links .navworks a { width: 5.3rem; }
}

@media (prefers-reduced-motion: reduce) {
  /* the spring still runs, as a plain cross-fade, and nothing drifts */
  .navworks, .navworks li { transform: none; }
  .navworks__cloud { animation: none; }
  .navworks__head i { animation: none; }
  .navworks {
    -webkit-backdrop-filter: blur(24px) saturate(1.8);
    backdrop-filter: blur(24px) saturate(1.8);
  }
  .navworks__art, .nav__links .navworks a:active .navworks__art { transition: none; translate: none; scale: none; rotate: none; }
  .nav__links .navworks a:hover .navworks__art,
  .nav__links .navworks a:focus-visible .navworks__art { translate: none; scale: none; rotate: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .navworks {
    background: color-mix(in srgb, var(--nav-glass, #0b0b12) 96%, #000);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* ============================================================ hero news === */

.news {
  position: relative;
  /* One screen plus the cloud seam's upper band, all of it added below the
     card: the card stays put and the seam starts under the fold. */
  min-height: calc(100svh + var(--seam-rise));
  display: grid;
  align-items: center;
  padding-block: clamp(6rem, 12vh, 9rem) calc(clamp(3rem, 7vh, 5rem) + var(--seam-rise));
  background: var(--tone-bg);
  color: var(--tone-ink);
  overflow: clip;
  transition: background 720ms cubic-bezier(.4,0,.2,1), color 720ms ease;
}
/* a full screen is mostly empty on a phone: half of one, plus the seam */
@media (max-width: 760px) {
  .news { min-height: calc(50svh + var(--seam-rise)); }
}

.news::after {
  /* deep vignette so the card floats off the flat colour */
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 50% 120%, var(--tone-deep) 0%, transparent 62%),
    radial-gradient(90% 60% at 50% -10%, #ffffff1f 0%, transparent 60%);
  transition: background 720ms cubic-bezier(.4,0,.2,1);
  pointer-events: none;
  z-index: 1;
}

/* ---- each headline's painted world (hero.js) ----
   The furthest layer: the painting the headline's project page wears, sharp
   and at the same crop. It is laid a little past every edge for the pointer
   drift. Its top deepens to --wash so the header reads, and its foot ends
   in --foot, the stage's colour, where the cloud seam takes over. Each
   painting carries its own two, so they travel with it.

   Turning the deck carries the paintings too (hero.js sweep): the old one
   slides the way the card went and goes out of focus, the new one arrives
   out of focus from the other side and sharpens as it comes to rest. With
   motion turned off they cross fade instead (the reduced motion block). */
.news__bgs {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.news__bg {
  position: absolute;
  inset: -2.5%;
  opacity: 0;
  translate: calc(var(--px, 0) * -6px) calc(var(--py, 0) * -4px);
  /* each painting keeps its own layer, so a sweep never has to build one
     (and paint the picture again) on its first frame */
  will-change: transform, filter, opacity;
}
.news__bg.is-on { opacity: 1; }
/* --zoom closes in on the corner the crop is anchored to (bg.news) */
.news__bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--at);
  transform-origin: var(--at);
  scale: var(--zoom, 1);
}
.news__bg picture { display: block; width: 100%; height: 100%; }
@media (max-aspect-ratio: 4/5) { .news__bg img { object-position: var(--at-tall); transform-origin: var(--at-tall); scale: 1; } }
.news__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--wash) 86%, transparent) 0,
    color-mix(in srgb, var(--wash) 58%, transparent) 14%,
    transparent 34%,
    transparent 74%,
    var(--foot) 97%);
}

/* --px / --py: the smoothed pointer, -1 to 1 (hero.js). Each layer drifts
   against it by its depth, so the hero reads as a room you look into. */
.news__clouds { position: absolute; inset: -12% -8%; z-index: 3; pointer-events: none; translate: calc(var(--px, 0) * -14px) calc(var(--py, 0) * -8px); }
.news__front { position: absolute; inset: -14% -10%; z-index: 5; pointer-events: none; translate: calc(var(--px, 0) * -30px) calc(var(--py, 0) * -16px); }
.news__clouds .cloud { opacity: 0.85; transition: background-color 720ms ease; }

/* ---- each headline's world (hero.js, scenes.js) ----
   The scenery its project page wears. Only the current headline's world is
   lit: switching fades one out as the next fades in, and the eyes shut on
   the way out. Behind the card sits the set piece; a canvas draws either
   behind it (the eyes' bokeh) or in front of it (سمرقند's leaf). */
.news__worlds { position: absolute; inset: 0; z-index: 2; pointer-events: none; translate: calc(var(--px, 0) * -8px) calc(var(--py, 0) * -6px); }
.news__fx { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.news__layer { position: absolute; inset: 0; opacity: 0; transition: opacity 900ms cubic-bezier(.4,0,.2,1); }
.news__layer.is-on { opacity: 1; }
.news__canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.news__layer .eye { transition: scale 480ms cubic-bezier(.3,1.4,.5,1); }
.news__layer:not(.is-on) .eye { scale: 1 0.06; transition-duration: 220ms; transition-timing-function: ease-in; }

.news__stage {
  /* Physical order, not reading order: prev is always the left button and
     next always the right one, whichever way the page reads. */
  direction: ltr;
  position: relative;
  z-index: 4;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(0.5rem, 2vw, 2rem);
}

.news__nav {
  flex: none;
  width: clamp(2.75rem, 4vw, 3.75rem);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: var(--hair) solid color-mix(in srgb, var(--tone-ink) 45%, transparent);
  background: color-mix(in srgb, var(--tone-ink) 8%, transparent);
  color: var(--tone-ink);
  backdrop-filter: blur(6px);
  cursor: pointer;
  transition: background 200ms ease, transform 160ms cubic-bezier(.2,.7,.3,1), border-color 200ms ease;
}
.news__nav:hover { background: color-mix(in srgb, var(--tone-ink) 20%, transparent); transform: scale(1.06); }
.news__nav:active { transform: scale(0.94); }
.news__nav svg { width: 42%; }

/* Narrow enough that header, card and dots fit one screen: the card is
   1448:814, and 22rem covers the bar, the header and the dots. */
.news__track {
  position: relative;
  direction: rtl;
  justify-self: center;
  width: min(100%, calc((100svh - 22rem) * 1.779));
  /* the card tips a touch toward the pointer, like the rest of the room */
  transform: perspective(1600px) rotateY(calc(var(--px, 0) * 2.2deg)) rotateX(calc(var(--py, 0) * -1.6deg));
}

/* أَخْبَارُنَا: centred like every other section header, lit like مَنْ نَحْنُ.
   Above the front clouds (z 5) so they never cross it. */
.news__head {
  position: relative;
  z-index: 6;
  text-align: center;
  margin-block-end: clamp(1rem, 2.5vw, 2rem);
}
.news__head .eyebrow {
  justify-content: center;
  color: color-mix(in srgb, var(--tone-ink) 72%, transparent);
}
/* The fill and the lit rim only paint inside the box, and the fatha over
   أَ rides well above the line: pad the top enough for it and take the
   room back in the margin. It rises in once the page is up. */
.news__title {
  padding-block: 0.6em 0.08em;
  margin-block: -0.45em 0;
  animation: news-in 1s cubic-bezier(.2,.75,.2,1) 120ms both;
}
.news__head .eyebrow { animation: news-in 1s cubic-bezier(.2,.75,.2,1) both; }
@keyframes news-in { from { opacity: 0; transform: translate3d(0, 16px, 0); } }

.news__slide {
  position: relative;
  border-radius: clamp(14px, 1.5vw, 22px);
  overflow: hidden;
  border: var(--hair) solid color-mix(in srgb, var(--tone-ink) 42%, transparent);
  box-shadow: 0 0 0 0 transparent;
  /* A shadow cannot be moved by the compositor, so every change repaints
     the card. Stepped at 20 a second the hue still glides (each step is a
     sliver of colour) and the card repaints a third as often. */
  animation: cardglow 9s steps(45) infinite;
  will-change: transform, opacity;
}
.news__slide.is-out { position: absolute; inset: 0; }

@keyframes cardglow {
  0%   { box-shadow: 0 30px 80px -40px #000a, 0 0 42px -6px #F5654966; }
  25%  { box-shadow: 0 30px 80px -40px #000a, 0 0 42px -6px #F7D03866; }
  50%  { box-shadow: 0 30px 80px -40px #000a, 0 0 42px -6px #45C4B966; }
  75%  { box-shadow: 0 30px 80px -40px #000a, 0 0 42px -6px #0084C166; }
  100% { box-shadow: 0 30px 80px -40px #000a, 0 0 42px -6px #F5654966; }
}

.news__art { width: 100%; aspect-ratio: 1448 / 814; object-fit: cover; }

.news__body {
  position: absolute;
  inset-block-end: clamp(1rem, 3.4vh, 2.75rem);
  inset-inline: clamp(1rem, 4%, 3.5rem);
  display: grid;
  gap: clamp(0.75rem, 1.6vh, 1.25rem);
  color: #fff;
  text-shadow: 0 2px 14px #0009;
}
/* the art already carries the logo. align the copy under wherever it sits. */
/* dir is rtl, so inline-start is the right edge: the side both logos sit on */
.news__slide[data-align='end'] .news__body { justify-items: start; text-align: start; padding-inline-end: 44%; }
.news__slide[data-align='center'] .news__body { justify-items: center; text-align: center; padding-inline-end: 50%; }

.news__text {
  margin: 0;
  font-size: clamp(0.75rem, 1.02vw, 1rem);
  line-height: 1.85;
  max-width: 44ch;
}

.news__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 0.65rem; }
.news__acts .btn { --btn-bg: #fff; --btn-fg: #1a1a1a; }
.news__acts .btn--ghost { --btn-bg: #fff; --btn-fg: #1a1a1a; }

/* The trailer, beside the two buttons and quieter than both: on a work that
   is a comic first, the pages are the story and this is the teaser for it. */
.news__watch {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.3em 0.2em;
  font-size: clamp(0.875rem, 1vw, 0.9375rem);
  font-weight: 500;
  color: #ffffffb5;
  text-decoration: none;
  border-bottom: 1px solid #ffffff3d;
  transition: color 160ms ease, border-color 160ms ease;
}
.news__watch:hover { color: #fff; border-color: #ffffffa8; }
/* play points right in every language: media controls are never mirrored */
.news__tri { width: 0.6em; aspect-ratio: 1; background: currentColor; clip-path: polygon(12% 4%, 96% 50%, 12% 96%); }

/* what the headline is, pinned to the card's far top corner. It blurs the
   art behind it only: the slide is its backdrop root. */
.news__chip {
  position: absolute;
  z-index: 2;
  inset-block-start: clamp(0.7rem, 1.8vw, 1.25rem);
  inset-inline-end: clamp(0.7rem, 1.8vw, 1.25rem);
  padding: 0.35em 0.95em;
  border-radius: 999px;
  font-size: clamp(0.75rem, 0.9vw, 0.875rem);
  font-weight: 600;
  line-height: 1.5;
  color: #fff;
  background: #00000059;
  backdrop-filter: blur(10px) saturate(150%);
  -webkit-backdrop-filter: blur(10px) saturate(150%);
  box-shadow: inset 0 0 0 1px #ffffff33;
}

.news__dots {
  position: absolute;
  z-index: 5;
  inset-block-end: clamp(-3rem, -4.5vh, -2rem);
  inset-inline-start: 0;
  display: flex;
  gap: 0.45rem;
}
.news__dot {
  width: 2.25rem; height: 3px;
  border: 0; padding: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tone-ink) 42%, transparent);
  cursor: pointer;
  transition: background 300ms ease, width 300ms ease;
}
.news__dot[aria-selected='true'] { background: var(--tone-ink); width: 3.5rem; }

/* Left alone, the lit dot fills and the deck moves on when it is full
   (hero.js listens for the fill's end). Pointing at the hero, focusing in
   it, or scrolling it away holds the fill. */
.news__dot { position: relative; overflow: hidden; }
.news.is-auto .news__dot[aria-selected='true'] { background: color-mix(in srgb, var(--tone-ink) 42%, transparent); }
.news.is-auto .news__dot[aria-selected='true']::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--tone-ink);
  transform-origin: inline-start;
  animation: dot-fill 8s linear both;
}
.news:is(:hover, :focus-within, .is-away) .news__dot::after { animation-play-state: paused; }
@keyframes dot-fill { from { transform: scaleX(0); } }

@media (max-width: 760px) {
  /* one cloud layer is plenty on a phone: the front one just covers the card */
  .news__front { display: none; }
  /* The logo is painted into the art, so never crop it. The copy moves
     below the frame instead of sitting on top of it. */
  .news__stage { grid-template-columns: 1fr; }
  .news__nav { position: absolute; z-index: 6; inset-block-start: 38%; }
  .news__nav--prev { inset-inline-start: -0.5rem; }
  .news__nav--next { inset-inline-end: -0.5rem; }
  /* every card as tall as the tallest (hero.js level), the spare room
     shared round the copy */
  .news__slide { border-radius: 14px; background: #12121a; min-height: var(--slide-h, 0px); display: flex; flex-direction: column; }
  .news__slide .news__body { flex: 1; align-content: center; }
  .news__body {
    position: static;
    padding: 1.1rem 1.15rem 1.35rem;
    justify-items: center;
    text-align: center;
    text-shadow: none;
  }
  .news__slide[data-align='end'] .news__body,
  .news__slide[data-align='center'] .news__body { padding-inline-end: 1.15rem; justify-items: center; text-align: center; }
  .news__text { font-size: 0.875rem; color: #ffffffc4; }
  .news__track { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .news__title, .news__head .eyebrow { animation: none; }
  .news__track, .news__clouds, .news__front, .news__worlds, .news__bg { transform: none; translate: none; }
  /* no sweep here: the paintings just change places */
  .news__bg { transition: opacity 400ms ease; will-change: auto; }
  .news__layer .eye { transition: none; }
}

/* --------------------------------------------------- shared scenery ---
   Set pieces from js/scenes.js used on more than one page: the news hero
   wears باب الحجرة's eyes and سمرقند's sun, and so do their project pages.
   The rest live in project.css. */

.sun {
  position: absolute;
  top: -34%;
  left: 50%;
  width: min(72rem, 130vw);
  aspect-ratio: 1;
  translate: -50% 0;
  background: radial-gradient(closest-side, #ffffff80, #ffffff1f 55%, transparent);
}

.eyes { position: absolute; inset: 0; }
.eye {
  position: absolute;
  filter: blur(var(--blur)) drop-shadow(0 0 0.7rem color-mix(in srgb, var(--accent, #9fd8ff) 65%, transparent));
}
.eye svg { width: 100%; height: auto; overflow: visible; transform-origin: 50% 50%; animation: blink var(--blink) ease-in-out var(--delay) infinite; }
@keyframes blink { 0%, 90%, 100% { transform: scaleY(1); } 94% { transform: scaleY(0.06); } }
@media (max-width: 760px) { .eye:nth-child(3n) { display: none; } }
@media (prefers-reduced-motion: reduce) { .eye svg { animation: none; } }

/* ============================================================== about ==== */

/* The cast loop is cropped from a flat blue frame, and browsers disagree on
   that blue by a few points. So the video never touches an edge: every side
   fades out through a mask and the section's own sky takes over. */

.about { background: var(--sky); color: #fff; overflow: clip; }
.about :focus-visible { outline-color: #fff; }

.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}

.about__copy { position: relative; z-index: 3; }
.about__copy p { color: #fff; }
.about__copy p + p { margin-top: 1.1rem; }
.about .eyebrow { color: #ffffffb8; }
.about .lead { color: #fff; }

.about__title {
  font-size: clamp(3.25rem, 7.2vw, 7.75rem); /* stays on one line down to the 880px stack */
  line-height: 1.25;
  /* The clipped fill and the filter only paint inside this box, and the
     tashkeel rides above the line. Pad the top for it, give it back in the
     margin. */
  padding-block: 0.3em 0.05em;
  margin-block: -0.4em 0.15em;
  color: #fff;
}

.about__roles {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.about__roles li {
  border-radius: 999px;
  padding: 0.35em 0.95em;
  font-size: 0.875rem;
  font-weight: 500;
  background: #fff;
  color: var(--ink);
  box-shadow: 0 6px 18px -10px #03335c99;
}
.about__roles li b { font-weight: 700; color: var(--role-accent, var(--ember)); }

.about__art {
  position: relative;
  isolation: isolate;
  margin: 0;
}

/* Wider than its column. The overflow runs toward the outer edge, where the
   frame is only faded blue, and the section clips it. The extra 1.5x is a
   transform, so the cast grows without making the section any taller. */
.about__stage {
  position: relative;
  z-index: 1;
  width: 124%;
  scale: var(--cast-scale, 1.5);
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 15%, #000 85%, transparent),
    linear-gradient(to bottom, transparent, #000 12%, #000 76%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent, #000 15%, #000 85%, transparent),
    linear-gradient(to bottom, transparent, #000 12%, #000 76%, transparent);
  mask-composite: intersect;
}
.about__video { display: block; width: 100%; height: auto; background: transparent; }

/* Clouds hang off the outer edge and the bottom, never across the copy:
   anything on the text side stops inside the column gap. Widths are a share
   of the art column, so they shrink with the cast instead of with the
   window. */
.about .cloud { --cloud-color: #fff; z-index: 2; filter: blur(var(--blur, 0px)); }
.about .cloud[data-flip] { transform: scaleX(-1); }
.about__cloud--a { inset-block-start: -10%; inset-inline-end: -30%; width: 43%; }
.about__cloud--b { inset-block-start: 46%;  inset-inline-end: -38%; width: 53%; }
.about__cloud--c { inset-block-start: 24%;  inset-inline-start: -3%; width: 25%; }
.about__cloud--d { inset-block-start: 60%;  inset-inline-start: 6%;  width: 13%; }
.about__cloud--e { inset-block-end: -12%;   inset-inline-start: 16%; width: 64%; z-index: 3; }
.about__cloud--f { inset-block-start: -2%;  inset-inline-start: 14%; width: 28%; z-index: 0; }
.about__cloud--g { inset-block-end: 4%;     inset-inline-end: -12%;  width: 21%; }

.about__spiral { inset-block-end: 3%; inset-inline-start: 2%; width: 4rem; }

/* The seam between the news block and مَنْ نَحْنُ: the house cloud stretched
   into two bands, one each side of the edge. Both keep their flat bases on
   the line (the lower band is flipped), so the join reads as one white strip
   with puffs rising into the news and hanging into the sky. It sits above
   the news front clouds (z 5). The upper band stays short so it never
   reaches the slider dots. */
:root {
  --seam-up: clamp(2rem, 4vw, 3.5rem);
  --seam-rise: calc(var(--seam-up) + 0.5rem); /* upper band plus half the join strip */
}
.seam { position: relative; z-index: 6; height: 0; pointer-events: none; }
/* one strip across the join itself, so the two bands never leave a hairline */
.seam::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: -0.5rem;
  height: 1rem;
  background: #fff;
}
/* Each band is one baked vector silhouette (tools/build-assets.py): three
   traced house clouds unioned over a solid floor, so there are no joins to
   show, and it stays sharp however far it stretches. Flush with the page:
   an overhang here would be scrollable in RTL. */
.seam__band {
  position: absolute;
  inset-inline: 0;
  background: #fff;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.seam__band--up {
  inset-block-end: 0;
  height: var(--seam-up);
  -webkit-mask-image: url(../assets/img/seam-up.svg);
  mask-image: url(../assets/img/seam-up.svg);
}
.seam__band--down {
  inset-block-start: 0;
  height: clamp(3.5rem, 8vw, 7.5rem);
  transform: scaleY(-1);
  -webkit-mask-image: url(../assets/img/seam-down.svg);
  mask-image: url(../assets/img/seam-down.svg);
}

@media (min-width: 881px) {
  /* short at the bottom on purpose: the foreground clouds run off the edge */
  .about { padding-block-end: clamp(1.5rem, 3vw, 3rem); }
}

@media (max-width: 880px) {
  .about__grid { grid-template-columns: 1fr; }
  .about__art { order: -1; }
  /* already edge to edge on a phone; 1.5x here would crop the cast */
  .about__stage { width: 136%; margin-inline: -18%; --cast-scale: 1.12; }
  /* The copy sits underneath now, so nothing may hang below the art, and on
     a screen this narrow the clouds keep to the corners, off the cast. */
  .about__cloud--a { inset-block-start: -4%; inset-inline-end: -12%; width: 46vw; }
  .about__cloud--b { inset-block-start: 52%; inset-inline-end: -30%; width: 44vw; }
  .about__cloud--c { inset-inline-start: -10%; width: 30vw; }
  .about__cloud--e { inset-block-end: 0; inset-inline-start: auto; inset-inline-end: -18%; width: 56vw; --blur: 8px !important; }
  .about__cloud--d,
  .about__cloud--g { display: none; }

  /* On a phone the cast is already on screen under the half height news
     block, before the reader has asked for it. It waits blurred under a blue
     fog that about.js lifts with the scroll (--fog: 1 hidden, 0 clear). The
     clouds stay in front of the fog. */
  /* A blur is redrawn from scratch every time its radius changes, and this
     one covers half the screen. --fogstep is the same lift held to a few
     steps (about.js), so the cast is rasterised a handful of times across
     the whole reveal instead of once per frame. The tint on top still
     follows the scroll exactly, which is what the eye is reading. */
  .about__stage { filter: blur(calc(var(--fogstep, 0) * 14px)); }
  .about__art::after {
    content: '';
    position: absolute;
    z-index: 1;
    inset: -2% -18%;
    pointer-events: none;
    background: linear-gradient(to top,
      var(--sky) 0%,
      var(--sky) 38%,
      color-mix(in srgb, var(--sky) 62%, transparent) 72%,
      color-mix(in srgb, var(--sky) 12%, transparent) 100%);
    opacity: var(--fog, 0);
  }
  /* The fog is now the only thing about.js animates on a phone, and it is a
     gradient the width of the screen: promoted, the lift is a composited
     fade instead of a full repaint of that band on every frame. */
  .about.is-live .about__art::after { will-change: opacity; }
  /* bottom corner under the pills, not on top of them */
  .about__spiral { inset-block-end: 1%; inset-inline-start: auto; inset-inline-end: 4%; width: 3rem; }
}

/* =============================================================== work ==== */

/* --glow is the lifted card's colour, pooled into the sky. Registered so
   it fades between cards instead of snapping. */
@property --glow { syntax: '<color>'; inherits: true; initial-value: transparent; }

.work {
  z-index: 5;                 /* سراج falls out from underneath this block */
  background: linear-gradient(to bottom, var(--paper) 0%, #f3f7fa 42%, #e3eef6 100%);
  overflow: clip;
  transition: --glow 700ms ease;
}
.work__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1.5rem; }

.work__sky { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.work__sky .cloud { --cloud-color: #fff; }
.work__glow {
  position: absolute;
  left: 50%;
  top: 62%;
  width: min(92rem, 150vw);
  height: 85%;
  translate: -50% -50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow) 42%, transparent), transparent);
}
.work .marquee, .work__foot { position: relative; z-index: 2; }

/* names the lifted card, or says how the strip works when none is */
.work__foot { display: flex; justify-content: center; }
.work__now {
  margin: 0;
  min-height: 2.4em;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.2rem 0.75rem;
  text-align: center;
  font-size: 0.9375rem;
  color: var(--ink-70);
}
.work__now > * { display: inline-block; }
.work__now b { font-family: var(--display); font-size: 1.375rem; color: var(--ink); }
.work__now em { font-style: normal; font-weight: 600; color: var(--ink); }
.work__now.is-swap > * { animation: work-swap 460ms cubic-bezier(.2,.7,.3,1) both; }
.work__now.is-swap > :nth-child(2) { animation-delay: 50ms; }
.work__now.is-swap > :nth-child(3) { animation-delay: 100ms; }
@keyframes work-swap { from { opacity: 0; transform: translate3d(0, 8px, 0); } }

/* On a mouse, a bubble rides the pointer over the strip and says what a
   press does there. Springs in marquee.js, so it lags like a real thing. */
.work__cursor {
  --ring: transparent;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 30;
  width: 4.6rem;
  height: 4.6rem;
  margin: -2.3rem 0 0 -2.3rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #323232e6;
  color: #fff;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
  box-shadow: 0 0 0 3px var(--ring), 0 12px 30px -12px #0008;
  pointer-events: none;
  transform: scale(0);
  transition: box-shadow 240ms ease;
}
@media (hover: hover) { .work__cursor { will-change: transform; } }
.marquee.has-bubble, .marquee.has-bubble .cover { cursor: none; }

/* The strip (js/marquee.js). It clips instead of hiding its overflow, so
   focusing a card can never scroll it behind the script's back. The block
   padding is room for a lifted, tipped card. pan-y leaves vertical swipes
   to the page and gives sideways ones to the strip. */
.marquee {
  margin-top: clamp(1rem, 2.5vw, 2rem);
  padding-block: clamp(1rem, 2vw, 1.75rem);
  overflow: clip;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  cursor: grab;
  -webkit-mask-image: linear-gradient(to left, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(to left, transparent, #000 4%, #000 96%, transparent);
}
.marquee.is-dragging { cursor: grabbing; }
.marquee__track {
  --lean: 0;
  display: flex;
  align-items: flex-start;
  width: max-content;
  will-change: transform;
}
/* Every cover file carries room for the art that breaks out of its card
   plus its shadow, so neighbours overlap those margins instead of leaving
   them as a gap. A fast strip leans its cards back against the motion. */
.marquee .cover { margin-inline: calc(var(--cw) * -0.09); rotate: calc(var(--lean) * -4deg); }
/* reduced motion: a still row you scroll yourself */
.marquee.is-still { overflow-x: auto; cursor: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.marquee.is-still::-webkit-scrollbar { display: none; }
.marquee.is-still .cover { scroll-snap-align: start; }

/* =========================================================== إنجازاتنا === */

/* The numbers on one side, the award table on the other. The table is a
   collage on a lit patch of the sun: rays behind the photo, clouds in front,
   and every piece placed in % of the table so it all scales as one. */

.wins {
  position: relative;
  z-index: 3;                 /* the floor سراج lands on, and lands over */
  color: var(--ink);
  overflow: clip;
  /* Creamy paper, with a warm patch of light on the side the table sits on
     (the left, in the page's direction) so the rays and the white clouds
     still have something to read against. */
  background:
    radial-gradient(72% 58% at 14% 4%, #ffe7a8 0%, #ffe7a800 64%),
    radial-gradient(58% 52% at 96% 92%, #fdf0cd 0%, #fdf0cd00 72%),
    linear-gradient(to bottom, #fffdf6 0%, #fdf8ea 52%, #fbf4e2 100%);
}
.wins__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 5.5rem);
}
.wins__lead { margin: 1.35rem 0 0; max-width: 40ch; }
.wins__lead--second { font-size: var(--t-body); color: var(--ink-70); }
.wins__stats {
  margin-top: clamp(1.25rem, 2.6vw, 2rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.6rem, 1.2vw, 0.95rem);
}

/* --h is the pointer lift, sprung by wins.js. Each card carries a wash of
   its own accent, never enough to take the text off black. */
.stat {
  --h: 0;
  --tint: var(--stat-accent, var(--ember));
  position: relative;
  display: grid;
  gap: 0.1rem;
  padding: clamp(0.95rem, 1.7vw, 1.3rem) clamp(1.05rem, 1.9vw, 1.45rem);
  border-radius: 18px;
  background: color-mix(in srgb, var(--tint) calc(10% + var(--h) * 6%), #fffefa);
  border: var(--hair) solid color-mix(in srgb, var(--tint) calc(28% + var(--h) * 24%), #fffefa);
  box-shadow: 0 calc(6px + var(--h) * 12px) calc(18px + var(--h) * 16px) -14px color-mix(in srgb, var(--tint) 55%, #32323200);
  translate: 0 calc(var(--h) * -5px);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
}
.stat:active { scale: 0.975; }
.stat__n {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.5rem, 2.4vw, 2.5rem);
  line-height: 1.05;
  white-space: nowrap; /* ٣٧٫٤ ألف is one figure, never two lines */
  color: var(--ink);   /* the colour is in the wash and the mark, not the figure */
}
.stat__l { font-size: 0.875rem; color: var(--ink-70); }
.stat__mark {
  position: absolute;
  inset-block-start: -18%;
  inset-inline-end: -6%;
  width: 5.5rem;
  aspect-ratio: 1;
  opacity: calc(0.14 + var(--h) * 0.2);
  rotate: calc(var(--h) * 24deg);
  scale: calc(1 + var(--h) * 0.16);
}
.stat[data-estimate] .stat__l::after {
  content: '≈';
  margin-inline-start: 0.35em;
  font-weight: 700;
  color: var(--ink-45);
}

/* ---- the award table ----
   Pieces are placed with physical left/top: it is a picture, so it does
   not mirror with the text direction. Sizes inside it are in cqw, a % of
   the table's width. */
.prize {
  --spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12.9 7.6 16.4 11.1 24 12C16.4 12.9 12.9 16.4 12 24C11.1 16.4 7.6 12.9 0 12C7.6 11.1 11.1 7.6 12 0Z'/%3E%3C/svg%3E");
  position: relative;
  z-index: 1;
  width: min(100%, 40rem, 74svh);
  aspect-ratio: 1 / 1.06;
  margin: 0 auto;
  container-type: inline-size;
  isolation: isolate;
}

/* the lit patch: a warm glow, and slow rays turning behind the photo */
.prize__glow {
  position: absolute;
  inset: -12% -16%;
  z-index: 0;
  background: radial-gradient(closest-side at 50% 40%, #ffe08f 0%, #ffdf8a00 100%);
}
.prize__rays {
  position: absolute;
  left: 50%;
  top: 38%;
  width: 150%;
  aspect-ratio: 1;
  translate: -50% -50%;
  z-index: 0;
  background: repeating-conic-gradient(#f6c53a5c 0deg 5deg, #fff0 5deg 15deg);
  -webkit-mask: radial-gradient(closest-side, #000 12%, #0000 70%);
  mask: radial-gradient(closest-side, #000 12%, #0000 70%);
  animation: prize-turn 90s linear infinite;
}
@keyframes prize-turn { to { rotate: 1turn; } }
.prize__glow,
.prize__rays { transition: opacity 1.2s ease, scale 1.6s cubic-bezier(.2,.7,.3,1); }
.prize.is-armed:not(.is-in) :is(.prize__glow, .prize__rays) { opacity: 0; scale: 0.6; }

/* --e is the entrance (0 off the table, 1 down on it, overshooting a
   little on the way), --h the pointer lift, --px/--py the parallax in px.
   Each piece sets its resting tilt (--r), where it is dealt in from (--fx,
   --fy, --fr) and how far the lift straightens it (--level). */
.prize__piece {
  --e: 1;
  --h: 0;
  --px: 0;
  --py: 0;
  position: absolute;
  translate:
    calc(var(--px) * 1px + (1 - var(--e)) * var(--fx, -150%))
    calc(var(--py) * 1px + (1 - var(--e)) * var(--fy, 0%) - var(--h) * 10px);
  rotate: calc(var(--r, 0deg) * (1 - var(--h) * var(--level, 0.5)) + (1 - var(--e)) * var(--fr, -24deg));
  scale: calc(1 + var(--h) * 0.045);
  opacity: clamp(0, var(--e) * 4, 1);
}
.prize.is-armed .prize__piece { --e: 0; }

.prize__card {
  position: relative;
  background: #fff;
  box-shadow: 0 calc(12px + var(--h) * 18px) calc(26px + var(--h) * 24px) -14px #6e4c0073;
  transition: scale 140ms cubic-bezier(.2,.7,.3,1);
}
/* feedback lands on the press */
.prize__piece:active .prize__card { scale: 0.97; transition-duration: 80ms; }
.prize__card img { width: 100%; height: auto; }

/* the red grin, drawn behind the photo */
.prize__grin {
  left: -4%; top: 25%; width: 37%;
  aspect-ratio: 59.77 / 60.75;
  z-index: 2;
  --r: -16deg; --fx: -180%; --fy: 10%; --fr: -60deg;
}
.prize__grin .mark {
  width: 100%;
  height: 100%;
  --mark-color: var(--ember);
  scale: calc(1 + var(--chomp, 0) * 0.14) calc(1 - var(--chomp, 0) * 0.14);
}

/* the photo from the night. It tilts toward the pointer, and light follows. */
.prize__photo {
  left: 29%; top: 3%; width: 45%;
  z-index: 3;
  --r: 6deg; --fx: -150%; --fy: 8%; --fr: -24deg;
  --tx: 0; --ty: 0;
}
.prize__photo .prize__card {
  padding: 1.5cqw;
  border-radius: 5cqw;
  transform: perspective(70cqw)
             rotateX(calc(var(--ty) * var(--h) * -8deg))
             rotateY(calc(var(--tx) * var(--h) * 10deg));
}
.prize__photo img { border-radius: 3.6cqw; }
.prize__glare {
  position: absolute;
  inset: 1.5cqw;
  border-radius: 3.6cqw;
  background: radial-gradient(circle at calc(50% + var(--tx) * 50%) calc(50% + var(--ty) * 50%), #ffffffb3, transparent 55%);
  mix-blend-mode: soft-light;
  opacity: var(--h);
  pointer-events: none;
}

/* the award's own mark, in its own colours, on a white plaque */
.prize__plaque {
  left: 52%; top: 61%; width: 41%;
  z-index: 4;
  --r: -5deg; --fx: -110%; --fy: 45%; --fr: -22deg;
}
.prize__plaque .prize__card { padding: 2.4cqw 3cqw; border-radius: 3.2cqw; }

/* a still from the film that won, taped down like a polaroid */
.prize__still {
  left: 3%; top: 57%; width: 31%;
  z-index: 5;
  --r: -9deg; --level: 1; --fx: -210%; --fr: -34deg;
}
.prize__still .prize__card { padding: 1.8cqw 1.8cqw 6.5cqw; border-radius: 0.8cqw; background: #fbfaf9; }
.prize__still img { aspect-ratio: 1; object-fit: cover; border-radius: 0.4cqw; }
.prize__tape {
  position: absolute;
  z-index: 1;
  top: -1.2cqw;
  right: -3cqw;
  width: 12cqw;
  height: 3.6cqw;
  rotate: 38deg;
  background: #f6e6bcc7;
  box-shadow: 0 0.2cqw 0.6cqw #0000001f;
}

/* المركز الثاني: a seal with two ribbon tails. It stamps down last,
   from big to its size, so the entrance scale rides on --e too. */
.prize__medal {
  left: 63%; top: 0; width: 27%;
  z-index: 6;
  --r: 10deg; --fx: 0%; --fy: 0%; --fr: 40deg;
  scale: calc((1 + var(--h) * 0.08) * (1 + (1 - var(--e)) * 1.4));
}
.prize__medal .prize__card {
  background: none;
  box-shadow: none;
  isolation: isolate;
  rotate: calc(var(--spin, 0) * 1deg);
}
.prize__seal {
  position: relative;
  isolation: isolate;
  aspect-ratio: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  color: #fff;
  text-align: center;
  filter: drop-shadow(0 1.2cqw 1.4cqw #6e4c0066);
}
/* three rounded squares at 30° apart make the twelve soft points */
.prize__seal i {
  position: absolute;
  inset: 10%;
  z-index: -1;
  border-radius: 24%;
  background: var(--ink);
}
.prize__seal i:nth-child(2) { rotate: 30deg; }
.prize__seal i:nth-child(3) { rotate: 60deg; }
.prize__seal::after {
  content: '';
  position: absolute;
  inset: 15%;
  z-index: -1;
  border-radius: 50%;
  border: max(1px, 0.35cqw) dashed #fbfaf973;
}
.prize__seal b {
  font-family: var(--display);
  font-weight: 800;
  font-size: 11cqw;
  line-height: 1;
  color: var(--sun);
  margin-block: -1.2cqw -0.4cqw;
}
.prize__seal span {
  font-family: var(--display);
  font-weight: 700;
  font-size: max(0.625rem, 2.7cqw);
  line-height: 1.25;
  white-space: nowrap;
}
.prize__ribbon {
  position: absolute;
  top: 58%;
  width: 26%;
  height: 64%;
  z-index: -1;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 82%, 0 100%);
}
.prize__ribbon--a { left: 22%; background: var(--sky); rotate: 18deg; }
.prize__ribbon--b { right: 22%; background: var(--mint); rotate: -16deg; }

/* sparks: a few twinkling around the photo, and a burst (wins.js) each
   time the medal lands or is touched */
.prize__sparks {
  position: absolute;
  inset: 0;
  z-index: 7;
  pointer-events: none;
  transition: opacity 0.8s ease 1.1s;
}
.prize.is-armed:not(.is-in) .prize__sparks { opacity: 0; transition: none; }
.prize__sparks i,
.prize__burst {
  position: absolute;
  width: calc(var(--s, 1) * 3.2cqw);
  aspect-ratio: 1;
  background: var(--c, var(--sun));
  -webkit-mask: var(--spark) center / contain no-repeat;
  mask: var(--spark) center / contain no-repeat;
  pointer-events: none;
}
.prize__sparks i {
  left: var(--x);
  top: var(--y);
  translate: -50% -50%;
  animation: prize-twinkle var(--t, 3s) ease-in-out var(--d, 0s) infinite;
}
@keyframes prize-twinkle {
  0%, 100% { opacity: 0.2; scale: 0.35; rotate: 0deg; }
  50%      { opacity: 1;   scale: 1;    rotate: 45deg; }
}

/* the house cloud, twice behind the table and three times in front of it.
   Drift is transform (util.js), the entrance is translate. */
.prize .cloud {
  --cloud-color: #fff;
  filter: blur(var(--blur, 0px)) drop-shadow(0 0.6cqw 0.9cqw #c9a14a38);
  transition: translate 1.3s cubic-bezier(.2,.7,.3,1), opacity 1.3s ease;
}
.prize.is-armed:not(.is-in) .cloud { translate: 0 45%; opacity: 0; }
.prize__cloud--back { left: 2%;   top: -6%; width: 34%; z-index: 1; opacity: 0.7; }
.prize__cloud--side { left: 78%;  top: 18%; width: 28%; z-index: 1; opacity: 0.85; transition-delay: 150ms; }
.prize__cloud--a    { left: -16%; top: 86%; width: 50%; z-index: 8; transition-delay: 700ms; }
.prize__cloud--b    { left: 36%;  top: 90%; width: 48%; z-index: 8; transition-delay: 850ms; }
.prize__cloud--c    { left: 80%;  top: 46%; width: 30%; z-index: 8; opacity: 0.9; transition-delay: 1000ms; }

@media (max-width: 999px) {
  .wins__layout { grid-template-columns: minmax(0, 1fr); }
  .prize { width: min(100%, 34rem); margin-top: clamp(0.5rem, 3vw, 1.5rem); }
  /* stacked, the table fills this corner and the plaque would sit on it */
  .wins__asterisk { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .prize__rays,
  .prize__sparks i { animation: none; }
  .prize__sparks i { opacity: 0.85; scale: 0.8; }
  .stat:hover,
  .stat:focus-visible { background: #fffdf6; }
}

/* ============================================================= voices ==== */

.voices {
  position: relative;
  z-index: 4;                 /* under .work, over .wins so he lands on top of it */
  background: var(--void);
  color: #fff;
  /* All 69 frames still play: they are mapped to a scroll fraction, so a
     shorter section scrubs the same frames over less thumb travel. */
  height: 300svh;
}

.voices__sky {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(72% 46% at 16% 10%, #0084c13d 0%, transparent 64%),
    radial-gradient(54% 38% at 86% 34%, #f565491a 0%, transparent 60%),
    radial-gradient(80% 52% at 50% 92%, #45c4b92e 0%, transparent 66%),
    var(--void);
}

.voices__stage {
  position: sticky;
  top: 0;
  height: 100svh;
}
/* the clip the stars, the intro and the comment field live inside */
.voices__clip { position: absolute; inset: 0; overflow: hidden; }

.voices__stars { position: absolute; inset: 0; width: 100%; height: 100%; }

/* The header rides above سراج (6) and the featured comments (7), so he
   falls behind the words instead of across them. JS fades it through --fade. */
.voices__intro {
  position: absolute;
  z-index: 8;
  inset-block-start: clamp(4.5rem, 12vh, 8rem);
  inset-inline-start: var(--gutter);
  max-width: min(34ch, 40vw);
  pointer-events: none;
}
.voices__intro > :not(.voices__veil) {
  position: relative;
  z-index: 1;
  opacity: var(--fade, 1);
}
.voices__intro .eyebrow { color: #ffffff94; }
.voices__intro .h2 { color: #fff; }
.voices__intro p { color: #ffffffcc; font-size: var(--t-body); }

/* A frosted pool behind the header, strongest under the words and melting
   to nothing at its edges, the way Control Center frosts what is behind it.
   Three stacked blurs, each masked tighter than the last, make the falloff
   progressive instead of one hard lens. Only the layers themselves carry
   opacity and masks: on an ancestor those would cut the blur off from the
   page behind it. */
.voices__veil {
  position: absolute;
  inset: -5.5rem -7rem -6rem;
  pointer-events: none;
}
.voices__veil i {
  position: absolute;
  inset: 0;
  opacity: var(--fade, 1);
  -webkit-mask-image: radial-gradient(closest-side, #000 var(--core), transparent var(--edge));
  mask-image: radial-gradient(closest-side, #000 var(--core), transparent var(--edge));
}
.voices__veil i:nth-child(1) {
  --core: 55%; --edge: 100%;
  background: radial-gradient(closest-side, #0b0b12b8 35%, #0b0b1200);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.voices__veil i:nth-child(2) {
  --core: 45%; --edge: 85%;
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
}
.voices__veil i:nth-child(3) {
  --core: 30%; --edge: 70%;
  -webkit-backdrop-filter: blur(26px);
  backdrop-filter: blur(26px);
}

.voices__field { position: absolute; inset: 0; z-index: 2; }
.voices__front { position: absolute; inset: 0; z-index: 7; pointer-events: none; }

.vcomment {
  /* physical left/top: the JS positions these in physical pixels, and
     inset-inline-start would anchor them to the right edge under RTL */
  position: absolute;
  top: 0;
  left: 0;
  width: 21rem;
  max-width: 62vw;
  display: flex;
  gap: 0.7rem;
  padding: 0.85rem 0.95rem;
  border-radius: 14px;
  background: #16161fef;
  border: 1px solid #ffffff14;
  box-shadow: 0 18px 40px -22px #000;
  transform-origin: 50% 50%;
}
.vcomment__pfp {
  flex: none;
  width: 2.15rem; height: 2.15rem;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9rem;
  color: #14141c;
  position: relative;
  overflow: hidden;
}
.vcomment__pfp img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vcomment__main { min-width: 0; }
.vcomment__top { display: flex; gap: 0.5rem; align-items: baseline; font-size: 0.75rem; }
/* plaintext: a Latin handle reads LTR, an Arabic one reads RTL with the @ in
   front of it, the way YouTube shows both */
.vcomment__u { font-weight: 600; color: #fff; direction: ltr; unicode-bidi: plaintext; }
.vcomment__at { color: #ffffff6b; }
.vcomment__t { margin: 0.2rem 0 0.45rem; font-size: 0.875rem; line-height: 1.55; color: #ffffffe0; white-space: pre-line; }
.vcomment__acts { display: flex; align-items: center; gap: 0.75rem; font-size: 0.75rem; color: #ffffff8a; }
.vcomment__acts svg { width: 0.95rem; height: 0.95rem; fill: currentColor; }
.vcomment__acts b { font-weight: 500; }
.vcomment__reply { color: #ffffffb5; font-weight: 500; }
/* the channel's own avatar with a small heart: the creator liked this one */
.vcomment__loved {
  position: relative;
  width: 1.1rem; height: 1.1rem;
  border-radius: 50%;
  background: #000 url(../assets/img/logo-mark.webp) center / cover;
}
.vcomment__acts .vcomment__loved svg {
  position: absolute;
  right: -0.32rem; bottom: -0.22rem;
  width: 0.62rem; height: 0.62rem;
  fill: #ff3040;
}

/* --- message types in the field ------------------------------------------
   Four surfaces, so the field reads like a real spread of places people
   talk about the studio rather than one repeated card.                   */

.vcomment--x { background: #15181cf5; }
.vcomment--x .vcomment__acts svg { width: 0.9rem; }

.vmsg {
  position: absolute;
  top: 0;
  left: 0;
  width: 17rem;
  max-width: 60vw;
  padding: 0.55rem 0.75rem 0.4rem;
  border-radius: 12px;
  font-size: 0.9375rem;
  line-height: 1.5;
  box-shadow: 0 14px 34px -20px #000;
  transform-origin: 50% 50%;
}
.vmsg__t { margin: 0; }
.vmsg__meta {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  justify-content: flex-start;
  font-size: 0.625rem;
  margin-top: 0.15rem;
  opacity: 0.65;
}
.vmsg__tick { display: inline-flex; width: 1rem; }
.vmsg__tick svg { width: 100%; }

/* outgoing: the green bubble, with the tail on the reading-start side */
.vmsg--wa {
  background: #075e54;
  color: #eaf6f2;
  border-start-start-radius: 4px;
}
.vmsg--wa .vmsg__tick { color: #62d6f3; }

/* incoming: light bubble, the contrast note in a dark field */
.vmsg--wi {
  background: #f4f2ee;
  color: #1d1d1f;
  border-start-end-radius: 4px;
}

/* A filler card's words. js/fall.js draws every background row as bars, never
   as text, so a device that loses the blur shows shapes and nothing to read. */
.vbar {
  display: block;
  max-width: 100%;
  height: 0.5em;
  margin: 0.5em 0;
  border-radius: 99px;
  background: currentColor;
  opacity: 0.42;
}
.vcomment__top .vbar,
.vcomment__acts .vbar,
.vmsg__meta .vbar { margin: 0.3em 0; }
.vcomment__top .vbar:first-child { opacity: 0.7; }

.voices__siraj,
.voices__rim {
  position: absolute;
  z-index: 6;                 /* deliberately outside the clip */
  top: 0;
  left: 0;
  pointer-events: none;
  will-change: transform;
}
/* His white hairline, directly under him. Overlay, so where it crosses stars
   and cards it lifts them instead of drawing a flat line over them. The stage
   is its own stacking context, so over empty sky there is nothing to blend
   with and it shows as plain white: the opacity is what keeps it slight. */
.voices__rim { mix-blend-mode: overlay; opacity: 0.45; }

/* Once he has landed the section folds to one screen, so going back up is
   one screen, not the whole fall again. fall.js keeps everything on screen
   still across the fold, and unfolds it once it is out of sight below. */
.voices.is-short { height: 100svh; }

.voices__floorglow {
  position: absolute;
  z-index: 3;
  inset-inline: 0;
  inset-block-end: 0;
  height: 13vh;
  background: linear-gradient(to top, #fbfaf91c, transparent);
  opacity: 0;
  transition: opacity 420ms ease;
  pointer-events: none;
}
.voices.is-landed .voices__floorglow { opacity: 1; }

/* --- featured comments -----------------------------------------------------
   The handful you are meant to read. Sharp, lit, and frosted, so سراج shows
   through softly when one passes over him. Everything else is out of focus. */
.vcomment.is-hi,
.vmsg.is-hi {
  box-shadow: inset 0 1px 0 #ffffff1f, 0 26px 50px -22px #000d;
}
/* The field is sixty cards, and it only moves while the fall is running
   (js/util.js sets `.is-live` a third of a screen early). `filter` is set
   once per card by js/fall.js and never touched again, so naming it here
   would buy a standing layer for something that does not animate. */
.voices.is-live .vcomment,
.voices.is-live .vmsg { will-change: transform; }
.vcomment.is-hi {
  background: #1a1a25c7;
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
  border-color: #ffffff2b;
}
.vcomment--x.is-hi { background: #171b20cc; }
.vmsg--wa.is-hi {
  background: #075e54e0;
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
}

@media (max-width: 760px) {
  .voices { height: 280svh; }
  .voices__intro { max-width: none; inset-inline-end: var(--gutter); }
  .voices__veil { inset: -4rem -3rem -4.5rem; }
  .vcomment { width: 12rem; padding: 0.6rem 0.65rem; }
  .vcomment__t { font-size: 0.75rem; }
  .vcomment__pfp { width: 1.7rem; height: 1.7rem; font-size: 0.75rem; }
  .vmsg { width: 9.5rem; font-size: 0.75rem; padding: 0.45rem 0.6rem 0.35rem; }

  /* on a phone there is no room beside him, so the featured cards take most
     of the width and pass over him instead */
  .vcomment.is-hi { width: min(78vw, 20rem); max-width: none; padding: 0.8rem 0.85rem; }
  .vcomment.is-hi .vcomment__t { font-size: 0.875rem; }
  .vcomment.is-hi .vcomment__pfp { width: 2rem; height: 2rem; font-size: 0.85rem; }
  .vmsg.is-hi { width: min(72vw, 16rem); max-width: none; font-size: 0.9375rem; padding: 0.55rem 0.75rem 0.4rem; }
}

@media (prefers-reduced-transparency: reduce) {
  .voices__veil i { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .voices__veil i:nth-child(1) { background: radial-gradient(closest-side, #0b0b12f0 45%, #0b0b1200); }
  .vcomment.is-hi, .vmsg.is-hi { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .vcomment.is-hi { background: #1a1a25; }
  .vmsg--wa.is-hi { background: #075e54; }
}

/* ========================================================= كيف أساهم؟ === */

/* A night sky under إنجازاتنا, deepening to navy at the bottom. */
.contribute {
  position: relative;
  z-index: 2;                 /* under .wins, so سراج's overhang never reaches it */
  background: var(--void);
  color: #fff;
  overflow: clip;
}
.contribute :focus-visible { outline-color: #fff; }

.contribute__sky {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 20% 30%, #ffffffc4 0 1px, transparent 1.6px) 0 0 / 190px 170px,
    radial-gradient(circle at 70% 62%, #ffffff8f 0 0.8px, transparent 1.4px) 0 0 / 233px 211px,
    radial-gradient(circle at 44% 86%, #ffffff75 0 1.2px, transparent 1.8px) 0 0 / 311px 269px,
    radial-gradient(circle at 86% 14%, #ffffff8c 0 0.7px, transparent 1.3px) 0 0 / 149px 131px,
    linear-gradient(to bottom, var(--void) 0%, #0a1224 58%, #0d2b4b 100%);
}

.contribute__head { display: grid; justify-items: center; text-align: center; }
.contribute .eyebrow { color: #ffffff6b; justify-content: center; }
.contribute__title { display: inline-flex; align-items: center; gap: 0.14em; color: #fff; }
.contribute__spark {
  --mark-color: var(--sun);
  width: 0.72em;
  aspect-ratio: 1;
  translate: 0 -0.14em;
  animation: twinkle 3.6s ease-in-out infinite alternate;
}
@keyframes twinkle {
  from { transform: rotate(-8deg) scale(0.92); }
  to   { transform: rotate(6deg) scale(1.04); }
}
.contribute .lead {
  margin: 0.9rem auto 0;
  max-width: 54ch;
  font-size: clamp(1rem, 1.25vw, 1.1875rem);
  color: #ffffffb3;
  text-wrap: balance;
}

/* ---- the three cards ----
   --h is the card's hover (0 to 1), --c the character's, --mx and --my the
   pointer across the card (-1 to 1). All four are springs in contribute.js,
   so every transform here is just a function of them. */

.ways__wrap { position: relative; margin-top: clamp(2.5rem, 5vw, 4rem); }

.ways {
  --star-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 26 26'%3E%3Cpath d='M12 1.6l3.1 6.6 7.2.9-5.3 4.9 1.4 7.1L12 17.6l-6.4 3.5 1.4-7.1L1.7 9.1l7.2-.9z'/%3E%3C/svg%3E");
  --star-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 26 26'%3E%3Cpath d='M12 1.6l3.1 6.6 7.2.9-5.3 4.9 1.4 7.1L12 17.6l-6.4 3.5 1.4-7.1L1.7 9.1l7.2-.9z' fill='none' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 66rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 3.6vw, 4rem);
}

.way { --h: 0; --c: 0; --mx: 0; --my: 0; position: relative; }

.way__hit {
  display: grid;
  justify-items: center;
  text-align: center;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 320ms ease, scale 420ms cubic-bezier(.2,.7,.3,1);
}
.way__hit:focus-visible { outline: none; }
.way__hit:focus-visible .way__card { outline: 3px solid #fff; outline-offset: 5px; }

/* one lit card at a time: the others step back */
.ways:has(.is-hot) .way:not(.is-hot) .way__hit { opacity: 0.72; scale: 0.97; }

.way__card {
  position: relative;
  width: 100%;
  aspect-ratio: 5 / 7;
  container-type: inline-size;
  border: clamp(4px, 0.42vw, 6px) solid var(--rim);
  border-radius: clamp(18px, 2vw, 26px);
  background: var(--way);
  overflow: hidden;
  isolation: isolate;
  /* pressed where the pointer is, lifted by the hover */
  transform: perspective(900px)
             translate3d(0, calc(var(--h) * -10px), 0)
             rotateX(calc(var(--my) * -7deg))
             rotateY(calc(var(--mx) * 7deg));
  box-shadow:
    0 calc(14px + var(--h) * 22px) calc(34px + var(--h) * 26px) -20px color-mix(in srgb, var(--way) 70%, #000),
    inset 0 1px 0 #ffffff59;
  transition: scale 160ms cubic-bezier(.2,.7,.3,1);
}
.way__hit:hover .way__card,
.way__hit:focus-within .way__card { will-change: transform; }
.way__hit:active .way__card { scale: 0.975; transition-duration: 90ms; }

/* a lighter pool of the card colour behind the character */
.way__card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(76% 56% at 50% 62%, color-mix(in srgb, #fff 32%, var(--way)), transparent 72%);
  opacity: calc(0.55 + var(--h) * 0.45);
}
/* light catching the card, following the pointer */
.way__card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: radial-gradient(circle at calc(50% + var(--mx) * 50%) calc(50% + var(--my) * 50%), #ffffff70, transparent 46%);
  mix-blend-mode: soft-light;
  opacity: var(--h);
}

.way__title {
  position: absolute;
  z-index: 3;
  inset-block-start: 11cqi;
  inset-inline: 5cqi;
  margin: 0;
  font-size: 22cqi;
  line-height: 1.15;
  color: var(--title, #fff);
  text-shadow: 0 2px 0 #0000001f;
  transform: translate3d(calc(var(--mx) * -4px), calc(var(--my) * -3px), 0);
}

/* The character layer. It moves further than the card and toward the
   pointer, so it reads as standing in front of the card face. Each card
   sets how far its character rises, tips and grows. */
.way__art {
  position: absolute;
  z-index: 1;
  inset: 0;
  transform-origin: 50% 100%;
  transform: translate3d(calc(var(--mx) * 10px), calc(var(--my) * 6px + var(--c) * var(--rise, -14px)), 0)
             rotate(calc(var(--c) * var(--tip, 0deg)))
             scale(calc(1 + var(--c) * var(--grow, 0.06)));
  -webkit-mask-image: linear-gradient(to top, transparent 5%, #000 34%);
  mask-image: linear-gradient(to top, transparent 5%, #000 34%);
}
.way__char { position: absolute; inset-inline: 0; margin-inline: auto; max-width: none; }

.way--jump .way__art { --rise: -18px; --tip: -4deg; --grow: 0.07; }
/* his PNG carries a transparent glow on its right, so the drawn figure sits
   at 37% of the file's width. Shift by the difference to centre the figure. */
.way--jump .way__char { inset-block-start: 34cqi; width: 92%; translate: 13% 0; }

.way--sheikh .way__art { --rise: -12px; --tip: 3deg; --grow: 0.05; transform-origin: 40% 100%; }
.way--sheikh .way__char { inset-block-start: 41cqi; width: 90%; }

/* the cast barely rises: its tallest head already sits under the title */
.way--cast .way__art { --rise: -4px; --grow: 0.06; }
.way__video {
  position: absolute;
  inset-block-start: 20cqi;
  left: 50%;
  height: 138cqi;
  width: auto;
  max-width: none;
  aspect-ratio: 2016 / 1440;
  translate: -50% 0;
  /* the decoded blue never quite matches the card, so the top edge fades in */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 18%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 18%);
}

.way__stars {
  position: absolute;
  z-index: 3;
  inset-inline: 0;
  inset-block-end: 6cqi;
  display: flex;
  justify-content: center;
  gap: 1.6cqi;
  filter: drop-shadow(0 2px 0 #00000026);
}
.way__stars i {
  width: 13.5cqi;
  aspect-ratio: 1;
  background: #fff;
  -webkit-mask: var(--star-off) center / contain no-repeat;
  mask: var(--star-off) center / contain no-repeat;
  transition: transform 420ms cubic-bezier(.3,1.5,.5,1) calc(var(--i, 0) * 45ms);
}
.way__stars i.is-on { -webkit-mask-image: var(--star-on); mask-image: var(--star-on); }
.way__stars i:nth-child(2) { --i: 1; }
.way__stars i:nth-child(3) { --i: 2; }
.way__stars i:nth-child(4) { --i: 3; }
.way__stars i:nth-child(5) { --i: 4; }
.way.is-hot .way__stars i { transform: translateY(-3px) scale(1.1); }
.way.is-hot .way__stars i.is-on { transform: translateY(-4px) scale(1.2); }

.way__desc {
  margin-top: clamp(0.9rem, 1.6vw, 1.25rem);
  max-width: 30ch;
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem);
  font-weight: 500;
  line-height: 1.55;
  color: #ffffffe0;
  text-wrap: balance;
}
.way__cta {
  margin-top: 0.55rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(0.9375rem, 1.05vw, 1.0625rem);
  color: #fff;
  /* the underline grows out of the start edge with the hover */
  background: linear-gradient(var(--line), var(--line)) 100% 100% / calc(30% + var(--h) * 70%) 2px no-repeat;
}
.way__cta span { transform: translateX(calc(var(--h) * -5px)); }

/* the foreground clouds: the big one parts when its card is hovered */
.ways__wrap .cloud { --cloud-color: #fff; z-index: 3; filter: blur(var(--blur, 0px)); transition: translate 700ms cubic-bezier(.2,.7,.3,1); }
.contribute__cloud--a { inset-block-start: 22%; inset-inline-end: -17%; width: 34%; opacity: 0.94; }
.contribute__cloud--b { inset-block-start: 43%; inset-inline-end: -6%; width: 17%; opacity: 0.8; }
.contribute__cloud--c { inset-block-end: 2%; inset-inline-start: -15%; width: 28%; opacity: 0.45; }
.ways:has(.way--cast.is-hot) ~ .contribute__cloud--a { translate: -9% 0; }
.ways:has(.way--cast.is-hot) ~ .contribute__cloud--b { translate: -14% 0; }

/* Phones: one swipe row, the middle card snapped to the centre and its
   neighbours peeking in from either side. */
@media (max-width: 820px) {
  .ways {
    max-width: none;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: min(70vw, 19rem);
    gap: 1rem;
    margin-inline: calc(var(--gutter) * -1);
    padding: 1.5rem calc(50vw - min(35vw, 9.5rem)) 0.75rem;
    /* overflow-x alone turns overflow-y to auto as well, and the lifted
       cards overhang the row by a few pixels, so a vertical swipe used to
       scroll the row instead of the page. Hidden clips exactly what auto
       already clipped, it only drops the vertical scroll. */
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .ways::-webkit-scrollbar { display: none; }
  .way { scroll-snap-align: center; }
  .contribute__cloud--a { inset-block-start: 30%; inset-inline-end: -30%; width: 54%; }
  .contribute__cloud--b { display: none; }
  .contribute__cloud--c { inset-inline-start: -24%; width: 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .contribute__spark { animation: none; }
  .way__card, .way__art, .way__title, .way__stars i, .way__cta span { transform: none !important; }
  .way__stars i, .ways__wrap .cloud { transition: none; }
}

/* ========================================================== community === */

/* Dawn after the night of كيف أساهم. The same z-index as both neighbours, so
   page order stacks them: this sky paints over كيف أساهم, and the footer's
   cloud bank rises over this sky. The bottom padding keeps that bank
   (--foot-rise) clear of everything here. It clips sideways only. */
.community {
  z-index: 2;
  overflow-x: clip;
  color: #fff;
  background: linear-gradient(to bottom, #0d2b4b 0%, #0b4f86 22%, #1479bb 48%, #4aa9e0 72%, #a9dcf5 90%, #d6effa 100%);
  padding-block-end: calc(var(--bay) + var(--foot-rise));
}
.community :focus-visible { outline-color: #fff; }

.community__sky { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
/* the last of the night's stars, going out as the sky lightens */
.community__sky::before {
  content: '';
  position: absolute;
  inset: 0 0 50%;
  background:
    radial-gradient(circle at 20% 30%, #ffffffb3 0 1px, transparent 1.6px) 0 0 / 190px 170px,
    radial-gradient(circle at 70% 62%, #ffffff80 0 0.8px, transparent 1.4px) 0 0 / 233px 211px,
    radial-gradient(circle at 44% 86%, #ffffff66 0 1.2px, transparent 1.8px) 0 0 / 311px 269px;
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
  mask-image: linear-gradient(to bottom, #000, transparent);
}
/* the sun coming up behind the call */
.community__sun {
  position: absolute;
  inset-inline-end: -12%;
  inset-block-end: -32%;
  width: min(70rem, 120vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, #F7D03873, #F5654930 45%, transparent);
}
.community__sky .cloud { --cloud-color: #fff; filter: blur(var(--blur, 0px)); }

.community__grid {
  display: grid;
  gap: clamp(3rem, 7vw, 4.5rem);
  align-items: center;
}
.community .eyebrow { color: #ffffffa3; }
/* lit like مَنْ نَحْنُ: the clipped fill only paints inside the box, so pad
   the top for the tashkeel and give it back in the margin */
.community__title {
  line-height: 1.25;
  padding-block: 0.3em 0.05em;
  margin-block: -0.4em 0;
}
.community__lead {
  margin: 0.6rem 0 0;
  max-width: 42ch;
  font-size: clamp(1rem, 1.25vw, 1.1875rem);
  color: #ffffffe0;
}
.community__where { margin-top: clamp(1.75rem, 3.2vw, 2.5rem); }
.community__sub { margin-block-end: clamp(1rem, 1.8vw, 1.4rem); color: #fff; }

/* ---- أَيْنَ تَجِدُنَا؟: four stickers taped to the sky ----
   --tilt is each one's slant (ambient.js) and --h its hover, sprung by
   community.js: it peels the sticker up and straightens it. The individual
   translate, rotate and scale properties never fight [data-rise]'s
   transform, so both run. */
.finds {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.9rem, 1.8vw, 1.35rem);
}
.find {
  --find: var(--ember);
  --tilt: 0deg;
  --h: 0;
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 0.8rem;
  align-items: center;
  padding: clamp(0.85rem, 1.5vw, 1.1rem);
  padding-inline-end: 2.2rem;
  border-radius: 16px;
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  box-shadow:
    0 calc(10px + var(--h) * 14px) calc(22px + var(--h) * 18px) -14px #05386bb0,
    inset 0 -3px 0 #0000000d;
  translate: 0 calc(var(--h) * -6px);
  rotate: calc(var(--tilt) * (1 - var(--h)));
  -webkit-tap-highlight-color: transparent;
  transition:
    opacity 620ms cubic-bezier(.2,.7,.3,1) var(--rise-delay, 0ms),
    transform 620ms cubic-bezier(.2,.7,.3,1) var(--rise-delay, 0ms),
    scale 140ms cubic-bezier(.2,.7,.3,1);
}
.find:active { scale: 0.97; transition-duration: 620ms, 620ms, 80ms; }
.find:focus-visible { outline-offset: 4px; }
.find__tape {
  position: absolute;
  inset-block-start: -0.6rem;
  inset-inline-end: 1.4rem;
  width: 3.4rem;
  height: 1.15rem;
  background: color-mix(in srgb, var(--find) 55%, #fff);
  opacity: 0.92;
  rotate: calc(var(--tilt) * -3);
  clip-path: polygon(0 12%, 5% 0, 12% 10%, 20% 0, 80% 6%, 88% 0, 95% 10%, 100% 0, 100% 88%, 94% 100%, 86% 90%, 78% 100%, 18% 94%, 10% 100%, 4% 90%, 0 100%);
}
.find__blob {
  grid-row: 1 / span 3;
  display: grid;
  place-items: center;
  width: clamp(2.9rem, 3.8vw, 3.4rem);
  aspect-ratio: 1;
  border-radius: 46% 54% 58% 42% / 52% 44% 56% 48%;
  background: var(--find);
  rotate: calc(var(--h) * -10deg);
  scale: calc(1 + var(--h) * 0.1);
}
/* each platform's own colours behind its own mark */
.find__blob { background: var(--brand, var(--find)); color: #fff; }
.find__blob svg { width: 54%; height: auto; }
.find[data-id="yt"] { --brand: #ff0033; }
.find[data-id="ig"] .find__blob { background: radial-gradient(circle at 30% 107%, #fdf497 0 5%, #fd5949 45%, #d6249f 60%, #285aeb 90%); }
.find[data-id="tt"] { --brand: #111; }
.find[data-id="tt"] .find__blob svg { filter: drop-shadow(-1.6px -1.2px 0 #25f4ee) drop-shadow(1.6px 1.2px 0 #fe2c55); }
.find[data-id="dc"] { --brand: #5865f2; }
.find__n { font-family: var(--display); font-weight: 700; font-size: clamp(1.15rem, 1.45vw, 1.35rem); line-height: 1.25; }
.find__h {
  justify-self: start;
  direction: ltr;
  unicode-bidi: isolate;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.4;
  color: color-mix(in srgb, var(--find) 45%, var(--ink));
}
.find__note { font-size: 0.8125rem; line-height: 1.45; color: var(--ink-70); }
.find__go {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 0.9rem;
  translate: calc(var(--h) * -5px) -50%;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.15rem;
  color: color-mix(in srgb, var(--find) 60%, var(--ink));
  opacity: calc(0.45 + var(--h) * 0.55);
}

/* ---- the call ----
   A drawing of نادي المدونة's voice room in Discord's own dark. On a tile
   --h is the hover and --k its سراج's hop, both springs in community.js.
   The real server peeks out from behind it and does not move. */
.call {
  --dc-bg: #1b1c21;
  --dc-tile: #2b2d34;
  --dc-text: #f2f3f5;
  --dc-mute: #a3a9b3;
  --dc-talk: #3ad07a;
  position: relative;
  margin: 0;
  padding-block-start: clamp(2.25rem, 4vw, 3.25rem);
}

.call__peek {
  position: absolute;
  z-index: 1;
  inset-block-start: 0;
  inset-inline-end: -3%;
  width: 50%;
  border-radius: 12px;
  overflow: hidden;
  background: #111;
  box-shadow: 0 26px 50px -26px #021a33, 0 0 0 1px #ffffff26;
  rotate: -7deg;
}
.call__peek img { width: 100%; }
.call__note {
  position: absolute;
  z-index: 5;
  inset-block-start: -1.5rem;
  inset-inline-end: 50%;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
  white-space: nowrap;
  rotate: -3deg;
  pointer-events: none;
}
.call__note svg { width: 2.6rem; color: var(--sun); translate: 0 0.55rem; }

.call__win {
  position: relative;
  z-index: 2;
  margin-inline-end: 8%;
  border-radius: 16px;
  background: var(--dc-bg);
  color: var(--dc-text);
  box-shadow: 0 44px 80px -40px #021a33, 0 0 0 1px #ffffff17, inset 0 1px 0 #ffffff14;
  rotate: 1.2deg;
}
.call__bar {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.65rem 1rem;
  padding-inline-start: clamp(4.25rem, 6.5vw, 5.75rem);  /* the corner is the sticker's */
  border-block-end: 1px solid #ffffff12;
  font-size: 0.875rem;
  line-height: 1.4;
}
.call__room { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 600; }
.call__room svg { width: 1.15rem; color: var(--dc-mute); }
.call__count { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.8125rem; color: var(--dc-mute); }
.call__count i { width: 7px; aspect-ratio: 1; border-radius: 50%; background: var(--dc-talk); box-shadow: 0 0 0 3px #3ad07a33; }
.call__lights { margin-inline-start: auto; display: flex; gap: 6px; direction: ltr; }
.call__lights i { width: 11px; aspect-ratio: 1; border-radius: 50%; background: #ff5f57; }
.call__lights i:nth-child(2) { background: #febc2e; }
.call__lights i:nth-child(3) { background: #28c840; }

.call__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
  padding: 0.6rem;
}
/* Discord tints a tile without a camera from its avatar: so do we */
.tile {
  --tint: var(--sky);
  --h: 0;
  --k: 0;
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 10;
  border-radius: 10px;
  background: color-mix(in srgb, var(--tint) 28%, var(--dc-tile));
  color: var(--dc-text);
  text-decoration: none;
  translate: 0 calc(var(--h) * -3px);
  box-shadow: inset 0 0 0 2px transparent;
  transition: box-shadow 180ms ease;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.tile.is-talking { box-shadow: inset 0 0 0 2px var(--dc-talk), 0 0 22px -6px var(--dc-talk); }

.tile--stream { grid-column: span 2; grid-row: span 2; aspect-ratio: auto; background: #0b0b12; }
.tile__view { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; }
/* a real clip plays here, so it needs no faked camera move of its own */
.tile__screen { display: block; width: 100%; height: 100%; object-fit: cover; }
.tile__live {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  padding: 0 0.45rem;
  border-radius: 4px;
  background: #ed4245;
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.6;
}
.tile__name {
  position: absolute;
  inset-block-end: 0.4rem;
  inset-inline-start: 0.4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  max-width: calc(100% - 0.8rem);
  padding: 0 0.5rem;
  border-radius: 6px;
  background: #000000a0;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.7;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tile__mini { width: 1.05rem; height: 1.05rem; border-radius: 50%; }

.tile__av {
  position: relative;
  width: 36%;
  aspect-ratio: 1;
  translate: 0 calc(var(--k) * -16px - 8%);
  scale: calc(1 + var(--h) * 0.07);
}
.tile__av img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
/* the talking ring */
.tile__av::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px var(--dc-talk);
  opacity: 0;
  scale: 0.92;
  transition: opacity 160ms ease, scale 240ms cubic-bezier(.3,1.4,.5,1);
}
.tile.is-talking .tile__av::after { opacity: 1; scale: 1; animation: talk 700ms ease-in-out infinite alternate; }
@keyframes talk { to { box-shadow: 0 0 0 5px #3ad07ab3; } }

.tile__mute {
  position: absolute;
  inset-block-start: 0.4rem;
  inset-inline-end: 0.4rem;
  display: grid;
  place-items: center;
  width: 1.45rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #da373c;
  color: #fff;
}
.tile__mute svg { width: 0.85rem; }

/* the empty seat: a grey سراج that takes its colour when you reach for it */
.tile--you {
  background: #ffffff08;
  border: 2px dashed #ffffff3d;
  transition: border-color 200ms ease, background 200ms ease;
}
.tile--you .tile__av img { filter: grayscale(1) brightness(1.15); opacity: 0.4; transition: filter 360ms ease, opacity 360ms ease; }
.tile--you .tile__name { background: var(--mint); color: #10222a; font-weight: 700; }
.tile--you:hover,
.tile--you:focus-visible { border-color: var(--mint); background: #45c4b91a; }
.tile--you:hover .tile__av img,
.tile--you:focus-visible .tile__av img { filter: none; opacity: 1; }
.tile--you:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

.call__say {
  position: absolute;
  z-index: 6;
  inset-block-end: calc(100% - 0.9rem);
  inset-inline-start: 50%;
  translate: 50% 0;
  width: max-content;
  max-width: 12.5rem;
  padding: 0.4rem 0.75rem;
  border-radius: 14px 14px 14px 4px;
  background: #fff;
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.45;
  text-align: center;
  box-shadow: 0 12px 26px -12px #000c;
  transform-origin: 50% 100%;
  pointer-events: none;
}

.call__dock { display: flex; align-items: center; gap: 0.5rem; padding: 0.2rem 0.6rem 0.65rem; }
.call__tools { display: flex; gap: 0.5rem; }
.call__tool {
  display: grid;
  place-items: center;
  width: 2.5rem;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #2e3038;
  color: var(--dc-text);
}
.call__tool svg { width: 1.1rem; }
.call__tool--on { background: var(--dc-text); color: var(--dc-bg); }
.call__react { cursor: pointer; transition: background 160ms ease, scale 140ms cubic-bezier(.2,.7,.3,1); }
.call__react .mark { --mark-color: var(--sun); width: 1.3rem; aspect-ratio: 1; }
.call__react:hover { background: #3b3e48; }
.call__react:active { scale: 0.88; transition-duration: 160ms, 70ms; }
.call__join {
  --btn-bg: var(--mint);
  --btn-fg: #10222a;
  margin-inline-start: auto;
  padding: 0.6em 1.25em;
  font-size: clamp(0.875rem, 1vw, 1rem);
}

/* a sticker slapped on the corner */
.call__badge {
  position: absolute;
  z-index: 5;
  inset-block-start: clamp(0rem, 1vw, 0.5rem);
  inset-inline-start: -1.5rem;
  display: grid;
  place-content: center;
  justify-items: center;
  width: clamp(5.25rem, 7.5vw, 6.75rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--sun);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.25;
  outline: 2px dashed #3232323d;
  outline-offset: -7px;
  box-shadow: 0 14px 26px -14px #021a33;
  rotate: 12deg;
  animation: sway 9s ease-in-out infinite alternate;
}
.call__badge b { font-family: var(--display); font-size: clamp(1.35rem, 2vw, 1.8rem); font-weight: 800; line-height: 1.1; }

.call__fx { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.call__pop { position: absolute; width: 1.9rem; aspect-ratio: 1; margin: -0.95rem 0 0 -0.95rem; }

.call .cloud { --cloud-color: #fff; z-index: 6; filter: blur(var(--blur, 0px)); }
.call__cloud--a { inset-block-end: -15%; inset-inline-start: -20%; width: 46%; }
.call__cloud--b { inset-block-end: -24%; inset-inline-end: -8%; width: 30%; opacity: 0.92; }
.call__cloud--c { inset-block-start: 30%; inset-inline-end: -22%; width: 30%; opacity: 0.55; z-index: 0; }

/* the header and the platforms on the start side, the call beside them */
@media (min-width: 1000px) {
  .community__grid {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    gap: clamp(2.5rem, 4.5vw, 5rem);
  }
}
@media (max-width: 999px) {
  .call { justify-self: center; width: 100%; max-width: 40rem; }
  .community__spark { display: none; }
}
/* Phones: the stream across the top, four seats under it */
@media (max-width: 640px) {
  .call__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile--stream { grid-row: auto; aspect-ratio: 16 / 9; }
  .tile[data-who="shamaa"], .call__tool--wide { display: none; }
  .call__win { margin-inline-end: 4%; rotate: 0.8deg; }
  .call__peek { width: 58%; inset-inline-end: -5%; }
  .call__note { inset-inline-end: 56%; font-size: 0.8125rem; }
  .call__badge { inset-inline-start: -0.5rem; }
  .call__say { max-width: 10rem; font-size: 0.75rem; }
  .call__join { padding: 0.55em 1em; font-size: 0.875rem; }
}
@media (max-width: 460px) {
  .finds { grid-template-columns: minmax(0, 1fr); }
  .call__tools .call__tool:nth-child(2) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .call__badge, .tile.is-talking .tile__av::after { animation: none; }
  .find, .tile--you, .call__react { transition: none; }
}

/* ============================================================= footer ==== */

/* One footer for every page (index.html and project.html). It rises out of
   the page as a bank of clouds in its own colour. It clips sideways only, so
   the clouds reach up over the section above without widening the page;
   the big faint wordmark clips inside its own box. --foot-bg and
   --foot-accent belong to the page: night and sun on the home page, the
   work's own colours on a project page (project.css). */
.pfoot {
  --foot-bg: #0d0d14;
  --foot-accent: var(--sun);
  position: relative;
  z-index: 2;
  background: var(--foot-bg);
  color: #fff;
  overflow-x: clip;
  padding-block: clamp(2rem, 5vw, 4rem) 1.75rem;
}
.pfoot :focus-visible { outline-color: #fff; }
.pfoot__clouds { position: absolute; inset-inline: 0; bottom: calc(100% - 2px); height: clamp(4rem, 9vw, 8rem); pointer-events: none; }
.pfoot__clouds .cloud { --cloud-color: var(--foot-bg); bottom: -38%; }

/* The home page's bank. Every cloud is sized from the band's height and
   sunk half its own --s below the edge, so none rises past --foot-rise and
   the section above keeps exactly that much clear (.community). The back
   row is the footer's night thinned with sky, for depth. */
:root { --foot-rise: clamp(4.5rem, 9vw, 8.5rem); }
.pfoot__clouds--bank { height: var(--foot-rise); }
.pfoot__clouds--bank .cloud {
  left: var(--x);
  bottom: calc(var(--s, 1) * -50%);
  width: auto;
  height: calc(var(--s, 1) * 150%);
}
.pfoot__clouds--bank .cloud[data-flip] { transform: scaleX(-1); }
.pfoot__clouds--bank .cloud.is-back { --cloud-color: color-mix(in srgb, var(--foot-bg) 62%, #4aa9e0); }
.pfoot__mark { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.pfoot__mark img { position: absolute; left: 50%; bottom: -14%; width: min(64rem, 120vw); translate: -50% 0; opacity: 0.045; }
.pfoot .shell { position: relative; }

.pfoot__cta {
  display: grid;
  justify-items: center;
  text-align: center;
  padding-bottom: clamp(2.75rem, 6vw, 4.5rem);
  border-bottom: 1px solid #ffffff1a;
}
.pfoot__cta .eyebrow { justify-content: center; color: #ffffff70; }
.pfoot__h { font-size: clamp(2.2rem, 6vw, 5rem); color: #fff; text-wrap: balance; }
.pfoot__cta p { max-width: 46ch; margin: 1rem auto 0; color: #ffffffad; }
.pfoot__acts { margin-top: 1.75rem; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.7rem; }
.pfoot__acts .btn { --btn-bg: var(--foot-accent); --btn-fg: var(--foot-bg); }
.pfoot__acts .btn--ghost { --btn-bg: #fff; --btn-fg: var(--foot-bg); }
/* its own width, wider than the paragraph above it, so the question and the
   answer stay on one line. Below that it wraps like anything else. */
.pfoot__cta .pfoot__note { max-width: none; margin-top: 1.25rem; font-size: 0.875rem; color: #ffffff80; }
@media (min-width: 60rem) { .pfoot__cta .pfoot__note { white-space: nowrap; } }
.pfoot__note a { color: #fff; text-underline-offset: 0.25em; }

.pfoot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.pfoot__brand img { height: 3rem; width: auto; }
.pfoot__brand p { max-width: 34ch; margin: 1rem 0 0; font-size: 0.9375rem; color: #ffffff99; }
.pfoot h3 { margin-bottom: 0.9rem; font-size: 1.0625rem; font-weight: 700; color: #fff; }
.pfoot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.pfoot li a { font-size: 0.9375rem; color: #ffffffa3; text-decoration: none; transition: color 160ms ease; }
.pfoot li a:hover { color: #fff; }
.pfoot li a[aria-current='page'] { color: var(--foot-accent); }

.pfoot__bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid #ffffff1a;
  font-size: 0.8125rem;
  color: #ffffff73;
}
.pfoot__up { color: inherit; text-decoration: none; }
.pfoot__up:hover { color: #fff; }

@media (max-width: 860px) {
  .pfoot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pfoot__brand { grid-column: 1 / -1; }
}

/* ================================================================= lite ===
   html.lite (util.js): a device that could not hold the frame rate. Every
   animation still runs. What goes are the effects redrawn on every frame:
   blurs on moving layers, and backdrop blurs, which fall back to the solid
   glass written for reduced transparency. */
.lite .cloud { filter: none !important; }
.lite .eye { filter: blur(var(--blur)); }
.lite .nav,
.lite .navworks,
.lite .news__nav,
.lite .news__chip {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
.lite .nav[data-on-tone].is-stuck { background: color-mix(in srgb, var(--nav-glass, #0b0b12) 92%, transparent); }
.lite .nav.is-stuck:not([data-on-tone]) { background: color-mix(in srgb, var(--paper) 96%, transparent); }
.lite .navworks { background: color-mix(in srgb, var(--nav-glass, #0b0b12) 96%, #000); }
.lite .news__chip { background: #000000a6; }
.lite .voices__veil i { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lite .voices__veil i:nth-child(1) { background: radial-gradient(closest-side, #0b0b12f0 45%, #0b0b1200); }
.lite .vcomment.is-hi,
.lite .vmsg.is-hi { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lite .vcomment.is-hi { background: #1a1a25; }
.lite .vcomment--x.is-hi { background: #171b20; }
.lite .vmsg--wa.is-hi { background: #075e54; }
