/* Get Paid! Piggy Smash — site styles, matched to the in-game look. */
/* Fredoka, served from this domain rather than fonts.googleapis.com. The
   @import that used to be here was a render-blocking chained request (HTML →
   CSS → Google's CSS → the font file) and it handed every visitor's IP to
   Google — on a site whose privacy page says it has no trackers. One variable
   file covers 400-700, so the four static weights became two subsets. */
@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('assets/fonts/fredoka-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('assets/fonts/fredoka-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --ink: #4a3329;
  /* 0.78, not 0.6. At 0.6 this computed to 3.46:1 on cream — under the 4.5:1
     AA bar — and it is the colour of nearly all secondary prose on the site:
     every .sub, every card paragraph, the footer, .numbers, .small-note. */
  --ink-soft: rgba(74, 51, 41, 0.78);
  --cream: #fff5e3;
  --paper: #fffcf2;
  --blush: #ffbfcc;
  --berry: #e05c78;
  --berry-dark: #b83a56;
  --gold: #ffcc47;
  /* Darkened from #b8851a, which was 3.19:1 on paper — it is used as TEXT
     (.page h3) at 16px, and 16px bold is not "large text", so it needed
     the full 4.5:1 rather than the 3:1 allowance. This is 4.98:1. */
  --gold-dark: #8f6612;
  --mint: #87d4a1;
  --mint-dark: #388c5c;
  --wood: #c78c4f;
  --sky: #73c2d4;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Fredoka', system-ui, sans-serif;
  color: var(--ink);
  background-color: var(--cream);
  background-image: radial-gradient(rgba(74, 51, 41, 0.05) 1.5px, transparent 1.5px);
  background-size: 22px 22px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.wrap { --gutter: 22px; max-width: 1040px; margin: 0 auto; padding: 0 var(--gutter); }

/* ---- header ---- */
header {
  padding: 18px 0;
  position: sticky; top: 0; z-index: 10;
  background: rgba(255, 245, 227, 0.9);
  backdrop-filter: blur(6px);
  border-bottom: 3px solid var(--ink);
}
header .wrap { display: flex; align-items: center; justify-content: space-between; }
/* Logo only. The icon used to be sized in three places (34 → 38 → 34
   !important) and the font-size in two, all to hold a text lockup that no
   longer exists; this is the one rule now. */
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; flex: 0 0 auto; }
/* The wordmark as text: same family and colour as the sign in the hero, at a
   size that leaves the nav and the CTA their room. Hidden under 700px, where
   the icon carries the brand and the button needs every pixel. */
.brand-name { font-weight: 700; font-size: 17px; color: var(--berry-dark); white-space: nowrap; letter-spacing: -0.2px; }
@media (max-width: 700px) { .brand-name { display: none; } }
.brand img {
  width: 36px; height: 36px; display: block;
  border-radius: 9px; border: 2px solid var(--ink);
}
/* Links are the only tap targets on most pages. 20px of text is too little to
   hit on a phone; the padding lifts each one past the 24px minimum without
   moving the text. Negative margin keeps the visual gap where it was. */
nav a { color: var(--ink); text-decoration: none; font-weight: 600; margin-left: 22px;
        padding: 10px 2px; margin-top: -10px; margin-bottom: -10px; display: inline-block; }
nav a:hover { color: var(--berry-dark); }
/* One clear action in the header. /play picks the right store for the device
   it is opened on, and utm_campaign=header lands these installs in their own
   row next to landing, press and smartbanner. */
header .header-cta, header .header-cta:hover { color: var(--ink); padding: 7px 14px; font-size: 15px;
  line-height: 1.3; margin: 0 0 0 18px; border-radius: 12px; box-shadow: 0 3px 0 var(--ink); }
header .header-cta:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--ink); }

/* ---- focus + skip link -----------------------------------------------------
   There were no authored focus styles anywhere in this file. The UA default
   survived (nothing set outline:none), but it was never checked against the
   cream page, and the sticky header at z-index 10 hid any focused element that
   landed under it — WCAG 2.4.11. scroll-margin-top is the fix for the second
   half: the browser scrolls the target clear of the bar. */
:focus-visible {
  outline: 3px solid var(--berry-dark);
  outline-offset: 3px;
  border-radius: 4px;
}
.storebadge:focus-visible, .brand:focus-visible { outline-offset: 5px; }
:target, h1, h2, h3 { scroll-margin-top: 96px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -120%);
  z-index: 20; background: var(--paper); color: var(--ink);
  font-weight: 700; padding: 12px 22px;
  border: 3px solid var(--ink); border-radius: 0 0 14px 14px;
  text-decoration: none;
}
.skip:focus { transform: translate(-50%, 0); }

/* ---- buttons ---- */
.btn {
  display: inline-block; font-weight: 700; font-size: 18px;
  color: #fff; background: var(--berry);
  padding: 14px 30px; border-radius: 16px;
  border: 3px solid var(--ink);
  box-shadow: 0 5px 0 var(--ink);
  text-decoration: none; cursor: pointer;
  transition: transform .08s ease, box-shadow .08s ease;
}
.btn:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--ink); }
.btn.mint { background: var(--mint); color: var(--ink); }
.btn.gold { background: var(--gold); color: var(--ink); }

/* ---- hero ---- */
/* 64px of padding above the logo was a third of the reason the store badges
   sat below the fold on a phone. It scales now instead of being a constant. */
