/* ---------------------------------------------------------------------------
   Colour — a phone drawing toy for small hands.
   Everything is oversized, high-contrast, and impossible to break by tapping.
--------------------------------------------------------------------------- */

:root {
  /* Gap between the toolbar and the bottom of the safe area. Named because the
     stow distance is derived from it in JS — see "Stowing the toolbar". */
  --tb-gap: 22px;

  /* Not pure white, for the same reason the dark paper is not pure black: an
     unbroken extreme reads as a screen rather than as a surface. The lift is
     much smaller than dark's — dark comes 22/255 off black to keep shadows
     alive, while light only needs enough to take the glare off and let a white
     pigment show against it. Warm rather than cool, because paper is warm and
     this app is about paint. */
  --paper: #fdfbf6;
  --bg: #f5f1e9;
  --panel: rgba(255, 253, 249, 0.92);
  --menu-text: #333333;
  --track: #e2e2e2;
  --grip: #cfcfcf;
  --grip-active: #9a9a9a;
  /* The palette's own "paper" — a warm ceramic, so mixed paint reads as paint
     rather than as ink on the same white the drawing sits on. */
  --palette-face: #f3efe6;
  --thumb-face: #fffdf9;
  --thumb-ring: #bbbbbb;
  --ring: rgba(0, 0, 0, 0.14);
  --active-ring: rgba(0, 0, 0, 0.55);
  --shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
  --danger: #e5342b;
  --eraser-stroke: #555555;
}

body.dark {
  --paper: #16181c;
  --bg: #0e0f11;
  --panel: rgba(34, 37, 42, 0.92);
  --menu-text: #ececec;
  --track: #3a3d43;
  --grip: #565b62;
  --grip-active: #8b9199;
  --palette-face: #24272c;
  --thumb-face: #ececec;
  --thumb-ring: #6a6e75;
  --ring: rgba(255, 255, 255, 0.22);
  --active-ring: rgba(255, 255, 255, 0.85);
  --shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  --danger: #ff6b61;
  --eraser-stroke: #cfd2d6;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  /* Kill every native touch gesture: scroll, pinch-zoom, double-tap-zoom. */
  touch-action: none;
  overscroll-behavior: none;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  transition: background 0.2s ease;
}

/* Body alone, deliberately. The theme is a class on <body>, so an <html> asking
   for var(--bg) is above it in the tree and only ever sees the light value —
   which then paints every strip the board does not cover, in either theme. Left
   without a background of its own, <html> hands the page background to <body>,
   where the class actually applies. */
body {
  background: var(--bg);
}

#board {
  position: fixed;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  background: var(--paper);
  touch-action: none;
  transition: background 0.2s ease;
}

/* --- Settings (top-left gear + menu) ------------------------------------ */

.settings {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 16px);
  left: calc(env(safe-area-inset-left, 0px) + 16px);
  /* Above the toolbar, not level with it: the menu is long enough to reach the
     panel, and a lifted panel comes up to meet it. Level pegging let the toolbar
     win on document order and swallow the last item or two. */
  z-index: 12;
}

.icon-btn {
  width: 56px;
  height: 56px;
  border: none;
  border-radius: 50%;
  background: var(--panel);
  box-shadow: var(--shadow);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: transform 0.12s ease;
}

.icon-btn:active {
  transform: scale(0.92);
}

.icon-btn svg {
  width: 26px;
  height: 26px;
  fill: var(--menu-text);
}

.settings-menu {
  position: absolute;
  top: 66px;
  left: 0;
  min-width: 200px;
  background: var(--panel);
  border-radius: 18px;
  box-shadow: var(--shadow);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Seven colourways make this taller than a short screen in landscape. Scroll
     inside rather than run off the bottom; the touchmove guard already lets
     gestures through inside #settings, and `contain` stops a flick at the end
     of the list carrying on into the page behind. */
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.settings-menu[hidden] {
  display: none;
}

.menu-item {
  border: none;
  background: transparent;
  border-radius: 12px;
  padding: 16px 18px;
  font-size: 18px;
  font-weight: 600;
  color: var(--menu-text);
  text-align: left;
  cursor: pointer;
}

.menu-item:active {
  background: rgba(128, 128, 128, 0.18);
}

/* Delete page on the home page: home answers to its address whether or not we
   list it, so there is nothing there to delete. */
.menu-item:disabled {
  opacity: 0.38;
  cursor: default;
}

.menu-item:disabled:active {
  background: transparent;
}

.menu-item--danger {
  color: var(--danger);
}

/* --- Colourways in the menu --------------------------------------------- */

.menu-sep {
  height: 1px;
  background: rgba(128, 128, 128, 0.25);
  margin: 6px 12px;
}

.menu-cap {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--menu-text);
  opacity: 0.55;
  padding: 2px 18px 4px;
}

