@layer components {
  /* Projects

     The same row rhythm as a task list, one rail shorter: a project has a name,
     how far it has got, and a date. No reference — a project is called by
     its name in a way a task never is. */

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

  .project {
    position: relative;
    display: grid;
    /* Three rails, and the name is the first thing on the row.

       It used to open with an empty --rail-status, kept so that "a project list
       and a task list start at the same left edge" — which is the right
       sentence and the wrong 28px. A task row starts with its reference, and
       the reference is flush against the page's own left edge; the empty rail
       put the project's name 44px in, aligned with neither that nor the task
       title 136px further along. A column of names indented under a heading
       that is not, for a rail with nothing in it.

       The progress rail is wider than the date rail it replaced: it holds a bar
       and "12 of 30 done" where the old one held "18 tasks left". The date
       takes --rail-when, which is the rail a date takes everywhere else — it
       was in --rail-who, and 64px is enough for "24 Aug" and not for
       "12 Mar 2027". */
    grid-template-columns:
      minmax(0, 1fr) calc(var(--rail-when) + 4rem) var(--rail-when);
    align-items: center;
    column-gap: var(--space-2);
    min-height: var(--row-h);
    padding: var(--space) var(--space-2);
    margin-inline: calc(var(--space-2) * -1);
    border-radius: var(--radius);
    transition: background var(--transition);
  }

  .project:hover { background: var(--surface-hover); }
  .project:has(.project__name:focus-visible) { background: var(--surface-hover); }

  .project__name {
    font-size: var(--text-md);
    letter-spacing: var(--tracking-tight);
    color: var(--ink);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .project__name::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
  .project__name:hover { text-decoration: underline; text-decoration-thickness: 1.5px; }

  /* How far a project has got, in the rail that used to say how much was left
     A bar and two numbers: the bar is the shape, read at a glance down
     a column of projects, and the numbers are the fact. Wider than the date
     rail it sits next to, because "12 of 30 done" is what it has to hold. */
  .project__progress {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space);
    font-size: var(--text-sm);
    color: var(--ink-muted);
    white-space: nowrap;
  }

  .project__count { font-variant-numeric: tabular-nums; }

  .progress {
    display: block;
    inline-size: 3.5rem;
    block-size: 0.375rem;
    border-radius: var(--radius-sm);
    background: var(--surface-sunk);
    overflow: hidden;
  }

  /* The done part, in the ink the done mark uses — one colour for "finished"
     wherever the product says it. */
  .progress__done {
    display: block;
    block-size: 100%;
    background: var(--go);
    transition: inline-size var(--transition);
  }

  .project__due { display: flex; justify-content: flex-end; }

  /* Starting one is naming it, so the field is the form — and the field and its
     button stay on one line. .input carries width: 100%, which as a flex basis
     is wide enough to push the button onto a row of its own; min-width: 0 lets
     it shrink back to what is actually there. */
  .project-start { flex-wrap: nowrap; align-items: stretch; }
  .project-start__input { flex: 1 1 auto; width: auto; min-width: 0; }

  /* Capture, inside a project. The same shape as starting a project,
     because it is the same gesture one level down: a field, a button, one
     line. It sits above the work rather than below it, where the eye already
     is when the thought arrives. */
  .project-capture { flex-wrap: nowrap; align-items: stretch; }
  .project-capture__input { flex: 1 1 auto; width: auto; min-width: 0; }

  /* The brief, folded away.

     A project's page is visited to read the work far more often than to rewrite
     the brief, and a Trix editor standing between the name and the list is a
     screenful to scroll past on every one of those visits. Same summary as the
     archive below it, so the two folds on the page read as one idea. */
  .brief__summary {
    font-size: var(--text-sm);
    color: var(--ink-faint);
    cursor: pointer;
    padding: var(--space) 0;
    list-style-position: inside;
    transition: color var(--transition), var(--responds);
  }

  .brief__summary:hover { color: var(--ink-muted); }

  /* Three bands, one page. The heading is the timeline's, which is the
     product's existing word for "a section of a page that is a list".

     No margin between them. They are children of a stack--loose, so the 48px is
     already there; the 32px this used to add on top of it made the gap between
     two bands 80px — half again as far apart as any two sections anywhere else
     in the product, on the one page where the sections are the same kind of
     thing. (See design.md: the gap is stated once.) */

  /* Work blocked on somebody outside the team is still the project's work and
     is not something anybody can pick up this morning, so the band holding it
     is quieter than the one above it — present, and not competing. */
  .band--quiet .task-list { opacity: 0.85; }

  /* Finished business, present but folded away. The stack it sits in decides
     how far below the work it sits, like everything else on the page — it
     carried 16px of its own, which put the fold 48px down on a project's page
     and 32px down on the projects list, for the same fold. */

  .archive__summary {
    font-size: var(--text-sm);
    color: var(--ink-faint);
    cursor: pointer;
    padding: var(--space) 0;
    list-style-position: inside;
  }

  .archive__summary { transition: color var(--transition), var(--responds); }
  .archive__summary:hover { color: var(--ink-muted); }

  /* Finished business, unfolding

     ::details-content is the only handle a browser offers on the part of a
     <details> that is not its summary, and it is what makes this animatable
     without JavaScript holding the element open through its own close.

     Behind @supports on calc-size(), which is the piece that lets a height of
     zero interpolate to a height nobody has measured, and which shipped
     alongside ::details-content. Where either is missing the archive opens
     exactly as it always did — a degradation nobody can see, which is the only
     kind worth writing. */
  @supports (block-size: calc-size(auto, size)) {
    .archive::details-content,
    .brief::details-content {
      block-size: 0;
      overflow: hidden;
      opacity: 0;
      transition: block-size var(--transition-exit),
                  opacity var(--transition-exit),
                  content-visibility var(--transition-exit) allow-discrete;
    }

    .archive[open]::details-content,
    .brief[open]::details-content {
      block-size: calc-size(auto, size);
      opacity: 1;
      transition: block-size var(--transition-enter),
                  opacity var(--transition-enter),
                  content-visibility var(--transition-enter) allow-discrete;
    }
  }

  /* An archived project is a name and a way back, and nothing else: no progress
     to draw and no date left to keep. Given the live row's rails it took them
     anyway, so the name landed in the 28px lead and "Last year's catalogue" was
     drawn as "L..". */
  .project-list--archived .project { grid-template-columns: minmax(0, 1fr) auto; }
  .project-list--archived .project__name { color: var(--ink-muted); }

  /* A property that is read rather than set still has to sit on the same line
     as the ones that are. */
  .property__control--static {
    display: flex;
    align-items: center;
    color: var(--ink-muted);
  }
}
