/* RUMSPRINGA
   Palette sampled from the source poster. The scene is a responsive
   diorama: independent layers positioned per breakpoint in viewport
   units, never welded to plate pixels. */

:root {
  --paper:        oklch(0.912 0.030 78);
  --paper-shade:  oklch(0.865 0.038 76);
  --ink:          oklch(0.235 0.028 48);
  --ink-muted:    oklch(0.435 0.038 52);
  --wood:         oklch(0.343 0.030 48);
  --wood-dark:    oklch(0.262 0.026 48);
  --barn:         oklch(0.405 0.092 36);
  --gold:         oklch(0.721 0.120 61);
  --straw:        oklch(0.810 0.109 78);

  --nail: radial-gradient(circle at 33% 30%,
      oklch(0.78 0.03 75), oklch(0.42 0.02 60) 46%,
      oklch(0.20 0.02 60) 78%, oklch(0.14 0.02 60));

  --font-body: Bitter, Georgia, "Times New Roman", serif;
  --font-mono: "Courier Prime", ui-monospace, "Courier New", monospace;

  --z-scene: 0;
  --z-signs: 10;
  --z-scrim: 20;
  --z-board: 30;

  --ease-settle: cubic-bezier(.2, 1.5, .35, 1);
  --ease-out: cubic-bezier(.22, 1, .36, 1);

  /* written by main.js, range -1..1 */
  --px: 0;
  --py: 0;
  --sy: 0;   /* mobile hero scroll progress, 0..1 */
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--wood-dark);
  font-family: var(--font-body);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------ the scene */

.scene {
  position: relative;
  width: 100%;
  height: 100svh;
  overflow: hidden;
  z-index: var(--z-scene);
}

/* The plate always covers. Nothing important is welded to it, so cropping
   it is safe -- which is exactly what v1 could not do. */
.plate {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 62%;
  display: block;
}

.layer {
  position: absolute;
  display: block;
  /* Both axes must be auto. The width/height HTML attributes are kept for
     layout stability, but without this the intrinsic width wins over the
     CSS height and every layer sized by height renders stretched. */
  width: auto;
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform;
}

/* Low sun spill and a soft edge burn, so the frame is held by light. */
.veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 45% 40% at 52% 46%,
      oklch(0.86 0.13 72 / .26), transparent 70%),
    radial-gradient(ellipse 120% 100% at 50% 55%,
      transparent 58%, oklch(0.20 0.04 46 / .5) 100%);
}

/* ---------------------------------------------------- layer positioning */

/* The wordmark is regenerated art on a transparent ground. Background
   removal stripped the blue rim glow the original carried, so it is
   restored here rather than baked into the asset. */
.wordmark { filter: drop-shadow(0 0 10px oklch(0.62 0.16 250 / .75))
                    drop-shadow(0 6px 18px oklch(0.15 0.03 45 / .45)); }

/* Mobile first: portrait plate, layers pulled tight. */
.wordmark {
  left: 50%;
  top: 3.5svh;
  width: min(92vw, 560px);
  transform: translateX(-50%);
}

.signpost {
  left: -6vw;
  bottom: 0;
  height: 46svh;
}

.guy {
  left: 56%;
  bottom: 6svh;
  height: 54svh;
  transform: translateX(-50%);
}

/* Desktop: the diorama spreads out. Signpost anchors left, the character
   stands on the road right of centre, and the field on the right is
   deliberate negative space for the board to open into. */
@media (min-width: 900px) {
  .scene { height: 100vh; }
  .plate { object-position: 50% 58%; }

  .wordmark {
    left: 46%;
    top: 2.5vh;
    width: min(52vw, 860px);
  }

  .signpost {
    left: 4vw;
    bottom: -1vh;
    height: min(62vh, 620px);
  }

  .guy {
    left: 52%;
    bottom: 4vh;
    height: min(74vh, 760px);
  }
}

/* Mid-width desktops are the tight case: the board occupies the right
   third, so the character shifts left to keep clear of it. */
@media (min-width: 900px) and (max-width: 1499px) {
  .guy { left: 42%; height: min(66vh, 660px); }
  .signpost { left: 1vw; height: min(54vh, 540px); }
  .signs    { left: 1vw; height: min(54vh, 540px); }
  .wordmark { left: 42%; width: min(56vw, 640px); }
}

@media (min-width: 1500px) {
  .signpost, .signs { left: 8vw; }
  .guy { left: 47%; }
  .wordmark { left: 47%; }
}

/* ------------------------------------------------------ signpost as nav */

.signs {
  position: absolute;
  z-index: var(--z-signs);
  /* the hotspot box tracks the signpost image exactly */
  left: -6vw;
  bottom: 0;
  height: 46svh;
  aspect-ratio: 503 / 1100;
}

