@view-transition {
  navigation: auto;
}

/* Turbo sets aria-busy="true" on the elements it manages during a visit: on
   <html> for the whole navigation, and on the submitted <form> while it's in
   flight. oat.css turns any [aria-busy=true] into a centered ::before spinner
   (meant for buttons and the like), so on <html> it became an in-flow band at
   the top of the page, and on the card edit <form> it became a spinner in the
   card body on save. We don't want a spinner on either — Turbo's own progress
   bar is the navigation indicator — so suppress it on exactly the elements
   Turbo auto-marks. oat's spinner on real elements (explicit aria-busy /
   data-spinner) is untouched. (Unlayered, so it wins over oat's @layer rule.) */
html[aria-busy]::before,
form[aria-busy]::before { content: none; }

/* The HTML `hidden` attribute must always win. Several components (e.g.
   .field-inline) set an explicit `display`, which — being an author rule —
   overrides the UA's [hidden]{display:none} regardless of specificity, so a
   `hidden` element would stay visible. This keeps `hidden` authoritative. */
[hidden] { display: none !important; }

:root {
  color-scheme: dark;

  /* palette */
  --page-bg:      #0a0a0b;
  --surface:      #111113;
  --elevated:     #18181b;
  --border:       #27272a;
  --border-soft:  #1f1f23;
  --text:         #fafafa;
  --muted:        #71717a;
  --muted-hi:     #a1a1aa;
  --indigo:       #818cf8;
  --indigo-bg:    #3730a3;
  --amber:        #fbbf24;
  --emerald:      #34d399;
  --red:          #f87171;

  --sidebar-w: 220px;
}

/* Light theme. Activated by data-theme="light" on <html> (set before paint in
   base.html from the localStorage 'scalar:theme' preference). Overrides the
   core palette variables; components that reference these vars flip with it. */
:root[data-theme="light"] {
  color-scheme: light;

  --page-bg:      #ffffff;
  --surface:      #f7f7f8;
  --elevated:     #efeff1;
  --border:       #d4d4d8;
  --border-soft:  #e4e4e7;
  --text:         #18181b;
  --muted:        #71717a;
  --muted-hi:     #52525b;
  --indigo:       #4f46e5;
  --indigo-bg:    #4f46e5;
  --amber:        #b45309;
  --emerald:      #047857;
  --red:          #dc2626;
}

/* ── Layout ─────────────────────────────────────────────── */

body {
  background: var(--page-bg);
  color: var(--text);
}

.app {
  display: flex;
  min-height: 100vh;
}

/* ── Sidebar ─────────────────────────────────────────────── */

.sidebar {
  width: var(--sidebar-w);
  background: var(--surface);
  border-right: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 100;
  transition: transform 0.18s ease;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
}

/* Desktop collapse toggle — pinned to the sidebar/main boundary. */
.sidebar-collapse {
  position: fixed;
  top: calc(1rem + env(safe-area-inset-top));
  left: calc(var(--sidebar-w) - 12px);
  width: 24px;
  height: 24px;
  padding: 0;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  color: var(--muted-hi);
  cursor: pointer;
  z-index: 101;
  transition: left 0.18s ease, color 0.12s;
}
.sidebar-collapse:hover { color: var(--text); border-color: var(--border); }
.sidebar-collapse svg {
  width: 14px;
  height: 14px;
  display: block;
  transition: transform 0.18s ease;
}

[data-sidebar-collapsed] .sidebar { transform: translateX(-100%); }
[data-sidebar-collapsed] .main { margin-left: 0; }
[data-sidebar-collapsed] .sidebar-collapse { left: 0.75rem; }
[data-sidebar-collapsed] .sidebar-collapse svg { transform: rotate(180deg); }

/* Make room for the toggle button so it doesn't overlap the page title. */
[data-sidebar-collapsed] .page-header { padding-left: 3rem; }

@media (max-width: 768px) {
  /* On mobile the existing topbar toggle handles the sidebar. Hide the
     desktop collapse chevron so it doesn't double up. */
  .sidebar-collapse { display: none; }
}

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 1rem 1.125rem;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.02em;
  color: var(--text);
  border-bottom: 1px solid var(--border-soft);
}

.logo-mark {
  width: 24px;
  height: 24px;
  background: var(--indigo-bg);
  border-radius: 6px;
  display: grid;
  place-items: center;
  font-size: 0.75rem;
  font-weight: 800;
  color: #fff;
  flex-shrink: 0;
}

/* The tile holds either a workspace initial (in the shell) or the product mark
   (on the auth and legal pages). Blocking the SVG keeps it off the text
   baseline so the grid centring is exact either way. */
.logo-svg {
  display: block;
}

.sidebar-nav {
  flex: 1;
  padding: 0.625rem;
  overflow-y: auto;
}

.nav-section {
  margin-bottom: 1.25rem;
}

.nav-label {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  padding: 0 0.5rem;
  margin-bottom: 0.25rem;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  border-radius: 6px;
  color: var(--muted-hi);
  text-decoration: none;
  font-size: 0.8125rem;
  transition: background 0.1s, color 0.1s;
}

.nav-link:hover  { background: var(--elevated); color: var(--text); }
.nav-link.active { background: var(--elevated); color: var(--text); }

.nav-link svg { opacity: 0.5; flex-shrink: 0; }
.nav-link.active svg,
.nav-link:hover  svg { opacity: 1; }

/* The foot carries no top border of its own: Contact support reads as the last
   nav item, and the rule below it is what separates the product from the
   account (see .sidebar-rule). */
.sidebar-foot {
  padding: 0.75rem;
}

/* Contact support: a button styled as a nav item. */
.support-btn {
  width: 100%;
  border: none;
  background: transparent;
  cursor: pointer;
  font: inherit;
  font-size: 0.8125rem;
  text-align: left;
}

/* Bleeds past the foot's padding so it spans the sidebar, like the rule it
   replaces did. */
.sidebar-rule {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: 0.5rem -0.75rem;
}

.user-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.375rem;
  border-radius: 6px;
}

.user-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  margin: -0.375rem -0.25rem -0.375rem -0.375rem;
  padding: 0.375rem 0.25rem 0.375rem 0.375rem;
  border-radius: 6px;
  text-decoration: none;
  transition: background 0.1s;
}

.user-link:hover  { background: var(--elevated); }
.user-link.active { background: var(--elevated); }
.user-link:hover .user-name,
.user-link.active .user-name { color: var(--text); }

/* ── Settings ─────────────────────────────────────────────── */

.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.setting-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
}

.setting-desc {
  font-size: 0.8125rem;
  color: var(--muted);
  margin-top: 0.125rem;
}

.theme-toggle {
  display: inline-flex;
  background: var(--page-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 3px;
  gap: 3px;
  flex-shrink: 0;
}

.theme-option {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: none;
  border: none;
  color: var(--muted-hi);
  padding: 0.375rem 0.75rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 500;
  transition: background 0.12s, color 0.12s;
}

.theme-option:hover { color: var(--text); }

.theme-option[aria-checked="true"] {
  background: var(--elevated);
  color: var(--text);
}

.theme-option svg { opacity: 0.7; }
.theme-option[aria-checked="true"] svg { opacity: 1; }

.password-form { max-width: 360px; }

.avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--indigo-bg);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 0.6875rem;
  font-weight: 600;
  flex-shrink: 0;
}

.avatar.sm {
  width: 20px;
  height: 20px;
  font-size: 0.5625rem;
}

.user-name {
  font-size: 0.8125rem;
  color: var(--muted-hi);
  font-weight: 500;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logout-btn {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0.25rem;
  border-radius: 4px;
  display: grid;
  place-items: center;
  transition: color 0.1s;
}
.logout-btn:hover { color: var(--text); }

/* ── Main ─────────────────────────────────────────────────── */

main {
  padding-block-start: 0;
}

.main {
  margin-left: var(--sidebar-w);
  transition: margin-left 0.18s ease;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--page-bg);
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(1rem + env(safe-area-inset-top)) 1.5rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border-soft);
  position: sticky;
  top: 0;
  z-index: 50;
}

.page-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}

.page-body {
  padding: 1.5rem;
  flex: 1;
  min-height: 0;
}
/* When the body hosts a kanban, become a flex column so the kanban can take
   the remaining viewport height instead of sizing to the tallest lane. */
.page-body:has(.kanban) {
  display: flex;
  flex-direction: column;
}

/* ── Kanban ───────────────────────────────────────────────── */

.kanban {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.875rem;
  align-items: stretch;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 0.5rem;
  -webkit-overflow-scrolling: touch;
  flex: 1;
  min-height: 0;
}

.column {
  flex: 0 0 280px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  min-height: 0;
  align-self: stretch;
}

.column-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.25rem;
  margin-bottom: 0.625rem;
}

