/* Taskboard — a dense, quiet workspace.
 *
 * The board is read far more often than it is touched, so the design gets out
 * of the way: one accent colour, a narrow type scale, and colour reserved for
 * things that carry meaning (priority, stage, who holds what). Everything else
 * is neutral. */

:root {
  color-scheme: light dark;

  /* Neutrals. A single ramp used for every surface, border and text level, so
     nothing drifts out of step when the palette changes. */
  --n-0: #ffffff;
  --n-25: #fbfbfc;
  --n-50: #f5f6f8;
  --n-100: #eceef2;
  --n-150: #e2e5ea;
  --n-200: #d4d8e0;
  --n-300: #b3bac7;
  --n-500: #6b7385;
  --n-600: #525a6b;
  --n-800: #2a3040;
  --n-900: #1a1f2b;

  --bg: var(--n-50);
  --surface: var(--n-0);
  --surface-2: var(--n-25);
  --sunken: var(--n-100);
  --line: var(--n-150);
  --line-strong: var(--n-200);

  --text: var(--n-900);
  --text-2: var(--n-600);
  --text-3: var(--n-500);

  --accent: #4f5bd5;
  --accent-text: #ffffff;
  --accent-weak: #eceefc;
  --accent-line: #c5c9f5;

  --ok: #1a7f57;
  --ok-weak: #e3f4ec;
  --warn: #9a6a00;
  --warn-weak: #fbf0d9;
  --bad: #c03744;
  --bad-weak: #fbe6e8;
  --mine: #6d3fc4;
  --mine-weak: #f0e9fb;

  --r-sm: 5px;
  --r: 8px;
  --r-lg: 12px;
  --r-full: 999px;

  --shadow-1: 0 1px 2px rgb(16 20 30 / 0.06), 0 1px 1px rgb(16 20 30 / 0.04);
  --shadow-2: 0 4px 12px rgb(16 20 30 / 0.08), 0 1px 3px rgb(16 20 30 / 0.06);
  --shadow-3: 0 16px 48px rgb(16 20 30 / 0.18), 0 2px 8px rgb(16 20 30 / 0.08);

  --sidebar: 232px;
  --topbar: 52px;

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
}

/* Dark is the default for anyone whose system says so, and is also reachable
   explicitly — the toggle writes data-theme, which wins over the media query. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --n-0: #14171f;
    --n-25: #171b24;
    --n-50: #0f1218;
    --n-100: #1c212c;
    --n-150: #262c39;
    --n-200: #333a4a;
    --n-300: #4a5364;
    --n-500: #8b93a5;
    --n-600: #a7aebd;
    --n-800: #dfe3ea;
    --n-900: #f1f3f7;

    --accent: #7c86ee;
    --accent-text: #10131a;
    --accent-weak: #23273f;
    --accent-line: #3a4170;

    --ok: #56c896;
    --ok-weak: #16322a;
    --warn: #e0b341;
    --warn-weak: #332a15;
    --bad: #f08b93;
    --bad-weak: #3a1f24;
    --mine: #b79bf5;
    --mine-weak: #2a2140;

    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.4);
    --shadow-2: 0 4px 14px rgb(0 0 0 / 0.45);
    --shadow-3: 0 18px 50px rgb(0 0 0 / 0.6);
  }
}

:root[data-theme="dark"] {
  --n-0: #14171f;
  --n-25: #171b24;
  --n-50: #0f1218;
  --n-100: #1c212c;
  --n-150: #262c39;
  --n-200: #333a4a;
  --n-300: #4a5364;
  --n-500: #8b93a5;
  --n-600: #a7aebd;
  --n-800: #dfe3ea;
  --n-900: #f1f3f7;

  --accent: #7c86ee;
  --accent-text: #10131a;
  --accent-weak: #23273f;
  --accent-line: #3a4170;

  --ok: #56c896;
  --ok-weak: #16322a;
  --warn: #e0b341;
  --warn-weak: #332a15;
  --bad: #f08b93;
  --bad-weak: #3a1f24;
  --mine: #b79bf5;
  --mine-weak: #2a2140;

  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.4);
  --shadow-2: 0 4px 14px rgb(0 0 0 / 0.45);
  --shadow-3: 0 18px 50px rgb(0 0 0 / 0.6);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 13.5px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.011em;
}
a {
  color: var(--accent);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-full);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--n-300);
  background-clip: content-box;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ---------------------------------------------------------------- controls */

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, border-color 0.12s;
}
.btn:hover {
  background: var(--sunken);
}
.btn:active {
  transform: translateY(0.5px);
}
.btn[disabled] {
  opacity: 0.5;
  pointer-events: none;
}
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}
.btn-primary:hover {
  background: var(--accent);
  filter: brightness(1.08);
}
.btn-ghost {
  border-color: transparent;
  background: transparent;
  color: var(--text-2);
}
.btn-ghost:hover {
  background: var(--sunken);
  color: var(--text);
}
.btn-danger {
  color: var(--bad);
  border-color: var(--line-strong);
}
.btn-danger:hover {
  background: var(--bad-weak);
  border-color: var(--bad);
}
.btn-sm {
  height: 26px;
  padding: 0 9px;
  font-size: 12.5px;
}
.btn-icon {
  width: 30px;
  padding: 0;
}

