/* FreeUp website. Apple-like: white and soft grey surfaces, sections told apart by tone, not lines.
   Colours follow the app icon: coral = delete, green = keep. */

:root {
  --bg: oklch(99.1% 0.002 260);
  --bg-alt: oklch(96.9% 0.003 260);
  --surface: oklch(100% 0 0);
  --ink: oklch(20% 0.008 265);
  --ink-2: oklch(45% 0.01 265);
  --ink-3: oklch(58% 0.01 265);
  --line: oklch(89.5% 0.005 265);
  --coral: oklch(63% 0.19 27);
  --green: oklch(62% 0.16 150);
  --blue: oklch(56% 0.2 256);
  --violet: oklch(56% 0.2 295);
  --orange: oklch(70% 0.17 60);
  --band: oklch(13% 0.004 265);
  --band-ink: oklch(97% 0.003 265);
  --band-ink-2: oklch(72% 0.008 265);
  --nav-bg: oklch(99.1% 0.002 260 / 0.8);
  --shadow-phone: 0 2px 6px oklch(20% 0.02 265 / 0.08), 0 40px 80px -30px oklch(20% 0.03 265 / 0.38);
  --radius: 22px;
  --wrap: 1180px;
  --gutter: clamp(16px, 5vw, 44px);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", system-ui, "Segoe UI", Roboto, sans-serif;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --nav-h: 52px;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: oklch(13.5% 0.004 265);
    --bg-alt: oklch(17.5% 0.006 265);
    --surface: oklch(21% 0.008 265);
    --ink: oklch(96.5% 0.003 265);
    --ink-2: oklch(76% 0.008 265);
    --ink-3: oklch(63% 0.008 265);
    --line: oklch(30% 0.008 265);
    --coral: oklch(71% 0.17 27);
    --green: oklch(74% 0.16 150);
    --blue: oklch(70% 0.16 252);
    --violet: oklch(72% 0.16 295);
    --orange: oklch(78% 0.15 65);
    --band: oklch(8% 0.003 265);
    --nav-bg: oklch(13.5% 0.004 265 / 0.78);
    --shadow-phone: 0 2px 6px oklch(0% 0 0 / 0.5), 0 40px 80px -30px oklch(0% 0 0 / 0.85);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: var(--nav-h); }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* clip, not hidden: hidden turns the page into a scroll container, which upsets sticky
     elements (the nav and the story phone) in Safari. */
  overflow-x: clip;
}
img, svg { display: block; max-width: 100%; }
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
a:focus-visible, summary:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; border-radius: 6px; }
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.022em; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
b, strong { font-weight: 600; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }
.skip { position: absolute; left: -999px; top: 8px; background: var(--surface); padding: 8px 14px; border-radius: 10px; z-index: 50; }
.skip:focus { left: 8px; }

/* Header. One look all the way down the page: a light frosted bar (dark in Dark Mode).
   Round 3 found the flicker: over the dark privacy band a script switched the bar to a dark style. The words
   changed colour at once while the bar's background faded over 0.35 s, so for a few frames the words were
   white on a light bar (or dark on a dark one) and the bar seemed to blink. The bar now never changes. */
.site-header {
  position: sticky; top: 0; z-index: 20;
  background: var(--nav-bg);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}
/* Round 4/5: on touch screens and narrow windows the bar is solid (the same colour as the page) with no live
   blur. A blurred bar is redrawn on every frame of a scroll from whatever moves under it, and phone GPUs are
   where Moey saw it blink. Nothing changes it while scrolling. Desktop keeps the frosted glass. */
