/* The shared look. Load with <link rel="stylesheet" href="/ui/ui.css">.
   An app overrides --ui-accent and nothing else. */
:root {
  color-scheme: dark;

  --ui-accent: #4fd6ff;
  --ui-on-accent: #08161d;

  --ui-bg: #1b1e22;
  --ui-chrome: #212529;
  --ui-sink: #191c1f;
  --ui-raise: #262b31;
  --ui-line: #2c3138;
  --ui-line-strong: #3a4149;
  --ui-ink: #e7eaed;
  --ui-dim: #9099a2;
  --ui-faint: #6d757d;
  --ui-hover: rgb(255 255 255 / 0.045);
  --ui-active: rgb(255 255 255 / 0.08);
  --ui-danger: #ff6b81;
  --ui-ok: #7fdc9a;
  --ui-shadow: 0 18px 44px -22px rgb(0 0 0 / 0.8);

  /* Derived from the accent, so one override recolors the app. */
  --ui-sel: color-mix(in srgb, var(--ui-accent) 13%, transparent);
  --ui-sel-strong: color-mix(in srgb, var(--ui-accent) 22%, transparent);
  --ui-ring: color-mix(in srgb, var(--ui-accent) 60%, transparent);

  --ui-r-sm: 6px;
  --ui-r: 8px;
  --ui-r-lg: 12px;
  --ui-row: 32px;

  --ui-font: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --ui-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --ui-fs: 13px;
  --ui-fs-sm: 12px;
  --ui-fs-xs: 11px;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;
    --ui-bg: #ffffff;
    --ui-chrome: #f7f8f9;
    --ui-sink: #f1f3f5;
    --ui-raise: #ffffff;
    --ui-line: #e3e6ea;
    --ui-line-strong: #cfd4da;
    --ui-ink: #1f2328;
    --ui-dim: #5f6873;
    --ui-faint: #868f9a;
    --ui-hover: rgb(0 0 0 / 0.04);
    --ui-active: rgb(0 0 0 / 0.07);
    --ui-danger: #c8304c;
    --ui-ok: #1f7a44;
    --ui-shadow: 0 18px 44px -26px rgb(0 0 0 / 0.28);
  }
}

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

/* A class rule carrying a display value beats the UA stylesheet's
   [hidden]{display:none} at equal specificity, so any component that hides
   via el.hidden needs this. Without it .dropzone{display:flex} shows the
   upload overlay permanently. */
[hidden] {
  display: none !important;
}

/* The chrome is furniture, not a document. Dragging across a toolbar, a
   row or a sidebar should move a selection marquee or do nothing at all —
   never leave a blue text smear. Real fields opt back in below. */
body {
  -webkit-user-select: none;
  user-select: none;
}

input,
textarea,
[contenteditable='true'] {
  -webkit-user-select: text;
  user-select: text;
}

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ui-bg);
  color: var(--ui-ink);
  font: var(--ui-fs) / 1.5 var(--ui-font);
  -webkit-font-smoothing: antialiased;
}

button, input, select { font: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--ui-ring); outline-offset: 1px; }

.ui-mono { font-family: var(--ui-mono); font-variant-numeric: tabular-nums; }

.ui-icon { display: block; flex: none; }

/* Buttons ---------------------------------------------------------------- */
.ui-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--ui-line-strong);
  background: var(--ui-chrome);
  color: var(--ui-ink);
  border-radius: var(--ui-r);
  padding: 6px 11px;
  font-size: var(--ui-fs);
  cursor: pointer;
  white-space: nowrap;
}
.ui-btn:hover:not(:disabled) { background: var(--ui-hover); border-color: var(--ui-dim); }
.ui-btn:disabled { opacity: 0.45; cursor: default; }
.ui-btn.is-primary {
  background: var(--ui-accent);
  border-color: var(--ui-accent);
  color: var(--ui-on-accent);
  font-weight: 600;
}
.ui-btn.is-primary:hover:not(:disabled) { filter: brightness(1.08); background: var(--ui-accent); }
.ui-btn.is-quiet { background: none; border-color: transparent; color: var(--ui-dim); padding: 6px 8px; }
.ui-btn.is-quiet:hover:not(:disabled) { background: var(--ui-hover); color: var(--ui-ink); }
.ui-btn.is-danger { color: var(--ui-danger); border-color: var(--ui-line-strong); }
.ui-btn.is-danger:hover:not(:disabled) { border-color: var(--ui-danger); background: color-mix(in srgb, var(--ui-danger) 10%, transparent); }

