:root {
  --bg: #eef0f4;
  --surface: #ffffff;
  --surface-2: #f5f6f9;
  --border: #dde1e8;
  --border-strong: #c7cddb;
  --ink: #1a1d29;
  --ink-muted: #666f84;
  --ink-faint: #97a0b3;
  --accent: #b8641c;
  --accent-ink: #ffffff;
  --accent-tint: #fbe9d7;
  --success: #1a7a4c;
  --success-tint: #dcf0e5;
  --warning: #8a6d00;
  --warning-tint: #f6ecc7;
  --danger: #b23a2e;
  --danger-tint: #f8e0dc;
  --shadow: 0 1px 2px rgba(20, 24, 38, 0.06), 0 1px 1px rgba(20, 24, 38, 0.04);
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* data/badge colors — separate from --accent, used for scannable categories only */
  --chart-1: #6d5bd0; --chart-1-tint: #ece9fb;
  --chart-2: #2f7dd1; --chart-2-tint: #e3eefb;
  --chart-3: #12897e; --chart-3-tint: #dcf1ee;
  --chart-4: #c14f7a; --chart-4-tint: #f9e5ed;
  --chart-5: #b8641c; --chart-5-tint: #fbe9d7;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #10121a;
    --surface: #181b26;
    --surface-2: #1f2330;
    --border: #2a2f3f;
    --border-strong: #3a4155;
    --ink: #e9ebf3;
    --ink-muted: #949db2;
    --ink-faint: #666f84;
    --accent: #e08a3e;
    --accent-ink: #171000;
    --accent-tint: #2e2110;
    --success: #4ad196;
    --success-tint: #123024;
    --warning: #e0c34a;
    --warning-tint: #332c0e;
    --danger: #e8776a;
    --danger-tint: #33201d;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 6px rgba(0, 0, 0, 0.25);

    --chart-1: #9c8cf0; --chart-1-tint: #241f3d;
    --chart-2: #6fa8ea; --chart-2-tint: #1a2a3d;
    --chart-3: #4fc3b6; --chart-3-tint: #12302c;
    --chart-4: #e2879f; --chart-4-tint: #35202a;
    --chart-5: #e08a3e; --chart-5-tint: #2e2110;
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  background: var(--bg); color: var(--ink); font-family: var(--font-ui);
  margin: 0; line-height: 1.5; font-size: 14px; -webkit-font-smoothing: antialiased;
}
code { font-family: var(--font-mono); }
.icon { width: 16px; height: 16px; flex: none; display: block; }

/* ---------------------------------------------------------------- shell */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 240px; flex: none; background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; padding: 1.25rem 1rem;
}
.brand { display: flex; align-items: center; gap: 0.65rem; padding: 0 0.4rem 1.25rem; }
.brand-mark {
  width: 32px; height: 32px; border-radius: 8px; background: var(--accent); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1rem; flex: none;
}
.brand-mark svg { width: 19px; height: 19px; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.brand-text strong { font-size: 0.95rem; font-weight: 700; }
.brand-text span { font-size: 0.65rem; color: var(--ink-muted); font-weight: 600; letter-spacing: 0.05em; }

.nav { display: flex; flex-direction: column; gap: 0.15rem; }
.nav-item {
  display: flex; align-items: center; gap: 0.65rem;
  background: none; border: none; text-align: left; width: 100%;
  padding: 0.5rem 0.65rem; border-radius: 7px; cursor: pointer;
  font-family: var(--font-ui); font-size: 0.86rem; font-weight: 500; color: var(--ink-muted);
}
.nav-item .nav-label { flex: 1; }
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item.active { background: var(--accent-tint); color: var(--accent); font-weight: 600; }
.nav-count {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 600; color: var(--ink-faint);
  background: var(--surface-2); border-radius: 8px; padding: 0.05rem 0.45rem; min-width: 1.4em; text-align: center;
}
.nav-item.active .nav-count { color: var(--accent); background: var(--surface); }

.quick-actions { margin-top: 1.5rem; padding: 0 0.4rem; display: flex; flex-direction: column; gap: 0.4rem; }
.qa-label { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-faint); margin: 0 0 0.35rem; }
.qa-btn {
  display: flex; align-items: center; gap: 0.55rem; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 7px; padding: 0.45rem 0.6rem; font-size: 0.8rem; font-weight: 500; color: var(--ink); cursor: pointer;
}
.qa-btn:hover { border-color: var(--accent); color: var(--accent); }
.qa-btn .icon { color: var(--accent); }

.sidebar-foot { margin-top: auto; padding: 1rem 0.5rem 0; border-top: 1px solid var(--border); }
.sidebar-foot p { font-size: 0.75rem; color: var(--ink-faint); line-height: 1.5; margin: 0.85rem 0 0; }
.sidebar-foot code { background: var(--surface-2); border-radius: 4px; padding: 0.05em 0.3em; font-size: 0.92em; }

