/* LUCID — THE BOARD ROOM'S STYLES (view-board: the canvas, its cards, tray and inspector).
 *
 * Moved out of app.css on 15 October 2026 by the room rebuild, loaded straight
 * after app.css (see the room-css:start marker in index.html). The comments that
 * explain a decision came with their rules. tests/test-room-board-unchanged.js is
 * the proof that nothing on screen changed. What stays in app.css is shared with
 * other rooms: the .view / #view-* layout lists that name several rooms at once,
 * and .kit-fam-tag, which the kit room shares with .bc-fam-tag.
 */

/* ==========================================================
   THE BOARD CANVAS
   ==========================================================
   Three layers, and keeping them separate is what makes the rest simple:

     .bc-viewport   fixed to the window. Clips, and owns the cursor.
     .bc-layer      carries translate(pan) scale(zoom). Everything on the
                    board is a child, positioned in CANVAS coordinates.
     .bc-card       absolutely positioned at its own x/y. Never told about
                    pan or zoom at all.

   The rule that keeps it honest: nothing outside bcScreenToCanvas() ever
   mixes the two coordinate systems. Every bug in a canvas like this is a
   screen number used where a canvas number was meant.

   transform-origin is 0 0 so the arithmetic is a plain
   screen = canvas * zoom + pan, invertible in one line. With a centred
   origin every conversion needs the viewport size and half of them are
   wrong. */

.bc-bar{ display:flex; align-items:center; gap:var(--space-3); padding:0 0 var(--space-3); flex:none; }

.bc-boards{ display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; min-width:0; }

.bc-bar-right{ margin-left:auto; display:flex; align-items:center; gap:var(--space-2); flex:none; }

.bc-board-tab{ display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-3); border-radius:var(--radius-pill);
    border:1px solid var(--glass-border); font-size:var(--type-body); font-weight:600; cursor:pointer;
    color:var(--text-dim); background:transparent; white-space:nowrap;
    transition:color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out); }

.bc-board-tab:hover{ color:var(--text); border-color:var(--glass-border-hi); }

.bc-board-tab.active{ color:var(--text); border-color:color-mix(in srgb, var(--accent) 50%, transparent);
    background:color-mix(in srgb, var(--accent) 12%, transparent); }

.bc-board-count{ font-family:var(--font-mono); font-size:var(--type-label); opacity:.65; }

.bc-board-add{ width:28px; height:28px; border-radius:var(--radius-round); border:1px dashed var(--glass-border-hi);
    display:flex; align-items:center; justify-content:center; cursor:pointer; color:var(--text-faint);
    font-size:var(--type-lead); line-height:1; flex:none; }

.bc-board-add:hover{ color:var(--text); border-color:var(--accent); }

.bc-zoom{ display:flex; align-items:center; gap:var(--space-hair); border:1px solid var(--glass-border);
    border-radius:var(--radius-pill); padding:var(--space-hair); }

.bc-zoom-btn{ width:26px; height:24px; display:flex; align-items:center; justify-content:center;
    cursor:pointer; border-radius:var(--radius-pill); color:var(--text); font-size:var(--type-lead); user-select:none; }

.bc-zoom-btn:hover{ background:color-mix(in srgb, var(--accent) 14%, transparent); color:var(--text); }

.bc-zoom-level{ font-family:var(--font-mono); font-size:var(--type-label); color:var(--text-dim);
    min-width:46px; text-align:center; cursor:pointer; user-select:none; }

.bc-stage{ position:relative; display:flex; gap:var(--space-3); flex:1; min-height:0; }

.bc-tray{ width:104px; flex:none; display:flex; flex-direction:column; gap:var(--space-1); padding:var(--space-3) var(--space-2);
    border-radius:var(--radius-card); overflow-y:auto; }

.bc-tray-title{ font-size:var(--type-label); text-transform:uppercase; letter-spacing:.09em;
    color:var(--text-faint); padding:0 var(--space-1) var(--space-1); }

.bc-tool{ display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-2); border-radius:var(--radius-control);
    font-size:var(--type-body); font-weight:600; color:var(--text-dim); cursor:grab; user-select:none;
    transition:background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }

.bc-tool:hover{ background:color-mix(in srgb, var(--accent) 12%, transparent); color:var(--text); }

.bc-tool:active{ cursor:grabbing; }

