/*
 * appTown design system. See the ui-design skill.
 * Layers: primitives → semantic tokens → components. Components use semantic tokens only.
 * Light/dark: semantic colors use light-dark(); <html data-theme> pins color-scheme,
 * otherwise the device preference applies ("system").
 */

/* 0. The interface font (self-hosted, SIL OFL; apps may pick another in branding) */
@font-face { font-family: "Inter"; src: url("fonts/inter.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
/* The appTown wordmark font: Quicksand Bold (the branding catalog's file, SIL OFL), rounded and
   geometric like the logo's lettering. Its own family name so an app's "Quicksand" never clashes. Only for Wordmark. */
@font-face { font-family: "appTown Wordmark"; src: url("fonts/quicksand.woff2") format("woff2"); font-weight: 300 700; font-display: swap; }

/* 1. Primitives ------------------------------------------------------------------- */
:root {
  --gray-0: oklch(100% 0 0);
  --gray-50: oklch(98.5% 0.002 260);
  --gray-100: oklch(96.5% 0.004 260);
  --gray-200: oklch(92.5% 0.006 260);
  --gray-300: oklch(87% 0.008 260);
  --gray-400: oklch(71% 0.012 260);
  --gray-500: oklch(55.5% 0.014 260);
  --gray-600: oklch(45% 0.014 260);
  --gray-700: oklch(37% 0.012 260);
  --gray-800: oklch(27.5% 0.01 260);
  --gray-850: oklch(23% 0.009 260);
  --gray-900: oklch(20% 0.008 260);
  --gray-950: oklch(15% 0.006 260);

  /* Brand teal (matches the logo); 600 on white and 400 on gray-950 stay above 4.5:1. */
  /* appTown violet (hue 285): the centre of the logo's gradient. Apps override it. */
  --accent-300: oklch(82% 0.1 285);
  --accent-400: oklch(72% 0.16 285);
  --accent-500: oklch(60% 0.22 285);
  --accent-600: oklch(51% 0.23 285);
  --accent-700: oklch(44% 0.21 285);
  /* The logo's colours, for appTown's own brand surfaces only (sign-in, the brand line);
     never in app content, which uses the accent. */
  --brand-cyan: oklch(80% 0.14 215);
  --brand-blue: oklch(58% 0.23 262);
  --brand-violet: oklch(51% 0.27 295);
  --brand-magenta: oklch(63% 0.26 355);
  --brand-orange: oklch(73% 0.19 50);
  --brand-yellow: oklch(87% 0.17 92);
  --brand-night: oklch(15% 0.025 280);
  --brand-gradient: linear-gradient(105deg, var(--brand-cyan), var(--brand-blue) 22%, var(--brand-violet) 45%, var(--brand-magenta) 70%, var(--brand-orange) 88%, var(--brand-yellow));

  --red-300: oklch(76% 0.12 25);
  --red-600: oklch(53% 0.2 25);
  --red-700: oklch(47% 0.18 25);
  --green-300: oklch(80% 0.13 150);
  --green-700: oklch(46% 0.12 150);
  --amber-300: oklch(84% 0.14 80);
  --amber-700: oklch(50% 0.12 70);

  --space-0: 0;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-brand: "appTown Wordmark", var(--font-sans);
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.75rem;
  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;

  --radius-preset-sharp: 0.125rem;
  --radius-preset-default: 0.5rem;
  --radius-preset-round: 1rem;
  --radius-full: 999px;

  --shadow-1: 0 1px 2px oklch(0% 0 0 / 0.06), 0 1px 3px oklch(0% 0 0 / 0.08);
  --shadow-2: 0 4px 12px oklch(0% 0 0 / 0.12), 0 2px 4px oklch(0% 0 0 / 0.08);

  --duration-fast: 120ms;
  --duration-normal: 200ms;
  --toast-timeout: 4s; /* success/info toasts hide after this; danger stays */

  --z-base: 0;
  --z-sticky: 10;
  --z-overlay: 25; /* the phone/tablet menu drawer, above the bars */
  --z-menu: 20;
  --z-toast: 30;

  --border-width: 1px;
  --focus-width: 2px;
  --touch-target: 2.75rem;
  --content-max: 112rem; /* desktop pages use the width; only absurdly wide screens stop growing */
  --site-max: 72rem; /* the public home page's column */
  --form-max: 36rem;
  --field-max: 32rem; /* widest a single input gets in a row form */
  --prose-max: 48rem; /* readable line length for long text */
  --icon-size: 1.25rem;
  --topbar-height: 3.25rem; /* the phone/tablet top bar */
  --sidenav-width: 15rem;
  --bottomnav-height: 3.75rem;
  --menu-min: 14rem;
  --select-max: 18rem; /* tallest a Select's option list gets before it scrolls */
  --avatar-size: 2rem;
  --toast-max: 28rem;
  /* Safe area: the system bars, notch and gesture bar of an edge-to-edge phone (the
     Android app, iOS). 0 everywhere else. The body pads by them, so full-height
     layouts use --viewport-height instead of 100dvh. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  /* The strips on top of the page (siteBanners) take their height from here, so
     full-screen layouts (editor, sign-in) still fit with them. */
  --banner-beta: 0px;
  --banner-app: 0px;
  --viewport-height: calc(100dvh - var(--safe-top) - var(--safe-bottom) - var(--banner-beta) - var(--banner-app));
}

/* 2. Semantic tokens ----------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  --color-bg: light-dark(var(--gray-50), var(--gray-950));
  --color-surface: light-dark(var(--gray-0), var(--gray-900));
  --color-surface-raised: light-dark(var(--gray-0), var(--gray-850));
  --color-surface-hover: light-dark(var(--gray-100), var(--gray-800));
  --color-border: light-dark(var(--gray-200), var(--gray-800));
  --color-border-strong: light-dark(var(--gray-300), var(--gray-700));
  --color-text: light-dark(var(--gray-900), var(--gray-50));
  --color-text-muted: light-dark(var(--gray-600), var(--gray-400));
  --color-accent: light-dark(var(--accent-600), var(--accent-400));
  --color-accent-hover: light-dark(var(--accent-700), var(--accent-300));
  --color-accent-contrast: light-dark(var(--gray-0), var(--gray-950));
  --color-danger: light-dark(var(--red-600), var(--red-300));
  --color-danger-hover: light-dark(var(--red-700), var(--red-300));
  --color-danger-contrast: light-dark(var(--gray-0), var(--gray-950));
  --color-success: light-dark(var(--green-700), var(--green-300));
  --color-warning: light-dark(var(--amber-700), var(--amber-300));
  --color-focus-ring: light-dark(var(--accent-500), var(--accent-300));

  /* Builder-customizable knobs (overridden by the generated app theme block). */
  --radius: var(--radius-preset-default);
  --radius-sm: calc(var(--radius) * 0.75);
  --density: 0.9; /* comfortable = 0.9, compact = 0.75 (app branding) */

  --control-height: max(calc(2.5rem * var(--density)), 2rem);
  --control-pad-x: calc(var(--space-4) * var(--density));
  --gap: calc(var(--space-4) * var(--density));
  --page-pad: var(--space-5);
  --section-gap: var(--space-6); /* above and below the hairline between sections */

  /* Accent tints: navigation, selected rows, chips (follow an app's accent). */
  --color-accent-soft: light-dark(color-mix(in oklab, var(--accent-600) 10%, var(--gray-0)), color-mix(in oklab, var(--accent-400) 16%, var(--gray-950)));
  --color-accent-softer: light-dark(color-mix(in oklab, var(--accent-600) 5%, var(--gray-0)), color-mix(in oklab, var(--accent-400) 8%, var(--gray-950)));
  --color-sidebar: light-dark(color-mix(in oklab, var(--accent-600) 4%, var(--gray-50)), color-mix(in oklab, var(--accent-400) 5%, var(--gray-900)));
}

/* Tile colours (app/group/role icon tiles, branding swatches): one hue each, white
   icon on the solid colour in both themes. */
.tile--teal { --tile: oklch(52% 0.09 195); }
.tile--blue { --tile: oklch(54% 0.17 255); }
.tile--indigo { --tile: oklch(50% 0.18 275); }
.tile--violet { --tile: oklch(52% 0.18 300); }
.tile--pink { --tile: oklch(56% 0.18 350); }
.tile--red { --tile: oklch(54% 0.19 25); }
.tile--orange { --tile: oklch(60% 0.16 50); }
.tile--amber { --tile: oklch(64% 0.13 80); }
.tile--green { --tile: oklch(54% 0.13 150); }
.tile--slate { --tile: oklch(48% 0.03 255); }

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* Breakpoints (media queries can't read custom properties; keep in sync):
   mobile < 40rem ≤ tablet < 64rem ≤ desktop */
@media (max-width: 39.99rem) {
  :root {
    --page-pad: var(--space-4);
    --control-height: var(--touch-target);
    --grid-min: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms;
    --duration-normal: 0ms;
  }
}

/* 3. Base ----------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
}
/* Behind the status bar: page content scrolls under it, never through it. */
body::before { content: ""; position: fixed; inset: 0 0 auto 0; z-index: var(--z-toast); height: var(--safe-top); background: var(--color-surface); pointer-events: none; }

h1, h2, h3 { margin: 0; line-height: var(--leading-tight); font-weight: var(--weight-semibold); }
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
p { margin: 0; }

a { color: var(--color-accent); }
a:hover { color: var(--color-accent-hover); }

:focus-visible {
  outline: var(--focus-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-width);
}

/* hidden always wins: components set display (e.g. .btn), which would beat the
   browser's own [hidden] rule and show elements meant to be hidden. */
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* 4. Components ------------------------------------------------------------------------- */

/* Layout */
.page {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--page-pad);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.page--narrow { max-width: var(--form-max); } /* centered single-card pages (sign in, errors) */
.page--center { min-height: var(--viewport-height); justify-content: center; }
.page__header { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: var(--gap); padding-bottom: var(--space-4); border-bottom: var(--border-width) solid var(--color-border); }
.page__subtitle { color: var(--color-text-muted); }

.stack { display: flex; flex-direction: column; gap: var(--gap); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.muted { color: var(--color-text-muted); font-size: var(--text-sm); }

/* Shell (see Shell / Navigation). Desktop (≥64rem): the sidebar (brand, app title,
   menu, the signed-in user at the bottom) beside the page. Phones and tablets: a top
   bar with a Menu drawer, and a bottom tab bar of at most 5 items (end of file). */
.shell { display: grid; grid-template-columns: var(--sidenav-width) minmax(0, 1fr); min-height: var(--viewport-height); }
.shell__main { min-width: 0; }
.nav { display: contents; }
.sidebar {
  position: sticky;
  top: var(--safe-top);
  align-self: start;
  height: var(--viewport-height);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-3);
  background: var(--color-sidebar);
  border-inline-end: var(--border-width) solid var(--color-border);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-inline: var(--space-2);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
  text-decoration: none;
}
/* The appTown wordmark (see Wordmark): "app" in the text colour, "Town" in the logo's warm gradient. */
.wordmark { font-family: var(--font-brand); font-size: var(--text-lg); font-weight: 700; letter-spacing: -0.02em; white-space: nowrap; }
.wordmark__town { background: linear-gradient(90deg, var(--brand-violet), var(--brand-magenta) 40%, var(--brand-orange) 75%, var(--brand-yellow)); -webkit-background-clip: text; background-clip: text; color: transparent; }
@media (forced-colors: active) { .wordmark__town { background: none; color: CanvasText; } }
/* The app at the top of its menu: its tile and name. */
.nav__app { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2); border-radius: var(--radius-sm); color: var(--color-text); text-decoration: none; font-weight: var(--weight-semibold); }
.nav__app:hover { background: var(--color-surface-hover); }
.nav__app span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav__title {
  padding-inline: var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.nav__title:hover { color: var(--color-text); }
.nav__list { display: flex; flex-direction: column; gap: var(--space-1); }
.navitem {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-height);
  padding-inline: var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
}
.navitem:hover { background: var(--color-surface-hover); color: var(--color-text); }
.navitem { position: relative; }
.navitem[aria-current="page"] { background: var(--color-accent-soft); color: var(--color-accent); }
/* The current page's marker: a short straight bar, inside the item's rounded shape. */
.navitem[aria-current="page"]::before { content: ""; position: absolute; inset-block: 25%; inset-inline-start: 0; width: 3px; border-radius: 0 3px 3px 0; background: var(--color-accent); }
.navitem .icon { color: inherit; }
.navitem__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-border);
}
.account__user { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-2); color: var(--color-text); text-decoration: none; }
.account__user:hover .account__name { color: var(--color-accent); }
.account__text { min-width: 0; display: flex; flex-direction: column; }
.account__name, .account__email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-sm); }
.account__email { font-size: var(--text-xs); color: var(--color-text-muted); }
.mobilebar, .tabbar { display: none; }
.drawer { position: relative; }
.drawer > summary { list-style: none; }
.drawer > summary::-webkit-details-marker { display: none; }
.drawer__panel {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: var(--z-overlay);
  width: min(calc(20rem + var(--safe-right)), 85vw);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  overflow-y: auto;
  background: var(--color-surface-raised);
  border-inline-start: var(--border-width) solid var(--color-border);
  box-shadow: var(--shadow-2);
}

