/* ==========================================================================
   Sayfarer — landing site
   Design source: Claude Design project "Landing Site.dc.html"
   ========================================================================== */

:root {
  --bg: #faf9f7;
  --bg-white: #fff;
  --bg-inset: #ecedf7;
  --bg-card: #f6f5f3;
  --bg-contact: #faeede;

  --ink: #20242e;
  --ink-2: #3a3f52;
  --ink-3: #41475a;
  --ink-4: #5a6078;
  --muted: #8b91a6;
  --muted-2: #8087a0;
  --muted-3: #6a7088;

  --amber: #e0913a;
  --amber-dark: #c07d2e;
  --violet: #6d6fc0;
  --green: #2fa36b;
  --red: #d1594e;
  --blue: #4f8fd6;
  --pink: #c268a0;

  --border-card: #ececea;

  --display: 'Bricolage Grotesque', 'Instrument Sans', system-ui, sans-serif;
  --body: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* horizontal page gutter — 1200px content, 40px minimum edge padding */
  --gutter: max(40px, calc((100% - 1200px) / 2));

  /* hero headline size, reused to position the overlapping phone */
  --h1-size: clamp(56px, 8.6vw, 104px);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--amber-dark); text-decoration: none; }
a:hover { color: var(--amber); }

img { max-width: 100%; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: #fff;
  padding: 12px 18px;
  border-radius: 0 0 10px 0;
  font-weight: 700;
  z-index: 99;
}
.skip-link:focus { left: 0; color: #fff; }

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

.section { padding-left: var(--gutter); padding-right: var(--gutter); }

/* --------------------------------------------------------------- headings */

.title {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(40px, 6vw, 60px);
  line-height: 0.92;
  letter-spacing: -1.8px;
  text-transform: uppercase;
  color: var(--ink);
}

.title--sm {
  font-size: clamp(34px, 5vw, 44px);
  line-height: 0.95;
  letter-spacing: -1.2px;
}

.eyebrow {
  font-family: var(--body);
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--muted-2);
  margin: 0;
}

.eyebrow--lg {
  margin-top: 14px;
  font-size: clamp(18px, 2.4vw, 22px);
  line-height: 1.3;
}

.eyebrow--sm {
  margin-top: 22px;
  font-size: 15px;
  color: #878da0;
}

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  border-radius: 14px;
}

.btn--dark {
  margin-top: 26px;
  background: var(--ink);
  color: #fff;
  font-size: 16px;
  padding: 15px 26px;
}
.btn--dark:hover { background: #2c3243; color: #fff; }

.btn--amber {
  background: var(--amber);
  color: #fff;
  font-size: 15px;
  padding: 13px 20px;
  border-radius: 12px;
}
.btn--amber:hover { background: var(--amber-dark); color: #fff; }

/* --------------------------------------------------------------- brand/nav */

/* Wordmark is set in type, no mark beside it. The colour is inherited from
   .nav__brand — var(--ink) in the header, #fff over the dark footer — so it
   is never declared twice. */
.brand-word {
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.3px;
  white-space: nowrap;
}
.brand-word--sm { font-size: 18px; }

/* Header only — the footer wordmark stays plain white.
   The same swoosh that runs under the hero and behind the app icon, drawn
   small under the word. It sits on a pseudo-element with a negative offset so
   it overhangs rather than growing the box: the nav's height is unchanged.
   Hover springs it out to the right, like the tail of a signature. */
.nav .brand-word {
  position: relative;
  display: inline-block;
  font-size: 26px;
  letter-spacing: -0.1px;
}
.nav .brand-word::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -9px;
  height: 11px;
  /* Two full cycles, chained with S so each crest mirrors the last and the
     line stays sine-smooth. Inset to x=2..118 so the round caps aren't
     clipped by the viewBox. */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 16' preserveAspectRatio='none'%3E%3Cpath d='M2 8C12 3 21 3 31 8S50 13 60 8S79 3 89 8S108 13 118 8' fill='none' stroke='%23e0913a' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / 100% 100%;
  transform-origin: left center;
  transition: transform 0.34s cubic-bezier(0.34, 1.36, 0.5, 1);
}
.nav .nav__brand:hover .brand-word::after { transform: scaleX(1.06) translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .nav .brand-word::after { transition: none; }
  .nav .nav__brand:hover .brand-word::after { transform: none; }
}

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

.nav__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
}
.nav__brand:hover { color: var(--ink); }

