/* Macros — the house style. One accent, and it only ever means "do it" or
   "this Mac is live". The one departure: a round preview of the knob's
   screen in the editor, so the 24-character name limit is something you can
   see rather than a number you're told. */
:root {
  --color-bg:          oklch(16% 0.015 260);   /* page */
  --color-bg-raise:    oklch(21% 0.018 260);   /* inputs, raised chrome */
  --color-surface:     oklch(25% 0.02 260);    /* cards, chips */
  --color-text:        oklch(93% 0.01 260);
  --color-text-dim:    oklch(65% 0.015 260);
  --color-accent:      oklch(72% 0.18 55);     /* filament orange */
  --color-accent-deep: oklch(60% 0.19 45);     /* gradient partner */
  --color-line:        oklch(35% 0.02 260);    /* borders */

  --radius: 14px;
  --duration-fast: 150ms;
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  font-family: "Avenir Next", Avenir, "Segoe UI", system-ui, sans-serif;

  /* App-local tokens, derived from the house palette. */
  --color-text-faint: oklch(50% 0.01 260);
  --color-danger:     oklch(70% 0.19 25);
  --color-danger-line: oklch(50% 0.16 25);
  --mono: ui-monospace, "SF Mono", Menlo, monospace;
  color-scheme: dark;
}
* { box-sizing: border-box; margin: 0; }
[hidden] { display: none !important; }   /* or your own CSS silently wins */

body {
  min-height: 100svh;
  background:
    radial-gradient(oklch(48% 0.025 250 / 0.5) 1.7px, transparent 2.4px),
    radial-gradient(90rem 40rem at 50% -10%, oklch(28% 0.05 55 / 0.35), transparent 60%),
    var(--color-bg);
  background-size: 58px 58px, 100% 100%, 100% 100%;
  color: var(--color-text);
  font-size: 1rem;
  line-height: 1.4;
}
button, input, textarea { font: inherit; }
button { cursor: pointer; border: 0; background: none; color: inherit; }
button:disabled { opacity: .35; cursor: default; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
em { font-style: normal; color: var(--color-accent); }

.kicker {
  font-family: var(--mono);
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--color-accent);
}

.primary {
  font-weight: 650;
  color: oklch(15% 0.03 55);
  background: linear-gradient(180deg, var(--color-accent), var(--color-accent-deep));
  border: 0; border-radius: calc(var(--radius) - 4px);
  padding: 0.6rem 1.3rem;
  transition: filter var(--duration-fast), transform var(--duration-fast) var(--ease-out-expo);
}
.primary:hover { filter: brightness(1.08); }
.primary:active { transform: scale(0.98); }

.ghost {
  color: var(--color-text-dim);
  padding: 0.55rem 1rem;
  border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 4px);
  transition: color var(--duration-fast), border-color var(--duration-fast);
}
.ghost:hover { color: var(--color-text); border-color: var(--color-accent-deep); }
.ghost.danger:hover { color: var(--color-danger); border-color: var(--color-danger-line); }

/* ===== The door ===== */
#gate { min-height: 100svh; display: grid; place-items: center; padding: 1.5rem; }
.gate-inner { width: min(26rem, 100%); text-align: center; }
.gate-inner h1 {
  font-size: clamp(2.4rem, 1.4rem + 5vw, 3.6rem);
  letter-spacing: -0.02em; line-height: 1.02; margin: 0.5rem 0 0.3rem;
}
.gate-sub { color: var(--color-text-dim); margin-bottom: 1.4rem; }
#people { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; }
.person {
  display: grid; gap: 0.3rem; justify-items: center;
  padding: 0.8rem 1rem; min-width: 5.5rem;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  transition: border-color var(--duration-fast), transform var(--duration-fast) var(--ease-out-expo);
}
.person:hover { border-color: var(--color-accent-deep); transform: translateY(-2px); }
.person .face { font-size: 1.6rem; line-height: 1; }
.person .name { font-size: 0.85rem; color: var(--color-text-dim); }
#pinForm { margin-top: 1.2rem; display: grid; gap: 0.7rem; }
#pinInput {
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  color: var(--color-text);
  text-align: center; letter-spacing: 0.6em; font-size: 1.4rem;
  padding: 0.7rem 0.5rem 0.7rem 1.1rem;
}
#pinInput:focus { outline: 0; border-color: var(--color-accent-deep); }
.gate-actions { display: flex; gap: 0.5rem; }
.gate-actions .ghost { flex: 0 0 auto; }
.gate-actions .primary { flex: 1; }
.gate-error { margin-top: 0.8rem; color: var(--color-danger); font-size: 0.9rem; min-height: 1.2em; }