.column-name {
  display: flex;
  align-items: center;
  gap: 0.4375rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.dot-todo  { background: #52525b; }
.dot-doing { background: var(--amber); }
.dot-done  { background: var(--emerald); }

.dot-gray   { background: #52525b; }
.dot-blue   { background: #60a5fa; }
.dot-green  { background: var(--emerald); }
.dot-orange { background: #fb923c; }
.dot-red    { background: var(--red); }
.dot-purple { background: #c084fc; }
.dot-pink   { background: #f472b6; }

.column-count {
  font-size: 0.6875rem;
  color: var(--muted);
  background: var(--elevated);
  padding: 0.1rem 0.4rem;
  border-radius: 9999px;
  font-weight: 500;
}

.task-list {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* ── Task card ────────────────────────────────────────────── */

.task-card {
  background: var(--elevated);
  border-radius: 8px;
  padding: 0.6875rem 0.75rem;
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  transition: border-color 0.15s;
  cursor: pointer;
}

.task-card:hover {
  border-color: #3f3f46;
}

.task-ghost {
  opacity: 0.35;
  border: 1px dashed var(--muted);
}

.task-title {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text);
  line-height: 1.4;
  margin-bottom: 0.25rem;
}

.task-desc {
  font-size: 0.75rem;
  color: var(--muted-hi);
  line-height: 1.4;
  margin-bottom: 0.5rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.task-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.assignee-chip {
  display: flex;
  align-items: center;
  gap: 0.3125rem;
  font-size: 0.6875rem;
  color: var(--muted);
}

.icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.2rem 0.35rem;
  border-radius: 4px;
  font-size: 0.6875rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 0.25rem;
  line-height: 1;
  transition: background 0.1s, color 0.1s;
}

.icon-btn:hover     { background: var(--border); color: var(--text); }
.icon-btn.del:hover { background: #3f1212; color: var(--red); }

/* ── Auth pages ───────────────────────────────────────────── */

.auth-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--page-bg);
  padding: 1rem;
}

.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border-radius: 12px;
  padding: 2rem;
  border: 1px solid var(--border);
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}

.auth-brand {
  display: flex;
  align-items: center;
  gap: 0.5625rem;
  margin-bottom: 1.5rem;
}

.auth-brand-name {
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--text);
}

.auth-heading {
  font-size: 1.1875rem;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 0.25rem;
}

.auth-sub {
  font-size: 0.875rem;
  color: var(--muted-hi);
  margin: 0 0 1.375rem;
}

.auth-link {
  color: var(--indigo);
  text-decoration: none;
  font-weight: 500;
}
.auth-link:hover { text-decoration: underline; }

.btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.625rem 1rem;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s;
}
.btn-google:hover { background: var(--border); border-color: var(--muted); }
.btn-google svg { flex-shrink: 0; }

/* "or" divider between Google and the email form. */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: var(--muted);
  font-size: 0.8125rem;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.auth-foot {
  margin-top: 1.25rem;
  font-size: 0.8125rem;
  color: var(--muted);
  text-align: center;
}

/* Label + helper link sharing a row (e.g. "Password   Forgot password?"). */
.field-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.field-label-row label { margin-bottom: 0; }
.field-label-row .auth-link { font-size: 0.8125rem; font-weight: 500; }

/* ── Legal pages (Terms / Privacy) ────────────────────────── */

.legal-wrap {
  min-height: 100vh;
  background: var(--page-bg);
  padding: 3rem 1rem 4rem;
  display: flex;
  justify-content: center;
}

.legal-page {
  width: 100%;
  max-width: 720px;
}

.legal-brand { margin-bottom: 2rem; }

.legal-title {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 0.25rem;
}

.legal-meta {
  font-size: 0.8125rem;
  color: var(--muted);
  margin: 0 0 2rem;
}

.legal-body {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--muted-hi);
}

.legal-body h2 {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--text);
  margin: 2rem 0 0.5rem;
}

.legal-body p { margin: 0 0 1rem; }

.legal-body ul {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
}
.legal-body li { margin-bottom: 0.375rem; }

.legal-foot {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border-soft);
  font-size: 0.8125rem;
  color: var(--muted);
}
.legal-foot-sep { margin: 0 0.5rem; color: var(--border); }

/* ── Flash alerts ─────────────────────────────────────────── */

.alert {
  padding: 0.625rem 0.875rem;
  border-radius: 8px;
  font-size: 0.875rem;
  margin-bottom: 0.875rem;
}

.alert.error   { background: #2d0f0f; color: var(--red);     border: 1px solid #5c1a1a; }
.alert.success { background: #0d2b1a; color: var(--emerald); border: 1px solid #1a4a30; }
.alert.warning { background: #2d2208; color: var(--amber);   border: 1px solid #5c4610; }

/* ── Dialog (base) ────────────────────────────────────────── */

dialog {
  border-radius: 12px;
  border: 1px solid var(--border);
  box-shadow: 0 16px 48px rgba(0,0,0,0.6);
  padding: 0;
  width: min(500px, 96vw);
  background: var(--surface);
  color: var(--text);
}

dialog::backdrop {
  background: rgba(0,0,0,0.65);
}

.dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.dialog-head-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.dialog-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
}

.dialog-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 0.25rem;
  border-radius: 4px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: color 0.1s;
}
.dialog-close:hover { color: var(--text); }

/* Pin-to-dashboard toggle in the card header. `margin-left: auto` parks it
   next to the close button — .dialog-head is space-between, so without it a
   third child would float to the middle. */
.dialog-pin {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 0.3rem;
  margin-left: auto;
  margin-right: 0.75rem;
  border-radius: 5px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: color 0.1s, background 0.1s;
}
.dialog-pin:hover { color: var(--text); background: var(--elevated); }
.dialog-pin.is-pinned { color: var(--amber); }
.dialog-pin.is-pinned svg { fill: currentColor; }

.dialog-body {
  padding: 1.125rem 1.25rem;
}

.dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.875rem 1.25rem;
  border-top: 1px solid var(--border);
}

/* ── Contact support dialog ───────────────────────────────── */

/* A shade wider than oat's 32rem default — it's mostly a message box. oat
   clips dialog overflow, so the body scrolls on a short viewport rather than
   pushing the Send button out of reach. */
.support-dialog { width: min(100% - 2rem, 34rem); }
.support-dialog .dialog-body { max-height: 62vh; overflow-y: auto; }
.support-dialog .section-sub { margin-top: 0; }
.support-sent { margin: 0; }

/* ── Task edit dialog ─────────────────────────────────────── */

.task-dialog {
  width: min(660px, 96vw);
  max-height: 90vh;
  padding: 0;
  /* Close instantly. oat.css gives every <dialog> a .15s fade/scale transition
     in BOTH directions and keeps it displayed for that .15s on close (display
     allow-discrete). But by then [open] is gone, so the `display:flex` column
     layout below no longer applies and the head/body/footer reflow into block
     flow for ~150ms — the "flash of unstyled content" on close. Zeroing the
     transition on the closed state removes that window. The [open] rule re-adds
     it so the entrance animation is preserved (the browser reads the transition
     from the after-change state, which on open is [open]). */
  transition: none;
}
/* Only switch to flex layout when the dialog is actually open — otherwise we
   override the browser's default `display: none` on closed <dialog>, which
   leaks the modal contents into the page flow. */
.task-dialog[open] {
  display: flex;
  flex-direction: column;
  transition: opacity .15s ease, transform .15s ease,
              overlay .15s ease allow-discrete, display .15s ease allow-discrete;
}
/* Match the dialog: no lingering backdrop fade on close. */
.task-dialog::backdrop {
  transition: none;
}

.task-id-badge {
  font-family: var(--font-mono, monospace);
  font-size: 0.75rem;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.2rem 0.5rem;
  letter-spacing: 0.03em;
}

/* One scroller for the whole card — form, then comments and activity below it.
   Both the editor and the new-card dialog scroll here. */
.task-dialog-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* .task-dialog-cols / .task-main / .task-side need no layout rules: comments
   and activity read as the tail of the card, so plain block flow stacks them
   under the form and .task-comments/.task-activity carry their own dividers.
   They keep their class names as hooks for the page and profile variants. */

/* Full-page card: the same dialog chrome, but a real page. Fixed over the app
   shell so it fills the screen and reads as a modal; close/Esc navigate back. */
.task-dialog--page {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: var(--page-bg);
}
.task-dialog--page .dialog-close { cursor: pointer; }
/* The page fills the screen, but the card inside it is the same narrow column
   as the modal — otherwise the form and the comments run the whole width. */
.task-dialog--page .task-dialog-cols {
  width: 100%;
  max-width: 46rem;
  margin-inline: auto;
}

/* Profile — a client's own card. Same body, but it's a destination in their
   sidebar rather than a modal over the portal, so it flows inside <main> and
   the nav stays visible. `flex: 1` against the shell's 100vh column keeps the
   header pinned and the scrolling inside, exactly like the covering version. */
.task-dialog--profile {
  position: static;
  z-index: auto;
  flex: 1;
  min-height: 0;
  height: auto;
}
/* No comments rail here (card/_detail.html), so the form would otherwise run
   the full width of the screen. Cap it and centre it in the column. */
.task-dialog--profile .task-main {
  width: 100%;
  max-width: 46rem;
  margin-inline: auto;
}

.task-dialog-body {
  padding: 1.5rem 1.75rem 1rem;
}

.task-title-input {
  width: 100%;
  background: none;
  border: none;
  outline: none;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text);
  padding: 0;
  margin-bottom: 1rem;
  line-height: 1.3;
}

.task-title-input::placeholder { color: var(--muted); }

.task-desc-input {
  width: 100%;
  background: transparent;
  border: 1px solid var(--border-soft);
  outline: none;
  font-size: 0.9375rem;
  color: var(--text);
  padding: 0.625rem 0.75rem;
  min-height: 12rem;
  line-height: 1.6;
  margin-bottom: 1.25rem;
  border-radius: 6px;
  transition: border-color 0.15s, box-shadow 0.15s;
  word-break: break-word;
  /* Drag the bottom-right corner to give a long description more room.
     `resize` is inert without a non-visible overflow, so the box scrolls its
     own content once it's been sized down. */
  resize: vertical;
  overflow: auto;
}
.task-desc-input:focus { border-color: var(--indigo); }

/* Placeholder via pseudo-element. Contenteditable elements are never truly
   :empty when they contain `<br>` from carets, so also gate on an explicit
   data-empty flag toggled by JS. */
.task-desc-input:empty::before,
.task-desc-input[data-empty]::before {
  content: attr(data-placeholder);
  color: var(--muted);
  pointer-events: none;
}
.task-desc-input p:first-child { margin-top: 0; }
.task-desc-input p:last-child { margin-bottom: 0; }
.task-desc-input a { color: var(--indigo); }

/* Drag-over highlight */
.task-desc-input.drag-over {
  box-shadow: 0 0 0 2px var(--indigo);
  background: rgba(129, 140, 248, 0.05);
}

/* Lists, whether the author pasted them or they came back from the Markdown
   view. oat.css lays some lists out as flex rows; these are prose. */
.task-desc-input ul, .task-desc-input ol,
.comment-body ul, .comment-body ol {
  display: block;
  padding-left: 1.25rem;
  margin: 0.35rem 0;
}
.task-desc-input ul, .comment-body ul { list-style: disc outside; }
.task-desc-input ol, .comment-body ol { list-style: decimal outside; }
.task-desc-input li, .comment-body li { margin: 0.1rem 0; }

/* Inline images */
.task-desc-input img {
  max-width: 100%;
  border-radius: 6px;
  margin: 0.375rem 0;
  display: block;
  cursor: default;
}

.task-meta-row {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--border-soft);
}

.task-meta-label {
  font-size: 0.875rem;
  color: var(--muted);
  width: 72px;
  flex-shrink: 0;
}

.pill-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.pill {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.3125rem 0.75rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  font-size: 0.8125rem;
  color: var(--muted-hi);
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
  user-select: none;
}

.pill input[type="radio"],
.pill input[type="checkbox"] { display: none; }

.pill:hover {
  border-color: var(--muted);
  color: var(--text);
}

.pill:has(input:checked) {
  border-color: var(--indigo);
  color: var(--text);
  background: rgba(129, 140, 248, 0.1);
}

/* A pill that states a value rather than offering one — the client portal's
   read-only assignee. Same shape, nothing to click. */
.pill.is-static {
  cursor: default;
  color: var(--text);
  border-color: var(--border-soft);
  background: var(--elevated);
}
.pill.is-static:hover { border-color: var(--border-soft); }

