:root {
  --paper: #fff;
  --text: #1c1b2e;
  --muted: #6b6f80;                       /* 4.9:1 on white: AA for the small status and note text */
  --panel: rgba(255, 255, 255, .88);
  --panel-solid: #fff;
  --line: rgba(20, 8, 88, .14);
  --hover: rgba(20, 8, 88, .07);
  --accent: #0050b4;
  --danger: #c0262d;
  --warn: #8a5300;
  color-scheme: light;
}

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

/* An author `display` beats the UA's [hidden] rule, and the toolbar buttons all set one. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  overscroll-behavior: none;              /* no pull-to-refresh or rubber-band under the pen */
  background: var(--paper);
  color: var(--text);
  font: 14px/1.4 system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;            /* iOS: no callout / loupe on a long press */
  -webkit-tap-highlight-color: transparent;
}

/* The writing surface is the whole viewport. `fixed` + `inset: 0` rather than 100vh, which
   on a phone includes the part of the page the address bar is covering. */
#board {
  position: fixed;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;                     /* handwriting.js sets this too; the page must not scroll or zoom under a pen */
  cursor: crosshair;
}

/* An uploaded image, behind the writing: as large as the screen allows, whole and unstretched.
   The canvas above it is transparent where there is no ink. */
.backdrop {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
}

.hint {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  color: rgba(20, 8, 88, .2);
  font-size: clamp(22px, 4vw, 36px);
  font-weight: 300;
  pointer-events: none;
  transition: opacity .25s ease;
}
body.has-ink .hint,
body.has-image .hint,
body.is-inking .hint { opacity: 0; }

/* The glass: what the toolbar, the notice above it and the result panel are all made of. It is
   one rule so that they cannot drift apart. Each adds its own shape and position below. */
.toolbar, .toast, .result {
  border: 1px solid var(--line);
  background: var(--panel);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: 0 8px 28px rgba(20, 8, 88, .12);
  transition: opacity .2s ease;
}

/* A short notice just above the toolbar, for things the page did on its own (app.js). It is the
   toolbar's own pill at the toolbar's own height, inside the same screen margins, and it steps
   back while you write (see is-inking below). --toolbar-h is the toolbar's real height, which
   changes when it wraps. The notice never takes a touch: what is under it can still be written on. */
.toast {
  position: fixed;
  bottom: calc(var(--toolbar-h, 46px) + 10px);
  left: calc(env(safe-area-inset-left, 0px) + 12px);
  right: calc(env(safe-area-inset-right, 0px) + 12px);
  width: fit-content;                     /* as the toolbar: centred, wrapping at the screen margin */
  margin: 0 auto;                         /* a <p>: zero the top and bottom margins the browser gives it */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;                      /* the toolbar's height: 36px controls + 4px padding + 1px border, each side */
  padding: 4px 20px;
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.toast.is-on { opacity: 1; visibility: visible; transition: opacity .2s ease; }

/* ---------------- toolbar ---------------- */

.toolbar {
  position: fixed;
  bottom: 0;                              /* on the screen's edge, so flat along the bottom */
  left: calc(env(safe-area-inset-left, 0px) + 12px);
  right: calc(env(safe-area-inset-right, 0px) + 12px);
  width: fit-content;                     /* with left/right and auto margins: centred, wraps at the screen edge */
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 2px 16px;
  padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));   /* clear of the iPhone's home indicator */
  border-bottom: 0;
  border-radius: 23px 23px 0 0;           /* half a one-row toolbar's height, so the end controls sit concentric with the top corners */
  touch-action: manipulation;
  transition: opacity .2s ease, transform .25s ease;
}

/* While a stroke is being written the toolbar, the notice and the result panel step back, so
   they are not under the hand. All of them fade out completely; the toolbar also slides down
   off the bottom edge as it fades, and back up when the pen lifts. */
body.is-inking .toolbar {
  opacity: 0;
  transform: translateY(100%);
  pointer-events: none;
}
body.is-inking .toast,
body.is-inking .result { opacity: 0; pointer-events: none; }

.group { display: flex; align-items: center; }

/* Every control is a 36px round target however small it draws, so the hover, armed and
   focus shapes all match the dots and the pill. */
.swatch, .nib, .tool {
  appearance: none;
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text);
  cursor: pointer;
}

