/* home.css — owned by new-ux lane 11; see docs/APP.md "The split stylesheets". */

/* ============================================================
 * The Home board (new-ux lane 11; spec 11 B1-B7, CONTRACTS §7.8)
 *
 * Everything AppCtrlHome paints at #/: the greeting block, the
 * credits line, the prompt line, the starter chips, the unread and
 * recent conversation chip rows, and the four-column board —
 * decisions, working, next, done.  The vocabulary is `hb-`
 * throughout, and every colour, size, family, radius and shadow
 * resolves through the token registry style.css declares: no literal
 * colours, no asset references, no stacking rung (the board is flat;
 * the slip and the drawers stack through AppSurface).  Two
 * conditional blocks close the sheet — the 720px phone block that
 * realises the §7.8 stack over the fixed DOM sequence, and the
 * reduced-motion guard that stills the pulse.  Edges are drawn with
 * the longhands (border-width / border-style / border-color): the
 * phone block's two `order` declarations are counted by a source
 * pin, and the shorthand's name would muddy a naive count.
 * ============================================================ */

/* --- The greeting block and the credits line (B1, B6) ------------- */

/* The gap below the greeting is the hero section's own (dc.html :56,
   `gap:22px`), which no --s-* rung holds; .tl-head :24 spends the same
   literal for the same reason.  --s-3's 12px left the rule-to-composer
   run at 101px where the mockup's is 111 (review round 6, R6-V1-1). */
.hb-greeting {
    margin: 0 0 22px;
}

.hb-greeting h1 {
    margin: 0;
    font-size: var(--fs-hero);
    line-height: 1.1;
    text-wrap: pretty;
}

/* The stored assistant greeting, one line under the h1 in the serif
   correspondence face. */
.hb-greeting-line {
    margin: var(--s-2) 0 0;
    font-family: var(--font-text);
    font-size: var(--fs-lede);
    line-height: 1.5;
    color: var(--c-ink-soft);
}

/* The one quiet credits line: balance, the burn line, the Account link. */
.hb-credits {
    margin: 0 0 var(--s-5);
    font-size: var(--fs-meta);
    letter-spacing: 0.02em;
    color: var(--c-ink-muted);
    font-variant-numeric: tabular-nums;
}

.hb-credits a {
    margin-left: var(--s-2);
    color: var(--c-accent);
    text-decoration: none;
}

.hb-credits a:hover,
.hb-credits a:focus-visible {
    text-decoration: underline;
}

/* --- The prompt line (B2) ------------------------------------------ */

.hb-composer {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 10px;
    padding: 8px 8px 8px 18px;
    background: var(--c-sand-card);
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-rule-strong);
    border-radius: var(--r-10);
    box-shadow: var(--sh-slip);
    transition: border-color var(--t-base), box-shadow var(--t-base);
}

/* Focus ADDS the ring; dc.html :61 carries `box-shadow:0 1px 3px` with no
   focus style at all, so the resting --sh-slip stays under it (R6-V1-4;
   .nt-brief-card:focus-within is the twin and moves with it). */
.hb-composer:focus-within {
    border-color: var(--c-gold);
    box-shadow: var(--sh-slip), var(--focus-ring);
}

.hb-composer-input {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    padding: 8px 0;
    font-family: inherit;
    font-size: var(--fs-base);
    /* dc.html :62 declares no line-height, so the field is one normal
       line + 8px 0 and the 38px send button (:63) sets the bar's 56px.
       A 1.5 rung made the field 40px and the bar 58 (R6-V1-6). */
    line-height: normal;
    color: var(--c-ink);
    background: transparent;
    border-width: 0;
    resize: none;
}

.hb-composer-input::placeholder {
    color: var(--c-ink-muted);
}

/* The form carries the focus ring for the pair (the rule above), so
   the field's own outline steps aside inside it. */
.hb-composer-input:focus {
    outline: none;
}

.hb-composer-send {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    font-family: inherit;
    font-size: var(--fs-lede);
    color: var(--c-sand-card);
    background: var(--c-accent);
    border-width: 0;
    border-radius: var(--r-7);
    cursor: pointer;
    transition: background var(--t-base);
}

