
:root { --accent: #1a5a4a; --accent-ink: #14483c; --accent-soft: #e9f1ed; --accent-line: #cfe0d8; --cream: #f2efe9; --paper: #faf8f4; --ink: #17120e; --text: #1c1d1f; --body: #3a3d40; --muted: #6b7075; --line: #d9d3c8; --rail: #cfc8bc; --line-dark: rgba(242,239,233,0.18); --frame: max(16px, 4.4vw); --gutter: calc(var(--frame) + 48px); --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif; --mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { background: var(--cream); color: var(--text); font-family: var(--sans); font-size: 17px; line-height: 1.55; -webkit-font-smoothing: antialiased; }
img { max-width: 100%; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Nav: one dark strip that stays put. Its negative bottom margin lets the hero run
   underneath it, so the first viewport is the whole hero and not the hero minus a bar. */
.bar { position: sticky; top: 0; z-index: 20; margin-bottom: -64px; background: rgba(23,18,14,0.88); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); color: #fff; border-bottom: 1px solid rgba(242,239,233,0.12); }
.bar-in { padding: 0 var(--frame); height: 64px; display: flex; align-items: center; gap: 40px; flex-wrap: nowrap; min-width: 0; }
.wordmark { font-weight: 800; font-size: 19px; color: #fff; text-decoration: none; letter-spacing: -0.01em; }
.wordmark b { color: #6fb39b; }
.bar-nav { display: flex; gap: 28px; align-items: center; }
.bar-nav a { color: #d8d4cd; text-decoration: none; font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.14em; text-transform: uppercase; padding: 10px 0; }
.bar-nav a:hover { color: #fff; }
.bar-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex: none; }
.bar-login { flex: none; display: inline-flex; align-items: center; min-height: 40px; padding: 8px 14px; border: 1px solid rgba(242,239,233,0.42); color: #e4e0d8; text-decoration: none; font-weight: 600; font-size: 14px; border-radius: 4px; white-space: nowrap; }
.bar-login:hover { border-color: #fff; color: #fff; }
.bar-cta { flex: none; display: inline-flex; align-items: center; min-height: 40px; padding: 8px 16px; background: var(--accent); color: #fff; text-decoration: none; font-weight: 700; font-size: 14.5px; border-radius: 4px; }
.bar-cta:hover { background: #237560; }

/* The frame: two rails down the page, a divider between sections. Content sits inside. */
.page { position: relative; }
.page::before, .page::after { content: ""; position: absolute; top: 0; bottom: 0; width: 1px; background: var(--rail); z-index: 2; pointer-events: none; }
.page::before { left: var(--frame); }
.page::after { right: var(--frame); }
.in { padding: 0 var(--gutter); }
.sec { position: relative; padding: 96px 0; background: var(--cream); scroll-margin-top: 64px; }
.sec.paper { background: var(--paper); }
.sec.dark { background: var(--ink); color: var(--cream); }
.sec::before { content: ""; position: absolute; top: 0; left: var(--frame); right: var(--frame); height: 1px; background: var(--line); }
.sec.dark::before { background: var(--line-dark); }
.eb { font-family: var(--mono); font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin-bottom: 22px; }
.dark .eb { color: #9a948a; }
.head { margin-bottom: 52px; }
.head h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(34px, 3.9vw, 54px); line-height: 1.06; letter-spacing: -0.012em; max-width: 16ch; }
.head p { font-size: 17.5px; color: var(--body); max-width: 58ch; margin-top: 18px; }
.dark .head p { color: #cfc9bf; }
.lab { font-family: var(--mono); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: 9px; }
.lab::before { content: ""; width: 7px; height: 7px; background: var(--accent); flex: none; }
.dark .lab { color: #9a948a; }
.dark .lab::before { background: var(--cream); }

/* Hero: a full-bleed halftone of a shop, the claim, and one caption per scene. */
.hero { position: relative; background: var(--ink); color: var(--cream); }
.hero-stick { position: relative; height: 100vh; height: 100svh; min-height: 640px; overflow: hidden; }
.scene { position: absolute; inset: 0; }
.scene img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; opacity: 0.62; }
.shade { position: absolute; inset: 0; background: linear-gradient(90deg, rgba(23,18,14,0.88) 0%, rgba(23,18,14,0.55) 48%, rgba(23,18,14,0.18) 100%), linear-gradient(0deg, rgba(23,18,14,0.92) 0%, rgba(23,18,14,0) 42%); }
.hero-in { position: relative; z-index: 1; height: 100%; display: grid; grid-template-rows: 1fr auto; padding: 106px var(--gutter) 54px; }
.pill { display: inline-flex; align-items: center; gap: 9px; padding: 8px 16px 8px 13px; border: 1px solid rgba(242,239,233,0.34); border-radius: 999px; font-size: 13.5px; font-weight: 600; color: #e4e0d8; margin-bottom: 26px; }
.pill svg { flex: none; opacity: 0.9; }
.hero h1 { font-weight: 500; font-size: clamp(38px, 4.6vw, 60px); line-height: 1.05; letter-spacing: -0.022em; max-width: 15ch; color: #fff; }
.hero-sub { margin-top: 22px; font-size: 18px; line-height: 1.5; max-width: 50ch; color: #e4e0d8; }
.cta-row { margin-top: 26px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.btn { display: inline-flex; align-items: center; min-height: 50px; padding: 12px 22px; background: var(--accent); color: #fff; text-decoration: none; font-weight: 700; font-size: 16px; border-radius: 4px; }
.btn:hover { background: #237560; }
.btn-ghost { display: inline-flex; align-items: center; min-height: 50px; padding: 12px 20px; border: 1px solid rgba(242,239,233,0.5); color: #fff; text-decoration: none; font-weight: 600; font-size: 15.5px; border-radius: 4px; }
.btn-ghost:hover { border-color: #fff; }
.hero-foot { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-top: 30px; }
.cta-note { font-size: 13.5px; color: #b9b4ac; max-width: 38ch; }
.hero-cap { width: 320px; border-top: 1px solid rgba(242,239,233,0.5); padding-top: 12px; }
.hero-cap span { display: block; font-size: 15px; color: #e4e0d8; }

/* How it works: three columns split by hairlines, each led by a product surface. */
.cols { display: grid; grid-template-columns: repeat(3, 1fr); }
.cols-4 { grid-template-columns: repeat(4, 1fr); }
.cols-4 .col { padding: 0 22px 4px; }
.cols-4 .fig { height: 300px; }
.cols-4 .col h3 { font-size: 19px; }
.cols-4 .col p { font-size: 15px; }
.col { padding: 0 36px 4px; border-left: 1px solid var(--line); }
.col:first-child { padding-left: 0; border-left: 0; }
.col:last-child { padding-right: 0; }
/* A figure box of one height per section, with the artifact centered in it, so a printed
   tent, a phone and a tablet can share a row and the headings under them still line up.
   Every frame carries its image's own aspect ratio and the image fills it with cover, so
   a frame can never stretch what is inside it, and max-width means a narrow screen
   shrinks the whole frame rather than squashing it. */
.fig { height: 400px; display: flex; align-items: center; justify-content: center; margin: 28px 0 26px; }
.fr-phone, .fr-tablet, .fr-tent, .fr-photo { position: relative; box-sizing: content-box; height: 94%; max-width: 92%; overflow: hidden; }
.fr-phone img, .fr-tablet img, .fr-tent img, .fr-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fr-phone { aspect-ratio: 420 / 956; border: 5px solid #2a2622; border-radius: 30px; background: #0d0b09; box-shadow: 0 16px 34px rgba(23,18,14,0.16); }
.fr-phone::before { content: ""; position: absolute; top: 9px; left: 50%; width: 44px; height: 12px; transform: translateX(-50%); background: #050403; border-radius: 7px; z-index: 2; }
.fr-tablet { height: 80%; aspect-ratio: 520 / 744; border: 7px solid #2a2622; border-radius: 16px; background: #0d0b09; box-shadow: 0 16px 34px rgba(23,18,14,0.16); }
.fr-tent { height: 72%; aspect-ratio: 480 / 640; border: 1px solid var(--line); box-shadow: 0 14px 30px rgba(23,18,14,0.14); }
.fr-photo { height: 62%; aspect-ratio: 1600 / 1200; border: 10px solid var(--cream); outline: 1px solid var(--line); }
.col h3 { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 8px; }
.col p { font-size: 16px; color: var(--body); }

/* The card. */
.card-row { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.card-copy h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(34px, 3.9vw, 54px); line-height: 1.06; letter-spacing: -0.012em; }
.card-copy .lede { margin-top: 18px; font-size: 19px; color: var(--text); max-width: 34ch; }
.card-copy .body { font-size: 16.5px; color: var(--body); margin-top: 14px; max-width: 48ch; }
.punch { background: #fff; border: 1px solid var(--line); padding: 26px 26px 20px; }
.punch-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; }
.pc { position: relative; display: block; aspect-ratio: 1; border-radius: 999px; border: 1.5px solid var(--accent-line); background: #fff; overflow: hidden; }
.pc .disc { position: absolute; inset: -1px; border-radius: 999px; background: var(--accent-soft); opacity: 0; transform: scale(0.4); }
.pc img { position: absolute; left: 50%; top: 50%; width: 44%; height: auto; transform: translate(-50%, -50%); }
.pc .pc-f { opacity: 0; }
.pc.on .disc { opacity: 1; transform: none; }
.pc.on .pc-f { opacity: 1; }
.pc.on .pc-e { opacity: 0; }
.pc.on { border-color: var(--accent); }
.punch-foot { display: flex; justify-content: space-between; align-items: baseline; margin-top: 18px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.punch-n { position: relative; height: 1.5em; width: 9ch; color: var(--accent-ink); font-size: 15px; letter-spacing: 0.04em; }
.punch-n span { position: absolute; left: 0; top: 0; opacity: 0; white-space: nowrap; }
.punch-n span:first-child { opacity: 1; }


/* The system, by the numbers: a grid of settings, split by hairlines. */

/* THE CLIENT SIGN-IN PAGE. It lives on the app host (owner.ts) because this site has no
   forms, but it is styled from THIS stylesheet so it is on brand by construction rather
   than by somebody copying hex values into a second place and letting them drift. Same
   tokens, same serif, same halftone as the hero. */
.portal { min-height: 100vh; min-height: 100svh; display: grid; place-items: center; padding: 96px var(--frame) 64px; position: relative; background: var(--ink); }
.portal-bg { position: absolute; inset: 0; overflow: hidden; }
.portal-bg img { width: 100%; height: 100%; object-fit: cover; opacity: 0.5; display: block; }
.portal-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(0deg, rgba(23,18,14,0.94) 0%, rgba(23,18,14,0.72) 100%); }
.portal-card { position: relative; z-index: 1; width: 100%; max-width: 452px; background: var(--paper); border: 1px solid var(--line); padding: 40px 36px 34px; }
.portal-mark { font-weight: 800; font-size: 19px; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 26px; }
.portal-mark b { color: var(--accent); }
.portal-card h1 { font-family: var(--serif); font-weight: 400; font-size: 34px; line-height: 1.1; letter-spacing: -0.012em; color: var(--text); }
.portal-lede { font-size: 16.5px; color: var(--body); margin-top: 14px; }
.portal-field { margin-top: 26px; }
.portal-field label { display: block; font-family: var(--mono); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-bottom: 9px; }
.portal-field input { width: 100%; min-height: 50px; padding: 12px 14px; font-size: 16px; font-family: var(--sans); color: var(--text); background: #fff; border: 1px solid var(--rail); border-radius: 4px; }
.portal-field input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-color: var(--accent); }
.portal-btn { display: inline-flex; align-items: center; justify-content: center; width: 100%; min-height: 50px; margin-top: 20px; padding: 12px 22px; background: var(--accent); color: #fff; border: 0; font-family: var(--sans); font-weight: 700; font-size: 16px; border-radius: 4px; cursor: pointer; }
.portal-btn:hover { background: #237560; }
.portal-fine { font-size: 14px; color: var(--muted); margin-top: 18px; }
.portal-err { margin-top: 18px; padding: 12px 14px; border-left: 3px solid var(--accent); background: var(--accent-soft); color: var(--accent-ink); font-size: 15px; }
.portal-turnstile { margin-top: 20px; }
.portal-back { display: inline-block; margin-top: 22px; font-size: 14.5px; color: var(--muted); }
@media (max-width: 480px) { .portal { padding: 72px 16px 48px; } .portal-card { padding: 30px 22px 26px; } .portal-card h1 { font-size: 29px; } }

/* Pricing. Two plans, one service, so both cards carry the SAME list of what is
   included: side by side that is the argument, since the only thing that differs is how
   you pay. The yearly card inverts to pine the way a highlighted plan usually does.
   The cards stretch to one height (no align-items) so the two never read as unequal
   offers, and each carries a note line in the same slot so their tick lists start on the
   same baseline: the monthly says what a year costs at that rate, the yearly strikes the
   same figure through. That figure is twelve times the published monthly price, so the
   struck comparison is a price we really charge, never an invented "was". */
.head-c { text-align: center; }
.head-c h2 { max-width: 20ch; margin: 0 auto; }
.head-c p { margin-left: auto; margin-right: auto; }
.plans { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; max-width: 940px; margin: 0 auto; }
.plan { position: relative; background: #fff; border: 1px solid var(--line); padding: 34px 32px 32px; display: flex; flex-direction: column; }
/* min-height is the height of the tag chip: without it the card that carries one sits
   six pixels lower than the card that does not, all the way down to the tick list. */
.plan h3 { display: flex; align-items: center; gap: 12px; min-height: 26px; font-family: var(--mono); font-weight: 400; font-size: 12.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.plan-when { font-size: 14.5px; color: var(--muted); margin-top: 10px; }
.plan .amt { font-size: 52px; font-weight: 400; letter-spacing: -0.025em; line-height: 1; margin-top: 12px; }
.plan .amt span { font-size: 15px; color: var(--muted); letter-spacing: 0; }
.plan .tag { margin-left: auto; background: var(--cream); color: var(--accent-ink); font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; padding: 4px 9px; border-radius: 3px; }
.plan-note { font-size: 14.5px; color: var(--muted); margin-top: 13px; }
.plan-note s { text-decoration-thickness: 1.5px; text-underline-offset: 2px; margin-right: 7px; }
.ticks { list-style: none; margin: 26px 0 30px; border-top: 1px solid var(--line); padding-top: 22px; }
.ticks li { position: relative; padding: 8px 0 8px 30px; font-size: 15.5px; color: var(--body); }
.ticks li::before { content: ""; position: absolute; left: 0; top: 13px; width: 15px; height: 15px; border: 1.5px solid var(--accent); }
.ticks li::after { content: ""; position: absolute; left: 4px; top: 17px; width: 7px; height: 4px; border-left: 2px solid var(--accent-ink); border-bottom: 2px solid var(--accent-ink); transform: rotate(-45deg); }
.plan-cta { margin-top: auto; justify-content: center; }
.plan-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.plan-on h3, .plan-on .plan-when, .plan-on .amt span, .plan-on .plan-note { color: rgba(242,239,233,0.78); }
.plan-on .amt, .plan-on .ticks li { color: #fff; }
.plan-on .ticks { border-top-color: rgba(242,239,233,0.28); }
.plan-on .ticks li::before { border-color: rgba(242,239,233,0.7); }
.plan-on .ticks li::after { border-left-color: #fff; border-bottom-color: #fff; }
.plan-on .tag { background: var(--cream); color: var(--accent-ink); }
.plan-on .plan-cta { background: var(--cream); color: var(--accent-ink); }
.plan-on .plan-cta:hover { background: #fff; }

/* The guarantee sits under both prices, because it applies to both. */
/* Straight answers. */

/* The closing band. */
.band { background: var(--accent); color: #fff; }
.band::before { display: none; }
.band-in { display: grid; grid-template-columns: 1.2fr auto; gap: 40px; align-items: center; }
.band h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(34px, 4vw, 56px); line-height: 1.06; letter-spacing: -0.012em; max-width: 18ch; }
.band p { margin-top: 16px; font-size: 18px; color: #dcebe4; max-width: 46ch; }
.btn-cream { display: inline-flex; align-items: center; min-height: 54px; padding: 14px 26px; background: var(--cream); color: var(--accent-ink); text-decoration: none; font-weight: 700; font-size: 16.5px; border-radius: 4px; }
.btn-cream:hover { background: #fff; }

/* Footer. */
footer { background: var(--ink); color: #b9b4ac; }
.foot-in { padding: 64px var(--frame) 28px; display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px; }
.foot-in p { font-size: 15px; max-width: 42ch; margin-top: 14px; }
.foot-in h4 { font-family: var(--mono); font-weight: 400; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: #9a948a; margin-bottom: 16px; }
.foot-in ul { list-style: none; }
.foot-in li { margin: 0 0 12px; }
.foot-in a { color: #e4e0d8; text-decoration: none; font-size: 16px; }
.foot-in a:hover { color: #fff; }
.foot-bottom { padding: 22px var(--frame) 30px; border-top: 1px solid rgba(242,239,233,0.14); margin: 0; display: flex; flex-wrap: wrap; gap: 10px 26px; font-size: 14px; }
.foot-bottom span:first-child { margin-right: auto; }
.foot-bottom a { color: #d8d4cd; text-decoration: none; }

/* Privacy and terms. */
.doc { max-width: 760px; margin: 0 auto; padding: 120px 24px 80px; }
.doc h1 { font-family: var(--serif); font-weight: 400; font-size: 40px; letter-spacing: -0.015em; margin-bottom: 6px; }
.doc .updated { color: var(--muted); font-size: 14.5px; margin-bottom: 26px; }
.doc h2 { font-size: 21px; margin: 28px 0 8px; }
/* The global reset zeroes every margin, so consecutive paragraphs ran together into one
   block. That was survivable on privacy and terms, where an h2 breaks up nearly every
   pair, and it is not on a long-form guide where four paragraphs sit under one heading. */
.doc p { font-size: 16.5px; color: #2a2c2e; margin: 0 0 14px; }
.doc li { font-size: 16.5px; color: #2a2c2e; }
.doc p:last-child { margin-bottom: 0; }
/* The guide FAQ reuses the home page's native details/summary: no script, and a reader who
   wants one answer does not have to scroll past the other three. */
.doc .qa { border-top: 1px solid var(--line); padding: 14px 0; }
.doc .qa summary { font-weight: 700; font-size: 16.5px; cursor: pointer; list-style: none; }
.doc .qa summary::-webkit-details-marker { display: none; }
.doc .qa summary::after { content: "+"; float: right; color: var(--muted); font-weight: 400; }
.doc .qa[open] summary::after { content: "-"; }
.doc .qa p { margin: 10px 0 0; color: var(--body); }
.doc ul { padding-left: 22px; margin: 8px 0; }
.doc li { margin: 5px 0; }
.doc a { color: var(--accent-ink); }
.draftnote { margin-top: 34px; padding: 12px 16px; border: 1px dashed #c9c2b6; color: var(--muted); font-size: 13.5px; }

/* The pass in a wallet, drawn in CSS. The phone carries a real device's proportions
   (1206 x 2622, an iPhone panel) and the same frame as the inbox phone, so the two read
   as one device. The stamps, the count and the countdown are live elements rather than
   baked art, because they animate: see the pass loop inside the motion gate. */
.hero-grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 40px; align-items: center; height: 100%; }
.phone-wrap { position: relative; justify-self: center; width: 300px; }
.phone { position: relative; width: 300px; aspect-ratio: 1206 / 2622; border-radius: 48px; background: linear-gradient(180deg, #17120e 0%, #0d0b09 46%); border: 6px solid #2a2622; box-shadow: 0 30px 60px rgba(0,0,0,0.55), inset 0 0 0 2px #050403; padding: 46px 12px 0; overflow: hidden; }
.phone::before { content: ""; position: absolute; top: 14px; left: 50%; width: 92px; height: 26px; transform: translateX(-50%); background: #050403; border-radius: 14px; z-index: 2; }
.pass { background: var(--accent); border-radius: 14px; overflow: hidden; color: #fff; padding-bottom: 78px; }
.pass-head { display: flex; align-items: flex-start; gap: 9px; padding: 12px 13px 10px; }
.pass-head img { width: 24px; height: 26px; flex: none; }
.pass-head > b { font-size: 13.5px; font-weight: 700; letter-spacing: 0.01em; padding-top: 4px; }
.pass-count { margin-left: auto; text-align: right; }
.pass-count small, .pass-fields small { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(242,239,233,0.72); }
.pass-count b { display: block; position: relative; height: 1.25em; font-size: 15px; font-weight: 600; margin-top: 3px; }
.pass-count b span { position: absolute; right: 0; top: 0; opacity: 0; }
.pass-count b span:first-child { opacity: 1; }
/* The strip: the shop's own photo with twelve cells over it, which is what the real
   pass strip is. Drawn rather than baked so the cells can fill. */
.pass-strip { position: relative; aspect-ratio: 1000 / 380; overflow: hidden; background: #143f34; }
.pass-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.42; }
.pass-cells { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(2, 1fr); gap: 3px; padding: 9px 11px; }
.ps { position: relative; display: flex; align-items: center; justify-content: center; }
.ps::before { content: ""; position: absolute; left: 50%; top: 50%; width: 78%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 999px; border: 1px solid rgba(242,239,233,0.5); }
.ps-cup { position: relative; width: 42%; height: auto; opacity: 0.5; }
.ps-on { position: absolute; left: 50%; top: 50%; width: 78%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 999px; background: var(--cream); display: flex; align-items: center; justify-content: center; opacity: 0; }
.ps-on .ps-cup { opacity: 1; width: 54%; }
.ps.on .ps-on { opacity: 1; }
.pass-fields { display: flex; justify-content: space-between; align-items: flex-start; padding: 13px 13px 0; }
.pass-fields b { display: block; position: relative; font-size: 15px; font-weight: 600; color: #fff; margin-top: 3px; }
.pass-fields div:last-child { text-align: right; }
.pass-away { height: 1.25em; }
.pass-away span { position: absolute; right: 0; top: 0; white-space: nowrap; opacity: 0; }
.pass-away span:first-child { opacity: 1; }
.chip { position: absolute; display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: rgba(23,18,14,0.92); border: 1px solid rgba(242,239,233,0.18); border-radius: 8px; color: #fff; font-size: 13.5px; white-space: nowrap; box-shadow: 0 12px 30px rgba(0,0,0,0.4); }
.chip i { width: 22px; height: 22px; border-radius: 999px; background: var(--accent); display: inline-flex; align-items: center; justify-content: center; font-style: normal; font-size: 12px; }
.chip small { display: block; font-size: 12px; color: #b9b4ac; }
.chip-a { left: -118px; top: 104px; }
.chip-b { right: -104px; top: 292px; }

/* The inbox: the emails the system actually sends, as they land. */
.inbox { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.inbox .head { display: block; margin-bottom: 22px; }
.inbox .head h2 { max-width: 13ch; }
.inbox .hero-sub { margin-top: 0; }
.tick { list-style: none; margin-top: 28px; }
.tick li { position: relative; padding: 10px 0 10px 36px; font-size: 17px; color: #e4e0d8; border-top: 1px solid var(--line-dark); }
.tick li:last-child { border-bottom: 1px solid var(--line-dark); }
.tick li::before { content: ""; position: absolute; left: 0; top: 14px; width: 20px; height: 20px; border-radius: 999px; border: 1.5px solid rgba(242,239,233,0.5); }
.tick li::after { content: ""; position: absolute; left: 6px; top: 19px; width: 8px; height: 5px; border-left: 2px solid var(--cream); border-bottom: 2px solid var(--cream); transform: rotate(-45deg); }
.lock { position: relative; justify-self: center; width: 350px; min-height: 762px; border-radius: 54px; border: 6px solid #2a2622; background: linear-gradient(160deg, #1d3a32 0%, #17120e 55%, #0d0b09 100%); box-shadow: 0 30px 60px rgba(0,0,0,0.55); padding: 44px 12px 28px; color: #fff; }
.lock::before { content: ""; position: absolute; top: 14px; left: 50%; width: 96px; height: 24px; transform: translateX(-50%); background: #050403; border-radius: 14px; }
.lock-time { text-align: center; padding: 18px 0 26px; }
.lock-time small { display: block; font-size: 13px; color: #cfc9bf; }
.lock-time b { display: block; font-size: 74px; font-weight: 250; letter-spacing: -0.03em; line-height: 1; margin-top: 4px; }
.note { display: grid; grid-template-columns: 34px 1fr; gap: 10px; padding: 11px 12px; background: rgba(242,239,233,0.14); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-radius: 14px; margin-top: 8px; }
/* The notification icon is a square tile with the shop's mark inside it. The mark is not
   square, so it needs contain: a bare 34 by 34 box was squashing it by a ninth. */
.note img { width: 34px; height: 34px; object-fit: contain; border-radius: 8px; background: var(--accent); padding: 4px; }
.note b { display: flex; justify-content: space-between; font-size: 13px; font-weight: 600; }
.note b small { font-weight: 400; color: #cfc9bf; font-size: 11.5px; }
.note p { font-size: 12.5px; line-height: 1.35; color: #f2efe9; margin-top: 2px; }

/* The step accordion: five steps, one open at a time, the rest folded into tabs. Pure
   CSS: radios carry the state, labels switch it, nothing runs. */
/* The radios that drive the accordion are hidden, but a label click still FOCUSES its
   radio, and a browser scrolls a focused element into view. Positioned absolute these sat
   at the top of the section, so opening a step threw the page up to three thousand pixels
   away. Fixed positioning is the fix: an element pinned to the viewport is already in
   view, so there is nothing to scroll to. Nothing here transforms .acc or its ancestors,
   so the containing block really is the viewport. */

.acc-row { display: flex; gap: 14px; min-height: 540px; }
.st { position: relative; flex: 0 0 68px; border: 1px solid var(--line); background: #fff; overflow: hidden; display: flex; }
.st-tab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 26px 0; cursor: pointer; color: var(--muted); text-decoration: none; }
.st-tab:hover { color: var(--text); background: var(--cream); }
.st-tab .st-lab { writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--mono); font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; }
.st-tab .st-n { font-family: var(--serif); font-size: 20px; }
.st-body { display: none; flex: 1; grid-template-columns: 1.05fr 0.95fr; gap: 40px; padding: 36px 40px; align-items: center; }
.st-body h3 { font-family: var(--serif); font-weight: 400; font-size: clamp(28px, 2.8vw, 40px); line-height: 1.1; letter-spacing: -0.01em; margin: 14px 0 16px; }
.st-body p { font-size: 16.5px; color: var(--body); max-width: 48ch; }
.st-body .fig { height: 380px; margin: 0; }

/* WHICH STEP IS OPEN is the URL's job, not a hidden input's. Each step is a real in-page
   link to itself, so a click does two things at once with no script: the browser scrolls
   that step into view (which is the whole point, the reader asked to be taken to what they
   opened) and :target opens it. scroll-margin-top is what stops the sticky nav landing on
   top of the heading. The previous radio version could not scroll a reader anywhere on
   purpose, and its one accidental scroll (focus moving to a hidden input) was the bug that
   started all of this. */
.st { scroll-margin-top: 76px; }
.st:target { flex: 1 1 auto; }
.st:target .st-tab { display: none; }
.st:target .st-body { display: grid; }
/* Nothing targeted yet, so the first step is the one that is open. */
.acc-row:not(:has(.st:target)) .st:first-child { flex: 1 1 auto; }
.acc-row:not(:has(.st:target)) .st:first-child .st-tab { display: none; }
.acc-row:not(:has(.st:target)) .st:first-child .st-body { display: grid; }

.facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; margin-top: 44px; }
.fact b { display: block; font-size: 30px; font-weight: 400; letter-spacing: -0.02em; color: var(--accent-ink); }
.fact span { display: block; margin-top: 10px; font-size: 15px; color: var(--body); }

/* The guarantee sits between the two prices and the included list, because it applies to
   both and is the actual promise being bought. */
.promise { margin-top: 40px; padding: 26px 30px; background: var(--accent-soft); border-left: 3px solid var(--accent); }
.promise p:last-child { font-size: 16.5px; color: var(--body); max-width: 76ch; margin-top: 10px; }

/* Answers open one at a time. Native details, so no script and no state to manage. */
.qas { border-top: 1px solid var(--line); }
.qa { border-bottom: 1px solid var(--line); }
.qa summary { list-style: none; cursor: pointer; padding: 22px 44px 22px 0; position: relative; font-family: var(--serif); font-size: 23px; line-height: 1.25; letter-spacing: -0.01em; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: ""; position: absolute; right: 8px; top: 50%; width: 13px; height: 13px; margin-top: -9px; border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent); transform: rotate(45deg); transition: transform 0.2s ease; }
.qa[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.qa summary:hover { color: var(--accent-ink); }
.qa summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.qa > p, .qa > ul { font-size: 16.5px; color: var(--body); max-width: 74ch; padding-bottom: 24px; }
.qa > ul { list-style: none; }
.qa > ul li { padding: 4px 0 4px 18px; position: relative; }
.qa > ul li::before { content: ""; position: absolute; left: 0; top: 14px; width: 8px; height: 2px; background: var(--accent); }
.head h2 em, .band h2 em { font-style: italic; color: var(--muted); }
.band h2 em { color: #bfe0d2; }

@media (max-height: 800px) {
  .phone-wrap, .phone { width: 268px; }
  .chip-a { top: 92px; left: -110px; }
  .chip-b { top: 258px; right: -96px; }
}
@media (max-height: 720px) {
  .phone-wrap, .phone { width: 232px; }
  .chip-a { top: 78px; }
  .chip-b { top: 224px; }
}

@media (max-width: 960px) {
  .card-row, .band-in, .inbox { grid-template-columns: 1fr; }
      .hero-grid { grid-template-columns: 1fr; }
  .phone-wrap { display: none; }
  .st-body { grid-template-columns: 1fr; }
  .cols, .cols-4 { grid-template-columns: 1fr; }
  .cols-4 .col { padding: 32px 0 0; }
  .col { padding: 32px 0 0; border-left: 0; border-top: 1px solid var(--line); margin-top: 32px; }
  .col:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
    .foot-in { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  :root { --gutter: calc(var(--frame) + 20px); }
  .facts { grid-template-columns: 1fr 1fr; gap: 22px; }
      .promise { padding: 20px 18px; }
  .qa summary { font-size: 20px; padding-right: 36px; }
  .bar { margin-bottom: -58px; }
  .doc { padding-top: 104px; }
  .bar-in { height: 58px; gap: 20px; }
  .bar-cta { white-space: nowrap; padding: 8px 11px; font-size: 13px; }
  .bar-actions { gap: 6px; }
  .bar-login { padding: 8px 10px; font-size: 13px; }
  .bar-in { gap: 12px; }
  .bar-nav a.hide-sm { display: none; }
  .bar-nav { display: none; }
  .sec { padding: 64px 0; }
  .fig { height: 320px; }
  .st-body .fig { height: 296px; }
  .hero-stick { min-height: 560px; }
  .hero-in { padding-top: 104px; padding-bottom: 44px; }
  .hero h1 { font-size: 38px; }
  .hero-sub { font-size: 17px; }
  .hero-foot { flex-direction: column; align-items: stretch; }
  .hero-cap { width: 100%; }
  .head { margin-bottom: 40px; }
  .punch { padding: 18px 18px 16px; }
  .punch-grid { gap: 9px; }
  /* On a phone the accordion stacks: each step is its own row, and the open one shows its
     panel directly under its own number. That layout only works because the number is a
     link to itself, so a tap TAKES the reader to the panel it just opened rather than
     leaving them to find it. Without that, closing the step above drags the tapped step up
     the screen, which is what made every earlier version of this annoying. */
  .acc-row { flex-direction: column; min-height: 0; }
  .st { flex: 0 0 auto; flex-direction: column; scroll-margin-top: 66px; }
  .st-tab { flex-direction: row; padding: 15px 16px; }
  .st-tab .st-lab { writing-mode: horizontal-tb; transform: none; }
  .st-body { padding: 22px 18px 24px; gap: 22px; }
          .plans { grid-template-columns: 1fr; }
  .foot-in { grid-template-columns: 1fr; gap: 28px; padding-top: 48px; }
}

/* MOTION. Everything from here down is scroll-driven animation and is gated twice: the
   browser has to support scroll-driven animations, scoped timelines and offset paths (all
   three, because a browser with two of them would render a half-built scene), and the
   visitor must not have asked for reduced motion. Outside the gate none of it applies and
   the page is the static site above: the first hero scene, every section fully lit, the
   card at 2 of 12. Nothing in here is a script, a request, or a header. */
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) and (offset-path: inset(0)) and (timeline-scope: --x) {
  /* Ambient motion, time-based rather than scroll-based: the event chips breathe and the
     phone floats, slow and out of phase, the way Regulars' hero feels alive. Inside the
     reduced-motion gate like every other animation on the page. The hero itself is a
     STATIC halftone by decision (2026-08-30): the drift was built, seen live, and cut. */
  .phone-wrap { animation: float 9s ease-in-out infinite alternate; }
  /* The pass fills itself on a slow loop: ten stamps land one at a time, the stamp count
     climbs, the reward countdown falls, then the card clears back to its head start and
     runs again. Time-based, not scroll-based, because the hero never scrolls. All three
     are generated from one set of numbers, so the cells, the count and the countdown can
     never disagree about how full the card is. */
  .ps .ps-on, .pass-count b span, .pass-away span { animation-duration: 24s; animation-timing-function: linear; animation-iteration-count: infinite; }
  @keyframes ps-3 { 0%, 9% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 11%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(3) .ps-on { animation-name: ps-3; }
  @keyframes ps-4 { 0%, 15.6% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 17.6%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(4) .ps-on { animation-name: ps-4; }
  @keyframes ps-5 { 0%, 22.2% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 24.2%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(5) .ps-on { animation-name: ps-5; }
  @keyframes ps-6 { 0%, 28.8% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 30.8%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(6) .ps-on { animation-name: ps-6; }
  @keyframes ps-7 { 0%, 35.4% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 37.4%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(7) .ps-on { animation-name: ps-7; }
  @keyframes ps-8 { 0%, 42% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 44%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(8) .ps-on { animation-name: ps-8; }
  @keyframes ps-9 { 0%, 48.6% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 50.6%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(9) .ps-on { animation-name: ps-9; }
  @keyframes ps-10 { 0%, 55.2% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 57.2%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(10) .ps-on { animation-name: ps-10; }
  @keyframes ps-11 { 0%, 61.8% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 63.8%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(11) .ps-on { animation-name: ps-11; }
  @keyframes ps-12 { 0%, 68.4% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } 70.4%, 92% { opacity: 1; transform: translate(-50%, -50%); } 92.5%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(0.55); } }
  .ps:nth-child(12) .ps-on { animation-name: ps-12; }
  @keyframes pn-2 { 0%, 11% { opacity: 1; } 11.5%, 92% { opacity: 0; } 92.5%, 100% { opacity: 1; } }
  .pass-count b span:nth-child(1), .pass-away span:nth-child(1) { animation-name: pn-2; }
  @keyframes pn-3 { 0%, 11% { opacity: 0; } 11.5%, 17.6% { opacity: 1; } 18.1%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(2), .pass-away span:nth-child(2) { animation-name: pn-3; }
  @keyframes pn-4 { 0%, 17.6% { opacity: 0; } 18.1%, 24.2% { opacity: 1; } 24.7%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(3), .pass-away span:nth-child(3) { animation-name: pn-4; }
  @keyframes pn-5 { 0%, 24.2% { opacity: 0; } 24.7%, 30.8% { opacity: 1; } 31.3%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(4), .pass-away span:nth-child(4) { animation-name: pn-5; }
  @keyframes pn-6 { 0%, 30.8% { opacity: 0; } 31.3%, 37.4% { opacity: 1; } 37.9%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(5), .pass-away span:nth-child(5) { animation-name: pn-6; }
  @keyframes pn-7 { 0%, 37.4% { opacity: 0; } 37.9%, 44% { opacity: 1; } 44.5%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(6), .pass-away span:nth-child(6) { animation-name: pn-7; }
  @keyframes pn-8 { 0%, 44% { opacity: 0; } 44.5%, 50.6% { opacity: 1; } 51.1%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(7), .pass-away span:nth-child(7) { animation-name: pn-8; }
  @keyframes pn-9 { 0%, 50.6% { opacity: 0; } 51.1%, 57.2% { opacity: 1; } 57.7%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(8), .pass-away span:nth-child(8) { animation-name: pn-9; }
  @keyframes pn-10 { 0%, 57.2% { opacity: 0; } 57.7%, 63.8% { opacity: 1; } 64.3%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(9), .pass-away span:nth-child(9) { animation-name: pn-10; }
  @keyframes pn-11 { 0%, 63.8% { opacity: 0; } 64.3%, 70.4% { opacity: 1; } 70.9%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(10), .pass-away span:nth-child(10) { animation-name: pn-11; }
  @keyframes pn-12 { 0%, 70.4% { opacity: 0; } 70.9%, 92% { opacity: 1; } 92.5%, 100% { opacity: 0; } }
  .pass-count b span:nth-child(11), .pass-away span:nth-child(11) { animation-name: pn-12; }
  .chip-a { animation: bob 6s ease-in-out infinite alternate; }
  .chip-b { animation: bob 7s ease-in-out 1.8s infinite alternate-reverse; }
  /* The lock screen fills the way a real one does: the three emails arrive one after
     another while the section is being read, hold, then clear and arrive again. */
  .notes .note { animation-duration: 15s; animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1); animation-iteration-count: infinite; animation-fill-mode: both; }
  .notes .note:nth-child(1) { animation-name: note-1; }
  .notes .note:nth-child(2) { animation-name: note-2; }
  .notes .note:nth-child(3) { animation-name: note-3; }
  /* The marker. Every section owns a second view timeline whose scrollport is squeezed
     to a reading line 42% down the viewport, so its cover range runs exactly from the
     section's top reaching that line to its bottom leaving it. The marker traces the
     section's own frame (the rails are the path's sides) over that range and is hidden
     outside it, so one marker is ever visible. The lap deliberately stops at 75%, the
     bottom-left corner: that corner is the same pixel as the NEXT section's top-left
     corner (they share the divider), and the two timelines meet at the same instant, so
     the marker flows from section to section instead of popping to a new start. */
  .sec { view-timeline-name: --s, --sl; view-timeline-axis: block, block; view-timeline-inset: 0, 42% 57%; }
  .sec::after { content: ""; position: absolute; top: 0; left: 0; width: 9px; height: 9px; background: var(--accent); z-index: 3; opacity: 0; offset-path: inset(0 var(--frame)); offset-rotate: 0deg; animation: lap linear both, hold linear none; animation-timeline: --sl, --sl; animation-range: cover, cover; }
  .sec.dark::after { background: var(--cream); }
  .band::after { display: none; }
  /* The card fills as the reader scrolls through it: the two head-start stamps are
     always filled (that is the state a customer signs up into, and the static state),
     the other ten fill one at a time on the card's own timeline, and the count under
     the card steps with them. */
  .punch { view-timeline-name: --punch; }
  .pc:not(.on) .disc { animation: disc linear both; }
  .pc:not(.on) .pc-f { animation: fade-in linear both; }
  .pc:not(.on) .pc-e { animation: fade-out linear both; }
  .pc:not(.on) .disc, .pc:not(.on) .pc-f, .pc:not(.on) .pc-e { animation-timeline: --punch; animation-range: cover var(--a) cover var(--b); }
  .punch-n span, .punch-n span:first-child { opacity: 0; animation: hold linear none; animation-timeline: --punch; animation-range: cover var(--a) cover var(--b); }
  .punch-n span:first-child { animation-fill-mode: backwards; }
  .punch-n span:last-child { animation-fill-mode: forwards; }
  .pc:nth-child(3) { --a: 24%; --b: 28%; }
  .pc:nth-child(4) { --a: 28%; --b: 32%; }
  .pc:nth-child(5) { --a: 32%; --b: 36%; }
  .pc:nth-child(6) { --a: 36%; --b: 40%; }
  .pc:nth-child(7) { --a: 40%; --b: 44%; }
  .pc:nth-child(8) { --a: 44%; --b: 48%; }
  .pc:nth-child(9) { --a: 48%; --b: 52%; }
  .pc:nth-child(10) { --a: 52%; --b: 56%; }
  .pc:nth-child(11) { --a: 56%; --b: 60%; }
  .pc:nth-child(12) { --a: 60%; --b: 64%; }
  .punch-n span:nth-child(1) { --a: 0%; --b: 28%; }
  .punch-n span:nth-child(2) { --a: 28%; --b: 32%; }
  .punch-n span:nth-child(3) { --a: 32%; --b: 36%; }
  .punch-n span:nth-child(4) { --a: 36%; --b: 40%; }
  .punch-n span:nth-child(5) { --a: 40%; --b: 44%; }
  .punch-n span:nth-child(6) { --a: 44%; --b: 48%; }
  .punch-n span:nth-child(7) { --a: 48%; --b: 52%; }
  .punch-n span:nth-child(8) { --a: 52%; --b: 56%; }
  .punch-n span:nth-child(9) { --a: 56%; --b: 60%; }
  .punch-n span:nth-child(10) { --a: 60%; --b: 64%; }
  .punch-n span:nth-child(11) { --a: 64%; --b: 100%; }
  /* Enter on view: each block sits dim and slightly low until it is about a third of
     the way up the screen, then lights, with a stagger across a row. The hero is
     deliberately left alone: it is the largest contentful paint and must never start
     invisible. */
  .st { transition: flex-basis 0.45s ease, flex-grow 0.45s ease; }
  .head, .col, .card-copy, .punch, .fact, .plan, .qa, .band-in, .inbox > div, .acc-row { animation: lit linear both; animation-timeline: view(); animation-range: entry 18% entry 68%; }
  /* The columns and the plans fade without rising: they are staggered, and a stagger that
     moves things vertically leaves headings and prices visibly out of line while it runs. */
  .col, .plan { animation-name: lit-flat; }
  .col:nth-child(2), .plan:nth-child(2), .fact:nth-child(3n+2) { animation-range: entry 30% entry 80%; }
  .col:nth-child(3), .fact:nth-child(3n+3) { animation-range: entry 42% entry 92%; }
  @media (max-width: 960px) {
    .col:nth-child(2), .col:nth-child(3), .plan:nth-child(2), .fact:nth-child(3n+2), .fact:nth-child(3n+3) { animation-range: entry 18% entry 68%; }
  }
}
}
@keyframes lit { from { opacity: 0.16; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes lit-flat { from { opacity: 0.16; } to { opacity: 1; } }
@keyframes lap { from { offset-distance: 0%; } to { offset-distance: 75%; } }
@keyframes disc { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes hold { from { opacity: 1; } to { opacity: 1; } }
@keyframes bob { from { transform: translateY(-7px); } to { transform: translateY(7px); } }
@keyframes float { from { transform: translateY(-5px); } to { transform: translateY(6px); } }
@keyframes note-1 { 0%, 4% { opacity: 0; transform: translateY(18px); } 9%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; transform: translateY(18px); } }
@keyframes note-2 { 0%, 14% { opacity: 0; transform: translateY(18px); } 19%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; transform: translateY(18px); } }
@keyframes note-3 { 0%, 24% { opacity: 0; transform: translateY(18px); } 29%, 88% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; transform: translateY(18px); } }
