/* ==========================================================================
   Tokens
   ========================================================================== */

:root {
  --color-accent: #0097ff;
  --color-ink: #333;
  --color-grid: #ccc;
  --color-glass: rgb(255 255 255 / 20%);
  --color-sheet: rgb(255 255 255 / 85%);

  --edge: 16px;
  --gap: 8px;
  --panel-size: 320px; /* draw board and chat are square on desktop */
  --tap-size: 44px;
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html,
body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  overscroll-behavior: none; /* no pull-to-refresh while dragging avatars */
}

body {
  font-family: "Gochi Hand", "Comic Sans MS", cursive;
}

/* Long-press must never trigger native UI: iOS magnifier/callout/selection,
   Android text-selection handles and the image/link context menu. */
body {
  -webkit-touch-callout: none; /* iOS link/image callout */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ...except where people actually type. */
input[type="text"],
input:not([type]),
.chat__input {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

img {
  -webkit-user-drag: none;
}

/* Hand-drawn cursors (src/cursor.js). They replace every native cursor, so the
   rules are !important; later, more specific rules pick the tool and grab states. */
*,
*::before,
*::after {
  cursor: var(--cursor-default, default) !important;
}

body:not(.is-dragging-avatar) .draw-panel__canvas[data-tool="paint"] {
  cursor: var(--cursor-paint, default) !important;
}

body:not(.is-dragging-avatar) .draw-panel__canvas[data-tool="erase"] {
  cursor: var(--cursor-erase, default) !important;
}

body:not(.is-dragging-avatar) .draw-panel__canvas[data-tool="fill"] {
  cursor: var(--cursor-fill, default) !important;
}

body.is-dragging-avatar,
body.is-dragging-avatar *,
canvas[data-grab] {
  cursor: var(--cursor-grab, default) !important;
}

canvas {
  image-rendering: pixelated;
}

input,
button {
  font: inherit; /* form controls don't inherit fonts by default */
}

button {
  cursor: pointer;
  touch-action: manipulation; /* no double-tap zoom delay */
  -webkit-tap-highlight-color: transparent;
}

.accent {
  color: var(--color-accent);
}

/* Available to screen readers only. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.svg-defs {
  position: absolute;
  width: 0;
  height: 0;
}

/* ==========================================================================
   World and overlay
   ========================================================================== */

@property --dim {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

.world[data-dim] {
  --dim: 0.7;
}

.world {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  /* grey = the image's average color, shown while it loads */
  background-color: #e2e2e2;
  /* The dim layer is part of the world's own background, so the avatars drawn
     on the canvas stay bright while the disco is on. */
  background-image:
    linear-gradient(rgb(15 5 40 / var(--dim)), rgb(15 5 40 / var(--dim))),
    url("public/background.jpg");
  background-position: center;
  background-size: cover;
  transition: --dim 0.8s;
  touch-action: none; /* lets you drag your own avatar without the browser taking over */
}

.world:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: -6px;
}

/* The overlay lets touches through to the world; only its children catch them. */
.ui {
  position: relative;
  z-index: 10;
  height: 100%;
  padding: var(--edge);
  pointer-events: none;
}

.site-header {
  display: flex;
  gap: 12px; /* between the logo and the description */
  width: fit-content;
  max-width: 100%;
  pointer-events: auto;
}

.site-header__logo {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 110px; /* the GIF is cropped to its drawing, so this is smaller than the old 200px */
}

.site-header__logo:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

.site-header__text {
  max-width: 400px;
  padding-top: 4px;
}

/* Disco easter egg (src/disco.js): the lights canvas sits above the world but
   below the UI, and never catches input. */
.disco {
  position: fixed;
  inset: 0;
  z-index: 5;
  width: 100%;
  height: 100%;
  pointer-events: none;
  image-rendering: pixelated; /* the canvas is tiny; scale it up with hard edges */
}

.disco[hidden] {
  display: none;
}

/* Music player: the play/pause button with the current track beside it, centered
   at the bottom between the chat and the draw panel. On compact screens it sits at
   the top of the bottom sheet instead (see src/main.js). */
.player {
  position: fixed;
  bottom: var(--edge);
  left: 50%;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--gap);
  width: max-content;
  max-width: calc(100vw - 2 * (var(--panel-size) + 2 * var(--edge))); /* the gap between the two panels */
  transform: translateX(-50%);
}

.dock .player {
  position: static;
  width: auto;
  max-width: none;
  transform: none;
}

.music-toggle {
  display: grid;
  flex: none;
  place-items: center;
  width: var(--tap-size);
  height: var(--tap-size);
  padding: 0;
  border: 1px solid var(--color-ink);
  border-radius: 0;
  background: var(--color-sheet);
  color: var(--color-ink);
}

/* Shows the action the button will take: pause icon while playing, play icon otherwise. */
.music-toggle[data-state="playing"] .music-toggle__icon--play,
.music-toggle:not([data-state="playing"]) .music-toggle__icon--pause {
  display: none;
}

/* Track title, artist and a link to the track, or "Tap to play" while the browser
   is holding the music back. No box of its own; a soft white halo keeps it readable. */
.music-now {
  min-width: 0;
  margin: 0;
  font-size: 15px;
  line-height: 1.3;
  text-shadow: 0 0 3px #fff, 0 0 6px #fff;
}

.music-now[hidden],
.music-now[data-dock-hidden] {
  display: none; /* data-dock-hidden: hidden with the dock's down button; the button stays */
}

.music-now a {
  color: var(--color-accent);
}

.music-toggle[data-state="playing"] {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* Wanted but blocked by the browser until the first tap: nudge so it's noticeable. */
.music-toggle[data-state="waiting"] {
  animation: music-nudge 1.6s ease-in-out infinite;
}

@keyframes music-nudge {
  50% {
    transform: scale(1.12);
  }
}

@media (prefers-reduced-motion: reduce) {
  .music-toggle[data-state="waiting"] {
    animation: none;
  }
}

/* ==========================================================================
   Dock: draw board (bottom-right) and chat (bottom-left)
   ========================================================================== */

.dock {
  position: absolute;
  right: var(--edge);
  bottom: var(--edge);
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  width: var(--panel-size);
  pointer-events: auto;
}

.tabs {
  display: none; /* only used by the compact layout */
}

/* Hide/show button: a small box just outside the dock's top-right corner. */
.dock__toggle {
  position: absolute;
  right: 0;
  bottom: calc(100% + 6px);
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
}

.dock__toggle svg {
  transition: transform 0.15s;
}

.dock[data-hidden] .dock__toggle svg {
  transform: rotate(180deg);
}

.dock[data-hidden] .draw-panel,
.dock[data-hidden] .chat,
.dock[data-hidden] .tabs {
  display: none;
}

/* Draw panel */

.draw-panel {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

.draw-panel__hint {
  margin: 0;
}

.draw-panel__hint--touch {
  display: none;
}

@media (pointer: coarse) {
  .draw-panel__hint--pointer {
    display: none;
  }

  .draw-panel__hint--touch {
    display: block;
  }
}

/* Wraps the canvas so the keyboard cursor can sit exactly over it. */
.draw-panel__board {
  position: relative;
  display: grid;
  width: fit-content;
}

/* The cell the arrow keys are on; only shown while the board has keyboard focus. */
.draw-panel__cursor {
  position: absolute;
  display: none;
  width: calc(100% / 16);
  height: calc(100% / 16);
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
  pointer-events: none;
}

.draw-panel__canvas:focus-visible + .draw-panel__cursor {
  display: block;
}

.draw-panel__canvas:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

.draw-panel__canvas {
  width: var(--draw-size, var(--panel-size));
  aspect-ratio: 1;
  background-image:
    linear-gradient(to right, var(--color-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--color-grid) 1px, transparent 1px);
  background-size: calc(100% / 16) calc(100% / 16);
  outline: 1px solid var(--color-ink);
  cursor: pointer;
  touch-action: none; /* painting and hold-to-drag must not scroll the page */
  -webkit-touch-callout: none;
  user-select: none;
}

.draw-panel__tools {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
}

/* Native color inputs look different on every platform (iOS pill, Android
   square, tiny desktop box), so strip them down to one flat swatch. */
.draw-panel__color {
  width: 100%;
  min-height: var(--tap-size);
  padding: 0;
  border: 1px solid var(--color-ink);
  border-radius: 0;
  background: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.draw-panel__color::-webkit-color-swatch-wrapper {
  padding: 0;
}

.draw-panel__color::-webkit-color-swatch {
  border: 0;
  border-radius: 0;
}

.draw-panel__color::-moz-color-swatch {
  border: 0;
  border-radius: 0;
}

.draw-panel__fill,
.draw-panel__erase,
.draw-panel__clear,
.draw-panel__undo,
.draw-panel__redo {
  min-height: var(--tap-size);
}

.draw-panel__fill[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: #fff;
}

/* The transparent "color": a checkerboard swatch that sits next to the picker.
   Whichever of the two is active gets the accent ring. */
.draw-panel__erase {
  width: 100%;
  border: 1px solid var(--color-ink);
  border-radius: 0;
  background:
    repeating-conic-gradient(#bbb 0% 25%, #fff 0% 50%) 0 0 / 16px 16px;
}

/* Color and Transparent are two swatches with captions; the one in use gets a
   ring and an accent caption. */
.swatch {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.swatch__label {
  text-align: center;
  font-size: 14px;
}

.draw-panel__erase[aria-pressed="true"],
.draw-panel__tools:not(:has(.draw-panel__erase[aria-pressed="true"])) .draw-panel__color {
  outline: 3px solid var(--color-accent);
  outline-offset: 1px;
}

.swatch--clear:has([aria-pressed="true"]) .swatch__label,
.draw-panel__tools:not(:has(.draw-panel__erase[aria-pressed="true"])) .swatch--color .swatch__label {
  color: var(--color-accent);
}

/* Chat */

.chat {
  position: fixed;
  bottom: var(--edge);
  left: var(--edge);
  display: grid;
  grid-template-rows: 1fr; /* messages fill the panel; the lock note and form take what they need */
  grid-auto-rows: auto;
  gap: var(--gap);
  width: var(--panel-size);
  height: var(--panel-size);
}

.chat__messages {
  min-height: 0;
  padding: var(--gap);
  overflow-y: auto;
  overflow-wrap: anywhere;
  border: 1px solid var(--color-grid);
  background-color: var(--color-glass);
}

.chat__lock {
  margin: 0;
  color: var(--color-accent);
}

.chat__lock[hidden] {
  display: none;
}

.chat__form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--gap);
}

.chat__input {
  min-width: 0;
}

/* ==========================================================================
   Compact layout: phones, and landscape phones (wide but short).
   The dock becomes a bottom sheet with Draw / Chat tabs so the world stays
   visible for dropping avatars. Keep the query in sync with COMPACT_QUERY in
   src/config.js.
   ========================================================================== */

@media (max-width: 700px), (max-height: 500px) {
  input,
  button {
    font-size: 16px; /* anything smaller makes iOS zoom in on focus */
  }

  .ui {
    height: 100dvh;
    padding:
      max(10px, env(safe-area-inset-top))
      max(10px, env(safe-area-inset-right))
      10px
      max(10px, env(safe-area-inset-left));
  }

  .site-header__logo {
    max-height: 40px;
  }

  .site-header__text {
    padding-top: 4px;
    font-size: 14px;
    line-height: 1.2;
    max-width: none;
  }

  .site-header__text p {
    margin: 0 0 4px;
  }

  .dock {
    --draw-size: min(52vw, 36dvh, var(--panel-size));

    inset: auto 0 0;
    width: auto;
    padding:
      var(--gap)
      max(12px, env(safe-area-inset-right))
      max(12px, env(safe-area-inset-bottom))
      max(12px, env(safe-area-inset-left));
    border-top: 1px solid var(--color-ink);
    background: var(--color-sheet);
    transition: opacity 0.15s;
  }

  /* Tabs */

  .tabs {
    display: flex;
    gap: var(--gap);
  }

  .tabs__tab {
    flex: 1;
    min-height: var(--tap-size);
  }

  .tabs__tab[aria-selected="true"] {
    border-color: var(--color-accent);
    background: var(--color-accent);
    color: #fff;
  }

  /* Hidden: only the toggle stays, floating above the bottom edge. */
  .dock[data-hidden] {
    padding-top: 0;
    border-top: 0;
    background: none;
  }

  .dock__toggle {
    right: max(12px, env(safe-area-inset-right));
    bottom: calc(100% + 6px);
  }

  .dock[data-tab="draw"] .chat,
  .dock[data-tab="chat"] .draw-panel,
  .dock[data-collapsed] .draw-panel,
  .dock[data-collapsed] .chat {
    display: none;
  }

  /* Draw panel: board on the left, hint and tools on the right */

  .draw-panel {
    display: grid;
    grid-template: "board hint" 1fr "board tools" auto / auto 1fr;
    column-gap: 12px;
  }

  .draw-panel__hint {
    grid-area: hint;
    align-self: start;
    font-size: 14px;
    line-height: 1.2;
  }

  .draw-panel__board {
    grid-area: board;
  }

  .draw-panel__tools {
    grid-area: tools;
    align-self: end;
  }

  /* Chat */

  .chat {
    position: static;
    width: 100%;
    height: min(40dvh, 280px);
  }

  .chat__input,
  .chat__send {
    min-height: var(--tap-size);
  }

  /* While dragging an avatar, get the sheet out of the way so the drop lands
     on the world. The board keeps pointer events because it owns the capture. */
  body.is-dragging-avatar .dock {
    opacity: 0.3;
    pointer-events: none;
  }

  body.is-dragging-avatar .draw-panel__canvas {
    pointer-events: auto;
  }
}

/* Landscape phones: the sheet moves to the right edge to save vertical space. */
@media (max-height: 500px) and (orientation: landscape) {
  .dock {
    --sheet-width: min(45vw, 360px);
    --draw-size: min(calc(100dvh - 100px), 200px);

    left: auto;
    width: var(--sheet-width);
    max-height: 100dvh;
    border-left: 1px solid var(--color-ink);
  }

  .site-header {
    max-width: calc(100% - var(--sheet-width) - 10px);
  }

  .site-header__text p:last-child {
    display: none;
  }

  .chat {
    height: calc(100dvh - 100px);
  }
}