/* MORE INK, NOT A DARKER TOKEN.
     At 9px a stroke is narrower than one pixel, so every pixel that renders it
     is already a blend with whatever is behind — darkening the colour moves the
     number in the stylesheet and almost nothing on the glass. Size is the lever
     that works, which is why these went to 11px rather than to a new colour. */
  .bc-tool-ico{ width:16px; height:16px; border-radius:var(--radius-tight); flex:none; border:1px solid var(--glass-border-hi);
    display:flex; align-items:center; justify-content:center; font-size:var(--type-label); font-weight:700; }

.bc-ico-h{ background:color-mix(in srgb, var(--text) 12%, transparent); color:var(--text); }

.bc-ico-sw{ background:linear-gradient(135deg, var(--pink), var(--orange) 50%, var(--teal)); border:none; }

.bc-ico-person{ background:color-mix(in srgb, var(--teal) 22%, transparent); color:var(--text); }

/* A 9px glyph has strokes thinner than a pixel, so no pixel ever receives the
     nominal colour — the fix is more ink rather than a darker token. */
  .bc-ico-mail{ background:color-mix(in srgb, var(--blue) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

.bc-ico-board{ background:color-mix(in srgb, var(--violet) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

.bc-ico-tpl{ background:color-mix(in srgb, var(--green) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

/* Four more, added 2 September — see the long note above bcDefaults('choice'). */
  .bc-ico-choice{ background:color-mix(in srgb, var(--pink) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

.bc-ico-goal{ background:color-mix(in srgb, var(--teal) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

.bc-ico-web{ background:color-mix(in srgb, var(--blue) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

.bc-ico-vault{ background:color-mix(in srgb, var(--orange) 22%, transparent);
    color:var(--text); font-size:var(--type-label); }

/* THE WAY BACK OUT of a sub-board. Deliberately not shaped like a tab: it is
     not another board to switch to, it is the door you came in through, and a
     tab would put it in the same row of equals as the boards it is parent to. */
  .bc-board-up{ display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-3); border-radius:var(--radius-pill);
    font-size:var(--type-body); font-weight:600; cursor:pointer; color:var(--text-faint); white-space:nowrap;
    border:1px dashed var(--glass-border-hi); background:transparent; }

.bc-board-up:hover{ color:var(--text); border-color:var(--accent); }

/* ARROWS.
     Drawn under every card — bcAdd starts the first card at z-index 0 and
     counts up, so nothing can sit below this. An arrow painted over the cards
     would cross their text.
     pointer-events:none on the layer, and back on for the fat invisible hit
     line only: without that the SVG would swallow every drag passing over the
     region it covers, which on a busy board is most of it. */
  .bc-arrow-layer{ position:absolute; overflow:visible; pointer-events:none; z-index:0; }

.bc-arrow{ stroke:var(--text-faint); stroke-width:1.6; fill:none; }

.bc-arrow.dashed{ stroke-dasharray:6 5; }

.bc-arrow-layer marker path{ fill:var(--text-faint); }

/* Twelve pixels wide and invisible: a 1.6px line is not something anybody can
     click, and the alternative — a delete handle riding the middle of every
     arrow — puts permanent furniture on the board for a thing done once. */
  .bc-arrow-hit{ stroke:transparent; stroke-width:12; fill:none; cursor:pointer; pointer-events:stroke; }

.bc-arrow-label{ font-size:var(--type-label); fill:var(--text-dim); font-weight:600;
    paint-order:stroke; stroke:var(--bg-base); stroke-width:3px; }

/* While a join is armed the whole board says so. A cursor change and a ring
     on whatever is under the pointer are the honest signals — a banner would
     cover the cards he is trying to pick between. */
  .bc-viewport.linking{ cursor:crosshair; }

.bc-viewport.linking .bc-card:hover{ outline:2px solid var(--accent); outline-offset:2px; }

/* THE TEMPLATE CHOOSER. Rows rather than thumbnails: a thumbnail of six empty
     notes says nothing a sentence does not, and it would be one more thing to
     keep in step with the templates themselves. */
  .bc-tpl-list{ display:flex; flex-direction:column; gap:var(--space-2); margin-top:var(--space-1); }

.bc-tpl-row{ padding:var(--space-3) var(--space-3); border-radius:var(--radius-card); cursor:pointer;
    border:1px solid var(--glass-border); }

.bc-tpl-row:hover{ background:color-mix(in srgb, var(--accent) 12%, transparent);
    border-color:color-mix(in srgb, var(--accent) 45%, transparent); }

.bc-tpl-name{ font-size:var(--type-body); font-weight:700; color:var(--text); }

.bc-tpl-blurb{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-hair); }

.bc-tpl-count{ font-family:var(--font-mono); font-size:var(--type-label); color:var(--text-faint); margin-top:var(--space-1); }

.bc-viewport{ position:relative; flex:1; min-width:0; border-radius:var(--radius-card); overflow:hidden;
    cursor:default; touch-action:none;
    /* The grid is drawn on the viewport rather than the layer and its size is
       set from JS on every zoom, so it scales with the board without a
       repaint of a huge background image. */
    background-image:radial-gradient(circle, var(--glass-border-hi) 1px, transparent 1px);
    background-size:24px 24px; background-position:0 0; }

.bc-viewport.panning{ cursor:grabbing; }

.bc-viewport.pannable{ cursor:grab; }

.bc-viewport.drop-active{ box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent); }

.bc-layer{ position:absolute; top:0; left:0; width:0; height:0; transform-origin:0 0; will-change:transform; }

.bc-marquee{ position:absolute; border:1px solid color-mix(in srgb, var(--accent) 70%, transparent);
    background:color-mix(in srgb, var(--accent) 12%, transparent); border-radius:var(--radius-tight);
    pointer-events:none; z-index:5; }

.bc-empty{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
    pointer-events:none; }

.bc-empty-inner{ text-align:center; max-width:340px; }

.bc-empty-title{ font-size:var(--type-lead); font-weight:700; color:var(--text-dim); margin-bottom:var(--space-2); }

.bc-empty-sub{ font-size:var(--type-body); color:var(--text-faint); line-height:1.7; }

.bc-key{ font-family:var(--font-mono); font-size:var(--type-label); padding:1px var(--space-2); border-radius:var(--radius-tight);
    border:1px solid var(--glass-border-hi); }

/* ---- cards ---- */
  .bc-card{ position:absolute; border-radius:var(--radius-card); box-sizing:border-box; overflow:hidden;
    border:1px solid var(--glass-border); background:var(--glass-bg);
    box-shadow:var(--glass-shadow); display:flex; flex-direction:column; }

/* No transition on transform or size: those change every frame during a
     drag, and an easing curve on them turns a drag into a lag. */
  .bc-card.selected{ border-color:color-mix(in srgb, var(--accent) 65%, transparent);
    box-shadow:var(--glass-shadow), 0 0 0 2px color-mix(in srgb, var(--accent) 40%, transparent); }

.bc-card.dragging{ opacity:.92; }

.bc-card-head{ display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-2) 0; flex:none;
    opacity:0; transition:opacity var(--dur-fast) var(--ease-out); }

.bc-card:hover .bc-card-head, .bc-card.selected .bc-card-head{ opacity:1; }

.bc-card-grip{ flex:1; height:14px; cursor:grab; border-radius:var(--radius-tight); }

/* --text-dim, not --text-faint. Measured at 3.88:1 as the fainter token —
     the same 4.5:1 floor every other control in Lucid has to clear. */
  .bc-card-btn{ width:18px; height:18px; border-radius:var(--radius-control); display:flex; align-items:center;
    justify-content:center; cursor:pointer; color:var(--text-dim); font-size:var(--type-body); line-height:1; flex:none; }

.bc-card-btn:hover{ background:color-mix(in srgb, var(--text) 12%, transparent); color:var(--text); }

.bc-card-body{ flex:1; min-height:0; padding:var(--space-hair) var(--space-3) var(--space-3); overflow:hidden; }

/* THE INSPECTOR.
     Floated over the canvas rather than docked beside it: a permanent panel
     down one edge is a permanent tax on the thing it is there to serve, and
     the canvas is the whole point. It sits at the bottom, where it covers the
     least of what is usually being worked on. */
  .bc-inspector{ position:absolute; left:50%; bottom:18px; transform:translate(-50%, 10px);
    display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; justify-content:center;
    max-width:calc(100% - 32px); padding:var(--space-2) var(--space-3); border-radius:var(--radius-card);
    background:var(--glass-bg); border:1px solid var(--glass-border);
    backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
    box-shadow:var(--elev-floating);
    opacity:0; pointer-events:none; z-index:40;
    transition:opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }

.bc-inspector.open{ opacity:1; pointer-events:auto; transform:translate(-50%, 0); }

.bc-insp-n{ font-family:var(--font-mono); font-size:var(--type-label); font-weight:600;
    letter-spacing:.08em; text-transform:uppercase; color:var(--text-dim); white-space:nowrap; }

.bc-insp-rule{ width:1px; height:18px; background:var(--glass-border); flex:none; }

.bc-insp-btn{ font-size:var(--type-body); font-weight:600; padding:var(--space-2) var(--space-3); border-radius:var(--radius-control);
    border:1px solid transparent; background:none; color:var(--text-dim); cursor:pointer;
    white-space:nowrap; transition:all var(--dur-fast) var(--ease-out); }

.bc-insp-btn:hover{ color:var(--text); background:color-mix(in srgb, var(--text) 8%, transparent); }

.bc-insp-btn.on{ color:var(--text); border-color:color-mix(in srgb, var(--accent) 55%, var(--glass-border)); }

.bc-insp-btn.danger:hover{ color:var(--pink-2, var(--pink));
    background:color-mix(in srgb, var(--pink) 12%, transparent); }

.bc-sw-row{ display:flex; gap:var(--space-2); }

.bc-sw{ width:19px; height:19px; border-radius:var(--radius-round); cursor:pointer; padding:0;
    border:1px solid var(--glass-border); background:none;
    transition:transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }

.bc-sw:hover{ transform:scale(1.14); }

.bc-sw.on{ border-color:var(--text); border-width:2px; }

.bc-seg{ display:flex; border:1px solid var(--glass-border); border-radius:var(--radius-control); overflow:hidden; }

.bc-seg button{ font-family:var(--font-mono); font-size:var(--type-label); font-weight:600;
    padding:var(--space-2) var(--space-2); border:none; background:none; color:var(--text-dim); cursor:pointer; }

.bc-seg button:hover{ color:var(--text); }

.bc-seg button.on{ color:var(--text); background:color-mix(in srgb, var(--text) 11%, transparent); }

/* A locked card still selects and still opens — it just cannot be shoved
     across the board by a stray drag, which is the whole complaint. */
  .bc-card.locked{ cursor:default; }

.bc-card.locked .bc-resize{ display:none; }

.bc-lock-mark{ font-size:var(--type-label); color:var(--text-faint); margin-left:var(--space-hair); }

/* The line the card snapped to, drawn only while dragging. */
  .bc-guide{ position:absolute; background:var(--accent); pointer-events:none; z-index:39; opacity:.85; }

.bc-due{ display:inline-block; margin-top:var(--space-2); font-family:var(--font-mono);
    font-size:var(--type-label); font-weight:600; letter-spacing:.07em; text-transform:uppercase;
    color:var(--text-dim); padding:var(--space-1) var(--space-2); border-radius:var(--radius-control);
    background:color-mix(in srgb, var(--text) 7%, transparent); }

.bc-due.soon{ color:var(--orange-text, var(--orange));
    background:color-mix(in srgb, var(--orange) 14%, transparent); }

.bc-resize{ position:absolute; right:0; bottom:0; width:16px; height:16px; cursor:nwse-resize;
    opacity:0; transition:opacity var(--dur-fast) var(--ease-out); }

.bc-resize::after{ content:''; position:absolute; right:4px; bottom:4px; width:7px; height:7px;
    border-right:2px solid var(--text-faint); border-bottom:2px solid var(--text-faint); border-radius:0 0 var(--radius-tight) 0; }

.bc-card:hover .bc-resize, .bc-card.selected .bc-resize{ opacity:1; }

.bc-text{ font-size:var(--bc-size, 13px); line-height:1.55; color:var(--text); outline:none; white-space:pre-wrap;
    word-break:break-word; height:100%; overflow:auto; }

.bc-text:empty::before{ content:attr(data-placeholder); color:var(--text-faint); }

.bc-card.type-heading .bc-text{ font-family:var(--font-display); font-size:var(--type-page); font-weight:600;
    line-height:1.2; }

.bc-card.type-heading{ background:transparent; border-color:transparent; box-shadow:none; }

/* A heading is one line of large type and nothing else, so it does not
     reserve a row for the hover controls the way a note does — with the row
     reserved, a 26px line inside a 56px card was clipped at the top. The
     controls float over it instead. */
  .bc-card.type-heading .bc-card-head{ position:absolute; top:2px; right:2px; left:auto; padding:0; }

.bc-card.type-heading .bc-card-grip{ display:none; }

.bc-card.type-heading .bc-card-body{ padding:var(--space-2) var(--space-3); display:flex; align-items:center; }

.bc-card.type-heading.selected{ border-color:color-mix(in srgb, var(--accent) 45%, transparent); }

.bc-todo-row{ display:flex; align-items:flex-start; gap:var(--space-2); padding:var(--space-1) 0; font-size:var(--type-body); }

.bc-todo-box{ width:14px; height:14px; border-radius:var(--radius-tight); border:1.5px solid var(--glass-border-hi);
    flex:none; margin-top:var(--space-hair); cursor:pointer; display:flex; align-items:center; justify-content:center;
    font-size:var(--type-label); font-weight:700; color:var(--neutral-ink); }

/* A DARK TICK ON A LIGHT GREEN, not a light tick on a dark one.
     White-on-green was measured at 2.25:1 — the tick is the only text in the
     box, so the fill IS its paper, and a saturated fill leaves nowhere for a
     pale glyph to go. Lightening the fill and keeping the ink dark clears the
     floor and still reads unmistakably as done. */
  .bc-todo-box.done{ background:color-mix(in srgb, var(--green) 58%, #FFFFFF);
    border-color:color-mix(in srgb, var(--green) 75%, transparent); color:#0A0D12; }

.bc-todo-text{ font-size:var(--bc-size, inherit); flex:1; outline:none; word-break:break-word; line-height:1.5; }

/* Struck through and dimmed with a TOKEN, not with opacity. Opacity fades the
     ink towards whatever is behind it, which is how a finished line ends up at
     4.26:1 — the same mistake the out-of-month calendar dates once made. */
  .bc-todo-row.done .bc-todo-text{ color:var(--text-dim); text-decoration:line-through; }

.bc-todo-add{ font-size:var(--type-body); color:var(--text-dim); cursor:pointer; padding:var(--space-1) 0 0; }

.bc-todo-add:hover{ color:var(--accent); }

.bc-img{ width:100%; height:100%; object-fit:cover; display:block; }

.bc-img-empty{ height:100%; display:flex; align-items:center; justify-content:center; text-align:center;
    font-size:var(--type-body); color:var(--text-faint); cursor:pointer; padding:var(--space-3); line-height:1.6; }

.bc-link{ display:block; text-decoration:none; height:100%; }

.bc-link-title{ font-size:var(--type-body); font-weight:700; color:var(--text); margin-bottom:var(--space-1); word-break:break-word; }

.bc-link-url{ font-size:var(--type-body); color:var(--accent); word-break:break-all; }

/* The body is not a flex container by default, so `flex:1` on the fill did
     nothing and a swatch card rendered as a white rectangle with a hex code on
     it — the one card type whose entire job is to show a colour. */
  .bc-card.type-swatch .bc-card-body{ padding:0; display:flex; flex-direction:column; }

.bc-swatch-fill{ flex:1; min-height:0; }

.bc-swatch-foot{ padding:var(--space-2) var(--space-3); font-family:var(--font-mono); font-size:var(--type-label);
    color:var(--text-dim); display:flex; justify-content:space-between; gap:var(--space-2); flex:none; }

/* The two card types that make this Lucid's board rather than a clone. Both
     hold a reference, not a copy — see the note in the boards migration. */
  .bc-ref{ display:flex; flex-direction:column; gap:var(--space-1); height:100%; cursor:pointer; }

.bc-ref-top{ display:flex; align-items:center; gap:var(--space-2); }

.bc-ref-name{ font-size:var(--type-body); font-weight:700; color:var(--text); }

.bc-ref-sub{ font-size:var(--type-body); color:var(--text-dim); line-height:1.5; word-break:break-word; }

.bc-ref-open{ margin-top:auto; font-size:var(--type-label); color:var(--accent); font-weight:600; }

.bc-ref-gone{ font-size:var(--type-body); color:var(--orange); line-height:1.5; }

.bc-ref-badge{ font-size:var(--type-label); text-transform:uppercase; letter-spacing:.07em; color:var(--text-faint);
    border:1px solid var(--glass-border-hi); border-radius:var(--radius-tight); padding:1px var(--space-1); flex:none; }

/* A vault chip within days of its own renewal reads the same as the vault's
     own "coming up" list — one visual language for "you should look at this"
     wherever it appears. */
  .bc-ref-sub.hot{ color:var(--orange); font-weight:600; }

/* .bc-colour-row / .bc-colour / .bc-colour.active came across in the split
     from index.html and have had nothing to style since before it. The board's
     colours live in the inspector now: .bc-sw-row and .bc-sw, a hundred lines
     above, round instead of square and marked with .on instead of .active. Both
     sets survived side by side long enough that "which one is the real
     swatch" was a question a reader had to answer by grepping. */
@media(max-width:760px) {
.bc-tray{ width:auto; flex-direction:row; overflow-x:auto; padding:var(--space-2); }
.bc-tray-title{ display:none; }
.bc-stage{ flex-direction:column; }
.bc-tool span:not(.bc-tool-ico){ display:none; }
}

/* ==========================================================
     THE THREE LIVE BOARD ELEMENTS.
     "what are we going to do to fancy up the board?"
     A countdown, a live number, and a line in big type. The
     first two read Lucid every time they are drawn.
     ========================================================== */
  .bc-ico-cd, .bc-ico-met, .bc-ico-qt{ display:flex; align-items:center; justify-content:center;
    font-size:var(--type-body); color:var(--text); }

.bc-cd, .bc-metric, .bc-quote{ height:100%; display:flex; flex-direction:column;
    justify-content:center; gap:var(--space-1); padding:var(--space-3) var(--space-3); cursor:pointer; }

.bc-cd-empty, .bc-quote-empty{ align-items:center; justify-content:center;
    color:var(--text-faint); font-size:var(--type-body); text-align:center; }

.bc-cd-n{ font-size:var(--type-page); font-weight:600; line-height:1.05; font-variant-numeric:tabular-nums; }

.bc-cd-l{ font-size:var(--type-body); line-height:1.3; }

.bc-cd-d{ font-size:var(--type-label); color:var(--text-faint); font-variant-numeric:tabular-nums; }

/* Within a week it warms up; once it is past it goes quiet rather than red.
     A date that has been and gone is a record, not a problem. */
  .bc-cd.is-soon .bc-cd-n{ color:var(--orange); }

.bc-cd.is-past{ opacity:.6; }

.bc-metric-n{ font-size:var(--type-figure); font-weight:600; line-height:1; font-variant-numeric:tabular-nums; }

.bc-metric-l{ font-size:var(--type-body); color:var(--text-faint); }

.bc-quote-t{ font-size:var(--type-lead); line-height:1.4; font-style:italic; }

.bc-quote-w{ font-size:var(--type-body); color:var(--text-faint); margin-top:var(--space-2); }

/* ==========================================================
     FOUR MORE, 2 SEPTEMBER — a real decision, a hand-set goal,
     a link that reads its own page, and a live vault reference.
     See the long note above bcDefaults('choice') for why these
     four and not four others.
     ========================================================== */
  .bc-choice-row{ display:flex; align-items:flex-start; gap:var(--space-2); padding:var(--space-1) 0; font-size:var(--type-body); }

.bc-choice-mark{ width:16px; height:16px; border-radius:var(--radius-round); border:1.5px solid var(--glass-border-hi);
    flex:none; margin-top:1px; cursor:pointer; display:flex; align-items:center; justify-content:center;
    font-size:var(--type-label); color:var(--text-on-accent, #fff); transition:background var(--dur-fast) var(--ease-out); }

.bc-choice-row.chosen .bc-choice-mark{ background:color-mix(in srgb, var(--green) 60%, #FFFFFF);
    border-color:transparent; }

.bc-choice-text{ flex:1; outline:none; word-break:break-word; line-height:1.5; }

.bc-choice-decided{ margin-top:var(--space-2); font-size:var(--type-label); color:var(--text-faint); }

.bc-choice-promote{ color:var(--accent); font-weight:600; cursor:pointer; }

.bc-choice-promote:hover{ text-decoration:underline; }

/* current can run past target — the fill stops at 100% (see the clamp in
     bcCardInner) but the numbers underneath keep counting, because "132/100"
     is a truer sentence than a bar that pretends it topped out exactly even. */
  .bc-goal{ height:100%; display:flex; flex-direction:column; justify-content:center;
    gap:var(--space-2); padding:var(--space-3) var(--space-3); cursor:pointer; }

.bc-goal-label{ font-size:var(--type-body); font-weight:600; }

.bc-goal-bar{ height:8px; border-radius:var(--radius-control); background:color-mix(in srgb, var(--text) 10%, transparent);
    overflow:hidden; }

.bc-goal-fill{ height:100%; border-radius:var(--radius-control); background:var(--accent);
    transition:width var(--dur-base) var(--ease-out); }

.bc-goal-fill.done{ background:var(--green); }

.bc-goal-nums{ font-size:var(--type-label); color:var(--text-faint); font-variant-numeric:tabular-nums; }

/* The picture is a background-image rather than an <img> because there is no
     alt text worth writing for a thumbnail somebody else's page chose — the
     title below it already says what the card is. */
  .bc-webcard{ display:flex; flex-direction:column; height:100%; color:inherit; text-decoration:none; }

.bc-webcard-img{ flex:none; height:44%; min-height:56px; background-size:cover; background-position:center;
    background-color:color-mix(in srgb, var(--text) 6%, transparent); }

.bc-webcard-body{ flex:1; min-height:0; padding:var(--space-2) var(--space-3); display:flex; flex-direction:column; gap:var(--space-1); overflow:hidden; }

.bc-webcard-title{ font-size:var(--type-body); font-weight:700; line-height:1.35;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }

.bc-webcard-desc{ font-size:var(--type-label); color:var(--text-dim); line-height:1.4;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }

.bc-webcard-host{ font-size:var(--type-label); color:var(--text-faint); margin-top:auto; }

/* ===========================================================================
   THE THUMB. 44 x 44, EVERYWHERE A FINGER LANDS.
   ===========================================================================

   Matt, 24 September: "Tiny buttons... big fingers dont work". The iPhone app
   is a web view showing this same web app, so that is a sentence about this
   stylesheet and not about Swift.

   Apple has asked for 44 x 44 points since 2008. Lucid had never measured it.
   When tests/test-phone-touch-targets.js first ran, 255 of the 405 controls a
   finger can reach at 430px were under it — five out of every eight. Three
   places in this file had already done the arithmetic properly and written it
   down (the bottom bar at 48, the folder rail at 44, the 16px text box that
   stops iOS zooming). It had just never become a rule. This block is the rule.

   THERE ARE ONLY TWO MOVES HERE, and which one a control gets is a judgement
   about its drawing, not about its importance:

     GROWN — the control is a button and it was simply too small. A 27px-tall
     button on a phone is a mistake however it is dressed, so min-height makes
     it 44 and it looks like what it is. This is most of the list.

     WIDENED — the control is drawn small ON PURPOSE and the drawing is the
     point: a hairline, three stacked rungs, a round avatar, a bare × in a
     corner. Those get an invisible ::after that reaches 44 while the visible
     control does not move by a pixel. Nothing about the look changes; what
     changes is where a finger may land and still be understood.

   WHAT IS NOT HERE. No control moved, no row was re-ordered, nothing was
   hidden and no type size changed. Sizes and hit areas only. Where a control
   could not reach 44 without moving something else, it is written up rather
   than fudged — the mini-calendar's neighbours, and the one checkbox, are in
   WORKER-TB-25-SEPT-THE-PHONE-TAP-TARGETS.md as work somebody has to choose.

   THE QUERY. Touch without hover is the real condition — that is an iPhone in
   either orientation, and it leaves the Mac app, which has a pointer and a
   hover, exactly as it was. The width clause is the belt to that braces: it
   catches a narrow window on a machine that reports a fine pointer, and it is
   what the check measures at.
   ======================================================================== */
@media (hover: none) and (pointer: coarse), (max-width: 480px) {
.bc-board-tab{ min-height:44px; min-width:44px; }
.bc-zoom-btn{ min-width:44px; min-height:44px; }
.bc-zoom-level{ min-height:44px; display:flex; align-items:center; justify-content:center; }
.bc-board-add{ min-width:44px; min-height:44px; }
}

:is(.btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
    .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
    .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
    .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
    .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
    .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
    .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
    .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
    .connect-banner-go, .ht-art-btn, .mn-step){
  transition-property: scale, transform, background, color, box-shadow, border-color;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease-out);
}

/* THE TRAVEL. */
:is(button, [role="button"], input[type="button"], input[type="submit"],
    .btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
    .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
    .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
    .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
    .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
    .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
    .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
    .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
    .artwin-nav, .connect-banner-go, .ht-art-btn, .mn-step):active:not(:disabled, [aria-disabled="true"], .is-unavailable){
  scale: var(--press-scale);
  transition-duration: 60ms;
}

.bc-fam-switch{ display:inline-flex; align-items:center; gap:var(--space-1); font:inherit; font-size:var(--type-label);
  color:var(--text-dim); background:transparent; border:1px solid var(--glass-border); border-radius:var(--radius-pill);
  padding:var(--space-1) var(--space-2); cursor:pointer; }

.bc-fam-switch i{ width:var(--space-2); height:var(--space-2); border-radius:var(--radius-round);
  border:1px solid var(--text-faint); }

.bc-fam-switch.is-on{ color:var(--text); border-color:color-mix(in srgb, var(--pink) 50%, transparent);
  background:color-mix(in srgb, var(--pink) 18%, transparent); }

.bc-fam-switch.is-on i{ background:var(--pink); border-color:var(--pink); }

/* ===========================================================================
   STURDY. THE PHONE, MADE OF SOMETHING. 15 October.
   ===========================================================================

   Matt, 14 Oct, about the iPhone app: "Feels cheap and flimsy. Button depth,
   responsiveness, enlarge font (current is tiny)." He approved changes to
   those three on the phone. Nothing here reaches a desktop window: every rule
   is inside the phone query below, and tests/test-phone-sturdy.js compares
   every text size and control box at 1440x900 with base-14oct.

   THE QUERY. A phone-width window (the same 780px the bottom bar appears at),
   or a touch-only screen too short to be anything but a phone on its side.

   1. TYPE. Measured at 390x844 before this: body text 13px, and every label,
      time, tab and bottom-bar word at 11px. iOS reads at 17pt with a 13pt
      footnote. So the scale itself moves, once, on the phone, and the 2,000
      declarations that reach for a token follow it: label 11 -> 13, body
      13 -> 17, lead 16 -> 19 (it must stay above body), title 20 -> 22. The
      page, figure, display and hero steps are already big enough to read.

   2. THE PRESS. The house press (search "ONE MECHANISM FOR EVERY PRESS")
      shrinks to .972 in 60ms and washes the control in its own ink. On the
      phone it goes a little further and a little darker: scale .97, and a
      brightness step down, arriving in 80ms. Darker in both modes, because a
      finger covers the control and the darkening is what shows round it. No
      new colour: the control's own fill, dimmed.

   3. NO WAIT. touch-action: manipulation on the document and every control,
      so a tap is never held back to see whether it is a double tap. :where()
      so a row that already says pan-y (the mail row's swipe) keeps saying it.
      And the document does not rubber-band: the page scrolls inside .main,
      so the only thing an overscroll of the document could move is the whole
      app, chrome and all (the native half is in WebPane-iOS.swift).

   4. REACH. The controls on Home, Mail, a mail and Calendar that were under
      44x44 to a finger. Reply's strip GROWS (it is a row of buttons and 34px
      was simply small). The Day/Week toggle on Home and the names on its day
      curve are drawn small on purpose and get the house's invisible reach
      instead, so they do not move by a pixel.
   =========================================================================== */
@media (max-width: 780px), (hover: none) and (pointer: coarse) and (max-height: 500px) {
/* 2. THE PRESS, phone weight. The same list as THE TRAVEL above, so the
     controls that sink are the controls that darken. */
:is(button, [role="button"], input[type="button"], input[type="submit"],
      .btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
      .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
      .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
      .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
      .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
      .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
      .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
      .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
      .artwin-nav, .connect-banner-go, .ht-art-btn, .mn-step):active:not(:disabled, [aria-disabled="true"], .is-unavailable){
    filter: var(--press-filter);
    transition-property: scale, transform, background, color, box-shadow, border-color, filter;
    transition-duration: var(--dur-press);
  }
}