/* ===== Shell ===== */
#app {
  max-width: 44rem; margin: 0 auto;
  padding: calc(1.1rem + env(safe-area-inset-top)) 1.1rem calc(4rem + env(safe-area-inset-bottom));
}
header.bar { display: flex; align-items: center; gap: .8rem; padding: .3rem 0 1rem; flex-wrap: wrap; }
header.bar > div:first-child { flex: 1 1 12rem; min-width: 0; }
header.bar h1 { font-size: 1.5rem; letter-spacing: -.015em; line-height: 1.1; margin-top: .15rem; }
header.bar h1 span { color: var(--color-accent); }
header.bar .spacer { flex: 1; }
header.bar .statusline {
  margin: .35rem 0 0; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .04em; color: var(--color-text-dim);
}
.bar-actions { display: flex; gap: .5rem; flex: 0 0 auto; }
.icon-btn {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 4px);
  color: var(--color-text-dim);
  transition: color var(--duration-fast), border-color var(--duration-fast);
}
.icon-btn:hover { color: var(--color-text); border-color: var(--color-accent-deep); }
.icon-btn.small { width: 36px; height: 36px; border-radius: 9px; }
.icon-btn.danger:hover { color: var(--color-danger); border-color: var(--color-danger-line); }

/* ===== Blocks ===== */
.block { margin-top: 2rem; }
.block-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: .35rem; }
.block-head h2 { font-size: 1.15rem; letter-spacing: -.01em; font-weight: 650; }
.note { font-size: .88rem; line-height: 1.55; color: var(--color-text-dim); margin: 0 0 .9rem; }
.note.dim { font-size: .8rem; color: var(--color-text-faint); margin: .2rem 0 0; }
.empty { margin-top: .6rem; color: var(--color-text-dim); font-size: .93rem; line-height: 1.6; }

/* ===== The dial ===== */
.macros { list-style: none; padding: 0; display: grid; gap: .5rem; }
.macro {
  display: grid; grid-template-columns: auto auto 1fr auto; align-items: center; gap: .85rem;
  padding: .7rem .9rem .7rem .8rem;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  transition: border-color var(--duration-fast), transform var(--duration-fast) var(--ease-out-expo);
}
.macro:hover { border-color: var(--color-accent-deep); }
.macro .pos { font-family: var(--mono); font-size: .68rem; letter-spacing: .08em; color: var(--color-text-faint); }
.tile {
  width: 2.7rem; height: 2.7rem; display: grid; place-items: center;
  background: var(--color-surface); border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--color-line);
}
/* A macro's own colour, when it has one. The knob paints its screen with
   this, so the row and the editor's preview do the same rather than making
   the person imagine it. color-mix keeps it a tint of the house surface
   instead of a saturated blob; where it isn't supported the plain rule
   above simply stays. */