.hb-composer-send:hover {
    background: var(--c-accent-hover);
}

.hb-composer-send:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}

.hb-composer-send:disabled,
.hb-composer-input:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* --- The starter chips (B5, R38) ----------------------------------- */

.hb-starters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin: 0;
}

.hb-starter {
    padding: 5px 10px;
    font-family: inherit;
    font-size: var(--fs-13);
    line-height: 1.3;
    text-align: left;
    color: var(--c-ink-soft);
    background: transparent;
    border-width: 1px;
    border-style: dashed;
    border-color: var(--c-rule-strong);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: border-color var(--t-base), color var(--t-base);
}

/* dc.html :83 hovers the starter's border to the mockup's hover rung,
   `--c-gold-hover`, and its text to the ink — not to the resting gold
   the border was already near.  Every site that spends the rung is
   recorded in HOVER_TINT_SITES with the dc.html line it came from. */
.hb-starter:hover,
.hb-starter:focus-visible {
    color: var(--c-ink);
    border-color: var(--c-gold-hover);
}

.hb-starter:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}

/* --- The conversation chip rows (B3) ------------------------------- */

.hb-unread,
.hb-recent {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin: 0 0 10px;
}

.hb-eyebrow {
    margin: 0 2px 0 0;
    font-size: var(--fs-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--c-ink-muted);
}

/* "New from your assistants" in gold-as-text (the token that clears
   the text floor; --c-gold itself is decorative only). */
.hb-unread .hb-eyebrow {
    color: var(--c-burnished-text);
}

.hb-chip-row {
    display: contents;
}

.hb-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    max-width: 100%;
    padding: 5px 10px 5px 7px;
    font-family: inherit;
    font-size: var(--fs-13);
    line-height: 1.3;
    text-align: left;
    color: var(--c-ink);
    background: var(--c-sand-card);
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-rule);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: border-color var(--t-base);
}

/* An unread chip's hairline is gold-tinted, the recent row's is the plain
   rule: the mockup gives the unread button the literal #e6d3a8 and the
   recent button the page's rule colour (dc.html :69, :77), pinned by
   tests/test_app_home_frontend.py::
   test_unread_chip_takes_the_mockups_gold_hairline. */
.hb-unread .hb-chip {
    border-color: var(--c-gold-rule);
}

/* dc.html :69 and :77 both hover the chip's border to the mockup's
   hover rung, `--c-gold-hover`. */
.hb-chip:hover,
.hb-chip:focus-visible {
    border-color: var(--c-gold-hover);
}

.hb-chip:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}

.hb-chip-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The unread count: a small accent pill — the mockup's 16px minimum
   square with 4px of side padding and 10px/700 type (dc.html :69),
   pinned by tests/test_app_home_frontend.py::
   test_unread_count_pill_is_the_mockups_box. */
.hb-chip-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    font-size: var(--fs-10);
    font-weight: 700;
    color: var(--c-sand-card);
    background: var(--c-accent);
    border-radius: var(--radius-pill);
    font-variant-numeric: tabular-nums;
}

/* The recent chip's gold dot. */
.hb-recent .hb-chip {
    gap: 6px;
    padding: 5px 10px;
}
.hb-chip-dot {
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    background: var(--c-gold);
    border-radius: 50%;
}

/* The thinking dots of a pending conversation: three dots pulsing in
   turn, the outer two drawn as pseudo-elements. */
.hb-chip-pending {
    position: relative;
    display: inline-block;
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    margin: 0 var(--s-2);
    background: var(--c-ink-muted);
    border-radius: 50%;
    animation: hb-pulse 1.2s ease-in-out infinite;
}

.hb-chip-pending::before,
.hb-chip-pending::after {
    content: '';
    position: absolute;
    top: 0;
    width: 5px;
    height: 5px;
    background: var(--c-ink-muted);
    border-radius: 50%;
    animation: hb-pulse 1.2s ease-in-out infinite;
}

.hb-chip-pending::before {
    left: -8px;
    animation-delay: -0.4s;
}

.hb-chip-pending::after {
    left: 8px;
    animation-delay: 0.4s;
}

