/* Contour responsive policy. Existing thresholds keep their original geometry.
   :root specificity keeps these rules ahead of lazily loaded surface styles.
   New behavior belongs only in the phone or coarse/no-hover sections below. */
:root { --rail-overlay: 0; --phone-layout: 0; --touch: 0; --phone-or-touch: 0; }
.touch-only, .phone-only { display: none; }

@media (max-width: 1200px) {
  /* app */
:root .app[data-config="open"] .workarea { grid-template-columns: var(--rail-w) minmax(0, 1fr) 0; }
  :root .app[data-rail="closed"][data-config="open"] .workarea { grid-template-columns: 0 minmax(0, 1fr) 0; }
  :root .app[data-config="open"] .configrail {
    position: fixed; top: calc(var(--topbar-h) + var(--viewbar-h)); right: 0; bottom: 0;
    width: var(--config-w); z-index: var(--z-sticky);
    border-left: var(--border); box-shadow: var(--shadow-md);
  }
}

@media (max-width: 1100px) {
  /* view-chart */
:root .view-chart .vc-grid .vc-tile[data-span="4"] { grid-column: span 6; }
  /* view-form */
:root .view-form .vf-builder { width: 300px; }
}

@media (max-width: 1000px) {
  /* view-timeline */
:root .view-timeline { --tl-side: 200px; }
  :root .view-timeline .tl-by { display: none; }
}

@media (max-width: 900px) {
  :root { --rail-overlay: 1; }
  /* app */
:root .workarea, :root .app[data-rail="open"] .workarea { grid-template-columns: 0 minmax(0, 1fr) 0; }
  :root .app[data-rail="open"] .viewrail {
    position: fixed; top: calc(var(--topbar-h) + var(--viewbar-h)); left: 0; bottom: 0;
    width: var(--rail-w); z-index: var(--z-sticky); box-shadow: var(--shadow-md);
  }
  :root .app[data-rail="closed"] .viewrail { display: none; }
  :root .topsearch { width: var(--control-h); padding: 0; justify-content: center; }
  :root .topsearch > span:not(.icon), :root .topsearch .kbd { display: none; }
  /* the six view controls drop to icons here: labelled they need 456px, and
     below ~960 that is more than the bar has left after the view name, the
     record count, Share and Configure. Each keeps title + aria-label. */
  :root .tools .tool > .tool-label { display: none; }
  :root .tools .tool { padding: 0 var(--sp-1); min-width: var(--control-h-sm); justify-content: center; }
  /* view-calendar */
:root .view-calendar .cal-tray { flex-basis: 200px; width: 200px; }
  :root .view-calendar .cal-title { font-size: var(--fs-base); }
  :root .view-calendar .cal-by { display: none; }
  /* view-chart */
:root .view-chart .vc-drawer { width: 240px; }
  /* builders */
:root .ob-split { grid-template-columns: minmax(0, 1fr); }
  :root .ob-preview { border-right: 0; border-bottom: var(--border-soft); }
}

@media (max-width: 860px) {
  /* view-form */
:root .view-form .vf-main { flex-direction: column; overflow-y: auto; }
  :root .view-form .vf-builder { width: auto; border-right: 0; border-bottom: var(--border); overflow: visible; }
  :root .view-form .vf-canvas { overflow: visible; padding: var(--sp-4) var(--sp-2) var(--sp-8); }
}

@media (max-width: 760px) {
  /* view-timeline */
:root .view-timeline .tl-body { flex-direction: column; }
  :root .view-timeline .tl-tray { flex: 0 0 auto; width: auto; max-height: 38%; border-left: 0; border-top: var(--border); }
  /* view-chart */
:root .view-chart .vc-grid .vc-tile { grid-column: span 12 !important; }
}

