@import url('./fonts.css?v=onest');

/* CONTENTS
 *   01 Tokens
 *   02 Dock Tokens
 *   03 Base
 *   04 Shell
 *   05 Page Frame
 *   06 Primitives
 *   07 Collections
 *   08 Surfaces
 *   09 Media
 *   10 Drag And Drop
 *   11 Dashboard
 *   12 Rich Editor
 *   13 Motion
 *   14 Dock
 * Each section owns one layer; JS reads token names, never copies values.
 */

/* == 01 Tokens ======== */

:root,
:host,
[data-print-palette='light'] {
  color-scheme: light;

  --canvas: #f5f5f5;
  --raised: #fafafa;
  --well: #f5f5f5;
  --sheet: #fff;
  --paper: var(--sheet);
  --bg: var(--canvas);
  --ink: #000;
  --ink-hover: var(--mute);
  --ink-2: #3d3d3d;
  --mute: #6e6e6e;
  --on-ink: #fff;
  --on-ink-mute: #8c8c8c;
  --hover: color-mix(in srgb, var(--ink) 5%, transparent);
  --rule: var(--line);
  --line: #d9d9d9;
  --field-line: #8c8c8c;
  --signal: #d4460c;
  --signal-text: #a3360a;
  --on-stone-highlight: var(--signal-text);
  --on-signal: #fff;
  --sig-line: color-mix(in srgb, var(--signal) 40%, transparent);
  --focus-ring: var(--signal);
  --dvokrapka-selection: color-mix(in srgb, var(--signal) 22%, transparent);
  --status-ok: #2c8a52;
  --status-warn: #94690a;
  --status-info: #356bba;
  --status-bad: #bf3228;
  --status-neutral: #767a81;
  --on-bad: #fff;
  --warn: var(--status-warn);
  --bad-soft: color-mix(in srgb, var(--status-bad) 8%, var(--sheet));

  /* Widget surfaces are steps of grey; hues live only in the dots drawn on them. */
  --tile-paper: var(--sheet);
  --tile-stone: var(--raised);
  --tile-graphite: #1a1a1a;
  --tile-ink: var(--ink);

  /* «Продовжити» stacks its drafts as layered strips, each a step darker than the tile. */
  --tile-strip-1: #e8e8e8;
  --tile-strip-2: color-mix(in srgb, var(--mute) 20%, var(--well));
  --tile-strip-3: color-mix(in srgb, var(--mute) 40%, var(--well));
  --on-tile: var(--ink);
  --on-tile-dark: #fff;
  --on-tile-dark-mute: #8c8c8c;
  --text-disabled: #8c8c8c;
  --logo-plate: transparent;

  /* Search preview only: the colours and type of a search results page, not part of the admin palette. */
  --search-sheet: #fff;
  --search-line: #dadce0;
  --search-favicon: #f1f3f4;
  --search-ink: #202124;
  --search-mute: #4d5156;
  --search-link: #1a0dab;
  --font-search: arial, 'Helvetica Neue', sans-serif;
  --type-search-title: 20px;
  --type-search-url: 12px;
  --leading-search: 1.58;
  --elevation-float: 0 16px 40px rgb(0 0 0 / 16%), 0 2px 6px rgb(0 0 0 / 10%);
  --font-ui: 'Onest', system-ui, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, monospace;
  --type-display: 40px;
  --type-display-md: 56px;
  --type-display-lg: 72px;
  --type-figure: 56px;
  --type-title: 22px;
  --type-body: 16px;
  --type-ui: 14px;
  --type-label: 11px;
  --type-badge: 10px;
  --type-micro: var(--type-label);
  --weight-light: 300;
  --weight-regular: 400;
  --weight-medium: 450;
  --leading-display: 0.95;
  --leading-tight: 1.3;
  --leading-body: 1.5;
  --leading-none: 1;
  --leading-head: 16px;

  /* A dashboard row is as tall as the smallest whole answer, not a share of the column width:
     padding, the head line, the gap, a 56 figure and its caption. Tall tiles are two of these. */
  --dashboard-row: calc(
    2 * var(--space-16) + var(--leading-head) + var(--space-12) + var(--type-display-md) + var(--space-4) +
      var(--leading-head)
  );

  /* Onest light digits carry ~0.06em of empty space on the left; large figures pull it back to the edge. */
  --optical-figure: -0.06em;
  --leading-badge: var(--badge);
  --tracking-display: -0.04em;
  --tracking-title: -0.015em;
  --tracking-label: 0.06em;
  --space-2: 2px;
  --space-4: 4px;
  --space-6: 6px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-20: 20px;
  --space-24: 24px;
  --space-32: 32px;
  --space-40: 40px;
  --space-48: 48px;
  --space-64: 64px;
  --grid-columns: 12;
  --gutter: 16px;
  --margin: 16px;
  --content-edge-phone: 16px;
  --content-edge-medium: 24px;
  --content-edge-wide: 40px;
  --bleed: calc(var(--gutter) / 2);
  --col: calc((100vw - 2 * var(--margin) - 11 * var(--gutter)) / 12);
  --aside-w: calc(3 * var(--col) + 3 * var(--gutter));
  --page-top: var(--space-40);
  --type-page: var(--type-display);
  --rhythm-header: 32px;
  --rhythm-nav: 24px;
  --rhythm-section: 64px;
  --chrome-h: 48px;
  --control-h: 40px;
  --control-h-sm: 32px;
  --control-h-xs: 24px;
  --row-h: 56px;

  /* One technical footer height: a control and its inset above and below. */
  --footer-h: calc(var(--control-h) + 2 * var(--space-12));
  --field-h: 44px;
  --marker: 8px;
  --icon: 16px;
  --icon-xl: 40px;
  --check: 18px;
  --dialog-s: 400px;
  --dialog-m: 560px;
  --dialog-l: 800px;

  /* A sheet that hangs from a fixed top edge keeps a ceiling of its own: it reads as a list, not a whole screen. */
  --dialog-max-h: 720px;
  --dock-safe-area: 104px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --badge: 16px;
  --avatar: 28px;
  --portrait: 200px;
  --portrait-sm: 120px;
  --radius-tile: 4px;
  --radius-control: 2px;
  --radius-pill: 999px;
  --status-bad-press: color-mix(in srgb, var(--status-bad) 86%, var(--ink));
  --status-bad-wash: color-mix(in srgb, var(--status-bad) 8%, transparent);
  --scrim: color-mix(in srgb, var(--ink) 32%, transparent);
  --signal-wash: color-mix(in srgb, var(--signal) 6%, transparent);
  --track: color-mix(in srgb, var(--ink) 15%, transparent);
  --on-ink-wash: color-mix(in srgb, var(--on-ink) 12%, transparent);

  /* currentColor resolves where the token is used, so these follow the text colour of their element. */
  --wash-current: color-mix(in srgb, currentcolor 10%, transparent);
  --line-current: color-mix(in srgb, currentcolor 18%, transparent);
  --trace-current: color-mix(in srgb, currentcolor 20%, transparent);

  /* A dot that counts but is already handled: paler than ink, darker than an empty slot. */
  --dot-off: color-mix(in srgb, currentcolor 36%, transparent);
  --track-current: color-mix(in srgb, currentcolor 30%, transparent);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-spatial: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-state: ease;
  --dur-state: 160ms;
  --dur-move: 220ms;
  --motion-ui: var(--dur-state);
  --motion-spatial: var(--dur-move);
  --motion-stagger: 20ms;
  --motion-loop: 900ms;
  --motion-run: 1400ms;
  --motion-tick: 1s;
  --z-sticky: 30;
  --z-dock: 40;
  --z-popover: 50;
  --z-overlay: 60;
  --z-toast: 70;
  --z-tooltip: 80;
  --z-drag: 90;
  --z-boot: 100;
  --ease-pen: cubic-bezier(0.45, 0.05, 0.3, 1);
  --dur-pen: 1.7s;
  --dur-pen-tick: 0.55s;
  --dur-leave: 0.5s;
  --delay-pen: 0.2s;
  --delay-boot-failsafe: 8s;
}

@media (min-width: 761px) {
  :root {
    --gutter: 24px;
    --margin: 24px;
    --page-top: var(--space-48);
    --type-page: var(--type-display-md);
  }
}

@media (min-width: 1201px) {
  :root {
    --margin: 40px;
    --page-top: var(--space-64);
    --type-page: var(--type-display-lg);
  }
}

/* DARK TOKENS START */

/* Four declarations of one palette: the system preference, an explicit choice on
   the document, and the same choice on a live-editing shadow host. They must stay
   identical; admin-appearance-self-test compares all three. Raw colours appear
   here and in the light root, nowhere else. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;

    --canvas: #1a1a1a;
    --raised: #222;
    --well: #000;
    --sheet: #222;
    --ink: #fff;
    --ink-hover: var(--mute);
    --ink-2: #d0d0d0;
    --mute: #a3a3a3;
    --on-ink: #000;
    --on-ink-mute: #8c8c8c;
    --line: #3a3a3a;
    --field-line: #767676;
    --signal: #ff6a2f;
    --signal-text: #ff8a5c;
    --on-stone-highlight: var(--signal-text);
    --on-signal: #1a1208;
    --status-ok: #5fbf85;
    --status-warn: #d9a441;
    --status-info: #79a8ea;
    --status-bad: #f0736a;
    --status-neutral: #8b9098;
    --on-bad: #1a0b0a;
    --tile-paper: #222;
    --tile-stone: #2c2c2c;
    --tile-graphite: #000;
    --tile-ink: #3a3a3a;
    --tile-strip-1: #2c2c2c;
    --tile-strip-2: #262626;
    --tile-strip-3: #202020;
    --on-tile-dark: #fff;
    --on-tile-dark-mute: #a3a3a3;
    --text-disabled: #767676;
    --logo-plate: #fff;
    --scrim: rgb(0 0 0 / 56%);
    --elevation-float: 0 16px 40px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%);
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;

  --canvas: #1a1a1a;
  --raised: #222;
  --well: #000;
  --sheet: #222;
  --ink: #fff;
  --ink-hover: var(--mute);
  --ink-2: #d0d0d0;
  --mute: #a3a3a3;
  --on-ink: #000;
  --on-ink-mute: #8c8c8c;
  --line: #3a3a3a;
  --field-line: #767676;
  --signal: #ff6a2f;
  --signal-text: #ff8a5c;
  --on-stone-highlight: var(--signal-text);
  --on-signal: #1a1208;
  --status-ok: #5fbf85;
  --status-warn: #d9a441;
  --status-info: #79a8ea;
  --status-bad: #f0736a;
  --status-neutral: #8b9098;
  --on-bad: #1a0b0a;
  --tile-paper: #222;
  --tile-stone: #2c2c2c;
  --tile-graphite: #000;
  --tile-ink: #3a3a3a;
  --tile-strip-1: #2c2c2c;
  --tile-strip-2: #262626;
  --tile-strip-3: #202020;
  --on-tile-dark: #fff;
  --on-tile-dark-mute: #a3a3a3;
  --text-disabled: #767676;
  --logo-plate: #fff;
  --scrim: rgb(0 0 0 / 56%);
  --elevation-float: 0 16px 40px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%);
}

:host([data-theme='dark']) {
  color-scheme: dark;

  --canvas: #1a1a1a;
  --raised: #222;
  --well: #000;
  --sheet: #222;
  --ink: #fff;
  --ink-hover: var(--mute);
  --ink-2: #d0d0d0;
  --mute: #a3a3a3;
  --on-ink: #000;
  --on-ink-mute: #8c8c8c;
  --line: #3a3a3a;
  --field-line: #767676;
  --signal: #ff6a2f;
  --signal-text: #ff8a5c;
  --on-stone-highlight: var(--signal-text);
  --on-signal: #1a1208;
  --status-ok: #5fbf85;
  --status-warn: #d9a441;
  --status-info: #79a8ea;
  --status-bad: #f0736a;
  --status-neutral: #8b9098;
  --on-bad: #1a0b0a;
  --tile-paper: #222;
  --tile-stone: #2c2c2c;
  --tile-graphite: #000;
  --tile-ink: #3a3a3a;
  --tile-strip-1: #2c2c2c;
  --tile-strip-2: #262626;
  --tile-strip-3: #202020;
  --on-tile-dark: #fff;
  --on-tile-dark-mute: #a3a3a3;
  --text-disabled: #767676;
  --logo-plate: #fff;
  --scrim: rgb(0 0 0 / 56%);
  --elevation-float: 0 16px 40px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%);
}

@media (prefers-color-scheme: dark) {
  :host:not([data-theme='light']) {
    color-scheme: dark;

    --canvas: #1a1a1a;
    --raised: #222;
    --well: #000;
    --sheet: #222;
    --ink: #fff;
    --ink-hover: var(--mute);
    --ink-2: #d0d0d0;
    --mute: #a3a3a3;
    --on-ink: #000;
    --on-ink-mute: #8c8c8c;
    --line: #3a3a3a;
    --field-line: #767676;
    --signal: #ff6a2f;
    --signal-text: #ff8a5c;
    --on-stone-highlight: var(--signal-text);
    --on-signal: #1a1208;
    --status-ok: #5fbf85;
    --status-warn: #d9a441;
    --status-info: #79a8ea;
    --status-bad: #f0736a;
    --status-neutral: #8b9098;
    --on-bad: #1a0b0a;
    --tile-paper: #222;
    --tile-stone: #2c2c2c;
    --tile-graphite: #000;
    --tile-ink: #3a3a3a;
    --tile-strip-1: #2c2c2c;
    --tile-strip-2: #262626;
    --tile-strip-3: #202020;
    --on-tile-dark: #fff;
    --on-tile-dark-mute: #a3a3a3;
    --text-disabled: #767676;
    --logo-plate: #fff;
    --scrim: rgb(0 0 0 / 56%);
    --elevation-float: 0 16px 40px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%);
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .login-logo,
  :root:not([data-theme='light']) .brand img {
    filter: invert(1);
  }
}

:root[data-theme='dark'] .login-logo,
:root[data-theme='dark'] .brand img {
  filter: invert(1);
}

/* DARK TOKENS END */

/* == 02 Dock Tokens ======== */

/* The Dock speaks the system palette; it only adds its own item size and the soft on-ink states.
   Radii are the one deliberate exception: pill container, circular items. */

.dock-wrap,
.dock-remove-indicator {
  --dock-item: 40px;
  --on-ink-hover-soft: color-mix(in srgb, var(--on-ink) 12%, transparent);
  --on-ink-line: color-mix(in srgb, var(--on-ink) 20%, transparent);
}

/* A light pill is a bright lamp at night: in dark the dock becomes a raised sheet and
   rebinds its local ink states, exactly like the live-editing dock. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .dock {
    --on-ink: var(--ink);
    --on-ink-mute: var(--mute);
    --on-ink-hover-soft: color-mix(in srgb, var(--ink) 12%, transparent);
    --on-ink-line: color-mix(in srgb, var(--ink) 20%, transparent);

    background: var(--sheet);
    color: var(--ink);
  }
}

:root[data-theme='dark'] .dock,
:host([data-theme='dark']) .dock {
  --on-ink: var(--ink);
  --on-ink-mute: var(--mute);
  --on-ink-hover-soft: color-mix(in srgb, var(--ink) 12%, transparent);
  --on-ink-line: color-mix(in srgb, var(--ink) 20%, transparent);

  background: var(--sheet);
  color: var(--ink);
}

/* == 03 Base ======== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-family: var(--font-ui);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;

  /* The scrollbar's place is always kept, so a page never shifts sideways when it gains or loses one. */
  scrollbar-width: thin;
  scrollbar-gutter: stable;
  scrollbar-color: var(--line) transparent;
}

body {
  margin: 0;
}

body.has-dialog {
  overflow: hidden;
}

h1,
h2,
h3,
h4,
p,
dl,
dd,
figure,
blockquote {
  margin: 0;
}

h1,
h2,
h3,
h4,
h5,
h6,
strong,
b {
  font-size: inherit;
  font-weight: var(--weight-regular);
}

ul,
ol {
  margin: 0;
  padding: 0;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
video {
  max-width: 100%;
  display: block;
}

[hidden] {
  display: none !important;
}

::selection {
  background: var(--dvokrapka-selection);
}

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Read by screen readers only: a filter named by its value, a compound part, a settings cell's media label,
   a headless table, a small tile's action, an icon picker's names. */

.visually-hidden,
.frame-filters > .field > :is(.label, .label-with-help),
.compound > .field > .label,
.settings-media-item .media-field > .label,
.data-table.is-headless thead,
[data-widget-display='small'] .widget-action-label,
.select[data-icon-picker] .select-option .icon-label > span {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

svg.icon {
  width: var(--icon);
  height: var(--icon);
  flex: none;
}

.icon {
  fill: none;
  stroke: currentcolor;
  color: currentcolor;
}

.label,
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  line-height: var(--leading-tight);
}

.muted {
  color: var(--mute);
}

.small {
  font-size: var(--type-ui);
}

.mono,
code,
kbd,
.document-id {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* A date is read, not copied: the text face with even figures, one line, like a date in any other row. */

time,
time.mono {
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

kbd {
  display: inline-block;
  padding: var(--space-2) var(--space-6);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--raised);
  font-size: var(--type-label);
  line-height: var(--leading-tight);
  color: var(--mute);
}

.text-bad {
  color: var(--status-bad);
}

.stack {
  display: grid;
  gap: var(--space-16);
  align-content: start;
  min-width: 0;
}

.full {
  grid-column: 1 / -1;
}

/* == 04 Shell ======== */

#app {
  min-height: 100dvh;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: center;
  min-height: var(--chrome-h);
  padding-inline: var(--margin);
  background: var(--canvas);
  font-size: var(--type-ui);
}

.topbar::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: var(--line);
}

.topbar .brand {
  grid-column: 1 / 5;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  justify-self: start;
  min-height: var(--control-h-sm);
}

.topbar .brand img {
  width: 108px;
  height: auto;
}

.top-site {
  display: none;
  color: var(--mute);
}

.search-launch {
  position: relative;
  grid-column: 5 / 10;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  justify-self: end;
  min-width: 0;
  min-height: var(--control-h-sm);
  color: var(--ink);
}

.search-launch > span {
  display: none;
}

.top-actions {
  grid-column: 10 / -1;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-12);
}

.top-actions .profile {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  min-width: 0;
  min-height: var(--control-h-sm);
  text-align: left;
}

.top-actions .profile > span:last-child {
  display: none;
  min-width: 0;
}

.top-actions .profile strong {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-weight: var(--weight-regular);
}

.top-actions .profile small {
  display: none;
}

/* The name needs a whole line: below 1201 it either wraps or shrinks to a couple of letters. */

@media (min-width: 1201px) {
  .top-actions .profile > span:last-child {
    display: grid;
  }
}

.avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--avatar);
  height: var(--avatar);
  overflow: hidden;
  border-radius: 50%;
  background: var(--raised);
  font-size: var(--type-label);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.notification-count {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  min-width: var(--badge);
  height: var(--badge);
  padding-inline: var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--signal);
  color: var(--on-signal);
  font-family: var(--font-mono);
  font-size: var(--type-badge);
  line-height: var(--leading-badge);
  text-align: center;
}

#notification-bell {
  position: relative;
}

@media (min-width: 761px) {
  .topbar .brand {
    grid-column: 1 / 4;
  }

  .top-site {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    grid-column: 4 / 7;
    justify-self: start;
  }

  .search-launch {
    grid-column: 7 / 10;
    justify-self: stretch;
  }

  .search-launch > span {
    display: inline;
  }
}

.search-launch > span {
  flex: 1;
  min-width: 0;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: opacity var(--dur-state) var(--ease-state);
}

.search-launch[data-fading] > span {
  opacity: 0;
}

.search-launch[data-pulse-tone]::after {
  content: '';
  position: absolute;
  top: var(--space-4);
  left: var(--space-12);
  width: var(--space-6);
  height: var(--space-6);
  border-radius: 50%;
  background: var(--mk);
}

.top-site:hover,
.search-launch:hover > span {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* The site link carries the site's state: the same square marker as every status, toned by shell state. */

.top-site::before {
  content: '';
  width: var(--marker);
  height: var(--marker);
  flex: none;
  background: var(--mk, var(--status-neutral));
  transition: background-color var(--dur-state) var(--ease-state);
}

.top-site.tone-success::before {
  animation: site-live calc(var(--dur-state) * 20) var(--ease-state) infinite;
}

@keyframes site-live {
  50% {
    opacity: 0.45;
  }
}

@media (prefers-reduced-motion: reduce) {
  .top-site.tone-success::before {
    animation: none;
  }
}

/* The line under the top bar is the status line: while a page loads, the colon runs along it;
   when it lands, the line lights up once and fades back. */

.global-led-progress {
  position: absolute;
  inset: auto 0 calc(-1 * var(--space-2));
  z-index: 1;
  height: var(--space-4);
  pointer-events: none;
  overflow: hidden;
}

.global-led-progress i {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  gap: var(--space-4);
  opacity: 0;
  translate: -100% 0;
}

.global-led-progress i::before,
.global-led-progress i::after {
  content: '';
  width: var(--space-4);
  height: var(--space-4);
  border-radius: 50%;
  background: var(--signal);
}

.global-led-progress::after {
  content: '';
  position: absolute;
  inset: auto 0 var(--space-2) 0;
  height: 1px;
  background: var(--signal);
  opacity: 0;
  transition: opacity var(--dur-leave) var(--ease-state);
}

.global-led-progress.is-active i {
  opacity: 1;
  animation: colon-run var(--motion-run) var(--ease-state) infinite;
}

.global-led-progress.is-finishing i {
  opacity: 0;
}

.global-led-progress.is-finishing::after {
  opacity: 1;
  transition: none;
}

@keyframes colon-run {
  from {
    translate: -100% 0;
  }

  to {
    translate: 100vw 0;
  }
}

@keyframes travel {
  from {
    translate: -100% 0;
  }

  to {
    translate: 250% 0;
  }
}

.workspace {
  display: block;
  min-height: calc(100dvh - var(--chrome-h));
  padding-bottom: calc(var(--dock-safe-area) + var(--safe-bottom));
  outline: none;
}

.workspace.screen-pending {
  opacity: 0.6;
}

/* Sign-in and credential screens: one narrow column on the canvas, nothing around it. */

.login {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: var(--space-40) var(--margin);
  background: var(--canvas);
}

.login-form {
  display: grid;
  gap: var(--space-24);
  width: 100%;
}

.login-logo {
  width: 190px;
  height: auto;
  justify-self: start;
}

.login-form h1,
.login-form h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
}

.login-form > .btn {
  justify-self: stretch;
}

.login-form .form-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
}

/* One top bar time slot, replaced by the active focus; duration controls live in the widget. */

/* The clock's colon ticks once a second: the product's own name, keeping time. */

.top-clock,
.top-timer {
  display: inline-flex;
  align-items: center;
  justify-content: end;
  font-family: var(--font-mono);
  font-size: var(--type-ui);
  line-height: var(--leading-head);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.top-clock b {
  padding-inline: 1px;
  animation: clock-tick var(--motion-tick) steps(1) infinite;
}

@keyframes clock-tick {
  50% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .top-clock b,
  .face-colon {
    animation: none;
  }
}

@media (max-width: 760px) {
  .top-clock {
    display: none;
  }
}

.top-timer {
  gap: var(--space-8);
  min-height: var(--control-h-sm);
  background: none;
}

.top-timer [data-top-timer-icon] {
  display: flex;
}

.top-timer svg {
  width: 1em;
  height: 1em;
}

.focus-timer-menu {
  position: fixed;
  inset: auto;
  display: grid;
  gap: var(--space-12);
  width: var(--aside-w);
  margin: 0;
  padding: var(--space-16);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--sheet);
  color: var(--ink);
}

.focus-timer-menu:not(:popover-open) {
  display: none;
}

.focus-timer-menu-presets {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.focus-timer-menu-presets button {
  min-height: var(--control-h);
  border: 0;
  background: var(--sheet);
  color: inherit;
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.focus-timer-menu-presets button:hover {
  background: var(--raised);
}

.focus-timer-menu-presets button[aria-pressed='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

.focus-timer-menu-custom {
  display: grid;
  gap: var(--space-4);
}

.focus-timer-menu-hint {
  color: var(--status-bad);
  font-size: var(--type-ui);
}

/* First run: the same narrow column as sign-in, with step dots above the content. */

.install-screen {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: var(--space-40) var(--margin);
  background: var(--canvas);
}

.install-panel {
  display: grid;
  gap: var(--space-32);
  width: 100%;
}

.install-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-16);
}

.install-progress {
  display: flex;
  gap: var(--space-8);
}

.install-dot {
  display: block;
  width: var(--marker);
  height: var(--marker);
  background: var(--line);
}

.install-step.complete .install-dot {
  background: var(--ink);
}

.install-step.current .install-dot {
  background: var(--signal);
}

.install-content {
  display: grid;
  gap: var(--space-20);
}

.install-content h1 {
  font-size: var(--type-display);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
}

.install-checks,
.install-summary {
  display: grid;
  border-top: 1px solid var(--line);
}

.install-actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-8);
}

