/* ── scrollbars: hover-only everywhere (v0.3 recipe) ── */
/* Resting panes show no scrollbar; hovering the pane (or anything inside
   it — :hover propagates up) reveals a thin theme-aware thumb. Both
   engines; vars resolve per scope, so dark cards/light cards/chrome each
   get a readable thumb. */
* { scrollbar-width: thin; scrollbar-color: transparent transparent; }
*:hover { scrollbar-color: var(--text-dim) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
*:hover::-webkit-scrollbar-thumb { background: var(--text-dim); }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 'Chakra Petch', system-ui, -apple-system, "Segoe UI", sans-serif;
}
/* ── sidebar — a navigator, not a list ──
   Three zones: ACT (new + search), BROWSE (the category tree), ACCOUNT
   (category mgmt + user). Each is separated by rule and rhythm so the eye can
   find the workflow instead of scanning one undifferentiated column.

   Two things were wrong before, and both read as "unformatted spreadsheet":
   the list had no gap at all, so rows sat flush and merged; and a subcategory
   differed from a category only by `padding-left: 8 + depth*14`, which is
   hierarchy you cannot see. Depth is now DRAWN — a branch rail with an elbow
   into each child — and the branch you are on lights up.

   Type: 500 for row labels (400 read as thin against the board, 600 every row
   read as noise), 600 only for the row you are on. Counts are mono tabular so
   they stop jittering as they change. */
:root {
  --font-display: 'Chakra Petch', ui-sans-serif, system-ui, sans-serif;
  /* Also fixes a latent defect: [data-mfa-codes] referenced var(--font-mono),
     which no rule defined — it resolved to nothing and silently fell back. */
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

#mainRow { display: flex; min-height: 100vh; }
#sidebar {
  --sb-indent: 18px;          /* one tree level */
  /* Fixed: names stay readable at every window size (the drawer below
     900px sets its own width in adaptive.css). */
  width: 232px; flex: none;
  height: 100vh; position: sticky; top: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 12px 10px;
  display: flex; flex-direction: column;
  /* zone rhythm: tight inside a zone, generous between zones */
  gap: 10px;
}
#newEntryBtn {
  display: flex; align-items: center; gap: 8px;
  background: var(--accent); border: 1px solid transparent; color: var(--on-accent);
  border-radius: 8px; padding: 8px 10px;
  font: inherit; font-weight: 700; cursor: pointer;
}
.nb-plus { font-size: 16px; line-height: 1; }
/* key hints: "N" adds a Brik, "/" searches */
#sidebar kbd {
  margin-left: auto; min-width: 18px; padding: 1px 5px; text-align: center;
  font: 700 10px/1.4 var(--font-mono); color: inherit;
  border: 1px solid currentColor; border-radius: 3px; opacity: .6;
}
.sb-search { position: relative; display: flex; align-items: center; color: var(--text-dim); }
.sb-search svg { position: absolute; left: 10px; pointer-events: none; }
.sb-search kbd { position: absolute; right: 8px; pointer-events: none; }
#searchInput {
  width: 100%;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 30px 6px 30px; font: inherit;
}
#searchInput::-webkit-search-cancel-button { display: none; }
.sb-search:focus-within kbd { display: none; }

/* brand: the only place the name shows once logged in */
.sb-brand {
  display: flex; align-items: center; gap: 8px; padding: 2px 4px;
  font-family: var(--font-display); font-size: 14px; font-weight: 700; letter-spacing: .14em;
  user-select: none;
}
.sb-brand img { display: block; }
/* CATEGORIES heading row: label, free-plan count, + new category */
.sb-head { display: flex; align-items: center; gap: 8px; margin: 6px 0 2px; }
.sb-head .sb-label { margin: 0; }
.sb-quota { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); cursor: help; }
.sb-quota.full { color: var(--danger); }
.sb-add {
  margin-left: auto; flex: none;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 16px; line-height: 1; cursor: pointer;
}
.sb-add:hover { color: var(--accent); border-color: var(--accent); }

