/* ============================================================
   THE SCENE CAPE TOWN: WEBSITE STYLESHEET
   Shared across all pages (landing, home, segment pages).
   Design tokens carried from Scene Studio.
   ============================================================ */

/* ============================================================
   DESIGN TOKENS
   ============================================================ */
:root {
  --scene-cyan:        #4BB9D0;
  --scene-cyan-soft:   #9FDCE7;
  --scene-cyan-wash:   #E4F5FA;
  --scene-cyan-deep:   #2A9BB5;
  --scene-blue:        #3380C1;
  --scene-blue-soft:   #8FB5DB;
  --scene-blue-wash:   #E8F0F9;
  --scene-blue-deep:   #1E5E96;
  --scene-white:       #FFFFFF;
  --scene-gradient:    linear-gradient(135deg, #3380C1 0%, #4BB9D0 100%);

  --charcoal:   #15233D;
  --slate:      #DCE6F2;

  --text:        #15233D;
  --text-soft:   #2E3E5E;
  --text-muted:  #6B7A95;
  --text-subtle: #A0ADC3;

  --warm-grey:  #F4F7FB;
  --cream:      #FFFCF7;
  --border:     rgba(51, 128, 193, 0.14);
  --border-sub: rgba(51, 128, 193, 0.08);

  --radius-sm:   10px;
  --radius-md:   18px;
  --radius-lg:   24px;
  --radius-xl:   32px;
  --radius-pill: 999px;

  --glass-bg:           rgba(255, 255, 255, 0.62);
  --glass-bg-strong:    rgba(255, 255, 255, 0.74);
  --glass-bg-soft:      rgba(255, 255, 255, 0.48);
  --glass-border:       rgba(255, 255, 255, 0.82);
  --glass-border-sub:   rgba(255, 255, 255, 0.48);
  --glass-blur:         blur(16px) saturate(140%);
  --glass-blur-strong:  blur(20px) saturate(160%);

  --shadow-xs: 0 2px 8px rgba(51, 128, 193, 0.06);
  --shadow-sm: 0 4px 18px rgba(51, 128, 193, 0.10),
               inset 0 1px 0 rgba(255, 255, 255, 0.70);
  --shadow-md: 0 12px 40px rgba(51, 128, 193, 0.15),
               inset 0 1px 0 rgba(255, 255, 255, 0.85);
  --shadow-lg: 0 28px 70px rgba(51, 128, 193, 0.22),
               inset 0 1px 0 rgba(255, 255, 255, 0.90);

  --font-body:    'DM Sans', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
}

/* ============================================================
   RESET
   ============================================================ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
/* overflow-x: clip (not hidden) contains the oversized background-glow blob
   without turning <html> into a scroll container — hidden can subtly break
   position:sticky and momentum scrolling on iOS; clip never does. */
html { -webkit-text-size-adjust: 100%; overflow-x: clip; }
a { text-decoration: none; }
img { display: block; max-width: 100%; }

/* ============================================================
   BASE
   ============================================================ */
body {
  font-family: var(--font-body);
  color: var(--text);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ============================================================
   PAGE: LANDING  (dark)
   ============================================================ */
body.page-landing {
  background: linear-gradient(135deg, #0D1829 0%, #15233D 60%, #0A1520 100%);
  color: #ffffff;
  position: relative;
}

body.page-landing::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse 70% 50% at 15% 15%, rgba(51, 128, 193, 0.18) 0%, transparent 70%),
    radial-gradient(ellipse 55% 40% at 85% 80%, rgba(75, 185, 208, 0.14) 0%, transparent 70%),
    radial-gradient(ellipse 45% 55% at 65% 5%,  rgba(30,  94, 150, 0.12) 0%, transparent 70%);
}

body.page-landing > * {
  position: relative;
  z-index: 1;
}

/* ============================================================
   HERO
   ============================================================ */
/* position + isolation exist so the hero can host a background canvas.
   Vanta (homepage hero) inserts its own canvas as a child of .hero and
   styles it position:absolute; z-index:0, which needs a positioned
   ancestor. isolation:isolate gives the hero its own stacking context,
   so that canvas and .hero__inner order against each other only and
   never interact with the page-level layers. */
.hero {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 1.5rem 2.5rem;
  text-align: center;
  position: relative;
  isolation: isolate;
}

.hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  max-width: 560px;
  width: 100%;
  position: relative;
  z-index: 1;
}

