/* ==========================================================================
   OnStage — Stage Glass marketing site
   Deep plum/black, violet + amber stage-light bloom, frosted glass surfaces.
   ========================================================================== */

:root {
  --bg-black: #07050b;
  --bg-plum-1: #120a1c;
  --bg-plum-2: #1b0f2a;
  --violet: #8b6bff;
  --violet-soft: rgba(139, 107, 255, 0.35);
  --amber: #f2a94e;
  --amber-soft: rgba(242, 169, 78, 0.35);
  --amber-highlight: #ffd9a0;
  --white: #f6f3f8;
  --gray: #a99cb8;
  --gray-dim: #7c6f8c;
  --glass-bg: rgba(255, 255, 255, 0.045);
  --glass-bg-strong: rgba(255, 255, 255, 0.07);
  --glass-border: rgba(255, 255, 255, 0.09);
  --glass-border-strong: rgba(255, 255, 255, 0.16);
  /* Glass-panel diagonal gradients (hero card, showcase cards; -3/-4 is the
     closing panel's own slightly softer pair) -- named so light mode can
     swap white-tinted glass for the opposite direction (a bright card
     lifted off a light page) without touching every rule that uses them. */
  --glass-grad-1: rgba(255, 255, 255, 0.055);
  --glass-grad-2: rgba(255, 255, 255, 0.02);
  --glass-grad-3: rgba(255, 255, 255, 0.045);
  --glass-grad-4: rgba(255, 255, 255, 0.015);
  --card-flat-bg: rgba(255, 255, 255, 0.02);
  --card-flat-border: rgba(255, 255, 255, 0.05);
  --hairline: rgba(255, 255, 255, 0.07);
  --hairline-soft: rgba(255, 255, 255, 0.05);
  --nav-bg: rgba(7, 5, 11, 0.55);
  --nav-border: rgba(255, 255, 255, 0.06);
  --panel-scrim: rgba(7, 5, 11, 0.48);
  --section-scrim-a: rgba(7, 5, 11, 0.5);
  --section-scrim-b: rgba(7, 5, 11, 0.72);
  --shadow-hero: rgba(0, 0, 0, 0.7);
  --shadow-hero-icon: rgba(0, 0, 0, 0.75);
  --shadow-card: rgba(0, 0, 0, 0.65);
  --shadow-closing: rgba(0, 0, 0, 0.6);
  --blob-op-1: 0.32;
  --blob-op-2: 0.22;
  --bokeh-opacity: 0.16;
  --grain-opacity: 0.035;
  --radius-lg: 32px;
  --radius-md: 22px;
  --radius-sm: 14px;
  --container: 1200px;
  /* Every section below the hero shares this one content width, so the
     page reads as a single consistent column; only the hero (its own
     two-column card) is wider. */
  --content: 760px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Light mode -- palette pulled from the iOS app's own light-mode design
   (ios/Shared/Theme.swift), not invented separately: iOS grouped-list page/
   card colors, the app's burnt-amber accentText (#c65a00) standing in for
   the vivid dark-mode amber wherever amber is TEXT (the vivid #f2a94e fails
   contrast on a white surface, same reason the app itself doesn't use it
   there), and near-black ink for primary text. Glass panels flip from a
   white tint floating on dark to a brighter-white card lifted off the
   light page, same direction the app's neutralCard uses. Manual toggle
   only (see script.js) -- this site's native/default look stays dark,
   matching its brand identity; light is an explicit opt-in, not something
   derived from system preference. */
:root[data-theme="light"] {
  --bg-black: #f2f2f7;
  --bg-plum-1: #eef0f8;
  --bg-plum-2: #e8ebf6;
  --violet: #6a5acd;
  --violet-soft: rgba(106, 90, 205, 0.22);
  --amber: #c65a00;
  --amber-soft: rgba(198, 90, 0, 0.22);
  --amber-highlight: #8a3d00;
  --white: #1a1a1a;
  --gray: rgba(60, 60, 67, 0.68);
  --gray-dim: rgba(60, 60, 67, 0.5);
  --glass-bg: rgba(20, 12, 30, 0.035);
  --glass-bg-strong: rgba(20, 12, 30, 0.055);
  --glass-border: rgba(20, 12, 30, 0.1);
  --glass-border-strong: rgba(20, 12, 30, 0.16);
  --glass-grad-1: rgba(255, 255, 255, 0.92);
  --glass-grad-2: rgba(255, 255, 255, 0.65);
  --glass-grad-3: rgba(255, 255, 255, 0.92);
  --glass-grad-4: rgba(255, 255, 255, 0.68);
  --card-flat-bg: rgba(20, 12, 30, 0.025);
  --card-flat-border: rgba(20, 12, 30, 0.07);
  --hairline: rgba(20, 12, 30, 0.1);
  --hairline-soft: rgba(20, 12, 30, 0.07);
  --nav-bg: rgba(247, 246, 250, 0.75);
  --nav-border: rgba(20, 12, 30, 0.08);
  --panel-scrim: rgba(255, 255, 255, 0.55);
  --section-scrim-a: rgba(255, 255, 255, 0.55);
  --section-scrim-b: rgba(255, 255, 255, 0.82);
  --shadow-hero: rgba(20, 12, 30, 0.14);
  --shadow-hero-icon: rgba(20, 12, 30, 0.18);
  --shadow-card: rgba(20, 12, 30, 0.12);
  --shadow-closing: rgba(20, 12, 30, 0.1);
  /* The ambient drifting blobs and the stage-lights photo/grain overlays
     were tuned for a near-black backdrop; on a light page the same
     opacities would muddy or wash out the surface, so all four dial down
     (the bokeh photo effectively off -- "screen" blend mode over white
     just flattens it to a soft haze with no atmosphere to add). */
  --blob-op-1: 0.16;
  --blob-op-2: 0.12;
  --bokeh-opacity: 0.55;
  --grain-opacity: 0.02;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  background: var(--bg-black);
  color: var(--white);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
    "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

a {
  color: inherit;
}

.wrap {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
}

/* ---------------------------------------------------------------------- */
/* Ambient background                                                      */
/* ---------------------------------------------------------------------- */

.stage-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background: radial-gradient(ellipse 90% 60% at 50% -10%, var(--bg-plum-2) 0%, var(--bg-plum-1) 45%, var(--bg-black) 80%);
  overflow: hidden;
}

.stage-bg::before,
.stage-bg::after {
  content: "";
  position: absolute;
  width: 60vw;
  height: 60vw;
  max-width: 900px;
  max-height: 900px;
  border-radius: 50%;
  filter: blur(120px);
  opacity: var(--blob-op-1);
  will-change: transform;
}

.stage-bg::before {
  top: -18%;
  left: -10%;
  background: radial-gradient(circle, var(--violet) 0%, transparent 70%);
  animation: driftA 46s ease-in-out infinite alternate;
}

.stage-bg::after {
  top: 10%;
  right: -15%;
  background: radial-gradient(circle, var(--amber) 0%, transparent 70%);
  opacity: var(--blob-op-2);
  animation: driftB 52s ease-in-out infinite alternate;
}

@keyframes driftA {
  from { transform: translate(0, 0) scale(1); }
  to { transform: translate(4%, 6%) scale(1.08); }
}

@keyframes driftB {
  from { transform: translate(0, 0) scale(1); }
  to { transform: translate(-5%, 4%) scale(1.05); }
}

.bokeh-layer {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: url("assets/home-hero-dark.png");
  background-size: cover;
  background-position: center top;
  opacity: var(--bokeh-opacity);
  mix-blend-mode: screen;
  pointer-events: none;
}

[data-theme="light"] .bokeh-layer {
  background-image: url("assets/home-hero-light.png");
  mix-blend-mode: normal;
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------- */
/* Launch banner -- strip above the nav, announcing the App Store launch.
   Not sticky: it scrolls away with the page while .nav (below) stays
   pinned, same pattern as a normal announcement bar. */
.launch-banner {
  position: relative;
  z-index: 51;
  background: linear-gradient(90deg, rgba(242, 169, 78, 0.22), rgba(139, 107, 255, 0.22));
  border-bottom: 1px solid var(--amber-soft);
}

.launch-banner .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 14px;
  padding: 10px 24px;
  text-align: center;
}

.launch-banner-text {
  margin: 0;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--white);
}

