/* White Label UI kit: every component, built only from tokens.css.
   Load order:  tokens.css -> wl.css -> (optional) wl.js
   Every class starts with .wl- so it can't collide with host pages (extension) or old app CSS.
   Specs and the "why" for each piece: 06-Components/*.md */

/* ---------- base ---------- */
.wl, .wl *, .wl *::before, .wl *::after { box-sizing: border-box; }
.wl { font: var(--text-md)/1.5 var(--font-mono); color: var(--c-ink); background: var(--c-bg); -webkit-font-smoothing: antialiased; }
.wl-sans { font-family: var(--font-sans); }
.wl-muted { color: var(--c-muted); }
.wl-focus:focus-visible, .wl :is(button, a, input, select, textarea, [tabindex]):focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
/* icon size (D-108): one size for every app, from the theme (--size-icon: Density sets it, 18 / 20 / 24, and it grows
   with Text size). Apps never set their own icon sizes (D-042); a step up or down is a kit class:
   .sm for an icon in a line of small text, .lg one step up, .xl for an illustration (a drop zone, an empty place).
   .wl-miniature scales the icons of a drawn-small preview (a brand preview, a step number). */
.wl-icon { width: var(--size-icon, 20px); height: var(--size-icon, 20px); flex: none; fill: none; stroke: currentColor; stroke-width: var(--icon-stroke, 1.5); stroke-linecap: square; stroke-linejoin: miter; }
.wl-icon.sm { width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); }
.wl-icon.lg { width: calc(var(--size-icon, 20px) + 4px); height: calc(var(--size-icon, 20px) + 4px); }
.wl-icon.xl { width: calc(var(--size-icon, 20px) * 2); height: calc(var(--size-icon, 20px) * 2); }
.wl-miniature { --size-icon: 12px; }
/* a key: readable at a glance (11 px, the soft ink, not the muted grey; 2026-10-02, the OS's keyboard shortcuts panel),
   with an edge that reads as a keycap: the sides between the mid and strong lines, the bottom the strong line */
.wl-kbd { display: inline-flex; align-items: center; height: 18px; padding: 0 var(--space-2); border: 1px solid color-mix(in srgb, var(--c-line-mid) 50%, var(--c-line-strong)); border-bottom: 2px solid var(--c-line-strong);
  border-radius: var(--radius-sm); font: var(--text-xs) var(--font-mono); color: var(--c-ink-soft); background: var(--c-panel); }
.wl-divider { height: 1px; background: var(--c-line-soft); border: 0; margin: var(--space-3) 0; }
.wl-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- buttons ---------- */
.wl-btn { --h: var(--size-control-md); height: var(--h); min-width: var(--h); padding: 0 var(--space-4); display: inline-flex; align-items: center; justify-content: center; gap: var(--space-3);
  border: 1px solid transparent; border-radius: var(--radius-md); background: transparent; color: var(--c-ink); cursor: var(--cursor-pointer, pointer); white-space: nowrap;
  font: var(--weight-medium) var(--text-md) var(--font-mono); text-decoration: none; user-select: none;
  transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease), opacity var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease); }
.wl-btn:active { transform: translateY(1px); }
.wl-btn:disabled, .wl-btn[aria-disabled="true"] { opacity: .4; pointer-events: none; }
.wl-btn.sm { --h: var(--size-control-sm); padding: 0 var(--space-3); font-size: var(--text-sm); gap: var(--space-2); }
.wl-btn.lg { --h: var(--size-control-lg); padding: 0 var(--space-5); }
.wl-btn.primary { background: var(--c-accent); color: var(--c-accent-text); }
.wl-btn.primary:hover { opacity: .88; }
.wl-btn.secondary { background: var(--c-bg); border-color: var(--c-line-mid); }
.wl-btn.secondary:hover { background: var(--c-panel-mid); }
.wl-btn.ghost { color: var(--c-ink-soft); }
.wl-btn.ghost:hover, .wl-btn.ghost[aria-expanded="true"] { background: var(--c-panel-mid); color: var(--c-ink); }
/* a chosen tool or an on toggle is filled in the brand, so it can't be mistaken for hover (D-076, Remy's pick A) */
.wl-btn:not(.primary):not(.danger)[aria-pressed="true"] { background: var(--c-brand); color: var(--c-brand-text); border-color: var(--c-brand); }
.wl-btn[aria-pressed="true"]:hover { background: var(--c-brand); color: var(--c-brand-text); opacity: .9; }
.wl-btn.danger { background: var(--c-danger); color: var(--c-danger-text); }
.wl-btn.danger:hover { opacity: .88; }
.wl-btn.icon { padding: 0; width: var(--h); }
/* an icon-only button is the density's icon button (D-108: 28 / 32 / 40), whatever its size class, so its icon has room */
.wl-btn.icon:not(.lg):not(.call) { --h: var(--size-icon-button, 32px); }
/* the arrow half of a split button (D-113): it takes the same size class as its words half, not .icon, so the two halves are
   always one height (an icon button beside a 24 px words half was 32 tall). Narrow, with the icon centred. */
.wl-btn.split { padding: 0 var(--space-1); gap: 0; }
/* Call controls (Meet, button.md "Call"): touch-size squares on the call stage. Off = the ink fill with the slashed icon, as in the OS
   Meet window; leave = danger outside a confirm, because leaving is recoverable (Rejoin) and always has an icon and a label */
.wl-btn.call { --h: var(--size-touch-min); width: var(--h); padding: 0; border-radius: var(--radius-lg); background: var(--c-panel-mid); border-color: var(--c-line-mid); color: var(--c-ink); }
.wl-btn.call:hover { background: var(--c-panel-deep); }
.wl-btn.call.is-off { background: var(--c-ink); color: var(--c-bg); border-color: var(--c-ink); }
.wl-btn.call.leave { width: calc(var(--h) * 1.5); background: var(--c-danger); color: var(--c-danger-text); border-color: var(--c-danger); }
.wl-btn.call.leave:hover { opacity: .88; }
.wl-btn[aria-busy="true"] { pointer-events: none; }
.wl-btn[aria-busy="true"] .wl-icon { display: none; }
.wl-btn[aria-busy="true"]::before { content: ""; width: 12px; height: 12px; border: 1.5px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: wl-spin .7s linear infinite; }
.wl-btn-group { display: inline-flex; }
.wl-btn-group > .wl-btn { border-radius: 0; margin-left: -1px; }
.wl-btn-group > .wl-btn:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); margin-left: 0; }
.wl-btn-group > .wl-btn:last-child { border-radius: 0 var(--radius-md) var(--radius-md) 0; }

/* ---------- form controls ---------- */
.wl-field { display: grid; gap: var(--space-2); min-width: 0; }
.wl-label { font-size: var(--text-sm); color: var(--c-ink-soft); display: flex; justify-content: space-between; gap: var(--space-3); }
.wl-help { font-size: var(--text-sm); color: var(--c-muted); margin: 0; overflow-wrap: anywhere; }   /* Zero clunky text, D-130: a brand or display name can be one long unbroken word; without this it ran past its own box instead of breaking */
.wl-input, .wl-select, .wl-textarea { width: 100%; height: var(--size-control-md); padding: 0 var(--space-3); border: 1px solid var(--c-line-strong); border-radius: var(--radius-md);
  background: var(--c-bg); color: var(--c-ink); font: var(--text-md) var(--font-mono); transition: border-color var(--motion-fast) var(--motion-ease); }
.wl-textarea { height: auto; min-height: 84px; padding: var(--space-3); resize: vertical; line-height: 1.5; }
.wl-select { appearance: none; padding-right: var(--space-7); cursor: var(--cursor-pointer, pointer);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 11px) 50%; background-size: 4px 4px; background-repeat: no-repeat; }
.wl-input:hover, .wl-select:hover, .wl-textarea:hover { border-color: var(--c-muted); }
.wl-input:focus, .wl-select:focus, .wl-textarea:focus { border-color: var(--c-ink); outline: 2px solid var(--c-focus); outline-offset: 1px; }
.wl-input::placeholder, .wl-textarea::placeholder { color: var(--c-muted); }
.wl-input:disabled, .wl-select:disabled, .wl-textarea:disabled { background: var(--c-panel-mid); opacity: .6; cursor: var(--cursor-not-allowed, not-allowed); }
.wl-field.error .wl-input, .wl-field.error .wl-textarea, .wl-field.error .wl-select { border-color: var(--c-danger); }
.wl-field.error .wl-help { color: var(--c-danger); display: flex; gap: var(--space-2); align-items: center; }
.wl-input-wrap { position: relative; display: flex; align-items: center; }
.wl-input-wrap > .wl-icon { position: absolute; left: var(--space-3); color: var(--c-muted); pointer-events: none; }
.wl-input-wrap > .wl-input { padding-left: calc(var(--space-3) + var(--size-icon, 20px) + var(--space-3)); }
.wl-input-wrap > .wl-kbd { position: absolute; right: var(--space-3); }
/* a search field is a pill when the Shape is Round (Remy, 28 Sep 2026); otherwise it has the field corners */
.wl-search > .wl-input { border-radius: var(--radius-search, var(--radius-md)); }

.wl-check, .wl-radio { display: inline-flex; align-items: center; gap: var(--space-3); cursor: var(--cursor-pointer, pointer); font-size: var(--text-md); }
.wl-check input, .wl-radio input { appearance: none; margin: 0; width: 16px; height: 16px; border: 1px solid var(--c-line-strong); background: var(--c-bg); cursor: var(--cursor-pointer, pointer); flex: none;
  display: grid; place-items: center; transition: background-color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease); }
.wl-check input { border-radius: var(--radius-sm); }
.wl-radio input { border-radius: var(--radius-pill); }
.wl-check input:checked, .wl-radio input:checked { background: var(--c-accent); border-color: var(--c-accent); }
.wl-check input:checked::after { content: ""; width: 8px; height: 4px; border: solid var(--c-accent-text); border-width: 0 0 1.5px 1.5px; transform: translateY(-1px) rotate(-45deg); }
.wl-radio input:checked::after { content: ""; width: 6px; height: 6px; background: var(--c-accent-text); border-radius: var(--radius-pill); }

.wl-toggle { display: inline-flex; align-items: center; gap: var(--space-3); cursor: var(--cursor-pointer, pointer); }
.wl-toggle input { appearance: none; margin: 0; width: 32px; height: 20px; border-radius: var(--radius-pill); background: var(--c-line-strong); position: relative; cursor: var(--cursor-pointer, pointer); flex: none;
  transition: background-color var(--motion-fast) var(--motion-ease); }
.wl-toggle input::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: var(--radius-pill); background: var(--c-bg);
  transition: transform var(--motion-fast) var(--motion-ease); }
.wl-toggle input:checked { background: var(--c-accent); }
.wl-toggle input:checked::after { transform: translateX(12px); background: var(--c-accent-text); }

/* the range fills in the brand (D-076, D-080): --c-brand-ink is the brand's readable variant, so a pale brand still
   shows on white and a dark one on black. Native, so the keyboard, touch and screen readers get everything. */
.wl-range { width: 100%; accent-color: var(--c-brand-ink); cursor: var(--cursor-pointer, pointer); }
.wl-range:disabled { opacity: .4; cursor: var(--cursor-not-allowed, not-allowed); }
.wl-check input:indeterminate { background: var(--c-accent); border-color: var(--c-accent); }
.wl-check input:indeterminate::after { content: ""; width: 8px; height: 0; border-top: 1.5px solid var(--c-accent-text); }
.wl-check:has(input:disabled), .wl-radio:has(input:disabled), .wl-toggle:has(input:disabled) { opacity: .4; cursor: var(--cursor-not-allowed, not-allowed); }
.wl-check:has(input:disabled) input, .wl-radio:has(input:disabled) input, .wl-toggle:has(input:disabled) input { cursor: var(--cursor-not-allowed, not-allowed); }
.wl-check input:hover:not(:checked):not(:disabled) { border-color: var(--c-muted); }