/* ---------------------------------------------------------------- main */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar { padding: 1.5rem 2rem; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: flex-start; gap: 1.5rem; }
.topbar h1 { font-size: 1.35rem; font-weight: 700; margin: 0 0 0.2rem; letter-spacing: -0.01em; }
.topbar p { margin: 0; color: var(--ink-muted); font-size: 0.88rem; }
.topbar-right { flex: none; padding-top: 0.1rem; display: flex; align-items: center; gap: 0.85rem; }
.search-box {
  display: flex; align-items: center; gap: 0.5rem; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 0.45rem 0.75rem; min-width: 280px;
}
.search-box .icon { color: var(--ink-faint); }
.search-box input { border: none; background: none; outline: none; font-size: 0.85rem; color: var(--ink); width: 100%; font-family: var(--font-ui); }
.search-box input::placeholder { color: var(--ink-faint); }

/* Was capped at 1180px with no centering — on any screen wider than
   sidebar+1180 that left a large dead gray gutter on the right while
   wide tables (Creatives) still overflowed and had to horizontal-scroll
   *inside* that narrower box. Let content actually use the viewport, with
   a generous cap so rows don't stretch unreadably wide on ultrawide
   monitors. width:100% is load-bearing here, not decorative — .main is a
   column flexbox, and a flex item with auto cross-axis margins but no
   explicit width shrink-wraps to its own content size instead of
   stretching (that's what centered this whole block in a sea of empty
   space the first time around). Explicit width:100% keeps it filling out
   to max-width, so the auto margins only ever absorb space *beyond* that. */
.content { padding: 1.75rem 2rem 3rem; width: 100%; max-width: 1800px; margin: 0 auto; }

.pane { display: none; }
.pane.active { display: block; }
.section-head { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-muted); margin: 1.75rem 0 0.9rem; }

/* ---------------------------------------------------------------- stats */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.85rem; margin-bottom: 1.5rem; }
.stat { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 1.1rem 1.2rem; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 0.7rem; font: inherit; text-align: left; cursor: pointer; width: 100%; }
.stat:hover { border-color: var(--accent); }
.stat-badge { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; }
.stat-badge .icon { width: 17px; height: 17px; }
.stat .n { font-family: var(--font-mono); font-size: 1.55rem; font-weight: 700; line-height: 1; color: var(--ink); }
.stat .l { font-size: 0.78rem; color: var(--ink-muted); margin-top: 0.3rem; font-weight: 500; }
.stat .sub { font-size: 0.72rem; color: var(--ink-faint); margin-top: 0.1rem; }

/* ---------------------------------------------------------------- alert */
.alert { display: flex; align-items: center; gap: 0.6rem; padding: 0.75rem 1.1rem; border-radius: 9px; font-size: 0.85rem; margin-bottom: 1.5rem; }
/* A class-based `display` declaration beats the browser's default
   `[hidden] { display: none }` UA rule at equal specificity (author
   stylesheets always win) — without this, setting the `hidden` attribute
   via JS does nothing visually and the bar stays on-screen, empty. */
.alert[hidden] { display: none; }
.alert .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.alert.warning { background: var(--danger-tint); color: var(--danger); }

/* ---------------------------------------------------------------- code block */
.code-block {
  display: block; font-family: var(--font-mono); font-size: 0.8rem; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 0.7rem 0.9rem; white-space: pre-wrap; word-break: break-all; overflow-x: auto;
}

/* ---------------------------------------------------------------- cards & grid */
.grid-2 { display: grid; grid-template-columns: 1.1fr 1fr; gap: 1rem; margin-bottom: 1rem; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 1.15rem 1.25rem; box-shadow: var(--shadow); margin-bottom: 1rem; }
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 1rem; }
.card-head h2 { font-size: 0.92rem; font-weight: 700; margin: 0; }
.card-head .hint { font-size: 0.74rem; color: var(--ink-faint); }
.view-all-link { font-size: 0.76rem; font-weight: 600; color: var(--accent); text-decoration: none; white-space: nowrap; margin-left: auto; }
.view-all-link:hover { text-decoration: underline; }
.bulk-bar {
  display: flex; align-items: center; gap: 0.9rem; padding: 0.55rem 0.9rem; margin-bottom: 0.6rem;
  background: var(--accent-tint, var(--surface-2)); border: 1px solid var(--accent); border-radius: 8px; font-size: 0.8rem; font-weight: 600;
}
.bulk-bar[hidden] { display: none; }
.checklist-filter {
  font-family: var(--font-ui); font-size: 0.78rem; padding: 0.35rem 0.55rem; border: 1px solid var(--border-strong);
  border-radius: 6px; background: var(--surface); color: var(--ink); width: 100%; box-sizing: border-box; margin-bottom: 0.5rem;
}
.loc-check.filtered-out { display: none; }

/* ---------------------------------------------------------------- donut */
.donut-row { display: flex; align-items: center; gap: 1.5rem; }
.donut { width: 132px; height: 132px; border-radius: 50%; flex: none; position: relative; }
.donut::after {
  content: attr(data-total); position: absolute; inset: 22px; background: var(--surface); border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-weight: 700; font-size: 1.3rem; color: var(--ink);
}
.legend-list { list-style: none; margin: 0; padding: 0; flex: 1; display: flex; flex-direction: column; gap: 0.55rem; }
.legend-list li { display: flex; align-items: center; gap: 0.55rem; font-size: 0.82rem; }
.legend-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.legend-list .lg-name { flex: 1; color: var(--ink); }
.legend-list .lg-value { font-family: var(--font-mono); color: var(--ink-muted); font-size: 0.78rem; }