.install-claim-card {
  display: grid;
  gap: var(--space-16);
  padding: var(--space-16);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
}

.install-claim-intro,
.install-claim-note {
  color: var(--mute);
  font-size: var(--type-ui);
}

.install-claim-divider {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-12);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
}

.install-claim-divider::before,
.install-claim-divider::after {
  content: '';
  height: 1px;
  background: var(--line);
}

/* The column grid is too narrow to size these on a phone; the cap starts with the tablet layout. */

@media (min-width: 761px) {
  .login-form {
    width: min(100%, var(--aside-w));
  }

  .install-panel {
    width: min(100%, calc(2 * var(--aside-w)));
  }
}

/* Offline: a signal in the top bar and the card that sends local changes when the network is back. */

.offline-signal {
  position: relative;
}

.offline-signal[data-state='offline'],
.offline-signal[data-state='warning'] {
  color: var(--status-warn);
}

.offline-status[data-state='error'] {
  color: var(--status-bad);
}

.offline-publish {
  position: fixed;
  top: calc(var(--chrome-h) + var(--space-8));
  right: var(--margin);
  z-index: var(--z-toast);
  display: grid;
  gap: var(--space-12);
  width: min(100% - 2 * var(--margin), var(--aside-w));
  padding: var(--space-16);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--sheet);
  opacity: 0;
  translate: 0 calc(-1 * var(--space-8));
  transition:
    opacity var(--dur-state) var(--ease-out),
    translate var(--dur-state) var(--ease-out);
}

.offline-publish.is-open {
  opacity: 1;
  translate: 0 0;
}

.offline-publish__head {
  display: grid;
  gap: var(--space-4);
}

.offline-publish__head p {
  color: var(--mute);
  font-size: var(--type-ui);
}

.offline-publish__list {
  display: grid;
  max-height: calc(4 * var(--row-h));
  overflow: auto;
  border-top: 1px solid var(--line);
}

.offline-publish__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-8);
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--line);
}

.offline-publish__text {
  display: grid;
  min-width: 0;
  font-size: var(--type-ui);
}

.offline-publish__text span {
  color: var(--mute);
}

.offline-publish__actions,
.offline-publish__foot {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.offline-publish__foot {
  justify-content: flex-end;
}

@media (prefers-reduced-motion: reduce) {
  .offline-publish {
    transition: opacity var(--dur-state) var(--ease-state);
    translate: 0 0;
  }
}

/* == 05 Page Frame ======== */

.frame-page {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: start;
  padding: var(--page-top) var(--margin) var(--rhythm-section);
}

.frame-page > * {
  grid-column: 1 / -1;
  min-width: 0;
}

.page-head {
  position: relative;
  display: grid;
  grid-template-columns: subgrid;
  row-gap: var(--space-24);
  margin-bottom: var(--rhythm-header);
  padding-bottom: var(--space-24);
}

.page-head::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--rule);
}

.page-head > * {
  grid-column: 1 / -1;
  min-width: 0;
}

/* Phone: a lone menu joins the title row instead of taking a row of its own. */

@media (max-width: 960px) {
  .page-head:has(> .head-actions > :only-child:is(.current-shortcut-menu, .action-menu)) > .page-head-main {
    grid-column: 1 / -2;
    grid-row: 1;
  }

  .page-head:has(> .head-actions > :only-child:is(.current-shortcut-menu, .action-menu)) > .head-actions {
    grid-column: -2 / -1;
    grid-row: 1;
    place-self: end end;
  }
}

.page-head-main h1 {
  font-size: var(--type-page);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
  overflow-wrap: anywhere;
  margin-left: calc(-1 * var(--optical-inset, 0em));
}

.page-title {
  display: flex;
  align-items: flex-start;
  min-width: 0;
}

.page-head-main sup {
  margin-left: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--type-ui);
  font-weight: var(--weight-regular);
  letter-spacing: 0;
  vertical-align: top;
  line-height: var(--leading-none);
}

.page-head-subtitle {
  max-width: 72ch;
  margin-top: var(--space-8);
  color: var(--mute);
  font-size: var(--type-body);
}

.page-head-back-slot {
  display: flex;
  align-items: center;
  height: var(--space-20);
  margin-bottom: var(--space-12);
}

.page-head-main .page-head-back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  color: var(--mute);
  font-size: var(--type-ui);
}

.page-head-main .page-head-back:hover {
  color: var(--ink);
}

.page-head-state {
  display: grid;
  gap: var(--space-8);
  align-content: end;
  max-width: 48ch;
}

.page-head-state:empty {
  display: none;
}

.head-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

/* A screen may swap its action set; each set is one row with the same rhythm as the slot. */

.head-actions-group:not([hidden]) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

/* Save state is a status, not a button: it leads the row; the overflow menu always closes it. */

.editor-save-state {
  order: -1;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  margin-right: var(--space-8);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.editor-save-state::before {
  content: '';
  width: var(--marker);
  height: var(--marker);
  flex: none;
  background: var(--status-ok);
}

[data-editor-dirty] .editor-save-state::before {
  background: var(--signal);
}

[data-editor-busy] .editor-save-state::before {
  background: var(--mute);
}

/* One save state for editors, the overview and settings: the dot carries the tone, empty means nothing to say. */

.editor-save-state:empty {
  display: none;
}

.editor-save-state:is([data-tone='neutral'], [data-tone='loading'])::before {
  background: var(--mute);
}

.editor-save-state[data-tone='warning']::before {
  background: var(--status-warn);
}

.editor-save-state[data-tone='error'] {
  color: var(--status-bad);
}

.editor-save-state[data-tone='error']::before {
  background: var(--status-bad);
}

.head-actions .action-menu {
  order: 10;
}

/* Phone: the save state takes its own line and the buttons share even rows; wider screens keep one quiet row. */

.editor-save-state {
  flex-basis: 100%;
}

.head-actions > .btn,
.head-actions-group > .btn,
.head-actions > .head-actions-group {
  flex: 1 1 auto;
}

@media (min-width: 761px) {
  .editor-save-state {
    flex-basis: auto;
  }

  .head-actions > .btn,
  .head-actions-group > .btn,
  .head-actions > .head-actions-group {
    flex: none;
  }
}

.head-actions .action-menu > summary {
  width: var(--control-h);
  height: var(--control-h);
}

/* Phone: header buttons beyond the main action live in «⋮» and read as menu items; the save state sits in the state row. */

.action-menu-panel > .btn[data-head-folded] {
  justify-content: flex-start;
  gap: var(--space-12);
  width: 100%;
  min-height: var(--control-h);
  padding: var(--space-8) var(--space-12);
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--ink);
  font-size: var(--type-ui);
  white-space: nowrap;
}

.action-menu-panel > .btn[data-head-folded]:hover {
  background: var(--raised);
}

.action-menu-panel > .btn[data-head-folded]:disabled {
  color: var(--text-disabled);
  background: none;
}

.page-head-state:has(> .editor-save-state) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8) var(--space-16);
}

.page-head-state > .editor-save-state {
  order: 0;
  flex-basis: auto;
  margin-right: 0;
}

.page-head-state .subtitle {
  color: var(--mute);
}

.head-actions:empty {
  display: none;
}

/* The state is a line under the title on every width. */

@media (min-width: 961px) {
  .page-head > .page-head-main {
    grid-column: 1 / 6;
    grid-row: 1;
    align-self: end;
  }

  .page-head > .page-head-state:not(:empty) {
    grid-column: 1 / 6;
    grid-row: 2;
    margin-top: calc(var(--space-12) - var(--space-24));
  }

  .page-head > .head-actions {
    grid-column: 6 / -1;
    grid-row: 1;
    justify-content: flex-end;
    align-self: end;
  }

  .page-head:has([data-dashboard-save-status]) > .page-head-main {
    grid-column: 1 / 9;
  }

  .page-head:has([data-dashboard-save-status]) > .head-actions {
    grid-column: 9 / -1;
  }
}

.frame-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12) var(--space-24);
  margin-bottom: var(--rhythm-nav);
}

.frame-nav-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
}

/* Board: one frame divided into sections; lines live in the gutters, text sits on the columns. */

.frame-board {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  padding: 1px;
  background: var(--line);
}

.frame-board > * {
  min-width: 0;
  padding: var(--space-24) var(--bleed);
  background: var(--canvas);
}

.frame-board > .is-flush {
  padding: 0;
}

/* A column of section rows owns its edges: the rows, not the region, carry the inset. */

.frame-board > :has(> .section-switcher-vertical) {
  padding: 0 var(--bleed);
}

@media (min-width: 961px) {
  .frame-board > :has(> .section-switcher-vertical) {
    padding: 0;
  }
}

/* Text that shares a flush region with a matrix gets the region inset back. */

.frame-board > .is-flush > .stack {
  padding: var(--space-24) var(--bleed);
}

/* A screen may put extra blocks below its board: each block is its own card on the page background. */

.frame-page > .frame-board + .frame-board {
  margin-top: var(--space-24);
}

/* One technical footer strip on every screen: the same height and inset, present even when it has
   nothing to say, so a list, a panel or a dialog never changes height around it. */

.frame-footer,
.footer-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8) var(--space-12);
  min-height: var(--footer-h);
  padding-block: var(--space-12);
}

/* The «Додати» strip under a builder list starts where the last row's line ends and closes the
   column at its bottom edge: the inset below it is the strip's own, not the region's padding. */

.page-builder-slot-content > .footer-bar {
  margin-block-start: calc(-1 * var(--space-16));
}

.page-builder-slot:last-child .page-builder-slot-content > .footer-bar {
  margin-block-end: calc(-1 * var(--space-24));
}

.frame-board > .frame-footer {
  grid-column: 1 / -1;
}

/* An action group in a footer takes the end of the strip, opposite the footer's own text. */

:is(.frame-footer, .footer-bar) > .row-actions {
  margin-inline-start: auto;
}

@media (min-width: 961px) {
  .frame-board.has-secondary {
    grid-template-columns: var(--aside-w) minmax(0, 1fr);
  }

  .frame-board.has-secondary > .frame-aside {
    grid-column: 1 / -1;
  }
}

@media (min-width: 1201px) {
  .frame-board.has-aside {
    grid-template-columns: minmax(0, 1fr) var(--aside-w);
  }

  /* An aside whose panels are all hidden (another tab is open) gives its column back. */

  .frame-board.has-aside:not(:has(> .frame-aside > :not([hidden]))) {
    grid-template-columns: minmax(0, 1fr);
  }

  .frame-board.has-secondary.has-aside {
    grid-template-columns: var(--aside-w) minmax(0, 1fr) var(--aside-w);
  }

  .frame-board.has-secondary.has-aside > .frame-aside {
    grid-column: auto;
  }

  .frame-board.has-secondary.has-aside:not(:has(> .frame-aside > :not([hidden]))) {
    grid-template-columns: var(--aside-w) minmax(0, 1fr);
  }
}

.frame-board > .frame-aside:not(:has(> :not([hidden]))) {
  display: none;
}

/* Dashboard: objects on the columns, no board. */

[data-topology='dashboard'] > .frame-primary {
  display: grid;
  grid-template-columns: subgrid;
  row-gap: var(--gutter);
}

/* Form inside a board: section title on 3 columns, fields on 6. */

.form-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  padding: var(--space-24) var(--bleed) var(--space-40);
}

.form-section + .form-section {
  border-top: 1px solid var(--line);
}

.form-section > h2,
.section-title h2,
.section-title h3 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
}

.form-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32) var(--gutter);
  min-width: 0;
  align-content: start;
}

/* A lone field takes the row; a toggle is a sentence and gets a row of its own. */

.form-grid:not(:has(> .field ~ .field)) > .field,
.form-grid > :is(.switch-setting, .field:has(> .setting-toggle-row:only-child)),
.form-grid > .field:not(.field + .field, :has(+ .field)) {
  grid-column: 1 / -1;
}

/* One row, one line: labels on top, lines at the bottom. */

.form-grid > .field {
  position: relative;
  align-content: space-between;
}

/* An error sits in the row gap under its line: the row keeps its height, so neither the field nor its neighbour moves. */

.form-grid > .field > .error:last-child {
  position: absolute;
  top: calc(100% + var(--space-4));
  left: 0;
  right: 0;
}

@media (min-width: 761px) {
  .form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Rows in a form are one list: they sit edge to edge under their group title, not a field-gap apart. */

.form-grid
  > :is(.setting-row, .setting-toggle-row, .switch-setting, .field:has(> .setting-toggle-row:only-child))
  + :is(.setting-row, .setting-toggle-row, .switch-setting, .field:has(> .setting-toggle-row:only-child)) {
  margin-top: calc(-1 * var(--space-32));
}

.form-grid > .switch-setting {
  border-bottom: 1px solid var(--line);
}

.form-grid > .switch-setting:not(:has(~ .switch-setting)) {
  border-bottom: 0;
}

.form-grid > .form-section-title + :is(.setting-row, .setting-toggle-row) {
  margin-top: calc(var(--space-8) - var(--space-32));
}

@media (min-width: 1201px) {
  .form-section {
    grid-template-columns: repeat(9, minmax(0, 1fr));
    column-gap: var(--gutter);
  }

  .form-section > h2,
  .form-section > .section-title {
    grid-column: 1 / 4;
  }

  .form-section > .section-title {
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    align-self: start;
  }

  .form-section > :not(h2, .section-title) {
    grid-column: 4 / -1;
  }
}

/* The left column of an editor is either its tab rail or, with no tabs, the section titles: as wide as the rail
   and closed by the same vertical line, so every editor has one left column and one divider on one vertical. */

@media (min-width: 1201px) {
  .frame-board:not(.has-secondary) > .frame-primary .form-section {
    position: relative;
    grid-template-columns: calc(var(--aside-w) - 2 * var(--bleed)) minmax(0, 1fr);
    column-gap: calc(2 * var(--bleed) + 1px);
  }

  /* The divider belongs to the column, not to a section: it runs the full height even under a short section. */

  .frame-board:not(.has-secondary) > .frame-primary.is-flush:has(.form-section:not([hidden] *)) {
    background-image: linear-gradient(var(--line), var(--line));
    background-size: 1px 100%;
    background-position: var(--aside-w) 0;
    background-repeat: no-repeat;
  }

  /* The entry editor paints its own opaque body over the frame, so its body carries the divider itself. */

  .entry-editor > .editor-body:has(> .form-section) {
    background-image: linear-gradient(var(--line), var(--line));
    background-size: 1px 100%;
    background-position: var(--aside-w) 0;
    background-repeat: no-repeat;
  }

  .frame-board:not(.has-secondary) > .frame-primary .form-section > h2,
  .frame-board:not(.has-secondary) > .frame-primary .form-section > .section-title {
    grid-column: 1;
  }

  .frame-board:not(.has-secondary) > .frame-primary .form-section > :not(h2, .section-title) {
    grid-column: 2;
  }

  /* Beside a rail a section is one column: its title sits above its fields, its actions on the title's line. */

  .frame-board.has-secondary > .frame-primary .form-section {
    grid-template-columns: minmax(0, 1fr);
  }

  .frame-board.has-secondary > .frame-primary .form-section > * {
    grid-column: 1;
  }

  .frame-board.has-secondary > .frame-primary .form-section > .section-title {
    flex-direction: row;
    align-items: center;
  }
}

.section-title {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-12);
}

.count {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: 0;
  color: var(--mute);
}

.aside-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  align-content: start;
}

/* == 06 Primitives ======== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  height: var(--control-h);
  padding-inline: var(--space-16);
  border: 1px solid var(--ink);
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--type-ui);
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--dur-state) var(--ease-state),
    color var(--dur-state) var(--ease-state),
    border-color var(--dur-state) var(--ease-state);
}

.btn:hover {
  background: var(--ink);
  color: var(--on-ink);
}

.btn.primary {
  background: var(--ink);
  color: var(--on-ink);
}

.btn.primary:hover {
  background: var(--ink-hover);
  border-color: var(--ink-hover);
}

.btn.primary:active {
  background: var(--ink-2);
}

.btn.ghost,
.btn.quiet {
  border-color: transparent;
  padding-inline: var(--space-8);
}

.btn.ghost:hover,
.btn.quiet:hover {
  background: var(--hover);
  color: var(--ink);
}

.btn.danger,
.btn.destructive {
  background: var(--status-bad);
  border-color: var(--status-bad);
  color: var(--on-bad);
}

.btn.danger:hover,
.btn.destructive:hover {
  background: var(--status-bad-press);
}

/* A quiet destructive action sits beside the main one without outshouting it. */

.btn.ghost.danger {
  background: transparent;
  border-color: transparent;
  color: var(--status-bad);
}

.btn.ghost.danger:hover {
  background: var(--status-bad-wash);
}

.btn.small,
.btn.sm,
.btn.compact {
  height: var(--control-h-sm);
  padding-inline: var(--space-12);
}

.btn:disabled,
.btn[aria-disabled='true'],
.btn:disabled:hover,
.btn[aria-disabled='true']:hover {
  background: transparent;
  border-color: var(--line);
  color: var(--text-disabled);
  cursor: not-allowed;
}

.btn[aria-pressed='true'],
.btn.active {
  background: var(--ink);
  color: var(--on-ink);
}

.btn[aria-busy='true'] {
  cursor: progress;
}

.btn .icon {
  width: var(--icon);
  height: var(--icon);
  display: block;
}

.btn > .icon,
.page-head-back > .icon,
.text-action > .icon {
  translate: none;
}

.icon-button {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--control-h);
  height: var(--control-h);
  flex: none;
  border-radius: var(--radius-control);
  color: var(--ink);
  transition:
    background-color var(--dur-state) var(--ease-state),
    color var(--dur-state) var(--ease-state);
}

.icon-button:hover {
  background: var(--hover);
}

/* Everything inside an icon button shares one cell, so a hidden counter or host never pushes the icon off centre. */

.icon-button > * {
  grid-area: 1 / 1;
}

.icon-button.compact,
.icon-button.row-action {
  width: var(--control-h-sm);
  height: var(--control-h-sm);
}

/* A dismiss control is the size of the corner badge, not of a row action: one 24 px square everywhere,
   from a tile cross to the dialog close. */
.icon-button.dismiss-control {
  width: var(--control-h-xs);
  height: var(--control-h-xs);
}

.icon-button.danger {
  color: var(--status-bad);
}

.icon-button.danger:hover {
  background: var(--status-bad-wash);
}

.icon-button:disabled {
  color: var(--text-disabled);
  cursor: not-allowed;
  background: none;
}

.text-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  min-height: var(--control-h-sm);
  font-family: var(--font-ui);
  font-size: var(--type-ui);
  letter-spacing: normal;
  text-transform: none;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 4px;
  transition: text-decoration-color var(--dur-state) var(--ease-state);
}

.text-action:hover {
  text-decoration-color: currentcolor;
}

.text-action.danger {
  color: var(--status-bad);
}

.text-action:disabled {
  color: var(--text-disabled);
  cursor: not-allowed;
}

.row-actions,
.list-actions,
.actions,
.detail-action-buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

.row-actions {
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Icon buttons sit close; words need a word gap, so two text actions never read as one word. */

.row-actions > .text-action + .text-action,
.row-actions > .text-action + .btn,
.row-actions > .btn + .text-action {
  margin-left: var(--space-12);
}

.spinner,
.async-action-spinner {
  position: relative;
  display: inline-block;
  width: var(--space-16);
  height: 1px;
  overflow: hidden;
  background: var(--track-current);
}

.spinner::after,
.async-action-spinner::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 40%;
  background: currentcolor;
  animation: travel var(--motion-loop) linear infinite;
}

/* Status: square marker + word, colour never alone */

.marker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink);
}

.marker::before {
  content: '';
  display: inline-block;
  width: var(--marker);
  height: var(--marker);
  flex: none;
  background: var(--mk, var(--status-neutral));
}

/* The product is a colon: every status mark is a dot. */

:is(.marker, .top-site, .editor-save-state, .row-open strong, [data-toast-message], .widget-row-name)::before,
.install-dot,
.live-caption-dot {
  border-radius: 50%;
}

.tone-success {
  --mk: var(--status-ok);
}

.tone-warning {
  --mk: var(--status-warn);
}

.tone-info {
  --mk: var(--status-info);
}

.tone-error {
  --mk: var(--status-bad);
}

/* Field: underline, small label, large value */

.field {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  align-content: start;
  min-width: 0;
}

.field > .label,
.label-with-help > .label {
  color: var(--mute);
}

.label-with-help {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.field .help,
.field-meta,
.helper {
  font-size: var(--type-ui);
  color: var(--mute);
}

.control {
  display: block;
  width: 100%;
  min-height: var(--field-h);
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--field-line);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-size: var(--type-body);
  text-align: left;
  transition:
    border-color var(--dur-state) var(--ease-state),
    box-shadow var(--dur-state) var(--ease-state);
}

/* A text area is an input that holds several lines: it opens at the input height, puts its first line where a
   single-line input puts its text, and grows with the content. Browsers without `field-sizing` are measured by
   the script on focus, on input and once per rendered screen. */

textarea.control {
  min-height: var(--field-h);
  /* One line is exactly the single-line field height: 1lh of text, the same inset above and below, the field line. */
  padding-block: calc((var(--field-h) - 1lh - 1px) / 2);
  resize: vertical;
  field-sizing: content;
  line-height: var(--leading-body);
}

.control::placeholder {
  color: var(--mute);
}

.control:hover {
  border-bottom-color: var(--ink);
}

