/* controls.css — the basic controls and surfaces (K1–K17), drawn: blocks/controls.js's rules alone.
   Tokens only (tokens.css). The heights are settings (blocks/settings.js), set by
   controls.js as --k-* custom properties on the root; with a mouse each keeps its
   own height, on touch every control is --k-touch (B25); each reads with a token as fallback.
   Linked on blocks.html only (scripts/lib/style-files.js).
   Who may write it: any worker, under P2. */

.k-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.k-top { align-items: flex-start; }
.k-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.k-sign { font-weight: var(--weight-semibold); }

/* A control's focus: one ring, the template's. */
.k-btn:focus-visible, .k-link:focus-visible, .k-box:focus-visible, .k-seg-opt:focus-visible, .k-chip:focus-visible,
.k-row:focus-visible, .k-hint-btn:focus-visible, .k-dark-undo:focus-visible, .k-pop:focus-visible,
.k-tick-input:focus-visible + .k-tick-box {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: var(--focus-ring-offset);
}
.k-seg-opt:focus-visible { outline-offset: calc(-1 * var(--focus-ring-width)); }

/* K1 Button. #633 (#627 (e)): its room above and below the words is the setting buttonPadYPx, so it grows with the line. */
.k-btn {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  max-width: 100%; min-height: var(--k-btn-h, var(--control-h-sm)); padding: var(--k-btn-pad-y, var(--space-1)) 12px; /* #652: the side insets stay at the 100 % token's size (--space-3, 0.75rem) at any text size (Studio, gate log 115) */
  font: inherit; font-weight: var(--weight-medium); text-align: center;
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-control); cursor: pointer;
}
/* #625 fix 9 (b): a button's words wrap at spaces, never inside a word: a C15 tag in it too. */
.k-btn .p-tag { overflow-wrap: normal; }
/* #598 D10: the one action of a holder fills it on a phone; content-width with a mouse. */
.k-phone .k-btn-full { display: flex; width: 100%; }
.k-full-holder { display: block; width: 100%; max-width: 30rem; }
.k-btn-main { color: var(--color-on-accent); background: var(--color-accent); border-color: var(--color-border-accent); font-weight: var(--weight-semibold); }
.k-btn-small { min-height: var(--k-btn-sm-h, var(--control-h-sm)); padding: var(--k-btn-pad-y, var(--space-1)) 8px; font-size: 0.92em; } /* #652: --space-2 at 100 % */
/* #808, #911 (c): a stepper's arrow (K13 arrow:true): 32 px with a mouse (the K13 record's size, the rendering's); with touch the coarse rule below makes it 44. */
.k-btn-arrow { min-height: 32px; padding: var(--k-btn-pad-y, var(--space-1)) 8px; font-size: 0.92em; }
.k-btn-red { color: var(--color-danger); border-color: var(--color-danger-border-strong); }
/* #806 S4-20 (K1 dashed): a small button as a pill with a dashed edge, the accent word (mockups/S4 .a-add). */
.k-btn-dashed { color: var(--color-text-accent); background: transparent; border: 1px dashed var(--color-border-strong); border-radius: 999px; font-weight: var(--weight-semibold); white-space: nowrap; }
/* #503 rounds 8-9 (K1 go, S20-9): a line that is a button — the line's width, the words at the left, › at the right end. */
.k-btn-go { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: var(--space-2); text-align: left; }
.k-btn-go-sign { flex: none; }
.k-btn-alert { color: light-dark(var(--btn-danger-solid-fg), var(--color-bg)); background: var(--btn-danger-solid-bg); border-color: var(--btn-danger-solid-bg); font-weight: var(--weight-semibold); }
.k-btn-square { min-width: var(--k-touch, var(--tap-target)); padding: 0; }
/* #611: one disabled form, every kind, both themes: no fill of its own (the ground it is on), the hairline edge (under 3:1 on purpose, WCAG 1.4.11 exempts a disabled control), the subtle word, never bold. */
.k-btn[aria-disabled="true"] { color: var(--color-text-subtle); background: transparent; border-color: var(--color-border); font-weight: var(--weight-normal); cursor: default; }
.k-btn[aria-busy="true"] { cursor: progress; }

/* K2 Text link */
.k-link {
  display: inline-flex; align-items: center; box-sizing: border-box; min-height: var(--k-btn-h, var(--control-h-sm)); padding: 0 var(--space-2);
  font: inherit; font-weight: var(--weight-medium); color: var(--color-text-accent);
  background: none; border: 0; cursor: pointer; text-decoration: none; overflow-wrap: anywhere; text-align: left;
}
.k-link-current { text-decoration: underline; }
/* K2 `wrapWords` (#810 round 16, G4): a word is never broken inside itself; the link wraps between words only. */
.k-link-words { overflow-wrap: normal; word-break: normal; }
/* #805 round 5, K2 inline: the link in a sentence is text (it wraps with the words, the line keeps its height); a finger's 44 px is an area around the words. */
.k-link.k-link-inline { display: inline; min-height: 0; min-width: 0; padding: 0; position: relative; }
/* #805 round 6 (the #697 form for a link part inside a line): the mouse box is K2's 32 px by vertical padding, which an inline box takes without moving its line (no margin to cancel: an inline box's vertical margins are void). */
.k-link.k-link-inline { padding-top: calc((var(--k-btn-h, var(--control-h-sm)) - 1em) / 2); padding-bottom: calc((var(--k-btn-h, var(--control-h-sm)) - 1em) / 2); }
@media (pointer: coarse) { .k-link.k-link-inline::after { content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, var(--k-touch, var(--tap-target))); height: var(--k-touch, var(--tap-target)); transform: translate(-50%, -50%); } }

/* K3 Picker, and the label over any box */
.k-field { position: relative; display: flex; flex-direction: column; gap: var(--space-1); min-width: 12em; max-width: 100%; }
.k-label { color: var(--color-text-muted); text-align: left; }   /* #709 (5): a label sits at its box's left edge wherever it is drawn (a cell's centring is not its own) */
.k-box {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); box-sizing: border-box;
  width: 100%; min-height: var(--k-box-h, var(--control-h-md)); padding: 0 var(--space-3); font: inherit; text-align: left;
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border-input); border-radius: var(--radius-control); cursor: pointer;
}
/* #635 (d): the chosen line is one line, never cut (the option's short form); the box is at least as wide as it,
   the C15 tag beside the box or, with no room, on the next line. The 12em least room gives way to the line. */