/* Icon (see the Icon component); sized by the text around it. */
.icon { display: block; flex: none; inline-size: var(--icon-size); block-size: var(--icon-size); }

/* Logo (the image carries its own rounded corners) */
.logo { display: block; inline-size: auto; block-size: 1.75rem; flex: none; }

/* Button */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding-inline: var(--control-pad-x);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast), border-color var(--duration-fast);
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn--primary { background: var(--color-accent); color: var(--color-accent-contrast); }
.btn--primary:hover:not(:disabled) { background: var(--color-accent-hover); color: var(--color-accent-contrast); }
.btn--secondary { background: var(--color-surface); color: var(--color-text); border-color: var(--color-border-strong); }
.btn--secondary:hover:not(:disabled) { background: var(--color-surface-hover); color: var(--color-text); }
.btn--ghost { background: transparent; color: var(--color-text); }
.btn--ghost:hover:not(:disabled) { background: var(--color-surface-hover); color: var(--color-text); }
.btn--danger { background: var(--color-danger); color: var(--color-danger-contrast); }
.btn--danger:hover:not(:disabled) { background: var(--color-danger-hover); color: var(--color-danger-contrast); }
.btn--sm { min-height: calc(var(--control-height) * 0.8); padding-inline: calc(var(--control-pad-x) * 0.75); }
.btn--lg { min-height: calc(var(--control-height) * 1.2); padding-inline: calc(var(--control-pad-x) * 1.5); font-size: var(--text-md); }
.btn--block { width: 100%; }

/* Panel: the boxed surface of centered single-purpose pages (see Panel). */
.panel {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: calc(var(--space-6) * var(--density));
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}
.panel__header { display: flex; flex-direction: column; gap: var(--space-1); }
.panel__header h1 { font-size: var(--text-xl); }
.textarea { min-height: auto; padding-block: var(--space-2); resize: vertical; line-height: var(--leading-normal); }

/* Section: the page building block. A heading (and short explanation) beside its
   content on wide screens, above it on narrow ones; sections are separated by
   hairlines, not boxes. */
.sections { display: flex; flex-direction: column; container-type: inline-size; }
/* Room above every hairline: a section's content never touches the next one's line. */
.section + .section { margin-top: var(--section-gap); }
.section {
  display: grid;
  grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
  gap: var(--space-3) var(--space-10);
  padding-top: var(--section-gap);
  border-top: var(--border-width) solid var(--color-border);
}
.page__header + .section, .page__header + .sections > .section:first-child, .toolbar + .section,
.editor__scroll > .sections > .section:first-child, .editor__scroll > .section:first-child { border-top: 0; padding-top: 0; }
.sections > .toolbar { padding-bottom: var(--space-4); }
/* A field in a section stays readable; tables and lists use the full width. */
.section__body .field, .section__body .fieldset { max-width: var(--form-max); }
.section__body /* A slot shown or hidden as a whole (data-show) whose fields sit in the row. */
.form-row__slot { display: contents; }
.form-row > .fieldset, .form-row__slot > .fieldset { flex-basis: 100%; }
.form-row > .field { max-width: var(--field-max); }
/* Narrow containers (the editor column, tablets): headings above the content. */
@container (max-width: 56rem) {
  .section { grid-template-columns: minmax(0, 1fr); }
}
.section--plain { grid-template-columns: minmax(0, 1fr); }
.section__head { display: flex; flex-direction: column; gap: var(--space-1); }
.section__head h2 { font-size: var(--text-md); }
.section__body { min-width: 0; display: flex; flex-direction: column; gap: var(--gap); }

/* Data table (see Table): hairline rows, compact, scrolls sideways when narrow. */
.table-wrap { overflow-x: auto; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table th {
  padding: var(--space-2) var(--space-3);
  text-align: start;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  white-space: nowrap;
  border-bottom: var(--border-width) solid var(--color-border);
  background: var(--color-accent-softer);
}
.table td { padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); vertical-align: middle; }
.table tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--color-surface-hover); }
.table a { color: var(--color-text); font-weight: var(--weight-medium); }
.table a:hover { color: var(--color-accent); }
.table__actions { text-align: end; white-space: nowrap; }
.table .cluster { flex-wrap: nowrap; }
.table td { white-space: nowrap; }
.table td.table__wrap { white-space: normal; }
/* A row's details on its own line under it (e.g. a group's roles). */
.table tr:has(+ .table__sub) td { border-bottom: 0; }
.table .table__sub td { padding-top: 0; white-space: normal; }
.table__sub .fieldset { margin: 0; }
.table__actions > * { display: inline-flex; vertical-align: middle; }
.table__icon { color: var(--color-text-muted); }
.table__muted { color: var(--color-text-muted); }

/* Toolbar: a row of actions at the top of a page or above a table. */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }

/* Editor: a fixed frame filling the screen. The editing column (header and tabs
   fixed, the manual editor scrolling, the AI builder docked at the bottom) beside
   the preview pane, which can be resized (drag the divider) and collapsed; both
   are remembered on the user (see EditorFrame). */
.editor { --preview-width: 30rem; display: grid; grid-template-columns: minmax(0, 1fr) auto var(--preview-width); height: var(--viewport-height); overflow: hidden; }
.editor--collapsed { grid-template-columns: minmax(0, 1fr) auto 2.75rem; }
.editor__main { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.editor__head { flex: none; padding: var(--space-4) var(--page-pad) 0; display: flex; flex-direction: column; gap: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); background: var(--color-surface); }
.editor__head .page__header { padding-bottom: 0; border-bottom: 0; }
.editor__scroll { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-5) var(--page-pad) var(--space-8); }
.editor__scroll > * + * { margin-top: var(--space-5); }
.editor__ai { flex: none; display: flex; flex-direction: column; max-height: 45%; border-top: var(--border-width) solid var(--color-border); background: var(--color-surface); }
.editor__ai-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) var(--page-pad); }
.editor__ai-title { display: flex; align-items: center; gap: var(--space-2); font-weight: var(--weight-semibold); font-size: var(--text-sm); }
.editor__ai-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 0 var(--page-pad) var(--space-3); overflow: hidden; }
/* The log takes what's left of the dock and scrolls; the message box always shows. */
.editor__ai-body > #ai-body { flex: 1 1 auto; min-height: 0; }
.editor__ai-body #ai-body > * { flex: none; }
.editor__ai-body #ai-body > .chat { flex: 1 1 auto; min-height: 4rem; max-height: none; }
.editor--ai-closed .editor__ai-body { display: none; }
.editor__divider { width: 0.5rem; cursor: col-resize; touch-action: none; background: var(--color-bg); border-inline: var(--border-width) solid var(--color-border); }
.editor__divider:hover { background: var(--color-accent-soft); }
.editor--collapsed .editor__divider { cursor: default; pointer-events: none; }
.editor__preview { min-width: 0; height: var(--viewport-height); display: flex; flex-direction: column; background: var(--color-bg); }
.editor--collapsed .preview__box, .editor--collapsed .preview__bar > :not(.preview__toggle) { display: none; }
.editor--collapsed .preview__bar { flex-direction: column; padding: var(--space-2) 0; border-bottom: 0; }
.preview__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); background: var(--color-surface); }
.preview__bar .status { white-space: nowrap; }
.preview__box { flex: 1; min-height: 0; overflow: hidden; display: flex; justify-content: center; padding: var(--space-3); }
.preview__frame {
  flex: none;
  width: 100%;
  max-width: none;
  height: 100%;
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-bg);
  box-shadow: var(--shadow-2);
  transform-origin: top center;
}

/* The device sizes before the fit script scales the frame (see PreviewDevices). */
.preview--phone .preview__frame { width: 390px; }
.preview--tablet .preview__frame { width: 820px; }

/* Status line (e.g. draft vs published) */
.status { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
.status__dot { width: 0.5rem; height: 0.5rem; border-radius: var(--radius-full); background: var(--color-warning); }
.status__dot--ok { background: var(--color-success); }

/* Chat (see ChatBubble): the AI builder and the in-app assistant. Newest first in
   a reversed column: the latest message sits at the bottom and stays in view. */
.chat { display: flex; flex-direction: column-reverse; gap: var(--space-3); max-height: 28rem; overflow-y: auto; }
.bubble { max-width: min(46rem, 92%); display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius); font-size: var(--text-sm); overflow-wrap: anywhere; }
.bubble__text { white-space: pre-wrap; }
/* Markdown (AI replies): paragraphs, lists, bold, code. */
.md { display: flex; flex-direction: column; gap: var(--space-2); }
.md p, .md ul, .md ol { margin: 0; }
.md ul, .md ol { padding-inline-start: var(--space-5); display: flex; flex-direction: column; gap: var(--space-1); }
.md code { font-family: var(--font-mono); font-size: 0.92em; padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--color-surface-hover); }
.bubble--user { align-self: flex-end; background: var(--color-accent-soft); color: var(--color-text); border: var(--border-width) solid color-mix(in oklab, var(--color-accent) 25%, transparent); }
.bubble--assistant { align-self: flex-start; background: var(--color-bg); border: var(--border-width) solid var(--color-border); }
.bubble__meta { display: flex; flex-wrap: wrap; gap: var(--space-2); white-space: normal; font-size: var(--text-xs); color: var(--color-text-muted); }
.bubble__actions { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--space-1); white-space: normal; font-size: var(--text-xs); color: var(--color-text-muted); }
.bubble__actions li::before { content: "✓ "; color: var(--color-success); }
.bubble__actions .bubble__action--error::before { content: "✕ "; color: var(--color-danger); }
.bubble__action--error { color: var(--color-danger); }
.chat-form { display: flex; gap: var(--space-2); align-items: flex-end; }
.chat-form .field { flex: 1; }
.chat-form .textarea { min-height: 2.5rem; }

