/* Poppinjay website: the page layer on top of tokens.css and components.css (the pj-* design system).
   Everything here is what the approved design wrote inline (design/*.dc.html), moved into classes. */

/* ---- fonts, self-hosted: no request ever leaves the site (the brand promise is "collects nothing") ---- */
@font-face {
  /* Lilita One, the game's own file, unmodified: its OFL reserves the name, so never subset or convert it */
  font-family: "Lilita One";
  src: url("../fonts/LilitaOne-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  /* Fredoka, the official variable font (weights 300-700): the prose style needs 500, the game ships only 600/700 */
  font-family: "Fredoka";
  src: url("../fonts/Fredoka-Variable.ttf") format("truetype-variations"),
       url("../fonts/Fredoka-Variable.ttf") format("truetype");
  font-weight: 300 700;
  font-stretch: 75% 125%;
  font-style: normal;
  font-display: swap;
}

/* ---- the ground ---- */
*, *::before, *::after { box-sizing: border-box; }
/* The canvas under the page is SKY, like the body: iOS Safari tints its status bar from it, and a grass canvas put a green
   strip above every page (the operator's iPhone, 2026-10-28: "The bleed above the page is really ugly"). */
html { background: var(--sky); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* ...and GRASS once the page is scrolled into its bottom half (assets/js/ground.js), so a pull past the footer shows the
   ground carrying on, not a sky band (the operator, 2026-10-30). A fixed grass panel behind the page (2026-10-28) showed
   through Safari's see-through bottom toolbar. */
html.pj-ground-grass { background: var(--grass); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; background: linear-gradient(var(--sky), var(--sky)); }
a { color: var(--plum); }
a:hover { color: var(--plum); }
img { max-width: 100%; }
.pj-page { min-height: 100vh; overflow-x: clip; display: flex; flex-direction: column; }
.pj-page > main { flex: 1 0 auto; }
/* A .wrap that is itself a flex item of the page would shrink to its content (auto margins beat
   stretch), so there it spans the page and centres its content with padding instead. */
.pj-page > .wrap {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  margin-inline: 0;
  padding-left: max(var(--gutter), env(safe-area-inset-left, 0px), calc((100% - var(--page-max)) / 2));
  padding-right: max(var(--gutter), env(safe-area-inset-right, 0px), calc((100% - var(--page-max)) / 2));
}
/* On a page that is all sky, the footer's hills stand on the page's own golden horizon: no seam. */
.pj-sky > .pj-footer { background: transparent; }
[id] { scroll-margin-top: 16px; }

.wrap {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
  padding-right: max(var(--gutter), env(safe-area-inset-right, 0px));
  box-sizing: content-box;
}

.skip {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 10;
  padding: 12px 18px;
  background: var(--cream);
  color: var(--plum);
  border: var(--stroke-outline) solid var(--plum);
  border-radius: var(--radius-sm);
  font-weight: 700;
  text-decoration: none;
}
.skip:focus { top: 12px; outline: 3px solid var(--focus); outline-offset: 3px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---- the header: one row on a desktop, the brand above the links on a phone ---- */
.pj-header__brand { min-height: var(--touch); }
.pj-header__link { display: inline-flex; align-items: center; min-height: var(--touch); padding-block: 0; }
@media (max-width: 719px) {
  .pj-header { justify-content: center; row-gap: 4px; }
  .pj-header__nav { justify-content: center; column-gap: 20px; row-gap: 4px; }
}
@media (max-width: 419px) {
  /* the home page's whole nav: at phone width the hero's own Get the game button is right below it, and Privacy is in
     the footer. The other pages keep theirs, since it is how a reader gets back. */
  .pj-header__nav--home { display: none; }
}

/* ---- type helpers the design set inline ---- */
.lede { margin: 0; font-size: 18px; line-height: 28px; }
.lede--hero { font-size: 20px; line-height: 30px; max-width: 30em; }
.lede--narrow { max-width: 36em; }
.copy { margin: 0; }
.plain-list { list-style: none; margin: 0; padding: 0; }
.lede--get { max-width: 34em; }
.band__inner--32 { gap: 32px; }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-row--centre { justify-content: center; gap: 12px; }
.chip-start { justify-self: start; margin: 0; }
.pj-chip__dot--coral { background: var(--coral); }
.pj-chip__dot--tangerine { background: var(--tangerine); }
.pj-chip__dot--mint { background: var(--mint); }
.pj-chip__dot--sky-blue { background: var(--sky-blue); }
.pj-chip__dot--grape { background: var(--grape); }
.pj-chip__dot--bubblegum { background: var(--bubblegum); }
.button-row { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }
/* phones: the hero's two buttons share one line (the operator, 2026-11-05, on the iPhone 17 Pro's 402 px: "Get the game
   and See how it plays in a single line"). At 180 px minimum, a 16 px gap and the 16 px face padding they needed 379 px
   of the 370 px row; without the minimum and with 12 px padding and a 10 px gap they fit down to 375 px wide phones,
   each growing to fill the row. Narrower (360 px) the row still wraps, each full width, so nothing is squeezed or clipped. */
@media (max-width: 719px) {
  .hero__copy .button-row { gap: 10px; }
  .hero__copy .button-row .pj-button { flex: 1 1 auto; min-width: 0; }
  .hero__copy .button-row .pj-button__face { padding-inline: 12px; }
}
.band-head { display: grid; gap: 16px; justify-items: center; text-align: center; }
.centre { text-align: center; }

/* ---- the hero: the title screen's sky over two hills ---- */
.hero-sky { position: relative; overflow: hidden; }
.hero-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 48px;
  padding-block: 56px 200px;
  position: relative;
  z-index: 1;
}
.hero__copy { flex: 1 1 380px; min-width: 0; display: grid; gap: 24px; }
.hero__word { font-size: 88px; line-height: 88px; }
/* the hero's card, the gameplay clip: straight, no tilt (the operator, 2026-10-28: "It could be straight, no need to
   slant it"), in the box the old still had (the operator: "Use the existing card size") */
.hero__shot { flex: 1.3 1 460px; min-width: 0; }
.hero__hills { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 220px; display: block; }
.hills__far { fill: var(--grass-far); stroke: var(--plum); stroke-width: 3; }
.hills__near { fill: var(--grass); stroke: var(--plum); stroke-width: 3; }

/* ---- bands ---- */
.band { padding-block: var(--space-80); }
.band__inner { display: grid; gap: var(--space-40); }
.band--grass { background: var(--grass); padding-block: var(--space-24) var(--space-80); }
.band--dawn { background: var(--sky-dawn); border-block: var(--stroke-outline) solid var(--plum); }
.band--cream { background: var(--cream); border-block: var(--stroke-outline) solid var(--plum); }
.band--sky { background: var(--sky); padding-block: 0 var(--space-80); }
.band--get { padding-block: var(--space-80) 120px; border-top: var(--stroke-outline) solid var(--plum); }

.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 32px; }
.grid-gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 32px 28px; }
.grid-panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); gap: 32px; align-items: start; }
.grid-offer { align-items: stretch; }
.card { display: grid; gap: 16px; align-content: start; }
.card--tight { gap: 12px; }
.pj-panel--dawn { background: var(--sky-dawn); }
.tilt-left { transform: rotate(-1deg); }
.tilt-right { transform: rotate(1deg); }