.control:focus,
.control:focus-visible {
  outline: none;
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.control.invalid,
.control[aria-invalid='true'],
.invalid .control {
  border-bottom-color: var(--status-bad);
  box-shadow: inset 0 -1px 0 var(--status-bad);
}

.control:disabled,
.control[readonly] {
  color: var(--text-disabled);
  border-bottom-style: dashed;
  cursor: not-allowed;
}

.control[readonly] {
  color: var(--ink-2);
  cursor: text;
}

/* Compound field (phone): one underline for the group; its parts draw none. */

.compound {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: stretch;
  gap: var(--space-12);
  border-bottom: 1px solid var(--field-line);
  transition:
    border-color var(--dur-state) var(--ease-state),
    box-shadow var(--dur-state) var(--ease-state);
}

.compound > .control,
.compound .select-trigger {
  border: 0;
  box-shadow: none;
}

.compound:hover {
  border-bottom-color: var(--ink);
}

.compound:focus-within {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.compound:has([aria-invalid='true']) {
  border-bottom-color: var(--status-bad);
  box-shadow: inset 0 -1px 0 var(--status-bad);
}

.compound:has(.control:disabled) {
  border-bottom-style: dashed;
}

.compound > .field {
  flex: none;
  gap: 0;
}

/* Rich text is a field too: the editor frame carries the underline states of its content. */

.rich-editor:has(.rich-content:focus) {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

@media (prefers-reduced-motion: reduce) {
  .control,
  .compound,
  .select-trigger .icon {
    transition: none;
  }
}

.error {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  font-size: var(--type-ui);
  color: var(--status-bad);
}

.error:empty {
  display: none;
}

.explain-trigger {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  color: var(--mute);
}

.explain-trigger .icon {
  width: 14px;
  height: 14px;
}

.explain-trigger:hover {
  color: var(--ink);
}

.explain-anchor {
  display: inline-flex;
}

.unit-control,
.phone-control,
.multi-value-control {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  border-bottom: 1px solid var(--field-line);
}

.unit-control .control,
.phone-control .control {
  border-bottom: 0;
  box-shadow: none;
}

.unit-control:focus-within,
.phone-control:focus-within {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.unit-suffix {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  color: var(--mute);
}

.title-input .control {
  font-size: var(--type-title);
}

.machine-secret {
  font-family: var(--font-mono);
}

/* Stepper */

.stepper {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  border-bottom: 1px solid var(--field-line);
}

.stepper .control,
.stepper-input {
  border: 0;
  text-align: center;
  font-family: var(--font-mono);
}

.stepper-input {
  width: 100%;
  min-width: 0;
  height: var(--field-h);
  background: transparent;
  color: inherit;
  font-size: var(--type-body);
  outline: none;
  appearance: textfield;
}

.stepper-input::-webkit-inner-spin-button,
.stepper-input::-webkit-outer-spin-button {
  margin: 0;
  appearance: none;
}

/* Number fields stay underline fields: no browser spinner glued to the edge. */

.control[type='number'] {
  appearance: textfield;
}

.control[type='number']::-webkit-inner-spin-button,
.control[type='number']::-webkit-outer-spin-button {
  margin: 0;
  appearance: none;
}

.stepper:focus-within {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.stepper button {
  width: var(--control-h);
  height: var(--field-h);
  font-size: var(--type-title);
  font-weight: var(--weight-light);
}

.stepper button:hover {
  background: var(--hover);
}

/* Select: a button trigger with an ARIA listbox; never native */

.select {
  position: relative;
}

.select-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  width: 100%;
  min-height: var(--field-h);
  border-bottom: 1px solid var(--field-line);
  font-size: var(--type-body);
  text-align: left;
  transition: border-color var(--dur-state) var(--ease-state);
}

.select-trigger:hover {
  border-bottom-color: var(--ink);
}

/* The current value keeps one line; a long label ends in an ellipsis instead of growing the field. */

.select-trigger > [data-current] {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.select-trigger[aria-expanded='true'] {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.select-trigger > .icon {
  color: var(--ink-2);
  rotate: 90deg;
  transition: rotate var(--dur-move) var(--ease-out);
}

.select-trigger[aria-expanded='true'] > .icon {
  rotate: -90deg;
}

.select-trigger:disabled {
  color: var(--text-disabled);
  border-bottom-style: dashed;
  cursor: not-allowed;
}

.select-menu,
.action-menu-panel,
.rich-block-menu {
  position: fixed;
  inset: auto;
  z-index: var(--z-popover);
  display: grid;
  min-width: 220px;
  max-height: 60dvh;
  margin: 0;
  padding: 0;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--sheet);
  color: var(--ink);
  box-shadow: var(--elevation-float);
}

/* A closed popover must not lay out at its static position inside the trigger: the author
   display:grid above would otherwise override the UA hidden rule and paint the menu at the
   trigger's right edge for a frame before it is placed. */

.action-menu-panel:not(:popover-open),
.select-menu:not(:popover-open),
.rich-block-menu:not(:popover-open) {
  display: none;
}

.select-menu .search-field {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0 var(--space-12);
  background: var(--sheet);
  border-bottom: 1px solid var(--line);
}

.select-option,
.action-menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  width: 100%;
  min-height: var(--control-h);
  padding: var(--space-8) var(--space-12);
  font-size: var(--type-body);
  text-align: left;
}

.select-option + .select-option {
  border-top: 1px solid var(--line);
}

.select-option:hover,
.action-menu-item:hover {
  background: var(--raised);
  outline: none;
}

.select-option:focus-visible,
.action-menu-item:focus-visible {
  background: var(--raised);
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.select-option.is-active {
  background: var(--raised);
  outline: none;
}

/* Icon picker: a plain grid, five to a row; names stay for search, tooltips and screen readers. */

.select[data-icon-picker] .select-menu {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.select[data-icon-picker] .select-menu > .search-field {
  grid-column: 1 / -1;
}

.select[data-icon-picker] .select-option {
  justify-content: center;
  padding: 0;
  border-top: 0;
  box-shadow: inset -1px -1px 0 var(--line);
}

.select[data-icon-picker] .select-option:nth-child(5n of .select-option) {
  box-shadow: inset 0 -1px 0 var(--line);
}

.select[data-icon-picker] .select-option[aria-selected='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

/* The active choice is lit, not marked: it turns to the accent. */

.select-option[aria-selected='true'] {
  color: var(--signal-text);
}

.icon-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
}

.action-menu {
  position: relative;
  display: inline-flex;
}

.action-menu > summary {
  list-style: none;
}

.action-menu > summary::-webkit-details-marker {
  display: none;
}

.action-menu-item {
  justify-content: flex-start;
  font-size: var(--type-ui);
  white-space: nowrap;
}

.action-menu-item.danger {
  color: var(--status-bad);
}

.action-menu-item:disabled {
  color: var(--text-disabled);
  background: none;
  cursor: not-allowed;
}

.action-menu-divider {
  height: 1px;
  background: var(--line);
}

/* Temporal: calendar as a grid of cells */

.temporal-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-mono);
  cursor: pointer;
}

.temporal-calendar {
  display: grid;
}

.temporal-calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-12);
  border-bottom: 1px solid var(--line);
}

.temporal-calendar-head strong {
  order: -1;
  margin-right: auto;
  font-weight: var(--weight-regular);
}

.temporal-weekdays,
.temporal-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
}

.temporal-weekdays span {
  padding: var(--space-6) var(--space-8);
  background: var(--sheet);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
}

.temporal-days > * {
  background: var(--sheet);
}

.temporal-days button {
  display: flex;
  align-items: flex-start;
  aspect-ratio: 1;
  padding: var(--space-6) var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--type-ui);
  transition: background-color var(--dur-state) var(--ease-state);
}

.temporal-days button:hover {
  background: var(--raised);
}

.temporal-days button.active,
.temporal-days button[aria-selected='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

.temporal-time {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-8) var(--space-12);
  border-top: 1px solid var(--line);
}

.temporal-time-control {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--font-mono);
}

/* Choice: check, radio, switch */

.check,
.radio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--control-h);
  cursor: pointer;
}

.check input,
.radio input,
input[type='checkbox']:not([role='switch']),
input[type='radio'] {
  appearance: none;
  display: inline-grid;
  place-items: center;
  width: var(--check);
  height: var(--check);
  margin: 0;
  flex: none;
  border: 1px solid var(--ink);
  border-radius: var(--radius-control);
  background: transparent;
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

input[type='radio'] {
  border-radius: 50%;
}

input[type='checkbox']:not([role='switch']):checked,
input[type='checkbox']:not([role='switch']):indeterminate {
  background: var(--ink);
}

input[type='checkbox']:not([role='switch']):checked::after {
  content: '';
  width: 9px;
  height: 5px;
  border: 1.5px solid var(--on-ink);
  border-top: 0;
  border-right: 0;
  rotate: -45deg;
  translate: 0 -1px;
}

input[type='checkbox']:not([role='switch']):indeterminate::after {
  content: '';
  width: 8px;
  height: 1.5px;
  background: var(--on-ink);
}

input[type='radio']:checked::after {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ink);
}

input[type='checkbox']:disabled,
input[type='radio']:disabled {
  border-color: var(--text-disabled);
  cursor: not-allowed;
}

.check:has(input:disabled),
.radio:has(input:disabled) {
  color: var(--text-disabled);
  cursor: not-allowed;
}

.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--control-h);
  cursor: pointer;
}

.switch input[role='switch'] {
  appearance: none;
  position: relative;
  width: 40px;
  height: 20px;
  margin: 0;
  flex: none;
  border: 1px solid var(--ink);
  border-radius: var(--radius-control);
  background: transparent;
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

.switch input[role='switch']::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 12px;
  height: 12px;
  background: var(--ink);
  transition:
    translate var(--dur-move) var(--ease-out),
    background-color var(--dur-state) var(--ease-state);
}

.switch input[role='switch']:checked {
  background: var(--ink);
}

.switch input[role='switch']:checked::after {
  translate: 20px 0;
  background: var(--on-ink);
}

.switch input[role='switch']:disabled {
  border-color: var(--text-disabled);
  cursor: not-allowed;
}

.switch input[role='switch']:disabled::after {
  background: var(--text-disabled);
}

.switch input[role='switch']:checked:disabled {
  background: var(--text-disabled);
}

.switch input[role='switch']:checked:disabled::after {
  background: var(--paper);
}

/* A switch is always a row: its name on the left, the switch at the row's end. Never beside a heading. */

.switch-setting {
  justify-content: space-between;
  width: 100%;
  min-height: var(--row-h);
}

.setting-toggle-row,
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  min-height: var(--row-h);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
}

.setting-toggle-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
}

.setting-toggle-label strong,
.setting-row strong {
  font-weight: var(--weight-regular);
}

.setting-row p,
.setting-row small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.setting-row-open {
  width: 100%;
  text-align: left;
}

.setting-list,
.settings-list {
  display: grid;
  border-top: 1px solid var(--line);
}

/* An empty list has nothing to separate: its empty state is the only frame. */

:is(.setting-list, .settings-list, .schema-list, .usage-list, .history-timeline):has(> .empty) {
  border-top: 0;
}

.setting-row-compact {
  min-height: var(--control-h);
  padding-block: var(--space-8);
}

.section-spacer {
  margin-top: var(--space-24);
}

/* A secondary list is a new block: the rule closes the list above and opens this one. */

.list-section {
  padding-top: var(--space-32);
  border-top: 1px solid var(--rule);
}

/* A block that is its own card: the card edge replaces the rule above the list. */

.list-section-block {
  padding-top: var(--space-24);
  border-top: 0;
}

.list-section > .section-title {
  margin-bottom: var(--space-8);
}

/* Inside a flush region the heading and its note stand on the text vertical of the rows, not on the frame line. */

.list-section > :is(.section-title, p) {
  padding-inline: var(--bleed);
}

.setting-copy,
.setting-row-open-copy {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

/* Schema rows: editable lists of parts (menu items, form fields, catalog fields). */

/* One row primitive: height and line live here only. */

:is(.check-row, .schema-row, .history-timeline > *) {
  min-height: var(--row-h);
  border-bottom: 1px solid var(--line);
}

.schema-list {
  display: grid;
  border-top: 1px solid var(--line);
}

.schema-list:empty {
  display: none;
}

.schema-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
}

.schema-row:hover {
  background: var(--raised);
}

.schema-row > .name {
  display: grid;
  gap: var(--space-2);
  flex: 1;
  min-width: 0;
  padding-block: var(--space-12);
  text-align: left;
}

.schema-row > .name b {
  font-weight: var(--weight-regular);
  overflow-wrap: anywhere;
}

.schema-row > .name small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.schema-row-open:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

/* A custom analytics event is a row you edit, not one you open: no hover, removal on the last control line. */

.analytics-event-row {
  display: block;
  padding-block: var(--space-16);
}

.analytics-event-row:hover {
  background: transparent;
}

.analytics-event-remove {
  display: flex;
  align-items: end;
  justify-content: end;
}

.section-title sup {
  font-size: var(--type-label);
  color: var(--mute);
  vertical-align: top;
}

.toggle-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--gutter);
  min-width: 0;
}

@media (min-width: 1201px) {
  .toggle-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.reference-list {
  display: grid;
  list-style: none;
}

.reference-list > li {
  border-bottom: 1px solid var(--line);
}

/* A picked record: name left, phone or e-mail right; hovered by its background. */

.reference {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-12);
  width: calc(100% + 2 * var(--space-12));
  min-height: var(--row-h);
  margin-inline: calc(-1 * var(--space-12));
  padding: var(--space-12) var(--space-12);
  text-align: left;
  overflow-wrap: anywhere;
}

.reference:hover {
  background: var(--raised);
}

.reference > :not(:first-child) {
  color: var(--mute);
}

/* Choice cards: one seamed grid; the card is the control, its input stays for keyboard. */

.choice-card-group {
  display: grid;
  gap: var(--space-8);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.choice-card-group > legend {
  margin-bottom: var(--space-8);
  padding: 0;
  color: var(--mute);
}

.choice-card-grid {
  display: grid;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: var(--radius-tile);
}

.choice-card-grid::after {
  content: '';
  box-shadow: inset -1px -1px 0 var(--line);
}

@media (min-width: 761px) {
  .choice-card-grid,
  .visual-choice-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.choice-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  padding: var(--space-12) var(--space-16);
  background: transparent;
  box-shadow: inset -1px -1px 0 var(--line);
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

.choice-card > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.choice-card:hover {
  background: var(--raised);
}

.choice-card:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.choice-card:has(input:disabled) {
  color: var(--text-disabled);
  cursor: not-allowed;
}

.choice-card:has(input:checked) {
  background: var(--sheet);
}

/* Visual choice: one pick from a set. The cells draw their own seams, so an odd last row leaves clean canvas. */

.visual-choice-grid {
  display: grid;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: var(--radius-tile);
}

/* Fills an odd last row so its empty slot is still closed by seams; with an even count it is a zero-height row. */

.visual-choice-grid::after {
  content: '';
  box-shadow: inset -1px -1px 0 var(--line);
}

.visual-choice {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: start;
  gap: var(--space-20) var(--space-12);
  padding: var(--space-20);
  background: transparent;
  box-shadow: inset -1px -1px 0 var(--line);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

.visual-choice:hover {
  background: var(--raised);
}

.visual-choice[aria-checked='true'] {
  outline: 1px solid var(--ink);
  outline-offset: -1px;
}

.visual-choice:focus-visible {
  outline-offset: -2px;
}

.visual-choice-copy {
  display: grid;
  grid-column: 1 / -1;
  gap: var(--space-4);
}

.visual-choice-copy strong {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

.visual-choice-copy small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.choice-card-copy {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
}

.choice-card-copy strong {
  font-weight: var(--weight-regular);
}

.choice-card-copy small {
  color: var(--mute);
  font-size: var(--type-ui);
}

/* Search */

.search-field {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-8);
  min-width: 0;
  border-bottom: 1px solid var(--field-line);
}

.search-field > span:first-child {
  display: grid;
  color: var(--mute);
}

.search-field input {
  flex: 1;
  min-width: 0;
  min-height: var(--control-h);
  border: 0;
  background: none;
  font-size: var(--type-body);
}

.search-field input:focus-visible {
  outline: none;
}

.search-field input::placeholder {
  color: var(--mute);
}

.search-field input::-webkit-search-cancel-button {
  display: none;
}

.search-field:focus-within {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.frame-nav .search-field {
  flex: 1 1 240px;
}

@media (min-width: 761px) {
  .frame-nav .search-field {
    max-width: 320px;
  }
}

/* Text switch: tabs and filters */

.section-switcher,
.locale-switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-24);
}

.section-switcher-item,
.locale-switcher button {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--control-h);
  color: var(--mute);
  font-size: var(--type-body);
  transition: color var(--dur-state) var(--ease-state);
}

.section-switcher-item:hover,
.locale-switcher button:hover {
  color: var(--ink);
}

.section-switcher-item[aria-pressed='true'],
.section-switcher-item[aria-selected='true'],
.section-switcher-item[aria-current='page'],
.locale-switcher [aria-pressed='true'] {
  color: var(--ink);
}

.section-switcher-item[aria-pressed='true']::after,
.section-switcher-item[aria-selected='true']::after,
.section-switcher-item[aria-current='page']::after,
.locale-switcher [aria-pressed='true']::after {
  content: '';
  position: absolute;
  inset: auto 0 var(--space-4);
  height: 1px;
  background: var(--ink);
}

.section-switcher-item .count,
.section-switcher-item sup {
  align-self: flex-start;
  margin-top: var(--space-8);
}

/* A signal dot on a tab sits in the gap after its word: it never pushes the next tab away. */

.section-switcher-item > .section-launcher-dot {
  position: absolute;
  top: 50%;
  left: 100%;
  margin-left: var(--space-8);
  transform: translateY(-50%);
}

.section-switcher-compact .section-switcher-item > .section-launcher-dot {
  margin-left: var(--space-4);
}

.section-switcher-vertical .section-switcher-item > .section-launcher-dot {
  position: static;
  transform: none;
}

/* Vertical switcher: a text nav on the phone, a column of rows once the board has a side column. */

@media (min-width: 961px) {
  .section-switcher-vertical {
    flex-direction: column;
    gap: 0;
  }

  .section-switcher-vertical .section-switcher-item {
    justify-content: flex-start;
    min-height: var(--row-h);
    padding-inline: var(--bleed);
    border-bottom: 1px solid var(--line);
  }

  .section-switcher-vertical .section-switcher-item::after {
    display: none;
  }

  .section-switcher-vertical .section-switcher-item:hover {
    background: var(--raised);
  }

  .section-switcher-vertical .section-switcher-item[aria-pressed='true'] {
    background: var(--sheet);
  }

  /* When the rail reaches the board edge, its last line lies on that edge instead of doubling it. */

  .section-switcher-vertical {
    margin-bottom: -1px;
  }
}

/* Phone: tabs and languages scroll in one row. */

@media (max-width: 760px) {
  .section-switcher-nav,
  .locale-switcher > .section-switcher {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .section-switcher-nav::-webkit-scrollbar,
  .locale-switcher > .section-switcher::-webkit-scrollbar {
    display: none;
  }

  .section-switcher-nav > .section-switcher-item,
  .locale-switcher > .section-switcher > * {
    flex: none;
    white-space: nowrap;
  }

  .frame-nav:has(> .frame-nav-end .locale-switcher) {
    flex-wrap: nowrap;
  }

  .frame-nav:has(> .frame-nav-end .locale-switcher) > .section-switcher-nav {
    flex: 1 1 auto;
    min-width: 0;
  }

  .frame-nav:has(> .frame-nav-end .locale-switcher) > .frame-nav-end {
    flex: none;
  }
}

.section-switcher-compact {
  gap: var(--space-4) var(--space-16);
}

.section-switcher-compact .section-switcher-item {
  font-size: var(--type-ui);
}

/* Small parts drawn by ui.js. */

.search-field-clear[hidden] {
  display: none;
}

.dismiss-control {
  color: var(--mute);
}

.dismiss-control:hover {
  color: var(--ink);
}

.multi-value-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.unit-input {
  flex: 1;
  min-width: 0;
}

.choice-card-mark {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: var(--space-20);
  height: var(--space-20);
  margin-left: auto;
  border: 1px solid var(--field-line);
  border-radius: var(--radius-control);
  color: transparent;
}

.choice-card-mark .icon {
  width: var(--space-12);
  height: var(--space-12);
}

.choice-card:has(input:checked) .choice-card-mark {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--on-ink);
}

.visual-choice[aria-checked='true'] .visual-choice-copy strong {
  color: var(--signal-text);
}

.visual-choice-preview {
  display: grid;
  grid-column: 1;
  grid-row: 1;
  align-content: center;
  gap: var(--space-6);
  width: var(--space-64);
}

.visual-choice-preview i {
  display: block;
  height: var(--space-6);
  background: var(--line);
}

.visual-choice-preview i:first-child {
  width: 60%;
  background: var(--mute);
}

.entity-selection-single-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.entity-selection-single-wrap > .entity-selection-single-control {
  flex: 1;
  min-width: 0;
  text-align: left;
}

.entity-selection-summary {
  display: grid;
  gap: var(--space-8);
}

.upload-surface-icon {
  display: grid;
  color: var(--mute);
}

.state-presentation-action,
.ui-disclosure-action {
  flex: none;
}

.local-loading-state {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-16) var(--bleed);
}

/* One-time code: six cells over one real input; the recovery code uses the input itself. */

.otp-control {
  position: relative;
  display: block;
  max-width: calc(6 * var(--space-48));
  cursor: text;
}

.otp-input {
  position: absolute;
  inset: 0;
  width: 100%;
  opacity: 0;
}

.otp-cells {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-8);
}

.otp-cell {
  display: grid;
  place-items: center;
  height: var(--field-h);
  border-bottom: 1px solid var(--field-line);
  font-family: var(--font-mono);
  font-size: var(--type-title);
}

.otp-cell.active {
  border-bottom-color: var(--signal);
  box-shadow: inset 0 -1px 0 var(--signal);
}

.otp-field[data-otp-mode='recovery'] .otp-cells {
  display: none;
}

.otp-field[data-otp-mode='recovery'] .otp-input {
  position: static;
  min-height: var(--field-h);
  border: 0;
  border-bottom: 1px solid var(--field-line);
  background: none;
  opacity: 1;
  font-family: var(--font-mono);
}

.otp-mode {
  justify-self: start;
  padding: 0;
  border: 0;
  background: none;
  color: var(--mute);
  font: inherit;
  font-size: var(--type-ui);
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
}

/* Dialog section head drawn by module scripts: a heading with its own action on the same line. */

.form-section-title {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-12);
}

.form-section-title h3 {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

/* In a dialog every group title is one size, whatever block drew it. */

.dialog :is(.section-title, .form-section-title) :is(h2, h3) {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
  letter-spacing: normal;
  line-height: var(--leading-body);
}

/* A switcher that does not fit scrolls sideways; the edge fades so the cut reads as more. */

.section-switcher-overflow {
  mask-image: linear-gradient(to right, var(--ink) calc(100% - var(--space-32)), transparent);
}

.entity-title-row {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

.entity-extension-slot:empty {
  display: none;
}

.profile-editor-form,
.profile-editor-fields {
  display: grid;
  gap: var(--space-16);
}

.profile-editor-row {
  display: grid;
  gap: var(--space-16);
}

.appearance-options {
  gap: var(--space-12);
}

.appearance-option-text {
  display: grid;
  gap: var(--space-2);
}

@media (min-width: 761px) {
  .profile-editor-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Profile: the photo is its own column, the line between them sits in the gutter. */

@media (min-width: 761px) {
  .profile-editor-form {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 0;
  }

  .profile-editor-form > .media-field-avatar {
    align-content: start;
    padding-right: var(--gutter);
    border-right: 1px solid var(--line);
  }

  .profile-editor-form > .profile-editor-fields {
    padding-left: var(--gutter);
  }

  .profile-editor-form > .profile-editor-error {
    grid-column: 1 / -1;
  }
}

.field-settings-group {
  display: grid;
  gap: 0;
  padding-top: var(--space-16);
  border-top: 1px solid var(--line);
}

/* Phone options are rows of one list: edge to edge, one line between. The general field
   toggle continues the same list, so the block does not end in a section-sized hole. */

.field-settings-group > .switch-setting + .switch-setting,
.field-settings-group + .switch-setting {
  border-top: 1px solid var(--line);
}

.field-settings-group + .switch-setting {
  margin-top: calc(var(--space-8) - var(--space-32));
}

.form-action-controls {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-8);
}

.language-order-cell,
.language-code-cell,
.language-toggle-cell {
  white-space: nowrap;
}

.language-code-cell strong {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
}

.translation-import-issues {
  max-height: calc(4 * var(--row-h));
  overflow: auto;
}

/* Page block dialog: choose the source, then its fields. */

.page-source-field {
  display: grid;
  gap: var(--space-8);
}

.page-source-card {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  width: 100%;
  min-height: var(--row-h);
  padding: var(--space-12);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--canvas);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.page-source-card:hover {
  background: var(--raised);
}

.page-source-card-empty {
  border-style: dashed;
}

.page-source-card-icon,
.page-source-card-arrow {
  display: grid;
  flex: none;
  color: var(--mute);
}

.page-source-card-copy {
  display: grid;
  flex: 1;
  gap: var(--space-2);
  min-width: 0;
}

.page-source-card-copy small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.page-section-fields {
  padding-top: var(--space-8);
}

.page-content-source-switch {
  display: flex;
}

.page-published-difference {
  margin-bottom: var(--space-12);
}

.section-switcher-filter,
.section-switcher-pill {
  gap: var(--space-4) var(--space-16);
}

.section-switcher-filter .section-switcher-item {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
}

.section-switcher-pill .section-switcher-item {
  font-size: var(--type-ui);
}

.entity-selection-single-arrow {
  display: grid;
  margin-left: auto;
  color: var(--mute);
}

.permission-surface {
  display: grid;
  justify-items: start;
  gap: var(--space-16);
  padding: var(--space-40) var(--margin);
}

.permission-surface h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
}

.permission-surface p {
  color: var(--mute);
}

.offline-editor__state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
}

.offline-fields {
  display: grid;
  gap: var(--space-16);
}

.offline-conflict {
  display: grid;
  gap: var(--space-16);
}

.offline-conflict__head {
  display: grid;
  gap: var(--space-4);
}

.offline-conflict__head span {
  color: var(--mute);
  font-size: var(--type-ui);
}

.offline-conflict__field {
  display: grid;
  gap: var(--space-8);
}

.offline-conflict__field h4 {
  font-size: var(--type-ui);
  font-weight: var(--weight-medium);
}