/* ── zone furniture ── */
.sb-label {
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 500;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-dim);
  padding: 0 6px;
  /* more space above a heading than below it */
  margin: 6px 0 2px;
  user-select: none;
}
.sb-rule {
  height: 1px; flex: none;
  background: var(--border);
  opacity: .65;
  margin: 2px 0;
}
/* the browse zone grows; the void below it is the tree's room to expand */
.sb-grow { flex: 1 1 auto; min-height: 8px; }

#categoryList {
  position: relative;   /* rows' offsetTop and the drop line are measured from here */
  display: flex; flex-direction: column;
  /* the fix for "everything sticks together" — rows breathe */
  gap: 2px;
  overflow-y: auto;
  min-height: 0;
}

/* ── a category row ── */
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 8px;
  padding-left: calc(8px + var(--depth, 0) * var(--sb-indent));
  border-radius: 8px; cursor: pointer;
  font-size: 13px; font-weight: 500;
  /* long names truncate rather than pushing the count out of the column */
  min-width: 0;
}
.nav-item:hover { background: var(--surface-2); }
.nav-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}
/* "you are here": tint + weight + a rounded position marker. The marker is a
   navigation cue on a row, not decorative side-striping on a card — the
   craft-floor default it earns is the one for list rows. */
.nav-item.active {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-weight: 600;
}
.nav-item.active::before {
  content: '';
  position: absolute;
  left: 3px; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 40%;
  border-radius: 999px;
  background: var(--accent);
}
/* card dragged over a category: the move target lights up */
.nav-item.category-drop-target {
  background: var(--surface-2);
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.category-name {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Category colour as a swatch. Rendered only when the API field actually
   parses as a colour, so it reserves no space and names stay aligned. */
.nav-swatch {
  flex: none;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: -2px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 35%, transparent);
}
.count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px; line-height: 1.6;
  color: var(--text-dim);
  background: var(--bg); border-radius: 999px;
  padding: 0 7px; flex: none;
}
.nav-item.active .count {
  background: var(--surface);
  color: var(--text);
}
/* ⋯ opens the category menu (same as right-click / long-press); it shows on
   hover or keyboard focus and stays on for touch (adaptive.css). */
.nav-more {
  flex: none; display: none;
  width: 22px; height: 22px; margin: -3px -4px -3px 0;
  align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 6px; padding: 0;
  color: var(--text-dim); font: inherit; font-size: 15px; line-height: 1; cursor: pointer;
}
.nav-item:hover .nav-more, .nav-item:focus-within .nav-more { display: inline-flex; }
.nav-more:hover { background: var(--bg); color: var(--text); }
/* category drag: a line before/after the target row, or an outline to nest */
.nav-item.dragging { opacity: .45; }
/* where a dragged category lands: a line with a dot between rows, or a ring
   round the row it nests into. Skins with an accent rail set --drop-line. */
.nav-item.drop-into { outline: 2px solid var(--drop-line, var(--accent)); outline-offset: -2px; }
.drop-line {
  position: absolute; right: 4px; height: 2px; z-index: 2; pointer-events: none;
  background: var(--drop-line, var(--accent)); border-radius: 1px;
}
.drop-line::before {
  content: ''; position: absolute; left: -3px; top: -3px; width: 8px; height: 8px; box-sizing: border-box;
  border-radius: 50%; border: 2px solid var(--drop-line, var(--accent)); background: var(--surface);
}

/* ── the tree ──
   Depth is drawn: a continuous branch rail at the parent's indent centre, with
   an elbow into each child. Indent, rail and elbow all derive from --depth so
   they cannot drift apart. */