/* ---- collect ---- */
.collect { display: flex; flex-wrap: wrap; gap: 48px; align-items: center; }
.collect__shot { flex: 1.3 1 460px; min-width: 0; transform: rotate(-1.5deg); }
.collect__copy { flex: 1 1 340px; min-width: 0; display: grid; gap: 20px; }

/* the comfy list borrows the legal list's balloon bullets, at full panel width */
.balloon-list { max-width: none; display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }

/* ---- get the game ---- */
.get { display: grid; gap: var(--space-24); justify-items: center; text-align: center; }
.get__icon { width: 120px; height: 120px; border: var(--stroke-outline) solid var(--plum); border-radius: 28px; box-shadow: var(--shadow-lift); display: block; }
.badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; margin: 0; padding: 0; list-style: none; }
.badge-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 180px;
  height: 56px;
  border: var(--stroke-outline) dashed var(--plum);
  border-radius: 12px;
  background: var(--cream);
  color: var(--plum);
  font-family: var(--font-rounded);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.6px;
  text-align: center;
}
/* a live store's badge, Google's own artwork as supplied (ASSETS.md): the slot's 180 px width, its height from the
   art's own 564 x 168 ratio (53.6 px, over the 44 px touch target), never stretched */
.badge { display: block; width: 180px; border-radius: 10px; }
.badge img { display: block; width: 100%; height: auto; }
/* Apple's badge as supplied (119.66 x 40, no margin), at the Play badge's height (Apple asks badges side by side to be
   the same height): 53.6 x 2.99 = 160 px wide */
