/* Wavelength — v5 "Daylight" visual system.
   Soft, open and flowing rather than boxed-in:
   - Light is the default appearance (a warm off-white page); dark is the
     same system on a deep ink ground, picked with the header toggle.
   - Sections sit straight on the page with a plain heading. Only the
     things you act on (track/label cards, stat tiles, lists) float, as
     rounded white cards with a soft shadow instead of hard borders.
   - One typeface, Plus Jakarta Sans, in sentence case. Numbers use its
     tabular figures where columns need to line up.
   - Shapes: --r-card for cards, --r-ctl for inputs and inner panels, and
     full pills (999px) for buttons, tags, badges and status chips.
   Colors, each with one job, never swapped:
     --accent (coral)       → actions: primary buttons, the current nav
                               item's tint, "Add a track", links.
     --brand-gold (teal)     → the quiet second accent (kept under its old
                               name to avoid renaming ~25 call sites):
                               hovers, small identity badges, match %.
     --status-*              → submission/label state only, always shown as
                               a soft tint with colored text, never a solid
                               slab: medium (amber) = sent / waiting,
                               high (rose) = declined, positive (green) =
                               signed, strategic (gray) = neutral. */

:root {
  --ink: #1F2233;
  --ink-soft: #62667C;
  --paper: #F6F4F1;
  --paper-dim: #EEEAE5;
  --card: #FFFFFF;
  --line: rgba(31, 34, 51, 0.10);
  --line-soft: rgba(31, 34, 51, 0.06);
  /* edge of a text field / select, visible against both card and page */
  --field-border: rgba(31, 34, 51, 0.22);

  --font-display: 'Plus Jakarta Sans', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-body: var(--font-display);
  --font-code: ui-monospace, SFMono-Regular, Menlo, monospace;

  --r-card: 20px;
  --r-ctl: 12px;
  --r-pill: 999px;
  --shadow-card: 0 1px 2px rgba(31, 34, 51, 0.04), 0 14px 36px -18px rgba(31, 34, 51, 0.20);
  --shadow-soft: 0 6px 20px -10px rgba(31, 34, 51, 0.22);
  --page-glow: #FDE9DA;

  --accent: #BD5226;
  --accent-soft: #A6481A;
  --accent-bg: #FBEDE3;
  --accent-line: rgba(189, 82, 38, 0.35);
  --accent-2: #2E8C8A;
  --accent-contrast: #FFFFFF;
  --accent-grad: linear-gradient(135deg, #C25A2C, #B04A20);

  --brand-gold: #1F7472;
  --brand-gold-bg: #E1F1F0;

  --status-high: #B23F58;
  --status-high-bg: #FBE6EA;
  --status-medium: #93600F;
  --status-medium-bg: #FBEFD9;
  --status-strategic: #676C82;
  --status-strategic-bg: #EFEDEA;
  --status-positive: #2B7550;
  --status-positive-bg: #E2F3EA;
  --status-contrast: #FFFFFF;

  /* Chart marks for the three outcomes (Stats page). One set for both
     themes, checked for colorblind separation and 3:1 against either
     card surface; text next to them stays in ink tokens. */
  --chart-sent: #B8862F;
  --chart-declined: #B94163;
  --chart-signed: #30A382;

  --dark-ink: #ECEAF0;
  --dark-ink-soft: #A3A6B8;
  --dark-paper: #14151C;
  --dark-paper-dim: #262833;
  --dark-card: #1E2029;
  --dark-line: rgba(236, 234, 240, 0.12);
  --dark-line-soft: rgba(236, 234, 240, 0.07);
  --dark-field-border: rgba(236, 234, 240, 0.22);
  --dark-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 16px 40px -20px rgba(0, 0, 0, 0.7);
  --dark-shadow-soft: 0 8px 24px -12px rgba(0, 0, 0, 0.7);
  --dark-page-glow: #2A1F1C;

  --dark-accent: #F0986A;
  --dark-accent-soft: #F6B48F;
  --dark-accent-bg: #3A2922;
  --dark-accent-line: rgba(240, 152, 106, 0.4);
  --dark-accent-2: #5BBFBA;
  --dark-accent-contrast: #1B1512;
  --dark-accent-grad: linear-gradient(135deg, #F4A677, #EB8656);

  --dark-brand-gold: #5BBFBA;
  --dark-brand-gold-bg: #183130;

  --dark-status-high: #EE8A9C;
  --dark-status-high-bg: #3A2129;
  --dark-status-medium: #E9B865;
  --dark-status-medium-bg: #372C19;
  --dark-status-strategic: #A3A6B8;
  --dark-status-strategic-bg: #2A2C37;
  --dark-status-positive: #74CFA2;
  --dark-status-positive-bg: #193227;
  --dark-status-contrast: #14151C;
}

/* Dark: chosen with the header toggle (data-theme="dark"). The boot script
   in each page's <head> always sets data-theme, so there is no
   prefers-color-scheme fallback to keep in step. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: var(--dark-ink);
  --ink-soft: var(--dark-ink-soft);
  --paper: var(--dark-paper);
  --paper-dim: var(--dark-paper-dim);
  --card: var(--dark-card);
  --line: var(--dark-line);
  --line-soft: var(--dark-line-soft);
  --field-border: var(--dark-field-border);
  --shadow-card: var(--dark-shadow-card);
  --shadow-soft: var(--dark-shadow-soft);
  --page-glow: var(--dark-page-glow);
  --accent: var(--dark-accent);
  --accent-soft: var(--dark-accent-soft);
  --accent-bg: var(--dark-accent-bg);
  --accent-line: var(--dark-accent-line);
  --accent-contrast: var(--dark-accent-contrast);
  --accent-2: var(--dark-accent-2);
  --accent-grad: var(--dark-accent-grad);
  --brand-gold: var(--dark-brand-gold);
  --brand-gold-bg: var(--dark-brand-gold-bg);
  --status-high: var(--dark-status-high);
  --status-high-bg: var(--dark-status-high-bg);
  --status-medium: var(--dark-status-medium);
  --status-medium-bg: var(--dark-status-medium-bg);
  --status-strategic: var(--dark-status-strategic);
  --status-strategic-bg: var(--dark-status-strategic-bg);
  --status-positive: var(--dark-status-positive);
  --status-positive-bg: var(--dark-status-positive-bg);
  --status-contrast: var(--dark-status-contrast);
}
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--paper);
  /* one soft warm glow behind the header — the only decoration on the page */
  background-image: radial-gradient(1100px 520px at 50% -160px, var(--page-glow), transparent 70%);
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font-family: inherit; }

input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

.wrap { max-width: 1120px; margin: 0 auto; padding: 32px 20px 80px; }

.loading, .empty {
  padding: 32px 20px;
  text-align: center;
  color: var(--ink-soft);
}

.empty a { color: var(--accent); text-decoration: underline; }

/* The header is not a box: the brand on the left, a floating pill nav and
   the account links on the right, all sitting on the page. */
header.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 16px;
  margin-bottom: 32px;
  padding: 4px 0;
}

header.top .brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.brand-mark { flex: none; }

.brand-text {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.brand-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
}

.beta-pill {
  display: inline-block;
  margin-left: 4px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--accent-bg);
  color: var(--accent-soft);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 16px;
  vertical-align: 1px;
  cursor: help;
}

header.top h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  margin: 0;
  letter-spacing: -0.02em;
}

header.top .header-controls {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

/* The section switcher every page's header carries — the same items in
   the same order on every page, with the current one filled so where you
   are is never ambiguous. */
.header-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--card);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-soft);
  flex-wrap: wrap;
}

.nav-link {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 7px 16px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  transition: color 0.15s ease, background 0.15s ease;
}

.nav-link:hover { color: var(--ink); }

.nav-link.nav-current {
  color: var(--card);
  background: var(--ink);
  font-weight: 600;
}

.nav-link.nav-current:hover { color: var(--card); }

.artist-section {
  margin-bottom: 48px;
}

/* The page heading with your artist name, and the button to set it. */
.artist-heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 0 0 20px;
}

.artist-heading h2 { margin: 0 !important; min-width: 0; }

.artist-name-edit,
.artist-name-add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  cursor: pointer;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 600;
}

.artist-name-edit {
  width: 32px;
  height: 32px;
  justify-content: center;
  padding: 0;
  background: transparent;
  color: var(--ink-soft);
}

.artist-name-edit:hover { background: var(--paper-dim); color: var(--ink); }

.artist-name-add {
  padding: 7px 14px 7px 12px;
  background: var(--accent-bg);
  color: var(--accent-soft);
}

.artist-name-add:hover { filter: brightness(0.97); }

.artist-name-edit svg,
.artist-name-add svg { width: 15px; height: 15px; flex: none; }

.artist-section h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 26px;
  margin: 0 0 20px;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

/* Fades each page's content in on load — a small, one-time touch. */
@keyframes dash-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

.artist-section {
  animation: dash-fade-in 0.35s ease both;
}

/* ...but only once: re-renders rebuild these sections, and replaying the
   fade on every click made the whole page blink (common.js sets this). */
.dash-settled .artist-section {
  animation: none;
}

/* One logical group of a page (My Tracks, Submissions Overview, By
   track…) — see renderDashSectionShell in the page scripts. Not a box: a
   heading and its content sitting on the page, separated by space. */
.dash-section {
  margin-bottom: 40px;
}

.dash-section:last-child { margin-bottom: 0; }

.dash-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}

.dash-section-head h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0;
}

.dash-section .track-list {
  margin-bottom: 0;
}

/* A plain floating card, for content inside a section that isn't already a
   card of its own (lists, charts, forms). */
.soft-card,
.overview-list,
.stats-chart,
.stats-track-list,
.stats-label-list,
.getting-started,
.manage-tags {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}

/* The on-hover "i" explainer (the data-tip buttons). A real <button>
   sized to sit quietly next to a label until it's needed; a plain CSS
   tooltip on hover/focus. */
.info-tip {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: none;
  background: var(--paper-dim);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 11px;
  line-height: 1;
  cursor: help;
  padding: 0;
  margin-left: 2px;
}