.nav-item[data-depth]:not([data-depth="0"])::before {
  content: '';
  position: absolute;
  left: calc(8px + (var(--depth, 1) - 1) * var(--sb-indent) + 7px);
  top: 0; bottom: 0;
  width: 1px;
  background: var(--border);
  opacity: .7;
}
.nav-item[data-depth]:not([data-depth="0"])::after {
  content: '';
  position: absolute;
  left: calc(8px + (var(--depth, 1) - 1) * var(--sb-indent) + 7px);
  top: 50%;
  width: calc(var(--sb-indent) - 9px);
  height: 1px;
  background: var(--border);
  opacity: .7;
}
/* the branch you are on lights up — the workflow cue, carried by structure */
.nav-item.active-branch[data-depth]:not([data-depth="0"])::before,
.nav-item.active-branch[data-depth]:not([data-depth="0"])::after {
  background: var(--accent);
  opacity: 1;
}
/* the caret lives in a fixed 16px slot so leaf rows stay aligned with parents */
.nav-slot {
  flex: none;
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
}
.nav-caret {
  flex: none;
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; margin: 0;
  color: var(--text-dim); cursor: pointer;
  border-radius: 4px;
}
.nav-caret:hover { color: var(--text); background: var(--surface-2); }
.nav-caret svg { transition: transform 160ms cubic-bezier(.16, 1, .3, 1); }
.nav-item.collapsed .nav-caret svg { transform: rotate(-90deg); }
.nav-item.active .nav-caret { color: var(--accent); }

/* ── the category menu ── */
.sidebar-foot { display: flex; flex-direction: column; gap: 8px; }
.sidebar-foot button {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px; cursor: pointer; font: inherit;
}

/* right-click menu on a category — the ONE place a destructive action lives.
   Above the phone drawer (120), below dialogs (200). */