.launch-banner-cta {
  flex-shrink: 0;
  padding: 6px 16px;
  border-radius: 999px;
  background: var(--amber);
  color: var(--bg-black);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease);
}

.launch-banner-cta:hover {
  background: var(--amber-highlight);
  transform: translateY(-1px);
}

/* ---------------------------------------------------------------------- */
/* Nav                                                                      */
/* ---------------------------------------------------------------------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  background: var(--nav-bg);
  border-bottom: 1px solid var(--nav-border);
}

.nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 68px;
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Tomorrow", -apple-system, BlinkMacSystemFont, "SF Pro Text",
    "SF Pro Display", sans-serif;
  font-weight: 400;
  font-size: 17px;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--white);
}

.nav-brand img {
  width: 28px;
  height: 28px;
  border-radius: 8px;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Icon-only, no label text per design -- the sun/moon glyph itself states
   the action (tap sun to brighten, tap moon to darken); aria-label carries
   the same meaning to assistive tech. Sized and styled like a compact
   twin of .nav-cta so the two read as one control group. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 999px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border-strong);
  color: var(--white);
  cursor: pointer;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease), border-color 0.35s var(--ease);
}

.theme-toggle:hover {
  background: rgba(242, 169, 78, 0.14);
  border-color: var(--amber-soft);
  transform: translateY(-1px);
}

.theme-toggle svg {
  width: 17px;
  height: 17px;
}

.theme-toggle .icon-moon {
  display: none;
}

[data-theme="light"] .theme-toggle .icon-sun {
  display: none;
}

[data-theme="light"] .theme-toggle .icon-moon {
  display: block;
}

/* App icon -- swaps to the app's own light-mode icon variant (same asset
   catalog as the iOS app's AppIconLight) rather than just showing the dark
   icon on a light page. Shared by the nav brand mark, the hero icon, and
   the footer brand mark. */