.hero__logo img {
  height: 72px;
  width: 72px;
  border-radius: 18px;
  object-fit: cover;
  margin: 0 auto;
}

.hero__logo-fallback {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.55);
  text-transform: uppercase;
}

.hero__headline {
  font-size: clamp(2.6rem, 8vw, 4.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  background: var(--scene-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.hero__tagline {
  font-size: clamp(1rem, 2.5vw, 1.15rem);
  font-weight: 600;
  color: rgba(255, 255, 255, 0.90);
  letter-spacing: 0.01em;
}

.hero__sub {
  font-size: clamp(0.9rem, 2vw, 1rem);
  color: rgba(255, 255, 255, 0.50);
  max-width: 380px;
  line-height: 1.65;
}

/* ============================================================
   STORE BUTTONS
   ============================================================ */
.hero__buttons {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  align-items: center;
  width: 100%;
  max-width: 320px;
  margin-top: 0.5rem;
}

.btn-store {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.8rem 1.4rem;
  border-radius: var(--radius-md);
  width: 100%;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.btn-store:active {
  transform: scale(0.97);
}

.btn-store__icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.btn-store__label {
  display: flex;
  flex-direction: column;
  text-align: left;
}

.btn-store__label small {
  font-size: 0.7rem;
  font-weight: 500;
  opacity: 0.85;
  line-height: 1.2;
}

.btn-store__label strong {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
}

.btn-store--ios {
  background: var(--scene-gradient);
  color: #ffffff;
  box-shadow: 0 4px 20px rgba(51, 128, 193, 0.45),
              inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.btn-store--ios:hover {
  box-shadow: 0 6px 28px rgba(51, 128, 193, 0.60),
              inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.btn-store--android {
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

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

/* ============================================================
   MOCKUP
   ============================================================ */
.mockup-section {
  display: flex;
  justify-content: center;
  padding: 2rem 1.5rem 3rem;
}

.mockup-placeholder {
  width: 220px;
  height: 490px;
  border-radius: 36px;
  border: 1.5px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.04);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.25);
  font-size: 0.8rem;
  text-align: center;
  line-height: 1.5;
  box-shadow:
    0 0 0 8px rgba(255, 255, 255, 0.025),
    0 40px 80px rgba(0, 0, 0, 0.5);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.mockup-image {
  width: 220px;
  height: 490px;
  border-radius: 36px;
  object-fit: cover;
  box-shadow:
    0 0 0 8px rgba(255, 255, 255, 0.04),
    0 40px 80px rgba(0, 0, 0, 0.5);
}

/* ============================================================
   VALUE PROPS
   ============================================================ */
.value-props {
  padding: 1rem 1.5rem 3rem;
}

.value-props__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  max-width: 960px;
  margin: 0 auto;
}

.vp-card {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.5rem;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  position: relative;
  overflow: hidden;
}

.vp-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--scene-gradient);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.vp-card__category {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--scene-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.vp-card__heading {
  font-size: 1.05rem;
  font-weight: 700;
  color: #ffffff;
  line-height: 1.3;
}

.vp-card__body {
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.60);
  line-height: 1.6;
}

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  padding: 1.5rem;
  text-align: center;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.site-footer p {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.30);
}

.site-footer a {
  color: rgba(255, 255, 255, 0.40);
  transition: color 0.15s ease;
}

.site-footer a:hover {
  color: rgba(255, 255, 255, 0.70);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (min-width: 640px) {
  .hero__buttons {
    flex-direction: row;
    max-width: none;
    justify-content: center;
  }

  .btn-store {
    width: auto;
    min-width: 180px;
  }
}

@media (min-width: 768px) {
  .value-props__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .mockup-placeholder,
  .mockup-image {
    width: 260px;
    height: 579px;
  }
}

/* ============================================================
   PAGE: SITE  (light, Scene Studio-derived design language)
   Shared by the homepage, about, and contributor pages. The
   landing page above stays dark/dramatic on purpose (poster QR
   destination): these rules are scoped to body.page-site so both
   themes can share component classes (.hero, .btn-store, .vp-card)
   without clashing.
   ============================================================ */
body.page-site {
  background: linear-gradient(135deg,
    #E8F2FB  0%,
    #F2F6FB 25%,
    #FAEEF1 50%,
    #F0F7FC 78%,
    #DDE9F5 100%);
  position: relative;
}

/* Anchored to the page (absolute), not the viewport (fixed): the two
   lower glows (15% 85%, 88% 88%) are meant to sit near the footer. When
   this layer was fixed they stayed pinned to the bottom of the *screen*,
   so a blue glow showed the moment you started scrolling — long before
   the footer, reading as a footer shadow with no footer. Absolute makes
   them scroll with the page and land at the true bottom. */
body.page-site::before {
  content: '';
  position: absolute;
  inset: -15%;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(ellipse 900px 700px  at 18% 22%, rgba(75, 185, 208, 0.18),  transparent 70%),
    radial-gradient(ellipse 1000px 800px at 85% 18%, rgba(240, 195, 210, 0.16), transparent 72%),
    radial-gradient(ellipse 900px 900px  at 15% 85%, rgba(170, 205, 230, 0.18), transparent 72%),
    radial-gradient(ellipse 1100px 800px at 88% 88%, rgba(51, 128, 193, 0.18),  transparent 70%);
  transform: translateZ(0);
}

body.page-site > * {
  position: relative;
  z-index: 1;
}

/* Flow field sits between the gradient blobs (-2) and page content (1).
   The ID selector's specificity overrides the wildcard rule above.

   Currently unwired: as of 23 Jul 2026 the homepage hero uses Vanta's
   TOPOLOGY effect instead (see hero-vanta.js and the HERO section).
   flow-field.js and this rule are both kept so reinstating it is a
   two-line change in index.html. */
#flowField {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Reused components need light-theme colour overrides since their base
   rules above were written for the dark landing page. */
body.page-site .hero { min-height: auto; padding: 3.5rem 1.5rem 3rem; }
body.page-site .hero__tagline { color: var(--text-soft); }
body.page-site .hero__sub { color: var(--text-muted); }
body.page-site .hero__logo-fallback { color: var(--text-subtle); }

body.page-site .btn-store--android {
  background: rgba(255, 255, 255, 0.75);
  color: var(--scene-blue);
  border: 1.5px solid rgba(51, 128, 193, 0.30);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.page-site .btn-store--android:hover {
  background: #ffffff;
  border-color: var(--scene-blue);
}

/* ------------------------------------------------------------
   HOMEPAGE HERO ON THE VANTA GROUND

   Only index.html carries .hero--vanta. Its hero sits on Vanta's
   opaque --scene-blue-deep canvas rather than the light page, so its
   copy needs the light treatment back: essentially the base
   (dark-landing-page) values that the body.page-site rules just above
   override. Scoped to .hero--vanta so the five other pages, whose
   heroes are still on the light background, are untouched.

   Values are lifted from the base rules rather than copied verbatim.
   The base was written for #0D1829, a much darker ground than
   #1E5E96, so the dimmer ones (sub at 0.50, logo fallback at 0.55)
   would not hold contrast here and are raised.
   ------------------------------------------------------------ */

/* Static fallback ground for the hero. hero-vanta.js skips the live
   TOPOLOGY effect on phones/tablets, low-power or reduced-motion setups,
   and very narrow viewports; on those this topographic graphic stands in,
   in the same deep-blue/cyan-soft palette. When the effect DOES run,
   Vanta's own opaque canvas paints over this, so it is only seen as the
   fallback (or for the split second before the canvas first paints). */
body.page-site .hero--vanta {
  background-color: #1E5E96; /* --scene-blue-deep, matches the Vanta ground */
  background-image: url("hero-fallback.svg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

body.page-site .hero--vanta .hero__tagline { color: rgba(255, 255, 255, 0.95); }
body.page-site .hero--vanta .hero__sub { color: rgba(255, 255, 255, 0.78); }
/* 0.78, not the 0.70 that looked right by eye: at 0.70 this lands on
   4.24:1 against the ground, and at 16px bold it does not qualify as
   large text, so it needs 4.5. */
body.page-site .hero--vanta .hero__logo-fallback { color: rgba(255, 255, 255, 0.78); }

/* The default --scene-gradient runs #3380C1 to #4BB9D0, and its blue
   end is nearly the ground colour here, so the headline would half
   disappear. White to cyan-soft keeps the brand ramp and stays legible
   across the whole word. */
body.page-site .hero--vanta .hero__headline {
  background: linear-gradient(135deg, #FFFFFF 0%, var(--scene-cyan-soft) 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* Deliberately NOT the base rule's backdrop-filter. This button sits
   directly on top of an always-animating canvas, so a blur here would
   have to re-run every frame the effect paints: exactly the compositing
   cost that made the site stutter on mobile in July. A flat translucent
   fill costs nothing. */
body.page-site .hero--vanta .btn-store--android {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.34);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.page-site .hero--vanta .btn-store--android:hover {
  background: rgba(255, 255, 255, 0.26);
  border-color: rgba(255, 255, 255, 0.55);
}

body.page-site .vp-card,
body.page-site .feature-card,
body.page-site .value-list li {
  background: var(--glass-bg-strong);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-md);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}
body.page-site .vp-card__heading { color: var(--text); }
body.page-site .vp-card__body { color: var(--text-muted); }

body.page-site .site-footer { border-top-color: var(--border); }
body.page-site .site-footer p { color: var(--text-muted); }
body.page-site .site-footer a { color: var(--scene-blue); }
body.page-site .site-footer a:hover { color: var(--scene-blue-deep); }

/* ------------------------------------------------------------
   SITE HEADER / NAV
   ------------------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 300;
  border-bottom: 1px solid var(--glass-border-sub);
}

/* The blur lives on a pseudo-element behind the header's own content,
   not on .site-header itself. Any element with backdrop-filter becomes
   the containing block for its position:fixed descendants (this is in
   the CSS spec, so every browser does it) — and .site-nav below switches
   to position:fixed on mobile. With backdrop-filter on .site-header the
   dropdown would anchor to the thin header box instead of the viewport.
   Keeping .site-header filter-free avoids that while the glass look
   stays identical. */
.site-header::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
}

/* Keep the header (and its fixed mobile dropdown) above the page.
   The `body.page-site > *` / `body.page-landing > *` rules set z-index:1
   on every direct child to lift content above the fixed background
   layers — but that selector (0,0,1,1) outweighs plain `.site-header`
   (0,0,1,0), dragging the header down to z-index:1 too. At equal
   z-index the later-in-DOM sections then paint OVER the header, which
   on mobile put the whole page on top of the open nav menu: it looked
   see-through and taps fell through to the content beneath. This
   higher-specificity selector restores the header's stacking. */
body.page-site > .site-header,
body.page-landing > .site-header {
  z-index: 300;
}

.site-header__inner {
  max-width: 1180px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 0.85rem 1.5rem;
}

.site-logo {
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin-right: auto;
  background: var(--scene-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

/* ------------------------------------------------------------
   CROSS-DOCUMENT VIEW TRANSITION — carries the active pill's slide
   across a real page navigation (this site has no client router,
   each page is a full document load). The browser snapshots the
   .is-active pill on the outgoing page and morphs it into its new
   box on the incoming page automatically; nothing else needed.
   Root is set to animation:none so only the pill (named below)
   animates — without this the whole page would crossfade too.
   Unsupported browsers (Safari/Firefox) just ignore @view-transition
   and get today's instant swap, no breakage.
   ------------------------------------------------------------ */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
}

.nav-track a.is-active {
  view-transition-name: nav-pill;
}

/* Honour reduced-motion for the cross-document transition too: keep the
   instant page swap, drop the pill morph. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* ------------------------------------------------------------
   NAV TRACK — "morphic" link group, in the spirit of Kokonut UI's
   Morphic Navbar: inactive links sit flush in one glass track;
   the active link detaches into its own gradient pill, and its
   neighbours round off the facing edge so the track reads as one
   continuous shape with a gap cut into it, not a broken row.
   Pure CSS (:has()) — no JS needed since each static page already
   renders with the right .is-active link server-side.
   ------------------------------------------------------------ */
.nav-track {
  display: flex;
  align-items: center;
  background: rgba(51, 128, 193, 0.055);
  border: 1px solid var(--glass-border-sub);
  border-radius: var(--radius-pill);
  padding: 4px;
}

.nav-track a {
  position: relative;
  padding: 0.5rem 1.05rem;
  font-size: 0.83rem;
  font-weight: 600;
  color: var(--text-soft);
  white-space: nowrap;
  border-radius: 0;
  transition: color 0.3s ease, background-color 0.3s ease, margin 0.3s ease,
              border-radius 0.3s ease, box-shadow 0.3s ease;
}

.nav-track a:hover:not(.is-active) {
  color: var(--scene-blue);
  background: rgba(255, 255, 255, 0.55);
}

/* Flush ends of the track round off, unless that end IS the active pill
   (which gets its own full radius below). */
.nav-track a:first-child:not(.is-active) {
  border-top-left-radius: var(--radius-pill);
  border-bottom-left-radius: var(--radius-pill);
}
.nav-track a:last-child:not(.is-active) {
  border-top-right-radius: var(--radius-pill);
  border-bottom-right-radius: var(--radius-pill);
}

/* The neighbours on either side of the active pill round off the edge
   facing the gap, so the track "flows around" the popped-out pill. */
.nav-track a:has(+ a.is-active) {
  border-top-right-radius: var(--radius-pill);
  border-bottom-right-radius: var(--radius-pill);
}
.nav-track a.is-active + a {
  border-top-left-radius: var(--radius-pill) !important;
  border-bottom-left-radius: var(--radius-pill) !important;
}

/* The active link detaches from the track into its own gradient pill. */
.nav-track a.is-active {
  margin: 0 4px;
  padding: 0.5rem 1.15rem;
  border-radius: var(--radius-pill) !important;
  background: var(--scene-gradient);
  color: #ffffff;
  font-weight: 700;
  box-shadow: var(--shadow-sm);
}

.nav-cta {
  flex-shrink: 0;
  padding: 0.6rem 1.25rem;
  border-radius: var(--radius-pill);
  background: var(--scene-gradient);
  color: #ffffff !important;
  font-weight: 700 !important;
  font-size: 0.84rem !important;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.nav-cta:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }

.menu-toggle-site {
  display: none;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-sm);
  padding: 7px 11px;
  color: var(--scene-blue);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
}

@media (max-width: 880px) {
  .site-nav {
    /* Anchored to the sticky .site-header (its nearest positioned ancestor)
       via top:100%, so the dropdown always sits flush under the header
       whatever its real height is — the old fixed `top: 62px` was a magic
       number that broke the moment the header grew (Android OS font scaling,
       font-load reflow), leaving the menu overlapping or detached. */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 250;
    flex-direction: column;
    align-items: stretch;
    gap: 0.9rem;
    padding: 1.1rem 1.5rem 1.5rem;
    /* Never taller than the viewport: on a short/landscape phone the last
       links (incl. "Get the App") stay reachable by scrolling the menu
       itself instead of running off-screen. */
    max-height: calc(100dvh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--glass-bg-strong);
    -webkit-backdrop-filter: var(--glass-blur-strong);
    backdrop-filter: var(--glass-blur-strong);
    border-bottom: 1px solid var(--glass-border-sub);
    box-shadow: var(--shadow-md);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease;
  }
  .site-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }

  /* On a narrow, stacked menu the "flush track with a pop-out pill"
     illusion only reads left-to-right — simplify to a plain vertical
     list where every row is a rounded tap target, and the active one
     still gets the gradient pill treatment. */
  .nav-track {
    flex-direction: column;
    align-items: stretch;
    background: none;
    border: none;
    padding: 0;
    gap: 0.35rem;
  }
  .nav-track a,
  .nav-track a:first-child,
  .nav-track a:last-child,
  .nav-track a:has(+ a.is-active),
  .nav-track a.is-active + a {
    border-radius: var(--radius-sm) !important;
    padding: 0.65rem 0.9rem;
  }
  .nav-track a.is-active { margin: 0; }

  .nav-cta { order: 3; margin-top: 0.25rem; text-align: center; }
  .menu-toggle-site { display: inline-flex; align-items: center; }
}

/* ------------------------------------------------------------
   SECTION LAYOUT UTILITIES
   ------------------------------------------------------------ */
.section { padding: 4.5rem 1.5rem; }
.section--tight { padding: 2.5rem 1.5rem; }
.section__inner { max-width: 1100px; margin: 0 auto; }

.section__kicker {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--scene-blue);
  text-align: center;
  margin-bottom: 0.85rem;
}

.section__title {
  font-size: clamp(1.9rem, 4vw, 2.75rem);
  font-weight: 800;
  letter-spacing: -0.028em;
  text-align: center;
  line-height: 1.1;
  margin-bottom: 0.9rem;
  color: var(--text);
}

.section__sub {
  font-size: 1rem;
  color: var(--text-muted);
  text-align: center;
  max-width: 600px;
  margin: 0 auto 3rem;
  line-height: 1.65;
}

/* ------------------------------------------------------------
   PAGE HERO: smaller top-aligned hero for inner pages
   ------------------------------------------------------------ */
.page-hero {
  padding: 4rem 1.5rem 3rem;
  text-align: center;
}

.page-hero__kicker {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--scene-blue);
  margin-bottom: 1rem;
}

.page-hero__title {
  font-size: clamp(2.1rem, 5vw, 3.2rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.08;
  max-width: 780px;
  margin: 0 auto 1.1rem;
  background: var(--scene-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.page-hero__sub {
  font-size: 1.05rem;
  color: var(--text-muted);
  max-width: 620px;
  margin: 0 auto;
  line-height: 1.7;
}

/* ------------------------------------------------------------
   FEATURE GRID: four-tab breakdown, laid out as an asymmetric
   bento (Scene as a 2x2 flagship, Zine as a wide footer card)
   instead of four identical boxes. Each card gets its own accent
   (falls back to --scene-gradient so the standalone .feature-card
   reused on promoters/theatres/publications for the Scene Studio
   callout is untouched) and an oversized ghost numeral for texture.
   ------------------------------------------------------------ */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(160px, auto);
  gap: 1.25rem;
}

.feature-grid .feature-card--flagship { grid-column: 1 / 3; grid-row: 1 / 3; padding: 2.25rem; }
.feature-grid .feature-card--wide { grid-column: 3 / 5; }

.feature-grid .feature-card:nth-child(1) { --card-accent: var(--scene-cyan); }
.feature-grid .feature-card:nth-child(2) { --card-accent: var(--scene-blue); }
.feature-grid .feature-card:nth-child(3) { --card-accent: var(--scene-cyan-deep); }
.feature-grid .feature-card:nth-child(4) { --card-accent: var(--scene-blue-deep); }

.feature-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.6rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-3px);
}

.feature-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--card-accent, var(--scene-gradient));
}

.feature-card__num {
  position: absolute;
  top: -0.5rem;
  right: 0.6rem;
  font-size: 4rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--card-accent, var(--scene-blue));
  opacity: 0.14;
  pointer-events: none;
}
.feature-card--flagship .feature-card__num { font-size: 6.5rem; }

.feature-card__name {
  position: relative;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  margin-bottom: 0.6rem;
  color: var(--text);
}
.feature-card--flagship .feature-card__name { font-size: 1.6rem; }

.feature-card__desc {
  position: relative;
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.65;
}

.feature-card__list {
  position: relative;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border-sub);
}

.feature-card__list li {
  position: relative;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.55;
}

.feature-card__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--card-accent, var(--scene-blue));
}

