/**
 * site.css
 * Styles for The Beansprout Trust site: a sage ground, the capsule sprout,
 * and its ground line carried across the page, with the name above the line
 * and the small print below it. Set in Fraunces throughout.
 *
 * Created: 2026-11-03
 * Last modified: 2026-11-03
 */

/* Self-hosted so the page loads nothing from other sites. Licence: fonts/OFL.txt */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-full-normal.woff2') format('woff2-variations');
}

:root {
  --sage: #9ead86;
  --ink: #1d3526;
  --ink-soft: #233d2b;
  --bubble: #d9e7d5;
  /* The footer's height, so the capsule and footer are centred together and
     fit one screen with a little room above and below. */
  --footer-height: 6.25rem;
  --capsule-height: min(82vh, 820px, calc(100vh - var(--footer-height) - 3rem));
  /* Where the ground line falls in the drawing: y 603 of 917. */
  --ground: 0.6576;
}

* { box-sizing: border-box; }

html, body { margin: 0; }

body {
  /* Keeps the stage's top margin inside the body, so a page that fits the
     window doesn't scroll by that margin. */
  display: flow-root;
  min-height: 100vh;
  background: var(--sage);
  color: var(--ink);
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'SOFT' 50, 'WONK' 0;
  overflow-x: hidden;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover { text-decoration-thickness: 2px; }

a:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- Bubbles ---------- */

.bubbles {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.bubbles span {
  position: absolute;
  left: var(--x);
  top: var(--top);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background: var(--bubble);
  opacity: 0.85;
}

.bubbles span:nth-child(1) { --x: 6%; --top: 14%; --size: 14px; --duration: 34s; --delay: -4s; }
.bubbles span:nth-child(2) { --x: 11%; --top: 62%; --size: 8px; --duration: 41s; --delay: -22s; }
.bubbles span:nth-child(3) { --x: 19%; --top: 84%; --size: 20px; --duration: 29s; --delay: -11s; }
.bubbles span:nth-child(4) { --x: 27%; --top: 30%; --size: 10px; --duration: 38s; --delay: -30s; }
.bubbles span:nth-child(5) { --x: 44%; --top: 8%; --size: 16px; --duration: 45s; --delay: -16s; }
.bubbles span:nth-child(6) { --x: 52%; --top: 92%; --size: 7px; --duration: 33s; --delay: -2s; }
.bubbles span:nth-child(7) { --x: 63%; --top: 18%; --size: 12px; --duration: 39s; --delay: -27s; }
.bubbles span:nth-child(8) { --x: 71%; --top: 76%; --size: 22px; --duration: 31s; --delay: -9s; }
.bubbles span:nth-child(9) { --x: 80%; --top: 40%; --size: 9px; --duration: 43s; --delay: -35s; }
.bubbles span:nth-child(10) { --x: 87%; --top: 12%; --size: 18px; --duration: 36s; --delay: -19s; }
.bubbles span:nth-child(11) { --x: 93%; --top: 58%; --size: 11px; --duration: 40s; --delay: -6s; }
.bubbles span:nth-child(12) { --x: 97%; --top: 88%; --size: 15px; --duration: 30s; --delay: -24s; }

/* The bubbles drift up slowly, unless the visitor has asked for less motion. */
@media (prefers-reduced-motion: no-preference) {
  .bubbles span {
    top: auto;
    bottom: -40px;
    animation: rise var(--duration) linear var(--delay) infinite;
  }
}

@keyframes rise {
  0% { transform: translate(0, 0); }
  50% { transform: translate(14px, -55vh); }
  100% { transform: translate(-6px, calc(-100vh - 60px)); }
}

/* ---------- The capsule and the words beside it ---------- */

.stage {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto minmax(0, 34rem);
  column-gap: clamp(2rem, 7vw, 7rem);
  justify-content: center;
  min-height: var(--capsule-height);
  margin-top: max(1.5rem, calc((100vh - var(--capsule-height) - var(--footer-height)) / 2));
  padding: 0 16px;
  /* Trims the horizon at the edges of the window without a sideways scroll. */
  overflow-x: clip;
}

/* The capsule is drawn on a 400 x 917 grid, so one unit of the drawing is
   the capsule height / 917. The drawing sits inline in the page (written by
   scripts/draw-sprout.mjs) so the rules below can animate its parts. */
.capsule {
  position: relative;
  height: var(--capsule-height);
  aspect-ratio: 400 / 917;
}

.sprout {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The capsule's ground line carried on across the window: the same wave at
   the same scale, with its tiles starting at the capsule's left edge, so it
   meets the line inside the glass exactly. The tile is 400 x 12 units and
   sits 6 units above the ground at y 603. */
.horizon {
  position: absolute;
  left: -100vw;
  right: -100vw;
  top: calc(var(--capsule-height) * 597 / 917);
  height: calc(var(--capsule-height) * 12 / 917);
  background-image: url('/assets/ground-line.svg');
  background-repeat: repeat-x;
  background-size: calc(var(--capsule-height) * 400 / 917) 100%;
  background-position: 100vw 0;
}

/* ---------- The drawing comes alive ----------
   Lengths are in units of the drawing, so every movement scales with the
   capsule. Transform origins are points in the drawing (see the comments in
   scripts/draw-sprout.mjs). Visitors who ask for less motion see everything
   still. */

@media (prefers-reduced-motion: no-preference) {
  .sprout .head,
  .sprout .leaves,
  .sprout .rays {
    transform-box: view-box;
  }

  /* The bean sways gently on its stem and the leaves flutter. */
  .sprout .head {
    transform-origin: 134px 343px;
    animation: sway 7s ease-in-out infinite;
  }

  .sprout .leaves {
    transform-origin: 150px 290px;
    animation: flutter 5.5s ease-in-out 0.8s infinite;
  }

  /* The sun's rays turn slowly and shimmer. */
  .sprout .rays {
    transform-origin: 192.5px 280px;
    animation: turn 150s linear infinite;
  }

  .sprout .rays line {
    animation: shimmer 3.6s ease-in-out infinite;
  }

  .sprout .rays line:nth-child(3n+1) { animation-delay: -1.2s; }
  .sprout .rays line:nth-child(3n+2) { animation-delay: -2.4s; }
  .sprout .rays line:nth-child(4n) { animation-duration: 4.4s; }

  /* The clouds drift across the sky and come round again, each bank at its
     own speed. The negative delay starts each bank where it is drawn: 340 of
     the 640 units of travel lie behind it. */
  .sprout .cloud {
    animation: drift var(--drift) linear calc(var(--drift) * -0.53125) infinite;
  }

  .sprout .cloud:nth-child(1) { --drift: 80s; }
  .sprout .cloud:nth-child(2) { --drift: 55s; }
  .sprout .cloud:nth-child(3) { --drift: 100s; }

  /* The bubbles around the capsule fizz: each rises a little, wobbles and
     fades, then starts again, at its own pace. */
  .sprout .fizz circle {
    transform-box: fill-box;
    transform-origin: center;
    animation: fizz 6s ease-in-out infinite both;
  }

  .sprout .fizz circle:nth-child(3n+1) { animation-duration: 5.2s; }
  .sprout .fizz circle:nth-child(3n+2) { animation-duration: 6.9s; }
  .sprout .fizz circle:nth-child(3n) { animation-duration: 8.3s; }

  .sprout .fizz circle:nth-child(4n+1) { animation-delay: -0.6s; }
  .sprout .fizz circle:nth-child(4n+2) { animation-delay: -2.4s; }
  .sprout .fizz circle:nth-child(4n+3) { animation-delay: -4.1s; }
  .sprout .fizz circle:nth-child(4n) { animation-delay: -5.7s; }
}

@keyframes sway {
  0%, 100% { transform: rotate(0deg); }
  50% { transform: rotate(-2.5deg); }
}

@keyframes flutter {
  0%, 100% { transform: rotate(0deg); }
  35% { transform: rotate(3deg); }
  70% { transform: rotate(-1.5deg); }
}

@keyframes turn {
  to { transform: rotate(360deg); }
}

@keyframes shimmer {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

@keyframes drift {
  from { transform: translateX(-340px); }
  to { transform: translateX(300px); }
}

@keyframes fizz {
  0% { transform: translate(0, 16px) scale(0.45); opacity: 0; }
  18% { opacity: 1; }
  45% { transform: translate(5px, -4px) scale(1); }
  70% { transform: translate(-4px, -20px) scale(0.95); opacity: 1; }
  100% { transform: translate(2px, -38px) scale(0.75); opacity: 0; }
}

.words {
  position: relative;
  display: grid;
  grid-template-rows: calc(var(--capsule-height) * var(--ground)) auto;
}

.above {
  align-self: end;
  padding-bottom: 1.6rem;
}

.below {
  max-width: 31rem;
  padding-top: 1.7rem;
}

.kicker {
  margin: 0 0 0.9rem;
  font-size: 0.8rem;
  font-weight: 650;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

h1 {
  margin: 0;
  font-size: clamp(3.2rem, 6.6vw, 6.4rem);
  font-weight: 560;
  font-variation-settings: 'SOFT' 100, 'WONK' 1, 'opsz' 144;
  line-height: 0.92;
  letter-spacing: -0.015em;
}

.below p {
  margin: 0 0 0.9rem;
  font-size: 1.12rem;
  line-height: 1.55;
  font-variation-settings: 'SOFT' 50, 'opsz' 14;
  overflow-wrap: break-word;
}

footer {
  position: relative;
  z-index: 1;
  padding: 1.5rem 16px;
  text-align: center;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

footer p { margin: 0; }

/* The trustees' address, a little larger than the domains below it, with
   enough height to be an easy target on a touch screen. */
footer .contact {
  margin-bottom: 0.35rem;
  font-size: 1rem;
  letter-spacing: 0.02em;
}

footer .contact a {
  display: inline-block;
  padding: 0.3rem 0;
  color: var(--ink);
}

/* ---------- The page that doesn't exist ---------- */

.not-found h1 {
  font-size: clamp(2.6rem, 5vw, 4.6rem);
}

/* Nothing has sprouted here: the bean is still a closed seed in the soil,
   its back half tucked behind the front, with no root, stem or leaves. These
   rules outrank the animations above, so the seed stays still with or
   without motion. The sun, clouds and bubbles carry on as usual. */
.not-found .sprout .root,
.not-found .sprout .stem,
.not-found .sprout .leaves {
  display: none;
}

.not-found .sprout .leaves {
  animation: none;
}

.not-found .sprout .head {
  transform-box: view-box;
  transform-origin: 134px 343px;
  transform: translate(108px, 285px) rotate(-215deg) scale(0.45);
  animation: none;
}

.not-found .sprout .back-half {
  transform-box: view-box;
  transform-origin: 150px 281px;
  transform: translate(45px, 19px) rotate(-80deg) scale(0.6);
}

/* ---------- Phones and narrow windows ---------- */

@media (max-width: 760px) {
  :root { --capsule-height: min(56vh, 460px); }

  .stage {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    min-height: 0;
    margin-top: 1.5rem;
  }

  .words { grid-template-rows: auto auto; }

  .above {
    padding: 1.5rem 0 0;
    text-align: center;
  }

  .below { padding-top: 1.1rem; }

  .below p { font-size: 1.05rem; }

  h1 { font-size: clamp(2.6rem, 12vw, 3.6rem); }

  .not-found h1 { font-size: clamp(2.2rem, 10vw, 3rem); }
}