.k-picker { min-width: min(12em, 100%); }
.k-picker-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); }
.k-picker-line > .k-box { flex: 1 1 auto; width: auto; min-width: min-content; }
.k-picker-tag { display: inline-flex; flex: none; }
.k-picker-tag[hidden] { display: none; }
/* #670 (d): never wider than its holder — the box shrinks to the holder and only then does the chosen line wrap,
   between its words (inside one only where a word is wider than the line); the page never scrolls sideways. */
.k-picker-value { flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere; }
.k-pop-tag { flex: none; }
.k-picker-legs { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); margin-top: var(--space-3); }
/* Where the list opens is B24 Layer's (behaviours.css); as a sheet on a phone its top corners are round. */
.k-pop.k-pop-sheet { border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.k-refused .k-box { border-color: var(--color-danger-border-strong); box-shadow: inset 0 0 0 1px var(--color-danger-border-strong); }
.k-msg { color: var(--color-danger); font-weight: var(--weight-medium); }
/* K3 chips (#620b): each option its own chip, the chips wrapping whole onto the next line; a chip wider than its line
   wraps between words, never inside one; the picked one pressed and filled with the text colour, as K5's. */
.k-chip-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* Chips wrap, so they need no picker's least width (12em): at large text it would be wider than a sheet's line (#620 fix 4). */
.k-field.k-chips { min-width: 0; }
.k-chip {
  display: inline-flex; align-items: center; box-sizing: border-box; max-width: 100%; min-height: var(--k-btn-h, var(--control-h-sm));
  padding: 0 var(--space-3); font: inherit; font-weight: var(--weight-semibold); text-align: left; white-space: normal; overflow-wrap: normal; word-break: normal;
  color: var(--color-text); background: var(--color-surface); border: 1px solid var(--color-border-strong); border-radius: var(--radius-control); cursor: pointer;
}
/* #803 (b): on is soft blue, a 1 px selected-edge border, the text colour. */
.k-chip[aria-checked="true"] { color: var(--color-text); background: var(--color-accent-subtle); border-color: var(--color-selected-edge); }
.k-refused .k-chip { border-color: var(--color-danger-border-strong); }
.k-plain { color: var(--color-text); min-height: var(--k-box-h, var(--control-h-md)); display: flex; align-items: center; }

/* K4 Tick box and its grid: the input covers the whole line */
.k-tick { position: relative; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); box-sizing: border-box; min-height: var(--k-tick-h, var(--control-h-sm)); cursor: pointer; }
.k-tick-input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; outline: none; cursor: inherit; }
.k-tick-box {
  position: relative; flex: none; box-sizing: border-box; width: 1.15em; height: 1.15em;
  background: var(--color-surface); border: 1.5px solid var(--color-border-strong); border-radius: var(--radius-xs);
}
.k-tick-input:checked + .k-tick-box, .k-tick-on > .k-tick-box { background: var(--color-accent); }
.k-tick-input:checked + .k-tick-box::after, .k-tick-on > .k-tick-box::after {
  content: ""; position: absolute; left: 0.32em; top: 0.08em; width: 0.3em; height: 0.6em;
  border: solid var(--color-on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.k-tick-why { flex-basis: 100%; padding-left: calc(1.15em + var(--space-2)); color: var(--color-text-muted); }
.k-tick-grid-wrap { overflow-x: auto; max-width: 100%; }
.k-tick-grid { border-collapse: collapse; table-layout: auto; width: auto; max-width: 100%; }
/* #676 (d): a column or row name wraps between its words (the page's th is nowrap), so the grid fits a phone without a sideways scroll. */
.k-tick-fill { width: 100%; }
.k-tick-fill > thead th { box-sizing: border-box; width: 11.5em; }
.k-tick-fill > thead th:first-child, .k-tick-fill > thead td:first-child { width: auto; }
.k-tick-grid th { white-space: normal; overflow-wrap: normal; padding: var(--space-1) var(--space-2); font-weight: var(--weight-semibold); text-align: left; }
.k-tick-grid td { padding: 0; text-align: center; }
.k-tick-grid .k-tick { justify-content: center; min-width: var(--k-tick-h, var(--control-h-sm)); width: 100%; }
/* S16-16 (#810): a row's name may be a text link with its state under it; a group heading row is a tinted band; a column's
   note is a small line under its name (amber when it needs you). On a phone the grid is a list: the column heads wrap in one band above, each
   row is a block and each of its ticks stands on a line of its own beside its column's name. */
/* #810 rounds 6-7 fix (c): a grid with a state under some names (.k-tick-subbed) draws every row as a name line in a K2
   link's box and one line under it, so a row with a plain name and no state is the same height as one with both. */
.k-tick-subbed .k-tick-name { display: inline-flex; align-items: center; box-sizing: border-box; min-height: var(--k-btn-h, var(--control-h-sm)); padding: 0 var(--space-2); }
.k-tick-subbed > tbody > tr:not(.k-tick-group) > th:not(:has(.k-tick-sub))::after { content: ''; display: block; height: 1lh; }
/* The state line stays whole (the column heads wrap first), so no row is taller than the others by a wrapped state; a phone's
   list (below) lets it wrap. */
.k-tick-grid th .k-tick-sub { min-width: max-content; }
.k-tick-grid th small, .k-tick-grid th .k-tick-sub { display: block; font-weight: var(--weight-normal); color: var(--color-text-muted); }
.k-tick-grid th .k-tick-warn { color: var(--color-text); font-weight: var(--weight-medium); box-shadow: inset 3px 0 0 var(--banner-edge); padding-left: var(--space-1); }
.k-tick-grid .k-tick-group th { padding: var(--space-1) var(--space-3); background: var(--color-surface-sunken); font-size: var(--text-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--color-text-muted); }
.k-tick-col { display: none; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) .k-tick-grid, .k-phone .k-tick-grid-wrap:has(.k-tick-col) tbody, .k-phone .k-tick-grid-wrap:has(.k-tick-col) tr { display: block; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) thead { display: block; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) thead tr { display: flex; flex-wrap: wrap; gap: 0 var(--space-3); }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) thead td { display: none; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) thead th small { display: inline; margin-left: var(--space-1); }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) th .k-tick-sub { min-width: 0; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) th { display: block; text-align: left; }
/* #810 rounds 6-7 fix (c): a tick line on a phone is K4's line: its column's name wraps between its words beside the box. */
.k-phone .k-tick-grid-wrap:has(.k-tick-col) td { display: flex; flex-wrap: wrap; align-items: center; text-align: left; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) .k-tick-col { flex: 1 1 0; min-width: 0; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) .k-tick { width: auto; justify-content: flex-start; }
.k-phone .k-tick-grid-wrap:has(.k-tick-col) .k-tick-col { display: inline; }

