/* Two In Play — twoinplay.com
   Colours and type follow the app (lib/src/app/theme): cream #FDEDE5,
   card cream #FEF6EF, rose #B06E6E / #A85F5F / #9C5656, body #6B5D55;
   the deep brown #4D3434 of the hero headline is the site's own. Lora
   Medium Italic for headings and captions, Nunito for text. No JavaScript
   anywhere. */

@font-face { font-family: "Lora"; font-style: italic; font-weight: 500; font-display: swap; src: url("fonts/Lora-MediumItalic.woff2?v=fa050083") format("woff2"); }
@font-face { font-family: "Nunito"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/Nunito-Regular.woff2?v=27428b73") format("woff2"); }
@font-face { font-family: "Nunito"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/Nunito-SemiBold.woff2?v=451e9c2e") format("woff2"); }
@font-face { font-family: "Nunito"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/Nunito-Bold.woff2?v=e1135a68") format("woff2"); }

:root {
  --cream: #FDEDE5;
  --light: #FEF6EF;
  --rose: #B06E6E;
  --headline: #A85F5F;
  --accent: #9C5656;
  --body: #6B5D55;
  --ink: #4D3434;
  --serif: Lora, Georgia, "Times New Roman", serif;
  --sans: Nunito, "Segoe UI", system-ui, sans-serif;
  --nav: 88px;
  --pad: 40px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* The page ends on the light band; the body wears it so nothing below
   the footer changes colour. */
body { margin: 0; background: var(--light); color: var(--body); font-family: var(--sans); font-size: 17px; line-height: 1.5; -webkit-font-smoothing: antialiased; }
img { max-width: 100%; height: auto; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--headline); text-decoration: underline; }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }
/* Every serif text on the site is Lora Medium Italic, the face of the
   headings in the app and of the captions in the store panels: lighter
   than the upright Lora (owners' decision, audit W46). It is the only Lora
   face the site loads, so no rule may ask for another weight or an
   upright serif, or the browser would fake it. */
h1, h2, h3 { font-family: var(--serif); font-style: italic; font-weight: 500; color: var(--headline); margin: 0; }
p { margin: 0; }

.skip-link { position: absolute; left: 16px; top: -80px; z-index: 3; padding: 12px 16px; background: var(--light); border-radius: 12px; }
.skip-link:focus { top: 16px; }
/* The skip link lands on <main tabindex="-1"> (build.py, skip_link()): no
   focus ring around the whole page content when it does. */
main:focus { outline: none; }
/* Text for screen readers only: the "opens in a new tab" hint on links to
   other sites and the language names in the switch (build.py, header()). */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Containers: 1120 px of content on the sections, 1200 px on the hero,
   both with --pad of side padding. */
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 var(--pad); }
.wrap-hero { max-width: 1280px; margin: 0 auto; padding: 0 var(--pad); }

/* ---- bands ---------------------------------------------------------- */
/* Alternating full-width bands: cream (the app background) and the
   lighter card cream. Each change is a soft 96 px gradient with a divider
   centred in it: line–heart–line, and after "Premium" a plain line, as
   the lock of the trust section sits right below it. */
.band-cream { background: var(--cream); }
.band-light { background: var(--light); }
.fade { height: 96px; display: flex; align-items: center; }
.fade .wrap { width: 100%; }
.fade-cream-light { background: linear-gradient(to bottom, var(--cream), var(--light)); }
.fade-light-cream { background: linear-gradient(to bottom, var(--light), var(--cream)); }
.divider { display: flex; align-items: center; gap: 18px; }
.divider span { flex: 1 1 auto; height: 1px; background: linear-gradient(to right, transparent, rgba(176, 110, 110, 0.45)); }
.divider span:last-child { background: linear-gradient(to left, transparent, rgba(176, 110, 110, 0.45)); }
.divider svg { flex: 0 0 auto; }
.rule { height: 1px; background: linear-gradient(to right, transparent, rgba(176, 110, 110, 0.45) 50%, transparent); }
/* ---- light --------------------------------------------------------------- */
/* Pools of soft light on the bands, like lamps in a warm room: large,
   very faint radial gradients in the rose of the brand and in the peach
   of the window in the hero photo. Every band is lit from both sides,
   rose on one and peach on the other, so no stretch of the page stays
   flat; the peach is kept gentle and the rose a shade stronger (owners'
   decision on audit W44). Each ellipse ends at 70 % of its radius, well
   inside its band, so the fades between bands stay seamless. The lower
   bands are named in build.py for this; the footer rule matches only the
   light footer of the landing page, the legal pages keep a plain cream
   one. */
.hero-band { background: radial-gradient(55% 42% at 14% 45%, rgba(176, 110, 110, 0.15), rgba(176, 110, 110, 0) 70%), radial-gradient(42% 40% at 84% 62%, rgba(255, 190, 150, 0.26), rgba(255, 190, 150, 0) 70%), var(--cream); }
#how { background: radial-gradient(48% 40% at 92% 42%, rgba(176, 110, 110, 0.12), rgba(176, 110, 110, 0) 70%), radial-gradient(42% 38% at 10% 72%, rgba(255, 190, 150, 0.22), rgba(255, 190, 150, 0) 70%), var(--light); }
.band-made { background: radial-gradient(50% 42% at 6% 62%, rgba(176, 110, 110, 0.14), rgba(176, 110, 110, 0) 70%), radial-gradient(40% 36% at 92% 32%, rgba(255, 190, 150, 0.24), rgba(255, 190, 150, 0) 70%), radial-gradient(42% 32% at 90% 76%, rgba(176, 110, 110, 0.13), rgba(176, 110, 110, 0) 70%), var(--cream); }
.band-final { background: radial-gradient(45% 40% at 50% 60%, rgba(176, 110, 110, 0.13), rgba(176, 110, 110, 0) 70%), radial-gradient(38% 34% at 82% 26%, rgba(255, 190, 150, 0.22), rgba(255, 190, 150, 0) 70%), var(--light); }
footer.band-light { background: radial-gradient(40% 70% at 12% 50%, rgba(176, 110, 110, 0.10), rgba(176, 110, 110, 0) 70%), var(--light); }
.simple-band { background: radial-gradient(55% 42% at 14% 40%, rgba(176, 110, 110, 0.14), rgba(176, 110, 110, 0) 70%), var(--cream); }

.section { padding-top: 36px; padding-bottom: 84px; }
.section-end { padding-bottom: 56px; }
.section-start { padding-top: 56px; }
.section-trust { padding-top: 36px; padding-bottom: 64px; }
.section-final { padding-top: 0; padding-bottom: 84px; }

/* ---- header ----------------------------------------------------------- */
/* Above the hero: on short windows the faded top of the hero photo box
   reaches up into the nav, and the links must stay clickable. */
header { position: relative; z-index: 2; }
/* Wordmark left, section links in the middle, language switch right; the
   grid keeps the links centred whatever the two sides measure, and on
   narrow windows the wordmark shrinks into its column. The wordmark is
   220 px here, 170 px in the footer and 160 px on phones (audit W30: the
   thin script needs the size; the darker rose it wears on the web is set
   in prepare_images.py). At 1021 px, the narrowest window with the links,
   87 px remain between the wordmark and the first link. */
.nav { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); column-gap: 32px; align-items: center; height: var(--nav); }
.nav-brand { display: block; width: 220px; max-width: 100%; }
.nav-brand img { display: block; width: 100%; height: auto; }
/* The links are a list (audit W60) drawn as a row: no bullets, no indent,
   no list margins. The same on the steps, the footer links and the plan
   cards. */
