/* ══════════════════════════════════════════════════════════════════
   BigWorkflow — design tokens and components
   Source of truth: docs/designs/style-guide.md
   ══════════════════════════════════════════════════════════════════ */

/* ── Tokens: light is the base, dark overrides ── */
:root {
  --bg:#F1F5F4; --panel:#FFFFFF; --panel2:#E8EEED;
  --rule:#D0DCD9; --rule2:#E1E9E8;
  --ink:#0E1C20; --ink2:#45605F; --ink3:#596E6D;
  --accent:#9C630A; --on-accent:#FFFFFF;
  --bug:#C4374A; --feat:#2560C4; --video:#7546C4;
  --biz:#137055; --idea:#8A5A00; --req:#0F6C7A; --task:#4A5568;
  --tint:rgba(156,99,10,.10);
  --glow-x:2px; --glow-b:0px;
  --shadow:0 1px 2px rgba(14,28,32,.06), 0 8px 24px rgba(14,28,32,.08);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#0D181C; --panel:#132329; --panel2:#182C33;
    --rule:#223D45; --rule2:#1B333A;
    --ink:#E4F0ED; --ink2:#9FB8BC; --ink3:#76969C;
    --accent:#F0A93C; --on-accent:#0D181C;
    --bug:#FF6B7A; --feat:#5B9DFF; --video:#B98CFF;
    --biz:#3FD8A0; --idea:#E8B54A; --req:#4FC9DC; --task:#9FB8BC;
    --tint:rgba(240,169,60,.15);
    --glow-x:9px; --glow-b:15px;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
  }
}
:root[data-theme="dark"] {
  --bg:#0D181C; --panel:#132329; --panel2:#182C33;
  --rule:#223D45; --rule2:#1B333A;
  --ink:#E4F0ED; --ink2:#9FB8BC; --ink3:#76969C;
  --accent:#F0A93C; --on-accent:#0D181C;
  --bug:#FF6B7A; --feat:#5B9DFF; --video:#B98CFF;
  --biz:#3FD8A0; --idea:#E8B54A; --req:#4FC9DC; --task:#9FB8BC;
  --tint:rgba(240,169,60,.15);
  --glow-x:9px; --glow-b:15px;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
}

/* ── Base ── */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; display: flex; flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, sans-serif;
  font-size: 14.5px;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1,h2,h3,dl,dd,dt,p,ol,ul { margin: 0; }
ol,ul { padding: 0; list-style: none; }
::selection { background: var(--accent); color: var(--on-accent); }
[x-cloak] { display: none !important; }

.font-display { font-family: "Familjen Grotesk", system-ui, sans-serif; }
.font-mono, .mono { font-family: "JetBrains Mono", ui-monospace, monospace; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* Available to screen readers, invisible on screen. Used wherever colour alone
   would otherwise carry the meaning — a status bar, a type rail.

   It is absolutely positioned, which means it needs a positioned ancestor or it
   escapes to the document. See .shell and .content below: without those, sixty
   of these inside a scrolling list each landed at its static position measured
   against the *document*, and the page grew 1,400px of invisible nothing to
   scroll through. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* First thing in the tab order, visible only once focused. Without it every
   keyboard user walks the entire nav before reaching the page. */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  padding: 10px 16px; border-radius: 8px;
  background: var(--panel); border: 1px solid var(--accent); color: var(--ink);
  transition: top .12s ease;
}
.skip-link:focus { top: 8px; }

.icon { display: block; flex-shrink: 0; }

/* macOS hides overlay scrollbars by default, so a long list can look like it
   simply ends. These make the bar visible while it is needed. */
* { scrollbar-width: thin; scrollbar-color: var(--ink3) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--ink3); border-radius: 6px;
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--ink2); background-clip: content-box; }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ── Shell ── */
/* position: relative is load-bearing, like the min-height: 0 below it. Every
   absolutely positioned descendant needs a containing block; without one it
   resolves against the document and drags the document's scroll height out to
   meet it. Visually-hidden text inside a long scrolling list did exactly that —
   the page scrolled into a blank region taller than the viewport. The shell is
   the backstop: it is the full viewport and it clips, so nothing inside it can
   make the page itself scroll. */
