/* ============================================================
   Studio page: the productivity dashboard.
   Loads on top of css/base.css, which owns the tokens, the reset,
   the hero and the 2-pane shell. Everything here is specific to
   this page: the client sidebar, the view tabs, and the panels
   each view draws.
   ============================================================ */

#appView {
  height: 100vh; width: 100%;
  display: flex; flex-direction: column;
  background: var(--paper-app);
  overflow: hidden; position: relative;
}

/* ---- The desktop-only notice (windows under 960px) ---- */
.desktop-only-card { text-align: center; }
.desktop-only-glyph {
  display: block; font-size: 30px; line-height: 1;
  color: var(--cobalt-pale-2); margin-bottom: 14px;
}
.desktop-only-card p + p { margin-top: 10px; }
.desktop-only-alt { color: var(--text-muted); font-size: 13px; }

.main-pane {
  background: var(--paper-body);
  opacity: 0; animation: fadeUp 0.5s ease 0.1s forwards;
}
.sheet {
  max-width: 1180px; margin: 0 auto; width: 100%;
  padding: 22px 32px 80px;
}

/* ---- View tabs: Dashboard / Projects / Calendar ---- */
.view-tabs {
  display: flex; gap: 4px; align-items: center;
  border-bottom: 1px solid var(--divider);
  margin-bottom: 22px;
}
/* With only one view built there is nothing to switch between, so the
   strip renders empty — don't leave its border behind as a stray rule. */
.view-tabs:empty { display: none; }
.view-tab {
  position: relative;
  padding: 9px 15px 12px;
  font-size: 13.5px; font-weight: 500; color: var(--text-secondary);
  border-radius: 0;
}
.view-tab:hover { color: var(--ink-body); background: rgba(35,51,221,0.04); }
.view-tab.is-active { color: var(--cobalt-hover); font-weight: 600; }
/* The active tab's cobalt underline sits on top of the row's own border. */
.view-tab.is-active::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px;
  height: 2px; background: var(--cobalt); border-radius: 0;
}

/* ---- Client rows in the sidebar ---- */
.client-group-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--text-muted-2);
  padding: 12px 6px 5px;
}
.client-row {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 8px; border-radius: 0; text-align: left;
  font-family: var(--font-ui); margin-bottom: 1px;
  background: transparent; transition: background 0.12s ease;
}
.client-row:hover { background: rgba(35,51,221,0.06); }
.client-row.is-active { background: rgba(35,51,221,0.10); }
.client-row .client-glyph { font-size: 14px; line-height: 1; color: var(--cobalt-pale-2); flex: none; }
.client-row.is-active .client-glyph { color: var(--cobalt); }
.client-row .client-name {
  flex: 1; font-size: 13.5px; font-weight: 500; color: #3E4459;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.client-row.is-active .client-name { color: var(--cobalt-hover); font-weight: 600; }
.client-row .client-count {
  font-size: 11.5px; color: var(--text-muted-2);
  font-variant-numeric: tabular-nums; flex: none;
}

/* ---- Panel: the common card every view builds inside ---- */
.panel {
  background: var(--paper-editor); border: 1px solid var(--divider);
  border-radius: 0; padding: 20px 22px; margin-bottom: 18px;
}
.panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.panel-title {
  font-family: var(--font-serif); font-size: 19px; font-weight: 500;
  color: var(--ink-heading);
}
.panel-sub { font-size: 12.5px; color: var(--text-muted); }

/* An editable heading: reads as text, becomes an input on click. */
.editable-title {
  font-family: var(--font-serif); font-size: 24px; font-weight: 500;
  color: var(--ink-heading); padding: 3px 7px; margin-left: -7px;
  border: 1px solid transparent; border-radius: 0; cursor: text;
}
.editable-title:hover { border-color: var(--divider); }
input.editable-title { background: rgba(255,255,255,0.72); }

.type-badge {
  display: inline-block; padding: 3px 9px; border-radius: 0;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase;
}
.type-badge.is-freelance { background: rgba(35,51,221,0.10); color: var(--cobalt-hover); }
.type-badge.is-personal { background: var(--done-wash); color: var(--done-ink); }

.client-head-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 6px;
}
/* Pushes the destructive action to the far end, away from the name you
   are probably clicking to rename. */
.head-spacer { flex: 1; }
.client-meta { font-size: 13px; color: var(--text-secondary); line-height: 1.6; }