/* slider (D-080): a name, the range, and its value, on one line; .bare when the row around it already names it */
.wl-slider { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--text-sm); }
.wl-slider.bare { grid-template-columns: minmax(0, 1fr) auto; }
.wl-slider-label { color: var(--c-muted); font-size: var(--text-xs); min-width: 0; overflow-wrap: anywhere; }
.wl-slider-value { min-width: 36px; text-align: right; font-size: var(--text-xs); color: var(--c-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* number field (D-080): type a number, Enter or leaving the field commits it, Esc puts it back, ↑/↓ steps (⇧ ×10) */
.wl-numfield { display: inline-grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--text-xs); color: var(--c-muted); }
.wl-numfield .wl-input { height: var(--size-control-sm); min-width: 0; padding: 0 var(--space-2); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.wl-numfield-unit { font-style: normal; white-space: nowrap; }
.wl-numfield:not(:has(.wl-numfield-label)) { grid-template-columns: minmax(0, 1fr) auto; }

/* colour field (D-080): a swatch you click for the picker, the hex code you can type, and (optional) your brand colour */
.wl-colorfield { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; max-width: 100%; }   /* in a narrow panel the hex box shrinks first, then Brand moves under: nothing is cut off */
.wl-colorfield input[type="color"] { width: 28px; height: 28px; padding: 2px; flex: none; border: 1px solid var(--c-line-strong); border-radius: var(--radius-sm); background: var(--c-bg); cursor: var(--cursor-pointer, pointer); }
.wl-colorfield input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.wl-colorfield input[type="color"]::-webkit-color-swatch { border: 0; border-radius: calc(var(--radius-sm) - 1px); }
.wl-colorfield .wl-input { width: auto; flex: 0 1 88px; min-width: 64px; height: var(--size-control-sm); padding: 0 var(--space-2); font-size: var(--text-sm); text-transform: lowercase; }
/* "Brand": one click to your brand colour. It's a secondary button, so when the brand is the colour it's pressed, and a
   pressed button is filled in the brand (D-076): the button itself says it's chosen */
.wl-colorfield-brand { flex: none; }
.wl-colorfield-brand .wl-swatch-sm { background: var(--c-brand); }
/* pressed, the button is filled with the brand too: a ring in the button's text colour keeps the swatch visible (a black
   brand was a black swatch on a black button) */
.wl-btn[aria-pressed="true"] .wl-swatch-sm { box-shadow: 0 0 0 1.5px var(--c-brand-text); }
.wl-colorfield.error .wl-input { border-color: var(--c-danger); }
.wl-colorfield > .wl-icon { color: var(--c-danger); }

.wl-seg { display: inline-flex; flex-wrap: wrap; padding: 2px; gap: 2px; background: var(--c-panel-mid); border-radius: var(--radius-md); }
/* flex-shrink: 0 + white-space: nowrap (Zero clunky text, 8 Oct: Settings → Appearance → Top bar's six options, "Brand
   tint" and "Brand colour", wrapped their own two words onto two lines inside the button at some widths — a flex
   child's default min-content is its unwrapped text width, but it still shrinks below that unless told not to). A
   button that no longer fits moves to its own row (the wrap above), never squeezes its own label.
   max-width + overflow (Zero clunky text, board a25: Graphics' "PDF for print" modal, "Which artboards" → "This one
   (<a long artboard name>)", is narrower than the .wl-seg itself (.wl-modal.sm) — nowrap alone let that one label run
   past the modal's edge). The button itself can't grow past its own box; a plain-text label (.wl-seg-label) is the
   one that's actually cut, with an ellipsis (text-overflow doesn't reach into a flex container's own text, only a
   block child's — kept as its own span so an icon beside it keeps its gap). Nothing is lost: the full text is still
   there as the button's title (the kit tooltip), reachable by pointing, keyboard focus or a press-and-hold. */
.wl-seg button { min-height: calc(var(--size-bar, 32px) - 4px); max-width: 100%; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--c-muted); cursor: var(--cursor-pointer, pointer);
  font: var(--weight-medium) var(--text-sm) var(--font-mono); display: inline-flex; align-items: center; gap: var(--space-2); flex-shrink: 0; white-space: nowrap; overflow: hidden;
  transition: background-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease); }
.wl-seg-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-seg button:hover { color: var(--c-ink); }
.wl-seg button[aria-pressed="true"] { background: var(--c-bg); color: var(--c-ink); box-shadow: 0 0 0 1px var(--c-line-soft); }

/* ---------- tabs ---------- */
.wl-tabs { display: flex; gap: var(--space-5); border-bottom: 1px solid var(--c-line-soft); }
.wl-tabs button { position: relative; height: 40px; padding: 0; border: 0; background: none; color: var(--c-muted); cursor: var(--cursor-pointer, pointer); font: var(--weight-medium) var(--text-md) var(--font-mono);
  transition: color var(--motion-fast) var(--motion-ease); }
.wl-tabs button:hover { color: var(--c-ink); }
.wl-tabs button[aria-selected="true"] { color: var(--c-ink); }
.wl-tabs button[aria-selected="true"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--c-ink); }
.wl-tabpanel[hidden] { display: none; }

/* ---------- badges, chips, avatars, status ---------- */
.wl-badge { display: inline-flex; align-items: center; gap: var(--space-1); height: 20px; padding: 0 var(--space-2); border-radius: var(--radius-sm); border: 1px solid var(--c-line-mid);
  font: var(--weight-medium) var(--text-xs) var(--font-mono); color: var(--c-ink-soft); background: var(--c-bg); white-space: nowrap; }
.wl-badge.solid { background: var(--c-ink); color: var(--c-bg); border-color: var(--c-ink); }
.wl-badge.success { color: var(--c-success); border-color: currentColor; }
.wl-badge.warning { color: var(--c-warning); border-color: currentColor; }
.wl-badge.danger { color: var(--c-danger); border-color: currentColor; }
.wl-badge .wl-icon { width: calc(var(--size-icon, 20px) * .6); height: calc(var(--size-icon, 20px) * .6); }
.wl-chip { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 24px; padding: 0 var(--space-1) 0 var(--space-3); border-radius: var(--radius-pill); background: var(--c-panel-mid);
  font-size: var(--text-sm); color: var(--c-ink); }
.wl-chip button { width: 20px; height: 20px; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--c-muted); cursor: var(--cursor-pointer, pointer); display: grid; place-items: center; padding: 0; }
.wl-chip button:hover { background: var(--c-line-mid); color: var(--c-ink); }
/* a chip names a filter or a tag; a long name wraps inside it (never clipped) and the × never gets pushed out (D-080) */
.wl-chip { max-width: 100%; min-width: 0; }
.wl-chip > .wl-chip-text { min-width: 0; overflow-wrap: anywhere; padding: 2px 0; line-height: 1.35; }
.wl-chip:not(:has(button)) { padding-right: var(--space-3); }
.wl-chip > .wl-icon, .wl-chip > .wl-dot { flex: none; }
.wl-chip .wl-icon { width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); }
.wl-chip button { flex: none; }
.wl-dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--c-muted); display: inline-block; flex: none; }
.wl-dot.success { background: var(--c-success); } .wl-dot.warning { background: var(--c-warning); } .wl-dot.danger { background: var(--c-danger); }
.wl-avatar { --s: 28px; width: var(--s); height: var(--s); border-radius: var(--radius-sm); background: var(--c-ink); color: var(--c-bg); display: inline-grid; place-items: center;
  font: var(--weight-bold) calc(var(--s) * .4) var(--font-mono); flex: none; overflow: hidden; text-transform: uppercase; }
.wl-avatar.sm { --s: 20px; } .wl-avatar.lg { --s: 40px; }
.wl-avatar img { width: 100%; height: 100%; object-fit: cover; }
.wl-avatars { display: inline-flex; }
.wl-avatars .wl-avatar { box-shadow: 0 0 0 2px var(--c-bg); margin-left: -3px; }
.wl-avatars .wl-avatar:first-child { margin-left: 0; }

/* ---------- surfaces: card, panel ---------- */
.wl-card { background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); padding: var(--space-5); }
.wl-card.interactive { cursor: var(--cursor-pointer, pointer); transition: border-color var(--motion-fast) var(--motion-ease); }
.wl-card.interactive:hover { border-color: var(--c-line-strong); }
.wl-card-title { font-weight: var(--weight-bold); margin: 0 0 var(--space-2); }
.wl-panel-head { display: flex; align-items: center; gap: var(--space-3); height: 36px; padding: 0 var(--space-4); border-bottom: 1px solid var(--c-line-soft);
  font: var(--weight-bold) var(--text-xs) var(--font-mono); color: var(--c-muted); text-transform: lowercase; }
.wl-panel-head > :last-child:not(:first-child) { margin-left: auto; }
.wl-section { padding: var(--space-4); border-bottom: 1px solid var(--c-line-soft); display: grid; gap: var(--space-3); }
.wl-section-title { font: var(--weight-bold) var(--text-xs) var(--font-mono); color: var(--c-muted); display: flex; justify-content: space-between; align-items: center; }
.wl-prop { display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
.wl-prop > span:first-child { color: var(--c-muted); }
.wl-prop-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.wl-mini { height: var(--size-control-sm); display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-2); border: 1px solid var(--c-line-soft); border-radius: var(--radius-md);
  font-size: var(--text-sm); background: var(--c-bg); }
.wl-mini span { color: var(--c-muted); font-size: var(--text-xs); }
.wl-swatch-sm { width: 14px; height: 14px; border-radius: var(--radius-sm); box-shadow: inset 0 0 0 1px rgba(128,128,128,.3); flex: none; }

/* ---------- app shell: header, switcher, sidebar, inspector, status bar ---------- */
.wl-app { display: grid; grid-template-rows: var(--size-topbar) 1fr auto; grid-template-columns: auto 1fr auto; height: 100%; min-height: 0; background: var(--c-bg); overflow: hidden; }
.wl-appbar { grid-column: 1 / -1; display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-3); border-bottom: 1px solid var(--c-line-soft); background: var(--c-bg); min-width: 0; }
.wl-appbar-brand { display: flex; align-items: center; gap: var(--space-3); padding: 0 var(--space-2); height: 32px; font-weight: var(--weight-bold); white-space: nowrap; }
.wl-appbar-brand img { width: 24px; height: 24px; }
.wl-appbar-brand .ws { font-weight: var(--weight-regular); color: var(--c-muted); }
.wl-appbar-sep { width: 1px; height: 20px; background: var(--c-line-soft); margin: 0 var(--space-2); flex: none; }
.wl-appbar-title { display: flex; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--text-md); }
.wl-appbar-title span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-appbar-title .crumb { color: var(--c-muted); }
.wl-appbar-spacer { flex: 1; }
.wl-appbar-search { width: 240px; }
/* nothing in the bar ever runs into anything else (Remy: "this can never happen"): buttons keep their size, the
   brand name and the workspace name give way first (ending in …), and on a phone the words on buttons and the key
   hints step aside so only the icons stay */
.wl-appbar > .wl-btn { flex: none; }
.wl-appbar > .wl-ws-trigger { flex: 0 1 auto; min-width: 0; }
.wl-appbar-brand { min-width: 0; flex: 0 1 auto; }
.wl-appbar-brand > span { overflow: hidden; text-overflow: ellipsis; }
.wl-appbar-brand > img, .wl-appbar-brand > .wl-appmark { flex: none; }
@media (max-width: 560px) {
  /* a full bar never squeezes its parts into each other: it slides sideways inside itself instead */
  .wl-appbar { gap: var(--space-1); padding: 0 var(--space-2); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .wl-appbar::-webkit-scrollbar { display: none; }
  .wl-appbar > * { flex-shrink: 0; }
  .wl-appbar > .wl-appbar-spacer { flex: 1 0 0; }
  .wl-appbar > .wl-ws-trigger { flex-shrink: 0; max-width: 150px; }
  .wl-appbar-search { display: none; }   /* the search button (⌘K) stays; a field this narrow would be an empty box */
  .wl-appbar .wl-kbd { display: none; }
  .wl-appbar-brand > span { display: none; }   /* the mark or logo stays; the workspace name beside it says whose it is */
  .wl-appbar > .wl-btn:not(.icon):not(.primary):not(.wl-ws-trigger) { font-size: 0; gap: 0; padding: 0; width: var(--h); justify-content: center; }
  .wl-appbar-sep { margin: 0 var(--space-1); }
}
.wl-appbar-search .wl-input { background: var(--c-panel); border-color: var(--c-line-soft); }   /* height: the bar's (fields in a bar, D-113) */

.wl-switcher { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-1); padding: var(--space-2); width: 300px; }
.wl-switcher a { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-2); border-radius: var(--radius-md); color: var(--c-ink);
  text-decoration: none; font-size: var(--text-xs); transition: background-color var(--motion-fast) var(--motion-ease); }
.wl-switcher a:hover { background: var(--c-panel-mid); }
.wl-switcher a[aria-current="true"] { background: var(--c-panel-mid); box-shadow: inset 0 0 0 1px var(--c-line-mid); }
.wl-switcher img { width: 32px; height: 32px; }