/* The shell no longer owns the viewport — the nav sits above it, so body is the
   column and the shell is what is left. */
.shell { display: flex; flex: 1; min-height: 0; overflow: hidden; position: relative; }
/* min-height: 0 is load-bearing. A flex item defaults to min-height: auto and
   will not shrink below its content, so a scrolling child grows to fit instead
   of scrolling — and .shell's overflow: hidden then clips it away with no
   scrollbar at all. The min-width: 0 beside it does the same job on the row
   axis; both are needed. */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.topbar {
  height: 60px; flex-shrink: 0; padding: 0 clamp(24px, 3vw, 44px);
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid var(--rule);
}
.content { flex: 1; overflow-y: auto; min-width: 0; min-height: 0; position: relative; }

/* The breathing room either side of a page's content. Losing the sidebar gave
   every screen 254px more width and left the tables sitting hard against the
   window edge. One class rather than thirteen inline paddings, so the gutter is
   tunable in one place — and it scales, so a narrow window keeps the space for
   content instead of spending it on margins. */
.page { padding: 24px clamp(24px, 3vw, 44px) 64px; }
.page-narrow { max-width: 560px; }
.page-wide { max-width: 720px; }
.detail {
  width: 440px; flex-shrink: 0; border-left: 1px solid var(--rule);
  background: var(--panel); overflow-y: auto; position: relative;
}
@media (max-width: 1100px) { .detail { display: none; } }

/* ── Top nav ──
   The only chrome on the page now. Across the top rather than down the side, so
   the content gets its full width back. */
.topnav {
  /* Same gutter as .page, so the brand lines up with the content below it
     rather than sitting 20px off from everything else. */
  flex-shrink: 0; height: 56px; padding: 0 clamp(24px, 3vw, 44px);
  display: flex; align-items: center; gap: 6px;
  background: var(--panel); border-bottom: 1px solid var(--rule);
}
.brand {
  display: flex; align-items: center; gap: 9px; margin-right: 18px;
  font-family: "Familjen Grotesk", system-ui, sans-serif;
  font-size: 16px; font-weight: 600; letter-spacing: -.01em; white-space: nowrap;
}
.brand .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }

.topnav-items { display: flex; align-items: center; gap: 4px; }
.topnav-right { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.topnav-item {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  padding: 7px 11px; border-radius: 6px; font-size: 14px;
  transition: background .12s ease;
}
.topnav-item:hover { background: var(--panel2); }
.topnav-item.active { background: var(--panel2); font-weight: 500; }
.topnav-item .caret { font-size: 9px; color: var(--ink3); }

/* Menus are <details>: keyboard-accessible, and open before Stimulus loads.
   menu_controller adds only what a disclosure lacks — closing on an outside
   click or Escape. */
.menu { position: relative; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 232px; max-height: 70vh; overflow-y: auto;
  padding: 5px; border-radius: 8px;
  background: var(--panel); border: 1px solid var(--rule); box-shadow: var(--shadow);
}
.menu-right { left: auto; right: 0; }
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border-radius: 5px; font-size: 13.5px; text-align: left;
  transition: background .12s ease;
}
.menu-item:hover { background: var(--panel2); }
.menu-item.active { background: var(--panel2); font-weight: 500; }
.menu-item.muted { color: var(--ink3); }
.menu-item .bar { width: 4px; height: 15px; border-radius: 2px; flex-shrink: 0; }
.menu-item .mono { margin-left: auto; }
.menu-rule { height: 1px; margin: 5px 0; background: var(--rule); }
/* The Recent menu is a list of records: type chip, title, how long ago. Wider
   than the projects menu because titles are sentences, and the title truncates
   rather than wrapping so six rows stay six rows. */