/* The chip rows' loading skeleton, held to a chip row's width. */
.hb-chips-loading {
    max-width: 480px;
    margin: 0 0 var(--s-4);
}

/* --- The board and its columns (B4) -------------------------------- */

/* A flex column with the mockup's 40px section gap (digest 70). */
.hb-board {
    display: flex;
    flex-direction: column;
    gap: 40px;
    margin: var(--s-6) 0 0;
}

.hb-column {
    min-width: 0;
}

.hb-column-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-3);
    margin: 0 0 14px;
    padding: 0 0 10px;
    border-bottom-width: 1px;
    border-bottom-style: solid;
    border-bottom-color: var(--c-rule-strong);
}

.hb-column-head h2 {
    margin: 0;
    font-size: var(--fs-section);
    line-height: 1.2;
}

/* "Done recently" reads a rung quieter (digest 102). */
.hb-column[data-board-column="done"] {
    padding-top: var(--s-5);
    border-top-width: 1px;
    border-top-style: solid;
    border-top-color: var(--c-rule);
}
.hb-column[data-board-column="done"] .hb-column-head {
    padding-bottom: 0;
    border-bottom-width: 0;
}
.hb-column[data-board-column="done"] .hb-column-head h2 {
    font-size: var(--fs-title);
    color: var(--c-ink-muted);
}

/* The count badges sit inline with their heading. */
.hb-count,
.hb-next-badge {
    font-size: var(--fs-meta);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--c-ink-muted);
    font-variant-numeric: tabular-nums;
}

.hb-column[data-board-column="decisions"] .hb-count {
    color: var(--c-accent);
}

.hb-column[data-board-column="working"] .hb-count {
    color: var(--c-burnished-text);
}
.hb-next-badge {
    color: var(--c-ink-muted);
}

/* The done head's links: "All tasks →" at the far end, "See all →"
   beside it when more than six rows exist. */
.hb-all-tasks,
.hb-done-more {
    font-size: var(--fs-13-5);
    color: var(--c-ink-muted);
    text-decoration: none;
}

.hb-all-tasks {
    margin-left: auto;
}

.hb-all-tasks:hover,
.hb-done-more:hover,
.hb-all-tasks:focus-visible,
.hb-done-more:focus-visible {
    color: var(--c-accent);
    text-decoration: underline;
}

/* The card stacks: every deck — decisions, working and Next alike —
   is the mockup's 320px grid with 14px gaps (dc.html :966 at the
   active `comfortable` density fixed on :898; the 260px / 10px pair is
   the compact branch the app never renders — fidelity audit
   2026-09-11, row 40).  Pinned, values derived from the mockup, by
   tests/test_app_home_frontend.py::test_desktop_deck_grid_is_the_mockups,
   which derives every declaration of that string — `align-items: start`
   among them, so a card keeps its own height instead of stretching to
   its row's tallest neighbour (fidelity audit 2026-09-11, review round
   2, V1-A).  The done column overrides this stack to a list below. */
.hb-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 14px;
    align-items: start;
}

/* The shared loading skeleton and the §4.1 empty line span the stack. */
.hb-cards > [data-loading] {
    grid-column: 1 / -1;
}

/* The Next deck's suggested cards on Home: the mockup draws them as
   dashed, unlifted, spine-less cards (dc.html :155) with a sentence-case
   muted reason beside the mark (:157), a 20px text-Caslon title over a
   14px muted line (:161-162) and "Start this" / "Not now" side by side
   as 13.5px controls (:163-171).  Fidelity audit 2026-09-11, rows
   34/36/37/39.  Attribute hooks only: the card's classes are lane 08's. */
.hb-cards-next > [data-card] {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 8px;
    padding: 18px 20px;
    border-width: 1px;
    border-style: dashed;
    border-color: var(--c-rule-strong);
    border-radius: var(--radius);
    box-shadow: none;
}
.hb-cards-next > [data-card]::before {
    display: none;
}
/* A blocked card keeps the card ground (dc.html :155 draws every
   suggested card on `cardBg`; row 38) — the soft fill is lane 08's. */
.hb-cards-next > [data-card][data-card-ready="false"] {
    background: var(--c-sand-card);
}
/* Two inline rows out of the renderer's flat children: mark + reason
   (dc.html :156-158) and the primary control + "Not now" (:163-171);
   the title and the line keep a row each. */