.field {
  display: grid;
  gap: 5px;
}
.field > span {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
}
.input,
select.input,
textarea.input {
  width: 100%;
  min-height: 32px;
  padding: 6px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--text);
  transition: border-color 0.12s, box-shadow 0.12s;
}
textarea.input {
  min-height: 92px;
  resize: vertical;
  line-height: 1.6;
}
.input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}
.input::placeholder {
  color: var(--text-3);
}

/* ------------------------------------------------------------------ pieces */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 19px;
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 11.5px;
  font-weight: 500;
  white-space: nowrap;
}
.chip-accent {
  background: var(--accent-weak);
  border-color: var(--accent-line);
  color: var(--accent);
}
.chip-ok {
  background: var(--ok-weak);
  border-color: transparent;
  color: var(--ok);
}
.chip-warn {
  background: var(--warn-weak);
  border-color: transparent;
  color: var(--warn);
}
.chip-bad {
  background: var(--bad-weak);
  border-color: transparent;
  color: var(--bad);
}
.chip-mine {
  background: var(--mine-weak);
  border-color: transparent;
  color: var(--mine);
}

.key {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-3);
  letter-spacing: 0.01em;
}

/* Priority reads as a single dot rather than a word: on a wall of cards, the
   eye finds a colour far faster than it reads "P1". */
.pri {
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  flex: none;
}
.pri-1 {
  background: var(--bad);
}
.pri-2 {
  background: var(--warn);
}
.pri-3 {
  background: var(--accent);
}
.pri-4,
.pri-5 {
  background: var(--n-300);
}

/* Avatars are initials on a hue derived from the agent's name, so the same
   agent is the same colour everywhere without a table of assignments. */
.avatar {
  width: 20px;
  height: 20px;
  border-radius: var(--r-full);
  display: grid;
  place-items: center;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  flex: none;
  text-transform: uppercase;
}
.avatar-lg {
  width: 26px;
  height: 26px;
  font-size: 11px;
}

/* Utilities. The page ships a strict Content-Security-Policy, which blocks
   `style=` attributes outright — so anything that would have been an inline
   style is either a class here or applied through the CSSOM in hydrate(). */
.clickable {
  cursor: pointer;
}
.mono {
  font-family: var(--mono);
  font-size: 11.5px;
}
.err-text {
  color: var(--bad);
}
.note {
  margin: 0;
  color: var(--text-3);
  font-size: 12.5px;
}
/* .input is width:100%, which makes a control grow inside the flex rows of the
   admin panel. This is the opt-out. The second selector is deliberate: the base
   rule is `select.input`, so a bare `.w-auto` would lose on specificity. */
.w-auto,
select.input.w-auto,
input.input.w-auto {
  width: auto;
  min-width: 104px;
  flex: none;
}
.mt-6 {
  margin-top: 6px;
}
.empty-tight {
  padding: 16px 8px;
}
.mint-grid {
  grid-template-columns: 1fr 150px auto;
  align-items: end;
}
.skel-title {
  height: 22px;
  width: 70%;
}
.skel-line {
  height: 14px;
  margin-top: 8px;
}
.skel-line-wide {
  height: 14px;
  margin-top: 14px;
}
.skel-line-short {
  height: 14px;
  width: 60%;
  margin-top: 8px;
}
.skel-head {
  width: 70px;
  height: 11px;
}
.skel-row {
  height: 40px;
}

