/**
 * The primitives, styled once.
 *
 * Every rule here resolves to a token. Nothing in this file invents a colour, a
 * size or a duration, and nothing outside this file styles a control — that pair
 * of rules is what keeps a tenth button identical to the first.
 *
 * Specificity is deliberately flat: single class selectors, modifiers as separate
 * classes. No nesting, no element selectors fighting class ones over padding.
 */

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

/*
 * The `hidden` attribute must always win over `display`, or an element with
 * any `display`-setting class (`.stack`, `.pane`, `.modes`, anything flex or
 * grid) stays visible the moment something sets `el.hidden = true` — an
 * author-level class selector beats the browser's built-in `[hidden]` rule at
 * equal specificity regardless of source order. Struck once already for the
 * preview panes (see `.pane--local[hidden]` etc. in app.css) as a one-off
 * per-selector patch; this is the same bug recurring somewhere new, fixed at
 * the root instead of a third scoped patch.
 */
[hidden] { display: none !important; }

html, body { height: 100%; margin: 0; }

/*
 * Dynamic viewport height, where supported.
 *
 * `100%`/`100vh` on a phone measures the viewport as if the browser chrome were
 * not there, so the last row — which here is the composer — sits under the
 * address bar until you scroll. `dvh` tracks the chrome as it hides and shows.
 */
@supports (height: 100dvh) {
  html, body { height: 100dvh; }
}

/* Nothing scrolls the page sideways. Wide children scroll inside themselves. */
html, body { overflow-x: hidden; }

body {
  background: var(--c-ground);
  color: var(--c-ink);
  font: var(--w-normal) var(--t-md) / var(--lh-body) var(--f-sans);
  -webkit-font-smoothing: antialiased;
}

/* Visible, consistent, and never removed. */
:focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ------------------------------------------------------------------- layout */

.row {
  display: flex;
  align-items: center;
  min-width: 0;
}

.row--start { align-items: flex-start; }
.row--baseline { align-items: baseline; }
.row--wrap { flex-wrap: wrap; }

.stack { display: flex; flex-direction: column; min-width: 0; }

.row--gap-1, .stack--gap-1 { gap: var(--s-1); }
.row--gap-2, .stack--gap-2 { gap: var(--s-2); }
.row--gap-3, .stack--gap-3 { gap: var(--s-3); }
.row--gap-4, .stack--gap-4 { gap: var(--s-4); }
.row--gap-5, .stack--gap-5 { gap: var(--s-5); }

.panel {
  background: var(--c-sunk);
  border: var(--border);
  border-radius: var(--r-lg);
  padding: var(--s-4);
}

/* ------------------------------------------------------------------ buttons */

/*
 * Measured from Claude Code: 30-32px tall, 13-14px, weight 400-500, radius 6-8,
 * and transparent by default. A filled accent pill is the exception, not the
 * baseline — most buttons in a working interface should recede.
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  height: var(--control-h);
  padding: 0 var(--s-3);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-ink);
  font: var(--w-medium) var(--t-sm) / 1 var(--f-sans);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--m-fast) var(--m-ease), color var(--m-fast) var(--m-ease);
}

.btn:hover:not(:disabled) { background: var(--c-raise); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* The one filled variant, for the single primary action on a surface. */
.btn--primary {
  background: var(--c-accent);
  color: var(--c-accent-ink);
}
.btn--primary:hover:not(:disabled) { background: color-mix(in oklab, var(--c-accent) 88%, black); }

.btn--quiet { border-color: var(--c-line); }
.btn--quiet:hover:not(:disabled) { background: var(--c-raise); }

.btn--bare { color: var(--c-ink-faint); padding: 0 var(--s-2); }
.btn--bare:hover:not(:disabled) { color: var(--c-ink); }

.btn--danger { background: var(--c-bad); color: #fff; }

.btn--sm { height: 26px; padding: 0 var(--s-2); font-size: var(--t-xs); }
.btn--lg { height: 34px; padding: 0 var(--s-5); font-size: var(--t-md); }

/* ------------------------------------------------------------------- inputs */

.input {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-sunk);
  color: inherit;
  font: var(--w-normal) var(--t-md) / var(--lh-body) var(--f-sans);
}

.input::placeholder { color: var(--c-ink-faint); }
.input:focus-visible { border-color: var(--c-accent); }

.input--area { resize: vertical; min-height: 4.5rem; }

.select {
  height: var(--control-h);
  padding: 0 var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--c-sunk);
  color: inherit;
  font: var(--w-normal) var(--t-sm) / 1 var(--f-sans);
  max-width: 15rem;
}
.select:hover { background: var(--c-raise); }

.field { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; }

.field__label {
  color: var(--c-ink-faint);
  font-size: var(--t-xs);
  white-space: nowrap;
}

.field__hint { color: var(--c-ink-faint); font-size: var(--t-sm); }