.cat-menu {
  position: fixed; z-index: 130;
  min-width: 188px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
}
.cat-menu-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  text-align: left;
  background: none; border: none;
  color: var(--text); font: inherit;
  padding: 8px 10px; border-radius: 7px;
  cursor: pointer;
}
.cat-menu-item:hover { background: var(--surface-2); }
.cat-menu-item.is-danger { color: var(--danger); }
.cat-menu-item.is-danger:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); }
.cat-menu-sep {
  height: 1px; margin: 4px 6px;
  background: var(--border); opacity: .7;
}
.user-row { display: flex; align-items: center; gap: 6px; }
.user-row .user-menu-btn { flex: 1; min-width: 0; }
.sidebar-foot .sb-gear {
  flex: none; width: 30px; height: 30px; padding: 0; cursor: pointer;
  font-size: 16px; line-height: 1; color: inherit;
  background: none; border: 1px solid transparent; border-radius: 6px;
}
.sidebar-foot .sb-gear:hover { border-color: var(--border); }
/* The whole row is the menu trigger — account + appearance live behind it. */
.user-menu-btn {
  flex: 1; min-width: 0;
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 1px solid transparent; border-radius: 8px;
  padding: 5px 6px; cursor: pointer; font: inherit;
}
.user-menu-btn:hover { background: var(--surface-2); border-color: var(--border); }
.topbar-user {
  flex: 1; min-width: 0; text-align: left;
  color: var(--text-dim); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.user-caret { flex: none; color: var(--text-dim); font-size: 10px; }
.user-avatar {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent); color: var(--on-accent);
  font-size: 11px; font-weight: 700; line-height: 1;
}
/* user menu (sidebar foot) — theme selector + the account actions */
.user-menu { min-width: 232px; padding: 6px; }
.user-menu-head {
  padding: 4px 8px 8px; margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.user-menu-label {
  padding: 6px 8px 4px;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px;
  color: var(--text-dim);
}
.look-seg { display: flex; gap: 4px; }
.user-menu :is(.look-seg, .look-swatches) { padding: 0 4px 2px; }
.look-seg button {
  min-width: 0;
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
  background: var(--surface-2); color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 7px; padding: 5px 8px;
}
.user-menu .look-seg button { flex: 1 1 0; }
.look-seg button.active { color: var(--text); border-color: var(--accent); }
/* style picker: a chip of the skin's paper and accent, its name under it */
.look-swatches { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.look-swatches button {
  display: flex; flex-direction: column; align-items: stretch; gap: 4px; min-width: 0;
  font: inherit; font-size: 11px; cursor: pointer; color: var(--text-dim);
  background: none; border: 1px solid transparent; border-radius: 6px; padding: 3px;
}
.look-swatches button.active { color: var(--text); border-color: var(--accent); }
.look-chip {
  height: 26px; border: 1px solid var(--border); border-radius: 4px;
  background: linear-gradient(90deg, var(--ink) 0 22%, var(--paper) 22%);
}
.look-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; }
.settings-box .look-swatches { width: min(440px, 100%); }
.settings-box .look-swatches button { font-size: 12px; padding: 4px; }
html[data-labels="off"] .bookmark-label { display: none; }
.user-menu-sep { height: 1px; background: var(--border); margin: 5px 2px; }
.user-menu-danger { color: var(--danger); }
.user-menu-danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.cols-label { font-size: 13px; color: var(--text-dim); display: flex; gap: 8px; align-items: center; }
.cols-label select { font: inherit; background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 6px; padding: 4px 6px; }
/* settings modal: large dialog, sectioned for current + future options */
#modalBack.modal-wide #modalBox { width: min(640px, 94vw); }
.settings-body { display: flex; flex-direction: column; gap: 4px; }
.set-section { padding: 10px 0; border-bottom: 1px solid var(--border); }
.set-section:first-child { padding-top: 0; }
.set-section h3 { margin: 0 0 10px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-dim); }
/* security section (MFA): status row + inline step buttons */
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.set-status { font-size: 12px; color: var(--text-dim); }
.set-mfa-btn {
  font: inherit; font-size: 13px; cursor: pointer;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 14px;
}
.set-mfa-btn:hover { border-color: var(--accent); }
.set-mfa .form-grid { margin: 10px 0; }
.set-mfa .modal-error { margin-top: 8px; }
.mfa-qr { margin: 12px 0; }
.mfa-qr svg { display: block; width: min(100%, 288px); height: auto; background: #fff; }
.set-foot { padding-top: 12px; font-size: 11px; color: var(--text-dim); }
.content { flex: 1; padding: 16px; overflow-y: auto; }
/* ── grid + tiles ── */
.card-grid {
  --grid-line: transparent;
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  grid-auto-rows: var(--grid-row-height);
  gap: var(--grid-gap);
  padding: calc(var(--grid-gap) / 2);
  width: 100%;
  min-height: calc(((var(--grid-row-height) + var(--grid-gap)) * 8 + var(--grid-gap)) * 0.95);
  align-content: start;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: calc(100% / var(--grid-cols)) calc(var(--grid-row-height) + var(--grid-gap));
  background-position: 0 0;
  justify-items: stretch;
  align-items: stretch;
}
/* search results: reading order, grouped by category (grid.js). Rows size to
   their content so headings stay short; cards keep their height explicitly. */
.is-search > .card, .is-search > .card-tile {
  grid-column: auto / span var(--span-w) !important;
  grid-row: auto !important; align-self: start;
  height: calc(var(--span-h) * var(--grid-row-height) + (var(--span-h) - 1) * var(--grid-gap));
}
.search-summary, .search-group { grid-column: 1 / -1; align-self: end; }
.search-summary { color: var(--text-dim); font-size: 13px; }
.search-group {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-dim); border-bottom: 1px solid var(--border); padding: 0 2px 6px;
}
.card-grid.is-search { grid-auto-rows: auto; grid-auto-flow: row; }   /* no backfilling across groups */
.empty-state {
  grid-column: 1 / -1; align-self: start; justify-self: center; max-width: 420px;
  margin-top: 48px; padding: 32px; text-align: center; color: var(--text-dim);
  border: 1px dashed var(--border); border-radius: var(--radius);
}
.empty-title { color: var(--text); font-size: 16px; font-weight: 600; }
.empty-state p { margin: 8px 0 18px; font-size: 13px; line-height: 1.5; }
.empty-action {
  background: var(--accent); color: var(--on-accent); border: 0; border-radius: 8px;
  padding: 8px 16px; font: inherit; font-weight: 600; cursor: pointer;
}
.empty-action:hover { filter: brightness(1.08); }
.card-tile {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
  transition: box-shadow 160ms ease, border-color 160ms ease;
  /* tile-internal sizing (icon) scales off the tile width, v3 recipe */
  container-type: inline-size;
}
.card-tile:hover { border-color: var(--accent); box-shadow: 0 5px 16px rgba(0, 0, 0, 0.30); }
.card-tile.dragging { opacity: 0.4; }
.tile-body { height: 100%; }
.bookmark-link {
  display: flex; flex-direction: column; align-items: center;
  height: 100%; padding: 12px 10px 8px;
  color: inherit; text-decoration: none;
  user-select: none; -webkit-user-drag: none;
}
.bookmark-link img { -webkit-user-drag: none; }
.bookmark-favicon { width: min(52px, 62cqw); height: auto; aspect-ratio: 1 / 1; margin-top: auto; margin-bottom: auto; }
.bookmark-mono {
  width: min(52px, 62cqw); aspect-ratio: 1 / 1; margin-top: auto; margin-bottom: auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--mono); color: #fff; border-radius: 4px;
  font-family: var(--font-display); font-weight: 700; font-size: min(28px, 34cqw); line-height: 1;
}
.bookmark-label {
  margin-top: auto;
  /* shrink with the tile (cqw needs the container-type on .card-tile):
     full size down to ~63px tiles, then down to an 8px floor — short names
     stay whole instead of collapsing to 'goo…'. */
  font-size: clamp(8px, 19cqw, 12px);
  text-align: center; width: 100%; line-height: 1.2;
  /* up to two lines, so 'Hacker News' fits a one-column tile */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; overflow-wrap: break-word;
}
.tile-actions { position: absolute; top: 4px; right: 4px; display: flex; gap: 4px; }
.card-action {
  display: none;
  width: 26px; height: 26px;
  align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
  cursor: pointer; font-size: 13px; line-height: 1;
}
.card-tile:hover .card-action, .card-head:hover .card-action,
.card-action:focus-visible { display: inline-flex; }
.card-action:hover { border-color: var(--danger); color: var(--danger); }
/* ── band chrome (built in P5, first consumer in P6) ── */
.card {
  position: relative;
  background: var(--surface);
  color: var(--text); /* own scope: card-level var overrides (note/table themes) must take effect here, not inherit past them */
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
  /* Resting depth: whisper-quiet shadow so the board reads tactile, not
     flat. Hover deepens it — no translate, so inline-edit carets never
     shift under the pointer (v0.3 lesson). */
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
  transition: box-shadow 160ms ease, border-color 160ms ease;
}
.card:hover { border-color: var(--accent); box-shadow: 0 5px 16px rgba(0, 0, 0, 0.30); }
.card.dragging { opacity: 0.4; }
.card-head {
  flex: none; height: 32px;
  display: flex; align-items: center; gap: 8px;
  padding: 0 10px;
  border-bottom: 1px solid var(--border);
}
.card-badge {
  font-size: 10px; letter-spacing: 0.4px; text-transform: uppercase;
  color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 1px 7px; white-space: nowrap;
}
/* type badge is hover-only (v0.3 recipe): collapsed out of layout when
   idle, slides open on card hover/focus. margin-right:-8px eats the head
   flex gap so the title sits flush while collapsed (gap is 8px above). */
