/* Minimal on purpose. Phase 1 brings the real layout; this only needs to make
   the prose readable while the structure is being proved. */

:root {
  --ink: #1b1b1f;
  --ink-soft: #55555f;
  --paper: #fbfaf7;
  --rule: #e2ded6;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #eceaea;
    --ink-soft: #a7a4ad;
    --paper: #17171a;
    --rule: #33323a;
  }
}

* { box-sizing: border-box; }

body {
  /* System stack: the page must never block on a font download. */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--paper);
  margin: 0;
  padding: 2rem 1.25rem 4rem;
  line-height: 1.6;
}

:root { --shell: 70rem; }

.layout, footer {
  max-width: var(--shell);
  margin: 0 auto;
}

.layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
}

/* The square drawing surface. Its exact pixel size is set by JavaScript to
   the largest square that fits inside this box; the rules here only decide
   how much room the box gets. Sized off dvh rather than vh, because iOS's
   collapsing toolbar makes vh taller than the visible page and clips the
   wheel at the worst possible moment. */
.stage {
  width: 100%;
  max-width: 32rem;
  aspect-ratio: 1 / 1;
  max-height: 60dvh;
  display: grid;
  place-items: center;
}

.stage canvas {
  display: block;
  cursor: pointer;
  /* Tapping the wheel spins it, so the browser must not spend 300ms waiting
     to see whether a second tap is coming, and must not treat one as zoom. */
  touch-action: manipulation;
}