.icon-light {
  display: none;
}

[data-theme="light"] .icon-dark {
  display: none;
}

[data-theme="light"] .icon-light {
  display: block;
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px;
  border-radius: 999px;
  background: var(--glass-bg-strong);
  border: 1px solid var(--glass-border-strong);
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease), border-color 0.35s var(--ease);
}

.nav-cta:hover {
  background: rgba(242, 169, 78, 0.14);
  border-color: var(--amber-soft);
  transform: translateY(-1px);
}

/* Nav gains contrast once scrolled past the hero -- see script.js. */
.nav.nav-scrolled .nav-cta {
  background: rgba(242, 169, 78, 0.16);
  border-color: var(--amber-soft);
}

/* ---------------------------------------------------------------------- */
/* Hero                                                                     */
/* ---------------------------------------------------------------------- */

.hero {
  position: relative;
  padding: 72px 0 96px;
}

/* .wrap already gives the hero its outer gutter (max-width + side padding,
   same as every other section); .hero-card is the glass surface *inside*
   that gutter, so the card never sits flush against the viewport edge. */
.hero-card {
  position: relative;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  align-items: center;
  gap: 40px;
  padding: 72px 64px;
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--glass-grad-1), var(--glass-grad-2));
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(22px) saturate(130%);
  -webkit-backdrop-filter: blur(22px) saturate(130%);
  box-shadow:
    0 50px 120px -50px var(--shadow-hero),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
}

.hero-copy .eyebrow {
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gray);
  margin: 0 0 22px;
  font-weight: 600;
}

/* Product-name wordmark, set above the tagline. Always in Tomorrow
   regular, matching the nav and footer marks. */
.hero-wordmark {
  margin: 0 0 8px;
  font-family: "Tomorrow", -apple-system, BlinkMacSystemFont, "SF Pro Text",
    "SF Pro Display", sans-serif;
  /* Stays regular weight per the wordmark spec -- size and color carry
     the extra emphasis instead of font-weight. */
  font-weight: 400;
  letter-spacing: 0.01em;
  font-size: clamp(20px, 2.4vw, 26px);
  color: var(--white);
}