.offline-conflict__columns {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

@media (min-width: 761px) {
  .offline-conflict__columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.offline-conflict__columns > * {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-12);
  background: var(--canvas);
}

.offline-conflict__columns pre {
  font-family: var(--font-mono);
  font-size: var(--type-ui);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Search preview: a results-page snippet on its own white sheet, set the way a search engine sets it. */

.search-preview {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-16) var(--space-20);
  background: var(--search-sheet);
  border: 1px solid var(--search-line);
  border-radius: var(--radius-tile);
  color: var(--search-ink);
  font-family: var(--font-search);
}

/* Under a field label the sheet sits where a control would. */

.field > .search-preview {
  margin-block-start: var(--space-8);
}

.search-preview-source {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-width: 0;
  margin-block-end: var(--space-4);
}

.search-preview-favicon {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: calc(var(--space-24) + var(--space-4));
  height: calc(var(--space-24) + var(--space-4));
  overflow: hidden;
  border: 1px solid var(--search-line);
  border-radius: var(--radius-pill);
  background: var(--search-favicon);
  color: var(--search-mute);
  font-size: var(--type-label);
}

.search-preview-favicon img {
  position: absolute;
  inset: var(--space-4);
  width: calc(100% - 2 * var(--space-4));
  height: calc(100% - 2 * var(--space-4));
  object-fit: contain;
}

.search-preview-source-copy {
  display: grid;
  min-width: 0;
  line-height: var(--leading-tight);
}

.search-preview-source-copy strong {
  font-size: var(--type-ui);
  font-weight: var(--weight-regular);
  color: var(--search-ink);
}

.search-preview-source-copy small {
  color: var(--search-mute);
  font-size: var(--type-search-url);
  overflow-wrap: anywhere;
}

.search-preview-title {
  font-size: var(--type-search-title);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  color: var(--search-link);
  overflow-wrap: anywhere;
}

.search-preview p {
  margin: 0;
  color: var(--search-mute);
  font-size: var(--type-ui);
  line-height: var(--leading-search);
  overflow-wrap: anywhere;
}

/* Social preview: the image, then the copy under one seam. */

.social-preview {
  display: grid;
  overflow: hidden;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 0;
}

.social-preview-media {
  aspect-ratio: 1.91 / 1;
  background: var(--well);
}

.social-preview-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.social-preview-copy {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-12);
  border-top: 1px solid var(--line);
}

.social-preview-copy strong {
  font-weight: var(--weight-regular);
  overflow-wrap: anywhere;
}

.social-preview-copy small {
  color: var(--mute);
  overflow-wrap: anywhere;
}

/* Launcher content: plain section names in three columns; a dot only where something waits. */

.section-launcher {
  display: grid;
  gap: var(--space-24);
}

/* The launcher filters in place: it hangs from a fixed top edge so the sheet never jumps as it shrinks.
   Its height pays for that edge itself — a ceiling, then the viewport minus both insets — so the bottom never leaves the screen. */

.dialog:has(.section-launcher),
.dialog[data-dialog-variant='command'] {
  align-self: start;
  margin-top: var(--space-48);
  max-height: min(var(--dialog-max-h), calc(100dvh - 2 * var(--space-16) - var(--space-48)));
}

.section-launcher-columns {
  display: grid;
  gap: var(--space-24) var(--gutter);
}

@media (min-width: 761px) {
  .section-launcher-columns {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.section-launcher-columns > div {
  display: grid;
  align-content: start;
  gap: var(--space-24);
}

/* A row lights up whole, as the canon says: the item spans its column and hovers with --raised. */

.section-launcher-group {
  display: grid;
}

.section-launcher-group h3 {
  margin-bottom: var(--space-4);
  padding-inline: var(--space-8);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.section-launcher-item {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-4) var(--space-8);
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

:is(.section-launcher-item, .search-line):is(:hover, :focus-visible) {
  background: var(--raised);
}

:is(.section-launcher-item, .search-line):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

/* Pulse tones. */

:is(.section-launcher-dot, .search-line)[data-tone],
[data-pulse-tone] {
  --mk: var(--status-info);
}

:is(.section-launcher-dot, .search-line)[data-tone='warning'],
[data-pulse-tone='warning'] {
  --mk: var(--status-warn);
}

:is(.section-launcher-dot, .search-line)[data-tone='error'],
[data-pulse-tone='error'] {
  --mk: var(--status-bad);
}

/* The dot sits on the lowercase middle. */

.section-launcher-item:has(> .section-launcher-dot) {
  display: block;
}

.section-launcher-dot {
  display: inline-block;
  width: var(--space-6);
  height: var(--space-6);
  margin-left: var(--space-8);
  border-radius: 50%;
  background: var(--mk);
  vertical-align: middle;
}

.search-line[data-tone] > span::before {
  content: '';
  display: inline-block;
  width: var(--space-6);
  height: var(--space-6);
  margin-right: var(--space-8);
  border-radius: 50%;
  background: var(--mk);
  vertical-align: middle;
}

/* Dock picker: rows, one line each. */

.section-launcher:has(.dock-picker-item) .section-launcher-group h3 {
  margin-bottom: var(--space-8);
  padding-block: var(--space-8);
}

.dock-picker-item {
  width: 100%;
  min-height: var(--control-h);
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--line);
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

.dock-picker-item:last-child {
  border-bottom: 0;
}

.dock-picker-item .icon {
  flex: none;
  color: var(--mute);
}

.dock-picker-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* == 07 Collections ======== */

.table-wrap {
  position: relative;
  width: 100%;
  overflow-x: auto;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-body);
}

/* An empty list is its empty state alone: no header line above it. */

.data-table:has(> tbody > tr:only-child > td > .empty:only-child) > thead {
  display: none;
}

.data-table th {
  height: var(--control-h);
  padding: 0 var(--space-12);
  border-bottom: 1px solid var(--rule);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}

.data-table td {
  height: var(--row-h);
  padding: var(--space-12) var(--space-12);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

/* A control inside a row is the compact 32. */

.data-table td :is(.switch, .check) {
  min-height: var(--control-h-sm);
}

.data-table th:first-child,
.data-table td:first-child {
  padding-left: var(--bleed);
}

.data-table th:last-child,
.data-table td:last-child {
  padding-right: var(--bleed);
}

.data-table tbody tr {
  transition: background-color var(--dur-state) var(--ease-state);
}

.data-table tbody tr:hover {
  background: var(--raised);
}

.data-table tbody tr[aria-selected='true'],
.data-table tbody tr.is-selected {
  background: var(--sheet);
}

.data-table tbody tr[data-canonical-page-hidden='1'] {
  display: none;
}

.data-table td small,
.data-table .sub {
  display: block;
  color: var(--mute);
  font-size: var(--type-ui);
}

.data-table .num,
.data-table td.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* A timestamp speaks like the status words in the row: table mono at label size, ink, no tracking. */

.data-table time {
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: normal;
}

.data-table .fit {
  width: 1%;
  white-space: nowrap;
}

/* Column on the page grid: the same span gives the same width in every table, the free column takes the rest. */

.data-table th[data-span='1'] {
  width: calc(var(--col) + var(--gutter));
}

.data-table th[data-span='2'] {
  width: calc(2 * var(--col) + 2 * var(--gutter));
}

.data-table th[data-span='3'] {
  width: calc(3 * var(--col) + 3 * var(--gutter));
}

.data-table th[data-span='4'] {
  width: calc(4 * var(--col) + 4 * var(--gutter));
}

.data-table th[data-span='5'] {
  width: calc(5 * var(--col) + 5 * var(--gutter));
}

.data-table th[data-span='6'] {
  width: calc(6 * var(--col) + 6 * var(--gutter));
}

.form-section + .table-wrap {
  border-top: 1px solid var(--line);
}

/* In the board the frame closes the table: no second line. */

.frame-board .data-table tbody tr:last-child > td,
.frame-board .data-table.is-stackable tbody tr:last-child {
  border-bottom: 0;
}

/* Actions below the table: it closes with its own line. */

@media (min-width: 761px) {
  .frame-board .form-section:has(> .section-title > :first-child:not(h2)) .data-table tbody tr:last-child > td {
    border-bottom: 1px solid var(--line);
  }
}

.data-table td:last-child .row-actions {
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.theme-text-table td:last-child .row-actions {
  opacity: 1;
}

/* The translations row lives inside #translation-editor, not directly in the flush board, so the board's
   inset never reaches it: it carries its own top inset and keeps the rhythm below. */

.translation-filters {
  padding: var(--space-16) var(--bleed) 0;
  margin-bottom: var(--rhythm-nav);
}

.form-section > .frame-filters {
  margin-bottom: var(--rhythm-nav);
}

#translation-editor > .list-foot {
  padding-block: var(--space-16);
  padding-inline: var(--bleed);
  border-top: 1px solid var(--line);
}

#translation-editor > .list-foot + .form-section {
  border-top: 1px solid var(--line);
}

@media (min-width: 761px) {
  .theme-text-table th:nth-child(2),
  .theme-text-table td:nth-child(2) {
    min-width: calc(2 * var(--col) + 2 * var(--gutter));
  }
}

.data-table tr:hover .row-actions,
.data-table tr:focus-within .row-actions {
  opacity: 1;
}

@media (hover: none) {
  .data-table td:last-child .row-actions {
    opacity: 1;
  }
}

.translation-group .entity-name {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  width: 100%;
}

.translation-group .entity-name > span {
  min-width: 0;
}

.translation-group .entity-name .icon {
  flex: none;
  width: var(--space-12);
  height: var(--space-12);
  margin-left: auto;
  rotate: 90deg;
  transition: rotate var(--dur-move) var(--ease-out);
}

.translation-group .entity-name[aria-expanded='true'] .icon {
  rotate: -90deg;
}

.data-table .entity-name,
.data-table strong {
  font-weight: var(--weight-regular);
}

/* Phone: a row is a record card; the first cell leads, the last holds its action, the rest read as lines. */

.data-table.is-stackable thead {
  display: none;
}

.data-table.is-stackable,
.data-table.is-stackable tbody {
  display: block;
}

.data-table.is-stackable tr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-4) var(--space-12);
  padding: var(--space-16) var(--bleed);
  border-bottom: 1px solid var(--line);
}

.data-table.is-stackable td {
  display: block;
  min-width: 0;
  height: auto;
  padding: 0;
  border: 0;
  overflow-wrap: anywhere;
}

.data-table.is-stackable td:first-child {
  grid-column: 1;
  grid-row: 1;
}

.data-table.is-stackable td:last-child {
  grid-column: 2;
  grid-row: 1;
  color: var(--mute);
  font-size: var(--type-ui);
}

.data-table.is-stackable td:not(:first-child, :last-child) {
  grid-column: 1 / -1;
  color: var(--mute);
  font-size: var(--type-ui);
}

.data-table.is-stackable td:only-child {
  grid-column: 1 / -1;
  color: inherit;
  font-size: inherit;
}

/* Language card: name first, menu beside it, no drag grip. */

.language-table td[data-cell='order'] {
  display: none;
}

.language-table td[data-cell='name'] {
  grid-column: 1;
  grid-row: 1;
  color: var(--ink);
  font-size: var(--type-body);
}

.language-table td[data-cell='actions'] {
  grid-column: 2;
  grid-row: 1;
}

.language-table td[data-cell='code'] {
  grid-column: 1 / -1;
  grid-row: 2;
}

/* On a phone a trailing date takes its own line instead of squeezing the title column. */

@media (max-width: 480px) {
  .data-table.is-stackable td[data-cell='date']:last-child {
    grid-column: 1 / -1;
    grid-row: auto;
  }
}

/* Stacked, a narrow figure loses its header: it carries the column name itself. */

.data-table.is-stackable
  td.fit[data-label]:not([data-label=''], :first-child, :last-child, :empty, :has(button, details, a))::before {
  content: attr(data-label) ': ';
  color: var(--mute);
}

@media (max-width: 760px) {
  [data-translation-rows] td[data-label]::before {
    content: attr(data-label) ': ';
    color: var(--mute);
  }

  [data-translation-rows] td:is(:first-child, :last-child)[data-label]::before {
    content: none;
  }
}

@media (min-width: 761px) {
  .data-table.is-stackable {
    display: table;
  }

  .data-table.is-stackable thead {
    display: table-header-group;
  }

  .data-table.is-stackable tbody {
    display: table-row-group;
  }

  .data-table.is-stackable tr {
    display: table-row;
    padding: 0;
    border: 0;
  }

  .data-table.is-stackable td {
    display: table-cell;
    height: var(--row-h);
    padding: var(--space-12) var(--space-12);
    border-bottom: 1px solid var(--line);
  }

  .data-table.is-stackable td:first-child {
    padding-left: var(--bleed);
  }

  .data-table.is-stackable td:last-child {
    padding-right: var(--bleed);
  }

  .data-table.is-stackable td:not(:first-child) {
    color: inherit;
    font-size: inherit;
  }

  .data-table.is-stackable td.fit[data-label]:not(:first-child)::before {
    content: none;
  }
}

@media (max-width: 760px) {
  .theme-text-table.is-stackable td[data-cell='select'] {
    grid-area: 2 / 2;
    justify-self: end;
  }

  .theme-text-table.is-stackable td[data-cell='actions'] {
    grid-area: 1 / 2;
  }

  .theme-text-table.is-stackable td[data-cell='text'] {
    grid-area: 1 / 1;
    color: var(--ink);
    font-size: var(--type-body);
  }

  [data-translation-rows] td[data-cell='select'] {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  [data-translation-rows] td[data-cell='field'] {
    grid-column: 1;
    grid-row: 1;
    color: var(--ink);
    font-size: inherit;
  }

  [data-translation-rows] td[data-cell='status'] {
    grid-column: 1 / -1;
    grid-row: auto;
  }
}

/* A row that opens a record: the whole row is the target; its hover says it opens. */

.data-table tbody tr {
  position: relative;
}

.row-open,
.row-title {
  display: grid;
  text-align: left;
  min-width: 0;
}

.row-open::after {
  content: '';
  position: absolute;
  inset: 0;
}

.row-open strong,
.row-title strong {
  font-weight: var(--weight-regular);
  overflow-wrap: anywhere;
}

.row-open small,
.row-title small {
  color: var(--mute);
  font-size: var(--type-ui);
}

/* entity-name is the row opener scripts draw; it behaves like row-open. */

.entity-name {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.data-table .entity-name::after {
  content: '';
  position: absolute;
  inset: 0;
}

.row-meta {
  display: block;
  color: var(--mute);
  font-size: var(--type-ui);
}

.data-table .row-actions,
.data-table .select,
.data-table a,
.data-table input {
  position: relative;
  z-index: 1;
}

.data-table tbody tr:has(.row-open) td:last-child:has(> time) {
  white-space: nowrap;
}

.data-table tbody tr:has(.row-open:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.row-open:focus-visible {
  outline: none;
}

/* The end of a section dot's trail: the record that waits carries the same dot before its name. */

.row-waiting :is(.entity-name, .row-open strong)::before {
  content: '';
  display: inline-block;
  width: var(--space-6);
  height: var(--space-6);
  margin-right: var(--space-8);
  border-radius: 50%;
  background: var(--status-info);
  vertical-align: middle;
}

.submission-row-unread .row-open strong {
  font-weight: var(--weight-medium);
}

.submission-row-unread .row-open strong::before {
  content: '';
  display: inline-block;
  width: var(--marker);
  height: var(--marker);
  margin-right: var(--space-8);
  background: var(--signal);
  vertical-align: 0.1em;
}

.frame-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16) var(--gutter);
  flex: 1;
}

/* A filter row inside a flush list keeps the table's inset and sits in the content column, beside the rail. */

.frame-board > .is-flush > .frame-filters {
  padding: var(--space-16) var(--bleed);
}

/* A filter row is one kind of control: the search is the first field and every control keeps the
   same width, so two screens never stretch their rows differently. */

.frame-filters > .field,
.frame-filters > .search-field {
  flex: 1 1 150px;
}

.frame-filters > .search-field {
  align-self: flex-end;
}

/* A filter row is one control high. */

.frame-filters {
  --field-h: var(--control-h);
}

/* Filter bar: rare filters, on the phone all, open from «Фільтри · N». */

.frame-filters-more {
  display: none;
}

.frame-filters-button {
  display: none;
  flex: none;
  align-self: flex-end;
}

.frame-filters:has(> .frame-filters-more) > .frame-filters-button {
  display: inline-flex;
}

@media (max-width: 760px) {
  .frame-filters[data-filter-bar] > .field {
    display: none;
  }

  .frame-filters[data-filter-bar] > .frame-filters-button {
    display: inline-flex;
  }
}

@media (max-width: 760px) {
  .overlay.filter-sheet-overlay {
    place-items: end stretch;
    padding: 0;
  }

  .filter-sheet-overlay .dialog {
    max-width: none;
    max-height: 85dvh;
    border-width: 1px 0 0;
    border-radius: var(--radius-tile) var(--radius-tile) 0 0;
  }
}

.frame-filters > .search-field input {
  min-height: calc(var(--control-h) - 1px);
}

@media (min-width: 761px) {
  .frame-filters > .field,
  .frame-filters > .search-field {
    max-width: 280px;
  }
}

.canonical-pagination-host {
  display: flex;
  align-items: center;
  min-height: var(--footer-h);
  padding: var(--space-12) var(--bleed);
}

.canonical-pagination-host > :first-child {
  flex: 1 1 auto;
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
}

.pagination .actions {
  gap: var(--space-2);
}

.pagination-button {
  display: inline-grid;
  place-items: center;
  min-width: var(--control-h-sm);
  height: var(--control-h-sm);
  padding-inline: var(--space-8);
  border-radius: var(--radius-control);
  font-family: var(--font-mono);
  font-size: var(--type-ui);
}

.pagination-button:hover {
  background: var(--hover);
}

.pagination-button.is-current {
  background: var(--ink);
  color: var(--on-ink);
}

.pagination-button:disabled {
  color: var(--text-disabled);
  cursor: not-allowed;
  background: none;
}

.pagination-gap {
  color: var(--mute);
  padding-inline: var(--space-4);
}

/* Modules: the state cell holds the switch or the install, the version cell holds a waiting update.
   The update reads as the version, a dot and the next number; the row's hover or focus swaps it for the button. */

.module-state {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.module-version {
  display: inline-grid;
  place-items: center start;
}

.module-version > * {
  grid-area: 1 / 1;
  transition: opacity var(--dur-state) var(--ease-state);
}

.module-version-hint {
  display: inline-flex;
  align-items: center;
  gap: var(--space-12);
}

.module-version-next {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--mute);
}

.module-version-next::before {
  content: '';
  width: var(--marker);
  height: var(--marker);
  border-radius: 50%;
  background: var(--signal);
}

.module-version > .btn {
  opacity: 0;
}

.data-table tr:hover .module-version > .btn,
.data-table tr:focus-within .module-version > .btn,
.module-version > .btn[data-async-action-state] {
  opacity: 1;
}

.data-table tr:hover .module-version-hint,
.data-table tr:focus-within .module-version-hint,
.module-version:has(> .btn[data-async-action-state]) > .module-version-hint {
  opacity: 0;
}

/* Without hover there is nothing to reveal: the version and its button stand side by side. */

@media (hover: none) {
  .module-version {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--space-12);
  }

  .module-version > * {
    grid-area: auto;
  }

  .module-version > *,
  .data-table tr:is(:hover, :focus-within) .module-version > * {
    opacity: 1;
  }

  .module-version-next {
    display: none;
  }
}

/* Matrix cells (modules, templates, integrations) */

/* A matrix is one grid: each cell draws its right and bottom seam, the frame is drawn over the cells,
   so a short last row leaves canvas closed by the frame instead of a grey fill. */

.admin-matrix-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}

.admin-matrix-grid::after {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid var(--line);
  pointer-events: none;
}

.admin-matrix-grid > * {
  box-shadow: inset -1px -1px 0 var(--line);
}

/* A tile picture runs edge to edge over the cell background, so it covers the inset seam. The same
   hairline is therefore drawn above the content; the frame and the grid's negative margin close the
   outer edges, so the first column and the first row keep no line of their own. */

.admin-matrix-cell::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  pointer-events: none;
}

@media (min-width: 761px) {
  .admin-matrix-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1201px) {
  .admin-matrix-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* A matrix of one is a panel: it fills the frame instead of leaving empty cells beside it. */

.admin-matrix-grid > :only-child {
  grid-column: 1 / -1;
}

/* An empty matrix is text, not a cell: no frame, no seam. */

.admin-matrix-grid:has(> .empty:only-child)::after {
  content: none;
}

.admin-matrix-grid > .empty {
  box-shadow: none;
}

.admin-matrix-cell,
.cell {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-16);
  min-height: 0;
  min-width: 0;
  padding: var(--space-20) var(--bleed);
  background: var(--canvas);
  transition: background-color var(--dur-state) var(--ease-state);
}

@media (min-width: 761px) {
  .admin-matrix-cell,
  .cell {
    min-height: 240px;
  }
}

.admin-matrix-cell--interactive:hover {
  background: var(--raised);
}

.admin-matrix-title {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-8);
  min-width: 0;
}

.cell-art {
  display: grid;
  place-items: center;
  color: var(--ink);
}

.cell-art .icon {
  width: var(--icon-xl);
  height: var(--icon-xl);
  stroke-width: 1;
}

.cell-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-8);
}

.cell-open {
  text-align: left;
  min-width: 0;
}

.cell-open::after {
  content: '';
  position: absolute;
  inset: 0;
}

.cell-open:focus-visible {
  outline: 0;
}

.admin-matrix-cell:has(.cell-open:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.cell-body {
  display: grid;
  align-content: start;
  gap: var(--space-12);
  min-width: 0;
}

.cell-body > .cell-art {
  justify-content: start;
}

.cell-body > .figure {
  font-size: var(--type-figure);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
}

.cell-copy {
  color: var(--mute);
  font-size: var(--type-ui);
  line-height: var(--leading-body);
  overflow-wrap: anywhere;
}

.cell-note {
  font-size: var(--type-ui);
  line-height: var(--leading-body);
}

.cell-foot .row-actions {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* Inside a board the frame already draws the outer edge: cells draw only their inner seams. */

.frame-board > .frame-primary:has(> .admin-matrix-grid) {
  overflow: hidden;
}

.frame-board .admin-matrix-grid {
  background: var(--canvas);
  margin: 0 -1px -1px 0;
}

.frame-board .admin-matrix-grid::after {
  content: none;
}

.frame-board .admin-matrix-cell {
  box-shadow: inset -1px -1px 0 var(--line);
}

/* Documentation: the index is a matrix of instructions, an article is a record read top to bottom. */

.docs-cell-title {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
}

.docs-cell-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--mute);
  font-size: var(--type-ui);
  transition: color var(--dur-state) var(--ease-state);
}

.docs-cell:hover .docs-cell-action {
  color: var(--ink);
}

.docs-article {
  display: grid;
  gap: var(--space-32);
  max-width: 68ch;
  padding: var(--space-24) var(--bleed) var(--space-40);
}

.docs-section {
  display: grid;
  gap: var(--space-12);
}

.docs-section > .label {
  color: var(--mute);
}

.docs-section > p {
  line-height: var(--leading-body);
}

.docs-steps {
  display: grid;
  list-style: none;
  border-top: 1px solid var(--line);
}

.docs-steps > li {
  display: grid;
  grid-template-columns: var(--space-32) minmax(0, 1fr);
  gap: var(--space-12);
  align-items: baseline;
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
  line-height: var(--leading-body);
}

.docs-step-index {
  color: var(--mute);
  font-size: var(--type-label);
}

/* Name cell with an inline marker (languages, roles). */

.language-name-cell {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-4) var(--space-12);
  min-width: 0;
}

.language-name-cell > [data-language-primary-marker]:empty {
  display: none;
}

.meter {
  display: block;
  height: var(--space-2);
  margin-top: var(--space-6);
  background: linear-gradient(to right, var(--signal) var(--progress, 0%), var(--track) 0);
}

/* Entry editor: one form, its own aside drawn as a board column (fields must stay inside the form). */

.entry-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--line);
}

.entry-editor > .editor-body,
.entry-editor > .editor-aside {
  min-width: 0;
  background: var(--canvas);
}

.entry-editor > .editor-aside {
  padding: var(--space-24) var(--bleed);
  container-type: inline-size;
}

.entry-editor > .editor-aside .aside-stack {
  gap: var(--space-24);
}

@media (min-width: 1201px) {
  .entry-editor {
    grid-template-columns: minmax(0, 1fr) var(--aside-w);
  }
}

.entry-media-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-16) var(--gutter);
  grid-column: 1 / -1;
  container-type: inline-size;
}