/* K5 Segmented control */
/* #620 fix 2: a segment never wraps, breaks or clips its words: each is its words on one line plus its padding,
   the control at least their sum (min-content: the tracks at their words; nothing clips it); on a phone the whole line, shared equally only where every
   word still fits (minmax(max-content, 1fr)). A list too wide for a 375 phone's line is refused by makeSeg. */
.k-seg { display: inline-grid; grid-auto-flow: column; grid-auto-columns: max-content; max-width: 100%; min-width: min-content; border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm); }
.k-seg-opt {
  box-sizing: border-box; min-height: var(--k-btn-h, var(--control-h-sm)); padding: 0 var(--space-3); font: inherit; font-weight: var(--weight-semibold);
  color: var(--color-text); background: var(--color-surface); border: 0; border-left: 1px solid var(--color-border-strong); cursor: pointer; white-space: nowrap;
}
.k-seg-opt:first-child { border-left: 0; border-radius: calc(var(--radius-sm) - 1px) 0 0 calc(var(--radius-sm) - 1px); }
.k-seg-opt:last-child { border-radius: 0 calc(var(--radius-sm) - 1px) calc(var(--radius-sm) - 1px) 0; }
/* #803 (a): the chosen segment is the neutral pill with a 2 px selected-edge ring, never a fill (as TS.segmented). */
.k-seg-opt[aria-checked="true"] { color: var(--color-text); background: var(--segment-pill); box-shadow: inset 0 0 0 2px var(--color-selected-edge); }
/* Stacked (#620 round 3): the words do not fit the line at this text size, so one segment a line, each the control's whole width, one frame,
   a 1 px line between (on the top edge now, not the left). */
.k-seg-word { display: inline-block; }
.k-seg.k-seg-stack { grid-auto-flow: row; grid-auto-columns: auto; }
/* Drawn as a row for a moment to see whether it overflows (#620 fix 4): narrower than its words is allowed, so the words show it. */
.k-seg.k-seg-try { min-width: 0; }
/* Stacked, a label wider than the whole line wraps between its words, never inside one. */
.k-seg-stack .k-seg-opt { border-left: 0; border-top: 1px solid var(--color-border-strong); white-space: normal; overflow-wrap: normal; }
.k-seg-stack .k-seg-opt:first-child { border-top: 0; border-radius: calc(var(--radius-sm) - 1px) calc(var(--radius-sm) - 1px) 0 0; }
.k-seg-stack .k-seg-opt:last-child { border-radius: 0 0 calc(var(--radius-sm) - 1px) calc(var(--radius-sm) - 1px); }

/* K6 Dialog */
.k-dialog {
  box-sizing: border-box; max-width: 26em; padding: var(--space-4);
  color: var(--color-text); background: var(--color-surface-raised); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.k-dialog-title { margin: 0 0 var(--space-2); font-weight: var(--weight-semibold); overflow-wrap: anywhere; }
.k-dialog-line { margin: 0 0 var(--space-4); overflow-wrap: anywhere; }
.k-dialog-actions { justify-content: flex-end; }
/* Over the page, the dimmed page behind is B24 Layer's (behaviours.css). */

/* K7 Pop list */
.k-pop {
  box-sizing: border-box; max-width: 100%; overflow-x: hidden; overflow-y: auto;
  color: var(--color-text); background: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-control); box-shadow: var(--shadow-md);
}
.k-pop-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--space-3);
  box-sizing: border-box; min-height: var(--k-pop-row, var(--control-h-lg)); padding: 0 var(--space-3); cursor: pointer;
}
/* A row's name is never cut (#634 fix 1 round 2 item 3): longer than the list's width (the gutter's cap) it wraps
   between its words and the row grows (44 px or more on touch, its least height); a word longer than the line alone breaks. */
/* #634 fix 3: a word is never broken: the name keeps its longest word (min-width auto) and, where the trailing note
   does not fit beside it, the note drops under the name at its left edge (#613 fix 2's rule, for every row). */
.k-pop-name { flex: 1 1 auto; max-width: 100%; overflow-wrap: break-word; }
/* #811 round 10 (@route-piece): a name in pieces breaks only between them, after the "·"; each piece is whole. */
.k-pop-piece { white-space: nowrap; }
.k-pop-main { display: flex; align-items: flex-start; gap: var(--space-3); flex: 1 1 auto; max-width: 100%; }
/* #634 fix 4: the box sits at the name's FIRST line on every row (its centre on that line's), and a note dropped
   under the name starts at the name's text start (past the box and the gap), so the tick column stays clear. */
.k-pop-main > .k-tick { margin-top: calc((1lh - 1.15em) / 2); }
.k-pop-main ~ .k-pop-note { margin-left: calc(1.15em + var(--space-3)); }
/* several: K4's box at the start of the row; the row is the target, the box only shows it. */
.k-pop-main > .k-tick { flex: none; min-height: 0; min-width: 0; pointer-events: none; }
/* links: the name, the note, then the links at the right; they wrap under the name when they do not fit. */
.k-pop-linkrow { flex-wrap: wrap; justify-content: flex-start; column-gap: var(--space-3); padding-top: var(--space-1); padding-bottom: var(--space-1); }
.k-pop-linkrow > .k-pop-name { flex: 1 0 auto; max-width: 100%; }
.k-pop-links { display: inline-flex; flex-wrap: wrap; gap: 0 var(--space-3); margin-left: auto; }
.k-pop-chosen { font-weight: var(--weight-semibold); }
.k-pop-note { flex: none; color: var(--color-text-muted); }
/* #613: a row that cannot be picked (C6's action with its reason): the subtle colour. */
.k-pop-off { color: var(--color-text-subtle); cursor: default; }
.k-pop-off > .k-pop-note { color: inherit; }
/* #613 fix 2: a row with a long note (a reason) keeps it at the right while it fits beside the name; when it must
   wrap it goes under the name, starting at the name's left edge (space-between leaves a line's one item at the
   start). A note shared by adjacent rows is drawn once, under the last of them (.k-pop-note-shared). */