.hero-title {
  margin: 0;
  font-weight: 750;
  letter-spacing: -0.02em;
  line-height: 1.05;
  /* Tuned so "READY | SET | SHOW" stays on one line within the hero-copy
     column at every desktop width (two-column layout kicks in at 981px).
     Below that, the mobile override in the responsive section rescales
     against vw instead of holding this 34px floor, so it keeps fitting
     on one line once the layout stacks full-width and narrows further. */
  font-size: clamp(34px, 4.6vw, 52px);
  color: var(--white);
  white-space: nowrap;
}

.hero-title .sep {
  color: var(--gray-dim);
  padding: 0 0.14em;
  font-weight: 300;
}

/* "Get OnStage" now sits beside the App Store badge inside .hero-ctas,
   as supporting pre-CTA text -- not styled as its own clickable control,
   so the badge stays the one obvious tap target. */
.hero-get {
  margin: 0;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--gray);
}

.hero-desc {
  margin: 18px 0 40px;
  max-width: 460px;
  font-size: 19px;
  line-height: 1.5;
  color: var(--gray);
  font-weight: 400;
}

.hero-ctas {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.appstore-badge {
  display: inline-flex;
  transition: transform 0.35s var(--ease), filter 0.35s var(--ease);
  border-radius: 12px;
}

.appstore-badge:hover {
  transform: translateY(-2px) scale(1.015);
  filter: brightness(1.08);
}

.appstore-badge svg {
  display: block;
  height: 54px;
  width: auto;
}

.hero-note {
  font-size: 13px;
  color: var(--gray-dim);
}

/* Hero icon stage */

.hero-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Sized to the icon itself now that the glass surface behind it is the
     whole hero card (.hero-card), not a small plane scoped to this box. */
  min-height: calc(min(58vw, 340px) + 24px);
}

.hero-stage-glow {
  position: absolute;
  width: 120%;
  height: 120%;
  background: radial-gradient(circle at 45% 40%, var(--violet-soft) 0%, transparent 45%),
    radial-gradient(circle at 60% 65%, var(--amber-soft) 0%, transparent 45%);
  filter: blur(50px);
  opacity: 0.85;
  pointer-events: none;
}

.hero-icon-link {
  position: relative;
  display: block;
  width: min(58vw, 340px);
  perspective: 900px;
  transform: translateZ(0);
  will-change: transform;
  transition: transform 0.5s var(--ease);
  border-radius: 26.5%;
}

.hero-icon-tilt {
  transform-style: preserve-3d;
  will-change: transform;
}

.hero-icon-link img {
  width: 100%;
  height: auto;
  border-radius: 26.5%;
  box-shadow:
    0 30px 60px -18px var(--shadow-hero-icon),
    0 12px 30px -8px rgba(124, 92, 255, 0.35),
    0 0 0 1px rgba(255, 255, 255, 0.06);
}

.hero-icon-link:hover,
.hero-icon-link:focus-visible {
  transform: translateY(-6px) scale(1.015);
}

.hero-icon-link:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 8px;
}

.hero-icon-caption {
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  color: var(--gray-dim);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------- */
/* Sections — shared                                                       */
/* ---------------------------------------------------------------------- */

section {
  position: relative;
  padding: 88px 0;
}

.section-label {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber);
  font-weight: 650;
  margin: 0 0 16px;
}

.section-title {
  font-size: clamp(28px, 3.6vw, 42px);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 22px;
  color: var(--white);
}

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Our Story -- Who We Are + How It Started as one continuous editorial
   column under a single heading; reads like a magazine profile, not a
   sequence of slide-sized beats. Top padding is 0 -- the gap in from
   Meet the Team is carried entirely by .team's bottom padding below,
   matching the single-sided-gap convention used elsewhere on the page. */

.story {
  padding: 0 0 132px;
  background: linear-gradient(180deg, transparent, rgba(139, 107, 255, 0.04) 25%, rgba(139, 107, 255, 0.04) 75%, transparent);
}

.story .wrap {
  max-width: var(--content);
}

.story-lede {
  font-size: 23px;
  line-height: 1.55;
  font-weight: 450;
  letter-spacing: -0.005em;
  color: var(--white);
  margin: 0 0 44px;
}

/* Vision + Mission -- one composed chapter. The pair is centered as a
   single unit inside one near-full-screen block; equal typographic
   weight for both statements, differentiated only by color, with a
   moderate (not screen-sized) pause between them so they read as a pair
   rather than two independent beats. */

