/* The Projects screens (docs/design/projects.md), on top of `activity.css`.
 *
 * They take the board's place the way Settings does, so they reuse its strip,
 * heading, sheets, fields and notices, and add only what a list of projects
 * and a log of sprints need: cards, rows, the headline figures, the chart and
 * the folds. Dark only, like the rest of the panel. One column at every width:
 * the panel is as narrow as a phone even on a monitor.
 *
 * This file has the rules every Projects screen shares. The screens with
 * more of their own have a file each, joined after this one into the one
 * stylesheet the page loads, in the order `projects_css_files!` in
 * `web/assets.rs` lists them. */

/* --- The screen ---------------------------------------------------------- */

.proj-screen {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

.proj-head h1 {
  overflow-wrap: anywhere;
}

/* A code for chat beside a name (`codes_view.rs`, docs/design/
 * sprint-todos.md section 6): small and quiet, in the code face, so it
 * reads as something to type and not as part of the name. */
.proj-code {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--muted);
  white-space: nowrap;
}

/* Each part of a screen on a card, as the settings tabs are. */
.proj-card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(0.8rem, 3vw, 1.1rem);
}

.proj-card h2 {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.proj-sec-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}

.proj-say {
  margin: 0;
  font-size: 0.88rem;
  color: var(--muted);
}