.hero { text-align: center; padding: clamp(16px, 4vw, 40px) 0 40px; }
.sign {
  display: inline-block; background: linear-gradient(180deg, var(--paper), var(--cream));
  border: 4px solid var(--ink); border-radius: 24px;
  padding: 22px 40px; box-shadow: 0 8px 0 var(--ink);
  transform: rotate(-1.2deg);
}
.sign h1 {
  font-size: clamp(46px, 9vw, 88px); font-weight: 700; color: var(--berry);
  letter-spacing: -1px; line-height: 0.95;
  text-shadow: 3px 3px 0 var(--ink);
}
.ribbon {
  display: inline-block; margin-top: 8px; background: var(--gold);
  color: var(--cream); font-weight: 700; letter-spacing: 3px;
  padding: 6px 26px; border: 3px solid var(--ink);
  clip-path: polygon(6% 0, 94% 0, 100% 50%, 94% 100%, 6% 100%, 0 50%);
  text-shadow: 2px 2px 0 var(--ink);
}
.sub { color: var(--ink-soft); max-width: 560px; margin: 0 auto 24px; }
.cta { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.soon { font-size: 14px; color: var(--ink-soft); margin-top: 14px; }
/* berry-dark, not berry: as TEXT the lighter berry is 3.25:1 on cream, and
   these are 13-14px so the large-text allowance does not apply. Buttons keep
   berry, where it is a background behind white and passes on its own. */
.soon a { color: var(--berry-dark); }

/* ---- store badges ----------------------------------------------------------
   Apple's and Google's own lockups, which neither company lets you restyle: no
   border, no shadow, no rounding of our own, and no scrapbook wobble. The only
   thing we control is size, and both guidelines say the same thing about that —
   the two badges get equal height and the App Store one is never the smaller.

   Equal height, from two DIFFERENT aspect ratios (Apple 3:1, Google 3.371:1),
   without a fixed pixel height: give each a flex-grow equal to its own ratio
   over a zero basis. Flex then hands out the row's width in exactly 3 : 3.371,
   which is the same thing as saying "same height". A fixed `height: 56px`
   looked identical on a desktop and ran off the side of a 360px phone, because
   two badges sized in px cannot shrink; this cannot overflow at any width. */
.cta.store { align-items: center; gap: 16px; max-width: 380px; margin: 0 auto; flex-wrap: nowrap; }
.storebadge { display: block; line-height: 0; min-width: 0; }
.storebadge.apple  { flex: 3 1 0; }
.storebadge.google { flex: 3.371 1 0; }
.storebadge img { width: 100%; height: auto; display: block; }
.storebadge:active { transform: translateY(2px); }
/* A row holding only one badge would stretch it to the full 380px a pair gets.
   This is the width the App Store badge actually has when the Google one sits
   next to it: (row - 16px gap) x 3/6.371, capped at the 380px row. */
.cta.store.single { max-width: min(172px, calc(47.09% - 8px)); }

/* ---- preview video ---------------------------------------------------------
   Portrait, so it is capped by WIDTH normally and by HEIGHT in landscape —
   a 9:19.5 element told only "70vw" becomes the entire viewport on a phone
   turned sideways. aspect-ratio reserves the box before the poster decodes, so
   nothing below it moves. */
.preview { margin: 26px auto 0; width: min(300px, 70vw); }
.preview video {
  display: block; width: 100%; height: auto;
  aspect-ratio: 9 / 19.5;
  background: var(--ink);
  border: 3px solid var(--ink); border-radius: 22px;
  box-shadow: 0 6px 0 rgba(74, 51, 41, 0.35);
}
.preview-sound {
  display: inline-block; margin-top: 10px;
  font: inherit; font-size: 14px; font-weight: 700;
  color: var(--ink); background: var(--gold);
  padding: 7px 18px; cursor: pointer;
  border: 3px solid var(--ink); border-radius: 12px;
  box-shadow: 0 3px 0 var(--ink);
}
.preview-sound:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--ink); }
/* Without JS the observer never runs, so the button would promise something it
   cannot deliver; coins.js reveals it. */
.preview-sound { display: none; }
.preview.is-live .preview-sound { display: inline-block; }

/* ---- shots ---- */
.shots { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; padding: 10px 0 34px; }
.shots img {
  /* height:auto is load-bearing: the width/height attributes on these images
     are there to reserve space and stop the layout jumping, and without this
     the height attribute would win and render them 220x958. */
  width: 220px; height: auto; max-width: 44vw; border-radius: 26px;
  border: 4px solid var(--ink); box-shadow: 0 8px 0 rgba(74, 51, 41, 0.35);
  transform: rotate(-2deg);
}
.shots img:nth-child(2) { transform: rotate(1.5deg) translateY(-10px); }
.shots img:nth-child(3) { transform: rotate(-1deg); }

/* ---- features ---- */
.features { padding: 22px 0 40px; }
.features h2, .page h1 { text-align: center; font-size: 34px; font-weight: 700; margin-bottom: 8px; }
/* Flex rather than grid so a row that does not fill up CENTRES its cards. An
   auto-fit grid packs the leftovers against the left edge, which stranded the
   fifth card of "What you do" on its own in the corner. The 320px cap is the
   natural width of a three-card row, so full rows lay out exactly as they did. */
.grid {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 18px; margin-top: 26px;
}
.card {
  flex: 1 1 220px; max-width: 320px;
  background: var(--paper); border: 3px solid var(--ink); border-radius: 20px;
  padding: 22px; box-shadow: 0 6px 0 var(--ink);
}
.card .emoji { font-size: 40px; }
.card h3 { margin: 8px 0 4px; font-size: 20px; font-weight: 700; }
.card p { color: var(--ink-soft); font-size: 15px; }

/* ---- content pages ---- */
.page { padding: 46px 0 60px; }
.page .panel {
  background: var(--paper); border: 3px solid var(--ink); border-radius: 22px;
  padding: 30px 34px; box-shadow: 0 6px 0 var(--ink); max-width: 760px; margin: 24px auto 0;
}
.page h2 { font-size: 22px; font-weight: 700; margin: 24px 0 8px; color: var(--berry-dark); }
.page p, .page li { color: var(--ink); margin-bottom: 10px; }
.page ul { padding-left: 22px; }
.page a { color: var(--berry-dark); font-weight: 600; }
.updated { text-align: center; color: var(--ink-soft); font-size: 14px; margin-top: 6px; }