@media (min-width: 900px) {
  .signs { left: 4vw; bottom: -1vh; height: min(62vh, 620px); }
}
@media (min-width: 1500px) {
  .signs { left: 8vw; }
}

.sign {
  position: absolute;
  left: var(--l); top: var(--t); width: var(--w); height: var(--h);
  min-height: 40px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: transparent;
  font: inherit;
  cursor: pointer;
  transition: background-color .2s var(--ease-out),
              box-shadow .2s var(--ease-out),
              transform .25s var(--ease-settle);
}

.sign:hover, .sign:focus-visible {
  background: oklch(0.86 0.13 72 / .2);
  box-shadow: 0 0 22px 3px oklch(0.82 0.13 70 / .55);
}
.sign[data-board="farm"]:hover,
.sign[data-board="farm"]:focus-visible { transform: translateX(-3%); }
.sign:not([data-board="farm"]):hover,
.sign:not([data-board="farm"]):focus-visible { transform: translateX(3%); }

.sign:focus-visible { outline: 3px solid var(--straw); outline-offset: 3px; }

@media (hover: none) {
  .sign:active { background: oklch(0.86 0.13 72 / .24); }
}

/* ------------------------------------------------- mobile: the sections */

.sections { display: block; }

.section {
  padding: clamp(2.2rem, 7vw, 3.4rem) clamp(1.1rem, 5vw, 2rem);
  background: url("assets/plank.webp") center / 300px auto repeat;
  border-top: 3px solid var(--wood-dark);
}

.section > .notice { margin: 0 auto; max-width: 34rem; }

@media (min-width: 900px) {
  .sections { display: none; }
}

/* ------------------------------------------------- the paper + the board */

.notice {
  position: relative;
  padding: clamp(1.2rem, 3vw, 1.9rem);
  background: var(--paper);
  background-image:
    radial-gradient(ellipse 70% 55% at 8% 4%, oklch(0.87 0.04 74 / .55), transparent 60%),
    radial-gradient(ellipse 60% 50% at 96% 98%, oklch(0.86 0.045 72 / .6), transparent 62%),
    radial-gradient(ellipse 96% 92% at 50% 50%, transparent 72%, oklch(0.72 0.05 66 / .5) 100%);
  box-shadow:
    0 1px 0 oklch(1 0 0 / .55) inset,
    0 -1px 0 oklch(0.72 0.05 60 / .5) inset,
    0 10px 22px oklch(0.15 0.03 45 / .5);
}

.scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  background: oklch(0.18 0.03 45 / .42);
  animation: fade .2s var(--ease-out) both;
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

@keyframes slam {
  0%   { transform: scale(1.14) rotate(-2.2deg); opacity: 0; }
  55%  { transform: scale(.97)  rotate(.6deg);   opacity: 1; }
  78%  { transform: scale(1.02) rotate(-.3deg); }
  100% { transform: scale(1)    rotate(0deg); }
}

/* Desktop only: the board opens into the open field on the right, so it
   never lands on top of the character. */
.board {
  position: fixed;
  top: 50%;
  right: 4vw;
  z-index: var(--z-board);
  width: min(90vw, 480px);
  margin-top: -1vh;
  translate: 0 -50%;
  padding: 26px 24px;
  background: url("assets/plank.webp") center / 300px auto repeat;
  border: 2px solid var(--wood-dark);
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 1px oklch(0.85 0.08 70 / .18),
    inset 0 2px 14px oklch(0.15 0.03 45 / .55),
    0 34px 80px oklch(0.12 0.03 45 / .7);
  animation: slam .42s var(--ease-settle) both;
}

.board .notice { max-height: min(74vh, 660px); overflow-y: auto; overscroll-behavior: contain; }

.board::before {
  content: "";
  position: absolute;
  inset: 5px;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: 17px 17px;
  background-position: left top, left bottom, right bottom;
  background-image: var(--nail), var(--nail), var(--nail);
}

.nail-close {
  position: absolute;
  top: 5px; right: 5px;
  width: 44px; height: 44px;
  transform: translate(12px, -12px);
  display: grid; place-items: center;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}
.nail-close span {
  display: grid; place-items: center;
  width: 25px; height: 25px;
  border-radius: 50%;
  background: var(--nail);
  box-shadow: 0 1px 3px oklch(0.14 0.02 60 / .7);
  color: var(--paper);
  font-size: .95rem;
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 1px 1px oklch(0.14 0.02 60);
  transition: scale .18s var(--ease-settle), box-shadow .18s var(--ease-out);
}
.nail-close:hover span { scale: 1.25; box-shadow: 0 0 0 3px oklch(0.82 0.13 70 / .5); }
.nail-close:focus-visible { outline: none; }
.nail-close:focus-visible span { scale: 1.25; box-shadow: 0 0 0 3px var(--straw); }

