/*
 * The board's own vocabulary, built on css-zero's components and color scales.
 * Everything here is a component class used by a partial in app/views -- feature
 * views never assemble these effects out of utilities (app CLAUDE.md, UI rules).
 */

/*
 * One tint per Stage value, so the status reads at a glance and survives dark
 * mode.
 *
 * The dark half changed in P10.5 round 2. It used to be the 900-shade of each
 * hue, which was designed against css-zero's near-black page; on the navy
 * backdrop those read as muddy blocks rather than as tints of a colour. Every
 * dark value is now an 18% wash of the hue's 400-shade over whatever is behind
 * it, with 200-shade text -- the same recipe for all eight, so no stage can
 * quietly drift louder than its neighbours.
 */
.stage-badge {
  --badge-background: light-dark(var(--zinc-100), rgb(from white r g b / .1));
  --badge-border-color: transparent;
  --badge-color: light-dark(var(--zinc-900), white);
}

.stage-badge--gathering {
  --badge-background: light-dark(var(--sky-100), rgb(from var(--sky-400) r g b / .18));
  --badge-color: light-dark(var(--sky-800), var(--sky-200));
}

.stage-badge--gate {
  --badge-background: light-dark(var(--amber-100), rgb(from var(--amber-400) r g b / .18));
  --badge-color: light-dark(var(--amber-800), var(--amber-200));
}

.stage-badge--building {
  --badge-background: light-dark(var(--violet-100), rgb(from var(--violet-400) r g b / .18));
  --badge-color: light-dark(var(--violet-800), var(--violet-200));
}

.stage-badge--client_review {
  --badge-background: light-dark(var(--orange-100), rgb(from var(--orange-400) r g b / .18));
  --badge-color: light-dark(var(--orange-800), var(--orange-200));
}

.stage-badge--launch {
  --badge-background: light-dark(var(--teal-100), rgb(from var(--teal-400) r g b / .18));
  --badge-color: light-dark(var(--teal-800), var(--teal-200));
}

.stage-badge--live {
  --badge-background: light-dark(var(--emerald-100), rgb(from var(--emerald-400) r g b / .18));
  --badge-color: light-dark(var(--emerald-800), var(--emerald-200));
}

.stage-badge--on_hold {
  --badge-background: light-dark(var(--red-100), rgb(from var(--red-400) r g b / .18));
  --badge-color: light-dark(var(--red-800), var(--red-200));
}

/* A board section: the template heading, then its task rows. */
.board-section {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-2);
}

.board-section__heading {
  align-items: center;
  column-gap: var(--size-2);
  display: flex;
  font-size: var(--text-lg);
  font-weight: var(--font-semibold);
}

/*
 * Round 2: the three emoji headings became drawn icons. The STORED heading keeps
 * its emoji -- it is the Asana template's string, byte-pinned by
 * InstantiationAudit against docs/asana-template.md -- so the glyph is stripped
 * for display only and replaced by this. Grayscale on purpose: David asked for
 * icons that read as UI, not as stickers.
 */
.board-section__icon {
  --icon-color: var(--color-text-subtle);
  --icon-size: 1.125rem;
}

/* A task row on the board: toggle, name, then its markers. */
.task-row {
  /*
   * P10.5 §5.1: `start`, not `center`. A long task name wraps to two lines, and
   * centring floats the circle to the middle of that block instead of sitting
   * against the first line. The name is its own flex item, so its second line
   * already begins under the text and never under the icon -- which is §5.1's
   * hanging indent, for free, rather than a text-indent hack.
   */
  align-items: start;
  column-gap: var(--size-2);
  display: flex;
  flex-wrap: wrap;
}