.info-tip:hover,
.info-tip:focus-visible {
  background: var(--brand-gold-bg);
  color: var(--brand-gold);
  outline: none;
}

.info-tip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);
  width: max-content;
  max-width: 240px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 400;
  font-size: 12.5px;
  line-height: 1.45;
  letter-spacing: 0;
  text-align: left;
  padding: 9px 12px;
  border-radius: var(--r-ctl);
  box-shadow: var(--shadow-soft);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 5;
}

/* Not laid out at all until shown: an invisible max-content tooltip near the
   right edge otherwise widens the page on phones (sideways scrolling). */
.info-tip:not(:hover):not(:focus-visible)::after { display: none; }

/* On a phone the tip spans its section heading's width instead of centring
   on the little "i", so one near the right edge can't run off screen. */
@media (max-width: 640px) {
  .dash-section-head { position: relative; }
  .dash-section-head .info-tip { position: static; }
  .dash-section-head .info-tip::after {
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    transform: translateY(2px);
  }
  .dash-section-head .info-tip:hover::after,
  .dash-section-head .info-tip:focus-visible::after { transform: none; }
}

.info-tip:hover::after,
.info-tip:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* The header's Feedback button — a quiet pill next to the theme toggle;
   just the icon on a phone. */
.feedback-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px 0 12px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--shadow-soft);
  color: var(--ink-soft);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  flex: none;
}

.feedback-btn svg { width: 16px; height: 16px; flex: none; }

.feedback-btn:hover { color: var(--accent); }

@media (max-width: 640px) {
  header.top .header-controls { gap: 8px; }
  .feedback-btn { width: 36px; padding: 0; justify-content: center; }
  .feedback-btn span { display: none; }
}

/* Sun/moon toggle in the header — flips the `data-theme` override (see
   initTheme/setTheme/setupThemeToggle in common.js). */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--card);
  box-shadow: var(--shadow-soft);
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0;
  flex: none;
}

.theme-toggle svg { display: block; width: 15px; height: 15px; }

.theme-toggle:hover { color: var(--brand-gold); }

/* Stat tiles — one small floating card per count, a colored dot naming
   what it counts. */
.urgency-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}

.urgency-tile {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 16px 18px 18px;
  min-width: 0;
}

.urgency-tile-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 4px;
}

.urgency-tile-label::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tile-color, var(--status-strategic));
}

.urgency-tile-count {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.urgency-tile.urgency-high { --tile-color: var(--status-high); }
.urgency-tile.urgency-medium { --tile-color: var(--status-medium); }
.urgency-tile.urgency-strategic { --tile-color: var(--status-strategic); }
.urgency-tile.urgency-accent { --tile-color: var(--status-medium); }
.urgency-tile.urgency-positive { --tile-color: var(--status-positive); }
.urgency-tile.urgency-info { --tile-color: var(--brand-gold); }

/* Buttons: soft pills. Primary is the coral action color, secondary a
   quiet outline. */
.action-copy-btn,
.action-search-btn {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  padding: 8px 16px;
  border-radius: var(--r-pill);
  border: none;
  cursor: pointer;
  white-space: nowrap;
  flex: none;
  text-decoration: none;
  display: inline-block;
  transition: filter 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.action-copy-btn {
  background: var(--accent-grad);
  color: var(--accent-contrast);
}

.action-copy-btn:hover { filter: brightness(1.06); }
.action-copy-btn:disabled { cursor: default; opacity: 0.7; }

.action-search-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink);
}

.action-search-btn:hover { border-color: var(--ink-soft); background: var(--card); }

/* Collapsible panels (label/track details, the Not right now / Archived
   groups) are plain <details>/<summary> — free expand/collapse and
   keyboard support, no JS needed for the toggle itself. */
.dismissed-toggle,
.stat-detail-toggle {
  margin-bottom: 10px;
}

.dismissed-toggle:last-child,
.stat-detail-toggle:last-child {
  margin-bottom: 0;
}

.dismissed-toggle > summary,
.stat-detail-toggle > summary {
  list-style: none;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  padding: 12px 16px;
  background: var(--paper);
  border-radius: var(--r-ctl);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  transition: background 0.15s ease;
}

.dismissed-toggle > summary:hover,
.stat-detail-toggle > summary:hover { background: var(--paper-dim); }

.dismissed-toggle > summary::-webkit-details-marker,
.stat-detail-toggle > summary::-webkit-details-marker {
  display: none;
}

.subgroup-chevron {
  color: var(--ink-soft);
  transition: transform 0.15s ease;
}

.dismissed-toggle[open] > summary .subgroup-chevron,
.stat-detail-toggle[open] > summary .subgroup-chevron {
  transform: rotate(180deg);
}

.dismissed-toggle > summary {
  color: var(--ink-soft);
  font-weight: 500;
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--line);
}

a.logout,
a.header-link {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
}
a.logout:hover,
a.header-link:hover { color: var(--accent); }

/* ---------------------------------------------------------------------
   Label Tracker (dashboard/public/labels.js) — reuses .dash-section,
   .urgency-strip/.urgency-tile, .stat-detail-toggle/.dismissed-toggle,
   .action-copy-btn/.action-search-btn and .info-tip (shared with the other
   pages, above); only the pieces below are specific to it.
   --------------------------------------------------------------------- */

.tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}

.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  padding: 4px 12px 4px 10px;
  border-radius: var(--r-pill);
  background: var(--accent-bg);
  color: var(--ink);
  white-space: nowrap;
}

/* The colored dot carries a vibe tag's "family" identity — see
   renderTagChips in labels.js. Text stays var(--ink) rather than the hue
   itself: coloring the text failed WCAG contrast for every color in the
   7-color vibe palette (as low as ~2:1 for the orange/gray ones). */
.tag-chip-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
}

.tag-chip-empty {
  background: var(--paper-dim);
  color: var(--ink-soft);
}

/* Track add/edit forms: a checkbox-chip picker limited to the vibe-tag
   vocabulary already in use across the label roster (see
   labelTagVocabulary/renderVibeTagPicker in tracks.js) — a track can only
   ever be tagged with a word a label also uses, since a tag neither label
   uses can never move a match score. Reuses .tag-chip's pill shape and
   vibeColor's per-tag hue so a tag looks the same whether you're picking
   it here or just viewing it read-only. Sits inside .inline-edit-form
   (a flex row of name/link/energy fields) but always takes its own full
   row — a wall of chips next to a name input would cramp both. */
.tag-picker {
  flex: 1 1 100%;
  order: 2;
  margin-top: 2px;
}

.tag-picker-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 8px;
}

.tag-picker-hint {
  font-weight: 400;
}

.tag-picker-options {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tag-picker-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 500;
  padding: 5px 12px 5px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}

.tag-picker-chip:hover {
  border-color: var(--ink-soft);
}

/* The checkbox itself is visually hidden (not display:none — it must stay
   in the tab order and stay part of the form) — the chip it's wrapped in
   carries all the visible checked/unchecked state instead. */

.tag-picker-chip input {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 1px !important;
  min-width: 0 !important;
  height: 1px;
  margin: 0;
  padding: 0;
}

.tag-picker-chip::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--chip-color);
  flex: none;
  opacity: 0.4;
}

.tag-picker-chip:has(input:checked) {
  background: color-mix(in srgb, var(--chip-color) 16%, var(--card));
  border-color: var(--chip-color);
  color: var(--ink);
}

.tag-picker-chip:has(input:checked)::before {
  opacity: 1;
}

.tag-picker-chip:has(input:focus-visible) {
  outline: 2px solid var(--accent-line);
  outline-offset: 1px;
}

.tag-picker-empty {
  flex: 1 1 100%;
  font-size: 13px;
  color: var(--ink-soft);
  margin: 2px 0 0;
}

.match-badge {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--brand-gold);
  background: var(--brand-gold-bg);
  padding: 3px 9px;
  border-radius: var(--r-pill);
  margin-left: 8px;
}

.match-badge-lg { font-size: 12.5px; padding: 3px 10px; }

/* My Tracks reuses .label-card/.label-list for its own cards (track-card
   layers on top only where a track needs something a label card doesn't)
   so the two panels read as the same visual system despite showing
   different things. */
.track-card .label-stat-chips { align-items: center; }

/* Each row is its own tiny form (label_id + track_id both fixed via
   data-* on the form) — ranked best-match-first, so tagging a track is
   what surfaces its labels, not the other way round. */
.suggest-list {
  margin-top: 12px;
  padding-top: 4px;
}

.suggest-list-head {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  margin: 8px 4px 8px;
}

.suggest-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--r-ctl);
}

.suggest-row:nth-of-type(odd) { background: color-mix(in srgb, var(--ink) 3%, transparent); }

.suggest-label-name-wrap {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
  min-width: 120px;
  max-width: 100%;
}

.suggest-label-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
}

/* Quick contact lookup right in the suggested-labels list — a small
   "Contact" toggle next to the label name (see renderLabelContactToggle in
   tracks.js) that reveals the demo/contact email or link on click, so
   logging a submission never means leaving the Tracks page to look it up
   on the Labels page. A plain <details>/<summary>, not JS-driven, with a
   shared `name` across every instance (native exclusive-group behavior —
   opening one closes whichever other contact reveal was open) plus a
   click-away-closes listener in tracks.js for the rest of that "only one
   at a time" behavior. Drops onto its own full-width line when open
   (order + flex-basis, same trick as .tag-picker) rather than floating —
   suggest-rows sit only ~49px apart, and an absolutely-positioned popover
   that size reliably covered the very next row's own controls, silently
   swallowing clicks meant for them. */
.label-contact-reveal {
  display: inline-flex;
  order: 5;
}

.label-contact-reveal[open] {
  flex: 1 1 100%;
  display: block;
  min-width: 0;
  max-width: 100%;
}

.label-contact-reveal summary {
  list-style: none;
  cursor: pointer;
}

.label-contact-reveal[open] > summary { display: inline-flex; }