.k-pop-wrap { flex-wrap: wrap; column-gap: var(--space-3); row-gap: 0; padding-top: var(--space-1); padding-bottom: var(--space-1); }
.k-pop-wrap > .k-pop-name { flex: 0 1 auto; max-width: 100%; }
.k-pop-wrap > .k-pop-note { flex: 0 1 auto; min-width: 0; overflow-wrap: break-word; }
/* #634 fix 5: a code (item nameCode / noteCode, as C5's fact { code: true }) is nowrap, in the fixed-width face (V4), one
   piece: it keeps its whole width (min-width auto) and, wider than the line beside the rest, takes a line of its own.
   #643: a note code may shrink (never below its least width, min-width auto: a code whole, a list of codes its widest
   part), so a list wider than even its own line (past the tick's inset too) breaks after a joiner, never past the list. */
.k-pop-code { white-space: nowrap; overflow-wrap: normal; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.k-pop-note.k-pop-code { flex-shrink: 1; min-width: auto; }
.k-pop-wrap > .k-pop-note-shared { flex-basis: 100%; }
/* #676 (c): a list in a layer is as wide as its widest row, within the gutter, however narrow the layer's own width was set
   (B24 sets it to its anchor's; a plain list placed there had its rows spilling past it). The fit and least forms say more. */
.b24 > .k-pop:not(.k-pop-sheet) { width: max-content; max-width: calc(100vw - 2 * var(--page-gutter)); }
/* #613 fix: width 'content' (a menu from a small button): its rows' own width, up to the screen's less the page gutter; a sheet keeps the screen's. */
.k-pop-fit:not(.k-pop-sheet) { width: max-content; max-width: calc(100vw - 2 * var(--page-gutter)); }
/* #634 fix 1: an anchored list is at least its box's width, else its widest row's (a row is never cut), within the gutter. */
.k-pop-least:not(.k-pop-sheet) { width: max-content; min-width: min(var(--k-pop-least, 0px), calc(100vw - 2 * var(--page-gutter))); max-width: calc(100vw - 2 * var(--page-gutter)); }
.k-pop-group-head { padding: var(--space-2) var(--space-3) var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--color-text-muted); overflow-wrap: break-word; }
.k-pop-active { background: var(--color-accent-subtle); box-shadow: inset 0 0 0 2px var(--color-border-accent); }
/* K2's rule (#575): a link is never on the raised ground. Rows with links take the surface, as ☰ and
   People do; the highlighted row keeps the fill and ring of K7's other forms (its links 7.07:1 light, 8.14:1 dark). */
.k-pop-linkform { background: var(--color-surface); }

/* K8 Banner: amber warns, red refuses */
.k-banner {
  display: flex; align-items: center; gap: var(--space-2); box-sizing: border-box; padding: var(--space-2) var(--space-3);
  font-weight: var(--weight-semibold); color: var(--color-text); border: 1px solid; border-radius: var(--radius-control);
}
.k-banner + .k-banner { margin-top: var(--space-2); }
/* #810 round 11 (S16-22, a block fault): a banner a page hides (`hidden`) is not drawn; the display above no longer overrides it. */
.k-banner[hidden] { display: none; }
.k-banner-warn { background: var(--banner-bg); border-color: var(--banner-edge); }
.k-banner-refused { background: var(--color-danger-surface); border-color: var(--color-danger-border-strong); }
/* K8's two options (#575): lines under the one line, its heading; the one button at the end */
.k-banner-lines { align-items: flex-start; }
.k-banner-body { flex: 1 1 auto; min-width: 0; }
.k-banner-body > span { display: block; min-width: 0; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; }   /* #798: pre-wrap as K12 (#795), WebKit folds a figure and its unit whole. #781 round 3: a block, so it takes the cell's width and its ellipsis applies */
/* #776: a word moves whole to the next line. The words keep 6em beside a button (K8 measures, k-banner-stack), else the button goes under, at the
   end; a word longer than the row is cut with an ellipsis, never broken inside itself. */
.k-banner > span { flex: 1 1 auto; min-width: 0; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; }
.k-banner-stack { flex-wrap: wrap; }
.k-banner-stack > span { flex-basis: 100%; }
.k-whole { display: inline-block; white-space: nowrap; }
/* #774: a figure and its unit (TSB.unitPieces): no break inside, and inline so the line's height is the sentence's (an inline-block moved the row below by 1 px). */
.k-whole.k-unit { display: inline; }
/* #503 rounds 8-9 (W8 small unit, S20-8): the unit .62em and muted after its figure, inside the one piece. */
.k-unit-small { font-size: 0.62em; color: var(--color-text-muted); font-weight: var(--weight-medium); }   /* round 12 (d): the medium weight, not the figure's bold */
.k-banner-list { margin: var(--space-1) 0 0; padding-left: 1.25em; font-weight: var(--weight-normal); }
.k-banner-list li { overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; }
.k-banner-more { margin: var(--space-1) 0 0; font-weight: var(--weight-normal); }
.k-banner > .k-btn { flex: none; margin-left: auto; }
.k-banner > .b-wait { flex: none; margin-left: auto; }
/* #720: the one button at the end (Dismiss) shares the row only where the heading's words keep 12em: at 200 % text on a phone
   they would be a 160 px column, so the button goes under them, at the end. 700 px and up, and 100 % text, are as before. */
.k-banner-dismiss { flex-wrap: wrap; }
.k-banner-dismiss > span, .k-banner-dismiss > .k-banner-body { flex: 1 1 12em; }
.k-banner-dismiss > .k-btn { margin-left: auto; }
/* K8's third option, said (#578): the banner's own colour and weight, between the heading and the button
   where all three fit on one row (K8 measures), else under the heading at full width with the button
   staying at the right end of the first row. Empty: not drawn, no gap. */
.k-banner-said { margin: 0; font-weight: var(--weight-normal); min-width: 0; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; }
.k-banner-said[hidden] { display: none; }
.k-banner-saying { display: grid; align-items: center; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "head said btn"; }
.k-banner-saying.k-banner-nobtn { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "head said"; }
.k-banner-saying.k-banner-under { row-gap: var(--space-1); grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); grid-template-areas: "head btn" "said said"; }
.k-banner-saying.k-banner-column { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "said" "btn"; }
.k-banner-saying.k-banner-nobtn.k-banner-under { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "said"; }
.k-banner-saying > span, .k-banner-saying > .k-banner-body { grid-area: head; }
.k-banner-saying > .k-banner-said { grid-area: said; }
.k-banner-saying > .k-btn, .k-banner-saying > .b-wait { grid-area: btn; justify-self: end; }
/* K8 measures the three at their natural width, on one line each. #781: no transition into the measure (a reduced-motion
   0.01ms one left flex-shrink at 1 when read, and the said line shrank to "fit"), and above `.k-banner > span` so the
   heading is measured whole, not shrunk to 0. */