.nav__links {
  flex: 1;
  display: flex;
  justify-content: center;
  gap: 34px;
}
.nav__links a {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-3);
}
.nav__links a:hover { color: var(--ink); }
.nav__links a[aria-current="page"] { color: var(--ink); }

/* "Available on / Android and iOS" + the two circular store links.
   Sits at the right end of the nav, where the Download App pill used to be.
   Duplicated markup in index.html and privacy.html. */
.nav__stores {
  display: flex;
  align-items: center;
  gap: 14px;
}
.nav__stores-text {
  font-size: 14px;
  color: var(--ink-4);
  line-height: 1.35;
  white-space: nowrap;
}

.store-circles { display: flex; gap: 10px; }

.store-circle {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  transition: background-color 0.15s ease;
}
.store-circle img {
  display: block;
  transition: filter 0.15s ease;
}

/* the Apple mark sits optically low in a circle; nudge it up a hair */
.store-circle--apple img { transform: translateY(-1px); }

/* Both logos are black artwork on transparency, so inverting them when the
   circle fills in gives a white mark on the dark ground. The Android robot's
   eyes are white in the source and invert to black against its now-white
   head, which is what we want. */
.store-circle:hover { background: var(--ink); }
.store-circle:hover img { filter: invert(1); }

/* Dark-ground variant for the footer. The same black artwork would be
   invisible on the dark footer, so it starts inverted (white mark, light
   border) and returns to black when the circle fills with white on hover —
   the light version's interaction, run in reverse. */