/* ---------------------------------------------------------------- ranked list */
.rank-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.rank-list li { display: flex; align-items: center; gap: 0.7rem; }
.rank-tile {
  width: 34px; height: 34px; border-radius: 8px; flex: none; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-weight: 700; font-size: 0.82rem; color: var(--ink-muted); background: var(--surface-2); border: 1px solid var(--border);
}
.rank-info { flex: 1; min-width: 0; }
.rank-info .r-name { font-size: 0.84rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rank-info .r-sub { font-size: 0.72rem; color: var(--ink-faint); }
.rank-count { font-family: var(--font-mono); font-size: 0.8rem; font-weight: 700; color: var(--accent); flex: none; }

/* ---------------------------------------------------------------- store list (clickable) */
tr.store-row { cursor: pointer; }
tr.store-row:hover { background: var(--surface-2); }
.row-index { font-family: var(--font-mono); color: var(--ink-faint); font-size: 0.78rem; width: 1.5rem; }
.store-name-cell { display: flex; flex-direction: column; }
.store-name-cell .s-name { font-weight: 700; font-size: 0.88rem; }
.store-name-cell .s-external { font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-faint); }
.chevron { color: var(--ink-faint); }

.back-link {
  background: none; border: none; cursor: pointer; color: var(--ink-muted); font-family: var(--font-ui);
  font-size: 0.82rem; font-weight: 600; padding: 0; margin-bottom: 1.25rem; display: inline-flex; align-items: center; gap: 0.4rem;
}
.back-link:hover { color: var(--accent); }

.breadcrumbs { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1.25rem; font-size: 0.82rem; }
.breadcrumb-link { background: none; border: none; cursor: pointer; color: var(--ink-muted); font-family: var(--font-ui); font-size: inherit; font-weight: 600; padding: 0; }
.breadcrumb-link:hover { color: var(--accent); text-decoration: underline; }
.breadcrumb-sep { color: var(--ink-faint); }
.breadcrumb-current { color: var(--ink); font-weight: 600; }

.quick-filter {
  font-family: var(--font-ui); font-size: 0.74rem; font-weight: 600; color: var(--ink-muted); background: var(--surface-2);
  border: 1px solid var(--border-strong); border-radius: 999px; padding: 0.3rem 0.8rem; cursor: pointer; margin-bottom: 0.7rem;
}
.quick-filter.active { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
tr.quick-filtered-out { display: none; }

/* ---------------------------------------------------------------- gantt */
.gantt { border: 1px solid var(--border-strong); border-radius: 8px; overflow: hidden; background: var(--surface); margin-bottom: 1.5rem; }
.gantt-scale { position: relative; height: 1.9rem; border-bottom: 1px solid var(--border); font-size: 0.68rem; color: var(--ink-faint); margin-left: 160px; }
.gantt-tick { position: absolute; top: 0; height: 100%; border-left: 1px solid var(--border); padding-left: 0.3rem; padding-top: 0.35rem; white-space: nowrap; }
.gantt-today-label { position: absolute; top: 0.3rem; font-size: 0.66rem; font-weight: 700; color: var(--accent); white-space: nowrap; }
.gantt-rows { position: relative; }
.gantt-today-line { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent); z-index: 2; }
.gantt-row { position: relative; height: 2.7rem; border-bottom: 1px solid var(--border); }
.gantt-row:last-child { border-bottom: none; }
.gantt-row-label {
  position: absolute; left: 0; top: 0; bottom: 0; width: 160px; display: flex; align-items: center; padding: 0 0.6rem;
  font-size: 0.76rem; font-weight: 600; background: var(--surface); border-right: 1px solid var(--border); z-index: 3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gantt-track { position: relative; margin-left: 160px; height: 100%; }
.gantt-bar {
  position: absolute; top: 0.55rem; bottom: 0.55rem; border-radius: 4px; font-size: 0.68rem; color: #fff;
  display: flex; align-items: center; padding: 0 0.5rem; overflow: hidden; white-space: nowrap; cursor: default; min-width: 4px;
}
.gantt-bar.status-active { background: #2f9e64; }
.gantt-bar.status-scheduled { background: #b98900; }
.gantt-bar.status-other { background: #6b7280; }
.gantt-empty { padding: 1.5rem; text-align: center; color: var(--ink-faint); font-size: 0.82rem; }

.store-detail-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1.5rem; }
.store-detail-head h2 { font-size: 1.3rem; font-weight: 700; margin: 0; }
.store-detail-head .hint { margin: 0.2rem 0 0; font-size: 0.82rem; }

/* ---------------------------------------------------------------- location cards */
.location-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.location-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 1.15rem 1.25rem;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 0.75rem;
}
.location-card .lc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; }
.location-card .lc-name { font-size: 1rem; font-weight: 700; margin: 0; }
.location-card .lc-external { font-family: var(--font-mono); font-size: 0.74rem; color: var(--ink-faint); margin: 0.15rem 0 0; }
.pill {
  display: inline-flex; align-items: center; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.01em;
  padding: 0.18rem 0.55rem; border-radius: 20px; white-space: nowrap;
}
.pill.venue { background: var(--surface-2); color: var(--ink-muted); font-family: var(--font-mono); font-size: 0.66rem; }
.pill.success { background: var(--success-tint); color: var(--success); }
.pill.warning { background: var(--warning-tint); color: var(--warning); }
.pill.danger { background: var(--danger-tint); color: var(--danger); }
.pill.neutral { background: var(--surface-2); color: var(--ink-muted); }
.pill-link { border: none; font: inherit; letter-spacing: inherit; cursor: pointer; }
.pill-link:hover { filter: brightness(1.08); text-decoration: underline; }

/* --------------------------------------------------------- recently viewed */
.recent-location-list { display: flex; flex-wrap: wrap; gap: 0.5rem; list-style: none; margin: 0; padding: 0; }
.recent-location-row {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.75rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2); font: inherit; cursor: pointer;
}
.recent-location-row:hover { border-color: var(--accent); }
.recent-location-row .pill { padding: 0; width: 8px; height: 8px; border-radius: 50%; }
.recent-location-name { font-size: 0.82rem; font-weight: 600; }