.wl-sidebar { width: var(--size-sidebar-l); border-right: 1px solid var(--c-line-soft); background: var(--c-panel); display: flex; flex-direction: column; min-height: 0; overflow: auto; }
.wl-inspector { width: var(--size-sidebar-r); border-left: 1px solid var(--c-line-soft); background: var(--c-bg); display: flex; flex-direction: column; min-height: 0; overflow: auto; }
.wl-nav { display: grid; gap: 1px; padding: var(--space-2); }
.wl-nav-label { padding: var(--space-4) var(--space-3) var(--space-2); font: var(--weight-bold) var(--text-2xs) var(--font-mono); color: var(--c-muted); text-transform: uppercase; letter-spacing: .06em; }
.wl-nav a, .wl-nav button { display: flex; align-items: center; gap: var(--space-3); padding: 0 var(--space-3); border: 0; border-radius: var(--radius-md); background: none;
  color: var(--c-ink-soft); text-decoration: none; font: var(--text-md) var(--font-mono); cursor: var(--cursor-pointer, pointer); text-align: left; width: 100%; min-height: var(--size-row, 36px);
  transition: background-color var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease); }
.wl-nav a:hover, .wl-nav button:hover { background: var(--c-panel-mid); color: var(--c-ink); }
.wl-nav [aria-current="page"], .wl-nav [aria-current="true"] { background: var(--c-panel-deep); color: var(--c-ink); font-weight: var(--weight-medium); }
.wl-nav .count { margin-left: auto; font-size: var(--text-xs); color: var(--c-muted); }
.wl-nav [aria-current] .count { color: var(--c-ink-soft); }   /* muted on panel-deep is 4.3–4.5:1, below AA */
.wl-nav .indent { padding-left: calc(var(--space-3) + var(--size-icon, 20px) + var(--space-3)); }
.wl-main { min-width: 0; min-height: 0; overflow: auto; position: relative; }
.wl-statusbar { grid-column: 1 / -1; min-height: 24px; display: flex; align-items: center; gap: var(--space-5); padding: 0 var(--space-4); border-top: 1px solid var(--c-line-soft);
  font-size: var(--text-xs); color: var(--c-muted); background: var(--c-panel); }
.wl-statusbar > span { display: inline-flex; align-items: center; gap: var(--space-2); }
.wl-statusbar .right { margin-left: auto; }
/* a status bar of items (D-123: Code and the AI window): each item a small button that opens a .wl-menu[data-float]
   (above it: add data-flip; .end for the ones on the right). Groups (.wl-sb-group) with a thin line (.wl-sb-sep)
   between them; .wl-sb-text for plain words that aren't clickable. Nothing clickable is only here (navigation.md). */
.wl-statusbar.items { gap: 2px; min-height: 26px; padding: 0 var(--space-2); color: var(--c-ink-soft); font-family: var(--font-mono); }
.wl-sb-group { display: inline-flex; align-items: center; gap: 2px; min-width: 0; }
.wl-sb-group.right { margin-left: auto; }
.wl-sb-sep { flex: none; width: 1px; height: 14px; margin: 0 var(--space-2); background: var(--c-line-mid); }
.wl-sb-item { display: inline-flex; align-items: center; gap: 6px; min-width: 0; height: 22px; padding: 0 7px; border: 0; border-radius: var(--radius-sm); background: none;
  color: inherit; font: var(--text-xs) var(--font-mono); white-space: nowrap; cursor: var(--cursor-pointer, pointer); }
.wl-sb-item:hover, .wl-sb-item[aria-expanded="true"] { background: var(--c-panel-mid); color: var(--c-ink); }
.wl-sb-item:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 1px; }
.wl-sb-item .wl-icon { flex: none; width: 13px; height: 13px; }
.wl-sb-item > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wl-sb-item b { color: var(--c-ink); font-weight: var(--weight-bold); }
.wl-sb-item small { flex: none; padding: 0 4px; border: 1px solid var(--c-line-mid); border-radius: var(--radius-sm); font-size: var(--text-2xs); line-height: 14px; color: var(--c-muted); }
.wl-sb-item .wl-progress { flex: none; width: 44px; }
.wl-sb-item .wl-progress > i { background: var(--c-ink-soft); }
.wl-sb-item.warn, .wl-sb-item.warn b { color: var(--c-warning); }
.wl-sb-item.warn .wl-progress > i { background: var(--c-warning); }
.wl-sb-item.muted { color: var(--c-muted); }
.wl-sb-text { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 7px; font-size: var(--text-xs); color: var(--c-muted); white-space: nowrap; }
.wl-statusbar .wl-menu { width: 300px; max-width: calc(100vw - 16px); font-family: var(--font-mono); white-space: normal; }
.wl-statusbar .wl-menu[data-float] { top: auto; bottom: calc(100% + 4px); }   /* a bar at the foot of a window: its menus always open above it */
.wl-statusbar .wl-menu[data-float]:not([data-open]) { display: none; }   /* closed, they take no room (a bar is full width: a hidden menu past its edge made the window scroll sideways) */
.wl-statusbar .wl-menu p { margin: 2px var(--space-3) var(--space-2); font: var(--text-xs)/1.45 var(--font-sans); color: var(--c-muted); }
.wl-statusbar .wl-menu .wl-menu-item[aria-disabled="true"] { opacity: .5; cursor: var(--cursor-default, default); }
.wl-sb-big { display: grid; gap: 2px; padding: var(--space-1) var(--space-3); }
.wl-sb-big b { font-size: var(--text-md); color: var(--c-ink); overflow-wrap: anywhere; }
.wl-sb-big span { font-size: var(--text-xs); color: var(--c-muted); overflow-wrap: anywhere; }
.wl-sb-meter { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); padding: 2px var(--space-3); font-size: var(--text-xs); }
.wl-sb-meter.warn > span:last-child { color: var(--c-warning); font-weight: var(--weight-bold); }
.wl-sb-meter.warn .wl-progress > i { background: var(--c-warning); }

.wl-toolbar { display: flex; align-items: center; gap: var(--space-1); padding: var(--space-1); background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float); width: max-content; }
/* a flat strip (D-113): the same toolbar laid along the edge of a pane, as Studio's timeline strip and Mail's selection strip.
   No frame, radius or shadow (it doesn't float), the panel colour and a line under it, full width. Add .wrap if its
   controls may go onto a second line; add .fold if its words should fold into their icons when the strip is narrow.
   Its padding is 4 px all round (--space-2) because the focus ring is 2 px with a 2 px offset: any less and the ring of a
   focused button is cut off where the strip meets its pane (Studio's timeline clips its overflow). */
.wl-toolbar.flat { flex: none; width: auto; min-width: 0; gap: var(--space-1) var(--space-2); padding: var(--space-2); background: var(--c-panel);
  border: 0; border-bottom: 1px solid var(--c-line-soft); border-radius: 0; box-shadow: none; }
.wl-toolbar.flat > .wl-btn { flex: none; }
.wl-toolbar.wrap { flex-wrap: wrap; }
.wl-toolbar.fold { container: wl-strip / inline-size; }
@container wl-strip (max-width: 600px) {   /* the words are still the button's name (said, and shown on hover) */
  .wl-toolbar.fold > .wl-btn:not(.icon) { font-size: 0; gap: 0; padding: 0; width: var(--h); }
}
.wl-toolbar-sep { flex: none; width: 1px; height: 20px; background: var(--c-line-soft); margin: 0 var(--space-1); }   /* flex: none, or a full strip squeezes it to 0 */
.wl-toolbar.vertical { flex-direction: column; }
.wl-toolbar.vertical .wl-toolbar-sep { width: 20px; height: 1px; margin: var(--space-1) 0; }

/* ---------- floating: menu, popover, tooltip ---------- */
/* a menu grows to fit its own widest item (width: max-content, not stuck at min-width while a label wraps under
   it), capped so one long item never makes the whole menu huge (9 Oct, Voltron FIX FIRST on the real menu bar: a
   menu's label wrapped to two lines under its own kbd badge — every app's View menu with "Enter full screen",
   Social Hub's own "Up next, Calendar or Results" worse still). Beyond the cap an item's own label clips with a
   clean ellipsis (.label below) instead of wrapping or overflowing; the kbd badge never shrinks to make room, so
   it always stays on the label's own line. */
.wl-menu { width: max-content; min-width: 200px; max-width: 320px; padding: var(--space-2); background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); box-shadow: var(--shadow-float); }
.wl-menu[data-float] { position: absolute; z-index: var(--z-dropdown); top: calc(100% + 4px); left: 0; opacity: 0; transform: translateY(-4px); pointer-events: none; visibility: hidden;
  transition: opacity var(--motion-fast) var(--motion-ease-in), transform var(--motion-fast) var(--motion-ease-in), visibility 0s var(--motion-fast); }
.wl-menu[data-float][data-open] { opacity: 1; transform: none; pointer-events: auto; visibility: visible;
  transition: opacity var(--motion-base) var(--motion-ease-out), transform var(--motion-base) var(--motion-ease-out), visibility 0s; }
.wl-menu-item { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: var(--size-row, 36px); padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: none;
  color: var(--c-ink); font: var(--text-md) var(--font-mono); text-align: left; white-space: nowrap; cursor: var(--cursor-pointer, pointer); text-decoration: none; }
.wl-menu-item:hover, .wl-menu-item:focus-visible { background: var(--c-panel-mid); outline: none; }
/* a label this long wraps a plain span around its own text (title carries the full words past the cap); a plain
   bare-text item (most of them, well inside the cap) needs none of this — .wl-menu-item's own white-space: nowrap
   above already keeps it on one line */
.wl-menu-item .label { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.wl-menu-item .wl-kbd, .wl-menu-item .hint { margin-left: auto; flex-shrink: 0; }
.wl-menu-item .hint { color: var(--c-muted); font-size: var(--text-xs); }
.wl-menu-item.danger { color: var(--c-danger); }
.wl-menu-item[aria-checked="true"]::after { content: "✓"; margin-left: auto; }
.wl-menu-label { padding: var(--space-2) var(--space-3); font: var(--weight-bold) var(--text-2xs) var(--font-mono); color: var(--c-muted); text-transform: uppercase; letter-spacing: .06em; }
.wl-menu hr { border: 0; border-top: 1px solid var(--c-line-soft); margin: var(--space-2) calc(-1 * var(--space-2)); }
.wl-anchor { position: relative; display: inline-flex; }
.wl-menu[data-float][data-flip] { top: auto; bottom: calc(100% + 4px); }
.wl-menu[data-float].end { left: auto; right: 0; }

/* tool tips (D-128, Proposed; wl-tips.js, 01-Brand/tool-tips.html): ONE tip for every icon-only control, drawn by the
   engine (it finds the words, places it and wires the events). Name and key on the first line, one plain line on what it
   does under it. The ink chip, so it reads in every style, light and dark. It never takes a click. .wl-tip[data-tip]
   still works: it's a wrapper whose one control gets the tip, so nothing that used it breaks. */
.wl-tip { position: relative; display: inline-flex; }
.wl-tooltip { position: fixed; left: 0; top: 0; z-index: var(--z-tooltip); display: flex; flex-direction: column; gap: 2px; max-width: min(280px, calc(100vw - 16px));
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--c-ink); color: var(--c-bg); box-shadow: var(--shadow-float);
  font: var(--text-xs)/1.35 var(--font-mono); pointer-events: none; user-select: none; opacity: 0; transform: translateY(2px);
  transition: opacity var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease); }
.wl-tooltip[hidden] { display: none; }
.wl-tooltip[data-open] { opacity: 1; transform: none; }
.wl-tooltip[data-side="above"] { transform: translateY(-2px); } .wl-tooltip[data-side="above"][data-open] { transform: none; }
.wl-tooltip[data-side="right"] { transform: translateX(2px); } .wl-tooltip[data-side="left"] { transform: translateX(-2px); }
.wl-tooltip[data-side="right"][data-open], .wl-tooltip[data-side="left"][data-open] { transform: none; }
.wl-tooltip-top { display: flex; align-items: baseline; gap: var(--space-3); }
.wl-tooltip-name { font-weight: var(--weight-bold); }
.wl-tooltip-key { margin-left: auto; font: var(--text-2xs) var(--font-mono); letter-spacing: .04em; opacity: .72; }
.wl-tooltip-key[hidden], .wl-tooltip-does[hidden] { display: none; }
.wl-tooltip-does { color: color-mix(in srgb, var(--c-bg) 80%, var(--c-ink)); }
@media (prefers-reduced-motion: reduce) { .wl-tooltip { transition: none; transform: none; } }

.wl-popover { width: 280px; padding: var(--space-4); background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); box-shadow: var(--shadow-float); }

/* ---------- overlays: modal, drawer, sheet, command palette ---------- */
.wl-backdrop { position: fixed; inset: 0; z-index: var(--z-overlay); background: rgba(0,0,0,.4); display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; padding: var(--space-5);   /* the cell is the screen, so a dialog's max-width/height: 100% can't overflow it (L-038) */
  opacity: 0; visibility: hidden; transition: opacity var(--motion-fast) var(--motion-ease-in), visibility 0s var(--motion-fast); }