/* Tiles: a coloured square with an icon, initials or a logo (apps, groups, roles). */
.tile { flex: none; display: inline-grid; place-items: center; inline-size: var(--tile-size, 2.25rem); block-size: var(--tile-size, 2.25rem); border-radius: calc(var(--radius) * 0.9); background: var(--tile, var(--color-accent)); color: var(--gray-0); font-size: var(--text-sm); font-weight: var(--weight-semibold); overflow: hidden; }
.tile .icon { inline-size: 55%; block-size: 55%; }
.tile img { inline-size: 100%; block-size: 100%; object-fit: cover; background: var(--gray-0); }
.tile--lg { --tile-size: 3rem; font-size: var(--text-md); }
.tile--sm { --tile-size: 1.75rem; font-size: var(--text-xs); }

/* Cards: a responsive grid of linked items (apps, groups, roles). */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: var(--space-3); }
.cardlink { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) var(--space-4); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); text-decoration: none; transition: border-color var(--duration-fast), box-shadow var(--duration-fast); }
.cardlink:hover { border-color: color-mix(in oklab, var(--tile, var(--color-accent)) 50%, var(--color-border)); box-shadow: var(--shadow-1); color: var(--color-text); }
.cardlink__text { min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.cardlink__title { font-weight: var(--weight-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cardlink__body { font-size: var(--text-sm); color: var(--color-text-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cardlink__meta { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* Swatches: colour choices (visually hidden radios). */
.swatches { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.swatch { inline-size: 2rem; block-size: 2rem; border-radius: var(--radius-full); background: var(--tile); cursor: pointer; box-shadow: inset 0 0 0 2px var(--color-surface); border: 2px solid transparent; }
.swatch:has(:checked) { border-color: var(--color-text); }
.swatch:has(:focus-visible) { outline: var(--focus-width) solid var(--color-focus-ring); outline-offset: var(--focus-width); }
.color-input { inline-size: 3rem; block-size: 2rem; padding: 0; border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-sm); background: none; }

/* Section heading chip: a small coloured icon before a section title. */
.chip { display: inline-grid; place-items: center; inline-size: 1.75rem; block-size: 1.75rem; border-radius: var(--radius-sm); background: var(--color-accent-soft); color: var(--color-accent); }
.chip .icon { inline-size: 1rem; block-size: 1rem; }
.section__title { display: flex; align-items: center; gap: var(--space-2); }

/* Expression editor result line. */
/* Expression editor (ExprEditor): the box, live help under it (suggestions, the
   function at the cursor, the check), and the field/function browser. */
.expr { gap: var(--space-1); }
.expr__input { resize: vertical; }
.expr-assist { display: flex; flex-direction: column; gap: var(--space-1); }
.expr-assist:empty { display: none; }
.expr__tools { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-3); }
.expr__links { display: inline-flex; align-items: center; gap: var(--space-2); margin-inline-start: auto; font-size: var(--text-xs); }
.expr__guide { color: var(--color-text-muted); }
.expr-sugg {
  margin: 0; padding: var(--space-1); list-style: none;
  max-height: 14rem; overflow-y: auto; overscroll-behavior: contain;
  background: var(--color-surface-raised); border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-2);
}
.expr-sugg[hidden], .expr:not(:focus-within) .expr-sugg, .expr:not(:focus-within) .expr-result--tip { display: none; }
.expr-sugg__item { display: flex; align-items: baseline; gap: var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-sm); cursor: pointer; }
.expr-sugg__item:hover { background: var(--color-surface-hover); }
.expr-sugg__item[aria-selected="true"] { background: var(--color-accent-soft); }
.expr-sugg__kind { flex: none; min-width: 4.5rem; font-size: var(--text-xs); color: var(--color-text-muted); }
.expr-sugg__kind--function { color: var(--color-accent); }
.expr-sugg__label { flex: none; font-family: var(--font-mono); }
.expr-sugg__detail { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--color-text-muted); font-family: var(--font-mono); }
.expr-call { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); padding: var(--space-2); border-radius: var(--radius-sm); background: var(--color-accent-softer); font-size: var(--text-xs); }
.expr-call__sig { font-family: var(--font-mono); font-size: var(--text-sm); }
.expr-call__param--active { font-weight: var(--weight-semibold); color: var(--color-accent); text-decoration: underline; text-underline-offset: 0.2em; }
.expr-call__desc { color: var(--color-text); }
.expr-call__example { color: var(--color-text-muted); }
.expr-call__example code, .expr-browse__example { font-family: var(--font-mono); }
.expr-spot { margin: 0; padding: var(--space-1) var(--space-2); overflow-x: auto; white-space: pre; font-family: var(--font-mono); font-size: var(--text-xs); background: var(--color-surface-hover); border-radius: var(--radius-sm); }
.expr-spot mark { background: color-mix(in oklab, var(--color-danger) 25%, transparent); color: var(--color-text); outline: var(--border-width) solid var(--color-danger); border-radius: 2px; }
.expr-result kbd { font-family: var(--font-mono); font-size: 0.95em; padding: 0 0.3em; border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-sm); background: var(--color-surface); }
.expr-browse { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-2); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface); }
.expr-browse__list { max-height: 20rem; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: var(--space-3); }
.expr-browse__group[hidden], .expr-browse__item[hidden] { display: none; }
.expr-browse__title { margin: 0 0 var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); }
.expr-browse__group ul { margin: 0; padding: 0; list-style: none; }
.expr-browse__item { display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr); gap: 0 var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-xs); }
.expr-browse__item:hover { background: var(--color-surface-hover); }
.expr-browse__label { font-family: var(--font-mono); font-size: var(--text-sm); overflow-wrap: anywhere; }
.expr-browse__detail { color: var(--color-text-muted); text-align: end; }
.expr-browse__desc, .expr-browse__example { grid-column: 1 / -1; color: var(--color-text-muted); }
.expr-result { margin: 0; font-size: var(--text-xs); font-family: var(--font-mono); color: var(--color-text-muted); }
.expr-result--ok { color: var(--color-success); }
.expr-result--error { color: var(--color-danger); }
.code { font-family: var(--font-mono); font-size: var(--text-sm); }

/* Stat: a number with a label (credits, usage). */
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: var(--space-3); }
.stat { padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--color-accent-softer); border: var(--border-width) solid var(--color-border); }
.stat__value { font-size: var(--text-xl); font-weight: var(--weight-semibold); }
.stat__label { font-size: var(--text-xs); color: var(--color-text-muted); text-transform: uppercase; }

/* Form field */
.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field__label { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.field__hint { font-size: var(--text-xs); color: var(--color-text-muted); }
.field__error { font-size: var(--text-xs); color: var(--color-danger); }
.field__row { display: flex; gap: var(--space-2); }
.field__row > .input { flex: 1; min-width: 0; }
.input {
  min-height: var(--control-height);
  padding-inline: var(--space-3);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
}
.input[aria-invalid="true"] { border-color: var(--color-danger); }
/* Only real text boxes: a Select trigger (a summary) also matches :read-only. */
.input:is(input, textarea):read-only { background: var(--color-surface-hover); color: var(--color-text-muted); }

/* Select: the only dropdown (see Select component). details/summary + radios, with a
   search box that narrows the list when Datastar runs. */
.select { position: relative; flex: 1; min-width: 0; }
.select__trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  cursor: pointer;
}
.select__trigger::-webkit-details-marker { display: none; }
.select__trigger::after {
  content: "";
  flex: none;
  width: 0.4em;
  height: 0.4em;
  margin-inline-start: auto;
  border-right: var(--focus-width) solid currentColor;
  border-bottom: var(--focus-width) solid currentColor;
  transform: translateY(-25%) rotate(45deg);
}
.select__value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.select__panel {
  position: absolute;
  inset-inline: 0;
  top: calc(100% + var(--space-1));
  z-index: var(--z-menu);
  min-width: min(var(--menu-min), calc(100vw - 2 * var(--page-pad)));
  padding: var(--space-2);
  background: var(--color-surface-raised);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  white-space: normal; /* not the nowrap of a table cell it opens from */
}
.select__search { width: 100%; }
.select__options {
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  max-height: var(--select-max);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.select__option {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--space-2);
  padding-block: var(--space-1);
  min-height: var(--control-height);
  padding-inline: var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  cursor: pointer;
  flex: none;
}
.select__option[hidden] { display: none; }
.select__option:hover { background: var(--color-surface-hover); }
.select__option:has(.select__radio:checked) { font-weight: var(--weight-semibold); color: var(--color-accent); }
.select__option:has(.select__radio:focus-visible) {
  outline: var(--focus-width) solid var(--color-focus-ring);
  outline-offset: calc(var(--focus-width) * -1);
}
.select__radio { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.select__label { flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere; }
/* The detail sits after the label, or wraps under it when the panel is narrow. */
.select__detail { flex: 1 1 10rem; min-width: 0; overflow-wrap: anywhere; font-size: var(--text-xs); color: var(--color-text-muted); font-weight: var(--weight-normal); }
.select__empty { padding: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
.select__empty[hidden] { display: none; }

/* Toasts: the one fixed message region (see Toasts component). Every error/success
   message looks the same and lives here, never inside a form. */
.toasts {
  position: fixed;
  z-index: var(--z-toast);
  inset-inline: calc(var(--page-pad) + var(--safe-left)) calc(var(--page-pad) + var(--safe-right));
  bottom: calc(var(--page-pad) + var(--safe-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  max-width: var(--toast-max);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-raised);
  color: var(--color-text);
  border: var(--border-width) solid var(--color-border);
  border-inline-start: calc(var(--focus-width) * 2) solid var(--toast-color);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  font-size: var(--text-sm);
  pointer-events: auto;
}
.toast--info { --toast-color: var(--color-accent); }
.toast--success { --toast-color: var(--color-success); }
.toast--danger { --toast-color: var(--color-danger); }
.toast--info, .toast--success { animation: toast-hide var(--duration-normal) var(--toast-timeout) forwards; }
.toast__msg { flex: 1; }
.toast__close {
  flex: none;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  margin: calc(var(--space-3) * -1) calc(var(--space-4) * -1) calc(var(--space-3) * -1) 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-lg);
  cursor: pointer;
}
.toast__close:hover { color: var(--color-text); }
@keyframes toast-hide { to { opacity: 0; visibility: hidden; } }

/* Menu (details/summary: works without JS, keyboard accessible) */
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::after {
  content: "";
  width: 0.4em;
  height: 0.4em;
  border-right: var(--focus-width) solid currentColor;
  border-bottom: var(--focus-width) solid currentColor;
  transform: translateY(-25%) rotate(45deg);
}
.menu__panel {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + var(--space-1));
  z-index: var(--z-menu);
  min-width: var(--menu-min);
  max-width: calc(100vw - 2 * var(--page-pad));
  padding: var(--space-2);
  background: var(--color-surface-raised);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.menu--start .menu__panel { inset-inline-end: auto; inset-inline-start: 0; }
.menu__label { padding: var(--space-1) var(--space-2); font-size: var(--text-xs); color: var(--color-text-muted); }
.menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding-inline: var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}
.menu__item:hover { background: var(--color-surface-hover); color: var(--color-text); }
.menu__item .icon { color: var(--color-text-muted); }
.menu__item[aria-current="true"] { font-weight: var(--weight-semibold); }
.menu__divider { border: 0; border-top: var(--border-width) solid var(--color-border); margin: var(--space-1) 0; width: 100%; }
.menu form { display: contents; }

/* Segmented control (theme picker) */
.segmented {
  display: inline-flex;
  padding: var(--space-1);
  gap: var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--color-surface-hover);
}
.segmented__option {
  min-height: calc(var(--control-height) * 0.8);
  padding-inline: var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}