.spin {
  width: 14px;
  height: 14px;
  border: 2px solid var(--line-strong);
  border-top-color: var(--accent);
  border-radius: var(--r-full);
  animation: spin 0.6s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Skeletons say "the shape you are about to see" instead of the word
   "loading", which tells you nothing about what is coming. */
.skel {
  background: linear-gradient(90deg, var(--sunken) 25%, var(--line) 37%, var(--sunken) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer {
  0% {
    background-position: 100% 0;
  }
  100% {
    background-position: 0 0;
  }
}

.empty {
  display: grid;
  gap: 6px;
  justify-items: center;
  padding: 28px 16px;
  text-align: center;
  color: var(--text-3);
  font-size: 12.5px;
}
.empty strong {
  color: var(--text-2);
  font-weight: 600;
  font-size: 13px;
}

/* -------------------------------------------------------------------- gate */

#gate {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: 24px;
  background: radial-gradient(1200px 600px at 50% -10%, var(--accent-weak), transparent 70%), var(--bg);
}
.gate-card {
  width: min(380px, 100%);
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.gate-card .mark {
  margin-bottom: 18px;
}
.gate-card h1 {
  font-size: 19px;
  margin-bottom: 4px;
}
.gate-card p {
  margin: 0 0 20px;
  color: var(--text-3);
  font-size: 12.5px;
  line-height: 1.6;
}
.gate-card form {
  display: grid;
  gap: 13px;
}
.gate-card code {
  display: block;
  margin-top: 6px;
  padding: 7px 9px;
  border-radius: var(--r-sm);
  background: var(--sunken);
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--text-2);
  word-break: break-all;
}
.form-err {
  min-height: 17px;
  color: var(--bad);
  font-size: 12.5px;
}

/* The wordmark: a 2x2 grid of cells, one filled — a board with one card. */
.mark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 650;
  font-size: 14px;
  letter-spacing: -0.015em;
  color: var(--text);
}
.mark svg {
  flex: none;
}

/* ------------------------------------------------------------------- shell */

#app {
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  height: 100dvh;
}

/* The platform panel has no sidebar. Without this it inherits the board's
   two-column shell and its content is squeezed into the 232px the sidebar
   would have occupied. */
#app.solo {
  grid-template-columns: minmax(0, 1fr);
}
#app.solo .topbar {
  padding-left: 16px;
  gap: 12px;
}
#app.solo .who {
  gap: 7px;
}
#app.solo .who .name b {
  font-size: 13px;
}

.sidebar {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--line);
  background: var(--surface-2);
}
.sidebar-head {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--topbar);
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
}
.sidebar-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 10px;
  display: grid;
  gap: 18px;
  align-content: start;
}
.sidebar-foot {
  border-top: 1px solid var(--line);
  padding: 10px;
}

.nav-label {
  padding: 0 8px;
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-3);
}
.nav {
  display: grid;
  gap: 1px;
  margin-top: 6px;
}
.nav button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.nav button:hover {
  background: var(--sunken);
  color: var(--text);
}
.nav button[aria-current="true"] {
  background: var(--accent-weak);
  color: var(--accent);
  font-weight: 600;
}
.nav svg {
  flex: none;
  opacity: 0.85;
}
.nav .count {
  margin-left: auto;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}

.who {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 6px;
  border-radius: var(--r);
}
.who .name {
  min-width: 0;
  line-height: 1.25;
}
.who .name b {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.who .name span {
  font-size: 11px;
  color: var(--text-3);
}

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--topbar);
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.topbar h1 {
  font-size: 14.5px;
}
.topbar .sub {
  font-size: 12px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.grow {
  flex: 1;
  min-width: 0;
}

.search {
  position: relative;
  width: min(240px, 34vw);
}
.search .input {
  padding-left: 30px;
  height: 30px;
}
.search svg {
  position: absolute;
  left: 9px;
  top: 8px;
  color: var(--text-3);
  pointer-events: none;
}

.view {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* ------------------------------------------------------------------- board */

.board {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  min-height: 100%;
  padding: 16px;
}
.col {
  display: flex;
  flex-direction: column;
  flex: none;
  width: 286px;
  max-height: calc(100dvh - var(--topbar) - 32px);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  transition: border-color 0.12s, background 0.12s;
}
.col.drop {
  border-color: var(--accent);
  background: var(--accent-weak);
}
.col-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 12px 8px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-2);
}
.col-head .dot {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--n-300);
  flex: none;
}
.col-head .n {
  margin-left: auto;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}
.col-body {
  flex: 1;
  min-height: 60px;
  overflow-y: auto;
  padding: 0 8px 8px;
  display: grid;
  gap: 7px;
  align-content: start;
}

.card {
  display: grid;
  gap: 7px;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  transition: border-color 0.12s, box-shadow 0.12s, transform 0.12s;
}
.card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-2);
}
/* Where the card will land. A line rather than a ghost card, so it reads as a
   position between two things instead of as another item in the list. */
.drop-line {
  height: 2px;
  margin: 1px 2px;
  border-radius: var(--r-full);
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}