.wl-backdrop[data-open] { opacity: 1; visibility: visible; transition: opacity var(--motion-base) var(--motion-ease-out), visibility 0s; }
.wl-backdrop.contained { position: absolute; }
.wl-modal { --w: 560px; width: var(--w); max-width: 100%; max-height: calc(100% - var(--space-6)); display: flex; flex-direction: column; z-index: var(--z-modal);
  background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); box-shadow: var(--shadow-overlay);
  transform: scale(.98); transition: transform var(--motion-fast) var(--motion-ease-in); }
.wl-modal:focus { outline: none; }   /* focused only so Esc reaches it when it has no fields */
.wl-backdrop[data-open] .wl-modal { transform: none; transition: transform var(--motion-base) var(--motion-ease-out); }
.wl-modal.sm { --w: 400px; } .wl-modal.lg { --w: 800px; }
.wl-modal-head { display: flex; align-items: flex-start; gap: var(--space-4); padding: var(--space-5) var(--space-6) 0; }
.wl-modal-head h2, .wl-modal-head h3 { margin: 0; font-size: var(--text-lg); font-weight: var(--weight-bold); flex: 1; }
.wl-modal-head .wl-btn { margin: -6px -10px 0 0; }
/* grid-template-columns: minmax(0, 1fr) (not the implicit "auto" column), board a25: a grid item's own automatic
   minimum size is its min-content size by default, and for unbreakable text (.wl-seg button's white-space: nowrap)
   that min-content IS the whole label — the single column grew wider than the modal to fit it, which is what the
   .wl-seg button ellipsis fix alone couldn't reach (the column grew before overflow/text-overflow ever got a width
   to clip against). minmax(0, …) lets the column (and everything in it) shrink to the modal's own width instead. */
.wl-modal-body { padding: var(--space-4) var(--space-6) var(--space-6); overflow: auto; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
.wl-modal-body > p { margin: 0; font-family: var(--font-sans); color: var(--c-ink-soft); }
.wl-modal-foot { display: flex; justify-content: flex-end; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-6); border-top: 1px solid var(--c-line-soft); }
.wl-modal-foot .left { margin-right: auto; }
.wl-modal.confirm .wl-modal-foot { border-top: 0; padding-top: 0; }
.wl-modal-icon { width: 40px; height: 40px; border-radius: var(--radius-md); display: grid; place-items: center; background: var(--c-panel-mid); flex: none; }
.wl-modal-icon.danger { color: var(--c-danger); }

.wl-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: 400px; max-width: 100%; z-index: var(--z-modal); display: flex; flex-direction: column;
  background: var(--c-bg); border-left: 1px solid var(--c-line-soft); box-shadow: var(--shadow-overlay);
  transform: translateX(100%); visibility: hidden; transition: transform var(--motion-base) var(--motion-ease-in), visibility 0s var(--motion-base); }
.wl-drawer[data-open] { transform: none; visibility: visible; transition: transform var(--motion-slow) var(--motion-ease-out), visibility 0s; }
.wl-drawer.contained { position: absolute; }

.wl-sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: var(--z-modal); background: var(--c-bg); border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-overlay); padding: var(--space-2) var(--space-5) calc(var(--space-6) + env(safe-area-inset-bottom)); }
.wl-sheet::before { content: ""; display: block; width: 36px; height: 4px; border-radius: var(--radius-pill); background: var(--c-line-mid); margin: 0 auto var(--space-4); }

.wl-cmdk { width: 600px; max-width: 100%; align-self: start; margin-top: 12vh; background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-overlay); overflow: hidden; transform: scale(.98); transition: transform var(--motion-fast) var(--motion-ease-in); }
.wl-backdrop[data-open] .wl-cmdk { transform: none; transition: transform var(--motion-base) var(--motion-ease-out); }
.wl-cmdk-input { display: flex; align-items: center; gap: var(--space-3); padding: 0 var(--space-5); height: 52px; border-bottom: 1px solid var(--c-line-soft); }
.wl-cmdk-input input, .wl-cmdk-input input:focus-visible { flex: 1; border: 0; outline: 0; background: none; color: var(--c-ink); font: var(--text-lg) var(--font-mono); }
.wl-cmdk-list { max-height: 340px; overflow: auto; padding: var(--space-2); }
.wl-cmdk-list .wl-menu-item { height: 36px; }
.wl-cmdk-list .wl-menu-item[aria-selected="true"] { background: var(--c-panel-mid); }
.wl-cmdk-list .wl-menu-item img { width: 20px; height: 20px; }
.wl-cmdk-foot { display: flex; gap: var(--space-5); padding: var(--space-2) var(--space-5); border-top: 1px solid var(--c-line-soft); font-size: var(--text-xs); color: var(--c-muted); background: var(--c-panel); }
.wl-cmdk-foot span { display: inline-flex; align-items: center; gap: var(--space-2); }

/* ---------- feedback: toast, banner, progress, loading, empty ---------- */
.wl-toasts { position: fixed; right: var(--space-5); bottom: var(--space-5); z-index: var(--z-toast); display: grid; gap: var(--space-3); justify-items: end; pointer-events: none; background: none;   /* it carries .wl for fonts; never its page background (L-030) */
  width: min(360px, calc(100vw - 32px)); }   /* a definite width, so toasts size to their text inside it */
.wl-toast { display: flex; align-items: center; gap: var(--space-3); width: max-content; max-width: min(360px, calc(100vw - 32px)); min-height: 40px; padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); pointer-events: auto;
  background: var(--c-ink); color: var(--c-bg); border-radius: var(--radius-md); box-shadow: var(--shadow-float); font-size: var(--text-sm);
  animation: wl-toast-in var(--motion-base) var(--motion-ease-out); }
.wl-toast[data-leaving] { animation: wl-fade-out var(--motion-fast) var(--motion-ease-in) forwards; }
.wl-toast .wl-btn { --h: 26px; color: var(--c-bg); padding: 0 var(--space-3); font-size: var(--text-sm); }
.wl-toast .wl-btn:hover, .wl-toast .wl-btn:focus-visible { background: rgba(128,128,128,.25); color: var(--c-bg); }   /* the toast is inverted: keep its buttons light on hover */
.wl-toast-msg { flex: 1 1 auto; }   /* auto basis, so the toast sizes to its message (L-019) */

.wl-banner { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--c-line-mid); border-radius: var(--radius-md);
  background: var(--c-panel); font-size: var(--text-sm); }
.wl-banner .wl-icon { margin-top: 2px; }
.wl-banner b { display: block; margin-bottom: var(--space-1); }
.wl-banner p { margin: 0; color: var(--c-ink-soft); font-family: var(--font-sans); }
.wl-banner .actions { margin-left: auto; display: flex; gap: var(--space-2); }
.wl-banner.warning { border-color: var(--c-warning); } .wl-banner.warning > .wl-icon { color: var(--c-warning); }
.wl-banner.danger { border-color: var(--c-danger); } .wl-banner.danger > .wl-icon { color: var(--c-danger); }
.wl-banner.success { border-color: var(--c-success); } .wl-banner.success > .wl-icon { color: var(--c-success); }

.wl-progress { height: 4px; background: var(--c-panel-deep); border-radius: var(--radius-pill); overflow: hidden; }
.wl-progress > i { display: block; height: 100%; background: var(--c-ink); border-radius: var(--radius-pill); transition: width var(--motion-slow) var(--motion-ease); }
.wl-progress.indeterminate > i { width: 30%; animation: wl-indeterminate 1.2s var(--motion-ease) infinite; }
.wl-spinner { width: 16px; height: 16px; border: 1.5px solid var(--c-line-mid); border-top-color: var(--c-ink); border-radius: 50%; animation: wl-spin .7s linear infinite; display: inline-block; }
.wl-spinner.lg { width: 24px; height: 24px; border-width: 2px; }
.wl-skel { background: var(--c-panel-deep); border-radius: var(--radius-sm); position: relative; overflow: hidden; }
.wl-skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--c-ink) 7%, transparent), transparent);
  animation: wl-shimmer 1.4s var(--motion-ease) infinite; }
.wl-empty { display: grid; justify-items: center; text-align: center; gap: var(--space-3); padding: var(--space-8) var(--space-5); }
.wl-empty-mark { width: 56px; height: 56px; border: 2px solid var(--c-line-mid); display: grid; place-items: center; color: var(--c-muted); margin-bottom: var(--space-2); }
.wl-empty-mark::before { content: ""; width: 22px; height: 22px; border: 2px solid var(--c-line-mid); }
.wl-empty h3 { margin: 0; font-size: var(--text-lg); }
.wl-empty p { margin: 0 0 var(--space-3); max-width: 42ch; color: var(--c-muted); font-family: var(--font-sans); }

/* ---------- table, list ---------- */
.wl-table { width: 100%; border-collapse: collapse; font-size: var(--text-md); }
.wl-table th { min-height: 32px; padding: 0 var(--space-4); text-align: left; font: var(--weight-bold) var(--text-xs) var(--font-mono); color: var(--c-muted); border-bottom: 1px solid var(--c-line-soft);
  white-space: nowrap; }
.wl-table td { height: 40px; padding: 0 var(--space-4); border-bottom: 1px solid var(--c-line-soft); white-space: nowrap; }
.wl-table tbody tr { transition: background-color var(--motion-fast) var(--motion-ease); }
.wl-table tbody tr:hover { background: var(--c-panel); }
.wl-table tbody tr[aria-selected="true"] { background: var(--c-panel-mid); }
.wl-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.wl-table .file { display: flex; align-items: center; gap: var(--space-3); }
.wl-thumb { width: 24px; height: 24px; border-radius: var(--radius-sm); background: var(--c-panel-deep); flex: none; }

/* ---------- motion keyframes ---------- */
@keyframes wl-spin { to { transform: rotate(360deg); } }
@keyframes wl-toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes wl-fade-out { to { opacity: 0; } }
@keyframes wl-shimmer { to { transform: translateX(100%); } }
@keyframes wl-indeterminate { 0% { transform: translateX(-100%); } 100% { transform: translateX(340%); } }
@media (prefers-reduced-motion: reduce) {
  .wl-skel::after, .wl-progress.indeterminate > i { animation: none; }
  .wl-spinner, .wl-btn[aria-busy="true"]::before { animation-duration: 1.6s; }
}

/* ---------- touch (mobile + tablets) ---------- */
@media (pointer: coarse) {
  .wl-btn { --h: var(--size-touch-min); }
  .wl-btn.sm { --h: 36px; }
  .wl-input, .wl-select { height: var(--size-touch-min); font-size: 16px; }   /* 16px stops iOS zoom-on-focus (L-002) */
  .wl-textarea { font-size: 16px; }
  .wl-menu-item, .wl-nav a, .wl-nav button { height: var(--size-touch-min); }
  .wl-btn.icon:not(.lg):not(.call) { --h: max(var(--size-touch-min), var(--size-icon-button, 32px)); }
  .wl-btn.icon.sm:not(.lg):not(.call) { --h: max(36px, var(--size-icon-button, 32px)); }
}

/* ---------- one bar height (D-113, Remy's option C, 01-Brand/button-sizes.html) ----------
   Everything in a bar is as tall as the density's icon button: buttons with words, icon buttons, split buttons and switches.
   A bar is a page bar, an app bar, a toolbar (floating or flat), anything with role="toolbar", or .wl-bar: the marker a host
   puts on a bar it draws itself (the OS's window header, the screenshot studio's bar) to get these sizes and nothing else
   (no colour, padding or layout, and no role, so screen readers hear the same thing). Words keep their small type
   and padding, so a bar's buttons get taller, not wider. --size-bar is 28 / 32 / 40 by Density (tokens.json size.bar,
   growing with Text size like the icon button); on touch a bar is never under the kit's 36. Large and call buttons, and a
   field's own clear button, keep their size. After the touch block on purpose: it has to win there too. */
:is(.wl-pagebar, .wl-appbar, .wl-toolbar, .wl-bar, [role="toolbar"]) .wl-btn:not(.lg):not(.call):not(.clear) { --h: var(--size-bar, 32px); }
@media (pointer: coarse) { :is(.wl-pagebar, .wl-appbar, .wl-toolbar, .wl-bar, [role="toolbar"]) { --size-bar: max(36px, var(--size-icon-button, 32px)); } }
/* a switch on touch is never under the bar's 36 either, in a bar or not (Compact made its buttons 24 there): 32 px buttons
   in their 2 px frame = 36, the same as a touch bar, so a switch in a bar still fits it */
@media (pointer: coarse) { .wl-seg button { min-height: max(32px, calc(var(--size-bar, 32px) - 4px)); } }
/* Fields in a bar are the bar's height too (Remy, 1 Oct: yes): text boxes, selects and the app header's search, so a
   bar never mixes a 24 px select with 32 px buttons. Small type like the buttons; on touch the type stays 16 px so
   iOS doesn't zoom into a focused field. Apps don't size their own bar fields. */