/* ---- footer ---- */
footer { border-top: 3px solid var(--ink); padding: 26px 0; text-align: center; color: var(--ink-soft); }
footer a { color: var(--berry-dark); text-decoration: none; font-weight: 600; margin: 0 10px; }
footer .small { font-size: 13px; margin-top: 8px; }
.langs { margin-top: 12px; font-size: 14px; }
.langs a { margin: 0 6px; font-weight: 500; color: var(--ink-soft); }
.langs a[aria-current] { color: var(--ink); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

/* ---- game-art additions ---- */
.hero-art { display: flex; align-items: flex-end; justify-content: center; gap: 6px; margin: 6px 0 26px; min-height: 160px; }
.hero-art .piggy { width: clamp(120px, 30vw, 168px); animation: bob 2.4s ease-in-out infinite; }
.hero-art .hammer { width: clamp(78px, 20vw, 112px); transform: rotate(-16deg); animation: swing 2.4s ease-in-out infinite; transform-origin: bottom center; }
.hero-art .coin { width: clamp(34px, 9vw, 48px); }
.hero-art .c1 { animation: float 2.8s ease-in-out infinite; }
.hero-art .c2 { animation: float 2.8s ease-in-out infinite 0.6s; }
@keyframes bob { 0%,100% { transform: translateY(0) rotate(-1deg); } 50% { transform: translateY(-8px) rotate(1deg); } }
@keyframes swing { 0%,100% { transform: rotate(-16deg); } 50% { transform: rotate(-30deg); } }
@keyframes float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@media (prefers-reduced-motion: reduce) { .hero-art * { animation: none !important; } }

.card { text-align: center; }
.card .ic { width: 62px; height: 62px; object-fit: contain; margin-bottom: 6px; }
/* Centred with the rest of the card. The badged icon and the heading were
   already centred, so ragged-left body under them read as a misprint. */
.card p { text-align: center; }


/* ---- real logo + badged icons (overrides) ---- */
/* Bounded by HEIGHT as well as width. `min(560px, 90vw)` alone rendered the
   wordmark 241px tall inside a 390px-tall landscape phone, because 90vw of an
   844px-wide viewport is 760px. 3.284 is the asset's own aspect ratio
   (1120x341), so the third term is "no taller than 30vh". */
.hero .logo {
  width: min(560px, 90vw, 30vh * 3.284);
  height: auto; display: block; margin: 0 auto 10px;
}
.card .ic {
  width: 74px; height: 74px; object-fit: contain; box-sizing: border-box;
  padding: 14px; margin: 0 auto 10px; display: block;
  background: var(--cream); border: 3px solid var(--ink); border-radius: 50%;
}

/* ---- hero smash animation (loops, resets ~2s after each smash) ---- */
.hero-art { min-height: 210px; display: flex; justify-content: center; align-items: flex-end; }
.smash { position: relative; width: 280px; height: 200px; }
.smash .piggy {
  position: absolute; left: 50%; bottom: 0; width: 152px; margin: 0;
  transform: translateX(-50%);
  transform-origin: bottom center;
  animation: piggy-smash 3s ease-in-out infinite;
}
.smash .hammer {
  position: absolute; left: 54%; bottom: 78px; width: 116px; margin: 0;
  transform: rotate(-42deg);
  transform-origin: bottom left;
  animation: hammer-smash 3s ease-in-out infinite;
  z-index: 3;
}
.smash .coins { position: absolute; left: 50%; bottom: 92px; width: 0; height: 0; }
.smash .coin {
  position: absolute; left: 0; top: 0; width: 40px; margin-left: -20px;
  opacity: 0;
  animation: coin-burst 3s ease-in-out infinite;
}
@keyframes hammer-smash {
  0%, 10% { transform: rotate(-42deg); }
  17%     { transform: rotate(10deg); }   /* SLAM onto the piggy */
  23%     { transform: rotate(3deg); }
  34%, 100% { transform: rotate(-42deg); } /* raise back up and wait */
}
@keyframes piggy-smash {
  0%, 15%  { transform: translateX(-50%) scale(1, 1); }
  18%      { transform: translateX(-50%) scale(1.14, 0.8); }  /* squish on impact */
  22%      { transform: translateX(-53%) scale(0.93, 1.08); }
  26%      { transform: translateX(-47%) scale(1.03, 0.97); }
  32%      { transform: translateX(-50%) scale(1, 1); }
  100%     { transform: translateX(-50%) scale(1, 1); }
}
@keyframes coin-burst {
  0%, 15%   { opacity: 0; transform: translate(0, 0) scale(0.4); }
  18%       { opacity: 1; transform: translate(calc(var(--dx) * 0.4), -18px) scale(1); }
  34%       { opacity: 1; transform: translate(var(--dx), -50px) scale(1); }  /* burst up and out */
  60%       { opacity: 1; transform: translate(var(--dx), 44px) scale(1); }   /* fall to the table */
  80%       { opacity: 1; transform: translate(var(--dx), 44px) scale(1); }   /* rest a beat */
  92%, 100% { opacity: 0; transform: translate(var(--dx), 44px) scale(0.7); } /* fade, then reset */
}
@media (prefers-reduced-motion: reduce) {
  .smash .piggy, .smash .hammer, .smash .coin { animation: none !important; }
  .smash .hammer { transform: rotate(-30deg); }
  .smash .coin:nth-child(2), .smash .coin:nth-child(4) { opacity: 1; transform: translate(var(--dx), 30px); }
}

/* ---- hero smash animation v2 (chop, reliable positioning) ---- */
.smash { position: relative; width: 240px; height: 210px; }
.smash .piggy {
  position: absolute; left: 50%; bottom: 0; width: 150px; margin: 0;
  transform: translateX(-50%); transform-origin: bottom center;
  animation: piggy-smash 3s ease-in-out infinite;
}
.smash .hammer {
  position: absolute; left: 50%; top: 0; width: 112px; margin-left: -42px;
  transform-origin: bottom center; transform: translateY(-34px) rotate(-16deg);
  animation: hammer-chop 3s ease-in-out infinite; z-index: 3;
}
.smash .coins { position: absolute; left: 50%; top: 62px; width: 0; height: 0; }
.smash .coin {
  position: absolute; left: -19px; top: -19px; width: 38px; margin: 0;
  opacity: 0; animation: coin-burst 3s ease-in-out infinite;
}
@keyframes hammer-chop {
  0%, 10%  { transform: translateY(-34px) rotate(-16deg); }
  17%      { transform: translateY(8px) rotate(6deg); }
  24%      { transform: translateY(0) rotate(2deg); }
  34%,100% { transform: translateY(-34px) rotate(-16deg); }
}
@keyframes piggy-smash {
  0%, 15%  { transform: translateX(-50%) scale(1,1); }
  18%      { transform: translateX(-50%) scale(1.14,0.8); }
  22%      { transform: translateX(-53%) scale(0.93,1.08); }
  26%      { transform: translateX(-47%) scale(1.03,0.97); }
  32%,100% { transform: translateX(-50%) scale(1,1); }
}
@keyframes coin-burst {
  0%, 16%  { opacity: 0; transform: translate(0,0) scale(0.4); }
  19%      { opacity: 1; transform: translate(calc(var(--dx)*0.35), -14px) scale(1); }
  36%      { opacity: 1; transform: translate(var(--dx), -48px) scale(1); }
  62%      { opacity: 1; transform: translate(var(--dx), 74px) scale(1); }
  82%      { opacity: 1; transform: translate(var(--dx), 74px) scale(1); }
  93%,100% { opacity: 0; transform: translate(var(--dx), 74px) scale(0.7); }
}

/* ---- hero smash animation v3 (game-like: swing, crack, coins fall) ---- */
.smash { position: relative; width: 240px; height: 210px; }
.smash .piggy { position:absolute; left:50%; bottom:0; width:150px; margin:0; transform:translateX(-50%); transform-origin:bottom center; animation: hs-piggy 3s ease-in-out infinite; }
.smash .crack { position:absolute; left:50%; bottom:0; width:150px; margin:0; transform:translateX(-50%); opacity:0; animation: hs-crack 3s ease-in-out infinite; z-index:2; }
.smash .coins { position:absolute; left:50%; top:72px; width:0; height:0; }
.smash .coin { position:absolute; left:-18px; top:-18px; width:36px; margin:0; opacity:0; animation: hs-coin 3s ease-in-out infinite; }
.smash .hammer { position:absolute; left:36%; top:16px; width:116px; margin:0; transform-origin:22% 86%; transform:rotate(46deg); animation: hs-hammer 3s ease-in-out infinite; z-index:3; }
@keyframes hs-hammer { 0%,8%{transform:rotate(46deg)} 16%{transform:rotate(-52deg)} 22%{transform:rotate(-44deg)} 32%,100%{transform:rotate(46deg)} }
@keyframes hs-piggy { 0%,14%{transform:translateX(-50%) scale(1,1)} 17%{transform:translateX(-50%) scale(1.13,0.82)} 21%{transform:translateX(-52%) scale(0.94,1.07)} 26%{transform:translateX(-48%) scale(1.02,0.98)} 32%,100%{transform:translateX(-50%) scale(1,1)} }
@keyframes hs-crack { 0%,15%{opacity:0} 18%{opacity:1} 78%{opacity:1} 90%,100%{opacity:0} }
@keyframes hs-coin { 0%,15%{opacity:0; transform:translate(0,0) scale(0.4)} 19%{opacity:1; transform:translate(calc(var(--dx)*0.35),-14px) scale(1)} 36%{opacity:1; transform:translate(var(--dx),-44px) scale(1)} 62%{opacity:1; transform:translate(var(--dx),72px) scale(1)} 82%{opacity:1; transform:translate(var(--dx),72px) scale(1)} 92%,100%{opacity:0; transform:translate(var(--dx),72px) scale(0.7)} }
@media (prefers-reduced-motion: reduce) { .smash .piggy, .smash .hammer, .smash .coin, .smash .crack { animation: none !important; } .smash .hammer { transform: rotate(30deg); } }

/* ---- hero smash animation v4 (hit, crack, hit, break, coins drop in place) ---- */
.smash { position: relative; width: 240px; height: 210px; }
.smash .piggy { position:absolute; left:50%; bottom:0; width:150px; margin:0; transform:translateX(-50%); transform-origin:bottom center; animation: hs2-piggy 4.5s ease-in-out infinite; }
.smash .crack { position:absolute; left:50%; bottom:0; width:150px; margin:0; transform:translateX(-50%); opacity:0; z-index:2; animation: hs2-crack 4.5s ease-in-out infinite; }
.smash .coins { position:absolute; left:50%; top:auto; bottom:34px; width:0; height:0; z-index:4; }
.smash .coin { position:absolute; left:-17px; top:-17px; width:34px; margin:0; opacity:0; z-index:4; animation: hs2-coin 4.5s ease-in-out infinite; }
.smash .hammer { position:absolute; left:36%; top:16px; width:116px; margin:0; transform-origin:22% 86%; transform:rotate(46deg); z-index:3; animation: hs2-hammer 4.5s ease-in-out infinite; }
@keyframes hs2-hammer { 0%,7%{transform:rotate(46deg)} 13%{transform:rotate(-52deg)} 22%{transform:rotate(46deg)} 35%{transform:rotate(-52deg)} 44%,100%{transform:rotate(46deg)} }
@keyframes hs2-piggy { 0%,11%{transform:translateX(-50%) scale(1,1); opacity:1} 14%{transform:translateX(-50%) scale(1.1,0.85)} 20%{transform:translateX(-50%) scale(1,1)} 36%{transform:translateX(-50%) scale(1.14,0.8); opacity:1} 39%{transform:translateX(-50%) scale(1.25,0.6); opacity:0} 86%{opacity:0} 91%{transform:translateX(-50%) scale(1,1); opacity:1} 100%{transform:translateX(-50%) scale(1,1); opacity:1} }
@keyframes hs2-crack { 0%,13%{opacity:0} 16%{opacity:1} 37%{opacity:1} 39%,100%{opacity:0} }
@keyframes hs2-coin { 0%,37%{opacity:0; transform:translate(0,-30px) scale(0.4)} 41%{opacity:1; transform:translate(calc(var(--dx)*0.7),-40px) scale(1)} 56%{opacity:1; transform:translate(var(--dx),0) scale(1)} 80%{opacity:1; transform:translate(var(--dx),0) scale(1)} 88%,100%{opacity:0; transform:translate(var(--dx),0) scale(0.85)} }
@media (prefers-reduced-motion: reduce) { .smash .piggy, .smash .hammer, .smash .coin, .smash .crack { animation: none !important; } .smash .hammer { transform: rotate(30deg); } }

/* ---- stacked feature sections + the numbers strip ---- */
.features + .features { padding-top: 0; }
.features .sub { margin-bottom: 0; }
.features h2 + .sub { margin-top: 4px; }

/* The one prose section on the page. `.features .sub` zeroes its bottom margin
   (it exists to sit tight under an h2 as a one-line deck), so two stacked
   paragraphs ran together; and `.features` only centres its h2, which left
   multi-line body copy ragged-right under a centred heading while every card on
   the page centres its text. Both are re-stated here rather than changed at
   source, because the one-line-deck behaviour is right everywhere else. */
.fair { text-align: center; }
.fair .sub { margin-bottom: 16px; }
.fair .sub:last-child { margin-bottom: 0; }

.numbers { padding: 8px 0 66px; }
.numbers ul {
  list-style: none; display: flex; flex-wrap: wrap;
  justify-content: center; gap: 12px 14px;
}
.numbers li {
  background: var(--paper); border: 3px solid var(--ink); border-radius: 999px;
  box-shadow: 0 4px 0 var(--ink);
  padding: 8px 20px; font-size: 15px; font-weight: 600; color: var(--ink-soft);
}
.numbers li:nth-child(odd)  { transform: rotate(-1.5deg); }
.numbers li:nth-child(even) { transform: rotate(1.5deg); }
.numbers b { font-size: 21px; font-weight: 700; color: var(--berry-dark); margin-right: 5px; }

/* ---- hero smash animation v5: the game's actual break ----------------------
   Ported from Views/MenuPiggy.swift. Two things the earlier versions got
   wrong. First, damage is drawn INTO the body art — the game swaps the whole
   sprite as HP drops (PiggyType.damageSprite), so the cracks spread and the
   piggy comes apart, rather than one doodle fading in on a pristine body.
   Second, it breaks into shards (SmashBurst), not thin air.
   Hammer geometry is the game's: pivot on the grip at (0.82, 0.84), resting
   at +50 degrees, winding back to +74, landing at +10. Nudge those three and
   nothing else if the contact point ever needs moving.                      */

.smash {
  --h: 132px;                        /* piggy height; everything derives from it */
  position: relative;
  width: calc(var(--h) * 2.3); height: calc(var(--h) * 1.6);
}

/* ---- body: five stacked frames, one visible at a time ---- */
.smash .pig {
  position: absolute; left: calc(50% - var(--h) * 0.20); bottom: 0;
  width: calc(var(--h) * 1.128); height: var(--h);
  transform-origin: bottom center; translate: -50% 0;
  animation: hs5-pig 6s linear infinite;
}
.smash .body {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; margin: 0; opacity: 0;
  animation: 6s steps(1, end) infinite;
}
.smash .s0 { animation-name: hs5-s0; }
.smash .s1 { animation-name: hs5-s1; }
.smash .s2 { animation-name: hs5-s2; }
.smash .s3 { animation-name: hs5-s3; }
.smash .s4 { animation-name: hs5-s4; }

@keyframes hs5-s0 { 0%,9.1%{opacity:1} 9.2%,79.9%{opacity:0} 80%,100%{opacity:1} }
@keyframes hs5-s1 { 0%,9.1%{opacity:0} 9.2%,21.6%{opacity:1} 21.7%,100%{opacity:0} }
@keyframes hs5-s2 { 0%,21.6%{opacity:0} 21.7%,34.1%{opacity:1} 34.2%,100%{opacity:0} }
@keyframes hs5-s3 { 0%,34.1%{opacity:0} 34.2%,46.6%{opacity:1} 46.7%,100%{opacity:0} }
@keyframes hs5-s4 { 0%,46.6%{opacity:0} 46.7%,48.4%{opacity:1} 48.5%,100%{opacity:0} }

/* Squash on the wind-up, harder squash on impact, overshoot, settle — then
   scale away to 0.4 and fade, which is the game's break transition. */
@keyframes hs5-pig {
  0%,3.3%   { transform: scale(1,1) rotate(0deg);          opacity: 1 }
  8%        { transform: scale(1.10,0.92) rotate(2.5deg);  opacity: 1 }
  9.2%      { transform: scale(1.14,0.86) rotate(0deg);    opacity: 1 }
  12%       { transform: scale(0.97,1.04) rotate(0deg) }
  15.8%     { transform: scale(1,1) rotate(0deg) }
  20.5%     { transform: scale(1.10,0.92) rotate(2.5deg) }
  21.7%     { transform: scale(1.14,0.86) rotate(0deg) }
  24.5%     { transform: scale(0.97,1.04) rotate(0deg) }
  28.3%     { transform: scale(1,1) rotate(0deg) }
  33%       { transform: scale(1.10,0.92) rotate(2.5deg) }
  34.2%     { transform: scale(1.14,0.86) rotate(0deg) }
  37%       { transform: scale(0.97,1.04) rotate(0deg) }
  40.8%     { transform: scale(1,1) rotate(0deg) }
  45.5%     { transform: scale(1.10,0.92) rotate(2.5deg) }
  46.7%     { transform: scale(1.16,0.84) rotate(0deg);    opacity: 1 }
  48.5%     { transform: scale(1.16,0.84) rotate(0deg);    opacity: 1 }
  50.8%     { transform: scale(0.4,0.4) rotate(0deg);      opacity: 0 }
  80%       { transform: scale(0.4,0.4) rotate(0deg);      opacity: 0 }
  87%,100%  { transform: scale(1,1) rotate(0deg);          opacity: 1 }
}

/* ---- hammer: rest 50deg, wind back to 74, snap down to 10 ---- */
.smash .hammer {
  position: absolute; left: calc(50% + var(--h) * 0.46); bottom: calc(var(--h) * 0.14);
  width: calc(var(--h) * 0.883); height: auto; margin: 0;
  translate: -50% 0;
  transform-origin: 82% 84%; transform: rotate(50deg);
  z-index: 3;
  animation: hs5-hammer 6s infinite;
}
@keyframes hs5-hammer {
  0%,3.3%   { transform: rotate(50deg); animation-timing-function: linear }
  8%        { transform: rotate(74deg); animation-timing-function: ease-in }
  9.2%      { transform: rotate(10deg); animation-timing-function: ease-out }
  15.8%     { transform: rotate(50deg); animation-timing-function: linear }
  20.5%     { transform: rotate(74deg); animation-timing-function: ease-in }
  21.7%     { transform: rotate(10deg); animation-timing-function: ease-out }
  28.3%     { transform: rotate(50deg); animation-timing-function: linear }
  33%       { transform: rotate(74deg); animation-timing-function: ease-in }
  34.2%     { transform: rotate(10deg); animation-timing-function: ease-out }
  40.8%     { transform: rotate(50deg); animation-timing-function: linear }
  45.5%     { transform: rotate(74deg); animation-timing-function: ease-in }
  46.7%     { transform: rotate(10deg); animation-timing-function: ease-out }
  53.3%,100%{ transform: rotate(50deg) }
}

/* ---- the break: a flash and ten chips of whatever it was made of ---- */
.smash .burst {
  position: absolute; left: calc(50% - var(--h) * 0.20); bottom: calc(var(--h) * 0.38);
  width: 0; height: 0; z-index: 2;
}
.smash .spark {
  position: absolute; left: -65px; top: -65px; width: 130px; height: 130px;
  margin: 0; opacity: 0; animation: hs5-spark 6s ease-out infinite;
}
@keyframes hs5-spark {
  0%,48.4%   { opacity: 0;   transform: scale(0.34) }
  48.5%      { opacity: .95; transform: scale(0.34) }
  57.2%,100% { opacity: 0;   transform: scale(1) }
}
.smash .burst i {
  position: absolute; opacity: 0; border: 2px solid var(--ink);
  animation: hs5-shard 6s ease-out infinite;
}
.smash .chip {
  width: var(--s); height: calc(var(--s) * 0.8);
  margin: calc(var(--s) * -0.4) 0 0 calc(var(--s) * -0.5);
  background: var(--blush); border-radius: 3px;
}
.smash .cap {
  width: calc(var(--s) * 1.1); height: calc(var(--s) * 0.65);
  margin: calc(var(--s) * -0.325) 0 0 calc(var(--s) * -0.55);
  background: var(--paper); border-radius: 999px;
}
@keyframes hs5-shard {
  0%,48.4%   { opacity: 0; transform: translate(0,0) rotate(0deg) scale(1) }
  48.5%      { opacity: 1; transform: translate(0,0) rotate(0deg) scale(1) }
  57.2%,100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--r)) scale(0.65) }
}