.entry-media-group-fields {
  display: grid;
  gap: var(--space-16);
  align-content: start;
}

@container (max-width: 400px) {
  .entry-content-fields,
  .entry-media-group,
  .entry-media-group-fields {
    grid-template-columns: minmax(0, 1fr);
  }
}

.choice-list {
  display: grid;
  gap: var(--space-8);
  border: 0;
  min-width: 0;
}

.hotspot-editor {
  display: grid;
  gap: var(--space-12);
}

.hotspot-stage {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--well);
  cursor: crosshair;
}

.hotspot-stage > img {
  display: block;
  width: 100%;
  height: auto;
}

.hotspot-marker,
.hotspot-peer {
  position: absolute;
  width: var(--space-16);
  height: var(--space-16);
  translate: -50% -50%;
  border-radius: var(--radius-control);
}

.hotspot-marker {
  background: var(--signal);
  border: 2px solid var(--sheet);
  cursor: grab;
}

.hotspot-marker:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.hotspot-peer {
  width: var(--space-8);
  height: var(--space-8);
  background: var(--ink);
  opacity: 0.4;
  pointer-events: none;
}

/* Diagnostics: what was checked, its state on the right. */

.check-list {
  display: grid;
  list-style: none;
}

.check-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--space-8) var(--gutter);
  padding: var(--space-12) var(--bleed);
}

.check-state {
  justify-self: end;
  white-space: nowrap;
}

.check-row:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.check-row.is-selected {
  background: var(--sheet);
}

.check-copy {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
}

.check-detail {
  color: var(--mute);
  font-size: var(--type-ui);
  overflow-wrap: anywhere;
}

.check-step {
  font-size: var(--type-ui);
  overflow-wrap: anywhere;
}

.check-step > b {
  font-weight: var(--weight-medium);
}

/* Passport: LABEL ........ value */

.spec,
.meta-list {
  display: grid;
}

/* An aside lists rows only when it has something to say: an empty one still holds a grid gap. */

.spec:empty,
.meta-list:empty {
  display: none;
}

.spec > div,
.meta-item {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-12);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
}

.spec > div:first-child,
.meta-list > .meta-item:first-child {
  border-top: 1px solid var(--rule);
}

.frame-aside .spec > div:first-child,
.frame-aside .meta-list > .meta-item:first-child {
  border-top: 0;
  padding-top: 0;
}

/* Two label-value lists in a row read as one list: the second does not draw its own top line. */

.stack > .meta-list + .entity-extension-slot:has(.meta-list) {
  margin-top: calc(-1 * var(--space-16));
}

.meta-list + .entity-extension-slot .meta-list > .meta-item:first-child {
  border-top: 0;
}

:is(.meta-list, :has(> .meta-list)) + :is(.meta-list, :has(> .meta-list)) .meta-item:first-child,
.meta-list + .meta-list > .meta-item:first-child {
  border-top: 0;
}

.spec dt,
.meta-item > span {
  flex: 0 1 auto;
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.spec dd,
.meta-item > div {
  min-width: 0;
  margin-left: auto;
  text-align: right;
  font-size: var(--type-ui);
  overflow-wrap: anywhere;
}

.meta-item strong {
  font-weight: var(--weight-regular);
}

.meta-item small {
  display: block;
  color: var(--mute);
}

.meta-item-stacked {
  display: grid;
  justify-content: stretch;
  gap: var(--space-8);
}

/* A linked record inside a row: its name and note on the left, its one action on the right. */

.meta-ref {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-12);
}

.meta-ref > span {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-4) var(--space-8);
  min-width: 0;
}

.meta-ref > .text-action {
  flex-shrink: 0;
  white-space: nowrap;
}

.meta-ref small {
  display: inline;
}

.submission-long {
  margin: 0;
  white-space: pre-line;
  max-width: 64ch;
}

.submission-contact {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.meta-item-stacked > div {
  margin-left: 0;
  text-align: left;
}

.meta-item > div > .marker + .marker {
  margin-left: var(--space-12);
}

/* Empty: text on the column's left edge and top inset, like any other content. No plate, nothing centred. */

.empty {
  display: grid;
  justify-items: start;
  align-content: start;
  gap: var(--space-12);
  min-height: 280px;
  padding: var(--space-24) var(--bleed);
  text-align: left;
}

/* Inside a section or a padded region the inset is already there: the empty text does not add a second one. */

:is(.form-section, .frame-board > :not(.is-flush), .dialog, .ui-disclosure-content) .empty {
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

/* Inside a section, a dialog or a disclosure the empty state is a sentence and a quiet note, never a second heading. */

:is(.dialog, .ui-disclosure-content) .empty,
.form-section .empty {
  gap: var(--space-4);
}

:is(.dialog, .ui-disclosure-content) .empty h2,
.form-section .empty h2 {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
  letter-spacing: normal;
  line-height: var(--leading-body);
}

:is(.dialog, .ui-disclosure-content) .empty p,
.form-section .empty p {
  font-size: var(--type-ui);
}

.empty h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
}

.empty p {
  max-width: 44ch;
  color: var(--mute);
}

.empty-action {
  margin-top: var(--space-8);
}

.empty.compact {
  justify-items: start;
  min-height: 0;
  padding: var(--space-20);
  background: transparent;
  border: 1px dashed var(--line);
  text-align: left;
}

/* An empty history is a line of text in its column, not a slab. */

.empty.history-empty {
  justify-items: start;
  gap: var(--space-4);
  min-height: 0;
  padding: var(--space-12) 0;
  background: transparent;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  text-align: left;
}

.empty.history-empty h2 {
  color: var(--mute);
  font-size: var(--type-ui);
  letter-spacing: 0;
}

.frame-board > .empty,
.frame-board > * > .empty:only-child {
  border-radius: 0;
}

/* State: loading, error, warning, success */

.state-presentation {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-16) var(--bleed);
  border: 1px solid var(--line);
}

.state-presentation-copy {
  display: grid;
  gap: var(--space-4);
}

.state-presentation strong {
  font-weight: var(--weight-regular);
}

.state-presentation small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.state-presentation.error {
  border-color: var(--status-bad);
}

.state-presentation.error strong {
  color: var(--status-bad);
}

.state-presentation.warning strong::before,
.state-presentation.success strong::before {
  content: '';
  display: inline-block;
  width: var(--marker);
  height: var(--marker);
  margin-right: var(--space-8);
  background: var(--mk);
}

.state-presentation.warning {
  --mk: var(--status-warn);
}

.state-presentation.success {
  --mk: var(--status-ok);
}

.state-presentation.inline {
  border: 0;
  padding: 0;
}

.loading-state,
.page-loading {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  padding-inline: var(--bleed);
}

.local-led-loader {
  position: relative;
  display: inline-block;
  width: 32px;
  height: 1px;
  overflow: hidden;
  background: var(--line);
}

.local-led-loader i {
  position: absolute;
  inset: 0;
  width: 40%;
  background: var(--signal);
  animation: travel var(--motion-loop) linear infinite;
}

.operation-pending {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  font-size: var(--type-ui);
  color: var(--mute);
}

/* Usage, history */

.usage-list {
  display: grid;
}

.aside-section {
  display: grid;
  gap: var(--space-8);
}

.aside-section > .label,
.aside-stack > .label {
  color: var(--mute);
}

.form-stack {
  display: grid;
  gap: var(--space-24);
}

/* A value that cannot change here still reads as a field: same height, a dashed line says it is fixed. */

.control-static {
  display: flex;
  align-items: center;
  min-height: var(--field-h);
  margin: 0;
  border-bottom: 1px dashed var(--field-line);
  color: var(--ink-2);
  font-size: var(--type-body);
}

.usage-item {
  display: flex;
  justify-content: space-between;
  gap: var(--space-12);
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--line);
  font-size: var(--type-ui);
}

.usage-item-link:hover {
  background: var(--raised);
}

.usage-item__copy {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
  text-align: start;
}

.usage-item__copy small {
  color: var(--mute);
  font-size: var(--type-micro);
}

.select-option:disabled {
  color: var(--mute);
  cursor: default;
}

.select-option:has(.select-option-hint) {
  flex-wrap: wrap;
  row-gap: var(--space-2);
}

.select-option-hint {
  flex-basis: 100%;
  order: 2;
  color: var(--mute);
  font-size: var(--type-micro);
}

.select-option:disabled:hover {
  background: transparent;
}

.history-timeline {
  display: grid;
  border-top: 1px solid var(--line);
}

/* A version row: rail with its number, the name and its state, then who and when at the far end. */

.history-timeline > * {
  position: relative;
  display: grid;
  grid-template-columns: var(--space-64) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-12);
  padding-block: var(--space-12);
  transition: background-color var(--dur-state) var(--ease-state);
}

.history-timeline > :has(.history-timeline-marker.plain) {
  grid-template-columns: minmax(0, 1fr);
}

.history-timeline > :has(.history-timeline-marker.plain) > .history-timeline-rail {
  display: none;
}

.history-timeline-rail {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  color: var(--mute);
}

.history-timeline-copy {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  font-size: var(--type-ui);
}

.history-timeline-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8) var(--space-16);
  min-width: 0;
}

.history-timeline-copy > small,
.history-timeline-copy > p {
  color: var(--mute);
}

@media (min-width: 761px) {
  .history-timeline-copy {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: var(--gutter);
  }

  .history-timeline-copy > small {
    font-family: var(--font-mono);
    font-size: var(--type-label);
    letter-spacing: var(--tracking-label);
    text-align: right;
    white-space: nowrap;
  }

  .history-timeline-copy > p {
    grid-column: 1 / -1;
  }
}

.history-timeline-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-size: var(--type-body);
  text-align: left;
}

.history-timeline-title::after {
  content: '';
  position: absolute;
  inset: 0;
}

.history-timeline > :has(.history-timeline-title):hover {
  background: var(--raised);
}

.history-timeline-title:focus-visible {
  outline: 0;
}

.history-timeline > :has(.history-timeline-title:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.history-timeline-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
}

/* Row lists in a board, one rule for all of them: the row owns the column edges and carries the bleed inset,
   the first row starts on the column's top edge. Same as the page editor's block list and the section rail. */

.frame-board :is(.form-section, .frame-board > :not(.is-flush)) :is(.schema-list, .usage-list, .history-timeline) {
  margin-inline: calc(-1 * var(--bleed));
  border-top: 0;
}

.frame-board :is(.schema-row, .usage-item, .history-timeline > *) {
  padding-inline: var(--bleed);
}

/* A list closes with its own line; in a flush region its last line lies on the board edge instead of doubling it. */

.frame-board > .is-flush > :is(.check-list, .schema-list, .usage-list, .history-timeline) {
  margin-bottom: -1px;
}

.frame-board :is(.form-section, .frame-board > :not(.is-flush)) > .table-wrap {
  width: auto;
  margin-inline: calc(-1 * var(--bleed));
}

.frame-board > :not(.is-flush) > :is(.schema-list, .usage-list, .history-timeline, .table-wrap):first-child {
  margin-top: calc(-1 * var(--space-24));
}

.frame-board .form-section > :is(.schema-list, .usage-list, .history-timeline, .table-wrap):first-child {
  margin-top: calc(-1 * var(--space-24));
}

/* A list with no rows yet: its sentence takes the inset a row would have. */

.frame-board :is(.schema-list, .usage-list, .history-timeline) > .empty:only-child {
  padding: var(--space-24) var(--bleed) 0;
}

@media (min-width: 1201px) {
  .frame-board:not(.has-secondary)
    .form-section
    > :is(h2, .section-title)
    + :is(.schema-list, .usage-list, .history-timeline, .table-wrap) {
    margin-top: calc(-1 * var(--space-24));
  }

  /* Beside a rail, a section that kept only its actions shows them under its list, as the page editor adds a block. */

  .frame-board.has-secondary .form-section > .section-title:not(:has(h2)) {
    order: 1;
  }

  .frame-board.has-secondary
    .form-section
    > .section-title:not(:has(h2))
    + :is(.schema-list, .usage-list, .history-timeline, .table-wrap) {
    margin-top: calc(-1 * var(--space-24));
  }
}

/* Metrics */

.metric-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

@media (min-width: 961px) {
  .metric-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.metric-card {
  display: grid;
  gap: var(--space-12);
  align-content: space-between;
  min-height: calc(2 * var(--row-h));
  padding: var(--space-20) var(--bleed);
  background: var(--canvas);
}

.metric-card__top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-8);
}

.metric-card__value {
  font-size: var(--type-display);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  font-variant-numeric: tabular-nums;
}

.metric-card__eyebrow {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.metric-card h3 {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

.metric-card strong,
.metric-card .figure {
  font-size: var(--type-display);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

/* Multi value chips, tags */

.multi-value-field {
  display: grid;
  gap: var(--space-4);
}

.multi-value-items {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-6);
  min-height: var(--field-h);
  padding-block: var(--space-6);
}

.multi-value-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 28px;
  padding-left: var(--space-8);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  font-size: var(--type-ui);
}

.multi-value-chip-meta {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
}

.multi-value-chip > .multi-value-chip-remove {
  display: grid;
  place-items: center;
  align-self: center;
  width: var(--control-h-xs);
  height: var(--control-h-xs);
  border-radius: var(--radius-control);
  color: var(--mute);
}

.multi-value-chip > .multi-value-chip-remove:hover {
  color: var(--ink);
  background: var(--hover);
}

.multi-value-add {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: var(--space-6);
  min-height: var(--control-h-sm);
  color: var(--ink);
  font-size: var(--type-ui);
}

.multi-value-control > .multi-value-items:empty {
  display: none;
}

.multi-value-add > span {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* Entity selection */

.entity-selection {
  display: grid;
  gap: var(--space-8);
}

.entity-selection-list {
  display: grid;
  border-top: 1px solid var(--line);
}

.entity-selection-item {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
}

.entity-selection-item-copy {
  display: grid;
  flex: 1;
  min-width: 0;
}

.entity-selection-single-control {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  border-bottom: 1px solid var(--field-line);
  min-height: var(--field-h);
}

.entity-picker-results {
  display: grid;
  border-top: 1px solid var(--line);
}

.entity-picker-results > * {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  padding: var(--space-12) var(--space-12);
  border-bottom: 1px solid var(--line);
}

.entity-picker-results > *:hover {
  background: var(--raised);
}

.entity-picker-thumb {
  width: 40px;
  height: 40px;
  background: var(--raised);
  object-fit: cover;
  flex: none;
}

/* Breadcrumbs, relation */

.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  color: var(--mute);
  font-size: var(--type-ui);
}

.breadcrumbs a:hover {
  color: var(--ink);
}

.relation-action {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-12);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
}

.relation-action__copy {
  display: grid;
  gap: var(--space-4);
}

.relation-action__copy > span {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
}

.relation-action__copy strong {
  font-weight: var(--weight-regular);
}

.relation-action__actions {
  display: flex;
  gap: var(--space-8);
}

/* == 08 Surfaces ======== */

.overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  place-items: center;
  padding: var(--space-16);
  background: var(--scrim);
  animation: overlay-in var(--dur-state) var(--ease-state);
}

.overlay.is-closing {
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.dialog {
  display: grid;

  /* Rows are pinned (header, nav, body, footer): the body owns the shrinking row. */
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  width: 100%;
  max-width: var(--dialog-m);
  max-height: calc(100dvh - 2 * var(--space-16));
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--sheet);
  color: var(--ink);
  box-shadow: var(--elevation-float);
  animation: dialog-in var(--dur-move) var(--ease-out);
}

.dialog-confirm,
.dialog-temporal {
  max-width: var(--dialog-s);
}

.dialog.wide,
.dialog-picker,
.dialog-workspace {
  max-width: var(--dialog-l);
}

/* A workspace editor switches tabs in place: it keeps the full height, so its header and footer never jump. */

.dialog-workspace {
  height: calc(100dvh - 2 * var(--space-16));
}

.drawer-overlay {
  place-items: stretch end;
  padding: 0;
}

.dialog.drawer {
  height: 100dvh;
  max-height: none;
  max-width: var(--dialog-m);
  border-radius: 0;
  border-width: 0 0 0 1px;
  animation: drawer-in var(--dur-move) var(--ease-spatial);
}

.dialog-header {
  grid-row: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-16) var(--space-12) var(--space-12) var(--space-20);
}

.dialog-header h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
  overflow-wrap: anywhere;
}

.dialog-navigation {
  grid-row: 2;
  padding: 0 var(--space-20) var(--space-12);
}

.dialog-body {
  grid-row: 3;
  display: grid;
  gap: var(--space-20);
  align-content: start;
  min-height: 0;
  padding: var(--space-4) var(--space-20) var(--space-24);
  overflow: auto;
}

.dialog-body > p {
  max-width: 60ch;
}

.dialog-footer {
  grid-row: 4;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--footer-h);
  padding: var(--space-12) var(--space-20);
  border-top: 1px solid var(--line);
}

.dialog-footer-primary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  margin-left: auto;
}

/* The overflow menu beside Cancel and Save is a full-height square on the same centre line, no resting fill. */

.dialog-footer .action-menu > summary.icon-button {
  width: var(--control-h);
  height: var(--control-h);
  background: transparent;
}

.dialog-footer .action-menu > summary.icon-button:hover,
.dialog-footer .action-menu[open] > summary.icon-button {
  background: var(--hover);
}

.dialog-footer-extra {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-right: auto;
  color: var(--mute);
}

@keyframes overlay-in {
  from {
    opacity: 0;
  }
}

@keyframes dialog-in {
  from {
    opacity: 0;
    scale: 0.98;
  }
}

@keyframes drawer-in {
  from {
    translate: 100% 0;
  }
}

#overlays:empty {
  display: none;
}

#toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--dock-safe-area) + var(--space-8));
  z-index: var(--z-toast);
  display: flex;
  align-items: center;
  gap: var(--space-12);
  max-width: min(480px, calc(100vw - 2 * var(--margin)));
  padding: var(--space-12) var(--space-12) var(--space-12) var(--space-16);
  border-radius: var(--radius-tile);
  background: var(--ink);
  color: var(--on-ink);
  box-shadow: var(--elevation-float);
  font-size: var(--type-ui);
  opacity: 0;
  translate: -50% var(--space-8);
  pointer-events: none;
  transition:
    opacity var(--dur-state) var(--ease-state),
    translate var(--dur-move) var(--ease-out);
}

/* The publication tick is drawn like the wordmark: one stroke, written once. */

.toast-flourish {
  flex: none;
  width: var(--space-20);
  height: var(--space-20);
  color: var(--status-ok);
}

.toast-flourish path {
  fill: none;
  stroke: currentcolor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: toast-flourish-write var(--dur-pen-tick) var(--ease-pen) var(--delay-pen) forwards;
}

@keyframes toast-flourish-write {
  to {
    stroke-dashoffset: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .toast-flourish path {
    animation: none;
    stroke-dashoffset: 0;
  }
}

#toast.show {
  opacity: 1;
  translate: -50% 0;
  pointer-events: auto;
}

#toast [data-toast-action] {
  flex: none;
  padding-inline: var(--space-8);
  color: var(--on-ink);
  font-weight: var(--weight-medium);
  text-decoration: underline;
  text-underline-offset: 3px;
}

#toast[data-tone='error'] [data-toast-message]::before,
#toast[data-tone='success'] [data-toast-message]::before {
  content: '';
  display: inline-block;
  width: var(--marker);
  height: var(--marker);
  margin-right: var(--space-8);
  background: var(--status-bad);
}

#toast[data-tone='success'] [data-toast-message]::before {
  background: var(--status-ok);
}

#toast:has(> .toast-flourish) [data-toast-message]::before {
  content: none;
}

#toast [data-toast-close] {
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  color: var(--on-ink-mute);
}

#toast [data-toast-close]::before {
  content: '\00d7';
  font-size: var(--type-title);
}

.context-help-surface {
  position: fixed;
  z-index: var(--z-tooltip);
  padding: var(--space-6) var(--space-8);
  border-radius: var(--radius-control);
  background: var(--ink);
  color: var(--on-ink);
  font-size: var(--type-ui);
  line-height: var(--leading-tight);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.context-help-surface[data-shown='1'] {
  opacity: 1;
}

.context-help-surface[data-instant='1'] {
  transition: none;
}

.context-help-surface[data-kind='explain'] {
  max-width: 320px;
  padding: var(--space-12);
  background: var(--sheet);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--elevation-float);
  pointer-events: auto;
}

.ui-disclosure {
  border-bottom: 1px solid var(--line);
}

.ui-disclosure > summary {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  list-style: none;
  cursor: pointer;
}

.ui-disclosure > summary::-webkit-details-marker {
  display: none;
}

.ui-disclosure-title {
  flex: 1;
}

.ui-disclosure-meta {
  color: var(--mute);
  font-size: var(--type-ui);
}

.ui-disclosure > summary .icon {
  rotate: 90deg;
  transition: rotate var(--dur-move) var(--ease-out);
}

.ui-disclosure[open] > summary .icon {
  rotate: -90deg;
}

.ui-disclosure-content {
  display: grid;
  gap: var(--space-16);
  padding-bottom: var(--space-20);
}

/* A disclosure with an action is one row; the action centres on the summary's line. */

.ui-disclosure-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-16);
  align-items: start;
  border-bottom: 1px solid var(--line);
}

.ui-disclosure-row > details {
  border-bottom: 0;
}

.ui-disclosure-row > .ui-disclosure-action {
  display: flex;
  align-items: center;
  min-height: var(--row-h);
}

.block-number {
  flex: none;
  min-width: 2ch;
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
}

/* Page blocks: one row per block, the whole row opens it. */

.page-builder,
.page-builder-slot,
.page-builder-slot-content {
  display: grid;
  gap: var(--space-16);
}

.page-builder-slot h3 {
  font-size: var(--type-ui);
  font-weight: var(--weight-regular);
  color: var(--mute);
}

.page-builder-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-height: var(--row-h);
  border-bottom: 1px solid var(--line);
}

[data-canonical-sort-list] > .page-builder-row:first-child,
[data-page-block-list] > .page-builder-row:first-child {
  border-top: 1px solid var(--line);
}

.page-builder-row:not(:has(.page-builder-row-open:disabled)):hover {
  background: var(--raised);
}

.page-builder-row:has(.page-builder-row-open:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.page-builder-row-open {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  min-width: 0;
  padding-block: var(--space-12);
  border-radius: 0;
  text-align: left;
}

.page-builder-row-open:focus-visible {
  outline: none;
}

.page-builder-row-open > span,
.page-builder-row > .block-main > span {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.page-builder-row strong {
  font-weight: var(--weight-regular);
  overflow-wrap: anywhere;
}

.page-builder-row small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.page-builder-row:hover .page-builder-row-open strong {
  color: var(--ink);
}

.page-builder-row[data-visible='false'] strong {
  color: var(--mute);
}

/* Block rows run to the column dividers; content keeps the inset. */

#page-editor .page-builder-row {
  margin-inline: calc(var(--bleed) * -1);
  padding-inline: var(--bleed);
}

/* A panel that opens with a row list (blocks, versions) starts on the column edge, like flush lists on every other screen. */

/* Search and an empty list keep the usual column inset. */

.frame-board
  > .frame-primary:has(> #page-editor > [data-page-panel]:not([hidden]) :is(.page-builder-row, .history-timeline)) {
  padding-block-start: 0;
}

/* The composition column fills the frame: the list takes the free height and the «Додати блок»
   strip closes the column at its bottom edge instead of hanging above empty space. */

.frame-board > .frame-primary:has(> #page-editor > [data-page-panel='composition']:not([hidden])) {
  display: grid;
  grid-template-rows: minmax(0, 1fr);
}

.frame-board > .frame-primary:has(> #page-editor > [data-page-panel='composition']:not([hidden])) > #page-editor {
  display: grid;
  min-height: 0;
}

#page-editor > [data-page-panel='composition']:not([hidden]) {
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
}

#page-editor > [data-page-panel='composition']:not([hidden]) > .page-builder {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  min-height: 0;
}

#page-editor .page-builder-slot {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  min-height: 0;
}

#page-editor .page-builder-slot:last-child {
  flex: 1 1 auto;
}

#page-editor .page-builder-slot-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  flex: 1 1 auto;
  min-height: 0;
}

/* The add action follows the last block. */

#page-editor .page-builder-slot-content > :first-child {
  min-height: 0;
}

#page-editor .page-builder-row:first-child {
  border-top: 0;
}

.page-builder-row.invalid {
  background: var(--bad-soft);
}