.k-banner.k-banner-saying.k-banner-measure { display: flex; flex-wrap: nowrap; }
.k-banner.k-banner-measure > * { flex: none; white-space: nowrap; transition: none; }

/* K9 Dark line: the template draws it as the text colour on the surface, so it is dark in light and light in dark */
.k-dark {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); box-sizing: border-box; max-width: 26em;
  padding: var(--space-2) var(--space-3); color: var(--color-surface); background: var(--color-text); border-radius: var(--radius-card);
}
.k-dark + .k-dark { margin-top: var(--space-2); }
/* #776: the words keep 6em before the button shares their row, else it goes under, at the end; a word longer than the row is cut with an
   ellipsis, never broken inside itself. */
.k-dark-text { flex: 1 1 6em; min-width: 0; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; }
.k-dark-undo {
  flex: none; margin-left: auto; min-height: var(--k-btn-h, var(--control-h-sm)); min-width: var(--k-touch, var(--tap-target)); padding: 0 var(--space-2); font: inherit; font-weight: var(--weight-semibold);
  color: inherit; background: none; border: 0; text-decoration: underline; cursor: pointer;
}

/* K10 Empty box and K11 List card share the card */
.k-card {
  box-sizing: border-box; max-width: 100%; overflow: hidden;
  color: var(--color-text); background: var(--color-surface);
  border: var(--hairline) solid var(--color-border-strong); border-radius: var(--radius-md); box-shadow: none;
}
.k-empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); padding: var(--space-4); }
.k-empty-dashed { border-style: dashed; }
/* #817 round 10 (@empty-state): `center` centres the card's words and its button. */
.k-empty-center { align-items: center; text-align: center; }
/* #810 round 10 (S16-27, S16-28): `add` as a list is one bar of buttons; `loading` is one muted line of words, the card's own padding. */
.k-empty-center .k-empty-adds { justify-content: center; }
.k-empty-adds { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.k-empty-loading { padding-block: var(--space-3); }
.k-empty-title { font-weight: var(--weight-semibold); overflow-wrap: anywhere; }
.k-empty-line { color: var(--color-text-muted); overflow-wrap: anywhere; }
.k-card-head {
  padding: var(--space-1) var(--space-3); font-size: 0.85em; font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-text-muted); background: var(--color-surface-sunken);
  overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; /* #799: folds whole as K12 (#795). #776: a word moves whole; one longer than the row is cut with an ellipsis */
}
.k-card-head .k-count-line, .k-card-head .k-count-line .k-count-name { overflow-wrap: normal; }
.k-card-group + .k-card-group .k-card-head { border-top: var(--hairline) solid var(--color-border-strong); }
.k-card-rows { margin: 0; padding: 0; list-style: none; }
/* #806: a group's content in place of rows, inside the card's padding. */
.k-card-body { padding: var(--space-2) var(--space-3); }
.k-row {
  display: flex; align-items: center; gap: var(--space-3); box-sizing: border-box; width: 100%; min-height: var(--k-row-h, var(--control-h-md)); padding: var(--space-1) var(--space-3);
  font: inherit; text-align: left; color: var(--color-text); background: none; border: 0;
  flex-wrap: wrap;   /* #799: a row too narrow for its code, text, note and sign folds onto lines; the sign is inside the card */
}
button.k-row { cursor: pointer; }
.k-card-rows li + li { border-top: var(--hairline) solid var(--color-border); }
.k-row-code { flex: none; min-width: 6em; }
/* #676 (f): a row's text wraps between words, never cut with "…" (nothing cut; a 1 px cut was the same fault). */
.k-row-text { flex: 1 1 auto; overflow-wrap: break-word; }
.k-row-note { flex: 0 1 auto; color: var(--color-text-muted); }
.k-row > .k-sign { flex: none; margin-left: auto; }   /* #799: the go sign never shrinks or leaves the row: the row folds (code, text, note, sign wrap onto lines), nothing narrower than its words */

/* K12 Sunken box */
.k-sunken {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); box-sizing: border-box; max-width: 30em;
  padding: var(--space-2) var(--space-3); color: var(--color-text); background: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-control);
}
.k-sunken .k-btn { flex: none; margin-left: auto; }
/* #776: a word moves whole; a value longer than the row (a key) is cut with an ellipsis and its whole is the box's title. */
/* #795: pre-wrap, not normal: WebKit's collapsing-space line breaker kept "tanks 57,000 lb ·" on one line 5 px past the clip edge and cut
   it ("57,000 l…") where Chromium folds the figure and its unit to the next line; pre-wrap breaks it the Chromium way (the text has
   no newline or doubled space, so nothing else changes). An ellipsis is left for one piece wider than the whole box. */
.k-sunken-text { flex: 1 1 6em; min-width: 0; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis; white-space: pre-wrap; }
/* #676 (a), the Studio's answer: option `groups`: four characters to a group, a drawn gap between groups, wrapping only between
   groups; each group is one nowrap piece. No scroll, no cut.
   Inline-block pieces, not flex items: a select-all of flex items copies a line break between them. */
.k-sunken-group { display: inline-block; white-space: nowrap; margin-right: var(--space-3); }
.k-sunken-group:last-child { margin-right: 0; }

/* K14 Count */
.k-count-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-4); }
/* #676 (e): a name is never cut with "…" (the standing rule: nothing cut); every count wraps its name, #615's `wrap` form
   is now the only one. Between words; inside a word only where the word alone is longer than the line (the #605 tag rule). */
.k-count-line, .k-count-line .k-count-name { display: inline; overflow: visible; text-overflow: clip; white-space: normal; overflow-wrap: break-word; }
.k-count-line { max-width: 100%; min-width: 0; }
.k-count-name { font-weight: var(--weight-semibold); }
.k-count-line .k-count { white-space: nowrap; }
.k-count { color: var(--color-text-muted); font-weight: var(--weight-normal); }