.hb-cards-next > [data-card] > * {
    flex: 1 1 100%;
}
.hb-cards-next > [data-card] > [data-mark] {
    flex: 0 0 auto;
}
.hb-cards-next > [data-card] > [data-card-reason] {
    flex: 1 1 0;
    min-width: 0;
}
.hb-cards-next > [data-card] > [data-card-start],
.hb-cards-next > [data-card] > [data-card-needs],
.hb-cards-next > [data-card] > [data-card-dismiss] {
    flex: 0 0 auto;
}
/* The integration pill keeps the mockup's own width on its own row
   (dc.html :160 draws it `align-self:flex-start` in a column card):
   the flat wrap-row layout gives every child a full line, so the pill
   sheds the stretch and pushes the rest of its line away with an end
   margin the card's `overflow: hidden` clips. */
.hb-cards-next > [data-card] > [data-card-needs-pill] {
    flex: 0 0 auto;
    margin-inline-end: 100%;
}
.hb-cards-next > [data-card] [data-card-reason] {
    font-size: var(--fs-meta);
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--c-ink-muted);
}
.hb-cards-next > [data-card] [data-card-title] {
    font-family: var(--font-text);
    font-size: var(--fs-title);
    line-height: 1.25;
}
.hb-cards-next > [data-card] [data-card-sub] {
    font-size: var(--fs-ui);
    line-height: 1.4;
    color: var(--c-ink-muted);
}
.hb-cards-next > [data-card] [data-card-start],
.hb-cards-next > [data-card] [data-card-needs] {
    padding: 8px 13px;
    font-size: var(--fs-13-5);
    font-weight: 500;
    border-radius: var(--r-6);
}
.hb-cards-next > [data-card] [data-card-dismiss] {
    font-size: var(--fs-13-5);
    letter-spacing: 0;
    text-transform: none;
    color: var(--c-ink-muted);
}

.hb-empty {
    grid-column: 1 / -1;
    margin: 0;
    padding: var(--s-3) 0;
    font-size: var(--fs-body);
    color: var(--c-ink-muted);
}

/* The done column is a list of compact rows, not a card grid.  As a
   flex column it reads the deck's `align-items: start` as a cross-axis
   rule, so it restores `stretch` and its rows stay full width. */
.hb-column[data-board-column="done"] .hb-cards {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
}

/* --- The working card (B5) ----------------------------------------- */

/* The whole card is the link to task detail.  A grid whose named
   areas, read down the rows below: the head row, then the
   conversation chip, then the title and the status line beside the
   progress ring, then the status chip on a row of its own at the
   foot.  That is the mockup's order — the chip sits between the head
   row and the ring (dc.html :133-135), and the mockup draws no status
   chip at all, so the app's gets the foot row rather than a place in
   the ring's row.  The pulse takes no area of its own: it shares
   `ring` with the ring it breathes around (`.hb-pulse` below).  The
   grid is placement, not source order — `taskCardEl` appends the
   conversation chip last (`app_ctrl_home.js`, `conversationChipEl()`)
   and the `conv` row lifts it to second.  An absent part leaves its
   area empty, so a card without marks, a ring or a chip keeps the
   same frame.

   Measured in Chromium on a 380px-wide card: head at y=20, the chip
   at y=55, ring/pulse/title at y=88, the status line at y=119 and the
   status chip at y=152 — five rows, three declared columns of which
   the third measures 0px because no area occupies it alone (fidelity
   audit 2026-09-11, review round 8, R8-CODE-4).

   The head — marks, source line, "Started …" — is ONE element
   spanning every column (`.hb-head` below), the mockup's own
   arrangement (dc.html :129-132 a full-width row, :136-142 the ring
   beside the title column).  While its three parts sat in the grid's
   own columns they shared the ring's track, so a ringed card indented
   its head by 59px and three cards in one deck opened their head line
   at three different x (fidelity audit 2026-09-11, review round 2,
   V1-B). */