.section-list {
  display: grid;
}

.section-list > .page-builder-row:first-child {
  border-top: 1px solid var(--line);
}

.block-error {
  color: var(--status-bad);
  font-size: var(--type-ui);
}

.list-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

/* Keeps the field rhythm under a field. */

.list-actions-after-field {
  margin-block-start: var(--space-16);
}

.alert,
.notice,
.error-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
  padding: var(--space-12) var(--bleed);
  border: 1px solid var(--line);
  font-size: var(--type-ui);
}

.alert::before,
.notice::before,
.error-alert::before {
  content: '';
  width: var(--marker);
  height: var(--marker);
  margin-top: var(--space-6);
  flex: none;
  border-radius: 50%;
  background: var(--mk, var(--status-info));
}

.alert.error,
.error-alert,
.alert.danger {
  --mk: var(--status-bad);

  border-color: var(--status-bad);
}

.alert.warning {
  --mk: var(--status-warn);
}

.alert.success {
  --mk: var(--status-ok);
}

/* Command centre: plain lines — a name, a dot where something waits, a quiet context. */

.search-dialog,
#global-results,
[data-search-home] {
  display: grid;
  gap: var(--space-24);
}

.dialog[data-dialog-variant='command'] .search-field input {
  min-height: var(--space-48);
  font-size: var(--type-title);
  font-weight: var(--weight-light);
}

.search-group {
  display: grid;
  align-content: start;
}

.search-group > h3 {
  margin-bottom: var(--space-4);
  padding-inline: var(--space-8);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.search-line {
  display: grid;
  justify-items: start;
  max-width: 100%;
  padding: var(--space-8);
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--type-body);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-state) var(--ease-state);
}

.search-line small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.search-query-hint {
  padding-inline: var(--space-8);
  color: var(--mute);
  font-size: var(--type-ui);
}

/* Notifications */

.notification-center {
  display: grid;
}

.notification-center-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: var(--space-12);
  border-bottom: 1px solid var(--rule);
}

.notification-center-head > div {
  display: grid;
  gap: var(--space-2);
}

.notification-center-head span {
  color: var(--mute);
  font-size: var(--type-ui);
}

.notification-list {
  display: grid;
}

.notification-list > * {
  display: flex;
  gap: var(--space-12);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
}

.notification-center-actions {
  display: flex;
  gap: var(--space-8);
}

/* A notice and its «Прибрати»: the cross shows on hover or focus, and always where there is no hover. */

.notification-row {
  align-items: flex-start;
}

.notification-row > .icon-button {
  flex: none;
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.notification-row:is(:hover, :focus-within) > .icon-button {
  opacity: 1;
}

@media (hover: none) {
  .notification-row > .icon-button {
    opacity: 1;
  }
}

.notification-copy {
  display: grid;
  gap: var(--space-4);
  flex: 1;
  min-width: 0;
}

.notification-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
}

.notification-copy p {
  margin: 0;
  color: var(--mute);
}

/* Design system reference: one column of sections, each a board row. */

.ds-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.ds-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  padding: var(--space-24) var(--bleed) var(--space-40);
  border-top: 1px solid var(--line);
}

.ds-section:first-child {
  border-top: 0;
}

@media (min-width: 961px) {
  .ds-section {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
  }

  .ds-section-head {
    grid-column: 1 / 4;
  }

  .ds-section-body {
    grid-column: 4 / -1;
  }
}

.ds-section-head {
  display: grid;
  align-content: start;
  gap: var(--space-8);
  scroll-margin-top: var(--space-40);
}

.ds-title {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
  letter-spacing: var(--tracking-title);
}

.ds-section-body {
  display: grid;
  gap: var(--space-24);
  min-width: 0;
}

.ds-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
}

.ds-toc ol {
  display: grid;
  list-style: none;
}

.ds-toc a {
  display: flex;
  align-items: center;
  min-height: var(--control-h);
  border-bottom: 1px solid var(--line);
  color: var(--mute);
}

.ds-toc a:hover {
  color: var(--ink);
}

.ds-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
  gap: var(--space-16) var(--gutter);
}

.ds-swatch {
  display: grid;
  gap: var(--space-8);
}

.ds-swatch-chip {
  height: var(--row-h);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
}

.ds-swatch-copy {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.ds-swatch-copy small {
  color: var(--mute);
  font-size: var(--type-label);
  overflow-wrap: anywhere;
}

.ds-type {
  display: grid;
}

.ds-type-row {
  display: grid;
  gap: var(--space-8);
  padding-block: var(--space-16);
  border-bottom: 1px solid var(--line);
}

.ds-type-display {
  font-size: var(--type-display);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

.ds-type-title {
  font-size: var(--type-title);
  letter-spacing: var(--tracking-title);
}

.ds-type-ui {
  font-size: var(--type-ui);
}

.ds-columns {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  height: var(--row-h);
}

.ds-columns span {
  background: var(--well);
}

.ds-counted {
  display: grid;
  gap: var(--space-4);
}

.ds-counter {
  justify-self: end;
  color: var(--mute);
  font-size: var(--type-label);
}

.ds-icons {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 112px), 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

.icon-sample {
  display: grid;
  justify-items: center;
  gap: var(--space-8);
  padding: var(--space-16) var(--space-8);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.icon-sample small {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  overflow-wrap: anywhere;
  text-align: center;
}

#admin-design-page .ds-editor-main-preview {
  padding: 0;
  border: 1px solid var(--line);
}

#admin-design-page .ds-editor-preview-block {
  padding: var(--space-24);
}

/* Entity picker rows drawn by ui.js; the result list owns the row geometry. */

.entity-picker-row {
  cursor: pointer;
}

.entity-picker-row.selected {
  background: var(--sheet);
}

.entity-picker-row:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.entity-picker-thumb.placeholder {
  display: grid;
  place-items: center;
  color: var(--mute);
}

.entity-picker-copy {
  display: grid;
  flex: 1;
  gap: var(--space-2);
  min-width: 0;
}

.entity-picker-copy small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.entity-picker-titleline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

.entity-picker-titleline strong {
  font-weight: var(--weight-regular);
}

.entity-picker-check-control {
  flex: none;
  min-height: 0;
  pointer-events: none;
}

.dialog-footer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

/* Each notification is a button, so it must opt out of the button's centred text. */

.notification {
  display: flex;
  gap: var(--space-12);
  width: 100%;
  text-align: start;
}

/* Submission record: attachments, delivery log, internal notes. */

.submission-attachments {
  display: grid;
  gap: var(--space-8);
}

.submission-attachment {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-8) var(--space-12);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  color: inherit;
  text-decoration: none;
}

.submission-attachment:hover {
  background: var(--raised);
}

.submission-attachment > span:nth-child(2) {
  display: grid;
  flex: 1;
  min-width: 0;
}

.submission-attachment small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.submission-attachment-action {
  color: var(--mute);
  font-size: var(--type-ui);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.submission-delivery,
.submission-notes {
  display: grid;
  gap: var(--space-12);
}

.submission-note-list {
  display: grid;
}

.submission-note {
  display: grid;
  gap: var(--space-4);
  padding-block: var(--space-12);
  border-bottom: 1px solid var(--line);
  white-space: pre-wrap;
}

.submission-note small {
  color: var(--mute);
  font-size: var(--type-ui);
  white-space: normal;
}

.submission-note-form {
  display: grid;
  gap: var(--space-8);
}

/* LIVE EDITING START */

/* Live editing: the overlay live-content.js mounts over the public site in a shadow root.
   The host ignores the pointer; only the dock and open overlays take it back.
   live-content.js hides the host until this sheet arrives; this rule is what reveals it. */

:host(.live-root) {
  visibility: visible;

  /* The host sits under <html>, not <body>: the admin base rule on `html` never reaches
     the shadow tree, so the chrome would inherit the browser default serif. */
  font-family: var(--font-ui);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

.live-dock-wrap {
  pointer-events: auto;
  transition:
    opacity var(--dur-state) var(--ease-state),
    translate var(--dur-state) var(--ease-state);
}

.dock.live-dock {
  --on-ink: var(--ink);
  --on-ink-mute: var(--ink-2);
  --on-ink-hover-soft: var(--hover);
  --on-ink-line: var(--line);

  background: var(--sheet);
}

/* An open dialog owns the screen: the Dock sinks out of the way instead of covering its footer. */

.live-dock-wrap.is-workspace-suppressed {
  opacity: 0;
  translate: 0 var(--space-16);
  pointer-events: none;
}

.live-overlays > * {
  pointer-events: auto;
}

.live-overlays {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

/* Section list field: items stack as bordered groups; order controls sit on the item head. */

.live-list {
  display: grid;
  gap: var(--space-8);
}

.live-list-items {
  display: grid;
  gap: var(--space-12);
  margin: 0;
  padding: 0;
  list-style: none;
}

.live-list-item {
  display: grid;
  gap: var(--space-8);
  padding: var(--space-12);
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
}

.live-list-item-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}

.live-list-item-actions {
  display: inline-flex;
  gap: var(--space-4);
}

.live-list > [data-list-add] {
  justify-self: start;
}

.live-veil > i {
  position: fixed;
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

:host(.selection-visible) .live-veil > i {
  opacity: 1;
}

.live-outline {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.live-outline:not([data-mode]),
.live-outline[data-mode=''] {
  display: none;
}

.live-edge,
.live-fill {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  transform-origin: 0 0;
}

.live-edge {
  background: var(--signal);
}

.live-edge[data-edge='top'],
.live-edge[data-edge='bottom'] {
  height: 2px;
}

.live-edge[data-edge='left'],
.live-edge[data-edge='right'] {
  width: 2px;
}

.live-outline[data-mode='hover'] .live-edge {
  opacity: 0.5;
}

.live-fill {
  background: var(--signal-wash);
}

.live-outline[data-mode='hover'] .live-fill {
  opacity: 0;
}

.live-outline.is-gliding .live-edge,
.live-outline.is-gliding .live-fill {
  transition: transform var(--dur-state) var(--ease-spatial);
}

.live-caption {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  max-width: var(--aside-w);
  padding: 0 var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.live-caption[hidden] {
  display: none;
}

.live-caption-dot {
  width: var(--marker);
  height: var(--marker);
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--signal);
}

.live-caption-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Language keys are dock items; the active one is filled. */

.live-locale-switcher {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.live-locale-switcher button {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
}

.live-locale-switcher button[aria-pressed='true'] {
  background: var(--on-ink-hover-soft);
  color: var(--on-ink);
}

.live-dock [data-publish].has-pending {
  position: relative;
}

.live-dock [data-publish].has-pending::after {
  content: '';
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-pill);
  background: var(--signal);
}

@media (prefers-reduced-motion: reduce) {
  .live-veil > i,
  .live-outline.is-gliding .live-edge,
  .live-outline.is-gliding .live-fill {
    transition: none;
  }
}

.live-caption-field {
  color: var(--mute);
}

/* LIVE EDITING END */

/* == 09 Media ======== */

.media-asset-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-16);
}

@media (min-width: 761px) {
  .media-asset-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.media-asset-grid > .empty {
  grid-column: 1 / -1;
  background: var(--canvas);
}

.media-asset-grid.admin-matrix-grid {
  gap: 0;
}

/* In a dialog the cells sit on the sheet; only hover and selection change their fill. */

.dialog .admin-matrix-grid > .admin-matrix-cell:not(:hover) {
  background: transparent;
}

@media (min-width: 1201px) {
  [data-topology='workspace'] .media-asset-grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* The library grid is part of the board: no inset, tiles meet the frame, seams run the full length. */

.frame-board > .frame-primary:has(> .media-browser) {
  padding: 0;
  overflow: hidden;
}

.frame-board > .frame-primary > .media-browser > .media-asset-grid {
  gap: 0;
  margin: 0 -1px -1px 0;
}

.frame-board > .frame-primary > .media-browser > .media-asset-grid > .empty {
  margin: 0 1px 1px 0;
  padding: var(--space-24) var(--bleed);
}

.frame-board > .frame-primary:has(> .media-browser) > .alert {
  margin: var(--space-16) var(--bleed);
}

.media-asset-caption {
  flex-wrap: wrap;
}

.media-asset-caption > .media-asset-usage {
  display: block;
  flex-basis: 100%;
  color: var(--mute);
}

/* File panel: the picture leads on the left, its description and facts read down the right. */

.media-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
}

.media-panel-visual {
  display: grid;
  place-items: center;
  min-height: var(--portrait);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  background: var(--canvas);
}

.media-panel-visual img {
  display: block;
  width: 100%;
  height: 100%;
  max-height: 60dvh;
  object-fit: contain;
}

.media-panel-body {
  display: grid;
  align-content: start;
  gap: var(--space-24);
  min-width: 0;
}

.media-panel-locale:empty {
  display: none;
}

.media-panel-usage > h3 {
  color: var(--mute);
}

.media-panel-locale {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 761px) {
  .media-panel {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: start;
  }

  .media-panel-visual {
    position: sticky;
    top: 0;
  }
}

.media-tile,
.media-card,
.photo-card {
  position: relative;
  display: grid;
  gap: var(--space-8);
  min-width: 0;
  text-align: left;
}

.media-tile-visual,
.photo-card-visual,
.media-control-preview {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--well);
}

.media-tile-visual img,
.photo-card-visual img,
.media-control-preview img,
.media-gallery-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.media-file-icon .icon,
.media-placeholder .icon {
  width: 28px;
  height: 28px;
  stroke-width: 1;
  color: var(--mute);
}

.media-tile-copy,
.photo-card-caption,
.media-asset-caption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-8);
  min-width: 0;
  font-size: var(--type-ui);
}

.media-tile-copy small,
.media-asset-meta {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  white-space: nowrap;
}

.media-tile[aria-selected='true'] .media-tile-visual,
.media-tile.is-selected .media-tile-visual,
.media-tile:has(input:checked) .media-tile-visual {
  outline: 1px solid var(--signal);
  outline-offset: 3px;
}

.media-tile:hover .media-tile-visual {
  outline: 1px solid var(--line);
  outline-offset: 3px;
}

.media-tile .order {
  position: absolute;
  top: var(--space-8);
  left: var(--space-8);
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding-inline: var(--space-4);
  background: var(--signal-text);
  color: var(--on-signal);
  font-family: var(--font-mono);
  font-size: var(--type-label);
}

.media-placeholder {
  display: flex;
  align-items: center;
  gap: var(--space-12);
}

.media-placeholder strong {
  font-weight: var(--weight-regular);
}

.media-placeholder small {
  display: block;
  color: var(--mute);
  font-size: var(--type-ui);
}

/* Media field: label, then one row: a square preview and what is there; hover darkens the preview only. */

.media-field {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
  padding-bottom: var(--space-12);
  border-bottom: 1px solid var(--field-line);
}

.media-control-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-12);
  min-width: 0;
}

.media-control-preview.media-tile {
  grid-template-columns: var(--space-64) minmax(0, 1fr);
  place-items: center start;
  gap: var(--space-16);
  width: 100%;
  aspect-ratio: auto;
  overflow: visible;
  background: transparent;
  cursor: pointer;
}

.media-control-preview.media-tile > .media-tile-visual {
  width: 100%;
  aspect-ratio: 1;
  outline: 0;
  transition: background-color var(--dur-state) var(--ease-state);
}

.media-control-preview .media-tile-visual img {
  object-fit: contain;
}

.media-control-preview .media-tile-copy {
  display: grid;
  gap: var(--space-2);
}

.media-control-preview .media-tile-copy :is(strong, small) {
  white-space: normal;
  overflow: visible;
  overflow-wrap: anywhere;
}

.media-control-preview .media-tile-copy strong {
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

.media-control-preview .media-tile-copy small {
  font-family: var(--font-ui);
  font-size: var(--type-ui);
  letter-spacing: normal;
  text-transform: none;
}

.media-control-preview.media-tile:hover > .media-tile-visual {
  background: var(--hover);
}

/* In a settings cell the cell seam closes the field, so it draws no underline of its own. */

.settings-media-item .media-field {
  padding-bottom: 0;
  border-bottom: 0;
}

/* Picked file: the remove control sits beside the preview, not under it. */

.media-control-shell:has(> .media-control-clear) {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
}

/* Cells in a row share lines, so previews align; the share image takes the rest of the last row. */

@media (min-width: 761px) {
  .branding-media-grid > .settings-media-item {
    grid-row: span 2;
    grid-template-rows: subgrid;
  }

  .branding-media-grid > .settings-media-item:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

@media (min-width: 1201px) {
  .branding-media-grid > .settings-media-item:last-child:nth-child(odd) {
    grid-column: auto;
  }

  .branding-media-grid > .settings-media-item:last-child:nth-child(4n + 1) {
    grid-column: 1 / -1;
  }

  .branding-media-grid > .settings-media-item:last-child:nth-child(4n + 2) {
    grid-column: span 3;
  }

  .branding-media-grid > .settings-media-item:last-child:nth-child(4n + 3) {
    grid-column: span 2;
  }
}

.media-field-card {
  display: grid;
  gap: var(--space-8);
  min-width: 0;
}

.media-control-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-16);
}

.media-field-avatar {
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--space-8);
  border-bottom: 0;
}

.media-field-avatar > .label {
  grid-column: 1 / -1;
}

.profile-avatar-control {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  max-width: var(--portrait-sm);
  aspect-ratio: 1;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-tile);
  overflow: hidden;
  background: var(--raised);
  cursor: pointer;
}

@media (min-width: 761px) {
  .profile-avatar-control {
    max-width: var(--portrait);
  }
}

.profile-avatar-image,
.profile-avatar-image img,
.profile-avatar-fallback {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.profile-avatar-initials {
  color: var(--mute);
  font-size: var(--type-display);
  font-weight: var(--weight-light);
  line-height: var(--leading-none);
  letter-spacing: var(--tracking-display);
}

.profile-avatar-silhouette {
  width: 40%;
  height: 40%;
  border-radius: 50% 50% 0 0;
  background: var(--field-line);
  translate: 0 30%;
}

.profile-avatar-edit {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--scrim);
  color: var(--on-tile-dark);
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.profile-avatar-control:hover .profile-avatar-edit,
.profile-avatar-control:focus-visible .profile-avatar-edit {
  opacity: 1;
}

.profile-avatar-control:disabled {
  cursor: not-allowed;
}

@media (min-width: 481px) {
  .dialog .media-gallery-selection {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 961px) {
  .dialog-workspace .media-gallery-selection {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Gallery cells are sized by their picture, not by the matrix minimum. */

.media-gallery-selection > .admin-matrix-cell {
  min-height: 0;
  grid-template-rows: none;
  align-content: start;
}

/* A photo cell in any matrix (library, picker, gallery) is the picture edge to edge, then one quiet footer. */

:is(.admin-matrix-grid, .media-asset-grid) > .photo-card {
  gap: 0;
  padding: 0;
  min-height: 0;
  grid-template-rows: none;
  align-content: start;
}

:is(.admin-matrix-grid, .media-asset-grid) > .photo-card > .photo-card-caption {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-8) var(--bleed) var(--space-12);
}

/* A caption shrinks with its tile: without a shrinkable track the nowrap title sets the track to
   its full width and paints over the next tile instead of ending with an ellipsis. */

:is(.admin-matrix-grid, .media-asset-grid) > .photo-card > .photo-card-caption > * {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.media-gallery-selection > .media-gallery-add {
  aspect-ratio: auto;
}

.media-field-multiple {
  border-bottom: 0;
}

.media-gallery-add {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  border: 1px dashed var(--field-line);
  color: var(--mute);
}

.media-gallery-add:hover {
  color: var(--ink);
  border-color: var(--ink);
}

/* Inside a matrix the add tile is one more cell: the seam is its edge, not a dashed box. */

.admin-matrix-grid > .media-gallery-add {
  grid-template-rows: none;
  place-content: center;
  border: 0;
  background: transparent;
}

.admin-matrix-grid > .media-gallery-add:hover {
  background: var(--raised);
}

.media-gallery-remove {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 1;
  color: var(--on-tile-dark);
  background: transparent;
}

/* The reorder handle sits opposite the remove control: on a pointer device it follows the tile's hover and
   focus, on touch it is always there, because touch reorders only from the handle. */

.media-gallery-grip {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  z-index: 1;
  color: var(--on-tile-dark);
  background: transparent;
  cursor: grab;
  opacity: 0;
  transition: opacity var(--dur-state) var(--ease-state);
}

.media-gallery-thumb:hover > .media-gallery-grip,
.media-gallery-thumb:focus-within > .media-gallery-grip,
.media-gallery-grip:focus-visible {
  opacity: 1;
}

.media-gallery-grip:active {
  cursor: grabbing;
}

/* A white cross and a white handle have no fill of their own, so the top of the picture is shaded:
   the same pair stays readable on a bright sky and on dark glass. */
.media-gallery-thumb .photo-card-visual::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 56px;
  background: linear-gradient(180deg, var(--scrim), transparent);
  pointer-events: none;
}

.media-gallery-thumb :is(.media-gallery-remove, .media-gallery-grip):is(:hover, :focus-visible) {
  background: var(--scrim);
}

@media (hover: none) {
  .media-gallery-grip {
    opacity: 1;
  }
}

/* A gallery is not a one-line input: in a two-column form it owns the whole row. */

.form-grid > .field.media-field-multiple {
  grid-column: 1 / -1;
}

.media-upload-dropzone,
.upload-surface {
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--space-8);
  min-height: 160px;
  padding: var(--space-16);
  border: 1px dashed var(--field-line);
  text-align: center;
  transition:
    background-color var(--dur-state) var(--ease-state),
    border-color var(--dur-state) var(--ease-state);
}

.media-upload-dropzone[data-dragging='1'] {
  background: var(--sheet);
  border-style: solid;
  border-color: var(--signal);
}

.upload-surface-copy,
.media-upload-dropzone-copy {
  display: grid;
  gap: var(--space-4);
}

.upload-surface-copy small,
.media-upload-dropzone-copy small {
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
}

.upload-queue,
.media-upload-queue {
  display: grid;
}

.upload-progress {
  position: relative;
  height: 2px;
  background: var(--track);
}

.upload-progress > i {
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-state) var(--ease-out);
}

.media-upload-item.processing .upload-progress > i {
  transform: scaleX(1);
  opacity: 0.4;
}

.media-upload-item.failed small {
  color: var(--status-bad);
}

/* A queued file: thumbnail, name and state, actions; the progress line runs under the whole row. */

.media-upload-item,
.upload-item {
  display: grid;
  grid-template-columns: var(--space-40) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-8) var(--space-12);
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--line);
}

.media-upload-item > .upload-progress,
.upload-item > .upload-progress {
  grid-column: 1 / -1;
}

.media-upload-item-preview {
  display: grid;
  place-items: center;
  width: var(--space-40);
  height: var(--space-40);
  overflow: hidden;
  border-radius: var(--radius-control);
  background: var(--well);
  color: var(--mute);
}

.media-upload-item-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.upload-item-copy {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.upload-item-copy strong {
  overflow: hidden;
  font-weight: var(--weight-regular);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.upload-item-copy small {
  color: var(--mute);
  font-size: var(--type-ui);
}

.media-upload-item.cancelled small {
  color: var(--mute);
}

.media-upload-item-actions {
  display: flex;
  gap: var(--space-4);
}

.media-upload-panel,
.media-picker-upload-panel {
  display: grid;
  gap: var(--space-16);
}

.media-upload-dropzone-icon {
  display: grid;
  color: var(--mute);
}

.media-upload-divider {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-12);
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
}

.media-upload-divider::before,
.media-upload-divider::after {
  content: '';
  height: 1px;
  background: var(--line);
}

.media-upload-url-control {
  display: flex;
  align-items: flex-end;
  gap: var(--space-8);
}

.media-upload-url-control > .control {
  flex: 1;
  min-width: 0;
}

.media-picker-pagination:empty {
  display: none;
}

.upload-progress > *,
.upload-progress::after {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--progress, 0%);
  background: var(--signal);
  content: '';
}

.media-picker-toolbar,
.folder-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
}

.media-picker-folders {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--space-4) var(--space-16);
}

/* Folders in the picker are tabs: the current one is underlined like any section switcher. */

.media-picker-folders .btn.folder-filter {
  position: relative;
}

.media-picker-folders .btn.folder-filter[aria-pressed='true']::after {
  content: '';
  position: absolute;
  inset: auto 0 var(--space-4);
  height: 1px;
  background: var(--ink);
}

.media-picker-shell {
  display: grid;
  gap: var(--space-16);
}