:is(.wl-pagebar, .wl-appbar, .wl-toolbar, .wl-bar, [role="toolbar"]) :is(.wl-input, .wl-select),
.wl-appbar-search .wl-input, .wl-apphead-search { height: var(--size-bar, 32px); font-size: var(--text-sm); }
@media (pointer: coarse) { :is(.wl-pagebar, .wl-appbar, .wl-toolbar, .wl-bar, [role="toolbar"]) :is(.wl-input, .wl-select), .wl-appbar-search .wl-input { font-size: 16px; } }
/* a field that renames the page (in the page bar's title: Canvas', Graphics' and Studio's names, a stop motion's name) is the
   bar's height but keeps the title's type, so the name doesn't shrink while you rename it (18 px, never under 16 on touch) */
.wl-pagebar-title .wl-input { font: inherit; }
/* a colour swatch in a bar (Studio's stop motion) is a square as tall as the bar, like the hex box and buttons beside it */
:is(.wl-pagebar, .wl-appbar, .wl-toolbar, .wl-bar, [role="toolbar"]) .wl-colorfield input[type="color"] { width: var(--size-bar, 32px); height: var(--size-bar, 32px); }

/* ---------- the mark as a live component (wl-mark.js) ----------
   Geometry from the master: frame centred at 5.5 (53 wide), inner square centred at 18.5 (27 wide), on a 64 grid.
   --w is the stroke in grid units: hairline 2 · regular 3 · bold 4 · heavy 4.8 (the master logo's weight). */
.wl-mark { --s: 64px; --w: 3; --u: calc(var(--s) / 64); --mk-ink: var(--c-ink); --mk-paper: transparent; --mk-accent: var(--c-brand);
  width: var(--s); height: var(--s); position: relative; flex: none; display: inline-block; }
.wl-mark > i { position: absolute; box-sizing: border-box; display: block; will-change: transform; }
.wl-mark .o { left: calc(var(--u) * (5.5 - var(--w) / 2)); top: calc(var(--u) * (5.5 - var(--w) / 2)); width: calc(var(--u) * (53 + var(--w))); height: calc(var(--u) * (53 + var(--w)));
  border: calc(var(--u) * var(--w)) solid var(--mk-ink); background: var(--mk-paper); }
.wl-mark .n { left: calc(var(--u) * (18.5 - var(--w) / 2)); top: calc(var(--u) * (18.5 - var(--w) / 2)); width: calc(var(--u) * (27 + var(--w))); height: calc(var(--u) * (27 + var(--w)));
  border: calc(var(--u) * var(--w)) solid var(--mk-ink); overflow: hidden; transition: border-color var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease); }
.wl-mark .n .fill { position: absolute; left: 0; right: 0; bottom: 0; height: 0; background: var(--mk-ink); }
.wl-mark .b { right: calc(var(--u) * 2); top: calc(var(--u) * 2); width: calc(var(--u) * 12); height: calc(var(--u) * 12); background: var(--mk-ink); opacity: 0; }
.wl-mark .d { width: calc(var(--u) * 6); height: calc(var(--u) * 6); background: var(--mk-ink); top: calc(var(--u) * 29); opacity: 0; }
.wl-mark .d1 { left: calc(var(--u) * 20); } .wl-mark .d2 { left: calc(var(--u) * 29); } .wl-mark .d3 { left: calc(var(--u) * 38); }
/* v2 parts (D-061), so each state has its own gesture instead of another pulse:
   .r the ring, an outline of the frame that ripples out (listening, success), turns dashed (syncing) or glows (focus);
   .t the satellite, a small square that travels round the mark (thinking glides, updating steps). */
.wl-mark .r { left: calc(var(--u) * (5.5 - var(--w) / 2)); top: calc(var(--u) * (5.5 - var(--w) / 2)); width: calc(var(--u) * (53 + var(--w))); height: calc(var(--u) * (53 + var(--w))); border: calc(var(--u) * var(--w) * .66) solid var(--mk-accent); opacity: 0; pointer-events: none; }
.wl-mark .r.dashed { border-style: dashed; }
.wl-mark .t { width: calc(var(--u) * 7); height: calc(var(--u) * 7); left: calc(var(--u) * 28.5); top: calc(var(--u) * -1); background: var(--mk-accent); opacity: 0; }
.wl-mark[data-frame="none"] .r { left: calc(var(--u) * -2); top: calc(var(--u) * -2); width: calc(var(--u) * 68); height: calc(var(--u) * 68); }
.wl-mark[data-frame="none"] .d { top: calc(var(--u) * 70); }   /* a logo keeps its face: the dots sit under it */
.wl-mark[data-frame="none"] .b { right: calc(var(--u) * -4); top: calc(var(--u) * -4); }
.wl-mark[data-frame="none"] .n { overflow: visible; }
.wl-mark[data-frame="none"] .n .fill { top: auto; bottom: calc(var(--u) * -10); height: calc(var(--u) * 3) !important; width: 0; background: var(--mk-accent); }
.wl-mark[data-weight="hairline"] { --w: 2; } .wl-mark[data-weight="bold"] { --w: 4; } .wl-mark[data-weight="heavy"] { --w: 4.8; }
.wl-mark[data-fill="solid"] .n { background: var(--mk-ink); }
.wl-mark[data-fill="inverted"] { --mk-paper: var(--c-ink); } .wl-mark[data-fill="inverted"] > i { border-color: var(--c-bg); }
.wl-mark[data-fill="inverted"] .n .fill, .wl-mark[data-fill="inverted"] .b, .wl-mark[data-fill="inverted"] .d { background: var(--c-bg); }
.wl-mark[data-fill="duotone"] .n { border-color: var(--mk-accent); } .wl-mark[data-fill="duotone"] .n .fill { background: var(--mk-accent); }
.wl-mark[data-fill="accent"] .o, .wl-mark[data-fill="accent"] .n { border-color: var(--mk-accent); } .wl-mark[data-fill="accent"] .n { background: var(--mk-accent); }
/* brand: the whole mark, both squares and every moving part, in the brand colour (D-054) */
.wl-mark[data-fill="brand"] { --mk-ink: var(--c-brand); }
.wl-mark[data-fill="brand"].is-filled .lg { color: var(--c-brand-text); }
/* echo: a calm resting state for a logo shown on its own (About, a splash). Two faint copies of the logo itself (any
   shape: the White Label mark, a customer's round logo, a wordmark) breathe out from it and fade, one after the other,
   like a slow ping (D-057: an outline square didn't fit other logos). The logo itself doesn't move.
   <span class="wl-echo"><span class="wl-echo-ghost" aria-hidden="true">LOGO</span><span class="wl-echo-ghost" aria-hidden="true">LOGO</span>LOGO</span>
   Reduced motion: no echo (and apps leave the ghosts out when the user picked Still). */
.wl-echo { position: relative; display: inline-grid; place-items: center; isolation: isolate; }
.wl-echo > * { grid-area: 1 / 1; place-self: center; line-height: 0; }
.wl-echo-ghost { display: grid; place-items: center; opacity: 0; pointer-events: none; z-index: -1; animation: wl-echo 4.8s cubic-bezier(.2, 0, 0, 1) infinite; }
.wl-echo-ghost + .wl-echo-ghost { animation-delay: 2.4s; }
@keyframes wl-echo { 0% { transform: scale(1); opacity: .28; } 75% { opacity: 0; } 100% { transform: scale(1.5); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .wl-echo-ghost { display: none; } }
.wl-mark.is-filled .n { background: var(--n-fill, var(--mk-ink)); border-color: var(--n-fill, var(--mk-ink)); }
.wl-mark.is-dashed .n { border-style: dashed; }
/* D-013: a customer's logo inside the inner square (framed), or as the whole mark (full white label) */
.wl-mark .lg { position: absolute; inset: calc(var(--u) * 2); display: grid; place-items: center; overflow: hidden; color: var(--mk-ink); font: 700 calc(var(--u) * 11)/1 var(--font-mono); letter-spacing: -.02em; }
.wl-mark .lg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }   /* pinned to the box: a tall logo used to render at its own height and get cropped */
.wl-mark.is-filled .lg { color: var(--c-bg); }
.wl-mark[data-logo] .n .fill { z-index: 0; } .wl-mark[data-logo] .lg { z-index: 1; }
.wl-mark[data-frame="none"] .o { display: none; }
.wl-mark[data-frame="none"] .n { left: 0; top: 0; width: var(--s); height: var(--s); border: 0; }
.wl-mark[data-frame="none"] .lg { inset: 0; font-size: calc(var(--u) * 26); }
.wl-mark[data-frame="none"].is-filled .n { background: none; }
.wl-wordmark { font: var(--weight-bold) calc(var(--s, 64px) * .42) / 1 var(--font-display, var(--font-mono)); letter-spacing: -.02em; color: var(--c-ink); white-space: nowrap; }
.wl-lockup { display: inline-flex; align-items: center; gap: calc(var(--s, 64px) * .28); }
.wl-lockup.stacked { flex-direction: column; gap: calc(var(--s, 64px) * .22); }
.wl-lockup .app { font-weight: var(--weight-regular); color: var(--c-muted); }

/* ---------- small additions for the React kit (packages/kit, D-042) ---------- */
.wl-layer { position: fixed; z-index: var(--z-dropdown); }                         /* a popover or menu placed next to what opened it */
.wl-layer > .wl-menu, .wl-layer > .wl-popover { box-shadow: var(--shadow-float); }
.wl-grow { flex: 1 1 auto; min-width: 0; }
.wl-btn.ghost.risky:hover { color: var(--c-danger); }                              /* delete buttons: calm until you point at them */
.wl-input-wrap > .wl-btn.clear { position: absolute; right: var(--space-1); --h: 24px; }
.wl-appmark svg { width: 100%; height: 100%; display: block; }

/* ---------- settings window (D-046): a two-pane dialog every app and the OS use for settings ----------
   Left: search + sections (grouped). Right: the section, made of groups and rows. Search jumps straight to a single
   setting and flashes it. Narrow windows stack the nav above the section. */
.wl-modal.wl-settings { --w: 960px; height: min(720px, calc(100% - var(--space-6))); }
.wl-settings .wl-modal-head { padding-bottom: var(--space-4); border-bottom: 1px solid var(--c-line-soft); }
.wl-settings .wl-modal-body { padding: 0; gap: 0; flex: 1; min-height: 0; display: grid; grid-template-columns: 232px minmax(0, 1fr); overflow: hidden; }
.wl-settings-nav { border-right: 1px solid var(--c-line-soft); background: var(--c-panel); overflow: auto; display: flex; flex-direction: column; min-height: 0; }
.wl-settings-nav .wl-input-wrap { margin: var(--space-3) var(--space-3) 0; }
.wl-settings-nav .wl-nav { padding: var(--space-2) var(--space-2) var(--space-4); }
/* Zero clunky text, D-130: this and .wl-set-group below are display: grid with no grid-template-columns, so their one
   implicit column was sized "auto" — to the widest min-content of anything inside it, which for a long unbroken brand
   or display name (no space to break at) could be hundreds of px wider than the window. The column then overflowed
   its own box (.wl-settings-main itself stayed the window's width; its grid track didn't), scrolling the whole
   Settings page sideways with no scrollbar in sight, and clipping ordinary paragraph text mid-word at the window's
   edge (a long name in the Browser or Account page scrolled "what websites may use" out of view, cut raw). The fix is
   both: minmax(0, 1fr) so the column can never grow past the box it's actually given, and overflow-wrap: anywhere
   (here and on .wl-help, .wl-set-label) so the long name itself breaks instead of needing the room in the first place. */
