/* swiperoll.app home: the scroll story (round 3).
   Static first: every beat is a plain stacked section with its own phone, break-out piece and bar state.
   The `js` class (set by story.js only when GSAP loaded and motion is allowed) turns the beats into
   layers of ONE pinned stage: one phone, one storage bar, text and pieces that change as you scroll. */

/* ---------- Header: fixed on every page (base.css); its edge shows once the page has scrolled ---------- */
html.hd .site-head { border-bottom-color: transparent; }
html.hd.scrolled .site-head { border-bottom-color: var(--edge); }

/* ---------- Beat shell ---------- */
.beat {
  --fill: var(--page);
  --piece: var(--card);
  --piece-edge: color-mix(in srgb, var(--sky) 38%, transparent);
  --bgc: var(--fill);
  position: relative;
  background: var(--fill);
  overflow: clip;
  padding: 36px var(--gutter) 48px;
  isolation: isolate;
}
.beat[data-fill="card"]    { --fill: var(--card);    --piece: var(--control); }
.beat[data-fill="control"] { --fill: var(--control); --piece: var(--card); }
.beat.is-later { border-radius: 50% 50% 0 0 / 28px 28px 0 0; }

.beat-inner {
  position: relative; z-index: 2;
  display: grid; gap: 24px; justify-items: center;
  max-width: 72rem; margin: 0 auto;
  text-align: center;
}
.copy { display: grid; gap: 12px; justify-items: center; max-width: 36rem; width: 100%; }
.beat h1.display, .beat h2.display {
  font-size: clamp(1.6rem, 7.2vw, 3.4rem); text-wrap: balance; white-space: nowrap;
}
.visual { display: grid; gap: 18px; justify-items: center; width: 100%; }

/* Icon bullets: one line each */
.points { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; justify-items: start; width: max-content; max-width: 100%; text-align: left; }
.points li { display: flex; align-items: center; gap: 10px; white-space: nowrap; font-size: clamp(14px, 3.9vw, 18px); line-height: 1.25; color: var(--text); }
.points svg { flex: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.points .keep { color: var(--keep); } .points .marked { color: var(--marked); } .points .pending { color: var(--pending); }
.points .sky { color: var(--sky); } .points .n { color: var(--text-2); }

.cta { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center; justify-content: center; margin-top: 0; }
.cta .button { padding: 0 26px; font-size: 1.0625rem; }
.beat .small { margin: 0; font-size: .8125rem; line-height: 1.2; }

.beat .small.note { color: var(--text-2); }
.copy .cta + .small { margin-top: 2px; }

/* ---------- Wall of drawn tiles (beats 1 and 9) ---------- */
.wallwrap { position: absolute; inset: 0; z-index: 1; perspective: 900px; pointer-events: none; }
.wall {
  position: absolute; left: -40%; right: -40%; top: 46%; height: 120%;
  display: grid; gap: 10px; align-content: start;
  transform: rotateX(58deg) translateZ(-40px); transform-origin: 50% 0;
  opacity: .3;
}
.wall .row { display: grid; grid-template-columns: repeat(9, 1fr); gap: 10px; }
.wall svg { width: 100%; aspect-ratio: 1; border-radius: 14px; }
/* the one allowed gradient: the wall fading into its fill */
.shade {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, var(--bgc) 30%, transparent 70%, var(--bgc) 100%);
}

/* ---------- Stage: phone + break-out pieces ----------
   The SCREEN is the 1206 x 2622 box; the phone body grows around it (3 px edge + 3.5% padding),
   so a screenshot is always shown whole and centred. Phone height is about 2.092 x its width. */