/* ---- Click-to-edit text (js/dom.js inlineEdit) ---- */
.inline-edit { display: inline-flex; min-width: 0; }
.inline-edit .is-placeholder { color: var(--text-muted); }

/* ---- Every-client list, shown when no single client is focused ----
   A fixed 4-column grid (Name / Type / Hourly rate / Projects) so every
   row lines up, the same structural fix commitment-head/-columns-head
   already established for Regular work — a name of any length can only
   ever grow or shrink its own column, never nudge the others out of
   line with the row above or below it. */
.client-list-columns-head, .client-list-row {
  display: grid;
  grid-template-columns: minmax(160px, 1fr) 110px 100px 150px;
  align-items: center; gap: 14px;
}
.client-list-columns-head {
  padding: 0 12px 8px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-muted-2);
}
.client-list-columns-head .is-numeric { text-align: right; }

.client-list-row {
  width: 100%; padding: 11px 12px; border-radius: 0; text-align: left;
  border-bottom: 1px solid var(--divider);
}
.client-list-row:last-child { border-bottom: none; }
.client-list-row:hover { background: rgba(35,51,221,0.05); }
.client-list-name {
  min-width: 0; text-align: left;
  font-size: 14.5px; font-weight: 500; color: var(--ink-title);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.client-list-name:hover { color: var(--cobalt-hover); }
.client-list-meta {
  font-size: 12px; color: var(--text-muted); white-space: nowrap;
  font-variant-numeric: tabular-nums; text-align: right;
}

/* ---- Hourly Payment cell in the client list — freelance clients get
   a small always-visible number input (matches .hours-input/.budget-input
   elsewhere), personal clients get a plain dash since they never bill. */
.hourly-rate-cell {
  display: flex; align-items: baseline; justify-content: flex-end; gap: 3px;
}
.hourly-rate-input {
  width: 56px; text-align: right; font-variant-numeric: tabular-nums;
  padding: 4px 6px; font-size: 13px;
}
.hourly-rate-unit { font-size: 11px; color: var(--text-muted); }
.client-hourly-rate-empty {
  font-size: 13.5px; color: var(--text-muted-2); text-align: right;
}

/* ---- Labelled field (js/dom.js field) ---- */
.field { display: flex; flex-direction: column; gap: 4px; }
.field-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted-2);
}

/* ============================================================
   Projects and milestones
   ============================================================ */

.add-project input[name="name"] { flex: 1 1 240px; }
.date-input { width: 148px; }
.status-select { width: 110px; }

.project-card {
  background: var(--paper-editor); border: 1px solid var(--divider);
  border-radius: 0; padding: 18px 20px; margin-bottom: 16px;
  /* A cobalt spine marks a live project, echoing the group headers on
     the shared board. Quieter states get a quieter spine. */
  border-left: 3px solid var(--cobalt);
}
.project-card.is-on_hold { border-left-color: var(--text-muted-2); }
.project-card.is-done { border-left-color: var(--done-ink); background: var(--paper-vault); }

.project-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.project-name {
  font-family: var(--font-serif); font-size: 20px; font-weight: 500;
  color: var(--ink-heading); padding: 2px 6px; margin-left: -6px;
  border: 1px solid transparent; border-radius: 0; cursor: text;
}
.project-name:hover { border-color: var(--divider); }
input.project-name { background: rgba(255,255,255,0.72); }
.project-card.is-done .project-name { color: var(--done-ink); }

.project-timeline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--text-secondary); margin-bottom: 14px;
}
/* With no milestones there is nothing to say here, so the row collapses
   instead of leaving a gap. */
.project-timeline:empty { display: none; }
/* One shared treatment for "this date has passed", wherever it appears. */
.timeline-next.is-overdue, .milestone-when.is-overdue {
  color: var(--over-ink); font-weight: 600;
}
.milestone-when.is-undated { color: var(--text-muted); font-style: italic; }
/* An overdue end date is flagged on the input itself, the same way the
   shared task board flags a passed deadline. */
.date-input.is-overdue { color: var(--over-ink); font-weight: 600; border-color: rgba(176,80,63,0.4); }
.timeline-next {
  padding: 2px 9px; border-radius: 0;
  background: rgba(35,51,221,0.07); color: var(--cobalt-hover); font-weight: 500;
}

.project-dates { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }

/* ---- Milestone list inside a project ---- */
.milestone-block {
  border-top: 1px solid var(--divider); padding-top: 13px;
}
.milestone-heading {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px;
}
.milestone-progress { font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* Milestone rows and the add-row below them share one column template —
   a strict table grid, minus the drawn lines — so Done, the date and
   Delete always land in the same place whether or not a cell has
   content. Empty grid cells still reserve their column's width. */
.milestone-row,
.add-milestone {
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) 96px 148px 72px;
  column-gap: 10px; align-items: center;
}
.milestone-row { padding: 6px 0; border-bottom: 1px solid var(--divider); }
.milestone-row:last-of-type { border-bottom: none; }
.add-milestone { margin-top: 10px; }

.milestone-row .done-button { grid-column: 1; }
.milestone-name {
  font-size: 13.5px; font-weight: 500; color: var(--ink-body-2);
  padding: 3px 6px; border: 1px solid transparent; border-radius: 0; cursor: text;
}
.milestone-name:hover { border-color: var(--divider); }
input.milestone-name { background: rgba(255,255,255,0.72); }
.milestone-row .inline-edit { grid-column: 2; min-width: 0; }
.milestone-row.is-done .milestone-name { color: var(--done-ink); text-decoration: line-through; }
.milestone-when {
  grid-column: 3;
  font-size: 12px; color: var(--text-secondary); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.milestone-row.is-done .milestone-when { color: var(--done-ink); }
.milestone-row .date-input { grid-column: 4; }
.milestone-row .delete-button { grid-column: -2 / -1; }

.add-milestone-name { grid-column: 2; min-width: 0; }
.add-milestone .quiet-button { grid-column: -2 / -1; }

/* ============================================================
   Tasks — the rows that carry the hours
   ============================================================ */

.task-block { border-top: 1px solid var(--divider); padding-top: 13px; margin-top: 16px; }
.task-heading { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.task-summary {
  font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums;
}

.task-row { padding: 7px 0; border-bottom: 1px solid var(--divider); }
.task-row:last-of-type { border-bottom: none; }

/* Task rows and the add-row below them share one column template — a
   strict table grid, minus the drawn lines — so Done, the hours, the
   date and Delete always land in the same place whether or not a cell
   has content. Empty grid cells still reserve their column's width.
   Project tasks gain an extra milestone column that personal-client
   tasks never render, so that variant gets its own template. */
.task-main,
.add-task {
  display: grid;
  grid-template-columns: 16px 60px minmax(0, 1fr) 96px 74px 148px 72px;
  column-gap: 10px; align-items: center;
}
.task-block.has-milestones .task-main,
.task-block.has-milestones .add-task {
  grid-template-columns: 16px 60px minmax(0, 1fr) 96px 74px 148px 158px 72px;
}
.add-task { margin-top: 10px; }

.task-row .done-button { grid-column: 2; }

/* Bulk-select checkbox: the only checkbox left on the row now that Done
   is a button, so it can afford to be quiet — hidden at rest and revealed
   by hover, keyboard focus, or once anything on the block is selected. */
input.task-select {
  grid-column: 1;
  width: 13px; height: 13px;
  opacity: 0; transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}
.task-select:hover, .task-select:focus-visible, .task-select:checked { opacity: 1; }
.task-row:hover .task-select, .task-row:focus-within .task-select { opacity: 1; }
.task-block.has-selection .task-select { opacity: 1; }

.task-row.is-selected { background: rgba(35,51,221,0.05); border-radius: 0; }
input.task-select-all {
  width: 13px; height: 13px; flex: none; margin-left: auto;
  opacity: 0.55; transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}
.task-select-all:hover, .task-select-all:focus-visible,
.task-select-all:checked, .task-select-all:indeterminate { opacity: 1; }

.task-main .inline-edit { grid-column: 3; min-width: 0; }
.task-title {
  font-size: 13.5px; font-weight: 500; color: var(--ink-body-2);
  padding: 3px 6px; border: 1px solid transparent; border-radius: 0; cursor: text;
  display: block; width: 100%;
}
.task-title:hover { border-color: var(--divider); }
input.task-title { background: rgba(255,255,255,0.72); }
.task-row.is-done .task-title { color: var(--done-ink); text-decoration: line-through; }

.task-when {
  grid-column: 4;
  font-size: 12px; color: var(--text-secondary); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.task-when.is-overdue { color: var(--over-ink); font-weight: 600; }
.task-when.is-undated { color: var(--text-muted); font-style: italic; }
.task-row.is-done .task-when { color: var(--done-ink); }

/* Right-aligned so a column of estimates reads as numbers. */
.hours-input {
  grid-column: 5; text-align: right;
  font-variant-numeric: tabular-nums;
}

.task-main .date-input,
.add-task .date-input { grid-column: 6; }

/* Wide enough that a two-word milestone name is not clipped mid-word. */
.milestone-select { grid-column: 7; }

.task-row .delete-button { grid-column: -2 / -1; }
.add-task .quiet-button { grid-column: -2 / -1; }

/* The notes line is indented to sit under the title, past the checkbox. */
.task-row > .inline-edit { display: block; margin-left: 26px; }
.task-notes {
  display: block; width: 100%;
  font-size: 12.5px; line-height: 1.5; color: var(--text-secondary);
  padding: 2px 6px; border: 1px solid transparent; border-radius: 0;
  cursor: text; white-space: pre-wrap; word-break: break-word;
}
.task-notes:hover { border-color: var(--divider); }
.task-notes.is-placeholder { color: var(--text-muted-2); }
textarea.task-notes { background: rgba(255,255,255,0.72); resize: vertical; }
/* An empty note should not shout for attention on every row. */
.task-row:not(:hover) .task-notes.is-placeholder { opacity: 0; }
.task-row:focus-within .task-notes.is-placeholder { opacity: 1; }

.add-task-title { grid-column: 3; min-width: 0; }

/* ============================================================
   Projected revenue — a hero figure plus the same table shape
   the Capacity view uses (.capacity-table, .table-number, etc.,
   reused as-is below rather than duplicated).
   ============================================================ */
.revenue-hero {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 18px;
}
.revenue-hero-value {
  font-family: var(--font-ui); font-size: 34px; font-weight: 600;
  letter-spacing: -0.5px; color: var(--ink-heading);
  font-variant-numeric: tabular-nums;
}
.revenue-hero-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted);
}

/* ---- The per-client row's disclosure toggle, and the per-project
   breakdown it reveals — reuses .commitment-toggle's bare rotating
   chevron rather than a new control, and a plain hidden attribute
   rather than commitment-detail's max-height animation, since a
   <tr> cannot animate height the way a block-level card can. */
.revenue-client-cell { display: flex; align-items: center; gap: 6px; }
.revenue-detail-row td {
  padding: 2px 10px 12px 34px; border-bottom: 1px solid var(--divider);
}
.revenue-project-row {
  display: grid; grid-template-columns: 1fr 90px 90px 90px; gap: 0 10px;
  padding: 5px 0; font-size: 12.5px; color: var(--text-secondary);
}
.revenue-project-row .is-numeric {
  text-align: right; font-variant-numeric: tabular-nums;
}
.revenue-project-empty {
  font-size: 12.5px; color: var(--text-muted); font-style: italic; padding: 6px 0;
}

/* ============================================================
   Capacity dashboard — the ring, its table twin, and the
   weekday budget editor.
   ============================================================ */

/* One filter row above everything it scopes, never inside the card. */
.filter-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px;
}
.period-group { display: flex; gap: 3px; }
.period-button {
  padding: 6px 13px; border-radius: 0;
  font-size: 12.5px; font-weight: 500; color: var(--text-secondary);
  border: 1px solid transparent;
}
.period-button:hover { background: rgba(35,51,221,0.06); color: var(--ink-body); }
.period-button.is-active {
  background: rgba(35,51,221,0.10); color: var(--cobalt-hover);
  font-weight: 600; border-color: rgba(35,51,221,0.18);
}

