#sky { position: fixed; inset: 0; z-index: -1; overflow: hidden; }

.sky-layer {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 700ms ease;
}
.sky-layer.is-active { opacity: 1; }

#cloud-field { position: absolute; inset: 0; }

.hero {
  min-height: 100dvh;          /* dvh, not vh — mobile chrome would clip it */
  display: grid;
  /* Content sits toward the top rather than centred: the tagline reads higher
     up, and the lower two thirds are left to the clouds and Little Guy. */
  grid-template-rows: auto auto 1fr;
  justify-items: center;
  align-content: start;
  position: relative;
  padding: 0 var(--space-s) var(--space-l);
  /* Little Guy exits by translating 150% to the right. Without clipping he
     widens the document and puts a horizontal scrollbar on every page. */
  overflow: hidden;
}

/* The sky fades lighter behind the masthead so the title reads without a
   card. Sits above the clouds in stacking order, but the clouds are kept
   below 26vh anyway — this is belt and braces, not the primary defence. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 34vh;
  /* Lighter than it was. It is a readability nicety, not a requirement —
     --ink on --sky-clear is 6.63:1 and passes AA unaided, and the painted SKY
     is a logotype, which WCAG 1.4.3 exempts. At full strength it washed out
     the clouds beneath it, which are the point of the page. */
  background: linear-gradient(to bottom,
    rgb(214 245 250 / 0.80) 0%,
    rgb(214 245 250 / 0.62) 45%,
    rgb(214 245 250 / 0.30) 72%,
    rgb(214 245 250 / 0) 100%);
  pointer-events: none;
}

.hero__title-block {
  position: relative;
  display: grid;
  justify-items: center;
  padding-top: clamp(1.5rem, 5vh, 3.5rem);
}

.hero__masthead {
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  margin: 0;
}

.hero__byline {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  color: var(--ink);
  margin: 0.35rem 0 0;
}

.hero__lede {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 4vw, 2.6rem);
  line-height: 1.05;
  color: var(--ink);
}

/* sky-word.png is 470px of artwork, so 430px is the sharpness ceiling. */
.hero__sky { width: clamp(230px, 34vw, 430px); height: auto; }

/* Sits below the masthead in normal flow, pushed down by a viewport-scaled
   margin so it still reads as sitting in the upper-middle of the screen.

   It was absolutely positioned at top:40% and that overlapped the byline by
   36px at 1280x720 — a very common laptop height. 40% of 720 is 288px and the
   masthead runs to 324px. Absolute positioning cannot know the masthead's
   height, which changes with viewport WIDTH as the title clamps, so no fixed
   percentage is safe at every size. Flow layout cannot overlap by
   construction. */
.hero__lead {
  margin-top: clamp(1.5rem, 10vh, 7rem);
  width: min(46rem, calc(100% - 2 * var(--space-s)));
  text-align: center;
}

.hero__tagline {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.2vw, 2.35rem);
  line-height: 1.4;
  /* 42ch breaks the 76-character tagline across two lines on desktop rather
     than three. It still wraps to more on a phone, which is correct there. */
  max-width: 26ch;
  margin: 0 auto;
  color: var(--ink);
  /* A soft white halo is the only thing standing between this line and a
     cloud drifting behind it. --ink on the clear sky is 6.63:1 and on a
     white cloud is ~10.5:1, so both extremes pass; the halo covers the
     transition and keeps the edges from muddying. */
  text-shadow: 0 1px 16px rgb(255 255 255 / 0.95),
               0 0 6px rgb(255 255 255 / 0.9);
}

.hero__guy {
  position: absolute;
  right: clamp(1rem, 5vw, 6rem);
  bottom: 0;
  width: clamp(120px, 18vw, 240px);
  height: auto;
}

.hero__scroll {
  position: absolute;
  bottom: var(--space-s);
  left: 50%;
  translate: -50% 0;
  display: grid;
  place-items: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  color: var(--ink);
  animation: nudge 2.4s ease-in-out infinite;
}

@keyframes nudge {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}

/* On a phone the hero was mostly empty sky. Scale the type and Little Guy up
   so the content occupies the screen instead of floating in the middle of it. */
