/* SHARED·QUESTIONROW (1067) — the question a tool asks, as one row.
 *
 * WHAT IT IS. A stem (the question, in the display face), an optional why-line under it, and
 * ONE control slot. The control is always the CALLER'S — an answer-pill row (430), a text box
 * (1035), a number field, a duration picker. The row owns the stem, the why-line, the slot's
 * layout, and the rule between rows. It owns nothing inside the slot.
 *
 * EXTRACTED 2026-09-04 from workbench/portrait/_shared/portrait.css:513-520 (`.pt-f` /
 * `.pt-f-l` / `.pt-f-n`) + :532 (the Firsts-group override) — the source REPORT-509 row 16
 * names. Every value below is that source's, except the four deltas the report's §top table
 * states with their reasons (why-line ink, hairline width, the answer-slot layout, and the
 * 8px 603 loses).
 *
 * 🔴 WHY THE SLOT'S LAYOUT BELONGS TO THE ROW AND NOT TO THE CONTROL. Four hand-drawn copies
 * of this row ship today and all four declare the answer area IDENTICALLY:
 *   portrait  .pt-opts          display:flex; flex-wrap:wrap; gap:var(--space-8)
 *   603       .mtl-pb           display:flex;                 gap:var(--space-8)
 *   605       .pha-item .opts   display:flex; flex-wrap:wrap; gap:var(--space-8)
 *   410       .tkq .ans         display:flex; flex-wrap:wrap; gap:var(--space-8)
 * (603's is the same rule minus a wrap that cannot fire — its buttons are `flex:1`, basis 0.)
 * Four independent authors reaching the same three declarations is the definition of a shared
 * rule; leaving it with each control would keep four copies of it alive.
 *
 * ⚠️ NOT 442 QUESTIONLABEL — that is this row's STEM TYPE only, and its row has not landed on
 * master (`status:"todo"`, no css/render/wb paths in workbench/cards.json). Until it does, the
 * stem rule below is the whole of it; when 442 lands, `.qrow-s` composes its family instead of
 * declaring type of its own.
 * ⚠️ NOT 410 TRACKQ — the same job inside a slate BOX with a head and a destination footrow.
 * ⚠️ NOT 449 CONCERTINA — a question and its STORED VALUE, collapsible. Deferred detail, not
 * a question being asked.
 */

/* The row. A field, not a card — one level of carding (D-435); the surface holding these rows
   is already the card. The rule is a hairline BETWEEN rows, so the last one has none. */
.qrow { padding: var(--space-16) 0; border-bottom: 1px solid var(--border-hairline); } /* token-exception: a hairline */
.qrow:last-child { border-bottom: 0; }

/* The stem — the question itself, always rendered through renderStem() upstream, never a
   hardcoded "she"/"her". Display face at body size: a posed question, not a section head. */
.qrow-s { font-family: var(--font-display); font-size: var(--text-body);
  font-weight: var(--weight-600); line-height: var(--leading-150);
  color: var(--text-primary); margin: 0 0 var(--space-4); }

/* The why-line — optional, and absent means absent (D-541): no placeholder, no empty node. */
.qrow-w { font-family: var(--font-label); font-size: var(--text-label);
  letter-spacing: var(--tracking-05); line-height: var(--leading-150);
  color: var(--text-secondary); margin: 0 0 var(--space-8); }

/* The control slot — the caller's control goes in here, whatever it is. */
.qrow-c { display: flex; flex-wrap: wrap; gap: var(--space-8); }
/* The SLOT spaces its own children, by `gap` — so a control's own top margin is dropped. A
   control is written to stand alone in a block-flow form (the loggers' `.otherbox` carries
   `margin-top: 8`); inside the slot that margin lands on top of the gap and doubles it. The
   portrait was already fixing this by hand — `.pt-f .otherbox { margin-top: 0 }`, one consumer
   reaching into one foreign class — so the next control would have had to be found and patched
   the same way. Direct children only: what a control does inside itself is its own business. */
.qrow-c > * { margin-top: 0; }

/* THE FOCUS FLOOR THE SLOT GUARANTEES (D-422). A question that can be answered by keyboard has
   to show where the keyboard is, and the row is the only piece that is present whatever the
   control turns out to be. A control that declares its own ring keeps it — this stylesheet is
   loaded before the consumers' in web/index.html, so their equal-specificity rule wins the
   cascade (603's `.mtl-btn:focus-visible` does exactly that). This is the fallback for one that
   declares none, and there is one in the tree right now: the portrait's `.pt-opt` answer pills
   have no focus rule at all (`grep -n "pt-opt" workbench/portrait/_shared/portrait.css` → the
   base rule and `.is-on`, nothing else). */
.qrow-c > :focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

/* DOOR — a row inside the Firsts group. A first is not a status: the group is set off by its
   own eyebrow and one hairline above it, so the rows inside carry no rules of their own and
   sit tighter. (portrait.css:532, verbatim.) */
.qrow.is-door { border-bottom: 0; padding: var(--space-12) 0; }

/* FLUSH — the row is the only one in its own container, and that container already provides
   the inset: 603's milestone popover, where the row is the last thing in a padded card. No
   rule, no vertical padding of its own. Where the row sits in that container is the
   container's business, not the row's. */
.qrow.is-flush { border-bottom: 0; padding: 0; }