/* ---- coins, thrown on the break and left on the table ---- */
.smash .coins {
  position: absolute; left: calc(50% - var(--h) * 0.20); bottom: calc(var(--h) * 0.24);
  width: 0; height: 0; z-index: 4;
}
.smash .coin {
  position: absolute; left: -18px; top: -18px; width: 36px; height: 36px;
  margin: 0; opacity: 0; animation: hs5-coin 6s ease-out infinite;
}
@keyframes hs5-coin {
  0%,47%   { opacity: 0; transform: translate(0,0) scale(0.4) }
  50%      { opacity: 1; transform: translate(calc(var(--dx) * 0.6), -34px) scale(1) }
  57%      { opacity: 1; transform: translate(var(--dx), -46px) scale(1) }
  68%      { opacity: 1; transform: translate(var(--dx), 6px) scale(1) }
  74%      { opacity: 1; transform: translate(var(--dx), 6px) scale(1) }
  79%,100% { opacity: 0; transform: translate(var(--dx), 6px) scale(0.8) }
}

.hero-art { min-height: calc(132px * 1.6); }
@media (max-width: 520px) { .smash { --h: 104px; } .hero-art { min-height: 168px; } }

/* Frozen, it should still read as "hammer, cracked piggy, coins". */
@media (prefers-reduced-motion: reduce) {
  .smash .pig, .smash .body, .smash .hammer, .smash .coin,
  .smash .spark, .smash .burst i { animation: none !important; }
  .smash .pig { transform: scale(1,1) }
  .smash .s2 { opacity: 1 }
  .smash .hammer { transform: rotate(28deg) }
  .smash .spark { opacity: 0 }
  .smash .coin { opacity: 1; transform: translate(var(--dx), 6px) }
}