.lc-metrics { display: flex; gap: 1.25rem; }
.lc-metric { display: flex; flex-direction: column; }
.lc-metric .m-n { font-family: var(--font-mono); font-weight: 700; font-size: 1.05rem; }
.lc-metric .m-l { font-size: 0.7rem; color: var(--ink-muted); }

.lc-zones { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.zone-chip { background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; padding: 0.15rem 0.5rem; font-size: 0.74rem; color: var(--ink-muted); }

.lc-sync { border-top: 1px dashed var(--border); padding-top: 0.65rem; margin-top: 0.1rem; }
.lc-sync-label { font-size: 0.68rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 0.3rem; font-weight: 600; }
.lc-sync-url { font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-muted); background: var(--surface-2); border-radius: 6px; padding: 0.35rem 0.55rem; word-break: break-all; display: block; }

/* ---------------------------------------------------------------- tables */
table.data-table { border-collapse: collapse; width: 100%; font-size: 0.85rem; margin-bottom: 1.25rem; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; box-shadow: var(--shadow); }
table.data-table.flush { border: none; box-shadow: none; margin-bottom: 0; border-radius: 0; }
table.data-table th, table.data-table td { text-align: left; padding: 0.7rem 1rem; vertical-align: top; border-bottom: 1px solid var(--border); }
table.data-table.flush th, table.data-table.flush td { padding: 0.6rem 0.5rem; }
table.data-table tbody tr:last-child td { border-bottom: none; }
table.data-table tbody tr:hover { background: var(--surface-2); }
table.data-table th { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-muted); font-weight: 600; background: var(--surface-2); }
table.data-table.flush th { background: none; border-bottom: 1px solid var(--border); }
table.data-table code { font-size: 0.82em; color: var(--ink-muted); background: var(--surface-2); border-radius: 4px; padding: 0.1em 0.35em; }
/* A raw filename in a <code> tag has no natural break points, so even at
   width:100% a table-layout:auto table will grow past its container to
   avoid breaking it — that's what was forcing the whole Creatives table to
   scroll/clip. Cap it and ellipsis instead; the full name is still in the
   title attribute. */