.task-dialog-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.75rem;
  border-top: 1px solid var(--border);
}

.task-dialog-foot-right {
  display: flex;
  gap: 0.625rem;
}

.task-dialog-delete {
  display: flex;
  justify-content: flex-start;
  padding: 1.25rem 1.75rem 1.5rem;
  border-top: 1px solid var(--border);
}

.autosave-status {
  font-size: 0.8125rem;
  color: var(--muted);
  font-style: italic;
}

.btn-delete-task {
  background: rgba(248, 113, 113, 0.08);
  border: 1px solid rgba(248, 113, 113, 0.35);
  color: var(--red);
  padding: 0.5rem 1.125rem;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 500;
  transition: background 0.12s, border-color 0.12s;
}

.btn-delete-task:hover {
  background: rgba(248, 113, 113, 0.15);
  border-color: var(--red);
}

.btn-cancel-task {
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--muted-hi);
  padding: 0.5rem 1.125rem;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 500;
  transition: background 0.12s;
}

.btn-cancel-task:hover { background: var(--border); color: var(--text); }

.btn-save-task {
  background: var(--indigo);
  border: none;
  color: #fff;
  padding: 0.5rem 1.375rem;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 600;
  transition: opacity 0.12s;
}

.btn-save-task:hover { opacity: 0.88; }

.btn-new-card {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.btn-new-card-kbd {
  margin-left: 0.1rem;
  font-size: 0.7rem;
  font-family: monospace;
  line-height: 1;
  color: #fff;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.35);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
}

/* ── Forms ────────────────────────────────────────────────── */

.field {
  margin-bottom: 0.875rem;
}

.field:last-child {
  margin-bottom: 0;
}

.field label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--muted-hi);
  margin-bottom: 0.3125rem;
}

/* ── Members page ─────────────────────────────────────────── */

.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  align-items: start;
}

/* Same shell as .two-col, one more column — the Billing page's three plan
   cards (Free/Pro/Once), mirroring the landing page's pricing table. */
.three-col {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1.5rem;
  align-items: start;
}

.section-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 0.75rem;
}

.invite-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border-soft);
}

.invite-item:last-child { border-bottom: none; }

.invite-email {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text);
}

.invite-link-text {
  font-family: monospace;
  font-size: 0.6875rem;
  color: var(--muted);
  word-break: break-all;
  margin-top: 0.25rem;
}

.badge {
  font-size: 0.6875rem;
  font-weight: 500;
  padding: 0.2rem 0.5rem;
  border-radius: 9999px;
  white-space: nowrap;
  flex-shrink: 0;
}

.badge-pending { background: #2d2208; color: var(--amber);   }
.badge-joined  { background: #0d2b1a; color: var(--emerald); }

.member-row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0;
  border-bottom: 1px solid var(--border-soft);
}

.member-row:last-child { border-bottom: none; }

.member-info { flex: 1; }
.member-name  { font-size: 0.875rem; font-weight: 500; color: var(--text); }
.member-email { font-size: 0.75rem;  color: var(--muted); }

/* ── Upgrade nudge ────────────────────────────────────────── */

/* Stands where a Pro-only form would be (invite a member, enable card
   logins). Indigo-tinted rather than red: this is a locked door, not an
   error. */
.upgrade-nudge {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
  padding: 0.875rem 1rem;
  border: 1px solid color-mix(in srgb, var(--indigo) 45%, transparent);
  background: rgba(129, 140, 248, 0.08);
  border-radius: 10px;
}

.upgrade-nudge-text { min-width: 0; }

.upgrade-nudge-title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--indigo);
}

.upgrade-nudge-text p {
  margin: 0.25rem 0 0;
  font-size: 0.8125rem;
  color: var(--muted-hi);
}

/* ── Billing page ─────────────────────────────────────────── */

/* Upgrade + Manage billing sit side by side on the current-plan row, and stack
   under it on narrow screens (where .setting-row wraps). */
.plan-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex-shrink: 0;
}

.plan-card { position: relative; }

/* The plan you're on gets the accent edge, so the pair reads as a choice
   already made rather than two equal options. */
.plan-card.is-current { border-color: var(--indigo); }

.plan-name {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.plan-price {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
  margin-top: 0.25rem;
}

.plan-per {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--muted);
  margin-left: 0.3rem;
}

.plan-note {
  font-size: 0.8125rem;
  color: var(--muted);
  margin: 0.375rem 0 0;
}

.plan-features {
  list-style: none;
  padding: 0;
  margin: 0.875rem 0 0;
  display: grid;
  gap: 0.4rem;
}

.plan-features li {
  font-size: 0.8125rem;
  color: var(--muted-hi);
  padding-left: 1.1rem;
  position: relative;
}

.plan-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--emerald);
  font-size: 0.75rem;
}

/* A limitation of the plan rather than something it includes. */
.plan-features li.is-limit { color: var(--muted); }
.plan-features li.is-limit::before { content: "–"; color: var(--muted); }

/* Free/Once's download links (Pro's own upgrade path lives in the "Current
   plan" card above, not here) — give them room under the feature list. */
.plan-card > a { display: inline-block; margin-top: 0.875rem; }

/* ── Template picker (New app dialog) ────────────────────── */
/* Same "card that's really a label around a radio" trick as .pill, just
   sized for two rich options instead of a row of small tags. */

.template-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.625rem;
  margin-top: 0.375rem;
}

.template-card {
  display: block;
  position: relative;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem 0.875rem;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, transform 0.12s, box-shadow 0.12s;
}

.template-card input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.template-card:hover { border-color: var(--muted); }

.template-card:has(input:checked) {
  border-color: var(--indigo);
  background: rgba(129, 140, 248, 0.1);
}

.template-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}

.template-price {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 0.1rem;
}

.template-note {
  font-size: 0.75rem;
  color: var(--muted-hi);
  margin-top: 0.375rem;
  line-height: 1.4;
}

.template-badge {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--indigo);
  background: rgba(129, 140, 248, 0.16);
  border-radius: 5px;
  padding: 0.1rem 0.4rem;
  margin-bottom: 0.3rem;
}

/* The Startup option is the one meant to catch the eye — a standing accent
   glow even unchecked, and a slight lift on hover — so Free reads as the
   plain default and Startup reads as the upgrade worth clicking. */
.template-card.is-featured {
  border-color: rgba(129, 140, 248, 0.35);
  background: linear-gradient(165deg, rgba(129, 140, 248, 0.1), transparent 70%);
}

.template-card.is-featured:hover {
  border-color: var(--indigo);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px -8px rgba(129, 140, 248, 0.45);
}

.template-card.is-featured .template-name { color: var(--indigo); }

/* Off Pro: the Startup card links to Billing instead of taking a radio —
   same shape, but no checked state and a plainer hover to read as "locked". */
.template-card.is-locked { cursor: pointer; }
.template-card.is-locked:hover {
  border-color: rgba(129, 140, 248, 0.35);
  transform: none;
  box-shadow: none;
}
.template-card.is-locked .template-price { color: var(--indigo); font-weight: 600; }

/* New app dialog: provisioning takes a few real seconds (see the
   data-provision-* script in apps/index.html), so the fields dim under
   oat's built-in overlay spinner ([data-spinner~=overlay][aria-busy=true],
   set by that script) rather than the dialog looking frozen. This message
   sits below it, at full opacity, so it stays readable while the fields
   don't. */
.provision-status {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
  color: var(--muted-hi);
  text-align: center;
}

/* ── Column quick-add ────────────────────────────────────── */

.col-add {
  margin-top: 0.5rem;
}

.col-add-trigger {
  width: 100%;
  background: none;
  border: none;
  color: var(--muted);
  padding: 0.375rem 0.5rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.8125rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
  transition: background 0.1s, color 0.1s;
}

.col-add-trigger:hover {
  background: var(--elevated);
  color: var(--text);
}

.col-add-form {
  display: none;
}

.col-add-form.open {
  display: block;
}

.col-add-form textarea {
  width: 100%;
  resize: none;
  font-size: 0.875rem;
  border-radius: 6px;
  margin-bottom: 0.5rem;
}

.col-add-actions {
  display: flex;
  gap: 0.375rem;
}

.col-add-actions button {
  font-size: 0.8125rem;
  padding: 0.3rem 0.75rem;
}

/* ── Mobile topbar (hidden on desktop) ───────────────────── */

.topbar {
  display: none;
}

/* ── Responsive ───────────────────────────────────────────── */