.swatch::before {
  content: '';
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--c);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14);
}
/* The hairline stays when chosen, so White still has an edge inside its ring. */
.swatch[aria-checked="true"]::before {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14), 0 0 0 2px var(--panel-solid), 0 0 0 4px var(--text);
}

.nib::before {
  content: '';
  width: var(--d);
  height: var(--d);
  border-radius: 50%;
  background: var(--muted);
}
.nib[aria-checked="true"]::before { background: var(--text); }

.tool:hover:not(:disabled) { background: var(--hover); }
.tool:disabled { opacity: .3; cursor: default; }

.swatch:focus-visible, .nib:focus-visible, .tool:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pen only: while it is on, the hand is struck through and lit, meaning no fingers. */
#penonly { position: relative; }
#penonly[aria-pressed="true"] { color: var(--accent); background: rgba(0, 80, 180, .1); }
#penonly[aria-pressed="true"]::after {
  content: '';
  position: absolute;
  left: 8px;
  right: 8px;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: currentColor;
  box-shadow: 0 0 0 1.5px var(--panel-solid);          /* a halo, so the slash reads over the hand's own lines */
  transform: rotate(-45deg);
  pointer-events: none;
}

/* Clear asks twice: the first press swaps the bin for a question mark (see app.js). */
.icon--sure { display: none; }
#clear.is-armed { color: var(--danger); background: rgba(192, 38, 45, .1); }
#clear.is-armed .icon--clear { display: none; }
#clear.is-armed .icon--sure { display: block; }

.icon--exit { display: none; }
#fullscreen[aria-pressed="true"] .icon--enter { display: none; }
#fullscreen[aria-pressed="true"] .icon--exit { display: block; }

/* ---------------- recognised text ---------------- */
/* Opens at the bottom, above the toolbar, when Recognise is pressed. data-state (set by app.js) decides what shows:
   busy (engine loading or reading), done, unsure (read, but not confidently), empty, error. */

.result {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--toolbar-h, 46px) + 10px);
  width: min(560px, calc(100% - 24px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)));
  margin-inline: auto;
  padding: 4px 4px 12px 18px;
  border-radius: 26px;                    /* not a full pill: it holds a text box */
  touch-action: pan-x pan-y pinch-zoom;   /* the page blocks zoom; the recognised text may need it */
}
.result:focus { outline: none; }         /* focused on opening (app.js) so it is announced; its controls show their own focus */

.result__bar { display: flex; align-items: center; gap: 2px; }

.result__status {
  flex: 1;
  margin: 0;
  padding: 8px 8px 8px 0;
  color: var(--muted);
  font-size: 13px;
}
.result[data-state="unsure"] .result__status { color: var(--warn); }
.result[data-state="empty"] .result__status,
.result[data-state="error"] .result__status { color: var(--danger); }

.result[data-state="busy"] .result__status::before {
  content: '';
  display: inline-block;
  width: 11px;
  height: 11px;
  margin-right: 8px;
  vertical-align: -2px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Only a finished reading has text to edit, copy, or qualify. */
.result__text, .result__note, #result-copy { display: none; }
.result[data-state="done"] .result__text,
.result[data-state="unsure"] .result__text { display: block; }
.result[data-state="done"] .result__note,
.result[data-state="unsure"] .result__note { display: block; }
.result[data-state="done"] #result-copy,
.result[data-state="unsure"] #result-copy { display: inline-grid; }

.result__text {
  width: calc(100% - 14px);
  min-height: 5.5em;
  max-height: 40vh;
  margin: 2px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #fff;
  color: var(--text);
  font: 16px/1.45 system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;   /* 16px: iOS zooms into anything smaller */
  resize: vertical;
  -webkit-user-select: text;
  user-select: text;                       /* the page itself is unselectable; this text must not be */
}
.result__text:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.result__note { margin: 8px 14px 0 0; color: var(--muted); font-size: 12px; }

.icon--copied { display: none; }
#result-copy.is-done .icon--copy { display: none; }
#result-copy.is-done .icon--copied { display: block; }

/* Recognise is working: the icon breathes. */
#recognise[aria-busy="true"] .icon { animation: breathe 1s ease-in-out infinite; }
@keyframes breathe { 50% { opacity: .35; } }

@media (prefers-reduced-motion: reduce) {
  .toolbar, .hint, .result, .toast { transition: none; }
  body.is-inking .toolbar { transform: none; }    /* no slide: it just goes */
  .result[data-state="busy"] .result__status::before,
  #recognise[aria-busy="true"] .icon { animation: none; }
}