@media (max-width: 34rem) {
  .hero__title-block { padding-top: clamp(2rem, 8vh, 4rem); }
  .hero__lede { font-size: clamp(1.6rem, 7vw, 2.2rem); }
  .hero__sky { width: min(330px, 82%); }
  .hero__byline { font-size: clamp(1rem, 3.8vw, 1.2rem); }
  /* 18ch capped the tagline at 221px inside a 311px container and broke it
     across four lines. 24ch uses the width that was already there and lands
     it on three. */
  .hero__tagline { font-size: clamp(1.35rem, 5.4vw, 1.8rem); max-width: 24ch; }
  /* Little Guy was 40vw — 150px of a 375px screen, wide enough to compete
     with the tagline for attention rather than accompany it. */
  .hero__guy { width: clamp(104px, 29vw, 150px); opacity: 0.95; }
}

/* Little Guy walks off to the right as the reader leaves, and comes back
   when they return to the top. */
.hero__guy {
  transition: translate 760ms cubic-bezier(0.4, 0, 0.25, 1),
              opacity 520ms ease;
}

:root.has-left-hero .hero__guy {
  translate: 150% 0;
  opacity: 0;
}

.hero__scroll {
  transition: opacity 380ms ease, visibility 380ms;
}

/* visibility as well as opacity: an element at opacity 0 still takes keyboard
   focus, so Tab would land on a scroll cue nobody can see. */
:root.has-left-hero .hero__scroll {
  opacity: 0;
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .hero__guy,
  .hero__scroll { transition: none; }
}

.section {
  padding: var(--space-xl) var(--space-s);
  display: grid;
  place-items: center;
}

/* Fills the card. The mockup is a photograph of the book being held, so it
   wants to be seen at size rather than reduced to a thumbnail the way a flat
   cover scan would be. The card's own padding is the only inset. */
.section__cover {
  width: 100%;
  margin: 0 0 var(--space-m);
  border-radius: 0.75rem;
  box-shadow: 6px 6px 0 rgb(94 51 50 / 0.25);
}

.poem {
  margin: 0 0 var(--space-m);
  font-family: var(--font-display);
  font-size: var(--step-1);
  border-left: 4px solid var(--sky);
  padding-left: var(--space-s);
}

/* Taped-photo treatment: each one is a little print pinned to the page, with
   alternating tilt so the grid does not read as a spreadsheet. */
.feelings {
  list-style: none;
  padding: 0;
  margin: var(--space-m) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1.5rem;
}

.feelings li {
  text-align: center;
  background: #fff;
  padding: 0.6rem 0.6rem 1rem;
  border-radius: 0.5rem;
  /* Hard offset rather than a soft blur — the same shadow the buttons use, so
     the prints and the controls belong to one visual family. */
  box-shadow: 4px 4px 0 rgb(94 51 50 / 0.22);
  transition: transform 180ms cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 180ms ease;
}

.feelings li:nth-child(odd) { transform: rotate(-1.6deg); }
.feelings li:nth-child(even) { transform: rotate(1.4deg); }
.feelings li:hover {
  transform: rotate(0deg) scale(1.04);
  box-shadow: 7px 7px 0 rgb(94 51 50 / 0.28);
}

.feelings img { border-radius: 0.3rem; margin-bottom: var(--space-xs); }
.feelings span {
  font-family: var(--font-display);
  font-size: 1.15rem;
  display: block;
  margin-top: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
  .feelings li { transition: none; }
  .feelings li:hover { transform: rotate(0deg); }
}

.about { display: grid; gap: var(--space-m); }
.about__portrait { border-radius: 50%; width: min(220px, 55%); margin-inline: auto; }

@media (min-width: 48rem) {
  .about { grid-template-columns: 220px 1fr; align-items: start; }
  .about__portrait { width: 220px; }
}