.hb-task-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "head head head"
        "conv conv conv"
        "ring title title"
        "ring line line"
        "status status status";
    align-items: start;
    column-gap: 0;
    row-gap: var(--s-1);
    padding: 18px 20px;
    color: inherit;
    text-decoration: none;
    background: var(--c-sand-card);
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-rule);
    border-top-width: 2px;
    border-top-color: var(--c-gold);
    border-radius: var(--radius);
    box-shadow: var(--sh-slip);
    transition: border-color var(--t-base), transform var(--t-fast), box-shadow var(--t-slow);
}

/* dc.html :128 hovers the card's border to the mockup's hover rung,
   `--c-gold-hover` — one shade on all four edges, the gold top rule
   included — plus the 2px lift.  The app used to darken the sides to
   `--c-rule-strong` and hold the top on the resting gold, which is two
   colours where the mockup draws one. */
.hb-task-card:hover,
.hb-task-card:focus-visible {
    border-color: var(--c-gold-hover);
    transform: translateY(-2px);
    box-shadow: var(--sh-lift);
}

.hb-task-card:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
}

/* The head row (dc.html :129): the marks 8px from the source line,
   "Started …" pushed to the card's right edge — the row itself spans
   the card, so it opens at the padding edge with or without a ring
   below it. */
.hb-task-card .hb-head {
    grid-area: head;
    display: flex;
    align-items: center;
    gap: var(--s-2);
    min-width: 0;
}

.hb-task-card .hb-marks {
    display: inline-flex;
    align-items: center;
}

/* The marks stack with the mockup's −7px overlap (digest 84). */
.hb-task-card .hb-marks [data-mark] {
    outline: 2px solid var(--c-sand-card);
}
.hb-task-card .hb-marks [data-mark] + [data-mark] {
    margin-left: -7px;
}

.hb-task-card .hb-source {
    margin: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--fs-meta);
    letter-spacing: 0.02em;
    color: var(--c-ink-muted);
}

.hb-task-card .hb-when {
    margin: 0 0 0 auto;
    padding-left: var(--s-3);
    font-size: var(--fs-meta);
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: var(--c-ink-muted);
}

.hb-task-card .hb-title {
    grid-area: title;
    margin: 6px 0 0;
    font-size: var(--fs-title);
    line-height: 1.25;
    overflow-wrap: anywhere;
}

.hb-task-card .hb-line {
    grid-area: line;
    margin: 0;
    font-size: var(--fs-ui);
    line-height: 1.4;
    color: var(--c-ink-muted);
}

/* The status chip: "Queued" in the muted register, "Needs your input"
   in gold-as-text, both on the soft fill. */
.hb-task-card .hb-status {
    grid-area: status;
    justify-self: start;
    margin-top: var(--s-2);
    padding: var(--s-1) var(--s-2);
    font-size: var(--fs-micro);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--c-ink-muted);
    background: var(--c-soft);
    border-radius: var(--radius-pill);
}

.hb-task-card[data-display-status="needs_input"] .hb-status {
    color: var(--c-burnished-text);
}

/* The progress ring (mockup 137): a 44px conic fill over the soft
   track, the 34px inner disc drawn as a second background layer in
   the card ground so the percentage sits on it without a stacking
   rung.  The fill stop is the `--hb-progress` custom property the
   controller sets inline — the one inline style the board emits —
   and reads 0% until it does. */
.hb-task-card .hb-ring {
    --hb-progress: 0%;
    grid-area: ring;
    align-self: center;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: 6px 14px 0 0;
    font-size: var(--fs-micro);
    font-weight: 500;
    color: var(--c-ink);
    font-variant-numeric: tabular-nums;
    border-radius: 50%;
    background:
        radial-gradient(circle closest-side, var(--c-sand-card) 76%, transparent 78%),
        conic-gradient(var(--c-gold) var(--hb-progress), var(--c-soft) 0);
}

/* The live pulse (B5): the mockup's 1px gold ring breathing 4px
   outside the progress disc (dc.html :137, `_pulse` :1114) — it shares
   the ring's grid area and is hidden on `queued`, which draws no disc;
   stilled and hidden under reduced motion. */