.stage-wrap {
  width: 100%;
  max-width: 32rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.result {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 600;
  text-align: center;
  /* The full label, always, whatever the wheel could fit on the slice. */
  overflow-wrap: anywhere;
}

.wheel-note {
  margin: 0;
  padding: 0 1rem;
  text-align: center;
  color: var(--ink-soft);
}

.beside {
  width: 100%;
  max-width: 38rem;
}

/* The only layout fork in the project. Portrait puts the wheel above the
   words, landscape puts it beside them. One orientation query rather than a
   ladder of breakpoints, so a phone on its side and a laptop take the same
   path through the code. */
@media (orientation: landscape) {
  /* Wider than the reading measure, because side by side there are two
     columns to fit and the wheel wants the room. The prose beside it is still
     held to 38rem, so nothing gets a line length you cannot read. */
  :root { --shell: 96rem; }

  .layout {
    flex-direction: row;
    align-items: flex-start;
    gap: 2.5rem;
  }

  /* A share of the row, not of the viewport: the layout is capped and the
     viewport is not, so sizing this off vw let the wheel take most of a wide
     screen and squeezed the editor beside it down to nothing.
     The height cap is what binds on most screens — a wheel is only ever as
     big as the shortest side lets it be. */
  .stage-wrap {
    flex: 0 1 auto;
    width: min(60%, 84dvh);
    max-width: none;
    position: sticky;
    top: 1.5rem;
  }

  .beside {
    flex: 1 1 0;
    min-width: 0;
  }

  .stage {
    width: 100%;
    max-width: none;
    max-height: 84dvh;
  }
}

/* ── the app ──────────────────────────────────────────────────────────── */

.app { margin-bottom: 3rem; }

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

button {
  font: inherit;
  padding: 0.5rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 0.4rem;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

button:hover:not(:disabled) { border-color: var(--ink-soft); }
button:disabled { opacity: 0.45; cursor: not-allowed; }

button.primary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  font-weight: 600;
}

/* Never remove the focus ring: the editor has to be usable from the keyboard
   end to end, and that is only true if you can see where you are. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.toggles {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

/* Each toggle carries its own explanation. "Draw without replacement" is the
   correct term and useless to most of the people this is for, so the plain
   description leads and the term follows it. */
.toggle {
  display: flex;
  align-items: start;
  gap: 0.5rem;
  cursor: pointer;
}

.toggle input { margin-top: 0.3rem; flex: 0 0 auto; }
.toggle-name { display: block; }

.toggle-hint {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
  max-width: 34rem;
}

.legend {
  list-style: none;
  padding: 0;
  margin: 0 0 1.25rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.25rem 1rem;
  font-size: 0.9rem;
}

.legend li { display: flex; align-items: center; gap: 0.5rem; }

.swatch {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 0.2rem;
  flex: 0 0 auto;
}

/* ── the editor ───────────────────────────────────────────────────────── */

.field { display: block; margin-bottom: 1rem; }
.field span { display: block; font-size: 0.85rem; color: var(--ink-soft); }

input[type="text"], input[type="number"] {
  font: inherit;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 0.3rem;
  background: var(--paper);
  color: var(--ink);
  min-width: 0;
}

.field input { width: 100%; }

/* Wraps rather than crushes. A grid would shrink the first column to zero
   when the panel is narrow, which hides the label input entirely and leaves
   a row of controls with nothing to explain them. The label keeps a floor of
   8rem and the buttons drop to a second line instead. */
.slice {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  margin-bottom: 0.5rem;
}

.slice-label { flex: 1 1 8rem; }
.slice-pct { flex: 0 0 4.5rem; }

/* The resolved percentage — the number the wheel will use, not the number
   typed. Every ambiguous case in the resolution rules becomes visible here
   rather than surprising. */
.slice-resolved {
  /* Allowed to grow, because an excluded slice appends a word to it. */
  flex: 0 1 auto;
  min-width: 4.5rem;
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: right;
}

.slice.is-excluded .slice-label { text-decoration: line-through; }
.slice.is-excluded .slice-resolved::after { content: " excluded"; }

button.icon {
  padding: 0.3rem 0.5rem;
  line-height: 1;
}

button.remove:hover:not(:disabled) { border-color: #c4564f; color: #c4564f; }

.add { margin-top: 0.5rem; }

.messages { margin-top: 0.75rem; }
.message { margin: 0.2rem 0; font-size: 0.9rem; }
.message.quiet { color: var(--ink-soft); }
.message.warn  { color: #8a6d1f; }
.message.error { color: #c4564f; font-weight: 600; }

@media (prefers-color-scheme: dark) {
  .message.warn { color: #d7b05a; }
}

/* ── present mode ─────────────────────────────────────────────────────── */

/* No chrome: no editor, no controls, no branding. Only the wheel and the
   result it lands on. */
body.presenting { padding: 0; }
body.presenting .masthead,
body.presenting .beside,
body.presenting footer,
body.presenting .wheel-note { display: none; }

body.presenting .layout {
  max-width: none;
  height: 100dvh;
  justify-content: center;
}

body.presenting .stage-wrap {
  width: min(96vw, 92dvh);
  max-width: none;
  position: static;
}

body.presenting .stage { max-height: 84dvh; }
body.presenting .result { font-size: clamp(1.8rem, 5vw, 4rem); }

/* Understated enough not to compete with the wheel, but a proper 44px touch
   target and never hidden — a presenter who has forgotten how they got here
   needs something to reach for. */
.leave {
  position: fixed;
  top: max(0.75rem, env(safe-area-inset-top));
  right: max(0.75rem, env(safe-area-inset-right));
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  font-size: 1.5rem;
  line-height: 1;
  border-radius: 50%;
  opacity: 0.3;
  z-index: 10;
}

.leave:hover, .leave:focus-visible { opacity: 1; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Above both columns, and first in the document. The heading that names the
   page should not come after the tool it names — for a reader or a crawler. */
.masthead {
  max-width: var(--shell);
  margin: 0 auto 2rem;
}

h1 {
  font-size: 2.5rem;
  letter-spacing: -0.02em;
  margin: 0 0 0.25rem;
}

.standfirst {
  font-size: 1.2rem;
  color: var(--ink-soft);
  margin: 0;
}

h2 {
  font-size: 1.1rem;
  margin: 2.25rem 0 0.5rem;
}

p { margin: 0 0 1rem; }

.status p {
  color: var(--ink-soft);
}

footer {
  margin-top: 3.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 0.9rem;
}