.capacity-layout {
  display: flex; align-items: center; gap: 40px; flex-wrap: wrap;
}

/* ---- The ring ---- */
.ring-figure { position: relative; flex: none; width: 220px; height: 220px; }
.doughnut { display: block; width: 220px; height: 220px; }
.ring-centre {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  pointer-events: none; text-align: center;
}
/* The hero figure stays in the UI sans, with proportional figures —
   tabular digits make a large number look loose. */
.ring-value {
  font-family: var(--font-ui); font-size: 40px; font-weight: 600;
  line-height: 1; letter-spacing: -1px; color: var(--ink-heading);
}
.ring-value.is-over { color: var(--over-ink); }
.ring-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-muted); margin-top: 6px;
}

/* ---- The table twin, which doubles as the legend ---- */
.capacity-table { flex: 1 1 320px; min-width: 300px; border-collapse: collapse; }
.capacity-table th {
  text-align: left; font-size: 10.5px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted-2); font-weight: 600;
  padding: 0 10px 7px; border-bottom: 1px solid var(--divider);
}
.capacity-table td {
  padding: 8px 10px; border-bottom: 1px solid var(--divider);
  font-size: 13.5px; color: var(--ink-body-2);
}
.capacity-table tbody tr:last-child td { border-bottom: none; }
.capacity-table th:nth-child(3), .capacity-table th:nth-child(4) { text-align: right; }
.capacity-table th.is-numeric { text-align: right; }
/* Numbers in a column align, so here tabular figures are right. */
.table-number { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-label { font-weight: 500; }
.swatch-cell { width: 26px; padding-right: 0; }
.swatch {
  display: block; width: 12px; height: 12px; border-radius: 0;
}
/* The free swatch mirrors its ring segment: the same blue gradation with
   the gaura over it, so legend and chart read as one thing. The gradient
   is layered under the image in the same background shorthand. */
.swatch.is-free {
  background-image: var(--gaura-bloom), linear-gradient(135deg, #CBD3F2, #8E99EA);
  background-size: cover, cover;
  background-position: center, center;
}
.table-empty {
  color: var(--text-muted); font-family: var(--font-serif); font-style: italic;
}

/* ---- The stated caveats ---- */
.capacity-notes { margin-top: 16px; display: flex; flex-direction: column; gap: 7px; }
.capacity-note { font-size: 12px; color: var(--text-muted); line-height: 1.55; }
/* Status never rests on colour alone — glyph plus a full sentence. */
.capacity-alert {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px 12px; border-radius: 0;
  background: rgba(176,80,63,0.07); border: 1px solid rgba(176,80,63,0.22);
  font-size: 12.5px; line-height: 1.5; color: var(--over-ink); font-weight: 500;
}
.alert-glyph { font-size: 11px; line-height: 1.4; flex: none; }

/* ---- The weekday pattern editor ---- */
.budget-grid { display: flex; gap: 10px; flex-wrap: wrap; }
.budget-day { display: flex; flex-direction: column; gap: 5px; }
.budget-day-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted-2);
}
.budget-input {
  width: 68px; text-align: right; font-variant-numeric: tabular-nums;
}
.budget-total {
  margin-top: 13px; font-size: 12.5px; color: var(--text-secondary); font-weight: 600;
}