.card-head .card-badge {
  max-width: 0; opacity: 0; overflow: hidden;
  padding: 1px 0; border-width: 0; margin-right: -8px;
  transition: max-width 160ms ease, opacity 160ms ease, padding 160ms ease,
    margin-right 160ms ease, border-width 160ms ease;
}
.card:hover .card-head .card-badge,
.card:focus-within .card-head .card-badge {
  max-width: 120px; opacity: 1;
  padding: 1px 7px; border-width: 1px; margin-right: 0;
}
.card-tag {
  font-size: 11px;
  background: var(--tag, var(--surface-2));
  border-radius: 999px; padding: 1px 8px; white-space: nowrap;
}
.card-title {
  flex: 1; font-size: 13px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card-title.can-edit { cursor: text; }
/* a short live fact in the head, e.g. "2 / 4" on a checklist */
.card-status:not(:empty) {
  flex: none; font-family: var(--font-mono); font-size: 10px; font-weight: 700;
  border: 1px solid currentColor; border-radius: 3px; padding: 0 5px; opacity: .85;
}
.card-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--text-dim); flex: none; }
.card-dot.is-live { background: #2e9e4f; box-shadow: 0 0 6px #2e9e4fcc; }
.card-dot.is-warn { background: #c77e1f; }
.card-resize-handle {
  touch-action: none; user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
  position: absolute; z-index: 5;
  background: none; border: none; color: var(--text-dim);
  padding: 0;
  display: none;
}
.card:hover .card-resize-handle { display: block; }
/* Declared drag surface: header-only cards (live-iframe bodies) advertise
   the header as the grip. Body keeps its native cursor (clicks pass to the
   player/page); the header shows the grab hand. */
.card[data-drag-surface="header"] .card-head { cursor: grab; }
.card[data-drag-surface="header"] .card-head:active { cursor: grabbing; }
/* corner: classic arrow glyph */
.card-resize-handle.resize-se {
  right: 2px; bottom: 2px; width: 18px; height: 18px;
  cursor: nwse-resize; padding: 2px;
}
/* edges: faint bars on card hover, accent on handle hover. Kept to the
   middle 40% so they never cover scrollbars at the corners. */
.card-resize-handle.resize-e, .card-resize-handle.resize-w {
  top: 30%; bottom: 30%; width: 10px;
  cursor: ew-resize; background-clip: content-box; padding: 0 3px;
}
.card-resize-handle.resize-e { right: 0; }
.card-resize-handle.resize-w { left: 0; }
.card-resize-handle.resize-s {
  bottom: 0; left: 30%; right: 30%; height: 10px;
  cursor: ns-resize; background-clip: content-box; padding: 3px 0;
}
.card:hover .card-resize-handle.resize-e,
.card:hover .card-resize-handle.resize-w,
.card:hover .card-resize-handle.resize-s { background-color: var(--border); }
.card-resize-handle.resize-e:hover,
.card-resize-handle.resize-w:hover,
.card-resize-handle.resize-s:hover { background-color: var(--accent); }
/* Touch devices have no hover: keep grips visible with room for a finger.
   Only grips reserve touch gestures; the card body still scrolls normally. */
@media (any-pointer: coarse) {
  .card .card-resize-handle { display: block; }
  .card-resize-handle.resize-se {
    right: 0; bottom: 0; width: 44px; height: 44px; padding: 12px;
  }
  .card-resize-handle.resize-e, .card-resize-handle.resize-w {
    width: 24px; padding: 0 9px;
  }
  .card-resize-handle.resize-s { height: 24px; padding: 9px 0; }
  .card .card-resize-handle.resize-e,
  .card .card-resize-handle.resize-w,
  .card .card-resize-handle.resize-s { background-color: var(--border); }
}
/* ── drag feedback ── */
.grid-drop-preview {
  border: 2px dashed var(--accent);
  border-radius: var(--radius);
  z-index: 60; pointer-events: none;
}
.grid-drop-preview.occupied { border-style: solid; background: color-mix(in srgb, var(--accent) 12%, transparent); }
.card-grid.drag-target {
  --grid-line: color-mix(in srgb, var(--accent) 16%, transparent);
  /* hide the outermost border lines — keep only inner grid */
  box-shadow: inset 0 0 0 8px var(--bg);
}
.card.swapped, .card-tile.swapped { animation: swapflash 2.5s ease-out; }
@keyframes swapflash {
  0% { box-shadow: 0 0 0 2px var(--danger); }
  100% { box-shadow: none; }
}
/* ── modal ── */
#modalBack {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
}
#modalBox {
  width: min(560px, 92vw); max-height: 88vh; overflow-y: auto;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 16px;
}
.modal-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.modal-head span { flex: 1; font-weight: 700; }
/* header buttons: quiet icon/text actions (close, delete lives here now,
   far from the save row — no more adjacent destructive misclicks) */