table.data-table td.truncate code { display: inline-block; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.hint { color: var(--ink-faint); font-size: 0.82em; }
.hint.warn { color: #e0a530; font-weight: 600; }
.link-btn { background: none; border: none; padding: 0; font: inherit; color: var(--accent, #6ea8fe); font-weight: 600; cursor: pointer; text-align: left; text-decoration: none; }
.link-btn:hover { text-decoration: underline; }
.cd-grid { display: flex; flex-direction: column; gap: 0.7rem; }
.cd-row { display: grid; grid-template-columns: 130px 1fr; gap: 0.8rem; align-items: start; font-size: 0.9rem; }
.cd-label { color: var(--ink-faint); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; padding-top: 0.15rem; }
.table-scroll { overflow-x: auto; }

/* ------------------------------------------------------------------- tags */
.tag-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; margin-top: 0.35rem; }
.tag-chip {
  display: inline-flex; align-items: center; gap: 0.3rem; background: var(--accent-tint, var(--surface-2));
  color: var(--accent); border-radius: 999px; padding: 0.12rem 0.55rem 0.12rem 0.6rem; font-size: 0.72rem; font-weight: 600;
}
.tag-chip button {
  border: none; background: none; color: inherit; opacity: 0.6; cursor: pointer; padding: 0; font-size: 0.9em; line-height: 1;
  font-family: var(--font-ui);
}
.tag-chip button:hover { opacity: 1; }
.tag-add-input {
  font-family: var(--font-ui); font-size: 0.72rem; border: 1px dashed var(--border-strong); background: none; color: var(--ink-muted);
  border-radius: 999px; padding: 0.12rem 0.6rem; width: 5.5rem; min-width: 0;
}
.tag-add-input:focus { outline: none; border-color: var(--accent); color: var(--ink); width: 8rem; }
.tag-cloud { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.9rem; }
.tag-cloud-pill {
  font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600; padding: 0.3rem 0.75rem;
  border-radius: 999px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink-muted); cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.35rem;
}
.tag-cloud-pill:hover { background: var(--surface-2); color: var(--ink); }
.tag-cloud-pill.active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.tag-cloud-pill .n { opacity: 0.65; font-weight: 500; }
.tag-cloud-pill.active .n { opacity: 0.85; }

/* --------------------------------------------------------------- media quick-view */
.media-cell { display: flex; align-items: flex-start; gap: 0.6rem; }
.media-thumb-wrap {
  flex: none; width: 44px; height: 44px; border-radius: 7px; overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border);
}
/* Click opens the existing full-size preview modal (previewCreative) — the
   thumbnail itself is the quick-view entry point, not a separate control
   to go hunting for. A modest in-place hover scale is as far as a CSS-only
   zoom can safely go without getting clipped: table.data-table has
   overflow:hidden for its rounded corners, so anything that tried to grow
   into a large popup would just get cut off at the row/table edge. */
.media-thumb-wrap:not(.media-thumb-empty) { cursor: zoom-in; }
.media-thumb { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.15s ease; }
.media-thumb-wrap:not(.media-thumb-empty):hover .media-thumb { transform: scale(1.25); }
.media-thumb-empty { display: flex; align-items: center; justify-content: center; color: var(--ink-faint); }
.media-thumb-empty .icon { width: 16px; height: 16px; }

/* ---------------------------------------------------------------- mode toggle */
.mode-toggle { display: flex; gap: 1rem; margin-bottom: 0.9rem; font-size: 0.85rem; }
.mode-toggle label { display: flex; align-items: center; gap: 0.35rem; font-weight: 500; cursor: pointer; }

/* ------------------------------------------------------- creative substeps */
.mode-cards { display: flex; gap: 0.8rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.mode-card {
  flex: 1 1 220px; text-align: left; font-family: var(--font-ui); cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: 10px; background: var(--surface);
  padding: 0.9rem 1rem; display: flex; flex-direction: column; gap: 0.35rem;
}
.mode-card:hover { border-color: var(--accent); background: var(--surface-2); }
.mode-card strong { font-size: 0.92rem; color: var(--ink); }
.mode-card span { font-size: 0.78rem; color: var(--ink-muted); line-height: 1.4; }
.creative-substep { margin-top: 0.2rem; }
.substep-back { margin-bottom: 0.7rem; }

/* ---------------------------------------------------------------- kind tabs */
.kind-tabs { display: flex; gap: 0.4rem; margin-bottom: 0.9rem; flex-wrap: wrap; }
.kind-tab {
  font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600; padding: 0.4rem 0.9rem;
  border-radius: 999px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink-muted); cursor: pointer;
}
.kind-tab:hover { background: var(--surface-2); color: var(--ink); }
.kind-tab.active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ------------------------------------------------------------- segmented control */
.segmented { display: inline-flex; gap: 0.15rem; padding: 0.2rem; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border-strong); }
.segmented-btn {
  font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600; padding: 0.35rem 0.85rem;
  border-radius: 999px; border: none; background: transparent; color: var(--ink-muted); cursor: pointer;
}
.segmented-btn:hover { color: var(--ink); }
.segmented-btn.active { background: var(--ink); color: var(--surface); }

/* ------------------------------------------------------------------ hierarchy */
.hierarchy-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 1rem; flex-wrap: wrap; }
.hierarchy-toolbar .kind-tabs { margin-bottom: 0; }
#hierarchy-tree { overflow-x: auto; }
.tree-node { border-top: 1px solid var(--border); }
.tree-node:first-child { border-top: none; }
.tree-row {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 0.4rem; cursor: pointer; border-radius: 6px;
}
.tree-row:hover { background: var(--surface-2); }
.tree-toggle {
  flex: none; width: 1.2rem; height: 1.2rem; display: flex; align-items: center; justify-content: center;
  color: var(--ink-faint); transition: transform 0.12s;
}
.tree-node.open > .tree-row .tree-toggle { transform: rotate(90deg); }
.tree-toggle svg { width: 0.85rem; height: 0.85rem; }
.tree-icon { flex: none; font-size: 1rem; line-height: 1; width: 1.4rem; text-align: center; }
.tree-icon.tree-icon-store {
  width: 2.1rem; height: 2.1rem; border-radius: 8px; background: var(--accent-tint, var(--surface-2));
  display: flex; align-items: center; justify-content: center; color: var(--accent); font-size: 1rem;
}
.tree-label { font-weight: 700; font-size: 0.88rem; color: var(--ink); }
.tree-count { font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 999px; background: var(--surface-2); color: var(--ink-muted); }
.tree-children { display: none; padding-left: 1.9rem; }
.tree-node.open > .tree-children { display: block; }
.tree-leaf-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.4rem; border-radius: 6px; cursor: pointer; min-width: 0; }
.tree-leaf-row:hover { background: var(--surface-2); }
/* min-width:0 lets this flex child actually shrink instead of forcing the
   row wider than its container and pushing the verified pill/link off the
   edge — the default flex-basis (auto, from content) refuses to shrink
   below the text's natural width otherwise. */