.tile.tinted {
  color: var(--tile-color);
  background: color-mix(in oklab, var(--tile-color) 20%, var(--color-surface));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--tile-color) 45%, var(--color-line));
}
.macro .grow { min-width: 0; display: grid; gap: .12rem; }
.macro .name { font-weight: 650; overflow-wrap: anywhere; }
.macro .summary { color: var(--color-text-dim); font-size: .9rem; overflow-wrap: anywhere; }
.macro .meta {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--color-text-faint);
}
.row-actions { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.row-actions .ghost { padding: .4rem .75rem; font-size: .85rem; }
.confirm-q { font-size: .85rem; color: var(--color-text); margin-right: .2rem; }

/* ===== Timers =====
   A shelf of rows. Each is its own form, so saving one has nothing to say
   about the others — and its colour runs down its left edge, which is the
   colour the knob will paint that timer. */
.timers { list-style: none; padding: 0; display: grid; gap: .5rem; }
.timer {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  padding: .7rem .8rem;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.timer:focus-within { border-color: var(--color-accent-deep); }
.timer.tinted { box-shadow: inset 3px 0 0 0 var(--timer-color); }
/* Not yet a row on the shelf: dashed until it is saved. */
.timer.draft { border-style: dashed; border-color: var(--color-accent-deep); }
.timer .n {
  flex: none; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .08em; color: var(--color-text-faint);
}
.timer input {
  min-width: 0;
  background: var(--color-bg); border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 6px); color: var(--color-text);
  padding: .5rem .65rem; outline: 0;
}
.timer input:focus { border-color: var(--color-accent-deep); }
.timer .t-name { flex: 2 1 7rem; }
.timer .t-min { flex: 0 1 5rem; text-align: right; font-variant-numeric: tabular-nums; }
.timer .t-wav { flex: 3 1 9rem; font-family: var(--mono); font-size: .82rem; }
.timer .unit { flex: none; font-size: .78rem; color: var(--color-text-faint); margin-left: -.2rem; }
.timer .ghost, .timer .primary { flex: none; padding: .45rem .9rem; font-size: .85rem; }
.timer .t-actions { flex: none; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
/* The swatches get the whole next line: eight circles beside four boxes
   would squeeze both. */
.timer .swatches { flex: 1 0 100%; gap: .4rem; }
.timer .swatch { width: 1.5rem; height: 1.5rem; }
.timer .swatch:hover { transform: translateY(-1px); }
.timer .field-error { flex: 1 0 100%; }

/* ===== Playlists ===== */
.playlists { list-style: none; padding: 0; display: grid; gap: .45rem; }
.playlist {
  display: flex; align-items: center; gap: .75rem;
  padding: .6rem .85rem;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 3px);
  transition: border-color var(--duration-fast);
}
.playlist:hover { border-color: var(--color-accent-deep); }
.playlist .tile { width: 2.2rem; height: 2.2rem; flex: none; color: var(--color-text-dim); }
.playlist .grow { flex: 1; min-width: 0; display: grid; gap: .1rem; }
.playlist strong { font-weight: 650; overflow-wrap: anywhere; }
.playlist .meta {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .04em;
  color: var(--color-text-faint); overflow-wrap: anywhere;
}
.playlist .meta a { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--color-line); }
.playlist .meta a:hover { color: var(--color-accent); border-bottom-color: var(--color-accent-deep); }
.block-head .count { font-family: var(--mono); font-size: .68rem; letter-spacing: .08em; }
.block-head .head-tools { display: flex; align-items: center; gap: .8rem; }
code.inline {
  font-family: var(--mono); font-size: .8em;
  background: var(--color-bg-raise); border: 1px solid var(--color-line);
  border-radius: 6px; padding: .05rem .3rem;
}

/* ===== Helpers ===== */
.inline-form { display: flex; gap: .45rem; flex-wrap: wrap; align-items: center; }
.inline-form input {
  flex: 1; min-width: 10rem;
  background: var(--color-bg-raise); border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 5px); color: var(--color-text);
  padding: .55rem .7rem; outline: 0;
}
.inline-form input:focus { border-color: var(--color-accent-deep); }
.inline-form .field-error { flex: 1 0 100%; }
.reveal {
  margin-top: .9rem; padding: .95rem 1rem;
  border: 1px solid var(--color-accent-deep); border-radius: var(--radius);
  background: var(--color-bg-raise);
  display: grid; gap: .55rem;
}
.reveal .warn { font-size: .9rem; line-height: 1.5; }
.reveal .row { display: flex; gap: .5rem; align-items: stretch; }
.reveal code {
  flex: 1; min-width: 0; display: block;
  font-family: var(--mono); font-size: .8rem; line-height: 1.5;
  background: var(--color-bg); border: 1px solid var(--color-line);
  border-radius: 8px; padding: .5rem .65rem;
  overflow-wrap: anywhere; user-select: all;
}
.reveal .ghost { flex: none; align-self: center; }
.keys { list-style: none; padding: 0; margin-top: .9rem; display: grid; gap: .4rem; }
.key-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .6rem .85rem;
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 3px);
}
.key-row .grow { flex: 1; min-width: 0; display: grid; gap: .1rem; }
.key-row strong { font-weight: 650; overflow-wrap: anywhere; }
.key-row .meta { font-family: var(--mono); font-size: .66rem; letter-spacing: .05em; color: var(--color-text-dim); }
.dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--color-line); flex: none; }
.dot.live { background: var(--color-accent); box-shadow: 0 0 0 3px oklch(72% 0.18 55 / .22); }

