/* The flow 2 board (build spec 3.11; board concept addendum v3.3, 2.1 to
   2.3; lane-walks widths). app.css carries the tokens, the fields, the
   buttons and .sr-only. Lanes are columns that share the topic rows through
   subgrid: 196 px normal, 392 px active, 44 px skinny. The board scrolls
   sideways inside its own frame, never the page. Nothing here is fixed over
   the page: the toast and the sheet sit above the safe-area inset and never
   cover the lane switcher, which sits in the page flow at the top. */

.board { --lane: 196px; --lane-active: 392px; --lane-skinny: 44px; --gap: 8px;
         padding: 16px; box-sizing: border-box; display: flex; flex-direction: column; gap: 12px;
         color: var(--ink); background: var(--page); }

/* THE AGREED MOCKUP'S COLOURS (docs/lane-walks.md "The card at three levels";
   scripts/theme/lane-walks.css, the cv- classes, as docs.theode.ai draws
   them). app.css carries the ink, the page and the edges; these name the
   board's own panels and the states. Two are darker than the mockup draws
   them, for WCAG 1.4.3 at the chips' 11 px: the amber text (#B86E00 read
   3.27:1 on its tint; #8A5200 reads 5.24) and the grey of New and Set aside
   (white on #8A8780 read 3.58; carbon-40 reads 7.12). */
.board {
  --b-lane: #F3EFE6; --b-panel: #fff; --b-rule: #DED5C3; --b-dash: #B9B2A3; --b-hair: #EFEBE2;
  --b-words: #44413C; --b-btn-edge: #CFC6B4;
  --b-link: #2F64B8;
  --b-new: var(--carbon-40); --b-triage: #2F64B8; --b-context: #3F7A2C; --b-invar: #6B4BB0;
  --b-aside: var(--carbon-40); --b-sup: #9A5A2E;
  --b-red: #B23A2E; --b-red-tint: #F4DEDA; --b-red-soft: #FBE9E5; --b-red-ink: #9A2F24;
  --b-amber: #8A5200; --b-amber-rule: #B86E00; --b-amber-tint: #F6E7CC; --b-amber-wash: #FBF5EA;
  --b-note: #ECE9E3;
}