.store-circle--light { border-color: var(--muted); }
.store-circle--light img { filter: invert(1); }
.store-circle--light:hover { background: #fff; border-color: #fff; }
.store-circle--light:hover img { filter: none; }

/* ------------------------------------------------------- app CTA flag

   Driven by SHOW_APP_ACTIVE_CTA in scripts/site-config.ts, which stamps
   data-app-cta onto <html> across every page when you run `npm run phrases`.

       data-app-cta="active"  the app is live — store badges and real links
       data-app-cta="soon"    pre-launch — "coming soon", nothing clickable

   Both variants sit in the markup; these rules only ever hide the one that
   doesn't apply, so the visible variant keeps its own display value (setting
   `display: revert` here would throw away the author's flex layouts).

   The second rule is the fallback: if the attribute is missing for any reason,
   the pre-launch view wins. Failing into "not available yet" is the honest
   direction to fail.

   NB: this deliberately does NOT cover the "Available on / Android and iOS"
   block in the site header, which still reads as available. If the header
   should follow the flag too, give its .nav__stores the same treatment. */
[data-app-cta="active"] .cta-soon { display: none; }
:root:not([data-app-cta="active"]) .cta-live { display: none; }

/* .nav__links is flex:1 and centres itself, so with the header's stores block
   hidden it would centre in the space left over — landing right of the page's
   true centre with an empty gap beside it. Right-aligning instead reads as a
   deliberate two-part nav rather than a layout with something missing. */
:root:not([data-app-cta="active"]) .nav__links { justify-content: flex-end; }

/* Pre-launch store marks: same circles, visibly inert. They are <span>s rather
   than links in the markup, so there is nothing to click; these rules stop the
   shared .store-circle hover styles from implying otherwise. */
.store-circle--off {
  border-color: var(--muted);
  opacity: 0.5;
  cursor: default;
}
.store-circle--off:hover { background: none; }
.store-circle--off:hover img { filter: none; }

/* Mirrors .hero__badges' placement so swapping the two doesn't move the
   hero's lower edge. */
.hero__soon {
  margin-top: auto;
  padding-top: 34px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

/* --------------------------------------------------------------- hero */

.hero {
  background: var(--bg);
  padding-top: 30px;
  padding-bottom: 60px;
  position: relative;
  overflow: hidden;
}

.hero__title {
  margin: 34px 0 0;
  padding-right: 368px;
  font-family: var(--display);
  text-transform: uppercase;
  line-height: 0.92;
  letter-spacing: -2.5px;
  color: var(--ink);
}
.hero__title span { display: block; font-size: var(--h1-size); }
.hero__title-light { font-weight: 400; }
.hero__title-bold { font-weight: 700; }

.hero__row { margin-top: 32px; position: relative; }

.hero__inset {
  background: var(--bg-inset);
  border-radius: 30px;
  padding: 38px 36px;
  position: relative;
  overflow: hidden;
  min-height: 452px;
}

.hero__swoosh {
  position: absolute;
  left: 0;
  bottom: -10px;
  width: 120%;
  height: 70%;
  opacity: 0.65;
  pointer-events: none;
}

.hero__copy {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 376px;
  max-width: min(540px, calc(100% - 340px));
}

.hero__lede {
  margin: 0;
  font-size: 19px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* Official App Store / Google Play badges, pinned to the bottom of the
   hero copy column where the "available now" note used to sit. The two
   badge SVGs have different aspect ratios (2.99 vs 3.38), so they are
   matched on height — the convention both stores' guidelines expect. */
.hero__badges {
  --badge-h: 44px;
  margin-top: auto;
  padding-top: 34px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.hero__badge { display: block; border-radius: 8px; }
.hero__badge img {
  display: block;
  height: var(--badge-h);
  width: auto;
}
.hero__badge:hover { opacity: 0.82; }

/* --------------------------------------------------------------- devices */

/* devices.css frames are fixed-size (428 × 868); scale them down while
   keeping the wrapper's layout box the correct scaled size. */
.phone {
  --frame-w: 428px;
  --frame-h: 868px;
  --phone-scale: 1;
  position: relative;
  width: calc(var(--frame-w) * var(--phone-scale));
  height: calc(var(--frame-h) * var(--phone-scale));
  flex: none;
}

.phone > .device {
  transform: scale(var(--phone-scale));
  transform-origin: top left;
}

/* recolour the stock frame to the Sayfarer dark navy + add a drop shadow */
.phone .device-frame {
  border-color: #14171f;
  box-shadow:
    inset 0 0 4px 2px #4a5266,
    inset 0 0 0 6px var(--ink),
    var(--phone-shadow, 0 34px 70px rgba(20, 24, 50, 0.28));
}
.phone .device-btns,
.phone .device-btns::after,
.phone .device-btns::before,
.phone .device-power { background: #14171f; }

.phone .device-screen { background-color: #f5f6fa; }

/* NB: --phone-scale must be set on the .phone element itself — the default
   above would otherwise shadow anything inherited from an ancestor. */
.phone--hero { --phone-scale: 0.673; }

/* The hero phone hangs above the inset card, overlapping the headline.
   1.84 = two headline lines at line-height 0.92. Declared after `.phone`
   so its `position: absolute` isn't overridden by `.phone`'s `relative`. */
.hero__phone {
  position: absolute;
  top: calc(-32px - 1.84 * var(--h1-size));
  right: 40px;
}

/* --------------------------------------------------------------- stats */

.stats-band {
  background: var(--bg);
  padding-top: 20px;
  padding-bottom: 24px;
}

.stats {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 36px 56px;
  max-width: calc(100% - 410px);
}
.stat { margin: 0; }

.stat__value {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(62px, 8vw, 84px);
  line-height: 0.85;
  letter-spacing: -2px;
  color: var(--ink);
}

.stat__label {
  margin: 14px 0 0;
  font-family: var(--body);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(19px, 2.4vw, 23px);
  line-height: 1.1;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --------------------------------------------------------------- phrases */

/* The copy column is much shorter than the device column, so centre the two
   against each other rather than top-aligning them. The negative margin pulls
   the whole row up so the phones overlap the stats band, as in the design. */
.phrases {
  margin-top: -92px;
  display: flex;
  gap: 40px;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
}

.phrases__copy { flex: 1; min-width: 300px; }
.phrases__copy .eyebrow--lg { margin-top: 16px; max-width: 440px; }

.phone-pair {
  flex: none;
  display: flex;
  align-items: flex-start;
}

.phone-pair .phone { --phone-scale: 0.495; }

.phone-pair .phone--front { z-index: 2; }
.phone-pair .phone--back {
  z-index: 1;
  --phone-shadow: 0 34px 70px rgba(20, 24, 50, 0.2);
  /* overlap scales with the frames: -56px / -113px at the base 0.495 scale */
  margin-left: calc(-113px * var(--phone-scale));
  margin-top: calc(53px * var(--phone-scale));
}

/* --------------------------------------------------------------- features */

.features {
  background: var(--bg-white);
  padding-top: 80px;
  padding-bottom: 80px;
}

.cards {
  list-style: none;
  margin: 36px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 20px;
}

.card {
  background: var(--bg-card);
  border: 1px solid var(--border-card);
  border-radius: 22px;
  padding: 28px;
}

.card__icon {
  width: 52px;
  height: 52px;
  border-radius: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  color: #fff;
}
.card__icon--amber  { background: var(--amber); }
.card__icon--violet { background: var(--violet); }
.card__icon--green  { background: var(--green); }
.card__icon--red    { background: var(--red); }
.card__icon--blue   { background: var(--blue); }
.card__icon--pink   { background: var(--pink); }

.card__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 21px;
  line-height: 1.2;
  margin: 16px 0 0;
}

.card__body {
  font-size: 15.5px;
  color: var(--ink-4);
  line-height: 1.55;
  margin: 8px 0 0;
}

/* --------------------------------------------------------------- showcase */

/* A rail of app screens drifting sideways, full-bleed between the two white
   sections. Deliberately wordless — the band is a visual breather, so it
   carries no heading and nothing here is a link. */
.showcase {
  --rail-gap: 30px;
  --drift: 78s;
  /* Clear lavender wanted above and below the screens. The rail's padding is
     this plus the stagger below, so the band stays evenly cushioned even
     though the screens sit at different heights. */
  --band-space: 46px;
  /* How far the stagger throws a screen past the track, worst case: the
     furthest translateY in either direction plus the overhang its rotation
     adds. Recalculate these if the stagger transforms below change. */
  --stagger-up: 33px;
  --stagger-down: 35px;
  background: var(--bg-inset);
  /* full bleed: the rail runs off both page edges */
  padding-left: 0;
  padding-right: 0;
  position: relative;
  overflow: hidden;
}

/* the hero's swoosh, doubled and crossed, sitting behind the phones */
.showcase__swoosh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.showcase__rail {
  position: relative;
  padding-top: calc(var(--band-space) + var(--stagger-up));
  padding-bottom: calc(var(--band-space) + var(--stagger-down));
  /* screens dissolve into the band rather than butting against the edge */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
}

.showcase__track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  width: max-content;
  animation: showcase-drift var(--drift) linear infinite;
}

/* Exactly half the track, because the eight screens are held twice and the
   spacing lives on the items rather than in a flex gap — so -50% lands the
   ninth screen precisely where the first one started. */
@keyframes showcase-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.showcase__rail:hover .showcase__track { animation-play-state: paused; }

.showcase__item {
  margin-right: var(--rail-gap);
  /* the stagger repeats every four screens; with an even number of screens
     held twice, the pattern carries straight across the loop's seam */
  transform: translateY(-28px) rotate(-3deg);
}
.showcase__item:nth-child(4n + 2) { transform: translateY(20px)  rotate(2deg); }
.showcase__item:nth-child(4n + 3) { transform: translateY(-6px)  rotate(3.5deg); }
.showcase__item:nth-child(4n + 4) { transform: translateY(32px)  rotate(-1.5deg); }

.showcase .phone { --phone-scale: 0.46; }

/* Nothing to pause for, so the rail becomes a plain scrollable strip and the
   duplicate screens — which only exist to close the loop — are dropped. */
@media (prefers-reduced-motion: reduce) {
  .showcase__track { animation: none; }
  .showcase__item--loop { display: none; }
  .showcase__rail {
    overflow-x: auto;
    scrollbar-width: none;
  }
  .showcase__rail::-webkit-scrollbar { display: none; }
}

/* --------------------------------------------------------------- support */

/* padding-top matches .features' padding-bottom so the showcase band between
   them sits on equal white margins */
.support {
  background: var(--bg-white);
  padding-top: 80px;
  padding-bottom: 80px;
}

.faq {
  margin-top: 28px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 28px 40px;
}

.faq__q {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.25;
  margin: 0;
}

.faq__a {
  font-size: 15px;
  color: var(--ink-4);
  line-height: 1.55;
  margin: 6px 0 0;
}
.faq__a strong { color: var(--ink); }

.contact {
  margin-top: 32px;
  background: var(--bg-contact);
  border-radius: 18px;
  padding: 22px 24px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}

.contact__copy { flex: 1; min-width: 240px; }

.contact__title {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  color: var(--ink);
}

.contact__sub {
  margin: 4px 0 0;
  font-size: 14.5px;
  color: #8a6a3e;
}

/* ------------------------------------------------- legal page (privacy.html) */

.legal-nav { padding-top: 30px; }

.legal {
  display: block;
  background: var(--bg);
  padding-top: 56px;
  padding-bottom: 96px;
}

.legal__back {
  display: inline-block;
  margin-bottom: 22px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-4);
}
.legal__back:hover { color: var(--ink); }

.legal__updated {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  margin: 14px 0 0;
}

.prose {
  max-width: 760px;
  margin-top: 24px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-3);
}
.prose p { margin: 0 0 20px; }
.prose__last { margin-bottom: 0; }
.prose h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 20px;
  color: var(--ink);
  margin: 28px 0 8px;
}

/* --------------------------------------------------------------- footer */

.site-footer {
  background: var(--ink);
  padding-top: 52px;
  padding-bottom: 52px;
}

.site-footer__top {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: center;
  justify-content: space-between;
}
.site-footer__top .nav__brand { color: #fff; }
.site-footer__top .nav__brand:hover { color: #fff; }

.site-footer__links { display: flex; gap: 24px; }
.site-footer__links a {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}
.site-footer__links a:hover { color: #fff; }
.site-footer__links a[aria-current="page"] { color: #fff; }

.site-footer__legal {
  margin: 24px 0 0;
  font-size: 13px;
  color: var(--muted-3);
  line-height: 1.6;
}

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

@media (max-width: 1080px) {
  .hero__title { padding-right: 320px; }
}

@media (max-width: 880px) {
  .hero__title { padding-right: 0; letter-spacing: -1.2px; }
  .hero__row { margin-top: 40px; }
  .hero__inset { min-height: 0; }
  .hero__copy { max-width: 100%; min-height: 0; }

  /* phone drops out of the overlap and sits under the copy */
  .hero__phone {
    position: static;
    margin: 28px auto 0;
  }

  .stats { max-width: 100%; }

  /* stacked: back to normal flow, no overlap, no cross-axis centring */
  .phrases {
    margin-top: 40px;
    align-items: flex-start;
    justify-content: center;
  }
  .phone-pair { margin: 32px auto 0; }
}

@media (max-width: 620px) {
  :root { --gutter: 22px; }

  /* brand + store circles share the first row, links drop to a second row.
     The "Available on…" label is dropped here — the full-size store badges
     sit a few hundred pixels below in the hero and say the same thing. */
  .nav { flex-wrap: wrap; gap: 14px 18px; }
  .nav__brand { flex: 1; }
  /* The brand shares row one with the store circles and the links wrap below,
     so ease the wordmark down and pull the wave's overhang back inside the
     14px row gap. */
  .nav .brand-word { font-size: 22px; }
  .nav .brand-word::after { bottom: -7px; height: 9px; }
  .nav__stores-text { display: none; }
  .nav__links {
    order: 3;
    flex: 1 1 100%;
    justify-content: flex-start;
    gap: 22px;
  }

  .hero { padding-bottom: 48px; }
  .hero__title span { font-size: clamp(40px, 13vw, 64px); }
  .hero__inset { padding: 26px 22px; }

  .phone--hero { --phone-scale: 0.62; }
  .phone-pair .phone { --phone-scale: 0.42; }

  /* fewer screens fit, so shorten the loop to keep the drift feeling the same.
     The stagger is a fixed pixel throw, so only the cushion tightens here. */
  .showcase { --rail-gap: 20px; --drift: 58s; --band-space: 26px; }
  .showcase .phone { --phone-scale: 0.38; }

  .stats { gap: 26px 32px; }

  .features { padding-top: 60px; padding-bottom: 60px; }
  .support { padding-top: 60px; padding-bottom: 60px; }
  .legal { padding-top: 40px; padding-bottom: 64px; }

  /* stack brand over links so the wordmark never wraps mid-name */
  .site-footer__top {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }
}

@media (max-width: 380px) {
  .phone--hero { --phone-scale: 0.55; }
  .phone-pair .phone { --phone-scale: 0.36; }
  .showcase .phone { --phone-scale: 0.34; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