.card.dragging {
  opacity: 0.45;
  transform: rotate(1.5deg);
}
.card[draggable="true"] {
  cursor: grab;
}
.card-top {
  display: flex;
  align-items: center;
  gap: 6px;
}
.card-title {
  font-size: 13px;
  line-height: 1.4;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-foot {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.card-foot .avatar {
  margin-left: auto;
}
.lock {
  color: var(--mine);
  flex: none;
}

/* ----------------------------------------------------------------- roadmap */

.page {
  padding: 20px;
  max-width: 940px;
}
#app.solo .page {
  margin: 0 auto;
  width: 100%;
}
.panel {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}
.panel + .panel {
  margin-top: 16px;
}
.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.panel-head h2 {
  font-size: 13.5px;
}
.panel-body {
  padding: 6px 16px 14px;
}

.ms {
  display: grid;
  gap: 7px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.ms:last-child {
  border-bottom: 0;
}
.ms-top {
  display: flex;
  align-items: center;
  gap: 9px;
}
.ms-top b {
  font-size: 13.5px;
  font-weight: 600;
}
.ms-top .pct {
  margin-left: auto;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}
.ms-desc {
  color: var(--text-3);
  font-size: 12px;
}
.bar {
  height: 6px;
  border-radius: var(--r-full);
  background: var(--sunken);
  overflow: hidden;
}
.bar i {
  display: block;
  height: 100%;
  border-radius: var(--r-full);
  background: var(--ok);
  transition: width 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.rows {
  display: grid;
}
.row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.row:last-child {
  border-bottom: 0;
}
.row > span:not(.grow):not(.chip):not(.key):not(.avatar) {
  min-width: 0;
}
.row .w {
  color: var(--text-3);
  font-size: 12px;
}

/* Activity reads as a timeline: a rail with a node per event, so scanning it
   gives the order at a glance instead of a list of equal-weight lines. */
.feed {
  display: grid;
  gap: 0;
  padding-left: 4px;
}
.ev {
  position: relative;
  padding: 9px 0 9px 22px;
  font-size: 12.5px;
  line-height: 1.5;
}
.ev::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 16px;
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: var(--line-strong);
  outline: 3px solid var(--surface);
}
.ev::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 23px;
  bottom: -2px;
  width: 1px;
  background: var(--line);
}
.ev:last-child::after {
  display: none;
}
.ev.k-stage_done::before,
.ev.k-done::before {
  background: var(--ok);
}
.ev.k-rejected::before,
.ev.k-blocked::before,
.ev.k-expired::before {
  background: var(--bad);
}
.ev.k-claimed::before,
.ev.k-handoff::before {
  background: var(--accent);
}
.ev .meta {
  color: var(--text-3);
  font-size: 11.5px;
}
.ev .body {
  color: var(--text-2);
  margin-top: 2px;
  white-space: pre-wrap;
}

/* -------------------------------------------------------------------- docs */

.doc-layout {
  display: grid;
  gap: 16px;
  padding: 16px;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
/* On a wide screen the documents view is two full-height columns, like the app
   sidebar beside it: each scrolls inside itself and neither drags the page. On
   a narrow one they stack and the page scrolls normally, because two nested
   scroll regions in a phone-width column are worse than one long page. */
@media (min-width: 900px) {
  .doc-layout {
    grid-template-columns: 250px minmax(0, 1fr);
    align-items: stretch;
    box-sizing: border-box;
    height: 100%;
    min-height: 0;
  }
  .doc-side,
  .doc-pane {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .doc-list {
    flex: 1;
    max-height: none;
  }
  .doc-body {
    flex: 1;
    /* The pane sets the height now, so the drag handle would only fight it. */
    min-height: 0;
    resize: none;
  }
}
/* 345 documents do not fit on a screen and never will, so the sidebar is a
   filter over collapsed groups rather than a list. The groups come from the
   source path, which is the arrangement the author already made. */
.doc-filter {
  margin-bottom: 6px;
}
.doc-count {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--text-3);
  padding: 0 2px 6px;
}
.doc-list {
  display: grid;
  gap: 2px;
  /* Bounded so the whole page does not become one long scroll; the reading
     pane keeps its own position while the list moves. The wide layout replaces
     this cap with the column's own height. */
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.doc-group {
  display: grid;
  gap: 1px;
}
.doc-group-head {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 6px 8px;
  margin-top: 4px;
  border: 0;
  border-radius: var(--r);
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: var(--text-2);
  font-size: 12px;
}
.doc-group-head:hover {
  background: var(--sunken);
}
.doc-group-head .caret {
  font-size: 10px;
  color: var(--text-3);
  width: 9px;
}
.doc-group-head b {
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.doc-group-head .n {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-3);
}
.doc-group .doc-item {
  padding-left: 24px;
}
.doc-item {
  display: grid;
  gap: 1px;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: var(--r);
  background: transparent;
  text-align: left;
  cursor: pointer;
  color: var(--text-2);
}
.doc-item:hover {
  background: var(--sunken);
}
.doc-item[aria-current="true"] {
  background: var(--surface);
  border-color: var(--line);
  color: var(--text);
  box-shadow: var(--shadow-1);
}
.doc-item b {
  font-size: 13px;
  font-weight: 600;
}
.doc-item span {
  font-size: 11px;
  color: var(--text-3);
  font-family: var(--mono);
}
.doc-pane {
  min-width: 0;
}
.doc-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.doc-head h2 {
  font-size: 16px;
}
/* The body is Markdown source, shown as source. Rendering it would mean
   shipping a parser and deciding what subset is safe; the people reading it
   here are the people who wrote it. */
.doc-body {
  width: 100%;
  min-height: 52vh;
  box-sizing: border-box;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--text);
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  resize: vertical;
  tab-size: 2;
}
.doc-body:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}
.doc-body[readonly] {
  background: var(--surface-2);
}
.hash {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-3);
}