.label-contact-reveal summary::-webkit-details-marker {
  display: none;
}

.label-contact-btn {
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  color: var(--ink-soft);
  background: var(--paper-dim);
  border: none;
}

.label-contact-btn:hover {
  color: var(--ink);
}

.label-contact-reveal[open] .label-contact-btn {
  background: var(--accent-bg);
  color: var(--accent-soft);
}

.label-contact-popover {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-width: 0;
  margin-top: 6px;
  padding: 8px 8px 8px 14px;
  background: var(--paper);
  border-radius: var(--r-ctl);
  font-size: 13px;
  color: var(--ink);
}

/* A long email or submission URL has no natural break points at all, so
   wrapping it just fragments it mid-word — truncated with an ellipsis
   instead (the native title tooltip and the Copy button both still carry
   the full, untruncated value) reads far cleaner in a popover this small. */
.label-contact-value {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.label-contact-value a {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  color: var(--accent);
}

.label-contact-copy {
  font-size: 12.5px;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink-soft);
  cursor: pointer;
  flex: none;
  white-space: nowrap;
}

.label-contact-copy:hover {
  border-color: var(--ink-soft);
  color: var(--ink);
}

.suggest-row select,
.suggest-row input[type="date"] {
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  padding: 7px 10px;
  background: var(--card);
  color: var(--ink);
}

/* The folded "Sent · today ▾" summary on a suggested-label row; opening it
   shows the status and date controls in place. */
.suggest-when {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.suggest-when > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  padding: 5px 8px 5px 12px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease;
}

.suggest-when > summary::-webkit-details-marker { display: none; }

.suggest-when > summary:hover,
.suggest-when[open] > summary {
  color: var(--ink);
  background: var(--paper-dim);
}

.suggest-when[open] > summary .subgroup-chevron { transform: rotate(180deg); }

.suggest-when-fields {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 6px;
}

@media (max-width: 640px) {
  .suggest-when[open] { flex: 1 1 100%; flex-wrap: wrap; gap: 6px; }
  .suggest-row > .match-badge { margin-left: 0; }
  .suggest-row { gap: 8px; }
  .suggest-when-fields { margin-left: 0; flex-wrap: wrap; max-width: 100%; }
  .suggest-when-fields input[type="date"] { min-width: 0; max-width: 100%; }
}

.match-badge-empty {
  color: var(--ink-soft);
  background: var(--paper-dim);
}

/* Labels page only: one line under the artist name giving the roster
   breakdown at a glance (a UX review flagged that most of a real roster
   can end up Archived with nothing in "Not right now" — this surfaces
   that split instead of it only being discoverable by opening every
   group). */
.roster-stat-line {
  font-size: 13.5px;
  color: var(--ink-soft);
  margin: -8px 0 20px;
}

/* Quick-tag: add vibe tags to a label right on its card, no full Edit
   form required — the fast path the suggestion feature on the Tracks
   page actually depends on. */
.quick-tag-form {
  display: flex;
  gap: 8px;
  margin: 12px 0 12px;
}

.quick-tag-form input {
  flex: 1;
  font-size: 13.5px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 8px 14px;
  background: var(--paper);
  color: var(--ink);
  min-width: 0;
}

.quick-tag-form input:focus {
  outline: none;
  border-color: var(--accent-line);
  background: var(--card);
}

/* The "N more labels with no shared tags yet" fold under a track's real
   suggestions — collapsed by default so a mostly-untagged label roster
   doesn't drown out the handful of rows that are an actual match. A UX
   pass flagged the original version (11px, --ink-soft, no border of its
   own) as too easy to miss inside an already-nested accordion — it read as
   trailing text, not a second thing you could click. The dashed border +
   its own tinted background give it a distinct, still-clearly-secondary
   affordance without competing with the real matches above it. */
.suggest-more {
  margin-top: 10px;
}

.suggest-more > summary {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--line);
}

.suggest-more > summary:hover {
  color: var(--ink);
  background: var(--paper);
}


.suggest-more .suggest-row:first-of-type {
  border-top: none;
  padding-top: 12px;
}

.label-add-trigger {
  margin-bottom: 12px;
}

.label-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px 16px;
  margin-top: 4px;
}

.label-form-wide { grid-column: 1 / -1; }

.label-form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
}

.label-form input,
.label-form select,
.label-form textarea,
.inline-edit-form input {
  font-size: 14px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  padding: 10px 12px;
  width: 100%;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.label-form input:focus,
.label-form select:focus,
.label-form textarea:focus,
.inline-edit-form input:focus {
  outline: none;
  border-color: var(--accent-line);
  background: var(--card);
}

.label-form textarea { resize: vertical; min-height: 38px; }

.label-form-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}

.inline-edit-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  flex: 1;
}

.inline-edit-form input { width: auto; flex: 1; min-width: 140px; }

/* The energy field is a <label> wrapping a <select> rather than a bare
   input (it needs visible "Energy" text next to the control, unlike the
   plain-placeholder inputs beside it), so it falls outside the
   ".inline-edit-form input" rule above and needs its own small treatment. */
.inline-edit-energy {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  flex: 0 0 auto;
}
.inline-edit-energy select {
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  padding: 9px 12px;
}
.inline-edit-energy select:focus {
  outline: none;
  border-color: var(--accent-line);
  background: var(--card);
}

/* Getting started (tracks.js renderGettingStarted) — a new account's
   three-step checklist. Accent rule on the left like an active card; the
   current step is the only one expanded. */
.getting-started {
  padding: 20px 22px;
  margin-bottom: 24px;
}

.getting-started-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 12px;
}

.getting-started-head h3 {
  font-family: var(--font-display);
  font-size: 16px;
  margin: 0;
}

.getting-started-count {
  font-size: 13px;
  color: var(--ink-soft);
}

.getting-started-hide {
  margin-left: auto;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink-soft);
  text-decoration: underline;
}

.getting-started-hide:hover { color: var(--ink); }

.getting-started-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.getting-started-step {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  color: var(--ink-soft);
}

.getting-started-step.is-next { color: var(--ink); }

.getting-started-mark {
  flex: none;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  background: var(--paper);
  border-radius: 50%;
}

.getting-started-step.is-next .getting-started-mark {
  background: var(--accent-bg);
  color: var(--accent-soft);
}

.getting-started-step.is-done .getting-started-mark {
  background: var(--status-positive-bg);
  color: var(--status-positive);
}

.getting-started-step.is-done strong {
  font-weight: 500;
  text-decoration: line-through;
  text-decoration-color: var(--line);
}

.getting-started-text { min-width: 0; padding-top: 2px; }
.getting-started-text strong { font-size: 14px; }

.getting-started-text p {
  margin: 4px 0 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 60ch;
}

.getting-started-note {
  font-size: 13.5px;
  color: var(--ink);
  background: var(--accent-bg);
  border-radius: var(--r-ctl);
  padding: 12px 16px;
  margin: 0 0 16px;
}

.getting-started-note a { color: var(--accent-soft); font-weight: 600; }

.getting-started-guide { margin: 14px 0 0; font-size: 13.5px; color: var(--ink-soft); }
.getting-started-guide a { color: var(--accent-soft); font-weight: 600; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Add-track CTA, above the Submissions Overview (see renderTrackAddCta in
   tracks.js) — the page's one filled, glowing pill, so it's the first thing
   your eye lands on without being a full-width slab. */
.track-add-cta-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-bottom: 28px;
}

.track-add-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 14.5px;
  font-weight: 600;
  padding: 12px 24px 12px 20px;
  border-radius: var(--r-pill);
  border: none;
  background: var(--accent-grad);
  color: var(--accent-contrast);
  box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--accent) 70%, transparent);
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.15s ease;
}

.track-add-cta:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
}

.track-add-cta-icon {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
}

/* Once "Add a track" is clicked, the form itself takes over the same slot
   in an accent-tinted panel — carrying the CTA's visual weight through the
   whole add flow instead of dropping back to a plain white box. */
.track-add-cta-panel {
  flex: 1;
  margin-bottom: 4px;
  padding: 20px 22px;
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card), inset 0 0 0 1px var(--accent-line);
}

/* The per-track "Suggested labels & submissions" accordion is the actual
   entry point into the submission process, but a UX pass found it read as
   generic collapse/expand chrome — the same quiet gray as every other
   collapsed panel on the page — with nothing marking it as the thing
   you're meant to act on. Restyled with the accent color and a live count
   badge (see suggestToggleLabel in tracks.js) so it reads as a clear next
   step rather than an FAQ toggle. */
.track-card .track-suggest-toggle { margin-top: 14px; }

.track-suggest-toggle > summary {
  background: var(--accent-bg);
  color: var(--accent-soft);
  box-shadow: none;
}

.track-suggest-toggle > summary:hover {
  background: color-mix(in srgb, var(--accent) 16%, var(--card));
}


.track-suggest-toggle .subgroup-chevron {
  color: var(--accent-soft);
}

.track-suggest-toggle-count {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent-contrast);
  background: var(--accent);
  padding: 2px 10px;
  border-radius: var(--r-pill);
  margin-left: 8px;
}

/* A signed track (see the signedTo branch of renderTrackCard in tracks.js)
   drops the submit toggle: one footer row holds a quiet "History"
   toggle, any energy/link chips, and the card's actions. Opening History
   gives it the full row (flex-basis 100%), which wraps the chips and
   actions onto the next line instead of squeezing the submission table. */
.track-card.track-card-signed {
  padding: 16px 20px;
}

.track-card-signed .tag-chips {
  margin-top: 8px;
}

.track-signed-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 10px;
}

.track-signed-footer .label-card-actions {
  margin-top: 0;
  margin-left: auto;
}

.track-signed-chips {
  margin: 0;
}

.track-history-toggle { min-width: 0; }

.track-history-toggle[open] {
  flex-basis: 100%;
}

.track-history-toggle > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 6px 0;
}

.track-history-toggle > summary::-webkit-details-marker {
  display: none;
}

.track-history-toggle > summary:hover,
.track-history-toggle[open] > summary {
  color: var(--ink);
}