/* ---- Time Allocation: the forward availability strip ---- */
.avail-headline {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.avail-headline-main {
  font-family: var(--font-serif); font-size: 19px; font-weight: 500;
  color: var(--ink-heading);
}
.avail-headline-detail { font-size: 12.5px; color: var(--text-secondary); }
.avail-headline.is-full { font-size: 14px; color: var(--over-ink); font-weight: 500; }

/* ---- The month switcher: prev / label / next, plus a "Today" jump
   that only shows once you have browsed away from the current month. */
.avail-nav {
  display: flex; align-items: center; gap: 4px; margin-bottom: 14px;
}
.avail-nav-btn {
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 0;
  font-size: 15px; line-height: 1; color: var(--text-secondary);
  border: 1px solid transparent;
}
.avail-nav-btn:hover { background: rgba(35,51,221,0.06); color: var(--cobalt-hover); }
.avail-nav-label {
  min-width: 132px; text-align: center;
  font-size: 13.5px; font-weight: 600; color: var(--ink-body-2);
}
.avail-nav-today { margin-left: 6px; padding: 4px 10px; }

.avail-grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px;
}
.avail-head {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted-2);
  padding-bottom: 2px;
}

.avail-cell {
  display: flex; flex-direction: column; gap: 3px;
  padding: 7px 9px 8px; border-radius: 0;
  background: rgba(255,255,255,0.66); border: 1px solid var(--divider);
}
/* Padding before the first day, so weekdays keep their columns. */
.avail-cell.is-blank { background: none; border-color: transparent; }
/* Not "full" — not a working day at all. */
.avail-cell.is-closed { background: var(--paper-vault); border-color: transparent; }
.avail-cell.is-full { background: var(--paper-vault); }
.avail-cell.is-over {
  background: rgba(176,80,63,0.07); border-color: rgba(176,80,63,0.24);
}
.avail-cell.is-today { border-color: var(--cobalt); }