@media (max-width: 768px) {
  /* Topbar */
  .topbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: env(safe-area-inset-top) 1rem 0;
    height: calc(52px + env(safe-area-inset-top));
    background: var(--surface);
    border-bottom: 1px solid var(--border-soft);
    position: sticky;
    top: 0;
    z-index: 90;
    flex-shrink: 0;
  }

  .topbar-toggle {
    background: none;
    border: none;
    color: var(--muted-hi);
    cursor: pointer;
    padding: 0.25rem;
    display: grid;
    place-items: center;
    border-radius: 6px;
  }
  .topbar-toggle:hover { background: var(--elevated); color: var(--text); }

  .topbar-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 1rem;
    color: var(--text);
  }

  /* Sidebar: slide in from left as overlay */
  .sidebar {
    transform: translateX(-100%);
    transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  }

  [data-sidebar-layout][data-sidebar-open] .sidebar {
    transform: translateX(0);
  }

  /* Desktop nav rows are 13px text on a 6px-tall padding — fine for a cursor,
     too small for a thumb. Bump the type and the padding so each row is a
     comfortable tap target while the sidebar is an overlay. */
  /* Scoped to .sidebar to outweigh .ws-menu-item, which is declared further
     down the file — a media query adds no specificity of its own. */
  .sidebar .nav-link,
  .sidebar .support-btn,
  .sidebar .ws-menu-item {
    font-size: 0.9375rem;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
  .sidebar .user-name { font-size: 0.9375rem; }
  .sidebar .nav-label { font-size: 0.75rem; }

  /* Backdrop */
  [data-sidebar-layout][data-sidebar-open]::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 99;
  }

  .app  { flex-direction: column; }
  .main { margin-left: 0; }
  /* The mobile topbar already absorbs the iOS notch via safe-area-inset-top;
     reset page-header so the title doesn't get pushed down twice. */
  .page-header { padding-top: 1rem; }

  /* On mobile each kanban column becomes a swipeable page. Tighten the
     page-body horizontal padding so the column has room to fit the screen,
     then size the column to the resulting container width (1rem each side).
     Scroll-snap is mobile-only — on desktop it would fight Sortable.js's
     drag-between-columns and prevent dropping. */
  .page-body { padding-left: 1rem; padding-right: 1rem; }
  .kanban {
    scroll-snap-type: x mandatory;
  }
  .kanban .column {
    flex-basis: calc(100vw - 2rem);
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }

  /* View toolbar: keep the tab strip on one row (scroll horizontally if
     needed) so the "+" affordance never wraps to a second line, and shrink
     the Configure button to an icon-only chip. */
  .view-toolbar { padding-left: 1rem; padding-right: 1rem; gap: 0.5rem; }
  .view-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .view-tabs::-webkit-scrollbar { display: none; }
  .view-tab, .view-add { flex-shrink: 0; }
  .view-config-label { display: none; }
  .view-config-btn { padding: 0.4rem 0.5rem; }

  /* New-card button shrinks to an icon-only chip on mobile so the binder
     title has room to breathe. */
  .btn-new-card { padding: 0.45rem 0.55rem; }
  .btn-new-card-label { display: none; }
  .btn-new-card-kbd { display: none; }
  .btn-new-card-icon { width: 22px; height: 22px; }

  /* Bump up the other header icons (Forms, Import, Export, Settings) to
     match — they sit on the same row and look tiny next to a 22px plus. */
  .page-header-link { padding: 0.4rem 0.5rem; }
  .page-header-link svg { width: 18px; height: 18px; }

  /* Card modal goes full-screen on mobile. The dialog itself caps at the
     viewport, the body scrolls inside it, and the footer stays pinned. */
  .task-dialog {
    width: 100vw;
    max-width: 100vw;
    max-height: 100vh;
    height: 100vh;
    margin: 0;
    border-radius: 0;
    border: none;
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .task-dialog .task-dialog-body {
    padding: 1rem 0.75rem;
  }
  .task-dialog .task-dialog-foot {
    padding: 0.75rem;
    gap: 0.5rem;
  }
  .task-dialog .task-attachments,
  .task-dialog .task-comments,
  .task-dialog .task-activity,
  .task-dialog .task-related,
  .task-dialog .task-account {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
  /* Keep wide inner content (long titles, images, code blocks) from making the
     card scroll sideways; the stacked layout itself is the same as desktop. */
  .task-dialog .task-dialog-scroll { overflow-x: hidden; }
  .task-dialog .task-dialog-scroll * { max-width: 100%; }
  .task-dialog .task-desc-input { overflow-wrap: anywhere; }

  /* Profile sits in the flow under the mobile topbar, so it can't claim the
     full viewport height — it sizes to its content and the page scrolls. */
  .task-dialog--profile { height: auto; max-height: none; }

  /* iOS Safari auto-zooms (and refuses to zoom back) when focusing a form
     control with computed font-size < 16px. Bumping mobile form fields to
     16px disables the zoom-on-focus without taking away the user's ability
     to pinch-zoom. !important is needed because many components define
     their own (smaller) font-size with higher specificity. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]),
  textarea,
  select,
  [contenteditable="true"] {
    font-size: 16px !important;
  }

  .two-col { grid-template-columns: 1fr; }
  .three-col { grid-template-columns: 1fr; }
  .binder-grid { grid-template-columns: 1fr; }
  .status-form { flex-wrap: wrap; }
}

/* ── Workspace switcher ──────────────────────────────────── */

.workspace-switcher {
  border-bottom: 1px solid var(--border-soft);
}
.workspace-switcher > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 1rem 1.125rem;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.02em;
  color: var(--text);
  border-bottom: none;
}
/* Suppress oat.css's default chevron on this <summary>; we use a kebab icon. */
.workspace-switcher > summary::after { content: none !important; }
.ws-kebab {
  color: var(--muted);
  flex-shrink: 0;
}
.workspace-switcher[open] .ws-kebab { color: var(--text); }
.workspace-switcher .ws-name { flex: 1; }
.workspace-switcher .ws-caret {
  color: var(--muted);
  transition: transform 0.15s;
}
.workspace-switcher[open] .ws-caret { transform: rotate(180deg); }
.ws-menu {
  padding: 0.375rem;
  background: var(--elevated);
  border-bottom: 1px solid var(--border-soft);
}
.ws-menu-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.625rem;
  border-radius: 6px;
  color: var(--muted-hi);
  text-decoration: none;
  font-size: 0.8125rem;
}
.ws-menu-item:hover { background: var(--surface); color: var(--text); }
.ws-menu-item.is-current { color: var(--text); font-weight: 500; }
.logo-mark.sm {
  width: 18px; height: 18px;
  font-size: 0.7rem;
  border-radius: 4px;
}

/* ── Binder grid ──────────────────────────────────────────── */

.binder-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0.75rem;
}
.binder-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  transition: border-color 0.15s, transform 0.15s;
}
.binder-card:hover { border-color: var(--border); }
.binder-card-ghost { opacity: 0.4; }
.binder-card-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  text-decoration: none;
  color: var(--text);
}
.binder-card-icon { font-size: 1.25rem; }
.binder-card-body { flex: 1; min-width: 0; }
.binder-card-name {
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 0.125rem;
}
.binder-card-meta {
  font-size: 0.75rem;
  color: var(--muted);
}
.binder-card-menu {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 1rem;
  line-height: 1;
}
.binder-card-menu:hover { background: var(--elevated); color: var(--text); }

/* Sidebar binder list */
.nav-binder { gap: 0.5rem; }
.nav-binder .binder-icon { font-size: 0.95rem; line-height: 1; }
.nav-binder .binder-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A binder row = the link + a hover-revealed 3-dots menu button. */
.nav-binder-row { position: relative; display: flex; align-items: center; }
.nav-binder-row .nav-binder { flex: 1; min-width: 0; }
.nav-binder-menu {
  position: absolute; right: 0.15rem; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; padding: 0;
  border: none; border-radius: 5px; background: transparent;
  color: var(--muted); cursor: pointer; font-size: 1rem; line-height: 1;
  opacity: 0; transition: opacity 0.1s, background 0.1s;
}
.nav-binder-row:hover .nav-binder-menu { opacity: 1; }
.nav-binder-menu:hover { background: var(--border); color: var(--text); }
@media (hover: none) { .nav-binder-menu { opacity: 1; } }

/* "New binder" — a button styled like a nav binder link. */
.nav-new-binder {
  width: 100%; border: none; background: transparent; cursor: pointer;
  font: inherit; font-size: 0.8125rem; color: var(--muted); text-align: left;
}
.nav-new-binder .binder-icon { font-size: 1rem; }
.nav-new-binder:hover { color: var(--text); }

/* ── Empty state ─────────────────────────────────────────── */

.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--muted);
}
.empty-state h2 {
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
}
.empty-state p {
  font-size: 0.875rem;
  margin: 0 0 1rem;
}

/* ── Page header extras ──────────────────────────────────── */

.page-header-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.page-header-link, .page-header-back {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.8125rem;
  color: var(--muted);
  text-decoration: none;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  background: transparent;
  border: none;
  cursor: pointer;
  font: inherit;
}
.page-header-link:hover, .page-header-back:hover {
  background: var(--elevated);
  color: var(--text);
}

/* CSS tooltip: anchor below the trigger (used where browser `title` would
   clip off-screen above the page). */
[data-tip] { position: relative; }
[data-tip][data-tip-pos="below"]::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--elevated);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.25rem 0.5rem;
  font-size: 0.75rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s 0.25s;
  z-index: 200;
}
[data-tip][data-tip-pos="below"]:hover::after,
[data-tip][data-tip-pos="below"]:focus-visible::after {
  opacity: 1;
}

/* ── Card edit dialog: plain textarea desc (replaces contenteditable) ── */

.task-desc-textarea {
  width: 100%;
  background: transparent;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.625rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
  line-height: 1.5;
  resize: vertical;
  min-height: 6rem;
  margin-bottom: 1rem;
}
.task-desc-textarea:focus {
  outline: none;
  border-color: var(--indigo);
}
/* Custom fields of type `date`. */
.date-input {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.375rem 0.5rem;
  color: var(--text);
  font: inherit;
  font-size: 0.8125rem;
}

/* ── Settings: status list ───────────────────────────────── */

.settings-section { margin-bottom: 2rem; }
.section-sub {
  font-size: 0.8125rem;
  color: var(--muted);
  margin: -0.25rem 0 0.75rem;
}
.status-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.status-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-soft);
}
.status-row:last-child { border-bottom: none; }
.status-drag {
  color: var(--muted);
  cursor: grab;
  user-select: none;
  padding: 0 0.25rem;
}
.status-form {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.status-form input[type="text"] { flex: 1; min-width: 8rem; }
.status-form select { min-width: 6rem; }
.status-form button {
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.3rem 0.75rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.8125rem;
}
.status-form button:hover { background: var(--border); }
.status-delete {
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--muted);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
}
.status-delete:hover { color: var(--red); border-color: var(--red); }
.status-add-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-soft);
  margin-top: 0.5rem;
  flex-wrap: wrap;
}
.status-add-form input[type="text"] { flex: 1; min-width: 8rem; }

/* ── Settings: field list ────────────────────────────────── */

.field-list {
  list-style: none;
  margin: 0 0 0.75rem;
  padding: 0;
}
.field-row {
  border-bottom: 1px solid var(--border-soft);
}
.field-row:last-child { border-bottom: none; }

.field-detail { padding: 0.5rem 0; }
.field-detail[open] { padding-bottom: 1rem; }

.field-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
}
.field-summary::-webkit-details-marker { display: none; }
.field-summary::marker { content: ''; }

.field-drag {
  color: var(--muted);
  cursor: grab;
  user-select: none;
  padding: 0 0.25rem;
}

.field-type-chip {
  font-size: 0.6875rem;
  color: var(--muted-hi);
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  white-space: nowrap;
}

.field-name-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text);
}

.field-key-mono {
  margin-left: auto;
  font-family: monospace;
  font-size: 0.7rem;
  color: var(--muted);
}