.track-history-count {
  font-weight: 500;
}

.track-history-toggle[open] > summary .subgroup-chevron {
  transform: rotate(180deg);
}

.track-history-toggle .label-detail-body {
  margin-top: 6px;
}

/* .track-list/.track-card (My Tracks) are deliberately separate class
   names from .label-list/.label-card, not just aliases — the label
   filter's JS (setupHandlers' data-label-filter handler) queries
   ".label-list .label-card" by name, and giving My Tracks' cards the same
   classes made them silently vanish under that filter. They share the
   same box styling below so the two panels still read as one visual
   system. */
.label-list,
.track-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 12px;
}

.label-card,
.track-card {
  position: relative;
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 20px 22px 22px;
}

/* The card's own color (its first vibe tag's hue, set inline as
   --card-accent by the page script) as a soft rounded bar on the left. */
.label-card[style*="--card-accent"]::before,
.track-card[style*="--card-accent"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 22px;
  height: 26px;
  width: 4px;
  border-radius: 0 4px 4px 0;
  background: var(--card-accent);
}

.label-card .empty,
.track-card .empty {
  padding: 18px 12px;
  font-size: 14px;
}

.label-card-head {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 2px;
}

/* A small decorative per-track waveform icon (see trackWaveformIcon in
   tracks.js) sitting inline next to the track name — the literal
   reference-material motif (Crates/Traktor), sized and placed like an
   icon rather than a full-width chart strip. Colored via an inline style
   attribute (the track's own vibe-tag color, same rule as the card's
   left-border accent) when the track has tags; falls back to a neutral
   ink tone when it doesn't. */
.track-waveform-icon {
  display: block;
  flex: none;
  color: var(--ink-soft);
  opacity: 0.85;
}

/* Editing swaps a card's own body for its form in place (see
   renderLabelCard in labels.js) — an accent border marks which card is
   currently open, since the surrounding list doesn't otherwise change. */
.label-card.label-card-editing {
  box-shadow: var(--shadow-card), 0 0 0 2px var(--accent-line);
}

.label-card-editing .label-card-head { margin-bottom: 10px; }

.label-card-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 4px;
}

.label-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  margin-right: 8px;
}

.label-status-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--paper-dim);
  color: var(--ink-soft);
  margin-right: 6px;
}

/* A soft tint with colored text, like every other status marker. */
.label-status-pill.label-status-prospect { background: var(--accent-bg); color: var(--accent-soft); }
.label-status-pill.label-status-not_right_now { background: var(--status-medium-bg); color: var(--status-medium); }
.label-status-pill.label-status-archived { background: var(--status-strategic-bg); color: var(--ink-soft); }

/* Label-suggestion status pills — same tint treatment, same
   good/waiting/closed-out meaning as everywhere else in the app. */
.label-status-pill.label-status-sug-pending { background: var(--status-medium-bg); color: var(--status-medium); }
.label-status-pill.label-status-sug-approved { background: var(--status-positive-bg); color: var(--status-positive); }
.label-status-pill.label-status-sug-rejected { background: var(--status-high-bg); color: var(--status-high); }

.label-detail-body {
  margin-top: 14px;
}

.label-detail-row {
  font-size: 14px;
  margin-bottom: 8px;
  word-break: break-word;
}

.label-detail-row strong {
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 13px;
  margin-right: 6px;
}

.label-detail-row a { color: var(--accent); text-decoration: none; }
.label-detail-row a:hover { text-decoration: underline; }

.submission-table-wrap {
  position: relative;
  overflow-x: auto;
  margin-top: 12px;
}

/* Signals there's more to the right (the Notes column, on a narrow phone)
   when plain overflow:auto would otherwise just look like the column is
   missing — toggled by labels.js based on actual scrollWidth vs.
   clientWidth, and cleared once scrolled to the end. */
.submission-table-wrap.has-more-right::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 28px;
  background: linear-gradient(to right, transparent, var(--card));
  pointer-events: none;
}

.submission-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: 13.5px;
}

.submission-table th {
  text-align: left;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 0 10px 8px 0;
}

.submission-table td {
  padding: 7px 10px 7px 0;
  vertical-align: middle;
  border-top: 1px solid var(--line-soft);
}

.sub-track-name {
  font-family: var(--font-display);
  font-weight: 600;
  white-space: nowrap;
}

.sub-status-select {
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  padding: 6px 10px;
  background: var(--card);
  color: var(--ink);
}

.sub-date-input,
.sub-notes-input {
  font-size: 13px;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  padding: 6px 10px;
  background: var(--paper);
  color: var(--ink);
  width: 100%;
  min-width: 100px;
}

/* Removes one logged submission entirely — subtle by default since it's a
   frequent-enough, low-stakes, easily-redone action (log it again via the
   picker below) that a confirm dialog would just be friction. */
.sub-remove-btn {
  background: none;
  border: none;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: var(--r-pill);
}

.sub-remove-btn:hover {
  color: var(--status-high);
  background: var(--status-high-bg);
}

/* Groups the copy-link icon with the remove "✕" in a submission row's last
   cell — same small-icon-button treatment as .sub-remove-btn, just without
   its hover-red (copying isn't a destructive action). */
.sub-row-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  white-space: nowrap;
}

/* One-click "copy this track's private share link" — see
   renderCopyLinkButton in tracks.js for where this shows up (the track
   card header, each suggested-label row, each logged submission row).
   Used to be background:none/border:none until hovered (same footprint
   as .sub-remove-btn) — turned out too easy to miss entirely, since
   nothing about it read as a button until a pointer happened to land on
   it. Now a quiet permanent outline instead, same "always visible, not
   shouting" treatment as .action-contact-btn elsewhere in this file. */
.copy-link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--paper);
  border: none;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 5px 8px;
  border-radius: var(--r-pill);
  min-width: 30px;
  height: 30px;
  flex: none;
  transition: color 0.15s ease, background 0.15s ease;
}

.copy-link-btn svg {
  width: 14px;
  height: 14px;
  display: block;
  flex: none;
}

.copy-link-btn:hover {
  color: var(--accent-soft);
  background: var(--accent-bg);
}

/* The one labeled instance (the track card header, where there's room) —
   a real "Copy link" text button rather than an icon someone has to
   already know to look for. The icon-only rows (suggest/submission) keep
   the compact form above; this just adds the label and lets the button
   size to its content instead of staying icon-square. */
.copy-link-btn--labeled {
  width: auto;
  padding: 5px 12px 5px 10px;
}

.copy-link-btn-label {
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

.copy-link-btn.is-copied {
  color: var(--status-positive);
  background: var(--status-positive-bg);
}

/* Sits inline with the "Log it" button/date picker in a suggested-label
   row rather than at the row's very end — orders itself just before the
   submit button (a fixed flex order, since the row wraps and its exact
   child order can otherwise shift on a narrow screen). */
.suggest-row-copy-link {
  order: 9;
}
.suggest-row button[type="submit"] {
  order: 10;
}

/* A sent/declined submission with no date logged — mostly the
   spreadsheet-migrated rows, which never tracked one. The 21-day
   follow-up nudge can only count submissions that have a date, so this
   flags the ones it's silently skipping rather than leaving them
   looking no different from a submission that's simply up to date. */
.sub-date-input.sub-date-missing {
  border-color: transparent;
  background: var(--status-medium-bg);
}

.label-card-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  flex-wrap: wrap;
}

.label-delete-btn:hover {
  border-color: var(--status-high);
  color: var(--status-high);
  background: var(--status-high-bg);
}

/* Favorite star toggle — outline by default, filled gold once favorited
   (reuses --brand-gold rather than a new hue, since this is exactly the
   "personality/identity" job that color is reserved for elsewhere in the
   app: marking something as yours, not encoding data). */
.star-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--r-ctl);
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  color: var(--ink-soft);
  /* Visible glyph stays 17px, but the actual tap target is padded out to
     ~28px — the visible star alone measured ~19x17px, under the ~24px
     minimum most accessibility guidelines call for a touch target. */
  width: 28px;
  height: 28px;
  padding: 0;
  margin: -5px -2px -5px -6px;
}

.star-btn.is-favorite {
  color: var(--brand-gold);
}

.star-btn:hover {
  color: var(--brand-gold);
}

/* A non-admin sees the favorite star but can't toggle it (favoriting
   writes to the shared label roster) — rendered as a plain span with this
   class instead of a <button data-toggle-favorite>, so it doesn't invite a
   click that would just come back as a permission error. */
.star-btn.star-static {
  cursor: default;
}
.star-btn.star-static:hover {
  color: var(--brand-gold);
}

/* Stat chips on a label card — small soft pills, so follower counts and
   pipeline progress register at a glance instead of blending into the
   meta row. */
.label-stat-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}

.label-stat-chip {
  display: inline-flex;
  align-items: center;
  font-size: 12.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  background: var(--paper);
  border: none;
  border-radius: var(--r-pill);
  padding: 5px 12px;
}

/* A small generic glyph in front of a contact/social field — see
   FIELD_ICONS in labels.js (and SOUNDCLOUD_ICON in tracks.js). Sized and
   colored to sit quietly next to the text, same treatment as the
   dashboard's own .stat-card .label .icon. */
.field-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  margin-right: 5px;
  color: var(--ink-soft);
  vertical-align: -2px;
  flex: none;
}

.field-icon svg { display: block; width: 100%; height: 100%; }

.label-stat-chip strong {
  color: var(--ink);
  font-weight: 600;
}

.label-stat-chip-signed {
  color: var(--status-positive);
  background: var(--status-positive-bg);
  font-weight: 600;
}

/* Search/filter box above the label list — plain DOM show/hide on input,
   not a re-render (see the 'input' handler in labels.js), so typing never
   loses focus. */
.label-list-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
}

.label-filter-input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: none;
  box-shadow: var(--shadow-soft);
  border-radius: var(--r-pill);
  padding: 11px 18px;
}

.label-filter-input:focus {
  outline: none;
  box-shadow: var(--shadow-soft), 0 0 0 2px var(--accent-line);
}