.badge--apple { width: 160px; border-radius: 0; }
.badge:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

/* ---- the footer: links and the maker only; the email lives on the Support page (as selectable text, never a mailto) ---- */
.pj-footer__links a { display: inline-flex; align-items: center; min-height: var(--touch); }
/* The focus token (#2B78E6) is 2.8:1 on grass, under the 3:1 the brand asks of a focus ring on every
   ground; on the footer's grass the ring is plum (8.5:1) instead. */
.pj-footer a:focus-visible { outline-color: var(--plum); }
.pj-footer__small { margin: 0; }
/* the maker: Wizard Coded's logo (the light-ground variant, from the Ra site's press kit) over the copyright line, at the
   footer's right; under the links, centred, once the row wraps on a phone */
.pj-footer__maker { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.pj-footer__logo { display: block; line-height: 0; border-radius: 8px; }
.pj-footer__logo img { display: block; width: 109px; height: 72px; }
@media (max-width: 719px) { .pj-footer__maker { align-items: center; width: 100%; } }
.email { user-select: all; -webkit-user-select: all; }

/* ---- legal pages ---- */
.legal-main { padding-block: var(--space-40) 96px; }
.pj-legal__date { margin: 0; }
.pj-legal__toc a { display: inline-flex; align-items: center; min-height: 44px; padding: 6px 14px; }
.placeholder {
  /* a [PLACEHOLDER] stays visible until the owner fills it (PLACEHOLDERS.md); dashed, like the badge slots */
  background: var(--sky-dawn);
  color: var(--plum);
  font-weight: 700;
  border: 2px dashed var(--plum);
  border-radius: 6px;
  padding: 0 4px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ---- 404 ---- */
.lost { display: grid; gap: var(--space-24); justify-items: center; text-align: center; padding-block: 48px 120px; }
.lost__balloon { width: min(320px, 70vw); height: auto; display: block; }

/* ---- phones ---- */
@media (max-width: 720px) {
  .hero-band { gap: 40px; padding-block: 32px 160px; }
  .hero__word { font-size: 48px; line-height: 52px; }
  .band-title { font-size: 32px; line-height: 36px; }
  .hero__hills { height: 160px; }
  .pj-legal__title { font-size: 32px; line-height: 36px; }
}

/* ======== PROPOSALS (mockup for the owner's review; see PLACEHOLDERS.md rows 10 and 11) ======== */

/* ---- 1. the store row in the hero: the two badge slots, and a QR on desktop widths ---- */
.store-row { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; }
.badges--start { justify-content: flex-start; }
/* desktop: the two slots stacked, the QR card beside them (the copy column is ~470 px wide) */
@media (min-width: 900px) { .badges--start { flex-direction: column; gap: 12px; } }
.qr-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px 8px 8px;
  background: var(--cream);
  border: var(--stroke-outline) solid var(--plum);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
  transform: rotate(-2deg);
}
/* 33 modules (25 + the 4-module quiet zone each side) at 3 css px: 99 px, every module on whole pixels */
.qr__code { display: block; width: 99px; height: 99px; border-radius: var(--radius-sm); }
.qr-card__label { margin: 0; max-width: 7.5em; font-family: var(--font-rounded); font-weight: 700; font-size: 15px; line-height: 19px; color: var(--plum); }
/* a phone cannot scan its own screen: the QR is for a visitor on a computer */
@media (max-width: 899px) {
  .qr-card { display: none; }
  /* phones: the two slots side by side, sharing the column (180 + 16 + 180 is wider than a 360 px phone's 328) */
  .store-row { display: block; }
  .badges--start { flex-wrap: nowrap; gap: 12px; }
  .badges--start .badge-slot { flex: 1 1 0; width: auto; min-width: 0; max-width: 180px; padding-inline: 6px; }
  /* grown in proportion to their widths (160 : 180), so the two badges keep one height when they shrink */
  .badges--start > li:has(.badge) { flex: 180 1 0; min-width: 0; max-width: 180px; }
  .badges--start > li:has(.badge--apple) { flex: 160 1 0; max-width: 160px; }
  .badges--start .badge { width: 100%; }
}

/* ---- 2. Pip, the mascot: the game's own renderer, on transparency (tools/render-pip.sh) ---- */
.pip { display: block; height: auto; pointer-events: none; user-select: none; }
.hero__art { flex: 1.3 1 460px; min-width: 0; position: relative; }
.hero__art .hero__shot { flex: none; }
/* she stands on the near hill below the capture's lower left, clear of it (review: an ear in its corner read as
   a mistake), aiming up at its balloons; her 714 px render is the 2x of 340 css px */
.pip--draw {
  position: absolute;
  z-index: 2;
  width: 340px;
  left: -64px;
  top: calc(100% + 16px);
}
.pip--cheer { width: 290px; flex: none; }
.get-row { display: flex; align-items: center; justify-content: center; gap: 24px 40px; }
.get-row .get { flex: 0 1 640px; min-width: 0; }
@media (prefers-reduced-motion: no-preference) {
  .pip--cheer { animation: pip-bob 2.4s cubic-bezier(0.34, 1.56, 0.64, 1) infinite alternate; }
}
@keyframes pip-bob { from { transform: translateY(0) rotate(-2deg); } to { transform: translateY(-10px) rotate(2deg); } }
@media (max-width: 899px) {
  .hero-band { padding-bottom: 240px; }
  /* phones: below the capture, never over its own little Pip and her arc in its lower left */
  .pip--draw { width: 210px; left: 0; top: calc(100% + 12px); }
  .get-row { flex-direction: column; gap: 8px; }
  .get-row .get { flex: none; width: 100%; }
  .pip--cheer { width: 200px; }
}

/* ---- 3. the bento: one big comfy tile beside two stacked ones, no dead space ---- */
.bento {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  grid-template-rows: auto auto;
  gap: 28px;
}
.bento__tile { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.bento__tile--comfy { grid-row: 1 / 3; }
.bento__copy { display: grid; gap: 10px; align-content: start; }
.bento__shot { margin: 0; }
/* the comfy capture grows to whatever height the two right tiles set, cropping only sky and ground */
.bento__shot--fill { flex: 1 1 auto; min-height: 220px; display: block; }
.bento__shot--fill { position: relative; }
/* absolutely placed so the capture never sets the tile's height: the two right tiles do; it keeps its right side
   (the patterned balloons, the POP and Pip on the right in Mirror World) and crops the far-left sky */
.bento__shot--fill img { position: absolute; inset: 0; height: 100%; object-fit: cover; object-position: 82% 50%; }
.bento__tile--heat .bento__shot { margin-top: auto; }
.bento__tile--private { flex-direction: row; align-items: center; gap: 22px; }
.bento__shot--stamps { flex: 0 0 42%; transform: rotate(-2deg); }
.balloon-list--two { grid-template-columns: 1fr 1fr; column-gap: 24px; row-gap: 8px; }
@media (max-width: 899px) {
  .bento { grid-template-columns: 1fr; grid-template-rows: none; gap: 24px; }
  .bento__tile--comfy { grid-row: auto; }
  .bento__shot--fill { min-height: 0; }
  .bento__shot--fill img { position: static; height: auto; }
  .balloon-list--two { grid-template-columns: 1fr; }
}
@media (max-width: 419px) {
  .bento__tile--private { flex-direction: column; align-items: stretch; }
  .bento__shot--stamps { flex: none; width: 56%; align-self: center; order: 2; }
}

/* ---- 4. the gameplay clip, the hero's card: a 16:9 frame holding the muted, looping capture (assets/js/clip.js) ---- */
.bite-head { display: grid; gap: var(--space-40); justify-items: center; }
.clip { margin: 0; width: 100%; display: block; }
.clip__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: var(--stroke-outline) solid var(--plum);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lift);
  background: var(--sky);
}
/* the poster is an <img> (the hero's first paint, fetchpriority high); the video lies over it, transparent until it has
   a frame. With JS the video stays invisible until it is really playing (is-live), so a loading or refused video never
   blanks the poster; without JS it shows at once, its native controls over the poster */