.field-form {
  padding: 0.75rem 0 0 1.625rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.field-form .field { margin: 0; }
.field-form input[type="text"],
.field-form input[type="number"],
.field-form select,
.field-form textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.375rem 0.5rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.field-form textarea { resize: vertical; min-height: 4.5rem; }
.field-form input:focus,
.field-form select:focus,
.field-form textarea:focus {
  outline: none;
  border-color: var(--indigo);
}

.field-hint {
  display: block;
  font-weight: 400;
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 0.125rem;
}
.field-hint code {
  background: var(--elevated);
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
  font-size: 0.7rem;
}

.field-inline {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.625rem;
}

.field-required {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  color: var(--muted-hi);
  cursor: pointer;
}

.field-form-actions {
  display: flex;
  gap: 0.5rem;
}
.field-form-actions button {
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.375rem 0.875rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  cursor: pointer;
}
.field-form-actions button:hover { background: var(--border); }

.field-delete-form {
  padding: 0.75rem 0 0 1.625rem;
}
.field-delete-form .btn-delete-task {
  font-size: 0.8125rem;
  padding: 0.35rem 0.875rem;
}

.field-add { margin-top: 0.5rem; border-top: 1px solid var(--border-soft); }
.field-add-trigger {
  list-style: none;
  cursor: pointer;
  padding: 0.75rem 1rem;
  font-size: 0.8125rem;
  color: var(--muted-hi);
}
.field-add-trigger::-webkit-details-marker { display: none; }
.field-add-trigger:hover { color: var(--text); }
.field-add[open] .field-add-trigger { color: var(--text); }
.field-add-form { padding: 0 1rem 1rem; }

/* ── Card modal: custom-field controls ───────────────────── */

.field-meta-row { align-items: flex-start; }
.field-meta-row .task-meta-label { padding-top: 0.4rem; }

.field-control {
  flex: 1;
  min-width: 0;
}
.field-control input[type="text"],
.field-control input[type="number"],
.field-control textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.4rem 0.55rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.field-control textarea { resize: vertical; min-height: 4rem; }
.field-control input:focus, .field-control textarea:focus {
  outline: none;
  border-color: var(--indigo);
}

.field-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  color: var(--muted-hi);
  cursor: pointer;
}

.field-req {
  color: var(--red);
  font-weight: 600;
}

/* ── View toolbar (tabs + configure) ─────────────────────── */

.view-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 1.5rem 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border-soft);
}

/* The view shell stickies the page-header + view-toolbar together as a single
   block. Sticking them separately was fragile: the toolbar's `top` had to
   match the header's measured height, but the header height varies with the
   safe-area inset and mobile breakpoint, producing a 1–2px gap or overlap. */
.view-shell-stick {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--surface);
}
.view-shell-stick .page-header,
.view-shell-stick .view-toolbar {
  position: static;
}
.view-tabs {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  min-width: 0;
  flex: 1 1 auto;
}
.view-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem;
  border-radius: 6px 6px 0 0;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.8125rem;
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  cursor: pointer;
}
/* Only apply the hover styling on devices that actually have a hover-capable
   pointer (mouse / trackpad). On touch devices iOS Safari otherwise treats
   the first tap as "hover" and only commits the navigation on the second
   tap, which feels broken. */
@media (hover: hover) {
  .view-tab:hover { color: var(--text); background: var(--elevated); }
}
.view-tab { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.view-tab.active {
  color: var(--text);
  background: var(--page-bg);
  border-color: var(--border-soft);
  font-weight: 500;
}
.view-tab-icon { opacity: 0.65; font-size: 0.9rem; }


/* ── Confirm dialog ──────────────────────────────────────── */

.confirm-dialog {
  width: min(420px, 92vw);
  padding: 0;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.confirm-dialog::backdrop { background: rgba(0,0,0,0.65); }
.confirm-body {
  padding: 1.5rem 1.5rem 1rem;
}
.confirm-title {
  margin: 0 0 0.4rem;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--text);
}
.confirm-message {
  margin: 0;
  font-size: 0.875rem;
  color: var(--muted-hi);
  line-height: 1.45;
}
.confirm-dialog .dialog-foot {
  border-top: none;
  padding-top: 0.5rem;
}
.view-add {
  color: var(--muted);
  font-weight: 600;
  font-size: 1rem;
  padding: 0.2rem 0.6rem;
}
.view-toolbar-right { display: flex; gap: 0.5rem; padding-bottom: 0.4rem; }
.view-config-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  color: var(--muted-hi);
  padding: 0.35rem 0.75rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  cursor: pointer;
}
.view-config-btn:hover { color: var(--text); border-color: var(--border); }

/* ── Table view ──────────────────────────────────────────── */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--surface);
}
.card-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
  color: var(--text);
}
.card-table th,
.card-table td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--border-soft);
  text-align: left;
  white-space: nowrap;
}
.card-table th {
  background: var(--elevated);
  font-weight: 500;
  font-size: 0.75rem;
  color: var(--muted-hi);
  position: sticky;
  top: 0;
  z-index: 2;
}
.card-table tbody tr {
  cursor: pointer;
  transition: background 0.08s;
}
.card-table tbody tr:hover { background: var(--elevated); }
.card-table tbody tr:last-child td { border-bottom: none; }

.th-title { min-width: 14rem; }
.td-title {
  font-weight: 500;
  color: var(--text);
  white-space: normal;
  word-break: break-word;
}
.td-empty {
  text-align: center;
  color: var(--muted);
  padding: 2rem !important;
}
.td-title, .card-table thead .th-title {
  position: sticky;
  left: 0;
  background: var(--surface);
  z-index: 1;
}
.card-table thead .th-title {
  background: var(--elevated);
  z-index: 3;
}
.card-table tbody tr:hover .td-title { background: var(--elevated); }

.th-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: inherit;
  text-decoration: none;
}
.th-sort:hover { color: var(--text); }
.th-sort.active { color: var(--text); }
.th-sort-arrow { font-size: 0.7rem; }

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  background: var(--elevated);
  font-size: 0.75rem;
}
.select-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.45rem;
  margin-right: 0.25rem;
  border-radius: 4px;
  background: var(--elevated);
  font-size: 0.7rem;
  color: var(--muted-hi);
}
.assignee-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.muted { color: var(--muted); }

.formula-cell {
  font-variant-numeric: tabular-nums;
}
.formula-err {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem;
  color: var(--danger, #c0392b);
  background: rgba(192, 57, 43, 0.08);
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
}
.formula-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
}

/* ── Automation rows ─────────────────────────────────────── */

.automation-list {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem;
}
.automation-row {
  border-bottom: 1px solid var(--divider, rgba(0, 0, 0, 0.08));
  padding: 0.4rem 0;
}
.automation-row:last-child { border-bottom: none; }
.automation-summary {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  cursor: pointer;
  list-style: none;
}
.automation-name {
  font-weight: 600;
}
.automation-meta {
  font-size: 0.78rem;
}
.automation-form {
  padding: 0.6rem 0 0.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.automation-form-actions {
  margin-top: 0.35rem;
}
.automation-row-buttons {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.4rem;
}

/* ── List view ───────────────────────────────────────────── */

.list-group {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  margin-bottom: 0.875rem;
  overflow: hidden;
}
.list-group-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.875rem;
  background: var(--elevated);
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.8125rem;
}
.list-group-label { font-weight: 600; color: var(--text); }
.list-group-count {
  margin-left: auto;
  font-size: 0.7rem;
  color: var(--muted);
  background: var(--surface);
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
}
.list-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.list-empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.875rem;
}
.list-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0.875rem;
  border-bottom: 1px solid var(--border-soft);
  cursor: pointer;
  transition: background 0.08s;
}
.list-row:last-child { border-bottom: none; }
.list-row:hover { background: var(--elevated); }
.list-row-main {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}
.list-row-title {
  font-size: 0.875rem;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.list-row-meta {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-shrink: 0;
}
/* Inline custom-field values on a list row: a faint uppercase label + value,
   matching the density of the Table view without needing column headers. */
.list-field {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  max-width: 15rem;
  min-width: 0;
  font-size: 0.8125rem;
  color: var(--text);
}
.list-field-label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
  flex: 0 0 auto;
}
.list-field-val {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted-hi);
}
.list-field-val .dot { flex: 0 0 auto; }
@media (max-width: 720px) {
  /* Keep list rows tidy on narrow screens — drop the inline field pills. */
  .list-row-meta .list-field { display: none; }
}

/* ── Card modal: Related section ─────────────────────────── */

.task-related {
  padding: 0.5rem 1.75rem 1.25rem;
  border-top: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

/* Account panel: sits outside the auto-saving card form, so it needs the same
   horizontal inset as the body plus a divider (mirrors .task-related). */
.task-account {
  padding: 1rem 1.75rem 1.25rem;
  border-top: 1px solid var(--border-soft);
}
.task-account .task-account-form { margin-top: 0.5rem; }

.related-group {
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 0.625rem 0.75rem;
}
.related-group.inverse {
  border-style: dashed;
}

.related-group-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.related-group-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
}
.related-group-meta {
  font-size: 0.7rem;
  color: var(--muted);
  font-family: monospace;
}

.related-cards {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.related-card {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font-size: 0.8125rem;
}
.related-card-link {
  flex: 1;
  color: var(--text);
  text-decoration: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.related-card-link:hover { color: var(--indigo); }
.related-unlink button {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.75rem;
}
.related-unlink button:hover {
  color: var(--red);
  border-color: var(--red);
}

.related-add {
  display: flex;
  gap: 0.4rem;
}
.related-add select {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.3rem 0.5rem;
  color: var(--text);
  font-size: 0.8125rem;
}
.related-add button {
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.3rem 0.75rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  cursor: pointer;
}
.related-add button:hover { background: var(--border); }

.related-empty {
  font-size: 0.75rem;
  margin: 0;
}

/* ── Workspace setup: wide auth card + template picker ───── */

.auth-wide {
  align-items: flex-start;
  padding: 3rem 1rem;
}
.auth-card-wide {
  max-width: 860px;
}
.setup-cols {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 2rem;
  margin-bottom: 1.25rem;
}
@media (max-width: 720px) {
  .setup-cols { grid-template-columns: 1fr; gap: 1.25rem; }
}
.setup-col { display: flex; flex-direction: column; }
.setup-label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--muted-hi);
  margin-bottom: 0.5rem;
}

.template-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.625rem;
}
.template-card {
  position: relative;
  display: block;
  cursor: pointer;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 0.75rem;
  background: var(--page-bg);
  transition: border-color 0.12s, background 0.12s;
}
.template-card:hover {
  border-color: var(--border);
  background: var(--elevated);
}
.template-card input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.template-card:has(input:checked) {
  border-color: var(--indigo);
  background: rgba(129, 140, 248, 0.08);
}
.template-card-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.25rem;
}
.template-card-desc {
  font-size: 0.75rem;
  color: var(--muted-hi);
  line-height: 1.4;
  margin-bottom: 0.5rem;
}
.template-card-binders {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.template-binder-chip {
  font-size: 0.65rem;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--muted-hi);
}

.ws-menu-new {
  border-top: 1px solid var(--border-soft);
  margin-top: 0.25rem;
  padding-top: 0.5rem !important;
  color: var(--indigo) !important;
  font-weight: 500;
}

/* ── Import wizard ───────────────────────────────────────── */

.page-header-meta {
  font-size: 0.75rem;
  color: var(--muted);
  margin-left: 0.5rem;
}