.menu-sets,
.menu-pages {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* A page row is a name and nothing else, so it needs the truncation a colourway
   row — which is a word and a fixed strip of dots — never does. */
.menu-page {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Shorter than a menu item, and wearing its own pigments: a colourway is a set
   of colours, so the row is the colours rather than a word for them. */
.menu-set {
  border: none;
  background: transparent;
  border-radius: 12px;
  padding: 9px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  font-size: 16px;
  font-weight: 600;
  color: var(--menu-text);
  text-align: left;
  cursor: pointer;
}

.menu-set:active {
  background: rgba(128, 128, 128, 0.18);
}

.menu-set-strip {
  display: flex;
  gap: 5px;
  flex: 0 0 auto;
}

.menu-set-strip i {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--c);
  /* A rim, so a pale pastel or a full white still reads as a disc on the menu. */
  box-shadow: inset 0 0 0 1px var(--ring);
}

/* A colourway is a choice, not a command, so the one in force stays lit rather
   than only reading right the moment it is pressed. */
.menu-set[aria-checked="true"] {
  background: rgba(128, 128, 128, 0.18);
}

/* --- Toolbar (colours + size) ------------------------------------------ */

/* One panel holds both rows. Generous horizontal padding leaves room for the
   big knob to sit near the slider's end without touching the panel edge. */
.toolbar {
  position: fixed;
  left: 50%;
  /* --tb-shift rides on top of the centring translate: JS slides the panel down
     to stow it, so the layout position stays the "home" it snaps back to. */
  transform: translateX(-50%) translateY(var(--tb-shift, 0px));
  bottom: calc(env(safe-area-inset-bottom, 0px) + var(--tb-gap));
  z-index: 10;
  width: min(86vw, 430px);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 4px 24px 20px;
  background: var(--panel);
  border-radius: 32px;
  box-shadow: var(--shadow);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  will-change: transform;
}

/* Only while snapping home or away — a dragging panel must track the finger
   with no lag at all, and the class is dropped again on transitionend. */
.toolbar.is-settling {
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Mixing palette ----------------------------------------------------- */

/* Same width and same resting place as the toolbar, one layer behind it, and
   JS matches its height too — so at home it is exactly covered and lifting the
   toolbar is the whole reveal. Its own translate only ever runs downwards, to
   stay tucked under a stowing toolbar. */
.palette {
  position: fixed;
  left: 50%;
  transform: translateX(-50%) translateY(var(--pl-shift, 0px));
  bottom: calc(env(safe-area-inset-bottom, 0px) + var(--tb-gap));
  z-index: 9;
  width: min(86vw, 430px);
  background: var(--palette-face);
  border-radius: 32px;
  box-shadow: var(--shadow);
  overflow: hidden; /* keeps paint inside the rounded card */
  /* Hidden until lifted: the toolbar over it is only 92% opaque, so a palette
     left at full strength behind it would show through as a smudge. */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, background 0.2s ease;
  will-change: transform;
}

.palette.is-revealed {
  opacity: 1;
  pointer-events: auto;
}

.palette.is-settling {
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.18s ease, background 0.2s ease;
}

/* Transparent, like the board: the card's background is the palette's face, so
   a theme switch recolours it without touching the paint. */
.palette-board {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}

/* --- Toolbar grab-handle ------------------------------------------------ */

/* Full panel width so it is hard to miss, and tall enough to stay a real touch
   target once it is the only thing left on screen. */
.tb-handle {
  align-self: stretch;
  height: 34px;
  margin-bottom: -6px;
  border: none;
  background: transparent;
  display: grid;
  place-items: center;
  cursor: grab;
  touch-action: none;
}

.tb-grip {
  width: 68px;
  height: 7px;
  border-radius: 999px;
  background: var(--grip);
  transition: background 0.16s ease;
}

/* Driven by a class, not :active — the press is preventDefault-ed by the
   pointer router, which suppresses the native active state. */
.toolbar.is-dragging {
  cursor: grabbing;
}

.toolbar.is-dragging .tb-grip {
  background: var(--grip-active);
}

/* Buttons: their own row, spanning the panel width. */
.colors {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 6px;
  min-height: 64px;
}

/* Unselected swatches are small; the active one grows big and obvious. */
.swatch {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 3px solid transparent;
  background: var(--c, #ccc);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: width 0.16s ease, height 0.16s ease, border-color 0.16s ease;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.35);
  flex: 0 0 auto;
}

.swatch:active {
  opacity: 0.8;
}

.swatch.is-active {
  width: 64px;
  height: 64px;
  border-color: var(--active-ring);
}

/* Black on a light panel, white on a dark one, so it always stands off the
   panel by itself. The default swatch highlight is a white inner ring, which
   would draw itself right across the black one — this uses the neutral ring
   instead, which disappears into either. */
.swatch--contrast {
  box-shadow: inset 0 0 0 2px var(--ring);
}

.swatch--eraser {
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--ring);
  font-size: 18px;
  line-height: 1;
  transition: width 0.16s ease, height 0.16s ease, border-color 0.16s ease,
    font-size 0.16s ease;
}

.swatch--eraser.is-active {
  font-size: 34px;
}

/* The eyedropper, in the palette's top-right corner. Same swatch as the rest,
   so it grows when it is the live tool; its face carries whatever colour was
   last lifted, which is what makes it read as "your mixed colour". */
.swatch--pick {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  background: var(--c, var(--palette-face));
  box-shadow: inset 0 0 0 2px var(--ring);
  font-size: 18px;
  line-height: 1;
  transition: width 0.16s ease, height 0.16s ease, border-color 0.16s ease,
    font-size 0.16s ease;
}

/* Unlike the others this one does not grow when it is the live tool: being big
   means "armed and waiting", so once it has a colour it shrinks back and just
   holds it. The active ring off .swatch still says it is the tool in hand. */
.swatch--pick.is-active {
  width: 30px;
  height: 30px;
  font-size: 18px;
}

/* Armed and waiting for you to touch a colour — the one state worth the size. */
.swatch--pick.is-picking {
  width: 64px;
  height: 64px;
  font-size: 30px;
  animation: pick-pulse 1.1s ease-in-out infinite;
}

@keyframes pick-pulse {
  50% {
    box-shadow: inset 0 0 0 2px var(--ring), 0 0 0 9px rgba(128, 128, 128, 0.2);
  }
}

/* Pen-size slider: its own div, a little narrower than the buttons row and
   centred. A wedge behind fattens to the right so the shape says "bigger this
   way"; the knob grows with the size and its centre reaches the rims. Being
   narrower keeps the big knob clear of the panel edge. */
.slider {
  position: relative;
  align-self: center;
  width: calc(100% - 56px);
  height: 68px;
}

.slider-wedge {
  position: absolute;
  inset: 0;
  margin: auto 0;
  height: 48px;
  background: var(--track);
  clip-path: polygon(0% 44%, 100% 0%, 100% 100%, 0% 56%);
  pointer-events: none;
}

/* The wedge doubles as the paint-amount meter, filling from the bottom as the
   amount rises. The parent's clip-path shapes this too, so the level reads
   inside the wedge's silhouette rather than as a bar behind it — which is also
   why the fill leans right: that is where the wedge has height to fill.
   Deliberately a neutral rather than the paint colour: the knob beside it is
   already the colour cue, and two of them made the panel shout. */
.slider-wedge::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--amt, 0) * 100%);
  background: var(--grip-active);
}

