/* =====================================================================
   site.css — the shell: hero, horizontal showcase rail, manifesto.
   The app replica itself lives in app.css.
   ===================================================================== */

@font-face {
  font-family: "Satoshi";
  src: url("../fonts/satoshi-var.woff2") format("woff2-variations");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #101114;
  --ink-2: #3d3f45;
  --muted: #74767e;
  --cream: #fffdf8;
  --amber: #f5b400;
  --amber-lite: #ffe9a8;
  --line: rgba(16, 17, 20, 0.1);

  --f-display: "Satoshi", -apple-system, "Segoe UI", system-ui, sans-serif;
  --f-ui: -apple-system, "SF Pro Text", "Inter", system-ui, sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --nav-h: 62px;
  --pad: clamp(20px, 5vw, 60px);
  /* one edge inset for the whole page: the nav uses it, and the slide
     card uses it too, so the card starts under the logo and ends under
     the last menu item with the same air on both sides */
  --edge: clamp(16px, 3vw, 34px);
  --gutter: var(--edge);
  --peek: 0px;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--f-display);
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  overflow: hidden; /* the .deck scrolls, not the body */
}

img {
  display: block;
  max-width: 100%;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
::selection {
  background: var(--amber-lite);
  color: var(--ink);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* =====================================================================
   Nav
   ===================================================================== */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--nav-h);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--edge);
  pointer-events: none;
}
.nav > * {
  pointer-events: auto;
}
.nav-brand {
  display: flex;
  align-items: center;
  gap: 9px;
}
.nav-brand img.mark {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.nav-brand img.word {
  height: 16px;
  width: auto;
  object-fit: contain;
}
/* Menu items are plain text on the background, icon first, the way an
   app's own menu reads. No pills, no filled buttons. */
.nav-menu {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.1vw, 32px);
}
.mi {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--ink-2);
  transition: color 0.2s;
}
.mi svg {
  width: 17px;
  height: 17px;
  flex: none;
  opacity: 0.72;
  transition: opacity 0.2s, color 0.2s;
}
.mi:hover {
  color: var(--ink);
}
.mi:hover svg {
  opacity: 1;
  color: var(--amber);
}
/* the legal pair and its divider belong to the mobile panel only; on a
   desktop bar they would crowd the four real destinations */
.mi-divider,
.mi-small {
  display: none;
}

/* the page behind the open menu goes soft, so the panel reads as a layer
   on top rather than another thing competing with the slide */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(28, 24, 12, 0.18);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease), visibility 0.3s;
}
body.menu-open .nav-scrim {
  opacity: 1;
  visibility: visible;
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  backdrop-filter: blur(14px) saturate(1.1);
}

/* mobile trigger, hidden on desktop */
.nav-toggle {
  display: none;
  width: 40px;
  height: 40px;
  /* pull the 40px tap target out so the visible burger lines up with the
     card edge below it, not the invisible box around it */
  margin-right: -11px;
  border-radius: 12px;
  place-items: center;
  color: var(--ink);
  transition: background 0.2s;
}
.nav-toggle .ic-cross {
  display: none;
}
body.menu-open .nav-toggle .ic-burger {
  display: none;
}
body.menu-open .nav-toggle .ic-cross {
  display: block;
}

/* =====================================================================
   Deck: full-screen vertical snap track
   ===================================================================== */

.deck {
  height: 100dvh;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-y: none;
  scrollbar-width: none;
}
.deck::-webkit-scrollbar {
  display: none;
}

.screen {
  position: relative;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
  isolation: isolate;
}

/* warm brand wash, same family as the App Store screenshots:
   white top-left, honey bottom-right */