.import-card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
  max-width: 720px;
  margin-bottom: 1rem;
}
.import-card-tight { padding: 0.875rem 1.25rem; }
.import-card-wide  { max-width: none; padding: 0; }

.import-page-body { padding-bottom: 3rem; }
.import-section   { margin-bottom: 1.75rem; }
.import-section:last-of-type { margin-bottom: 1rem; }

/* Override .card-table tbody tr's cursor:pointer + hover — the import preview
   rows aren't clickable, and hover highlight implies they are. */
.import-preview-wrap .card-table tbody tr { cursor: default; }
.import-preview-wrap .card-table tbody tr:hover { background: transparent; }

.section-meta {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--muted);
  margin-left: 0.4rem;
}

.import-form { max-width: 520px; }
.import-form input[type="file"] {
  width: 100%;
  background: var(--page-bg);
  border: 1px dashed var(--border);
  border-radius: 6px;
  padding: 0.875rem;
  color: var(--text);
}
.import-form input[type="text"] {
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.45rem 0.6rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.radio-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  font-size: 0.875rem;
  color: var(--muted-hi);
}
.radio-row strong { color: var(--text); font-weight: 600; }
.field.nested { margin-left: 1.5rem; margin-bottom: 0.625rem; }

.import-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}
.import-actions .btn-cancel-task,
.import-actions a.btn-cancel-task {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.map-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.625rem;
  margin-bottom: 1rem;
}
.map-col {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 0.625rem 0.75rem;
}
.map-col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.map-col-header {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-type, .map-target {
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.3rem 0.45rem;
  color: var(--text);
  font-size: 0.75rem;
}
.map-type { width: auto; min-width: 6rem; }
.map-col-options {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.5rem;
}

.dry-run-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--muted-hi);
}
.dry-run-list strong { color: var(--text); font-weight: 600; }
.dry-run-list .status-chip { margin-left: 0.25rem; }

/* ── Dashboard ───────────────────────────────────────────── */

.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 0.875rem;
  align-items: start;
}
.dash-widget {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 0.875rem 1rem 1rem;
}
.dash-widget-status_summary { grid-column: 1 / -1; }

.dash-widget-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
.dash-widget-title {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}
.dash-widget-total {
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--muted);
  background: var(--elevated);
  padding: 0.1rem 0.45rem;
  border-radius: 9999px;
}
.dash-card-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.dash-card-row {}
.dash-card-link {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.55rem;
  border-radius: 6px;
  text-decoration: none;
  color: var(--text);
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  transition: border-color 0.1s, background 0.1s;
  min-width: 0;
}
.dash-card-link:hover {
  border-color: var(--border);
  background: var(--elevated);
}
.dash-card-title {
  flex: 1;
  font-size: 0.8125rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash-card-meta {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}
.dash-card-binder {
  font-size: 0.65rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dash-empty {
  margin: 0;
  font-size: 0.8125rem;
}

.dash-breakdown {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.dash-breakdown-row {
  display: grid;
  grid-template-columns: 10rem 1fr 2.5rem;
  align-items: center;
  gap: 0.75rem;
}
.dash-breakdown-name {
  font-size: 0.8125rem;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash-breakdown-name:hover { color: var(--indigo); }
.dash-bar {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--elevated);
}
.dash-bar-seg { display: block; height: 100%; min-width: 6px; }
.dash-breakdown-total {
  font-size: 0.75rem;
  color: var(--muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .dash-breakdown-row {
    grid-template-columns: 1fr;
    gap: 0.25rem;
  }
}

/* ── Client portal home ──────────────────────────────────── */
/* Reuses the dashboard's card rows (.dash-card-*) so a card looks the same
   wherever it appears; everything else is quieter and roomier — the client
   reads this page, they don't work in it. */

.portal-hero {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.portal-hello {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
}
.portal-hero-link {
  font-size: 0.75rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--border-soft);
}
.portal-hero-link:hover { color: var(--indigo); border-color: currentColor; }

.portal-block {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 0.875rem 1rem 1rem;
}
.portal-attention {
  margin-bottom: 0.875rem;
  border-color: var(--border);
}
.portal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 0.875rem;
  align-items: start;
}
/* Their records are the spine of the page — give them the full width. */
.portal-projects { grid-column: 1 / -1; }

.portal-block-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
.portal-block-title {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}

.portal-group + .portal-group { margin-top: 1rem; }
.portal-group-head {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
}
.portal-group-name {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  text-decoration: none;
}
.portal-group-name:hover { color: var(--indigo); }
.portal-group-count {
  font-size: 0.6875rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.portal-more {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.75rem;
  color: var(--muted);
  text-decoration: none;
}
.portal-more:hover { color: var(--indigo); }

.portal-status {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.6875rem;
  color: var(--muted-hi);
  white-space: nowrap;
}

.portal-updates,
.portal-files {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.portal-updates > li + li,
.portal-files > li + li { border-top: 1px solid var(--border-soft); }

.portal-update {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.5rem 0.15rem;
  text-decoration: none;
  color: var(--text);
}
.portal-update:hover .portal-update-card { color: var(--indigo); }
/* Two lines, then clip: a message preview is worth wrapping for, an essay
   isn't. */
.portal-update-line {
  flex: 1;
  min-width: 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.portal-update-card { font-weight: 500; }
.portal-update-text { color: var(--muted-hi); }
.portal-update-text::before { content: ' — '; color: var(--muted); }
.portal-update-ago {
  flex-shrink: 0;
  font-size: 0.6875rem;
  color: var(--muted);
}

.portal-file {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.15rem;
  text-decoration: none;
  color: var(--text);
  min-width: 0;
}
.portal-file svg { flex-shrink: 0; color: var(--muted); }
.portal-file:hover .portal-file-name { color: var(--indigo); }
.portal-file-name {
  font-size: 0.8125rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.portal-file-meta {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 0.6875rem;
  color: var(--muted);
}

/* ── Card modal: attachments / comments / activity ───────── */

.task-section-title {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.task-attachments,
.task-comments,
.task-activity {
  padding: 0.875rem 1.75rem;
  border-top: 1px solid var(--border-soft);
}

.att-list {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.att-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.55rem;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  font-size: 0.8125rem;
}
.att-link {
  flex: 1;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.att-link:hover { color: var(--indigo); }
.att-meta { color: var(--muted); font-size: 0.7rem; }
.att-delete button {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.75rem;
}
.att-delete button:hover { color: var(--red); border-color: var(--red); }

.att-upload {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.att-upload input[type="file"] {
  flex: 1;
  background: var(--page-bg);
  border: 1px dashed var(--border-soft);
  border-radius: 6px;
  padding: 0.3rem 0.5rem;
  color: var(--muted-hi);
  font-size: 0.75rem;
}
.att-upload button {
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.3rem 0.75rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  cursor: pointer;
}

.comment-list {
  list-style: none;
  margin: 0 0 0.5rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.comment-row {
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
}
.comment-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}
.comment-author {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
}
.comment-time {
  font-size: 0.7rem;
  color: var(--muted);
  margin-left: auto;
}
.comment-delete button {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
}
.comment-delete button:hover { color: var(--red); border-color: var(--red); }
.comment-body {
  font-size: 0.875rem;
  color: var(--muted-hi);
  line-height: 1.45;
  word-break: break-word;
}
.comment-body p { margin: 0 0 0.4rem; }
.comment-body p:last-child { margin-bottom: 0; }
/* Rendered Markdown can carry an inline image; keep it inside its column. */
.comment-body img, .form-intro img, .form-success img {
  max-width: 100%;
  border-radius: 6px;
  display: block;
}
.mention {
  background: rgba(129, 140, 248, 0.15);
  color: var(--indigo);
  padding: 0.05rem 0.25rem;
  border-radius: 3px;
  font-weight: 500;
}

.mention-menu {
  position: absolute;
  z-index: 1000;
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  min-width: 160px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
}
.mention-menu[hidden] { display: none; }
.mention-menu li {
  padding: 0.4rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--text);
  cursor: pointer;
}
.mention-menu li.is-active,
.mention-menu li:hover {
  background: rgba(129, 140, 248, 0.15);
  color: var(--text);
}
.comment-compose {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.comment-compose textarea {
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.45rem 0.6rem;
  color: var(--text);
  font: inherit;
  font-size: 0.8125rem;
  min-height: 3.25rem;
  resize: vertical;
}
.comment-compose textarea:focus {
  outline: none;
  border-color: var(--indigo);
}
.comment-compose button {
  align-self: flex-end;
  background: var(--indigo);
  border: none;
  color: #fff;
  padding: 0.35rem 1rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
}

.activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.activity-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  font-size: 0.75rem;
  color: var(--muted-hi);
}
.activity-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--border);
  flex-shrink: 0;
}
.activity-body { flex: 1; }
.activity-time { color: var(--muted); font-size: 0.7rem; }

/* ── Nav pill (unread count) ─────────────────────────────── */

.nav-pill {
  margin-left: auto;
  font-size: 0.65rem;
  font-weight: 600;
  background: var(--indigo-bg);
  color: #fff;
  padding: 0.1rem 0.4rem;
  border-radius: 9999px;
  min-width: 1rem;
  text-align: center;
}

/* ── Notifications page ──────────────────────────────────── */

.notif-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 720px;
}
.notif-row {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
}
.notif-row.unread { border-color: var(--border); background: var(--elevated); }
.notif-row-form {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.55rem 0.75rem;
}
.notif-kind {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  color: var(--muted-hi);
  white-space: nowrap;
  flex-shrink: 0;
}
.notif-kind-mention { color: var(--indigo); border-color: var(--indigo); }
.notif-headline {
  flex: 1;
  text-align: left;
  background: transparent;
  border: none;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  padding: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.notif-headline:hover { color: var(--indigo); }
.notif-time { color: var(--muted); font-size: 0.7rem; flex-shrink: 0; }

/* ── Command palette ─────────────────────────────────────── */

.cmd-palette {
  width: min(620px, 92vw);
  border-radius: 12px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  margin-top: 8vh;
}
.cmd-palette::backdrop { background: rgba(0,0,0,0.55); }

#cmd-palette-input {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border-soft);
  padding: 0.875rem 1rem;
  color: var(--text);
  font: inherit;
  font-size: 0.95rem;
  outline: none;
}

#cmd-palette-results {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  max-height: 50vh;
  overflow-y: auto;
}

.palette-section {
  padding: 0.4rem 1rem 0.25rem;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  font-weight: 600;
}

.palette-row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.45rem 1rem;
  color: var(--text);
  text-decoration: none;
  font-size: 0.875rem;
}
.palette-row:hover, .palette-row:focus {
  background: var(--elevated);
}
.palette-kind {
  width: 1.25rem;
  display: inline-flex;
  justify-content: center;
  color: var(--muted);
}
.palette-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.palette-meta {
  font-size: 0.7rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.palette-empty {
  padding: 1rem;
  text-align: center;
  font-size: 0.8125rem;
}

/* ── Sidebar keyboard hint pill ──────────────────────────── */

.nav-kbd {
  margin-left: auto;
  font-size: 0.65rem;
  font-family: monospace;
  color: var(--muted);
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
}

/* ── Public form page ────────────────────────────────────── */

.public-form-card { max-width: 520px; }
.public-form input[type="text"],
.public-form input[type="number"],
.public-form input[type="date"],
.public-form textarea,
.public-form select {
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.public-form textarea { resize: vertical; min-height: 5rem; }
.public-form input:focus, .public-form textarea:focus, .public-form select:focus {
  outline: none;
  border-color: var(--indigo);
}
.public-form button[type="submit"] {
  background: var(--indigo);
  color: #fff;
  border: none;
  padding: 0.6rem 1rem;
  border-radius: 6px;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  margin-top: 0.5rem;
}

.form-intro, .form-success {
  font-size: 0.875rem;
  color: var(--muted-hi);
  line-height: 1.5;
  margin: 0 0 1.25rem;
}
.form-success { color: var(--emerald); }

/* Honeypot: visually + accessibility hidden, but submittable */
.hp {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Forms admin (binder-scoped) ─────────────────────────── */

.form-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-width: 760px;
}
.form-row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.875rem;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
}
.form-row-main { flex: 1; display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.form-row-name { font-size: 0.9rem; font-weight: 600; color: var(--text); text-decoration: none; }
.form-row-name:hover { color: var(--indigo); }
.form-row-url {
  font-family: monospace;
  font-size: 0.7rem;
  color: var(--muted);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.form-row-url:hover { color: var(--indigo); }
.form-row-archive button {
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--muted);
  padding: 0.3rem 0.65rem;
  border-radius: 6px;
  font-size: 0.75rem;
  cursor: pointer;
}
.form-row-archive button:hover { color: var(--red); border-color: var(--red); }

/* Public-link callout — a standout card above the edit form so the shareable
   URL is the first thing you spot, not buried among the Basics fields. */
.form-share {
  max-width: 960px;
  margin: 0 0 1.5rem;
  padding: 1rem 1.15rem;
  border: 1px solid color-mix(in srgb, var(--indigo) 40%, var(--border));
  border-left: 3px solid var(--indigo);
  border-radius: 12px;
  background: color-mix(in srgb, var(--indigo) 8%, transparent);
}
.form-share-head { display: flex; align-items: flex-start; gap: .6rem; margin-bottom: .8rem; }
.form-share-icon { color: var(--indigo); flex: 0 0 auto; margin-top: .1rem; }
.form-share-title { font-weight: 700; font-size: .95rem; color: var(--text); }
.form-share-sub { font-size: .82rem; color: var(--muted); margin-top: .1rem; }
.form-share-row { display: flex; gap: .5rem; align-items: stretch; flex-wrap: wrap; }
.form-share-input {
  flex: 1; min-width: 12rem;
  padding: .55rem .7rem; border-radius: 8px;
  border: 1px solid var(--border); background: var(--page-bg);
  color: var(--text); font-size: .875rem; font-family: var(--font-mono, monospace);
}
.form-share-input:focus { outline: none; border-color: var(--indigo); }
.btn-copy-link {
  display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap;
  padding: .55rem .9rem; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent; background: var(--indigo); color: #fff;
  font-size: .875rem; font-weight: 600; transition: opacity .12s, background .12s;
}
.btn-copy-link:hover { opacity: .92; }
.btn-copy-link.is-copied { background: var(--emerald); }
.btn-copy-open {
  display: inline-flex; align-items: center;
  padding: .55rem .9rem; border-radius: 8px; white-space: nowrap;
  border: 1px solid var(--border); color: var(--muted-hi);
  font-size: .875rem; font-weight: 600; text-decoration: none;
}
.btn-copy-open:hover { color: var(--text); border-color: var(--muted); }

.form-edit-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  align-items: start;
  max-width: 960px;
}
@media (max-width: 720px) {
  .form-edit-grid { grid-template-columns: 1fr; }
}
.form-edit-col {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 1rem 1.25rem;
}
.form-edit-col input[type="text"],
.form-edit-col textarea,
.form-edit-col select {
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 0.4rem 0.6rem;
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.form-edit-col textarea { resize: vertical; min-height: 4.5rem; }
.form-edit-col input:focus, .form-edit-col textarea:focus, .form-edit-col select:focus {
  outline: none;
  border-color: var(--indigo);
}

.form-pick-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px dashed var(--border-soft);
}
.form-pick-row:last-child { border-bottom: none; }
.form-pick-name { font-size: 0.8125rem; font-weight: 500; color: var(--text); }
.form-pick-meta { font-size: 0.7rem; color: var(--muted); text-transform: uppercase; }
.form-pick-req {
  font-size: 0.7rem;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.form-edit-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
  max-width: 960px;
}

/* ── Relation picker: chips + searchable dialog ──────────── */

.rel-picker {
  width: 100%;
}
.rel-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.rel-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.4rem 0.25rem 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  font-size: 0.8125rem;
}
.rel-chip-link {
  color: var(--text);
  text-decoration: none;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rel-chip-link:hover { color: var(--indigo); }
.rel-chip-x {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0 0.2rem;
  border-radius: 999px;
  font-size: 0.75rem;
}
.rel-chip-x:hover { color: var(--red); }
.rel-add-btn {
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted-hi);
  cursor: pointer;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8125rem;
}
.rel-add-btn:hover { color: var(--text); border-color: var(--muted); }

.rel-pick-dialog {
  width: min(520px, 92vw);
  border-radius: 12px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--border);
}
.rel-pick-dialog::backdrop { background: rgba(0,0,0,0.55); }
.rel-pick-search {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border-soft);
  padding: 0.75rem 1rem;
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  outline: none;
}
.rel-pick-list {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  max-height: 50vh;
  overflow-y: auto;
}
.rel-pick-list li.is-hidden { display: none; }
.rel-pick-item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  color: var(--text);
  padding: 0.5rem 1rem;
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
}
.rel-pick-item:hover, .rel-pick-item:focus { background: var(--elevated); }

.rel-pick-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 1rem;
  cursor: pointer;
  font-size: 0.875rem;
  color: var(--text);
}
.rel-pick-row:hover { background: var(--elevated); }
.rel-pick-row input[type="checkbox"] { accent-color: var(--indigo); }