@media (hover: none) and (pointer: coarse), (max-width: 899.98px) {
  .site-header { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
/* Round 5: on phones the bar is fixed, not sticky. Recorded in iPhone Safari: a fast flick into the bounce at the
   bottom of the page made the sticky bar vanish for about 13 frames (it is only sticky inside the page's box,
   and the bounce pulls that box up past it). A fixed bar is pinned to the screen and cannot leave. */
@media (max-width: 899.98px) {
  .site-header { position: fixed; top: 0; left: 0; right: 0; }
  body { padding-top: var(--nav-h); }
}
.header-inner { display: flex; align-items: center; justify-content: space-between; height: var(--nav-h); }
.brand { display: flex; align-items: center; gap: 10px; color: var(--ink); font-weight: 600; font-size: 17px; letter-spacing: -0.01em; }
.brand:hover { text-decoration: none; }
.brand img { width: 28px; height: 28px; }
.site-header nav { display: flex; gap: clamp(16px, 3vw, 30px); font-size: 13px; letter-spacing: 0.005em; }
.site-header nav a { color: var(--ink-2); }
.site-header nav a:hover { color: var(--ink); text-decoration: none; }

/* Icons: Phosphor "regular", outline only, never a fill and never a tile or circle behind them.
   Two sizes: 24px beside a line of words (eyebrows), 44px above a short block (promises, pricing, privacy). */
.ic { width: 1em; height: 1em; flex: none; }
.eyebrow { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 600; color: var(--ink-3); margin-bottom: 16px; letter-spacing: -0.01em; }
.eyebrow .ic { width: 24px; height: 24px; }
.tone-blue { color: var(--blue); }
.tone-coral { color: var(--coral); }
.tone-green { color: var(--green); }
.tone-violet { color: var(--violet); }
.tone-orange { color: var(--orange); }
.text-link { font-weight: 500; font-size: 17px; }
.text-link::after { content: " \203A"; }

.feat-ic { display: block; }
.feat-ic .ic, .privacy-points .ic { width: 44px; height: 44px; }
.promises .feat-ic { color: var(--blue); }
.pricing .feat-ic { color: var(--green); }

/* App Store badge: Apple's official artwork (static/img/badges, from Apple's Marketing Tools), used unmodified.
   Black badge on the light look, white badge on the dark look (switched by <picture>). Apple's rules: at least
   40px tall on screen, clear space of at least a quarter of its height on every side, nothing touching it.
   At 50px tall that is 12.5px: the "Coming soon" line sits 13px below it, and the gaps around it are wider. */
.store-badge-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 13px; }
.closing .store-badge-wrap { align-items: center; }
.store-badge { display: block; line-height: 0; border-radius: 9px; }
.store-badge:hover { text-decoration: none; }
.store-badge-wrap .store-badge img { display: block; height: 50px; width: auto; }
.store-badge-note { font-size: 14px; line-height: 1.3; color: var(--ink-2); }

/* Phone frame. --sw is the screen width; the screenshots are 1206 x 2622 (iPhone 17 Pro). */
.phone {
  --sw: min(280px, 64vw);
  --bez: calc(var(--sw) * 0.034);
  width: calc(var(--sw) + 2 * var(--bez));
  padding: var(--bez);
  border-radius: calc(var(--sw) * 0.17);
  background: oklch(14% 0.004 265);
  box-shadow: inset 0 0 0 1.5px oklch(52% 0.008 265), inset 0 0 0 3px oklch(20% 0.004 265), var(--shadow-phone);
}
.screen {
  position: relative; overflow: hidden;
  width: var(--sw); aspect-ratio: 1206 / 2622;
  border-radius: calc(var(--sw) * 0.136);
  background: oklch(10% 0.003 265);
}
.story-phone .screen { transform: translateZ(0); }
.screen img { width: 100%; height: 100%; object-fit: cover; }

/* Story. Phones (round 5): each step is its words and then one still picture of the app in a phone frame.
   Nothing is pinned, nothing moves with the scroll, no script runs. Wide screens (900px and up): one large
   phone stays to the right of the words and changes its screen as each step reaches the middle (round 4).
   Swap-ready: the screens are the files in /img/app/ (780 x 1696 WebP). New screenshots with the same names
   and size drop in with no code change. */
.story-grid { display: grid; grid-template-columns: minmax(0, 1fr); }
.step { padding: 64px 0; }
.step h1 { font-size: clamp(2.8rem, 8vw, 5.4rem); line-height: 1.02; letter-spacing: -0.045em; max-width: 12ch; }
.step h2 { font-size: clamp(2.1rem, 5vw, 3.5rem); line-height: 1.05; letter-spacing: -0.04em; max-width: 14ch; }
.step h2 + p { margin-top: 24px; }
.step p:not(.eyebrow):not(.lead) { margin-top: 16px; color: var(--ink-2); font-size: 19px; line-height: 1.5; max-width: 42ch; }
.step-hero { padding-top: clamp(40px, 8vw, 88px); }
.hero-icon img { width: 88px; height: 88px; margin-bottom: 30px; filter: drop-shadow(0 10px 18px oklch(30% 0.03 265 / 0.18)); }
.step-hero .lead { margin-top: 24px; font-size: clamp(1.2rem, 2.2vw, 1.45rem); line-height: 1.42; color: var(--ink-2); max-width: 32ch; }
.hero-actions { margin-top: 36px; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 18px 28px; }
.hero-actions .text-link { line-height: 50px; }
.step-phone { margin: 44px 0 0; display: flex; justify-content: center; }
.story-phone { display: none; }

@media (max-width: 899.98px) {
  /* Every other step sits on the soft grey, so the steps are told apart by tone, as elsewhere on the page. */
  .steps .step:nth-child(odd) { border-image: conic-gradient(var(--bg-alt) 0 0) fill 0 / / 0 100vmax; }
  .step:not(.step-hero) h2 { font-size: clamp(2rem, 8.6vw, 2.6rem); line-height: 1.07; letter-spacing: -0.035em; }
  .step:not(.step-hero) p:not(.eyebrow) { font-size: 17px; }
  .step .eyebrow { font-size: 16px; }
}

@media (min-width: 900px) {
  .story-grid {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: clamp(56px, 8vw, 128px);
  }
  .step-hero { grid-column: 1; grid-row: 1; }
  .steps { grid-column: 1; grid-row: 2; }
  .step {
    min-height: 92vh; min-height: 92svh;
    display: flex; flex-direction: column; justify-content: center;
    padding: 8vh 0;
  }
  .step-hero { min-height: calc(100vh - var(--nav-h)); min-height: calc(100svh - var(--nav-h)); padding-top: 4vh; }
  .step-phone { display: none; }
  .story-phone {
    --sw: clamp(240px, 37vh, 340px);
    --ph: calc(var(--sw) * 2.242); /* whole phone height: screen plus bezels */
    display: block; grid-column: 2; grid-row: 1 / span 2;
    position: sticky; align-self: start;
    /* centred in the space under the nav, from the first screen to the last step */
    top: calc(var(--nav-h) + (100vh - var(--nav-h) - var(--ph)) / 2);
    margin: calc((100vh - var(--nav-h) - var(--ph)) / 2) 0 calc(46vh - var(--ph) / 2);
  }
  .story-phone .phone { --sw: inherit; }
  /* Screen changes (round 4). The new screen fades in on top (.on) while the one it replaces (.was) stays fully
     there underneath; every other screen is hidden at once. The script starts the next change only after this
     one has finished, so a quick scroll can never leave an older screen on top. */
  .story-phone img { position: absolute; inset: 0; opacity: 0; will-change: opacity; }
  .story-phone img.was { opacity: 1; z-index: 1; }
  .story-phone img.on { opacity: 1; z-index: 2; transition: opacity .38s ease; }
  /* With the script running, the pictures inside each step are only for screen readers: the story phone shows
     them instead. */
  .js .step-phone {
    display: flex; position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  .js .story-phone { display: block; }
  /* With the script running, the steps that are not in the middle of the window step back a little. */
  .js .step { transition: opacity .5s ease; }
  .js .step:not(.is-active) { opacity: .28; }
}

/* Promises */
.promises { background: var(--bg-alt); padding: clamp(80px, 11vw, 140px) 0; }
.promise-grid { display: grid; gap: 48px; }
.promise h3 { margin-top: 18px; font-size: 26px; letter-spacing: -0.025em; }
.promise p { margin-top: 8px; color: var(--ink-2); font-size: 18px; max-width: 30ch; }
@media (min-width: 820px) { .promise-grid { grid-template-columns: repeat(3, 1fr); gap: 56px; } }

/* Pricing */
.pricing { padding: clamp(88px, 12vw, 150px) 0; }
.pricing h2 { font-size: clamp(2.1rem, 5vw, 3.5rem); letter-spacing: -0.04em; line-height: 1.05; }
.price-cols { margin-top: 64px; display: grid; gap: 48px; }
.price-cols h3 { margin-top: 18px; font-size: 22px; letter-spacing: -0.02em; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.price-cols p { margin-top: 10px; color: var(--ink-2); max-width: 40ch; }
@media (min-width: 760px) { .price-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 64px; max-width: 900px; } }

/* Privacy band: the one dark section, with a big outline lock (it closes as it comes into view on wide screens) */
.privacy-band { background: var(--band); color: var(--band-ink); padding: clamp(96px, 13vw, 168px) 0; text-align: center; }
.privacy-inner { display: flex; flex-direction: column; align-items: center; }
.lock {
  position: relative; width: clamp(132px, 18vw, 184px); color: oklch(80% 0.16 150); margin-bottom: 40px;
}
.lock svg { position: relative; width: 100%; height: auto; overflow: visible; }
.privacy-band h2 { font-size: clamp(2.4rem, 6.4vw, 4.6rem); line-height: 1.03; letter-spacing: -0.045em; max-width: 15ch; }
.privacy-points { margin-top: 64px; display: grid; gap: 40px; max-width: 1020px; text-align: left; }
.privacy-points > div { display: flex; flex-direction: column; gap: 16px; }
.privacy-points .ic { width: 40px; height: 40px; color: oklch(80% 0.14 150); }
.privacy-points p { color: var(--band-ink-2); font-size: 17px; }
.privacy-points b { display: block; color: var(--band-ink); font-size: 20px; margin-bottom: 4px; letter-spacing: -0.015em; }
@media (min-width: 860px) { .privacy-points { grid-template-columns: repeat(3, 1fr); gap: 48px; } }
.text-link.on-band { display: inline-block; margin-top: 56px; color: oklch(76% 0.13 250); }

/* Closing: a strip of everyday photos, fading into the page, then the app */
.closing { background: var(--bg-alt); padding: 0 0 clamp(96px, 12vw, 150px); text-align: center; }
.mosaic {
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 3px;
  -webkit-mask-image: linear-gradient(to bottom, #000 35%, transparent);
  mask-image: linear-gradient(to bottom, #000 35%, transparent);
}
.mosaic img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }
.closing-inner { position: relative; margin-top: clamp(-72px, -5vw, -40px); display: flex; flex-direction: column; align-items: center; }
.closing-inner > picture img { width: 112px; height: 112px; filter: drop-shadow(0 12px 22px oklch(30% 0.03 265 / 0.22)); }
.closing h2 { margin-top: 26px; font-size: clamp(2.2rem, 5.4vw, 3.4rem); letter-spacing: -0.04em; }
.closing-inner p { margin: 10px 0 32px; color: var(--ink-2); font-size: 20px; }
@media (max-width: 760px) { .mosaic { grid-template-columns: repeat(6, 1fr); } .mosaic img:nth-child(n+13) { display: none; } }

/* Big headlines grow into place as they scroll in, as on Apple's product pages. Scroll-driven, so it runs
   off the main thread and costs nothing where it isn't supported. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 900px) {
    .grow { animation: grow linear both; animation-timeline: view(); animation-range: entry 10% cover 38%; transform-origin: 0 50%; }
    .privacy-band .grow { transform-origin: 50% 50%; }
  }
}
@keyframes grow { from { opacity: .2; transform: scale(.88); } to { opacity: 1; transform: none; } }

/* Reveal: cards and the lock ease up once, on wide screens only, only with the script, never with Reduce
   Motion. Phones get no reveals at all (round 5): everything is simply there. */
@media (min-width: 900px) {
  .js.wide .reveal { opacity: 0; transform: translateY(18px); transition: opacity .8s ease, transform .9s var(--ease-out); }
  .js.wide .reveal.in { opacity: 1; transform: none; }
  .js.wide .lock .shackle { transform: translateY(-30px); transition: transform 1s var(--ease-out) .35s; }
  .js.wide .lock.in .shackle { transform: none; }
  .js.wide .lock .body { transform-origin: 50% 70%; transform: scale(.94); transition: transform 1.1s var(--ease-out) .2s; }
  .js.wide .lock.in .body { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal, .js .reveal.in { opacity: 1 !important; transform: none !important; transition: none !important; }
  .js .lock .shackle, .js .lock .body { transform: none !important; transition: none !important; }
  .story-phone img.on { transition: opacity .2s linear; }
  .grow { animation: none !important; }
}

/* Footer */
.site-footer { background: var(--bg-alt); padding: 40px 0 48px; font-size: 13px; color: var(--ink-3); }
.home .site-footer { padding-top: 0; }
.home .footer-inner { padding-top: 32px; box-shadow: 0 -1px 0 var(--line); }
.footer-inner { display: grid; gap: 18px; }
.footer-brand { display: flex; flex-direction: column; gap: 2px; }
.footer-brand strong { color: var(--ink); font-size: 15px; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 10px 24px; }
.site-footer nav a { color: var(--ink-2); }
.fine { font-size: 12px; max-width: 70ch; }

/* Document pages: privacy, terms, support */
.doc { padding: clamp(48px, 8vw, 96px) 0 clamp(72px, 10vw, 120px); }
.doc .wrap { max-width: 780px; }
.doc h1 { font-size: clamp(2.3rem, 6vw, 3.4rem); letter-spacing: -0.04em; line-height: 1.05; }
.doc .meta { margin-top: 12px; color: var(--ink-3); font-size: 15px; }
.doc .intro { margin-top: 26px; font-size: 20px; line-height: 1.5; color: var(--ink-2); }
.doc h2 { margin-top: 52px; font-size: 24px; letter-spacing: -0.025em; }
.doc h3 { margin-top: 28px; font-size: 18px; letter-spacing: -0.015em; }
.doc p, .doc li { color: var(--ink-2); }
.doc p { margin-top: 14px; max-width: 68ch; }
.doc ul { margin: 14px 0 0; padding-left: 1.2em; max-width: 66ch; }
.doc li { margin-top: 8px; padding-left: 4px; }
.doc li::marker { color: var(--ink-3); }
.doc strong { color: var(--ink); }
.summary {
  margin-top: 36px; padding: 22px 24px; border-radius: var(--radius);
  background: var(--bg-alt);
}
.summary h2 { margin-top: 0; font-size: 17px; letter-spacing: -0.01em; }
.summary ul { margin-top: 8px; }

/* FAQ */
.faq-group { margin-top: 52px; }
.faq-group > h2 { margin-top: 0; }
.faq { margin-top: 16px; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer; padding: 18px 36px 18px 0; position: relative;
  font-size: 18px; font-weight: 600; letter-spacing: -0.015em; color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 6px; top: 50%; width: 9px; height: 9px; margin-top: -7px;
  border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg); transition: transform .3s var(--ease-out);
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }
.faq .answer { padding: 0 0 22px; }
.faq .answer p:first-child { margin-top: 0; }
.contact-card { margin-top: 56px; padding: 28px; border-radius: var(--radius); background: var(--bg-alt); }
.contact-card h2 { margin-top: 0; }

@media (max-width: 520px) {
  .hide-sm { display: none; }
  .brand span { font-size: 16px; }
}