/* Menus ------------------------------------------------------------------ */
.ui-menu {
  position: fixed;
  z-index: 900;
  min-width: 184px;
  padding: 5px;
  border: 1px solid var(--ui-line-strong);
  border-radius: var(--ui-r-lg);
  background: var(--ui-raise);
  box-shadow: var(--ui-shadow);
}
.ui-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--ui-r-sm);
  background: none;
  color: var(--ui-ink);
  font-size: var(--ui-fs);
  text-align: left;
  cursor: pointer;
}
.ui-menu-item:hover:not(.is-disabled),
.ui-menu-item:focus-visible { background: var(--ui-hover); outline: none; }
.ui-menu-item.is-danger { color: var(--ui-danger); }
.ui-menu-item.is-disabled { opacity: 0.4; cursor: default; }
.ui-menu-item .ui-menu-hint { margin-left: auto; color: var(--ui-faint); font-size: var(--ui-fs-xs); }
.ui-menu-sep { height: 1px; margin: 5px 6px; background: var(--ui-line); }

/* Dialogs ---------------------------------------------------------------- */
.ui-dialog {
  border: 1px solid var(--ui-line-strong);
  border-radius: var(--ui-r-lg);
  background: var(--ui-raise);
  color: var(--ui-ink);
  padding: 20px;
  width: min(380px, 92vw);
  box-shadow: var(--ui-shadow);
}
.ui-dialog.is-wide { width: min(560px, 92vw); }
.ui-dialog::backdrop { background: rgb(0 0 0 / 0.45); }
.ui-dialog h3 { margin: 0 0 4px; font-size: 15px; }
.ui-dialog .ui-hint { margin: 0 0 14px; font-size: var(--ui-fs-sm); color: var(--ui-faint); }
.ui-dialog .ui-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* ui.modal(): the padding moves to an inner wrapper so a click whose target
   is the <dialog> itself can only be the backdrop (see modal() in ui.js). */
.ui-modal { padding: 0; }
.ui-modal-inner { padding: 20px; }
.ui-modal.is-wide { width: min(760px, 94vw); }

.ui-field { display: block; margin-bottom: 12px; }
.ui-field span { display: block; margin-bottom: 5px; font-size: var(--ui-fs-sm); color: var(--ui-dim); }
.ui-field input,
.ui-field textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--ui-line-strong);
  border-radius: var(--ui-r);
  background: var(--ui-sink);
  color: var(--ui-ink);
}
.ui-field textarea {
  display: block;
  resize: vertical;
  font: var(--ui-fs) / 1.5 var(--ui-font);
}
/* A dialog field showing a value (e.g. a join code) rather than collecting
   one — still selectable and copyable, styled just enough to not invite
   editing. */
.ui-field input:read-only { background: var(--ui-hover); cursor: default; }

/* Toasts ----------------------------------------------------------------- */
.ui-toasts {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 950;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  pointer-events: none;
}
.ui-toast {
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: min(420px, 80vw);
  padding: 9px 13px;
  border: 1px solid var(--ui-line-strong);
  border-radius: var(--ui-r);
  background: var(--ui-raise);
  box-shadow: var(--ui-shadow);
  font-size: var(--ui-fs);
  animation: ui-toast-in 0.16s ease-out;
}
.ui-toast.is-error { border-color: var(--ui-danger); color: var(--ui-danger); }
@keyframes ui-toast-in {
  from { opacity: 0; transform: translateY(6px); }
}
@media (prefers-reduced-motion: reduce) {
  .ui-toast { animation: none; }
}