@media (max-width: 780px) {
  .feature-grid { grid-template-columns: 1fr; }
  .feature-grid .feature-card--flagship,
  .feature-grid .feature-card--wide { grid-column: auto; grid-row: auto; }
}

/* ------------------------------------------------------------
   SEGMENT LIST: homepage teasers linking to contributor pages,
   as an editorial numbered list rather than a repeat of the
   feature-grid's card treatment above.
   ------------------------------------------------------------ */
.segment-list {
  display: flex;
  flex-direction: column;
  max-width: 820px;
  margin: 0 auto;
  border-top: 1px solid var(--border);
}

.segment-row {
  display: grid;
  grid-template-columns: 2.75rem 1fr auto;
  align-items: center;
  gap: 1.25rem;
  padding: 1.6rem 0.75rem;
  border-bottom: 1px solid var(--border);
  transition: padding-left 0.25s ease, background-color 0.25s ease;
}

.segment-row:hover {
  padding-left: 1.25rem;
  background: var(--glass-bg-soft);
}

.segment-row__num {
  font-size: 1.05rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--scene-blue);
  opacity: 0.5;
}

.segment-row__body {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.segment-row__label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--scene-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.segment-row__title {
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.015em;
}

.segment-row__desc {
  font-size: 0.87rem;
  color: var(--text-muted);
  line-height: 1.6;
}

.segment-row__arrow {
  font-size: 1.3rem;
  color: var(--scene-blue);
  transition: transform 0.2s ease;
}
.segment-row:hover .segment-row__arrow { transform: translateX(6px); }

@media (max-width: 640px) {
  .segment-row { grid-template-columns: 2rem 1fr; }
  .segment-row__arrow { display: none; }
}

/* Kept standalone: used for the "Open Scene Studio" link on
   promoters/theatres/publications, unrelated to segment-row above. */
.segment-card__arrow {
  margin-top: 0.4rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--scene-blue);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  transition: gap 0.15s ease;
}