/* -------------------------------------------------- §5.1 completion toggle
 * Round 2. The circle used to be drawn by the button -- a border, a radius and a
 * separate check glyph inside it -- and it came out 20x30, an oval. Cause:
 * `.completion-toggle` and `.btn` both declare block-size at (0,1,0), the app
 * bundle is alphabetical, and button.css sorts after board.css, so
 * `block-size: auto` won and the box grew to its content. The same collision
 * silently overrode --icon-size (`.btn .icon` beat `.completion-toggle .check`),
 * which is why the check measured 16px when this file asked for 13.
 *
 * So the circle is no longer drawn by CSS at all: it IS the icon, mdi's
 * check-circle-outline when open and check-circle when done -- David's pick, and
 * the same family the frontend uses. A square icon in a plain, padding-free
 * button cannot come out an oval, and the two states are the same glyph size, so
 * the click target does not move. `.btn.completion-toggle` is (0,2,0) and pins
 * the box regardless of bundle order.
 */
.completion-toggle__wrap {
  display: inline-flex;
  flex-shrink: 0;
}

.completion-toggle__form { display: inline-flex; }

.btn.completion-toggle {
  --btn-background: transparent;
  --btn-border-color: transparent;
  --btn-box-shadow: none;
  --btn-hover-color: transparent;
  --btn-padding: 0;
  --btn-radius: var(--rounded-full);
  --icon-size: 1.25rem;

  align-items: center;
  aspect-ratio: 1;
  block-size: 1.25rem;
  display: inline-flex;
  inline-size: 1.25rem;
  justify-content: center;
  /* Optical alignment with the first line of a 1.5-line-height row. */
  margin-block-start: 0.0625rem;

  .completion-toggle__check {
    --icon-color: var(--color-border-dark);
    --icon-size: 1.25rem;
  }

  &:hover .completion-toggle__check {
    --icon-color: var(--color-text-subtle);
  }
}

/*
 * Done: the filled circle, in green. Hover LIGHTENS it (emerald-500) -- the old
 * rule set --btn-background under &:hover, which `.btn:hover` ignores, so the
 * fallback grey painted over the green and left a white check on light grey.
 * Nothing is painted behind the glyph now, so there is no grey to fall back to.
 */
/* `.btn.completion-toggle--done`, not `.completion-toggle--done`: the open rules
   above are (0,4,0) once `.btn` and `:hover` are counted, so a bare class here
   loses to them and a completed toggle turned grey under the cursor. */
.btn.completion-toggle--done {
  .completion-toggle__check { --icon-color: var(--emerald-600); }

  &:hover .completion-toggle__check { --icon-color: var(--emerald-500); }
}

/*
 * css-zero's tooltip example carries `class="popover bg-black text-reversed
 * text-xs pb-1 pi-2"` plus an inline style. Utilities repeated at 19 render sites
 * are exactly the "utility-class soup" the UI rules ban, and the inline style
 * cannot carry a CSP nonce -- so the whole look is one component class.
 */
.popover--tooltip {
  background-color: light-dark(var(--zinc-900), var(--zinc-100));
  color: light-dark(white, var(--zinc-900));
  font-size: var(--text-xs);
  padding: var(--size-1) var(--size-2);
}

.task-row--completed .task-row__name {
  color: var(--color-text-subtle);
  text-decoration: line-through;
}

/*
 * `flex: 1 1 0`, not `flex-grow: 1`. With flex-basis:auto the name's hypothetical
 * size is its MAX-content width, and flex line-breaking happens before shrinking
 * -- so a long name did not fit beside the toggle at that size and was pushed
 * whole onto the next line, leaving the circle stranded alone above it. Measured
 * before the fix on /tasks/594: 2 of 13 rows wrapped at 1280px, 3 of 13 at 800px
 * ("Domain: registration verified …" among them, which is how David found it).
 * A zero basis makes the name always fit on the toggle's line and wrap its own
 * text instead, and min-inline-size:0 keeps min-content from re-introducing the
 * same floor for a row with a long unbroken token.
 */
.task-row__name {
  flex: 1 1 0;
  min-inline-size: 0;
  overflow-wrap: anywhere;
}