/* ------------------------------------------------------------------ drawer */

.scrim {
  position: fixed;
  inset: 0;
  background: rgb(10 12 18 / 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s;
  z-index: 40;
}
.scrim.open {
  opacity: 1;
  pointer-events: auto;
}

/* A slide-over, not a centred modal: the board stays visible beside it, which
   is what you want while comparing a task to the column it sits in. */
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(520px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow-3);
  transform: translateX(100%);
  transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 50;
}
.drawer.open {
  transform: none;
}
.drawer-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}
.drawer-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 18px 28px;
}
.drawer h2 {
  font-size: 16px;
  line-height: 1.35;
  margin-bottom: 12px;
}
.drawer h3 {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 22px 0 8px;
}
.settings {
  display: grid;
  gap: 12px;
}
.hint {
  font-size: 11.5px;
  color: var(--text-3);
}
.hint code {
  color: var(--accent);
}
.input.mono {
  font-family: var(--mono);
  font-size: 12.5px;
}

.facts {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 7px 12px;
  font-size: 12.5px;
}
.facts dt {
  color: var(--text-3);
}
.facts dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.prose {
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-2);
  font-size: 12.5px;
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-word;
}
.prose.accent {
  border-color: var(--accent-line);
  background: var(--accent-weak);
}
.actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.mono-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}
.mono-row:last-child {
  border-bottom: 0;
}
.mono-row code {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--accent);
  flex: none;
}

/* ------------------------------------------------------------------ dialog */

dialog {
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-3);
  width: min(520px, calc(100vw - 32px));
}
dialog::backdrop {
  background: rgb(10 12 18 / 0.5);
}
.dlg-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line);
}
.dlg-head h2 {
  font-size: 14px;
}
.dlg-body {
  padding: 16px;
  max-height: 64dvh;
  overflow-y: auto;
  display: grid;
  gap: 13px;
}
.dlg-foot {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}
.two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.secret {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--ok);
  border-radius: var(--r);
  background: var(--ok-weak);
  font-size: 12.5px;
}
.secret code {
  font-family: var(--mono);
  font-size: 11.5px;
  word-break: break-all;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--text);
}

/* ------------------------------------------------------------------ toasts */

.toasts {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  gap: 8px;
  z-index: 60;
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  font-size: 12.5px;
  animation: rise 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.toast.bad {
  border-color: var(--bad);
  color: var(--bad);
}
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* -------------------------------------------------------------- responsive */

.only-narrow {
  display: none;
}

@media (max-width: 860px) {
  #app {
    grid-template-columns: minmax(0, 1fr);
  }
  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: 260px;
    z-index: 45;
    transform: translateX(-100%);
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
    box-shadow: var(--shadow-3);
  }
  .sidebar.open {
    transform: none;
  }
  .only-narrow {
    display: inline-flex;
  }
  .search {
    width: 150px;
  }
  .board {
    padding: 12px;
  }
  .col {
    width: 82vw;
    max-width: 300px;
  }
  .page {
    padding: 14px;
  }
  .settings {
  display: grid;
  gap: 12px;
}
.hint {
  font-size: 11.5px;
  color: var(--text-3);
}
.hint code {
  color: var(--accent);
}
.input.mono {
  font-family: var(--mono);
  font-size: 12.5px;
}

.facts {
    grid-template-columns: 76px 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