.statement-chapter {
  min-height: 88vh;
  display: flex;
  align-items: center;
  padding: 48px 0 32px;
  background: var(--panel-scrim);
}

.statement-chapter-inner {
  max-width: var(--content);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
}

.statement-block {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.statement-kicker {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-dim);
  font-weight: 650;
  margin: 0 0 20px;
}

.statement-line {
  font-size: clamp(30px, 4.6vw, 56px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
}

.vision-line {
  color: var(--white);
}

.mission-line {
  background: linear-gradient(120deg, var(--amber) 0%, var(--amber-highlight) 50%, var(--amber) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.origin-date {
  font-size: 15px;
  color: var(--gray-dim);
  margin: 0 0 26px;
}

.story p {
  font-size: 17.5px;
  line-height: 1.75;
  color: var(--gray);
  margin: 0 0 26px;
}

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

.story strong {
  color: var(--white);
  font-weight: 600;
}

/* What is OnStage */

.what .wrap {
  max-width: var(--content);
}

.what-prominent .section-title {
  font-size: clamp(32px, 4.6vw, 54px);
  margin-bottom: 26px;
}

.what p {
  font-size: 18px;
  line-height: 1.7;
  color: var(--gray);
  margin: 0 0 18px;
}

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

/* Hero -> Meet OnStage -> Follow the Show should read as one quick,
   energetic sequence of short breaths, not three stately, evenly-spaced
   blocks -- see the combined budget note above .capabilities below. */
.what-prominent {
  padding-top: 96px;
  padding-bottom: 72px;
  background: linear-gradient(180deg, var(--section-scrim-a), var(--section-scrim-b) 35%, var(--section-scrim-b) 65%, var(--section-scrim-a));
}

/* ---------------------------------------------------------------------- */
/* Follow the Show — full-bleed, scroll-driven horizontal product tour     */
/* This section deliberately does NOT use .wrap / var(--content) like the  */
/* rest of the page: it's meant to break out of the site's normal column   */
/* so the horizontal track can read as its own wide composition.           */
/* ---------------------------------------------------------------------- */

/* This section supplies none of its own top padding: the ~72px breath
   between the Meet OnStage copy and this heading comes entirely from
   .what-prominent's padding-bottom above, so the two beats don't stack
   two separate gaps on top of each other. */
.capabilities {
  padding-top: 0;
  --showcase-inset: clamp(24px, 6vw, 96px);
}

.showcase {
  position: relative;
}

.showcase-pin {
  position: static;
}

.showcase-heading {
  margin: 36px 0 36px;
  padding-left: var(--showcase-inset);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--white);
}

.showcase-viewport {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  padding-bottom: 6px;
}

.showcase-viewport::-webkit-scrollbar {
  display: none;
}

.showcase-track {
  display: flex;
  gap: 24px;
  padding: 0 var(--showcase-inset);
  transform: none;
}

/* Each card is one composed unit -- device art and copy share a single
   glass surface, never floating separately. */
.showcase-card {
  flex: 0 0 min(86vw, 460px);
  scroll-snap-align: center;
  opacity: 1;
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 28px;
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--glass-grad-1), var(--glass-grad-2));
  border: 1px solid var(--glass-border);
  box-shadow:
    0 40px 90px -46px var(--shadow-card),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.showcase-card-media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}

.showcase-card-media:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}

/* Expand affordance -- hidden until hover/focus on pointer devices that
   support it; always shown on touch, where there's no hover to reveal it. */
.showcase-media-expand {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(7, 5, 11, 0.55);
  border: 1px solid var(--glass-border-strong);
  color: var(--white);
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
  pointer-events: none;
}

.showcase-media-expand svg {
  width: 16px;
  height: 16px;
}

[data-theme="light"] .showcase-media-expand {
  background: rgba(255, 255, 255, 0.75);
}

.showcase-card-media:hover .showcase-media-expand,
.showcase-card-media:focus-visible .showcase-media-expand {
  opacity: 1;
  transform: scale(1);
}

@media (hover: none) {
  .showcase-media-expand {
    opacity: 1;
    transform: scale(1);
  }
}

.showcase-card-media img {
  width: auto;
  height: auto;
  max-height: min(40vh, 380px);
  max-width: 100%;
  object-fit: contain;
  display: block;
}

