/* Palette: Olive Ocher, Orange Yellow and Cerulian Blue,
   from Sanzo Wada's Dictionary of Color Combinations. */
:root {
  --ocher: #d6b43e;
  --yellow: #fcb315;
  --blue: #0093a5;
  --cream: #f8f5ee;
  --check: #f3ecd6;
  --paper: #fffdf8;
  --ink: #17363b;

  --beat: 0.5s;          /* the robot dances at 120 bpm */
  --tile: 128px;         /* two checks wide */
  --edge: 3px;           /* outline weight */

  --pixel: "Jersey 15", ui-monospace, "Courier New", monospace;
  --round: "Nunito", ui-rounded, "Segoe UI", system-ui, sans-serif;
}

@font-face {
  font-family: "Jersey 15";
  src: url("/fonts/jersey-15.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Nunito";
  src: url("/fonts/nunito.woff2") format("woff2");
  font-weight: 200 1000;
  font-display: swap;
}

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

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

body {
  margin: 0;
  min-height: 100svh;
  display: grid;
  background: var(--cream);
  color: var(--ink);
  font: 600 1.0625rem/1.5 var(--round);
  overflow-x: hidden;
}

/* ---------- Drifting chequered background ---------- */

.checks {
  position: fixed;
  inset: calc(var(--tile) * -1);
  z-index: -2;
  background:
    conic-gradient(var(--check) 25%, transparent 0 50%, var(--check) 0 75%, transparent 0)
    0 0 / var(--tile) var(--tile);
  animation: drift 24s linear infinite;
  will-change: transform;
}

/* Keeps the middle of the page calm so the words stay easy to read. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: radial-gradient(closest-side, var(--cream) 20%, transparent);
}

@keyframes drift {
  to { transform: translate3d(var(--tile), var(--tile), 0); }
}

/* ---------- Layout ---------- */

main {
  place-self: center;
  width: min(100%, 44rem);
  padding: clamp(2rem, 6vh, 4rem) 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

h1 {
  margin: 0;
  font: 400 clamp(4rem, 17vw, 6.75rem)/0.95 var(--pixel);
  text-wrap: balance;
}

.fun {
  display: inline-block;
  padding: 0 0.14em;
  background: var(--yellow);
  border: var(--edge) solid var(--ink);
  box-shadow: 0.06em 0.06em 0 var(--ink);
  rotate: -4deg;
  animation: wiggle calc(var(--beat) * 2) step-end infinite;
}

@keyframes wiggle {
  50% { rotate: 3deg; }
}

/* ---------- Robot ---------- */

.robot {
  display: block;
  width: min(78vw, 20rem);
  margin: clamp(1.25rem, 4vh, 2.5rem) 0 clamp(1rem, 3vh, 2rem);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.robot-art {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.r-shadow {
  opacity: 0.12;
}

/* Everything on the robot moves in whole pixels, on the beat. */
.r-bob {
  animation: bob var(--beat) step-end infinite;
}

.r-head {
  animation: tilt calc(var(--beat) * 2) step-end infinite;
}

@keyframes bob {
  50% { transform: translateY(1px); }
}

@keyframes tilt {
  0% { transform: translateX(-1px); }
  50% { transform: translateX(1px); }
}

/* Each arm has an "up" drawing and a "down" drawing; a dance decides which shows when. */
.r-pose,
.r-bulb-on,
.r-heart-lit {
  opacity: 0;
}

@keyframes first-half {
  0% { opacity: 1; }
  50% { opacity: 0; }
}

@keyframes second-half {
  0% { opacity: 0; }
  50% { opacity: 1; }
}

.r-bulb-on {
  animation: first-half var(--beat) step-end infinite;
}

.r-heart-lit {
  animation: second-half calc(var(--beat) * 2) step-end infinite;
}

/* Groove: arms take turns. */
[data-move="groove"] :is(.r-l-up, .r-r-down) {
  animation: first-half calc(var(--beat) * 2) step-end infinite;
}
[data-move="groove"] :is(.r-l-down, .r-r-up) {
  animation: second-half calc(var(--beat) * 2) step-end infinite;
}

/* Hooray: both arms together, head stays level and pops up with them. */
[data-move="hooray"] :is(.r-l-up, .r-r-up) {
  animation: first-half calc(var(--beat) * 2) step-end infinite;
}
[data-move="hooray"] :is(.r-l-down, .r-r-down) {
  animation: second-half calc(var(--beat) * 2) step-end infinite;
}
[data-move="hooray"] .r-head {
  animation-name: pop;
}

@keyframes pop {
  0% { transform: translateY(-1px); }
  50% { transform: none; }
}

/* Sway: slow arms, whole body leaning side to side. */
[data-move="sway"] :is(.r-l-up, .r-r-down) {
  animation: first-half calc(var(--beat) * 4) step-end infinite;
}
[data-move="sway"] :is(.r-l-down, .r-r-up) {
  animation: second-half calc(var(--beat) * 4) step-end infinite;
}
[data-move="sway"] .r-bob {
  animation: lean calc(var(--beat) * 4) step-end infinite;
}

@keyframes lean {
  0% { transform: translate(-1px, 0); }
  25% { transform: translate(-1px, 1px); }
  50% { transform: translate(1px, 0); }
  75% { transform: translate(1px, 1px); }
}

/* Party: arms up, bobbing double time. Plays after someone signs up. */
[data-move="party"] :is(.r-l-up, .r-r-up) {
  opacity: 1;
}
[data-move="party"] .r-bob {
  animation-duration: calc(var(--beat) / 2);
}

/* Face: blinks now and then, and slides toward whatever it is looking at. */
.r-face {
  transform: translate(calc(var(--look-x, 0) * 1px), calc(var(--look-y, 0) * 1px));
}

.r-eyes-open {
  animation: eyes-open 4.5s step-end infinite;
}

.r-eyes-shut {
  opacity: 0;
  animation: eyes-shut 4.5s step-end infinite;
}

@keyframes eyes-open {
  0% { opacity: 1; }
  95% { opacity: 0; }
}

@keyframes eyes-shut {
  0% { opacity: 0; }
  95% { opacity: 1; }
}

.r-eyes-happy,
.r-mouth-happy,
.is-happy .r-eyes,
.is-happy .r-mouth {
  display: none;
}

.is-happy :is(.r-eyes-happy, .r-mouth-happy) {
  display: inline;
}

/* ---------- Sign-up ---------- */

.signup {
  width: min(100%, 30rem);
}

.signup label {
  display: block;
  margin-bottom: 0.6rem;
  font-weight: 800;
  font-size: 1.125rem;
}

.signup-row {
  display: flex;
  gap: 0.75rem;
}

.signup input[type="email"],
.signup button {
  min-height: 3.25rem;
  border: var(--edge) solid var(--ink);
  border-radius: 0;
  box-shadow: 4px 4px 0 var(--ink);
  color: var(--ink);
}

.signup input[type="email"] {
  flex: 1;
  min-width: 0;
  padding: 0 0.9rem;
  background: var(--paper);
  font: 700 1.0625rem var(--round);
  appearance: none;
}

.signup input::placeholder {
  color: var(--ink);
  opacity: 0.45;
}

.signup button {
  padding: 0 1.1rem;
  background: var(--yellow);
  font: 400 1.625rem var(--pixel);
  white-space: nowrap;
  cursor: pointer;
  transition: translate 80ms, box-shadow 80ms;
}

.signup button:hover {
  translate: -1px -1px;
  box-shadow: 5px 5px 0 var(--ink);
}

.signup button:active,
.signup button[aria-busy="true"] {
  translate: 3px 3px;
  box-shadow: 1px 1px 0 var(--ink);
}

:focus-visible {
  outline: var(--edge) solid var(--blue);
  outline-offset: 3px;
}

.trap {
  position: absolute;
  left: -200vw;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Messages. Shown by main.js, or by the address ending in #joined / #oops
   when the form was sent without JavaScript. */
.note {
  display: none;
  margin: 0;
  padding: 0.7rem 1.1rem;
  background: var(--paper);
  border: var(--edge) solid var(--ink);
  box-shadow: 4px 4px 0 var(--blue);
  font: 400 1.75rem/1.2 var(--pixel);
}

.note-oops {
  margin-top: 1.25rem;
  box-shadow: 4px 4px 0 var(--ocher);
  font: 700 1rem/1.4 var(--round);
}

.note:target,
.note.is-shown {
  display: block;
}

main:has(#joined:target) .signup,
main.is-joined .signup {
  display: none;
}

/* ---------- Contact ---------- */

.hello {
  margin: clamp(1.75rem, 5vh, 2.75rem) 0 0;
  font-weight: 700;
}

.hello a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--blue);
  text-decoration-thickness: var(--edge);
  text-underline-offset: 0.3em;
}

.hello a:hover {
  text-decoration-color: var(--yellow);
}

/* ---------- Confetti (added by main.js) ---------- */

.confetti {
  position: fixed;
  z-index: 1;
  width: 10px;
  height: 10px;
  pointer-events: none;
}

/* ---------- Small screens ---------- */

@media (max-width: 30rem) {
  :root {
    --tile: 96px;
  }

  .signup-row {
    flex-direction: column;
    gap: 0.9rem;
  }
}

/* ---------- Calm mode ---------- */

@media (prefers-reduced-motion: reduce) {
  .checks,
  .fun,
  .robot * {
    animation: none !important;
  }

  /* Hold a friendly wave instead of dancing. */
  .r-l-up,
  .r-r-down {
    opacity: 1;
  }
}