/* ===== Sheet ===== */
.sheet-wrap {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; padding: 1.2rem;
  background: oklch(8% 0.01 260 / .68); backdrop-filter: blur(3px);
  overflow-y: auto;
}
.sheet {
  width: min(24rem, 100%);
  background: var(--color-bg-raise);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 1.2rem 1.2rem 1rem;
  display: grid; gap: .9rem;
  box-shadow: 0 18px 50px oklch(0% 0 0 / .45);
}
.sheet.wide { width: min(37rem, 100%); }
.sheet-title { font-weight: 650; font-size: 1.05rem; }
.sheet-actions { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .2rem; }

.editor-top { display: flex; gap: 1.1rem; align-items: center; }
.knob-preview {
  flex: none; width: 7.5rem; height: 7.5rem; border-radius: 50%;
  display: grid; place-content: center; justify-items: center; gap: .35rem;
  padding: .9rem; text-align: center;
  background: radial-gradient(circle at 50% 38%, var(--color-surface), var(--color-bg) 85%);
  box-shadow: inset 0 0 0 5px var(--color-bg-raise), inset 0 0 0 6px var(--color-line),
              0 10px 30px oklch(0% 0 0 / .4);
}
.knob-preview .pname {
  font-size: .78rem; font-weight: 650; line-height: 1.2;
  max-width: 5.6rem; overflow-wrap: anywhere;
}
/* The preview is the only place the chosen colour can be judged, because it
   is the only thing on the page shaped like the screen it lands on. */
.knob-preview.tinted {
  color: var(--knob-color);
  background: radial-gradient(circle at 50% 38%,
    color-mix(in oklab, var(--knob-color) 26%, var(--color-surface)),
    var(--color-bg) 85%);
}
.knob-preview.tinted .pname { color: var(--color-text); }

.field { display: grid; gap: .4rem; border: 0; padding: 0; min-width: 0; }
.field.grow { flex: 1; }
.label {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-text-dim); display: flex; justify-content: space-between; gap: .5rem;
}
.count { color: var(--color-text-faint); letter-spacing: .04em; }
.field > input, .step input, .step textarea {
  width: 100%; background: var(--color-bg); border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 6px); color: var(--color-text);
  padding: .55rem .7rem; outline: 0;
}
.field > input:focus, .step input:focus, .step textarea:focus { border-color: var(--color-accent-deep); }
.field-error, .form-error { color: var(--color-danger); font-size: .85rem; line-height: 1.35; min-height: 1.15em; }
.form-error:empty { display: none; }
.invalid > input, .invalid > textarea { border-color: var(--color-danger-line); }

.icon-grid { display: flex; flex-wrap: wrap; gap: .4rem; }
.icon-chip {
  position: relative;
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .8rem; color: var(--color-text-dim);
  border: 1px solid var(--color-line); border-radius: 999px;
  padding: .35rem .75rem .35rem .6rem; min-height: 34px;
  cursor: pointer; white-space: nowrap;
  transition: color var(--duration-fast), border-color var(--duration-fast);
}
.icon-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.icon-chip:hover { color: var(--color-text); }
.icon-chip:has(input:checked) { color: var(--color-text); border-color: var(--color-accent-deep); background: var(--color-surface); }
.icon-chip:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* Swatches, not a hex box: eight that look right on the knob's glass, plus
   "leave it alone", which is the honest default. */