.tree-leaf-info { display: flex; flex-direction: column; gap: 0.1rem; min-width: 5rem; flex: 1 1 auto; }
.tree-leaf-name, .tree-leaf-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-leaf-name { font-weight: 700; font-size: 0.86rem; color: var(--ink); }
.tree-leaf-sub { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); }
.tree-leaf-spacer { flex: none; width: 0.5rem; }
.tree-leaf-link { flex: none; color: var(--ink-faint); }
.tree-leaf-row .pill { flex: none; white-space: nowrap; }
.tree-empty { padding: 1.5rem 0.5rem; text-align: center; }

/* ---------------------------------------------------------------- forms */
.add-form { border: 1px solid var(--border); border-radius: 10px; padding: 0 1.1rem; margin-bottom: 2rem; background: var(--surface); box-shadow: var(--shadow); }
.add-form summary { cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--accent); padding: 0.85rem 0; list-style: none; display: flex; align-items: center; gap: 0.4rem; }
.add-form summary::-webkit-details-marker { display: none; }
.add-form summary::before { content: "+"; font-weight: 700; }
.add-form[open] summary::before { content: "\2212"; }
.add-form form { display: flex; flex-wrap: wrap; gap: 0.9rem; padding: 0.25rem 0 1.15rem; align-items: flex-end; border-top: 1px solid var(--border); padding-top: 1rem; }
.add-form label { display: flex; flex-direction: column; gap: 0.32rem; font-size: 0.76rem; color: var(--ink-muted); font-weight: 500; }
.add-form label[hidden] { display: none; }
.add-form input, .add-form select {
  font-family: var(--font-ui); font-size: 0.85rem; padding: 0.45rem 0.6rem; border: 1px solid var(--border-strong);
  border-radius: 6px; background: var(--surface); color: var(--ink); min-width: 170px;
}
.add-form input:focus-visible, .add-form select:focus-visible, .btn:focus-visible, .nav-item:focus-visible, .qa-btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.add-form fieldset { border: 1px solid var(--border-strong); border-radius: 6px; padding: 0.6rem 0.8rem; }
.add-form legend { font-size: 0.72rem; color: var(--ink-muted); padding: 0 0.3rem; }
.add-form legend em { font-style: italic; }
/* `label.loc-check` (not just `.loc-check`) so this beats `.add-form label`
   on specificity — every checklist here lives inside an `.add-form`, whose
   own label rule (stacked column layout, for the surrounding text inputs)
   was otherwise winning and stacking each checkbox above its text instead
   of a normal checkbox-then-label row. */
label.loc-check {
  display: flex; flex-direction: row; align-items: center; gap: 0.5rem; width: 100%;
  font-size: 0.85rem; color: var(--ink); padding: 0.4rem 0.2rem; border-radius: 4px;
}
label.loc-check:hover { background: var(--surface-2); }
/* `.add-form input` sets min-width:170px for the surrounding text inputs —
   min-width wins over width when they conflict, so the checkbox was
   actually rendering ~170px wide (invisible, but pushing everything after
   it way out to the right) despite width:16px above. Override the floor. */
label.loc-check input[type="checkbox"] { flex: none; width: 16px; min-width: 16px; height: 16px; margin: 0; }