/* ---- press kit (press.html) ------------------------------------------- */
.kit-cta { text-align: center; margin: 22px 0 4px; }

.facts { width: 100%; border-collapse: collapse; margin-top: 6px; }
.facts th, .facts td { text-align: left; padding: 9px 6px; vertical-align: top;
  border-bottom: 2px dotted rgba(74,51,41,.22); }
.facts th { width: 38%; color: var(--berry-dark); font-weight: 700; white-space: nowrap; }
.facts tr:last-child th, .facts tr:last-child td { border-bottom: 0; }

.small-note { font-size: 14px; color: var(--ink-soft); margin-top: 12px; }

.page h3 { font-size: 16px; font-weight: 700; margin: 18px 0 4px;
  color: var(--gold-dark); text-transform: uppercase; letter-spacing: .5px; }

.page blockquote { margin: 0; padding: 14px 16px; background: var(--cream);
  border: 3px solid var(--ink); border-radius: 16px; box-shadow: 0 4px 0 var(--ink); }
.page blockquote p:last-child { margin-bottom: 0; }

/* Screenshots are 1320x2868 and there are six: a fixed 3-up would be a wall of
   thumbnails on a phone, so let them reflow and cap the height instead. */
.shotgrid, .artgrid { display: grid; gap: 14px; margin-top: 14px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.artgrid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); align-items: center; }
.shotgrid img, .artgrid img { width: 100%; height: auto; display: block;
  border: 3px solid var(--ink); border-radius: 14px; box-shadow: 0 5px 0 var(--ink);
  background: var(--paper); }