.swatches { display: flex; flex-wrap: wrap; gap: .5rem; }
.swatch {
  position: relative; flex: none;
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  background: var(--sw);
  box-shadow: inset 0 0 0 1px oklch(100% 0 0 / .16);
  cursor: pointer;
  transition: transform var(--duration-fast) var(--ease-out-expo),
              box-shadow var(--duration-fast);
}
.swatch input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.swatch:hover { transform: translateY(-2px); }
.swatch.none {
  background:
    linear-gradient(135deg, transparent 45%, var(--color-text-faint) 45% 55%, transparent 55%),
    var(--color-bg);
  box-shadow: inset 0 0 0 1px var(--color-line);
}
.swatch:has(input:checked) {
  box-shadow: inset 0 0 0 1px oklch(100% 0 0 / .3),
              0 0 0 2px var(--color-bg-raise),
              0 0 0 4px var(--sw, var(--color-text-dim));
}
.swatch.none:has(input:checked) {
  box-shadow: inset 0 0 0 1px var(--color-line),
              0 0 0 2px var(--color-bg-raise),
              0 0 0 4px var(--color-text-dim);
}
.swatch:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 4px; }

.step-list { list-style: none; padding: 0; display: grid; gap: .5rem; }
.step {
  display: grid; gap: .45rem;
  padding: .6rem .7rem .7rem;
  background: var(--color-bg); border: 1px solid var(--color-line);
  border-radius: calc(var(--radius) - 4px);
}
.step input, .step textarea { background: var(--color-bg-raise); }
.step-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.step-kind { font-size: .88rem; font-weight: 650; display: inline-flex; align-items: center; gap: .55rem; }
.step-kind .n { font-family: var(--mono); font-size: .68rem; letter-spacing: .08em; color: var(--color-accent); }
.step-tools { display: flex; gap: .25rem; }
.step textarea { resize: vertical; min-height: 4.6rem; font-family: var(--mono); font-size: .82rem; line-height: 1.5; }
.step .hint { font-size: .78rem; color: var(--color-text-faint); }
.add-steps { display: flex; gap: .4rem; flex-wrap: wrap; }
.add-steps .ghost { border-style: dashed; }
.add-steps .ghost:hover { border-style: solid; }

#toast {
  position: fixed; bottom: calc(1.2rem + env(safe-area-inset-bottom));
  left: 50%; transform: translateX(-50%); z-index: 90;
  background: var(--color-surface); border: 1px solid var(--color-line);
  border-radius: 999px; padding: .55rem 1.2rem; font-size: .92rem;
  box-shadow: 0 8px 26px oklch(0% 0 0 / .4);
}

