/* ==========================================================================
   DISPUTT DESIGN SYSTEM — base: reset, page, typography, utilities
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: dark;
  background: var(--burgundy-800);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  color: var(--fg);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  line-height: 1.45;
  font-weight: 500;
  background: var(--tex-grain), var(--tex-dark), var(--bg);
  overscroll-behavior-y: none;
  touch-action: manipulation; /* no double-tap zoom; pinch zoom still works */
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
.display {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.012em;
  text-wrap: balance;
  /* Names end up in headings ("Kari har spørsmålet", "Petter vant!"), and a name is the one thing in them that cannot be
     broken at a space: better broken anywhere than run off the screen. */
  overflow-wrap: anywhere;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); line-height: 1.1; }

p { margin: 0; text-wrap: pretty; overflow-wrap: anywhere; } /* (names sit in sentences too, and a name has no spaces to break at) */
a { color: var(--yellow); text-underline-offset: 0.2em; text-decoration-thickness: 2px; }
strong, b { font-weight: 700; }
small, .small { font-size: var(--fs-small); }
img, svg { display: block; max-width: 100%; }
img { -webkit-user-drag: none; }

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
button { touch-action: manipulation; }

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

::selection { background: var(--yellow); color: var(--ink); }

/* ---- App shell ------------------------------------------------------------ */
#app {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: var(--app-width);
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  overflow-x: clip;
}

.screen {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  padding: var(--page-top) var(--page-x) 0;
}
.screen > .grow { flex: 1 0 auto; }
.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack--tight { gap: var(--s-2); }
.stack--loose { gap: var(--s-5); }
.row { display: flex; align-items: center; gap: var(--s-3); }
.row--wrap { flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.row--center { justify-content: center; }
.center { text-align: center; }
.muted { color: var(--fg-muted); }
.lead { font-size: var(--fs-lead); line-height: 1.35; }
/* (ordinary lower-case text: no capitals, and no wide letter-spacing, which only made sense for capitals) */
.eyebrow {
  font-family: var(--font-text);
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--fg-muted);
}
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
[hidden] { display: none !important; }

/* The bar with a screen's main action (a button), frozen to the bottom of the screen. Its background is solid: the last
   layer is an opaque colour, so nothing that scrolls underneath shows through its text or its button. (A bar that only
   has text or links is not frozen at all: that is `.foot`, below. `node tools/qa/overlap.mjs` checks both rules.) */
.dock {
  --page-bg: var(--burgundy-700);
  --dock-tex: var(--tex-dark);
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin: auto calc(var(--page-x) * -1) 0;
  padding: var(--s-4) var(--page-x) var(--page-bottom);
  background: var(--tex-grain), var(--dock-tex), var(--page-bg);
}
/* A soft edge: what scrolls up to the bar fades into the page colour instead of being cut off by a straight line. */
.dock::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 1.4rem;
  background: linear-gradient(to top, var(--page-bg), transparent);
  pointer-events: none;
}
.dock > * + * { margin-top: var(--s-3); }

/* The end of a page: text and links that need no freezing (waiting for the host, "how to play"). It sits after the
   content, and at the bottom of the screen when the content is short. */
.foot {
  margin-top: auto;
  padding: var(--s-5) 0 var(--page-bottom);
}
.foot > * + * { margin-top: var(--s-3); }

/* A screen that ends without a bar: the same room under the last thing on it. */
.screen--padded { padding-bottom: var(--page-bottom); }

/* Hand-drawn underline under a word */
.scribble {
  display: inline-block;
  padding-bottom: 0.28em;
  background: url('../assets/art/scribble-underline.svg') left bottom / 100% 0.42em no-repeat;
}

/* ---- Boot splash (visible until the app mounts) ---------------------------- */
.boot {
  display: grid;
  place-items: center;
  min-height: 100dvh;
}
.boot img { width: 12rem; height: auto; opacity: 0.9; }

/* ---- Motion ------------------------------------------------------------------ */
@keyframes pop {
  0% { transform: scale(0.3) rotate(-14deg); opacity: 0; }
  70% { transform: scale(1.08) rotate(3deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}
@keyframes rise {
  from { transform: translateY(18px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes slide-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes wobble {
  0%, 100% { transform: rotate(var(--tilt, 0deg)) scale(1, 1); }
  25% { transform: rotate(calc(var(--tilt, 0deg) + 2.2deg)) scale(1.025, 0.975); }
  75% { transform: rotate(calc(var(--tilt, 0deg) - 2.2deg)) scale(0.975, 1.025); }
}
@keyframes float {
  0%, 100% { transform: translateY(0) rotate(var(--tilt, 0deg)); }
  50% { transform: translateY(-10px) rotate(calc(var(--tilt, 0deg) + 3deg)); }
}
@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.06); }
}
@keyframes blink {
  0%, 92%, 100% { transform: scaleY(1); }
  95% { transform: scaleY(0.08); }
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px) rotate(-1deg); }
  40% { transform: translateX(6px) rotate(1deg); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
@keyframes drip {
  from { transform: translateY(-120%) rotate(var(--r0, 0deg)); opacity: 1; }
  to { transform: translateY(120vh) rotate(var(--r1, 360deg)); opacity: 1; }
}

.pop-in { animation: pop 0.5s var(--ease-bounce) both; }
.rise-in { animation: rise 0.45s var(--ease-out) both; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