/* ---------------------------------------------------------------- stepper */
.stepper-nav { display: flex; flex-wrap: wrap; gap: 0.4rem; padding: 0.2rem 0 1rem; border-top: 1px solid var(--border); padding-top: 1rem; }
.step-dot {
  font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600; color: var(--ink-muted); background: var(--surface-2);
  border: 1px solid var(--border-strong); border-radius: 999px; padding: 0.35rem 0.85rem 0.35rem 0.5rem; cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.step-num {
  display: inline-flex; align-items: center; justify-content: center; width: 1.3rem; height: 1.3rem; border-radius: 50%;
  background: var(--surface); font-size: 0.7rem; color: var(--ink-muted);
}
.step-dot.active { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.step-dot.active .step-num { background: rgba(0,0,0,0.15); color: inherit; }
.add-form .step { display: none; flex-wrap: wrap; gap: 0.9rem; width: 100%; align-items: flex-end; }
.add-form .step.active { display: flex; }
.stepper-actions { display: flex; gap: 0.6rem; width: 100%; padding-top: 0.6rem; border-top: 1px solid var(--border); }

/* A plain form living directly in a .card (not inside a collapsible
   .add-form <details>) — same label/input treatment, no accordion chrome. */
.inline-form { display: flex; flex-wrap: wrap; gap: 0.9rem; align-items: flex-end; }
.inline-form label { display: flex; flex-direction: column; gap: 0.32rem; font-size: 0.76rem; color: var(--ink-muted); font-weight: 500; }
.inline-form input, .inline-form select {
  font-family: var(--font-ui); font-size: 0.85rem; padding: 0.45rem 0.6rem; border: 1px solid var(--border-strong);
  border-radius: 6px; background: var(--surface); color: var(--ink); min-width: 170px;
}
/* Checkbox + label side by side, sized like a normal control — not the
   column-stacked layout .inline-form label gives text inputs, and not the
   browser-default checkbox with no vertical alignment against its text. */
.inline-form label.checkbox-label {
  flex-direction: row; align-items: center; gap: 0.45rem; font-size: 0.85rem; color: var(--ink);
  min-width: 0; padding: 0.45rem 0; font-weight: 400;
}
.inline-form label.checkbox-label input[type="checkbox"] {
  /* .inline-form input sets min-width:170px for text inputs — min-width
     always wins over a plain width, so without overriding it here too the
     checkbox renders full-width instead of checkbox-sized. */
  width: 15px; min-width: 15px; height: 15px; accent-color: var(--accent); margin: 0; flex: none;
}
/* A fieldset inside .inline-form (not .add-form) had no styling at all —
   fell back to the browser's default inset-border/legend chrome and broke
   out of the flex row's alignment. */
.inline-form fieldset {
  border: 1px solid var(--border-strong); border-radius: 8px; padding: 0.55rem 0.9rem 0.7rem;
  display: flex; flex-wrap: wrap; gap: 0 1rem; align-items: center; min-width: 0;
}
.inline-form fieldset legend { font-size: 0.72rem; font-weight: 600; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.03em; padding: 0 0.3rem; }
.inline-form .form-row-full { flex-basis: 100%; display: flex; gap: 0.9rem; flex-wrap: wrap; align-items: flex-end; }

/* ---------------------------------------------------------------- chips */
.chip {
  display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; font-weight: 500;
  padding: 0.3rem 0.4rem 0.3rem 0.7rem; border-radius: 999px; border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--ink);
}
.chip-remove {
  border: none; background: none; cursor: pointer; color: var(--ink-muted); font-size: 1rem; line-height: 1; padding: 0 0.2rem;
}
.chip-remove:hover { color: var(--danger); }
.chip-row { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.45rem; min-height: 1.7rem; }
.chip-row-hint { font-size: 0.76rem; color: var(--ink-faint); align-self: center; }
.chip-multiselect-list {
  max-height: 6.5rem; overflow-y: auto; border: 1px solid var(--border-strong); border-radius: 6px;
  padding: 0.5rem 0.7rem; background: var(--surface); transition: max-height 0.15s ease;
}
fieldset:focus-within .chip-multiselect-list { max-height: 16rem; }

/* ---------------------------------------------------------------- buttons */
.btn {
  /* inline-flex, not the default inline-block — a `.btn` with a mounted
     [data-icon] (see logout-btn) contains a `.icon` that's `display:block`
     (see mountIcons), which would otherwise start a new line inside the
     button and stack the icon above the label instead of beside it. */
  display: inline-flex; align-items: center; gap: 0.4rem; justify-content: center;
  font-family: var(--font-ui); font-size: 0.82rem; font-weight: 600; padding: 0.5rem 1rem;
  border-radius: 7px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink); cursor: pointer;
}
/* Same class of bug as .alert[hidden] before it: an unconditional
   `display: inline-flex` on .btn beats the browser's default
   `[hidden] { display: none }` at equal specificity — every hidden button
   (cancel-edit, disconnect, etc.) was rendering anyway. */
.btn[hidden] { display: none; }
.btn:hover { background: var(--surface-2); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { filter: brightness(1.06); }
.btn.small { font-size: 0.74rem; padding: 0.32rem 0.65rem; }
.btn.danger { color: var(--danger); border-color: var(--danger); background: none; }
.btn.danger:hover { background: var(--danger-tint); }

.hidden-row { display: none !important; }

/* ---------------------------------------------------------------- content viewer modal */
.preview-thumb {
  width: 40px; height: 40px; border-radius: 6px; border: 1px solid var(--border-strong); background: var(--surface-2);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; overflow: hidden; padding: 0; color: var(--ink-muted);
}
.preview-thumb:hover { border-color: var(--accent); color: var(--accent); }
.preview-thumb img { width: 100%; height: 100%; object-fit: cover; }
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(10, 12, 20, 0.55); display: flex; align-items: center; justify-content: center;
  padding: 2rem; z-index: 100;
}
.modal-backdrop[hidden] { display: none; }
.modal-box {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow);
  max-width: 640px; width: 100%; max-height: 90vh; overflow: auto; padding: 1.25rem 1.4rem;
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 0.75rem; }
.modal-head h3 { margin: 0 0 0.2rem; font-size: 1rem; }
.modal-close { border: none; background: none; color: var(--ink-muted); font-size: 1.3rem; line-height: 1; cursor: pointer; padding: 0.2rem 0.4rem; }
.modal-close:hover { color: var(--ink); }
.modal-media { width: 100%; max-height: 55vh; background: #000; border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.modal-media img, .modal-media video { width: 100%; max-height: 55vh; object-fit: contain; display: block; }
.modal-meta { font-family: var(--font-mono); font-size: 0.76rem; color: var(--ink-muted); margin-top: 0.75rem; line-height: 1.6; word-break: break-all; }
.modal-meta .pill { margin-right: 0.4rem; }
#fm-body form { display: flex; flex-direction: column; gap: 0.7rem; }
#fm-body label { display: flex; flex-direction: column; gap: 0.32rem; font-size: 0.76rem; color: var(--ink-muted); font-weight: 500; }
#fm-body input, #fm-body select, #fm-body textarea {
  font-family: var(--font-ui); font-size: 0.85rem; padding: 0.45rem 0.6rem; border: 1px solid var(--border-strong);
  border-radius: 6px; background: var(--surface); color: var(--ink); width: 100%; box-sizing: border-box;
}