.menu-recent { min-width: 320px; }
.menu-recent .chip { font-size: 10px; letter-spacing: .1em; width: 34px; flex-shrink: 0; margin: 0; }
.menu-recent .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-recent .when { font-size: 11.5px; color: var(--ink3); flex-shrink: 0; }
.menu-label {
  padding: 8px 10px 4px; font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px; letter-spacing: .14em; color: var(--ink3);
}
/* ── Theme switch ──
   Lived in the sidebar; it lives in the user menu now, but it is the same
   segmented control and needs the same rules. */
.theme-switch { display: flex; border: 1px solid var(--rule); border-radius: 6px; padding: 2px; }
/* button_to wraps each control in its own form, so the form is the flex child. */
.theme-switch form { flex: 1; display: flex; }
.theme-switch button {
  width: 100%; flex: 1; padding: 4px 0; border-radius: 4px; font-size: 12.5px;
  text-transform: capitalize; color: var(--ink3); text-align: center;
  transition: background .12s ease;
}
.theme-switch button:hover { color: var(--ink); }
.theme-switch button[aria-pressed="true"] { background: var(--panel2); color: var(--ink); font-weight: 500; }
.menu-panel .theme-switch { margin: 0 6px 4px; }

@media (max-width: 700px) {
  .topnav { padding: 0 16px; gap: 2px; }
  .brand span:not(.dot) { display: none; }
  .topnav-right .kbd { display: none; }
}

/* ── Type-coded rail: the signature element ──
   Glows into the row on dark where light bleeds; a clean bar on light,
   because the same bleed reads as a smear on paper. */
.rail { box-shadow: inset 2px 0 0 var(--c), inset var(--glow-x) 0 var(--glow-b) -11px var(--c); }