.stage {
  --pw: min(62vw, 300px, max(170px, calc((100svh - 360px) / 2.092)));
  --pad: calc(var(--pw) * .035);
  --sw: calc(var(--pw) - 2 * var(--pad) - 6px);
  position: relative; width: var(--pw);
  height: calc(var(--sw) * 2622 / 1206 + 2 * var(--pad) + 6px);
  perspective: 1400px; font-size: calc(var(--pw) / 20);
  margin: 0 auto;
}
.stage .phone {
  --w: var(--pw);
  position: absolute; left: 0; top: 0; width: var(--pw); height: auto; aspect-ratio: auto;
  transform: rotateY(var(--ry, 0deg)) rotateX(var(--rx, 0deg));
}
.stage .phone .screen { width: 100%; height: auto; aspect-ratio: 1206 / 2622; }
.phone .screen picture { position: absolute; inset: 0; display: none; }
.phone .screen picture.is-still { display: block; }
.phone .screen picture img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center; }

/* the drawn screen of beat 1 */
.roll { position: absolute; inset: 0; background: #000; padding: 12% 0 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5px; align-content: start; }
.roll .t, .roll .t svg { display: block; width: 100%; aspect-ratio: 1; }

/* Break-out pieces. Depth = perspective + a 2 px edge, never a shadow. */
.pop {
  position: absolute; z-index: 4; transform-style: preserve-3d; text-align: left;
  transform: rotate(var(--r, 0deg)) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(var(--z, 60px)) scale(var(--s, 1));
}
.pop-i { transform-style: preserve-3d; }
.tile { width: 9.2em; padding: .6em; border-radius: 1.8em; background: var(--piece); border: 2px solid var(--piece-edge); position: relative; }
.tile > svg { width: 100%; aspect-ratio: 5 / 6; border-radius: 1.3em; }
.pill {
  position: absolute; left: 50%; bottom: .9em; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: .35em; padding: .25em .8em .25em .5em; border-radius: 999px;
  background: var(--piece); border: 2px solid var(--piece-edge); color: var(--text);
  font: 700 1.2em/1.2 var(--font); white-space: nowrap;
}
.pill svg { width: 1.2em; height: 1.2em; }
.pill.keep svg { color: var(--keep); }
.pill.mark svg { color: var(--marked); }
.pill.sim { padding-left: .8em; }

.bubble {
  width: 8.6em; height: 8.6em; border-radius: 50%; display: grid; place-items: center;
  background: var(--piece); border: .3em solid var(--sky); color: var(--sky-text);
}
.bubble svg { width: 4em; height: 4em; }
.pop-bubble .pop-i { display: grid; justify-items: center; gap: .5em; }
.bub-label { font: 700 1.2em/1.2 var(--font); color: var(--text); background: var(--piece); border-radius: 999px; padding: .15em .7em; border: 2px solid var(--piece-edge); }

.card { background: var(--piece); border: 2px solid var(--piece-edge); border-radius: 2.2em; padding: 1.4em 1.6em; }
.card .ctitle { font-weight: 700; font-size: 1.5em; line-height: 1.2; letter-spacing: -0.01em; }
.card .big { font-size: 3.4em; font-weight: 800; letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.card .cap { font-size: 1.2em; color: var(--text-2); margin-top: .3em; line-height: 1.3; }
.card.sky { border-color: var(--sky); }
.card.sky .big { color: var(--sky-text); }
.pop-saved .card { text-align: center; }
.pop-saved .big { font-size: 2.9em; white-space: nowrap; }
.card.warn { display: flex; gap: .8em; align-items: flex-start; border-color: color-mix(in srgb, var(--pending) 60%, transparent); }
.card.warn svg { flex: none; width: 2em; height: 2em; }
.card.warn .ctitle { font-size: 1.4em; }

/* the 30-day bin: big, 1.2 times the phone width (owner, round 3) */
.bin { width: 22em; color: var(--pending); background: var(--piece); border: 2px solid var(--piece-edge); border-radius: 2.2em; padding: .7em; }
.bin svg, .drive svg { width: 100%; height: auto; }
.drive { color: var(--sky); }
.mini { width: 3em; padding: .2em; border-radius: .9em; background: var(--piece); border: 2px solid var(--piece-edge); }
.mini svg { width: 100%; aspect-ratio: 1; border-radius: .65em; }

/* confetti: small rects and dots, behind the card */
.confetti { position: absolute; left: 10em; top: 33em; width: 0; height: 0; z-index: 3; pointer-events: none; }
.confetti i {
  position: absolute; left: calc(var(--d) / -2); top: calc(var(--d) / -2); width: var(--d); height: var(--d);
  transform: translate(calc(var(--x) * 1em), calc(var(--y) * 1em)) rotate(var(--r));
}
.confetti .rc { height: calc(var(--d) * .55); border-radius: 1px; }
.confetti .dot { border-radius: 50%; }
.confetti .c1 { background: var(--keep); } .confetti .c2 { background: var(--sky); } .confetti .c3 { background: var(--pending); }
.confetti .c4 { background: var(--marked); } .confetti .c5 { background: #fff; }
html:not(.js) .more { display: none; }

.steps {
  display: flex; align-items: center; justify-content: space-between; gap: .4em; margin: 0; padding: 1.2em 1em 1em; list-style: none;
  background: var(--piece); border: 2px solid var(--piece-edge); border-radius: 2.2em; color: var(--sky);
}
.steps li { flex: 1; text-align: center; font: 700 1.15em/1.2 var(--font); color: var(--text); }
.steps li svg { margin: 0 auto .5em; width: 4.4em; height: 4.4em; }
.steps li svg.drv { width: 6.4em; height: 5.2em; }
.steps li svg.chk { color: var(--keep); }
.steps .sep { flex: none; font-size: 1.8em; font-weight: 800; color: var(--sky-text); }

/* flyers: hidden in the still layout, shown only by the scroll motion */
.flyer { position: absolute; z-index: 3; width: 4em; opacity: 0; pointer-events: none; }
.flyer svg { width: 100%; aspect-ratio: 1; border-radius: .9em; }
.beat[data-beat="backup"] .flyer { left: calc(50% + var(--fx) * 1.1em - 2em); top: 29.4em; }
.beat[data-beat="free-up"] .flyer { left: calc(-6.4em + var(--fx) * 1.3em); top: 21.4em; width: 3.2em; }

/* ---------- Storage bar: layered segments so only transform and opacity move ---------- */
.storage { width: min(100%, 360px); text-align: left; }
.storage .label { font-size: clamp(1.05rem, 3.2vw, 1.15rem); margin-bottom: 9px; }
.storage .track { position: relative; display: block; height: 18px; border-radius: 999px; overflow: hidden; border: 1px solid var(--edge); background: var(--piece); }
.storage .track > span { position: absolute; top: 0; bottom: 0; left: var(--l); width: var(--w); transform-origin: 0 50%; }
.storage .back { transform-origin: 100% 50%; }
.storage .labels { display: grid; }
.storage .labels .label { grid-area: 1 / 1; }

/* ---------- Free up flag (D166): one attribute hides the beat ---------- */
html[data-free-up="off"] [data-beat="free-up"] { display: none; }

/* ---------- Wide: two-column stage, text left, phone right ---------- */
@media (min-width: 900px) {
  .beat { padding: 72px 32px; }
  .beat-inner { grid-template-columns: minmax(0, 36rem) auto; justify-content: center; gap: 6rem; align-items: center; text-align: left; }
  .copy { justify-items: start; }
  .cta { justify-content: flex-start; }
  .beat h1.display, .beat h2.display { font-size: clamp(2rem, 2.8vw, 2.7rem); }
  .points li { font-size: 1.2rem; }
  .copy { gap: 16px; }
  .points { gap: 10px; }
  .points svg { width: 24px; height: 24px; }
  /* The phone fits the window height; the storage bar moves under the text */
  .beat-inner { grid-template-areas: "copy stage" "bar stage"; grid-template-rows: auto auto; row-gap: 32px; }
  .copy { grid-area: copy; align-self: end; }
  .visual { display: contents; }
  .stage { grid-area: stage; align-self: center; --pw: min(460px, max(220px, calc((100svh - 150px) / 2.092))); margin: 0; }
  .visual .storage { grid-area: bar; align-self: start; justify-self: start; width: min(100%, 400px); }
  .wall { top: 66%; left: -10%; right: -10%; }
}

/* ---------- Motion on: ONE pinned stage of 100svh under the header (set by story.js) ---------- */
.js .story {
  position: relative; overflow: clip; background: var(--page);
  height: calc(100svh - var(--head-h, 77px));
}
.js .story-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; --bgc: var(--page); }
.js .bg-wall { position: absolute; inset: 0; }
.js .beat {
  position: absolute; inset: 0; z-index: 1; min-height: 0;
  background: transparent; border-radius: 0; overflow: visible; isolation: auto; pointer-events: none;
  padding: 12px var(--gutter) 8px;
  display: grid; align-content: center; justify-items: center;
}
.js .beat-inner { width: 100%; gap: 8px; }
.js .visual { gap: 16px; padding-bottom: 16px; }
.js .copy { min-height: var(--copy-h, 0px); align-content: end; gap: 12px; margin-bottom: 20px; will-change: transform, opacity; }
.js .beat:not([data-beat="full"]) .copy { opacity: 0; }
.js .cta { pointer-events: auto; }
.js .story .beat .stage { --pw: var(--story-pw, 220px); }
.js .beat:not([data-beat="full"]) .phone { display: none; }
.js .storage.is-ph { visibility: hidden; }
.js .phone { transform: none; }
.js .phone .screen picture { display: block; opacity: 0; }
.js .pop-i { will-change: transform, opacity; }
.js .beat:not([data-beat="full"]) .pop-i, .js .confetti i, .js .flyer { opacity: 0; }
.js .confetti i { transform: none; }
@media (min-width: 900px) {
  .js .beat { padding: 16px 32px; }
  .js .beat-inner { row-gap: 24px; }
}

/* ---------- The app's bin flight (beat 4): row of thumbnails, bin with a lid hinged at its left end ---------- */
.bf {
  width: 22em; display: grid; justify-items: center; gap: .4em; padding: .9em 1em .8em;
  background: var(--piece); border: 2px solid var(--piece-edge); border-radius: 2.2em; color: var(--pending);
}
.bf-row { position: relative; z-index: 2; display: flex; align-items: center; gap: .45em; }
.bf-slot { position: relative; display: block; width: 2.9em; height: 2.9em; }
.bf-t, .bf-d { position: absolute; inset: 0; display: block; border-radius: .6em; border: 2px solid var(--piece-edge); overflow: hidden; background: var(--card); }
.bf-t svg, .bf-d svg { display: block; width: 100%; height: 100%; }
.bf-d { opacity: 0; }
.bf-plus { min-width: 2.7em; height: 2.2em; display: grid; place-items: center; border-radius: 999px; background: var(--control); color: var(--text-2); font: 700 1.1em/1 var(--font); font-variant-numeric: tabular-nums; }
.bf-binw { position: relative; z-index: 3; width: 11em; margin-top: .9em; }
.bf-bin { width: 100%; height: auto; overflow: visible; }
html:not(.js) .bf .lid { transform-origin: 72px 119px; transform: rotate(-80deg); }
.bf-cap { margin: 0; text-align: center; color: var(--text-2); font: 600 1.25em/1.3 var(--font); text-wrap: balance; }
/* still layout: lid open, three thumbnails mid-air */
html:not(.js) .bf-d.mid { opacity: 1; transform: translate(calc(var(--tx) * 1em), calc(var(--ty) * 1em)) rotate(var(--tr)) scale(.8); z-index: 3; }
.js .bf-d { transform: none; }
.js .bf-cap { opacity: 0; }

/* ---------- Streak card (beat 9) ---------- */
.card.streak { text-align: left; }
.srow { display: flex; align-items: center; gap: .35em; }

/* ---------- Phone layout: the phone takes all the height left between copy and bar, centred there ---------- */
@media (max-width: 899px) {
  .js .beat { display: block; }
  .js .beat-inner { height: 100%; grid-template-rows: auto minmax(0, 1fr); }
  .js .visual { height: 100%; min-height: 0; grid-template-rows: minmax(0, 1fr) auto; align-items: center; }
  .js .visual .stage { align-self: center; }
  .js .visual .storage { align-self: end; }
}

/* Beat 1: iPhone's own storage alert, redrawn as in the storage-full carousel (marketing/carousels/02-storage-full).
   Literal colours here depict iOS's alert, not the brand. Depth from the edge, no shadow. */
/* ---------- iOS 26 Liquid Glass alert (beat 1). Works without backdrop-filter: its own blurred tile mosaic is the glass ---------- */
.ios-alert {
  position: relative; overflow: hidden; border-radius: 2.6em; color: #fff; text-align: center;
  background: rgba(30, 34, 44, 0.3);
  -webkit-backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
  transform-style: flat;
}
.glass-bg { position: absolute; inset: -2em; display: grid; grid-template-columns: repeat(4, 1fr); gap: .3em; filter: blur(14px) saturate(1.4); }
.glass-bg svg { width: 100%; aspect-ratio: 1; border-radius: 1em; }
.ios-alert::after { content: ""; position: absolute; inset: 0; background: rgba(30, 34, 44, 0.45); pointer-events: none; }
.ios-alert::before {
  content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(140deg, rgba(255,255,255,.95), rgba(255,255,255,.28) 30%, rgba(255,255,255,.06) 60%, rgba(255,255,255,.4));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.glass-hi { position: absolute; left: 0; right: 0; top: 0; height: 42%; z-index: 2; pointer-events: none; background: linear-gradient(180deg, rgba(255,255,255,.2), rgba(255,255,255,0)); }
.glass-in { position: relative; z-index: 2; padding: 1.6em 1.3em 1.25em; }
.ios-alert .t { font-weight: 700; font-size: 2em; line-height: 1.12; letter-spacing: -0.015em; }
.ios-alert .b { font-size: 1.3em; line-height: 1.28; color: rgba(255,255,255,.85); margin: .35em 0 1em; }
/* iOS proportions (as in the storage-full carousel): buttons about 12% of the alert width tall. It is a picture, not a control. */
.ios-alert .btns { display: flex; gap: .55em; }
.ios-alert .btns span { flex: 1; height: 2.25em; display: grid; place-items: center; border-radius: 999px; font-weight: 600; font-size: 1.3em; background: rgba(255,255,255,.2); border: 1px solid rgba(255,255,255,.28); }
.ios-alert .btns .pri { background: #0A84FF; border-color: rgba(255,255,255,.4); }
.js .ios-alert { opacity: 0; }


/* ---------- Beat 2: decision tiles (kept, marked for deletion, favourite) ---------- */
.dtile { position: relative; width: 6.6em; padding: .5em; border-radius: 1.5em; background: var(--piece); border: 2px solid var(--piece-edge); }
.dtile > svg.ph { display: block; width: 100%; aspect-ratio: 5 / 6; border-radius: 1.1em; }
.dec-mark .dtile > svg.ph { opacity: .75; }
.dbadge { position: absolute; left: -.8em; top: -.8em; width: 2.2em; height: 2.2em; border-radius: 50%; display: grid; place-items: center; }
.dbadge svg { width: 1.3em; height: 1.3em; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.dbadge svg.f { fill: #fff; stroke-width: 1.6; }
.dbadge.keep { background: var(--keep); } .dbadge.mark { background: var(--marked); } .dbadge.fav { background: var(--sky); }
.chip { display: block; width: max-content; margin: .6em auto 0; padding: .25em .8em; border-radius: 999px; background: var(--piece); border: 2px solid var(--piece-edge); color: var(--text); font: 700 1.1em/1.2 var(--font); white-space: nowrap; }
.chip.keep { border-color: var(--keep); } .chip.mark { border-color: var(--marked); } .chip.fav { border-color: var(--sky); }
.chip.left { margin-left: 0; }
.chip.right { margin-left: auto; margin-right: 0; }

/* ---------- Beat 8: the privacy screen zoomed on its top card, the rest faded out ---------- */
.zoomwrap { position: absolute; inset: 0; overflow: hidden; }
.phone .screen .zoomwrap picture { display: block; transform: scale(1.06); transform-origin: 50% 22%; }
.zfade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(3,8,19,0) 31%, #030813 38%); }
.js .phone .screen .zoomwrap { opacity: 0; }
.js .phone .screen .zoomwrap picture { opacity: 1; transform: none; }
.js .zfade { opacity: 0; }

/* ---------- Streak card (beat 9): the app's pill, bigger. Flame, count, then the Max look ---------- */
.pop-streak-wrap, .pop:has(.card.streak) .pop-i { display: flex; justify-content: center; }
.card.streak { position: relative; width: fit-content; text-align: left; padding: 1.1em 1.5em 1.2em; }
.gold-edge {
  position: absolute; inset: -2px; border-radius: 2.2em; padding: 2px; opacity: 0; pointer-events: none;
  background: linear-gradient(135deg, #FFD84A, #FFFBE0 50%, #FFD84A);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.srow { display: flex; align-items: center; gap: .5em; }
.flames { position: relative; width: 3.2em; height: 3.2em; flex: none; margin: 0 .2em 0 .2em; }
.flames .flame { position: absolute; inset: 0; width: 100%; height: 100%; }
.flames .flame.gold { opacity: 0; }
.flames .aura { position: absolute; left: 50%; top: 50%; width: 7.6em; height: 7.6em; margin: -3.8em 0 0 -3.8em; max-width: none; opacity: 0; pointer-events: none; }
.card.streak .big { font-size: 3em; color: var(--text); }
.maxcap { display: none; position: relative; align-items: center; padding: .28em .8em; border-radius: 999px; background: linear-gradient(90deg, #FFFBE0, #FFD84A, #FFFBE0); color: #1F1600; font: 800 1.35em/1.1 var(--font); letter-spacing: -.01em; }
.maxcap .sp { position: absolute; right: -.45em; top: -.6em; width: .95em; height: .95em; }
.js .maxcap { display: inline-flex; opacity: 0; }
.spk { position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px; background: #FFFBE0; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%); opacity: 0; }
.caps { display: grid; margin-top: .4em; }
.caps > div { grid-area: 1 / 1; }
.caps .cb { opacity: 0; align-self: center; }
.card.streak .caps .cap { color: var(--text-2); font-size: 1.2em; }
.card.streak .cap2 { font-size: 1.1em; color: var(--text-2); margin-top: .35em; line-height: 1.3; }

@media (min-width: 900px) { .js .copy { gap: 16px; margin-bottom: 0; } }

/* beat 1: a longer headline, so it is a little smaller (each line stays on one line at 360 px) */
/* Beat 1: same size as every headline; on a phone the question breaks after "cluttered" (owner: title too small) */
.beat h1 br.m { display: none; }
@media (max-width: 899px) { .beat h1 br.m { display: inline; } }

/* Scroll hint: a soft blinking arrow at the bottom of the first screen only; gone once the page scrolls (owner) */
.scroll-hint { position: fixed; left: 50%; bottom: max(4px, env(safe-area-inset-bottom)); z-index: 40; width: 28px; height: 20px; margin-left: -14px; pointer-events: none; transition: opacity .3s ease; }
.scroll-hint svg { width: 28px; height: 20px; fill: none; stroke: var(--text-2); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; animation: hint-blink 1.8s ease-in-out infinite; }
@keyframes hint-blink { 0%, 100% { opacity: .35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(4px); } }
html.scrolled .scroll-hint { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .scroll-hint svg { animation: none; opacity: .7; } }