/* K15 Hint on demand */
.k-hint-stack { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }
.k-hint-wrap { position: relative; display: inline-flex; flex-direction: column; align-items: flex-start; max-width: 100%; }
.k-hint { color: var(--color-text-muted); overflow-wrap: anywhere; }
.k-hint[hidden] { display: none; }
/* A tap hint's words open in a B24 layer under the thing (B24 places it): a surface of their own over the page. */
.k-hint-line {
  display: block; box-sizing: border-box; width: max-content; max-width: min(var(--measure-cell), calc(100vw - 2 * var(--space-3))); padding: var(--space-2) var(--space-3);
  background: var(--color-surface); border: 1px solid var(--color-border-strong); border-radius: var(--radius-control); box-shadow: var(--shadow-md);
}
.k-hint-stage { min-height: 9rem; }
/* K15's term form (#575): the term in the text's own words, dotted as an abbreviation; its name opens under it. */
.k-term { text-decoration: underline dotted; text-underline-offset: 0.2em; cursor: help; }
.k-term:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: 2px; }
.k-term-note { white-space: normal; }
/* inControl (#689): inside a K5 segment or a K1 button the control is what is pressed; no dotted underline, no help cursor. */
.k-term-in { text-decoration: none; cursor: inherit; }
@media (pointer: coarse) { .k-term-in { display: inline; min-height: 0; min-width: 0; } }
@media (pointer: coarse) { .k-term { display: inline-flex; align-items: center; justify-content: center; min-height: var(--k-touch, var(--tap-target)); min-width: var(--k-touch, var(--tap-target)); } }
.k-hint-btn {
  display: inline-flex; align-items: center; gap: var(--space-1); box-sizing: border-box; min-height: var(--k-btn-h, var(--control-h-sm)); padding: 0 var(--space-3);
  font: inherit; font-weight: var(--weight-semibold); color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-full); cursor: pointer;
}

/* K16 Text box: the frame holds the box and its unit; the message line sits under it */
.k-text { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; max-width: 100%; }
/* #658: nothing in K16 transitions. The box measures its lines (grow) when its size changes; under reduced motion
   tokens.css gives every element a 0.01 ms transition of `all`, so after a text-size change the box's own font size
   landed a rendering step after its padding: grow measured the old font, and the regrow came a step late (on CI,
   after the check read). Its sizes now follow what holds it in the step they change, as C5's row (#581 round 7). */
.k-text, .k-text * { transition-property: none; }
.k-text-narrow { width: 8em; }
/* #635 (c): a box with a unit holds its value whole beside the unit word (controls.js sets the input's least width). */
.k-text.k-text-figure { min-width: min-content; }
/* #625 fix 9 (a): measured (controls.js), its least width is capped at the line: never wider than its window. */
.k-text.k-text-figure.k-text-fit:not(.k-text-tagged) { min-width: min(var(--k-text-least, 0px), 100%); }
.k-text-full { width: 100%; }
/* #810 round 12 (@timeout-open, the valve): a narrow figure is as wide as its measured least when that is more than 8em (its widest allowed value, `widest`, whole), so a box shrink-wrapped by its holder never clips it. */
.k-text-narrow.k-text-figure.k-text-fit:not(.k-text-tagged) { width: max(8em, var(--k-text-least, 0px)); max-width: 100%; }
/* #806 S4-37: a time's frame is 5.4em and a fuel's or a weight's 6.6em, its text mono at 1.08em (the em is the frame's
   own, as the rendering's .a-in); the label may run wider than the frame. On a phone the frame takes the box's width. */