.artgrid img { padding: 10px; }
.artgrid img.icon { max-width: 180px; margin: 0 auto; }
.shotgrid a:active img, .artgrid a:active img { transform: translateY(3px);
  box-shadow: 0 2px 0 var(--ink); }

.swatches { list-style: none; padding-left: 0; display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.swatches li { display: flex; align-items: center; gap: 9px; font-size: 15px; }
.swatches i { width: 26px; height: 26px; flex: 0 0 auto; border-radius: 8px;
  border: 2px solid var(--ink); }
.swatches code { color: var(--ink-soft); font-size: 13px; }

/* ---- narrow screens ----
   This used to stack the header into two rows, because the brand text plus
   three nav links overflowed a 390px viewport and the nowrap row gave the whole
   PAGE a horizontal scrollbar. The brand is now a 36px icon, which frees about
   150px — the header fits one row down to 320px and the stacking is gone. */
@media (max-width: 560px) {
  /* The CTA needs the room. Privacy and Press stay one tap away in the footer. */
  nav a[href$="privacy.html"] { display: none; }
  .facts th { white-space: normal; width: 42%; }
  .kit-cta .btn { display: block; }
  /* One card per row down here, so the 320px cap that centres a short row on a
     wide screen would just inset every card behind pointless gutters. */
  .card { max-width: 100%; }
}

/* ---- 320-400px: the smallest phones still in the wild (SE, older Androids) --
   Nothing here is decorative; it is the margin that keeps the header on one
   row and the page free of a horizontal scrollbar at 320px. */
@media (max-width: 400px) {
  .wrap { --gutter: 16px; }
  nav a[href$="press.html"] { display: none; }
  header .header-cta { padding: 7px 11px; margin-left: 12px; }
  nav a { margin-left: 14px; font-size: 15px; }
}

/* ---- landscape phone -------------------------------------------------------
   The only breakpoint keyed on HEIGHT. Everything in the hero is sized against
   viewport WIDTH, which in landscape is the long edge — so the wordmark and the
   portrait video both try to grow while there is less room than ever. Cap both
   against the short edge instead and cut the padding to almost nothing. */
@media (orientation: landscape) and (max-height: 500px) {
  .hero { padding: 12px 0 24px; }
  .hero .logo { width: min(360px, 60vw, 22vh * 3.284); margin-bottom: 8px; }
  .sub { margin-bottom: 16px; font-size: 15px; }
  .preview { width: auto; margin-top: 18px; }
  .preview video { width: auto; height: 62vh; max-height: 62vh; margin: 0 auto; }
  .hero-art { min-height: 0; transform: scale(0.8); transform-origin: top center; }
  /* Still sticky, because "Get the game" is the reason the bar exists, but
     half the height: 79px of a 390px-tall viewport was a fifth of the screen. */
  header { padding: 7px 0; }
  header .brand img { width: 30px; height: 30px; }
  header .header-cta { padding: 5px 12px; }
}

/* ---- coin shower ----------------------------------------------------------
   Every so often a handful of coins falls past the page, then it goes quiet
   again. Scattering, timing and the length of the quiet spell are picked in JS
   (index.html) and handed down as custom properties; the motion itself is CSS,
   so it runs off the compositor and costs nothing while it plays.

   The layer sits BEHIND the content — header/main/footer are lifted to z-index
   1 for it — so a coin passes behind the cards and screenshots instead of over
   the copy. Most of the page is transparent, so they are still plainly there;
   they just have somewhere to go. It never takes a pointer event.

   Two nested elements because one cannot animate `transform` twice: the span
   falls (and drifts), the image inside it spins. */
.coinfall {
  position: fixed; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
main, footer { position: relative; z-index: 1; }
/* Not in the rule above on purpose. `header` there beat `position: sticky`
   declared earlier and quietly un-stuck the header everywhere; sticky is a
   positioned value, so its own z-index:10 already clears the coin layer. */

.coinfall .drop {
  position: absolute; top: -14vh; left: var(--x);
  margin-left: calc(var(--size) * -0.5);
  animation: coin-fall var(--dur) linear forwards;
}
.coinfall .drop img {
  display: block; width: var(--size); height: auto; margin: 0;
  animation: coin-flip var(--spindur) linear infinite;
  filter: drop-shadow(0 2px 0 rgba(74, 51, 41, 0.16));
}

/* Y is spaced out rather than even so the coin reads as accelerating under a
   linear clock; X wanders either side of the line it started on. */
@keyframes coin-fall {
    0% { transform: translate(0, 0); opacity: 0; }
    7% { opacity: 1; }
   25% { transform: translate(var(--sway), 16vh); }
   50% { transform: translate(calc(var(--sway) * -0.6), 42vh); }
   75% { transform: translate(calc(var(--sway) * 0.8), 74vh); }
   93% { opacity: 1; }
  100% { transform: translate(0, 122vh); opacity: 0; }
}
@keyframes coin-flip { to { transform: rotate(var(--spin)); } }

@media (prefers-reduced-motion: reduce) { .coinfall { display: none; } }


/* ---- the hero piggy takes a tap (smash.js) ---------------------------------
   .is-manual stops the six-second loop and hands the same frames, hammer and
   shards to the visitor. data-hit picks the body frame; .winding and .hitting
   are the two halves of one swing; .broken plays the break once. */
.smash { cursor: pointer; user-select: none; -webkit-user-select: none; touch-action: manipulation;
         -webkit-tap-highlight-color: transparent; border-radius: 18px; }
.smash:focus-visible { outline: 3px solid var(--berry); outline-offset: 8px; }
.smash.is-manual .pig, .smash.is-manual .body, .smash.is-manual .hammer,
.smash.is-manual .spark, .smash.is-manual .burst i, .smash.is-manual .coin { animation: none; }
.smash.is-manual .body { opacity: 0; }
.smash.is-manual[data-hit="0"] .s0, .smash.is-manual[data-hit="1"] .s1, .smash.is-manual[data-hit="2"] .s2,
.smash.is-manual[data-hit="3"] .s3, .smash.is-manual[data-hit="4"] .s4 { opacity: 1; }
.smash.is-manual .pig { transform: scale(1,1); opacity: 1; transition: transform .11s ease-out, opacity .3s ease-out; }
.smash.is-manual.hitting .pig { transform: scale(1.14, 0.86); }
.smash.is-manual .hammer { transform: rotate(50deg); transition: transform .09s ease-out; }
.smash.is-manual.winding .hammer { transform: rotate(74deg); transition-timing-function: ease-in; }
.smash.is-manual.hitting .hammer { transform: rotate(10deg); }
.smash.is-manual.broken .pig { transform: scale(0.4, 0.4); opacity: 0; transition-delay: .12s; }
.smash.is-manual.broken .spark { animation: manual-spark .5s ease-out .1s forwards; }
.smash.is-manual.broken .burst i { animation: manual-shard .5s ease-out .1s forwards; }
.smash.is-manual.broken .coin { animation: manual-coin 1.3s ease-out .1s forwards; }
@keyframes manual-spark { from { opacity: .95; transform: scale(0.34) } to { opacity: 0; transform: scale(1) } }
@keyframes manual-shard { from { opacity: 1; transform: none } to { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--r)) scale(0.65) } }
@keyframes manual-coin {
  0%   { opacity: 0; transform: translate(0, -30px) scale(0.4) }
  18%  { opacity: 1; transform: translate(calc(var(--dx) * 0.7), -44px) scale(1) }
  50%  { opacity: 1; transform: translate(var(--dx), 0) scale(1) }
  85%  { opacity: 1; transform: translate(var(--dx), 0) scale(1) }
  100% { opacity: 0; transform: translate(var(--dx), 0) scale(0.85) }
}
.cta.store.pulse .storebadge { animation: badge-pulse .55s ease-out 2; }
@keyframes badge-pulse { 0%,100% { transform: scale(1) } 40% { transform: scale(1.07) } }
@media (prefers-reduced-motion: reduce) {
  .smash.is-manual .pig, .smash.is-manual .hammer { transition: none; }
  .smash.is-manual.broken .spark, .smash.is-manual.broken .burst i, .smash.is-manual.broken .coin,
  .cta.store.pulse .storebadge { animation: none; }
  .smash.is-manual.broken .coin { opacity: 1; transform: translate(var(--dx), 0); }
}