/* Search holds the left; the count and upload sit together at the right edge. On a phone the search takes its own row. */

.media-picker-shell > .media-picker-toolbar > :first-child {
  flex: 1 1 100%;
}

@media (min-width: 761px) {
  .media-picker-shell > .media-picker-toolbar > :first-child {
    flex: 0 1 auto;
    margin-right: auto;
  }
}

.media-asset-usage {
  display: grid;
  gap: var(--space-8);
}

/* A chosen card says so in words in the corner: «Вибрано», «Головне». */

.photo-card-badge {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  z-index: 1;
  height: var(--control-h-xs);
  padding: 0 var(--space-8);
  background: var(--sheet);
}

.photo-card:not(.selected) > .photo-card-badge[aria-hidden] {
  display: none;
}

/* Selection mode: every card shows its check in the picture's corner; a selected card fills it. */

[data-media-selection-mode='active'] .photo-card::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: var(--space-8);
  left: var(--space-8);
  width: var(--space-20);
  height: var(--space-20);
  border: 1px solid var(--on-tile-dark);
  background: var(--scrim);
  box-shadow: var(--elevation-float);
  transition:
    background-color var(--dur-state) var(--ease-state),
    scale var(--dur-state) var(--ease-out);
}

[data-media-selection-mode='active'] .photo-card.selected::before {
  border-color: var(--ink);
  background: var(--ink);
  scale: 1.1;
}

[data-media-selection-mode='active'] .photo-card.selected .photo-card-visual::after {
  content: '';
  position: absolute;
  z-index: 2;
  top: calc(var(--space-8) + var(--space-4));
  left: calc(var(--space-8) + var(--space-6) + 1px);
  width: var(--space-6);
  height: var(--space-12);
  border: solid var(--on-ink);
  border-width: 0 2px 2px 0;
  rotate: 45deg;
}

/* Folder column: text navigation, one folder at a time. */

.folder-list {
  display: grid;
  align-content: start;
  gap: var(--space-24);
}

.folder-list-items {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-24);
}

.btn.folder-filter {
  justify-content: flex-start;
  height: auto;
  min-height: var(--control-h);
  padding-inline: 0;
  border-color: transparent;
  color: var(--mute);
  text-align: left;
}

.btn.folder-filter:hover {
  background: none;
  color: var(--ink);
}

.btn.folder-filter.active,
.btn.folder-filter[aria-pressed='true'] {
  background: none;
  color: var(--ink);
}

.folder-list-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

/* Folders are a side rail: rows reach the column edges, text keeps the inset. */

@media (min-width: 961px) {
  .frame-board > :has(> .folder-list) {
    padding: 0;
  }

  .folder-list-items {
    display: grid;
    gap: 0;
  }

  .folder-list-items .btn.folder-filter {
    width: 100%;
    min-height: var(--row-h);
    padding-inline: var(--bleed);
    border-width: 0 0 1px;
    border-bottom-color: var(--line);
    border-radius: 0;
  }

  .folder-list-items .btn.folder-filter:hover {
    background: var(--raised);
  }

  .folder-list-items .btn.folder-filter[aria-pressed='true'] {
    background: var(--sheet);
  }

  .folder-list-actions {
    display: grid;
    justify-items: start;
    padding-inline: var(--bleed);
  }
}

/* Selection toolbar: appears only while something is selected. */

/* Selection bar: takes the Dock's place at the bottom while something is selected, so the grid never moves. */

.selection-reveal {
  position: fixed;
  z-index: var(--z-dock);
  left: 50%;
  bottom: calc(var(--space-16) + var(--safe-bottom));
  max-width: calc(100% - 2 * var(--space-12));
  translate: -50% 0;
  transition:
    opacity var(--dur-state) var(--ease-state),
    translate var(--dur-move) var(--ease-out);
}

.selection-reveal[data-visible='0'] {
  opacity: 0;
  translate: -50% var(--space-24);
  pointer-events: none;
}

.selection-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-8) var(--space-8) var(--space-20);
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--on-ink);
  box-shadow: var(--elevation-float);
  white-space: nowrap;
}

.selection-count {
  margin-right: var(--space-12);
  color: var(--on-ink-mute);
  font-size: var(--type-ui);
}

.selection-count b {
  color: var(--on-ink);
  font-weight: var(--weight-regular);
}

.selection-toolbar .btn {
  border-color: transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--on-ink);
}

.selection-toolbar .btn:hover {
  background: var(--on-ink-wash);
}

.selection-toolbar .btn.danger {
  color: var(--on-ink);
  background: var(--status-bad);
}

.selection-toolbar .icon-button {
  color: var(--on-ink);
}

.selection-toolbar .icon-button:hover {
  background: var(--on-ink-wash);
}

@media (max-width: 480px) {
  .selection-toolbar {
    flex-wrap: wrap;
    border-radius: var(--radius-tile);
  }

  .selection-count {
    margin-right: auto;
  }

  .selection-toolbar > .icon-button {
    order: 1;
  }

  .selection-toolbar .btn {
    order: 2;
    flex-basis: 100%;
    white-space: nowrap;
    text-align: left;
  }
}

body:has(.selection-reveal[data-visible='1']) .dock-wrap {
  opacity: 0;
  pointer-events: none;
}

.dock-wrap {
  transition: opacity var(--dur-state) var(--ease-state);
}

@media (prefers-reduced-motion: reduce) {
  .selection-reveal,
  .dock-wrap {
    transition: none;
  }
}

.list-foot {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
}

.form-section > .list-foot,
#translation-editor > .list-foot {
  min-height: var(--footer-h);
}

/* A footer closes its section: the section's bottom padding becomes the footer's inset, so the
   control sits at the panel edge instead of floating above it. */

.form-section > :is(.list-foot, .footer-bar):last-child {
  margin-block-end: calc(-1 * var(--space-40));
}

/* Provider marks: a logo on its own plate, dark marks on the inverse plate. */

.provider-logo-surface {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: var(--row-h);
}

.provider-logo-surface.inverse {
  justify-content: center;
  padding: var(--space-12);
  border-radius: var(--radius-tile);
  background: var(--tile-graphite);
}

/* Every provider mark stands on one cap height, so a wide wordmark does not shout over a compact one. */

.provider-logo {
  display: block;
  width: auto;
  height: var(--space-24);
  max-width: 60%;
  object-fit: contain;
  object-position: left center;
}

/* Dark marks would vanish on a dark sheet: the plate is transparent in light and paper in dark. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .provider-logo {
    padding: var(--space-4);
    border-radius: var(--radius-control);
    background: var(--logo-plate);
  }
}

:root[data-theme='dark'] .provider-logo {
  padding: var(--space-4);
  border-radius: var(--radius-control);
  background: var(--logo-plate);
}

/* == 10 Drag And Drop ======== */

/* One DnD core (dnd-core.js): the lifted copy follows the pointer, neighbours slide, the slot shows the drop line. */

[data-dnd-handle],
.dashboard-drag-handle {
  cursor: grab;
  touch-action: none;
}

.is-dragging,
.is-dragging * {
  cursor: grabbing;
  user-select: none;
}

.sortable-ghost {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-drag);
  margin: 0;
  background: var(--sheet);
  outline: 1px solid var(--ink);
  box-shadow: var(--elevation-float);
  scale: 1.02;
  pointer-events: none;
}

.sortable-ghost.is-landing {
  box-shadow: none;
}

.sortable-ghost.is-blocked {
  outline-color: var(--status-bad);
}

.sortable-lifted {
  opacity: 0;
}

.sortable-placeholder {
  position: relative;
  background: var(--raised);
}

.sortable-placeholder::before {
  content: '';
  position: absolute;
  inset: -1px 0 auto;
  height: 2px;
  background: var(--signal);
}

.sortable-zone.is-drop-target {
  background: var(--raised);
  outline: 1px dashed var(--ink);
  outline-offset: -1px;
}

.sortable-zone.is-drop-blocked {
  outline: 1px dashed var(--status-bad);
  outline-offset: -1px;
}

/* == 11 Dashboard ======== */

/* A row holds one answer; columns follow the viewport. */

.dashboard-widget-grid {
  --dashboard-track-count: 1;

  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--dashboard-track-count), minmax(0, 1fr));
  grid-auto-rows: var(--dashboard-row);
  grid-auto-flow: dense;
  gap: var(--gutter);
  grid-column: 1 / -1;
}

@media (min-width: 761px) {
  .dashboard-widget-grid {
    --dashboard-track-count: 2;
  }
}

@media (min-width: 961px) {
  .dashboard-widget-grid {
    --dashboard-track-count: 4;
  }
}

/* First paint already has each tile's footprint; dashboard-grid.js only places it. */

.dashboard-widget-grid > [data-widget-display='strip'],
.dashboard-widget-grid > [data-widget-display='row'] {
  grid-column: span 2;
}

.dashboard-widget-grid > [data-widget-display='tile'] {
  grid-row: span 2;
}

.dashboard-widget-grid > [data-widget-display='wide'] {
  grid-column: span 2;
  grid-row: span 2;
}

.dashboard-grid-guide {
  position: absolute;
  inset: 0 0 auto;
  z-index: 0;
  display: grid;
  height: var(--dashboard-guide-height, auto);
  gap: inherit;
  pointer-events: none;
}

.dashboard-grid-guide span {
  border: 1px dashed var(--line);
  border-radius: var(--radius-tile);
}

.dashboard-grid-guide span[data-drop-state='valid'] {
  border: 1px solid var(--signal);
  background: var(--dvokrapka-selection);
}

.dashboard-grid-guide span[data-drop-state='blocked'] {
  border: 1px solid var(--status-bad);
}

.tile {
  --tile-bg: var(--tile-paper);
  --tile-fg: var(--on-tile);
  --tile-mute: var(--mute);

  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  min-width: 0;
  padding: var(--space-16);
  border-radius: var(--radius-tile);
  background: var(--tile-bg);
  color: var(--tile-fg);
}

.tile[data-tone='stone'] {
  --tile-bg: var(--tile-stone);
  --tile-mute: var(--ink-2);
}

.tile:is([data-tone='graphite'], [data-tone='ink']) {
  --tile-bg: var(--tile-graphite);
  --tile-fg: var(--on-tile-dark);
  --tile-mute: var(--on-tile-dark-mute);
}

.tile[data-tone='ink'] {
  --tile-bg: var(--tile-ink);
}

.dashboard-card {
  position: relative;
  z-index: 1;
  min-height: 0;
  overflow: hidden;
  transition: opacity var(--dur-state) var(--ease-state);
}

.dashboard-card .marker,
.dashboard-card .text-action,
.dashboard-card .icon-button {
  color: inherit;
}

.dashboard-card[data-widget-loading] .widget-body {
  opacity: 0.4;
}

.dashboard-card.is-grid-dragging {
  opacity: 0.3;
}

/* The head is one fixed line: whatever sits in it (a status dot, an action, edit controls) never moves the title. */

.widget-head {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  height: var(--space-16);
  min-width: 0;
}

.widget-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  line-height: var(--leading-head);
  color: var(--tile-mute);
}

.widget-dot {
  flex: none;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: 50%;
  background: var(--signal);
}

.widget-dot[data-state='warning'] {
  background: var(--status-warn);
}

.widget-dot[data-state='error'] {
  background: var(--status-bad);
}

.widget-control {
  display: flex;
  flex: none;
  gap: var(--space-2);
}

.face-settings-button {
  flex: none;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
}

.widget-queue-dots {
  display: flex;
  gap: var(--space-4);
}

.widget-queue-dots i {
  width: var(--space-8);
  height: var(--space-8);
  border-radius: 50%;
  background: var(--status-warn);
}

.widget-queue-dots i[data-state='error'] {
  background: var(--status-bad);
}

/* «Потребує уваги» reads top down in every size: the first reason as a sentence, what it means under it. */

.widget-reason {
  font-size: var(--type-title);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
}

.dashboard-card[data-widget-tier='attention'] .widget-body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-4);
}

.widget-control:empty {
  display: none;
}

.widget-control:not(:empty) ~ .widget-action {
  display: none;
}

.widget-action {
  min-height: 0;
  white-space: nowrap;
}

/* Where to go appears with the pointer: at rest a tile shows only its answer. Touch keeps it visible. */

@media (hover: hover) {
  .dashboard-card :is(.widget-action, [data-goal-edit]) {
    opacity: 0;
    transition: opacity var(--dur-state) var(--ease-state);
  }

  .dashboard-card:is(:hover, :focus-within) :is(.widget-action, [data-goal-edit]) {
    opacity: 1;
  }
}

/* Settings belong to arranging the board, not to reading it. */

[data-editing='0'] .face-settings-button {
  display: none;
}

:is(.widget-action, .widget-next) .icon {
  width: 14px;
  height: 14px;
}

.widget-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  flex: 1;
  min-height: 0;
}

.widget-lead {
  display: grid;
  align-content: start;
  gap: var(--space-4);
}

/* Tall cards hold the answer at the top and what explains it at the foot, in every widget alike. */

.widget-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  margin-top: auto;
  min-width: 0;
}

.widget-main:empty + .widget-detail {
  margin-top: 0;
}

/* One figure per tile, two sizes only: 72 on a tall tile, 56 on a one-row one; money and versions a step down. */

.widget-figure {
  font-size: var(--type-display-md);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  font-variant-numeric: lining-nums tabular-nums;
  margin-left: var(--optical-figure);
}

/* The caption sits under the figure in every size. A small tile is one answer: the figure, or a
   sentence when it has none; the arrow leads through. */

.widget-context {
  min-width: 0;
  overflow: hidden;
  color: var(--tile-mute);
  text-overflow: ellipsis;
  white-space: nowrap;
}

[data-widget-display='small']:not(:has(.widget-ring))
  .widget-main:has(.widget-figure)
  + .widget-detail
  :is(.widget-signal, .widget-subtitle) {
  display: none;
}

/* A small tile with a row of checks shows the dots instead of the ratio: the picture is the answer. */

[data-widget-display='small']:has(.widget-ring) .widget-lead {
  display: none;
}

[data-widget-display='small'] .widget-signal {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

[data-widget-display='small'] .widget-action::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

[data-widget-display='small'] .widget-action:focus-visible {
  outline: none;
}

[data-widget-display='small'] .widget-action:focus-visible::after {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

[data-editing='1'] [data-widget-display='small'] .widget-action::after {
  content: none;
}

/* A one-row card splits on the board's own grid line: the answer under the first column's title,
   what explains it exactly where the next column's cards begin. One explanation only: dots before
   rows, a row before the signal; «Ще» waits behind the head's action. */

:is([data-widget-display='strip'], [data-widget-display='row']) .widget-body:has(> .widget-main) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: calc(var(--gutter) + 2 * var(--space-16));
  align-items: start;
}

:is([data-widget-display='strip'], [data-widget-display='row']) .widget-detail {
  margin-top: 0;
}

:is([data-widget-display='strip'], [data-widget-display='row']) .widget-detail:has(.widget-dots) {
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  align-self: stretch;
  min-height: 0;
}

:is([data-widget-display='strip'], [data-widget-display='row'])
  :is(.widget-main:empty + .widget-detail, .widget-main:only-child) {
  grid-column: 1 / -1;
}

:is([data-widget-display='strip'], [data-widget-display='row']) .widget-detail:has(.widget-dots) .widget-rows,
:is([data-widget-display='strip'], [data-widget-display='row'])
  .widget-detail:has(.widget-rows)
  :is(.widget-signal, .widget-subtitle),
:is([data-widget-display='small'], [data-widget-display='strip'], [data-widget-display='row']) .widget-more {
  display: none;
}

.widget-lead:empty {
  display: none;
}

/* A wide card splits on the same line when it has records or facts: the answer (and its dots) holds the
   first column top to foot, the records start level with the figure in the second. */

[data-widget-display='wide']
  .widget-body:has(> .widget-main:not(:empty) + .widget-detail :is(.widget-rows, .widget-facts)) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: minmax(0, 1fr);
  column-gap: calc(var(--gutter) + 2 * var(--space-16));
}

[data-widget-display='wide'] .widget-main:has(+ .widget-detail :is(.widget-rows, .widget-facts)) {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-height: 0;
}

[data-widget-display='wide'] .widget-main:not(:empty) + .widget-detail:has(.widget-rows, .widget-facts) {
  margin-top: 0;
}

:is([data-widget-display='tile'], [data-widget-display='wide'])
  .widget-figure:is([data-figure-kind='quantity'], [data-figure-kind='ratio']) {
  font-size: var(--type-display-lg);
}

.widget-figure small {
  margin-left: var(--space-4);
  font-size: var(--type-title);
  letter-spacing: var(--tracking-title);
}

.widget-figure[data-figure-kind='version'],
.widget-figure[data-figure-kind='time'] {
  font-size: var(--type-display);
}

.widget-headline {
  font-size: var(--type-title);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
}

/* Phone typography fits one track. */

@media (max-width: 760px) {
  :is([data-widget-display='small'], [data-widget-display='tile']) :is(.widget-headline, .face-note-text) {
    font-size: var(--type-ui);
    letter-spacing: normal;
  }

  [data-widget-display='small'] .face-time {
    font-size: var(--type-display);
  }

  [data-face='calendar'] .face-hint {
    display: none;
  }
}

/* Nothing to count: the sentence and the one step that changes it, pinned to the card's foot. */

.widget-next {
  align-self: flex-start;
  margin-top: auto;
  min-height: 0;
  gap: var(--space-4);
}

:is([data-widget-display='strip'], [data-widget-display='row']) .widget-next {
  margin-top: 0;
}

.dashboard-card:is(
    [data-widget-state='zero'],
    [data-widget-state='nodata'],
    [data-widget-state='empty'],
    [data-widget-state='unconfigured'],
    [data-widget-state='disabled']
  )
  .widget-figure {
  color: var(--tile-mute);
}

.widget-error,
.widget-subtitle {
  color: var(--tile-mute);
  font-size: var(--type-ui);
}

.widget-signal {
  font-size: var(--type-ui);
}

.widget-signal .marker {
  white-space: normal;
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-ui);
  font-size: var(--type-ui);
}

.dashboard-card .widget-signal .marker {
  align-items: baseline;
}

/* Every check is one dot: ink when it passed, the status colour when it did not. */

.widget-ring {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: auto;
}

.widget-ring span {
  width: var(--space-12);
  height: var(--space-12);
  border-radius: 50%;
  background: currentcolor;
}

.widget-ring span[data-state='warning'] {
  background: var(--status-warn);
}

.widget-ring span[data-state='error'] {
  background: var(--status-bad);
}

.widget-ring span[data-state='unknown'] {
  background: var(--trace-current);
}

/* Data drawn as the picture: a column of dots per day, stacked from the bottom. */

.widget-dots {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: var(--space-4);
  margin-top: auto;
  min-width: 0;
  min-height: 0;
}

/* Dots keep their size while there is room and shrink together when there is not: the height sets them. */

.widget-dots-field {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-2);
  height: 100%;
  min-height: 0;
}

.widget-dots-field span {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: var(--space-2);
  min-height: 0;
  container-type: inline-size;
}

.widget-dots-field i {
  flex: 0 1 min(var(--space-8), 100cqi);
  min-height: 0;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--trace-current);
}

.widget-dots-field i[data-state='gap'] {
  visibility: hidden;
}

.widget-dots-field i[data-state='on'] {
  background: currentcolor;
}

.widget-dots-field i[data-state='off'] {
  background: var(--dot-off);
}

.widget-dots-field i[data-state='now'] {
  background: var(--signal);
}

.widget-dots-field i[data-state='bad'] {
  background: var(--status-bad);
}

.widget-dots-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--tile-mute);
}

:is([data-widget-display='strip'], [data-widget-display='row']) :is(.widget-dots, .widget-ring) {
  margin-top: 0;
}

.widget-rows,
.dashboard-signal-list {
  list-style: none;
  display: grid;
}

.widget-rows > li + li,
.dashboard-signal-list > li + li {
  border-top: 1px solid var(--line-current);
}

.widget-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-12);
  width: 100%;
  padding-block: var(--space-8);
  text-align: left;
}

/* A clickable row is hovered by a translucent wash: the tile may be tinted. */

/* A row is a link: like every text action it answers the pointer with an underline, inside its own lines. */

button.widget-row .widget-row-name {
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 4px;
  transition: text-decoration-color var(--dur-state) var(--ease-state);
}

button.widget-row:is(:hover, :focus-visible) .widget-row-name {
  text-decoration-color: currentcolor;
}

.widget-row-copy {
  display: grid;
  min-width: 0;
}

.widget-row-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--type-ui);
}

.widget-row-copy small {
  color: var(--tile-mute);
  font-size: var(--type-ui);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-row-aside {
  display: grid;
  flex: none;
  justify-items: end;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  color: var(--tile-mute);
  text-align: right;
}

.widget-row-aside small {
  color: inherit;
  font-size: inherit;
}

li[data-severity] .widget-row-name::before {
  content: '';
  display: inline-block;
  width: var(--marker);
  height: var(--marker);
  margin-right: var(--space-8);
  background: var(--status-warn);
}

li[data-severity='error'] .widget-row-name::before {
  background: var(--status-bad);
}

/* «Продовжити»: the drafts lie as strips along the bottom edge, the newest on top of the pile. */

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-rows {
  margin: auto calc(-1 * var(--space-16)) calc(-1 * var(--space-16));
}

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-rows > li {
  border: 0;
  border-radius: var(--radius-tile) var(--radius-tile) 0 0;
  background: var(--tile-strip-1);
}

[data-widget-type='content'] .widget-rows > li:nth-child(2) {
  background: var(--tile-strip-2);
}

[data-widget-type='content'] .widget-rows > li:nth-child(3) {
  background: var(--tile-strip-3);
}

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-rows > li + li {
  margin-top: calc(-1 * var(--space-4));
}

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-row {
  flex-direction: column-reverse;
  gap: var(--space-4);
  width: 100%;
  margin: 0;
  padding: var(--space-12) var(--space-16) var(--space-16);
}

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-row-name {
  font-size: var(--type-body);
}

[data-widget-type='content']:is([data-widget-display='tile'], [data-widget-display='wide']) .widget-row-aside {
  justify-items: start;
}

[data-widget-type='content'] .widget-more {
  display: none;
}

.widget-more {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  color: var(--tile-mute);
}

.widget-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter);
}

.widget-facts dt {
  color: var(--tile-mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
}

.widget-facts dd {
  font-size: var(--type-title);
}

.widget-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-16);
}

.widget-stale {
  color: var(--tile-mute);
}

.dashboard-edit-reveal {
  grid-column: 1 / -1;
  min-width: 0;
}

.dashboard-edit-reveal[data-visible='0'] {
  display: none;
}

.dashboard-edit-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-bottom: var(--gutter);
  grid-column: 1 / -1;
}

.dashboard-drag-handle,
.dashboard-remove-button {
  display: grid;
  place-items: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  border-radius: var(--radius-control);
  background: var(--wash-current);
}

.dashboard-drag-handle:hover,
.dashboard-remove-button:hover {
  background: var(--line-current);
}

.dashboard-resize-handle {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
}

.dashboard-resize-handle[data-dashboard-resize='right'] {
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--space-16);
  cursor: ew-resize;
}

.dashboard-resize-handle[data-dashboard-resize='bottom'] {
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--space-16);
  cursor: ns-resize;
}

.dashboard-resize-handle span {
  width: 2px;
  height: var(--space-24);
  background: currentcolor;
  opacity: 0.5;
}

.dashboard-resize-handle[data-dashboard-resize='bottom'] span {
  width: var(--space-24);
  height: 2px;
}

.dashboard-resize-handle:hover span,
.dashboard-resize-handle:focus-visible span {
  opacity: 1;
}

.dashboard-resize-label {
  position: absolute;
  right: var(--space-16);
  bottom: 0;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  line-height: var(--leading-head);
  color: var(--tile-mute);
}

.dashboard-card.is-resizing,
.dashboard-card.is-size-preview {
  outline: 1px solid var(--signal);
  outline-offset: 2px;
}

.dashboard-gallery-toolbar {
  position: sticky;
  top: calc(-1 * var(--space-4));
  z-index: 2;
  margin-top: calc(-1 * var(--space-4));
  padding-block: var(--space-4) var(--space-12);
  background: var(--sheet);
}

.dashboard-gallery-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-20);
}

.dashboard-gallery-filters button {
  position: relative;
  min-height: var(--control-h);
  color: var(--mute);
}