.avail-date { font-size: 10.5px; color: var(--text-muted-2); }
.avail-hours {
  font-size: 14px; font-weight: 600; color: var(--ink-body-2);
  font-variant-numeric: tabular-nums; line-height: 1.2;
  display: flex; align-items: baseline; gap: 3px;
}
.avail-cell.is-closed .avail-hours { color: var(--text-muted-2); font-weight: 500; }
.avail-cell.is-full .avail-hours { color: var(--text-muted); }
.avail-cell.is-over .avail-hours { color: var(--over-ink); }
.avail-glyph { font-size: 9px; }

/* The meter fills with what is left, so a fuller bar reads as a freer
   day. Its blue is the ring's free slice, not a client hue. */
.avail-meter {
  display: block; height: 3px; border-radius: 0; margin-top: 2px;
  background: rgba(35,51,221,0.10); overflow: hidden;
}
.avail-meter > span { display: block; height: 100%; background: #8E99EA; }

/* ---- Regular work: the commitments editor ---- */
/* The headline this page leads on, now that it is a tab of its own with
   no ring above it to give the hours a scale. Serif and larger than the
   cards below, so the eye lands on the total before the list. */
.commitments-summary {
  font-family: var(--font-serif); font-size: 16.5px; line-height: 1.6;
  color: var(--ink-body); padding: 14px 18px; margin-bottom: 18px;
  background: var(--paper-vault); border-radius: 0;
}
.commitments-summary strong {
  font-weight: 600; color: var(--ink-heading);
  font-variant-numeric: tabular-nums;
}
.commitments-summary .summary-warn { color: var(--over-ink); font-weight: 500; }

/* Same card as a project, because it is the same kind of object on the
   page: a named thing you edit in place. The spine is set from the
   client's slice colour in js/commitments.js so a card and its wedge in
   the ring read as one thing; with no client it falls back to the
   neutral "other" hue. A deliberate true white, not the app's
   paper-editor tone — matches the same one-off crispness the Daily
   Overview table uses. */
.commitment-card {
  background: #FFFFFF; border: 1px solid var(--divider);
  border-radius: 0; padding: 14px 16px; margin-bottom: 10px;
  border-left: 3px solid var(--cobalt);
}

/* Every card's head lays out in the same five columns, so the list
   reads as one aligned block — a name of any length can only ever grow
   or shrink its own column, never nudge Client/Weekly/the buttons out
   of line with the row above or below it. buildColumnsHead() labels
   this exact grid once, above the first card. */
.commitment-head, .commitment-columns-head {
  display: grid;
  grid-template-columns: minmax(160px, 1fr) 160px 84px 28px 68px;
  align-items: center; gap: 14px;
}
.commitment-head { margin-bottom: 6px; }
.commitment-columns-head {
  padding: 0 4px 8px; margin-bottom: 4px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-muted-2);
}
.commitment-columns-head .is-numeric { text-align: right; }

/* A long name can only run out of room sideways now that its column has
   a fixed width — ellipsis rather than wrapping, so one long name never
   makes its card taller than its neighbours. The full text still shows
   on hover (title, set in js/dom.js) or by clicking to edit. */