.nav-links { display: flex; align-items: center; gap: 36px; font-size: 17px; font-weight: 600; list-style: none; margin: 0; padding: 0; }
/* Bigger touch targets with no change of look (audit W24): padding grows
   the link's box to 44 px or more of height and the matching negative
   margin gives the space back, so nothing around the link moves; only
   the focus ring is drawn around the larger box. The same on the footer
   links below. */
.nav-links a { color: var(--body); display: inline-block; padding: 11px 0; margin: -11px 0; }
.nav-links a:hover { color: var(--headline); }
/* CS / EN: the current language in rose, the other one a plain link. The
   link also reaches 8 px sideways, over the separator and the edge. */
.nav-lang { justify-self: end; display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; letter-spacing: 0.04em; }
.nav-lang a { color: var(--body); display: inline-block; padding: 11px 8px; margin: -11px -8px; }
.lang-on { color: var(--accent); }
.lang-sep { font-weight: 400; color: rgba(176, 110, 110, 0.55); }

/* ---- hero -------------------------------------------------------------- */
/* The hero fills the first screen: at least the viewport minus the nav,
   so the first divider sits just below the fold, with the content centred
   in it. svh is the viewport with the phone's address bar shown; browsers
   without it keep the vh line. */
.hero-band { display: flex; flex-direction: column; justify-content: center; min-height: calc(100vh - var(--nav)); min-height: calc(100svh - var(--nav)); overflow-x: clip; }
/* Copy stacked in the left 45 %, the square photo with the phone on the
   right; on phones everything stacks (headline, photo, actions).
   The visual is 55 % of the hero plus a 40 px overhang; --visual-w is
   that width as seen from the hero here and from the visual's own column
   below. The grid row is the visible photo (see .hero-visual), so the
   copy centres on the picture; the padding makes room for the phone,
   which hangs 16.9 % of the visual below the picture, so the band
   centres the whole composition and the phone stays clear of the divider.
   The top padding is the room the Ken Burns drift needs (see "motion"):
   at its peak the visible picture reaches 3 % of the visual above its
   resting top, and on short windows, where the composition fills the
   band, the opaque nav would cut it off; the same rule as in the app
   (_kenBurnsPeakOverflow). */