.segmented__option[aria-pressed="true"] { background: var(--color-surface); color: var(--color-text); box-shadow: var(--shadow-1); }

/* Avatar */
.avatar {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  overflow: hidden;
  object-fit: cover;
}

/* Empty state */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-12) var(--space-6);
  text-align: center;
  border: var(--border-width) dashed var(--color-border-strong);
  border-radius: var(--radius);
  color: var(--color-text-muted);
}
.empty__title { color: var(--color-text); font-size: var(--text-lg); font-weight: var(--weight-semibold); }

/* Description list (key/value rows) */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-6); margin: 0; font-size: var(--text-sm); }
.kv dt { color: var(--color-text-muted); }
.kv dd { margin: 0; overflow-wrap: anywhere; }

/* Form layouts (see ActionForm) */
.form-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2) var(--gap); }
/* Buttons in a row line up with the inputs (below their labels), not with hints. */
.form-row > .btn, .form-row > .cluster { margin-top: calc(var(--text-sm) * var(--leading-normal) + var(--space-1)); }
.form-row > .field { flex: 1; min-width: min(100%, var(--menu-min)); max-width: var(--field-max); }
.form-inline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.form-inline > .field { min-width: var(--menu-min); }


/* List rows */
.list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-bottom: var(--border-width) solid var(--color-border);
}
.list__item:last-child { border-bottom: 0; }
.list__main { flex: 1; min-width: min(100%, var(--menu-min)); display: flex; flex-direction: column; gap: var(--space-1); }
.list__title { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); font-weight: var(--weight-medium); overflow-wrap: anywhere; }
.list__title a { color: var(--color-text); }
.list__title a:hover { color: var(--color-accent); }
.list__meta { font-size: var(--text-sm); color: var(--color-text-muted); overflow-wrap: anywhere; }
.list__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.list__actions:empty { display: none; }

/* Fieldset: a label over a group of controls (see Fieldset, IconPicker) */
.fieldset { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; margin: 0; padding: 0; border: 0; }

/* Icon picker: a wrapping grid of icon tiles (visually hidden radios inside) */
.icon-picker__options { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.icon-picker__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--control-height);
  block-size: var(--control-height);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  cursor: pointer;
}
.icon-picker__option:hover { background: var(--color-surface-hover); color: var(--color-text); }
.icon-picker__option:has(:checked) { border-color: var(--color-accent); color: var(--color-accent); box-shadow: inset 0 0 0 var(--border-width) var(--color-accent); }
.icon-picker__option:has(:focus-visible) { outline: var(--focus-width) solid var(--color-focus-ring); outline-offset: var(--focus-width); }

/* Badge */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  border: var(--border-width) solid color-mix(in oklab, var(--badge-color) 35%, transparent);
  background: color-mix(in oklab, var(--badge-color) 12%, transparent);
  color: var(--badge-color);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-normal);
}

.badge--neutral { --badge-color: var(--color-text-muted); }
.badge--accent { --badge-color: var(--color-accent); }
.badge--warning { --badge-color: var(--color-warning); }

/* Checkbox */
.checkbox { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; }
.checkbox__input {
  flex: none;
  width: var(--space-5);
  height: var(--space-5);
  margin: var(--space-1) 0 0;
  accent-color: var(--color-accent);
}
.checkbox__text { display: flex; flex-direction: column; gap: var(--space-1); }
.checkbox__label { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.checkbox__hint { font-size: var(--text-xs); color: var(--color-text-muted); }

/* Prose: rendered Markdown (legal pages, AI replies). Only the elements Markdown produces. */
.prose { max-width: var(--prose-max); display: flex; flex-direction: column; gap: var(--space-4); }
.prose h1, .prose h2, .prose h3 { margin-top: var(--space-4); }
.prose h1:first-child { margin-top: 0; }
.prose ul, .prose ol { margin: 0; padding-inline-start: var(--space-6); display: flex; flex-direction: column; gap: var(--space-1); }
.prose code { font-family: var(--font-mono); font-size: 0.9em; padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--color-surface-hover); }
.prose pre {
  margin: 0;
  padding: var(--space-4);
  overflow-x: auto;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}
.prose pre code { padding: 0; background: transparent; }
.prose table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); display: block; overflow-x: auto; }
.prose th, .prose td { padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); text-align: start; vertical-align: top; }
.prose th { font-weight: var(--weight-semibold); }
.prose blockquote { margin: 0; padding-inline-start: var(--space-4); border-inline-start: calc(var(--focus-width) * 2) solid var(--color-accent); color: var(--color-text-muted); }
.prose hr { width: 100%; border: 0; border-top: var(--border-width) solid var(--color-border); }

/* Phones and tablets (<64rem): top bar + bottom tab bar instead of the sidebar;
   no preview pane (the editor is desktop-first). */
@media (max-width: 63.99rem) {
  .shell { display: block; }
  .sidebar { display: none; }
  .mobilebar {
    position: sticky;
    top: var(--safe-top);
    /* Above the tab bar: the menu drawer opens from inside this bar (its stacking
       context), so it must cover the tab bar too. */
    z-index: var(--z-overlay);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    height: var(--topbar-height); /* exact: full-height pages subtract it */
    padding: 0 var(--page-pad);
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
  }
  .mobilebar .btn { min-width: var(--touch-target); min-height: var(--touch-target); }
  /* Touch screens: every button and toggle is at least a finger wide and tall. */
  .btn, .btn--sm, .segmented__option { min-height: var(--touch-target); }
  .btn--sm:has(> .icon:only-child) { min-width: var(--touch-target); }
  .mobilebar__title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--weight-semibold); color: var(--color-text); text-decoration: none; }
  .tabbar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: var(--z-sticky);
    display: flex;
    padding: 0 var(--safe-right) var(--safe-bottom) var(--safe-left);
    background: var(--color-surface);
    border-top: var(--border-width) solid var(--color-border);
  }
  .tabbar .navitem { flex: 1 1 0; min-width: 0; min-height: var(--bottomnav-height); flex-direction: column; justify-content: center; gap: var(--space-1); padding: var(--space-1); border-radius: 0; font-size: var(--text-xs); text-align: center; }
  .tabbar .navitem[aria-current="page"] { background: transparent; }
  .tabbar .navitem[aria-current="page"]::before { inset-block: 0 auto; inset-inline: 30%; width: auto; height: 3px; border-radius: 0 0 3px 3px; }
  .tabbar .navitem__label { max-width: 100%; }
  body:has(.tabbar) .shell__main { padding-bottom: var(--bottomnav-height); } /* the body already pads the gesture bar */
  body:has(.tabbar) .toasts { bottom: calc(var(--bottomnav-height) + var(--page-pad) + var(--safe-bottom)); }
  .section { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 39.99rem) {
  .kv { grid-template-columns: 1fr; gap: var(--space-1); }
  .kv dd { margin-bottom: var(--space-2); }
}

/* Disclosure: a details element that reveals a secondary form. */
.disclosure > summary { cursor: pointer; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-accent); }
.disclosure[open] > summary { margin-bottom: var(--space-3); }

/* The builder fills the screen: only its panes scroll, never the page. It is
   desktop-only (user decision 2026-11-04): on phones, tablets and narrow windows
   the editor frame is replaced by .desktop-only, which says so. */
body:has(.editor) { overflow: hidden; }
.desktop-only { display: none; }
/* Content for where building works (only-desktop) or doesn't (only-mobile); the
   same breakpoint as the builder. */
.only-mobile { display: none; }
@media (max-width: 63.99rem), (hover: none) and (pointer: coarse) {
  .editor, .only-desktop { display: none; }
  .desktop-only { display: flex; }
  .only-mobile { display: revert; }
  body:has(.editor) { overflow: auto; }
}
@media (max-width: 63.99rem) {
  .checkbox { min-height: var(--touch-target); align-items: center; }
  .disclosure > summary { min-height: var(--touch-target); display: flex; align-items: center; }
}

/* The link between the running app and its builder, under the menu. */
.nav__switch { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-height); padding-inline: var(--space-3); border: var(--border-width) dashed var(--color-border-strong); border-radius: var(--radius-sm); color: var(--color-text-muted); font-size: var(--text-sm); font-weight: var(--weight-medium); text-decoration: none; }
.nav__switch:hover { border-style: solid; color: var(--color-accent); background: var(--color-accent-softer); }

/* Sign-in page: the pitch on a deep accent panel, signing in beside it (stacked on
   phones). The panel keeps its colours in both themes. */
.landing { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-rows: 1fr auto; min-height: calc(var(--viewport-height) - var(--safe-bottom)); background: var(--color-bg); }
/* The brand panel runs up under the status bar instead of a plain bar on top of it:
   the body drops its top inset and the panel adds it to its own padding. */
body:has(.landing) { padding-top: 0; }
body:has(.landing)::before { content: none; }
.landing > .sitefoot { grid-column: 1 / -1; }
/* The landing's own, bigger mark: the start page shows the brand first. */
.landing__mark .logo { block-size: 2.25rem; }
.landing__mark .wordmark { font-size: var(--text-2xl); }

/* sitefoot: the signed-out pages' footer (legal links, cookie notice, contact). */
.sitefoot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-6); padding: var(--space-3) clamp(var(--space-4), 6vw, var(--space-16)); border-top: var(--border-width) solid var(--color-border); color: var(--color-text-muted); font-size: var(--text-sm); }
.sitefoot__links { display: flex; gap: var(--space-6); }
.sitefoot__links a { color: inherit; text-decoration: none; }
.sitefoot__links a:hover { color: var(--color-accent); text-decoration: underline; }
.sitefoot__note { margin: 0 0 0 auto; }
@media (max-width: 36rem) {
  .sitefoot { justify-content: space-between; }
  .sitefoot__note { order: 3; flex-basis: 100%; margin: 0; }
}

/* Legal pages (/privacy, /terms, /cookies): mark on top, the text, the site footer. */
.legal { display: flex; flex-direction: column; min-height: calc(var(--viewport-height) - var(--safe-top) - var(--safe-bottom)); background: var(--color-bg); }
.legal__head { padding: var(--space-6) clamp(var(--space-4), 6vw, var(--space-16)); }
.legal__home { display: inline-flex; align-items: center; gap: var(--space-3); color: var(--color-text); text-decoration: none; }
.legal__main { flex: 1; padding: var(--space-4) clamp(var(--space-4), 6vw, var(--space-16)) var(--space-12); }
.legal__main .prose { margin-inline: auto; }
.landing__brand { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-12); padding: calc(var(--space-12) + var(--safe-top)) clamp(var(--space-6), 6vw, var(--space-16)) var(--space-12); color: var(--gray-0); background:
  radial-gradient(60% 50% at 8% 0%, oklch(from var(--brand-cyan) l c h / 0.45), transparent 70%),
  radial-gradient(55% 45% at 30% 35%, oklch(from var(--brand-blue) l c h / 0.4), transparent 70%),
  radial-gradient(50% 45% at 85% 80%, oklch(from var(--brand-magenta) l c h / 0.4), transparent 70%),
  radial-gradient(45% 40% at 105% 105%, oklch(from var(--brand-orange) l c h / 0.5), transparent 70%),
  var(--brand-night); }