.dashboard-gallery-filters button:hover,
.dashboard-gallery-filters button[aria-pressed='true'] {
  color: var(--ink);
}

.dashboard-gallery-filters button[aria-pressed='true']::after {
  content: '';
  position: absolute;
  inset: auto 0 var(--space-4);
  height: 1px;
  background: var(--ink);
}

/* Library: one even grid of identical cards; the stage is fixed, the real tile is fitted into it. */

/* Live previews (clocks, timer) redraw inside zoomed tiles; Chrome then loses its scroll anchor and
   throws the list back. The library scroll is the reader's alone. */

.dashboard-gallery-dialog .dialog-body,
.dashboard-card-gallery {
  overflow-anchor: none;
}

/* The library is a grid of cells like the icon picker: hairlines between cells, no frames around tiles. */

.dashboard-card-gallery {
  position: relative;
  z-index: 1;
  isolation: isolate;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}

@media (max-width: 760px) {
  .dashboard-card-gallery {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* A library entry is the tile itself and one line under it: no frame around the tile, no frame around the entry. */

.dashboard-card-gallery__item {
  display: grid;
  align-content: start;
  gap: var(--space-12);
  min-width: 0;
  padding: var(--space-16);
  box-shadow: inset -1px -1px 0 var(--line);
}

@media (min-width: 761px) {
  .dashboard-card-gallery__item:nth-child(2n of :not([hidden])) {
    box-shadow: inset 0 -1px 0 var(--line);
  }
}

@media (max-width: 760px) {
  .dashboard-card-gallery__item {
    box-shadow: inset 0 -1px 0 var(--line);
    padding-inline: 0;
  }
}

.dashboard-card-gallery__item[hidden] {
  display: none;
}

.dashboard-gallery-stage {
  display: grid;
  place-items: center;
  aspect-ratio: 2 / 1;
  overflow: hidden;
}

/* The entry names the widget once, under it; the preview keeps its layout but not the repeated title. */

.dashboard-gallery-content .widget-title {
  visibility: hidden;
}

.dashboard-gallery-content {
  display: grid;
  grid-template-columns: repeat(var(--preview-cols, 2), var(--preview-unit, 220px));
  grid-auto-rows: var(--preview-row, 102px);
  gap: var(--preview-gap, var(--space-16));
  zoom: var(--preview-scale, 1);
  pointer-events: none;
}

.dashboard-gallery-content
  :is(.dashboard-resize-handle, .dashboard-resize-label, .dashboard-drag-handle, .dashboard-remove-button) {
  display: none;
}

.dashboard-gallery-content > .dashboard-card {
  grid-column: 1 / -1;
  grid-row: span 1;
}

.dashboard-gallery-stage:is([data-display='tile'], [data-display='wide']) .dashboard-card {
  grid-row: span 2;
}

.dashboard-gallery-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-8);
  min-width: 0;
}

[data-editing='0'] [data-dashboard-edit-toggle] {
  display: none;
}

.dashboard-gallery-head strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--type-body);
  font-weight: var(--weight-regular);
}

/* A size is drawn as its shape on a 4×4 cell grid: people pick a form, not a formula. */

.dashboard-gallery-sizes {
  display: flex;
  gap: var(--space-2);
}

.dashboard-gallery-toggle {
  display: grid;
  place-items: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  border-radius: var(--radius-control);
  background: var(--ink);
  color: var(--on-ink);
}

.dashboard-gallery-toggle:hover {
  background: var(--ink-hover);
}

[data-added] .dashboard-gallery-toggle {
  background: var(--raised);
  color: var(--ink);
}

[data-added] .dashboard-gallery-toggle:hover {
  background: var(--hover);
}

.dashboard-gallery-toggle:disabled {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--text-disabled);
  cursor: not-allowed;
}

.dashboard-gallery-sizes button {
  display: grid;
  place-items: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  border-radius: var(--radius-control);
  color: var(--mute);
}

.dashboard-gallery-sizes button i {
  width: calc(var(--w, 1) * 6px);
  height: calc(var(--h, 1) * 6px);
  border: 1px solid currentcolor;
}

.dashboard-gallery-sizes button:hover {
  background: var(--hover);
  color: var(--ink);
}

.dashboard-gallery-sizes button[aria-checked='true'] {
  color: var(--ink);
  background: var(--raised);
}

.dashboard-gallery-sizes button[aria-checked='true'] i {
  background: currentcolor;
}

.dashboard-gallery-empty {
  color: var(--mute);
}

.dashboard-signals-dialog .dashboard-signal-list {
  border-top: 1px solid var(--rule);
}

.dashboard-signals-dialog .widget-row-copy small,
.dashboard-signals-dialog .widget-row-aside {
  color: var(--mute);
}

/* Time zones: the shared search field, then rows divided by hairlines like every list in the admin.
   A row is a dot slot, the city with its zone, the difference in mono, and its actions. */

.timezone-settings {
  display: grid;
  gap: var(--space-24);
  min-width: 0;
}

.timezone-settings-group {
  display: grid;
  gap: var(--space-8);
  min-width: 0;
}

.timezone-settings-group > .label {
  color: var(--mute);
}

.timezone-list {
  display: grid;
  list-style: none;
  border-top: 1px solid var(--line);
}

/* One column set for both lists, so differences and actions line up from row to row. */

.timezone-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto calc(2 * var(--control-h-sm) + var(--space-2));
  align-items: center;
  gap: var(--space-12);
  width: 100%;
  min-height: var(--row-h);
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.timezone-list > li:has(> button.timezone-row) {
  border-bottom: 1px solid var(--line);
}

.timezone-list > li > button.timezone-row {
  border-bottom: 0;
}

button.timezone-row:hover,
button.timezone-row:focus-visible {
  background: var(--hover);
}

button.timezone-row:disabled {
  color: var(--text-disabled);
  cursor: not-allowed;
  background: none;
}

/* The active choice is lit, not marked: its name turns to the accent. */

:is(.timezone-row.is-base, .timezone-row[aria-selected='true']) .timezone-row-copy > span {
  color: var(--signal-text);
}

.timezone-row-copy {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.timezone-row-copy > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.timezone-row-copy small,
.timezone-row-note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: var(--type-label);
}

.timezone-row-note {
  text-align: right;
}

.timezone-row-add {
  display: grid;
  justify-self: end;
  place-items: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  color: var(--mute);
}

button.timezone-row:hover .timezone-row-add {
  color: var(--ink);
}

[data-world='0'] .timezone-row {
  grid-template-columns: minmax(0, 1fr) auto;
}

[data-world='0'] .timezone-row-add {
  display: none;
}

.timezone-row .row-actions {
  justify-self: end;
}

.timezone-row-add .icon,
.timezone-row .row-actions .icon {
  width: var(--icon);
  height: var(--icon);
}

.timezone-settings-empty {
  margin: 0;
  padding-block: var(--space-12);
  color: var(--mute);
}

/* Time faces: dashboard-faces.js draws them for their size */

.dashboard-face {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  flex: 1;
  min-height: 0;
  font-variant-numeric: tabular-nums;
}

.face-row,
.face-controls {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-12);
}

.face-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  align-content: start;
  min-width: 0;
}

.face-stack > .text-action {
  justify-self: start;
}

.face-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-8);
}

.face-label,
.face-meta {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  line-height: var(--leading-head);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--tile-mute);
}

.face-accent {
  color: var(--signal-text);
}

.tile[data-tone='stone'] .face-accent {
  color: var(--on-stone-highlight);
}

:is([data-tone='graphite'], [data-tone='ink']) .face-accent {
  color: inherit;
}

.face-time {
  font-size: var(--type-display-md);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

.face-time small {
  font-size: var(--type-title);
  color: var(--tile-mute);
}

.face-time.is-stacked {
  display: grid;
}

:is([data-widget-display='tile'], [data-widget-display='wide']) :is(.face-time, .face-day) {
  font-size: var(--type-display-lg);
}

/* The small clock gives its head to the face: the title is read, not shown; the setting floats in the corner. */

[data-editing='0'] [data-widget-face='digital'][data-widget-display='small'] .widget-title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

[data-editing='0'] [data-widget-face='digital'][data-widget-display='small'] .widget-head {
  position: absolute;
  inset: var(--space-16) var(--space-16) auto;
}

/* Two round dots, not a typed colon: the brand's own mark keeps the time. */

.face-time > [aria-hidden] {
  display: inline-flex;
  align-items: center;
}

.face-colon {
  display: inline-flex;
  flex-direction: column;
  gap: 0.2em;
  margin-inline: 0.1em;
  animation: clock-tick var(--motion-tick) steps(1) infinite;
}

.face-colon i {
  padding: 0.06em;
  border-radius: 50%;
  background: var(--signal);
}

.face-day {
  font-size: var(--type-display-md);
  font-weight: var(--weight-light);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

/* A dial on a small tile stands where a figure would: the figure's height, at the card's edge. */

[data-widget-display='small'] [data-face='analog'] .face-dial {
  align-self: flex-start;
  height: var(--type-display-md);
  margin-inline: 0;
}

/* A two-column face splits like every two-column card, on the board's grid line. */

:is(.face-split, [data-widget-display='wide'] :is([data-face='analog'], [data-face='calendar'], [data-face='timer'])) {
  align-self: stretch;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: calc(var(--gutter) + 2 * var(--space-16));
}

[data-widget-display='wide'] [data-face='analog'] .face-dial {
  height: 100%;
  margin-inline: 0;
}

.face-dial-wrap {
  position: relative;
  display: grid;
  place-items: center;
  flex: 1;
  min-height: 0;
}

.face-dial {
  width: auto;
  height: 100%;
  max-width: 100%;
  aspect-ratio: 1;
  margin-inline: auto;
}

.face-dial-plate {
  fill: none;
  stroke: var(--trace-current);
  stroke-width: 0.6;
}

.face-dial-ticks line {
  stroke: currentcolor;
  stroke-width: 0.6;
  opacity: 0.5;
}

.face-dial-ticks line.is-hour {
  stroke-width: 1.2;
  opacity: 1;
}

.face-dial-digits text {
  fill: currentcolor;
  font-family: var(--font-mono);
}

.face-hand {
  stroke: currentcolor;
  stroke-linecap: round;
}

.face-hand.is-hour {
  stroke-width: 2.4;
}

.face-hand.is-minute {
  stroke-width: 1.6;
}

.face-hand.is-second {
  stroke: var(--signal);
  stroke-width: 0.8;
}

.face-dial-pin {
  fill: var(--signal);
}

.face-dial-date {
  position: absolute;
  bottom: 22%;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
}

/* The month fills the height it is given: the row height sets the day dot, so six weeks never spill out. */

.face-cal {
  display: grid;
  flex: 1;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-template-rows: auto;
  grid-auto-rows: minmax(0, 1fr);
  align-items: center;
  gap: var(--space-2);
  min-height: 0;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-align: center;
}

.face-cal-head {
  color: var(--tile-mute);
  text-transform: uppercase;
  line-height: var(--leading-head);
}

/* On the wide calendar the weekday letters stand on the head line, level with the title: the month starts where
   the card does. While arranging, the head carries the edit controls, so the month steps back below it. */

[data-editing='0'] [data-widget-display='wide'] [data-face='calendar'] .face-cal {
  margin-top: calc(-1 * (var(--leading-head) + var(--space-12)));
}

.face-cal-day {
  display: grid;
  place-items: center;
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: var(--space-32);
  aspect-ratio: 1;
  margin-inline: auto;
  border-radius: 50%;
  background: var(--wash-current);
}

.face-cal .is-weekend {
  color: var(--tile-mute);
}

.face-cal-day[aria-current='date'] {
  background: var(--signal);
  color: var(--on-signal);
}

/* A day with a publication is a filled dot; today is the accent. */

.face-cal-day.is-marked {
  background: var(--tile-fg);
  color: var(--tile-bg);
}

.face-event {
  display: grid;
  min-width: 0;
  padding-block: var(--space-8);
  text-align: left;
  border-top: 1px solid var(--line-current);
}

.face-plan {
  grid-template-rows: auto 1fr;
  height: 100%;
}

.face-figure {
  display: grid;
  justify-items: start;
  gap: var(--space-4);
}

.face-events,
.face-hint {
  align-self: end;
}

.face-note.face-hint {
  white-space: normal;
}

.face-cities {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-16);
  flex: 1;
  min-height: 0;
}

.face-city {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
  padding-left: var(--space-12);
  border-left: 1px solid var(--line-current);
}

.face-city:first-child {
  padding-left: 0;
  border-left: 0;
}

.face-city .face-time {
  margin: var(--space-4) 0 0;
  font-size: var(--type-display);
  white-space: nowrap;
}

.face-city.is-night .face-time {
  opacity: 0.6;
}

/* Large digits start at the card edge like the title above them; a centred time keeps its centre. */

.dashboard-face :is(.face-time, .face-day, .face-figure > :first-child):not(.face-gauge-core *) {
  margin-left: var(--optical-figure);
}

.face-hours {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-4) var(--space-2);
  margin-top: auto;
  justify-items: center;
}

.face-hours i,
.face-year i,
.face-goal-dots i {
  width: 100%;
  max-width: var(--space-8);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--trace-current);
}

.face-hours.is-line {
  grid-template-columns: repeat(24, minmax(0, 1fr));
}

.face-hours i.is-day {
  background: currentcolor;
}

.face-hours i.is-now,
.face-year i.is-now {
  background: var(--signal);
}

.face-hours-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--type-label);
  color: var(--tile-mute);
}

.face-city :is(.face-hours, .face-hours-axis) {
  display: none;
}

@media (min-width: 761px) {
  .face-cities {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .face-city .face-hours {
    display: grid;
  }

  .face-city .face-hours-axis {
    display: flex;
  }
}

@media (max-width: 760px) {
  .face-city:nth-child(3) {
    padding-left: 0;
    border-left: 0;
  }

  [data-widget-display='wide'] [data-face='calendar'] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  [data-widget-display='wide'] [data-face='calendar'] .face-plan {
    display: flex;
    align-items: end;
    gap: var(--space-12);
    height: auto;
    min-height: 0;
  }

  [data-widget-display='wide'] [data-face='calendar'] .face-plan > * {
    flex: 1;
    min-width: 0;
  }
}

/* The year: a week per column, seven days down; the days lived are filled. */

/* The year fills what room is left: the row height sets the dot, so it never spills out of a strip. */

.face-year {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-rows: repeat(7, minmax(0, 1fr));
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-2);
  place-items: center center;
}

.dashboard-face .face-year i {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: var(--space-8);
}

.face-year i.is-past {
  background: currentcolor;
}

.face-year i.is-gap {
  visibility: hidden;
}

/* The month goal: dots fill as the count grows; reaching it lights the last one in the accent. */

.face-goal-dots {
  display: grid;
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: auto;
  justify-items: center;
}

.face-goal-dots.is-few {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

.face-goal-dots.is-few i {
  width: var(--space-16);
  max-width: none;
}

.face-goal-dots i.is-lit {
  background: currentcolor;
}

.face-goal-dots.is-done i:last-child {
  background: var(--signal);
}

.face-note-text {
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  flex: 1;
  min-height: 0;
  resize: none;
  font-size: var(--type-title);
  letter-spacing: var(--tracking-title);
  line-height: var(--leading-tight);
}

.face-note-text:focus {
  outline: none;
  box-shadow: inset 0 -1px 0 var(--signal);
}

.face-gauge {
  position: relative;
  display: grid;
  place-items: center;
  flex: 1;
  min-height: 0;
}

/* A round face on a tile is centred on the card, not under the head: the circle rises to the title line
   (the title sits in its corner, clear of the circle). While arranging, the head's controls keep it below. */

[data-editing='0']
  [data-widget-display='tile']
  :is([data-face='timer'] .face-gauge, [data-face='analog'] .face-dial-wrap) {
  margin-top: calc(-1 * (var(--leading-head) + var(--space-12)));
}

/* Wide calendar and focus: two halves side by side (what is coming | the month; the dial | its time and task). */

.face-comb {
  height: 100%;
  max-width: 100%;
  aspect-ratio: 1;
}

.face-comb circle,
.face-comb-line circle {
  fill: var(--trace-current);
}

.face-comb .is-lit,
.face-comb-line .is-lit {
  fill: currentcolor;
}

.face-comb .is-head,
.face-comb-line .is-head {
  fill: var(--signal);
}

.face-comb-line {
  width: 100%;
  height: var(--space-8);
  margin-top: auto;
}

.face-gauge-core {
  position: absolute;
  display: grid;
  justify-items: center;
  gap: var(--space-4);
}

.face-gauge-core .face-time {
  font-size: var(--type-display);
}

.face-play,
.face-rewind {
  display: grid;
  place-items: center;
  width: var(--control-h);
  height: var(--control-h);
  border-radius: 50%;
  border: 1px solid currentcolor;
}

.face-play {
  background: var(--tile-fg);
  color: var(--tile-bg);
}

/* A white button on a white tile is invisible in light: the round control keeps the edge it has on dark tiles. */

.face-play:not([class*='is-large']) {
  border-color: var(--tile-mute);
}

.face-play.is-large {
  width: var(--space-64);
  height: var(--space-64);
}

.face-play.is-corner,
.face-rewind.is-corner {
  position: absolute;
  bottom: 0;
}

.face-play.is-corner {
  right: 0;
}

.face-rewind.is-corner {
  left: 0;
}

.dashboard-face[data-timer-state='idle'] .face-rewind {
  visibility: hidden;
}

.face-glyph {
  width: var(--icon);
  height: var(--icon);
  fill: currentcolor;
}

.face-rewind .face-glyph {
  fill: none;
  stroke: currentcolor;
  stroke-width: 2;
}

.face-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
}

.face-chip:disabled {
  opacity: 0.6;
  cursor: default;
}

.face-chevron {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentcolor;
  stroke-width: 2;
}

/* The task a focus is for: a line that reads as text until it is written in. */

.face-task {
  border: 0;
  border-bottom: 1px solid var(--line-current);
  background: none;
  color: inherit;
  font: inherit;
}

/* A quiet one-line note on a face: the task, an event's date, an empty schedule. */

.face-note {
  color: var(--tile-mute);
  font-size: var(--type-ui);
}

.face-event span,
.face-note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 961px) {
  .dashboard-gallery-dialog .dialog {
    max-width: calc(4 * var(--aside-w) + 3 * var(--gutter));
  }
}

/* == 12 Rich Editor ======== */

.rich-editor {
  display: grid;
  border-bottom: 1px solid var(--field-line);
}

.rich-editor-chrome {
  position: sticky;
  top: var(--chrome-h);
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-4);
  background: var(--canvas);
  border-bottom: 1px solid var(--line);
}

.rich-tool-separator {
  width: 1px;
  height: 20px;
  margin-inline: var(--space-4);
  background: var(--line);
}

.rich-tool[aria-pressed='true'] {
  background: var(--ink);
  color: var(--on-ink);
}

.rich-content {
  min-height: 200px;
  padding-block: var(--space-16);
  line-height: var(--leading-body);
  outline: none;
}

.rich-content > * + * {
  margin-top: var(--space-12);
}

.rich-content h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
}

.rich-content ul,
.rich-content ol {
  padding-left: var(--space-24);
}

.rich-content a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.rich-editor.read-only .rich-editor-chrome {
  display: none;
}

.rich-media-placeholder {
  display: grid;
  place-items: center;
  min-height: 120px;
  background: var(--well);
}

.rich-selection-toolbar {
  position: fixed;
  z-index: var(--z-popover);
  display: flex;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--ink);
  color: var(--on-ink);
  border-radius: var(--radius-control);
  box-shadow: var(--elevation-float);
}

.rich-selection-toolbar .icon-button {
  color: var(--on-ink);
}

.rich-selection-toolbar .icon-button:hover {
  background: var(--on-ink-wash);
}

.rich-editor-field {
  display: grid;
  gap: var(--space-8);
}

.rich-editor-source {
  display: none;
}

/* A formatted text owns the whole row, and its slot is held before the editor mounts so nothing below it jumps. */

.entry-content-fields > [data-entry-language]:has(.rich-editor-field) {
  grid-column: 1 / -1;
}

.rich-editor-field:not(:has(.rich-editor)) {
  align-content: start;
  min-height: calc(var(--space-64) * 4 + var(--space-8));
}

.rich-format-tools,
.rich-history-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.rich-history-tools {
  margin-left: auto;
}

.rich-block-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--control-h-sm);
  padding: 0 var(--space-8);
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--type-ui);
  cursor: pointer;
}

.rich-block-trigger:hover,
.rich-block-trigger[aria-expanded='true'] {
  background: var(--raised);
}

.rich-block-sample {
  display: block;
}

.rich-block-sample-h2 {
  font-size: var(--type-title);
  font-weight: var(--weight-light);
}

.rich-block-sample-h3 {
  font-size: var(--type-body);
  font-weight: var(--weight-medium);
}

.rich-block-sample-p {
  font-size: var(--type-body);
}

/* == 13 Motion ======== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  .switch input[role='switch']::after,
  .ui-disclosure > summary .icon,
  #toast {
    transition: none;
  }

  .sortable-ghost {
    scale: none;
  }

  .spinner::after,
  .async-action-spinner::after,
  .local-led-loader i,
  .global-led-progress.is-active i {
    animation: none;
    width: 100%;
    opacity: 0.6;
  }
}

/* == 14 Dock ======== */

/* 48px bar: 40px circular items on a 4px inset, the same height as the top bar. */

.dock-wrap {
  pointer-events: auto;
  position: fixed;
  z-index: var(--z-dock);
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  max-width: calc(100% - 24px);
}

.dock {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--ink);
  color: var(--on-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--elevation-float);
  max-width: calc(100vw - 24px);
  overflow-x: auto;
  scrollbar-width: none;
  overscroll-behavior-inline: contain;
}

.dock::-webkit-scrollbar {
  display: none;
}

.dock button,
.dock .dock-link {
  display: grid;
  place-items: center;
  position: relative;
  flex: 0 0 var(--dock-item);
  width: var(--dock-item);
  height: var(--dock-item);
  padding: 0;
  color: var(--on-ink-mute);
  border-radius: 50%;
  transition:
    background-color var(--dur-state) var(--ease-state),
    color var(--dur-state) var(--ease-state),
    opacity var(--dur-move) var(--ease-out),
    scale var(--dur-move) var(--ease-out);
}

.dock button:hover,
.dock .dock-link:hover {
  background: var(--on-ink-hover-soft);
  color: var(--on-ink);
}

.dock button.active {
  background: var(--on-ink-hover-soft);
  color: var(--on-ink);
}

.dock :is(button, .dock-link):focus-visible {
  outline-color: var(--on-ink);
  outline-offset: -3px;
}

.dock .icon {
  width: 20px;
  height: 20px;
}

.dock-divider {
  width: 1px;
  height: 24px;
  background: var(--on-ink-line);
  margin-inline: var(--space-4);
  flex: none;
}

.dock.is-editing [data-dock-edit-item] {
  cursor: grab;
  touch-action: none;
}

.dock.is-editing [data-dock-edit-item]:active {
  cursor: grabbing;
}

.dock .is-remove-candidate {
  background: var(--status-bad);
  color: var(--on-ink);
}

.dock .is-leaving {
  opacity: 0;
  scale: 0.6;
}

/* The lifted Dock item is the round button itself, never a white card. */

.sortable-ghost.dock-drag-image {
  display: grid;
  place-items: center;
  background: var(--ink);
  color: var(--on-ink);
  outline: none;
  border-radius: 50%;
  box-shadow: var(--elevation-float);
  scale: 1.2;
}

.sortable-ghost.dock-drag-image.is-remove {
  background: var(--status-bad);
}

.dock .sortable-placeholder {
  flex: 0 0 var(--dock-item);
  border-radius: 50%;
  background: var(--on-ink-hover-soft);
}

.dock .sortable-placeholder::before {
  content: none;
}

.dock .dock-add-action {
  color: var(--on-ink);
}

.dock .dock-done-action {
  color: var(--ink);
  background: var(--on-ink);
}

.dock .dock-done-action:hover {
  color: var(--ink);
  background: var(--on-ink);
}

.dock-remove-indicator {
  position: fixed;
  z-index: var(--z-drag);
  display: flex;
  gap: var(--space-8);
  align-items: center;
  padding: var(--space-8) var(--space-12);
  background: var(--ink);
  color: var(--on-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--elevation-float);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .sortable-ghost.dock-drag-image {
    scale: none;
  }
}

@media (max-width: 480px) {
  .dock-divider {
    margin-inline: var(--space-4);
  }
}
