/* ============================================================================
   Homepage. Loaded only by index.html, after site.css. Layout follows the
   Payr reference section by section; sizes are measured from it at 1440px.

   Every pop-up around a phone is cut from a real app screenshot
   (assets/pop-*.webp), never rebuilt in HTML, so nothing shown is invented.
   ========================================================================= */

.title { font-weight: 500; font-size: clamp(2rem, 3.6vw, 3.25rem); line-height: 1.15; letter-spacing: -0.025em; text-wrap: balance; }
.title .muted { color: var(--grey); }
.center { text-align: center; }

/* Real app crops: their black screen corners are clipped by the radius. */
/* The crops carry their own transparent rounded corners (48px at source,
   the app's card radius). The CSS radius matches that at display size so the
   shadow and outline follow the card edge exactly. */
.pop { position: absolute; z-index: 2; border-radius: 10px; box-shadow: var(--shadow-float); }
.pop-left { border-radius: 12px; }
.card-peek .pop { border-radius: 8px; }
.tile { position: absolute; z-index: 2; border-radius: 14px; border: 4px solid #ffffff; box-shadow: var(--shadow-float); overflow: visible; background: #ffffff; }
.tile img { border-radius: 10px; width: 100%; height: 100%; object-fit: cover; }
.icon-badge {
  position: absolute; width: 34px; height: 34px; border-radius: 10px; background: var(--blue);
  display: grid; place-items: center; box-shadow: 0 6px 16px rgba(53, 194, 253, 0.35);
}
.icon-badge svg { width: 18px; height: 18px; }

/* ---------- Hero ---------- */
.hero { overflow: hidden; padding-top: 84px; }
.hero h1 { font-weight: 500; font-size: clamp(2.2rem, 4vw, 3.625rem); line-height: 1.2; letter-spacing: -0.025em; text-align: center; }
.hero h1 .muted { color: var(--grey); }
.hero-cta { margin-top: 20px; text-align: center; }
/* Store badges: Apple's and Google's official artwork, shown at the same
   height as each other (Google asks for its badge to be no smaller than
   others beside it). 48px also clears Apple's 40px minimum. */
.store-badges { display: flex; justify-content: center; align-items: center; gap: 14px; flex-wrap: wrap; }
.store-badge { display: inline-flex; padding: 2px; }
.store-badge img { height: 48px; width: auto; }
.store-note { margin-top: 12px; font-size: 0.86rem; color: var(--body); }
.cta-badges { margin-top: 30px; }
.cta-badges .store-badges { justify-content: flex-start; }
.cta-badges .store-note { color: rgba(255, 255, 255, 0.92); }
/* The hero fills exactly one screen: the stage (phone area) takes whatever
   height is left below the headline and badges, minus a 28px peek, so the
   top edge of the How it works panel shows at the bottom of the screen on
   load (a cue that the page goes on). The stage starts 302px plus the
   two headline lines down the page. Between 420px (short laptops; the panel
   is then pulled up to the screen edge instead) and 640px (very tall
   screens, where the panel peeks in). */
.hero-stage { position: relative; height: clamp(420px, calc(100vh - 330px - 2.4 * clamp(2.2rem, 4vw, 3.625rem)), 640px); margin-top: 76px; }
/* Centred with auto margins, not translateX(-50%): the entrance scales the
   phone, and a scale also shrinks a -50% shift, which slid the phone
   sideways as it rose. */
.hero-phone { position: absolute; left: 0; right: 0; top: 0; width: 480px; margin: 0 auto; }
/* The reference's widgets carry a 1px #e4e4e4 hairline (sampled) on top of
   the shadow, which separates them from the phone they overlap. */
.hero .pop { box-shadow: 0 0 0 var(--pop-ring-w) var(--pop-ring), var(--pop-shadow); }
/* A slow, drifting float for depth on all five pieces around the phone:
   mostly up and down with a slight sideways sway. Every piece has its own
   length and starting point, so they never line up or move in step. Off for
   anyone with reduce-motion switched on. */
.hero .pop, .hero .tile { animation: drift 7s ease-in-out infinite; will-change: transform; }
@keyframes drift {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(2px, -5px); }
  50%      { transform: translate(0, -9px); }
  75%      { transform: translate(-2px, -4px); }
}
/* ---------- Page-load entrance ----------
   A staggered reveal, under two seconds end to end: nav, headline (blurring
   into focus), button, phone rising, then the five floating pieces one by
   one. The entrance moves pieces with the separate `translate` and `scale`
   properties, while the drift above uses `transform`, so the two run together
   without fighting: each piece eases into place and is already drifting. */