.modal-head button {
  font: inherit; cursor: pointer;
  background: none; border: 1px solid transparent; border-radius: 8px;
  color: var(--text-dim); padding: 6px 10px;
}
.modal-head button:hover { background: var(--surface-2); color: var(--text); }
#modalDelete:hover { color: var(--danger); border-color: var(--danger); }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
/* footer holds the single primary action; ✕/Esc dismiss (no Cancel). */
.modal-foot button { font: inherit; cursor: pointer; border-radius: 8px; padding: 6px 14px; }
#modalCancel { background: none; border: 1px solid var(--border); color: var(--text); }
#modalSave { background: var(--accent); border: 1px solid transparent; color: var(--on-accent); font-weight: 600; }
/* The confirm button on a destructive dialog. It is the destructive act, so it
   wears danger — a red-washed accent Save is a trap next to a harmless one. */
#modalSave.is-danger {
  background: var(--danger);
  border-color: transparent;
  color: var(--surface);
}
/* inline validation errors: silent collect() refusals surface here instead */
.modal-error {
  display: none;
  margin-top: 12px; padding: 8px 10px; border-radius: 8px;
  background: #b3261e22; color: var(--text); font-size: 13px;
}
.form-grid { display: flex; flex-direction: column; gap: 10px; }
.form-grid label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.form-grid input {
  font: inherit; color: var(--text);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px;
}
/* ── toasts ── */
#toasts { position: fixed; bottom: 16px; right: 16px; z-index: 300; display: flex; flex-direction: column; gap: 8px; }
.toast {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 10px; padding: 10px 14px; max-width: 340px;
  display: flex; gap: 10px; align-items: center;
}
.toast-error { border-left-color: var(--danger); }
.toast-action {
  background: var(--accent); color: var(--on-accent); border: none;
  border-radius: 7px; padding: 4px 10px; cursor: pointer; font: inherit;
}
/* ── auth ── */
#authView { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.auth-card {
  width: min(380px, 92vw);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px;
  display: flex; flex-direction: column; gap: 12px;
}
.auth-head { display: flex; align-items: center; justify-content: center; gap: 10px; }
.auth-logo { font-family: var(--font-display); font-weight: 800; letter-spacing: 3px; font-size: 20px; line-height: 1.1; }
.auth-tagline { font-size: 12px; color: var(--text-dim); }
#authBody { display: flex; flex-direction: column; gap: 12px; }
.auth-tabs { display: flex; gap: 8px; }
.auth-tabs button {
  flex: 1; font: inherit; cursor: pointer;
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--text-dim); padding: 6px;
}
.auth-tabs button.active { color: var(--text); border-bottom-color: var(--accent); }
.auth-msg { font-size: 13px; border-radius: 8px; padding: 8px 10px; }
.auth-msg.is-error { background: #b3261e22; }
.auth-msg.is-ok { background: #2e9e4f22; }
.auth-card label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.auth-card #authCredentials, .auth-card [data-authmode-only] { display: flex; flex-direction: column; gap: 12px; }
.auth-card h2 { margin: 0; font-size: 20px; }
.auth-card [data-authmode-only] p { margin: 0; font-size: 13px; color: var(--text-dim); }
.auth-card input {
  font: inherit; color: var(--text);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px;
}
.auth-card button#authGo {
  font: inherit; cursor: pointer;
  background: var(--accent); color: var(--on-accent); border: none;
  border-radius: 8px; padding: 9px; font-weight: 600;
}
.auth-card button#authGo:disabled { opacity: 0.65; cursor: default; }
.auth-links { text-align: center; font-size: 13px; }
.auth-links a, .auth-links button { color: var(--accent); }
.auth-links button { background: none; border: none; font: inherit; text-decoration: underline; cursor: pointer; padding: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.user-menu .look-swatches { grid-template-columns: repeat(2, minmax(0, 1fr)); }