.row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; height: 38px; padding: 0 12px;
  border-radius: 6px; text-align: left; transition: background .12s ease;
}
.row:hover { background: var(--panel2); }
.row.sel { background: var(--panel2); }
.row.sel .title { color: var(--ink); font-weight: 500; }
.row .title { flex: 1; min-width: 0; color: var(--ink2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row.rail { padding-left: 16px; }
.row .disclose { width: 12px; font-size: 11px; color: var(--ink3); flex-shrink: 0; }

/* Tree indent guide */
.children { margin-left: 20px; padding-left: 12px; border-left: 1px solid var(--rule2); }

/* ── Type chips ── */
.type-chip {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px; letter-spacing: .1em; width: 52px; flex-shrink: 0;
}
.t-bug   { color: var(--bug); }   .c-bug   { --c: var(--bug); }
.t-feat  { color: var(--feat); }  .c-feat  { --c: var(--feat); }
.t-video { color: var(--video); } .c-video { --c: var(--video); }
.t-biz   { color: var(--biz); }   .c-biz   { --c: var(--biz); }
.t-idea  { color: var(--idea); }  .c-idea  { --c: var(--idea); }
.t-req   { color: var(--req); }   .c-req   { --c: var(--req); }
.t-task  { color: var(--task); }  .c-task  { --c: var(--task); }

/* Stage is where a record is, not what it is — never coloured. */
.pill {
  font-size: 12px; padding: 2px 8px; border-radius: 999px;
  background: var(--panel2); border: 1px solid var(--rule);
  color: var(--ink2); flex-shrink: 0; white-space: nowrap;
}
.target { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 11px; color: var(--ink3); width: 44px; text-align: right; flex-shrink: 0; }
.count  { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 11px; color: var(--ink3); }

.badge-promoted {
  font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 10px;
  letter-spacing: .08em; padding: 2px 6px; border-radius: 4px;
  background: var(--tint); color: var(--accent);
}

/* ── Labels and prose ── */
.mono-label {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px; letter-spacing: .14em; color: var(--ink3); text-transform: uppercase;
}
.reading {
  font-size: 15.5px; line-height: 1.7; font-weight: 400;
  letter-spacing: .003em; color: var(--ink2); max-width: 34em;
}
.marginalia {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px; letter-spacing: .08em; color: var(--ink3); text-transform: uppercase;
}

/* ── Buttons ── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 6px; font-size: 13px;
  border: 1px solid var(--rule); transition: background .12s ease;
}
.btn:hover { background: var(--panel2); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn:disabled:hover { background: none; }
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent); filter: brightness(1.08); }
.btn-ghost { border-color: transparent; color: var(--ink3); }
.btn-ghost:hover { color: var(--ink); background: var(--panel2); }
.link { color: var(--accent); }
.link:hover { text-decoration: underline; }

.seg { display: flex; background: var(--panel); border: 1px solid var(--rule); border-radius: 6px; padding: 2px; }
/* Segments are buttons in some views and links in others — both must sit flush. */
.seg button, .seg a {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 5px 13px; border-radius: 4px; font-size: 13px;
  color: var(--ink3); white-space: nowrap;
}
.seg button:hover, .seg a:hover { color: var(--ink); }
.seg button.active, .seg a.active { background: var(--panel2); color: var(--ink); font-weight: 500; }

.kbd {
  font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 11px;
  padding: 1px 5px; border: 1px solid var(--rule); border-radius: 4px; color: var(--ink3);
}

/* ══ Tables ══
   The primary way data is shown. Gridlines and aligned columns, closer to a
   spreadsheet than a feed of cards. The outline is a table too — a tree that
   happens to have columns, the way OmniFocus does it. */
.tbl { width: 100%; border-collapse: collapse; table-layout: fixed; }
.tbl th {
  position: sticky; top: 0; z-index: 5;
  background: var(--panel); text-align: left; font-weight: 400;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink3);
  padding: 8px 12px; white-space: nowrap;
  border-bottom: 1px solid var(--rule);
}
.tbl th.sortable { cursor: pointer; user-select: none; }
.tbl th.sortable:hover { color: var(--ink); }
.tbl th .caret { color: var(--accent); }
.tbl td {
  height: 34px; padding: 0 12px; vertical-align: middle;
  border-bottom: 1px solid var(--rule2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tbl th + th, .tbl td + td { border-left: 1px solid var(--rule2); }
.tbl tbody tr:hover td { background: var(--panel2); }
.tbl tr.sel td { background: var(--panel2); }
.tbl tr.sel .name { color: var(--ink); font-weight: 500; }

/* Type-coded rail on the first cell. No glow here — inside a gridded table the
   bleed competes with the rules, so it stays a clean 3px bar in both themes.
   :first-of-type, not :first-child — Alpine leaves <template> nodes as earlier
   siblings, which breaks :first-child on rows built with x-if. */
.tbl tr.rec td:first-of-type { box-shadow: inset 3px 0 0 var(--c); }

/* Container rows read as structure, not data — the name carries the weight,
   the numbers stay regular so the columns still scan. */
.tbl tr.grp td { background: var(--bg); }
.tbl tr.grp:hover td { background: var(--panel2); }
.tbl tr.grp .name {
  font-family: "Familjen Grotesk", system-ui, sans-serif;
  font-weight: 600; color: var(--ink);
}

.tbl .name { color: var(--ink2); }
.tbl .num, .tbl .when { text-align: right; font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 12px; color: var(--ink3); }
.tbl .mid { text-align: center; }
.tbl .muted { color: var(--ink3); font-size: 13px; }
.tbl .disclose { display: inline-block; width: 14px; color: var(--ink3); font-size: 10px; }
.tbl a { display: block; }
/* ...except where a cell deliberately mixes content, e.g. a status bar sitting
   beside the name. Without this the link takes its own line and the row doubles
   in height. */
.tbl td.name a { display: inline; }

.tbl-wrap { border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; background: var(--panel); }
.tbl-wrap .tbl tr:last-child td { border-bottom: 0; }

.tbl-caption {
  display: flex; align-items: baseline; gap: 10px;
  padding: 0 2px 8px;
}

/* ── Cards, panels ── */
.card {
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: 10px; padding: 20px; transition: border-color .12s ease;
}
a.card:hover { border-color: var(--accent); }
.divide > * + * { border-top: 1px solid var(--rule2); }

.breadcrumb { font-size: 13px; color: var(--ink3); }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb .sep { margin: 0 6px; color: var(--rule); }

.page-title { font-family: "Familjen Grotesk", system-ui, sans-serif; font-size: 28px; font-weight: 600; letter-spacing: -.02em; }
.node-title { font-family: "Familjen Grotesk", system-ui, sans-serif; font-size: 16px; font-weight: 600; }
.record-title { font-family: "Familjen Grotesk", system-ui, sans-serif; font-size: 22px; font-weight: 600; letter-spacing: -.01em; line-height: 1.3; }

/* ── Stage track ── */
.track { position: relative; height: 24px; display: flex; align-items: center; }
.track .rail-bg {
  position: absolute; inset-inline: 0; height: 1px;
  background: repeating-linear-gradient(90deg, var(--rule) 0 3px, transparent 3px 7px);
}
.track .fill { position: absolute; left: 0; height: 1px; background: var(--c); }
.track .nodes { position: relative; width: 100%; display: flex; justify-content: space-between; }
.track .node { width: 8px; height: 8px; border-radius: 50%; background: var(--rule); box-shadow: 0 0 0 4px var(--panel); }
.track .node.done { background: var(--c); }
.track .node.now  { background: var(--c); transform: scale(1.5); }

/* ── Empty states: an invitation, never a reprimand ── */
/* ── Inbox selection and drag ── */
/* Rows are a surface you select on, so a shift-click must not also drag a
   text selection across three of them. */
#inbox-list .tbl tbody tr { cursor: default; user-select: none; }

/* ── The inbox inspector ──
   Its own column beside the list. Unlike the record detail pane it does not
   vanish on a narrow window — with the Sort dialog gone this is the only way to
   file without a mouse, and a keyboard path that disappears at 1100px is not a
   path. It stacks beneath the list instead. */
.inbox-detail { display: block; }
@media (max-width: 1100px) {
  .shell:has(.inbox-detail) { flex-wrap: wrap; overflow-y: auto; }
  .inbox-detail {
    display: block; width: 100%; flex: 1 0 100%;
    border-left: 0; border-top: 1px solid var(--rule);
  }
}

.inspector { padding: 20px 24px 40px; }
.inspector-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 14px; margin-bottom: 16px;
  border-bottom: 1px solid var(--rule);
}
.inspector-edit { display: flex; flex-direction: column; }
.inspector-section {
  margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--rule);
}
.inspector-section .btn + .btn, .inspector-section p + .btn { margin-top: 10px; }
.inspector-section select + label { display: block; }
/* The suggestion explains itself, and the explanation is not a caption on a
   control — it is the reason you are about to accept it. */
.inspector-reason {
  font-size: 12.5px; line-height: 1.55; color: var(--ink3);
  margin: 10px 0 14px;
}
.inspector-blank { padding: 40px 4px; color: var(--ink2); font-size: 13.5px; line-height: 1.6; }

/* Rows are a surface you select on, so a shift-click must not also drag a text
   selection across three of them. */
#inbox-list .tbl tbody tr { cursor: default; user-select: none; }

/* A table you pick a row from. The label fills its cell so the whole row is a
   hit target, and the row highlights on hover like every other table here —
   without it the only thing you can click is a 13px radio, which is how you end
   up not knowing a choice is a choice. */
.tbl.choose tbody tr { cursor: pointer; }
.tbl.choose label { display: block; padding: 10px 0; margin: -10px 0; cursor: pointer; }
.tbl.choose input[type="radio"] { accent-color: var(--accent); cursor: pointer; width: 15px; height: 15px; }
.tbl.choose tbody tr:has(input:checked) td { background: var(--tint); }
.tbl.choose tbody tr:has(input:focus-visible) td { box-shadow: inset 0 0 0 2px var(--accent); }

.empty { padding: 64px 24px; text-align: center; color: var(--ink3); }
.empty h3 { font-family: "Familjen Grotesk", system-ui, sans-serif; font-size: 17px; font-weight: 600; color: var(--ink2); margin-bottom: 6px; }

/* ── Modal ── */
.scrim {
  position: fixed; inset: 0; background: rgba(6,14,17,.55);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh; z-index: 50;
}
.modal {
  width: 100%; max-width: 560px; background: var(--panel);
  border: 1px solid var(--rule); border-radius: 12px; box-shadow: var(--shadow);
  overflow: hidden;
}
.modal-head { padding: 16px 20px; border-bottom: 1px solid var(--rule2); }
.modal-body { padding: 20px; }
.modal-foot { padding: 14px 20px; border-top: 1px solid var(--rule2); display: flex; justify-content: flex-end; gap: 8px; background: var(--bg); }

.field {
  width: 100%; padding: 10px 13px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--rule); color: var(--ink); font: inherit;
}
.field:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
.field::placeholder { color: var(--ink3); }