/* Anchor the footer to the end of the document, and to the bottom of the
   viewport when the page is shorter than one screen. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

main { flex: 1 0 auto; }

.site-footer {
  margin-top: auto;
  width: 100%;
  padding: var(--space-l) var(--space-s);
  background: var(--cloud-card);
  display: grid;
  justify-items: center;
  text-align: center;
}

.site-footer__inner { width: 100%; max-width: 46rem; }
.site-footer img { margin: 0 auto var(--space-s); width: 200px; }

/* A link alone in its own paragraph is a standalone control, not an inline
   link in a sentence, so WCAG 2.5.8's inline exception does not cover it. */
.section__back a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
}


/* Section headings scale up — they were competing with body copy for weight. */
.section h2,
.site-footer h2 {
  font-size: clamp(2rem, 5vw, 3rem);
  margin-bottom: 1rem;
}

/* Mobile-first: essentially all traffic here is a thumb in the Instagram
   in-app browser. Static sky — those browsers are CPU-throttled and it is
   someone's battery. */
.links-page { background: var(--sky-clear) url("/img/sky/clear.webp") center / cover fixed; }

/* The painted SKY in the wordmark measures 1.30:1 against the sky plate —
   cyan on cyan. AA wants 3:1 even for large text, and an image of text counts.
   The landing page solves this with a fade band behind its masthead; this is
   the same device, sized to the header block. */
.links::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 58vh;
  background: linear-gradient(to bottom,
    rgb(252 254 254 / 0.94) 0%,
    rgb(252 254 254 / 0.88) 45%,
    rgb(252 254 254 / 0.55) 75%,
    rgb(252 254 254 / 0) 100%);
  pointer-events: none;
  z-index: 0;
}

.links > * { position: relative; z-index: 1; }

.links {
  position: relative;
  min-height: 100dvh;
  max-width: 30rem;
  margin-inline: auto;
  padding: var(--space-l) var(--space-s) var(--space-xl);
  text-align: center;
}

.links__guy { width: 110px; margin: 0 auto var(--space-xs); }
.links h1 { margin-bottom: var(--space-m); }
.links h1 img { width: min(240px, 62%); margin-inline: auto; }

.links__list { display: grid; gap: var(--space-s); }
.links__list .btn { width: 100%; min-height: 52px; }

.links__social { margin-top: var(--space-l); font-family: var(--font-display); }

/* Text links, not .btn pills, so they need their own 44px tap target —
   same pattern as .site-nav__list a. */
.links__social a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding: 0 0.25rem;
}

/* ---- Desktop rhythm: alternating bands -----------------------------------
   Feelings, About and the footer become edge-to-edge bands; the rest stay as
   floating cards over the sky. Card, band, card, band — the sky vanishing and
   returning is the point, not an accident. */
#feelings,
#about {
  background: var(--cloud-card);
  padding-block: var(--space-xl);
}

/* Inside a band the card has nothing left to do: the band IS the surface. */
#feelings > .u-card,
#about > .u-card {
  background: none;
  filter: none;
  padding: 0;
  max-width: 62rem;
}

/* Floating sections sit narrower than the bands so the two modes read as a
   deliberate pair rather than as inconsistent widths. */
#the-book > .u-card,
#signup > .u-card,
#visits > .u-card,
#events > .u-card {
  max-width: 44rem;
}

.section { padding-block: var(--space-l); }


/* Short viewports — a 1280x720 laptop is the common case. The masthead was
   taking 45% of the screen and the tagline another 22%, leaving about 16vh of
   sky for clouds that are 21vh tall. Scaling by width alone never caught this,
   because the width is generous and only the height is tight. */
@media (max-height: 820px) and (min-width: 34rem) {
  .hero__title-block { padding-top: clamp(0.75rem, 2vh, 1.5rem); }
  .hero__lede { font-size: clamp(1.2rem, 2.6vw, 1.8rem); }
  .hero__sky { width: clamp(170px, 22vw, 260px); }
  .hero__byline { font-size: clamp(0.95rem, 1.8vw, 1.15rem); }
  .hero__lead { margin-top: clamp(1rem, 4vh, 2.5rem); }
  .hero__tagline { font-size: clamp(1.15rem, 2vw, 1.5rem); max-width: 40ch; }
  .hero::before { height: 26vh; }
}