@media (max-width: 720px) {
  /* app */
/* Share and Configure lose their labels too, and keep title + aria-label */
  :root .tool > .tool-label { display: none; }
  :root .tool { padding: 0 var(--sp-1); min-width: var(--control-h-sm); justify-content: center; }
  /* same rule for the layout control: the icon IS the layout, and the button
     keeps title + aria-label naming it to pointer and screen reader */
  :root .view-layout-label { display: none; }
  :root .view-layout { padding: 0 var(--sp-1); }
  :root .ws-switch > span.truncate { display: none; }
  :root .ws-switch { max-width: none; padding: 0 var(--sp-1); }
  :root .tab-add > span:not(.icon) { display: none; }
  :root .tab-add { padding: 0 var(--sp-2); margin-left: 0; }
  :root .tab { padding: 0 var(--sp-2); max-width: 160px; }
  :root .topbar { padding: 0 var(--sp-1); gap: var(--sp-1); }
  :root .topbar-right .btn.icon.ghost { display: none; }   /* both live in the account menu */
  /* view-board */
:root .view-board { --board-col-w: 240px; }
  :root .view-board .board-scrim { padding: 0; align-items: flex-end; }
  :root .view-board .board-dialog { width: 100%; max-height: 92%; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  /* view-gallery */
:root .view-gallery { --gal-card-w: 160px; }
  /* builders */
:root .rec-section.cols-2 .rec-secgrid, :root .rec-section.cols-3 .rec-secgrid { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  /* view-calendar */
:root .view-calendar .cal-body { flex-direction: column; }
  :root .view-calendar .cal-tray { flex: 0 0 auto; width: auto; max-height: 40%; border-left: 0; border-top: var(--border); }
}

@media (max-width: 680px) {
  /* builders */
:root .bx-unresrow { grid-template-columns: minmax(0, 1fr); }
  :root .bx-impactcounts { grid-template-columns: 1fr; }
}

@media (max-width: 600px) {
  /* unit B: grid, list, gallery */
  :root .view-grid .vg-pop > .panel, :root .view-list .vl-pop > .panel { min-width: 0; }
  :root .view-grid .vg-paste { width: 100%; min-height: 88px; }
  :root .view-list .vl-metacell { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
  :root .view-list .vl-rowacts { margin-left: auto; }
  :root .view-gallery .gal-facts dd { min-width: 0; overflow-wrap: anywhere; }

  :root { --phone-layout: 1; --phone-or-touch: 1; }
  /* tokens */
:root { --viewbar-h: calc(2 * var(--control-h-sm) + 20px); }
  /* app */
:root .viewbar {
    flex-wrap: wrap; align-content: center;
    row-gap: var(--sp-1); padding: var(--sp-1) var(--sp-2);
    overflow-x: auto;                  /* wrapping means it should not overflow;
                                          if it ever does, it scrolls — it never
                                          silently zeroes a control again */
  }
  :root .viewbar > .tools { order: 2; flex: 1 0 100%; }
  :root .viewbar > .vrule { display: none; }
  /* a wrapping flex line wraps before it shrinks, so the view name is given a
     zero basis and told to grow: it then fills whatever line 1 has left
     instead of pushing Share and Configure onto a third row (measured at
     320px: three rows, 15px of clipped overflow). The spacer is redundant
     once the name does the pushing. */
  :root .viewbar > .view-name { flex: 1 1 0; max-width: none; }
  :root .viewbar > .spacer { display: none; }
  /* tour */
:root .tour-label { display: none; }
  /* Shell: the viewport owns the height; each surface keeps its own scroller. */
  :root .phone-only { display: inline-flex; }
  :root .app { height: 100vh; height: var(--visible-height, 100dvh); }
  :root .topbar-right { gap: var(--sp-1); }
  :root .tabs { min-width: 0; }
  :root .tab { flex: 0 0 auto; max-width: 50vw; }
    :root .tools { min-width: 0; overflow-x: auto; }
  :root .vb-count { min-width: 0; max-width: 20vw; }
  :root .modal-wrap { padding: var(--sp-2); height: 100vh; height: var(--visible-height, 100dvh); top: var(--visible-top, 0px); }
  :root .modal { max-height: calc(100vh - 16px); max-height: calc(var(--visible-height, 100dvh) - 16px); }
  :root .modal-head, :root .modal-foot, :root .panel-head { flex-wrap: wrap; }
  :root .popover, :root .bx-menu { min-width: 0; max-width: calc(100vw - 16px); }
  :root .fb-line { flex-wrap: wrap; }
  :root .fb-val { min-width: 0; flex: 1 1 100%; }
  :root .arch-row { flex-wrap: wrap; }
  :root .arch-row .grow { flex-basis: 60%; }
  :root .pal-list { min-height: 0; }
  :root .pal-head, :root .pal-foot { flex-wrap: wrap; }
  :root .pal-scope { flex-wrap: wrap; }
  :root .pal-input { min-width: 0; flex-basis: 70%; }
  :root .vg-toasthost, :root .vl-toasthost { max-width: calc(100vw - 24px); }
  :root .vg-toast, :root .vl-toast, :root .board-toast { min-width: 0; max-width: 100%; white-space: normal; flex-wrap: wrap; }

  /* Rails: full width, with an explicit close and a scrim behind the view rail. */
  :root .app[data-rail="open"] .viewrail,
  :root .app[data-config="open"] .configrail { width: 100%; }
  :root .rail-scrim { display: none; }
  :root .app[data-rail="open"] .rail-scrim {
    display: block; position: fixed; inset: 0; border: 0; padding: 0;
    background: var(--scrim); z-index: var(--z-rail);
  }
  :root .rail-phone-close { align-self: flex-end; margin: var(--sp-2); }

  /* Grid: keep the existing table scroller. Touch gutter geometry is below. */
  :root .view-grid .vg-pop { max-width: calc(100vw - 16px); }

  /* List: metadata wraps beneath the title instead of displacing actions. */
  :root .view-list .vl-scroll { padding: var(--sp-2); }
  :root .view-list .vl-row { flex-wrap: wrap; gap: var(--sp-1); }
  :root .view-list .vl-indent { max-width: 44px; overflow: hidden; }
  :root .view-list .vl-main { flex: 1 1 80px; overflow-wrap: anywhere; }
  :root .view-list .vl-meta { flex: 1 1 100%; max-width: 100%; flex-wrap: wrap; }

  /* Board: cap the actual flex basis, not the inline configuration variable. */
  :root .view-board .board-col:not(.is-collapsed),
  :root .view-board .board-col-head:not(.is-collapsed) { width: min(var(--board-col-w), calc(100vw - 32px)); flex-basis: min(var(--board-col-w), calc(100vw - 32px)); }
  :root .view-board .board-cover-blank { height: var(--sp-8); min-height: 0; }

  /* Calendar: horizontal scroll preserves readable days and distinct Add targets. */
  :root .view-calendar .cal-month { min-width: 0; }
  :root .view-calendar .cal-grid, :root .view-calendar .cal-weekdays { min-width: calc(var(--cal-cols) * 80px); }
  :root .view-calendar .cal-time { overflow: auto; }
  :root .view-calendar .cal-time-scroll { overflow: visible; }
  :root .view-calendar .cal-time-head, :root .view-calendar .cal-time-canvas { min-width: calc(var(--cal-gutter-w) + var(--cal-cols) * 80px); }
  :root .view-calendar .cal-tray { min-height: 0; overflow: auto; }
  :root .view-calendar .cal-pop { max-width: calc(100vw - 24px); }

  /* Timeline: preserve the horizontal timeline and reduce its sticky label reservation. */
  :root .view-timeline { --tl-side: 120px; }
  :root .view-timeline .tl-tray { min-height: 0; overflow: auto; }
  :root .view-timeline .tl-toolbar { flex-wrap: wrap; }

  /* Gallery */
  :root .view-gallery { --gal-card-w: min(160px, calc(100vw - 32px)); }

  /* Chart: drawer stacks beneath the still-scrollable chart. */
  :root .view-chart .vc-main { flex-direction: column; }
  :root .view-chart .vc-drawer { width: 100%; max-height: 50%; border-left: 0; border-top: var(--border); }
  :root .view-chart .vc-tile { min-width: 0; }

  /* Form: two independently scrollable regions. */
  :root .view-form .vf-main { overflow: hidden; }
  :root .view-form .vf-builder { flex: 0 1 45%; min-height: 0; overflow-y: auto; }
  :root .view-form .vf-canvas { flex: 1 1 55%; min-height: 0; overflow-y: auto; }

  /* Builders/designers: max-width wins even against an inline width. */
  :root .bx-wrap { max-height: 100vh; height: var(--visible-height, 100dvh); max-height: var(--visible-height, 100dvh); top: var(--visible-top, 0px); }
  :root .bx-modal { padding: var(--sp-2); }
  :root .bx-panel { max-width: 100%; max-height: 100%; }
  :root .bx-modal > .bx-panel { max-height: calc(100vh - 16px); max-height: calc(var(--visible-height, 100dvh) - 16px); }
  :root .bx-foot, :root .bx-row { flex-wrap: wrap; }
  :root .bx-wrap.designer-dock.beside-rail { padding-right: 0; top: calc(var(--visible-top, 0px) + var(--visible-height, 100dvh) / 2); height: calc(var(--visible-height, 100dvh) / 2); background: var(--surface); overflow: hidden; }
  :root .app:has(.configrail .designer) .configrail { top: var(--visible-top, 0px); bottom: auto; height: calc(var(--visible-height, 100dvh) / 2); z-index: var(--z-sticky); }
  /* The desktop slide starts 24px outside the screen and fades over the board.
     Both phone halves must cover their full region from the first frame. */
  :root .designer-dock .bx-panel { width: 100%; animation: none; }
  :root .dz-stagecol { flex-basis: min(var(--board-col-w), calc(100vw - 64px)); }

  /* Record */
  :root .rec-grid { grid-template-columns: minmax(0, 1fr); }
  :root .rec-field { min-width: 0; }
  :root .rec-secgrid { min-width: 0; }

  /* unit D: builders, designers, record */
  :root .bx-rail:has(> .designer) { bottom: auto; height: calc(var(--visible-height, 100dvh) / 2); }
  :root .designer-dock:not(.beside-rail) { top: calc(var(--visible-top, 0px) + var(--visible-height, 100dvh) / 2); height: calc(var(--visible-height, 100dvh) / 2); }
  :root .dz-tabs, :root .rec-tabs, :root .rec-stages, :root .rec-actions { flex-wrap: wrap; }
  :root .bx-field, :root .bx-field > *, :root .cmp-row, :root .rec-control { min-width: 0; max-width: 100%; }
  :root .bx-body input, :root .bx-body select, :root .bx-body textarea { max-width: 100%; }
  :root .rec-sign, :root .rec-gatehead, :root .rec-actline { flex-wrap: wrap; }
  :root .bx-vocrow .input { min-width: 0; width: 0; }
  :root .bx-toast { min-width: 0; max-width: calc(100vw - 16px); flex-wrap: wrap; }

  /* Login */
  :root body:has(#login) main { padding: var(--sp-3); }
  :root #login { padding: var(--sp-4); }

  /* Tour */
  :root .tour-bubble { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); overflow-y: auto; }

  /* unit C: board, calendar, timeline, chart, form */
  :root .view-calendar .cal-bar, :root .view-chart .vc-bar, :root .view-form .vf-bar { flex-wrap: wrap; }
  :root .view-calendar .cal-grid, :root .view-calendar .cal-weekdays { min-width: calc(var(--cal-cols) * 140px); }
  :root .view-calendar .cal-time-head, :root .view-calendar .cal-time-canvas { min-width: calc(var(--cal-gutter-w) + var(--cal-cols) * 140px); }
  :root .view-form .vf-item-head { flex-wrap: wrap; }
  :root .view-form .vf-item-name { flex: 1 1 70%; }
  :root .view-form .vf-item-acts { margin-left: auto; }
  :root .view-form .vf-item-editor, :root .view-form .vf-card { min-width: 0; max-width: 100%; }
  :root .view-chart .vc-tile-head, :root .view-chart .vc-tile-actions { flex-wrap: wrap; }
  :root .view-chart .vc-editor { min-width: 0; max-width: 100%; }
  :root .view-chart .vc-tip { max-width: calc(100% - 16px); max-height: calc(100% - 16px); overflow: auto; }

}

@media (max-width: 520px) {
  /* builders */
:root .rel-cards { flex-direction: column; align-items: stretch; }
  :root .rel-arrow { transform: rotate(90deg); align-self: center; margin: 0; }
}

/* Input capability is independent of width: a wide tablet needs the same targets. */
@media (pointer: coarse) {
  :root { --touch: 1; --phone-or-touch: 1; }
  /* unit B: grid, list, gallery */
  :root .view-grid .vg-th.vg-colhead { display: table-cell; position: sticky; vertical-align: top; }
  :root .view-grid .vg-colhead .vg-resize { position: absolute; right: 0; bottom: 0; top: auto; }
  :root .view-grid .vg-range { position: absolute; left: 0; bottom: 0; width: 44px; height: 44px; padding: 0; }
  :root .view-grid .vg-fill { display: flex; align-items: center; justify-content: center; }
  :root .view-grid .vg-fill::after { content: '+'; font-size: 24px; }
  :root .view-grid .vg-range-actions { width: 44px; height: 44px; padding: 0; }
  :root .view-list .vl-rowact { width: 44px; height: 44px; }
  :root .view-list .vl-move { flex: none; padding: 0; width: 44px; height: 44px; }

  :root {
    --control-h: 44px; --control-h-sm: 44px; --control-h-lg: 44px;
    --row-short: 44px; --row-medium: 44px; --col-header-h: 44px;
    -webkit-tap-highlight-color: transparent;
  }
  :root .touch-only { display: inline-flex; }
  /* View writers attach their pointer gestures to this explicit handle. */
  :root .touch-handle { display: inline-flex; min-width: 44px; min-height: 44px; touch-action: none; }
  :root .view-calendar .cal-chip, :root .view-calendar .cal-tray-chip,
  :root .view-timeline .tl-bar, :root .view-timeline .tl-tray-chip { touch-action: pan-x pan-y; }
  :root .view-timeline { --tl-lane-h: 48px; --tl-bar-h: 44px; }
  :root .view-grid { --vg-head: 88px; }
  :root .view-grid .vg-colhead { display: flex; flex-direction: column; }
  :root .view-grid .vg-colbtn { height: 44px; }
  :root .view-grid .vg-resize { position: static; width: 44px; height: 44px; align-self: flex-end; touch-action: none; }
  :root .view-grid .vg-fill { width: 44px; height: 44px; right: 0; bottom: 0; touch-action: none; }
  :root .view-grid .vg-cell { padding-bottom: 44px; }
  :root .board-check, :root .rec-tag { min-height: 44px; min-width: 44px; }
  :root button, :root [role="button"], :root [role="menuitem"], :root label.check,
  :root .check:has(input), :root select, :root input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]) {
    min-width: var(--control-h); min-height: var(--control-h);
  }
  :root .btn.icon, :root .tool, :root .rail-more, :root .avatar { flex-shrink: 0; }
  :root .rail-item, :root .tab, :root .panel-head { min-height: var(--control-h); }
  :root .viewbar { align-content: center; }
  :root .swatches { flex-wrap: wrap; }
  :root .check { min-width: 44px; min-height: 44px; }
  :root .view-grid .vg-rowact, :root .view-grid .vg-check, :root .view-grid .vg-fx,
  :root .view-grid .vg-groupadd, :root .view-grid .vg-aggadd, :root .view-grid .vg-colcaret,
  :root .view-list .vl-select, :root .view-list .vl-rowacts, :root .view-calendar .cal-add,
  :root .view-board .board-chip-x, :root .rail-more, :root .tab-caret, :root .rec-fieldmenu { opacity: 1; }
  :root .view-grid .vg-rownum { opacity: 0; }
  /* The gutter is fixed by the grid's column model. Stack its three targets so
     none overlaps a neighboring cell or another action. */
  :root .view-grid { --vg-row: max(var(--row-h), 136px); --vg-foot: 44px; }
  :root .view-grid .vg-gut { flex-direction: column; justify-content: center; }
  :root .view-grid .vg-rowid { width: 44px; height: 44px; }
  :root .view-grid .vg-check { width: 44px; height: 44px; inset: 0; }
  :root .view-grid .vg-rowact { width: 44px; height: 44px; }
  :root .view-list .vl-select { width: 44px; height: 44px; }
  :root .view-grid .vg-summary { min-height: 44px; }
  :root .view-calendar { --cal-chip-h: 44px; }
  :root .view-calendar .cal-cell-head { min-height: 44px; }
  :root .view-board .board-chip { min-height: 44px; }
  :root .view-board .board-resize { position: relative; top: auto; right: auto; width: 44px; height: 44px; flex: none; }
  :root .view-board .board-col-head.is-collapsed, :root .view-board .board-col.is-collapsed { width: 64px; flex-basis: 64px; }
  :root .view-board .board-resize { grid-column: 1 / -1; justify-self: end; }
  :root .rec-fieldmenu { position: static; flex: none; }
  /* unit B: grid, list, gallery — compact touch grid and bottom actions */
  :root .view-grid { --vg-row: max(var(--row-h), 44px); --vg-head: 44px; --vg-dock-h: 44px; }
  :root .view-grid.has-bulk { --vg-dock-h: 96px; }
  :root .view-grid .vg-gutter { padding: 0; }
  :root .view-grid .vg-gut { flex-direction: row; gap: 0; }
  :root .view-grid .vg-rownum, :root .view-grid .vg-rowmore { display: none; }
  :root .view-grid .vg-check { appearance: none; border: 0; border-radius: 0; background: transparent; }
  :root .view-grid .vg-check::after { content: ''; display: block; width: 18px; height: 18px; margin: 13px; border: var(--border); border-radius: var(--radius-sm); }
  :root .view-grid .vg-check:checked::after { background: var(--accent); box-shadow: inset 0 0 0 3px var(--surface); }
  :root .view-grid .vg-check:indeterminate::after { background: var(--accent); }
  :root .view-grid .vg-cell { padding-bottom: 0; }
  :root .view-grid .vg-colhead .vg-resize { top: 0; bottom: 0; right: -5px; width: 10px; height: 44px; }
  :root .view-grid .vg-star { min-width: 0; min-height: 0; pointer-events: none; }
  :root .view-grid .vg-scroll { bottom: var(--vg-dock-h); padding-bottom: var(--vg-dock-h); scroll-padding-bottom: calc(var(--vg-dock-h) + 44px); }
  :root .view-grid .vg-bulkhost { left: 0; right: 0; bottom: 0; transform: none; flex-direction: column-reverse; height: var(--vg-dock-h); background: var(--raised); }
  :root .view-grid .vg-bulk { flex: none; width: 100%; max-width: none; height: 52px; padding: 4px; border-radius: 0; overflow-x: auto; white-space: nowrap; box-sizing: border-box; }
  :root .view-grid .vg-bulk > * { flex-shrink: 0; }
  :root .view-grid .vg-rangebar { height: 44px; align-items: center; gap: var(--sp-2); }
  :root .view-grid .vg-rangebar .vg-range { position: static; }
  :root .view-grid .vg-range-actions { width: auto; padding: 0 var(--sp-2); }
  :root .view-grid .vg-toasthost,
  :root .view-grid .vg-bulkhost:not(:empty) ~ .vg-toasthost { left: 0; right: 0; bottom: var(--vg-dock-h); transform: none; max-width: none; }
  :root .view-grid .vg-toasthost > * { pointer-events: none; }
  :root .view-grid .vg-toast { max-width: 100%; }

  /* unit B: grid, list, gallery — native tap timing and reserved dock space */
  :root .view-grid button, :root .view-grid .vg-cell { touch-action: manipulation; }
  :root .view-grid .touch-handle, :root .view-grid .vg-fill { touch-action: none; }
  :root .view-grid .vg-row .vg-td, :root .view-grid thead .vg-th { border-bottom: 0; box-shadow: inset 0 -1px var(--line-2); }
  :root .view-grid thead .vg-check { display: block; }
  :root .view-grid:has(.vg-rangepanel) { --vg-dock-h: 220px; }
  :root .view-grid.has-bulk:has(.vg-rangepanel) { --vg-dock-h: 272px; }
  :root .view-grid .vg-rangepanel { display: grid; flex: none; height: 176px; grid-template: 44px 88px 44px / 1fr 1fr; }
  :root .view-grid .vg-rangepanel textarea, :root .view-grid .vg-range-paste { grid-column: 1 / -1; }
  :root .view-grid .vg-rangepanel textarea { width: 100%; height: 88px; min-width: 0; resize: none; box-sizing: border-box; }
  :root .view-grid:has(.vg-toast) .vg-scroll { bottom: calc(var(--vg-dock-h) + 64px); }
  :root .view-grid .vg-toast { height: 64px; width: 100%; box-sizing: border-box; padding: 4px; flex-wrap: nowrap; overflow-y: auto; pointer-events: auto; }
  :root .view-grid .vg-toast-msg { flex: 1; min-width: 0; }

  /* unit B: grid, list, gallery — keep the sticky footer below reserved padding */
  :root .view-grid tfoot .vg-td { bottom: calc(0px - var(--vg-dock-h)); }

  /* unit C: board, calendar, timeline, chart, form */
  :root .view-board .board-card { position: relative; padding-right: 56px; min-height: 52px; }
  :root .view-board .board-touch-move { position: absolute; right: 4px; top: 4px; width: 44px; height: 44px; padding: 0; justify-content: center; }
  :root .board-check, :root .board-dialog button, :root .designer .btn { touch-action: manipulation; }
  :root .board-check input { width: 44px; height: 44px; flex: none; }
  :root .palette .pal-foot > .row { display: none; }
  /* All-day chips share the timed grid's width and stay in their own row. */
  :root .view-calendar .cal-allday { position: relative; overflow: auto; }
  :root .view-calendar .cal-allday-cell { overflow: hidden; }
  :root .view-calendar .cal-touch-move, :root .view-timeline .tl-touch-move { align-items: center; justify-content: center; flex: none; cursor: grab; }
  :root .view-calendar .cal-chip { min-height: 44px; }
  :root .view-calendar .cal-grid { grid-auto-rows: minmax(144px, 1fr); }
  :root .view-calendar .cal-chip.is-timed { padding-right: 44px; min-width: 52px; }
  :root .view-calendar .cal-chip.is-timed .cal-touch-move { position: absolute; top: 0; right: 0; }
  /* Reserve a 44px Add strip and readable lanes beside it on touch screens. */
  :root .view-calendar .cal-time { --cal-add-w: 44px; }
  :root .view-calendar .cal-time-head, :root .view-calendar .cal-allday, :root .view-calendar .cal-time-canvas { min-width: calc(var(--cal-gutter-w) + var(--cal-cols) * (44px + var(--cal-slot-cols, 1) * 96px)); }
  :root .view-calendar .cal-hour { width: 44px; flex-shrink: 0; box-sizing: border-box; }
  :root .view-calendar .cal-time-add { max-width: 100%; white-space: normal; }
  :root .view-timeline { --row-h: 100px; }
  :root .view-timeline .tl-bar { overflow: visible; top: 4px; transform: none; }
  :root .view-timeline .tl-handle, :root .view-timeline .tl-bar > .tl-touch-move {
    position: absolute; top: 44px; width: 44px; height: 44px; min-width: 44px; touch-action: none;
    background: var(--raised); border: var(--border); border-radius: var(--radius-sm); opacity: 1;
  }
  :root .view-timeline .tl-handle.is-start { left: 0; right: auto; }
  :root .view-timeline .tl-bar > .tl-touch-move { left: 44px; }
  :root .view-timeline .tl-handle.is-end { left: 88px; right: auto; }
  :root .view-timeline .tl-handle.is-start::after { content: '←'; }
  :root .view-timeline .tl-handle.is-end::after { content: '→'; }
  :root .view-chart .vc-tip { pointer-events: auto; }

  /* unit C: board, calendar, timeline, chart, form */
  :root .view-board .board-collapse { touch-action: manipulation; }
  /* Success notices contain no actions and must not intercept the next drag. */
  :root .view-timeline .tl-flash.ok, :root .view-calendar .cal-flash.ok { pointer-events: none; }


  /* unit D: builders, designers, record */
  :root .designer .dz-touch-move { touch-action: none; min-width: 44px; min-height: 44px; }
  :root .rec-item:has(.dz-touch-move) { position: relative; padding-right: 48px; min-height: 44px; }
  :root .dz-touch-move { position: absolute; right: 0; top: 0; }
  :root .rec-label { min-width: 0; }
  :root .rec-files label.btn, :root .rec-file a.btn { min-height: 44px; min-width: 44px; }

}