/* -------------------------------------------------------------- access / RBAC */
.user-menu { display: flex; align-items: center; gap: 0.6rem; margin-left: 0.75rem; }
body:not(.role-admin) #nav-access,
body:not(.role-admin) #nav-audit,
body:not(.role-admin) [data-tab="integrations"] { display: none; }
/* Server-side is the real enforcement (403s any mutation); this just keeps a
   viewer from clicking into controls that would only bounce off the API. */
body.role-viewer .qa-btn[data-quick],
body.role-viewer form:not(#form-login):not(#form-pin) button[type="submit"],
body.role-viewer [data-edit-device],
body.role-viewer [data-edit-sd-device],
body.role-viewer [data-edit-zone],
body.role-viewer #sd-add-zone,
body.role-viewer #sd-add-device,
body.role-viewer [data-edit-location],
body.role-viewer [data-edit-device-jump],
body.role-viewer [data-edit-user],
body.role-viewer [data-del],
body.role-viewer [data-del-user],
body.role-viewer [data-del-zone],
body.role-viewer [data-replace-media],
body.role-viewer [data-restore-version],
body.role-viewer .btn.danger,
body.role-viewer button[data-quick-filter] { pointer-events: none; opacity: 0.4; cursor: not-allowed; }

/* -------------------------------------------------------------- version history */
.version-list { display: flex; flex-direction: column; gap: 0.6rem; max-height: 50vh; overflow-y: auto; }
.version-row { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.6rem 0.7rem; border: 1px solid var(--border); border-radius: 8px; }
.version-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.version-url { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-muted); }

/* ------------------------------------------------------------ zone-grouped devices (Store Detail) */
.zone-group { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 0.85rem; overflow: hidden; }
.zone-group-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.6rem 0.9rem; background: var(--surface-2); font-weight: 700; font-size: 0.84rem;
}
.zone-group-head .zone-group-actions { display: flex; align-items: center; gap: 0.6rem; font-weight: 400; }
.zone-group-count { font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600; color: var(--ink-muted); }
.zone-group table.data-table { margin-bottom: 0; border: none; box-shadow: none; border-radius: 0; }

/* ------------------------------------------------------------------ version fab */
.version-fab {
  position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 40;
  padding: 0.4rem 0.75rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); color: var(--ink-muted); font-family: var(--font-mono);
  font-size: 0.76rem; font-weight: 600; box-shadow: var(--shadow); cursor: pointer;
}
.version-fab:hover { color: var(--ink); border-color: var(--accent); }
.release-file-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.6rem; }
.release-file-grid label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.78rem; color: var(--ink-muted); }
/* #form-store-release carries the .add-form class directly on the <form>
   itself (no wrapping <details>, unlike every other add-form in this file),
   so the ".add-form form" descendant rule that makes fields flex-wrap
   instead of stacking full-width never matched it — same reasoning for
   .form-row-full, which was scoped only to .inline-form. Both fixed here
   rather than restructuring the HTML to match the <details> pattern. */
#form-store-release { display: flex; flex-wrap: wrap; gap: 0.9rem; align-items: flex-end; }
.add-form .form-row-full { flex-basis: 100%; display: flex; flex-direction: column; gap: 0.4rem; }
.upgrade-status-pill.idle { background: var(--surface-2); color: var(--ink-muted); }
.upgrade-status-pill.pending, .upgrade-status-pill.downloading, .upgrade-status-pill.validating, .upgrade-status-pill.applying { background: var(--accent-tint); color: var(--accent); }
.upgrade-status-pill.success { background: var(--success-tint, #dcf3e3); color: var(--success, #1d7a3c); }
.upgrade-status-pill.failed, .upgrade-status-pill.rolled_back { background: var(--danger-tint); color: var(--danger); }

/* Documentation tab */
.docs-diagram { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 1rem; margin: 0.75rem 0 1.1rem; }
.docs-list { max-width: 68ch; margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: 0.6rem; line-height: 1.6; }
.docs-list li::marker { color: var(--accent); }