.landing__brand::after { content: ""; position: absolute; inset: auto 0 0 0; height: 3px; background: var(--brand-gradient); }
.landing__pitch h1 em { font-style: normal; background: var(--brand-gradient); -webkit-background-clip: text; background-clip: text; color: transparent; }
.landing__mark { display: flex; align-items: center; gap: var(--space-3); color: inherit; text-decoration: none; font-size: var(--text-lg); font-weight: var(--weight-semibold); letter-spacing: -0.01em; }
.landing__pitch { display: flex; flex-direction: column; gap: var(--space-10); max-width: 34rem; margin-block: auto; }
.landing__pitch h1 { margin: 0; font-size: clamp(var(--text-2xl), 3.4vw, 2.75rem); line-height: 1.1; letter-spacing: -0.02em; font-weight: var(--weight-semibold); }
.landing__points { display: flex; flex-direction: column; gap: var(--space-6); margin: 0; padding: 0; list-style: none; }
.landing__points li { display: flex; gap: var(--space-4); align-items: flex-start; }
.landing__points strong { display: block; font-weight: var(--weight-semibold); }
.landing__point-text { display: block; color: oklch(from var(--gray-0) l c h / 0.78); line-height: var(--leading-normal); }
.landing__point-icon { display: grid; place-items: center; flex: none; inline-size: 2.25rem; block-size: 2.25rem; border-radius: var(--radius-sm); background: oklch(from var(--gray-0) l c h / 0.14); }
.landing__signin { display: grid; place-items: center; padding: var(--space-8) var(--space-6); }
.landing__card { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; max-width: 22rem; }
.landing__card h2 { margin: 0; font-size: var(--text-2xl); letter-spacing: -0.01em; }
.landing__card p { margin: 0; }
.landing__fine { padding-top: var(--space-4); border-top: var(--border-width) solid var(--color-border); color: var(--color-text-muted); font-size: var(--text-sm); }
@media (max-width: 52rem) {
  .landing { grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; }
  .landing__brand { gap: var(--space-8); padding: calc(var(--space-8) + var(--safe-top)) var(--space-4) var(--space-8); }
  .landing__pitch { gap: var(--space-6); }
  .landing__signin { place-items: start center; padding: var(--space-8) var(--space-4) var(--space-12); }
}
/* Phones: the whole sign-in page fits on one screen without scrolling. The points
   keep only their titles; short phones also drop the small print. */
@media (max-width: 36rem) {
  .landing__brand { gap: var(--space-6); padding: calc(var(--space-6) + var(--safe-top)) var(--space-4) var(--space-6); }
  .landing__pitch { gap: var(--space-5); }
  .landing__points { gap: var(--space-3); }
  .landing__points li { align-items: center; gap: var(--space-3); }
  .landing__point-text { display: none; }
  .landing__point-icon { inline-size: 2rem; block-size: 2rem; }
  .landing__signin { place-items: center; padding: var(--space-6) var(--space-4); }
}
@media (max-width: 36rem) and (max-height: 44rem) {
  .landing__fine, .sitefoot__note { display: none; }
}

/* Public home page (/, see Landing): a dark bar and hero on the brand panel (the
   same in both themes, like the sign-in page), then sections on the page colour.
   No JavaScript: anchors jump to the sections. */
.site { --site-pad: clamp(var(--space-4), 6vw, var(--space-16)); --site-edge: max(var(--site-pad), (100% - var(--site-max)) / 2); display: flex; flex-direction: column; min-height: calc(var(--viewport-height) - var(--safe-bottom)); background: var(--color-bg); }
body:has(.site) { padding-top: 0; }
body:has(.site)::before { content: none; }
.site > main { flex: 1; }
.site__bar { position: sticky; top: 0; z-index: var(--z-sticky); display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: calc(var(--space-3) + var(--safe-top)) var(--site-edge) var(--space-3); background: var(--brand-night); color: var(--gray-0); }
.site__brand { display: flex; align-items: center; gap: var(--space-3); color: inherit; text-decoration: none; }
.site__brand .wordmark { font-size: var(--text-xl); }
.site__nav { display: flex; align-items: center; gap: var(--space-2) var(--space-6); }
.site__link { color: oklch(from var(--gray-0) l c h / 0.82); font-size: var(--text-sm); font-weight: var(--weight-medium); text-decoration: none; }
.site__link:hover { color: var(--gray-0); text-decoration: underline; }
.site__hero { position: relative; isolation: isolate; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: center; gap: var(--space-12); padding: var(--space-16) var(--site-edge); color: var(--gray-0); background:
  radial-gradient(60% 60% at 8% 0%, oklch(from var(--brand-cyan) l c h / 0.4), transparent 70%),
  radial-gradient(55% 50% at 35% 45%, oklch(from var(--brand-blue) l c h / 0.35), transparent 70%),
  radial-gradient(50% 50% at 90% 70%, oklch(from var(--brand-magenta) l c h / 0.35), transparent 70%),
  radial-gradient(45% 45% at 105% 110%, oklch(from var(--brand-orange) l c h / 0.45), transparent 70%),
  var(--brand-night); }
.site__hero::after { content: ""; position: absolute; inset: auto 0 0 0; height: 3px; background: var(--brand-gradient); }
.site__hero-text { display: flex; flex-direction: column; gap: var(--space-6); max-width: 38rem; }
.site__hero h1 { margin: 0; font-size: clamp(var(--text-2xl), 4.2vw, 3.25rem); line-height: 1.08; letter-spacing: -0.02em; font-weight: var(--weight-semibold); }
.site__hero h1 em { font-style: normal; background: var(--brand-gradient); -webkit-background-clip: text; background-clip: text; color: transparent; }
.site__eyebrow { margin: 0; color: var(--brand-cyan); font-size: var(--text-sm); font-weight: var(--weight-semibold); letter-spacing: 0.06em; text-transform: uppercase; }
.site__lead { margin: 0; color: oklch(from var(--gray-0) l c h / 0.85); font-size: var(--text-lg); line-height: var(--leading-normal); }
.site__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.site__fine { margin: 0; color: oklch(from var(--gray-0) l c h / 0.7); font-size: var(--text-sm); }
/* The hero's picture of an app: a card in the page's own colours. */
.site__mock { display: flex; flex-direction: column; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); box-shadow: var(--shadow-2); overflow: hidden; }
.site__mock-bar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: var(--border-width) solid var(--color-border); }
.site__mock-dots { display: flex; gap: var(--space-1); margin-inline-start: auto; }
.site__mock-dots span { inline-size: var(--space-2); block-size: var(--space-2); border-radius: var(--radius-full); background: var(--color-border-strong); }
.site__mock-rows { margin: 0; padding: 0; list-style: none; }
.site__mock-rows li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: var(--border-width) solid var(--color-border); }
.site__mock-rows strong { display: block; font-weight: var(--weight-medium); }
.site__mock-meta { display: block; color: var(--color-text-muted); font-size: var(--text-sm); }
.site__mock-auto { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4); background: var(--color-accent-softer); color: var(--color-text); font-size: var(--text-sm); line-height: var(--leading-normal); }
.site__mock-auto .icon { flex: none; margin-top: 0.15em; color: var(--color-accent); }
/* Sections: a heading, then the content, in one centred column. */
.site__section { display: flex; flex-direction: column; gap: var(--space-8); width: 100%; max-width: calc(var(--site-max) + 2 * var(--site-pad)); margin-inline: auto; padding: var(--space-16) var(--site-pad) 0; scroll-margin-top: var(--space-16); }
.site__head { display: flex; flex-direction: column; gap: var(--space-2); max-width: 40rem; }
.site__head h2, .site__cta h2 { margin: 0; font-size: clamp(var(--text-xl), 2.6vw, var(--text-2xl)); letter-spacing: -0.01em; }
.site__head p, .site__cta p { margin: 0; color: var(--color-text-muted); line-height: var(--leading-normal); }
.site__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.site__card { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-5); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.site__card h3, .site__step h3 { margin: 0; font-size: var(--text-md); }
.site__card p, .site__step p { margin: 0; color: var(--color-text-muted); font-size: var(--text-sm); line-height: var(--leading-normal); }
.site__steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: var(--space-6); margin: 0; padding: 0; list-style: none; counter-reset: step; }
.site__step { display: flex; flex-direction: column; gap: var(--space-2); counter-increment: step; }
.site__step::before { content: counter(step); display: grid; place-items: center; inline-size: 2.25rem; block-size: 2.25rem; margin-bottom: var(--space-2); border-radius: var(--radius-full); background: var(--color-accent); color: var(--color-accent-contrast); font-weight: var(--weight-semibold); }
.site__uses { display: flex; flex-wrap: wrap; gap: var(--space-3); margin: 0; padding: 0; list-style: none; }
.site__uses li { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-full); background: var(--color-surface); font-size: var(--text-sm); }
.site__uses .icon { color: var(--color-accent); }
/* Pricing (from PRICING): one card per plan; the highlighted one has an accent border. */
.site__plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.site__plan { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-6); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.site__plan--highlight { border-color: var(--color-accent); box-shadow: 0 0 0 var(--border-width) var(--color-accent), var(--shadow-2); }
.site__plan-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.site__plan h3 { margin: 0; font-size: var(--text-lg); }
.site__price { display: flex; align-items: baseline; gap: var(--space-2); margin: 0; }
.site__price strong { font-size: var(--text-2xl); font-weight: var(--weight-semibold); letter-spacing: -0.01em; }
.site__price span, .site__plan-text, .site__note { color: var(--color-text-muted); font-size: var(--text-sm); }
.site__plan-text { margin: 0; line-height: var(--leading-normal); }
.site__plan-features { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; margin: 0; padding: 0; list-style: none; font-size: var(--text-sm); }
.site__plan-features li { display: flex; align-items: flex-start; gap: var(--space-2); }
.site__plan-features .icon { flex: none; margin-top: 0.15em; color: var(--color-success); }
.site__note { margin: 0; }
.site__cta { align-items: center; padding-bottom: var(--space-16); text-align: center; }
.site__cta .site__actions { justify-content: center; }
.site > .sitefoot { margin-top: var(--space-4); }
@media (max-width: 63.99rem) {
  .site__hero { grid-template-columns: minmax(0, 1fr); gap: var(--space-10); padding-block: var(--space-12); }
  .site__mock { max-width: 32rem; }
}
/* Phones: the bar keeps the brand, Docs and Sign in; sections sit closer. */
@media (max-width: 47.99rem) {
  .site__link--wide { display: none; }
  .site__nav { gap: var(--space-4); }
  .site__hero { padding-block: var(--space-10); }
  .site__lead { font-size: var(--text-md); }
  .site__section { gap: var(--space-6); padding-top: var(--space-12); }
}

/* Site banners (see siteBanners): "get the app" in phone browsers and the beta
   strip. Fixed heights (one line, cut with …), counted in --viewport-height. */
:root:has(.betabar) { --banner-beta: 2rem; }
:root:has(.appbanner) { --banner-app: 3.75rem; }
.sitebanners { position: relative; z-index: var(--z-sticky); }
/* Pages whose brand panel runs under the status bar: the banners take the inset instead. */
body:has(.landing) > .sitebanners, body:has(.site) > .sitebanners { padding-top: var(--safe-top); }
.appbanner { display: flex; align-items: center; gap: var(--space-3); block-size: var(--banner-app); padding-inline: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); background: var(--color-surface); color: var(--color-text); }
.appbanner__icon { flex: none; inline-size: 2.25rem; block-size: 2.25rem; border-radius: var(--radius-sm); }
.appbanner__text { display: flex; flex-direction: column; flex: 1; min-width: 0; font-size: var(--text-sm); line-height: var(--leading-tight); }
.appbanner__text span { overflow: hidden; color: var(--color-text-muted); font-size: var(--text-xs); white-space: nowrap; text-overflow: ellipsis; }
.appbanner form { display: contents; }
.appbanner__close { display: grid; place-items: center; inline-size: 2rem; block-size: 2rem; padding: 0; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--color-text-muted); cursor: pointer; }
.appbanner__close:hover { background: var(--color-surface-hover); color: var(--color-text); }
.betabar { display: flex; align-items: center; justify-content: center; gap: var(--space-3); block-size: var(--banner-beta); padding-inline: var(--space-4); overflow: hidden; background: var(--color-accent-soft); color: var(--color-text); font-size: var(--text-xs); white-space: nowrap; }
.betabar__text { overflow: hidden; text-overflow: ellipsis; }
.betabar__link { flex: none; color: var(--color-accent); font-weight: var(--weight-medium); }
/* The editor preview's "Test data" ribbon: a corner sash like a debug banner, over
   everything and never in the way of a tap. */