/* ---------------------------------------------------------- notice type */

h2 {
  margin: 0 0 .85rem;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.1rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.01em;
  text-wrap: balance;
  color: var(--ink);
}

.board-body, .section-body { max-width: 65ch; }
.notice p { margin: 0 0 .9rem; line-height: 1.55; text-wrap: pretty; }
.notice p:last-child { margin-bottom: 0; }

.steps { margin: 0 0 1rem; padding-left: 1.35rem; line-height: 1.55; }
.steps li { margin-bottom: .4rem; }
.steps li::marker { color: var(--ink-muted); font-weight: 700; }

.stamp {
  margin-top: 1.2rem;
  padding-top: .9rem;
  border-top: 1px dashed oklch(0.435 0.038 52 / .5);
  font-weight: 700;
  color: var(--ink-muted);
}

.stats { display: grid; grid-template-columns: auto 1fr; gap: .45rem 1rem; margin: 0 0 1rem; }
.stats dt { font-weight: 700; color: var(--ink); }
.stats dd { margin: 0; text-align: right; color: var(--ink-muted); }

.ca {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: center;
  margin: 0 0 1rem;
  padding: .7rem .8rem;
  background: var(--paper-shade);
  border: 1px dashed oklch(0.343 0.030 48 / .6);
  border-radius: 3px;
}
.ca code {
  flex: 1 1 12rem;
  font-family: var(--font-mono);
  font-size: .82rem;
  color: var(--ink);
  word-break: break-all;
}

.btn {
  display: inline-block;
  margin: 0 .5rem .5rem 0;
  padding: .72rem 1.15rem;
  min-height: 44px;
  background: var(--wood-dark);
  color: var(--paper);
  border: 0;
  border-radius: 3px;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover { background: oklch(0.32 0.03 48); }
.btn-primary { background: var(--barn); }
.btn-primary:hover { background: oklch(0.46 0.10 36); }
.btn:focus-visible { outline: 3px solid var(--barn); outline-offset: 2px; }
.btn[aria-disabled="true"] {
  background: oklch(0.435 0.038 52 / .35);
  color: var(--ink-muted);
  cursor: not-allowed;
}
.socials { display: flex; flex-wrap: wrap; gap: 0 .5rem; }
.socials .btn { flex: 1 1 auto; text-align: center; }

@media (max-width: 600px) {
  .ca code { font-size: .74rem; }
}
@media (max-height: 460px) and (min-width: 900px) {
  .board { padding: 14px 12px; }
  .board .notice { max-height: 84vh; padding: 1rem 1.1rem; }
}

/* ---------------------------------------------------------------- motion */

/* Parallax. Percentages of each layer's own box, so the movement scales
   with the layer at every viewport size. */
.wordmark { translate: calc(var(--px) * -1.1%) calc(var(--py) * -0.5%); }
.signpost { translate: calc(var(--px) * -2.6%) calc(var(--py) * -1.1%); }
.signs    { translate: calc(var(--px) * -2.6%) calc(var(--py) * -1.1%); }

/* The character is cut as one piece, so the springs cannot coil on their
   own. The boing comes from the whole body: travel with real overshoot,
   squash and stretch on Y, and a wobble out of phase with both. The pivot
   sits at his boots so squash reads as weight landing. */
@keyframes boing {
  0%,  100% { transform: translateX(-50%) translateY(0)     scaleY(1)    rotate(0deg); }
  18%       { transform: translateX(-50%) translateY(-2.4%) scaleY(1.05) rotate(-1.1deg); }
  42%       { transform: translateX(-50%) translateY(-2.8%) scaleY(0.98) rotate(0.7deg); }
  70%       { transform: translateX(-50%) translateY(0.7%)  scaleY(0.94) rotate(0.4deg); }
  86%       { transform: translateX(-50%) translateY(-0.5%) scaleY(1.02) rotate(-0.2deg); }
}

.guy {
  transform-origin: 50% 97%;
  animation: boing 2.6s ease-in-out infinite;
  translate: calc(var(--px) * -3.6%) calc(var(--py) * -1.5%);
}

@keyframes flare { 0%, 100% { opacity: .85 } 50% { opacity: 1 } }
.veil { animation: flare 7s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .guy, .veil, .board, .scrim { animation: none; }
  .wordmark, .signpost, .signs, .guy { translate: none; }
  .guy { transform: translateX(-50%); }
  .sign { transition: none; }
  .sign:hover, .sign:focus-visible { transform: none; }
}