/* ---- only the badge this visitor can use --------------------------------
   The head script tags <html> with is-ios / is-android / is-desktop before
   paint. Both badges stay in the markup; the one that cannot apply is hidden,
   and the row is capped at the width that badge has when it sits in a pair,
   so a lone badge is not blown up to fill the pair's space. The more-games
   page keeps both on purpose: those rows describe other apps. */
.is-ios .hero .cta.store .google, .is-ios main > .cta.store .google,
.is-android .hero .cta.store .apple, .is-android main > .cta.store .apple { display: none; }
.is-ios .hero .cta.store, .is-ios main > .cta.store { max-width: min(172px, calc(47.09% - 8px)); }
.is-android .hero .cta.store, .is-android main > .cta.store { max-width: min(193px, calc(52.91% - 8px)); }


/* ---- the screenshot strip: the loop in three steps -------------------- */
.shots figure { margin: 0; width: 220px; max-width: 44vw; text-align: center; }
.shots figure img { width: 100%; max-width: none; }
.shots figure:nth-child(2) img { transform: rotate(1.5deg) translateY(-10px); }
.shots figure:nth-child(3) img { transform: rotate(-1deg); }
.shots figcaption { margin-top: 16px; font-size: 14px; line-height: 1.35; color: var(--ink-soft); padding: 0 6px; }
.shots figcaption b {
  display: inline-grid; place-items: center; width: 22px; height: 22px; margin-right: 6px;
  border-radius: 50%; background: var(--gold); border: 2px solid var(--ink);
  font-size: 12px; color: var(--ink); vertical-align: -5px;
}