.hero { --visual-w: calc(55% + 40px); display: grid; grid-template-columns: 45% 55%; align-items: center; gap: 0; padding-top: calc(0.03 * var(--visual-w)); padding-bottom: calc(0.169 * var(--visual-w)); }
/* The six parts of the copy share one gap. */
.hero-left { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; min-width: 0; }
/* Above the photo, whose faded edge reaches under the copy (the parts
   carry it themselves, as on narrow windows the column dissolves). */
.hero-left > * { position: relative; z-index: 1; }
/* On wide windows the hero container is 40 px wider on each side than
   the sections, so the copy steps in to line up with the wordmark and
   the section headings. */
@media (min-width: 1280px) { .hero-left { padding-left: 40px; } }
/* Eyebrow: small spaced capitals with a short rule after them. */
.eyebrow { display: flex; align-items: center; gap: 16px; white-space: nowrap; font-size: 13.5px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); }
.eyebrow::after { content: ""; width: 64px; min-width: 20px; height: 1px; background: rgba(176, 110, 110, 0.5); }
/* The italic's descenders and the Czech carons need the roomier leading. */
.hero-title { font-size: clamp(2.3rem, 4.6vw, 3.4rem); line-height: 1.2; color: var(--ink); text-wrap: balance; }
/* Under 350 px the headline steps down a notch, so "date-night game" still
   shares a line at 320 px: at 2.3 rem it is 277 px in 276 and "game" would
   drop to a line of its own (audit W26; 2.2 rem leaves 11 px, Georgia
   fallback included). Old max-width syntax on purpose: the 320 px phones
   run browsers that do not know range queries (width < 350px). */
@media (max-width: 349px) { .hero-title { font-size: 2.2rem; } }
.nowrap { white-space: nowrap; }
/* The sentences of the Czech headline: a line each next to the photo;
   when the hero stacks (below) they go side by side while they fit. */