.testribbon { position: fixed; top: calc(var(--safe-top) + 0.85rem); inset-inline-end: -2.6rem; z-index: var(--z-toast); inline-size: 10rem; padding-block: 2px; rotate: 45deg; background: var(--color-warning); color: var(--color-accent-contrast); box-shadow: var(--shadow-1); font-size: 0.625rem; font-weight: var(--weight-semibold); letter-spacing: 0.08em; line-height: 1.4; text-align: center; text-transform: uppercase; pointer-events: none; }

/* Page changes: same-site navigations cross-fade quickly while the frame that
   stays (sidebar, editor header, divider, preview, AI dock) holds still instead of
   repainting, so moving between builder sections doesn't jump. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.sidebar { view-transition-name: sidebar; }
.tabbar { view-transition-name: tabbar; }
.mobilebar { view-transition-name: mobilebar; }
.editor__head { view-transition-name: editor-head; }
.editor__divider { view-transition-name: editor-divider; }
.editor__preview { view-transition-name: editor-preview; }
.editor__ai { view-transition-name: editor-ai; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--duration-fast); }
/* The parts that stay show the new page at once (no fade), and the preview keeps
   the old picture until the transition ends, covering the frame's reload. */
::view-transition-group(*) { animation-duration: 0s; }
::view-transition-old(sidebar), ::view-transition-old(tabbar), ::view-transition-old(mobilebar), ::view-transition-old(editor-head), ::view-transition-old(editor-divider), ::view-transition-old(editor-ai) { display: none; }
::view-transition-new(sidebar), ::view-transition-new(tabbar), ::view-transition-new(mobilebar), ::view-transition-new(editor-head), ::view-transition-new(editor-divider), ::view-transition-new(editor-ai) { animation: none; }
::view-transition-new(editor-preview) { animation: none; opacity: 0; }
::view-transition-old(editor-preview) { animation: vt-hold var(--duration-normal); }
@keyframes vt-hold { from, to { opacity: 1; } }

/* Rows of inline forms (roles, view access): hairline-divided, label first. */
.rows { display: flex; flex-direction: column; }
.rows__item { display: flex; align-items: flex-start; gap: var(--space-2); padding-block: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
.rows__item:first-child { padding-top: 0; }
.rows__item > form:first-child { flex: 1; min-width: 0; }
.rows__item > .form-inline { margin-top: calc(var(--text-sm) * var(--leading-normal) + var(--space-1)); }
.rows__label { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 10rem; min-height: var(--control-height); margin-top: calc(var(--text-sm) * var(--leading-normal) + var(--space-1)); font-weight: var(--weight-medium); }

/* The way back up in the editor (one table or view → the list). */
.backlink { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-height); color: var(--color-text-muted); font-size: var(--text-sm); font-weight: var(--weight-medium); text-decoration: none; }
.backlink:hover { color: var(--color-accent); }
.editor__scroll > .backlink + * { margin-top: var(--space-2); }

/* The brand line: the logo's gradient as a thin line on top of appTown's own frame. */
.sidebar { background: var(--brand-gradient) top / 100% 3px no-repeat, var(--color-sidebar); }
.mobilebar { background: var(--brand-gradient) top / 100% 2px no-repeat, var(--color-surface); }
.landing__point-icon { background: oklch(from var(--gray-0) l c h / 0.1); box-shadow: inset 0 0 0 1px oklch(from var(--gray-0) l c h / 0.14); }

/* NewForm: adding to a list. A "+ New x" button opens a marked card (accent dashed
   border, "+" before its title), so a new item never looks like editing an existing one;
   the button becomes Cancel while open. */
.newform { position: relative; }
.newform__toggle { list-style: none; display: inline-flex; cursor: pointer; }
.newform__toggle::-webkit-details-marker { display: none; }
.newform__toggle .btn { pointer-events: none; }
.newform__cancel, .newform[open] .newform__add { display: none; }
.newform[open] .newform__cancel { display: inline-flex; }
.newform[open] > .newform__toggle { position: absolute; top: var(--space-3); inset-inline-end: var(--space-3); z-index: 1; }
.newform__card {
  display: flex; flex-direction: column; gap: var(--gap);
  padding: var(--space-4);
  border: var(--border-width) dashed color-mix(in oklab, var(--color-accent) 55%, transparent);
  border-radius: var(--radius);
  background: var(--color-accent-softer);
}
.newform__head { display: flex; align-items: center; gap: var(--space-2); padding-inline-end: 5rem; }
.newform__head > .icon { color: var(--color-accent); }
.newform__title { font-size: var(--text-md); }
.newform__hint { margin-top: calc(var(--gap) * -0.5); font-size: var(--text-sm); }
.newform .field, .newform .fieldset { max-width: var(--form-max); }

/* EditRow: an existing item reads as itself with an Edit button; editing opens a
   highlighted panel under it and Edit becomes Cancel. */
.editrows { display: flex; flex-direction: column; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); overflow: hidden; }
.editrow + .editrow { border-top: var(--border-width) solid var(--color-border); }
.editrow__view { list-style: none; display: flex; align-items: center; gap: var(--space-2); min-height: calc(var(--control-height) + var(--space-2)); padding: var(--space-1) var(--space-2) var(--space-1) var(--space-3); cursor: pointer; }
.editrow__view::-webkit-details-marker { display: none; }
.editrow__view:hover { background: var(--color-surface-hover); }
.editrow__view:focus-visible { outline: var(--focus-width) solid var(--color-focus-ring); outline-offset: calc(var(--focus-width) * -1); }
.editrow__main { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: var(--space-1) var(--space-3); flex-wrap: wrap; font-size: var(--text-sm); }
.editrow__main > svg { align-self: center; }
.editrow__title { font-weight: var(--weight-medium); }
.editrow__detail { color: var(--color-text-muted); }
.editrow__view .btn { pointer-events: none; }
.editrow__cancel, .editrow[open] .editrow__edit { display: none; }
.editrow[open] .editrow__cancel { display: inline-flex; }
.editrow[open] { background: var(--color-accent-softer); box-shadow: inset 3px 0 0 var(--color-accent); }
.editrow[open] > .editrow__view { background: transparent; }
.editrow__panel { display: flex; flex-direction: column; gap: var(--gap); padding: var(--space-2) var(--space-3) var(--space-3); }
.editrow__panel .field, .editrow__panel .fieldset { max-width: var(--form-max); }
.editrow__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }

/* The builder is a tool: denser than the running app (the app keeps its branding
   density). Every size token is redefined because they are computed on :root.
   Phones keep full-size touch targets; only the spacing tightens there. */
.editor {
  --gap: var(--space-3);
  --page-pad: var(--space-4);
  --section-gap: var(--space-4);
}
@media (min-width: 40rem) {
  .editor {
    --control-height: 2rem;
    --control-pad-x: var(--space-3);
  }
}
.editor .section { gap: var(--space-2) var(--space-6); grid-template-columns: minmax(0, 13rem) minmax(0, 1fr); }
.editor .section__head h2 { font-size: var(--text-sm); }
.editor .section__head .muted { font-size: var(--text-xs); }
.editor .table th { padding-block: var(--space-1); }
.editor .table td { padding-block: var(--space-1); }
.editor .table__actions .cluster { gap: 0; }
.editor .input, .editor .btn { font-size: var(--text-sm); }
.editor__head { padding-top: var(--space-3); }
.editor__head h1 { font-size: var(--text-lg); }
.editor__head .tile { --tile-size: 2rem; }
.editor__scroll { padding-top: var(--space-4); }
.editor__scroll > * + * { margin-top: var(--space-4); }
.editor .chat:empty { display: none; }
/* Reorder buttons sit side by side, right-aligned (each arrow keeps its column). */
.table__move { display: flex; justify-content: flex-end; }
/* Several NewForms side by side: closed ones are buttons in a row; an open one takes the full width. */
.newforms { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2); }
.newforms > .newform[open] { flex-basis: 100%; }
/* CardMenu: a card with a menu button in its top corner (the card stays one link). */
.cardmenu { position: relative; min-width: 0; }
.cardmenu > .cardlink { height: 100%; padding-inline-end: calc(var(--control-height) + var(--space-3)); }
.cardmenu__menu { position: absolute; top: var(--space-2); inset-inline-end: var(--space-2); }
.cardmenu__menu > summary::after { display: none; }
.cardmenu__button { color: var(--color-text-muted); }
.cardmenu__menu[open] .cardmenu__button, .cardmenu__button:hover { color: var(--color-text); background: var(--color-surface-hover); }
/* Phone menu: the app switcher and sign out. */
.switcher { display: flex; flex-direction: column; gap: var(--space-1); }
.switcher__all, .switcher__app { position: relative; display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-height); padding-inline: var(--space-2); border-radius: var(--radius-sm); color: var(--color-text); text-decoration: none; font-size: var(--text-sm); }
.switcher__all { font-weight: var(--weight-medium); color: var(--color-text-muted); }
.switcher__all:hover, .switcher__app:hover { background: var(--color-surface-hover); color: var(--color-text); }
.switcher__app[aria-current="page"] { background: var(--color-accent-soft); font-weight: var(--weight-semibold); }
.drawer__signout { margin-top: auto; padding-top: var(--space-3); border-top: var(--border-width) solid var(--color-border); display: flex; flex-direction: column; gap: var(--space-2); }
.drawer__who { font-size: var(--text-xs); color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ✕ sits exactly where the ☰ button is (same top bar height, same page padding). */
.drawer__panel { padding: calc(var(--topbar-height) + var(--safe-top)) calc(var(--space-4) + var(--safe-right)) calc(var(--space-4) + var(--safe-bottom)) var(--space-4); }
.drawer__close { position: absolute; top: calc(var(--safe-top) + (var(--topbar-height) - var(--touch-target)) / 2); inset-inline-end: calc(var(--page-pad) + var(--safe-right)); }
/* The open drawer dims the page; tapping the dimmed part (the summary's own
   backdrop, so no JS needed) closes it. */
.drawer[open] > summary::before { content: ""; position: fixed; inset: 0; z-index: var(--z-overlay); background: oklch(0% 0 0 / 0.35); cursor: default; }
/* The AI's reply while it is being written: "Thinking" + pulsing dots, then the text. */
.bubble--working { border-style: dashed; }
.thinking { display: inline-flex; align-items: baseline; gap: var(--space-1); color: var(--color-text-muted); }
.thinking__dots { display: inline-flex; gap: 3px; align-self: center; }
.thinking__dots > span { width: 5px; height: 5px; border-radius: 50%; background: var(--color-text-muted); opacity: 0.35; }
@media (prefers-reduced-motion: no-preference) {
  .thinking__dots > span { animation: thinking-dot 1.2s infinite ease-in-out; }
  .thinking__dots > span:nth-child(2) { animation-delay: 0.15s; }
  .thinking__dots > span:nth-child(3) { animation-delay: 0.3s; }
}
@keyframes thinking-dot { 0%, 80%, 100% { opacity: 0.35; transform: none; } 40% { opacity: 1; transform: translateY(-2px); } }
/* The builder's "use a computer" message (see the editor frame). */
.cluster--center { justify-content: center; }
.desktop-only { flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); min-height: 70dvh; padding: var(--space-8) var(--page-pad); text-align: center; }
.desktop-only > .icon { inline-size: 2.5rem; block-size: 2.5rem; color: var(--color-accent); }
.desktop-only h1 { font-size: var(--text-xl); }
.desktop-only p { max-width: 26rem; color: var(--color-text-muted); }
/* Full-page chat (the in-app assistant): the page's full content width, filling the
   screen; the conversation scrolls, the composer stays at the bottom. */