.label-sort-select {
  flex: none;
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: none;
  box-shadow: var(--shadow-soft);
  border-radius: var(--r-pill);
  padding: 11px 16px;
}

.label-sort-select:focus {
  outline: none;
  box-shadow: var(--shadow-soft), 0 0 0 2px var(--accent-line);
}

/* Filter chips under the search box (renderFilterChips in labels.js). */
.filter-chips {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: -4px 0 20px;
}

.filter-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: none;
  background: var(--card);
  color: var(--ink-soft);
  box-shadow: inset 0 0 0 1px var(--line);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.filter-chip:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink-soft); }

.filter-chip.is-on {
  background: var(--ink);
  color: var(--card);
  box-shadow: none;
  font-weight: 600;
}

.filter-chip-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--chip-color);
  flex: none;
}

.filter-chip-more {
  background: transparent;
  box-shadow: none;
  color: var(--accent-soft);
  font-weight: 600;
}

.filter-chip-more:hover { box-shadow: none; text-decoration: underline; }

.filter-chip-clear {
  align-self: flex-start;
  background: none;
  border: none;
  padding: 2px 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-soft);
  cursor: pointer;
}

.filter-chip-clear:hover { text-decoration: underline; }

/* On a phone each chip row scrolls sideways instead of stacking up. */
@media (max-width: 640px) {
  .filter-chip-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 -16px;
    padding: 0 16px 2px;
  }
  .filter-chip-row::-webkit-scrollbar { display: none; }
  .filter-chip { flex: none; }
}

@media (max-width: 520px) {
  .label-list-controls {
    flex-wrap: wrap;
  }
  .label-sort-select {
    flex: 1 1 100%;
  }
}

/* My Tracks' own sort control + "move signed to bottom" toggle — same
   treatment as .label-list-controls/.label-sort-select above, just without
   a filter box. */
.track-list-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.track-sort-select {
  font-size: 14px;
  color: var(--ink);
  background: var(--card);
  border: none;
  box-shadow: var(--shadow-soft);
  border-radius: var(--r-pill);
  padding: 10px 16px;
}

.track-sort-select:focus {
  outline: none;
  box-shadow: var(--shadow-soft), 0 0 0 2px var(--accent-line);
}

.track-sort-signed-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
}

.track-sort-signed-toggle input {
  cursor: pointer;
}

/* "Signed to X" badge — used both on a track row in My Tracks and in the
   Submissions Overview, always the same look: a green tinted pill. */
.signed-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--status-positive);
  background: var(--status-positive-bg);
  padding: 4px 8px 4px 12px;
  border-radius: var(--r-pill);
  margin-left: 8px;
  max-width: 100%;
}

.signed-badge-text {
  white-space: normal;
  min-width: 0;
  overflow-wrap: anywhere;
}

.track-private-link {
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}

.track-private-link:hover { text-decoration: underline; }

.sub-row-signed {
  background: color-mix(in srgb, var(--status-positive) 6%, transparent);
}

/* Submissions Overview — one row per track, either a signed badge or a
   row of small status-colored pills naming every label it's gone to. */
.overview-list {
  margin-top: 4px;
  padding: 6px 22px;
}

.overview-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  padding: 13px 0;
  border-top: 1px solid var(--line-soft);
}

.overview-row:first-child { border-top: none; }

.overview-track-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  min-width: 150px;
}

.overview-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.overview-pill {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 12.5px;
  font-weight: 500;
  padding: 4px 6px 4px 12px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  max-width: 100%;
}

.overview-pill-empty {
  background: var(--status-strategic-bg);
  color: var(--ink-soft);
  padding: 4px 12px;
}

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

/* The status half of a pill/badge is a real <select> — see
   renderOverviewStatusSelect in labels.js — styled to disappear into the
   pill it sits in (no border, matching background, a tiny caret) so
   changing "Sent" to "Signed" is one click right here instead of a trip
   into the label card. */
.overview-status-select {
  appearance: none;
  -webkit-appearance: none;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 16px 2px 4px;
  border-radius: var(--r-pill);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 7px top 55%, right 4px top 55%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  opacity: 0.9;
}

.overview-status-select:hover,
.overview-status-select:focus-visible {
  opacity: 1;
  background-color: color-mix(in srgb, currentColor 12%, transparent);
}

.overview-pill-select {
  font-size: 12.5px;
}

.signed-badge-select {
  color: var(--status-positive);
  font-size: 12.5px;
}

.signed-badge-select:hover,
.signed-badge-select:focus-visible {
  background-color: color-mix(in srgb, currentColor 12%, transparent);
}

.overview-more {
  border: none;
  background: transparent;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent-soft);
  cursor: pointer;
}

.overview-more:hover { background: var(--accent-bg); }

/* Signed tracks fold into one line at the bottom of the overview. */
.overview-signed {
  border-top: 1px solid var(--line-soft);
}

.overview-list > .overview-signed:first-child { border-top: none; }

.overview-signed > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
}

.overview-signed > summary::-webkit-details-marker { display: none; }

.overview-signed-title {
  flex: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--status-positive);
  background: var(--status-positive-bg);
  padding: 4px 12px;
  border-radius: var(--r-pill);
}

.overview-signed-names {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.overview-signed > summary:hover .overview-signed-names { color: var(--ink); }

.overview-signed[open] > summary .subgroup-chevron { transform: rotate(180deg); }

.overview-signed[open] .overview-signed-names { visibility: hidden; }

/* Soft tints: amber = sent and waiting, rose = declined, green = signed. */
.overview-pill.sub-sent { background: var(--status-medium-bg); color: var(--status-medium); }
.overview-pill.sub-declined { background: var(--status-high-bg); color: var(--status-high); }
.overview-pill.sub-signed { background: var(--status-positive-bg); color: var(--status-positive); }

/* Sticky "couldn't save" banner — appended straight to <body> (see
   renderSyncBanner in labels.js), not inside #app, specifically so a
   normal full-page re-render never touches or clears it. Uses the shared
   status-high red rather than a one-off color: this genuinely is the
   "something needs your attention" state that color is reserved for
   elsewhere in the app. */
.sync-banner {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  background: var(--status-high);
  color: var(--status-contrast);
  border-radius: var(--r-card);
  padding: 10px 10px 10px 18px;
  box-shadow: var(--shadow-card);
  font-size: 13.5px;
  line-height: 1.4;
}

.sync-banner button {
  flex: none;
  background: var(--status-contrast);
  color: var(--status-high);
  border: none;
  border-radius: var(--r-pill);
  padding: 8px 14px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
}

.sync-banner button:disabled {
  opacity: 0.7;
  cursor: default;
}

@media (max-width: 640px) {
  .sync-banner {
    left: 14px;
    right: 14px;
    bottom: 14px;
    transform: none;
    max-width: none;
    flex-direction: column;
    align-items: stretch;
    text-align: center;
  }
}

/* "You don't have permission to do that" — same fixed-toast placement as
   .sync-banner (stacks above it if both are ever showing at once) but its
   own quieter ink-soft tone rather than status-high red: this isn't an
   error to fix, it's an expected boundary (only an admin edits the shared
   roster) and it auto-dismisses on its own rather than sitting there
   asking to be retried. See showPermissionNotice in labels.js. */
.permission-banner {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 51;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  background: var(--ink);
  color: var(--card);
  border-radius: var(--r-card);
  padding: 10px 12px 10px 18px;
  box-shadow: var(--shadow-card);
  font-size: 13.5px;
  line-height: 1.4;
}

.permission-banner button {
  flex: none;
  background: transparent;
  color: var(--card);
  border: none;
  opacity: 0.7;
  font-size: 14px;
  cursor: pointer;
  padding: 2px 4px;
}

.permission-banner button:hover { opacity: 1; }

@media (max-width: 640px) {
  .permission-banner {
    left: 14px;
    right: 14px;
    bottom: 14px;
    transform: none;
    max-width: none;
  }
}

/* Label-suggestion cards — the review queue (admin) and "my suggestions"
   history (artist), both on labels.html. Deliberately plain — a quieter
   cousin of .label-card, since a suggestion isn't a full roster entry yet. */
.suggestion-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}

.suggestion-card {
  border-radius: var(--r-card);
  padding: 16px 18px;
  background: var(--card);
  box-shadow: var(--shadow-card);
}

.suggestion-card-reviewed {
  opacity: 0.85;
}

.suggestion-card-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* Private labels (labels.js) — an outline pill beside the name, so it
   reads as "who can see this", distinct from the solid status pills. */
.label-private-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  color: var(--brand-gold);
  background: var(--brand-gold-bg);
  margin-right: 6px;
  white-space: nowrap;
}

/* "Share with everyone" on your own private label (renderShareStrip). */
.share-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: 14px;
  padding: 10px 10px 10px 16px;
  border-radius: var(--r-ctl);
  background: var(--accent-bg);
}

.share-strip-text {
  font-size: 13.5px;
  color: var(--ink);
  min-width: 0;
}

.share-strip.is-pending {
  background: var(--brand-gold-bg);
  padding: 10px 16px;
}

.share-strip.is-pending .share-strip-text {
  color: var(--brand-gold);
  font-weight: 600;
}

.label-private-note {
  align-self: center;
  font-size: 13px;
  color: var(--ink-soft);
}

.label-form-hint {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--ink-soft);
  max-width: 70ch;
}

.label-form-private {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 12px;
  font-size: 13px;
  color: var(--ink);
}

.label-owner-line {
  font-size: 13px;
  color: var(--brand-gold);
}

.label-card-readonly .label-detail-row { margin: 8px 0 0; }

.others-private-intro {
  margin: 12px 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-soft);
}

.suggestion-byline {
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-soft);
}

.suggestion-meta {
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-soft);
}

.suggestion-meta a { color: inherit; }