.hero-line { display: block; }
.hero-tagline { font-size: clamp(1.15rem, 1.7vw, 1.35rem); line-height: 1.5; }
.hero-actions { display: flex; flex-direction: column; align-items: flex-start; }
.hero-how { font-size: 19px; font-weight: 600; }
.hero-how a { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
/* The arrow is an inline SVG (build.py, ARROW_DOWN); inline-block keeps
   the underline from running under it and vertical-align sets it on the
   text's x-height like a glyph would sit. */
.hero-how .arrow { display: inline-block; margin-left: 8px; vertical-align: -0.1em; }
.hero-meta { font-size: 15px; }
/* The photo fades into the cream, so its box is taller than what is
   seen: with the mask below the picture starts 12.8 % from the top of the
   box and ends at 84.8 % (sites/measure_hero.py); the tilted phone
   reaches 1.7 % below the box. The margins trim the box to the visible
   picture, so the grid centres the copy on it, not on the box. */
.hero-visual { --visual-w: calc(100% + 40px); position: relative; width: var(--visual-w); margin-top: calc(-0.128 * var(--visual-w)); margin-bottom: calc(-0.152 * var(--visual-w)); aspect-ratio: 1 / 1; isolation: isolate; }
.hero-photo { display: block; width: 100%; height: auto; mix-blend-mode: multiply; -webkit-mask-image: radial-gradient(ellipse 68% 65% at 50% 48%, #000 44%, transparent 77%); mask-image: radial-gradient(ellipse 68% 65% at 50% 48%, #000 44%, transparent 77%); }
/* The visual box ends at the window edge below 1280 px, and the 8° tilt
   pushes the phone's corner about 3 % of the box past its own right edge,
   so it keeps 4 % of margin; the band clips the x axis as a safety net
   against a horizontal scrollbar. */
.hero-phone { position: absolute; bottom: 0; right: 4%; width: 27%; padding: 6px; border: 2px solid #B9A798; border-radius: 29px; background: #EFE1D6; box-shadow: 9px 18px 28px rgba(98, 67, 49, 0.16), inset 0 0 0 1px rgba(255, 255, 255, 0.6); transform: rotate(8deg); overflow: hidden; }
.hero-phone img { display: block; width: 100%; height: auto; border-radius: 21px; }

/* ---- store badges ------------------------------------------------------ */
/* The official badge artwork (build.py, badges()); nothing of ours on
   top. 48 px tall (the stores ask for 40 px at least) with a gap of a
   quarter of that, the clear space both stores want. */
.badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.badges a { display: inline-flex; line-height: 0; border-radius: 6px; }
.badges img { display: block; height: 48px; width: auto; }
/* Before release: the "coming soon" line and, under it, the invitation
   to ask for a note by e-mail (audit W02). Plain text on purpose: the
   earlier pill looked like a button that did nothing (W36). The block
   inherits the alignment of its place: left in the desktop hero,
   centred everywhere else. */
.coming-soon { color: var(--accent); font-size: 16px; font-weight: 600; line-height: 1.3; }
.coming-notify { margin-top: 8px; font-size: 15px; }
.coming-notify a { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
/* The store line after the screens, where the visitor has just seen what
   the game is: on every width, not only on phones (audit W14). Centred
   under the four steps; the hero and the closing invitation carry the
   other two. */
.steps-actions { display: flex; flex-direction: column; align-items: center; text-align: center; margin-top: 48px; }

/* ---- sections ---------------------------------------------------------- */
.h2 { font-size: 36px; line-height: 1.25; }
/* The intro spans the whole content column, so the one-sentence lead of
   "How it works" runs as wide as it can (owners' decision 14. 9. 2026,
   audit W18): the Czech one (about 1 040 px) is a single line on a
   desktop, the English one (about 1 200 px) is wider than the column and
   wraps into two even lines thanks to text-wrap: balance — without it
   the second line would be two words. Browsers without balance (Safari
   before 17.5) show a long first line and a short second one. */
.section-intro { display: flex; flex-direction: column; gap: 12px; margin-bottom: 44px; }
.lead { font-size: 18px; line-height: 1.55; text-wrap: balance; }
/* The How-it-works lead runs the full column width and wraps like body
   text: balanced lines left its first line short in windows where the
   sentence no longer fits on one line (owners 2026-09-16). */
.lead-full { text-wrap: wrap; }
.h2-space { margin-bottom: 32px; }
.h2-space-lg { margin-bottom: 40px; }

/* How it works: four phones in the hero's light bezel, a caption centred
   above each. The steps share the two rows of the section grid (subgrid),
   so the caption row is as tall as the longest caption, every caption
   sits centred in it and the four phones share one top edge. The steps
   are a numbered list (audit W60), the picture first in the markup; the
   list's own numbers, indent and margins go. */
.steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 36px; list-style: none; margin: 0; padding: 0; }
.step { display: grid; grid-template-rows: subgrid; grid-row: span 2; }
.step .caption { grid-row: 1; align-self: center; }
/* Browsers without subgrid (Safari before 16, Chrome before 117, Firefox
   before 71) lay each step out on its own, so a one-line caption would
   pull its phone up. There every caption gets the height of two lines,
   which is what the desktop captions have (each breaks in two), with the
   text centred in it, and the step gets the 18 px row gap the subgrid
   would take from .steps, so the phones stand where they do with subgrid.
   Should a caption ever run to three lines, only its phone drops a line;
   align-self keeps the other bezels from stretching to match. Only on the
   grid widths: on phones the caption sits beside its phone and the extra
   height would push its text off centre. Browsers with subgrid never see
   this (audit W58). */
@supports not (grid-template-rows: subgrid) {
  @media (min-width: 721px) {
    .step { row-gap: 18px; }
    .step .caption { min-height: 2.7em; display: grid; align-content: center; }
    .step .phone { align-self: start; }
  }
}
/* Like the benefits below, four in a row and two and two on tablets; on
   phones each step is a row, the phone beside its caption. In the wide
   tablet columns the phone stops at 256 px (a 240 px picture, one of the
   files in srcset) and sits centred. */
.step .phone { grid-row: 2; width: 100%; max-width: 256px; justify-self: center; }
.phone { padding: 6px; border: 2px solid #B9A798; border-radius: 29px; background: #EFE1D6; box-shadow: 9px 18px 28px rgba(98, 67, 49, 0.16), inset 0 0 0 1px rgba(255, 255, 255, 0.6); overflow: hidden; }
.phone img { display: block; width: 100%; height: auto; border-radius: 21px; }
.caption { font-family: var(--serif); font-style: italic; font-weight: 500; font-size: 21px; line-height: 1.35; color: var(--body); text-align: center; }

/* Made for the two of you: icon + caption. */
.benefits { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; list-style: none; margin: 0; padding: 0; }
.benefit { display: flex; gap: 14px; align-items: center; }
.benefit-icon { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 15px; background: var(--light); display: flex; align-items: center; justify-content: center; }
/* 19 px on every width (owners' decision, W46 follow-up): a step under the
   21 px step captions, and the last size at which every title keeps one
   line from 1280 px up. */
.benefit-title { font-family: var(--serif); font-style: italic; font-weight: 500; font-size: 19px; line-height: 1.3; color: var(--body); }

/* Free / Premium. */
.plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
.card { background: var(--light); border: 1px solid rgba(176, 110, 110, 0.35); border-radius: 24px; padding: 36px 40px; display: flex; flex-direction: column; gap: 18px; }
/* A step under the 36 px section heading; the italic reads lighter than
   the old upright face did at 24 px (owners' decision, W46 follow-up). */
.card-title { font-size: 28px; margin-bottom: 6px; }
/* The check lines are a list (audit W60); the card spaces only its own
   children, so the list carries the same 18 px between its rows. */
.card-lines { display: flex; flex-direction: column; gap: 18px; list-style: none; margin: 0; padding: 0; }
.card-line { display: flex; gap: 12px; align-items: flex-start; }
.card-line svg { flex: 0 0 auto; margin-top: 3px; }
.card-line strong { font-weight: 700; color: var(--accent); }
.card-note { margin-top: 8px; font-size: 15px; }

/* Trust and the closing invitation. */
.centered { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; max-width: 36em; margin: 0 auto; }
.centered-final { gap: 22px; }
.h2-trust { font-size: 28px; line-height: 1.3; }
.h2-final { font-size: 44px; line-height: 1.2; }
.note { font-size: 15px; color: var(--accent); }

/* Footer. */
/* Vertical padding only, so the .wrap side padding survives. */
.footer { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 40px; padding-top: 36px; padding-bottom: 44px; border-top: 1px solid rgba(176, 110, 110, 0.22); }
.footer-brand { display: block; width: 170px; }
.footer-brand img { display: block; width: 100%; height: auto; }
/* The links sit in a <nav> of their own (build.py, footer()), so a screen
   reader lists it next to the header navigation and can jump to it. */
.footer-links { display: flex; gap: 24px; flex-wrap: wrap; font-size: 15px; font-weight: 600; list-style: none; margin: 0; padding: 0; }
/* Touch targets as in the header (audit W24); the 24 px gaps of both rows
   keep the enlarged boxes from overlapping when the links wrap. */
.footer-links a { white-space: nowrap; display: inline-block; padding: 11px 0; margin: -11px 0; }
.footer-meta { display: flex; gap: 24px; flex-wrap: wrap; font-size: 14px; }
.footer-meta a { display: inline-block; padding: 12px 0; margin: -12px 0; }
/* The badge attributions, only after release (build.py, TRADEMARKS). */
.footer-trademarks { grid-column: 1 / -1; margin: 0; font-size: 12px; line-height: 1.5; opacity: 0.8; }

/* Simple pages (privacy, terms, support, 404). Vertical paddings only,
   so the .wrap side padding survives on phones. */
.simple { max-width: 40em; padding-top: 48px; padding-bottom: 96px; }
.simple .h1 { font-size: 36px; line-height: 1.25; margin-bottom: 20px; }
.simple p { margin-bottom: 16px; font-size: 18px; line-height: 1.6; }
/* Privacy and Terms: short sections with a summary list on top. */
.simple h2 { font-size: 22px; line-height: 1.3; margin: 32px 0 12px; }
.simple ul { margin: 0 0 16px; padding-left: 1.25em; font-size: 18px; line-height: 1.6; }
.simple li { margin-bottom: 8px; }
.simple li::marker { color: var(--rose); }
.simple a { text-decoration: underline; text-underline-offset: 2px; }
.simple .legal-meta { font-size: 16px; color: var(--rose); margin-bottom: 8px; }
.simple-band { min-height: calc(100vh - var(--nav)); min-height: calc(100svh - var(--nav)); }
/* The 404 page is short; it sits in the middle of the first screen, the
   footer below the fold as on the landing page. */
.simple-band-centered { display: flex; flex-direction: column; justify-content: center; }

/* ---- 404 --------------------------------------------------------------- */
/* One centred column (build.py, not_found): the two cards of the app
   icon, the English message and, under a short rule, the Czech one with
   a smaller heading (audit W49). The cards are an inline SVG; its
   heart pulses with the divider hearts, and transform-box keeps that
   pulse centred on the heart itself inside the tilted card. */
.notfound { display: flex; flex-direction: column; align-items: center; text-align: center; max-width: 36em; margin: 0 auto; padding-top: 40px; padding-bottom: 56px; }
.nf-art { display: block; width: 156px; height: auto; margin-bottom: 30px; overflow: visible; }
.nf-art .beat { transform-box: fill-box; }
.nf-title { font-size: 36px; line-height: 1.25; }
.nf-text { margin-top: 12px; font-size: 18px; line-height: 1.6; }
.nf-link { margin-top: 14px; font-size: 18px; font-weight: 600; }
.nf-link a { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
/* The Czech block: the rule above it fades out at both ends like .rule
   and spans the middle three fifths of the column. */
.nf-cs { position: relative; width: 100%; margin-top: 40px; padding-top: 32px; }
.nf-cs::before { content: ""; position: absolute; left: 20%; right: 20%; top: 0; height: 1px; background: linear-gradient(to right, transparent, rgba(176, 110, 110, 0.45) 50%, transparent); }
.nf-cs .nf-title { font-size: 26px; }
.nf-cs .nf-text, .nf-cs .nf-link { font-size: 17px; }

/* ---- tablets ----------------------------------------------------------- */
/* Between phone and desktop the four steps and the four benefits go two
   and two; the second pair of steps sits 32 px under the first. */
@media (min-width: 721px) and (max-width: 1024px) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .step:nth-child(n+3) .caption { margin-top: 32px; }
  .benefits { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
  /* Plan cards: narrower side padding, so a line such as "18 and 24 cards"
     does not leave a single word on its own row (audit W55). */
  .card { padding: 28px; }
}

/* Between phone and 1200 px the footer's middle column is too narrow for
   the links, so they broke one per row (audit W56). The Czech row needs
   about 1 030 px of column and gets it with room to spare only from
   1 200 px; just below that it fits by a few pixels, too close to rely
   on. Two rows instead: wordmark and e-mail/copyright first, the links
   across the full width below. */
@media (min-width: 721px) and (max-width: 1199px) {
  .footer { grid-template-columns: auto 1fr; row-gap: 20px; }
  .footer-nav { grid-column: 1 / -1; }
  .footer-meta { grid-column: 2; grid-row: 1; justify-content: flex-end; }
}

/* ---- narrow and portrait windows: the hero ----------------------------- */
/* Below 1020 px the two hero columns get too narrow for the headline, and
   in any window taller than wide (a tablet held upright) the two-column
   composition is small and the band, sized to the first screen, would
   centre it in a lot of empty cream. In both cases the hero stacks
   earlier than the rest of the page: one column, all centred, the photo
   between the tagline and the store line. The left group dissolves so
   the parts can be ordered and share the hero's gap. */
@media (max-width: 1020px), (orientation: portrait) {
  .hero { display: flex; flex-direction: column; align-items: center; gap: 22px; padding: 12px 0 28px; text-align: center; }
  .hero-left { display: contents; }
  .eyebrow { order: 1; justify-content: center; }
  .eyebrow::after { display: none; }
  .hero-title { order: 2; }
  /* Both sentences on one line while the window is wide enough; each
     stays whole, so a narrower window breaks exactly between them. */
  .hero-line { display: inline; white-space: nowrap; }
  .hero-tagline { order: 3; font-size: 1.2rem; }
  /* Full bleed up to 800 px of window; wider than that the photo stops
     growing and sits centred, so it does not dwarf the copy around it
     (the side margins are negative on the bleed, positive when capped).
     It also never grows past 65 % of the window height: on a tablet held
     upright a full-width photo pushed the store line below the first
     screen (audit W16). On a phone held sideways that cap alone left
     a 250 px photo with an unreadable phone in it, which looked wrong
     (owners, 13 Sep 2026), so the photo never drops under 480 px; that
     floor only ever applies to landscape windows, as upright phones are
     narrower than it and 65 % of a tablet's height is above it. vh on
     purpose, not svh: a custom property is not checked when set, so
     a second line with svh would win in every browser and break in
     those without svh.
     The invisible top strip of the photo is pulled up so the visible
     picture starts one gap below the tagline; the phone ends 2 % above
     the box, so the bottom margin gives it the same gap. */
  .hero-visual { --visual-w: min(100% + 2 * var(--pad), 800px, max(65vh, 480px)); order: 4; width: var(--visual-w); margin: calc(-0.128 * var(--visual-w)) calc((100% - var(--visual-w)) / 2) calc(-0.02 * var(--visual-w)); }
  .hero-phone { right: 5%; bottom: 2%; width: 27%; }
  .hero-actions { order: 5; align-items: center; }
  .hero-how { order: 6; font-size: 18px; }
  .hero-meta { order: 7; font-size: 14px; }
}

/* ---- phones ------------------------------------------------------------ */
@media (max-width: 720px) {
  :root { --nav: 72px; --pad: 22px; }
  .nav-brand { width: 160px; }
  /* No section links; two columns keep the switch at the right edge. */
  .nav { grid-template-columns: 1fr auto; }
  .nav-links { display: none; }
  /* A thinner bezel on the small phone of the stacked hero. */
  .hero-phone { padding: 4px; border-radius: 21px; }
  .hero-phone img { border-radius: 15px; }
  .section { padding-top: 28px; padding-bottom: 56px; }
  .section-end { padding-bottom: 40px; }
  .section-start { padding-top: 40px; }
  .section-trust { padding-top: 28px; padding-bottom: 44px; }
  .section-final { padding-top: 0; padding-bottom: 60px; }
  .fade { height: 72px; }
  .h2 { font-size: 30px; }
  .h2-final { font-size: 36px; }
  /* Phone and caption half and half, sides alternating step by step, the
     caption text set towards its phone. */
  .steps { grid-template-columns: repeat(1, minmax(0, 1fr)); gap: 28px; }
  .step { display: flex; flex-direction: row; align-items: center; gap: 20px; grid-row: auto; }
  .step:nth-child(even) { flex-direction: row-reverse; }
  .step .phone { flex: 1 1 0; min-width: 0; border-radius: 24px; padding: 5px; }
  .step .phone img { border-radius: 19px; }
  .step .caption { flex: 1 1 0; min-width: 0; font-size: 18px; text-align: left; }
  .step:nth-child(even) .caption { text-align: right; }
  .steps-actions { margin-top: 40px; }
  .benefits { grid-template-columns: repeat(1, minmax(0, 1fr)); gap: 28px; }
  .plans { grid-template-columns: repeat(1, minmax(0, 1fr)); gap: 20px; }
  .card { padding: 28px 26px; }
  /* Steps down with .h2 (30 px here), so the two stay apart. */
  .card-title { font-size: 26px; }
  .footer { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
  .simple { padding-top: 32px; padding-bottom: 72px; }
  .simple .h1 { font-size: 30px; }
  .simple h2 { font-size: 20px; }
  .notfound { padding-top: 24px; padding-bottom: 40px; }
  .nf-art { width: 128px; margin-bottom: 24px; }
  .nf-title { font-size: 30px; }
  .nf-cs { margin-top: 32px; padding-top: 26px; }
  .nf-cs .nf-title { font-size: 23px; }
}

/* ---- motion ------------------------------------------------------------ */
/* The two idle motions of the app's home screen, with its values
   (lib/src/features/home/presentation/pages/home_page.dart and
   core/widgets/heart_ornament.dart). Each swings between two states and
   back: "alternate" with ease-in-out is Flutter's repeat(reverse: true)
   with Curves.easeInOut. Transforms only, so nothing around them moves;
   both stand still under "reduce motion" (below). */
/* Ken Burns drift of the hero photo: a slow breath from 1 to 1.08 and
   back, 12 s each way, too slow to read as motion. At the peak the photo
   grows 4 % of its box past each edge, but that is faded edge, not
   picture: the visible picture (measure_hero.py) stays inside the box
   left and right and reaches 3 % of the box past its resting top and
   bottom. Below, the phone and the actions keep their distance; above,
   the top padding of .hero keeps it from under the nav on short windows
   and the gap after the tagline absorbs it on the stacked hero. The
   band clips the x axis (see .hero-band). */
@keyframes hero-drift { from { transform: scale(1); } to { transform: scale(1.08); } }
.hero-photo { animation: hero-drift 12s ease-in-out infinite alternate; }
/* Heartbeat of the hearts: 1 s up, 1 s down, as everywhere in the app.
   The ornamental heart above the closing invitation swells to 1.16 like
   the heart on the app's home screen (HeartOrnament.defaultPeakScale);
   the small hearts in the dividers to 1.2 like the divider heart on the
   app's card screen (emphasizedPeakScale), as the quieter pulse would
   barely move at 18 px. */
@keyframes heartbeat { from { transform: scale(1); } to { transform: scale(1.16); } }
@keyframes heartbeat-strong { from { transform: scale(1); } to { transform: scale(1.2); } }
.beat { transform-origin: 50% 50%; animation: heartbeat 1s ease-in-out infinite alternate; }
.beat-strong { animation-name: heartbeat-strong; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero-photo, .beat { animation: none; }
}