/* the Wardrobe clip keeps the phone's whole landscape frame (Pip at the far left, the hoods' grid to the far right edge;
   tools/clip/encode-clip.sh FRAME=full): its frame is the encode's own shape, 1560 x 720 */
.clip--wide .clip__frame { aspect-ratio: 1560 / 720; }
.clip__poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.clip__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; background: transparent; }
.clip.is-js .clip__video { opacity: 0; transition: opacity 0.35s cubic-bezier(0.22, 1, 0.36, 1); }
.clip.is-js.is-live .clip__video { opacity: 1; }
/* the play control: a coral balloon-button disc in the clip's bottom-right corner, in EVERY state (the operator,
   2026-10-30: "can we have it on the pause button instead? I really don't want any pop in"): a cream triangle while
   paused, a spinning ring while loading, two cream bars while playing, so the disc itself never moves or resizes and
   only its icon changes. The moving clip can always be stopped from it (WCAG 2.2.2) */
.clip__play {
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 48px;
  height: 48px;
  padding: 0;
  border-radius: 50%;
  background: var(--coral);
  border: var(--stroke-outline) solid var(--plum);
  box-shadow: 0 3px 0 var(--coral-base), 0 3px 0 var(--stroke-outline) var(--plum);
  opacity: 0.92;
  cursor: pointer;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.clip__play[hidden] { display: none; }
.clip__play:hover { transform: scale(1.06); }
.clip__play:active { transform: scale(0.96); }
.clip__play:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* paused: the triangle, nudged right of the disc's centre so it reads as centred (its mass sits in its left third) */
.clip__play::after {
  content: "";
  position: absolute;
  left: 16px;
  top: 11px;
  border-style: solid;
  border-width: 10px 0 10px 16px;
  border-color: transparent transparent transparent var(--cream);
}
.is-playing .clip__play::after {
  left: 13px;
  top: 12px;
  width: 6px;
  height: 18px;
  border: 0;
  border-radius: 2px;
  background: var(--cream);
  box-shadow: 10px 0 0 var(--cream);
}
/* loading (clip.js is-loading): the same corner disc, a cream ring spinning in it, until the first frame is on screen */
.is-loading .clip__play::after {
  left: 12px;
  top: 12px;
  width: 18px;
  height: 18px;
  border: 3px solid var(--cream);
  border-right-color: transparent;
  border-radius: 50%;
  background: none;
  box-shadow: none;
  animation: clip-spin 0.8s linear infinite;
}
@keyframes clip-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .is-loading .clip__play::after { animation: none; } }
/* the sound toggle: the pause disc's twin, always in the corner beside it (left of where the pause disc sits). The clip
   starts muted and only this button unmutes it; the speaker shows its waves when the sound is on (aria-pressed="true")
   and a cross when it is off */