.proj-btns {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.proj-btns form {
  margin: 0;
}

/* A small button beside a line it acts on. The target grows on a touch
 * screen, below. */
button.proj-small {
  min-height: 2rem;
  padding: 0.25rem 0.65rem;
  font-size: 0.85rem;
  font-weight: 500;
}

button.proj-danger {
  color: var(--bad);
}

.proj-form {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  margin: 0;
}

.proj-form select {
  width: 100%;
  min-height: 2.4rem;
  padding: 0.45rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

.proj-form select:focus-visible,
.proj-choice input:focus-visible,
.proj-check input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- The list ------------------------------------------------------------ */

.proj-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* One project: a card that opens it. */
.proj-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  width: 100%;
  min-height: 3.2rem;
  padding: 0.7rem 0.9rem;
  text-align: left;
  font-weight: 400;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.proj-row-name {
  font-size: 1.02rem;
  font-weight: 500;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.proj-row-totals {
  font-size: 0.9rem;
  color: var(--ink);
}

.proj-row-last {
  font-size: 0.8rem;
  color: var(--muted);
}

.proj-empty h2 {
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
}

.proj-empty ol {
  margin: 0;
  padding-left: 1.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.9rem;
}

.proj-arch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.5rem 0;
}

.proj-arch-row + .proj-arch-row {
  border-top: 1px solid var(--border);
}

.proj-arch-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.proj-arch-row form {
  margin: 0;
  flex: none;
}

/* --- Folds --------------------------------------------------------------- */

/* The archived projects, the done tasks: a triangle and a count, like the
 * board's own "More". */
.proj-fold > summary {
  cursor: pointer;
  list-style: none;
  color: var(--muted);
  font-size: 0.88rem;
  padding: 0.5rem 0;
}

.proj-fold > summary::-webkit-details-marker {
  display: none;
}

.proj-fold > summary::before {
  content: "";
  display: inline-block;
  margin-right: 0.45rem;
  vertical-align: 0.05em;
  border-top: 0.3em solid transparent;
  border-bottom: 0.3em solid transparent;
  border-left: 0.42em solid currentColor;
  transition: transform 0.12s ease;
}

.proj-fold[open] > summary::before {
  transform: rotate(90deg);
}

.proj-fold > summary:hover {
  color: var(--ink);
}

/* --- One project: the figures --------------------------------------------- */

/* The change over the last 30 days, over the chart. The book's own figures
 * are in `projects-book.css`. */
.proj-recent {
  font-size: 0.82rem;
  color: var(--muted);
}

.proj-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 0.6rem;
  font-size: 0.9rem;
}

.proj-starting {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

/* --- The chart ----------------------------------------------------------- */

.proj-chart-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 0;
}

.proj-chart {
  position: relative;
  height: 10.5rem;
  min-width: 0;
}

.proj-chart canvas {
  display: block;
  max-width: 100%;
}

.proj-chart-say {
  margin: 0;
  font-size: 0.78rem;
  color: var(--muted);
}

/* Share image is wider than other popups on a wide screen: its preview is
 * the PNG, 1200 x 630, and at the usual 28rem it was too small to read. */
@media (min-width: 46rem) {
  dialog.sheet.chart-share-sheet {
    width: min(44rem, 92vw);
  }
}

/* Share image's picture of the PNG (1200 x 630), above its switch. */
.chart-preview {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1200 / 630;
  margin-block-end: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.chart-image .proj-figure {
  margin-block-end: 0.6rem;
}

.proj-measures {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

button.proj-measure {
  min-height: 2rem;
  padding: 0.2rem 0.7rem;
  font-size: 0.82rem;
  background: transparent;
  color: var(--muted);
  border-radius: 999px;
}

button.proj-measure[aria-pressed="true"] {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* --- Tasks --------------------------------------------------------------- */

.proj-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

.proj-task {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 0.6rem;
  padding: 0.55rem 0;
}

.proj-rows > li + li {
  border-top: 1px solid var(--border);
}

.proj-task-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 10rem;
}

.proj-task-name {
  overflow-wrap: anywhere;
}

.proj-task-line {
  font-size: 0.8rem;
  color: var(--muted);
}

/* A row's buttons. Each is its own form so it can carry the screen's fields,
 * but a form is not a layout. */
.proj-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.proj-acts form {
  display: contents;
}

.proj-modes {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 0;
}

.proj-modes[hidden],
.proj-mode-time[hidden] {
  display: none;
}

.proj-modes legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

/* A radio or a checkbox with its words beside it, the whole line pressable. */
.proj-choice,
.proj-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.35rem 0.2rem;
  cursor: pointer;
}

.proj-choice input,
.proj-check input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin: 0.2rem 0 0;
  accent-color: var(--accent);
}

.proj-choice .l,
.proj-check .l {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.proj-choice small,
.proj-check small {
  font-size: 0.78rem;
  color: var(--muted);
}

/* The settings sheet's sections after the starting counts: the switch and
 * the sprint board's names, each under a rule as the starting counts are. */
.proj-edit-sheet .part-switch,
.proj-board {
  margin: 0;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

/* The sprint board's names: two ticks under a heading, then what the board
 * would show beside the next count and where it shows it. */
.proj-board fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.proj-board legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.proj-board-tick {
  margin: 0;
}

.proj-board-shows {
  margin: 0.3rem 0 0.15rem;
  font-size: 0.85rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* The value in that line, in the ink colour the board itself would use. */
.proj-board-label {
  color: var(--ink);
}

/* Neither tick on: the board shows no name. */
.proj-board-none {
  font-style: italic;
  color: var(--muted);
}

/* The project's settings, beside its name: the strip's gear (`cog()`), in
 * a class of its own because `.cog` is hidden on the smallest Lounge tiles
 * (`activity-sizes.css`). About 30px square, 44px on a touch screen. */
button.proj-cog {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.35rem;
  min-height: 0;
  border-color: transparent;
  background: transparent;
  color: var(--muted);
  line-height: 0;
}

button.proj-cog:hover {
  color: var(--ink);
  border-color: var(--border);
}

/* --- The log of sprints -------------------------------------------------- */

/* A row per day, newest first, under a row of column names: the day's
 * month, the day, the time, the part, what it added, the sprint time and
 * the running total (owner, 2026-10-26: the old log stacked every number
 * and detail on top of each other in a thin column). A day with more than
 * one sprint or record adds them up on its row and lists them under it.
 *
 * The columns need about 46rem: below that the part column is narrower
 * than a chip like "300+ words a minute". The screen is 34rem wide in a
 * Discord window and up to 58rem in a wide one (`activity-sizes.css`), so
 * the rows measure the log's own width, not the window's. Under 46rem each
 * row is two lines: the day and what it added, then the part and the
 * running total. */
.proj-log-rows {
  container: proj-log / inline-size;
  font-variant-numeric: tabular-nums;
}

.proj-days,
.proj-day-entries {
  list-style: none;
  margin: 0;
  padding: 0;
}

.proj-log-row {
  display: grid;
  grid-template-columns: 2.5rem 6.2rem 5.4rem minmax(0, 1fr) 7.2rem 4.6rem 5.6rem;
  grid-template-areas: 'mini day time part added min run';
  column-gap: 0.6rem;
  /* The first lines line up: a time beside the change of a Set round, not
   * beside the middle of its two lines. */
  align-items: baseline;
  padding: 0.4rem 0.3rem;
  border-radius: 4px;
}

.proj-log-row > .mini-month {
  grid-area: mini;
  align-self: center;
}

.proj-log-day {
  grid-area: day;
  font-weight: 500;
}

.proj-log-time {
  grid-area: time;
  color: var(--muted);
}

.proj-log-part {
  grid-area: part;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.4rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.proj-log-added {
  grid-area: added;
}

.proj-log-min {
  grid-area: min;
}

.proj-log-run {
  grid-area: run;
}

/* The numbers line up on the right. What a row added is the figure to
 * read; its sprint time and the running total are quieter. */
.proj-log-added,
.proj-log-min,
.proj-log-run {
  text-align: right;
}

.proj-log-min,
.proj-log-run {
  font-size: 0.88rem;
  color: var(--muted);
}

/* The column names: small and quiet, over the rows they name. */
.proj-log-cols {
  padding-top: 0;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.proj-log-cols > * {
  font-size: inherit;
  font-weight: 400;
  color: inherit;
}

.proj-day + .proj-day {
  border-top: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
}

/* "Today" or "Yesterday" under the date. */
.proj-log-day small {
  display: block;
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.1;
  color: var(--muted);
}

/* A row that opens a sprint's or record's sheet (`record_sheet.rs`): the
 * background on hover says it can be pressed. The row that adds up a day
 * with several opens nothing, so it has no hover. */
.proj-entry-row {
  cursor: pointer;
}

.proj-entry-row:hover {
  background: var(--surface-2);
}

/* The sprints and records of a day with several, under its row. */
.proj-log-sub {
  padding-top: 0.2rem;
  padding-bottom: 0.2rem;
  font-size: 0.9rem;
}

.proj-log-sub .proj-log-added {
  color: var(--muted);
}

/* The time and the amount are buttons, so the keyboard reaches the sheet:
 * on When and on Amount. They look like the text around them. */
.proj-log-row button {
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

.proj-log-row button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* A Set round's count under its change: "Set to 12,340 words". */
.proj-log-set {
  display: block;
  font-size: 0.75rem;
  color: var(--muted);
}

/* A record added by hand with no time: its time column offers one. */
.proj-no-time {
  font-style: italic;
}

/* "From TrackBear" in the part column, for the narrow layout only: wide,
 * the time column says "TrackBear", and so does a narrow row under a day. */
.proj-log-from {
  display: none;
}

.proj-log-name + .proj-log-from::before {
  content: "· ";
}

/* A part marked complete names the part and adds no number. */
.proj-entry-row.is-complete .proj-log-name {
  color: var(--muted);
}

/* A removed sprint or record stays in the log, muted and struck through.
 * Its sheet can put it back. */
.proj-entry-row.is-removed {
  color: var(--muted);
}

.proj-entry-row.is-removed :is(.proj-when, .proj-log-name, .proj-amount, .proj-log-min) {
  text-decoration: line-through;
}

@container proj-log (max-width: 46rem) {
  .proj-log-row {
    grid-template-columns: 2.5rem minmax(0, 1fr) auto;
    grid-template-areas:
      'mini day added'
      'mini part run';
    column-gap: 0.55rem;
    row-gap: 0.05rem;
  }

  /* Beside the day, however tall the row's chips make it. */
  .proj-log-row > .mini-month {
    align-self: start;
  }

  .proj-log-cols,
  .proj-log-time,
  .proj-log-min {
    display: none;
  }

  .proj-log-part {
    font-size: 0.85rem;
    color: var(--muted);
  }

  .proj-log-run {
    font-size: 0.82rem;
  }

  /* A Set round's two lines wrap here rather than take the day's room. */
  .proj-log-added {
    max-width: 11rem;
  }

  /* The rows under a day: the time where the day is. */
  .proj-log-sub {
    grid-template-areas:
      'mini time added'
      'mini part run';
  }

  .proj-log-sub .proj-log-time {
    display: block;
  }

  .proj-log-row:not(.proj-log-sub) .proj-log-from {
    display: inline;
  }
}

/* The day's month (`mini_month.rs`): a grey box a day, the day starred
 * when everything on it counts toward goals, dotted when something does
 * not. */
.mini-month .mm-days {
  fill: var(--border);
}

.mini-month .mm-star {
  fill: #fac775;
  stroke: #854f0b;
  stroke-width: 0.7;
  stroke-linejoin: round;
}

/* The page's own text color, ringed in the card's, so it stands off the
 * boxes around it. */
.mini-month .mm-dot {
  fill: var(--ink);
  stroke: var(--surface);
  stroke-width: 1;
}

/* The day a sprint counts for, under its time when it started on another
 * date: the one difference on the row worth seeing at a glance, so in ink. */
.proj-counts-for {
  display: block;
  font-size: 0.75rem;
  color: var(--ink);
}

/* The timezone sheet: what is true about the sprint, then what can be done,
 * each group apart. */
.zone-sheet .zone-why {
  color: var(--ink);
}

.zone-sheet .zone-day {
  margin: 0.4rem 0 0.2rem;
}

/* Add a record: the date and the time side by side, under one legend. */
.hand-when {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

/* When: Now, Whole day, Day and time, the one picked pressed, as the
 * Writing card's Chart | Calendar. Across the sheet, so each label fits. */
.hand-seg {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.hand-seg button {
  flex: 1 1 0;
  min-height: 2.25rem;
  padding: 0.3rem 0.5rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  cursor: pointer;
}

.hand-seg button + button {
  border-left: 1px solid var(--border);
}

.hand-seg button[aria-pressed="true"] {
  background: var(--surface-2);
  color: var(--ink);
}

/* The boxes of the one picked, right under the buttons. */
.hand-pane {
  margin: 0.55rem 0 0;
}

.hand-pane[hidden] {
  display: none;
}

.hand-now {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.hand-day {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.hand-day input {
  flex: 1 1 8rem;
  min-width: 0;
}

/* Today and Yesterday: the one the date box holds pressed. */
.hand-chip {
  min-height: 2.25rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  cursor: pointer;
}

.hand-chip[aria-pressed="true"] {
  background: var(--surface-2);
  border-color: var(--muted);
}

/* The preview's lines under when: the timezone, the day a record counts
 * for, and a later total on that day. */
.hand-notes .hand-line {
  margin: 0.4rem 0 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.hand-notes .hand-line button.link {
  font-size: inherit;
}

.hand-notes .hand-line.is-bad {
  color: var(--ink);
}

/* A later total takes up this record: the one line here worth reading
 * before the press, boxed as the join card's choice is. */
.hand-notes .hand-warn {
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
  background: color-mix(in srgb, var(--amber) 8%, transparent);
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.6rem;
}

/* The number rows: the sprint count block's grid (`activity-count.css`),
 * with New and Total always boxed, since this is a form to fill in. */
.hand-tally {
  margin: 0.9rem 0 0;
}

.hand-tally input.tally-num {
  background: var(--paper);
  border-color: var(--border);
}

.hand-tally input.tally-num:focus {
  border-color: var(--accent);
  outline: none;
}

.hand-tally .tally-num.is-none {
  font-style: italic;
  color: var(--muted);
  font-size: 0.85rem;
}

/* How the record is kept: quiet, under the rows, with the button that
 * keeps it the other way. */
.hand-kept {
  margin: 0.45rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
  text-align: right;
}

.hand-kept[hidden] {
  display: none;
}

.hand-kept button.link {
  font-size: inherit;
}

.hand-when legend {
  padding: 0;
  margin-bottom: 0.3rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.hand-when-row {
  display: flex;
  gap: 0.5rem;
}

.hand-when-row input {
  flex: 1 1 0;
  min-width: 0;
}

/* The time box, styled as the text boxes beside it (`activity-count.css`),
 * its picker in the page's own light or dark. */
.hand-when-row input[type="time"] {
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  padding: 0.55rem 0.7rem;
  font: inherit;
  color-scheme: light dark;
}

.hand-when-row input[type="time"]:focus {
  border-color: var(--accent);
}

/* A record added by hand's date and time, under the line that says when it
 * is dated, as the first thing on its sheet that can be changed. */
.zone-when {
  margin: 0.5rem 0 0.8rem;
}

/* Shown only while its choice is picked in Counts for (owner, 2026-10-28:
 * a wall of timezone settings on every sheet, needed 1% of the time). */
.zone-from {
  margin: 0.8rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

/* Whether a timezone picked below applies to the sprints after this one
 * too: the one press and the search box both send it. */
.zone-from .zone-later {
  margin: 0.3rem 0 0.5rem;
}

.zone-from h3 {
  margin: 0 0 0.2rem;
  font-size: 0.92rem;
}

.zone-from .tz-search {
  padding: 0.3rem 0 0;
}

.zone-links {
  margin-top: 0.6rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--border);
}

.zone-links .zone-link {
  cursor: pointer;
}

.zone-links .zone-link:hover {
  background: var(--surface-2);
}

/* What looks wrong about a sprint or record, and its TrackBear marks:
 * chips after its part, in the part column. */
.proj-marks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

/* An entry's sheet: its tabs across the top, one pane at a time. The
 * dialog's `data-tab` says which (`projects-record.js`). */
.rec-tabs {
  display: flex;
  gap: 0.25rem;
  margin: 0 0 0.75rem;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}

.rec-tabs::-webkit-scrollbar {
  display: none;
}

.rec-tab {
  flex: 1 0 auto;
  min-height: 2.4rem;
  padding: 0.4rem 0.6rem;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}

.rec-tab:hover {
  color: var(--ink);
}

/* A tab with nothing to change for this entry: greyed, so every sheet keeps
 * the same four tabs (owner, 2026-10-28), and still a tab that opens, on
 * one line saying why. Open, it reads like any open tab. 70% keeps it at
 * 3:1 or more on Paper and Ink (3.2 and 3.9), against 6.4 for a live tab. */
.rec-tab.is-off,
.rec-tab.is-off:hover {
  color: color-mix(in srgb, var(--muted) 70%, transparent);
}

/* The day a greyed When tab gives after "Counts for", as text. */
.rec-fixed .rec-fixed-day {
  font-size: 1rem;
}

/* The four panes share one grid cell, the open one shown: the sheet is as
 * tall as its tallest tab, up to the sheet's 85dvh, so switching tabs moves
 * nothing, and a sheet whose tabs are all short is short (owner, 2026-10-28:
 * a TrackBear record's sheet was mostly empty space on a phone). Hidden
 * panes are `visibility: hidden`, out of reach of the keyboard and screen
 * readers, but still sized. */
.rec-panes {
  display: grid;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  flex: 0 1 auto;
  min-height: 0;
}

.rec-pane {
  grid-area: 1 / 1;
  visibility: hidden;
}

/* The title and the tabs stay in place while the open tab scrolls: the pane
 * is the one part that scrolls, and on a wide window the sheet hangs from a
 * fixed top. Centred, the tabs moved up and down on every switch, and on a
 * short or zoomed window they scrolled out of sight with the rest (owner,
 * 2026-10-26). The pane's side padding keeps focus rings clear of its
 * clipped edges. */
dialog.rec-sheet[open] {
  overflow: hidden;
}

dialog.rec-sheet > .sheet-head,
dialog.rec-sheet > .rec-tabs,
dialog.rec-sheet > .rec-foot,
dialog.rec-sheet > .sheet-foot {
  flex: none;
}

/* Back sits straight under Delete. With nothing left to delete the Delete
 * row is empty, and its divider would stand alone over Back, so it goes. */
dialog.rec-sheet > .sheet-foot {
  margin-top: 0;
}

dialog.rec-sheet > .rec-foot:empty {
  display: none;
}

dialog.rec-sheet > .rec-foot:empty + .sheet-foot {
  margin-top: auto;
}

.rec-sheet .rec-pane {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  margin-inline: -4px;
  padding-inline: 4px;
}

@media (min-width: 46rem) {
  dialog.rec-sheet {
    margin: 6dvh auto auto;
  }
}

.rec-sheet[data-tab="name"] .rec-tab[data-rec-tab="name"],
.rec-sheet[data-tab="project"] .rec-tab[data-rec-tab="project"],
.rec-sheet[data-tab="when"] .rec-tab[data-rec-tab="when"],
.rec-sheet[data-tab="amount"] .rec-tab[data-rec-tab="amount"],
.rec-sheet[data-tab="counting"] .rec-tab[data-rec-tab="counting"],
.rec-sheet[data-tab="move"] .rec-tab[data-rec-tab="move"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.rec-sheet[data-tab="name"] .rec-pane[data-rec-pane="name"],
.rec-sheet[data-tab="project"] .rec-pane[data-rec-pane="project"],
.rec-sheet[data-tab="when"] .rec-pane[data-rec-pane="when"],
.rec-sheet[data-tab="amount"] .rec-pane[data-rec-pane="amount"],
.rec-sheet[data-tab="counting"] .rec-pane[data-rec-pane="counting"],
.rec-sheet[data-tab="move"] .rec-pane[data-rec-pane="move"] {
  visibility: visible;
}

/* Delete, apart from the tabs at the sheet's foot. */
.rec-foot {
  margin-top: 1rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

/* A line's number and its Save, side by side. */
.rec-line-form {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}

.rec-line-form input[name="count"] {
  width: 7rem;
  min-width: 0;
}

/* The Counting tab: the total's box, then the goals box under it. */
.total-switch {
  margin: 0;
}

.rec-pane .total-switch + .goal-switch {
  margin-top: 0.7rem;
}

/* The goals box while the entry is not counted in the total. */
.proj-check.is-off {
  color: var(--muted);
  cursor: default;
}

.proj-parts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* A record: what it was, then its buttons on the same line when they fit,
 * then why it is marked, if it is. */
.proj-part {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.6rem;
  padding: 0.45rem 0.6rem;
  border-left: 2px solid var(--border);
}

.proj-part-head {
  flex: 1 1 9rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.5rem;
  min-width: 0;
  font-size: 0.88rem;
}

.proj-part .proj-mark-why {
  flex-basis: 100%;
}

.proj-part.is-removed .proj-part-text {
  color: var(--muted);
}

/* Why a mark is there, in a sentence. */
.proj-mark-why {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}

/* A change kept as text: its text, which opens to the change in full. */
.proj-exact {
  min-width: 0;
}

.proj-exact > summary {
  display: inline;
  list-style: none;
  cursor: pointer;
  text-decoration: underline dotted var(--muted);
  text-underline-offset: 0.2em;
}

.proj-exact > summary::-webkit-details-marker {
  display: none;
}

.proj-exact-n {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* --- Sheets -------------------------------------------------------------- */

/* Cancel beside Archive: the header's Close, with a word the reader chose. */
.sheet button.proj-cancel {
  min-height: 2.4rem;
  padding: 0.5rem 0.9rem;
}

/* --- The task chip on the board ------------------------------------------ */

.task-now {
  margin: 0;
  overflow-wrap: anywhere;
}

button.chip-open {
  min-height: 0;
  padding: 0.2rem 0.1rem;
  border: 0;
  font-size: 0.85rem;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 0.2em;
}

/* The count block's line while joined: the task recorded, and Change task. */
.task-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.6rem;
  row-gap: 0.1rem;
  min-width: 0;
}

/* A writing sprint with nothing on it, for a writer outside Projects: the
 * line has nothing to say. */
.task-line:empty {
  display: none;
}

.task-now {
  font-size: 0.9rem;
  color: var(--ink);
}

/* Pick a task: a heading per project over its tasks, No task last. */
.pick-sheet .pick-project {
  margin: 0.8rem 0 0.2rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.pick-sheet .pick-project:first-of-type {
  margin-top: 0.2rem;
}

/* The project's icon before its name, as on the Projects list. */
.pick-sheet .pick-project {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.pick-sheet .pick-project .pi {
  width: 1.1rem;
  height: 1.1rem;
  flex: none;
}

/* A project's other parts and tasks, folded under the one shown (owner,
 * 2026-10-30: only the current chapter, with a way to pick another). */
.pick-sheet .pick-more > summary {
  cursor: pointer;
  padding: 0.35rem 0 0.35rem 0.2rem;
  font-size: 0.9rem;
  color: var(--muted);
}

/* A project's tasks, a level in under its parts, as on the project page. */
.pick-sheet .pick-tasks {
  margin-left: 1rem;
}

.pick-sheet .pick-tasks-head {
  margin: 0.4rem 0 0.1rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.pick-sheet .pick-none {
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.pick-sheet .pick-empty {
  margin: 0 0 0.8rem;
  color: var(--muted);
}

/* --- Big enough to hit ---------------------------------------------------- */

@media (pointer: coarse) {
  button.proj-small,
  button.proj-measure,
  .proj-row,
  .proj-fold > summary,
  .proj-entry-row,
  .rec-tab,
  .proj-choice,
  .proj-check,
  button.chip-open {
    min-height: 44px;
  }

  .proj-fold > summary {
    display: flex;
    align-items: center;
  }

  button.proj-cog {
    min-width: 44px;
    min-height: 44px;
  }

  /* The website's links over the screen. Inline boxes ignore min-height,
   * so these become inline flex boxes, their text centred in the taller
   * box. (`button.link` sits inside sentences, so it keeps its line height
   * and gets an invisible 44px square instead: activity-count.css.) */
  .web-bar a,
  .web-logout button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* A flex box drops the space between the brand's star and its name. */
  .web-bar .web-brand {
    gap: 0.25em;
  }

  /* A goal's title in the Goals card: an inline block, so its icon and a
   * long title wrap as they do on a desktop, with room above and below.
   * `button.goal-open`, to win over `.goal-open`'s `all: unset` in
   * projects-goals.css, which comes later. */
  button.goal-open {
    display: inline-block;
    box-sizing: border-box;
    min-height: 44px;
    padding-block: 0.55rem;
  }
}

/* --- On the website ------------------------------------------------------ */
/* Sprinto's website shows the Projects and Settings screens in this same
 * panel, in a browser tab (`web/lounge_web.rs`), with `lounge-web` on the
 * body. There is no room there: the strip's corner, which names the Lounge's
 * room and opens Rooms, and its bar of the room's sprint have nothing to say.
 * A control marked `data-lounge-only` would open a Lounge screen the website
 * does not have (none is marked today). The strip goes too once nothing is
 * left in it, which is any screen with no Back. */

.lounge-web .where-am-i,
.lounge-web .panel-bar .tl,
.lounge-web [data-lounge-only],
.lounge-web .panel-bar:not(:has(.back)) {
  display: none;
}

/* The way to the rest of the website, over the screen: its pages, in the
 * words of its own nav bar, the one on show marked. */
.web-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.35rem 1rem;
  font-size: 0.9rem;
}

.web-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.9rem;
}

/* Never a name broken across two lines ("log / out"): on a narrow phone the
 * pages and Log out wrap under the brand instead, still on the right. */
.web-bar .web-brand,
.web-links a,
.web-logout button {
  white-space: nowrap;
}

@container panel (max-width: 22rem) {
  .web-bar,
  .web-right,
  .web-links {
    column-gap: 0.7rem;
  }
}

.web-bar a {
  color: var(--muted);
  text-decoration: none;
}

.web-bar a:hover,
.web-bar a:focus-visible,
.web-bar a[aria-current='page'] {
  color: var(--ink);
}

.web-bar a:hover,
.web-bar a:focus-visible {
  text-decoration: underline;
}

.web-bar .web-brand {
  color: var(--ink);
  font-weight: 600;
}

/* The pages and Log out, one group on the right. On a phone too narrow for
 * one line, what does not fit wraps under them, still on the right. */
.web-right {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
  margin-left: auto;
}

/* Log out, after the pages: a button, since it posts, drawn as the links
 * beside it are. */
.web-logout {
  margin: 0;
}

.web-logout button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
}

.web-logout button:hover,
.web-logout button:focus-visible {
  color: var(--ink);
  text-decoration: underline;
}

.web-brand img {
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
  vertical-align: middle;
}
/* A project's parts (`parts_view.rs`, docs/design/parts.md): the switch,
 * and the Add and Edit sheets; the rows on a project's page are in
 * `projects-book.css`. Joined after `projects.css` (`projects_css_files!`
 * in `web/assets.rs`). */

/* --- Parts as a plain list ------------------------------------------------- */

/* The TrackBear card's list of tasks no longer in the tree, each level's
 * parts under it. A rule down the left of each level's parts says which
 * level they are in. */
.parts {
  list-style: none;
  margin: 0;
  padding: 0;
}

.parts .parts {
  margin: 0 0 0.2rem 0.3rem;
  padding-left: 0.7rem;
  border-left: 1px solid var(--border);
}

.parts > li + li {
  border-top: 1px solid var(--border);
}

.part-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.3rem 0.6rem;
  padding: 0.5rem 0;
}

/* Small enough a basis that a part two levels down keeps Mark complete
 * and Edit on its line at phone width; a long name wraps instead. */
.part-text {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  min-width: 0;
  flex: 1 1 6.5rem;
}

.part-name {
  overflow-wrap: anywhere;
}

.part-below {
  margin: 0 0 0.45rem;
  font-size: 0.8rem;
  color: var(--bad);
}

/* The switch: two choices, each with what the join card offers. */
.part-switch {
  margin: 0;
}

.part-switch fieldset,
.part-kinds {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.part-switch legend,
.part-kinds legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.part-switch .hint {
  margin: 0.15rem 0 0;
}

.part-kind-fold .part-kinds legend {
  display: none;
}

/* A part's kind in the Add and Edit sheets: "Kind: Chapter", opening to
 * the three choices. */
.part-kind-fold > summary {
  font-size: 0.9rem;
  color: var(--ink);
}

.part-kind-fold > summary [data-kind-now] {
  font-weight: 500;
}

.part-kind-fold[open] {
  padding-bottom: 0.3rem;
}

/* The Edit sheet's switch and its other actions, below the form. */
.part-sheet .part-switch {
  margin-top: 0.9rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
}

.part-sheet .part-more {
  margin-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.part-sheet .part-tb {
  padding: 0.4rem 0;
}

.part-del-opts {
  margin: 0.2rem 0 0.6rem;
}

.part-del-final {
  margin: 0 0 0.6rem;
}
/* Past sprints (`import_view.rs`, `import_runs.rs`): the viewer, and adding
 * them to a project by runs. Joined after `projects-parts.css`. */

/* --- Importing past sprints ------------------------------------------------ */

/* The three places a sprint can stand, one colour each wherever it is drawn.
 * Checked against the card (`--surface`) with the dataviz palette validator,
 * all pairs, for colour-blind readers too. */
.imp-screen {
  --imp-included: var(--accent);
  --imp-left-out: #9085e9;
  --imp-already: #199e70;
}

.imp-top p {
  margin: 0;
}

.imp-range {
  font-size: 1.05rem;
  font-weight: 600;
}

.imp-count {
  font-size: 0.9rem;
}

/* Download CSV and JSON on the website; in the Lounge, where the file never
 * saves, the line saying where the website's buttons are. `!important` over
 * the display the buttons' own rules give them. */
body:not(.lounge-web) .imp-actions [data-download],
body.lounge-web .imp-in-discord {
  display: none !important;
}

/* The website's address in that line, as a link. */
.imp-in-discord a {
  color: var(--link);
}

.imp-help {
  margin: 0 0 0.2rem;
}

/* The rule for runs, in its fold: the two near cases, then the tie-breaks
 * in order. */
.imp-rule {
  margin: 0;
  padding-left: 1.4rem;
}

.imp-rule li + li {
  margin-top: 0.15rem;
}

.imp-rule-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0 0 0.4rem;
}

/* A button that reads as a link: the summary's links, and a run's number of
 * sprints, which shows them in the table. */
button.imp-link {
  display: inline;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--link);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

button.imp-link:hover,
.imp-sum a:hover {
  text-decoration: underline;
}

button.imp-link[aria-pressed="true"] {
  color: var(--ink);
  text-decoration: underline;
}

/* --- The intro: what a run is, and how many sprints are where ----------- */

.imp-lead {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink);
}

.imp-none {
  margin: 0;
  font-size: 0.9rem;
}

/* Each part of the screen below, linked, with its sprints beside it. */
.imp-sum {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.imp-sum dt,
.imp-sum dd {
  margin: 0;
}

.imp-sum a {
  color: var(--link);
  text-decoration: none;
}

.imp-dates-fold,
.imp-rule-fold,
.imp-unusual {
  border-top: 1px solid var(--border);
}

.imp-unusual-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0 0 0.5rem;
}

.imp-dates-fold .imp-dates {
  border-top: 0;
  padding: 0 0 0.4rem;
}

/* --- Runs ---------------------------------------------------------------- */

.imp-run-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A clear break between runs: the line under one run's Add must not read
 * as the next run's. */
.imp-run {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.3rem 0 1.1rem;
}

.imp-run:first-child {
  padding-top: 0.2rem;
}

.imp-run + .imp-run {
  border-top: 1px solid var(--border);
}

/* The counts it runs between, the most important line on the card, and its
 * number of sprints at the right. */
.imp-run-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.2rem 0.8rem;
}

.imp-run-range,
.proj-card h2.imp-run-range {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.imp-run-n {
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

/* When, where and the tasks said, one line that wraps between its parts. */
.imp-run-when {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1rem;
  font-size: 0.82rem;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.imp-label {
  color: var(--muted);
}

/* Shorter than the viewer's charts: one line, and a card per run. */
.proj-chart.imp-run-chart {
  height: 9rem;
}

.imp-runs .proj-form {
  gap: 0.5rem;
}

/* --- The run list: two runs or more, one line each, ticked to add -------- */

/* The picker and What to add for the ticked runs, above the list. */
.imp-tick-pick {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--border);
}

.imp-run-order {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  font-size: 0.85rem;
}

/* Each line: its tick, then the line itself, which opens to the run's chart.
 * Columns of fixed width, so counts, sprints and dates line up down the
 * list. */
.imp-lines .imp-line {
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr);
  align-items: start;
  border-top: 1px solid var(--border);
}

.imp-lines .imp-line:last-child {
  border-bottom: 1px solid var(--border);
}

/* A ticked run, tinted: what the bar's Add adds. */
.imp-line.is-ticked {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}

/* The whole height of the line presses the tick. */
.imp-tick {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.6rem;
  cursor: pointer;
}

.imp-tick input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  accent-color: var(--accent);
}

.imp-tick input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.imp-line-sum {
  display: grid;
  grid-template-columns: minmax(10rem, 14rem) 6.5rem 5.5rem minmax(9rem, 12rem) minmax(0, 1fr);
  align-items: center;
  gap: 0 0.8rem;
  min-height: 2.6rem;
  padding-right: 0.5rem;
  list-style: none;
  cursor: pointer;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.imp-line-sum::-webkit-details-marker {
  display: none;
}

/* Closed or open, as a fold everywhere else shows it. */
.imp-line-sum .imp-run-range::before {
  content: "▸";
  display: inline-block;
  width: 1rem;
  color: var(--muted);
  font-weight: 400;
}

.imp-line-more[open] > .imp-line-sum .imp-run-range::before {
  content: "▾";
}

.imp-line-sum .imp-run-range {
  font-size: 0.95rem;
  white-space: nowrap;
}

.imp-line-sum:hover .imp-run-range {
  text-decoration: underline;
}

.imp-line-sum:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* The run's count over time, small: the shape at a glance, the chart with
 * its values one press away. */
.imp-spark svg {
  display: block;
  width: 100%;
  height: 1.5rem;
}

.imp-spark polyline {
  fill: none;
  stroke: var(--imp-included);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.imp-line-n {
  text-align: right;
  white-space: nowrap;
}

.imp-line-when {
  white-space: nowrap;
}

.imp-line-room {
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.imp-line-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.2rem 0.5rem 0.9rem 1rem;
}

.imp-line-body p {
  margin: 0;
}

/* The channel is on the line itself, except on a phone. */
.imp-line-room-again {
  display: none;
}

/* Under the list while runs are ticked, in view as the list scrolls. */
.imp-tick-bar {
  position: sticky;
  bottom: 0.5rem;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.4rem;
  padding: 0.7rem 0.8rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.imp-tick-bar-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.2rem 0.8rem;
}

/* Untick all: a link to read, a button's height to press. */
.imp-tick-bar-line button.imp-link {
  min-height: 2rem;
}

.imp-tick-n {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.imp-tick-bar form {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.imp-tick-to-pick {
  align-self: flex-start;
}

/* On a phone: the counts and the small line, then the sprints and dates
 * under them. */
@media (max-width: 40rem) {
  .imp-line-sum {
    grid-template-columns: auto minmax(0, 1fr) 5rem;
    grid-template-areas:
      "range range spark"
      "n when when";
    gap: 0 0.6rem;
    padding: 0.35rem 0.5rem 0.35rem 0;
  }

  .imp-line-sum .imp-run-range {
    grid-area: range;
  }

  .imp-spark {
    grid-area: spark;
  }

  .imp-line-n,
  .imp-line-when {
    font-size: 0.8rem;
    color: var(--muted);
    text-align: left;
  }

  /* Under the counts, past the fold's arrow. */
  .imp-line-n {
    grid-area: n;
    padding-left: 1rem;
  }

  .imp-line-when {
    grid-area: when;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .imp-line-room {
    display: none;
  }

  .imp-line-room-again {
    display: inline;
  }
}

/* The whole count, greyed out: the project or part picked has words. */
.proj-choice.is-off {
  cursor: not-allowed;
}

.proj-choice.is-off .l > span {
  color: var(--muted);
}

/* --- Unusual counts: each kind, its sprints, and Include or Skip --------- */

.imp-kinds {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.imp-kinds th,
.imp-kinds td {
  padding: 0.4rem 0;
  text-align: left;
  vertical-align: middle;
}

.imp-kinds tr + tr th,
.imp-kinds tr + tr td {
  border-top: 1px solid var(--border);
}

.imp-kinds th {
  font-weight: 400;
  padding-right: 0.8rem;
}

.imp-kinds .imp-kind-n {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-right: 0.8rem;
}

.imp-kinds td:last-child {
  text-align: right;
}

/* A kind no sprint has: its switch still holds, but there is nothing to
 * read. */
.imp-kinds tr.is-empty th,
.imp-kinds tr.is-empty .imp-kind-n {
  color: var(--muted);
}

/* Include | Skip, the one in force filled, as the Writing card's Chart |
 * Calendar. Radios under the labels, so the keyboard moves between them. */
.imp-seg {
  display: inline-flex;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.imp-seg label {
  position: relative;
  display: flex;
}

.imp-seg input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.imp-seg span {
  min-height: 2rem;
  display: flex;
  align-items: center;
  padding: 0.25rem 0.7rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}

.imp-seg label + label span {
  border-left: 1px solid var(--border);
}

/* The side in force, filled, as a selection is everywhere else. */
.imp-seg input:checked + span {
  background: var(--accent);
  color: var(--on-accent);
}

.imp-seg input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* On a phone the switch goes under its kind. */
@media (max-width: 30rem) {
  .imp-kinds tr {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.2rem 0.6rem;
    padding: 0.4rem 0;
  }

  .imp-kinds tr + tr {
    border-top: 1px solid var(--border);
  }

  .imp-kinds th,
  .imp-kinds td {
    padding: 0;
    border-top: 0 !important;
  }

  .imp-kinds td:last-child {
    grid-column: 1 / -1;
    text-align: left;
  }
}

/* Jumped to from the intro's links and a run's sprints: clear of the
 * panel's Back bar, which stays at the top. */
#imp-runs,
#imp-zero,
#imp-unusual,
#imp-sprints,
#imp-all {
  scroll-margin-top: 3.5rem;
}

/* Scrolled to after an Add here, clear of the Back bar (`add_swap`). */
#notice {
  scroll-margin-top: 3.5rem;
}

/* Jumped to from the run list's bar, with its label in view. */
#imp-tick-level {
  scroll-margin-top: 5rem;
}

/* The table, narrowed to one run or the skipped sprints: what it shows, and
 * the way back to all of them. */
.imp-showing {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 0.6rem;
  font-size: 0.9rem;
}

.imp-showing p {
  margin: 0;
}

.imp-marks-form,
.imp-dates {
  margin: 0;
}

.imp-dates {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.7rem;
}

.imp-date-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  min-width: 0;
}

.imp-date-fields .field {
  flex: 1 1 9rem;
  min-width: 0;
}

/* The date picker's boxes (`data-datepick`), text boxes taking YYYY-MM-DD. */
.imp-dates input[data-datepick] {
  width: 100%;
  min-height: 2.4rem;
  padding: 0.4rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

.imp-dates input[data-datepick]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.imp-charts h2 {
  margin-top: 0.2rem;
}

.imp-charts .proj-chart-wrap + .proj-chart-wrap {
  border-top: 1px solid var(--border);
  padding-top: 0.8rem;
}

/* Plot, axis labels and legend together. */
.proj-chart.imp-chart {
  height: 13rem;
}

.imp-go form {
  margin: 0;
}

button.imp-button {
  width: 100%;
  white-space: normal;
  text-align: center;
}

/* Cannot be pressed yet; the line under it says why. */
button.imp-button:disabled {
  background: transparent;
  color: var(--muted);
  border-color: var(--border);
  cursor: not-allowed;
}

.imp-go-line {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted);
}

/* What the checkboxes say, over their column. */
.imp-rows-head {
  margin: 0;
  text-align: right;
  font-size: 0.75rem;
  color: var(--muted);
}

/* The table: two lines a sprint, its checkbox at the right. */
.imp-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}

.imp-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.55rem 0;
}

.imp-row + .imp-row {
  border-top: 1px solid var(--border);
}

.imp-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
  min-width: 0;
}

.imp-head {
  font-size: 0.8rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.imp-line {
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.imp-row.is-out .imp-line,
.imp-row.is-already .imp-line {
  color: var(--muted);
}

.imp-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.3rem;
  margin-top: 0.25rem;
}

/* A mark opens to the sentence saying why it is there. */
.imp-mark > summary {
  display: inline-block;
  list-style: none;
  cursor: pointer;
}

.imp-mark > summary::-webkit-details-marker {
  display: none;
}

.imp-mark[open] {
  flex-basis: 100%;
}

.imp-mark .proj-mark-why {
  margin-top: 0.25rem;
}

.imp-pick {
  flex: none;
  display: flex;
  justify-content: flex-end;
  max-width: 45%;
}

.imp-pick form {
  margin: 0;
}

.imp-check {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  cursor: pointer;
}

/* Ticked is the usual state, so the tick is quiet; a skipped row's amber
 * tag is the exception that shows. */
.imp-check input {
  width: 1.2rem;
  height: 1.2rem;
  margin: 0;
  accent-color: var(--muted);
}

.imp-check input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.imp-already {
  font-size: 0.78rem;
  color: var(--muted);
  text-align: right;
  overflow-wrap: anywhere;
  padding-top: 0.1rem;
}

.imp-zone {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

.imp-batches {
  border-bottom: 1px solid var(--border);
}

.imp-open {
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

@media (pointer: coarse) {
  .imp-check {
    width: 44px;
    height: 44px;
  }

  .imp-mark > summary {
    min-height: 32px;
    display: inline-flex;
    align-items: center;
  }
}
/* TrackBear (`trackbear_view.rs`, `tb_import_view.rs`): the link, the
 * card on a project, and Import from TrackBear. Joined after
 * `projects-import.css`. */

/* --- TrackBear ----------------------------------------------------------- */
/* The section at the foot of the list, the card on a project, the connect
 * and link sheets (`trackbear_view.rs`). */

.tb-line,
.tb-linked {
  margin: 0;
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}

.tb-linked {
  font-weight: 500;
}

.tb-status {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.tb-line.is-bad,
.proj-task-line.is-bad {
  color: var(--bad);
}

.tb-line.is-ok {
  color: var(--good);
}

.tb-retry {
  margin: 0;
}

.tb-flag {
  margin: 0;
}

.tb-flag-lines {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.tb-steps {
  margin: 0;
  padding-left: 1.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.88rem;
}

.tb-ext-line {
  margin: 0;
}

/* One block of key steps per choice of site; projects-trackbear.js shows
   the chosen one. */
.tb-key-steps {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.tb-key-steps[hidden] {
  display: none;
}

a.tb-ext {
  color: var(--link);
  font-size: 0.88rem;
}

.tb-connect input[type="password"],
.tb-connect input[type="url"] {
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  padding: 0.55rem 0.7rem;
  font: inherit;
  min-width: 0;
  width: 100%;
}

.tb-connect input[type="password"]:focus,
.tb-connect input[type="url"]:focus {
  border-color: var(--accent);
}

.tb-connect input[type="password"]::placeholder,
.tb-connect input[type="url"]::placeholder {
  color: var(--muted);
  opacity: 0.7;
}

/* The connect sheet's choice of site. The address box shows only while
   "Another TrackBear-compatible site" is picked. */
.tb-site {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.tb-site legend,
.tb-site-legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.tb-site-fixed p {
  margin: 0;
}

.tb-site-option {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* The site name box goes with the address box. */
.tb-site .tb-site-address,
.tb-site .tb-site-name {
  display: none;
  margin-left: 1.4rem;
}

.tb-site:has(input[name="site"][value="custom"]:checked) .tb-site-address,
.tb-site:has(input[name="site"][value="custom"]:checked) .tb-site-name {
  display: flex;
}

.tb-pick {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.tb-pick legend {
  padding: 0;
  margin-bottom: 0.3rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.tb-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-height: 2.5rem;
}

.tb-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 16rem;
  overflow-y: auto;
}

.tb-rows > li + li {
  border-top: 1px solid var(--border);
}

.proj-choice.is-taken {
  cursor: not-allowed;
  color: var(--muted);
}

.tb-empty-head {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
}

.tb-zone {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 0.6rem;
}

.tb-link-form button[data-tb-go]:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* A linked project's imports from TrackBear, each with Undo, and its
 * TrackBear settings fold. */
.tb-imports {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.tb-imports > li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.3rem 0.6rem;
}

.tb-settings form {
  margin: 0.4rem 0 0;
}

/* How much a link sends: The book daily first, the rest in a fold. */
.tb-detail {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.tb-detail legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.tb-more-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--border);
}

.tb-more-body .tb-ticks-for {
  margin: 0.35rem 0 0;
}

/* --- Import from TrackBear, and to settle ------------------------------- */
/* `tb_import_view.rs`: the screen's groups, each with its box, and the
 * to-settle card on the Projects list. */

.tbi-group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--border);
}

.tbi-head {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.tbi-both {
  margin: 0;
  padding-left: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.88rem;
}

.tbi-starting {
  margin: 0;
  padding: 0.6rem 0 0;
  border: 0;
  border-top: 1px solid var(--border);
  min-width: 0;
}

.tbi-starting legend {
  padding: 0;
  margin-bottom: 0.3rem;
  font-size: 0.88rem;
}

.tbs-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.tbs-item {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.6rem 0;
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}

.tbs-item + .tbs-item {
  border-top: 1px solid var(--border);
}

.tbs-item p {
  margin: 0;
}

.tbs-act {
  margin: 0;
}

/* Also send, until a pick with earlier records to send is made. */
.tb-also[hidden] {
  display: none;
}

.tb-marks .tag:not(.warn) {
  color: var(--muted);
}

.proj-starting-from {
  font-size: 0.8rem;
}
/* The Tasks screen (`todo/view.rs`, once the To-do list), a to-do's part
 * and amount, and a project's Tasks section. Joined after
 * `projects-trackbear.css`. */

/* --- The to-do list (docs/design/lounge-todo.md) --------------------------- */

/* The add box and its button on one line, the box taking the width. */
.todo-add {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
}

.todo-add-row {
  display: flex;
  gap: 0.5rem;
  min-width: 0;
}

.todo-add-row input {
  flex: 1 1 auto;
  min-width: 0;
}

.todo-add-row button {
  flex: none;
}

/* A to-do's part and amount (docs/design/parts.md, section 9): the fold
 * under the add box, a to-do's sheet, and the join card's chip panel. */
.todo-add-more > summary {
  padding: 0.3rem 0;
}

.aim-fields {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.todo-add-more .aim-fields {
  padding: 0.1rem 0 0.4rem;
}

.aim-fields select {
  width: 100%;
  min-height: 2.4rem;
  padding: 0.45rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

.aim-fields select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The amount and its unit on one line; the box sized for a number. */
.aim-amount-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.aim-amount-row input[type="text"] {
  flex: none;
  width: 7rem;
}

.aim-amount-row .unit {
  color: var(--muted);
}

.aim-fields [hidden] {
  display: none;
}

/* A to-do's amount for this sprint on the join card (board/join.rs,
 * `sprint_amount_fields`): the unit is typed beside the amount, in a box
 * wide enough for "thank you cards" (20 characters at most), and shrinks
 * before the number box does on a narrow panel. */
.aim-amount-row input.aim-unit-in {
  flex: 1 1 6rem;
  width: auto;
  min-width: 0;
  max-width: 12rem;
}

.join-amount .aim-start input {
  width: 7rem;
}

.join-amount[hidden],
.join-amount [hidden] {
  display: none;
}

/* The fold's choice between a part and amount and a task on a project
 * (docs/design/parts.md, section 12), and the task's fields. */
.todo-kind {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0.1rem 0 0.6rem;
}

.todo-kind label {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}

.todo-kind .hint {
  display: block;
  margin: 0.1rem 0 0;
}

[data-kind-group][hidden],
.task-fields [hidden] {
  display: none;
}

.task-fields {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-bottom: 0.4rem;
}

.task-fields select {
  width: 100%;
  min-height: 2.4rem;
  padding: 0.45rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

.task-fields select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.todo-over[hidden],
.todo-err[hidden] {
  display: none;
}

.todo-said {
  margin: 0;
  font-size: 0.85rem;
  color: var(--ink);
}

/* A press that did not land, next to where it was made. */
.todo-err {
  margin: 0;
  font-size: 0.85rem;
  color: var(--bad);
}

.todo-empty {
  margin: 0.4rem 0;
  color: var(--muted);
}

/* The Tasks screen (docs/design/sprint-todos.md, section 7): a project's
 * name over its tasks, as the join card heads a project's tasks
 * (`.task-group-h`): a label for the list under it, smaller than the
 * screen's title. */
.todo-group {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.todo-group-h {
  margin: 0.2rem 0 0;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.todo-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* One to-do: the tick box, then its name, which opens its sheet. */
.todo-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 0.3rem;
  padding: 0 0.5rem 0 0.2rem;
}

.todo-item + .todo-item {
  border-top: 1px solid var(--border);
}

.todo-item > .todo-err {
  grid-column: 2;
  padding: 0 0.5rem 0.5rem;
}

.todo-tick {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  min-height: 2.8rem;
}

/* Drawn rather than native: the browser's own box is a white square on the
 * dark panel, brighter than anything else on the screen. */
.todo-tick input {
  appearance: none;
  display: grid;
  place-content: center;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0;
  border: 1.5px solid var(--muted);
  border-radius: 5px;
  background: var(--paper);
  cursor: pointer;
}

.todo-tick input:hover {
  border-color: var(--ink);
}

.todo-tick input::before {
  content: "";
  width: 0.7rem;
  height: 0.7rem;
  background: var(--paper);
  clip-path: polygon(14% 44%, 0 65%, 40% 100%, 100% 20%, 84% 6%, 38% 68%);
  transform: scale(0);
  transition: transform 0.1s ease-in-out;
}

.todo-tick input:checked {
  background: var(--accent);
  border-color: var(--accent);
}

.todo-tick input:checked::before {
  transform: scale(1);
}

.todo-tick input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.todo-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.05rem;
  width: 100%;
  min-height: 2.8rem;
  padding: 0.45rem 0.5rem;
  text-align: left;
  font-weight: 400;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
}

button.todo-row:hover {
  background: var(--paper);
}

.todo-name {
  color: var(--ink);
  overflow-wrap: anywhere;
}

.todo-line {
  font-size: 0.8rem;
  color: var(--muted);
}

.todo-item.is-done .todo-name {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
}

.todo-window {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  color: var(--muted);
}

/* The row's sheet: a counted task's project under the title. */
.todo-sheet-line {
  margin: -0.3rem 0 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.todo-sheet textarea {
  width: 100%;
  box-sizing: border-box;
  min-height: 5.5rem;
  resize: vertical;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  padding: 0.55rem 0.7rem;
  font: inherit;
}

.todo-sheet textarea:focus {
  border-color: var(--accent);
  outline: none;
}

.todo-sheet textarea::placeholder {
  color: var(--muted);
  opacity: 0.7;
}

.todo-sheet-foot {
  margin-top: 0.9rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
}

/* The to-dos in Pick a task, and the way to the list under them. */
.pick-sheet .pick-todos + .pick-empty {
  margin-bottom: 0.4rem;
}

.pick-sheet .pick-todos ~ button[hx-get] {
  margin-top: 0.4rem;
}

@media (pointer: coarse) {
  .todo-tick,
  .todo-row {
    min-height: 48px;
  }
}
/* Goals (`goals_view.rs`): the card, its charts, and the Add and Edit
 * sheets. Joined last, after `projects-todo.css`. */

/* --- Goals (goals_view.rs) ------------------------------------------------- */

.goal-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* Each goal as on Home (app.css, `.goal-home`): its title on a line of its
 * own, then a bar beside one status line. The bars share one column, so
 * they compare at a glance. The marks and line charts are on the goal's
 * sheet: under every goal, the card read as a panel of instruments (owner,
 * 2026-10-26). */
.goal {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0.15rem 0.75rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border);
  min-width: 0;
}

.goal:first-child {
  border-top: 0;
  padding-top: 0.2rem;
}

.goal > :not(.goal-bar):not(.goal-status) {
  grid-column: 1 / -1;
}

.goal-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* The title opens the goal's Edit sheet: a button that reads as the
 * heading it is. */
.goal-open {
  all: unset;
  cursor: pointer;
  font: inherit;
  color: var(--ink);
  border-radius: var(--radius-sm);
}

.goal-open:hover {
  text-decoration: underline;
  text-decoration-color: var(--muted);
  text-underline-offset: 0.2em;
}

.goal-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.goal-head-btns {
  margin: 0;
}

/* One status line per goal. */
.goal-status {
  margin: 0;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.goal-check {
  color: var(--good);
  font-weight: 700;
}

.goal-behind {
  color: var(--amber);
}

.goal-more {
  color: var(--muted);
}

/* How far toward the amount (`goals_view::bar`), level with the middle of
 * the status line's first line. Grey even when met: the ✓ marks that, and
 * only behind pace gets a colour. */
.goal-bar {
  align-self: start;
  margin-top: 0.45rem;
  height: 6px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 12%, transparent);
}

.goal-bar.is-empty {
  background: none;
}

.goal-bar-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 55%, transparent);
}

.goal-bar.is-behind .goal-bar-fill {
  background: var(--amber);
}

/* The goal's picture on its sheet, under the sentence that reads it back. */
.goal-sheet-picture {
  margin: 0.1rem 0 0.3rem;
}

/* A repeating goal's marks: solid fills, no borders, no glyphs. Met is
 * the calm green; today fills from the bottom as far as it has come; a
 * miss is a quiet solid, a rest day the same with a dash; days to come
 * fainter still. Each mark's title says its date and figure. */
.goal-marks {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 15rem;
}

.goal-mark-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 3px;
  font-size: 0.62rem;
  line-height: 1;
  color: var(--muted);
  text-align: center;
}

.goal-mark-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 3px;
}

.goal-mark {
  aspect-ratio: 1;
  border-radius: 4px;
  background: color-mix(in srgb, var(--ink) 13%, transparent);
}

.goal-mark.is-met {
  background: var(--good);
}

.goal-mark.is-today {
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--good) 55%, transparent) var(--fill, 0%),
    color-mix(in srgb, var(--good) 14%, transparent) var(--fill, 0%)
  );
}

/* A short dash across the middle, drawn in the background so the mark
 * stays one plain box. */
.goal-mark.is-rest {
  background:
    linear-gradient(
        color-mix(in srgb, var(--ink) 45%, transparent),
        color-mix(in srgb, var(--ink) 45%, transparent)
      )
      center / 40% 2px no-repeat,
    color-mix(in srgb, var(--ink) 13%, transparent);
}

.goal-mark.is-future {
  background: color-mix(in srgb, var(--ink) 5%, transparent);
}

.goal-mark.is-pad {
  background: none;
}

/* A dated goal: its whole span, small, the even pace dashed. */
.goal-chart {
  position: relative;
  height: 2.8rem;
  max-width: 22rem;
  min-width: 0;
}

.goal-chart canvas {
  display: block;
  max-width: 100%;
}

.goal-acts form {
  margin: 0;
}

/* The goal sheet: the goal read back as a sentence, then its fields. */
.goal-readback {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.goal-readback p {
  margin: 0;
}

.goal-readback-title {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.goal-readback-sofar {
  font-size: 0.85rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.goal-amount {
  display: flex;
  gap: 0.4rem;
}

.goal-amount input {
  flex: 1 1 8rem;
  min-width: 0;
}

.goal-amount select {
  flex: 0 1 9rem;
  width: auto;
  min-width: 0;
}

/* Edit goal: From today and From the start under Amount, shown only when
 * the amount of a repeating goal with a finished day, week or month
 * changed (`goal_sheet.rs`, `projects-goals.js`). A sibling of Amount's
 * field (inside it, `.field label` would restyle the choices), pulled up
 * so it reads as part of Amount; the existing radio pattern. */
.goal-form .goal-amount-from {
  margin: -0.3rem 0 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.goal-form .goal-amount-from[hidden] {
  display: none;
}

/* The figures under each choice, and the record line in the live title's
 * box or under What counts, change as the fields are typed in: tabular
 * figures, so the lines do not jitter. */
.goal-amount-from small,
.goal-readback-record,
.goal-scope-record,
.goal-flip {
  font-variant-numeric: tabular-nums;
}

/* Today's result changing with the new amount: news, so in the text
 * colour, under both choices since it holds for either. */
.goal-form p.hint.goal-flip {
  margin-top: -0.3rem;
  font-size: 0.8rem;
  color: var(--ink);
}

/* How many earlier days, weeks or months are met after a change that
 * checks them all again, and how many before: in the So far line's
 * style. */
.goal-readback-record {
  font-size: 0.85rem;
  color: var(--muted);
}

/* Save makes a new goal and ends this one: news, so in the text colour, at
 * the record line's size. */
.goal-readback-change {
  font-size: 0.85rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.goal-when-line {
  margin: 0;
}

/* Change sits in the sentence, so it keeps the line's height (every
 * button is 2.75rem tall otherwise); its invisible 44px square is in
 * activity-count.css. */
.goal-when-line button.link {
  min-height: 0;
}

.goal-when-pick {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.goal-when-pick select {
  flex: 1 1 12rem;
}

.goal-when-pick input[type='month'] {
  flex: 0 1 10rem;
  color-scheme: light dark;
}

.goal-dates {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.8rem;
}

.goal-date {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 1 1 9rem;
  min-width: 0;
}

.goal-date input {
  min-width: 0;
  flex: 1 1 auto;
}

.goal-dates .hint {
  flex-basis: 100%;
}

.goal-today-tag {
  font-size: 0.8rem;
  color: var(--muted);
}

.goal-rest {
  padding-left: 1.7rem;
}

.goal-facts {
  margin: 0.6rem 0 0;
  padding: 0.6rem 0 0;
  border-top: 1px solid var(--border);
  list-style: none;
  font-size: 0.85rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.goal-past .hint {
  margin: 0.2rem 0 0.4rem;
}

/* Organize: each goal on one line, its title, then the move buttons and
 * Archive at the right. A long title takes a line of its own, with the
 * buttons under it at the right. */
.goal-org {
  margin: 0;
}

.goal-org-list {
  list-style: none;
  margin: 0.4rem 0;
  padding: 0;
}

.goal-org-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.3rem 0.5rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border);
}

/* The title asks for its whole width on one line (`auto`). A title that
 * fits beside the buttons shares the row with them; a longer one has the
 * row to itself, the buttons wrapping onto the next line, so it is not
 * squeezed into a narrow column (docs/design/parts.md, Organize). */
.goal-org-title {
  flex: 1 1 auto;
  overflow-wrap: anywhere;
  min-width: 0;
}

/* The move buttons and Archive wrap as one group, never Archive alone. */
.goal-org-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
}

.goal-org-move {
  display: flex;
  gap: 0.3rem;
}

.goal-org-move button {
  min-width: 2.75rem;
  min-height: 2.75rem;
}

.goal-org-archive {
  flex: none;
}

/* An ended goal's end date, where the move buttons are on the others. */
.goal-org-ended {
  color: var(--muted);
  font-size: 0.9rem;
}

.goal-form .goal-scope,
.goal-form .goal-projects {
  margin: 0;
  padding: 0;
  border: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.goal-form legend {
  padding: 0;
  margin-bottom: 0.2rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.goal-form [hidden] {
  display: none;
}

/* Chosen projects' boxes, under its choice, set in from the choices. */
.goal-form .goal-projects {
  padding-left: 1.7rem;
}

.goal-form .goal-projects legend {
  margin: -1px;
}

/* Every goal's icon (`goal_icon.rs`) before its line in running text: a
 * little larger than the text, centred on it. Every place an icon shows
 * needs a size: an `svg` with none is drawn 300 by 150. */
.goal-icon {
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.2em;
}

/* Before its goal's title, larger again, so its star or its amount reads. */
.goal-title .goal-icon,
.goal-readback-title .goal-icon,
.goal-org-title .goal-icon {
  width: 1.6em;
  height: 1.6em;
  vertical-align: -0.45em;
}

/* The Goals switch in a log entry's sheet: the mark at the end of the
 * line, on or off as the box is. */
.goal-switch {
  margin: 0;
}

.goal-switch .proj-check .l {
  flex: 1 1 auto;
}

.goal-switch-mark {
  flex: none;
  display: flex;
}

.goal-switch-mark .event-mark {
  width: 2.6rem;
  height: 2.6rem;
}

.goal-switch-mark .event-mark.is-off,
.goal-switch:has(input[name="on"]:not(:checked)) .goal-switch-mark .event-mark:not(.is-off) {
  display: none;
}

.goal-switch:has(input[name="on"]:not(:checked)) .goal-switch-mark .event-mark.is-off {
  display: block;
}

/* The month box, styled as the text boxes beside it, its picker in the
 * page's own light or dark. */
.goal-form input[type="month"] {
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  padding: 0.55rem 0.7rem;
  font: inherit;
  min-width: 0;
}

.goal-form input[type="month"]:focus {
  border-color: var(--accent);
}

/* --- The goal sheet's Icon section (`goal_icon_pick.rs`) ------------------
 * Three rows of choices, each drawn as the icon it makes. The ticked
 * colour sets `--gi-stripe` on the section (the rules for each colour come
 * with the section, from `goal_icon.rs`), and every icon's stripe takes it;
 * every pattern is drawn in each picture and shown only while it is the
 * ticked one. So a colour or a pattern changes every icon here at once,
 * with no round trip. */
.goal-form .gi-pick {
  margin: 0.4rem 0 0;
  padding: 0;
  border: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.goal-form .gi-row {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

/* Each row's name, under the section's: smaller and lighter, so "Goal
 * icon" reads as the heading of the three. */
.goal-form .gi-row-name {
  font-size: 0.75rem;
  font-weight: 400;
  margin-bottom: 0.1rem;
}

.gi-opts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.gi-stripe {
  fill: var(--gi-stripe);
}

.gi-pat {
  display: none;
}

.gi-pick:has(input[name="icon_pattern"][value="stripes"]:checked) .gi-pat-stripes,
.gi-pick:has(input[name="icon_pattern"][value="dots"]:checked) .gi-pat-dots,
.gi-pick:has(input[name="icon_pattern"][value="checks"]:checked) .gi-pat-checks {
  display: inline;
}

/* A choice: its radio is hidden, and the whole tile is the target. The
 * ticked one has the accent's ring, and no tinted fill (an outlined chip
 * with a tinted fill is a look the owner turned down); the focus ring sits
 * outside it. Wide enough for "Project icon" on two lines. */
.gi-tile,
.gi-swatch {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.3rem 0.2rem 0.25rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: center;
}

.gi-tile {
  width: 4.1rem;
}

.gi-tile input,
.gi-swatch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.gi-tile .goal-icon {
  width: 2.25rem;
  height: 2.25rem;
}

.gi-name {
  font-size: 0.75rem;
  line-height: 1.15;
  color: var(--muted);
}

.gi-tile:hover,
.gi-swatch:hover {
  background: var(--surface-2);
}

.gi-tile:has(input:checked),
.gi-swatch:has(input:checked) {
  box-shadow: inset 0 0 0 2px var(--accent);
}

.gi-tile:has(input:checked) .gi-name,
.gi-swatch:has(input:checked) .gi-name {
  color: var(--ink);
}

.gi-tile:has(input:focus-visible),
.gi-swatch:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Colours: a round swatch each, 28 across inside a 36 target, so all eight
 * fit on one row of a phone's sheet. */
.gi-swatches {
  align-items: flex-start;
  gap: 0.1rem;
}

.gi-swatch {
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding: 0.2rem;
  justify-content: center;
}

.gi-dot {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px #2C2C2A;
}

/* A pattern's swatch: the stripe close up, as wide as two colours. Its
 * outline is the icon's (#2C2C2A), drawn by the wrapper, since an `svg`
 * draws no inset shadow over its own content. */
.gi-pat-swatch {
  display: block;
  width: 3rem;
  height: 1.5rem;
  border-radius: 6px;
  outline: 1.5px solid #2C2C2A;
  outline-offset: -1.5px;
}

/* --- A goal's own page (`goals_view/goal_page.rs`) -------------------------- */

/* Laid out as a project's page is (owner, 2026-10-29): the icon button and
 * the cog beside the title, a card like the book card (`.bk`, in
 * `projects-book.css`), then the same Writing card. */
.goal-page-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* The title takes the row, so the cog sits at its end whatever the
 * title's length. */
.goal-page-head h1 {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.goal-page-head .goal-icon {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
}

/* The icon is a button that opens the Goal icon popup, as a project's icon
 * opens its picker (`button.pi-open`, `projects-icons.css`). The goal's icon
 * keeps its own colours, so where a project's icon turns the accent colour
 * on hover, this one gets a ring in it (a reviewer found the button looked
 * inert). */
button.goal-icon-open {
  border-radius: var(--radius-sm);
}

button.goal-icon-open:hover {
  box-shadow: 0 0 0 1.5px var(--accent);
}

/* Where the goal stands: one figure, as big as a project's total. A
 * repeating goal's "Today 312 of 1,667 words" is longer than a total, so
 * it is a little smaller, and wraps on a phone. */
.bk-total.goal-now {
  font-size: 1.6rem;
}

/* What counts, beside the figure, as the project page has its goal beside
 * its total; under it on a phone. */
.goal-page-counts {
  margin: 0;
  text-align: right;
}

.goal-page-counts dt {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.goal-page-counts dd {
  margin: 0.1rem 0 0;
  overflow-wrap: anywhere;
}

/* The project's name is a button (`view::screen_link`), which centres a
 * name long enough to wrap. */
.goal-page-counts dd > * {
  text-align: inherit;
}

/* On a phone there is no room beside the figure, and What counts would sit
 * between the figure and its bar: the top row's wrapper steps aside
 * (`display: contents`) so What counts can follow the facts. */
@media (max-width: 480px) {
  .goal-card .bk-top {
    display: contents;
  }

  .goal-page-counts {
    order: 1;
    text-align: left;
  }
}

/* An archived goal: the line that says so, with Put back beside it. */
.goal-page-archived {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 1rem;
}

.goal-page-archived p,
.goal-page-archived form {
  margin: 0;
}

/* A goal in sprints still has its own small line chart: the Writing card
 * has no measure for sprints. */
.goal-page .goal-chart {
  height: 8rem;
  max-width: none;
}

.goal-page-lines {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-size: 0.88rem;
  color: var(--muted);
}

.goal-page-lines p {
  margin: 0;
}

/* Under the status line: a first week or month that began before the
 * goal's start date counts from its first day. */
.goal-page-note {
  margin: 0;
  font-size: 0.88rem;
  color: var(--muted);
}

.goal-page .goal-facts {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* A repeating goal's marks, with its streaks beside them where there is
 * room and under them on a phone. */
.goal-page-marks {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.6rem 2rem;
}

/* The marks keep the width they have on their own line. */
.goal-page-marks .goal-marks {
  flex: 0 1 15rem;
  margin: 0;
}

/* A weekly or monthly goal's weeks or months, newest first: as wide as its
 * columns, figures lined up (`pictures.rs::periods_table`). */
.goal-periods-table {
  align-self: flex-start;
  width: auto;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.goal-periods-table th,
.goal-periods-table td {
  padding: 0.3rem 1.4rem 0.3rem 0;
  text-align: left;
  white-space: nowrap;
}

.goal-periods-table .is-num {
  text-align: right;
}

.goal-periods-table th[scope='row'] {
  font-weight: 400;
}

.goal-periods-table thead th {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.goal-periods-table tbody tr + tr {
  border-top: 1px solid var(--border);
}

.goal-periods > button.link {
  align-self: flex-start;
}

/* The Goal amount column, shown only when the rows were checked against
 * more than one amount: muted, as the amount is context for the total. */
.goal-periods-table .is-amount {
  color: var(--muted);
}

/* With the fourth column, a phone has no room for the table's wide gaps:
 * narrower gaps, and the two-word heading may wrap. */
@container panel (max-width: 30rem) {
  .goal-periods-table:has(.is-amount) th,
  .goal-periods-table:has(.is-amount) td {
    padding-right: 0.9rem;
  }

  .goal-periods-table thead th.is-amount {
    white-space: normal;
  }
}

/* Beside the marks: the streak lines, then the goal's amounts under their
 * own heading, in the card's heading style (`pictures.rs::facts`). */
.goal-page-facts {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  min-width: 0;
}

.goal-amounts h3 {
  margin: 0 0 0.2rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.goal-amounts .goal-facts {
  font-variant-numeric: tabular-nums;
}

/* End goal at the foot of Edit goal, the end date it sets beside it (under
 * it on a phone), then Archive and Delete goal. */
.goal-sheet-foot {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.goal-sheet-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.7rem;
  margin: 0;
}

.goal-sheet-end .hint {
  margin: 0;
}

/* Archive and Delete goal, under the cards. */
.goal-page-acts {
  justify-content: space-between;
}

.goal-page-acts form {
  margin: 0;
}

/* The Goal icon popup: the Icon section of Edit goal on its own, under the
 * popup's heading, which already says "Goal icon". */
.goal-icon-sheet .gi-pick > legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* A dated word goal's plan on its page (`goals_view/plan.rs`): the amount
 * and pace to plan for, a table of what each day takes writing every day
 * and with days off, and the chart (`projects-plan.js`). */
/* The two inputs, one under the other, in a light box that keeps them apart
 * from the plan worked out from them (owner, 2026-10-31). */
.goal-plan-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 0;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.goal-plan-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

/* The label and its control on one line, read as a sentence: "I plan to
 * write − 50,000 words +". */
.goal-plan-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.7rem;
  min-width: 0;
}

.goal-plan-label {
  color: var(--ink);
}

.goal-plan-hint button.link {
  min-height: 0;
  padding: 0;
  vertical-align: baseline;
}

.goal-plan-stepper {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.goal-plan-stepper button {
  min-width: 2.2rem;
  font-size: 1rem;
}

/* The amount keeps its width as it changes, so − and + stay put. */
.goal-plan-amount {
  min-width: 8.5ch;
  text-align: center;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.goal-plan-hint {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}

/* The planned amount is not the saved goal's: the line saying so is ink,
 * with Reset beside it. */
.goal-plan-hint.goal-plan-saved {
  color: var(--ink);
}

.goal-plan-hint button.proj-small {
  min-height: 1.6rem;
  margin-left: 0.3rem;
  padding: 0.1rem 0.55rem;
}

/* As the Projects forms draw a drop-down (`.proj-form select`). */
.goal-plan-field select {
  width: auto;
  max-width: 100%;
  min-height: 2.4rem;
  padding: 0.45rem 0.6rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

.goal-plan-field select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.goal-plan-to-go {
  margin: 0;
  font-size: 0.9rem;
}

/* As wide as its figures, not the card: the two columns sit beside their
 * row names. */
.goal-plan .goal-plan-table {
  align-self: flex-start;
  width: auto;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.goal-plan-table th,
.goal-plan-table td {
  padding: 0.3rem 1.2rem 0.3rem 0;
  text-align: right;
  white-space: nowrap;
}

.goal-plan-table th[scope='row'] {
  text-align: left;
  font-weight: 400;
  color: var(--muted);
}

.goal-plan-table thead th {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--muted);
}

.goal-plan-table tbody tr + tr {
  border-top: 1px solid var(--border);
}

.goal-plan-words td {
  font-size: 1.15rem;
  font-weight: 600;
}

/* "(1 per week + 1 spare)" beside the 5 days off. */
.goal-plan-rule {
  font-size: 0.8rem;
  color: var(--muted);
}

.goal-plan-chart {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin: 0;
  min-width: 0;
}

/* Three panels: total, words a day, time a day. */
.goal-plan-canvas {
  position: relative;
  height: 24rem;
  min-width: 0;
}

@media (max-width: 480px) {
  .goal-plan-table th,
  .goal-plan-table td {
    padding-right: 0.6rem;
    white-space: normal;
  }
}
/* Project icons (`projects/icons/`, `projects/project/icon.rs`): the icon
 * beside a project's name on its page, its row on the settings sheet, the
 * icon on the Projects list, and the picker.
 *
 * An icon is `<svg class="pi">` drawn from the sprite with `<use>`. The
 * sprite's paths have no fill, so each icon is the colour of the text
 * around it, in every theme. */

.pi {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  fill: currentColor;
}

/* --- Beside the name, on the project's page ------------------------------ */

/* The icon is about 1.3 times the heading's size (the h1 is 1.05rem). The
 * button around it is larger, so it is easy to hit, and is pulled left by
 * the difference so the icon lines up with the screen's left edge. With no
 * icon, an empty dashed square of the same size holds the place, so the
 * name doesn't move when an icon is chosen. */
button.pi-open {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  min-height: 0;
  margin: 0 -0.25rem 0 -0.3125rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
}

.pi-open .pi,
.pi-blank {
  width: 1.375rem;
  height: 1.375rem;
}

.pi-blank {
  display: block;
  box-sizing: border-box;
  border: 1.5px dashed var(--muted);
  border-radius: var(--radius-sm);
}

button.pi-open:hover {
  color: var(--accent);
}

button.pi-open:hover .pi-blank {
  border-color: var(--accent);
}

/* On a touch screen the target reaches 44px, as every Projects button's
 * does, without making the heading's row taller. */
@media (pointer: coarse) {
  button.pi-open::after {
    content: "";
    position: absolute;
    inset: -0.375rem;
  }
}

/* --- The settings sheet's Icon row ---------------------------------------- */

.pi-value {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.pi-value .pi {
  width: 1.375rem;
  height: 1.375rem;
}

.pi-line-none {
  color: var(--muted);
}

/* --- The Projects list ----------------------------------------------------- */

/* The size of the name's own text, in its colour. */
.proj-row-name .pi {
  margin-right: 0.35em;
  vertical-align: -0.125em;
}

/* --- The picker ------------------------------------------------------------ */

/* The search box stays at the top while the icons scroll under it. */
.pi-find {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0.2rem 0 0.4rem;
  background: var(--surface);
}

/* A fixed height, so the picker stays where it is while a search shortens
 * the list: a sheet sized to its content re-centres on every key press. */
dialog.sheet.pi-sheet {
  height: min(85dvh, 44rem);
}

/* Drawn the way the panel's text boxes are (`activity-count.css`), which the
 * browser would otherwise leave as its own for a search box. */
.pi-sheet input[type="search"] {
  width: 100%;
  min-width: 0;
  padding: 0.55rem 0.7rem;
  background: var(--paper);
  color: var(--ink);
  color-scheme: dark;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

:root[data-theme="paper"] .pi-sheet input[type="search"] {
  color-scheme: light;
}

.pi-sheet input[type="search"]:focus {
  border-color: var(--accent);
}

.pi-sheet input[type="search"]::placeholder {
  color: var(--muted);
  opacity: 0.7;
}

.pi-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
}

button.pi-none {
  align-self: flex-start;
  min-height: 2.5rem;
  padding: 0.35rem 0.8rem;
  font-weight: 400;
}

.pi-group h3 {
  margin: 0.4rem 0 0.25rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Cells of about 40px with 28px icons: seven across at 375px wide, more on
 * a wider sheet, never wider than the sheet. */
.pi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(2.5rem, 1fr));
  gap: 0.25rem;
}

button.pi-choice {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 2.5rem;
  min-height: 0;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
}

button.pi-choice .pi {
  width: 1.75rem;
  height: 1.75rem;
}

/* Hidden by the search. Needed because `display: flex` above would
 * otherwise keep a hidden button on screen. */
button.pi-choice[hidden] {
  display: none;
}

/* The project's icon now, or No icon: a solid fill in the accent with
 * white on it, as a primary button has. The panel's buttons rest on
 * `--surface-2`, which is too close to the sheet's own colour to find one
 * icon among 211, and a fill doesn't rewrap the way bold would. */
button.pi-none[aria-current="true"],
button.pi-choice[aria-current="true"] {
  background: var(--accent);
  border-color: var(--accent-strong);
  color: var(--on-accent);
}

.pi-credit {
  font-size: 0.78rem;
}
/* The adjustment section of the Add a record and Starting count sheets
 * (`projects/adjust_view.rs`; docs/design/parts.md, section 6,
 * "Adjustments: the popup, as decided"). Settled with the owner in the
 * mockup (projects/sprinto/sprinto-mockups/adjustments/). */

.adj-body:empty {
  display: none;
}

.adj-in {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  min-width: 0;
}

.adj-say,
.adj-sum,
.adj-hint {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

/* A line's gist first (bold), its reason quieter after it. */
.adj-hint b,
.adj-say b {
  font-weight: 500;
  color: var(--ink);
}

.adj-why {
  color: var(--muted);
}

/* A link inside a sentence: the line keeps the sentence's height. */
.adj-say button.link,
.adj-links button.link {
  min-height: 0;
  padding: 0;
  vertical-align: baseline;
}

/* "Raise from the starting count instead" and "Make the 760 words a new
   chapter instead": one line each on a phone, side by side when they fit. */
.adj-links {
  margin: 0;
  font-size: 0.85rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
}

/* Until's four stops fit one line on a phone. */
.adj-seg button {
  white-space: nowrap;
  font-size: 0.88rem;
  padding-left: 0.3rem;
  padding-right: 0.3rem;
}

.adj-when {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.adj-when input[type="date"] {
  width: 9.5rem;
  padding: 0.2rem 0.4rem;
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
}

/* The key over the calendars: a real day's two figures, red, the shading
 * and the outline. */
.adj-key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
}

.adj-key-item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  color: var(--muted);
}

.adj-key-cell {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  flex: none;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  line-height: 1.1;
  font-size: 0.78rem;
}

.adj-key-swatch {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 3px;
}

.adj-key-range {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}

.adj-key-rec {
  box-shadow: inset 0 0 0 2px var(--accent);
}

.adj-key-neg {
  color: var(--bad);
  font-weight: 600;
}

.adj-months {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.adj-month-name {
  margin: 0 0 0.2rem;
  font-size: 0.85rem;
  font-weight: 500;
}

/* Smaller squares than the Projects calendar's: the sheet is 28rem wide. */
.adj-cal .ec {
  font-size: 0.78rem;
}

.adj-cal .ec-day {
  min-block-size: 3.3em;
}

/* The two figures stacked, centred in the square. The event's title is a
 * row by default, which put them side by side and widened the calendar
 * past the sheet. */
/* Two classes on the host: the library's stylesheet loads after this one
 * and wins a tie. */
.adj-cal.cal-host .ec-event-body,
.adj-cal.cal-host .ec-event-title {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  line-height: 1.1;
  white-space: nowrap;
}

.adj-cal .ec {
  min-width: 0;
}

.adj-months {
  min-width: 0;
  overflow-x: hidden;
}

/* A day: its new words (quiet) over its count (bold). Owner: the counts are
 * what to read, with the new words on top so the count reads as their
 * result. */
.adj-change {
  display: block;
  font-size: 0.85em;
  font-weight: 400;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.adj-count {
  display: block;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.adj-neg,
.adj-change.adj-neg {
  color: var(--bad);
  font-weight: 600;
}

.cal-host .ec-bg-event.adj-range {
  margin: 0;
  border-radius: 0;
  background-color: color-mix(in srgb, var(--accent) 22%, transparent);
}

.cal-host .ec-bg-event.adj-recday {
  margin: 1px;
  border-radius: 3px;
  background: none;
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* On a phone a day is about 47px wide. */
@media (max-width: 30rem) {
  .adj-cal .ec {
    font-size: 0.68rem;
  }
}

/* The update whose new words change, and the ones only raised. */
.adj-rows {
  display: grid;
  grid-template-columns: auto auto auto;
  justify-content: start;
  column-gap: 1rem;
  row-gap: 0.1rem;
  font-variant-numeric: tabular-nums;
  font-size: 0.88rem;
}

.adj-row {
  display: contents;
}

.adj-row[hidden] {
  display: none;
}

.adj-row-change,
.adj-row-total {
  text-align: right;
}

.adj-row-typed {
  grid-column: 1 / -1;
  margin-bottom: 0.3rem;
  font-size: 0.75rem;
  color: var(--muted);
}

.adj-note[hidden],
.adj-part[hidden] {
  display: none;
}

/* In the log: a record's adjustment and its note, under the part's name. */
.proj-log-adjust {
  display: block;
  flex-basis: 100%;
  font-size: 0.75rem;
  color: var(--muted);
}

.proj-log-adjust b {
  font-weight: 500;
  color: var(--ink);
}
/* One project's page (`project/book.rs`, `project/mod.rs`; owner,
 * 2026-10-26, "it needs some more drastic redesign"): the book card, the
 * Writing card and the goals at the foot. Joined last into `projects.css`.
 *
 * The book card leads with the total and the project's own goal, then one
 * plain bar toward that goal. A bar made of the parts was tried in a mockup
 * and read as days (owner, 2026-10-27), so each part has its own small bar
 * in its row instead, on one scale: the longest part. */

/* --- The book ------------------------------------------------------------- */

.bk {
  gap: 0.5rem;
}

.bk-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.3rem 1rem;
}

/* The total and its small line, one block, so the goal beside them wraps
 * under both on a phone rather than between them. */
.bk-head {
  display: flex;
  flex-direction: column;
  /* The card's own gap, so the small line sits where it did. */
  gap: 0.5rem;
  min-width: 0;
}

.bk-total {
  margin: 0;
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

/* The project's own goal: a quiet button that reads as the line it is. */
button.bk-goal {
  min-height: 0;
  padding: 0.2rem 0.4rem;
  margin-right: -0.4rem;
  background: none;
  border: 0;
  color: var(--muted);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

button.bk-goal:hover {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--muted);
  text-underline-offset: 0.2em;
}

/* The goal's icon (`goal_icon.rs`) before the book's goal. */
.bk-goal .goal-icon {
  width: 1.3em;
  height: 1.3em;
  vertical-align: -0.35em;
  margin-right: 0.25rem;
}

.bk-sub {
  margin: -0.2rem 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* The total opens the count editor: the number and the pencil after it
 * (owner, 2026-10-29, "put a pencil or something next to the word count to
 * show it's editable"). The pencil is quiet until pointed at; the number
 * itself takes the press too. */
.bk-total[data-count-open] {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
}

button.bk-total-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  min-height: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1;
}

.bk-total[data-count-open]:hover button.bk-total-edit,
button.bk-total-edit:focus-visible,
button.bk-total-edit[aria-expanded="true"] {
  color: var(--ink);
  border-color: var(--border);
  background: var(--paper);
}

/* The count editor (`by_hand::count_editor`): the sprint's count block
 * (`activity-count.css`, `.tally`) on the book card. Figures in one column
 * of a grid, read down as a sum, with a rule over the last; only the row
 * being typed in is drawn as a box. Narrower than the card, so the figures
 * stay beside their labels rather than at the card's far edge. */
.bk-count {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-width: 30rem;
  margin: 0.2rem 0 0.4rem;
}

/* Shut until the pencil is pressed. */
.bk-count[hidden] {
  display: none;
}

.bk-tally {
  display: grid;
  /* The label, the figure, the pencil and plus, and "Was 142". */
  grid-template-columns: minmax(0, 1fr) minmax(5rem, 9rem) auto minmax(4.5rem, auto);
  align-items: center;
  row-gap: 0.1rem;
  column-gap: 0.5rem;
}

.bk-tally-row {
  display: contents;
}

/* `display: contents` beats the `hidden` attribute's own rule. */
.bk-tally-row[hidden] {
  display: none;
}

.bk-tally-name {
  grid-column: 1;
  min-width: 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* The part picked, as the forms' drop-downs, in the label's place. */
select.bk-tally-pick {
  justify-self: start;
  max-width: 100%;
  min-height: 2.2rem;
  padding: 0.3rem 0.5rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.9rem;
}

select.bk-tally-pick:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* A figure that is not a box keeps the box's padding and a clear border,
 * so its digits line up with one that is. Two classes deep, over the
 * panel's own `input[type="text"]`. */
.bk-tally .bk-tally-num {
  grid-column: 2;
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  text-align: right;
  font: inherit;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  padding: 0.32rem 0.55rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
}

.bk-tally input.bk-tally-num {
  cursor: text;
}

.bk-tally input.bk-tally-num:not([readonly]):hover {
  border-color: var(--border);
}

.bk-tally input.bk-tally-num[readonly] {
  cursor: default;
}

.bk-tally[data-live="level"] input.bk-tally-num[data-field="level"],
.bk-tally[data-live="new"] input.bk-tally-num[data-field="new"],
.bk-tally[data-live="total"] input.bk-tally-num[data-field="total"] {
  background: var(--paper);
  border-color: var(--border);
}

.bk-tally input.bk-tally-num:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--paper);
}

.bk-tally input.bk-tally-num::selection {
  background: var(--accent);
  color: var(--on-accent);
}

.bk-tally-tools {
  grid-column: 3;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.bk-tally-tools > span {
  display: contents;
}

.bk-tally-tools > span[hidden] {
  display: none;
}

.bk-tally-edit,
.bk-tally-add {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  min-height: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1;
}

.bk-tally-add {
  font-size: 1.1rem;
}

/* Gone while the row of new words is open: it is the row it opens. Its
 * space is kept, so the figures do not move. */
.bk-tally-add[hidden] {
  visibility: hidden;
}

/* A target the size of a fingertip, laid over the space around the
 * drawing (`activity-count.css`, "Big enough to hit"). */
.bk-tally-edit::after,
.bk-tally-add::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 2.2rem);
  height: max(100%, 2.2rem);
  transform: translate(-50%, -50%);
}

.bk-tally-edit:hover,
.bk-tally-add:hover,
.bk-tally-edit:focus-visible,
.bk-tally-add:focus-visible {
  color: var(--ink);
  border-color: var(--border);
  background: var(--paper);
}

/* The part's count before, while its figure differs; red when it goes
 * down. In its own column, so nothing moves as it comes and goes. */
.bk-tally-was {
  grid-column: 4;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.bk-tally-was.is-down {
  color: var(--bad);
}

/* The rule the sum is drawn under, the width of the figures. */
.bk-tally-rule {
  grid-column: 2;
  border-top: 1px solid var(--muted);
  margin: 0.35rem 0 0.2rem;
}

/* The answer: the total, the number the reader came to change. */
.bk-tally .lead .bk-tally-name {
  color: var(--ink);
  font-weight: 600;
}

.bk-tally .lead .bk-tally-num {
  font-size: 1.15rem;
  font-weight: 700;
}

.bk-count-go {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.bk-count-go button {
  min-height: 2.4rem;
  max-width: 100%;
  font-variant-numeric: tabular-nums;
}

.bk-count-go button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* No hover on a touch screen: the boxes and the buttons beside them show
 * that they can be pressed. */
@media (pointer: coarse) {
  .bk-tally input.bk-tally-num:not([readonly]) {
    border-color: var(--border);
  }

  .bk-tally-edit,
  .bk-tally-add,
  button.bk-total-edit {
    color: var(--ink);
    border-color: var(--border);
  }
}

/* On a phone "Was 142" goes under the part's figure, keeping its line. */
@media (max-width: 520px) {
  .bk-tally {
    grid-template-columns: minmax(0, 1fr) minmax(5rem, 8rem) auto;
  }

  .bk-tally-was {
    grid-column: 2;
    text-align: right;
    padding-right: 0.55rem;
  }

  .bk-tally[data-summed="1"] .bk-tally-was:empty::before {
    content: "\00a0";
  }
}

/* The bar toward the goal: the goals' bar (`goals_view::bar`), taller here
 * where it is the card's one picture. */
.bk-progress .goal-bar {
  height: 10px;
  margin: 0.35rem 0 0;
  border-radius: 5px;
}

.bk-progress .goal-bar-fill {
  border-radius: 5px;
}

.bk-status {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1rem;
  margin: 0;
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.bk-pace {
  color: var(--muted);
}

.bk-pace.goal-behind {
  color: var(--amber);
}

/* The project's own daily goal, a line that opens its sheet. */
button.bk-habit {
  align-self: flex-start;
  min-height: 0;
  padding: 0.1rem 0;
  background: none;
  border: 0;
  color: var(--ink);
  font-weight: 400;
  font-size: 0.95rem;
  text-align: left;
  font-variant-numeric: tabular-nums;
}

button.bk-habit:hover {
  text-decoration: underline;
  text-decoration-color: var(--muted);
  text-underline-offset: 0.2em;
}

.bk-habit .goal-more {
  color: var(--muted);
}

/* --- Its parts -------------------------------------------------------------- */

.bk-parts {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.bk-parts-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.2rem;
}

.bk h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 500;
}

.bk-parts-done {
  margin-left: 0.5rem;
  font-weight: 400;
  font-size: 0.85rem;
  color: var(--muted);
}

.bk-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.bk-part + .bk-part {
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

/* One part: name, its length bar, its total, its sprint time, where it
 * stands. The whole row is the button that opens its Edit sheet. Every
 * column but the name has a fixed width, so the bars and the figures line
 * up from row to row. */
button.bk-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(3rem, 9rem) 6.5rem 5rem 6.5rem;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  min-height: 2.3rem;
  padding: 0.3rem 0.4rem 0.3rem calc(0.4rem + var(--depth, 0) * 1.1rem);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-weight: 400;
  font-size: 0.95rem;
  text-align: left;
  font-variant-numeric: tabular-nums;
}

button.bk-row:hover {
  background: var(--surface-2);
}

.bk-own .bk-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(3rem, 9rem) 6.5rem 5rem 6.5rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.3rem 0.4rem;
  color: var(--muted);
}

.bk-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A part's or task's code for chat beside its name (`codes_view.rs`,
 * docs/design/sprint-todos.md section 6): the name is cut short first, so
 * the code stays readable. */
.bk-name.has-code {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}

.bk-name-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bk-name .proj-code {
  flex: none;
}

.bk-len {
  height: 6px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  overflow: hidden;
}

.bk-len-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 50%, transparent);
}

.bk-figs,
.bk-time {
  text-align: right;
  white-space: nowrap;
}

.bk-time {
  font-size: 0.85rem;
  color: var(--muted);
}

.bk-state {
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
}

.bk-part.is-writing .bk-state {
  color: var(--ink);
}

.bk-part.is-empty .bk-name,
.bk-part.is-empty .bk-figs {
  color: var(--muted);
}

.bk-part.is-group > .bk-row {
  font-weight: 500;
}

/* The project's tasks: a "Tasks" row drawn like a part with parts, at the
 * bottom of the parts (owner, 2026-10-29), the tasks a level in under it.
 * A task has no count of its own (owner, 2026-10-31), so its row is its
 * name and Finished. */
.bk-task-list {
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.bk-tasks-group > .bk-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.3rem;
  padding: 0.3rem 0.4rem;
  font-size: 0.95rem;
}

/* A task's row has its name and Finished only: Finished in the parts'
 * state column, so it lines up with Complete and Writing above. */
.bk-task .bk-state {
  grid-column: 5;
}

/* Add a task, at the end of the Tasks row; on a phone it wraps under the
 * name rather than squeeze it. */
.bk-tasks-btns {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.4rem;
}

/* A task's sprint to-dos (docs/design/sprint-todos.md, section 3): the
 * tally is the fold's line, under the task's row and indented with it, so
 * it reads as the task's; the history opens under it as a table, so the
 * dates, amounts and lengths line up. */
.bk-task-hist,
.bk-task-none {
  padding: 0 0.4rem 0.3rem calc(0.4rem + var(--depth, 0) * 1.1rem);
  font-size: 0.82rem;
  color: var(--muted);
}

/* A task with no sprint to-dos: the same line as the tally, not a fold. */
.bk-task-none {
  margin: 0;
}

.bk-task-hist > summary {
  cursor: pointer;
  width: fit-content;
  font-variant-numeric: tabular-nums;
}

.bk-hist {
  width: 100%;
  margin-top: 0.3rem;
  border-collapse: collapse;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.bk-hist th {
  font-weight: 500;
  color: var(--muted);
  text-align: left;
}

.bk-hist th,
.bk-hist td {
  padding: 0.2rem 0.5rem 0.2rem 0;
  vertical-align: baseline;
}

.bk-hist tbody tr + tr td {
  border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
}

.bk-hist .num {
  text-align: right;
  white-space: nowrap;
}

.bk-hist .bk-hist-date,
.bk-hist .bk-hist-state {
  white-space: nowrap;
}

.bk-hist .bk-hist-state .task-box {
  vertical-align: -3px;
}

.bk-hist .muted {
  color: var(--muted);
  font-style: italic;
}

.bk-part.is-done .bk-name {
  color: var(--muted);
}

.bk-part .tb-task-linked,
.bk-part .proj-task-line,
.bk-part .bk-tasks-note,
.bk-part .bk-on-top {
  display: block;
  padding: 0 0.4rem 0.3rem calc(0.4rem + var(--depth, 0) * 1.1rem);
  font-size: 0.8rem;
  color: var(--muted);
}

.bk-part .part-below {
  margin: 0 0.4rem 0.3rem;
  font-size: 0.82rem;
  color: var(--amber);
}

.bk-more > summary {
  padding: 0.4rem;
  color: var(--muted);
  font-size: 0.9rem;
  cursor: pointer;
}

/* --- Writing ---------------------------------------------------------------- */

/* Chart or Calendar: the view on show pressed. */
.bk-views {
  display: inline-flex;
  margin-left: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.bk-views button {
  min-height: 2rem;
  padding: 0.25rem 0.75rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
}

.bk-views button[aria-pressed="true"] {
  background: var(--surface-2);
  color: var(--ink);
}

.bk-writing .proj-recent {
  margin: 0;
}

/* Writing's head: Chart | Calendar, then Added | Running total beside it,
 * then Share image, together at the right. On a phone they wrap onto a
 * second line whole, not squeezed into a cut-off word each. */
.bk-writing .proj-sec-head {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.bk-writing .proj-sec-head .bk-views {
  flex: none;
}

.bk-writing .proj-sec-head .proj-figure {
  margin-left: 0;
}

/* --- The other goals, at the foot -------------------------------------------- */

.bk-also {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.2rem 0.2rem 0;
}

.bk-also-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.bk-also h2 {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.bk-also-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.bk-also-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.6rem;
}

.bk-also-list .goal-open {
  font-weight: 500;
}

.bk-also-list .goal-status {
  font-size: 0.88rem;
  color: var(--muted);
}

.bk-also-list .goal-title .goal-icon,
.bk-also-list .goal-open .goal-icon {
  width: 1.2em;
  height: 1.2em;
  vertical-align: -0.3em;
  margin-right: 0.25rem;
}

/* --- Narrow ----------------------------------------------------------------- */

@container panel (max-width: 30rem) {
  .bk-total {
    font-size: 1.6rem;
  }

  /* Two lines a row: the name and where it stands; the bar, the total and
   * the sprint time. */
  button.bk-row,
  .bk-own .bk-row {
    grid-template-columns: minmax(0, 1fr) 6rem 4.4rem;
    grid-template-areas: "name name state" "len figs time";
    gap: 0.15rem 0.5rem;
  }

  .bk-name { grid-area: name; }
  .bk-figs { grid-area: figs; }
  .bk-time { grid-area: time; }
  .bk-len { grid-area: len; align-self: center; }
  .bk-state { grid-area: state; text-align: right; }

  /* A task's history, two lines a sprint: the date and the to-do; how it
   * went, then the amount and the length at the right. The date's column
   * has a fixed width, so the to-dos line up from sprint to sprint. The
   * column heads stay for screen readers. */
  .bk-hist thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .bk-hist,
  .bk-hist tbody { display: block; }
  .bk-hist tr {
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 1fr) auto auto;
    gap: 0.1rem 0.5rem;
    padding: 0.25rem 0;
  }
  .bk-hist tbody tr + tr { border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent); }
  .bk-hist tbody tr + tr td { border-top: 0; }
  .bk-hist td { padding: 0; }
  .bk-hist .bk-hist-name { grid-column: 2 / -1; }
  .bk-hist .bk-hist-state { grid-column: 1 / 3; }

  .bk-views {
    margin-left: 0;
  }
}