.wl-settings-main { overflow: auto; min-height: 0; padding: var(--space-5) var(--space-6) var(--space-7, 48px); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-6); align-content: start; }
.wl-settings-main > header { display: grid; gap: var(--space-1); min-width: 0; }
.wl-settings-main > header h3 { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold); overflow-wrap: anywhere; }
.wl-settings-main > header p { margin: 0; font-family: var(--font-sans); color: var(--c-ink-soft); max-width: 62ch; overflow-wrap: anywhere; }
.wl-settings-results { display: grid; gap: 1px; padding: var(--space-2); }
.wl-settings-results button { display: grid; gap: 1px; text-align: left; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-md); background: none; color: var(--c-ink); cursor: var(--cursor-pointer, pointer); font: inherit; }
.wl-settings-results button:hover, .wl-settings-results button:focus-visible { background: var(--c-panel-mid); }
.wl-settings-results small { color: var(--c-muted); font-size: var(--text-xs); }
.wl-settings-results .none { padding: var(--space-3); color: var(--c-muted); font-size: var(--text-sm); }
/* a group of rows with a title, like "Sign-in" or "Brand colour" */
.wl-set-group { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }   /* Zero clunky text, D-130: see .wl-settings-main above — the same grid blowout, one level down */
.wl-set-group > .wl-section-title { padding-bottom: var(--space-1); }
.wl-set-group > .wl-help { margin-top: calc(var(--space-1) * -1); }
.wl-set-rows { border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); background: var(--c-bg); }
.wl-set-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--space-3) var(--space-5); padding: var(--space-3) var(--space-4); min-height: 52px; }
.wl-set-row + .wl-set-row { border-top: 1px solid var(--c-line-soft); }
.wl-set-row.stack { grid-template-columns: minmax(0, 1fr); }
.wl-set-label { display: grid; gap: 2px; min-width: 0; }
.wl-set-label b { font-weight: var(--weight-medium); overflow-wrap: anywhere; }   /* Zero clunky text, D-130: a row's own label can be a signed-in email, a profile or workspace name */
.wl-set-label small { font-family: var(--font-sans); font-size: var(--text-sm); color: var(--c-muted); overflow-wrap: anywhere; }
.wl-set-ctrl { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; min-width: 0; }
.wl-set-row.stack .wl-set-ctrl { justify-content: flex-start; }
.wl-set-hit { animation: wl-set-hit 1.6s var(--motion-ease-out); }
@keyframes wl-set-hit { 0%, 30% { background: var(--c-panel-deep); box-shadow: inset 3px 0 0 var(--c-ink); } 100% { background: transparent; box-shadow: inset 3px 0 0 transparent; } }
/* people, workspaces: a list with an avatar, name + detail, and actions */
.wl-set-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-3); }
.wl-set-item .who { display: grid; min-width: 0; }
.wl-set-item .who small { color: var(--c-muted); font-size: var(--text-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* usage meters and plan cards */
.wl-meter { display: grid; gap: var(--space-2); }
.wl-meter .top { display: flex; justify-content: space-between; gap: var(--space-3); font-variant-numeric: tabular-nums; }
.wl-meter .top span { color: var(--c-ink-soft); font-size: var(--text-sm); }
.wl-meter.warn .wl-progress > i { background: var(--c-warning); }
.wl-meter.over .wl-progress > i { background: var(--c-danger); }
.wl-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
.wl-plan { border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); padding: var(--space-4); display: grid; gap: var(--space-2); align-content: start; background: var(--c-bg); }
.wl-plan[aria-current="true"] { border-color: var(--c-ink); box-shadow: inset 0 0 0 1px var(--c-ink); }
.wl-plan .price { font-size: var(--text-xl); font-weight: var(--weight-bold); font-variant-numeric: tabular-nums; }
.wl-plan .price small { font-size: var(--text-sm); font-weight: var(--weight-regular, 400); color: var(--c-muted); }
.wl-plan ul { margin: 0; padding-left: 1.1em; font-family: var(--font-sans); font-size: var(--text-sm); color: var(--c-ink-soft); display: grid; gap: 2px; }
/* brand: colour swatches, logo slots, the live preview and the readability check */
.wl-swatches { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.wl-swatches button { width: 32px; height: 32px; border: 1px solid var(--c-line-mid); border-radius: var(--radius-md); cursor: var(--cursor-pointer, pointer); padding: 0; }
.wl-swatches button[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--c-bg), 0 0 0 4px var(--c-ink); }
.wl-swatches input[type="color"] { width: 44px; height: 32px; padding: 2px; border: 1px solid var(--c-line-mid); border-radius: var(--radius-md); background: var(--c-bg); cursor: var(--cursor-pointer, pointer); }
.wl-logo-slot { width: 120px; height: 64px; border: 1px dashed var(--c-line-strong); border-radius: var(--radius-md); display: grid; place-items: center; overflow: hidden; background: var(--c-panel); }
.wl-logo-slot.dark { background: #0a0a0a; border-color: #3f3f46; }
.wl-logo-slot img { max-width: 88%; max-height: 80%; object-fit: contain; }
.wl-logo-slot small { color: var(--c-muted); font-size: var(--text-xs); }
.wl-logo-slot.dark small { color: #a3a3a3; }   /* on the slot's own near-black in both modes: 7.9:1 (the page's muted grey was 3.7:1) */
.wl-brand-preview { border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); padding: var(--space-4); display: grid; gap: var(--space-3); background: var(--c-bg); }
.wl-checks { display: grid; gap: var(--space-1); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.wl-checks span { display: flex; gap: var(--space-2); align-items: center; }
.wl-checks .pass { color: var(--c-success); } .wl-checks .fail { color: var(--c-danger); }
@media (max-width: 720px) {
  .wl-modal.wl-settings { height: calc(100% - var(--space-4)); }
  .wl-settings .wl-modal-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .wl-settings-nav { border-right: 0; border-bottom: 1px solid var(--c-line-soft); max-height: 38vh; }
  .wl-settings-main { padding: var(--space-4); }
  .wl-set-row { grid-template-columns: minmax(0, 1fr); }
  .wl-set-ctrl { justify-content: flex-start; }
}

/* ---------- shell pieces (D-048): workspace switcher, profile menu, search everything, notifications ---------- */
.wl-ws-trigger { gap: var(--space-2); max-width: 240px; }
.wl-ws-trigger > span:not(.wl-ws-badge) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-ws-badge { width: 20px; height: 20px; flex: none; border-radius: var(--radius-sm); display: inline-grid; place-items: center; font: var(--weight-bold) 10px/1 var(--font-mono); color: #fff; background: var(--c-ink); overflow: hidden; text-transform: uppercase; }
.wl-ws-badge img { width: 100%; height: 100%; object-fit: contain; background: var(--c-bg); }
.wl-menu .wl-input-wrap { margin: var(--space-1) var(--space-1) var(--space-2); }
.wl-menu-scroll { max-height: 280px; overflow: auto; display: grid; }
.wl-profile-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-3); align-items: center; padding: var(--space-3); }
.wl-profile-head span { display: grid; min-width: 0; }
.wl-profile-head small { color: var(--c-muted); font-size: var(--text-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-trigger-badge { position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--radius-pill); background: var(--c-danger); color: #fff; font: var(--weight-bold) 10px/16px var(--font-mono); text-align: center; pointer-events: none; }
.wl-cmdk-list .wl-menu-label { padding-top: var(--space-3); }
.wl-cmdk-list .wl-menu-item .hint { margin-left: auto; color: var(--c-muted); font-size: var(--text-xs); }
.wl-cmdk-list .wl-menu-item .sub { color: var(--c-muted); font-size: var(--text-xs); margin-left: var(--space-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wl-cmdk-empty { padding: var(--space-6) var(--space-4); text-align: center; color: var(--c-muted); font-size: var(--text-sm); }
.wl-notes-panel { width: 360px; max-width: calc(100vw - 32px); padding: 0; display: grid; }
.wl-notes-panel > header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-line-soft); }
.wl-notes-list { max-height: 420px; overflow: auto; display: grid; }
.wl-note-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-line-soft); align-items: start; }
.wl-note-item.unread { background: var(--c-panel); }
.wl-note-item .dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--c-brand); margin-top: 6px; }
.wl-note-item .dot.read { background: transparent; }
.wl-note-item b { display: block; font-weight: var(--weight-medium); }
.wl-note-item p { margin: 2px 0 0; font-family: var(--font-sans); font-size: var(--text-sm); color: var(--c-ink-soft); }
.wl-note-item time { font-size: var(--text-xs); color: var(--c-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.wl-note-item .acts { grid-column: 2 / -1; display: flex; gap: var(--space-2); flex-wrap: wrap; }
.wl-notes-panel > footer { display: flex; justify-content: space-between; padding: var(--space-2) var(--space-3); background: var(--c-panel); }

.wl-fileicon { display: inline-block; flex: none; line-height: 0; }
.wl-fileicon svg { display: block; width: 100%; height: 100%; }

/* scrollbars in the brand (D-076, Remy's pick B): a thin bar in the brand colour on a soft track, readable in both modes */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--c-panel); }
::-webkit-scrollbar-thumb { background: var(--c-brand-ink); border: 3px solid var(--c-panel); }
::-webkit-scrollbar-thumb:hover { border-width: 2px; }
::-webkit-scrollbar-corner { background: var(--c-panel); }
@supports not selector(::-webkit-scrollbar) { * { scrollbar-width: thin; scrollbar-color: var(--c-brand-ink) var(--c-panel); } }

/* the app header (D-077, Remy's pick C; D-085: the customer leads). A light row with the brand as a stripe along the top.
   First the customer: their logo (or their initials on a tile in their colour, never White Label's mark) and their
   name, which is the workspace switcher; then the app as a small label (its mark and name). App things only; page
   things go in .wl-pagebar under it. Nothing overflows: a long name ends in … and says itself in full on hover. */
/* The logo is the workspace's Logo size (D-108; AppHeader sets --logo-header from it). The row is the larger of the
   density's row and logo + 4, so Extra large grows it (to 52 at Comfortable) instead of squeezing the logo. */
.wl-apphead { --apphead-logo: var(--logo-header, 40px); height: calc(max(var(--size-topbar-density, var(--size-topbar, 44px)), var(--apphead-logo) + 4px) + 7px); padding-top: 3px; gap: var(--space-3); box-shadow: inset 0 3px 0 var(--c-brand); }
.wl-apphead-you { display: flex; align-items: center; gap: var(--space-2); min-width: 0; max-width: 100%; height: calc(100% - 4px); padding: 0 var(--space-2) 0 var(--space-1);
  font-weight: var(--weight-bold); color: var(--c-ink); white-space: nowrap; flex: 0 1 auto; border-radius: var(--radius-md); }
button.wl-apphead-you { border: 0; background: transparent; font: inherit; font-weight: var(--weight-bold); cursor: var(--cursor-pointer, pointer); text-align: left; }
button.wl-apphead-you:hover { background: var(--c-panel); }
button.wl-apphead-you:focus-visible { outline: 2px solid var(--c-focus); outline-offset: -2px; }
.wl-apphead-you .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: var(--text-lg); }
.wl-apphead-you .on { flex: none; font: var(--weight-regular) var(--text-2xs)/1 var(--font-mono); color: var(--c-muted); }
.wl-apphead-you > .wl-icon { flex: none; width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); color: var(--c-muted); }
/* a wide logo keeps the full height, up to 5x as wide */
.wl-apphead-you .wl-brandlogo { height: var(--apphead-logo); max-width: calc(var(--apphead-logo) * 5); }
.wl-apphead-you .wl-brandtile { width: var(--apphead-logo); height: var(--apphead-logo); font-size: calc(var(--apphead-logo) * .4); }
.wl-apphead-you .wl-brandtile[data-n="1"] { font-size: calc(var(--apphead-logo) * .5); }
.wl-apphead-app { display: flex; align-items: center; gap: var(--space-2); flex: none; color: var(--c-ink-soft); font-size: var(--text-sm); white-space: nowrap; }
.wl-apphead-you + .wl-apphead-app { padding-left: var(--space-3); border-left: 1px solid var(--c-line-soft); }   /* a line only between them and the app */
.wl-apphead-app .demo { font: var(--weight-regular) var(--text-2xs)/1 var(--font-mono); color: var(--c-muted); padding: 3px 6px; border: 1px solid var(--c-line-soft); border-radius: var(--radius-sm); }
.wl-apphead-search { display: flex; align-items: center; gap: var(--space-3); width: min(360px, 34vw); height: var(--size-bar, 32px); padding: 0 var(--space-4); flex: 0 1 auto;   /* the bar's height (fields in a bar, D-113) */
  border: 1px solid var(--c-line-mid); border-radius: var(--radius-search, var(--radius-md)); background: var(--c-bg); color: var(--c-muted); font: inherit; font-size: var(--text-sm); cursor: var(--cursor-text, text); text-align: left; }
.wl-apphead-search:hover { border-color: var(--c-line-strong); }
.wl-apphead-search:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 1px; }
.wl-apphead-search > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-apphead-menu { display: none; }
.wl-apphead > .wl-apphead-you { flex-shrink: 1; min-width: 40px; }   /* the name gives way first, before anything else moves */
@media (max-width: 720px) {
  .wl-apphead-menu { display: inline-flex; }
  .wl-apphead-search { width: var(--size-bar, 32px); padding: 0; justify-content: center; }   /* a square: as wide as it is tall */
  .wl-apphead-search > span, .wl-apphead-search > .wl-kbd { display: none; }
  .wl-apphead-app .demo, .wl-apphead-you .on { display: none; }
  .wl-apphead-app > span:not(.wl-appmark) { display: none; }   /* the app's mark stays; its name is in the tab and the mark's label */
  .wl-apphead-you .nm { font-size: var(--text-md); }
  /* on a phone the header stops at Large, and a wide logo gives way in width (never in the row's height) */
  .wl-apphead { --apphead-logo: min(var(--logo-header, 40px), 40px); gap: var(--space-2); }
  .wl-apphead-you .wl-brandlogo { max-width: min(calc(var(--apphead-logo) * 5), 112px); }
}