/* AI suggestions are always shown as proposals awaiting confirmation. */
.suggestion {
  border: 1px dashed var(--accent); background: var(--tint);
  border-radius: 8px; padding: 12px 14px;
}

/* A finished queue item stays legible but stops competing for attention.
   No strikethrough on the whole row — the stage pill already says "Done". */
.tbl tr.is-done .name { color: var(--ink3); }
.tbl tr.is-done td { opacity: .72; }

/* An inline status select: reads as a plain label, behaves as a control. */
.status-select {
  appearance: none; width: auto; min-width: 84px;
  padding: 2px 6px; margin: 0; cursor: pointer;
  background: none; border: 1px solid transparent; border-radius: 4px;
}
.status-select:hover { border-color: var(--rule); background: var(--bg); }
.status-select:focus { border-color: var(--accent); background: var(--bg); outline: none; }

/* ── Rails additions ─────────────────────────────────────────────────
   Elements the static prototype never produced: real forms, flash
   messages, validation errors. */

select.field {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink3) 50%),
                    linear-gradient(135deg, var(--ink3) 50%, transparent 50%);
  background-position: calc(100% - 16px) center, calc(100% - 11px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}
textarea.field { line-height: 1.6; resize: vertical; }

/* Toasts stack upward from one fixed rail. Positioning the messages themselves
   piled them on top of each other the moment there were two. */
#toasts {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  z-index: 100; display: flex; flex-direction: column-reverse; gap: 8px;
  align-items: center; max-width: 90vw;
}
.flash {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 18px; border-radius: 8px;
  background: var(--panel); border: 1px solid var(--rule);
  box-shadow: var(--shadow); font-size: 14px;
}
.flash.alert { border-color: var(--bug); color: var(--bug); }
.flash .undo { padding: 2px 10px; color: var(--accent); border-color: var(--rule); }
.flash .undo:hover { color: var(--accent); background: var(--tint); }

.field-errors {
  border: 1px solid var(--bug); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 16px; font-size: 13px; color: var(--bug);
}
.field-errors ul { margin-top: 4px; }
.field-errors li::before { content: "— "; }

/* An inline editable cell: reads as text until focused. */
.inline-field {
  width: 100%; background: none; border: 1px solid transparent;
  border-radius: 4px; padding: 3px 6px; margin: -3px -6px;
  color: inherit; font: inherit;
}
.inline-field:hover { border-color: var(--rule); }
.inline-field:focus { border-color: var(--accent); background: var(--bg); outline: none; }

/* Turbo's progress bar, in the accent. */
.turbo-progress-bar { background: var(--accent); height: 2px; }