.wash {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(90% 70% at 8% 4%, #ffffff 0%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(75% 60% at 100% 30%, #fbdc8e 0%, rgba(251, 220, 142, 0) 68%),
    linear-gradient(128deg, #fffdf8 0%, #fff6df 44%, #fce9b4 100%);
}
/* quiet ground behind the slide cards, so the cards themselves carry the
   warmth and read as separate surfaces */
.wash.cool {
  background: linear-gradient(150deg, #fbf7ee 0%, #f7f1e2 100%);
}
.wash.deep {
  background:
    radial-gradient(80% 60% at 12% 0%, #ffffff 0%, rgba(255, 255, 255, 0) 58%),
    radial-gradient(85% 70% at 100% 40%, #f6cf78 0%, rgba(246, 207, 120, 0) 66%),
    linear-gradient(135deg, #fffcf4 0%, #fdefc9 50%, #f7dc9a 100%);
}

/* =====================================================================
   Shared type + buttons (intro slide, closing screen, manifesto)
   ===================================================================== */


h1 {
  margin-top: 22px;
  font-size: clamp(40px, 6.6vw, 82px);
  font-weight: 900;
  line-height: 0.98;
  letter-spacing: -0.038em;
  color: var(--ink);
  text-wrap: balance;
}
h1 .thin {
  font-weight: 400;
  color: var(--ink-2);
}

.hero-actions {
  margin-top: 32px;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 14px 24px;
  border-radius: 999px;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease),
    background 0.2s;
}
.btn svg {
  flex: none;
}
.btn-primary {
  background: var(--ink);
  color: #fff;
  box-shadow: 0 10px 24px -10px rgba(16, 17, 20, 0.55);
}
.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 32px -12px rgba(16, 17, 20, 0.55);
}
.btn-ghost {
  color: var(--ink);
  border: 1px solid rgba(16, 17, 20, 0.16);
  background: rgba(255, 255, 255, 0.5);
}
.btn-ghost:hover {
  background: #fff;
  transform: translateY(-2px);
}

.hero-note {
  margin-top: 16px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: #a09a86;
  letter-spacing: 0.01em;
}

/* =====================================================================
   Showcase: horizontal rail of modules
   ===================================================================== */

#showcase {
  display: grid;
  /* minmax(0,...) on both axes: neither the rail nor the hint row may
     grow the column beyond the screen */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
}

/* One compact line under the card: a dot travelling along a track shows
   which way to move, the word says what you get. Two words, no sentence. */
.rail-hints {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  min-width: 0;
  gap: clamp(14px, 2.2vw, 26px);
  padding: clamp(11px, 1.6vh, 18px) var(--edge)
    max(clamp(11px, 1.6vh, 18px), env(safe-area-inset-bottom));
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #a09277;
}
.hint-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  transition: color 0.2s;
}
.hint-down:hover {
  color: var(--ink);
}
.hint-sep {
  width: 1px;
  height: 12px;
  background: rgba(16, 17, 20, 0.14);
  flex: none;
}

/* Minimal slider indicator: grey dots, the active one grows into an
   amber pill. Width and colour both ease, so moving between slides reads
   as one continuous motion instead of a jump. */
.slide-dots {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: none;
}
.slide-dots button {
  width: 6px;
  height: 6px;
  padding: 0;
  border-radius: 999px;
  background: rgba(16, 17, 20, 0.16);
  transition: width 0.45s var(--ease), background-color 0.45s var(--ease),
    transform 0.45s var(--ease);
}
.slide-dots button:hover {
  background: rgba(16, 17, 20, 0.3);
}
.slide-dots button[aria-current="true"] {
  width: 22px;
  background: var(--amber);
}

/* the glyphs: a track with a dot that keeps making the gesture */
.gl {
  flex: none;
  overflow: visible;
}
.gl-x {
  width: 22px;
  height: 14px;
}
.gl-y {
  width: 14px;
  height: 22px;
}
.gl rect {
  fill: currentColor;
  opacity: 0.22;
}
.gl .dot {
  fill: var(--amber);
}
.gl-x .dot {
  animation: gl-swipe-x 2.4s var(--ease) infinite;
}
.gl-y .dot {
  animation: gl-swipe-y 2.4s var(--ease) infinite;
}
@keyframes gl-swipe-x {
  0%, 8% { transform: translateX(0); }
  50%, 58% { transform: translateX(14px); }
  100% { transform: translateX(0); }
}
@keyframes gl-swipe-y {
  0%, 8% { transform: translateY(0); }
  50%, 58% { transform: translateY(14px); }
  100% { transform: translateY(0); }
}

@media (max-width: 420px) {
  .rail-hints {
    font-size: 10.5px;
    gap: 12px;
    letter-spacing: 0.12em;
  }
  .slide-dots {
    gap: 6px;
  }
  .slide-dots button[aria-current="true"] {
    width: 18px;
  }
}

.rail {
  position: relative;
  min-height: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  /* contain on x stops a sideways swipe triggering the browser's
     back-gesture at the edges. y stays auto on purpose: that is what lets
     a downward swipe inside the rail carry on to the screen below. */
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x pan-y;
  cursor: grab;
}
.rail::-webkit-scrollbar {
  display: none;
}
.rail.dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}
/* JS turns snapping off while it animates the rail itself */
.rail.gliding {
  scroll-snap-type: none;
}

/* Each slide is a panel holding one big rounded card, inset by --edge on
   every side so it lines up with the nav above it. --peek is kept as a
   token (set to 0) so the rail maths stays in one place. */
.panel {
  flex: none;
  width: calc(100% - var(--peek));
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: grid;
  padding: calc(var(--nav-h) + clamp(6px, 1vh, 12px)) var(--gutter)
    var(--gutter);
}
/* lets the last panel still settle against the left edge */
.rail-tail {
  flex: none;
  width: var(--peek);
  height: 100%;
}

.module {
  --card-r: clamp(20px, 2.2vw, 34px);
  height: 100%;
  min-height: 0;
  border-radius: var(--card-r);
  overflow: hidden;
  background:
    radial-gradient(85% 65% at 6% 0%, #ffffff 0%, rgba(255, 255, 255, 0) 58%),
    radial-gradient(70% 60% at 100% 20%, #fbdc8e 0%, rgba(251, 220, 142, 0) 70%),
    linear-gradient(134deg, #fffdf8 0%, #fff6df 46%, #fbe6ae 100%);
  box-shadow:
    0 0 0 1px rgba(120, 96, 34, 0.07),
    0 18px 40px -22px rgba(90, 72, 26, 0.28);
  /* content stays capped at 1240 while the card itself runs full width */
  padding: clamp(20px, 4vh, 56px)
    max(var(--pad), calc((100% - 1240px) / 2 + var(--pad))) 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  align-items: center;
  gap: clamp(20px, 4vw, 70px);
}

.module-copy {
  max-width: 560px;
}
.module-no {
  font-family: var(--f-ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: #b39a55;
}
.module h2 {
  margin-top: 14px;
  font-size: clamp(32px, 4.5vw, 58px);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--ink);
  text-wrap: balance;
}
.module .sub {
  margin-top: 16px;
  font-family: var(--f-ui);
  font-size: clamp(14.5px, 1.25vw, 17.5px);
  font-weight: 400;
  line-height: 1.55;
  color: var(--muted);
  letter-spacing: -0.01em;
  max-width: 34ch;
}

/* Same here: the crop belongs to .panel / .module, not to this column.
   Clipping it here cut the right bezel off and squared off the shadow. */
.module-visual {
  position: relative;
  height: 100%;
  min-height: 0;
}
/* push the device down far enough that the card's bottom edge always
   crops it, the way the App Store screenshots are composed */
.module-visual .phone-stage {
  padding-top: clamp(14px, 7vh, 84px);
}

/* entrance: each panel's content settles when it becomes the active one */
.panel .module-copy > *,
.panel .module-visual {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.4s var(--ease), transform 0.45s var(--ease);
}
.panel.live .module-copy > *,
.panel.live .module-visual {
  opacity: 1;
  transform: none;
}
.panel.live .module-copy > *:nth-child(2) {
  transition-delay: 0.04s;
}
.panel.live .module-copy > *:nth-child(3) {
  transition-delay: 0.07s;
}
.panel.live .module-copy > *:nth-child(4) {
  transition-delay: 0.1s;
}
.panel.live .module-visual {
  transition-delay: 0.03s;
}

/* The card behind sits back a touch, so the peek reads as a stack you can
   pull forward rather than a cropped page. */
.module {
  transition: transform 0.55s var(--ease), opacity 0.55s var(--ease);
}
.panel:not(.live) .module {
  transform: scale(0.955);
  opacity: 0.72;
}

/* The arrows stay in the DOM for keyboard and screen-reader users and
   appear only when tabbed to. Pointers never see them: the peeking card
   and the settle nudge do that job without covering the slide. */
.rail-nav {
  position: absolute;
  top: 50%;
  z-index: 6;
  opacity: 0;
  pointer-events: none;
  width: clamp(38px, 3.4vw, 48px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.66);
  border: 1px solid rgba(16, 17, 20, 0.09);
  box-shadow: 0 6px 18px -8px rgba(70, 55, 15, 0.3);
  display: grid;
  place-items: center;
  color: var(--ink);
  transform: translateY(-50%);
  transition: transform 0.25s var(--ease), background 0.2s, opacity 0.25s;
}
.rail-nav.prev {
  left: clamp(10px, 2.2vw, 32px);
}
.rail-nav.next {
  right: clamp(10px, 2.2vw, 32px);
}
.rail-nav:focus,
.rail-nav:focus-visible {
  opacity: 1;
  pointer-events: auto;
  -webkit-backdrop-filter: blur(10px) saturate(1.4);
  backdrop-filter: blur(10px) saturate(1.4);
}
.rail-nav:focus:hover:not(:disabled) {
  background: #fff;
  transform: translateY(-50%) scale(1.07);
}
.rail-nav:disabled {
  opacity: 0;
  pointer-events: none;
}


/* the two stores sit under the buttons in exactly the menu-bar style */
.store-links {
  margin-top: 22px;
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.2vw, 30px);
  flex-wrap: wrap;
}
.store-links .mi {
  font-size: 15px;
}
.store-links .mi svg {
  width: 18px;
  height: 18px;
}
@media (max-width: 900px), (max-aspect-ratio: 10/9) {
  .store-links {
    justify-content: center;
    margin-top: 16px;
  }
}

/* =====================================================================
   Hook: the first screen. One claim, one action, and the live card
   doing on screen what the claim promises.
   ===================================================================== */

#hook {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
}
.hook-inner {
  width: min(1240px, 100%);
  margin: 0 auto;
  min-height: 0;
  padding: calc(var(--nav-h) + clamp(8px, 2vh, 30px)) var(--pad) 0;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(20px, 4vw, 64px);
}
.hook-copy {
  max-width: 620px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(18px, 2.6vh, 28px);
}
#hook h1 {
  margin-top: 0;
  font-size: clamp(44px, 7vw, 96px);
  line-height: 0.94;
  letter-spacing: -0.042em;
}
.hook-sub {
  margin-top: clamp(18px, 2.6vh, 28px);
  max-width: 34ch;
  font-family: var(--f-ui);
  font-size: clamp(16px, 1.4vw, 19px);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -0.01em;
  color: var(--muted);
}
#hook .store-links {
  margin-top: clamp(26px, 3.4vh, 38px);
  gap: clamp(18px, 2.4vw, 32px);
}
#hook .store-links .mi {
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}
#hook .store-links .mi svg {
  width: 21px;
  height: 21px;
  opacity: 0.9;
}
#hook .hero-note {
  margin-top: 14px;
}
.hook-visual {
  position: relative;
  /* the row is centred, so stretch this one back out or the live stage
     collapses to the card's own height and the card scales to minimum */
  align-self: stretch;
  height: 100%;
  min-height: 0;
}