/* Reachable by keyboard and assistive tech, absent for everyone else — for a
   control whose real interface is a gesture (see #amount in index.html). */
.a11y-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The visible knob. Its left is a % set from JS and it is centred on that
   point, so at min/max the centre sits right on the track's outer rim. */
.slider-knob {
  position: absolute;
  top: 50%;
  left: 0;
  width: var(--thumb, 24px);
  height: var(--thumb, 24px);
  border-radius: 50%;
  background: var(--thumb-face);
  border: 3px solid var(--thumb-ring);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* The knob previews the mark: its diameter is the pen size, and this disc is the
   colour at the current paint amount. Drag the slider up and down and the fill
   is what tells you the amount changed — there is no second track to watch. */
.slider-knob::after {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: var(--ink-c, transparent);
  opacity: var(--amt, 1);
}

.size {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  width: 100%;
  height: 68px;
  background: transparent;
  outline: none;
  cursor: pointer;
}

.size::-webkit-slider-runnable-track {
  height: 48px;
  background: transparent;
}

/* Native thumb is a thin, invisible strip: 1px wide keeps the value mapping
   linear across the full track (so the knob centre tracks the rim exactly);
   tall for an easy grab. */
.size::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1px;
  height: 48px;
  background: transparent;
  border: none;
}

.size::-moz-range-track {
  height: 48px;
  background: transparent;
}

.size::-moz-range-thumb {
  width: 1px;
  height: 48px;
  background: transparent;
  border: none;
}