.commitment-head > .inline-edit { min-width: 0; overflow: hidden; }
.commitment-name {
  display: block; font-family: var(--font-serif); font-size: 17px; font-weight: 500;
  color: var(--ink-heading); padding: 2px 6px; margin-left: -6px;
  border: 1px solid transparent; border-radius: 0; cursor: text;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.commitment-name:hover { border-color: var(--divider); }
input.commitment-name { background: rgba(255,255,255,0.72); }

.commitment-client-select { width: 100%; }

.commitment-total {
  font-size: 12.5px; font-weight: 600; color: var(--text-secondary);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}

/* The disclosure toggle: a bare glyph, no button box around it — colour
   alone marks it as interactive, matching the borderless chevrons on
   the Daily Overview table's column headers. Rotates rather than swaps
   so the click reads as "turning" the row open instead of a new icon. */
.commitment-toggle {
  justify-self: center; border: none; background: transparent; color: #3F00FF;
}
.commitment-toggle-glyph {
  display: inline-block; font-size: 20px; line-height: 1;
  transition: transform 0.15s ease;
}
.commitment-toggle.is-open .commitment-toggle-glyph { transform: rotate(180deg); }

/* Collapsed by default: max-height animates the reveal, then `hidden`
   (set in js/commitments.js once the transition ends) drops the day
   grid and date inputs out of tab order until it opens again. */
.commitment-detail {
  overflow: hidden; max-height: 0; transition: max-height 0.18s ease;
}
.commitment-detail.is-open { max-height: 420px; }

.commitment-meta {
  font-size: 12px; color: var(--text-muted); line-height: 1.55;
  margin-bottom: 13px;
}
.commitment-dates { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 13px; }

/* ---- The add-client form ---- */
.add-row {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  background: var(--paper-editor); border: 1px solid var(--divider);
  border-radius: 0; padding: 14px 16px; margin-bottom: 20px;
}
.add-row input[name="name"] { flex: 1 1 220px; }
.add-row select { width: 150px; }
.add-row .primary-button { height: 36px; }

.form-hint {
  flex: 1 1 100%; font-size: 12px; color: var(--text-muted); line-height: 1.5;
}

.sheet-footnote { margin-top: 14px; font-size: 12px; color: var(--text-muted); line-height: 1.6; }

.display-name-input { width: 220px; margin-bottom: 16px; }

/* ---- Daily Overview ---- */
.daily-greeting { margin-bottom: 20px; }
/* Baseline-aligned so the note sits on the greeting's own line rather
   than floating beside it, and wrapping so a long name never pushes it
   off the edge. */
.daily-greeting-row {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.daily-greeting-title {
  font-family: var(--font-serif); font-size: 24px; font-weight: 500;
  color: var(--ink-heading);
}
/* Quieter than the greeting it follows — it is an answer, not a heading. */
.daily-greeting-note {
  font-family: var(--font-serif); font-style: italic; font-size: 14.5px;
  color: var(--text-muted);
}
.daily-greeting-date { font-size: 12.5px; color: var(--text-muted); margin-top: 3px; }

/* ---- Punch clock ---- opt-in, Daily Overview only. KISS by design: no
   icon or image, just the greeting row extended sideways — a status
   dot, the label, a digital readout, and the buttons the state calls
   for, all on one line. Colour follows the same vocabulary as
   everywhere else in the dashboard: cobalt while running, the "tight"
   amber while paused, muted once idle or stopped — carried by the dot
   and the digits, never by the dot alone (see aria-label in
   js/dailyOverview.js). */
.punch-clock {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px;
}
.clock-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--text-muted); }
.clock-dot.is-running { background: var(--cobalt); }
.clock-dot.is-paused { background: var(--tight-ink); }
.punch-clock-label { font-size: 12.5px; font-weight: 500; color: var(--text-secondary); }
/* The digital-clock readout: tabular digits, ticking once a second
   while running only (see ensureTicking in js/dailyOverview.js) —
   plain enough to read at a glance, distinct enough from the serif
   greeting above it to read as a live instrument rather than prose. */
.punch-clock-digits {
  font-family: var(--font-ui); font-size: 17px; font-weight: 600;
  letter-spacing: 0.02em; color: var(--ink-heading);
  font-variant-numeric: tabular-nums;
}
.punch-clock-button { height: 28px; padding: 0 12px; font-size: 11.5px; }
.punch-clock-done { font-size: 11.5px; font-weight: 500; color: var(--text-muted); }

/* The 12-hour cap notice — the "tight" amber tone already used for
   capacity warnings elsewhere, an informative caution rather than an
   error (see --tight-ink in css/base.css). */
.punch-clock-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px; padding: 9px 12px;
  background: var(--tight-wash); border: 1px solid rgba(151,112,47,0.25);
  border-radius: 0; font-size: 12.5px; color: var(--tight-ink); max-width: 420px;
}
.punch-clock-banner-dismiss {
  flex: none; font-size: 15px; line-height: 1; color: var(--tight-ink);
  opacity: 0.6; padding: 0 2px;
}
.punch-clock-banner-dismiss:hover { opacity: 1; }

.daily-section { margin-bottom: 22px; }
.daily-section-title {
  font-size: 12px; font-weight: 600; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 8px;
}
.daily-section-title.is-overdue { color: var(--over-ink); }

/* A deliberate true white, not the app's paper-editor tone — this table
   is meant to read as crisper than the rest of the page. */
.daily-table-panel {
  background: #FFFFFF; border: 1px solid var(--divider);
  border-radius: 0; padding: 6px 18px 16px;
}
.daily-table-panel.is-overdue { border-color: rgba(176,80,63,0.25); }