/* ---- scroll-driven reveals -----------------------------------------------
   Cards and the strip fade up as they enter the viewport. Browsers without
   view() timelines, and anyone who asked for less motion, get the page as it
   was: fully visible, no animation. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .card, .shots figure { animation: reveal linear both; animation-timeline: view(); animation-range: entry 0% entry 35%; }
  }
}
@keyframes reveal { from { opacity: 0.15; transform: translateY(22px) } to { opacity: 1; transform: none } }

/* ---- button rows: the "longer version" links, as things you can press ---- */
.btn-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; margin: 22px 0 6px; }
.features .btn-row { margin-top: 26px; }
.page .btn-row { margin-top: 26px; }
.page .btn-row .btn { font-weight: 700; }
.btn:hover { filter: brightness(1.04); }
@media (max-width: 560px) { .btn-row .btn { display: block; width: 100%; max-width: 360px; text-align: center; box-sizing: border-box; } }

/* ---- two-column hero ----------------------------------------------------
   Copy, badges, price line and the piggy on the left; the video on the right.
   Left column is the wider one because it holds the wordmark. Under 860px
   the grid is gone and the source order stacks, centred, as before. */
@media (min-width: 860px) {
  .hero { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: 24px 48px;
          align-items: center; text-align: left; padding-bottom: 28px; }
  .hero-copy .sub, .hero-copy .cta.store { margin-left: 0; margin-right: 0; }
  .hero-copy .cta.store { justify-content: flex-start; }
  .hero .logo { margin-left: 0; }
  /* Bounded by the viewport's HEIGHT, not just its width: a 320px-wide phone
     frame is 693px tall, which pushed the wordmark 200px down the column to
     centre it against nothing. */
  .hero-media .preview { margin: 0 auto; width: min(320px, 100%); }
  .hero-media .preview video { max-height: 68vh; width: auto; margin: 0 auto; }
  /* The wordmark no longer has the page to itself, so it is sized to the copy
     beside it rather than to the column it sits in. */
  .hero .logo { width: min(380px, 100%, 26vh * 3.284); }
}

/* The price line is a footnote to the badges above it, not a paragraph: small,
   narrow, and out of the way of the wordmark and the buttons. */
.soon { font-size: 12.5px; line-height: 1.45; max-width: 44ch; margin-top: 12px; }
.hero-copy .soon { margin-left: 0; margin-right: 0; }

/* Down from the fold and centred under both columns. */
.hero-art { margin: 8px auto 34px; }

/* Five card sections in a row read as one long block, so each one gets a
   little more room above its heading than between its own cards. */
.features + .features { border-top: 2px dashed rgba(74, 51, 41, 0.16); padding-top: 34px; }
.features.fair, .numbers { border-top: 2px dashed rgba(74, 51, 41, 0.16); padding-top: 34px; }

/* ---- phone density -------------------------------------------------------
   Nothing is hidden or removed here; the same cards and the same screenshots
   are laid out for a narrow screen instead of being the desktop layout at
   one per row. Between them these two blocks take about three phone screens
   off the page. */
@media (max-width: 560px) {
  .card { display: grid; grid-template-columns: 52px 1fr; gap: 0 14px; align-items: start; text-align: left; padding: 16px 18px; }
  .card .ic { width: 52px; height: 52px; padding: 9px; margin: 0; grid-row: span 2; }
  .card h3 { margin: 0 0 2px; align-self: center; }
  .card p { text-align: left; margin: 0; }

  /* The three steps become a swipeable strip. Snap points and a visible
     sliver of the next card make it read as scrollable without a hint. */
  .shots { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory;
           gap: 14px; margin-inline: calc(var(--gutter) * -1);
           padding: 10px var(--gutter) 26px; scroll-padding-inline: var(--gutter);
           -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .shots::-webkit-scrollbar { display: none; }
  .shots figure { flex: 0 0 68vw; width: 68vw; max-width: none; scroll-snap-align: center; }
  .shots figure img { transform: none !important; }
  .shots figcaption { margin-top: 12px; }
}
