/* ------------------ UTILITY ------------------ */

/* Announcement target for assistive technology: in the accessibility tree,
   out of the visual one. */
.cloudcanvas-live-region {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------ UI KIT: CONTROLS ------------------ */

.cloudcanvas-ui-button {
  min-height: var(--cc-control-min, 28px);
  padding: var(--cc-space-1, 4px) var(--cc-space-3, 12px);
  font: inherit;
  font-size: var(--cc-type-md, 13px);
  color: var(--cc-btn-text, #7dd3fc);
  background: var(--cc-btn-bg, rgba(56, 189, 248, 0.12));
  border: 1px solid var(--cc-btn-border, rgba(56, 189, 248, 0.35));
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-button:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); }
.cloudcanvas-ui-button.is-primary { color: var(--cc-ui-on-accent, #0f172a); background: var(--cc-accent, #38bdf8); }
/* A danger button keeps the page's ink and says so by its border: the tone's colour is not one ink that clears 4.5:1 on both the dark and the light page. */
.cloudcanvas-ui-button.is-danger { color: var(--cc-text, #e2e8f0); border-color: var(--cc-tone-danger, #f87171); border-width: 2px; font-weight: var(--cc-weight-semibold, 600); }
/* Off is unavailable for now: drawn as disabled is, and still there to be focused and read. */
.cloudcanvas-ui-button:disabled, .cloudcanvas-ui-button[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.cloudcanvas-ui-field {
  box-sizing: border-box;
  min-height: var(--cc-control-min, 28px);
  padding: var(--cc-space-1, 4px) var(--cc-space-2, 8px);
  font: inherit;
  font-size: var(--cc-type-md, 13px);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-input-bg, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--cc-input-border, rgba(255, 255, 255, 0.16));
  border-radius: var(--cc-radius-sm, 6px);
}
:is(.cloudcanvas-ui-button, .cloudcanvas-ui-field, .cloudcanvas-ui-splitter, .cloudcanvas-ui-results-option,
  .cloudcanvas-ui-dialog-panel, .cloudcanvas-ui-kanban-card, .cloudcanvas-ui-kanban-label[data-ui-id], .cloudcanvas-ui-calendar-day, .cloudcanvas-ui-calendar-day-head,
  .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-calendar-more, .cloudcanvas-ui-calendar-scroller, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-timeline-group-label, .cloudcanvas-ui-graph-node,
  .cloudcanvas-ui-breadcrumbs-open, .cloudcanvas-ui-tree-row, .cloudcanvas-ui-chips-toggle, .cloudcanvas-ui-chips-remove,
  .cloudcanvas-ui-navbar-link):focus-visible {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: var(--cc-focus-ring-offset, 2px);
}
/* Its parent clips what is drawn outside it, so the hour grid wears the ring inside. */
.cloudcanvas-ui-calendar-scroller:focus-visible { outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px)); }
.cloudcanvas-ui-dialog, .cloudcanvas-ui-tabs, .cloudcanvas-ui-results, .cloudcanvas-ui-status, .cloudcanvas-ui-toasts,
.cloudcanvas-ui-composer, .cloudcanvas-ui-voice, .cloudcanvas-ui-markdown, .cloudcanvas-ui-breadcrumbs, .cloudcanvas-ui-tree,
.cloudcanvas-ui-progress, .cloudcanvas-ui-chips, .cloudcanvas-ui-navbar, .cloudcanvas-ui-empty, .cloudcanvas-ui-menu-panel {
  font-family: var(--cc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  color: var(--cc-text, #e2e8f0);
}
[class^="cloudcanvas-ui-"][hidden], [class*=" cloudcanvas-ui-"][hidden] { display: none; }
.cloudcanvas-ui-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Centred by its own margin: a host that resets every margin takes the browser's away. One that is not modal stands above the toasts. */
.cloudcanvas-ui-dialog {
  z-index: var(--cc-z-ui-dialog, 1350);
  width: min(var(--cc-ui-dialog-width, 36rem), calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  margin: auto;
  padding: 0;
  background: transparent;
  border: 0;
  overflow: visible;
}
.cloudcanvas-ui-dialog::backdrop { background: var(--cc-ui-backdrop, rgba(2, 6, 23, 0.6)); }
.cloudcanvas-ui-dialog.is-modal:not([open]) { display: none; }
.cloudcanvas-ui-dialog-panel {
  display: grid;
  gap: var(--cc-space-3, 12px);
  max-height: calc(100dvh - 2rem);
  overflow: auto;
  padding: var(--cc-space-4, 16px);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
  backdrop-filter: blur(var(--cc-card-blur, 12px));
}
.cloudcanvas-ui-dialog-header { display: flex; align-items: center; justify-content: space-between; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-dialog-title { margin: 0; font-size: var(--cc-type-lg, 15px); font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-dialog-description { margin: 0; color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-dialog-body { min-width: 0; }

/* A drawer's place and size are the host's; the sheet says where it folds to: its control's aim, or its own top edge. */
.cloudcanvas-ui-drawer { transform-origin: var(--drawer-origin-x, 50%) var(--drawer-origin-y, 0%); }

.cloudcanvas-ui-splitter { flex: none; position: relative; min-width: 8px; min-height: 8px; touch-action: none; cursor: col-resize; }
.cloudcanvas-ui-splitter[aria-orientation="horizontal"] { cursor: row-resize; }
.cloudcanvas-ui-splitter::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 2px;
  background: var(--cc-card-border, rgba(255, 255, 255, 0.1));
}
.cloudcanvas-ui-splitter[aria-orientation="horizontal"]::before { width: auto; height: 2px; }
.cloudcanvas-ui-splitter:hover::before, .cloudcanvas-ui-splitter.is-dragging::before { background: var(--cc-accent, #38bdf8); }

.cloudcanvas-ui-results-list { display: grid; gap: 2px; }
.cloudcanvas-ui-results-option {
  display: grid;
  padding: var(--cc-space-2, 8px);
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-results-option[aria-selected="true"], .cloudcanvas-ui-results-option:hover { background: var(--cc-ui-selected, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22))); }
.cloudcanvas-ui-results-detail { font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-results-empty { margin: 0; padding: var(--cc-space-2, 8px); color: var(--cc-text-muted, #94a3b8); }

.cloudcanvas-ui-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-status-message { color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-status[data-status="error"] .cloudcanvas-ui-status-label { color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-status[data-status="unavailable"] .cloudcanvas-ui-status-label { color: var(--cc-tone-warning, #eab308); }

/* Held off each edge by a token of its own, and by nothing else: no margin a host gives its sections moves it. */
.cloudcanvas-ui-toasts {
  position: fixed;
  inset: auto var(--cc-ui-toast-inset-right, var(--cc-space-3, 12px)) var(--cc-ui-toast-inset-bottom, var(--cc-ui-toast-offset, 16px)) var(--cc-ui-toast-inset-left, var(--cc-space-3, 12px));
  z-index: var(--cc-z-ui-toast, 1300);
  display: grid;
  justify-items: center;
  margin: 0;
  gap: var(--cc-space-2, 8px);
  pointer-events: none;
}
.cloudcanvas-ui-toast {
  display: flex;
  align-items: center;
  gap: var(--cc-space-2, 8px);
  max-width: min(32rem, 100%);
  padding: var(--cc-space-2, 8px) var(--cc-space-3, 12px);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-left: 4px solid var(--cc-tone-info, #38bdf8);
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
  pointer-events: auto;
}
.cloudcanvas-ui-toast[data-tone="success"] { border-left-color: var(--cc-tone-success, #22c55e); }
.cloudcanvas-ui-toast[data-tone="warning"] { border-left-color: var(--cc-tone-warning, #eab308); }
.cloudcanvas-ui-toast[data-tone="danger"] { border-left-color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-toast-message { flex: 1; }

.cloudcanvas-ui-composer { display: grid; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-composer-input { width: 100%; min-height: 4.5rem; resize: vertical; }
.cloudcanvas-ui-composer-actions { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-end; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-composer-voice { margin-right: auto; }
.cloudcanvas-ui-composer.is-pending .cloudcanvas-ui-composer-input { opacity: 0.7; }

.cloudcanvas-ui-voice { display: grid; gap: var(--cc-space-2, 8px); justify-items: start; }
.cloudcanvas-ui-voice.is-listening .cloudcanvas-ui-voice-mic { color: var(--cc-ui-on-accent, #0f172a); background: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-voice-consent, .cloudcanvas-ui-voice-review { display: flex; flex-wrap: wrap; gap: var(--cc-space-2, 8px); align-items: center; }
.cloudcanvas-ui-voice-consent-text { flex-basis: 100%; margin: 0; font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-voice-status { margin: 0; font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-voice-status:empty { display: none; }
.cloudcanvas-ui-voice-preview { flex-basis: 100%; min-height: 3rem; }

.cloudcanvas-ui-markdown { line-height: 1.5; overflow-wrap: anywhere; }
.cloudcanvas-ui-markdown :is(p, ul, ol, blockquote, pre) { margin: 0 0 var(--cc-space-2, 8px); }
.cloudcanvas-ui-markdown :is(h1, h2, h3, h4, h5, h6) { margin: var(--cc-space-3, 12px) 0 var(--cc-space-1, 4px); font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-markdown :is(ul, ol) { padding-left: var(--cc-space-4, 16px); }
.cloudcanvas-ui-markdown blockquote {
  padding: 0 var(--cc-space-3, 12px);
  color: var(--cc-text-muted, #94a3b8);
  border-left: 3px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
}
.cloudcanvas-ui-markdown :is(code, pre) { font-family: var(--cc-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: var(--cc-type-sm, 12px); }
.cloudcanvas-ui-markdown pre { padding: var(--cc-space-2, 8px); overflow-x: auto; background: var(--cc-input-bg, rgba(255, 255, 255, 0.06)); border-radius: var(--cc-radius-sm, 6px); }
.cloudcanvas-ui-markdown a { color: var(--cc-accent, #38bdf8); }
.cloudcanvas-ui-markdown-task-item { list-style: none; }
.cloudcanvas-ui-markdown-mention { color: var(--cc-accent, #38bdf8); font-weight: var(--cc-weight-medium, 500); }

.cloudcanvas-ui-breadcrumbs { font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-breadcrumbs-list { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cc-space-1, 4px); margin: 0; padding: 0; list-style: none; }
.cloudcanvas-ui-breadcrumbs-item { position: relative; display: inline-flex; align-items: center; gap: var(--cc-space-1, 4px); min-width: 0; overflow-wrap: anywhere; }
.cloudcanvas-ui-breadcrumbs-item + .cloudcanvas-ui-breadcrumbs-item::before {
  content: "";
  flex: none;
  width: 0.4em;
  height: 0.4em;
  border-top: 1px solid var(--cc-text-muted, #94a3b8);
  border-right: 1px solid var(--cc-text-muted, #94a3b8);
  transform: rotate(45deg);
}
.cloudcanvas-ui-breadcrumbs-open {
  padding: 0 var(--cc-space-1, 4px);
  font: inherit;
  color: var(--cc-accent, #38bdf8);
  background: transparent;
  border: 0;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-breadcrumbs-open:hover { text-decoration: underline; }
.cloudcanvas-ui-breadcrumbs-item[aria-current="page"] { color: var(--cc-text, #e2e8f0); font-weight: var(--cc-weight-semibold, 600); }

.cloudcanvas-ui-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 var(--cc-space-1, 4px);
  font: inherit;
  font-size: var(--cc-type-xs, 11px);
  font-weight: var(--cc-weight-semibold, 600);
  line-height: 1;
  color: var(--cc-ui-on-accent, #0f172a);
  background: var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-pill, 9999px);
  box-sizing: border-box;
}
.cloudcanvas-ui-badge.is-dot {
  min-width: 0.5rem;
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
}
.cloudcanvas-ui-badge[data-tone="danger"] { background: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-badge[data-tone="warning"] { background: var(--cc-tone-warning, #eab308); }
.cloudcanvas-ui-badge[data-tone="success"] { background: var(--cc-tone-success, #22c55e); }
/* A flag is its SVG: the box keeps only the tone, stands in front of what it is planted on, and rises by what a host gives it. */
.cloudcanvas-ui-badge[data-shape="flag"] {
  z-index: var(--cc-z-ui-raised, 2);
  width: auto;
  min-width: 0;
  height: auto;
  padding: 0;
  color: var(--cc-accent, #38bdf8);
  background: transparent;
  border-radius: 0;
  transform: translateY(calc(-1 * var(--cc-ui-flag-rise, 0px)));
}
.cloudcanvas-ui-badge[data-shape="flag"][data-tone="danger"] { color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-badge[data-shape="flag"][data-tone="warning"] { color: var(--cc-tone-warning, #eab308); }
.cloudcanvas-ui-badge[data-shape="flag"][data-tone="success"] { color: var(--cc-tone-success, #22c55e); }
.cloudcanvas-ui-badge-flag { display: block; flex: none; overflow: visible; filter: drop-shadow(0 1px 1px var(--cc-ui-flag-shadow, rgba(2, 6, 23, 0.4))); }
.cloudcanvas-ui-badge-flag-pennant { fill: currentColor; }
.cloudcanvas-ui-badge-flag-staff { fill: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-badge-flag-lit { fill: var(--cc-ui-flag-light, #ffffff); stop-color: var(--cc-ui-flag-light, #ffffff); }
.cloudcanvas-ui-badge-flag-shaded { fill: var(--cc-ui-flag-shade, #020617); stop-color: var(--cc-ui-flag-shade, #020617); }
.cloudcanvas-ui-badge-flag-figure { fill: var(--cc-ui-on-accent, #0f172a); font-variant-numeric: tabular-nums; text-anchor: middle; }

/* One column as wide as the tree, whatever its rows hold: a label the tree has no room for ends in an ellipsis (and is said whole in its row's title), it does not widen the tree. */
.cloudcanvas-ui-tree { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; }
.cloudcanvas-ui-tree-row {
  display: flex;
  align-items: center;
  gap: var(--cc-space-1, 4px);
  width: 100%;
  min-height: var(--cc-control-min, 28px);
  padding: 0 var(--cc-space-2, 8px);
  font: inherit;
  text-align: left;
  color: inherit;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-tree-row:hover, .cloudcanvas-ui-tree-row[aria-selected="true"] { background: var(--cc-ui-selected, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22))); }
.cloudcanvas-ui-tree-row[aria-selected="true"] { font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-tree-indent { flex: none; width: calc(var(--tree-level, 0) * var(--cc-space-4, 16px)); }
.cloudcanvas-ui-tree-twisty { flex: none; display: inline-grid; place-items: center; width: 1.25em; height: 1.25em; visibility: hidden; }
.cloudcanvas-ui-tree-twisty::before {
  content: "";
  width: 0.4em;
  height: 0.4em;
  border-top: 1px solid var(--cc-text-muted, #94a3b8);
  border-right: 1px solid var(--cc-text-muted, #94a3b8);
  transform: rotate(45deg);
}
.cloudcanvas-ui-tree-row[aria-expanded] .cloudcanvas-ui-tree-twisty { visibility: visible; }
.cloudcanvas-ui-tree-row[aria-expanded="true"] .cloudcanvas-ui-tree-twisty::before { transform: rotate(135deg); }
.cloudcanvas-ui-tree-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloudcanvas-ui-tree-count { flex: none; font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-tree-row > .cloudcanvas-ui-badge { flex: none; }
.cloudcanvas-ui-tree[data-movable] .cloudcanvas-ui-tree-row { cursor: grab; }
.cloudcanvas-ui-tree.is-drag-active { cursor: grabbing; }
.cloudcanvas-ui-tree-row.is-dragging { pointer-events: none; opacity: 0.6; }
.cloudcanvas-ui-tree-row.is-drop-target { outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8)); outline-offset: -2px; }
.cloudcanvas-ui-tree-row.is-unmatched { opacity: 0.45; }
/* What a search that found nothing says, beside the rows: a polite live region, in the words the tree holds; empty, it takes no room. */
.cloudcanvas-ui-tree-status:empty { padding: 0; }
.cloudcanvas-ui-tree-status { margin: 0; padding: var(--cc-space-1, 4px) var(--cc-space-2, 8px); font-family: var(--cc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif); font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }

.cloudcanvas-ui-progress { display: grid; gap: var(--cc-space-1, 4px); }
.cloudcanvas-ui-progress-label { font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-progress-bar { width: 100%; height: 0.5rem; accent-color: var(--cc-accent, #38bdf8); }

.cloudcanvas-ui-chips { display: flex; flex-wrap: wrap; gap: var(--cc-space-1, 4px); }
.cloudcanvas-ui-chips-chip {
  display: inline-flex;
  align-items: stretch;
  max-width: 100%;
  font-size: var(--cc-type-sm, 12px);
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-sm, 6px);
}
.cloudcanvas-ui-chips-chip[data-tone] { border-left-width: 3px; }
.cloudcanvas-ui-chips-toggle, .cloudcanvas-ui-chips-label, .cloudcanvas-ui-chips-remove {
  display: inline-flex;
  align-items: center;
  min-height: var(--cc-control-min, 28px);
  padding: 0 var(--cc-space-2, 8px);
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
}
.cloudcanvas-ui-chips-toggle, .cloudcanvas-ui-chips-remove { cursor: pointer; }
.cloudcanvas-ui-chips-toggle:hover, .cloudcanvas-ui-chips-remove:hover { background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); }
.cloudcanvas-ui-chips-toggle[aria-pressed="true"] {
  font-weight: var(--cc-weight-semibold, 600);
  background: var(--cc-ui-selected, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)));
}
.cloudcanvas-ui-chips-remove { padding: 0 var(--cc-space-1, 4px); color: var(--cc-text-muted, #94a3b8); }

.cloudcanvas-ui-navbar-list {
  display: flex;
  gap: var(--cc-space-1, 4px);
  margin: 0;
  padding: 0;
  padding-top: var(--cc-ui-flag-rise, 0px);
  overflow-x: auto;
  list-style: none;
}
.cloudcanvas-ui-navbar-item { flex: none; }
.cloudcanvas-ui-navbar-icon { display: inline-flex; flex: none; }
/* A kit icon is as large as the text beside it and drawn in that text's colour, so what recolours the text recolours it. */
.cloudcanvas-ui-icon { flex: none; width: 1.25em; height: 1.25em; }
.cloudcanvas-ui-navbar-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cc-space-1, 4px);
  width: 100%;
  min-height: var(--cc-control-min, 28px);
  padding: var(--cc-space-1, 4px) var(--cc-space-3, 12px);
  font: inherit;
  color: var(--cc-text-muted, #94a3b8);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.cloudcanvas-ui-navbar-link:hover { color: var(--cc-text, #e2e8f0); }
.cloudcanvas-ui-navbar-link[aria-current="page"] {
  font-weight: var(--cc-weight-semibold, 600);
  color: var(--cc-text, #e2e8f0);
  border-bottom-color: var(--cc-accent, #38bdf8);
}
.cloudcanvas-ui-navbar[data-placement="bottom"] .cloudcanvas-ui-navbar-list { gap: 0; overflow-x: visible; }
.cloudcanvas-ui-navbar[data-placement="bottom"] .cloudcanvas-ui-navbar-item { flex: 1; min-width: 0; }
.cloudcanvas-ui-navbar[data-placement="bottom"] .cloudcanvas-ui-navbar-link { border-bottom: 0; border-top: 2px solid transparent; }
.cloudcanvas-ui-navbar[data-placement="bottom"] .cloudcanvas-ui-navbar-link[aria-current="page"] { border-top-color: var(--cc-accent, #38bdf8); }

.cloudcanvas-ui-empty { display: grid; justify-items: center; gap: var(--cc-space-2, 8px); padding: var(--cc-space-4, 16px); text-align: center; }
/* The icon is a graphic, told by its tone: muted for nothing and for loading, the info tone for what needs something first, the danger tone for what failed. */
.cloudcanvas-ui-empty-icon { display: inline-flex; color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-empty-icon > .cloudcanvas-ui-icon { width: 2.5rem; height: 2.5rem; }
.cloudcanvas-ui-empty[data-kind="locked"] .cloudcanvas-ui-empty-icon { color: var(--cc-tone-info, #38bdf8); }
.cloudcanvas-ui-empty[data-kind="error"] .cloudcanvas-ui-empty-icon { color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-empty-title { margin: 0; font-size: var(--cc-type-lg, 15px); font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-empty-body { margin: 0; color: var(--cc-text-muted, #94a3b8); }

.cloudcanvas-ui-combobox {
  position: absolute;
  z-index: var(--cc-z-ui-raised, 2);
  display: flex;
  flex-direction: column;
  max-width: min(24rem, calc(100vw - 2rem));
  max-height: 16rem;
  overflow: hidden;
  padding: var(--cc-space-1, 4px);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
  backdrop-filter: blur(var(--cc-card-blur, 12px));
}
/* The list is what scrolls, not the popup around it: the field controls the list (aria-controls), the one scroller a keyboard need not reach, since the field is operated through aria-activedescendant. The popup's max-height, the kit's or a host's, is what the list gives way to. */
.cloudcanvas-ui-combobox > .cloudcanvas-ui-results { display: flex; flex-direction: column; min-height: 0; }
.cloudcanvas-ui-combobox .cloudcanvas-ui-results-list { min-height: 0; overflow: auto; }

@media (pointer: coarse) {
  :is(.cloudcanvas-ui-button, .cloudcanvas-ui-field, .cloudcanvas-ui-breadcrumbs-open,
    .cloudcanvas-ui-tree-row, .cloudcanvas-ui-chips-toggle, .cloudcanvas-ui-chips-remove, .cloudcanvas-ui-navbar-link) { min-height: var(--cc-control-min-coarse, 44px); }
  /* A toast's controls say so themselves, whatever a host does to its buttons. */
  .cloudcanvas-ui-toast :is(.cloudcanvas-ui-toast-action, .cloudcanvas-ui-toast-dismiss) { min-width: var(--cc-control-min-coarse, 44px); min-height: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-splitter { min-width: 20px; min-height: 20px; }
}
@media (max-width: 40rem) {
  .cloudcanvas-ui-dialog { width: 100vw; max-width: 100vw; margin: auto 0 0; }
  .cloudcanvas-ui-dialog-panel { border-radius: var(--cc-radius-md, 10px) var(--cc-radius-md, 10px) 0 0; }
}

/* ------------------ UI KIT: SETTINGS ROWS ------------------ */

/* The words take the row; the box keeps its own column at the end. The row is the target, so the box can stay small. */
.cloudcanvas-ui-switch { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: var(--cc-space-3, 12px); min-height: 2.75rem; font: inherit; color: inherit; cursor: pointer; }
.cloudcanvas-ui-switch-text { display: flex; flex-wrap: wrap; align-items: baseline; min-width: 0; }
.cloudcanvas-ui-switch-label { min-width: 0; overflow-wrap: anywhere; }
.cloudcanvas-ui-switch-box { grid-column: 2; margin: 0; width: 1.25rem; height: 1.25rem; accent-color: var(--cc-accent, #38bdf8); cursor: inherit; }
.cloudcanvas-ui-switch-detail { flex-basis: 100%; font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-switch-detail[hidden] { display: none; }
/* The status is there before it has words, so it takes no room and no gap until it has some. Its words are the page's own ink: a tone's colour is a marker, never the only ink a note has. */
.cloudcanvas-ui-switch-status { font-size: var(--cc-type-sm, 12px); color: var(--cc-text, #e2e8f0); }
.cloudcanvas-ui-switch-status:not(:empty) { margin-inline-start: var(--cc-space-2, 8px); }
/* The marker a tone is told by: one dot, before the words of a status and of an invalid select's error. It is a :where(), with no specificity of its own, so the rule for each tone that follows it is the one that colours it. */
:where(.cloudcanvas-ui-switch-status:not(:empty), .cloudcanvas-ui-select-status:not(:empty), .cloudcanvas-ui-select[data-invalid] .cloudcanvas-ui-select-hint)::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin-inline-end: 0.4em;
  border-radius: var(--cc-radius-pill, 9999px);
  background: var(--cc-text-muted, #94a3b8);
}
.cloudcanvas-ui-switch-status[data-tone="success"]::before, .cloudcanvas-ui-select-status[data-tone="success"]::before { background: var(--cc-tone-success, #22c55e); }
.cloudcanvas-ui-switch-status[data-tone="warning"]::before, .cloudcanvas-ui-select-status[data-tone="warning"]::before { background: var(--cc-tone-warning, #eab308); }
.cloudcanvas-ui-switch-status[data-tone="danger"]::before, .cloudcanvas-ui-select-status[data-tone="danger"]::before { background: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-switch-status[data-tone="muted"]::before, .cloudcanvas-ui-select-status[data-tone="muted"]::before { background: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-switch-status[aria-live="assertive"], .cloudcanvas-ui-select-status[aria-live="assertive"] { font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-switch:has(.cloudcanvas-ui-switch-box:disabled) { opacity: 0.6; cursor: default; }
.cloudcanvas-ui-switch-box:focus-visible { outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8)); outline-offset: 2px; }

/* The select reads as the switch does: words first, the control at the end of the line. The row wraps, so on a phone the control stands under its words and never reaches past the row. */
.cloudcanvas-ui-select { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--cc-space-1, 4px) var(--cc-space-3, 12px); min-height: 2.75rem; font: inherit; color: inherit; }
.cloudcanvas-ui-select-label { flex: 1 1 10rem; min-width: 0; overflow-wrap: anywhere; }
.cloudcanvas-ui-select-control { flex: 0 1 14rem; min-width: 0; max-width: 100%; }
.cloudcanvas-ui-select-hint { flex-basis: 100%; margin: 0; font-size: var(--cc-type-sm, 12px); color: var(--cc-text, #e2e8f0); }
.cloudcanvas-ui-select-hint[hidden] { display: none; }
/* The status is a line of its own under the hint. Empty it is out of the row and not hidden: a region that comes with its words is not reliably read. */
.cloudcanvas-ui-select-status { flex-basis: 100%; margin: 0; font-size: var(--cc-type-sm, 12px); color: var(--cc-text, #e2e8f0); }
.cloudcanvas-ui-select-status:empty { position: absolute; flex-basis: auto; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.cloudcanvas-ui-select[data-invalid] .cloudcanvas-ui-select-control { border-color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-select[data-invalid] .cloudcanvas-ui-select-hint::before { background: var(--cc-tone-danger, #f87171); }

/* ------------------ UI KIT: OVERLAYS ------------------ */

.cloudcanvas-ui-confirm-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--cc-space-2, 8px); }

/* A popover stands in the viewport, sized by its content and held by the screen's width: placed by the control, so no ancestor clips it. */
.cloudcanvas-ui-popover {
  position: fixed;
  z-index: var(--cc-z-ui-popover, 1375);
  box-sizing: border-box;
  width: max-content;
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--cc-space-3, 12px);
  font-family: var(--cc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
}
/* The popover clips what is drawn outside it, so it wears its ring inside. */
.cloudcanvas-ui-popover:focus-visible {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}
/* ------------------ UI KIT: VIEWS ------------------ */

.cloudcanvas-ui-kanban, .cloudcanvas-ui-calendar, .cloudcanvas-ui-timeline, .cloudcanvas-ui-graph {
  font-family: var(--cc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  color: var(--cc-text, #e2e8f0);
}
:is(.cloudcanvas-ui-calendar, .cloudcanvas-ui-timeline, .cloudcanvas-ui-graph) { --item-more-size: 1.5rem; --item-more-room: calc(var(--item-more-size) + 6px); }
.cloudcanvas-ui-item-more {
  position: absolute;
  z-index: var(--cc-z-ui-raised, 2);
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: var(--item-more-size);
  height: var(--item-more-size);
  padding: 0;
  font: inherit;
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  border-radius: var(--cc-radius-pill, 9999px);
  cursor: pointer;
}
.cloudcanvas-ui-item-more > .cloudcanvas-ui-icon { width: 1rem; height: 1rem; }
.cloudcanvas-ui-item-more:is(:hover, :focus-visible) { background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); }
.cloudcanvas-ui-item-more:focus-visible { outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8)); outline-offset: var(--cc-focus-ring-offset, 2px); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-graph-node)[data-tone="success"] { border-left-color: var(--cc-tone-success, #22c55e); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-graph-node)[data-tone="warning"] { border-left-color: var(--cc-tone-warning, #eab308); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-graph-node)[data-tone="danger"] { border-left-color: var(--cc-tone-danger, #f87171); }
/* Category tones one to eight: the host's own palette, on the same edge. */
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="1"] { border-left-color: var(--cc-ui-tone-1, #60a5fa); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="2"] { border-left-color: var(--cc-ui-tone-2, #a78bfa); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="3"] { border-left-color: var(--cc-ui-tone-3, #f472b6); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="4"] { border-left-color: var(--cc-ui-tone-4, #fb923c); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="5"] { border-left-color: var(--cc-ui-tone-5, #facc15); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="6"] { border-left-color: var(--cc-ui-tone-6, #4ade80); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="7"] { border-left-color: var(--cc-ui-tone-7, #2dd4bf); }
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-chips-chip, .cloudcanvas-ui-tree-row)[data-tone="8"] { border-left-color: var(--cc-ui-tone-8, #94a3b8); }
:is(.cloudcanvas-ui-kanban-item, .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-graph-node).is-grabbed,
.cloudcanvas-ui-kanban-item.is-grabbed .cloudcanvas-ui-kanban-card {
  outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8));
  outline-offset: 2px;
}
/* Selected: a ring inside the item. */
:is(.cloudcanvas-ui-kanban-card, .cloudcanvas-ui-kanban-label[data-ui-id], .cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar, .cloudcanvas-ui-timeline-group-label).is-selected {
  box-shadow: var(--cc-ui-selected-ring, inset 0 0 0 2px var(--cc-accent, #38bdf8));
}
/* A heading that stands for an item: a button that reads as the heading it is. */
:is(.cloudcanvas-ui-kanban-label[data-ui-id], .cloudcanvas-ui-timeline-group-label) {
  padding: 0 var(--cc-space-1, 4px);
  font: inherit;
  text-align: start;
  color: var(--cc-text, #e2e8f0);
  background: transparent;
  border: 0;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}

/* Kanban */
.cloudcanvas-ui-kanban-lane {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(15rem, 1fr);
  gap: var(--cc-space-3, 12px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  isolation: isolate;
}
.cloudcanvas-ui-kanban-column {
  display: flex;
  flex-direction: column;
  min-height: 8rem;
  padding: var(--cc-space-2, 8px);
  background: var(--cc-scope-bg, rgba(0, 0, 0, 0.2));
  border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  border-radius: var(--cc-radius-md, 10px);
  scroll-snap-align: start;
}
.cloudcanvas-ui-kanban-column.is-drop-target { outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8)); }
.cloudcanvas-ui-kanban-column.is-refused { outline: 2px dashed var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-kanban-heading {
  display: flex;
  justify-content: space-between;
  margin: 0 0 var(--cc-space-2, 8px);
  font-size: var(--cc-type-sm, 12px);
  font-weight: var(--cc-weight-semibold, 600);
}
.cloudcanvas-ui-kanban-count { color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-kanban-cards { flex: 1; display: grid; align-content: start; gap: var(--cc-space-2, 8px); margin: 0; padding: 0; list-style: none; }
.cloudcanvas-ui-kanban-item.is-dragging { position: relative; z-index: var(--cc-z-ui-raised, 2); pointer-events: none; opacity: 0.85; }
.cloudcanvas-ui-kanban-card {
  display: grid;
  gap: 2px;
  width: 100%;
  padding: var(--cc-space-2, 8px) var(--cc-space-3, 12px);
  font: inherit;
  text-align: left;
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-card-bg, rgba(30, 41, 59, 0.85));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-left: 4px solid var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-sm, 6px);
  cursor: grab;
  touch-action: manipulation;
}
.cloudcanvas-ui-kanban-title { font-weight: var(--cc-weight-medium, 500); }
.cloudcanvas-ui-kanban-detail, .cloudcanvas-ui-kanban-meta { font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }

/* Calendar */
.cloudcanvas-ui-calendar { display: grid; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-calendar-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-calendar-nav, .cloudcanvas-ui-calendar-views { display: flex; gap: var(--cc-space-1, 4px); }
.cloudcanvas-ui-calendar-title { flex: 1 1 10rem; margin: 0; font-size: var(--cc-type-lg, 15px); font-weight: var(--cc-weight-semibold, 600); }
:is(.cloudcanvas-ui-calendar-view, .cloudcanvas-ui-timeline-scale)[aria-pressed="true"] { color: var(--cc-ui-on-accent, #0f172a); background: var(--cc-accent, #38bdf8); }
:is(.cloudcanvas-ui-calendar-month, .cloudcanvas-ui-calendar-time) { border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); border-radius: var(--cc-radius-md, 10px); overflow: hidden; }
:is(.cloudcanvas-ui-calendar-weekdays, .cloudcanvas-ui-calendar-week) { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cloudcanvas-ui-calendar-weekday { padding: var(--cc-space-1, 4px); font-size: var(--cc-type-xs, 11px); text-align: center; color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-calendar-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  min-height: 5.5rem;
  padding: var(--cc-space-1, 4px);
  border-top: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  border-left: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  cursor: pointer;
}
.cloudcanvas-ui-calendar-cell:first-child { border-left: 0; }
.cloudcanvas-ui-calendar-cell.is-outside { opacity: 0.55; }
:is(.cloudcanvas-ui-calendar-day, .cloudcanvas-ui-calendar-day-head, .cloudcanvas-ui-calendar-more) {
  font: inherit;
  font-size: var(--cc-type-sm, 12px);
  color: var(--cc-text, #e2e8f0);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.cloudcanvas-ui-calendar-day { align-self: flex-end; min-width: 1.75rem; min-height: 1.75rem; border-radius: var(--cc-radius-pill, 9999px); }
:is(.cloudcanvas-ui-calendar-cell.is-today .cloudcanvas-ui-calendar-day, .cloudcanvas-ui-calendar-day-head.is-today) {
  color: var(--cc-ui-on-accent, #0f172a);
  background: var(--cc-ui-today, var(--cc-accent, #38bdf8));
}
.cloudcanvas-ui-calendar-more { padding: 0 var(--cc-space-1, 4px); text-align: left; color: var(--cc-accent, #38bdf8); }
.cloudcanvas-ui-calendar-events { display: grid; gap: 2px; min-width: 0; }
.cloudcanvas-ui-calendar-event {
  position: relative;
  display: flex;
  gap: var(--cc-space-1, 4px);
  min-width: 0;
  padding: 0 var(--cc-space-1, 4px);
  overflow: hidden;
  font: inherit;
  font-size: var(--cc-type-xs, 11px);
  text-align: left;
  white-space: nowrap;
  color: var(--cc-ui-bar-text, var(--cc-text, #e2e8f0));
  background: var(--cc-ui-bar, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)));
  border: 0;
  border-left: 3px solid var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-calendar-event[data-movable] { cursor: grab; }
.cloudcanvas-ui-calendar-event-title { overflow: hidden; text-overflow: ellipsis; }
.cloudcanvas-ui-calendar-event-time { opacity: 0.8; }
:is(.cloudcanvas-ui-calendar-time-head, .cloudcanvas-ui-calendar-allday, .cloudcanvas-ui-calendar-time-grid) {
  display: grid;
  grid-template-columns: 3.5rem repeat(var(--calendar-days), minmax(0, 1fr));
}
.cloudcanvas-ui-calendar-day-head { padding: var(--cc-space-1, 4px); border-left: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-calendar-gutter { padding: var(--cc-space-1, 4px); font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-calendar-allday { border-top: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-calendar-allday-cell { display: grid; align-content: start; gap: 2px; min-height: 1.75rem; min-width: 0; padding: var(--cc-space-1, 4px); border-left: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-calendar-scroller { max-height: var(--cc-ui-time-height, 32rem); overflow-y: auto; border-top: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-calendar-time-grid { height: calc(var(--calendar-hours) * var(--cc-ui-hour-height, 48px)); }
.cloudcanvas-ui-calendar-hours { display: grid; grid-template-rows: repeat(var(--calendar-hours), 1fr); }
.cloudcanvas-ui-calendar-hour { padding: 0 var(--cc-space-1, 4px); font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); border-top: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-calendar-column {
  position: relative;
  min-width: 0;
  border-left: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  background-image: var(--cc-ui-hour-lines, repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.06) 0 1px, transparent 1px var(--cc-ui-hour-height, 48px)));
  cursor: pointer;
}
.cloudcanvas-ui-calendar-timed {
  position: absolute;
  top: calc(var(--calendar-top) * var(--cc-ui-hour-height, 48px) / 60);
  left: calc(var(--calendar-lane) * 100% / var(--calendar-lanes) + 1px);
  width: calc(100% / var(--calendar-lanes) - 2px);
  height: calc(var(--calendar-length) * var(--cc-ui-hour-height, 48px) / 60 - 2px);
  flex-direction: column;
  white-space: normal;
}

@media (max-width: 40rem) {
  .cloudcanvas-ui-kanban-lane { grid-auto-columns: 85%; }
  :is(.cloudcanvas-ui-calendar-time-head, .cloudcanvas-ui-calendar-allday, .cloudcanvas-ui-calendar-time-grid) {
    grid-template-columns: 2.5rem repeat(var(--calendar-days), minmax(0, 1fr));
  }
  .cloudcanvas-ui-calendar-cell { min-height: 4rem; }
}
@media (pointer: coarse) {
  /*
   * A button a view's toolbar draws is 44px wide as it is tall: the glyphs (zoom, previous, next) and the short words (Fit).
   * A day's number and a day's heading keep what is drawn - the number's circle, the heading's fill - and the rest of the
   * 44px is transparent border round it, which is part of the button and takes the press; a "more" link is as tall as a finger.
   */
  :is(.cloudcanvas-ui-graph-toolbar, .cloudcanvas-ui-calendar-toolbar, .cloudcanvas-ui-timeline-toolbar) .cloudcanvas-ui-button { min-width: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-calendar-day { min-width: var(--cc-control-min-coarse, 44px); min-height: var(--cc-control-min-coarse, 44px); padding: 0; border: calc((var(--cc-control-min-coarse, 44px) - 1.75rem) / 2) solid transparent; }
  .cloudcanvas-ui-calendar-day-head { min-height: var(--cc-control-min-coarse, 44px); border-block: calc((var(--cc-control-min-coarse, 44px) - 2.25rem) / 2) solid transparent; }
  :is(.cloudcanvas-ui-calendar-cell.is-today .cloudcanvas-ui-calendar-day, .cloudcanvas-ui-calendar-day-head.is-today) { background-clip: padding-box; }
  .cloudcanvas-ui-calendar-more { min-height: var(--cc-control-min-coarse, 44px); }
  :is(.cloudcanvas-ui-kanban-label[data-ui-id], .cloudcanvas-ui-timeline-group-label) { min-height: var(--cc-control-min-coarse, 44px); }
  /* Room for one whole target: the all-day strip, and a day of the month under its number. A timeline row sets its own height, in ./timeline.js: its rule comes later in the sheet. */
  .cloudcanvas-ui-calendar-allday-cell { min-height: calc(var(--cc-control-min-coarse, 44px) + 2 * var(--cc-space-1, 4px)); }
  .cloudcanvas-ui-calendar-cell { min-height: 6.25rem; }

  /* The 44px targets of what is drawn smaller: see the head of this file. */
  :is(.cloudcanvas-ui-calendar, .cloudcanvas-ui-timeline, .cloudcanvas-ui-graph) { --target: var(--cc-control-min-coarse, 44px); --target-under: -1; }
  :is(.cloudcanvas-ui-calendar, .cloudcanvas-ui-timeline) { --item-more-size: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-item-more > .cloudcanvas-ui-icon { width: 1.25rem; height: 1.25rem; }
  .cloudcanvas-ui-graph-node { --target: calc(var(--cc-control-min-coarse, 44px) / var(--graph-k, 1)); }
  .cloudcanvas-ui-calendar-month { isolation: isolate; }
  .cloudcanvas-ui-calendar-day { position: relative; z-index: var(--cc-z-ui-raised, 2); }
  :is(.cloudcanvas-ui-calendar-events, .cloudcanvas-ui-calendar-allday-cell, .cloudcanvas-ui-calendar-column, .cloudcanvas-ui-timeline-track, .cloudcanvas-ui-graph-nodes) { isolation: isolate; }
  :is(.cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar.is-point) { overflow: visible; }
  /* A chip cuts nothing itself now: its time does, as its title does, and still gives way last. */
  .cloudcanvas-ui-calendar-event-time { flex: none; max-width: 100%; max-height: 100%; overflow: hidden; }
  .cloudcanvas-ui-timeline-bar.is-point::before { border-radius: inherit; }
  :is(.cloudcanvas-ui-calendar-event, .cloudcanvas-ui-timeline-bar.is-point, .cloudcanvas-ui-graph-node)::after {
    content: "";
    position: absolute;
    top: 50%;
    left: calc(50% - 1.5px);
    z-index: var(--target-under);
    width: max(100%, var(--target));
    height: max(100%, var(--target));
    translate: -50% -50%;
  }
  .cloudcanvas-ui-calendar .cloudcanvas-ui-calendar-event::after { top: 0; translate: -50% 0; }
  .cloudcanvas-ui-calendar .cloudcanvas-ui-calendar-timed::after { left: 0; width: 100%; translate: none; }
  .cloudcanvas-ui-timeline-bar.is-point::after { rotate: -45deg; }
  /* A dimmed node is faded by opacity, a stacking context of its own: its reach could not lie under the node drawn before it, so it has none. */
  .cloudcanvas-ui-graph-node:is(.is-dim, .is-unmatched)::after { pointer-events: none; }
}
/* ------------------ UI KIT: CALENDAR ------------------ */

/* A drag across the grid selects no text on its way. */
.cloudcanvas-ui-calendar-body.is-drag-active { user-select: none; }

/* The line under the toolbar: what the selection can do. */
.cloudcanvas-ui-calendar-hint { margin: 0; font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }

/* The handle on a timed event's bottom edge: it resizes, and says so under the pointer. */
.cloudcanvas-ui-calendar-event-handle { position: absolute; right: 0; bottom: 0; left: 0; height: 6px; cursor: ns-resize; }
.cloudcanvas-ui-calendar-event-handle::before {
  content: "";
  position: absolute;
  bottom: 2px;
  left: calc(50% - 7px);
  width: 14px;
  height: 2px;
  background: currentcolor;
  border-radius: var(--cc-radius-sm, 6px);
  opacity: 0;
}
.cloudcanvas-ui-calendar-event:is(:hover, :focus-visible, .is-selected, .is-grabbed) .cloudcanvas-ui-calendar-event-handle::before { opacity: 0.7; }

/* The "more" button of the selected event, and the room its chip keeps for it. */
:is(.cloudcanvas-ui-calendar-events, .cloudcanvas-ui-calendar-allday-cell) { position: relative; }
.cloudcanvas-ui-calendar-event.is-holding-more { padding-right: var(--item-more-room); }
:is(.cloudcanvas-ui-calendar-events, .cloudcanvas-ui-calendar-allday-cell) > .cloudcanvas-ui-calendar-more-actions { grid-column: 1 / 2; top: 50%; right: 3px; translate: 0 -50%; }
.cloudcanvas-ui-calendar-more-actions.is-timed {
  top: calc(var(--calendar-top) * var(--cc-ui-hour-height, 48px) / 60 + 2px);
  right: auto;
  left: calc((var(--calendar-lane) + 1) * 100% / var(--calendar-lanes) - var(--item-more-size) - 3px);
  translate: none;
}

/* The range being made: a band of slots with their times in it down a column; the days of a month or the strip, lit. Its words are the page's text: the band is a wash over the page, and a bar's text colour is for a bar's accent fill. */
.cloudcanvas-ui-calendar-draft {
  position: absolute;
  top: calc(var(--calendar-top) * var(--cc-ui-hour-height, 48px) / 60);
  right: 1px;
  left: 1px;
  height: calc(var(--calendar-length) * var(--cc-ui-hour-height, 48px) / 60);
  padding: 0 var(--cc-space-1, 4px);
  overflow: hidden;
  font-size: var(--cc-type-xs, 11px);
  white-space: nowrap;
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22));
  border: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8));
  border-radius: var(--cc-radius-sm, 6px);
  pointer-events: none;
}
.cloudcanvas-ui-calendar-cell.is-range, .cloudcanvas-ui-calendar-allday-cell.is-range { background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8)); outline-offset: -2px; }

@media (pointer: coarse) {
  .cloudcanvas-ui-calendar-event-handle { height: 14px; }
  /* The handle's reach runs on from it, down over the ground below the event and out over its edge: under every event, so a neighbour below keeps its own. */
  .cloudcanvas-ui-calendar-event-handle::after { content: ""; position: absolute; top: 0; right: 0; left: -3px; z-index: var(--target-under); height: var(--cc-control-min-coarse, 44px); }
}
/* ------------------ UI KIT: GRAPH ------------------ */

.cloudcanvas-ui-graph { display: grid; gap: var(--cc-space-2, 8px); min-width: 0; }
.cloudcanvas-ui-graph-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cc-space-1, 4px); }
.cloudcanvas-ui-graph-search { flex: 1 1 10rem; min-width: 0; max-width: 20rem; }
.cloudcanvas-ui-graph-hint { margin: 0; font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-graph-viewport {
  position: relative;
  height: var(--cc-ui-graph-height, 24rem);
  overflow: hidden;
  touch-action: none;
  background: var(--cc-scope-bg, rgba(0, 0, 0, 0.2));
  border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  border-radius: var(--cc-radius-md, 10px);
  cursor: grab;
}
.cloudcanvas-ui-graph-viewport:is(.is-panning, .is-drag-active) { cursor: grabbing; }
:is(.cloudcanvas-ui-graph-world, .cloudcanvas-ui-graph-edges, .cloudcanvas-ui-graph-nodes) { position: absolute; top: 0; left: 0; transform-origin: 0 0; overflow: visible; }
.cloudcanvas-ui-graph-edges { pointer-events: none; }
.cloudcanvas-ui-graph-overlay { z-index: var(--cc-z-ui-raised, 2); }

.cloudcanvas-ui-graph-edge { fill: none; stroke: var(--cc-connector, rgba(56, 189, 248, 0.6)); stroke-width: 1.5; }
.cloudcanvas-ui-graph-edge.is-related { stroke-dasharray: 6 5; }
.cloudcanvas-ui-graph-edge.is-depends-on { stroke: var(--cc-accent, #38bdf8); stroke-width: 2; }
.cloudcanvas-ui-graph-arrow { fill: var(--cc-accent, #38bdf8); }
/* A label is a chip on its edge: the surface's colour behind its words, so the line does not run through them. */
.cloudcanvas-ui-graph-edge-label-back { fill: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))); stroke: var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); stroke-width: 1px; }
.cloudcanvas-ui-graph-edge-label-text { fill: var(--cc-text-muted, #94a3b8); font-size: var(--cc-type-xs, 11px); }
.cloudcanvas-ui-graph-draft { fill: none; stroke: var(--cc-accent, #38bdf8); stroke-width: 2; stroke-dasharray: 4 4; }

.cloudcanvas-ui-graph-node {
  position: absolute;
  top: var(--graph-y);
  left: var(--graph-x);
  box-sizing: border-box;
  display: grid;
  grid-template-rows: auto auto;
  align-content: space-between;
  padding: var(--cc-space-1, 4px) var(--cc-space-2, 8px);
  font: inherit;
  font-size: var(--cc-type-md, 13px);
  line-height: 1.3;
  text-align: left;
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-card-bg, rgba(30, 41, 59, 0.85));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-left: 4px solid var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-1, 0 4px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.06));
  cursor: pointer;
  user-select: none;
}
.cloudcanvas-ui-graph[data-can-move] .cloudcanvas-ui-graph-node { cursor: grab; }
/* Two lines of the title, then an ellipsis: the node's tooltip and name hold the rest. */
.cloudcanvas-ui-graph-node-label {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  font-weight: var(--cc-weight-medium, 500);
}
.cloudcanvas-ui-graph-node-meta { display: flex; align-items: center; gap: var(--cc-space-1, 4px); min-width: 0; font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-graph-status {
  flex: none;
  max-width: 50%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  padding: 0 var(--cc-space-1, 4px);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-btn-bg, rgba(56, 189, 248, 0.12));
  border-radius: var(--cc-radius-pill, 9999px);
}
.cloudcanvas-ui-graph-time { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cloudcanvas-ui-graph-toggle {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: auto;
  padding: 0 var(--cc-space-1, 4px);
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-pill, 9999px);
}
/* A toggle that folds wears a chevron after its count: right to open what is folded, left to fold it back. */
.cloudcanvas-ui-graph[data-can-fold] .cloudcanvas-ui-graph-toggle { cursor: pointer; }
.cloudcanvas-ui-graph[data-can-fold] .cloudcanvas-ui-graph-toggle::before {
  content: "";
  order: 1;
  width: 0.35em;
  height: 0.35em;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  rotate: -135deg;
}
.cloudcanvas-ui-graph[data-can-fold] .cloudcanvas-ui-graph-node[aria-expanded="false"] .cloudcanvas-ui-graph-toggle::before { rotate: 45deg; }
.cloudcanvas-ui-graph-node[aria-expanded="false"] .cloudcanvas-ui-graph-toggle { color: var(--cc-ui-on-accent, #0f172a); background: var(--cc-accent, #38bdf8); border-color: var(--cc-accent, #38bdf8); }
.cloudcanvas-ui-graph-handle {
  position: absolute;
  top: 50%;
  right: 0;
  display: none;
  width: 12px;
  height: 12px;
  box-sizing: border-box;
  translate: 50% -50%;
  background: var(--cc-card-bg, rgba(30, 41, 59, 0.85));
  border: 2px solid var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-pill, 9999px);
  opacity: 0;
  cursor: crosshair;
}
.cloudcanvas-ui-graph[data-can-link] .cloudcanvas-ui-graph-handle { display: block; }
.cloudcanvas-ui-graph-node:is(:hover, :focus-visible, .is-selected) .cloudcanvas-ui-graph-handle { opacity: 1; }
/* A mouse gets a whole target of what is drawn small: the fold toggle (24x16) and the link handle (12) reach 24px on the screen, kept within the node's own room - 30 world units tall, so a map at the first view's least scale, 0.8, still has them whole. The reach of the handle starts at its own edge and runs out from the node. */
:where(.cloudcanvas-ui-graph[data-can-fold]) .cloudcanvas-ui-graph-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, min(calc(24px / var(--graph-k, 1)), 40px));
  height: max(100%, min(calc(24px / var(--graph-k, 1)), 30px));
  translate: -50% -50%;
}
.cloudcanvas-ui-graph-handle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: -2px;
  width: max(100%, min(calc(24px / var(--graph-k, 1)), 40px));
  height: max(100%, min(calc(24px / var(--graph-k, 1)), 30px));
  translate: 0 -50%;
}

/* The "more" button of the selected node: its top right corner, the title keeping its room. Its reach is its own. */
.cloudcanvas-ui-graph-more { top: 3px; right: 3px; }
.cloudcanvas-ui-graph-more::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, min(calc(24px / var(--graph-k, 1)), 36px));
  height: max(100%, min(calc(24px / var(--graph-k, 1)), 36px));
  translate: -50% -50%;
}
/* Drawn at the graph's zoom it would shrink to a dot on a map zoomed out to the 0.5 a big one opens at: it holds 16px on the screen, up to 36 of the graph's own units. */
.cloudcanvas-ui-graph-node { --item-more-size: min(max(1.5rem, calc(16px / var(--graph-k, 1))), 2.25rem); --item-more-room: calc(var(--item-more-size) + 4px); }
.cloudcanvas-ui-graph[data-can-menu] .cloudcanvas-ui-graph-node.is-selected .cloudcanvas-ui-graph-node-label { padding-right: var(--item-more-room); }

.cloudcanvas-ui-graph-node.is-selected {
  box-shadow: var(--cc-ui-selected-ring, inset 0 0 0 2px var(--cc-accent, #38bdf8)), var(--cc-shadow-1, 0 4px 16px rgba(0, 0, 0, 0.4));
}
.cloudcanvas-ui-graph-node.is-path { border-color: var(--cc-accent, #38bdf8); }
:is(.cloudcanvas-ui-graph-node, .cloudcanvas-ui-graph-edge, .cloudcanvas-ui-graph-edge-label).is-dim, .cloudcanvas-ui-graph-node.is-unmatched { opacity: 0.4; }
.cloudcanvas-ui-graph-node.is-drop-target { outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8)); outline-offset: 3px; }
.cloudcanvas-ui-graph-node.is-dragging {
  z-index: var(--cc-z-ui-raised, 2);
  pointer-events: none;
  opacity: 0.85;
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55));
}

.cloudcanvas-ui-graph-minimap {
  position: absolute;
  right: var(--cc-space-2, 8px);
  bottom: var(--cc-space-2, 8px);
  z-index: var(--cc-z-ui-raised, 2);
  width: 10rem;
  height: 6.25rem;
  overflow: hidden;
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
  border-radius: var(--cc-radius-sm, 6px);
  box-shadow: var(--cc-shadow-1, 0 4px 16px rgba(0, 0, 0, 0.4));
  touch-action: none;
  cursor: pointer;
}
.cloudcanvas-ui-graph-minimap-picture { display: block; width: 100%; height: 100%; }
.cloudcanvas-ui-graph-minimap-node { fill: var(--cc-text-muted, #94a3b8); fill-opacity: 0.6; }
.cloudcanvas-ui-graph-minimap-node.is-selected { fill: var(--cc-accent, #38bdf8); fill-opacity: 1; }
.cloudcanvas-ui-graph-minimap-view { fill: var(--cc-btn-bg, rgba(56, 189, 248, 0.12)); stroke: var(--cc-accent, #38bdf8); stroke-width: 2; vector-effect: non-scaling-stroke; }

@media (max-width: 40rem) {
  .cloudcanvas-ui-graph-minimap { width: 6.5rem; height: 4.25rem; }
}
@media (pointer: coarse) {
  /* The toggle and the handle are drawn small, at the graph's zoom: a finger gets 44px of each on the screen. */
  :is(.cloudcanvas-ui-graph-toggle, .cloudcanvas-ui-graph-handle)::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, calc(var(--cc-control-min-coarse, 44px) / var(--graph-k, 1)));
    height: max(100%, calc(var(--cc-control-min-coarse, 44px) / var(--graph-k, 1)));
    translate: -50% -50%;
  }
  /* The handle's reach starts at the node's right edge and runs out from it, never over the node: the pill is the pill's, a node's middle is the node's. It is there for the node that is pointed at, focused or selected, as the handle is drawn. */
  .cloudcanvas-ui-graph-handle { pointer-events: none; }
  .cloudcanvas-ui-graph-node:is(:hover, :focus-visible, .is-selected) .cloudcanvas-ui-graph-handle { pointer-events: auto; }
  .cloudcanvas-ui-graph-handle::after { left: 7px; translate: 0 -50%; }
  /* The button is drawn at 24px and reaches a finger's 44px, which the room at a node's corner allows. */
  .cloudcanvas-ui-graph-more::after { width: max(100%, min(calc(var(--cc-control-min-coarse, 44px) / var(--graph-k, 1)), 52px)); height: max(100%, min(calc(var(--cc-control-min-coarse, 44px) / var(--graph-k, 1)), 52px)); }
  .cloudcanvas-ui-graph-node { --item-more-room: calc(var(--item-more-size) + 14px); }
}
/* ------------------ UI KIT: TIMELINE ------------------ */

.cloudcanvas-ui-timeline { --timeline-gutter: var(--cc-ui-gutter, 10rem); display: grid; gap: var(--cc-space-2, 8px); min-width: 0; }
.cloudcanvas-ui-timeline-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cc-space-2, 8px); }
.cloudcanvas-ui-timeline-scales { display: flex; gap: var(--cc-space-1, 4px); }
.cloudcanvas-ui-timeline-range { font-size: var(--cc-type-sm, 12px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-timeline-hint { margin: 0; font-size: var(--cc-type-xs, 11px); color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-timeline-sheet { position: relative; isolation: isolate; max-height: var(--cc-ui-timeline-height, 28rem); overflow: auto; touch-action: pan-x pan-y; border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); border-radius: var(--cc-radius-md, 10px); }
.cloudcanvas-ui-timeline-sheet.is-drag-active { user-select: none; }
.cloudcanvas-ui-timeline-grid { position: relative; width: calc(var(--timeline-gutter) + var(--timeline-width)); min-width: 100%; padding-bottom: var(--cc-space-2, 8px); }
.cloudcanvas-ui-timeline-axis { position: sticky; top: 0; z-index: var(--cc-z-ui-sticky, 3); display: flex; height: 1.75rem; background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))); border-bottom: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-timeline-corner { position: sticky; left: 0; z-index: var(--cc-z-ui-raised, 2); flex: none; width: var(--timeline-gutter); background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))); }
.cloudcanvas-ui-timeline-ticks { position: relative; flex: none; width: var(--timeline-width); }
.cloudcanvas-ui-timeline-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--timeline-x);
  padding: var(--cc-space-1, 4px);
  font-size: var(--cc-type-xs, 11px);
  white-space: nowrap;
  color: var(--cc-text-muted, #94a3b8);
  border-left: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1)));
}

/* The gutter's separator: a grip on the corner's edge, a cursor that says what a drag does. */
.cloudcanvas-ui-timeline-gutter-handle { position: absolute; top: 0; right: -3px; bottom: 0; width: 6px; cursor: col-resize; touch-action: none; border-radius: var(--cc-radius-sm, 6px); }
.cloudcanvas-ui-timeline-gutter-handle::after { content: ""; position: absolute; top: 6px; bottom: 6px; left: 2px; width: 2px; border-radius: var(--cc-radius-sm, 6px); background: var(--cc-text-muted, #94a3b8); opacity: 0.5; }
.cloudcanvas-ui-timeline-gutter-handle:is(:hover, :focus-visible, .is-grabbed)::after { background: var(--cc-accent, #38bdf8); opacity: 1; }
/* The separator is drawn 6px wide and takes a mouse 24px: it stands on the axis alone, so its reach has no neighbour to take a press from. */
.cloudcanvas-ui-timeline-gutter-handle::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 24px; translate: -50% 0; }
.cloudcanvas-ui-timeline-gutter-handle:focus-visible { outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8)); outline-offset: 0; }

/* A group's heading: a row of its own, level 1 of the treegrid. */
/* It is as wide as the sheet's content, so the empty track beside its name takes a dragged span; the name stays in view as the sheet is scrolled. */
.cloudcanvas-ui-timeline-group { position: relative; display: flex; }
.cloudcanvas-ui-timeline-group > .cloudcanvas-ui-timeline-track { position: absolute; top: 0; bottom: 0; left: var(--timeline-gutter); height: auto; }
/* The heading's cell is the title column's, as a row's title is: at least as wide, on its surface, so a summary or a band scrolled under it is hidden as a bar is under a title. */
.cloudcanvas-ui-timeline-group-cell { position: sticky; left: 0; z-index: var(--cc-z-ui-raised, 2); flex: none; box-sizing: border-box; min-width: var(--timeline-gutter); display: flex; align-items: center; gap: var(--cc-space-1, 4px); padding: var(--cc-space-1, 4px) var(--cc-space-2, 8px); font-size: var(--cc-type-sm, 12px); font-weight: var(--cc-weight-semibold, 600); color: var(--cc-text-muted, #94a3b8); background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))); }
.cloudcanvas-ui-timeline-group-label:focus-visible { outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8)); outline-offset: var(--cc-focus-ring-offset, 2px); }
/* The chevron: drawn, not written, so the heading's words are its name alone; it points down when the group is open and right when it is folded. */
.cloudcanvas-ui-timeline-group-toggle {
  position: relative;
  order: -1;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-timeline-group-toggle::before {
  content: "";
  position: absolute;
  top: calc(50% - 4px);
  left: calc(50% - 3px);
  width: 6px;
  height: 6px;
  border-right: 2px solid currentcolor;
  border-bottom: 2px solid currentcolor;
  rotate: 45deg;
}
.cloudcanvas-ui-timeline-group-toggle[aria-expanded="false"]::before { top: calc(50% - 3px); left: calc(50% - 4px); rotate: -45deg; }
.cloudcanvas-ui-timeline-group-toggle:is(:hover, :focus-visible) { color: var(--cc-text, #e2e8f0); background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); }
.cloudcanvas-ui-timeline-group-toggle:focus-visible { outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8)); outline-offset: 0; }
.cloudcanvas-ui-timeline-group-count { padding: 0 var(--cc-space-1, 4px); font-weight: var(--cc-weight-medium, 500); color: var(--cc-text-muted, #94a3b8); border: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); border-radius: var(--cc-radius-sm, 6px); }

.cloudcanvas-ui-timeline-row { display: flex; align-items: center; min-height: 2.25rem; border-bottom: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-timeline-label {
  position: sticky;
  left: 0;
  z-index: var(--cc-z-ui-raised, 2);
  flex: none;
  box-sizing: border-box;
  width: var(--timeline-gutter);
  padding: 0 var(--cc-space-2, 8px);
  overflow: hidden;
  font-size: var(--cc-type-sm, 12px);
  white-space: nowrap;
  text-overflow: ellipsis;
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  cursor: pointer;
}
.cloudcanvas-ui-timeline-label::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; border-right: 1px solid var(--cc-ui-grid-line, var(--cc-card-border, rgba(255, 255, 255, 0.1))); }
.cloudcanvas-ui-timeline-row.is-current .cloudcanvas-ui-timeline-label { font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-timeline-track { position: relative; flex: none; width: var(--timeline-width); height: 2.25rem; }
.cloudcanvas-ui-timeline[data-can-create] .cloudcanvas-ui-timeline-track { cursor: crosshair; }
/* The span being made: a band of the days it covers - its border within them - and its dates in a tag of their own. A title drawn beside a short bar or a milestone is centred on the row, where a band over those days would write its dates too, so the tag hangs below that line: its top is the row's middle (the band's own) and 0.85em down, past a title's half height at the line height of 1.6 a page may inherit, which on the last row is below the row, so the grid keeps room for it and the sheet does not grow when it is drawn - on the sheet's surface so it is read at 4.5:1 whatever is under it, in the page's text colour (see the calendar's band). */
.cloudcanvas-ui-timeline-draft {
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: var(--timeline-x);
  width: var(--timeline-w);
  box-sizing: border-box;
  overflow: visible;
  background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22));
  border: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8));
  border-radius: var(--cc-radius-sm, 6px);
  pointer-events: none;
}
.cloudcanvas-ui-timeline-draft-words {
  position: absolute;
  top: calc(50% + 0.85em);
  left: -2px;
  padding: 0 var(--cc-space-1, 4px);
  font-size: var(--cc-type-xs, 11px);
  line-height: 1;
  white-space: nowrap;
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border-radius: var(--cc-radius-sm, 6px);
}

/* A folded group's summary: the days its items cover, its name and count in the page's text; a press opens the group's item, so it points, and it is no row to drag a span across. */
.cloudcanvas-ui-timeline-summary {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: var(--timeline-x);
  width: var(--timeline-w);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  padding: 0 var(--cc-space-2, 8px);
  font-size: var(--cc-type-xs, 11px);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px dashed var(--cc-text-muted, #94a3b8);
  border-left: 4px solid var(--cc-text-muted, #94a3b8);
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-timeline-summary-title { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* A bar: its title inside (or beside it), its status in its outline and fill, its progress as the fill that is done. */
.cloudcanvas-ui-timeline-bar {
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: var(--timeline-x);
  width: var(--timeline-w);
  min-width: 1.25rem;
  display: flex;
  align-items: center;
  padding: 0 var(--cc-space-2, 8px);
  font: inherit;
  font-size: var(--cc-type-xs, 11px);
  color: var(--cc-ui-bar-text, var(--cc-text, #e2e8f0));
  background: var(--cc-ui-bar, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)));
  border: 1px solid var(--timeline-tone, var(--cc-accent, #38bdf8));
  border-left-width: 4px;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-timeline-bar[data-movable] { cursor: grab; }
.cloudcanvas-ui-timeline-bar[data-status-tone="success"] { --timeline-tone: var(--cc-tone-success, #22c55e); }
.cloudcanvas-ui-timeline-bar[data-status-tone="warning"] { --timeline-tone: var(--cc-tone-warning, #eab308); }
.cloudcanvas-ui-timeline-bar[data-status-tone="danger"] { --timeline-tone: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-timeline-bar[data-status-tone="muted"] { --timeline-tone: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-timeline-bar::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(var(--timeline-progress, 0) * 100%);
  background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22));
  border-radius: inherit;
}
.cloudcanvas-ui-timeline-bar[data-status-tone]::before { background: color-mix(in oklab, var(--timeline-tone) var(--timeline-fill, 40%), transparent); }
.cloudcanvas-ui-timeline-bar.is-point { top: 50%; bottom: auto; left: calc(var(--timeline-x) - 7px); width: 14px; height: 14px; padding: 0; translate: 0 -50%; rotate: 45deg; }
.cloudcanvas-ui-timeline-bar.is-short { padding: 0; }
.cloudcanvas-ui-timeline-bar-title { position: relative; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* The title of a milestone, or of a bar too short to hold it: beside it, a part of the same item. */
.cloudcanvas-ui-timeline-outside {
  position: absolute;
  top: 50%;
  left: calc(var(--timeline-x) + var(--timeline-w) + 22px);
  translate: 0 -50%;
  font-size: var(--cc-type-xs, 11px);
  white-space: nowrap;
  color: var(--cc-text, #e2e8f0);
  cursor: pointer;
}
.cloudcanvas-ui-timeline-outside.is-point { left: calc(var(--timeline-x) + 12px); }
.cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-outside { left: calc(var(--timeline-x) + var(--timeline-w) + 30px); }
.cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-outside.is-point { left: calc(var(--timeline-x) + 32px); }

/* The handle a link is dragged from: beside a bar's right edge, drawn when the host can link and the row is hovered, focused or selected. */
.cloudcanvas-ui-timeline-link {
  position: absolute;
  top: 50%;
  left: calc(var(--timeline-x) + var(--timeline-w) + 6px);
  width: 12px;
  height: 12px;
  box-sizing: border-box;
  z-index: var(--cc-z-ui-raised, 2);
  translate: 0 -50%;
  background: var(--cc-card-bg, rgba(30, 41, 59, 0.85));
  border: 2px solid var(--cc-accent, #38bdf8);
  border-radius: var(--cc-radius-pill, 9999px);
  opacity: 0;
  cursor: crosshair;
}
.cloudcanvas-ui-timeline-link.is-point { left: calc(var(--timeline-x) + 16px); }
/* A mouse gets 24px of the handle: from the bar's edge, a whole target, clear of the title drawn beside it. */
.cloudcanvas-ui-timeline-link::after { content: ""; position: absolute; top: 50%; left: -6px; width: 24px; height: 24px; translate: 0 -50%; }
.cloudcanvas-ui-timeline-row:is(:hover, :focus-within, .is-current) .cloudcanvas-ui-timeline-link { opacity: 1; }
.cloudcanvas-ui-timeline-bar.is-drop-target { outline: 2px dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8)); outline-offset: 2px; }

/* The dependencies: connectors in a layer of their own over the bars, a picture the pointer passes through everywhere - the bars are the pointer's, and so is the handle a link is dragged from, which stands above the layer where a connector starts. */
.cloudcanvas-ui-timeline-links {
  position: absolute;
  top: 0;
  left: var(--timeline-gutter);
  z-index: var(--cc-z-ui-raised, 2);
  width: var(--timeline-width);
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.cloudcanvas-ui-timeline-connector-line { fill: none; stroke: var(--cc-connector, rgba(56, 189, 248, 0.6)); stroke-width: 1.5; }
.cloudcanvas-ui-timeline-arrow { fill: var(--cc-accent, #38bdf8); }
.cloudcanvas-ui-timeline-draft-link { fill: none; stroke: var(--cc-accent, #38bdf8); stroke-width: 2; stroke-dasharray: 6 5; }

/* The handles at a bar's ends: each resizes, and says so under the pointer. */
:is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start) { position: absolute; top: 0; bottom: 0; width: min(10px, 30%); cursor: ew-resize; background: var(--cc-accent, #38bdf8); opacity: 0.4; }
.cloudcanvas-ui-timeline-handle { right: 0; border-radius: 0 var(--cc-radius-sm, 6px) var(--cc-radius-sm, 6px) 0; }
.cloudcanvas-ui-timeline-handle-start { left: 0; border-radius: var(--cc-radius-sm, 6px) 0 0 var(--cc-radius-sm, 6px); }
.cloudcanvas-ui-timeline-row:is(:hover, :focus-within, .is-current) :is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start) { opacity: 0.75; }
/* A mouse gets 24px of each end: inward from the bar's edge, never past a third of what is inside its borders (4px at the start, 1px at the end), so its middle is its own to move - a bar of half an hour is 20px wide, and its body is still its body; the handle is as tall as the bar. */
:is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start)::after { content: ""; position: absolute; top: 50%; width: min(24px, calc((var(--timeline-w) - 5px) / 3)); height: max(100%, 24px); translate: 0 -50%; }
.cloudcanvas-ui-timeline-handle::after { right: 0; }
.cloudcanvas-ui-timeline-handle-start::after { left: 0; }

/* The "more" button of the selected bar: where a title beside the bar would begin, which the selected row's title gives way to. */
.cloudcanvas-ui-timeline-more { top: 50%; left: calc(var(--timeline-x) + var(--timeline-w) + 22px); translate: 0 -50%; }
.cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-more { left: calc(var(--timeline-x) + var(--timeline-w) + 30px); }
.cloudcanvas-ui-timeline-more.is-point { left: calc(var(--timeline-x) + 12px); }
.cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-more.is-point { left: calc(var(--timeline-x) + 32px); }
.cloudcanvas-ui-timeline[data-can-menu] .cloudcanvas-ui-timeline-row.is-current:not(.is-crowded) .cloudcanvas-ui-timeline-outside { margin-left: var(--item-more-room); }
.cloudcanvas-ui-timeline-now {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--timeline-gutter) + var(--timeline-x));
  width: 2px;
  pointer-events: none;
  background: var(--cc-tone-danger, #f87171);
}

@media (max-width: 40rem) {
  .cloudcanvas-ui-timeline { --timeline-gutter: var(--cc-ui-gutter, 6rem); }
}
@media (pointer: coarse) {
  /* A finger gets a whole target at everything that is dragged or pressed: the toggle, the separator, a bar's handles. */
  .cloudcanvas-ui-timeline-group-toggle { width: var(--cc-control-min-coarse, 44px); height: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-timeline-gutter-handle { right: calc(-0.5 * var(--cc-control-min-coarse, 44px)); width: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-timeline-gutter-handle::after { left: calc(50% - 1px); }
  :is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start) { width: min(14px, 30%); }
  /* A bar's ends reach inward a third of the bar at most, so its body keeps a third; a bar too short for three targets is one, its ends inert. */
  :is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start)::after {
    content: "";
    position: absolute;
    top: 50%;
    width: min(var(--cc-control-min-coarse, 44px), calc(var(--timeline-w) / 3));
    height: var(--cc-control-min-coarse, 44px);
    translate: 0 -50%;
  }
  .cloudcanvas-ui-timeline-bar.is-short :is(.cloudcanvas-ui-timeline-handle, .cloudcanvas-ui-timeline-handle-start) { pointer-events: none; }
  /* The grab area of a bar drawn narrower than a finger is padding round it: it lies under the bar, so the bar keeps its own look. A folded group's summary is a whole target the same way. */
  .cloudcanvas-ui-timeline-bar { overflow: visible; }
  /* A milestone's reach stands over the title drawn beside it - a part of the same item - so a finger 12 to 22px from its middle moves the milestone, not just opens it. */
  .cloudcanvas-ui-timeline-bar.is-point { z-index: var(--cc-z-ui-raised, 2); }
  .cloudcanvas-ui-timeline-bar:not(.is-point)::after, .cloudcanvas-ui-timeline-summary::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: var(--target-under);
    width: max(100%, var(--target));
    height: max(100%, var(--target));
    translate: -50% -50%;
  }
  .cloudcanvas-ui-timeline-handle::after { right: 0; }
  .cloudcanvas-ui-timeline-handle-start::after { left: 0; }
  /*
   * THE LINK HANDLE'S REACH lies past the bar's right end - the whole 44px of it, starting at the bar's edge (a milestone's
   * right corner) - never over the bar: the middle of every bar is the bar's, to tap, to hold and to drag. Where a bar is
   * narrower than two targets the handle is there only for the item that is selected or focused; its title, drawn beside
   * it, stands clear of the reach.
   */
  .cloudcanvas-ui-timeline-link::after { content: ""; position: absolute; top: 50%; left: -6px; width: var(--cc-control-min-coarse, 44px); height: var(--cc-control-min-coarse, 44px); translate: 0 -50%; }
  .cloudcanvas-ui-timeline-link.is-point::after { left: 0; }
  .cloudcanvas-ui-timeline-link.is-narrow { pointer-events: none; }
  .cloudcanvas-ui-timeline-row:is(.is-current, :focus-within) .cloudcanvas-ui-timeline-link.is-narrow { pointer-events: auto; }
  .cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-outside { left: calc(var(--timeline-x) + var(--timeline-w) + var(--cc-control-min-coarse, 44px) + 8px); }
  .cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-outside.is-point { left: calc(var(--timeline-x) + var(--cc-control-min-coarse, 44px) + 20px); }
  .cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-more { left: calc(var(--timeline-x) + var(--timeline-w) + var(--cc-control-min-coarse, 44px) + 8px); }
  .cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-more.is-point { left: calc(var(--timeline-x) + var(--cc-control-min-coarse, 44px) + 20px); }
  .cloudcanvas-ui-timeline[data-can-link] .cloudcanvas-ui-timeline-row.is-current .cloudcanvas-ui-timeline-link { opacity: 1; }
  /* A row is one whole target tall, and so is its track: a bar's grab area and the link handle's reach lie within it. */
  .cloudcanvas-ui-timeline-row { min-height: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-timeline-track { height: var(--cc-control-min-coarse, 44px); }
  /* The axis is a target tall too, for the separator on its corner: 44px of content and its 1px rule below, whichever box a host sizes by. A row's title in the gutter, and the title beside a short bar, are the bar's: the whole height of the row. */
  .cloudcanvas-ui-timeline-axis { box-sizing: content-box; height: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-timeline-tick { display: flex; align-items: center; }
  .cloudcanvas-ui-timeline-label { align-self: stretch; line-height: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-timeline-outside { min-width: var(--cc-control-min-coarse, 44px); line-height: var(--cc-control-min-coarse, 44px); }
}

.cloudcanvas-ui-context-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cc-space-1, 4px);
}
.cloudcanvas-ui-context-actions-pin[aria-pressed="true"] {
  background: var(--cc-ui-selected, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)));
  font-weight: var(--cc-weight-semibold, 600);
}
.cloudcanvas-ui-context-window {
  position: fixed;
  box-sizing: border-box;
  top: calc(var(--context-viewport-top, 0px) + var(--context-viewport-height, 100dvh) - var(--cc-space-2, 8px) - env(safe-area-inset-bottom, 0px));
  right: calc(var(--context-viewport-right, 0px) + var(--cc-space-2, 8px) + env(safe-area-inset-right, 0px));
  transform: translateY(-100%);
  z-index: var(--cc-z-ui-context, 1200);
  width: min(28rem, calc(var(--context-viewport-width, 100vw) - 2 * var(--cc-space-2, 8px) - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)));
  max-height: calc(var(--context-viewport-height, 100dvh) - 2 * var(--cc-space-2, 8px) - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cc-space-2, 8px);
  overflow: auto;
  padding: var(--cc-space-3, 12px);
  font-family: var(--cc-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  color: var(--cc-text, #e2e8f0);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
  backdrop-filter: blur(var(--cc-card-blur, 12px));
  overflow-wrap: anywhere;
}
.cloudcanvas-ui-context-window:focus-visible {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}
.cloudcanvas-ui-context-window-header, .cloudcanvas-ui-context-window-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cc-space-2, 8px);
  min-width: 0;
  flex: none;
}
.cloudcanvas-ui-context-window-header { justify-content: space-between; }
.cloudcanvas-ui-context-window-title {
  flex: 1 1 100%;
  min-width: 0;
  margin: 0;
  font-size: var(--cc-type-lg, 15px);
  font-weight: var(--cc-weight-semibold, 600);
}
.cloudcanvas-ui-context-window-tools { justify-content: flex-end; width: 100%; }
.cloudcanvas-ui-context-window-description { flex: none; margin: 0; color: var(--cc-text-muted, #94a3b8); }
.cloudcanvas-ui-context-window-body { min-width: 0; min-height: 0; overflow: auto; }
.cloudcanvas-ui-context-window-body > * { max-width: 100%; box-sizing: border-box; }

/* ------------------ UI KIT: MENU ------------------ */

/* The menu's own box draws nothing and takes no room where it is mounted: the control places its panels in the viewport. */
.cloudcanvas-ui-menu { display: contents; }
.cloudcanvas-ui-menu-panel {
  position: fixed;
  z-index: var(--cc-z-ui-menu, 1400);
  box-sizing: border-box;
  display: grid;
  min-width: var(--cc-menu-min-width, 168px);
  overflow: auto;
  padding: var(--cc-space-1, 4px);
  font-size: var(--cc-type-md, 13px);
  background: var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85)));
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-md, 10px);
  box-shadow: var(--cc-shadow-2, 0 12px 32px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.09));
  backdrop-filter: blur(var(--cc-card-blur, 12px));
}
.cloudcanvas-ui-menu-item {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cc-space-3, 12px);
  min-width: 0;
  min-height: var(--cc-control-min, 28px);
  padding: var(--cc-space-1, 4px) var(--cc-space-3, 12px);
  font: inherit;
  text-align: start;
  white-space: nowrap;
  color: inherit;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: var(--cc-radius-sm, 6px);
  cursor: pointer;
}
.cloudcanvas-ui-menu-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cloudcanvas-ui-menu-icon { display: inline-flex; flex: none; }
/* One highlight: the pointer moves focus, so the item under it and the item the keys are on are the same item. An open submenu's item keeps it. */
.cloudcanvas-ui-menu-item:is(:hover, :focus, [aria-expanded="true"]):not(:disabled) { background: var(--cc-ui-selected, var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22))); }
.cloudcanvas-ui-menu-item:disabled { opacity: 0.5; cursor: not-allowed; }
/* The panel clips what is drawn outside it, so an item - and a menu with nothing to choose - wears the ring inside. */
:is(.cloudcanvas-ui-menu-item, .cloudcanvas-ui-menu-panel):focus-visible {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}
/* A dangerous item wears its tone as text. Under the highlight that tone loses its contrast: there the label is text again, and the edge carries the tone. */
.cloudcanvas-ui-menu-item[data-tone="danger"] { color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-menu-item[data-tone="danger"]:is(:hover, :focus):not(:disabled) { color: inherit; border-left-color: var(--cc-tone-danger, #f87171); }
.cloudcanvas-ui-menu-item[aria-haspopup="menu"]::after {
  content: "";
  flex: none;
  width: 0.4em;
  height: 0.4em;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: rotate(45deg);
}
.cloudcanvas-ui-menu-separator { height: 1px; margin: var(--cc-space-1, 4px) 0; background: var(--cc-card-border, rgba(255, 255, 255, 0.1)); }

@media (pointer: coarse) {
  .cloudcanvas-ui-menu-item { min-height: var(--cc-control-min-coarse, 44px); }
}

/* ------------------ UI KIT: TABS ------------------ */

/* A strip that scrolls clips, so it keeps the room a risen flag stands in. */
.cloudcanvas-ui-tabs {
  --tab-close: var(--cc-control-min, 28px);
  --tab-close-back: calc(-1 * var(--tab-close));
  display: flex;
  gap: var(--cc-space-1, 4px);
  padding-top: var(--cc-ui-flag-rise, 0px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.cloudcanvas-ui-tabs-item { display: inline-flex; align-items: center; flex: none; overflow-x: clip; scroll-snap-align: start; }
.cloudcanvas-ui-tabs-tab, .cloudcanvas-ui-tabs-close {
  min-height: var(--cc-control-min, 28px);
  font: inherit;
  color: var(--cc-text, #e2e8f0);
  background: transparent;
  border: 0;
  cursor: pointer;
}
/* A tab is one row: its mark, its label, its badge. The label is what gives way. */
.cloudcanvas-ui-tabs-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cc-space-1, 4px);
  max-width: var(--cc-ui-tab-width, 16rem);
  padding: var(--cc-space-1, 4px) var(--cc-space-3, 12px);
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.cloudcanvas-ui-tabs-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* The icon is a mark in the tab's own ink; it never shrinks, so the label is what gives way. A kit icon is as large as the label's text, so it makes no tab taller; a host's own element is as large as the host draws it. */
.cloudcanvas-ui-tabs-icon { display: inline-flex; flex: none; }
.cloudcanvas-ui-tabs-icon > .cloudcanvas-ui-icon { width: 1em; height: 1em; }
.cloudcanvas-ui-tabs-tab > .cloudcanvas-ui-badge { flex: none; }
.cloudcanvas-ui-tabs-tab[aria-selected="true"] { border-bottom-color: var(--cc-accent, #38bdf8); font-weight: var(--cc-weight-semibold, 600); }
.cloudcanvas-ui-tabs-tab:disabled { opacity: 0.5; cursor: not-allowed; }
/* A badge needs the height a tab's padding takes: the label is centred in the whole tab instead, where it already sat. */
.cloudcanvas-ui-tabs-tab.is-badged { padding-top: 0; padding-bottom: 0; }
/* A pinned tab stays put and cannot be closed: a small mark before its label says so, in the label's own colour. */
.cloudcanvas-ui-tabs-tab[data-pinned="true"]::before {
  content: "";
  flex: none;
  width: 0.375em;
  height: 0.375em;
  background: currentColor;
  border-radius: var(--cc-radius-pill, 9999px);
}
/* The close control stands back over the far end of its tab, in the room the tab keeps for it. */
.cloudcanvas-ui-tabs .is-closable > .cloudcanvas-ui-tabs-tab { padding-right: var(--tab-close); }
.cloudcanvas-ui-tabs-close { position: relative; flex: none; align-self: stretch; width: var(--tab-close); margin-left: var(--tab-close-back); padding: 0; }
/* The ring is worn inside: a strip cuts what is drawn outside its tabs. */
.cloudcanvas-ui-tabs-tab:focus-visible {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}

/* The folder face: opaque, the tab in front of whatever is behind it in its row. */
.cloudcanvas-ui-tabs[data-face="folder"] {
  --tab-face: linear-gradient(var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))), var(--cc-ui-surface, var(--cc-card-bg, rgba(30, 41, 59, 0.85))));
  --layer-shade: linear-gradient(var(--cc-ui-tab-layer, var(--cc-scope-bg, rgba(0, 0, 0, 0.2))), var(--cc-ui-tab-layer, var(--cc-scope-bg, rgba(0, 0, 0, 0.2))));
}
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-tab {
  position: relative;
  align-self: stretch;
  background-color: var(--cc-bg, #0f1117);
  background-image: var(--tab-face);
  border-top: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-left: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-right: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-radius: var(--cc-radius-sm, 6px) var(--cc-radius-sm, 6px) 0 0;
  box-shadow: var(--cc-ui-tab-layer-shadow, var(--cc-shadow-1, 0 4px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.06)));
}
/* One step back: a step lower, under one wash of shade. A flag that rises keeps its height. */
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-item:not(.is-active) { padding-top: var(--cc-ui-tab-layer-step, 3px); }
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-item:not(.is-active) > .cloudcanvas-ui-tabs-tab { background-image: var(--layer-shade), var(--tab-face); }
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-item:not(.is-active) .cloudcanvas-ui-badge[data-shape="flag"] {
  transform: translateY(calc(-1 * (var(--cc-ui-flag-rise, 0px) + min(var(--cc-ui-flag-rise, 0px), var(--cc-ui-tab-layer-step, 3px)))));
}

/* A tab in hand, and the bar where it would land. */
.cloudcanvas-ui-tabs.is-drag-active, .cloudcanvas-ui-tabs.is-drag-active button { cursor: grabbing; }
.cloudcanvas-ui-tabs-item.is-dragging > .cloudcanvas-ui-tabs-tab {
  outline: var(--cc-focus-ring-width, 2px) dashed var(--cc-ui-drop, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}
.cloudcanvas-ui-tabs-item[data-drop] { position: relative; }
.cloudcanvas-ui-tabs-item[data-drop]::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  z-index: var(--cc-z-ui-raised, 2);
  width: var(--cc-focus-ring-width, 2px);
  background: var(--cc-ui-drop, var(--cc-accent, #38bdf8));
  outline: 1px solid var(--cc-bg, #0f1117);
}
.cloudcanvas-ui-tabs-item[data-drop="after"]::after { inset: 0 0 0 auto; }

/* Under a finger a tab is 44px tall and its close control 44px wide. */
@media (pointer: coarse) {
  .cloudcanvas-ui-tabs { --tab-close: var(--cc-control-min-coarse, 44px); }
  .cloudcanvas-ui-tabs-tab, .cloudcanvas-ui-tabs-close { min-height: var(--cc-control-min-coarse, 44px); }
}

/* ------------------ UI KIT: TAB LAYERS ------------------ */

.cloudcanvas-ui-tabs-layers { display: inline-flex; align-self: stretch; }
.cloudcanvas-ui-tabs-layer {
  position: relative;
  flex: none;
  box-sizing: border-box;
  min-height: var(--cc-control-min, 28px);
  padding: 0;
  font: inherit;
  font-size: var(--cc-type-sm, 12px);
  color: var(--cc-text, #e2e8f0);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.cloudcanvas-ui-tabs-layer:disabled { opacity: 0.5; cursor: not-allowed; }
/* The face carries the label, and cuts one that is too long for it. */
.cloudcanvas-ui-tabs-layer-face { box-sizing: border-box; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The ring is the face's, inside it: on a folder strip the face is in front of every neighbour by then, and wider than the place it left. */
.cloudcanvas-ui-tabs-layer:focus-visible { outline: none; }
.cloudcanvas-ui-tabs-layer:focus-visible > .cloudcanvas-ui-tabs-layer-face {
  outline: var(--cc-focus-ring-width, 2px) solid var(--cc-focus-ring, var(--cc-accent, #38bdf8));
  outline-offset: calc(-1 * var(--cc-focus-ring-width, 2px));
}
/* The fold's menu is mounted beside the strip and takes no room there. */
.cloudcanvas-ui-tabs-menu { display: contents; }

/* On a line strip: the label in line, then a mark that points on to the tab. */
.cloudcanvas-ui-tabs[data-face="line"] .cloudcanvas-ui-tabs-layer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cc-space-1, 4px);
  max-width: var(--cc-ui-tab-layer-width, 12rem);
}
.cloudcanvas-ui-tabs[data-face="line"] .cloudcanvas-ui-tabs-layer-face { min-width: 0; padding: var(--cc-space-1, 4px) var(--cc-space-2, 8px); border-radius: var(--cc-radius-sm, 6px); }
.cloudcanvas-ui-tabs[data-face="line"] .cloudcanvas-ui-tabs-layer::after {
  content: "";
  flex: none;
  width: 0.4em;
  height: 0.4em;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: rotate(45deg);
}
.cloudcanvas-ui-tabs[data-face="line"] .cloudcanvas-ui-tabs-layer:is(:hover, :focus-visible):not(:disabled) > .cloudcanvas-ui-tabs-layer-face { background: var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)); }

/* On a folder strip: a stack. The button is what peeks out; its face is free of the row. */
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer { width: var(--cc-ui-tab-layer-peek, 4.5rem); }
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer.is-fold { width: var(--cc-control-min, 28px); }
/* The label starts at the face's near edge, at its top as on a folder's tab, and ends before the corner the face is tucked under. */
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer-face {
  position: absolute;
  inset: var(--cc-ui-tab-layer-step, 3px) auto 0 0;
  width: max-content;
  min-width: calc(100% + var(--cc-radius-sm, 6px));
  max-width: calc(100% + var(--cc-radius-sm, 6px));
  padding: var(--cc-space-1, 4px) var(--cc-space-3, 12px) 0 var(--cc-space-2, 8px);
  line-height: 1.2;
  text-align: start;
  background-color: var(--cc-bg, #0f1117);
  border: 1px solid var(--cc-card-border, rgba(255, 255, 255, 0.1));
  border-width: 1px 0 0 1px;
  border-radius: var(--cc-radius-sm, 6px) var(--cc-radius-sm, 6px) 0 0;
  box-shadow: var(--cc-ui-tab-layer-shadow, var(--cc-shadow-1, 0 4px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.06)));
}
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer.is-fold > .cloudcanvas-ui-tabs-layer-face { padding-right: var(--cc-space-2, 8px); text-align: center; }
/* One step back, one step lower and one wash of shade more over the tab's own face. */
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer[data-depth="1"] > .cloudcanvas-ui-tabs-layer-face { background-image: var(--layer-shade), var(--tab-face); }
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer[data-depth="2"] > .cloudcanvas-ui-tabs-layer-face {
  top: calc(2 * var(--cc-ui-tab-layer-step, 3px));
  background-image: var(--layer-shade), var(--layer-shade), var(--tab-face);
}
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer[data-depth="3"] > .cloudcanvas-ui-tabs-layer-face {
  top: calc(3 * var(--cc-ui-tab-layer-step, 3px));
  background-image: var(--layer-shade), var(--layer-shade), var(--layer-shade), var(--tab-face);
}
/* Behind a tab a step back: one wash more. No heavier than the rules above, so a layer brought forward is still lit. */
.cloudcanvas-ui-tabs[data-face="folder"] :where(.cloudcanvas-ui-tabs-item:not(.is-active)) .cloudcanvas-ui-tabs-layer[data-depth="1"] > .cloudcanvas-ui-tabs-layer-face { background-image: var(--layer-shade), var(--layer-shade), var(--tab-face); }
.cloudcanvas-ui-tabs[data-face="folder"] :where(.cloudcanvas-ui-tabs-item:not(.is-active)) .cloudcanvas-ui-tabs-layer[data-depth="2"] > .cloudcanvas-ui-tabs-layer-face { background-image: var(--layer-shade), var(--layer-shade), var(--layer-shade), var(--tab-face); }
.cloudcanvas-ui-tabs[data-face="folder"] :where(.cloudcanvas-ui-tabs-item:not(.is-active)) .cloudcanvas-ui-tabs-layer[data-depth="3"] > .cloudcanvas-ui-tabs-layer-face {
  background-image: var(--layer-shade), var(--layer-shade), var(--layer-shade), var(--layer-shade), var(--tab-face);
}
/* Under the pointer or the keys a layer comes to the front and opens out to its label, over what stood in front of it:
   whole now, and lit as a control is under the pointer rather than shaded as something behind. */
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer:is(:hover, :focus-visible):not(:disabled) { z-index: var(--cc-z-ui-raised, 2); }
.cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer:is(:hover, :focus-visible):not(:disabled) > .cloudcanvas-ui-tabs-layer-face {
  max-width: var(--cc-ui-tab-layer-width, 12rem);
  background-image: linear-gradient(var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22)), var(--cc-btn-bg-hover, rgba(56, 189, 248, 0.22))), var(--tab-face);
  border-right-width: 1px;
}

/* A folder layer eases open only for a user who has not asked for less motion. */
@media (prefers-reduced-motion: no-preference) {
  .cloudcanvas-ui-tabs[data-face="folder"] .cloudcanvas-ui-tabs-layer-face { transition: max-width 120ms ease-out; }
}
@media (pointer: coarse) {
  .cloudcanvas-ui-tabs-layer { min-width: var(--cc-control-min-coarse, 44px); min-height: var(--cc-control-min-coarse, 44px); }
}