.assistant { display: flex; flex-direction: column; gap: var(--space-3); height: var(--viewport-height); max-width: var(--content-max); margin-inline: auto; padding: var(--space-4) var(--page-pad) var(--space-3); }
.assistant > .pagehead { flex: none; }
/* Messages keep a readable width inside the full-width page. */
.chatbox--page .bubble { max-width: min(52rem, 88%); }
.chatbox--page { flex: 1 1 auto; min-height: 0; gap: var(--space-3); }
.chatbox--page > .chat { flex: 1 1 auto; min-height: 0; max-height: none; padding-inline: var(--space-1); }
.chatbox__composer { flex: none; display: flex; flex-direction: column; gap: var(--space-2); }
.chatbox--page .chatbox__composer { padding: var(--space-2); border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius); background: var(--color-surface); box-shadow: var(--shadow-1); }
.chatbox--page .chatbox__composer:focus-within { border-color: var(--color-focus-ring); }
.chatbox--page .chat-form .textarea { border: 0; box-shadow: none; resize: none; padding-inline: var(--space-2); }
.chatbox--page .chat-form .textarea:focus { outline: none; }
.chat-meta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.chat-meta .field { flex: 0 1 auto; }
.chat-meta .select { min-width: 10rem; }
.chat-empty { margin: auto; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-6) 0; text-align: center; }
.chat-empty__title { font-weight: var(--weight-semibold); font-size: var(--text-md); }
.chat-empty__ideas { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); }
.chat-empty__ideas[hidden] { display: none; }
@media (max-width: 63.99rem) {
  .assistant { height: calc(var(--viewport-height) - var(--topbar-height)); }
  body:has(.tabbar) .assistant { height: calc(var(--viewport-height) - var(--topbar-height) - var(--bottomnav-height)); }
}
/* PageHead: the running app's compact page heading (views, assistant, app home). */
.pagehead { display: flex; align-items: center; gap: var(--space-2); min-width: 0; padding-bottom: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
.pagehead h1 { font-size: var(--text-lg); white-space: nowrap; }
.pagehead__detail { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-sm); color: var(--color-text-muted); }
.page--app { gap: var(--space-4); padding-top: var(--space-4); }

/* 4. Record views (internal/ui/pages/records.templ) -------------------------------- */
/* Option colours (select options, chart series): one hue each, readable in both themes. */
.optbadge--blue, .chart--blue { --opt: oklch(55% 0.16 255); }
.optbadge--green, .chart--green { --opt: oklch(55% 0.13 150); }
.optbadge--orange, .chart--orange { --opt: oklch(62% 0.16 50); }
.optbadge--purple, .chart--purple { --opt: oklch(53% 0.18 300); }
.optbadge--pink, .chart--pink { --opt: oklch(58% 0.18 350); }
.optbadge--teal, .chart--teal { --opt: oklch(55% 0.09 195); }
.optbadge--yellow, .chart--yellow { --opt: oklch(70% 0.14 90); }
.optbadge--red, .chart--red { --opt: oklch(55% 0.19 25); }
.optbadge--gray, .chart--gray, .optbadge--neutral, .chart--neutral { --opt: var(--color-text-muted); }

.viewhead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); padding-bottom: var(--space-3); }
.viewhead + .sections > .section:first-child { border-top: 0; padding-top: 0; }
.viewhead > .pagehead { border-bottom: 0; padding-bottom: 0; flex: 1 1 auto; }
.viewhead__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.viewsearch .input { min-height: calc(var(--control-height) * 0.8); width: min(16rem, 60vw); }
.input--sm { min-height: calc(var(--control-height) * 0.8); padding-inline: calc(var(--control-pad-x) * 0.6); font-size: var(--text-sm); }

.filterbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.filterbar form { display: contents; }
.filterchip { display: inline-flex; align-items: center; gap: var(--space-1); padding: var(--space-1) var(--space-2); border: var(--border-width) solid color-mix(in oklab, var(--color-accent) 40%, transparent); border-radius: var(--radius-full); background: var(--color-accent-soft); color: var(--color-text); font: inherit; font-size: var(--text-sm); cursor: pointer; }
.filterchip:hover { border-color: var(--color-accent); }
.filterchip .icon { inline-size: 0.875rem; block-size: 0.875rem; color: var(--color-text-muted); }

.optbadge { display: inline-flex; align-items: center; max-width: 100%; padding: 0 var(--space-2); border-radius: var(--radius-full); border: var(--border-width) solid color-mix(in oklab, var(--opt) 35%, transparent); background: color-mix(in oklab, var(--opt) 14%, transparent); color: var(--color-text); font-size: var(--text-xs); font-weight: var(--weight-medium); line-height: var(--leading-normal); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
a.optbadge:hover { border-color: var(--opt); }
.cellbadges { display: inline-flex; flex-wrap: wrap; gap: var(--space-1); }
.cellcheck { display: inline-grid; place-items: center; inline-size: 1.125rem; block-size: 1.125rem; border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-sm); }
.cellcheck--on { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-contrast); }
.cellcheck .icon { inline-size: 0.875rem; block-size: 0.875rem; }
.cellstars { color: var(--color-warning); letter-spacing: 0.05em; }
.cellfiles { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.cellthumb { display: block; inline-size: 2.25rem; block-size: 2.25rem; object-fit: cover; border-radius: var(--radius-sm); border: var(--border-width) solid var(--color-border); }
.cellcolor { display: inline-flex; align-items: center; gap: var(--space-2); }
.cellcolor__dot { inline-size: 0.875rem; block-size: 0.875rem; stroke: var(--color-border-strong); }
.celljson { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-text-muted); max-width: 24rem; overflow: hidden; text-overflow: ellipsis; display: inline-block; vertical-align: bottom; }

/* The spreadsheet-like table: column menus, resizable columns (widths per device
   come from the person's cols.css). Phones get a compact list instead. */
.datagrid-wrap { max-height: none; }
.datagrid th { position: relative; padding: 0; }
.datagrid td { max-width: 28rem; overflow: hidden; text-overflow: ellipsis; }
.datagrid col.datagrid__open { width: 2.25rem; }
.datagrid .datagrid__open { width: 2.25rem; padding-inline: var(--space-2); text-align: center; }
.datagrid .datagrid__open a { color: var(--color-text-muted); display: inline-grid; place-items: center; }
.datagrid .datagrid__open .icon { inline-size: 0.875rem; block-size: 0.875rem; }
.datagrid__num { text-align: end; font-variant-numeric: tabular-nums; }
.datagrid__title { color: var(--color-text); }
.datagrid__resize { position: absolute; inset-block: 0; inset-inline-end: -3px; inline-size: 6px; cursor: col-resize; z-index: var(--z-sticky); touch-action: none; }
.datagrid__resize:hover, .datagrid__resize.is-dragging { background: var(--color-accent); opacity: 0.5; }
.colmenu > summary { list-style: none; }
.colmenu > summary::-webkit-details-marker { display: none; }
.colmenu__trigger { display: flex; align-items: center; gap: var(--space-1); padding: var(--space-2) var(--space-3); cursor: pointer; text-transform: none; letter-spacing: 0; }
.colmenu__trigger:hover { background: var(--color-surface-hover); color: var(--color-text); }
.colmenu__trigger .icon { inline-size: 0.875rem; block-size: 0.875rem; flex: none; }
.colmenu__trigger .icon:last-child { opacity: 0.5; }
.colmenu__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.colmenu[open] .colmenu__trigger { background: var(--color-surface-hover); color: var(--color-text); }
.colmenu__panel { position: absolute; inset-inline-start: 0; top: 100%; z-index: var(--z-menu); min-width: max(var(--menu-min), 100%); max-width: 22rem; display: flex; flex-direction: column; padding: var(--space-1); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface-raised); box-shadow: var(--shadow-2); text-align: start; font-weight: var(--weight-normal); text-transform: none; letter-spacing: 0; color: var(--color-text); }
.datagrid__num .colmenu__trigger { justify-content: flex-end; }
.colmenu__group { display: flex; flex-direction: column; padding-block: var(--space-1); }
.colmenu__group + .colmenu__group { border-top: var(--border-width) solid var(--color-border); }
.colmenu__group form { display: contents; }
.colmenu__group form.stack { display: flex; padding: var(--space-1) var(--space-2); gap: var(--space-2); }
.colmenu__cond { display: flex; flex-direction: column; gap: var(--space-2); }
.colmenu__values { display: flex; flex-direction: column; gap: var(--space-1); }
.colmenu__list { display: flex; flex-direction: column; max-height: 14rem; overflow-y: auto; }
.colmenu__value { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1); border-radius: var(--radius-sm); font-size: var(--text-sm); cursor: pointer; }
.colmenu__value:hover { background: var(--color-surface-hover); }
.colmenu__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.listsection { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-text-muted); margin-top: var(--space-2); }

.reclist { list-style: none; margin: 0; padding: 0; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.reclist__item + .reclist__item { border-top: var(--border-width) solid var(--color-border); }
.reclist__link { display: flex; align-items: center; gap: var(--space-3); min-height: var(--touch-target); padding: var(--space-2) var(--space-3); color: var(--color-text); text-decoration: none; }
a.reclist__link:hover { background: var(--color-surface-hover); }
.reclist__link > .icon { flex: none; color: var(--color-text-muted); }
.reclist__img { flex: none; inline-size: 2.75rem; block-size: 2.75rem; object-fit: cover; border-radius: var(--radius-sm); }
.reclist__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.reclist__title { font-weight: var(--weight-medium); color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; }
.reclist__meta { display: flex; flex-wrap: wrap; column-gap: var(--space-3); font-size: var(--text-sm); color: var(--color-text-muted); }
.reclist__meta > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

.reccards { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); }
.reccard { display: flex; flex-direction: column; height: 100%; overflow: hidden; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); color: var(--color-text); text-decoration: none; transition: border-color var(--duration-fast); }
.reccard:hover { border-color: var(--color-accent); }
.reccard__img { display: block; inline-size: 100%; aspect-ratio: 16 / 10; object-fit: cover; background: var(--color-surface-hover); }
.reccard__img--none { display: grid; place-items: center; color: var(--color-text-muted); }
.reccard__body { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); }
.reccard__title { font-weight: var(--weight-semibold); }
.reccard__field { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); }

.kanban { display: flex; gap: var(--gap); overflow-x: auto; align-items: flex-start; padding-bottom: var(--space-2); scroll-snap-type: x proximity; }
.kanban__col { flex: 0 0 min(18rem, 85vw); display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius); background: var(--color-surface-hover); scroll-snap-align: start; }
.kanban__col.is-over { outline: var(--focus-width) dashed var(--color-accent); }
.kanban__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); font-size: var(--text-sm); }
.kanban__cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); min-height: 2.5rem; }
.kanban__card { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) var(--space-3); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface); box-shadow: var(--shadow-1); }
.kanban__card[draggable="true"] { cursor: grab; }
.kanban__card.is-dragging { opacity: 0.5; }
.kanban__title { font-weight: var(--weight-medium); color: var(--color-text); text-decoration: none; }
.kanban__title:hover { color: var(--color-accent); }
.kanban__field { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--text-xs); }
.kanban__move { align-self: flex-end; }

