/* Gramina — shared site styles.
   Tokens come from the Figma Look Board (Landing / Mobile · 390, Landing / Desktop · 1440).

   Fluid sizing: every size token runs linearly from its 390 value (A) to its 1440 value (B),
   then keeps growing to 1.2 × B at 2560. Pattern:
     calc((A * 1px + (B - A) * var(--s1) / 1050 + B * 0.2 * var(--s2) / 1120) * var(--k))
   --k is a global multiplier the responsive rules lower on short screens. */

:root {
  --paper: #f6f1e4;
  --ink: #3a2e22;
  --ink-90: rgba(58, 46, 34, 0.9);
  --ink-85: rgba(58, 46, 34, 0.85);
  --ink-75: rgba(58, 46, 34, 0.75);
  --ink-40: rgba(58, 46, 34, 0.4);
  --line-outer: rgba(58, 46, 34, 0.5);
  --line-inner: rgba(58, 46, 34, 0.35);

  --font-script: "Pinyon Script", cursive;
  --font-caps: "IM Fell English SC", Georgia, serif;
  --font-text: "Libre Caslon Text", Georgia, serif;

  --s1: clamp(0px, 100vw - 390px, 1050px);
  --s2: clamp(0px, 100vw - 1440px, 1120px);
  --k: 1;

  /* Plate frame */
  --pad: calc(12px + 12 * var(--s1) / 1050);
  --pad-t: max(var(--pad), env(safe-area-inset-top));
  --pad-r: max(var(--pad), env(safe-area-inset-right));
  --pad-b: max(var(--pad), env(safe-area-inset-bottom));
  --pad-l: max(var(--pad), env(safe-area-inset-left));
  --plate-gap: 4px;
  --radius-outer: 42px;
  --radius-inner: 38px;
  --inner-pt: calc(20px + 8 * var(--s1) / 1050);
  --inner-px: calc(20px + 12 * var(--s1) / 1050);
  --inner-pb: 24px;

  /* Type */
  --fs-caption: calc((13px + 2 * var(--s1) / 1050 + 3 * var(--s2) / 1120) * var(--k));
  --fs-wordmark: calc((60px + 28 * var(--s1) / 1050 + 17.6 * var(--s2) / 1120) * var(--k));
  --fs-tagline: calc((19px + 7 * var(--s1) / 1050 + 5.2 * var(--s2) / 1120) * var(--k));
  --fs-badge: calc((14px + 2.8 * var(--s2) / 1120) * var(--k));
  --lede-max: calc((320px + 220 * var(--s1) / 1050 + 108 * var(--s2) / 1120) * var(--k));

  /* Hero rhythm */
  --hero-pt: calc((56px - 8 * var(--s1) / 1050 + 9.6 * var(--s2) / 1120) * var(--k));
  --hero-gap: calc((22px + 2 * var(--s1) / 1050 + 4.8 * var(--s2) / 1120) * var(--k));
  --title-gap: calc((10px + 2 * var(--s1) / 1050 + 2.4 * var(--s2) / 1120) * var(--k));
  --copy-gap: calc((12px + 4 * var(--s1) / 1050 + 3.2 * var(--s2) / 1120) * var(--k));
  --icon: calc((76px + 28 * var(--s1) / 1050 + 20.8 * var(--s2) / 1120) * var(--k));

  /* Meadow: height of the tallest grass above the viewport bottom, and the clear gap above it.
     Capped at 38% of the small viewport height so short landscape phones keep room for the text.
     site-meadow.js reads the canvas height and scales the engine plate to fill it. */
  --meadow-h: min(calc((316px + 14 * var(--s1) / 1050 + 66 * var(--s2) / 1120) * var(--k)), 38svh);
  --meadow-gap: calc(20px * var(--k));
}

@supports not (height: 1svh) {
  :root { --meadow-h: min(calc((316px + 14 * var(--s1) / 1050 + 66 * var(--s2) / 1120) * var(--k)), 38vh); }
}

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; }

body {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  padding: var(--pad-t) var(--pad-r) var(--pad-b) var(--pad-l);
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}

/* Paper texture: Figma tiles its 256px scan at 100px / 25%, which shows an obvious grid in the browser.
   Two layers of the same scan at unrelated sizes and offsets (400px and 283px, about √2 apart, one rotated a quarter turn)
   keep the overall 25% density while the repeats never line up. */
html::before,
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
body::before {
  background: url("/assets/img/paper.jpg") 0 0 / 400px 400px;
  opacity: 0.16;
}
html::before {
  /* Oversized so the quarter-turn still covers any viewport. */
  inset: -50vmax;
  background: url("/assets/img/paper.jpg") 151px 97px / 283px 283px;
  opacity: 0.12;
  transform: rotate(90deg);
}
/* Vignette: warm edge falloff from 55% to the outermost viewport edge, multiplied over paper. */
body::after {
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0) 55%, rgba(184, 160, 112, 0.08) 100%);
  mix-blend-mode: multiply;
}