.task-row__markers {
  align-items: center;
  column-gap: var(--size-1);
  display: flex;
  flex-wrap: wrap;
}

/* Subtasks hang off their parent and are visually subordinate to it. */
.subtask-list {
  display: flex;
  flex-direction: column;
  margin-inline-start: var(--size-6);
  row-gap: var(--size-1);
}

/* The definition list used for the client's 11 template fields. */
.field-grid {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-2);
}

.field-grid__row {
  column-gap: var(--size-4);
  display: flex;
  flex-wrap: wrap;
}

.field-grid__label {
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
  min-inline-size: 12rem;
}

/* Round 3: the value inherited the 16px body size while its own label sat at 14px,
   so every answer read a size larger than the card around it. Label and value are
   one row and they take one size. */
.field-grid dd {
  font-size: var(--text-sm);
}

/* A comment: who said it and when, then the body exactly as it was pasted. */
.comment__meta {
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

.comment__body {
  font-family: inherit;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Rendered markdown (MarkdownHelper, 2026-09-13). css-zero's reset strips list
 * bullets and heading sizes, so the few shapes a report uses get them back here,
 * scaled to sit inside a comment rather than compete with the page's own headings. */
.prose {
  overflow-wrap: anywhere;

  > * + * { margin-block-start: var(--size-2); }

  h1, h2, h3, h4, h5, h6 {
    font-weight: 600;
    line-height: 1.3;
    margin-block-start: var(--size-4);
  }

  h1 { font-size: var(--text-xl); }
  h2 { font-size: var(--text-lg); }
  h3, h4, h5, h6 { font-size: var(--text-base); }

  > :first-child { margin-block-start: 0; }

  ul, ol { padding-inline-start: var(--size-5); }
  ul { list-style: disc; }
  ol { list-style: decimal; }
  li + li { margin-block-start: var(--size-1); }

  a { color: var(--color-link, inherit); text-decoration: underline; }

  code {
    background-color: var(--color-surface);
    border-radius: var(--rounded-sm);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.9em;
    padding-inline: 0.25em;
  }

  pre {
    background-color: var(--color-surface);
    border-radius: var(--rounded-md);
    overflow-x: auto;
    padding: var(--size-3);

    code { background: none; padding: 0; }
  }

  blockquote {
    border-inline-start: 3px solid var(--color-border);
    color: var(--color-text-subtle);
    padding-inline-start: var(--size-3);
  }

  hr { border-block-start: var(--border) solid var(--color-border); }

  table {
    border-collapse: collapse;
    display: block;
    max-inline-size: 100%;
    overflow-x: auto;
  }

  th, td {
    border: var(--border) solid var(--color-border);
    padding: var(--size-1) var(--size-2);
    text-align: start;
  }
}

/* ------------------------------------------------------ P10.5 §7 answers page
 * The old .field-grid put the label and the answer on one flex row, so a short
 * answer sat beside its question and a long one wrapped underneath it -- a column
 * of answers with no column to run down. Label above, answer below, always, and
 * enough space between rows to tell one answer from the next.
 */
.answer-grid {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-5);
}

.answer-row {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  row-gap: var(--size-1);
}

.answer-row__label {
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

.answer-row__value {
  font-family: inherit;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
}

/* R2, 2026-09-13 (David): uploads are a gallery, not an inline flow. The flex-wrap
 * row this replaces put a thumbnail, a filename and a long note wherever they fit,
 * so one line held two images, the next held one, and captions trailed beside them.
 * Now each file is a stacked card (image → filename + size → note); one column on a
 * phone, two equal columns from 48rem. Grid rows stretch to their tallest card and
 * every image box shares one aspect ratio, so the two images in a row line up. */
.answer-row__files {
  align-self: stretch;
  display: grid;
  gap: var(--size-5) var(--size-4);
  grid-template-columns: minmax(0, 1fr);

  @media (min-width: 48rem) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.answer-file {
  display: flex;
  flex-direction: column;
  margin: 0;
  min-inline-size: 0;
  row-gap: var(--size-2);
}

/* `contain`, not `cover`: this page is where a Manager judges what a photo shows,
 * so nothing is cropped out of it. The surface fills the letterbox. */
.answer-file__image {
  aspect-ratio: 4 / 3;
  background-color: var(--color-surface);
  border-radius: var(--rounded-lg);
  border-width: var(--border);
  display: block;
  inline-size: 100%;
  overflow: hidden;

  img {
    block-size: 100%;
    display: block;
    inline-size: 100%;
    object-fit: contain;
  }

  &:hover { border-color: var(--color-selected-dark); }

  &:focus-visible { outline: 2px solid var(--color-selected-dark); outline-offset: 2px; }
}

.answer-file__caption {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-1);
}

.answer-file__name {
  align-items: baseline;
  column-gap: var(--size-2);
  display: flex;
  flex-wrap: wrap;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------- P10.5 §8 comments
 * A labelled checkbox that sits inline with its sentence: the round-answers form's
 * "this is my summary" box (usability spec 04; it was the comment form's kind box).
 */
.comment-kind {
  align-items: center;
  column-gap: var(--size-2);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--text-sm);
}

/* Edit/delete sit quietly in the meta row until the row is hovered or focused --
   they are corrections, not primary actions, and a delete icon on every comment
   reads as an invitation. Always visible to keyboard focus. */
.comment__actions {
  align-items: center;
  column-gap: var(--size-1);
  display: inline-flex;
  opacity: 0;
  transition: opacity var(--time-100);
}

.comment:hover .comment__actions,
.comment:focus-within .comment__actions {
  opacity: 1;
}

@media (hover: none) {
  .comment__actions { opacity: 1; }
}

.comment__delete { display: inline-flex; }

/* The round-answers help popover, on the client page's reply form since usability
   spec 04. A width, not max-content, so the instructions wrap instead of running off
   the screen. */
.round-answers-help {
  --popover-size: min(30rem, calc(100vw - 2rem));
  display: none;
  padding: var(--size-3);

  &:popover-open { display: flex; flex-direction: column; gap: var(--size-2); }
}

.round-answers-help__list {
  font-size: var(--text-sm);
  list-style: disc;
  padding-inline-start: var(--size-4);

  & li + li { margin-block-start: var(--size-1); }
}

/*
 * Usability spec 02 §2.4 -- the Next step card, under the progress bar on the
 * client page (clients/_next_step). A washed panel inside the header card rather
 * than a card of its own: it answers the progress bar's "how far", so it reads as
 * part of the same block.
 */
.next-step {
  background-color: var(--surface-wash);
  border-radius: var(--rounded-lg);
  border-width: var(--border);
  display: flex;
  flex-direction: column;
  margin-block-start: var(--size-4);
  padding: var(--size-3);
  row-gap: var(--size-3);
}

.next-step__group {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-1);
}

.next-step__label {
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.next-step__primary {
  align-items: baseline;
  column-gap: var(--size-2);
  display: flex;
  flex-wrap: wrap;
}

/* A flex <ul> would drop its markers, so the rows are spaced by margin. */
.next-step__list {
  list-style: disc;
  padding-inline-start: var(--size-5);
}

.next-step__list > li + li { margin-block-start: var(--size-1); }


/* Usability spec 01 §2.3 -- one sentence under each board heading. */
.board-section__lede {
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

/*
 * Usability spec 01 §2.2 -- "About this step" (tasks/_about_step): the guide's three
 * written headings and the generated fourth, a size under the card's own title.
 */
.about-step {
  display: flex;
  flex-direction: column;
  row-gap: var(--size-2);
}

.about-step__heading {
  font-weight: var(--font-semibold);
  margin-block-start: var(--size-2);
}

.about-step__strip {
  border-block-start-width: var(--border);
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
  margin-block-start: var(--size-2);
  padding-block-start: var(--size-2);
}