.suggestion-notes {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* Mobile. Most layout already flexes without a breakpoint; this tightens
   spacing/sizing that reads cramped once the whole page is phone-width. */
@media (max-width: 640px) {
  .wrap {
    padding: 20px 16px 56px;
  }

  header.top {
    margin-bottom: 20px;
  }

  header.top h1 {
    font-size: 20px;
  }

  .artist-section h2 {
    font-size: 22px;
  }

  .dash-section {
    margin-bottom: 32px;
  }

  .dash-section-head h3 {
    font-size: 18px;
  }

  .urgency-strip {
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
  }

  .urgency-tile {
    padding: 10px 12px 12px;
    border-radius: 16px;
  }

  .urgency-tile-label {
    font-size: 12px;
    gap: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .urgency-tile-count {
    font-size: 22px;
  }

  /* fill the last row: a lone last tile spans it, two share it */
  .urgency-strip > .urgency-tile:last-child:nth-child(3n+1) { grid-column: 1 / -1; }
  .urgency-strip > .urgency-tile:last-child:nth-child(3n+2) { grid-column: span 2; }

  .label-card,
  .track-card {
    padding: 16px 16px 18px;
    border-radius: 18px;
  }

  .overview-list,
  .stats-track-list,
  .stats-label-list {
    padding: 4px 16px;
  }

  .stats-chart {
    padding: 18px 16px 16px;
  }

  .label-form-grid {
    grid-template-columns: 1fr;
  }

  .suggest-row {
    padding: 10px;
  }

  .suggest-label-name-wrap {
    flex: 1 1 calc(100% - 30px);
    min-width: 0;
  }

  .suggest-row button[type="submit"] {
    margin-left: auto;
  }

  .label-card-title {
    gap: 6px 4px;
  }

  .overview-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ---------------------------------------------------------------------
   Label Stats (dashboard/public/stats.js) — reuses .urgency-strip/
   .urgency-tile and .dash-section (shared, above); the
   pieces below are specific to its two charts: a monthly "sends over
   time" bar chart, and a per-track stacked-bar outcome breakdown.
   Plain HTML/CSS bars rather than SVG — per the dataviz skill's mark
   spec: <=24px thick bars, 4px rounded top squared at the baseline,
   hairline recessive gridlines, a 2px surface gap between stacked
   segments, text in ink tokens (never the series color).
   --------------------------------------------------------------------- */

.stats-chart {
  margin-top: 4px;
  padding: 22px 24px 20px;
}

.stats-chart-plot {
  position: relative;
  height: 150px;
  margin-left: 34px;
  border-bottom: 1px solid var(--line-soft);
  background-image: linear-gradient(var(--line-soft), var(--line-soft)), linear-gradient(var(--line-soft), var(--line-soft));
  background-size: 100% 1px, 100% 1px;
  background-position: top, center;
  background-repeat: no-repeat;
}

.stats-axis-label {
  position: absolute;
  left: -34px;
  width: 28px;
  text-align: right;
  font-size: 12px;
  color: var(--ink-soft);
}

.stats-bar-row {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 4px;
  padding: 0 4px;
}

.stats-bar-col {
  flex: 1;
  min-width: 0;
  display: flex;
  justify-content: center;
}

.stats-bar {
  width: 100%;
  max-width: 34px;
  background: var(--accent);
  border-radius: 4px 4px 0 0;
}

/* The busiest month, called out in the second accent color — same
   "peak reading" treatment as the mentions histogram and the sparklines'
   current-value bar. */
.stats-bar.stats-bar-peak {
  background: var(--accent-2);
}

.stats-bar-labels {
  display: flex;
  gap: 4px;
  margin-left: 38px;
  margin-right: 4px;
  margin-top: 6px;
}

.stats-bar-label-item {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-size: 12px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stats-chart-note {
  margin-top: 12px;
  font-size: 13px;
  color: var(--ink-soft);
}

.stats-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 14px;
  font-size: 13px;
  color: var(--ink-soft);
}

.stats-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.stats-legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}

.stats-track-list, .stats-label-list {
  display: flex;
  flex-direction: column;
  padding: 6px 22px;
}

.stats-track-row, .stats-label-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--line-soft);
}

.stats-track-row:first-child, .stats-label-row:first-child {
  border-top: none;
}

.stats-track-name, .stats-label-name {
  width: 170px;
  flex: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stats-track-bar-wrap, .stats-label-bar-wrap {
  flex: 1;
  min-width: 60px;
}

.stats-track-bar, .stats-label-bar {
  display: flex;
  height: 12px;
  border-radius: 4px;
  overflow: hidden;
  gap: 2px;
}

.stats-track-seg, .stats-label-seg {
  display: block;
}

.stats-track-total, .stats-label-total {
  width: 64px;
  flex: none;
  text-align: right;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

.stats-track-rate, .stats-label-rate {
  width: 90px;
  flex: none;
  text-align: right;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--status-positive);
}

@media (max-width: 640px) {
  .stats-track-row, .stats-label-row {
    flex-wrap: wrap;
  }

  .stats-track-name, .stats-label-name {
    width: 100%;
  }

  .stats-track-bar-wrap, .stats-label-bar-wrap {
    order: 1;
    flex: 1 1 auto;
  }

  .stats-track-total, .stats-label-total,
  .stats-track-rate, .stats-label-rate {
    width: auto;
    text-align: left;
  }
}

/* ---------------------------------------------------------------------
   Phone-width bottom navigation (renderPageHeader in common.js). Under
   640px the header's section tabs, Account and Log out move to a fixed
   bar along the bottom edge, in thumb reach; Log out stays on /account.
   Everything else that pins itself to the bottom (sync/permission
   banners, toasts) sits above it.
   --------------------------------------------------------------------- */
.bottom-nav { display: none; }

@media (max-width: 640px) {
  .bottom-nav {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom, 0));
    z-index: 40;
    padding: 4px;
    background: color-mix(in srgb, var(--card) 90%, transparent);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-radius: 22px;
    box-shadow: 0 12px 34px -10px rgba(20, 21, 28, 0.35);
  }
  .bottom-nav-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 4px 7px;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--ink-soft);
    text-decoration: none;
    border-radius: 18px;
  }
  .bottom-nav-link svg { width: 20px; height: 20px; }
  .bottom-nav-link.is-current {
    color: var(--accent-soft);
    background: var(--accent-bg);
    font-weight: 600;
  }
  header.top .header-nav,
  header.top .header-link,
  header.top a.logout { display: none; }
  .wrap { padding-bottom: calc(110px + env(safe-area-inset-bottom, 0)); }
  .sync-banner,
  .permission-banner { bottom: calc(88px + env(safe-area-inset-bottom, 0)); }
  .toast-stack { bottom: calc(88px + env(safe-area-inset-bottom, 0)); }
}

/* ---------------------------------------------------------------------
   Tag input (renderTagInput in common.js): chosen tags as chips inside
   what looks like one text field, with suggestions from a <datalist>.
   --------------------------------------------------------------------- */
.tag-input { display: flex; flex-direction: column; gap: 6px; }
.tag-input-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
}
.tag-input-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  background: var(--paper);
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  min-height: 42px;
}
.tag-input-box:focus-within { border-color: var(--accent-line); }
.tag-input-chips { display: contents; }
.tag-input-chip { padding-right: 2px; }
.tag-input-remove {
  background: none;
  border: none;
  padding: 0 4px;
  margin-left: 2px;
  cursor: pointer;
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1;
}
.tag-input-remove:hover { color: var(--ink); }
.tag-input-text {
  flex: 1 1 140px;
  min-width: 120px;
  border: none;
  background: transparent;
  color: var(--ink);
  font-size: 14px;
  padding: 4px 4px;
}
.tag-input-text:focus { outline: none; }

/* ---------------------------------------------------------------------
   In-page dialogs (openDialog in common.js) and toasts (showToast /
   deleteWithUndo). Rounded floating cards over a softly dimmed page.
   --------------------------------------------------------------------- */
.app-dialog {
  width: min(460px, calc(100vw - 32px));
  padding: 0;
  border: none;
  border-radius: var(--r-card);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.35);
}
.app-dialog::backdrop { background: rgba(20, 21, 28, 0.45); backdrop-filter: blur(3px); }
.app-dialog-form { padding: 24px 26px 22px; display: flex; flex-direction: column; gap: 12px; }
.app-dialog-title { font-family: var(--font-display); font-size: 19px; font-weight: 700; letter-spacing: -0.01em; margin: 0; line-height: 1.3; }
.app-dialog-body p { margin: 0 0 8px; font-size: 14px; line-height: 1.55; color: var(--ink-soft); }
.app-dialog-body p:last-child { margin-bottom: 0; }
.app-dialog-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.app-dialog-field input,
.app-dialog-field textarea {
  font-size: 14px;
  font-weight: 400;
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  background: var(--paper);
  color: var(--ink);
  resize: vertical;
}
.app-dialog-field input:focus,
.app-dialog-field textarea:focus { outline: none; border-color: var(--accent-line); }
.app-dialog-choices {
  border: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.app-dialog-choices legend {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 6px;
  padding: 0;
}

.app-dialog-choice { position: relative; }

.app-dialog-choice input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.app-dialog-choice span {
  display: inline-block;
  font-size: 13px;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink-soft);
  cursor: pointer;
}

.app-dialog-choice input:checked + span {
  background: var(--ink);
  color: var(--card);
  box-shadow: none;
  font-weight: 600;
}

.app-dialog-choice input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.label-form-share { margin-top: 16px; }

.label-form-share-note {
  flex: 1 1 100%;
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------
   Guide (guide.js) and the click-to-load example players
   (renderTrackEmbed in common.js).
   --------------------------------------------------------------------- */
.guide-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 28px;
}

.guide-toc a {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 7px 14px;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
}

.guide-toc a:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink-soft); }

.guide-section {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 24px 26px;
  margin-bottom: 20px;
  scroll-margin-top: 16px;
}

.guide-section-title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 10px;
}

.guide-section p,
.guide-section li {
  font-size: 15px;
  line-height: 1.6;
  max-width: 72ch;
}

.guide-section p { margin: 0 0 12px; }

.guide-section a { color: var(--accent); }