.rel-pick-foot {
  display: flex;
  justify-content: flex-end;
  padding: 0.625rem 1rem;
  border-top: 1px solid var(--border-soft);
}

/* ── Inline attachments inside the card body ─────────────── */

.att-upload-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.4rem;
}
.att-upload-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.3rem 0.75rem;
  border-radius: 6px;
  font-size: 0.8125rem;
  cursor: pointer;
}
.att-upload-btn:hover { background: var(--border); }
.att-row button[form] {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.75rem;
}
.att-row button[form]:hover { color: var(--red); border-color: var(--red); }


/* ── AI chat ─────────────────────────────────────────────── */

.page-header-meta-err { color: var(--red); }

.chat-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  flex: 1;
  min-height: 0;
}

.chat-threads {
  border-right: 1px solid var(--border-soft);
  background: var(--surface);
  padding: 0.5rem 0.5rem 2rem;
  overflow-y: auto;
}
.chat-thread-item {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  color: var(--muted-hi);
  text-decoration: none;
  font-size: 0.8125rem;
  margin-bottom: 0.125rem;
}
.chat-thread-item:hover { background: var(--elevated); color: var(--text); }
.chat-thread-item.active { background: var(--elevated); color: var(--text); }
.chat-thread-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-thread-time { font-size: 0.6875rem; color: var(--muted); }

.chat-main {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0;
}

.chat-setup {
  margin: 1.5rem;
  padding: 1.25rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--amber);
  border-radius: 10px;
  color: var(--text);
  font-size: 0.875rem;
}
.chat-setup h2 { margin: 0 0 0.5rem; font-size: 1rem; }
.chat-setup p, .chat-setup ol { margin: 0.5rem 0; }
.chat-setup code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
  font-size: 0.8125rem;
}
.chat-setup-meta { color: var(--muted); font-size: 0.8125rem; }

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-height: 0;
}

.chat-empty {
  margin: auto;
  text-align: center;
  color: var(--muted);
  max-width: 28rem;
}
.chat-empty-title { color: var(--text); font-size: 1.0625rem; margin: 0 0 0.5rem; }
.chat-empty-sub { font-size: 0.875rem; line-height: 1.6; margin: 0; }
.chat-empty em {
  font-style: normal;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
}

.chat-msg {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 48rem;
}
.chat-msg-user { align-self: flex-end; align-items: flex-end; }
.chat-msg-assistant { align-self: flex-start; }

.chat-msg-role {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.chat-msg-body {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--text);
  white-space: normal;
  word-wrap: break-word;
}
.chat-msg-user .chat-msg-body {
  background: var(--indigo-bg);
  border-color: transparent;
  color: #fff;
}

/* Markdown rendered inside a chat bubble. The bubble has its own
   padding, so tighten internal block margins to keep replies compact. */
.chat-msg-body > :first-child { margin-top: 0; }
.chat-msg-body > :last-child  { margin-bottom: 0; }
.chat-msg-body p { margin: 0.5em 0; }
.chat-msg-body h1,
.chat-msg-body h2,
.chat-msg-body h3,
.chat-msg-body h4 {
  margin: 0.75em 0 0.35em;
  font-weight: 600;
  line-height: 1.3;
}
.chat-msg-body h1 { font-size: 1.125rem; }
.chat-msg-body h2 { font-size: 1.0625rem; }
.chat-msg-body h3 { font-size: 1rem; }
.chat-msg-body h4 { font-size: 0.9375rem; }
.chat-msg-body ul,
.chat-msg-body ol { margin: 0.4em 0; padding-left: 1.5rem; }
.chat-msg-body li { margin: 0.15em 0; }
.chat-msg-body li > p { margin: 0.2em 0; }
.chat-msg-body a { color: var(--indigo); text-decoration: underline; }
.chat-msg-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.875em;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 0.05em 0.35em;
}
.chat-msg-body pre {
  margin: 0.5em 0;
  padding: 0.6rem 0.8rem;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  overflow-x: auto;
}
.chat-msg-body pre code {
  background: transparent;
  border: 0;
  padding: 0;
  font-size: 0.8125rem;
}
.chat-msg-body blockquote {
  margin: 0.5em 0;
  padding: 0.1em 0.85em;
  border-left: 3px solid var(--border);
  color: var(--muted-hi);
}
.chat-msg-body hr {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: 0.75em 0;
}
.chat-msg-body table {
  border-collapse: collapse;
  margin: 0.5em 0;
  font-size: 0.875em;
}
.chat-msg-body th,
.chat-msg-body td {
  border: 1px solid var(--border-soft);
  padding: 0.35em 0.6em;
  text-align: left;
}
.chat-msg-body th { background: var(--elevated); font-weight: 500; }