.calendar, .timeline { display: flex; flex-direction: column; gap: var(--space-3); }
.calendar__nav { display: flex; align-items: center; gap: var(--space-2); }
.calendar__nav h2 { font-size: var(--text-md); min-width: 10rem; text-align: center; }
.calendar__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); overflow: hidden; background: var(--color-border); gap: var(--border-width); }
.calendar__dow { padding: var(--space-1) var(--space-2); background: var(--color-surface); font-size: var(--text-xs); color: var(--color-text-muted); font-weight: var(--weight-medium); }
.calendar__day { min-height: 6rem; display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-1); background: var(--color-surface); min-width: 0; }
.calendar__day--out { background: var(--color-bg); }
.calendar__day--out .calendar__num { color: var(--color-text-muted); }
.calendar__day--today .calendar__num { background: var(--color-accent); color: var(--color-accent-contrast); }
.calendar__num { align-self: flex-start; min-width: 1.5rem; padding: 0 var(--space-1); border-radius: var(--radius-full); font-size: var(--text-xs); text-align: center; }
.calendar__event { display: block; padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--color-accent-soft); color: var(--color-text); font-size: var(--text-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
.calendar__event:hover { background: var(--color-accent); color: var(--color-accent-contrast); }
@media (max-width: 39.99rem) {
  /* Phones: the month becomes an agenda (days with records only). */
  .calendar__grid { grid-template-columns: 1fr; }
  .calendar__dow, .calendar__day--empty { display: none; }
  .calendar__day { min-height: 0; flex-direction: row; flex-wrap: wrap; align-items: center; }
  /* Whole-width rows, tall enough to tap. */
  .calendar__event { flex: 1 1 100%; display: flex; align-items: center; min-height: var(--touch-target); padding: 0 var(--space-2); font-size: var(--text-sm); }
}

.timeline__scroll { overflow-x: auto; border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.timeline__svg { display: block; font-family: var(--font-sans); font-size: 12px; }
.timeline__col { fill: transparent; }
.timeline__col--weekend { fill: var(--color-bg); }
.timeline__col--today { fill: var(--color-accent-soft); }
.timeline__month { fill: var(--color-text); font-weight: 500; }
.timeline__daynum { fill: var(--color-text-muted); }
.timeline__rule { stroke: var(--color-border); stroke-width: 1; }
.timeline__name { fill: var(--color-text); font-weight: 500; }
.timeline__bar { fill: var(--color-accent); }
.timeline__barlabel { fill: var(--color-accent-contrast); pointer-events: none; }
a:hover > .timeline__bar { fill: var(--color-accent-hover); }
a:hover > .timeline__name { fill: var(--color-accent); }

.chart { margin: 0; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.chart__title { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-text-muted); }
.chart__number { margin: 0; font-size: var(--text-2xl); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.chart__bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.chart__row { display: grid; grid-template-columns: minmax(6rem, 12rem) 1fr auto; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
.chart__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart__track { display: block; inline-size: 100%; block-size: 1rem; border-radius: var(--radius-sm); background: var(--color-surface-hover); }
.chart__bar { fill: var(--opt); }
.chart__value { font-variant-numeric: tabular-nums; color: var(--color-text-muted); }
.chart__pie { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-6); }
.chart__svg--pie { inline-size: min(14rem, 60vw); block-size: auto; }
.chart__svg--line { inline-size: 100%; block-size: auto; overflow: visible; }
.chart__slice { fill: var(--opt); stroke: var(--color-surface); stroke-width: 0.01; }
.chart__axis { stroke: var(--color-border-strong); stroke-width: 1; }
.chart__line { fill: none; stroke: var(--color-accent); stroke-width: 2.5; stroke-linejoin: round; }
.chart__dot { fill: var(--color-accent); }
.chart__tick { fill: var(--color-text-muted); font-size: 12px; }
.chart__legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); }
.chart__swatch { display: inline-block; inline-size: 0.75rem; block-size: 0.75rem; margin-inline-end: var(--space-2); border-radius: var(--radius-sm); background: var(--opt); vertical-align: middle; }

.dashboard { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(28rem, 100%), 1fr)); align-items: start; }
.dashboard__item { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; max-width: 100%; overflow: hidden; }
.page--app > * { min-width: 0; }
.dashboard__title { font-size: var(--text-md); }
.dashboard__title a { color: var(--color-text); text-decoration: none; }
.dashboard__title a:hover { color: var(--color-accent); }

.recfields { margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr)); gap: var(--space-3) var(--space-6); }
.recfields__row { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.recfields dt { font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.recfields dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }

.recform { display: flex; flex-direction: column; gap: var(--gap); max-width: var(--form-max); }
.recform__fields { display: flex; flex-direction: column; gap: var(--gap); }
.wizard { display: flex; flex-direction: column; gap: var(--gap); }
.wizard__steps { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
.wizard__steps li { padding: var(--space-1) var(--space-3); border-radius: var(--radius-full); background: var(--color-surface-hover); }
.wizard__steps li.current { background: var(--color-accent-soft); color: var(--color-text); font-weight: var(--weight-medium); }
.wizard__step { display: flex; flex-direction: column; gap: var(--gap); border: 0; margin: 0; padding: 0; }
.wizard__step > legend { font-weight: var(--weight-semibold); margin-bottom: var(--space-2); }
.rating { border: 0; margin: 0; padding: 0; }
.rating__stars { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
.rating__stars input { position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; }
.rating__star, .rating__none { display: inline-grid; place-items: center; min-inline-size: var(--touch-target); min-block-size: var(--touch-target); border-radius: var(--radius-sm); cursor: pointer; color: var(--color-text-muted); font-size: var(--text-xl); }
.rating__none { font-size: var(--text-sm); min-inline-size: auto; padding-inline: var(--space-2); }
.rating__star:has(input:checked), .rating__star:has(~ .rating__star input:checked) { color: var(--color-warning); }
.rating__stars label:has(input:focus-visible) { outline: var(--focus-width) solid var(--color-focus-ring); }
.rating__none:has(input:checked) { color: var(--color-text); font-weight: var(--weight-medium); }
.fileinput__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.fileinput__file { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.fileinput__pick, .fileinput__clear { align-self: flex-start; }
.fileinput__pick { cursor: pointer; }
.fileinput__pick:focus-within { outline: var(--focus-width) solid var(--color-focus-ring); }
.sigpad { inline-size: 100%; max-inline-size: 36rem; aspect-ratio: 3 / 1; block-size: auto; border: var(--border-width) dashed var(--color-border-strong); border-radius: var(--radius); background: var(--color-surface); touch-action: none; }
.select__check { inline-size: 1rem; block-size: 1rem; margin: 0; flex: none; accent-color: var(--color-accent); }

.printpage { max-width: 52rem; margin: 0 auto; padding: var(--space-6) var(--page-pad); display: flex; flex-direction: column; gap: var(--space-6); }
.printpage__bar { display: flex; align-items: center; justify-content: space-between; }
.printpage__head h1 { font-size: var(--text-2xl); }
.recfields--print { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media print {
  .printpage__bar, #toasts { display: none !important; }
  .printpage { padding: 0; }
  body { background: white; color: black; }
}

/* Phones: a table view reads as a compact list (first column as the title). */
@media (max-width: 39.99rem) {
  .datagrid thead { display: none; }
  .datagrid, .datagrid tbody, .datagrid tr, .datagrid td { display: block; }
  .datagrid col { display: none; }
  .datagrid tr { position: relative; display: flex; flex-wrap: wrap; column-gap: var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
  .datagrid tr:last-child { border-bottom: 0; }
  .datagrid td { border: 0; padding: 0; max-width: none; text-align: start; }
  .datagrid td.datagrid__open { position: absolute; inset: 0; width: auto; opacity: 0; }
  .datagrid td.datagrid__open a { inline-size: 100%; block-size: 100%; }
  .datagrid td:nth-child(2) { flex-basis: 100%; font-weight: var(--weight-medium); }
  .datagrid td:nth-child(n+3) { font-size: var(--text-sm); color: var(--color-text-muted); }
  .datagrid td:nth-child(n+5) { display: none; }
  .recfields--print { grid-template-columns: 1fr; }
}

/* Automation run log (Build → Automations → a run). */
.runlog { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.runlog__step { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.runlog__io > summary { cursor: pointer; font-size: var(--text-sm); color: var(--color-text-muted); }
.runlog__json { margin: var(--space-2) 0 0; padding: var(--space-2) var(--space-3); max-height: 20rem; overflow: auto; border-radius: var(--radius-sm); background: var(--color-surface-hover); font-family: var(--font-mono); font-size: var(--text-xs); white-space: pre-wrap; overflow-wrap: anywhere; }

/* The offer banner on the apps list (people who own no app yet). */
.promo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-4) var(--space-5); border: var(--border-width) solid color-mix(in oklab, var(--color-accent) 35%, transparent); border-radius: var(--radius); background: var(--color-accent-softer); }
.promo__text { display: flex; flex-direction: column; gap: var(--space-1); max-width: var(--prose-max); }
.promo__title { font-weight: var(--weight-semibold); font-size: var(--text-md); }
.promo__text p:not(.promo__title) { color: var(--color-text-muted); font-size: var(--text-sm); }
.promo__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.promo__more { font-size: var(--text-sm); }
.promo__close { display: inline-grid; place-items: center; inline-size: var(--touch-target); block-size: var(--touch-target); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--color-text-muted); cursor: pointer; }
.promo__close:hover { background: var(--color-surface-hover); color: var(--color-text); }
.navitem__count { margin-inline-start: auto; min-inline-size: 1.25rem; padding: 0 var(--space-1); border-radius: var(--radius-full); background: var(--color-accent); color: var(--color-accent-contrast); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-align: center; }
.notifs { list-style: none; margin: 0; padding: 0; }
.notifs__item { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) 0; border-bottom: var(--border-width) solid var(--color-border); }
.notifs__item--new .notifs__title::before { content: ""; display: inline-block; inline-size: 0.5rem; block-size: 0.5rem; margin-inline-end: var(--space-2); border-radius: var(--radius-full); background: var(--color-accent); vertical-align: middle; }
.notifs__title { font-weight: var(--weight-medium); }
.preview__as { padding: var(--space-2) var(--space-3) 0; }
.preview__as .field { flex-direction: row; align-items: center; gap: var(--space-2); }
.preview__as .field__label { white-space: nowrap; }
.datagrid .datagrid__pick { width: 2.25rem; padding-inline: var(--space-2); text-align: center; }
.bulkbar > summary { list-style: none; display: inline-flex; }
.bulkbar > summary::-webkit-details-marker { display: none; }
.bulkbar__form { margin-top: var(--space-2); padding: var(--space-3); border: var(--border-width) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); align-items: end; }
@media (max-width: 39.99rem) { .datagrid .datagrid__pick { display: none; } }
.mapimg { display: block; inline-size: 100%; max-inline-size: 64rem; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius); border: var(--border-width) solid var(--color-border); }
.celltoggle { display: inline-grid; place-items: center; padding: 0; border: 0; background: transparent; cursor: pointer; }
.celltoggle:hover .cellcheck { border-color: var(--color-accent); }
.datagrid td[data-edit] { cursor: cell; }
.datagrid td.is-saving { opacity: 0.6; }
.datagrid td .input--sm { inline-size: 100%; min-inline-size: 6rem; }