/* ------------------------------------------------------------
   VALUE LIST: checklist-style bullets on contributor pages
   ------------------------------------------------------------ */
.value-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 640px;
  margin: 0 auto;
}

.value-list li {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  border-radius: var(--radius-md);
  padding: 1.1rem 1.3rem;
  box-shadow: var(--shadow-sm);
}

.value-list__icon {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--scene-gradient);
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 800;
  margin-top: 0.1rem;
}

.value-list__text strong {
  display: block;
  color: var(--text);
  font-weight: 700;
  font-size: 0.98rem;
  margin-bottom: 2px;
}

.value-list__text span {
  color: var(--text-muted);
  font-size: 0.88rem;
  line-height: 1.6;
}

/* ------------------------------------------------------------
   PULL QUOTE: manifesto excerpts
   ------------------------------------------------------------ */
.pull-quote {
  font-size: clamp(1.35rem, 2.8vw, 1.9rem);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: var(--text);
  text-align: center;
  max-width: 760px;
  margin: 0 auto;
}

.pull-quote cite {
  display: block;
  margin-top: 1.4rem;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-style: normal;
}

/* ------------------------------------------------------------
   CTA BAND: closing call-to-action before the footer
   ------------------------------------------------------------ */
.cta-band {
  margin: 1rem auto 0;
  max-width: 1100px;
  background: var(--scene-gradient);
  border-radius: var(--radius-xl);
  padding: 3.25rem 2rem;
  text-align: center;
  color: #ffffff;
  box-shadow: var(--shadow-lg);
}

.cta-band__title {
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 0.65rem;
}

.cta-band__sub {
  font-size: 0.95rem;
  opacity: 0.92;
  max-width: 520px;
  margin: 0 auto 1.75rem;
  line-height: 1.6;
}

.cta-band .hero__buttons { margin: 0 auto; }

.cta-band .btn-store--ios {
  background: rgba(255, 255, 255, 0.96);
  color: var(--scene-blue-deep);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
}
.cta-band .btn-store--ios:hover { background: #ffffff; }

.cta-band .btn-store--android {
  background: rgba(255, 255, 255, 0.14) !important;
  border: 1px solid rgba(255, 255, 255, 0.4) !important;
  color: #ffffff !important;
}
.cta-band .btn-store--android:hover { background: rgba(255, 255, 255, 0.22) !important; }

/* ------------------------------------------------------------
   RESPONSIVE: site pages
   ------------------------------------------------------------ */
@media (min-width: 768px) {
  .value-list li { padding: 1.25rem 1.5rem; }
}