/* On the user's indigo bubble, override muted-by-default colours so
   inline code / links / quotes stay readable. */
.chat-msg-user .chat-msg-body code {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.chat-msg-user .chat-msg-body a { color: #fff; }
.chat-msg-user .chat-msg-body blockquote {
  border-left-color: rgba(255, 255, 255, 0.45);
  color: rgba(255, 255, 255, 0.85);
}

/* Animated "assistant is typing" dots used in the optimistic bubble
   between Send and the server's reply landing. */
.chat-loading-dots {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.15em 0;
}
.chat-loading-dots > span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--muted-hi);
  animation: chat-typing-dot 1.2s infinite ease-in-out;
}
.chat-loading-dots > span:nth-child(2) { animation-delay: 0.18s; }
.chat-loading-dots > span:nth-child(3) { animation-delay: 0.36s; }
@keyframes chat-typing-dot {
  0%, 60%, 100% { opacity: 0.3; transform: scale(0.85); }
  30%          { opacity: 1;   transform: scale(1); }
}

/* Subtle ghosted look for the optimistic user-message bubble while the
   server is still working. Reload swaps in the real saved bubbles
   without this class. */
.chat-msg-pending.chat-msg-user .chat-msg-body { opacity: 0.85; }

.chat-cite-inline {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8125rem;
  padding: 0.05rem 0.3rem;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  color: var(--indigo);
}

.chat-msg-cites {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  font-size: 0.75rem;
}
.chat-cite-label { color: var(--muted); margin-right: 0.25rem; }
.chat-cite-chip {
  display: inline-flex;
  gap: 0.3rem;
  padding: 0.2rem 0.5rem;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  color: var(--muted-hi);
  text-decoration: none;
  font-size: 0.75rem;
}
.chat-cite-chip:hover { color: var(--text); border-color: var(--border); }

.chat-msg-confirm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.5rem;
  padding: 0.5rem 0.7rem;
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
}
.chat-confirm-label { color: var(--muted-hi); font-size: 0.8rem; }
.chat-confirm-actions { display: flex; gap: 0.4rem; margin-left: auto; }

.chat-compose {
  border-top: 1px solid var(--border-soft);
  background: var(--surface);
  padding: 0.875rem 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.chat-compose textarea {
  resize: vertical;
  min-height: 2.75rem;
  width: 100%;
  background: var(--page-bg);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  color: var(--text);
  padding: 0.6rem 0.75rem;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.45;
}
.chat-compose textarea:focus {
  outline: none;
  border-color: var(--indigo);
}
.chat-compose-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}

@media (max-width: 768px) {
  .chat-layout { grid-template-columns: 1fr; }
  .chat-threads {
    display: flex;
    gap: 0.25rem;
    overflow-x: auto;
    padding: 0.5rem;
    border-right: none;
    border-bottom: 1px solid var(--border-soft);
  }
  .chat-thread-item { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 0.4rem; }
  .chat-thread-time { display: none; }
}

/* ── View toolbar: tags (left) + kind dropdown & configure (right) ── */

/* Left side holds the tag chips; scrolls if they overflow so the right-hand
   controls stay put. */
.view-toolbar-left {
  display: flex; align-items: center; min-width: 0; flex: 1 1 auto;
  overflow-x: auto; padding-bottom: 0.4rem; scrollbar-width: none;
}
.view-toolbar-left::-webkit-scrollbar { display: none; }

/* Shared sizing for the two right-hand controls so they line up at the same
   height, with a comfortably big, easy-to-read icon. */
.view-ctl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
  height: 2.1rem; padding: 0 0.6rem; box-sizing: border-box;
  border: 1px solid var(--border-soft); border-radius: 6px;
  background: var(--elevated); color: var(--text); cursor: pointer;
  font-family: inherit;
}
.view-ctl-btn:hover { border-color: var(--border); color: var(--text); }
.view-ctl-btn svg { display: block; }
.vk-icon { display: block; }

/* View-kind switch as a segmented icon group (all four kinds side by side). */
.view-kind-group {
  display: inline-flex; align-items: stretch; flex: 0 0 auto;
  border: 1px solid var(--border-soft); border-radius: 6px;
  background: var(--elevated); overflow: hidden;
}
.view-kind-seg {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.1rem; width: 2.4rem; padding: 0;
  border: none; border-left: 1px solid var(--border-soft);
  background: transparent; color: var(--muted); cursor: pointer;
}
.view-kind-seg:first-child { border-left: none; }
.view-kind-seg:hover { color: var(--text); background: var(--surface); }
.view-kind-seg.active { color: #fff; background: var(--indigo); }
.view-kind-seg .vk-icon { display: block; }

/* View-kind dropdown (JS-toggled) — kept for the commented-out fallback. */
.view-kind-menu { position: relative; flex: 0 0 auto; }
.view-kind-caret { color: var(--muted); }
.view-kind-list {
  position: absolute; right: 0; top: calc(100% + 0.3rem); z-index: 100;
  min-width: 9.5rem; background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; padding: 0.3rem; box-shadow: 0 12px 32px rgba(0,0,0,0.35);
  display: flex; flex-direction: column; gap: 0.1rem;
}
.view-kind-list[hidden] { display: none; }
.view-kind-list form { display: block; margin: 0; }
.view-kind-item {
  display: flex; align-items: center; gap: 0.55rem; width: 100%; text-align: left;
  padding: 0.45rem 0.6rem; border: 0; border-radius: 6px; background: transparent;
  color: var(--text); font-size: 0.85rem; cursor: pointer; font-family: inherit;
}
.view-kind-item .vk-icon { flex: 0 0 auto; opacity: 0.85; }
.view-kind-item:hover { background: var(--elevated); }
.view-kind-item.active { background: var(--elevated); font-weight: 600; }

/* Floating action button for "New card" — a round, icon-only + button that
   sits where the labelled button used to (page-header, upper right). */
.fab-new-card {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.9rem; height: 2.9rem; flex: 0 0 auto;
  border: none; border-radius: 50%; cursor: pointer;
  background: var(--indigo); color: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  transition: opacity 0.12s, transform 0.08s;
}
.fab-new-card:hover { opacity: 0.9; }
.fab-new-card:active { transform: scale(0.94); }
.fab-new-card-icon { width: 26px; height: 26px; }

/* The binder's tags, shown in the toolbar in place of saved views. */
.view-toolbar-right { flex: 0 0 auto; align-items: center; gap: 0.5rem; }
.tag-strip { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: 0.75rem;
  text-decoration: none;
  color: var(--text);
  background: var(--elevated);
  border: 1px solid var(--border-soft);
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
@media (hover: hover) { .tag-chip:hover { background: var(--surface); } }
/* Colour the chip's leading dot from the tag colour class. */
.tag-chip.dot-gray::before,
.tag-chip.dot-blue::before,
.tag-chip.dot-green::before,
.tag-chip.dot-orange::before,
.tag-chip.dot-red::before,
.tag-chip.dot-purple::before,
.tag-chip.dot-pink::before {
  content: "";
  width: 0.5rem; height: 0.5rem;
  border-radius: 999px;
  flex-shrink: 0;
}
.tag-chip.dot-gray::before   { background: #9ca3af; }
.tag-chip.dot-blue::before   { background: #60a5fa; }
.tag-chip.dot-green::before  { background: #34d399; }
.tag-chip.dot-orange::before { background: #fb923c; }
.tag-chip.dot-red::before    { background: #f87171; }
.tag-chip.dot-purple::before { background: #a78bfa; }
.tag-chip.dot-pink::before   { background: #f472b6; }
.tag-chip.active { border-color: var(--text); font-weight: 600; }
.tag-chip.tag-clear { color: var(--muted); }
.tag-chip.tag-clear::before { display: none; }

/* ── Quick capture (dashboard binder list) ───────────────── */
.capture { margin: 0 0 1.5rem; }
.capture-box { position: relative; }
.capture-input {
  display: block; width: 100%; box-sizing: border-box;
  padding: 0.85rem 3.9rem 0.85rem 1rem;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); color: var(--text);
  font-family: inherit; font-size: 0.95rem; line-height: 1.5;
  resize: vertical; min-height: 3.2rem; outline: none;
  transition: border-color 0.12s;
}
.capture-input::placeholder { color: var(--muted); }
.capture-input:focus { border-color: var(--indigo); }
.capture-fab {
  position: absolute; right: 0.6rem; bottom: 0.6rem;
  width: 2.8rem; height: 2.8rem; border: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--indigo); color: #fff; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  transition: opacity 0.12s, transform 0.08s;
}
.capture-fab:hover { opacity: 0.9; }
.capture-fab:active { transform: scale(0.93); }
.capture-fab:disabled { opacity: 0.5; cursor: default; }
.capture-status { min-height: 1.2rem; margin-top: 0.4rem; padding-left: 0.15rem;
  font-size: 0.8125rem; color: var(--muted); }
.capture-status.ok { color: var(--muted-hi); }
.capture-status.ok b { color: var(--text); }
.capture-status.ok a { color: var(--indigo); }
.capture-status.err { color: var(--red); }

/* ── View switcher: segmented group (desktop) vs dropdown (mobile) ── */
/* The single-icon dropdown is mobile-only; the segmented group is the default. */
.view-kind-menu { display: none; }

@media (max-width: 768px) {
  .view-kind-group { display: none; }
  .view-kind-menu { display: block; }

  /* On a binder page the header collapses into the mobile topbar: the binder
     name shows in the topbar, the action icons + the header FAB are hidden, and
     the New Card FAB lives in the topbar instead. Two rows → one. */
  .page-header--binder { display: none; }

  .topbar-brand { min-width: 0; }
  .topbar-brand-name {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* Small round New Card button on the topbar's right. */
  .topbar-fab {
    margin-left: auto; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.6rem; height: 2.6rem; border: none; border-radius: 50%;
    background: var(--indigo); color: #fff; cursor: pointer;
  }
  /* Icon nearly fills the button so the + reads big without a big button. */
  .topbar-fab svg {
    stroke: #fff; fill: none; display: block;
    width: 26px; height: 26px; stroke-width: 2.5;
  }
  .topbar-fab:active { transform: scale(0.94); }
}