.guide-note {
  background: var(--paper);
  border-radius: var(--r-ctl);
  padding: 12px 16px;
  color: var(--ink-soft);
  font-size: 14px !important;
}

.guide-video {
  margin: 4px 0 18px;
  border-radius: var(--r-ctl);
  overflow: hidden;
  background: #000;
  max-width: 720px;
}

.guide-video video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; }

.guide-steps {
  margin: 0 0 14px;
  padding-left: 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.guide-steps li::marker { color: var(--accent); font-weight: 700; }

.guide-list {
  margin: 0 0 12px;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.guide-energy {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.guide-energy li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.guide-energy-num {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent-contrast);
  background: color-mix(in srgb, var(--accent) calc(var(--lvl, 3) * 20%), var(--paper-dim));
}

.guide-energy-num[data-level="1"] { --lvl: 1; color: var(--ink); }
.guide-energy-num[data-level="2"] { --lvl: 2; color: var(--ink); }
.guide-energy-num[data-level="3"] { --lvl: 3; }
.guide-energy-num[data-level="4"] { --lvl: 4; }
.guide-energy-num[data-level="5"] { --lvl: 5; }

.guide-embeds {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  margin: 0 0 14px;
}

.guide-embeds-tight { margin-bottom: 0; }

.guide-tags {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 16px;
  margin-bottom: 8px;
}

.guide-tag {
  background: var(--paper);
  border-radius: var(--r-ctl);
  padding: 16px;
}

.guide-tag p { font-size: 14px !important; margin: 10px 0 12px; }

.guide-inline-btn {
  border: none;
  background: var(--accent-bg);
  color: var(--accent-soft);
  font: inherit;
  font-weight: 600;
  padding: 1px 10px;
  border-radius: var(--r-pill);
  cursor: pointer;
}

.track-embed {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.track-embed-play {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 72px;
  padding: 12px 14px;
  border: none;
  border-radius: var(--r-ctl);
  text-align: left;
  cursor: pointer;
  color: var(--ink);
  background:
    radial-gradient(120px 80px at 0% 0%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%),
    radial-gradient(160px 90px at 100% 100%, color-mix(in srgb, var(--brand-gold) 14%, transparent), transparent 70%),
    var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.track-embed-play:hover { box-shadow: inset 0 0 0 1px var(--accent-line), var(--shadow-soft); transform: translateY(-1px); }

.track-embed-icon {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-grad);
  color: var(--accent-contrast);
}

.track-embed-icon svg { width: 18px; height: 18px; margin-left: 2px; }

.track-embed-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.track-embed-title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.track-embed-artist { font-size: 13px; color: var(--ink-soft); }

.track-embed-source {
  flex: none;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--paper-dim);
  padding: 3px 8px;
  border-radius: var(--r-pill);
}

.track-embed-frame {
  width: 100%;
  border: 0;
  border-radius: var(--r-ctl);
  background: #000;
}

.track-embed-frame-youtube { aspect-ratio: 16 / 9; }
.track-embed-frame-soundcloud { height: 166px; background: transparent; }

.track-embed-note {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.45;
}

.track-embed-link {
  font-size: 12.5px;
  color: var(--ink-soft);
  text-decoration: none;
}

.track-embed-link:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 640px) {
  .guide-section { padding: 18px 16px; }
  .guide-toc { flex-wrap: nowrap; overflow-x: auto; margin: 0 -16px 22px; padding: 0 16px 2px; scrollbar-width: none; }
  .guide-toc a { flex: none; }
}

/* Feedback inbox (feedback.js) */
.feedback-tabs { margin-bottom: 16px; }

.feedback-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.feedback-card {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 18px 20px;
}

.feedback-card.is-done { opacity: 0.7; }

.feedback-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.feedback-kind {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--status-strategic-bg);
  color: var(--ink-soft);
}

.feedback-kind-bug { background: var(--status-high-bg); color: var(--status-high); }
.feedback-kind-idea { background: var(--brand-gold-bg); color: var(--brand-gold); }

.feedback-who { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }

.feedback-when { font-size: 13px; color: var(--ink-soft); }

.feedback-message {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.app-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.app-dialog-danger {
  background: var(--status-high) !important;
  border-color: var(--status-high) !important;
  color: var(--status-contrast) !important;
}

.toast-stack {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: max-content;
  max-width: calc(100vw - 32px);
}
.toast {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--ink);
  color: var(--card);
  border-radius: 22px;
  padding: 8px 8px 8px 20px;
  box-shadow: var(--shadow-card);
  font-size: 13.5px;
  animation: dash-fade-in 0.2s ease both;
}
.toast button {
  background: color-mix(in srgb, var(--card) 14%, transparent);
  border: none;
  border-radius: var(--r-pill);
  color: var(--card);
  font-size: 13px;
  font-weight: 600;
  padding: 7px 14px;
  cursor: pointer;
}
.toast button:hover { background: color-mix(in srgb, var(--card) 24%, transparent); }

/* "Show 25 more" under long lists (renderShowMore in common.js). */
.show-more-btn {
  display: block;
  width: 100%;
  margin: 8px 0 0;
  padding: 12px 16px;
  background: transparent;
  border: none;
  border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.show-more-btn span { color: var(--ink-soft); font-weight: 500; }
.show-more-btn:hover { background: var(--card); }

/* Several submissions at once (tracks.js): a box per suggested label, and
   a sticky bar once any are ticked. */
.suggest-pick { flex: none; width: 17px; height: 17px; accent-color: var(--accent); margin: 0; }
.bulk-log-bar {
  position: sticky;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 8px 8px 8px 18px;
  background: var(--card);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-card), inset 0 0 0 1px var(--accent-line);
  font-size: 13.5px;
  z-index: 5;
}
.bulk-log-bar [data-bulk-count] { font-size: 13.5px; font-weight: 600; margin-right: auto; }
@media (max-width: 640px) {
  .bulk-log-bar { bottom: calc(92px + env(safe-area-inset-bottom, 0)); }
}

/* "Log a submission" on a label card (labels.js). */
.log-submission-form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
  padding: 12px 14px;
  background: var(--paper);
  border-radius: var(--r-ctl);
}
.log-submission-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-right: 4px;
}
.log-submission-form select,
.log-submission-form input[type="date"] {
  font-size: 13px;
  border: none;
  border-radius: var(--r-ctl);
  padding: 7px 10px;
  background: var(--card);
  color: var(--ink);
  max-width: 100%;
}

/* Reply rate chip (renderReplyChip in common.js) — teal, the app's quiet
   "information" accent, so it doesn't read as a status. */
.reply-chip { color: var(--brand-gold); background: var(--brand-gold-bg); }

/* Manage tags (admin, labels.js). */
.manage-tags-toggle { margin-bottom: 16px; }
.manage-tags { padding: 18px 20px 10px; margin-top: 8px; }
.manage-tags.is-busy { opacity: 0.55; pointer-events: none; }
.manage-tags-intro { margin: 0 0 12px; font-size: 13px; line-height: 1.5; color: var(--ink-soft); max-width: 75ch; }
.manage-tags-callout,
.manage-tags-dupe {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  margin-bottom: 8px;
  background: var(--paper);
  border-radius: var(--r-ctl);
  font-size: 13.5px;
}
.manage-tags-callout { background: var(--accent-bg); }
.manage-tags-dupes h4 { margin: 16px 0 8px; font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.manage-tags-dupe code { font-family: var(--font-code); font-size: 12.5px; }
.manage-tags-table-wrap { overflow-x: auto; margin-top: 12px; }
.manage-tags-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.manage-tags-table th {
  text-align: left;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 8px 8px;
  border-bottom: 1px solid var(--line);
}
.manage-tags-table td { padding: 8px 8px; border-bottom: 1px solid var(--line-soft); }
.manage-tags-actions { text-align: right; white-space: nowrap; }
.manage-tags-actions .action-search-btn { padding: 6px 12px; font-size: 12.5px; }

.reply-rate-note { margin: -4px 0 12px; font-size: 13px; color: var(--ink-soft); line-height: 1.5; }
.reply-chip-inline { color: var(--brand-gold); font-weight: 600; }

/* The tag box sits inside forms whose plain inputs are bordered boxes —
   inside .tag-input-box it's the box itself that carries the border. */
.label-form .tag-input-text,
.tag-input .tag-input-text,
.label-form .tag-input-text:focus {
  border: none;
  background: transparent;
  padding: 4px 2px;
  width: auto;
}
.tag-input-text::-webkit-calendar-picker-indicator { display: none !important; }

.label-form label.label-form-private {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--ink);
}
.label-form label.label-form-private input { width: auto; accent-color: var(--accent); }


/* Every text field, select and date picker gets the same visible edge and
   the same soft focus ring, so fields read as fields on white cards and on
   the page alike. */
.label-form input,
.label-form select,
.label-form textarea,
.inline-edit-form input,
.inline-edit-energy select,
.sub-status-select,
.sub-date-input,
.sub-notes-input,
.suggest-row select,
.suggest-row input[type="date"],
.log-submission-form select,
.log-submission-form input[type="date"],
.quick-tag-form input,
.tag-input-box,
.app-dialog-field input,
.app-dialog-field textarea {
  border: 1px solid var(--field-border);
}

.label-form input:focus,
.label-form select:focus,
.label-form textarea:focus,
.inline-edit-form input:focus,
.inline-edit-energy select:focus,
.sub-status-select:focus,
.sub-date-input:focus,
.sub-notes-input:focus,
.suggest-row select:focus,
.suggest-row input[type="date"]:focus,
.log-submission-form select:focus,
.log-submission-form input[type="date"]:focus,
.quick-tag-form input:focus,
.tag-input-box:focus-within,
.app-dialog-field input:focus,
.app-dialog-field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-line);
}

/* the text box inside a tag field is part of the field, not a field of its own */
.tag-input-box .tag-input-text,
.tag-input-box .tag-input-text:focus {
  border: none;
  box-shadow: none;
}

.sub-date-input.sub-date-missing { border-color: var(--status-medium); }

/* The hidden attribute always wins (a display: flex rule on .bulk-log-bar
   used to keep an empty "0 selected" bar on screen). */