/* the way down to the app */
.hook-cue {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: clamp(12px, 1.8vh, 20px) var(--edge)
    max(clamp(14px, 2vh, 22px), env(safe-area-inset-bottom));
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #a09277;
  transition: color 0.2s;
}
.hook-cue:hover {
  color: var(--ink);
}
.hook-cue svg {
  animation: cue-drop 2.4s var(--ease) infinite;
}
@keyframes cue-drop {
  0%, 100% { transform: translateY(0); opacity: 0.65; }
  50% { transform: translateY(4px); opacity: 1; }
}

@media (max-width: 900px), (max-aspect-ratio: 10/9) {
  .hook-inner {
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
    align-items: start;
    text-align: center;
    gap: clamp(14px, 2.5vh, 28px);
  }
  /* Stacked hero: one centred column with a single rhythm between the
     blocks, instead of each block carrying its own margin. */
  .hook-copy {
    margin: 0 auto;
    align-items: center;
  }
  #hook .store-links {
    justify-content: center;
    gap: clamp(20px, 6vw, 34px);
  }
  #hook h1 {
    font-size: clamp(38px, 11vw, 62px);
  }
  #hook .hero-note {
    display: none;
  }
}

/* =====================================================================
   Closing screen
   ===================================================================== */

#download .close-inner {
  height: 100%;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
  padding: var(--nav-h) clamp(20px, 5vw, 60px) 0;
  gap: 0;
}
#download .mark {
  width: 62px;
  height: 62px;
  object-fit: contain;
  margin-bottom: 26px;
}
#download h2 {
  font-size: clamp(32px, 5vw, 62px);
  font-weight: 900;
  line-height: 1.04;
  letter-spacing: -0.038em;
  text-wrap: balance;
  max-width: 19ch;
}
#download p {
  margin-top: 20px;
  max-width: 52ch;
  font-family: var(--f-ui);
  font-size: clamp(15px, 1.3vw, 18px);
  color: var(--muted);
  line-height: 1.55;
  max-width: 44ch;
}
#download .hero-actions {
  justify-content: center;
}
.foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0 clamp(20px, 5vw, 60px) 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--f-ui);
  font-size: 12.5px;
  color: #a09a86;
  flex-wrap: wrap;
}
.foot nav {
  display: flex;
  gap: 18px;
}
.foot a:hover {
  color: var(--ink);
}