.clip__sound {
  position: absolute;
  right: 70px;
  bottom: 12px;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--coral);
  border: var(--stroke-outline) solid var(--plum);
  box-shadow: 0 3px 0 var(--coral-base), 0 3px 0 var(--stroke-outline) var(--plum);
  color: var(--cream);
  opacity: 0.92;
  cursor: pointer;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.clip__sound[hidden] { display: none; }
.clip__sound:hover { transform: scale(1.06); }
.clip__sound:active { transform: scale(0.96); }
.clip__sound:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.clip__sound svg { display: block; overflow: visible; }
.clip__speaker { fill: currentColor; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.clip__waves, .clip__cross { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.clip__sound[aria-pressed="true"] .clip__cross, .clip__sound[aria-pressed="false"] .clip__waves { display: none; }
@media (max-width: 719px) {
  .clip__play { right: 8px; bottom: 8px; }
  .clip__sound { right: 64px; bottom: 8px; }
}

/* ======== THE SKIES: Picnic Meadow's own sun, faced clouds, hills with their tree lines and bunting ========
   Every piece is the game's drawing code's output on transparency (tools/render-sky.sh, site/assets/img/sky/). They are
   CSS backgrounds on aria-hidden spans: decoration, never content. 1x and 2x copies through image-set(); phones get the
   small strips. Motion is a slow cloud drift and a sun bob, transforms only, and none at all under reduced motion. */
.sky { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
/* :where() keeps this default at a single element's weight, so each piece's own background-size wins: as `.sky > span`
   it outranked .sky__hills and .sky__bunting, whose sizes never applied (the hills stopped short of a wide window) */
:where(.sky) > span { position: absolute; display: block; background-repeat: no-repeat; background-size: contain; }
.sky__sun {
  width: 220px;
  aspect-ratio: 1;
  background-image: url("../img/sky/sun-280.webp");
  background-image: -webkit-image-set(url("../img/sky/sun-280.webp") 1x, url("../img/sky/sun.webp") 2x);
  background-image: image-set(url("../img/sky/sun-280.webp") 1x, url("../img/sky/sun.webp") 2x);
}
.sky__cloud { aspect-ratio: 355 / 212; width: 170px; }
.sky__cloud--1 { background-image: url("../img/sky/cloud-1-sm.webp"); background-image: -webkit-image-set(url("../img/sky/cloud-1-sm.webp") 1x, url("../img/sky/cloud-1.webp") 2x); background-image: image-set(url("../img/sky/cloud-1-sm.webp") 1x, url("../img/sky/cloud-1.webp") 2x); }
.sky__cloud--3 { aspect-ratio: 329 / 212; background-image: url("../img/sky/cloud-3-sm.webp"); background-image: -webkit-image-set(url("../img/sky/cloud-3-sm.webp") 1x, url("../img/sky/cloud-3.webp") 2x); background-image: image-set(url("../img/sky/cloud-3-sm.webp") 1x, url("../img/sky/cloud-3.webp") 2x); }
.sky__cloud--6 { aspect-ratio: 266 / 212; background-image: url("../img/sky/cloud-6-sm.webp"); background-image: -webkit-image-set(url("../img/sky/cloud-6-sm.webp") 1x, url("../img/sky/cloud-6.webp") 2x); background-image: image-set(url("../img/sky/cloud-6-sm.webp") 1x, url("../img/sky/cloud-6.webp") 2x); }
.sky__cloud--8 { aspect-ratio: 363 / 212; background-image: url("../img/sky/cloud-8-sm.webp"); background-image: -webkit-image-set(url("../img/sky/cloud-8-sm.webp") 1x, url("../img/sky/cloud-8.webp") 2x); background-image: image-set(url("../img/sky/cloud-8-sm.webp") 1x, url("../img/sky/cloud-8.webp") 2x); }
/* depth: the far clouds smaller and a little hazed into the sky */
.sky__cloud.is-far { width: 96px; opacity: 0.75; }
.sky__cloud.is-mid { width: 130px; opacity: 0.9; }
/* the hills and their tree lines, hazed: they sit BEHIND the page's own outlined hills, as the game's far layers do */
.sky__hills {
  left: 0;
  right: 0;
  height: 260px;
  opacity: 0.6;
  background-image: url("../img/sky/hills-1600.webp");
  background-image: -webkit-image-set(url("../img/sky/hills-1600.webp") 1x, url("../img/sky/hills.webp") 2x);
  background-image: image-set(url("../img/sky/hills-1600.webp") 1x, url("../img/sky/hills.webp") 2x);
  /* at least 1300 px wide, else the window's width; the box grows with the width (the art is 3168 x 570, 18 % as tall as
     wide), so the tree tops are never cropped. (The hills once stopped ~1445 px wide, short of a wide window's edges:
     the operator's screen, 2026-10-28; see :where(.sky) above.) */
  background-size: 1300px auto;
  background-position: center bottom;
}
@media (min-width: 1300px) { .sky__hills { background-size: 100% auto; height: max(260px, 18vw); } }
.sky__bunting {
  left: 0;
  right: 0;
  top: 4px;
  height: 44px;
  background-image: url("../img/sky/bunting-1200.webp");
  background-image: -webkit-image-set(url("../img/sky/bunting-1200.webp") 1x, url("../img/sky/bunting.webp") 2x);
  background-image: image-set(url("../img/sky/bunting-1200.webp") 1x, url("../img/sky/bunting.webp") 2x);
  /* at least 900 px wide, else the window's width (the art is 2419 x 68, 2.81 % as tall) */
  background-size: 900px auto;
  background-position: center top;
}
@media (min-width: 900px) { .sky__bunting { background-size: 100% auto; height: max(44px, 2.82vw); } }
@media (prefers-reduced-motion: no-preference) {
  /* the game's drift is 0.03-0.08 u/s; here a slow sway out and back, on an eased curve (never linear) */
  .sky__cloud { animation: sky-drift 48s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate; }
  .sky__cloud.is-mid { animation-duration: 64s; animation-delay: -20s; }
  .sky__cloud.is-far { animation-duration: 90s; animation-delay: -45s; }
  .sky__sun { animation: sky-bob 7s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate; }
}
@keyframes sky-drift { from { transform: translateX(-24px); } to { transform: translateX(36px); } }
@keyframes sky-bob { from { transform: translateY(0) scale(1); } to { transform: translateY(-8px) scale(1.03); } }

/* ---- the hero: bunting under the header, the sun over the capture, clouds at three depths, the hazy hills ---- */
.sky--hero .sky__sun { right: 5%; top: 6px; }
.sky--hero .sky__cloud--1 { left: -36px; top: 330px; }
.sky--hero .sky__cloud--6 { left: 41%; top: 54px; }
.sky--hero .sky__cloud--8 { left: 70%; top: 120px; }
.sky--hero .sky__cloud--3 { right: 3%; bottom: 250px; }
.sky--hero .sky__hills { bottom: 80px; }
.hero-band { padding-top: 72px; }

/* ---- "Coming soon": the golden hour, the title screen's low sun over the horizon ---- */
.band--get { position: relative; overflow: hidden; }
.band--get > .wrap { position: relative; z-index: 1; }
.sky--get .sky__sun { width: 280px; right: 5%; bottom: 150px; }
.sky--get .sky__cloud--1 { left: 5%; top: 36px; }
.sky--get .sky__cloud--3 { right: 14%; top: 26%; }
.sky--get .sky__cloud--6 { left: 6%; bottom: 210px; }

/* ---- the blue bands: clouds drifting in the margins ---- */
.band--clouds { position: relative; overflow: clip; }
.band--clouds > .wrap { position: relative; z-index: 1; }
.sky--band .sky__cloud--8 { left: -50px; top: 28px; }
.sky--band .sky__cloud--6 { right: -30px; bottom: 48px; }
.sky--band .sky__cloud--3 { right: 9%; top: 18px; }
.sky--band-b .sky__cloud--1 { right: -40px; top: 40px; }
.sky--band-b .sky__cloud--3 { left: 4%; bottom: 36px; }

/* ---- the footer: a hazy tree line rising behind its outlined hills, on every page ---- */
.pj-footer__hills, .pj-footer__ground { position: relative; z-index: 1; }
/* over main (z-index 1), so its tree line can rise into the sky above the footer */
.pj-page > .pj-footer { z-index: 2; }
.pj-footer::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% - 70px);
  /* the whole strip (3168 x 570: 18 % as tall as wide), so its tree tops are never cut */
  height: calc(max(100vw, 1100px) * 0.18);
  opacity: 0.55;
  pointer-events: none;
  background: url("../img/sky/hills-1600.webp") center bottom / max(100%, 1100px) auto no-repeat;
  background: image-set(url("../img/sky/hills-1600.webp") 1x, url("../img/sky/hills.webp") 2x) center bottom / max(100%, 1100px) auto no-repeat;
}

/* ---- the 404, privacy and terms: their whole page is the sky, so the deco sits at the page's top ---- */
.pj-page { position: relative; }
.pj-page > .wrap, .pj-page > main { position: relative; z-index: 1; }
.sky--page { bottom: auto; height: 760px; }
.sky--page .sky__sun { right: 4%; top: 64px; }
.sky--page .sky__cloud--1 { left: -30px; top: 170px; }
.sky--page .sky__cloud--8 { right: 13%; top: 330px; }
.sky--page .sky__cloud--6 { left: 9%; top: 520px; }
.sky--page .sky__cloud--3 { left: 30%; top: 96px; }

@media (max-width: 719px) {
  .sky__sun { width: 150px; }
  .sky__cloud { width: 120px; }
  .sky__cloud.is-mid { width: 96px; }
  .sky__cloud.is-far { width: 72px; }
  .sky__hills { height: 150px; background-image: url("../img/sky/hills-1600.webp"); background-size: auto 100%; }
  .sky__bunting { height: 26px; background-image: url("../img/sky/bunting-1200.webp"); background-size: auto 100%; background-repeat: repeat-x; }
  .pj-footer::before { height: 120px; bottom: calc(100% - 56px); background: url("../img/sky/hills-1600.webp") center bottom / auto 100% no-repeat; }
  .hero-band { padding-top: 44px; }
  .sky--hero .sky__sun { right: -30px; top: 2px; }
  .sky--hero .sky__cloud--1 { left: -56px; top: auto; bottom: 330px; }
  .sky--hero .sky__cloud--6 { left: 52%; top: 26px; }
  .sky--hero .sky__cloud--8 { display: none; }
  .sky--hero .sky__cloud--3 { right: -20px; bottom: 260px; }
  .sky--hero .sky__hills { bottom: 84px; }
  .sky--get .sky__sun { width: 170px; right: -36px; top: 120px; bottom: auto; }
  .sky--get .sky__cloud--6 { display: none; }
  .sky--page .sky__sun { right: -24px; top: 76px; }
  .sky--page .sky__cloud--3 { display: none; }
}