/* your brand, first (D-085): your logo, or your initials on a tile in your colour (never White Label's mark). Sizes come
   from Logo size (D-108, --logo-<surface>); the kit's BrandLogo also sets them per logo, because a wide logo in a box
   (loading, welcome) keeps a square logo's area, which needs the picture's shape. */
.wl-brandlogo { display: block; flex: none; width: auto; height: var(--logo-header, 40px); max-width: calc(var(--logo-header, 40px) * 5); object-fit: contain; }
.wl-brandtile { display: inline-grid; place-items: center; flex: none; width: var(--logo-header, 40px); height: var(--logo-header, 40px); border-radius: var(--radius-md); background: var(--c-brand); color: var(--c-brand-text);
  font: var(--weight-bold) calc(var(--logo-header, 40px) * .4)/1 var(--font-mono); letter-spacing: -.02em; text-transform: uppercase; user-select: none; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-ink) 10%, transparent); }
/* loading: your logo breathing, gently. It keeps still with reduced motion or when Motion is Still (its length follows
   --motion-slow, which is 0 at Still; the resting frame is the logo at full strength, so a stopped one never looks faded) */
.wl-brandload { display: grid; place-items: center; align-content: center; gap: var(--space-3); flex: 1; min-height: 160px; width: 100%; height: 100%; }
.wl-breathe { display: inline-grid; place-items: center; animation: wl-breathe calc(var(--motion-slow, 320ms) * 9) ease-in-out infinite; }   /* Still: 0ms, so it rests */
@keyframes wl-breathe { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .8; transform: scale(.94); } }   /* mostly a gentle scale: initials stay readable (AA large text) all the way through */
@media (prefers-reduced-motion: reduce) { .wl-breathe { animation: none; } }
/* welcome: a first visit or an empty place leads with your logo and says whose it is */
.wl-welcome .wl-brandlogo { height: var(--logo-welcome, 64px); max-width: min(calc(var(--logo-welcome, 64px) * 4), 100%); }
.wl-welcome .wl-brandtile { width: var(--logo-welcome, 64px); height: var(--logo-welcome, 64px); font-size: calc(var(--logo-welcome, 64px) * .4); border-radius: var(--radius-lg); }
.wl-brandload .wl-brandlogo { height: var(--logo-load, 64px); max-width: min(calc(var(--logo-load, 64px) * 4), 100%); }
.wl-brandload .wl-brandtile { width: var(--logo-load, 64px); height: var(--logo-load, 64px); font-size: calc(var(--logo-load, 64px) * .4); border-radius: var(--radius-lg); }
.wl-welcome h3 { overflow-wrap: anywhere; }
/* floating over a canvas or artboard that has nothing on it yet: never in the way (clicks go through), gone after the
   first change */
.wl-welcome-float { position: absolute; left: 50%; top: var(--space-6); transform: translateX(-50%); width: min(420px, calc(100% - 2 * var(--space-4))); z-index: 2;
  pointer-events: none; background: var(--c-bg); border: 1px solid var(--c-line-soft); border-radius: var(--radius-lg); box-shadow: var(--shadow-float); }
.wl-welcome-float .wl-empty { padding: var(--space-5) var(--space-4); }
/* sign in: your logo, name and colour when this computer has seen you before; White Label's plain one otherwise */
.wl-signin { display: grid; place-items: center; min-height: 100%; padding: var(--space-6) var(--space-4); }
.wl-signin-card { width: min(400px, 100%); display: grid; gap: var(--space-4); padding: var(--space-6); box-shadow: inset 0 3px 0 var(--c-brand); }
.wl-signin-who { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); min-width: 0; }   /* a wide logo puts the name under it */
.wl-signin-who .wl-brandlogo { height: var(--logo-signin, 48px); max-width: min(calc(var(--logo-signin, 48px) * 5), 100%); }
.wl-signin-who .wl-brandtile { width: var(--logo-signin, 48px); height: var(--logo-signin, 48px); font-size: calc(var(--logo-signin, 48px) * .4); }
.wl-signin-who b { min-width: 0; overflow-wrap: anywhere; font-size: var(--text-lg); }
.wl-signin-card h1 { margin: 0; font-size: var(--text-2xl); overflow-wrap: anywhere; }
.wl-signin-card p { margin: 0; color: var(--c-ink-soft); font-family: var(--font-sans); }
.wl-signin-card form { display: grid; gap: var(--space-2); }
.wl-signin-card .or { display: flex; align-items: center; gap: var(--space-3); color: var(--c-muted); font-size: var(--text-xs); }
.wl-signin-card .or::before, .wl-signin-card .or::after { content: ""; flex: 1; border-top: 1px solid var(--c-line-soft); }
.wl-signin-card .err { color: var(--c-danger); font-size: var(--text-sm); margin: 0; }
.wl-signin-card .row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.wl-signin-card .not-you { justify-self: start; max-width: 100%; height: auto; min-height: var(--h); white-space: normal; text-align: left; line-height: 1.3; padding-block: var(--space-1); }   /* a long name wraps, never runs off a phone */
.wl-signin-card.embedded { width: 100%; padding: 0; box-shadow: none; }
/* what you share (a Drive link page): whose it is, at the top; "Made with White Label" only if the workspace turns it on */
.wl-sharedby { display: flex; align-items: center; gap: var(--space-3); min-width: 0; width: 100%; justify-self: stretch; padding-bottom: var(--space-3); border-bottom: 1px solid var(--c-line-soft); }
.wl-sharedby .wl-brandlogo { height: 32px; max-width: 160px; }
.wl-sharedby .wl-brandtile { width: 32px; height: 32px; font-size: 13px; }
.wl-sharedby span { display: grid; min-width: 0; }
.wl-sharedby b { overflow-wrap: anywhere; }
.wl-sharedby small { color: var(--c-muted); font-size: var(--text-xs); }
.wl-madewith { margin: 0; text-align: center; color: var(--c-muted); font: var(--text-2xs)/1.4 var(--font-mono); }

/* the page bar: where you are, the page's views, its save state and its buttons */
.wl-pagebar { display: flex; align-items: center; gap: var(--space-4); min-height: 52px; padding: var(--space-2) var(--space-5); border-bottom: 1px solid var(--c-line-soft); background: var(--c-bg); min-width: 0; flex-wrap: wrap; }
.wl-pagebar-title { margin: 0; display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; font: var(--weight-bold) var(--text-xl)/1.2 var(--font-display); }
.wl-pagebar-title .crumb { color: var(--c-muted); font-weight: var(--weight-regular); white-space: nowrap; }
.wl-pagebar-title .t { min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }   /* Zero clunky text, D-130: without min-width: 0 a flex child never shrinks below its own content, so the ellipsis never gets the room to do its job (a tight "Inbox" showed as 17% of itself, almost nothing) */
.wl-pagebar-title .t:has(.wl-input) { overflow: visible; }   /* a rename field in the title: its focus ring isn't cut off (D-113) */
.wl-pagebar-views, .wl-pagebar-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* the "Send to" button (kit send.tsx, D-091 round, 28 Sep 2026): layout only; in narrow windows the app's name hides and the send icon stays */
.wl-send { display: inline-flex; }
@media (max-width: 900px) { .wl-send-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } }

/* Settings › Brand: Logo size shown at real size (D-108), in an app's header and the OS's menu bar. A picture, not controls. */
.wl-logo-preview { display: grid; gap: var(--space-3); width: 100%; min-width: 0; pointer-events: none; user-select: none; }
.wl-logo-preview-head, .wl-logo-preview-bar { display: flex; align-items: center; gap: var(--space-2); min-width: 0; overflow: hidden; padding: 0 var(--space-3); border: 1px solid var(--c-line-soft); border-radius: var(--radius-md); background: var(--c-bg); color: var(--c-ink); }
.wl-logo-preview-head { padding-top: 3px; box-shadow: inset 0 3px 0 var(--c-brand); }
.wl-logo-preview-head b { font-size: var(--text-lg); }
.wl-logo-preview-head small { flex: none; padding-left: var(--space-3); border-left: 1px solid var(--c-line-soft); color: var(--c-ink-soft); font-size: var(--text-sm); }
.wl-logo-preview-bar { height: 32px; background: var(--c-panel); font-size: var(--text-sm); }
.wl-logo-preview-bar .sp { flex: 1; }
.wl-logo-preview b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wl-logo-preview .wl-brandlogo, .wl-logo-preview .wl-brandtile { flex: none; }

/* The AI's own pointer (D-112, CURSORS.md §4). The drawing comes from WL_CURSOR.ai(); this only places it and its label.
   It sits on its own layer and never catches a click or a hover, so the person's own mouse is never in its way.
   --aiptr-size is the person's pointer size (the AI's pointer follows it). The drawing carries its own tip (--aiptr-hx, --aiptr-hy on the 32 box, set by WL_CURSOR.ai()), so every drawing direction lands its tip on the point. */
.wl-aiptr { --aiptr-size: var(--size-cursor); position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: var(--z-pointer); pointer-events: none; will-change: transform; transition: opacity var(--motion-base) var(--motion-ease); }
.wl-aiptr > svg { position: absolute; left: calc(var(--aiptr-size) * var(--aiptr-hx, 7) / -32); top: calc(var(--aiptr-size) * var(--aiptr-hy, 5) / -32); display: block; overflow: visible; }
.wl-aiptr[data-off] { opacity: 0; }
.wl-aiptr[data-idle] { opacity: .5; }
.wl-aiptr-label { position: absolute; left: calc(var(--aiptr-size) * 30 / 32); top: calc(var(--aiptr-size) * 20 / 32); display: inline-flex; align-items: center; gap: var(--space-2); padding: 3px var(--space-3); border-radius: var(--radius-md); white-space: nowrap;
  background: var(--c-brand); color: var(--c-brand-text); font: var(--weight-medium) var(--text-xs)/1.4 var(--font-mono); box-shadow: 0 0 0 1px var(--c-bg), var(--shadow-float); }
.wl-aiptr-label:empty { display: none; }
.wl-aiptr-label .who { font-weight: var(--weight-bold); }
.wl-aiptr[data-wait] .wl-aiptr-label { background: var(--c-bg); color: var(--c-ink); box-shadow: inset 0 0 0 1.5px var(--c-brand-ink), var(--shadow-float); }
.wl-aiptr[data-flip] .wl-aiptr-label { left: auto; right: calc(var(--aiptr-size) * 4 / 32); }
/* acting: one ring from the tip (the mark's ring gesture); still with reduced motion */
.wl-aiptr-ring { position: absolute; left: -14px; top: -14px; width: 28px; height: 28px; box-sizing: border-box; border: 2px solid var(--c-brand-ink); border-radius: 50%; animation: wl-aiptr-ring calc(var(--motion-slow) * 2) var(--motion-ease-out) forwards; }
.wl-aiptr-ring.still { animation: none; }
@keyframes wl-aiptr-ring { from { transform: scale(.4); opacity: .9; } to { transform: scale(2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .wl-aiptr { transition: none; } .wl-aiptr-ring { animation: none; } }

/* ---- help that points (D-126, PLAN part D; 01-Brand/ai-pointer.html, Remy's picks 7 Oct) ----
   1 · the AI's pointer, B: its label stays folded while it travels and opens once it lands ([data-travel]); it leaves in
       0.2 s the moment your own pointer reaches the control, you click it, or press Esc ([data-leaving]). */
.wl-aiptr .wl-aiptr-label { transform-origin: left center; transition: opacity var(--motion-base) var(--motion-ease), transform var(--motion-base) var(--motion-ease); }
.wl-aiptr[data-travel] .wl-aiptr-label { opacity: 0; transform: translateX(-6px) scale(.96); }
.wl-aiptr[data-leaving] { opacity: 0; transition: opacity var(--motion-fast) var(--motion-ease); }
/* 2 · the highlight, A: a 2 px ring in the brand's ink colour, 3 px outside the control. It pulses twice when it appears,
       then holds still. A click on the control closes it onto the control and it's gone in 0.2 s ([data-ending]); Esc or
       Stop takes it away at once. Drawn by its host over the control (it never takes a click). */
.wl-ring { position: absolute; z-index: var(--z-pointer); pointer-events: none; box-sizing: border-box; border-radius: calc(var(--radius-md) + 3px); outline: 2px solid var(--c-brand-ink); outline-offset: 1px;
  animation: wl-ring-pulse 1.1s var(--motion-ease) 2; transition: transform var(--motion-fast) var(--motion-ease), opacity var(--motion-fast) var(--motion-ease); }
.wl-ring[hidden] { display: none; }
.wl-ring[data-ending] { transform: scale(.86); opacity: 0; }
@keyframes wl-ring-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c-brand-ink) 45%, transparent); } 70%, 100% { box-shadow: 0 0 0 9px color-mix(in srgb, var(--c-brand-ink) 0%, transparent); } }
/* 3 · the ? box, B: 320 px, dropping from the ? itself. Up to three one-line answers (name, where, key, Show me); "How do
       I …" gets numbered steps and Walk me through it; Full guide and (with an AI plugged in) Ask the assistant at the foot. */