.daily-table { width: 100%; border-collapse: collapse; }
.daily-table th {
  position: relative; text-align: left; font-size: 10.5px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-muted-2); font-weight: 600;
  padding: 0 10px 8px; border-bottom: 1px solid var(--divider);
}
.daily-table th:nth-child(3) { text-align: right; }
.daily-table th:last-child, .daily-table td:last-child { width: 140px; }

/* The chevron is a bare glyph, no border or fill of its own — colour
   alone marks it as interactive, matching the rest of this table's
   restraint. Sized to stay legible rather than shrinking to match the
   tiny uppercase label beside it. */
.daily-th-label { display: inline-flex; align-items: center; gap: 4px; }
.daily-th-chevron {
  border: none; background: transparent; color: var(--text-muted-2);
  font-size: 13px; line-height: 1; padding: 0; cursor: pointer;
}
.daily-th-chevron:hover { color: var(--cobalt); }

.daily-th-popover {
  position: absolute; top: 100%; left: 10px; z-index: 5; margin-top: 6px;
  background: #FFFFFF; border: 1px solid var(--divider); border-radius: 0;
  box-shadow: 0 4px 14px rgba(23,35,63,0.10); padding: 10px 12px;
  min-width: 140px; text-transform: none; letter-spacing: normal;
}
.daily-th-popover-label {
  font-size: 10.5px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px;
}
.daily-th-popover-label:not(:first-child) {
  border-top: 1px solid var(--divider); padding-top: 8px; margin-top: 2px;
}
.daily-th-popover-item {
  display: block; width: 100%; text-align: left; font-size: 12.5px;
  font-weight: 500; color: var(--ink-body-2); padding: 3px 0;
}
.daily-th-popover-item:hover { color: var(--cobalt); }
.daily-th-popover-check {
  display: flex; align-items: center; gap: 6px; font-size: 12.5px;
  font-weight: 500; color: var(--ink-body-2); padding: 3px 0; cursor: pointer;
}
.daily-table td {
  padding: 11px 10px; border-bottom: 1px solid var(--divider);
  font-size: 13.5px; color: var(--ink-body-2); vertical-align: top;
}
.daily-table tbody tr:last-child td { border-bottom: none; }

.daily-client-cell { font-weight: 500; white-space: nowrap; }
.daily-detail-head { display: flex; align-items: baseline; gap: 6px; }
.daily-detail-title { font-family: var(--font-serif); font-size: 14.5px; color: var(--ink-heading); }
.daily-detail-brief { font-size: 12px; color: var(--text-muted); margin-top: 2px; margin-left: 26px; }

/* ---- Project Details: progressive disclosure. Reuses
   .commitment-toggle's bare rotating chevron and the same "extra <tr>
   the toggle shows and hides" pattern as .revenue-detail-row — the
   four-column grid itself never changes shape, only a fifth row
   appears beneath the one it belongs to. */
.daily-detail-row td {
  padding: 2px 10px 14px 34px; border-bottom: 1px solid var(--divider);
}
.daily-detail-grid {
  display: grid; grid-template-columns: 112px 1fr; gap: 5px 12px;
  font-size: 12.5px; padding-top: 6px; max-width: 480px;
}
.daily-detail-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-muted-2);
}
.daily-detail-value { color: var(--ink-body-2); }
.daily-days-cell {
  text-align: right; font-variant-numeric: tabular-nums;
  color: var(--over-ink); font-weight: 600;
}
.daily-hours-cell { text-align: right; font-variant-numeric: tabular-nums; }

.daily-empty {
  color: var(--text-muted); font-family: var(--font-serif); font-style: italic;
  text-align: center; padding: 16px 0;
}

/* Square corners on purpose — this is a plain control, styled like every
   other select in the app, not a pill. Colour alone carries the state,
   the same trio used for done tasks and overdue dates elsewhere. */
.status-select {
  font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 7px 9px; border-radius: 0; cursor: pointer; width: 100%;
}
.status-select.is-overdue {
  background: rgba(176,80,63,0.14); color: var(--over-ink);
  border: 1px solid rgba(176,80,63,0.35);
}
.status-select.is-pending {
  background: var(--paper-vault); color: var(--text-secondary);
  border: 1px solid var(--divider);
}
.status-select.is-done {
  background: var(--done-wash); color: var(--done-ink);
  border: 1px solid rgba(94,113,80,0.3);
}