/* =====================================================================
   Manifesto page
   ===================================================================== */

body.page {
  overflow: auto;
  background: var(--cream);
}
.page-wash {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(70% 50% at 82% -6%, #fbe3a6 0%, rgba(251, 227, 166, 0) 62%),
    radial-gradient(60% 45% at 4% 102%, #fdf0cd 0%, rgba(253, 240, 205, 0) 60%),
    var(--cream);
}

.mf {
  width: min(760px, 100%);
  margin: 0 auto;
  padding: calc(var(--nav-h) + clamp(50px, 12vh, 130px)) clamp(22px, 6vw, 40px)
    clamp(70px, 12vh, 140px);
}
.mf-lede h1 {
  margin-top: 20px;
  font-size: clamp(38px, 6.4vw, 74px);
  line-height: 0.99;
}
.mf-lede p {
  margin-top: 26px;
  font-family: var(--f-ui);
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.6;
  color: var(--ink-2);
  letter-spacing: -0.012em;
  max-width: 34ch;
}
.mf-rule {
  height: 1px;
  background: var(--line);
  margin: clamp(46px, 8vh, 82px) 0;
}
.mf-block + .mf-block {
  margin-top: clamp(44px, 7vh, 76px);
}
.mf-block h2 {
  font-size: clamp(24px, 3.2vw, 34px);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.12;
  text-wrap: balance;
}
.mf-block p {
  margin-top: 15px;
  font-family: var(--f-ui);
  font-size: clamp(15.5px, 1.6vw, 17.5px);
  line-height: 1.72;
  color: var(--ink-2);
  letter-spacing: -0.008em;
}
.mf-block p + p {
  margin-top: 13px;
}
.mf-pull {
  margin: clamp(48px, 8vh, 86px) 0;
  padding-left: clamp(18px, 3vw, 30px);
  border-left: 3px solid var(--amber);
  font-size: clamp(23px, 3vw, 33px);
  font-weight: 800;
  line-height: 1.22;
  letter-spacing: -0.026em;
  text-wrap: balance;
}
.mf-end {
  margin-top: clamp(56px, 9vh, 96px);
  padding-top: clamp(34px, 5vh, 52px);
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.mf-sign {
  font-family: var(--f-ui);
  font-size: 13.5px;
  color: var(--muted);
}

/* fade-in on scroll for the manifesto */
.rise {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.8s var(--ease), transform 0.9s var(--ease);
}
.rise.in {
  opacity: 1;
  transform: none;
}

/* =====================================================================
   Responsive
   ===================================================================== */

/* tablet and below: stack copy above the device, matching the
   composition of the App Store screenshots (headline, then phone
   cropped by the bottom edge) */
@media (max-width: 900px), (max-aspect-ratio: 10/9) {

  .module {
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
    align-items: start;
    gap: clamp(12px, 2.5vh, 26px);
    text-align: center;
  }
  .module {
    padding-top: clamp(18px, 3.5vh, 40px);
  }
    .module-copy {
    max-width: 620px;
    margin: 0 auto;
  }
    .module .sub {
    margin-left: auto;
    margin-right: auto;
  }
  .panel .hero-actions,
  .panel .store-links {
    justify-content: center;
  }
  /* stacked layout: let the device use the full panel width, not just the
     padded text column, but keep 14px so its shadow never hits the edge */
    .module-visual {
    width: auto;
    margin-inline: min(0px, calc(14px - var(--pad)));
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .module-visual .phone-stage {
    padding-top: clamp(4px, 1.2vh, 14px);
  }
}

/* =====================================================================
   Mobile menu: one trigger, then the same items at a size you can
   actually hit, in the same icon-then-text style.
   ===================================================================== */

@media (max-width: 1024px) {
  .nav-toggle {
    display: grid;
  }
  .mi-divider {
    display: block;
    height: 1px;
    margin: 8px 12px 6px;
    background: rgba(16, 17, 20, 0.1);
  }
  .mi-small {
    display: inline-flex;
    padding: 11px 14px;
    font-size: 15px;
    font-weight: 500;
    color: var(--muted);
  }
  .mi-small svg {
    width: 17px;
    height: 17px;
  }
  .mi-small + .mi-small {
    box-shadow: none;
  }
  .nav-menu {
    position: fixed;
    top: calc(var(--nav-h) - 4px);
    right: var(--edge);
    left: auto;
    width: min(340px, calc(100vw - 2 * var(--edge)));
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 10px;
    border-radius: 26px;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid rgba(16, 17, 20, 0.08);
    box-shadow: 0 26px 56px -20px rgba(70, 55, 15, 0.45);
    -webkit-backdrop-filter: blur(24px) saturate(1.6);
    backdrop-filter: blur(24px) saturate(1.6);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px) scale(0.97);
    transform-origin: top right;
    transition: opacity 0.24s var(--ease), transform 0.28s var(--ease),
      visibility 0.28s;
  }
  body.menu-open .nav-menu {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .nav-menu .mi {
    gap: 15px;
    padding: 17px 15px;
    border-radius: 16px;
    font-size: 20px;
    font-weight: 500;
    letter-spacing: -0.015em;
    color: var(--ink);
  }
  .nav-menu .mi + .mi {
    box-shadow: 0 -1px 0 rgba(16, 17, 20, 0.07);
  }
  .nav-menu .mi svg {
    width: 23px;
    height: 23px;
    opacity: 0.85;
  }
  .nav-menu .mi:active {
    background: rgba(16, 17, 20, 0.05);
  }
}

@media (max-width: 640px) {
  h1 {
    font-size: clamp(34px, 10.5vw, 52px);
  }
  .module h2 {
    font-size: clamp(27px, 8.2vw, 42px);
  }
    .module .sub {
    font-size: 15px;
  }
  .nav-link.hide-sm {
    display: none;
  }
  .btn {
    padding: 12px 20px;
    font-size: 14.5px;
  }
}

/* very short viewports: give the device the space instead of the copy */
@media (max-height: 620px) and (min-width: 901px) {
  .hero-actions {
    margin-top: 22px;
  }
  .hero-note {
    display: none;
  }
}
@media (max-width: 900px), (max-aspect-ratio: 10/9) {
  .hero-note {
    display: none;
  }
  .hero-actions {
    margin-top: 20px;
  }
  h1 {
    margin-top: 16px;
  }
  .hero-sub {
    margin-top: 14px;
  }
}

/* =====================================================================
   Motion + a11y
   ===================================================================== */

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .panel .module-copy > *,
  .panel .module-visual,
  .rise {
    opacity: 1 !important;
    transform: none !important;
  }
  .deck,
  .rail {
    scroll-snap-type: none;
  }
}

/* the rail is only focusable so screen readers can reach it; the ring
   around a full-screen slide reads as a selection box, so drop it there */
.rail:focus,
.rail:focus-visible {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
  border-radius: 6px;
}

/* On a phone you flick through these quickly, so the incoming slide has to
   be readable straight away rather than fading in behind your thumb. */
@media (max-width: 760px) {
  .panel .module-copy > *,
  .panel .module-visual {
    transform: none;
    transition-duration: 0.24s;
  }
  .panel.live .module-copy > *,
  .panel.live .module-visual {
    transition-delay: 0s;
  }
}

/* =====================================================================
   Not live yet
   The stores are not open, so the links carry no href: not clickable,
   not reachable by keyboard. They stay visible because seeing which
   platforms are coming is the point.
   ===================================================================== */

.is-soon {
  opacity: 0.42;
  cursor: not-allowed;
  pointer-events: none;
}
.is-soon:hover {
  transform: none;
  background: inherit;
}
.btn.is-soon {
  box-shadow: none;
}
.mi.is-soon:hover svg {
  opacity: inherit;
  color: inherit;
}

.soon-line {
  margin-top: 14px;
  font-family: var(--f-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #b0912e;
}
#hook .soon-line {
  margin-top: 16px;
}
#download .soon-line {
  margin-top: 22px;
}
#download .hero-note,
#hook .hero-note {
  margin-top: 8px;
}

/* The hero copy is a flex column with one gap, so no block inside it may
   add a margin of its own. Last rule in the file on purpose: the shared
   button and "coming soon" styles above would otherwise win on order. */
#hook .hook-copy > * {
  margin-top: 0;
}