/* Light-mode screenshot variants -- same dark/light swap pattern as the app
   icon, but scoped to .showcase-card-media so it wins over the more specific
   ".showcase-card-media img { display: block; }" rule above. */
.showcase-card-media .icon-light {
  display: none;
}

[data-theme="light"] .showcase-card-media .icon-dark {
  display: none;
}

[data-theme="light"] .showcase-card-media .icon-light {
  display: block;
}

.showcase-card-copy {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.showcase-card-copy h3 {
  margin: 0;
  font-size: clamp(21px, 2.2vw, 26px);
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.01em;
}

.showcase-card-copy p {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--gray);
}

/* CarPlay -- the only horizontal-photo card in the showcase. It breaks from
   the shared device-mockup + side-by-side copy pairing: a wider card, full-
   width landscape photo in its own rounded frame on top, copy stacked below. */
.showcase-card--wide {
  flex-basis: min(90vw, 640px);
}

.showcase-card-media--photo {
  width: 100%;
}

.showcase-card-media--photo img {
  width: 100%;
  height: auto;
  max-width: none;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-md);
  display: block;
}

/* Pin the section and drive the track's position (and a subtle
   scale/opacity difference for hierarchy) from scroll via JS -- see
   script.js. Applies at every width, mobile included -- only
   reduced-motion falls back to the plain swipeable row above (the two
   modes share one set of markup).

   Every level below is sized as a percentage of the level above it, all
   the way down to the screenshot -- rather than each card guessing a vh
   value that may or may not fit. That guarantees the card always fits
   exactly inside the pinned frame (rounded corners included, never
   clipped) and the screenshot always fills whatever room is left over
   after its copy text, which is also the most it could ever safely be. */
@media (prefers-reduced-motion: no-preference) {
  .showcase {
    /* svh (the viewport height with mobile browser toolbars accounted
       for) keeps this scroll-distance total stable as those toolbars
       collapse/expand mid-scroll; without it the total and the JS's
       window.innerHeight reading drift out of sync on mobile Safari and
       the slide-advance math stalls. vh stays first as a fallback for
       browsers that don't support svh. */
    height: calc(100vh + 5 * 85vh);
    height: calc(100svh + 5 * 85svh);
  }

  .showcase-pin {
    position: sticky;
    top: 68px;
    /* Shorter than the full 100vh - 68px available: the panel stops
       short of the viewport's bottom edge so it reads as hovering above
       it, not pinned flush against it. */
    height: calc(100vh - 68px - 56px);
    height: calc(100svh - 68px - 56px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .showcase-heading {
    flex: 0 0 auto;
  }

  .showcase-viewport {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    scroll-snap-type: none;
    padding-bottom: 0;
  }

  .showcase-track {
    height: 100%;
    transform: translate3d(0, 0, 0);
    will-change: transform;
  }

  .showcase-card {
    height: 100%;
    padding: 24px;
    gap: 18px;
    opacity: var(--showcase-opacity, 1);
    transform: scale(var(--showcase-scale, 1));
    transition: opacity 0.2s linear, transform 0.2s linear;
  }

  /* Mobile stacks media above copy in a flex column -- the media block
     grows to fill whatever height the copy text doesn't need. */
  .showcase-card-media {
    flex: 1 1 auto;
    min-height: 0;
  }

  .showcase-card-copy {
    flex: 0 0 auto;
  }

  .showcase-card-media img {
    max-height: 100%;
    max-width: 100%;
  }

  /* CarPlay's landscape photo fills its box edge-to-edge instead of being
     bounded by an aspect-ratio that may not match the space available. */
  .showcase-card-media--photo img {
    width: 100%;
    height: 100%;
    max-width: none;
    aspect-ratio: auto;
    object-fit: cover;
  }
}

/* Desktop: same stacked shape as every other width -- media on top, copy
   below, one glass panel -- just wider cards and more breathing room,
   since there's more screen to give it. A two-column (phone beside copy)
   layout was tried here and dropped in favor of this stacked shape at
   every width; it read better regardless of screen size. */
@media (min-width: 981px) and (prefers-reduced-motion: no-preference) {
  .showcase-track {
    gap: 48px;
    padding: 0 0 0 var(--showcase-inset);
  }

  .showcase-card {
    flex: 0 0 min(38vw, 480px);
    padding: 40px;
    gap: 28px;
  }

  .showcase-card-copy p {
    max-width: 42ch;
  }

  /* Wide card carries a landscape photo instead of a portrait device
     mockup, so it gets noticeably more width. */
  .showcase-card--wide {
    flex-basis: min(58vw, 760px);
  }

  .showcase-card--wide .showcase-card-copy p {
    max-width: none;
  }
}

/* ---------------------------------------------------------------------- */
/* Team                                                                     */
/* ---------------------------------------------------------------------- */

/* An amber-lit transition into this closing chapter of the page. Top
   padding is the gap in from the Vision/Mission chapter; bottom padding
   is the gap into Our Story below -- both single-sided, per the page's
   spacing convention. */
.team {
  padding: 96px 0 104px;
  background: linear-gradient(180deg, transparent, rgba(242, 169, 78, 0.045) 35%, rgba(242, 169, 78, 0.045) 65%, transparent);
}

.team .wrap {
  max-width: 880px;
}

.team-grid {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-top: 28px;
}

/* Flattened: lighter background, near-invisible border -- less glass,
   more plain surface -- kept compact so the pair reads as editorial, not
   a pair of dashboard modules. */
.team-card {
  padding: 28px 32px;
  border-radius: var(--radius-md);
  background: var(--card-flat-bg);
  border: 1px solid var(--card-flat-border);
  transition: border-color 0.4s var(--ease);
}

.team-card:hover {
  border-color: var(--glass-border);
}

.team-name {
  font-size: 24px;
  font-weight: 750;
  color: var(--white);
  margin: 0 0 4px;
  letter-spacing: -0.01em;
}

.team-nickname {
  color: var(--amber);
  font-weight: 600;
}

.team-role {
  font-size: 12.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--amber);
  margin: 0 0 18px;
  font-weight: 650;
}

.team-bio {
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--gray);
  margin: 0;
}