/* -------------------------------------------------------------------- chips */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 1px var(--s-2);
  border: 0;
  border-radius: var(--r-sm);
  background: var(--c-sunk);
  color: var(--c-ink-faint);
  font: var(--w-normal) var(--t-xs) / 1.7 var(--f-sans);
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chip--good { color: var(--c-good); background: var(--c-accent-soft); }
.chip--warn { color: var(--c-warn); background: var(--c-warn-soft); }
.chip--bad  { color: var(--c-bad);  background: var(--c-bad-soft); }

.chip--code { font-family: var(--f-mono); font-size: var(--t-xs); }

.chip--action { cursor: pointer; border: 0; }
.chip--action:hover { background: var(--c-raise); color: var(--c-ink); }

/* ------------------------------------------------------------------- sheets */

.sheet {
  border: var(--border);
  border-radius: var(--r-lg);
  padding: 0;
  background: var(--c-surface);
  color: var(--c-ink);
  width: min(34rem, calc(100vw - var(--s-6)));
  box-shadow: var(--shadow-sheet);
}
/* Block view with a live canonical preview needs desktop width so responsive
   sections render at their real (non-collapsed) breakpoint. */
.sheet--wide { width: min(76rem, calc(100vw - var(--s-6))); }

.sheet::backdrop { background: rgb(0 0 0 / 0.45); }

.sheet__form { display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-5); }
.sheet__title { margin: 0; font-size: var(--t-lg); font-weight: var(--w-medium); }
.sheet__body { display: flex; flex-direction: column; gap: var(--s-4); }
.sheet__actions { display: flex; justify-content: flex-end; gap: var(--s-2); margin: 0; padding: 0; }

/* --------------------------------------------------------------------- menu */

/*
 * The collapsible menu (see Menu in ui.js). A dropdown anchored under the bar on
 * a wide screen; a bottom sheet on a narrow one. Same dialog, same items — only
 * where it sits changes, and that is a media query, not a second component.
 */
.menu-trigger { padding: 0 var(--s-2); gap: var(--s-2); }

/* Three lines drawn in the current text colour — no glyph, no icon font. */
.menu-trigger__bars {
  width: 16px;
  height: 12px;
  flex: 0 0 auto;
  background:
    linear-gradient(currentColor, currentColor) 0 0 / 100% 2px,
    linear-gradient(currentColor, currentColor) 0 50% / 100% 2px,
    linear-gradient(currentColor, currentColor) 0 100% / 100% 2px;
  background-repeat: no-repeat;
}

.menu {
  margin: 0;
  position: fixed;
  top: calc(var(--bar-h) + var(--s-1));
  left: var(--s-3);
  width: min(18rem, calc(100vw - var(--s-5)));
  max-height: calc(100dvh - var(--bar-h) - var(--s-4));
  padding: var(--s-2);
  border: var(--border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  color: var(--c-ink);
  box-shadow: var(--shadow-sheet);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.menu::backdrop { background: rgb(0 0 0 / 0.3); }

.menu__list { display: flex; flex-direction: column; gap: 2px; }

.menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  text-align: left;
  padding: var(--s-2) var(--s-3);
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-ink);
  font: var(--w-medium) var(--t-sm) / 1.2 var(--f-sans);
  cursor: pointer;
}
.menu__item:hover:not(:disabled) { background: var(--c-raise); }
.menu__item:disabled { opacity: 0.4; cursor: not-allowed; }
.menu__item--danger { color: var(--c-bad); }
.menu__item--primary { color: var(--c-accent); }

.menu__hint { color: var(--c-ink-faint); font-size: var(--t-xs); white-space: nowrap; }

.menu__section {
  padding: var(--s-3) var(--s-3) var(--s-1);
  font: 600 var(--t-xs) / 1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--c-ink-fainter);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.menu__section:first-child { padding-top: var(--s-1); }

.menu__divider { height: 1px; background: var(--c-line); margin: var(--s-1) 0; }

.menu__custom { padding: var(--s-1) var(--s-3); }

/* A phone: the menu rises from the bottom edge, full width, thumb-reachable. */
@media (max-width: 54rem) {
  .menu {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    max-height: 80dvh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-inline: 0;
    border-bottom: 0;
    padding: var(--s-2) var(--s-2) max(var(--s-2), env(safe-area-inset-bottom));
  }
}

/* -------------------------------------------------------------------- empty */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-7) var(--s-4);
  color: var(--c-ink-faint);
  text-align: center;
}

.empty__text { margin: 0; max-width: 34ch; }

/* ------------------------------------------------------------------- shared */

.mono { font-family: var(--f-mono); }
.faint { color: var(--c-ink-faint); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.grow { flex: 1 1 auto; min-width: 0; }
.spacer { flex: 1 1 auto; }

.label {
  font: var(--w-medium) var(--t-xs) / 1 var(--f-mono);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink-faint);
}