/* ===== Phones ===== */
@media (max-width: 760px) {
  header.bar { gap: .5rem; padding-bottom: .8rem; }
  header.bar .spacer { display: none; }
  /* Its own full-width row — never crammed beside the title. */
  .bar-actions { flex: 1 0 100%; justify-content: flex-end; }
  .macro { grid-template-columns: auto 1fr; gap: .7rem .8rem; padding: .75rem .8rem; }
  .macro .pos { display: none; }
  .row-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .row-actions .ghost, .icon-btn.small { min-height: 40px; min-width: 40px; }
  .ghost, .primary { min-height: 40px; }
  .sheet-wrap { padding: .6rem; align-items: start; }
  .sheet { padding: 1rem .9rem .9rem; }
  .editor-top { flex-direction: column; align-items: stretch; }
  .knob-preview { justify-self: center; margin: 0 auto; }
  .icon-chip { min-height: 40px; }
  .swatch { width: 2.6rem; height: 2.6rem; }
  .timer input, .timer .ghost, .timer .primary { min-height: 40px; }
  .timer .t-name { flex: 1 1 100%; }
  .timer .t-min { flex: 0 1 4.5rem; }
  .timer .t-wav { flex: 1 1 7rem; }
  /* Its own row, like the playlist's: save, delete and a confirm never fit
     beside the boxes on a phone. */
  .timer .t-actions { flex: 1 0 100%; justify-content: flex-end; }
  /* The same finger-sized swatch as the macro editor's, wrapping onto a
     second line rather than shrinking below a touch target. */
  .timer .swatch { width: 2.6rem; height: 2.6rem; }
  /* A link box squeezed to half a phone line shows about eight characters
     of the thing you just pasted. Give each box the width. */
  #playlistForm input { flex: 1 0 100%; }
  /* Its own row: the row's four controls never fit beside its name. */
  .playlist { flex-wrap: wrap; }
  .playlist .row-actions { flex: 1 0 100%; justify-content: flex-start; }
  .reveal .row { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------- agents ---------- */
.agents { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem .9rem; }
.agent-row { margin: 0; }
.agent-label { display: inline-flex; align-items: center; gap: .5rem; padding: .45rem .8rem; border: 1px solid var(--color-line, rgba(0,0,0,.14)); border-radius: 999px; cursor: pointer; font-size: .92rem; }
.agent-label:has(input:checked) { border-color: var(--color-accent, #d0552a); background: color-mix(in oklab, var(--color-accent, #d0552a) 12%, transparent); }
.agent-label input { accent-color: var(--color-accent, #d0552a); }
.agent-label:has(input:disabled) { cursor: default; opacity: .7; }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: .25rem; flex-wrap: wrap; margin: .2rem 0 1.4rem; border-bottom: 1px solid var(--color-line); }
.tabs .tab {
  appearance: none; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: .95rem; color: var(--color-text-dim);
  padding: .55rem .85rem; border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .15s ease, border-color .15s ease;
}
.tabs .tab:hover { color: var(--color-text); }
.tabs .tab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; border-radius: 4px 4px 0 0; }
.tabs .tab.on { color: var(--color-text); border-bottom-color: var(--color-accent); font-weight: 600; }
.block[id^="panel-"] { margin-top: 0; }

/* ---------- tasks ---------- */
.tasks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.task {
  --task-color: var(--color-line);
  display: grid; align-items: center; gap: .55rem;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  padding: .6rem .8rem; border: 1px solid var(--color-line); border-radius: 12px;
  background: var(--color-bg-raise);
  border-left: 3px solid var(--task-color);
}
.task.draft { border-style: dashed; }
.task.done .k-text { text-decoration: line-through; opacity: .55; }
.task .k-text {
  /* Pinned to column 2. A draft row has no checkbox and no hours, so without this the text field falls
     into the narrow `auto` column meant for the checkbox — making the box you type a NEW task into the
     narrowest field on the list. */
  grid-column: 2;
  background: none; border: 0; color: inherit; font: inherit; font-size: 1rem;
  min-width: 0; padding: .2rem 0;
}
.task .t-actions { grid-column: 4; }
.task.draft .t-actions { grid-column: 3 / -1; justify-self: end; }
.task .k-text:focus-visible { outline: 0; box-shadow: 0 2px 0 var(--color-accent); }
.task .k-hours { font-family: var(--mono); font-size: .72rem; color: var(--color-text-dim); white-space: nowrap; }
.task .k-hours strong { color: var(--color-text); font-weight: 600; }
.task .k-done { accent-color: var(--task-color); width: 1.05rem; height: 1.05rem; }
.task .swatches { grid-column: 1 / -1; }
.task .field-error { grid-column: 1 / -1; }
.task .running { position: relative; }
.task .running::before {
  content: ""; display: inline-block; width: .5rem; height: .5rem; margin-right: .4rem;
  border-radius: 50%; background: currentColor; animation: clock-tick 1.6s ease-in-out infinite;
}
@keyframes clock-tick { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .task .running::before { animation: none; } }

@media (max-width: 30rem) {
  .task { grid-template-columns: auto minmax(0, 1fr); }
  .task .k-text { grid-column: 2; }
  .task .k-hours, .task .t-actions, .task.draft .t-actions { grid-column: 1 / -1; justify-self: start; }
}