img { display: block; max-width: 100%; }
h1, p { margin: 0; }

/* ---------- Plate: double hairline frame ---------- */

.plate {
  flex: 1;
  display: flex;
  padding: var(--plate-gap);
  border: 0.75px solid var(--line-outer);
  border-radius: var(--radius-outer);
}

.plate__inner {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--inner-pt) var(--inner-px) var(--inner-pb);
  border: 0.5px solid var(--line-inner);
  border-radius: var(--radius-inner);
}

/* Free height splits 30 / 70 above and below the hero, so tall screens sit the content a little high.
   The top share starts at the caption line plus the Figma hero padding; the bottom share starts
   at the room the meadow needs (its height + clear gap, less the frame below the inner line). */
.plate__inner::before {
  content: "";
  flex: 3 1 calc(var(--fs-caption) * 1.25 + var(--hero-pt));
}
.plate__inner::after {
  content: "";
  flex: 7 1 max(0px, calc(var(--meadow-h) + var(--meadow-gap) - var(--pad-b) - var(--plate-gap) - var(--inner-pb) - 1.25px));
}

.captions {
  position: absolute;
  top: var(--inner-pt);
  left: var(--inner-px);
  right: var(--inner-px);
  display: flex;
  justify-content: space-between;
  gap: 1em;
  font-style: italic;
  font-size: var(--fs-caption);
  line-height: 1.25;
  color: var(--ink-40);
  white-space: nowrap;
}
/* Decorative plate marks, so they are generated content rather than document text.
   Each page sets its own marks with data-left / data-right. */
.captions::before { content: attr(data-left); }
.captions::after { content: attr(data-right); }

/* ---------- Hero ---------- */

.hero {
  flex: none;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hero-gap);
  text-align: center;
}

.app-icon {
  position: relative;
  width: var(--icon);
  height: var(--icon);
  background: var(--paper);
  border: calc(var(--icon) * 0.00833) solid rgba(0, 0, 0, 0.15);
  border-radius: calc(var(--icon) * 0.2237);
  overflow: hidden;
}
.app-icon img {
  position: absolute;
  inset: 6.67%;
  width: 86.66%;
  height: 86.66%;
}

.titleset {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--title-gap);
}

.wordmark {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: var(--fs-wordmark);
  /* Figma: 69px on mobile, Pinyon's "normal" (~110px) on desktop. */
  line-height: calc((69px + 41 * var(--s1) / 1050 + 22 * var(--s2) / 1120) * var(--k));
  color: var(--ink-90);
}

.copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--copy-gap);
}

.divider { width: 96px; height: 10px; }

.tagline {
  font-family: var(--font-caps);
  font-size: var(--fs-tagline);
  line-height: 1.2;
  letter-spacing: 0.06em;
  color: var(--ink);
  text-wrap: balance;
}

.lede {
  max-width: var(--lede-max);
  font-style: italic;
  /* 16px at every width; shrinks with the rest only when the screen is too short to fit (--k < 1), never below 12px. */
  font-size: max(12px, calc(16px * var(--k)));
  line-height: 1.5;
  color: var(--ink-75);
  text-wrap: pretty;
}

/* iOS-style glass pill: translucent fill with backdrop blur, a light rim that is brightest on top,
   a soft inner highlight and a faint lift shadow. */
.badge {
  position: relative;
  padding: 0.857em 2.143em 0.857em 2em;
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.22) 55%, rgba(255, 255, 255, 0.3) 100%);
  -webkit-backdrop-filter: blur(14px) saturate(1.6);
  backdrop-filter: blur(14px) saturate(1.6);
  box-shadow:
    inset 0 1px 0.5px rgba(255, 255, 255, 0.9),
    inset 0 -1px 1px rgba(58, 46, 34, 0.05),
    0 0.5px 1px rgba(58, 46, 34, 0.08),
    0 6px 18px -6px rgba(58, 46, 34, 0.16);
  font-style: italic;
  font-size: var(--fs-badge);
  line-height: 1;
  color: var(--ink);
  white-space: nowrap;
}
/* The pill as a link (e.g. on the 404 page). */
a.badge {
  text-decoration: none;
  transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
a.badge:hover {
  background-color: rgba(255, 255, 255, 0.25);
  transform: translateY(-1px);
}
a.badge:focus-visible {
  outline: 1.5px solid var(--ink);
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  a.badge, a.badge:hover { transition: none; transform: none; }
}

/* Gradient rim: white at the top fading to a faint ink edge at the bottom. */
.badge::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: 0.75px;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.35) 45%, rgba(58, 46, 34, 0.14));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

/* ---------- Meadow ---------- */

/* Set by site-meadow.js while a mouse is over the grass: brushing it is the interaction. */
.meadow-hover { cursor: grab; }

.meadow {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: var(--meadow-h);
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: multiply;
}