.hb-task-card .hb-pulse {
    grid-area: ring;
    justify-self: start;
    align-self: center;
    width: 52px;
    height: 52px;
    margin: 6px 0 0 -4px;
    pointer-events: none;
    background: transparent;
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-gold);
    border-radius: 50%;
    animation: hb-pulse 1.6s ease-in-out infinite;
}
.hb-task-card[data-display-status="queued"] .hb-pulse {
    display: none;
}

@keyframes hb-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.85); }
}

/* The conversation chip, the card's second row — under the head and
   above the ring, where the mockup draws it (dc.html :133-135): a
   button inside the link, a gold dot and the title in gold-as-text. */
.hb-task-card .hb-conv {
    grid-area: conv;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    max-width: 100%;
    margin-top: var(--s-3);
    padding: 3px 9px;
    font-family: inherit;
    font-size: var(--fs-meta);
    line-height: 1.3;
    text-align: left;
    color: var(--c-burnished-text);
    background: var(--c-sand-card);
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-rule);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: border-color var(--t-base);
}

.hb-task-card .hb-conv::before {
    content: '';
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    background: var(--c-gold);
    border-radius: 50%;
}

/* dc.html :134 hovers the chip's border to the mockup's hover rung,
   `--c-gold-hover`. */
.hb-task-card .hb-conv:hover,
.hb-task-card .hb-conv:focus-visible {
    border-color: var(--c-gold-hover);
}

.hb-task-card .hb-conv:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}

/* --- The done rows (B6) -------------------------------------------- */

/* Compact 46px rows under hairline rules (mockup 183-188): the status
   glyph, the title, the finish time. */
.hb-done-row {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    min-height: 46px;
    padding: 0;
    color: inherit;
    text-decoration: none;
    border-top-width: 1px;
    border-top-style: solid;
    border-top-color: var(--c-rule);
    transition: background var(--t-fast);
}

.hb-done-row:last-child {
    border-bottom-width: 1px;
    border-bottom-style: solid;
    border-bottom-color: var(--c-rule);
}

.hb-done-row:hover,
.hb-done-row:focus-visible {
    background: var(--c-sand-card);
}

.hb-done-row:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: -2px;
}

/* The glyph: "✓" in moss for a complete row; the status word as a
   small tag for the other three terminal states. */
.hb-done-row .hb-glyph {
    flex: 0 0 auto;
    min-width: var(--s-4);
    font-size: var(--fs-micro);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--c-ink-muted);
}

.hb-done-row .hb-glyph[data-display-status="complete"] {
    min-width: 12px;
    font-size: var(--fs-meta);
    letter-spacing: 0;
    text-transform: none;
    color: var(--c-status-complete);
}

.hb-done-row .hb-glyph[data-display-status="failed"] {
    color: var(--c-status-failed);
}

.hb-done-row .hb-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-text);
    font-size: var(--fs-base);
    line-height: 1.2;
    color: var(--c-ink);
}

.hb-done-row .hb-when {
    flex: 0 0 auto;
    font-size: var(--fs-13);
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: var(--c-ink-muted);
}

/* --- The decision fallback anchor (B4, lane 09 absent) ------------- */

/* The minimal card to a decision on task detail: the accent top edge
   the decide cards carry (mockup 99), the title, the question and the
   task it belongs to. */
.hb-decision-fallback {
    display: flex;
    flex-direction: column;
    gap: var(--s-1);
    padding: var(--s-4) var(--s-5);
    color: inherit;
    text-decoration: none;
    background: var(--c-sand-card);
    border-width: 1px;
    border-style: solid;
    border-color: var(--c-rule);
    border-top-width: 2px;
    border-top-color: var(--c-accent);
    border-radius: var(--radius);
    box-shadow: var(--sh-slip);
    transition: border-color var(--t-base), box-shadow var(--t-slow);
}

.hb-decision-fallback:hover,
.hb-decision-fallback:focus-visible {
    border-color: var(--c-rule-strong);
    border-top-color: var(--c-accent);
    box-shadow: var(--sh-lift);
}

.hb-decision-fallback:focus-visible {
    outline: 2px solid var(--c-burnished);
    outline-offset: 2px;
}

.hb-decision-fallback .hb-title {
    margin: 0;
    font-size: var(--fs-title);
    line-height: 1.25;
}