.wl-qbox { position: absolute; z-index: var(--z-dropdown); width: min(320px, calc(100% - 16px)); box-sizing: border-box; display: grid; gap: var(--space-2); padding: var(--space-3);
  border-radius: var(--radius-lg); background: var(--c-bg); color: var(--c-ink); box-shadow: var(--shadow-overlay), inset 0 0 0 1px var(--c-line-soft); font-family: var(--font-sans); }
.wl-qbox[hidden] { display: none; }
.wl-qbox .wl-input { height: 34px; font-size: var(--text-sm); }
.wl-qres { display: grid; gap: 2px; max-height: 260px; overflow: auto; align-content: start; }
.wl-qa { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: var(--space-2); align-items: center; padding: 6px var(--space-2); border-radius: var(--radius-md); }
.wl-qa:first-child { background: var(--c-panel); }
.wl-qa-ico { width: 28px; height: 28px; display: grid; place-items: center; box-sizing: border-box; border: 1px solid var(--c-line-soft); border-radius: var(--radius-sm); background: var(--c-bg); }
.wl-qa-ico .wl-icon { width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); }
.wl-qa-t { display: grid; min-width: 0; }
.wl-qa-t b { font: var(--weight-medium) var(--text-sm) var(--font-mono); }
.wl-qa-t small { color: var(--c-ink-soft); font-size: var(--text-xs); }
.wl-qa-t small .wl-kbd { height: 15px; font-size: var(--text-2xs); }
.wl-qtask { display: grid; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--c-panel); }
.wl-qtask ol { margin: 0; padding-left: 20px; display: grid; gap: 1px; font-size: var(--text-sm); }
.wl-qnone { display: grid; gap: var(--space-1); justify-items: start; padding: var(--space-2); font-size: var(--text-sm); }
.wl-qnone b { font-family: var(--font-mono); font-weight: var(--weight-medium); }
.wl-qline { margin: 0; font-size: var(--text-xs); color: var(--c-ink-soft); }
.wl-qfoot { display: flex; align-items: center; gap: var(--space-1); padding-top: var(--space-2); border-top: 1px solid var(--c-line-soft); }
/* 4 · Do it or Show me, B (D-126), its shape and place (D-127, Proposed): asked once (the card), then one slim line
       saying what it's doing, with the other way one click away. Both are a small question IN THE FLOW, never a
       column, a layer or a pop-up: in the chat it is the assistant's own message (inside .ai-msg, right after your
       request); beside Claude Code's terminal it sits in the window's question strip above the terminal, where the
       "Waiting for your OK" questions sit. Never prepend either to a window's .body: that is a flex ROW, so the part
       becomes a full-height side column and squeezes the assistant (L-067). The line replaces the card in the same
       place, so the answer reads as the card, answered.
       Card: the question (sans, medium, ink) · what it's about, app first (mono, xs, up to two lines, so a long request loses its tail, never the app) · two equal choices that stack
       full-width when there's no room for both · Remember my choice, with where to change it. The card's own lines are
       qualified (.wl-ask-card .wl-ask-q) so a host's message styles (the chat's .ai-msg p) can't restyle them. */
.wl-ask-card { display: grid; gap: var(--space-2); align-content: start; justify-items: stretch; min-width: 0; max-width: 400px; box-sizing: border-box; padding: var(--space-3); border: 1px solid var(--c-line-mid); border-radius: var(--radius-md); background: var(--c-bg); color: var(--c-ink); }
.wl-ask-card .wl-ask-q { margin: 0; font: var(--weight-medium) var(--text-sm)/1.45 var(--font-sans); color: var(--c-ink); }
.wl-ask-card .wl-ask-what { margin: 0; min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; font: var(--text-xs)/1.4 var(--font-mono); color: var(--c-ink-soft); }
.wl-ask-acts { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.wl-ask-acts > .wl-btn { flex: 1 1 120px; justify-content: center; }
.wl-ask-keep { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); min-height: 24px; font: var(--text-xs)/1.4 var(--font-sans); color: var(--c-ink-soft); }
.wl-ask-keep .wl-check { gap: var(--space-2); min-height: 24px; font: inherit; color: var(--c-ink); }
.wl-ask-keep small { margin-left: auto; font: inherit; }
.wl-mode-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); min-height: 32px; min-width: 0; max-width: 400px; box-sizing: border-box; padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3); border: 1px solid var(--c-line-soft); border-radius: var(--radius-md); background: var(--c-bg); font: var(--text-sm)/1.4 var(--font-sans); color: var(--c-ink-soft); }
.wl-mode-line > .wl-icon { flex: none; width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); color: var(--c-brand-ink); }
.wl-mode-line > span { flex: 1 1 140px; min-width: 0; overflow-wrap: anywhere; }
.wl-mode-line > span b { font-weight: var(--weight-medium); color: var(--c-ink); }
.wl-mode-line > .wl-btn { flex: none; }
@media (prefers-reduced-motion: reduce) { .wl-aiptr .wl-aiptr-label, .wl-ring { animation: none; transition: none; } }

/* ---------- page panel (.wl-site, component 21, page-panel.md; draft) ----------
   The one panel beside a web page for what you can do with it: Check this site, Save, Add to Customers (the Browser's
   tools, whitelabel-apps packages/kit/src/browser-tools: wl-check.js, wl-save.js, wl-insights.js). Moved here from the
   tools' own browser-tools.css (3 Oct) so it arrives with the kit like every other part. Made of kit parts
   (.wl-panel-head, .wl-section, .wl-banner, .wl-btn, .wl-radio, .wl-check, .wl-input, .wl-spinner, .wl-empty); these rules
   only place them. Its home gives it a place BESIDE the page (the page gets narrower), never over it, and it fills it. */
.wl-site, .wl-site *, .wl-site *::before, .wl-site *::after { box-sizing: border-box; }
.wl-site { position: relative; display: flex; flex-direction: column; width: 100%; height: 100%; min-width: 0; min-height: 0; background: var(--c-bg); color: var(--c-ink); font-family: var(--font-sans); font-size: var(--text-sm); }
.wl-site .wl-panel-head { flex: none; }
.wl-site-name { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.wl-site-name .wl-icon, .wl-site-opt > span:nth-child(2) > .wl-icon { width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); color: var(--c-ink-soft); }
/* the body is the only part that scrolls; Check this site's body is a tab stop (all words, it has to scroll by keyboard) */
.wl-site-body { flex: 1; min-height: 0; overflow: auto; outline: 0; }
.wl-site-body:focus-visible { box-shadow: inset 0 0 0 2px var(--c-focus); }
.wl-site-body > .wl-banner { margin: 0 var(--space-4) var(--space-3); }
/* the panel is narrow (about 340 px): a result's button ("Open Customers", "Open Drive") goes under its words, lined up
   with them, instead of squeezing them to three words a line */
.wl-site .wl-banner { flex-wrap: wrap; }
.wl-site .wl-banner > div:not(.actions) { flex: 1 1 0; min-width: 0; }
.wl-site .wl-banner > .actions { flex-basis: 100%; margin-left: calc(var(--size-icon, 20px) + var(--space-3)); }
.wl-site-host { margin: 0; padding: var(--space-4) var(--space-4) var(--space-3); display: grid; gap: var(--space-1); overflow-wrap: anywhere; }
.wl-site-host b { font-size: var(--text-md); }
.wl-site h3.wl-section-title, .wl-site legend.wl-section-title, .wl-site label.wl-section-title { margin: 0; }
/* findings (Check this site): icon + bold title + a line; the icon's colour says the level, the words say it too */
.wl-site-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.wl-site-item { display: grid; grid-template-columns: auto 1fr; gap: var(--space-2); align-items: start; }
.wl-site-item > .wl-icon { width: calc(var(--size-icon, 20px) - 4px); height: calc(var(--size-icon, 20px) - 4px); margin-top: 1px; color: var(--c-muted); }
.wl-site-item.ok > .wl-icon { color: var(--c-success); }
.wl-site-item.care > .wl-icon { color: var(--c-warning); }
.wl-site-item.danger > .wl-icon { color: var(--c-danger); }
.wl-site-item b { display: block; font-weight: var(--weight-medium); }
.wl-site-item p, .wl-site-note { margin: var(--space-1) 0 0; color: var(--c-ink-soft); line-height: 1.45; overflow-wrap: anywhere; }
.wl-site-note { margin: 0; font-size: var(--text-xs); color: var(--c-muted); }
.wl-site-wait { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-6) var(--space-4); color: var(--c-muted); }
/* choices: a fieldset of rows (a radio or a tick, an icon, a name and a small reason) */
.wl-site-set { margin: 0; padding: var(--space-4); border: 0; border-bottom: 1px solid var(--c-line-soft); min-width: 0; display: grid; gap: var(--space-2); }
.wl-site-set > legend { float: left; width: 100%; padding: 0; margin: 0 0 var(--space-1); }
.wl-site-opt { display: grid; grid-template-columns: auto 1fr auto; gap: var(--space-2); align-items: start; padding: var(--space-2); margin: 0 calc(-1 * var(--space-2)); border-radius: var(--radius-md); cursor: var(--cursor-pointer, pointer); }
.wl-site-opt:hover { background: var(--c-panel); }
/* an option that can't be used: its control and name dim, its reason stays readable (it says why) */
.wl-site-opt.off { cursor: var(--cursor-default, default); }
.wl-site-opt.off:hover { background: transparent; }
.wl-site-opt.off > .wl-radio, .wl-site-opt.off > .wl-check, .wl-site-opt.off > span:nth-child(2) > :is(.wl-icon, b) { opacity: .4; }
.wl-site-opt > .wl-radio, .wl-site-opt > .wl-check { margin-top: var(--space-1); }
.wl-site-opt > span:nth-child(2) { display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-2); min-width: 0; }
.wl-site-opt b { font-weight: var(--weight-medium); overflow-wrap: anywhere; }
.wl-site-opt small { grid-column: 2; color: var(--c-muted); font-size: var(--text-xs); line-height: 1.4; overflow-wrap: anywhere; }
.wl-site-mini { align-self: center; }
.wl-site-thumb { display: block; max-width: 100%; max-height: 160px; margin-top: var(--space-1); border: 1px solid var(--c-line-soft); border-radius: var(--radius-sm); object-fit: contain; object-position: left top; background: var(--c-panel); }
/* Add to Customers: who it is (a company's name, or a person's first and last name side by side), "Add as" a company or
   a person when the page could be either (a social profile), then what the page shows, each with a tick */
.wl-site-co { display: grid; grid-template-columns: auto 1fr; gap: var(--space-3); align-items: start; padding: var(--space-4); }
.wl-site-co-t { display: grid; gap: var(--space-1); min-width: 0; }
.wl-site-co-t > small { overflow-wrap: anywhere; }
.wl-site-logo { width: 44px; height: 44px; border-radius: var(--radius-md); border: 1px solid var(--c-line-soft); object-fit: contain; background: var(--c-bg); }   /* a customer's logo: framed, never rotated (D-013) */
.wl-site-letter { display: grid; place-items: center; background: var(--c-panel-mid); font: var(--weight-bold) var(--text-lg) var(--font-sans); color: var(--c-ink-soft); }
.wl-site-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); min-width: 0; }
.wl-site-pair .wl-input { min-width: 0; }
.wl-site-as-row { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
/* the question slot: empty until an app asks its own Yes there; never more than 45 % of the panel */
.wl-site-ask:empty { display: none; }
.wl-site-ask { flex: none; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--c-line-soft); max-height: 45%; overflow: auto; }
.wl-site-foot { flex: none; display: grid; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--c-line-soft); background: var(--c-bg); }
.wl-site-fine { margin: 0; color: var(--c-muted); font-size: var(--text-xs); line-height: 1.4; }
.wl-site-acts { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: var(--space-2); }
.wl-site .wl-empty { padding: var(--space-6) var(--space-4); }
@media (prefers-reduced-motion: reduce) { .wl-site * { transition: none !important; } }