/* ---- The head: name, home link, tabs, banners ---- */
.board-header { display: flex; flex-direction: column; gap: 8px; }
.board-title { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.board-name { font-family: var(--font-title); font-size: 1.25rem; margin: 0; }
.project-name { font-weight: 700; cursor: pointer; min-height: 44px; display: inline-flex; align-items: center; }
.board-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.tab { padding: 8px 12px; min-height: 44px; box-sizing: border-box; display: inline-flex; align-items: center;
       text-decoration: none; color: inherit; border-bottom: 2px solid transparent; }
.tab.is-current { border-bottom-color: currentColor; font-weight: 700; }
/* The brief's line under the tabs (phase 2 Task 30): its version and state,
   and Generate brief in the brief band, both links to the Brief tab. */
.board-brief { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.board-brief-summary { min-height: 44px; display: inline-flex; align-items: center; color: inherit; }
.board-brief .btn-small { text-decoration: none; }
.board .banner { margin: 0; padding: 8px 12px; border-radius: 6px; background: var(--field); }
.board .banner-quiet { background: transparent; padding: 0; opacity: 0.8; }

/* ---- Lanes ---- */
.board-scroller { overflow-x: auto; overflow-y: visible; max-width: 100%; padding-bottom: 8px; }
.board-grid { display: grid; grid-auto-flow: column; grid-auto-columns: max-content; column-gap: var(--gap);
              grid-template-rows: auto repeat(var(--rows), auto) auto; align-items: start; }
.lane { grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; row-gap: var(--gap);
        width: var(--lane); box-sizing: border-box; transition: width 150ms ease; align-content: start;
        /* The mockup's soft lane panel (.cv-lane). */
        background: var(--b-lane); border: 1px solid var(--b-rule); border-radius: 10px; padding: 8px 8px 12px; }
.lane.is-skinny { padding: 8px 2px; }
/* Outside the active lane the panel is tighter, so a level 1 card keeps the
   width a 48-character title needs for two lines (addendum 3.1). */
.lane:not(.is-active):not(.is-skinny) { padding: 8px 3px 12px; }
.lane:not(.is-active) .cell { padding: 4px 3px 6px; }
.lane.is-active { width: var(--lane-active); }
.lane.is-skinny { width: var(--lane-skinny); }
.lane.is-incoming > .lane-body { grid-row: 2 / -1; }
.lane-top { grid-row: 1; display: flex; flex-direction: column; gap: 6px; }
.lane-foot { grid-row: -2; display: flex; flex-direction: column; gap: 6px; }
/* Triage's tools (D1, D2): Accept all into context and the topic order. */
.lane-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.lane-head { display: flex; align-items: center; gap: 4px; position: sticky; top: 0; }
.lane-head { background: var(--b-lane); }
.lane-head-btn { flex: 1; min-height: 44px; text-align: left; background: none; border: 0;
                 padding: 2px 4px; cursor: pointer; color: inherit; font: inherit; font-size: 0.875rem;
                 font-weight: 700; display: flex; flex-direction: column; justify-content: center; }
.lane-head-btn[aria-expanded="true"] .lane-word { text-decoration: underline; text-underline-offset: 4px; }
/* "Triage" over "9 requests" (.cv-lanehead small). */
.lane-sub { display: block; font-weight: 400; font-size: 0.75rem; color: var(--helper); }
.lane-switch-btn .lane-count { font-weight: 400; color: var(--helper); }
.lane.is-skinny .lane-head { flex-direction: column; }
.lane.is-skinny .lane-head-btn { writing-mode: vertical-rl; min-height: 120px; padding: 8px 0; text-align: center;
                                 flex-direction: row; align-items: center; }
.lane.is-skinny .lane-sub { display: none; }
.lane-empty { margin: 0; padding: 8px; font-size: 0.8125rem; color: var(--helper); }
/* Where the variation lanes would be (walk round 1, O1; ruling R1-2): in the
   brief band, a lane-wide dashed panel after the last lane that says when
   variations start and links to the stage change. On a phone it is a line
   above the lanes. */
.lane-later { grid-row: 1 / -1; width: var(--lane); box-sizing: border-box; align-self: start;
              border: 1.5px dashed var(--b-dash); border-radius: 10px; padding: 12px 10px;
              display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.lane-later-words { margin: 0; font-size: 0.875rem; }
.lane-later .btn-small { text-decoration: none; display: inline-flex; align-items: center; }
.board.is-phone .lane-later { width: auto; margin: 0 0 8px; }
/* The requests In context in a variation band (walk round 1, O2): an entry
   above the lanes, as plain as a lane's head, its list full width under it. */
.context-strip { background: var(--b-lane); border: 1px solid var(--b-rule); border-radius: 10px;
                 padding: 4px 8px 8px; margin: 0 0 8px; }
.context-strip .lists { padding-top: 4px; }
/* The topic box (.cv-topic): a dashed rounded box, its name in small caps. */
.cell { border: 1.5px dashed var(--b-dash); border-radius: 10px; padding: 4px 8px 8px; display: flex;
        flex-direction: column; gap: 8px; min-height: 32px; }
.lane.is-skinny .cell { border-color: transparent; padding: 0; }
/* An empty box keeps to its own height: a row is as tall as its tallest
   lane, and a stretched empty box read as a tall empty frame (LOOK-tall). */
.lane > .cell { align-self: start; }
/* A quiet box (LOOK-empty): a topic with nothing in any variation lane is
   one thin dashed line there. */
.lane .cell.is-quiet { min-height: 0; height: 0; padding: 0; border-width: 1px 0 0; border-radius: 0; margin: 6px 4px 0;
                 border-color: var(--b-dash); }
.topic-label { display: flex; align-items: center; gap: 4px; font-size: 0.6875rem; font-weight: 700;
               letter-spacing: 0.04em; text-transform: uppercase; color: var(--helper); cursor: grab; }
.topic-name { font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; background: none;
              border: 0; padding: 0; min-height: 32px; display: inline-flex; align-items: center; gap: 4px;
              cursor: pointer; }
.topic-chevron { font-size: 0.625rem; }
.topic-label .topic-menu > summary, .topic-label .icon-btn { text-transform: none; letter-spacing: 0; }
/* A variation group in its home topic's row (Task 33): its head over its members' cards. */
/* A variation group (.cv-vgroup): the lane's tint, a dashed edge and the
   In-a-variation purple down its left. */
.var-group { background: var(--b-lane); border: 1.5px dashed var(--b-dash); border-left: 4px solid var(--b-invar);
             border-radius: 10px; padding: 8px 10px 10px; margin: 2px 0; display: flex; flex-direction: column;
             gap: 6px; font-size: 0.8125rem; }
.var-group.is-pending { border-left-style: dashed; }
.var-group.is-drop-over { outline: 2px solid currentColor; outline-offset: 2px; }
.var-group-bar { display: flex; align-items: center; gap: 4px; }
.var-group-toggle { background: none; border: 0; color: inherit; font: inherit; min-width: 32px; min-height: 32px;
                    padding: 0; cursor: pointer; }
.var-group-members { display: flex; flex-direction: column; gap: 6px; }
.var-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 0; color: inherit;
                  min-height: 32px; font-size: 0.8125rem; text-underline-offset: 2px; }
a.var-group-head { color: var(--ink); }
.var-group-title { font-weight: 700; }
.var-group-rev, .var-group-total { color: var(--helper); }
.var-group-line { margin: 0; font-size: 0.75rem; color: var(--helper); }
.board-totals { margin: 4px 0 0; font-size: 0.8125rem; color: var(--helper); }
.topic-count::before { content: "· "; }
.topic-menu > summary, .topic-new > summary { cursor: pointer; min-height: 32px; min-width: 32px;
                                              display: inline-flex; align-items: center; justify-content: center; }
.topic-menu[open] { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
/* Level 3's category Change (D4) opens under its line. */
.card-category-change { display: inline-block; font-size: 0.75rem; }
.card-category-change > summary { cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
                                  min-height: 32px; display: inline-flex; align-items: center; }
.card-category-change fieldset { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.card-category-change .stage-radio { display: flex; align-items: center; gap: 6px; min-height: 32px; }
.placeholder { margin: 0; font-size: 0.75rem; font-style: italic; color: var(--helper); }
.draft-group { border: 1.5px dashed var(--b-dash); border-left: 4px solid var(--b-invar); border-radius: 10px;
               padding: 6px; display: flex; flex-direction: column; gap: 6px; }
.draft-group-head { margin: 0; font-weight: 700; font-size: 0.8125rem; }

/* ---- Cards (.cv-card, .cv-focus and the rest of the mockup's card) ---- */
.card { background: var(--b-panel); border: 1px solid var(--b-rule); border-left: 4px solid var(--b-rule);
        border-radius: 8px; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; cursor: pointer;
        font-size: 0.8125rem; line-height: 1.45; overflow-wrap: anywhere; box-shadow: 0 1px 2px rgb(40 40 40 / 0.06);
        position: relative; }
.card.level-1 { padding: 7px; gap: 4px; }
/* An expanded card: a dark edge, a dark left rule and a soft ring. */
.card.level-3 { border-color: var(--ink); border-left-color: var(--ink); box-shadow: 0 0 0 2px rgb(40 40 40 / 0.10); }
.card.is-selected { outline: 2px solid var(--ink); outline-offset: 1px; }
.card[data-state="new"] { border-left-style: dashed; border-left-color: var(--edge-firm); }
.card p { margin: 0; }
.card a { color: var(--b-link); text-underline-offset: 2px; }
.card-head { display: flex; align-items: flex-start; gap: 8px; }
.card-head .card-heading { flex: 1; }
.card-heading { font-weight: 700; font-size: 0.84375rem; line-height: 1.35; }
/* Level 1's title at the addendum's 12.5 px (3.1), so 48 characters fit two
   lines of a 196 px lane (phase 1 Task 28's walk measured three at 14 px). */
.card.level-1 .card-heading { font-size: 0.78125rem; }
.card-meta { font-size: 0.75rem; color: var(--helper); }
.card-words { color: var(--b-words); }
/* An untitled card's words are its head (walk 9, item 7): plain weight. */
.card-heading.card-untitled { font-weight: 400; }
.clamp-1, .clamp-2, .clamp-4 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.clamp-1 { -webkit-line-clamp: 1; }
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-4 { -webkit-line-clamp: 4; }
.card-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* The card's chevron (bug N1-6; it replaced Collapse ▴, the mockup's
   .cv-collapse): v to expand, ^ to collapse, a placeholder until Kieren's
   icon. Borderless, the helper's grey, ink on hover; 32 px square as the
   board's other small controls, 44 on a phone. It is the card's last child and
   sits at its bottom right, out of the head's row: in the row it took
   28 px from a level 1 heading and a 48-character title wrapped to 3 lines
   (ruling N-6b; addendum 2.1 gives level 1 155 px of text). The card keeps a
   strip under its content for it, so it covers no badge or meta. */
.card-toggle { position: absolute; right: 4px; bottom: 0; display: inline-flex; align-items: center;
               justify-content: center; min-width: 32px; min-height: 32px; margin: 0; padding: 0; background: none;
               border: 0; border-radius: 6px; color: var(--helper); cursor: pointer; }
.card:has(> .card-toggle) { padding-bottom: 34px; }
.card-toggle:hover { color: var(--ink); }
.card-toggle:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.board.is-phone .card-toggle { min-width: 44px; min-height: 44px; bottom: 0; }
.board.is-phone .card:has(> .card-toggle) { padding-bottom: 48px; }
/* A statement folded under the top (.cv-stk): a warm wash, a dashed amber
   rule on its left, and its label in small amber capitals. The mockup fades
   it at levels 1 and 2; a fade took the amber label under 4.5:1, so it is
   drawn at full strength. */
.card-line { margin-top: 4px; padding: 8px 10px; border-left: 2px dashed var(--b-amber-rule);
             background: var(--b-amber-wash); border-radius: 0 6px 6px 0; display: flex; flex-direction: column;
             gap: 4px; }
.card.level-1 .card-line { padding: 6px 8px; display: block; }
.card-line.is-faded .line-label { display: block; }
.card-line > button { align-self: flex-start; }
.line-label { font-size: 0.625rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
              color: var(--b-amber); }
.line-title { font-weight: 600; font-size: 0.78125rem; }
.card-btns, .form-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.card-line .card-btns .icon-btn:last-child { margin-left: auto; }
/* The person's own words (.cv-quote): a left rule and quotation marks. */
.card-quote { font-style: italic; color: var(--b-words); display: -webkit-box; -webkit-box-orient: vertical;
              -webkit-line-clamp: 8; overflow: hidden; }
.card-quote::before { content: "\201C"; }
.card-quote::after { content: "\201D"; }
.card-quote-wrap { display: flex; flex-direction: column; border-left: 2px solid var(--b-rule); padding-left: 8px;
                   margin-top: 4px; }
.card.level-3 > .card-quote-wrap, .card-folded > .card-quote-wrap { margin-top: 6px; }
.card-quote-more { order: 2; font-size: 0.75rem; }
.card-quote-more[open] + .card-quote { display: none; }
.card-quote.card-quote-all { -webkit-line-clamp: unset; display: block; }
/* Level 3's sections (.cv-sec): a hairline over each, a small-caps label on
   its own line. */
.card-sec { font-size: 0.8125rem; margin-top: 4px; padding-top: 8px; border-top: 1px solid var(--b-hair); }
.sec-label { display: block; margin: 0 0 2px; font-size: 0.625rem; font-weight: 700; letter-spacing: 0.05em;
             text-transform: uppercase; color: var(--helper); }
.card-issue a { color: var(--b-link); font-weight: 700; }
.card-partner { color: var(--b-words); }
.card-checking { font-size: 0.75rem; color: var(--helper); }
.card-checking::before { content: "◌ "; }
.card-not-checked, .card-repeats { font-size: 0.75rem; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.card-edit { display: flex; flex-direction: column; gap: 4px; }

/* The state chip (.cv-chip): filled with the state's colour, white words. */
.state-chip { display: inline-flex; align-items: center; padding: 1px 7px; border-radius: 10px; font-size: 0.6875rem;
              font-weight: 700; line-height: 1.5; white-space: nowrap; color: #fff; background: var(--b-new); }
.state-chip[data-card-state="in_triage"] { background: var(--b-triage); }
.state-chip[data-card-state="in_context"] { background: var(--b-context); }
.state-chip[data-card-state="in_variation"] { background: var(--b-invar); }
.state-chip[data-card-state="set_aside"] { background: var(--b-aside); }
.state-chip[data-card-state="superseded"] { background: var(--b-sup); }
/* Badges (.cv-badge): a tinted fill, no edge. Definitive red, Conditional a
   softer red, Marginal and the notes grey, a conflict or a stack amber. */
.badge { display: inline-flex; align-items: center; padding: 1px 6px; border-radius: 4px; font-size: 0.6875rem;
         font-weight: 700; line-height: 1.5; border: 0; background: var(--b-note); color: var(--helper); }
.badge[data-word="Definitive"] { background: var(--b-red-tint); color: var(--b-red-ink); }
.badge[data-word="Conditional"] { background: var(--b-red-soft); color: var(--b-red-ink); }
.badge[data-word="Marginal"] { background: var(--b-note); color: var(--helper); }
.badge[data-word="Conflict"], .badge-stack, .badge-conflict { background: var(--b-amber-tint); color: var(--b-amber); }
/* A consultant's warning (fix wave J-F item 5; review of #352): the amber
   wash with its rule, apart from a conflict's solid tint. */
.badge[data-word="Warning"] { background: var(--b-amber-wash); color: var(--b-amber); box-shadow: inset 0 0 0 1px var(--b-amber-rule); }
.badge-note { background: var(--b-note); color: var(--helper); }
/* A stated deadline (fix wave J-E, item 9): amber like a conflict, so it reads as urgent. */
.badge-due { background: var(--b-amber-tint); color: var(--b-amber); }
/* An issue badge is a button (gap U4): it keeps the badge's look and says it
   can be pressed. */
.badge-btn { font-family: inherit; margin: 0; cursor: pointer; }
.badge-btn:hover { text-decoration: underline; }

/* ---- Buttons and focus ---- */
.icon-btn, .btn-small { min-height: 32px; min-width: 32px; padding: 4px 10px; border: 1px solid var(--b-btn-edge);
                        border-radius: 6px; background: var(--b-panel); color: var(--ink); font: inherit; font-size: 0.75rem;
                        font-weight: 700;
                        cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.icon-btn { padding: 4px 7px; }
.board .btn-primary { background: var(--ink); color: var(--page); border-color: var(--ink); }
.lane-add { min-height: 44px; min-width: 44px; font-size: 1.25rem; font-weight: 700; }
button:disabled { opacity: 0.45; cursor: not-allowed; }
.board :focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }

/* ---- The add form ---- */
.add-form { display: flex; flex-direction: column; gap: 4px; padding: 8px; border: 1px solid var(--edge-firm);
            border-radius: 8px; }
.field-count { font-size: 0.75rem; align-self: flex-end; opacity: 0.75; }
.field-count.is-over, .field-error { color: var(--danger); opacity: 1; }
.field-error { margin: 0; font-size: 0.8125rem; }

/* ---- Lists, menu, gate, ask, toast ---- */
.lists { display: flex; flex-direction: column; gap: 4px; }
.list-link { background: none; border: 0; padding: 8px 0; min-height: 44px; text-align: left; cursor: pointer;
             color: inherit; font: inherit; text-decoration: underline; }
.list-cards { list-style: none; margin: 0; padding: 0 0 0 12px; display: flex; flex-direction: column; gap: 4px; }
.list-card { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* History's answered PDF (phase 4 Task 18) is a finger's target on a phone (the Task 24 walk). */
.list-card [data-history-pdf] { display: inline-flex; align-items: center; min-height: 44px; }
/* The In context list by topic, each with Draft a variation from these (V53). */
.list-topics { display: flex; flex-direction: column; gap: 8px; padding-left: 12px; }
.list-topic-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.list-topic-name { font-weight: 600; }
/* The gate, the Ask and Move to… are modal <dialog>s in the top layer
   (board-modal.js): nothing on the board sits over them, and the board
   behind them is inert. */
.board dialog { margin: auto; border: 2px solid var(--ink); border-radius: 10px; padding: 16px; background: var(--page);
                color: var(--ink); max-width: min(40rem, calc(100vw - 32px)); max-height: calc(100vh - 32px);
                overflow: auto; box-sizing: border-box; }
.board dialog::backdrop { background: rgb(0 0 0 / 0.35); }
.move-dialog { min-width: 240px; padding: 6px; }
.ask button { min-height: 44px; padding: 0 12px; border: 1px solid var(--edge-firm); border-radius: 6px;
              background: var(--page); color: inherit; font: inherit; cursor: pointer; }
.ask .btn-primary { background: var(--ink); color: var(--page); }
.move-menu { display: flex; flex-direction: column; gap: 2px; }
.move-menu button { text-align: left; min-height: 44px; background: none; border: 0; padding: 0 8px; color: inherit;
                    font: inherit; cursor: pointer; }
.menu-group { margin: 4px 8px 0; font-size: 0.75rem; font-weight: 700; }
.menu-form { display: flex; flex-direction: column; gap: 4px; padding: 6px 0; }
.ask[open] { display: flex; flex-direction: column; gap: 8px; }
/* The gate's own rules are in gate.css, which the Issues page loads too. */
/* The toast takes its own room in the page flow, above the lists, so it
   never floats over a control at any width or scroll (review I4); the
   board keeps room below it for the safe-area inset. It carries its own
   dismiss button, and the live region says its words wherever the person is. */
.toast { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 8px; background: var(--ink);
         color: var(--page); align-self: flex-start; max-width: 100%; box-sizing: border-box; min-height: 44px; }
.board.has-toast { padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
.toast-close { min-width: 44px; min-height: 44px; font-size: 1.125rem; }
.toast .btn-small { background: transparent; color: inherit; border-color: currentColor; }

/* ---- The phone: one lane at a time ---- */
.lane-switch { display: none; }
@media (max-width: 699px) {
  .board { padding: 12px 16px; }
  .board.is-phone { scroll-padding-top: 56px; }
  /* A finger's target on a phone (PR F final review Minor 6). */
  .board.is-phone .icon-btn, .board.is-phone .btn-small { min-height: 44px; min-width: 44px; }
  .board.is-phone .lane-switch { display: flex; gap: 4px; overflow-x: auto; position: sticky; top: 0;
                                 background: var(--page); padding: 4px 0; z-index: 1; }
  .lane-switch-btn { min-height: 44px; white-space: nowrap; padding: 0 12px; border: 1px solid var(--edge);
                     border-radius: 999px; background: var(--page); color: inherit; font: inherit; }
  .lane-switch-btn[aria-pressed="true"] { font-weight: 700; border-color: var(--ink); }
  .lane-switch-btn.is-empty { opacity: 0.55; }
  .board.is-phone .board-grid { grid-auto-columns: minmax(0, 1fr); width: 100%; }
  .board.is-phone .board-scroller { overflow-x: visible; }
  .board.is-phone .lane, .board.is-phone .lane.is-active { width: 100%; }
  .board dialog.sheet { margin: auto 0 0; width: 100%; max-width: 100%; border-radius: 12px 12px 0 0;
                        padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); }
}

@media (prefers-reduced-motion: reduce) {
  .lane { transition: none; }
}

/* The board's fields are smaller than the app's page-sized ones. */
.board .field-input { height: auto; min-height: 36px; padding: 6px 8px; box-sizing: border-box; width: 100%; }

/* ---- Drag (Task 26) ----
   A card or a topic head is a drag source. On touch a swipe still scrolls
   the page and the board sideways, and a pinch still zooms (manipulation;
   the drag's own non-passive touchmove stops the scroll once a drag runs);
   a 350 ms press starts the drag, and the press neither
   selects text nor opens the callout. While a drag runs, nothing selects,
   the lane and the box under the pointer are outlined, and the ghost
   follows the pointer without taking its events. */
.card { cursor: grab; }
.topic-move { margin-left: auto; }
.board [data-select-mode][aria-pressed="true"] { background: var(--ink); color: var(--page); border-color: var(--ink); }
@media (pointer: coarse) {
  .card, .topic-label { touch-action: manipulation; -webkit-user-select: none; user-select: none;
                        -webkit-touch-callout: none; }
}
.board.is-dragging, .board.is-dragging * { -webkit-user-select: none; user-select: none; cursor: grabbing; }
.lane.is-drop-over { outline: 2px dashed var(--ink); outline-offset: 2px; border-radius: 8px; }
.cell.is-drop-over { border-color: var(--ink); border-style: solid; }
.drag-ghost { position: fixed; left: 0; top: 0; z-index: 10; pointer-events: none; max-width: 240px;
              padding: 6px 10px; border-radius: 8px; background: var(--page); color: var(--ink);
              border: 2px solid var(--ink); box-shadow: 0 4px 12px rgb(0 0 0 / 0.2); font-size: 0.875rem; }
.drag-ghost-words { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }

/* A board that did not load (walk check 2026-10-20, bug 3): the sentence and
   the way back sit in a column with room around them, not at the corner. */
.board-unloaded { max-width: 36rem; margin: 0 auto; padding: 64px 16px; box-sizing: border-box;
                  display: flex; flex-direction: column; gap: 16px; color: var(--ink); }

/* Linked conversations (plan 2026-10-20, Task 12; the walk's values,
   scripts/theme/lane-walks.css): one line per card or group, blue while
   someone else has the move, red when the practice has it, grey when nobody
   does. The red edge marks an owed card or group in every lane. */
.conv-line { display: flex; gap: 6px; align-items: flex-start; margin: 8px 0 0; padding: 5px 7px; border-radius: 6px;
             font-size: 0.8125rem; line-height: 1.4; background: #EEF2F8; color: #2D3B52; }
.conv-line[data-conv="owed"] { background: var(--b-red-soft); color: var(--b-red-ink); font-weight: 600; }
.conv-line[data-conv="quiet"] { background: var(--b-note); color: var(--helper); }
.conv-line .conv-icon { flex: 0 0 auto; margin-top: 2px; }
.conv-words { flex: 1 1 auto; min-width: 0; }
.conv-short { font-size: 0.75rem; padding: 4px 6px; }
.conv-toggle { flex: 1 1 auto; text-align: left; background: none; border: 0; padding: 0; font: inherit; color: inherit;
               cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.conv-dismiss { flex: 0 0 auto; align-self: center; color: var(--b-red); border-color: #E7B9B1; }
.card[data-conv-owed="1"], .var-group[data-conv-owed="1"] { border-left-color: var(--b-red); }
.conv-sec .sec-label { display: flex; justify-content: space-between; gap: 8px; }
.conv-count { font-weight: 500; letter-spacing: 0; text-transform: none; }
.conv-sec .conv-line { margin: 0 0 8px; }
.conv-sec:focus { outline: 2px solid var(--ink); outline-offset: 2px; }
.conv-summary { font-size: 0.8125rem; line-height: 1.5; margin: 0 0 4px; }
.conv-msgs { list-style: none; margin: 8px 0 0; padding: 0; }
.conv-msg { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; padding: 4px 0; border-top: 1px solid var(--b-rule);
            font-size: 0.8125rem; }
.conv-msg:first-child { border-top: 0; }
.conv-date { flex: 0 0 48px; color: var(--helper); }
.conv-from { flex: 1 1 auto; min-width: 0; color: inherit; }
.conv-mark { color: var(--b-red-ink); font-weight: 700; font-size: 0.75rem; white-space: nowrap; }
/* A message's photographs, inline (walkthrough 2026-10-21, A34): a row of
   thumbnails under the message, each a link to its file. */
.conv-images { flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 6px; }
.conv-image { color: inherit; overflow-wrap: anywhere; }
.conv-image img { display: block; max-width: 100%; width: 160px; max-height: 160px; object-fit: cover;
                  border: 1px solid var(--b-rule); border-radius: 4px; }
.conv-image:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.conv-earlier, .conv-reading { font-size: 0.8125rem; color: var(--helper); margin: 6px 0 0; }
.var-group-conv { margin: 0 0 6px; }
.board-act-on { display: inline-flex; align-items: center; min-height: 44px; color: var(--b-red-ink); font-weight: 600; }

/* The Messages view (linked conversations Task 13): app/messages.html. */
.messages-main { max-width: 760px; margin: 0 auto; padding: 16px; }
.msg-row { background: var(--b-panel); border: 1px solid var(--b-rule); border-left: 4px solid var(--b-rule);
           border-radius: 8px; padding: 10px 12px; margin: 0 0 10px; }
.msg-row:focus { outline: 2px solid var(--ink); outline-offset: 2px; }
.msg-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; margin: 0; }
.msg-from { flex: 1 1 auto; font-weight: 600; color: inherit; min-height: 44px; display: inline-flex; align-items: center; }
.msg-tag { font-size: 0.75rem; font-weight: 700; border-radius: 4px; padding: 2px 6px; background: var(--b-note);
           color: var(--helper); }
.msg-tag[data-msg-tag="owed"] { background: var(--b-red-soft); color: var(--b-red-ink); }
.msg-subject { margin: 2px 0 6px; color: var(--helper); font-size: 0.875rem; }
.msg-points { list-style: none; margin: 0; padding: 0; }
.msg-point { border-top: 1px solid var(--b-rule); padding: 6px 0; }
.msg-point-words { margin: 0 0 4px; }
.msg-point-done { font-size: 0.8125rem; color: var(--helper); margin: 0; }
.msg-btns { margin: 6px 0 0; }
.msg-link-form { margin: 6px 0 0; display: flex; flex-direction: column; gap: 4px; max-width: 100%; }
.msg-link-form select { max-width: 100%; }
.msg-archived { margin: 16px 0 0; }
.messages-page .btn-small, .messages-page select { min-height: 44px; }