.hb-decision-fallback .hb-question {
    margin: 0;
    font-size: var(--fs-body);
    line-height: 1.5;
    color: var(--c-ink-soft);
}

.hb-decision-fallback .hb-task-title {
    margin: var(--s-1) 0 0;
    font-size: var(--fs-meta);
    letter-spacing: 0.02em;
    color: var(--c-ink-muted);
}

/* --- The Home-owned "Not now" (B5: a renderer without the app variant) */

.hb-not-now {
    justify-self: start;
    padding: var(--s-1) var(--s-2);
    font-family: inherit;
    font-size: var(--fs-micro);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--c-ink-muted);
    background: none;
    border-width: 0;
    cursor: pointer;
}

.hb-not-now:hover,
.hb-not-now:focus-visible {
    color: var(--c-ink);
}

/* --- Phone (§7.8; spec 11 B7) --------------------------------------
 * The DOM sequence is fixed and viewport-independent (the controller
 * never asks the surface how wide the page is); the stack the
 * contract reads — greeting, credits line, prompt line, starters,
 * decisions, working, next, done, unread chips, recent chips — comes
 * from the main element becoming a flex column and the two chip
 * groups alone taking a CSS `order` past the board.  Every card runs
 * full width, the Next deck becomes a snap-scrolling row of 82vw
 * cards (lane 08's composer-deck rule), the badges stay inline with
 * their heading, every tap target is at least 44px and the chip rows
 * wrap — the page body never scrolls sideways. */
@media (max-width: 720px) {
    main[data-page="home"] {
        display: flex;
        flex-direction: column;
    }

    .hb-unread {
        order: 8;
    }

    .hb-recent {
        order: 9;
    }

    .hb-unread,
    .hb-recent {
        margin: var(--s-5) 0 0;
    }

    .hb-board {
        gap: var(--s-6);
        margin-top: var(--s-5);
    }

    .hb-column-head h2 {
        font-size: var(--fs-title);
    }

    /* Every card full-width. */
    .hb-cards {
        grid-template-columns: minmax(0, 1fr);
    }

    /* The Next deck: one snap-scrolling row — a flex row, where the
       deck's `align-items: start` would rag the cards' bottoms, so the
       scroller keeps the equal heights of a row. */
    .hb-cards-next {
        display: flex;
        align-items: stretch;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        gap: 10px;
        padding-bottom: var(--s-2);
        -webkit-overflow-scrolling: touch;
    }

    .hb-cards-next > [data-card] {
        flex: 0 0 82vw;
        scroll-snap-align: start;
    }

    .hb-cards-next > .hb-not-now {
        flex: 0 0 auto;
        align-self: center;
    }

    .hb-cards-next > .hb-empty,
    .hb-cards-next > [data-loading] {
        flex: 1 1 100%;
    }

    /* Tap targets. */
    .hb-chip,
    .hb-starter,
    .hb-composer-send,
    .hb-conv {
        min-height: 44px;
    }
    /* The long placeholder wraps at 400px; size the empty field to it
       (rows stays the controller's floor once text is typed) instead of
       cutting the second line — fidelity audit 2026-09-11, Home P2. */
    .hb-composer-input {
        field-sizing: content;
    }

    /* The starters run two per row.  The chip rows take no rule here:
       `.hb-unread` / `.hb-recent` are already wrapping flex rows at
       every width (above), and `.hb-chip-row` — the only thing between
       them and the chips — is `display: contents`, so it is not a flex
       container and a `flex-wrap` on it can never apply.  Measured in
       Chromium, five unread chips in a 390px viewport: five lines, and
       the same five rects with `flex-wrap: nowrap` forced onto
       `.hb-chip-row`; forcing `nowrap` onto the sections instead runs
       all five onto one line, the last opening at x=1312.  The
       sections' own `flex-wrap` is what the "wrap, never scroll"
       contract (spec 11 B7) rests on, and the pin says so — fidelity
       audit 2026-09-11, review round 8, R8-CODE-3/R8-REG-1. */
    .hb-starters {
        flex-wrap: wrap;
    }

    .hb-starter {
        flex: 1 1 calc(50% - var(--s-2));
    }

    .hb-task-card,
    .hb-decision-fallback {
        padding: var(--s-4);
    }
}