.k-text-time > .k-text-frame, .k-text-weight > .k-text-frame { font-family: var(--font-mono); font-size: 1.08em; font-variant-numeric: tabular-nums; }
.k-text-time > .k-text-frame { width: 5.4em; max-width: 100%; }
.k-text-weight > .k-text-frame { width: 6.6em; max-width: 100%; }
.k-phone .k-text-time > .k-text-frame, .k-phone .k-text-weight > .k-text-frame { width: 100%; }
/* #806 S4-30: the unit after the label, set apart from its words and muted. */
.k-text-label-unit { margin-inline-start: 0.15em; font-weight: 400; color: var(--color-text-muted); }
.k-text-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.k-text-frame {
  display: flex; align-items: center; gap: var(--space-2); box-sizing: border-box;
  min-height: var(--k-box-h, var(--control-h-md)); padding: 0 var(--k-text-start, var(--space-3));
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border-input); border-radius: var(--radius-control);
}
.k-text-window { border-color: var(--color-border-strong); }
.k-text-frame:focus-within { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.k-text-area { position: relative; display: flex; flex: 1 1 auto; min-width: 0; }
.k-text-input { flex: 1 1 auto; width: 100%; min-width: 0; box-sizing: border-box; min-height: var(--k-box-h, var(--control-h-md)); margin: -1px 0; padding: var(--space-2) 0; font: inherit; color: inherit; background: none; border: 0; outline: none; resize: none; }
/* The box fills the frame's height, over its 1 px edge, so the box itself is the 36 px (44 on touch). */
textarea.k-text-input { max-height: calc(var(--k-text-lines, 6) * 1lh + 2 * var(--space-2)); overflow-y: auto; }
.k-text-input::placeholder { color: var(--color-text-muted); opacity: 1; }
.k-text-right { text-align: right; }
.k-text-inherit { position: absolute; inset: 0; display: flex; align-items: center; color: var(--color-text-muted); pointer-events: none; overflow: hidden; white-space: nowrap; }
.k-text-inherit.k-text-right { justify-content: flex-end; }
.k-text-inherit[hidden] { display: none; }
.k-text-unit { flex: none; color: var(--color-text-muted); }
/* #597 fix 9: the frame's room round the text is fixed in px (--space-3's 100 % value): a larger text
   size grows the words, never the margins round them, so a box keeps its room for them (S10 round 2 item 4).
   #627 (d): the three insets (start, gap, the action's own) are one setting, textBoxInsetsPx, set by controls.js. */
/* #616: K16's one small action, inside the frame at its right end and as tall as the box. #597 fix 9
   (597b (a)): it lies over the box's right end; the box's end padding is its measured width plus the
   frame's gap, set by controls.js after each draw and resize, so the text never runs under it. The room
   round its word and that gap are fixed in px (the tokens' 100 % values): a larger text size grows the
   word, never the room round it. */
.k-text-acting { position: relative; padding-inline-end: 0; gap: var(--k-text-gap, var(--space-2)); }
.k-text-acting:focus-within:not(:has(.k-text-input:focus)) { outline: none; }
.k-text-act { position: absolute; inset-block: -1px; inset-inline-end: 0; justify-content: center; padding-inline: var(--k-text-act-pad, var(--space-2)); white-space: nowrap; }
.k-text-refused { border-color: var(--color-danger-border-strong); box-shadow: inset 0 0 0 1px var(--color-danger-border-strong); }
.k-text-warned { border-color: var(--banner-edge); box-shadow: inset 0 0 0 1px var(--banner-edge); }
.k-text-waiting, .k-text-denied { background: var(--color-surface-sunken); }
.k-text-waiting { cursor: progress; }
.k-text-denied, .k-text-denied .k-text-input { color: var(--color-text-muted); }
.k-text-plain { padding: 0; background: none; border-width: 0; }
.k-text-line { display: flex; align-items: baseline; gap: var(--space-3); }
.k-text-msg { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; color: var(--color-text-muted); }
.k-msg-refused { color: var(--color-danger); font-weight: var(--weight-medium); }
.k-msg-warned { color: var(--color-text); font-weight: var(--weight-medium); }
.k-text-count { flex: none; margin-left: auto; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.k-text-count-over { color: var(--color-danger); font-weight: var(--weight-medium); }
/* #581: freeLine(): the line under the box is on one line and not held to the box's width; on a phone it wraps. */
.k-text-free { align-items: flex-start; }
.k-text-free > .k-text-line .k-text-msg { white-space: nowrap; }
/* A several-line box keeps its whole width: only its line is freed (#581 fix round 8, item 17's Reminder takes the rest). */
.k-text-free.k-text-many > .k-text-frame { align-self: stretch; }
.k-phone .k-text-free { align-items: stretch; }
.k-phone .k-text-free > .k-text-line .k-text-msg { white-space: normal; }
/* Studio round 3 (S15 Q2): freeLine(false): the line wraps in the box's own width and never widens what holds the box. */
.k-text-held > .k-text-line { contain: inline-size; }
/* #607 c; fix 2, items 1-2: a box with a tag lays its parts in a row that wraps: the label, then the tag line
   (the C15 tag and up to two K2 links, after the box in the page so Tab reaches the box first) at the right
   end of the label row, or on a second line where that row has no room; the box and its line under them.
   The tag line is one line, never wrapped inside, and the box is at least as wide as it (min-content). */
.k-text.k-text-tagged { flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: var(--space-3); row-gap: var(--space-1); min-width: min-content; }
.k-text-tagged > .k-text-label { flex: 0 1 auto; min-width: 0; }
.k-text-tagged > :not(.k-text-label):not(.k-text-tag) { flex: 0 0 100%; order: 1; }
.k-text-tag { display: inline-flex; flex: 0 0 auto; flex-wrap: nowrap; align-items: center; column-gap: var(--space-1); margin-left: auto; white-space: nowrap; }
.k-text-links { display: inline-flex; flex-wrap: nowrap; align-items: center; column-gap: var(--space-1); }
.k-phone .k-text-tag { margin-left: 0; margin-right: auto; }
/* #635 (c): on a phone the tagged box is never wider than its line: where the tag line has no room it wraps
   BETWEEN its pieces — the tag, then its links together on the next line, then each link on its own — never inside one.
   A computer keeps #607's one tag line and the box at least as wide as it (G6, #621). */
.k-phone .k-text.k-text-tagged { min-width: fit-content; max-width: 100%; }
.k-phone .k-text-tag { flex-wrap: wrap; row-gap: var(--space-1); max-width: 100%; white-space: normal; }
.k-phone .k-text-links { flex-wrap: wrap; row-gap: var(--space-1); }
.k-phone .k-text-tag > * { white-space: nowrap; }
.k-phone .k-text-tagged > .k-text-label { flex-basis: 100%; }
/* #625: on a phone a tagged box is the line's width and never wider; its tag line stays one line while it fits
   and breaks between its pieces (the tag, Accept, Dismiss) only where it cannot, as at 200 % text on a 390 phone. */
.k-phone .k-text.k-text-tagged { min-width: 0; }
.k-phone .k-text-narrow.k-text-tagged { width: auto; }
.k-phone .k-text-tag { flex-wrap: wrap; flex-shrink: 1; min-width: 0; row-gap: var(--space-1); }
/* #635 fix 4: the read-only form. (1) On a computer the reader's tag follows its label one gap after it on the label's line
   (it has no links, so it adds no width). (2) A one-line value and its unit are one nowrap piece at the column's start, the
   unit one gap after the value: the area is as wide as its text (a hidden copy of it, data-v), never the column. On a phone the
   tag keeps its own line; boxes on one row share the tallest's height, the frames level at the foot. */
html:not(.k-phone) .k-text-ro.k-text-tagged { column-gap: var(--space-2); }
html:not(.k-phone) .k-text-ro > .k-text-tag { margin-left: 0; }
.k-text-ro > .k-text-frame { margin-top: auto; align-items: baseline; } /* #625 fix 9 (d): the value and its unit on one baseline */
/* #625 fix 9 (a): a reader's value is never wider than its line: wider, it scrolls in its box (its mirror clipped). */
.k-text-plain .k-text-area[data-v] { display: inline-grid; flex: 0 1 auto; min-width: 0; grid-template-columns: minmax(0, auto); overflow: clip; }
.k-text-plain .k-text-area[data-v]::after { content: attr(data-v); grid-area: 1 / 1; visibility: hidden; white-space: pre; padding-inline: 1px; }
.k-text-plain .k-text-area[data-v] > .k-text-input { grid-area: 1 / 1; width: 0; min-width: 100%; }
.k-phone .k-text-ro.k-text-tagged { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; }
.k-phone .k-text-ro.k-text-tagged > .k-text-label, .k-phone .k-text-ro.k-text-tagged > .k-text-frame { flex: 0 0 auto; }
.k-phone .k-text-ro.k-text-tagged > .k-text-frame { align-self: stretch; }
.k-text-stack { display: flex; flex-direction: column; gap: var(--space-3); max-width: 28em; }

/* On touch every control is --k-touch (B25), and a picker's text is 16 px so the phone does not zoom. */
@media (pointer: coarse) {
  .k-btn, .k-btn-small, .k-btn-arrow, .k-link, .k-seg-opt, .k-chip, .k-hint-btn, .k-dark-undo, .k-box, .k-plain, .k-tick, .k-row,
  .k-pop-row, .k-text-frame, .k-text-input { min-height: var(--k-touch, var(--tap-target)); }
  .k-btn, .k-link, .k-seg-opt, .k-chip, .k-hint-btn, .k-tick-grid .k-tick { min-width: var(--k-touch, var(--tap-target)); }
  .k-tick-subbed .k-tick-name { min-height: var(--k-touch, var(--tap-target)); }
  /* #635 fix 4 (3): the least size is a floor; the text scales above it with the form's text size. */
  /* #792: the picker's box and the text input share one size rule (its 1em floor), so the text grows with the page's. */
  .k-text-input, .k-box { font-size: max(var(--k-touch-text, var(--text-lg)), 1em); }
  /* #637 (e): a reader's value is no target (nothing happens on a tap): its area is its text, the unit one gap after it,
     as on a computer ("4.12 per gal" as tight as "1,200 gal"). The 44 px is the edit box's alone. */
  .k-text-plain .k-text-area[data-v] { font-size: max(var(--k-touch-text, var(--text-lg)), 1em); }
}
/* A phone is the setting phoneMaxWidthPx: controls.js puts .k-phone on the root. */
.k-phone .k-seg { display: grid; width: 100%; grid-auto-columns: minmax(max-content, 1fr); }
.k-phone .k-seg.k-seg-stack { grid-auto-columns: auto; }
/* K1's set() demonstration (#616): the button, then its caption */
.k-demo { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); margin-top: var(--space-3); }
.k-demo-note { margin: 0; color: var(--color-text-muted); }

/* K17 Bullet list (#688, STUDIO ANSWER S1 #594 17f). The marker is a dot in the text colour, centred on the first
   line's x-height: an inline dot in the marker's own line, raised half an ex less half its size over the baseline,
   the marker and the words aligned on their first baselines. One gap (bulletGapPx) between them; the words are their
   own column, so wrapped lines hang under the words. Nothing is cut: no ellipsis, no nowrap on a line. */
.k-bl-stack { display: flex; flex-direction: column; gap: var(--space-4); }
.k-bl-sample { max-width: 20em; }
.k-bl-wrap { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1); min-width: 0; color: var(--color-text); }
.k-bl-wrap[hidden], .k-bl[hidden], .k-bl-empty[hidden] { display: none; }
.k-bl-head { margin: 0; font-size: 1em; font-weight: var(--weight-semibold); line-height: var(--leading-snug); color: var(--color-text); overflow-wrap: break-word; }
.k-bl { display: flex; flex-direction: column; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.k-bl-line {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: var(--k-bl-gap, var(--space-2));
  align-items: baseline; line-height: var(--leading-normal); color: var(--color-text);
}
.k-bl-dot {
  display: inline-block; width: 0.36em; height: 0.36em; border-radius: 50%;
  background: currentColor; vertical-align: calc(0.5ex - 0.18em); forced-color-adjust: none;
}
.k-bl-text { min-width: 0; color: var(--color-text); overflow-wrap: break-word; white-space: normal; }
.k-bl-lead { font-weight: var(--weight-bold); }
.k-bl-empty { margin: 0; color: var(--color-text-muted); overflow-wrap: break-word; }
button.k-bl-edit {
  box-sizing: border-box; margin: 0; padding: 0; font: inherit; line-height: inherit; text-align: left;
  min-block-size: 24px; /* #701: WCAG 2.2 target size; the words stay on their own baseline */
  background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
button.k-bl-edit:hover { background: var(--color-surface-hover); }
button.k-bl-edit:focus-visible { outline: var(--focus-ring-width) solid var(--color-focus); outline-offset: var(--focus-ring-offset); }
.k-bl-row { min-width: 0; }
.k-bl-add { align-self: flex-start; }
@media (pointer: coarse) { button.k-bl-edit { min-height: var(--k-touch, var(--tap-target)); } }
/* #688 (b), the Studio's marker rule (gate log 144): **bold** is the lead's semibold in the text colour (inside the
   lead it draws once, never heavier); *italic* is the slant alone, the weight and colour unchanged. */
.k-bl-b { font-weight: var(--weight-semibold); color: var(--color-text); }
.k-bl-i { font-style: italic; font-weight: inherit; }

/* #688 (b), K16 format (the Studio's format bar, gate log 146): three K1 square toggles joined in one group, each
   apart (several may be pressed); pressed is filled with the text colour, the glyph in the surface's (K5's
   selected look). B semibold, I italic, M on the C15 piece tint. On a mouse K1's 36 px, its hit area 44 px tall;
   44 × 44 on touch (K1's own coarse rule). The group wraps whole. */
.k-fmt { display: inline-flex; flex: none; align-self: flex-start; border: 1px solid var(--color-border-strong); border-radius: var(--radius-control); background: var(--color-surface); }
.k-fmt > .k-fmt-btn { position: relative; border: 0; border-radius: 0; background: transparent; }
.k-fmt > .k-fmt-btn + .k-fmt-btn { border-left: 1px solid var(--color-border-strong); }
.k-fmt > .k-fmt-btn:first-child { border-radius: calc(var(--radius-control) - 1px) 0 0 calc(var(--radius-control) - 1px); }
.k-fmt > .k-fmt-btn:last-child { border-radius: 0 calc(var(--radius-control) - 1px) calc(var(--radius-control) - 1px) 0; }
.k-fmt > .k-fmt-btn::after { content: ''; position: absolute; left: 0; right: 0; top: min(0px, calc((100% - var(--k-touch, 44px)) / 2)); bottom: min(0px, calc((100% - var(--k-touch, 44px)) / 2)); }
.k-fmt > .k-fmt-btn:focus-visible { outline-offset: calc(-1 * var(--focus-ring-width)); }
.k-fmt > .k-fmt-btn[aria-pressed="true"] { color: var(--color-text); background: var(--segment-pill); box-shadow: inset 0 0 0 2px var(--color-selected-edge); }
.k-fmt-bold .k-sign { font-weight: var(--weight-semibold); }
.k-fmt-italic .k-sign { font-style: italic; font-weight: var(--weight-normal); }
.k-fmt-mark .k-sign { padding: 0 0.2em; border-radius: 3px; font-weight: var(--weight-normal); color: var(--color-text); background: var(--cell-changed-bg); }
/* In a row's bar (K17 puts it in B3's): at the left, --space-4 after Remove, which no longer pushes it right; the bar
   stays on the screen's foot while its row is open (a phone's keyboard, 200 % text): sticky inside its row. */
.b-bar.k-fmt-host { position: sticky; bottom: 0; z-index: 1; background: var(--color-surface); }
.b-bar.k-fmt-host > .b-bar-remove { margin-right: 0; }
.b-bar.k-fmt-host > .k-fmt { margin-right: auto; align-self: center; }
.b-bar.k-fmt-host > .b-bar-remove + .k-fmt { margin-left: calc(var(--space-4) - var(--space-3)); }