[hidden] { display: none !important; }

/* --- Exclusive demos (common.js exclusivePill, labels.js form) --------- */
.label-exclusive-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  color: var(--status-medium);
  background: var(--status-medium-bg);
  margin-right: 6px;
  white-space: nowrap;
  cursor: help;
}
.label-stat-chip.chip-exclusive {
  color: var(--status-medium);
  background: var(--status-medium-bg);
  font-weight: 600;
}
.label-form label.label-form-check {
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  font-weight: 400;
  color: var(--ink-soft);
  line-height: 1.45;
}
.label-form label.label-form-check strong { color: var(--ink); font-weight: 600; }
.label-form label.label-form-check input { width: auto; margin-top: 3px; accent-color: var(--accent); flex: none; }
.label-form-optional { font-weight: 400; }

/* --- Suggested edits (labels.js renderSuggestedChanges) --------------- */
.suggestion-kind {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  color: var(--accent-soft);
  background: var(--accent-bg);
}
.suggestion-changes-wrap { overflow-x: auto; margin-top: 10px; }
.suggestion-changes {
  border-collapse: collapse;
  font-size: 13.5px;
  width: 100%;
}
.suggestion-changes th,
.suggestion-changes td {
  text-align: left;
  padding: 7px 8px;
  border-top: 1px solid var(--line-soft);
  vertical-align: top;
  overflow-wrap: anywhere;
}
.suggestion-changes thead th {
  border-top: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  padding-top: 0;
}
.suggestion-changes tbody th { font-weight: 600; color: var(--ink); white-space: nowrap; width: 1%; }
.suggestion-changes .suggestion-was { color: var(--ink-soft); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--ink-soft) 50%, transparent); }
.suggestion-changes .suggestion-to { color: var(--ink); font-weight: 600; }
.suggestion-changes .suggestion-arrow { color: var(--ink-soft); width: 1%; padding-left: 0; padding-right: 0; }
.suggestion-empty { color: var(--ink-soft); font-weight: 400; text-decoration: none; }
.label-card .share-strip.is-pending .action-search-btn { padding: 6px 14px; font-size: 13px; }

.guide-energy + .guide-embeds { margin-top: 18px; }

/* The logo in the app header (common.js renderPageHeader): symbol and
   wordmark as one link home, with the Beta tag beside it. The page's own
   title is in the nav (current item) and a hidden h1 for screen readers. */
.brand-link { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); text-decoration: none; }
.brand-link:hover { opacity: 0.85; }
.brand-wordmark { display: block; color: var(--ink); }
header.top .brand .beta-pill { margin-left: 2px; }
@media (max-width: 640px) {
  header.top { flex-wrap: nowrap; }
  header.top .brand { gap: 6px; min-width: 0; }
  .brand-link { gap: 8px; }
  .brand-link .brand-mark { width: 28px; height: 28px; }
  .brand-link .brand-wordmark { height: 12px; width: auto; }
}
@media (max-width: 360px) {
  .brand-link .brand-wordmark { height: 10px; }
  header.top .brand .beta-pill { display: none; }
}

/* --- How long a demo has been out (common.js sentAgeHtml) ------------- */
.sent-age {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  padding: 1px 6px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--ink-soft) 10%, transparent);
  white-space: nowrap;
}
.sent-age.is-overdue { color: var(--status-high); background: var(--status-high-bg); }
.overview-pill .sent-age { margin-left: 2px; }
.overview-pill.is-overdue { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--status-high) 45%, transparent); }
td .sent-age { margin-left: 6px; }

/* --- My notes on a shared label (labels.js renderMyNote) -------------- */
.my-note { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 12px; }
.my-note-head { display: flex; align-items: baseline; gap: 8px; font-size: 13.5px; }
.my-note-hint { font-size: 12px; color: var(--ink-soft); }
.label-form-note { font-weight: 400; font-size: 12px; color: var(--ink-soft); margin-left: 4px; }
.my-note textarea {
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--field-border);
  border-radius: var(--r-ctl);
  padding: 10px 12px;
  resize: vertical;
}
.my-note textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-line); }
.label-stat-chip.chip-my-note { gap: 5px; color: var(--accent-soft); background: var(--accent-bg); }
.suggest-my-note { color: var(--accent-soft); font-size: 13px; cursor: help; margin-left: 2px; }
.overview-pills { min-width: 0; max-width: 100%; }
.overview-pill .sent-age,
.overview-pill .overview-pill-select { flex: none; }
.overview-pill .overview-pill-label { flex: 0 1 auto; }

/* ---------------------------------------------------------------------
   Import (/import): bring a demo spreadsheet in, in four steps.
   --------------------------------------------------------------------- */
.import-card {
  display: flex; flex-direction: column; gap: 16px;
  background: var(--card); border-radius: var(--r-card); box-shadow: var(--shadow-card);
  padding: 22px; min-width: 0;
}
.import-steps {
  list-style: none; margin: 0 0 14px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  font-size: 13px; font-weight: 600; color: var(--ink-soft);
}
.import-steps li { display: flex; align-items: center; gap: 7px; }
.import-steps span {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: 50%; font-size: 12px; box-shadow: inset 0 0 0 1px var(--line);
}
.import-steps .is-current { color: var(--ink); }
.import-steps .is-current span { background: var(--accent); color: var(--accent-contrast); box-shadow: none; }
.import-steps .is-done span { background: var(--paper-dim); color: var(--ink); box-shadow: none; }
.import-lead { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink); max-width: 62ch; }
.import-drop {
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  padding: 16px; border-radius: var(--r-ctl);
  background: var(--paper); border: 1px dashed var(--field-border);
  font-size: 13px; color: var(--ink-soft); line-height: 1.45;
}
.import-drop { cursor: pointer; }
.import-drop:hover, .import-drop:focus-within { border-color: var(--accent-line); background: var(--accent-bg); }
.import-drop input[type="file"] { font-size: 13px; max-width: 100%; color: var(--ink); }
.import-map select, .import-word select {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--card);
  border: 1px solid var(--field-border); border-radius: var(--r-ctl);
  padding: 9px 11px; width: 100%; min-width: 0;
}
.import-map select:focus, .import-word select:focus { outline: none; border-color: var(--accent-line); }
.import-error {
  margin: 0; padding: 10px 14px; border-radius: var(--r-ctl);
  background: var(--status-high-bg); color: var(--status-high); font-size: 14px; font-weight: 500;
}
.import-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.import-actions .action-copy-btn { text-decoration: none; }
.import-sample-wrap { overflow-x: auto; border-radius: var(--r-ctl); box-shadow: inset 0 0 0 1px var(--line); max-width: 100%; }
.import-sample { border-collapse: collapse; font-size: 12px; white-space: nowrap; min-width: 100%; }
.import-sample th, .import-sample td {
  padding: 6px 10px; text-align: left; border-bottom: 1px solid var(--line-soft);
  max-width: 220px; overflow: hidden; text-overflow: ellipsis;
}
.import-sample th { background: var(--paper); color: var(--ink); font-weight: 600; }
.import-sample td { color: var(--ink-soft); }
.import-hint { margin: 0; font-size: 13px; color: var(--ink-soft); line-height: 1.5; }
.import-map { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px 14px; }
.import-map-row { display: flex; flex-direction: column; gap: 5px; font-size: 13px; font-weight: 600; color: var(--ink-soft); min-width: 0; }
.import-req { font-weight: 500; font-size: 11px; color: var(--accent); margin-left: 4px; }
.import-trackcols { border: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 16px; }
.import-trackcols legend { font-size: 13px; font-weight: 600; color: var(--ink-soft); margin-bottom: 8px; padding: 0; }
.import-trackcols legend span { font-weight: 400; }
.import-trackcols label { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.import-block h4 { margin: 0 0 10px; font-size: 15px; color: var(--ink); }
.import-words { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 8px 18px; }
.import-word { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 4px 0; }
.import-word select { flex: 0 0 auto; width: auto; }
.import-word-text { flex: 1; min-width: 0; font-size: 14px; color: var(--ink); overflow-wrap: anywhere; }
.import-word-text small { margin-left: 6px; font-size: 12px; color: var(--ink-soft); }
.import-near-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.import-near { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; min-width: 0; }
.import-near .import-word-text { flex: 0 1 auto; }
.import-near select {
  font: inherit; font-size: 14px; color: var(--ink); background: var(--card);
  border: 1px solid var(--field-border); border-radius: var(--r-ctl);
  padding: 9px 11px; width: auto; max-width: 100%; min-width: 0;
}
.import-near select:focus { outline: none; border-color: var(--accent-line); }
.import-word.is-unknown select { border-color: var(--status-medium); background: var(--status-medium-bg); }
.import-summary { margin: 0 0 10px; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 14px; color: var(--ink); line-height: 1.45; overflow-wrap: anywhere; }
.import-skipped, .import-note { color: var(--ink-soft); }
.import-done { display: flex; flex-direction: column; gap: 10px; }
.import-done p { margin: 0; }
.import-done-big { font-size: 22px; font-weight: 700; color: var(--status-positive); }
.import-progress p { margin: 0 0 8px; }
.import-bar { height: 8px; border-radius: var(--r-pill); background: var(--paper-dim); overflow: hidden; margin-bottom: 8px; }
.import-bar span { display: block; height: 100%; background: var(--accent); border-radius: var(--r-pill); transition: width 0.25s ease; }
.import-part { display: flex; flex-direction: column; gap: 10px; padding-bottom: 18px; border-bottom: 1px solid var(--line-soft); }
.import-part:last-of-type { border-bottom: none; padding-bottom: 0; }
.import-part h4 { margin: 0; font-size: 15px; color: var(--ink); }
.import-part em { font-style: normal; font-weight: 600; color: var(--ink); }
.import-drop strong { color: var(--ink); font-size: 14px; }
.import-entry { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--accent); text-decoration: none; }
.import-entry:hover { text-decoration: underline; }
@media (max-width: 700px) {
  .import-card { padding: 16px; }
}