/* --- Card entrance stagger (feature-gap home-44, G2) ---------------- */

/* The mockup's decision, working and suggestion cards enter with
   `animation: ease .5s cubic-bezier(.2,.7,.2,1) both` (dc.html :99,
   :128, :155) over `@keyframes ease` — opacity 0 and translateY(6px) to
   none (dc.html :33) — each column staggered by the index the
   controller stamps as `--hb-i`: decisions `i*60ms` (dc.html :917),
   working `wi*60+120ms` (:925), suggestions `si*60+200ms` (:926).  The
   done column is not animated (its rows carry no delay).

   One departure: the fill is `backwards`, not `both`.  The final
   keyframe is the card's resting state, so the two draw the same
   frames — but a `both` fill keeps `transform: none` applied from the
   animation origin after the entrance ends, which outranks the
   `.hb-task-card:hover` 2px lift the mockup also draws (dc.html :128
   style-hover).  `backwards` holds the first frame through the delay
   and then lets the hover rule through. */
@keyframes hb-ease {
    from {
        opacity: 0;
        transform: translateY(6px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.hb-cards[data-board-body="decisions"] > [data-decision-card],
.hb-cards[data-board-body="working"] > [data-task-card],
.hb-cards[data-board-body="next"] > [data-card] {
    animation: hb-ease .5s cubic-bezier(.2, .7, .2, 1) backwards;
}

.hb-cards[data-board-body="decisions"] > [data-decision-card] {
    animation-delay: calc(var(--hb-i, 0) * 60ms - var(--hb-t, 0ms));
}

.hb-cards[data-board-body="working"] > [data-task-card] {
    animation-delay: calc(var(--hb-i, 0) * 60ms + 120ms - var(--hb-t, 0ms));
}

.hb-cards[data-board-body="next"] > [data-card] {
    animation-delay: calc(var(--hb-i, 0) * 60ms + 200ms - var(--hb-t, 0ms));
}

/* The entrance plays once per CARD: the mockup's board mounts once and
   its reconciler keeps a card's node, so `ease .5s` (dc.html :917-926)
   runs when the node is minted, runs to its end and never runs again,
   while a card prepended to a column that already holds cards (dc.html
   :928, :1024) is a fresh node and rises alone.  `_renderColumn` /
   `_renderDeck` re-mint every card on each live frame, poll settle and
   answered decision, so `app_ctrl_home.js` (`staggered`, over
   `seenCards` / `rememberCards`) remembers each card's entrance.  A card
   whose entrance has FINISHED is stamped `data-hb-still` and this rule
   cancels its animation.  A card whose entrance is still RUNNING keeps
   the `--hb-i` it entered with and carries `--hb-t`, the milliseconds
   that entrance has actually played (read off the replaced node's own
   animation just before the repaint, so a node wiped before its first
   frame hands on nothing: review c1), which the delays above subtract:
   the delay goes negative and the fresh node resumes the fade where the
   node it replaced left off, rather than snapping to rest (review c2) or
   restarting from opacity 0 (review r1).  The drawer lane's
   `data-cv-repainted` idiom, per node rather than per container
   (surfaces.css :370-380).  Ties on specificity with the rule that sets
   the entrance, so it must stay after it. */
.hb-cards[data-board-body] > [data-hb-still] {
    animation: none;
}

/* --- Reduced motion ------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .hb-pulse {
        animation: none;
        display: none;
    }

    .hb-chip-pending,
    .hb-chip-pending::before,
    .hb-chip-pending::after {
        animation: none;
    }

    .hb-cards[data-board-body="decisions"] > [data-decision-card],
    .hb-cards[data-board-body="working"] > [data-task-card],
    .hb-cards[data-board-body="next"] > [data-card] {
        animation: none;
    }

    .hb-task-card,
    .hb-decision-fallback,
    .hb-done-row,
    .hb-chip,
    .hb-starter,
    .hb-conv,
    .hb-composer,
    .hb-composer-send {
        transition: none;
    }

    .hb-task-card:hover {
        transform: none;
    }
}