/* ---------------------------------------------------------------------- */
/* Closing CTA                                                             */
/* ---------------------------------------------------------------------- */

/* Compressed into a single contained panel rather than another near-
   full-screen statement section -- the page's closing beat, not another
   chapter. Top padding is 0 -- the gap in from Our Story is carried by
   .story's own bottom padding above; bottom padding is the gap into the
   footer. */
.closing {
  text-align: center;
  padding: 0 0 80px;
}

.closing .wrap {
  max-width: 560px;
  padding: 84px 40px;
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--glass-grad-3), var(--glass-grad-4));
  border: 1px solid var(--glass-border);
  box-shadow: 0 30px 70px -42px var(--shadow-closing), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.closing-title {
  font-size: clamp(26px, 3.6vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 26px;
}

.closing-desc {
  font-size: 17px;
  color: var(--gray);
  margin: 0 0 36px;
  line-height: 1.6;
}

.closing-ctas {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

/* ---------------------------------------------------------------------- */
/* Footer                                                                   */
/* ---------------------------------------------------------------------- */

/* Darkest tone on the page -- footer settles below all the ambient
   stage-glow used elsewhere. */
footer {
  position: relative;
  z-index: 1;
  background: var(--bg-black);
  border-top: 1px solid var(--hairline);
  padding: 36px 0 44px;
}

.footer-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  margin-bottom: 26px;
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Tomorrow", -apple-system, BlinkMacSystemFont, "SF Pro Text",
    "SF Pro Display", sans-serif;
  font-weight: 400;
  font-size: 16px;
}

.footer-brand img {
  width: 24px;
  height: 24px;
  border-radius: 7px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-links a {
  font-size: 13.5px;
  color: var(--gray-dim);
  text-decoration: none;
  transition: color 0.25s var(--ease);
}

.footer-links a:hover {
  color: var(--white);
}

.footer-bottom {
  font-size: 13px;
  color: var(--gray-dim);
  border-top: 1px solid var(--hairline-soft);
  padding-top: 22px;
}

/* ---------------------------------------------------------------------- */
/* Responsive                                                               */
/* ---------------------------------------------------------------------- */

@media (max-width: 980px) {
  .hero-card {
    grid-template-columns: 1fr;
    text-align: center;
    padding: 56px 40px;
  }

  /* Rescales against vw (rather than the desktop clamp's 34px floor) and
     never wraps, so "READY | SET | SHOW" stays on one line as the stacked
     layout keeps narrowing all the way down to small phones. */
  .hero-title {
    font-size: clamp(20px, 7.8vw, 34px);
    white-space: nowrap;
  }

  .hero-desc {
    max-width: 560px;
    margin-left: auto;
    margin-right: auto;
  }

  .hero-ctas {
    justify-content: center;
  }

  .hero-stage {
    order: -1;
  }
}

@media (max-width: 640px) {
  .wrap {
    padding: 0 20px;
  }

  .hero {
    padding: 40px 0 56px;
  }

  .hero-card {
    padding: 40px 24px;
    border-radius: var(--radius-md);
  }

  section {
    padding: 64px 0;
  }

  .hero-ctas {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .appstore-badge {
    align-self: center;
  }

  .nav-cta span.long {
    display: none;
  }
}

/* ---------------------------------------------------------------------- */
/* Screenshot lightbox                                                     */
/* ---------------------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.32s var(--ease), visibility 0s linear 0.32s;
}

.lightbox.is-open {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.32s var(--ease);
}

.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(7, 5, 11, 0.8);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
}

[data-theme="light"] .lightbox-backdrop {
  background: rgba(242, 242, 247, 0.85);
}

/* Scale only -- opacity is NOT set here on purpose. The stage sits inside
   .lightbox, which already fades the whole dialog (backdrop, buttons, and
   this stage) in one pass; giving the stage its own opacity transition on
   top would compound multiplicatively with the parent's (two fades
   stacked = opacity_a * opacity_b), making the image vanish well before
   the buttons and before any scale motion is visible. One fade, one
   scale, both readable together. */
.lightbox-stage {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 97vw;
  max-height: 96vh;
  padding: 0 16px;
  transform: scale(0.92);
  transition: transform 0.32s var(--ease);
  touch-action: none;
}

.lightbox.is-open .lightbox-stage {
  transform: scale(1);
}

/* No card fill behind the image -- the screenshot sits directly on the
   blurred backdrop, background: none rather than the glass-tint used
   elsewhere, so it reads as the photo itself, not a panel holding it. */
.lightbox-image {
  display: block;
  max-width: 100%;
  max-height: 93vh;
  background: none;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--glass-border-strong);
  color: var(--white);
  cursor: pointer;
  transition: background 0.2s var(--ease), transform 0.2s var(--ease);
}

[data-theme="light"] .lightbox-close,
[data-theme="light"] .lightbox-nav {
  background: rgba(20, 12, 30, 0.06);
}

.lightbox-close:hover,
.lightbox-nav:hover {
  background: rgba(255, 255, 255, 0.16);
  transform: translateY(-50%) scale(1.05);
}

.lightbox-close:hover {
  transform: scale(1.05);
}

.lightbox-close:focus-visible,
.lightbox-nav:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 3px;
}

.lightbox-close {
  top: 24px;
  right: 24px;
  width: 44px;
  height: 44px;
}

.lightbox-close svg {
  width: 20px;
  height: 20px;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 52px;
}

.lightbox-nav svg {
  width: 22px;
  height: 22px;
}

.lightbox-prev {
  left: 24px;
}

.lightbox-next {
  right: 24px;
}

/* A single-item gallery has nowhere to navigate to -- hidden by JS via
   this class rather than removed, so re-opening never has to re-add them. */
.lightbox-nav.is-hidden {
  display: none;
}

body.lightbox-open {
  overflow: hidden;
}

@media (max-width: 720px) {
  .lightbox-stage {
    padding: 0 10px;
  }

  .lightbox-close {
    top: 16px;
    right: 16px;
    width: 40px;
    height: 40px;
  }

  .lightbox-nav {
    width: 42px;
    height: 42px;
  }

  .lightbox-prev {
    left: 8px;
  }

  .lightbox-next {
    right: 8px;
  }

  .lightbox-image {
    max-height: 90vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox,
  .lightbox-stage,
  .lightbox-image {
    transition-duration: 0.15s;
  }
}