.nav { animation: enter-down 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.hero h1 { animation: enter-focus 1s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s both; }
.hero h1 .muted { display: inline-block; animation: enter-focus 1s cubic-bezier(0.2, 0.7, 0.2, 1) 0.3s both; }
.hero-cta { animation: enter-up 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.5s both; }
.hero-phone { animation: enter-rise 1.2s cubic-bezier(0.16, 0.8, 0.2, 1) 0.55s both; }
.hero .tile, .hero .pop { animation-name: enter-pop, drift; animation-timing-function: cubic-bezier(0.2, 0.9, 0.25, 1.15), ease-in-out; animation-fill-mode: both, none; animation-iteration-count: 1, infinite; }
.hero .tile-tl   { animation-duration: 0.8s, 8.3s; animation-delay: 1.00s, -2.1s; }
.hero .pop-left  { animation-duration: 0.8s, 7.9s; animation-delay: 1.10s, -4.3s; }
.hero .pop-right { animation-duration: 0.8s, 6.1s; animation-delay: 1.20s, -0.8s; }
.hero .tile-tr   { animation-duration: 0.8s, 7.4s; animation-delay: 1.30s, -5.6s; }
.hero .pop-br    { animation-duration: 0.8s, 6.7s; animation-delay: 1.40s, -3.2s; }

@keyframes enter-down  { from { opacity: 0; translate: 0 -16px; } to { opacity: 1; translate: 0 0; } }
@keyframes enter-up    { from { opacity: 0; translate: 0 16px; } to { opacity: 1; translate: 0 0; } }
@keyframes enter-focus { from { opacity: 0; translate: 0 18px; filter: blur(10px); } to { opacity: 1; translate: 0 0; filter: blur(0); } }
@keyframes enter-rise  { from { opacity: 0; translate: 0 90px; } to { opacity: 1; translate: 0 0; } }
@keyframes enter-pop   { from { opacity: 0; translate: 0 14px; scale: 0.86; } to { opacity: 1; translate: 0 0; scale: 1; } }

@media (prefers-reduced-motion: reduce) {
  .nav, .hero h1, .hero h1 .muted, .hero-cta, .hero-phone, .hero .pop, .hero .tile { animation: none; }
  .step, .step::after, .js .step .step-text, .steps-phone .phone-next { transition: none; }
  .step:not(.is-active):hover { translate: none; }
}
.tile-tl { left: 3px; top: 73px; width: 240px; height: 150px; }
.tile-tl .icon-badge { right: -14px; top: -14px; }
.tile-tr { right: 3px; top: 0; width: 224px; height: 157px; }
.pop-right { left: calc(50% + 184px); top: 121px; width: 250px; }
/* The hero stays still while the panel slides over it, so anything below
   the bottom of the window is never seen. On shorter windows the two lower
   widgets move up to stay in view (24-28px above the window bottom; the
   stage starts 440px down), but never higher than just under the Somi
   tiles above them. Tall windows get the reference positions. */
.pop-left { left: calc(50% - 512px); top: clamp(243px, calc(100vh - 595px), 389px); width: 300px; }
.pop-br { right: 0; top: clamp(234px, calc(100vh - 599px), 380px); width: 220px; }

/* ---------- Slide-over (desktop) ----------
   The hero pins exactly where it loads (top 70px, just under the nav's
   space), so it never moves; the How it works panel scrolls up over it.
   The panel is pulled up so its top starts at the bottom of the window;
   without that, the first scroll on a short window would move nothing.
   home.js measures where the hero ends (--hero-end). The pin ends with the
   wrapper, once the panel (1010px tall) covers the whole hero. */
@media (min-width: 901px) {
  .hero { position: sticky; top: 70px; z-index: 1; }
  .slide-over .panel { margin-top: min(0px, calc(100vh - 28px - var(--hero-end, 1000px))); }
}
/* Mobile does the same. Its headline can wrap to a third line on narrow
   phones, so instead of a formula home.js measures where the hero ends and
   sets --hero-end (800px is the fallback). svh is the screen height with the
   browser bars showing, so the panel starts right at the visible bottom. */
@media (max-width: 900px) {
  .hero { position: sticky; top: 70px; z-index: 1; }
  .slide-over .panel {
    margin-top: min(0px, calc(100vh - 20px - var(--hero-end, 800px)));
    margin-top: min(0px, calc(100svh - 20px - var(--hero-end, 800px)));
  }
}

/* ---------- How it works: dark full-bleed panel ---------- */
.panel { background: var(--panel); color: #ffffff; border: 1px solid var(--panel-line); border-radius: 40px; box-shadow: var(--panel-shadow); padding: 56px 0 60px; position: relative; z-index: 3; }
/* The panel is always a full screen tall (the window minus the nav), and at
   least as tall as the hero it slides over; its contents sit in the middle.
   So the box stays big and only the contents were made smaller to fit.
   --hero-end comes from home.js (where the hero ends on the page). */
.panel {
  min-height: max(calc(100vh - 70px), calc(var(--hero-end, 0px) - 70px));
  display: flex; flex-direction: column; justify-content: center;
}
.panel > .wrap { width: 100%; }
.panel .title .muted { color: #8b93a0; }
.panel-hint { margin-top: 12px; text-align: center; font-size: 0.92rem; color: #8b93a0; }
/* Desktop says "tap", mobile says "swipe"; the mobile slideshow and its dots
   only exist below 900px. */
.hint-mobile, .steps-slides, .slide-dots, .carousel-dots { display: none; }
/* Desktop phone size grows with the window height (Daniel, 20 Oct): the
   phone is whatever height is left after the heading and spacing (about
   330px), kept between 540px (the old fixed size, used on short laptop
   screens) and 680px. Its width and the four card rows follow it. */
#how { --phone-h: clamp(540px, calc(100vh - 330px), 680px); }
.steps { margin-top: 40px; display: grid; grid-template-columns: 1fr calc(var(--phone-h) * 0.4815) 1fr; column-gap: 58px; align-items: center; }
.steps-phone { grid-column: 2; grid-row: 1 / -1; position: relative; }
/* Shadow on the wrapper, not the pictures, so the cross-fade never doubles it. */
.steps-phone { filter: drop-shadow(0 34px 38px rgba(0, 0, 0, 0.75)) drop-shadow(0 10px 14px rgba(0, 0, 0, 0.55)); }
.steps-phone img { width: 100%; transform: rotate(3deg); }
/* Screen change: home.js lays the next screen over the current one and fades
   it in. Both pictures share the same frame, so only the screen changes. */
.steps-phone .phone-next { position: absolute; left: 0; top: 0; opacity: 0; transition: opacity 0.45s ease; }
.steps-phone .phone-next.is-in { opacity: 1; }
/* Zig-zag down the phone: left, right, left, right, each a row lower.
   Fixed row heights (4 x 135px, the phone's height) keep the panel the same
   height when a card opens; an open card spills into the empty row beside it. */
.steps { grid-template-rows: repeat(4, calc(var(--phone-h) / 4)); }
.step-1 { grid-column: 1; grid-row: 1; }
.step-2 { grid-column: 3; grid-row: 2; }
.step-3 { grid-column: 1; grid-row: 3; }
.step-4 { grid-column: 3; grid-row: 4; }
.step {
  position: relative; display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--step); color: #b9c0cb; border: 1px solid transparent; border-radius: 14px; padding: 20px 22px;
  transition: border-color 0.35s ease, color 0.35s ease, background-color 0.35s ease, box-shadow 0.35s ease, translate 0.35s ease;
}
.step:not(.is-active):hover { background-color: #172036; color: #ffffff; translate: 0 -2px; }
/* Dark mode: a lighter charcoal instead of the navy, to match the app (21 Oct). */
@media not all and (prefers-color-scheme: dark) { :root:has(#theme:checked) .step:not(.is-active):hover { background-color: #2c2f36; } }
@media (prefers-color-scheme: dark) { :root:not(:has(#theme:checked)) .step:not(.is-active):hover { background-color: #2c2f36; } }
.step-label { display: block; font-size: 0.78rem; letter-spacing: 0.04em; text-transform: uppercase; color: #8b93a0; margin-bottom: 6px; }
.step-title { display: block; font-size: 1.06rem; line-height: 1.45; }
.step-text { display: block; margin-top: 10px; font-size: 0.9rem; line-height: 1.6; color: #b9c0cb; }
.step.is-active { color: #ffffff; box-shadow: 0 14px 32px rgba(0, 0, 0, 0.45), 0 4px 10px rgba(0, 0, 0, 0.30); }
/* Connector to the phone. The blue fills along it, from the card towards the
   phone, when the step becomes active. */
.step::after {
  content: ""; position: absolute; top: 50%; width: 58px; height: 1px;
  background: linear-gradient(rgba(53, 194, 253, 0.6), rgba(53, 194, 253, 0.6)) no-repeat, rgba(255, 255, 255, 0.14);
  background-size: 0% 100%, auto; transition: background-size 0.5s ease 0.1s;
}
.step-1::after, .step-3::after { left: 100%; background-position: left center, 0 0; }
.step-2::after, .step-4::after { right: 100%; background-position: right center, 0 0; }
.step.is-active::after { background-size: 100% 100%, auto; }
/* Without JavaScript every card shows its text, so nothing is unreachable. */
/* With it, the active card's text slides open and the others fold shut. */
.js .step .step-text { max-height: 0; margin-top: 0; opacity: 0; overflow: hidden; transition: max-height 0.45s ease, margin-top 0.45s ease, opacity 0.3s ease; }
.js .step.is-active .step-text { max-height: 140px; margin-top: 10px; opacity: 1; transition: max-height 0.45s ease, margin-top 0.45s ease, opacity 0.4s ease 0.12s; }

/* ---------- Light/dark circle reveal ----------
   home.js drives the circle; this turns off the browser's default
   cross-fade so only the circle shows. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

/* ---------- Scroll reveal ----------
   home.js adds .reveal (or .reveal-box for cards) to pieces below How it works, then .is-in
   the first time each one scrolls into view, and removes both once it has
   settled. Nothing is hidden without JavaScript or with reduced motion. */
.reveal { opacity: 0; translate: 0 16px; }
.reveal.is-in { opacity: 1; translate: 0 0; transition: opacity 0.6s ease, translate 0.7s cubic-bezier(0.2, 0.7, 0.2, 1); transition-delay: var(--reveal-delay, 0s); }
/* Cards and panels: the box itself stays put and visible; only what is
   inside it fades up. */
.reveal-box > * { opacity: 0; translate: 0 16px; }
.reveal-box.is-in > * { opacity: 1; translate: 0 0; transition: opacity 0.6s ease, translate 0.7s cubic-bezier(0.2, 0.7, 0.2, 1); transition-delay: var(--reveal-delay, 0s); }

/* ---------- Key features: 3 + 2 grid ---------- */
.features { padding: 130px 0 120px; }
.grid { margin-top: 70px; display: grid; gap: 26px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 25px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.card {
  position: relative; overflow: hidden; height: 378px; border-radius: 20px;
  background: var(--feature-card); border: 1px solid var(--feature-line);
  box-shadow: 0 1px 2px rgba(10, 20, 40, 0.03), 0 12px 32px rgba(10, 20, 40, 0.04);
  padding: 40px 32px 0; display: flex; flex-direction: column;
}
/* App pieces float on the card rather than sitting in it like holes. */
.card .card-img, .card .peek { filter: var(--img-shadow); }
.card h3 { font-size: 1.25rem; font-weight: 500; letter-spacing: -0.01em; }
.card p { margin-top: 10px; color: var(--body); font-size: 0.95rem; }
.card-c { text-align: center; }
.card-c p { max-width: 280px; margin-left: auto; margin-right: auto; }
/* Picture sizes. Every app picture is set so its text shows at the same size
   (a title's capitals about 8.5px tall), measured from each source image:
   the sources come from different screenshots at different zooms, so equal
   percentages gave text anywhere from 5px to 19px. */
.card-top { justify-content: flex-end; padding-bottom: 40px; }
.card-top .card-img { margin: 0 auto auto; width: 280px; }
.card-low .card-img { margin: auto auto 34px; width: 319px; }
/* Phone peeking up from the bottom, a real app card floating over its edge. */
.card .peek { position: absolute; width: 280px; top: 168px; filter: var(--img-shadow); }
.card-peek .peek { left: 50%; transform: translateX(-28%); }
.card-peek .pop { left: 24px; top: 250px; width: 181px; z-index: 3; border-radius: 13px; }
.card-recipe .card-text { max-width: 300px; }
.card-recipe .peek { right: 36px; top: 182px; }
.card-recipe .card-img { position: absolute; left: 32px; top: 252px; width: 261px; z-index: 3; border-radius: 14px; }
.card-l .card-text { max-width: 330px; }
.card-dark { background: var(--accent-card); border-color: var(--accent-card-line); color: var(--accent-ink); }
.card-dark p { color: var(--accent-body); }
/* The progression card keeps its earlier, larger size: 86% of the card,
   tucked into the bottom right. */
.card-dark .card-img { position: absolute; right: 0; bottom: 28px; width: 86%; }
/* The two chips floating over phones get the hero widgets' treatment: the
   grey hairline and the deeper shadow, so they sit above the phone instead
   of sinking into it. Radii match each chip's own corners (measured). */
.card-peek .pop, .card-recipe .card-img { filter: none; box-shadow: 0 0 0 var(--pop-ring-w) var(--pop-ring), var(--pop-shadow); }

/* Hover: only the pictures move, the card stays put (the cards don't link
   anywhere, so a lifting card would promise a click). App pictures rise 6px
   and grow 3%; the floating chips rise twice as far, for depth. Mouse only;
   off with reduced motion. Uses translate/scale, not transform, so the
   peeking phone keeps its sideways offset. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card .card-img, .card .peek, .card .pop {
    transition: translate 0.35s cubic-bezier(0.2, 0.7, 0.2, 1), scale 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .card:hover .card-img, .card:hover .peek { translate: 0 -6px; scale: 1.03; }
  .card-peek:hover .pop, .card-recipe:hover .card-img { translate: 0 -12px; scale: 1.03; }
}

/* ---------- Privacy: words left, picture right ---------- */
.safe { padding: 0 0 130px; }
.safe-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: center; }
.safe-text p { margin-top: 20px; color: var(--body); font-size: 1.05rem; max-width: 470px; }
/* Picture on the left, words on the right, as in the reference. */
.safe-media { position: relative; order: -1; max-width: 430px; }
.safe-media > img { border-radius: 24px; border: 1px solid var(--line); }
.safe-media .icon-badge { right: -14px; top: -14px; width: 48px; height: 48px; border-radius: 14px; }
/* Pro features: two columns of blue checks. */
.pro-list { margin-top: 22px; display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; max-width: 520px; }
.pro-list li { position: relative; padding-left: 30px; color: var(--ink-soft); }
.pro-list li::before {
  content: ""; position: absolute; left: 0; top: 3px; width: 18px; height: 18px; border-radius: 6px;
  background: var(--blue) url("assets/check.svg") center / 12px no-repeat;
}
.safe-media .icon-badge svg { width: 24px; height: 24px; }

/* ---------- Follow along ----------
   Same soft full-width panel the reviews used. The logo row glides left on
   a loop: the track holds two identical groups and slides by exactly one
   group's width (-50%), so the restart is invisible. Hovering pauses it;
   with reduced motion it stands still. The edges fade out. */
.follow { padding: 0 0 130px; }
.follow-panel { background: var(--soft-panel); border-radius: 40px; padding: 88px 0 80px; overflow: hidden; }
.marquee {
  margin-top: 44px; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee-track { display: flex; width: max-content; animation: marquee 38s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-group { display: flex; gap: 20px; padding-right: 20px; }
.follow-chip {
  display: inline-flex; align-items: center; gap: 14px; padding: 16px 28px 16px 18px;
  background: var(--chip); border: 1px solid var(--line); border-radius: 18px;
  font-size: 1.1rem; font-weight: 500; color: var(--ink); text-decoration: none; white-space: nowrap;
  box-shadow: 0 8px 24px rgba(10, 20, 40, 0.04);
}
.follow-chip img { width: 40px; height: 40px; }
@keyframes marquee { from { translate: 0 0; } to { translate: -50% 0; } }
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ---------- Reviews ---------- */
.reviews { padding: 0 0 130px; }
.rating { margin-top: 14px; display: flex; align-items: center; gap: 10px; color: var(--body); font-size: 0.92rem; }
.stars { display: flex; gap: 3px; }
.stars svg { width: 18px; height: 18px; }
.track {
  margin-top: 40px; display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 50px) / 3); gap: 25px; align-items: end;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: 6px;
}
.track::-webkit-scrollbar { display: none; }
.reviews-panel { background: var(--soft-panel); border-radius: 40px; padding: 88px 0 72px; }
.reviews-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; }
/* Arrows only appear when the script that drives them is running. */
.review-arrows { display: none; gap: 10px; }
.js .review-arrows { display: flex; }
.arrow {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  background: var(--review-card); color: var(--ink); border: 1px solid var(--line);
}
.arrow svg { width: 18px; height: 18px; }
.arrow-next { background: var(--blue); border-color: var(--blue); color: #ffffff; }
.arrow:disabled { opacity: 0.4; cursor: default; }
/* Dots under the cards: one per stop the row can scroll to. */
.dots { margin-top: 30px; display: flex; justify-content: center; gap: 8px; }
.dots span { width: 8px; height: 8px; border-radius: 50%; background: var(--dot); transition: background 0.2s ease, width 0.2s ease; }
.dots span.is-active { width: 22px; border-radius: 4px; background: var(--blue); }
.review { scroll-snap-align: start; background: var(--review-card); border: 1px solid var(--line); border-radius: 20px; padding: 28px; box-shadow: 0 8px 24px rgba(10, 20, 40, 0.04); }
.review p { margin-top: 16px; color: var(--body); }
.review strong { display: block; margin-top: 18px; font-weight: 500; }

/* ---------- Closing blue panel ----------
   Words left, two upright phones rising out of the bottom edge on the right.
   The panel clips them, so they read as coming up from below. */
.cta { padding-bottom: 100px; }
.cta-panel {
  position: relative; overflow: hidden; background: var(--blue); color: #ffffff; border-radius: 40px;
  display: grid; grid-template-columns: 1fr 1fr; align-items: center; min-height: 480px; padding: 0 72px;
}
.cta-copy { padding: 80px 0; }
.cta-kicker { font-size: 1rem; color: rgba(255, 255, 255, 0.92); }
.cta-panel .title { margin-top: 12px; color: #ffffff; }
.cta-panel .btn { margin-top: 30px; }
.cta-phones { position: relative; align-self: stretch; }
.cta-phones img { position: absolute; filter: drop-shadow(0 30px 50px rgba(2, 7, 17, 0.30)); }
.cta-front { width: 290px; left: calc(50% - 40px); top: 64px; z-index: 2; }
.cta-back { width: 250px; left: calc(50% - 230px); top: 124px; z-index: 1; }

/* ---------- FAQ ----------
   Heading left, questions right. Each question is a <details> card; the plus
   turns into a cross when it opens. */
.faq { padding: 20px 0 96px; }
.faq-grid { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: 64px; align-items: start; }
.faq-head { position: sticky; top: 104px; }  /* below the pinned nav */
.faq-head p { margin-top: 18px; color: var(--body); }
.faq-head a { color: var(--ink); }
.faq-list { display: grid; gap: 12px; }
.faq-item { background: var(--card); border: 1px solid var(--line); border-radius: 18px; }
.faq-item summary {
  position: relative; padding: 22px 64px 22px 26px;
  font-size: 1.06rem; font-weight: 500; color: var(--ink);
}
.faq-item summary::before, .faq-item summary::after {
  content: ""; position: absolute; right: 26px; top: 50%; width: 14px; height: 2px; margin-top: -1px;
  border-radius: 2px; background: var(--grey); transition: transform 0.25s ease;
}
.faq-item summary::after { transform: rotate(90deg); }
.faq-item[open] summary::before { transform: rotate(45deg); }
.faq-item[open] summary::after { transform: rotate(135deg); }
.faq-item summary:hover::before, .faq-item summary:hover::after { background: var(--ink); }
.faq-item p { padding: 0 26px 24px; margin-top: -4px; color: var(--body); max-width: 62ch; }
/* Answers roll open and closed. Browsers that can animate to "auto" height
   (Chrome, Edge) slide the box; the rest open instantly and still fade the
   text in. Nothing is hidden where the features are missing. */
/* With home.js running, the script animates the height instead (works in
   every browser, including iPhone Safari, which cannot animate to "auto").
   These CSS rules are the no-script fallback. */
:root:not(.js) .faq-item { interpolate-size: allow-keywords; }
:root:not(.js) .faq-item::details-content { block-size: 0; overflow: hidden; transition: block-size 0.4s cubic-bezier(0.2, 0.7, 0.2, 1), content-visibility 0.4s allow-discrete; }
:root:not(.js) .faq-item[open]::details-content { block-size: auto; }
.faq-item p { transition: opacity 0.35s ease 0.05s, translate 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) 0.05s; }
@starting-style { .faq-item[open] p { opacity: 0; translate: 0 -6px; } }
@media (prefers-reduced-motion: reduce) {
  :root:not(.js) .faq-item::details-content, .faq-item p { transition: none; }
}

/* ---------- Narrow: the reference's mobile layout ---------- */
@media (max-width: 1100px) {
  .tile-tl, .tile-tr { display: none; }
  /* Two phones crowd the panel's text below this width (the back one covered
     the end of the kicker line at 935px). Keep the front one, centred. */
  .cta-back { display: none; }
  .cta-front { left: calc(50% - 145px); }
}
@media (max-width: 900px) {
  .hero { padding-top: 48px; }
  /* Same idea as desktop: the hero fills exactly one phone screen (with the
     browser bars showing, 100svh) minus a 20px peek of the How it works
     panel. The stage starts 314px down with a two-line headline. */
  .hero-stage { height: clamp(300px, calc(100vh - 334px), 623px); height: clamp(300px, calc(100svh - 334px), 623px); margin-top: 48px; }
  .hero-phone { width: 300px; }
  /* No floating widgets or Somi tiles on mobile: they crowd the phone. */
  .hero .pop, .hero .tile { display: none; }

  .panel { border-radius: 28px; padding: 24px 0 24px; }
  /* How it works becomes a slideshow: the phones swipe sideways (one screen
     per step, neighbours peeking in at the edges), the matching step card
     sits underneath, dots below. Native scroll-snap does the swiping. */
  .hint-desk, .steps-phone { display: none; }
  .hint-mobile { display: inline; }
  /* Sized so the whole section (heading to dots) fits on one phone screen
     below the nav: everything around the phone takes about 370px, and the
     phone takes what is left of the screen height (100vh, the screen with
     the browser bars tucked away, as they are while scrolling down),
     between 120 and 200px wide. */
  /* Text matches the rest of the page on phones (heading 2rem like Key
     features and the FAQ, card text like the feature cards). The "Swipe to
     see each step" line shows under the heading (Daniel, 21 Oct: put it
     back); the phone gives up 30px of height to make room for it. */
  .panel .title { font-size: 2rem; }
  .panel-hint { margin-top: 8px; }
  .steps-slides {
    --shot-w: clamp(104px, calc((100vh - 455px) * 0.4817), 240px);
    display: flex; gap: 18px; margin: 14px calc(-1 * var(--pad)) 0;
    padding: 4px calc(50% - var(--shot-w) / 2 + var(--pad)) 8px;
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .steps-slides::-webkit-scrollbar { display: none; }
  .steps-slides img {
    flex: none; width: var(--shot-w); scroll-snap-align: center;
    filter: drop-shadow(0 18px 30px rgba(0, 0, 0, 0.55));
    transition: opacity 0.35s ease, scale 0.35s ease;
  }
  .js .steps-slides img { opacity: 0.4; scale: 0.94; }
  .js .steps-slides img.is-current { opacity: 1; scale: 1; }
  .steps { grid-template-columns: 1fr; grid-template-rows: none; margin-top: 8px; row-gap: 10px; }
  .step { padding: 14px 16px; border-radius: 12px; }
  .step-label { margin-bottom: 3px; font-size: 0.7rem; }
  .step-title { font-size: 1.02rem; line-height: 1.35; }
  .step-1, .step-2, .step-3, .step-4 { grid-column: 1; grid-row: auto; margin: 0; }
  .step::after { display: none; }
  /* With the script running, the four cards share one spot and cross-fade,
     so only the current step's card shows. Every card keeps its full text,
     so the spot is as tall as the longest and nothing below jumps. */
  .js .steps .step { grid-area: 1 / 1; opacity: 0; pointer-events: none; transition: opacity 0.35s ease; }
  .js .steps .step.is-active { opacity: 1; pointer-events: auto; }
  .js .step .step-text { max-height: none; margin-top: 6px; opacity: 1; font-size: 0.92rem; line-height: 1.5; }
  .js .slide-dots { display: flex; justify-content: center; gap: 4px; margin-top: 6px; }
  /* 32 x 28px tap targets around 8px dots. */
  .slide-dot { width: 32px; height: 28px; display: grid; place-items: center; padding: 0; border: 0; background: none; cursor: pointer; }
  .slide-dot span { width: 8px; height: 8px; border-radius: 4px; background: rgba(255, 255, 255, 0.25); transition: width 0.25s ease, background 0.25s ease; }
  .slide-dot.is-active span { width: 22px; background: var(--blue); }

  /* Key features on a phone: the full-size cards in a side-swipe row, the
     next card peeking in at the right, dots underneath. Every card is the
     same height so the row stays tidy. Desktop is untouched. */
  .features { padding: 64px 0; }
  .grid {
    position: relative; display: flex; gap: 14px; margin: 32px calc(-1 * var(--pad)) 0;
    padding: 4px var(--pad) 12px; scroll-padding: 0 var(--pad);
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  }
  .grid::-webkit-scrollbar { display: none; }
  .grid-3, .grid-2 { display: contents; }
  .card { flex: 0 0 min(82vw, 340px); height: 400px; padding: 28px 22px 0; scroll-snap-align: start; }
  .card h3 { font-size: 1.2rem; }
  .card p { margin-top: 8px; font-size: 0.92rem; }
  .card-top { justify-content: flex-end; padding-bottom: 28px; }
  .card-top .card-img { width: 100%; max-width: none; margin: 8px auto auto; }
  .card-low .card-img { width: 100%; max-width: 290px; margin: auto auto 34px; }
  .card-peek .peek, .card-recipe .peek { width: 220px; top: auto; bottom: -250px; }
  .card-peek .peek { left: 50%; transform: translateX(-24%); }
  .card-peek .pop { left: 16px; top: auto; bottom: 64px; width: 170px; }
  .card-recipe .peek { left: auto; right: 16px; }
  .card-recipe .card-img { position: absolute; left: 16px; top: auto; bottom: 56px; width: 230px; max-width: none; margin: 0; }
  .card-dark .card-img { position: absolute; right: 0; bottom: 28px; width: 92%; max-width: none; margin: 0; }
  .js .carousel-dots { display: flex; justify-content: center; gap: 4px; margin-top: 14px; }
  .carousel-dots .slide-dot span { background: var(--dot); }
  .carousel-dots .slide-dot.is-active span { background: var(--blue); }

  /* Continue with Pro on a phone: one rounded card inside the page margins
     (Key features card colours), everything centred: star Somi on top, the
     heading, the line, then the Pro features as small check-marked tiles in
     two even columns (every tile the same size, checks lined up). The text wrapper steps aside
     (display: contents) so its pieces can be ordered around the picture. */
  .safe { padding-bottom: 72px; }
  .safe-grid {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 0; width: auto; margin: 0 var(--pad); padding: 30px 14px 24px;
    background: var(--feature-card); border: 1px solid var(--feature-line); border-radius: 28px;
  }
  .safe-text { display: contents; }
  .safe-media { order: -1; width: 150px; max-width: none; margin: 0 0 20px; }
  .safe-media > img { border-radius: 18px; }
  .safe-media .icon-badge { left: auto; right: -10px; top: -10px; width: 32px; height: 32px; border-radius: 10px; }
  .safe-media .icon-badge svg { width: 17px; height: 17px; }
  .safe-text .title { font-size: 1.9rem; }
  .safe-text p { margin-top: 10px; max-width: 30ch; font-size: 0.95rem; }
  .safe-text .pro-list {
    display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
    width: 100%; margin-top: 20px; max-width: none;
  }
  .safe-text .pro-list li {
    display: flex; align-items: center; min-height: 44px; text-align: left;
    padding: 7px 8px 7px 29px; border-radius: 12px; font-size: 0.78rem; line-height: 1.3;
    background: var(--bg); border: 1px solid var(--feature-line); color: var(--ink);
  }
  .safe-text .pro-list li::before { left: 8px; top: 50%; translate: 0 -50%; width: 15px; height: 15px; border-radius: 5px; background-size: 9px; }

  .reviews { padding-bottom: 80px; }
  .track { grid-auto-columns: 86%; gap: 14px; }

  .cta-panel { border-radius: 28px; grid-template-columns: 1fr; text-align: center; padding: 0 20px; min-height: 0; }
  .cta-copy { padding: 56px 0 40px; }
  .cta-badges .store-badges { justify-content: center; }
  /* Keep the two store badges side by side on phones: 40px tall (Apple's
     minimum for its badge) fits both in one row from about 350px wide.
     Only narrower screens than that let them stack. */
  .store-badges { gap: 10px; flex-wrap: nowrap; }
  .store-badge img { height: 40px; }
  .cta-panel .btn { width: 100%; }
  /* Both phones on mobile, smaller, matching the blog posts' banner: the
     nutrition screen behind on the left, the home screen in front. */
  .cta-phones { height: 300px; }

  .cta-back { display: block; width: 160px; left: calc(50% - 148px); top: 46px; }
  .cta-front { width: 190px; left: calc(50% - 46px); top: 0; transform: none; }

  /* FAQ: one column. The heading sits above the questions (centred, like
     the other section headings on mobile) and no longer sticks, since the
     questions now run underneath it. Rows get a little tighter. */
  /* Follow along on a phone: a compact strip inside the page margins, like
     the blue download panel, with smaller logo cards so three or more show
     at once and the row reads as a ticker. */
  .follow { padding-bottom: 72px; }
  .follow-panel { margin: 0 var(--pad); border-radius: 28px; padding: 44px 0 40px; }
  .marquee { margin-top: 26px; }
  .marquee-group { gap: 10px; padding-right: 10px; }
  .follow-chip { gap: 8px; padding: 8px 14px 8px 8px; border-radius: 13px; font-size: 0.88rem; }
  .follow-chip img { width: 26px; height: 26px; }

  .faq { padding: 8px 0 72px; }
  .faq-grid { grid-template-columns: 1fr; gap: 28px; }
  .faq-head { position: static; text-align: center; }
  .faq-head p { margin-top: 12px; }
  .faq-list { gap: 10px; }
  .faq-item { border-radius: 16px; }
  .faq-item summary { padding: 18px 52px 18px 20px; font-size: 1rem; line-height: 1.4; }
  .faq-item summary::before, .faq-item summary::after { right: 20px; }
  .faq-item p { padding: 0 20px 20px; font-size: 0.95rem; }
}

/* ---------- Latest blogs (below the FAQ) ----------
   The cards themselves come from blog.css, so they match the Blogs page. */
.latest { padding: 0 0 130px; }
/* Light divider between the FAQ and this section, the width of the content,
   with equal space above (FAQ padding) and below. */
.latest .wrap::before { content: ""; display: block; height: 1px; background: var(--line); margin-bottom: 96px; }
.latest-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; }
.latest-all { display: inline-flex; align-items: center; gap: 8px; font-size: 0.95rem; color: var(--ink); text-decoration: none; padding: 10px 18px; border-radius: 999px; border: 1px solid var(--line); }
.latest-all:hover { border-color: var(--grey); }
.latest-all svg { width: 16px; height: 16px; }
.latest .post-grid { margin-top: 40px; }
@media (max-width: 900px) {
  .latest { padding-bottom: 80px; }
  .latest .wrap::before { margin-bottom: 64px; }
  .latest-head { flex-direction: column; align-items: center; text-align: center; gap: 16px; }
  /* On a phone the three cards become compact rows: a square picture on the
     left, the date line and title on the right. Full cards were about 430px
     tall each. The brief and author are on the post itself. */
  .latest .post-grid { margin-top: 28px; gap: 12px; }
  .latest .post-card { flex-direction: row; align-items: center; gap: 14px; padding: 10px; border-radius: 18px; }
  .latest .post-card-img { flex: none; width: 96px; aspect-ratio: 1 / 1; border-radius: 12px; }
  .latest .post-card-text { padding: 0 4px 0 0; }
  .latest .post-card h3 { margin-top: 4px; font-size: 1rem; line-height: 1.3; }
  .latest .post-meta { font-size: 0.8rem; }
  .latest .post-brief, .latest .post-author { display: none; }
}

@media (max-width: 349px) {
  .store-badges { flex-wrap: wrap; }
}

/* Free resources (SEO audit item 15, 22 Oct): the cards line up with the
   section heading and the Latest blogs grid instead of sitting in the
   narrower centered block they use on the Resources page. Two across on
   desktop and tablets (four across was cramped), one on phones. */
.home-res .tool-grid { max-width: none; margin: 40px 0 0; grid-template-columns: 1fr 1fr; animation: none; }
@media (max-width: 900px) { .home-res .tool-grid { grid-template-columns: 1fr; margin-top: 28px; gap: 12px; } }

/* Links inside FAQ answers use the site's link blue, like the blog posts
   (Daniel, 22 Oct). The email link beside the FAQ heading is unchanged. */
.faq-item p a { color: var(--link); }

/* Key features, first card (26 Oct): now laid out like the AI routine card
   (card-low: title and text on top, the Search and Scan image below), so all
   five cards read the same way (Daniel: "match it"). */

/* Key features: balanced line breaks in the card titles and text, so no
   line ends with one word on its own (Daniel, 26 Oct: "jarring"). Words are
   unchanged; only where the lines break. */
.card h3, .card p { text-wrap: balance; }

/* Phones (Daniel, 26 Oct): the AI routine card's image was pinned to the
   bottom, leaving a big empty gap under the text, so it sat "super low".
   Center it in the space below the text instead. Desktop is unchanged. */
@media (max-width: 900px) {
  .card-low .card-img { margin: auto; }
}

/* Key features: one spacing rule for every card (Daniel, 26 Oct). Title,
   text, then the picture starting the same distance (--card-gap) below the
   text on every card; spare room falls at the bottom. The cards become a
   one-column grid and the pictures sit in the last row instead of being
   pinned to the top or bottom, so the gap holds whatever the text length.
   Pictures that overlap (phone + floating card) share that row; the
   floating card keeps its old offset from the phone's top. Before this
   change: ~/sfn-dev/backups-home-before-card-spacing.css */
.features .card { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; --card-gap: 28px; }
.features .card-c { grid-template-rows: auto auto 1fr; }
.features .card-l { grid-template-rows: auto 1fr; }
.features .card-c > .card-img, .features .card-c > .peek, .features .card-c > .pop { grid-row: 3; grid-column: 1; }
.features .card-l > .card-img, .features .card-l > .peek { grid-row: 2; grid-column: 1; }
.features .card .card-img, .features .card .peek, .features .card .pop {
  position: relative; inset: auto; align-self: start; margin: var(--card-gap) 0 0;
}
.features .card-low .card-img { justify-self: center; width: 319px; max-width: 100%; }
.features .card-peek .peek { justify-self: center; width: 280px; transform: translateX(22%); }
.features .card-peek .pop { justify-self: start; width: 181px; margin: calc(var(--card-gap) + 82px) 0 0 -8px; z-index: 3; }
.features .card-recipe .peek { justify-self: end; width: 280px; margin-right: 4px; }
.features .card-recipe .card-img { justify-self: start; width: 261px; margin-top: calc(var(--card-gap) + 70px); z-index: 3; }
.features .card-dark .card-img { justify-self: end; width: calc((100% + 64px) * 0.86); margin-right: -32px; }
@media (max-width: 900px) {
  /* Shorter cards on phones (was 400px) so the barcode, routine and
     progression cards don't end in a big empty band (Daniel, 26 Oct). 340 is
     the shortest that still fits the Build a recipe card. */
  .features .card { --card-gap: 24px; height: 340px; }
  .features .card-low .card-img { width: 100%; max-width: 290px; }
  .features .card-peek .peek { width: 220px; transform: translateX(26%); }
  .features .card-peek .pop { width: 170px; margin: calc(var(--card-gap) + 87px) 0 0 -6px; }
  .features .card-recipe .peek { width: 220px; margin-right: -6px; }
  .features .card-recipe .card-img { width: 230px; margin: calc(var(--card-gap) + 90px) 0 0 -6px; }
  .features .card-dark .card-img { width: calc((100% + 44px) * 0.92); margin-right: -22px; }
}

/* Follow along chips are links now (26 Oct): keep the chip look. */
a.follow-chip { text-decoration: none; color: inherit; }
/* Daniel, 26 Oct: on phones only, the Search and Scan buttons sit a little
   lower than the shared gap (16px more). Desktop keeps the shared gap. */
@media (max-width: 900px) {
  .features .card-low .card-img[src*="search-scan"] { margin-top: calc(var(--card-gap) + 16px); }
}
