/* Ho Hey, Let's Play! — hand-written, no build step, no framework.
   Sour Gummy (900) shouts, Jua talks. */

:root {
  --ink: #141414;
  --paper: #f7f4e9;
  --gray: #ded9cb;      /* warm offwhite fill, for contrast against paper */
  --muted: #5a564c;     /* quiet text on paper */
  --muted-dark: #7d7869; /* the title's offset shadow — decorative, not text */
  /* No grey on the dark ground: text there is paper, and hierarchy comes
     from size and weight rather than from washing the colour out. */
  --yellow: #ffd93d;    /* the only colour left — reserved for calls to action */
  --stroke: 3px;
  --wrap: 34rem;

  --font-display: 'Sour Gummy', 'Trebuchet MS', system-ui, sans-serif;
  --font-body: 'Jua', 'Trebuchet MS', system-ui, sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* The jump link lands the heading below the top edge, not flush against it. */
[id] { scroll-margin-top: 2rem; }

body {
  margin: 0;
  /* Ink is the page's ground now; the hero is the light block sitting on it,
     and the skewed cut below the hero reveals this. */
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.6;
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

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

/* The default ink ring works on the light hero and inside the white form.
   Everywhere on the dark ground it would vanish, so it borrows the CTA yellow. */
.paper :focus-visible,
.sheet-view :focus-visible { outline-color: var(--yellow); }
.reply :focus-visible { outline-color: var(--ink); }

.display {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1.05;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

/* Reusable sticker block: thick outline, hard offset shadow. */
.sticker {
  border: var(--stroke) solid var(--ink);
  border-radius: 14px;
  box-shadow: 5px 5px 0 var(--ink);
}

/* ---------- The stage (hero) ---------- */

.stage {
  position: relative;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  /* Extra bottom padding clears the skewed edge below. */
  padding-block: 3rem 5rem;
  /* The stage ends on a slant instead of square across the page. */
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 2.5rem), 0 100%);
}

.stage__checker {
  position: absolute;
  top: -3rem;
  right: -3rem;
  width: 14rem;
  height: 14rem;
  background: repeating-conic-gradient(var(--ink) 0 25%, var(--paper) 0 50%) 0 0 / 2rem 2rem;
  transform: rotate(12deg);
}

.stage > .wrap { position: relative; }

.stage__title { margin: 0; }

/* The wordmark carries its own black plate and outline, so it sits on the
   stage without further treatment. */
.stage__logo { width: min(100%, 26rem); height: auto; }

.stage__lede {
  margin: 1.5rem 0 0;
  max-width: 26rem;
  font-size: 1.15rem;
  line-height: 1.5;
}

.downloads { list-style: none; margin: 1.75rem 0 0; padding: 0; }

/* The hero's jump button stands clear of the lede above it. */
.stage .button { margin-top: 2rem; }
.downloads li + li { margin-top: 1rem; }

.button {
  display: inline-block;
  padding: 0.85rem 1.4rem;
  border: var(--stroke) solid var(--ink);
  border-radius: 999px;
  background: var(--yellow);
  color: var(--ink);
  font-size: 1.125rem;
  text-decoration: none;
  box-shadow: 5px 5px 0 var(--btn-shadow, var(--ink));
  transform: rotate(-1.5deg);
}

/* Hovering presses the button part-way into the page; activating it presses
   all the way, until the offset shadow is gone. */
.button:hover { transform: rotate(-1.5deg) translate(2px, 2px); box-shadow: 3px 3px 0 var(--btn-shadow, var(--ink)); }
.button:active { transform: rotate(-1.5deg) translate(5px, 5px); box-shadow: 0 0 0 var(--btn-shadow, var(--ink)); }

.downloads__meta {
  display: block;
  /* Everything under the button is one block of small print: it opens with a
     clear gap from the button, then the three lines sit evenly together. */
  margin-top: 2.5rem;
  color: var(--paper);
  font-size: 1rem;
}

/* The long half of the page is now the dark one. Buttons on it need a light
   offset shadow to read at all. */
.paper {
  background: var(--ink);
  color: var(--paper);
  padding-block: 0.5rem 3rem;
  --btn-shadow: var(--paper);
}

/* ---------- Paper sections ---------- */

.section { margin-top: 2.5rem; }

.section__title {
  margin: 0 0 0.9rem;
  font-size: 1.4rem;
}

.section > p { margin: 0 0 0.75rem; }
.section > p:last-child { margin-bottom: 0; }

.cards { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.9rem; }

.card { padding: 0.85rem 1rem; }
.card:nth-child(1) { transform: rotate(-1deg); }
.card:nth-child(2) { transform: rotate(0.8deg); }
.card:nth-child(3) { transform: rotate(-0.6deg); }

/* On the dark ground the trio reads as two filled cards and one outlined. */
/* On black, an offset shadow can only be grey, so the cards go flat and
   let their own edges do the work. */
.paper .sticker { box-shadow: none; }
.card--plain  { background: #fff; color: var(--ink); }
.card--gray   { background: var(--gray); color: var(--ink); }
.card--invert { background: transparent; color: var(--paper); border-color: var(--paper); }

.card__title { margin: 0 0 0.25rem; font-size: 1.1rem; }

/* The pro tip borrows the sticker cards' look so it reads as an aside rather
   than as another paragraph — kept to the prose measure, not the full column. */
.protip { margin-top: 1.75rem; max-width: 34rem; transform: rotate(-0.7deg); }
/* No size of its own — the cards read at the same size as the page. */
.card__text { margin: 0; line-height: 1.5; }

/* ---------- Take a look ---------- */

.look { display: grid; gap: 1.5rem; margin-top: 2rem; }

/* Page two sits behind page one, offset so you can see it's there. The stack
   is sized by the front sheet; the back one is positioned against it. */
.sheets { position: relative; }

.preview {
  display: block;
  border: 2px solid var(--ink);
  background: #fff;
  box-shadow: none;
}

.preview--front { position: relative; transform: rotate(-1.5deg); width: 88%; }

.preview--back {
  position: absolute;
  top: 0;
  right: 0;
  width: 88%;
  transform: rotate(3deg);
}

/* Hovering the back sheet slides it further out rather than bringing it
   forward — it stays behind, it just peeks. */
.preview--back { transition: transform 160ms ease-out; }
.preview--back:hover, .preview--back:focus-visible { transform: rotate(3deg) translateX(1.75rem); }

.look__aside { display: flex; flex-direction: column; gap: 0.5rem; }

/* The disclaimers sit well clear of the download button. */
.look__hint { margin: 0; }
.look__privacy { margin: 0; }
.look__hint,
.look__privacy { font-size: 1rem; color: var(--paper); }

/* ---------- Full-size sheet pages ---------- */

/* Opening a page is a real navigation, so the morph is declarative: both
   documents opt in, and the thumbnail and the full-size image share a name.
   No script involved. Browsers without cross-document transitions (Firefox
   today) simply navigate instantly. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

.preview--front img { view-transition-name: sheet-1; }
.preview--back img { view-transition-name: sheet-2; }
.sheet-view__img--1 { view-transition-name: sheet-1; }
.sheet-view__img--2 { view-transition-name: sheet-2; }

.sheet-page { background: var(--ink); color: var(--paper); }

.sheet-view {
  padding-block: 1.5rem 3rem;
  display: grid;
  justify-items: center;
  gap: 1.25rem;
}

.sheet-view__back { justify-self: start; box-shadow: 5px 5px 0 var(--paper); }

.sheet-view__img {
  width: min(100%, 44rem);
  border: 3px solid var(--ink);
  background: #fff;
}

.sheet-view__meta { margin: 0; font-size: 0.9rem; color: var(--paper); text-align: center; }
.sheet-view__meta a { text-decoration: none; border-bottom: 1px solid currentColor; }
.sheet-view :focus-visible { outline-color: var(--yellow); }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
  .preview--back { transition: none; }
}

/* ---------- Reply card ---------- */

.reply {
  background: #fff;
  color: var(--ink);
  --btn-shadow: var(--ink);
  border-style: dashed;
  border-radius: 4px;
  padding: 1.25rem 1.1rem 1.4rem;
  transform: rotate(-0.5deg);
  box-shadow: none;
}

.reply__note { margin: -0.4rem 0 1rem; color: var(--muted); }

.field { margin-bottom: 0.9rem; }
.field__label { display: block; margin-bottom: 0.3rem; }

.field__input {
  width: 100%;
  padding: 0.55rem 0.6rem;
  border: 2px solid var(--ink);
  border-radius: 2px;
  background: #fffdf6;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: inherit;
}

.field__input::placeholder { color: #6b6659; }

.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.75rem; }

/* Honeypot: hidden from people, present for bots. Never display:none — some
   bots skip hidden inputs, and this one needs to look fillable. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.button--send {
  background: var(--yellow);
  transform: rotate(-1deg);
  cursor: pointer;
}

.button--send:hover { transform: rotate(-1deg) translate(2px, 2px); box-shadow: 3px 3px 0 var(--ink); }
.button--send:active { transform: rotate(-1deg) translate(5px, 5px); box-shadow: 0 0 0 var(--ink); }
.button--send[disabled] { opacity: 0.6; cursor: progress; }

.reply__status { margin: 0.9rem 0 0; min-height: 1.5rem; }

/* Without a red to lean on, an error is marked by a heavy rule instead. */
.reply__status--error {
  border-left: 4px solid var(--ink);
  padding-left: 0.6rem;
}

/* Same shape as the other Ludoratory projects: mark, then two quiet lines. */
.footer {
  margin-top: 2.5rem;
  padding-block: 1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--paper);
}

/* The mark ships slate-blue; flatten it to pure white for the dark ground. */
.footer__mark { flex: none; filter: brightness(0) invert(1); }

.footer__text { flex: 1; min-width: 11rem; }
.footer__text p { margin: 0; }

.footer a { text-decoration: none; border-bottom: 1px solid currentColor; }

/* ---------- Desktop ----------
   The column widens and the type steps up, but prose keeps its own narrower
   measure — a 52rem line of body copy is a chore to read. Only the pieces
   that gain from width (the cards, the previews) use the full column. */

@media (min-width: 48rem) {
  :root { --wrap: 52rem; }

  body { font-size: 1.1875rem; }

  .stage { padding-block: 4.5rem 3.5rem; }

  /* The check scales with the block — otherwise a bigger patch is just more
     of the same small squares, which reads as texture rather than pattern.
     Size stays an exact multiple of the tile (8 × 3rem) so the cut edges
     land on whole squares instead of slicing the last row. */
  .stage__checker {
    width: 24rem; height: 24rem; top: -5rem; right: -5rem;
    background-size: 3rem 3rem;
  }

  .stage__logo { width: min(100%, 32rem); }

  .stage__lede { margin-top: 1.75rem; max-width: 30rem; font-size: 1.3rem; }

  .downloads { margin-top: 2.25rem; }
  .stage .button { margin-top: 2.75rem; }
  .button { padding: 1rem 1.75rem; font-size: 1.25rem; }
  .downloads__meta { font-size: 0.95rem; }

  .section { margin-top: 3.5rem; }
  .section__title { font-size: 2rem; margin-bottom: 1.2rem; }
  .section > p { max-width: 40rem; }

  /* Three across, stretched to a common height — the row reads as one shelf
     rather than three loose stickers with ragged bottoms. */
  .cards { grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
  .card { padding: 1.1rem 1.2rem; }
  .card__title { font-size: 1.25rem; }

  /* Sheets left, download and its small print right. */
  .look { grid-template-columns: minmax(0, 1fr) minmax(14rem, 1fr); gap: 2.25rem; align-items: center; }
  .sheets { max-width: 22rem; }
  .look__hint,
  .look__privacy { font-size: 1.1rem; }
  .downloads__meta { font-size: 1.1rem; }

  /* Full width, with the two optional fields stacked beside the message box
     so the card stops looking like a long ribbon on a wide screen. */
  .reply {
    max-width: none;
    padding: 1.75rem 1.6rem 2rem;
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(12rem, 1fr);
    column-gap: 1.5rem;
    align-items: start;
  }
  .reply > .section__title,
  .reply__note,
  .button--send,
  .reply__status { grid-column: 1 / -1; }
  .field:has(textarea) { grid-column: 1; margin-bottom: 0; }
  .field:has(textarea) .field__input { min-height: 9.5rem; }
  .field-row { grid-column: 2; grid-template-columns: 1fr; gap: 0.9rem; }
  .button--send { margin-top: 1.1rem; justify-self: start; }

  .footer { margin-top: 3.5rem; font-size: 0.95rem; }
}

/* ---------- Wide desktop ----------
   A second step for real monitors. The column keeps growing but the prose
   measure only creeps — the extra width goes to the hero, the card shelf and
   the sheet previews, which are the things worth looking at large. */

@media (min-width: 75rem) {
  :root { --wrap: 68rem; }

  body { font-size: 1.25rem; }

  .stage { padding-block: 6rem 4.5rem; }
  /* 8 × 4rem — again an exact multiple, so no sliced squares at the edges. */
  .stage__checker {
    width: 32rem; height: 32rem; top: -7rem; right: -7rem;
    background-size: 4rem 4rem;
  }

  .stage__logo { width: min(100%, 38rem); }

  .stage__lede { max-width: 34rem; font-size: 1.5rem; }

  .button { padding: 1.15rem 2rem; font-size: 1.35rem; }

  .section { margin-top: 4.5rem; }
  .section__title { font-size: 2.4rem; }
  .section > p { max-width: 44rem; }

  .cards { gap: 1.5rem; }
  .card { padding: 1.4rem 1.5rem; }
  .card__title { font-size: 1.4rem; }

  .look { grid-template-columns: minmax(0, 1fr) minmax(16rem, 1fr); gap: 3rem; }
  .sheets { max-width: 26rem; }

  .reply { padding: 2rem 1.9rem 2.25rem; column-gap: 2rem; }
  .field:has(textarea) .field__input { min-height: 11rem; }
}

/* ---------- Photo credits ---------- */

.credits { list-style: none; margin: 1.5rem 0 0; padding: 0; display: grid; gap: 0.9rem; }

.credit { display: grid; gap: 0.15rem; }

.credit__box { font-size: 1rem; }
.credit__what { font-size: 0.9rem; line-height: 1.5; color: var(--paper); }
/* Scoped through .section > p, which would otherwise win on specificity and
   flatten the top margin — the same trap the previews caption hit. */
.section > p.credits__note { margin: 3.5rem 0 0; font-size: 0.9rem; color: var(--paper); }
.section > p.credits__note + p.credits__note { margin-top: 0.35rem; }

@media (min-width: 48rem) {
  /* Box name and credit sit side by side once there's room for both. */
  .credit { grid-template-columns: 12rem 1fr; gap: 1rem; align-items: baseline; }
  .credit__what { font-size: 1rem; }
}
