/* ==========================================================
   VERYQUERY · components
   Composed app vocabulary that sits on top of design-system.css.
   Loaded by every tool surface (admin, dashboard, help, docs)
   and the marketing pricing page (for .plan-card).

   Cascade order:
     1. fonts.css         font manifest
     2. design-system.css tokens, resets, .btn, .field, .checkbox,
                          .switch, .dv-radio, .chip, form-layout
                          primitives, utilities, ambient glow,
                          scrollbar
     3. components.css    THIS FILE, composed patterns:
                          · app shell (.app, .app__header/__body/
                            __sidebar/__main, .app__mark, .app__alert)
                          · page chrome (.page__head, .page__title)
                          · panels, cards, summary row, .tbl tables
                          · badges, status pills
                          · modals, dropdowns, toasts, banners
                          · intel cards, item-intel rows
                          · intel-map overlay primitives (canvas,
                            svg, dot, label, tooltip, legend)
                          · volume-trend (time-series bar chart)
                          · plan-card (tier pricing card)
                          · help-link (? icon next to titles)
     4. <surface>.css     per-surface layout + bespoke patterns

   Adding here: anything two or more surfaces would want. If only
   one surface needs it, keep it surface-local.
========================================================== */

/* ==========================================================
   KEYFRAMES
========================================================== */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes spin   { to { transform: rotate(360deg); } }

/* ==========================================================
   APP SHELL
   Viewport-locked container with a translucent toolbar on top
   and a sidebar + main grid below. Used by every tool surface.
========================================================== */
.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  position: relative;
  z-index: 1;
  background: var(--paper-0);
}

/* Toolbar, translucent material, sticks on scroll. */
.app__header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  /* Lock a fixed bar height so every surface renders the same chrome
     regardless of what its app__header-end carries, dashboard/admin
     have btn--small clusters (~3.4rem natural), help/docs have plain-
     text link clusters (~2.8rem natural). Without this, the bar's
     height drifts per surface. */
  min-height: 3.5rem;
  padding: 0 1.5rem;
  background: var(--bar);
  backdrop-filter: saturate(180%) blur(1.375rem);
  -webkit-backdrop-filter: saturate(180%) blur(1.375rem);
  border-bottom: 1px solid var(--rule-soft);
}

.app__mark {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  font-family: var(--font-wordmark);
  /* Geist is variable and fonts.css loads 300..700, so 700 is a
     drawn weight, not a synthesised bold. Going past 700 would need
     the import range widened first. */
  font-size: var(--t-2xl);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}
/* Logo mark sits to the left of the wordmark. Height is set here so
   the SVG scales to the bar, .app__mark's flex gap handles spacing. */
.app__mark-logo {
    display: block;
    height: 1.65rem;
    width: auto;
    margin-bottom: 0.15rem;
}
.app__mark-sigil { display: none; }  /* legacy § sigil retired */

/* Small tag chip after the wordmark, used for "Admin", "Beta", etc. */
.app__mark-tag {
  margin-left: 0.25rem;
  padding: 2px 0.5rem;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-mid);
  background: var(--paper-1);
  border-radius: var(--radius-full);
}

.app__header-end {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--t-sm);
  color: var(--ink-mid);
}

/* Drill-out trail (Common.setTrail), shared by dashboard + admin. Lives in the
   header between the mark and the account cluster. Last segment is the current
   view; earlier segments are jump-ups (a = cross-page, button = same-document).
   Shown only when a page pushes 2+ segments. */
.app__crumbs {
  display: flex; align-items: center; gap: var(--s-2);
  min-width: 0; flex: 1 1 auto;
  font-size: var(--t-sm); overflow: hidden; white-space: nowrap;
}
.app__crumb {
  color: var(--ink-mid); overflow: hidden; text-overflow: ellipsis;
  text-decoration: none; transition: color var(--dur) var(--ease);
}
button.app__crumb {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  max-width: 22rem; text-align: left;
}
a.app__crumb:hover, button.app__crumb:hover { color: var(--accent); }
.app__crumb--current { color: var(--ink); font-weight: var(--font-weight-medium); }
.app__crumb-sep { color: var(--ink-ghost); user-select: none; }
/* Cross-surface link clusters (help, docs) put plain text anchors in
   .app__header-end. The global `a { color: inherit; text-decoration:
   none }` rule strips affordance, restore mid-weight color + hover. */
.app__header-end a {
  color: var(--ink-mid);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.app__header-end a:hover { color: var(--ink); }
.app__header-start {
  display: inline-flex;
  align-items: center;
  gap: 1rem;
}

/* Secondary nav element next to the logo (e.g. "← Back"). */
.app__back {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.app__back:hover { color: var(--accent); }

/* Slim shell for User/Org settings: no sidebar, narrower main column.
 *
 * The base `.app` rule locks height to 100vh so the dashboard
 * surfaces (sidebar + viewport-locked main) scroll inside their own
 * area. For the user-layout pages (Org Home, User Settings) we want
 * the WHOLE PAGE to scroll naturally, like a document. Override
 * `height` to auto and let the page grow past the viewport. Without
 * this, content longer than 100vh produced a confusing scroll
 * region around the centered max-width column. */
.app--user {
  min-height: 100vh;
  height: auto;
  display: grid;
  grid-template-rows: auto 1fr;
}
.app__main--user {
  max-width: 56rem;
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* Alert banner shown between header and body. */
.app__alert {
  position: relative;
  z-index: 9;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1.5rem;
  background: var(--paper-1);
  color: var(--ink-soft);
  border-bottom: 1px solid var(--rule-soft);
  font-family: var(--font-body);
  font-size: var(--t-sm);
  letter-spacing: 0;
}
.app__alert-body { flex: 1; line-height: 1.4; }
.app__alert .btn { flex-shrink: 0; }
.app__alert--warn {
  background: var(--badge-warning-bg);
  color: var(--status-warning);
  border-left: 0.1875rem solid var(--status-warning);
}
.app__alert--warn strong { color: var(--ink); }
.app__alert-more {
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  margin-inline: 0.4em;
  vertical-align: middle;
}

/* ==========================================================
   APP BODY GRID
========================================================== */
.app__body {
  flex: 1;
  display: grid;
  grid-template-columns: 14.5rem 1fr;
  min-height: 0;
  background: var(--paper-0);
}
@media (max-width: 51.25em) {
  .app__body { grid-template-columns: 1fr; }
  .app__body > .app__sidebar { display: none; }
}

/* Main column inside .app__body. */
.app__main {
  padding: 2.25rem;
  /* Full-width scroll container so the scrollbar hugs the viewport's
     right edge; content is capped + centered via symmetric inline
     padding (NOT max-width on the scroller, which would float the
     scrollbar beside a centered column). Below the cap, max() falls
     back to the base 2.25rem side padding. Tune the cap per surface
     with --app-main-max (e.g. admin sets a wider one for tool tables). */
  padding-inline: max(2.25rem, calc((100% - var(--app-main-max, 68.75rem)) / 2));
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
  overflow-y: auto;
}

/* Layout-transparent wrapper for JS render targets. */
.app__slot { display: contents; }

/* ==========================================================
   SIDEBAR
   Rounded selected pill, no left-bar indicator. Group headings
   are quiet sans, not loud mono caps.
========================================================== */
.app__sidebar {
  padding: var(--s-4) var(--s-3);
  overflow-y: auto;
  border-right: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.app__sidebar ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.app__sidebar a,
.app__sidebar li > button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  text-decoration: none;
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
  position: relative;
  border-radius: var(--radius-sm);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.app__sidebar a:hover,
.app__sidebar li > button:hover {
  background: var(--paper-2);
  color: var(--ink);
}
.app__sidebar a.is-active,
.app__sidebar li > button.is-active {
  background: var(--accent-tint);
  color: var(--accent);
}
.nav__group--pin-bottom { margin-top: auto; }

/* Nested children inside a top-level nav entry (used by help's
   parent → child sub-pages). Same vocabulary as the parent links;
   indented, slightly softer, and the active state is unchanged so
   "you're on the child page" still reads as the bright pill. */
.app__sidebar ul ul {
  padding-left: 0.5rem;
  margin: 2px 0 0;
}
.app__sidebar ul ul a {
  padding-left: 1.5rem;
  font-size: var(--t-xs);
  color: var(--ink-mid);
}

/* Nav group: heading + list, rendered as a subtle paper-1 card so
   every section sits at the same elevation. Sibling spacing is
   handled by the parent .app__sidebar's flex gap. */
.nav__group {
  background: var(--paper-1);
  border-radius: var(--radius-md);
  padding: 0.375rem;
}
.nav__group-heading {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0;
    color: var(--ink-ghost);
    padding: 0.25rem 0.75rem 0.5rem;
    text-transform: uppercase;
}

/* Roadmap placeholder: a nav entry for a surface that isn't built yet. Looks
   like a link but is muted and non-interactive, with a "Soon" tag on the right. */
.nav__soon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.75rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-ghost);
  border-radius: var(--radius-sm);
  cursor: default;
}
.nav__soon-tag {
  font-family: var(--font-mono);
  font-size: var(--t-3xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-ghost);
  border: 1px solid var(--rule);
  border-radius: var(--radius-full);
  padding: 0.0625rem var(--s-2);
}

/* ==========================================================
   PAGE HEAD, iOS large-title posture
========================================================== */
.page__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  padding-bottom: 0;
  flex-wrap: wrap;
  position: static;
}

.page__title {
  font-family: var(--font-display);
  font-size: var(--t-4xl);
  font-weight: 600;
  letter-spacing: -0.032em;
  color: var(--ink);
  line-height: 1.02;
  margin-bottom: 0;
}
.page__lede {
  font-family: var(--font-body);
  font-size: var(--t-md);
  color: var(--ink-mid);
  max-width: 60ch;
  line-height: 1.5;
  margin-top: 0.625rem;
}
.page__lede code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  padding: 2px 0.4375rem;
  background: var(--paper-1);
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
}
.page__datum {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  flex: 1 0 100%;
  margin-bottom: 0.375rem;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}
.page__breadcrumb {
  flex: 1 0 100%;
  width: fit-content;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  text-decoration: none;
  margin-bottom: 0.25rem;
}
.page__breadcrumb:hover { color: var(--accent); }

/* The one action-row construct for both surfaces (replaces the admin-only
   .page-actions twin). gap --s-3 (0.75rem) is the agreed shared value. */
.page__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}

/* Interior section heading */
.section-title {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 1.5rem 0 0.75rem;
}
.section-title:first-child { margin-top: 0; }

/* ==========================================================
   PANELS
========================================================== */
.panel {
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.375rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  position: relative;
}
/* `display:flex` above outranks the plain `[hidden]` attribute (UA display:none), so a
   panel with the hidden attribute would still show as an empty box. Restore hiding. */
.panel[hidden] { display: none; }
.panel--compact { padding: 0.875rem 1.125rem; gap: 0.75rem; }
.panel--accent {
  background: var(--accent-tint);
}
.panel--accent .panel__title { color: var(--accent); }
.panel--accent .panel__head { border-color: var(--rule-soft); }
.panel--ok    { box-shadow: inset 0.1875rem 0 0 var(--status-success); }
.panel--warn  { box-shadow: inset 0.1875rem 0 0 var(--status-warning); }
.panel--error { box-shadow: inset 0.1875rem 0 0 var(--status-error); }
.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--rule);
}
.panel__title {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
/* A panel body is a flex-gap stack, same rhythm as .panel itself, so its
   stacked children space themselves. Margin is the exception, not the
   mechanism: add an mt or mb utility only where a spot must break from the gap. */
.panel__body {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
/* .section-title carries its own margins for prose contexts; as a direct
   child of a flex-gap panel (or panel body) those would stack on top of the
   gap (no margin-collapse in flex), so the gap owns the spacing. Scoped to
   direct children so a section-title nested in a non-flex wrapper keeps its
   own rhythm. */
.panel > .section-title,
.panel__body > .section-title { margin-top: 0; margin-bottom: 0; }
/* Same story for .banner: it carries its own margin-bottom for non-flex
   contexts, but as a direct child of a flex-gap body the gap owns the
   spacing (otherwise margin + gap stack to a double gap below the banner). */
.panel__body > .banner,
.modal__body > .banner { margin-bottom: 0; }

/* ==========================================================
   CARDS
========================================================== */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
}
.card {
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
  padding: 1.125rem 1.25rem;
  position: relative;
}
.card--current {
  background: var(--accent-tint);
}
.card--disabled { opacity: 0.55; }
.card--ok    { box-shadow: inset 0.1875rem 0 0 var(--status-success); }
.card--warn  { box-shadow: inset 0.1875rem 0 0 var(--status-warning); }
.card--error { box-shadow: inset 0.1875rem 0 0 var(--status-error); }

.card__value {
  font-family: var(--font-display);
  font-size: var(--t-3xl);
  font-weight: 300;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.card__value--md  { font-size: var(--t-xl); font-weight: 500; }
.card__value--sm  { font-size: var(--t-lg); font-weight: 500; }
.card__value--err { color: var(--status-error); }
.card__label {
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  display: block;
  margin-bottom: 0.5rem;
}
.card__sub {
  font-size: var(--t-sm);
  color: var(--ink-mid);
  margin-top: 0.375rem;
}

/* ==========================================================
   PLAN CARD · tier pricing card
   Single card shape used on the marketing pricing page and the
   dashboard plan picker. Slots: optional kicker + name, price
   block (currency · amount · per), optional billing/savings
   lines, full-width CTA, check-bulleted feature list. Featured
   variant adds an accent ring + glow; current variant tints the
   background. Both surfaces emit the same markup so a styling
   change ripples to both at once.
========================================================== */
.plan-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1rem, 1.5vw, 1.5rem);
  align-items: stretch;
}

/* Monthly/annual segmented toggle above the plan cards */
.plan-interval {
    display: inline-flex;
    gap: 0.25rem;
    margin: 0;
    padding: 0.25rem;
    background: var(--paper-2);
    border: 1px solid var(--rule);
    border-radius: var(--radius-full);
    align-self: center;
}
.plan-interval__opt {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.375rem 0.875rem; border: none; background: none; cursor: pointer;
  color: var(--ink-mid); font-family: inherit; font-size: var(--t-sm);
  border-radius: var(--radius-full);
  transition: background 160ms var(--ease-out), color 160ms var(--ease-out);
}
.plan-interval__opt.is-active { background: var(--accent); color: #fff; }
.plan-interval__save { font-size: var(--t-2xs); font-weight: 600; color: var(--status-success); }
.plan-interval__opt.is-active .plan-interval__save { color: #fff; }

.plan-card {
  position: relative;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 2.5vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: border-color 160ms var(--ease-out);
}
.plan-card:hover { border-color: rgba(255, 255, 255, 0.14); }

.plan-card--featured {
  background: var(--paper-1);
  border-color: rgba(10, 132, 255, 0.45);
  box-shadow: 0 0 0 1px rgba(10, 132, 255, 0.18), 0 1.5rem 3rem -1.25rem rgba(10, 132, 255, 0.32);
}
.plan-card--featured:hover { border-color: rgba(10, 132, 255, 0.70); }

.plan-card--current {
  background: var(--accent-tint);
  border-color: rgba(10, 132, 255, 0.30);
}

/* Enterprise contact-us card: no price, quieter, dashed edge */
.plan-card--contact { background: var(--paper-1); border-style: dashed; }
.plan-card__amount--sm { font-size: clamp(1.5rem, 2.2vw, 1.875rem); }

.plan-card__flag {
  position: absolute;
  top: 0;
  right: 1.5rem;
  transform: translateY(-50%);
  background: var(--accent);
  color: #fff;
  padding: 0.3125rem 0.6875rem;
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 0.375rem 0.875rem rgba(10, 132, 255, 0.4);
}

.plan-card__top {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.plan-card__kicker {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mid);
  font-variant-numeric: tabular-nums;
}
.plan-card__name {
  margin: 0;
  font-size: clamp(1.5rem, 2.2vw, 1.875rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: var(--ink);
}

.plan-card__price-block {
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.plan-card__price {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.1em;
  line-height: 1;
  color: var(--ink);
}
.plan-card__currency {
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  color: var(--ink-mid);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.plan-card__amount {
  font-size: clamp(2.75rem, 5.5vw, 3.75rem);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
}
.plan-card__per {
  font-size: var(--t-md);
  color: var(--ink-mid);
  font-weight: 500;
  letter-spacing: -0.005em;
}
.plan-card__billing {
  margin: 0;
  font-size: var(--t-xs);
  color: var(--ink-mid);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.plan-card__savings {
  margin: 0;
  font-size: var(--t-xs);
  color: var(--accent);
  font-weight: 500;
  line-height: 1.45;
}
.plan-card__savings strong {
  color: var(--accent);
  font-weight: 600;
}
.plan-card__savings:empty { display: none; }

.plan-card__cta {
  align-self: stretch;
  justify-content: center;
  margin-top: 0.25rem;
}

.plan-card__list {
  list-style: none;
  padding: 1rem 0 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-soft);
  border-top: 1px solid var(--rule);
  font-weight: 400;
}
.plan-card__list li {
  position: relative;
  padding-left: calc(1rem + 0.625em);
}
/* Checkmark sits in the left padding, out of flow, so the bullet text is
   plain inline content (a bolded number flows inline instead of becoming a
   sibling flex item with a gap around it). Uses a CSS mask so the fill
   tracks --accent at runtime (an inline SVG data URI would hard-code the
   color and drift if the accent ever changes). */
.plan-card__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.15rem;
  width: 1rem;
  height: 1rem;
  background-color: var(--accent);
  -webkit-mask: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='3 8.5 6.5 12 13 4.5'/%3e%3c/svg%3e") no-repeat center / contain;
          mask: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='3 8.5 6.5 12 13 4.5'/%3e%3c/svg%3e") no-repeat center / contain;
}
.plan-card__list strong {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================
   SUMMARY ROW, rounded cards, big numerals
========================================================== */
.summary-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.625rem;
}
.summary-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  padding: 1.125rem 1.375rem 1.25rem;
  /* L2, raised above the panel it sits in (and above the page
     background when it isn't wrapped in a panel). */
  background: var(--paper-2);
  border: 0;
  border-radius: var(--radius-lg);
  color: inherit;
  text-align: left;
  font: inherit;
  text-decoration: none;
  position: relative;
  overflow: hidden;
  transition: background var(--dur) var(--ease);
}
button.summary-cell, a.summary-cell { cursor: pointer; }
/* Hover-lift one elevation step (L2 → L3). */
button.summary-cell:hover,
a.summary-cell:hover { background: var(--paper-3); }

.summary-cell--active { background: var(--accent-tint); }
.summary-cell--active::after {
  content: "";
  position: absolute;
  top: 1.125rem;
  right: 1.125rem;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--accent);
}
.summary-cell__label {
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  margin-bottom: 0.625rem;
}
.summary-cell--active .summary-cell__label { color: var(--accent); }
.summary-cell__count {
  font-family: var(--font-display);
  font-size: var(--t-5xl);
  font-weight: 300;
  letter-spacing: -0.045em;
  line-height: 0.95;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.summary-cell__badge { margin-top: auto; }

/* ==========================================================
   TABLE
========================================================== */
.tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}
.tbl thead th {
  text-align: left;
  vertical-align: bottom;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--rule);
  background: transparent;
}
.tbl tbody td {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: middle;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.tbl tbody tr { transition: background var(--dur-fast) var(--ease); }
.tbl tbody tr:hover { background: var(--paper-1); }
.tbl tbody tr:last-child td { border-bottom: 0; }

.tbl td.num, .tbl th.num {
  text-align: right;
  font-family: var(--font-mono);
}
.tbl td.mono, .tbl th.mono {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--ink-mid);
}
.tbl tr.tbl-row-clickable { cursor: pointer; }
.tbl .tbl-actions {
  display: inline-flex;
  gap: 0.5rem;
  justify-content: flex-end;
  flex-wrap: nowrap;
  white-space: nowrap;
}
.dash {
  font-family: var(--font-body);
  font-style: normal;
  color: var(--ink-ghost);
}

/* ==========================================================
   PAGINATION
   Two mechanisms share the design-system button affordance:
   the admin numbered pager (Components.renderPagination →
   .pagination) and the dashboard cursor "Load more" wrapper.
   Page cells read like a .btn at rest (translucent fill +
   hairline ring); the current page takes the accent fill.
========================================================== */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-5);
}
.page-btn,
.page-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  padding: 0.375rem 0.5rem;
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  border: 0;
  border-radius: var(--radius-md);
}
.page-btn {
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 1px var(--rule);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.page-btn:hover {
  background: rgba(255, 255, 255, 0.10);
  color: var(--ink);
}
.page-number.active {
  color: var(--ink);
  background: var(--accent);
  box-shadow: 0 0 0 1px rgba(10, 132, 255, 0.40);
  cursor: default;
}
.page-ellipsis {
  color: var(--ink-mid);
  padding: 0 var(--s-1);
  font-size: var(--t-xs);
}
.page-goto {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-left: auto;
  color: var(--ink-mid);
  font-size: var(--t-xs);
}
.page-goto__label { color: var(--ink-mid); white-space: nowrap; }
.page-goto-input {
  width: 3.25rem;
  text-align: center;
  padding: 0.375rem 0.5rem;
  font-size: var(--t-xs);
}
.page-goto-input::-webkit-outer-spin-button,
.page-goto-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Cursor "Load more", the dashboard's pagination. The button is a
   .btn--secondary (styled in design-system.css); this only centers it
   under the list with breathing room. */
.load-more {
  display: flex;
  justify-content: center;
  margin-top: var(--s-5);
}

/* ==========================================================
   TOOLBAR
   The canonical horizontal filter / action row shared by every
   surface (dashboard, admin, future). Replaces the parallel
   `.dashboard-toolbar` / `.admin-toolbar` rules that used to
   live in each surface's own CSS.

   Three building blocks:
     · .toolbar         , outer flex row; wraps on narrow widths
     · .toolbar__group  , wraps a label + control pair so within-
                           group spacing stays tight while between-
                           group spacing reads clearly
     · .toolbar__label  , inline label text (e.g. "Window:")

   Single-control toolbars don't need __group wrappers; the base
   `gap: 0.5rem` keeps the old "Find: [input]" / "Window: [select]"
   layouts looking identical to before.

   Multi-group toolbars (queries page filters, future admin
   filter rows) opt in by wrapping each label+control pair in
   `.toolbar__group`. The :has() rule then bumps the outer gap
   to 1.75rem so the eye reads each group as one unit.

   Text-like inputs (search/text/password) grow to fill row
   width; selects, chips, and buttons keep their intrinsic width.
========================================================== */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.toolbar__label {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-mid);
}
.toolbar__group {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.toolbar:has(.toolbar__group) {
  gap: var(--s-5);
}
.toolbar > input[type="search"],
.toolbar > input[type="text"],
.toolbar > input[type="password"] {
  flex: 1 1 18rem;
  max-width: 28rem;
}

/* ==========================================================
   LOADING BAR
   Thin 2px accent gradient that sweeps left-to-right at the top
   edge of an opt-in container during an in-place refetch. The
   target element marks itself with `data-loading-target`; JS
   flips `data-loading="true"` while a request is in flight.
   Decoupled from `.panel` on purpose, `.panel` is a generic
   shell and a page might host several of them for unrelated
   content. Only the element the page explicitly designates as
   the data-list root gets the bar.
   Hosts on the existing container with no layout shift.
========================================================== */
[data-loading-target][data-loading="true"] {
  position: relative;
}
[data-loading-target][data-loading="true"]::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent 0%, var(--accent) 50%, transparent 100%);
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: loading-bar 1.2s linear infinite;
  z-index: 1;
  pointer-events: none;
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
}
@keyframes loading-bar {
  0%   { background-position: -40% 0; }
  100% { background-position: 140% 0; }
}
@media (prefers-reduced-motion: reduce) {
  [data-loading-target][data-loading="true"]::before {
    animation: none;
    background: var(--accent);
    opacity: 0.5;
  }
}

/* ==========================================================
   BADGES + STATUS PILLS, capsule
========================================================== */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: var(--badge-padding);
  font-family: var(--font-body);
  font-size: var(--badge-font-size);
  font-weight: 500;
  letter-spacing: var(--badge-letter-spacing);
  text-transform: none;
  color: var(--ink-soft);
  background: var(--badge-neutral-bg);
  border-radius: var(--radius-full);
  line-height: 1.4;
}
.badge--success { color: var(--status-success); background: var(--badge-success-bg); }
.badge--warning { color: var(--status-warning); background: var(--badge-warning-bg); }
.badge--danger  { color: var(--status-error);   background: var(--badge-danger-bg); }
.badge--info    { color: var(--status-info);    background: var(--badge-info-bg); }
.badge--pending { color: var(--ink-mid);        background: var(--badge-pending-bg); }
.badge--unknown { color: var(--ink-mid);        background: var(--badge-unknown-bg); }

.title-badges {
  display: flex;
  gap: 0.375rem;
  align-items: center;
  margin-top: 0.375rem;
}

/* ==========================================================
   MODAL
========================================================== */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(6, 6, 7, 0.72);
  backdrop-filter: blur(0.5rem);
  -webkit-backdrop-filter: blur(0.5rem);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  animation: fadeIn var(--dur) var(--ease);
}
.modal {
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
  max-width: 36rem;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  padding: 1.5rem;
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--rule-soft);
}
.modal__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--rule-soft);
}
.modal__title {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.modal__close {
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--t-md);
  color: var(--ink-mid);
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.modal__close:hover {
  color: var(--ink);
  background: var(--paper-2);
}
.modal__close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Same flex-gap stack as .panel__body. gap = --s-4 (1rem) preserves the
   field-to-field spacing the old `.field + .field` rule provided, and now
   spaces every other stacked child (description, helper text, actions) too. */
.modal__body {
  margin-bottom: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.modal__foot {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  padding-top: 1rem;
  border-top: 1px solid var(--rule-soft);
}
.confirm-message {
  color: var(--ink-soft);
  font-size: var(--t-sm);
  line-height: 1.5;
}

/* ==========================================================
   HEADER DROPDOWN
========================================================== */
.hd-dropdown { position: relative; display: inline-flex; }

/* Layout-only overrides on top of the shared .select-trigger chrome
   (see design-system.css). The trigger stacks an eyebrow above the
   value instead of a single-line value, so we flip flex direction
   and tighten vertical padding for the 2-line content. Background,
   border, chevron, hover, and focus all come from .select-trigger
   so every dropdown in the header looks identical to every <select>
   on every surface. */
.hd-dropdown__trigger {
  flex-direction: row;
  align-items: center;
  gap: var(--s-3);
  padding: 0.4375rem 2rem 0.4375rem 0.875rem;
  line-height: 1.2;
  max-width: 18rem;
}
.hd-dropdown.is-open .hd-dropdown__trigger {
  background-color: var(--paper-3);
}
.hd-dropdown__trigger:hover .hd-dropdown__eyebrow { color: var(--ink-mid); }

.hd-dropdown__eyebrow {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
  display: block;
  line-height: 1.1;
}
.hd-dropdown__value {
  font-size: var(--t-sm);
  color: inherit;
  display: block;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 14rem;
}

.hd-menu {
  position: absolute;
  top: calc(100% + 0.375rem);
  left: 0;
  min-width: 14rem;
  max-width: 22rem;
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-md);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--rule-soft);
  padding: 0.375rem;
  z-index: 50;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-0.25rem);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.hd-menu--right,
.hd-dropdown--auto-right > .hd-menu { left: auto; right: 0; }
.hd-dropdown.is-open .hd-menu {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.hd-menu__head { padding: 0.5rem 0.75rem 0.25rem; }
.hd-menu__head-name {
  font-size: var(--t-sm);
  color: var(--ink);
  font-weight: 600;
}
.hd-menu__head-email {
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  color: var(--ink-mid);
  word-break: break-all;
  margin-top: 2px;
}
.hd-menu__group { display: flex; flex-direction: column; }
.hd-menu__divider {
  border-top: 1px solid var(--rule-soft);
  margin: 0.375rem 0;
}
.hd-menu__item {
  appearance: none;
  background: transparent;
  border: 0;
  width: 100%;
  text-align: left;
  padding: 0.4375rem 0.75rem;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: var(--radius-sm);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.hd-menu__item:hover,
.hd-menu__item:focus-visible {
  background: var(--paper-2);
  color: var(--ink);
  outline: none;
}
.hd-menu__item.is-current { color: var(--ink); font-weight: 600; }
.hd-menu__item-label {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--t-sm);
}
.hd-menu__check, .hd-menu__plus {
  color: var(--accent);
  font-size: var(--t-sm);
  line-height: 1;
}
.hd-menu__item--add { color: var(--accent); }
.hd-menu__item--add:hover { color: var(--accent); }
.hd-menu__hint {
  padding: 0.4375rem 0.75rem;
  font-size: var(--t-xs);
  line-height: 1.45;
  color: var(--ink-mid);
}
/* ==========================================================
   TOASTS
========================================================== */
.toast-stack {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
}
.toast {
  min-width: 16rem;
  max-width: 24rem;
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-md);
  padding: 0.75rem 1rem;
  font-family: var(--font-body);
  font-size: var(--t-sm);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--rule-soft);
  pointer-events: auto;
  animation: fadeIn var(--dur) var(--ease);
}
.toast--success { box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--status-success); }
.toast--warning { box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--status-warning); }
.toast--error   { box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.5), 0 0 0 1px var(--status-error); }
.toast__action {
  display: inline-block;
  margin-left: 0.5rem;
  color: var(--accent);
  text-decoration: underline;
  font-weight: 600;
}
.toast__action:hover { color: var(--accent-deep); }

/* ==========================================================
   CALLOUT
   Small in-prose boxed note. Used in long-form pages (help,
   future marketing pages) to call out a tip, caveat, or aside
   without breaking the read-down rhythm. The `__k` keyword sits
   above the body as a quiet label.
========================================================== */
.callout {
  background: var(--paper-2);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
  padding: var(--s-3) var(--s-4);
  margin: var(--s-4) 0;
  max-width: 60ch;
  font-size: var(--t-sm);
  color: var(--ink-soft);
  line-height: 1.55;
}
.callout__k {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--ink-mid);
  display: block;
  margin-bottom: 0.25rem;
}

/* ==========================================================
   LOADING
========================================================== */
.loading-overlay {
  position: fixed; inset: 0;
  background: rgba(6, 6, 7, 0.72);
  backdrop-filter: blur(0.25rem);
  -webkit-backdrop-filter: blur(0.25rem);
  z-index: 150;
  display: none;
  align-items: center;
  justify-content: center;
}
.loading-overlay.is-shown { display: flex; }
.spinner {
  width: 2rem;
  height: 2rem;
  border: 2px solid var(--rule);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}

/* ==========================================================
   EMPTY STATES
========================================================== */
.empty-state {
  text-align: center;
  padding: 3.5rem 0;
}
.empty-state__title {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 0.75rem;
  color: var(--ink);
}
.empty-state__body {
  font-size: var(--t-md);
  color: var(--ink-mid);
  max-width: 36rem;
  margin: 0 auto 1.25rem;
  line-height: 1.5;
}
.empty-state__actions {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
}

.empty {
  padding: 2rem;
  text-align: center;
  color: var(--ink-mid);
  font-style: normal;
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
}
.empty--error { color: var(--status-error); }
.empty--inline {
  padding: 0.75rem;
  background: transparent;
  text-align: left;
}

/* ==========================================================
   KEY-FLASH, DASH-SECTION
========================================================== */
.key-flash {
  background: var(--accent-tint);
  border: 0;
  border-radius: var(--radius-md);
  padding: 0.75rem;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  word-break: break-all;
  color: var(--ink);
  letter-spacing: 0;
  text-transform: none;
  margin: 0.75rem 0;
}

.dash-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.dash-subhead {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.dash-subhead__note {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  color: var(--ink-mid);
  letter-spacing: 0;
  text-transform: none;
}

/* ==========================================================
   PROGRESS, METER, BANNER
========================================================== */
.progress {
  margin-top: 0.75rem;
  height: 0.5rem;
  background: var(--paper-2);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.progress__fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 120ms;
}
.progress__text { margin-top: 0.5rem; font-size: var(--t-xs); color: var(--ink-mid); }
.progress__errors {
  font-size: var(--t-xs);
  margin-top: 0.5rem;
  color: var(--ink-mid);
}

.meter__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.meter__label {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.meter__value {
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--ink);
}
.meter__bar {
  height: 0.5rem;
  background: var(--paper-2);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.meter__fill {
  height: 100%;
  background: var(--accent);
  transition: width 500ms var(--ease);
}
.meter__fill--safe    { background: var(--status-success); }
.meter__fill--warning { background: var(--status-warning); }
.meter__fill--danger  { background: var(--status-error); }
.meter__foot {
  display: flex;
  justify-content: space-between;
  margin-top: 0.375rem;
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.meter--catalog {
  margin-top: 0.75rem;
  padding: 1rem 1.25rem;
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
}
.meter--na {
  opacity: 0.55;
  color: var(--ink-mid);
  font-family: var(--font-body);
  padding: 0.5rem 0;
}
.meter--na__label { color: var(--ink-mid); }
.meter--na__note  { margin-left: 0.75rem; }

.banner {
  font-size: var(--t-sm);
  line-height: 1.5;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background: var(--paper-1);
  border-left: 0;
  border-radius: var(--radius-md);
  color: var(--ink-soft);
}
.banner strong { font-weight: 600; color: var(--ink); }
.banner--info {
  background: var(--accent-tint);
  color: var(--accent);
}
.banner--info strong { color: var(--ink); }
.banner--warning {
  background: var(--badge-warning-bg);
  color: var(--status-warning);
}
.banner--warning strong { color: var(--ink); }
.banner--danger {
  background: var(--badge-danger-bg);
  color: var(--status-error);
}
.banner--danger strong { color: var(--ink); }
.banner a:not(.btn) {
  color: var(--accent);
  text-decoration: underline;
}

/* ==========================================================
   COPY-INPUT, readonly input with an inline Copy button.
   Rendered by Components.copyInput({ label, value, id, hint,
   monospace }). One visual unit: input fills the available
   width, button sits flush against its right edge inside the
   input's chrome. Used for referral links, handoff invite
   URLs, just-minted API keys, attribution tokens, anywhere
   the user is supposed to copy a value verbatim.
========================================================== */
.copy-input {
  position: relative;
  display: flex;
}
.copy-input__field {
  /* Inherits base input chrome from design-system.css's :where(input)
     rule. The padding-right gives the absolute-positioned button
     a no-collision lane so long values are visually truncated
     before they slide under it. */
  flex: 1;
  padding-right: 4.25rem;
  min-width: 0;
}
/* The Copy button sits visually inside the input, so hovering the
   button shouldn't break the input's hover state. The wrapper's
   :hover fires whenever the cursor is over any child (input OR
   button); we cascade the input's `:hover` background-color from
   that selector so the input lifts as if the cursor were on it
   directly. The base input rule's `transition: background-color`
   handles the animation. Uses the same `--field-bg-hover` variable
   the base input rule consumes, so any ancestor override (deeper-
   nested cases) lifts the copy-input field to the right level. */
.copy-input:hover .copy-input__field:not(:disabled) {
  background-color: var(--field-bg-hover, var(--paper-3));
}
.copy-input__btn {
  position: absolute;
  right: 0.375rem;
  top: 50%;
  transform: translateY(-50%);
  height: calc(100% - 0.75rem);
  display: inline-flex;
  align-items: center;
  padding: 0 0.625rem;
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--accent);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color 120ms var(--ease);
}
.copy-input__btn:disabled {
  cursor: default;
}
.copy-input__btn.is-copied {
  color: var(--status-success);
}

/* ==========================================================
   PREVIEW (definition-list)
========================================================== */
.preview { display: flex; flex-direction: column; }
.preview__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px dashed var(--rule-soft);
  font-size: var(--t-sm);
}
.preview__row:last-child { border-bottom: 0; }
.preview__k {
  font-family: var(--font-body);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-mid);
}
.preview__v {
  color: var(--ink-soft);
  text-align: right;
}

/* ==========================================================
   INTEL CARDS
========================================================== */
.intel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 0.75rem;
}
.intel-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  background: var(--paper-1);
  border: 0;
  border-radius: var(--radius-lg);
  padding: 1.25rem;
  text-decoration: none;
  color: inherit;
  transition: background var(--dur) var(--ease);
  min-height: 11rem;
  position: relative;
}
.intel-card:hover { background: var(--paper-2); }
.intel-card__title {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.intel-card__lede {
  font-size: var(--t-sm);
  color: var(--ink-mid);
  line-height: 1.45;
}
.intel-card__signal { margin-top: auto; }
.intel-card__count {
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  color: var(--ink-soft);
}
.intel-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.intel-chip {
  display: inline-block;
  padding: 2px 0.5rem;
  background: var(--paper-0);
  border: 0;
  border-radius: var(--radius-full);
  font-size: var(--t-xs);
  color: var(--ink-mid);
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.intel-chip--gap { color: var(--status-error); background: var(--badge-danger-bg); }
.intel-card__when { font-size: var(--t-xs); color: var(--ink-mid); }
.intel-card__empty {
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--t-md);
  color: var(--ink-mid);
}
.intel-card__empty::before {
  content: "·";
  margin-right: 0.375rem;
  color: var(--accent);
}
.intel-card__empty--error { color: var(--status-error); }
.intel-card__arrow { color: var(--ink-mid); }
.intel-card--static { cursor: default; }
.intel-card--static:hover { background: var(--paper-1); }
.item-intel-row { display: grid; gap: 0.75rem; }
.item-intel-row--3up { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.item-intel-row--2up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 56em) {
  .item-intel-row--3up, .item-intel-row--2up { grid-template-columns: 1fr; }
}

/* ==========================================================
   INTELLIGENCE MAP · overlay primitives
   The heatmap canvas + SVG overlay pattern is shared across every
   surface that consumes the VQHeatmap module (dashboard, marketing
   prospect page, demo storefronts). Each surface owns its own
   .intel-map-frame dimensions; everything inside the frame -
   canvas/svg positioning, anchor dots, anchor labels, tooltip, and
   the corner legend, is identical across consumers and lives here.
========================================================== */
.intel-map__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: crosshair;
}
.intel-map__svg {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

/* Anchor dots, dark fill, white ring. Reads as a crisp landmark on
   any plasma color (bright yellow highs, dim indigo lows). Hover
   swaps fill to the accent. */
.intel-map__node-dot {
  fill: var(--paper-2);
  stroke: var(--ink);
  stroke-width: 1;
  transition: fill 160ms var(--ease);
}
.intel-map__node-dot.is-hovered {
  fill: var(--accent);
}

/* Anchor labels, white text with a dark halo via paint-order stroke.
   Stays readable across the plasma range: white fill on the dark/
   indigo lows, dark halo on the bright yellow highs. Hover state
   leaves the label alone; only the dot's fill swaps to accent. */
.intel-map__node-label {
  fill: var(--ink);
  stroke: var(--shade);
  stroke-width: 3;
  paint-order: stroke fill;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0;
  pointer-events: none;
}

/* Tooltip, floats over the canvas while hovering. Surfaces position
   it via JS (left/top in pixel coords). */
.intel-map-tooltip {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  background: var(--paper-1);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: 0.5rem 0.75rem;
  max-width: 18rem;
  font-size: var(--t-sm);
  color: var(--ink-soft);
  box-shadow: var(--shadow-md);
  z-index: 2;
}
.intel-map-tooltip[hidden] { display: none; }
.intel-map-tooltip__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 2px;
}
.intel-map-tooltip__name {
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
}
.intel-map-tooltip__desc {
  font-size: var(--t-xs);
  color: var(--ink-mid);
  line-height: 1.45;
  margin-top: 0.125rem;
}

/* Legend, corner chip with the running query count. */
.intel-map__legend {
  position: absolute;
  left: 1rem;
  bottom: 0.75rem;
  font-size: var(--t-xs);
  color: var(--ink-mid);
  background: var(--bar);
  backdrop-filter: blur(0.5rem);
  -webkit-backdrop-filter: blur(0.5rem);
  padding: 0.375rem 0.625rem;
  border-radius: var(--radius-sm);
  pointer-events: none;
  z-index: 1;
}
.intel-map__legend strong {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================
   VOLUME TREND · time-series bar chart
   Used on the admin Property-detail Billing panel (7d hourly =
   168 bars) and the dashboard's items / search-queries metrics
   surfaces (variable period). The renderer sets --bar-count
   (number of grid columns) and --bar-h (per-bar height as a
   percentage); CSS does the rest. Tooltip + skeleton + both
   axis (start/end) and tick (per-column) label variants ship
   in one component.
========================================================== */
.volume-trend {
  position: relative;
  margin-top: 0.75rem;
}
.volume-trend + .volume-trend { margin-top: 1rem; }
.volume-trend:empty { display: none; }
.volume-trend__skeleton {
  height: 8rem;
  background: var(--paper-2);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md);
}
.volume-trend__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.volume-trend__title {
  font-size: var(--t-sm);
  color: var(--ink);
  font-weight: 500;
}
.volume-trend__meta {
  font-size: var(--t-xs);
  color: var(--ink-mid);
}
.volume-trend__bars {
  display: flex;
  align-items: stretch;
  gap: 0.125rem;
  height: 7rem;
  padding: 0.5rem 0 0;
  border-top: 1px dashed var(--rule-soft);
  border-bottom: 1px solid var(--rule-soft);
}
/* Dense series (many bars per row) get a tighter gap so the bars
   read as a continuous curve rather than isolated ticks. */
.volume-trend__bars:has(> :nth-child(80)) { gap: 0.0625rem; }
.volume-trend__col {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-width: 0;
  overflow: visible;
}
.volume-trend__bar-wrap {
  flex: 1 1 auto;
  display: flex;
  align-items: flex-end;
  min-height: 0;
  padding: 0 0.0625rem;
}
.volume-trend__bar {
  width: 100%;
  min-height: 0.125rem;
  height: var(--bar-h, 0%);
  background: var(--accent);
  border-radius: 0.125rem 0.125rem 0 0;
}
.volume-trend__col.is-empty .volume-trend__bar {
  min-height: 0.0625rem;
  background: var(--rule);
}
.volume-trend__col:hover .volume-trend__bar,
.volume-trend__col.is-active .volume-trend__bar { background: var(--accent-deep); }
.volume-trend__col.is-active.is-empty .volume-trend__bar { background: var(--ink-mid); }

.volume-trend__tooltip {
  position: absolute;
  transform: translateX(-50%);
  background: var(--paper-1);
  color: var(--ink-soft);
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-sm);
  font-size: 0.75rem;
  line-height: 1.2;
  pointer-events: none;
  white-space: nowrap;
  box-shadow: var(--shadow-md);
  z-index: 5;
}
.volume-trend__tooltip[hidden] { display: none; }
.volume-trend__tooltip::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -0.3125rem;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 0.3125rem solid transparent;
  border-right: 0.3125rem solid transparent;
  border-top: 0.3125rem solid var(--paper-1);
}
.volume-trend__tooltip-count {
  font-weight: 600;
  font-size: 0.8125rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.volume-trend__tooltip-when {
  color: var(--ink-mid);
  margin-top: 0.125rem;
}
/* Per-bar tick labels (one per column, narrow). Spans can spill
   outside their narrow grid track since overflow: visible above. */
.volume-trend__tick {
  font-size: 0.6875rem;
  color: var(--ink-mid);
  margin-top: 0.375rem;
  min-height: 1rem;
  position: relative;
  line-height: 1;
}
.volume-trend__tick > span {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
}
/* Axis labels (start + end of period, no per-bar ticks). */
.volume-trend__axis {
  display: flex;
  justify-content: space-between;
  font-size: var(--t-xs);
  color: var(--ink-mid);
  margin-top: 0.25rem;
}

/* ==========================================================
   HELP LINK · small `?` icon next to a title
   Emitted by Common.panelTitle / Common.helpLink to point at
   the relevant help-doc page. Title-groups wrap the title +
   help-link so the icon hugs the heading instead of stacking.
========================================================== */
.help-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.125rem;
  height: 1.125rem;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-mid);
  text-decoration: none;
  transition: color 120ms var(--ease);
}
.help-link:hover { color: var(--accent); }
.panel__title-group {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.page__title-group {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.page__title-group .help-link {
  width: 1.5rem;
  height: 1.5rem;
  font-size: 0.95rem;
}



/* ── Activity histogram ────────────────────────────────────────────────────────
   Stacked daily-change bars + calendar-day axis. One component shared by the landing
   "daily changes" trend (static, `--card`) and the dashboard region Map instrument
   (interactive: clickable bars select a day, `--interactive`). Segment colors are passed
   inline per surface (the landing's category palette, the dashboard's signal-group
   palette), so this stays color-agnostic. Bar/stack heights are set inline as percentages. */
.dv-hist { --dv-hist-h: 5rem; }
.dv-hist--card {
  border: 1px solid var(--rule); border-radius: var(--radius-lg);
  overflow: hidden; background: var(--paper-1);
}
.dv-hist__bars { display: flex; align-items: flex-end; gap: 2px; height: var(--dv-hist-h); }
.dv-hist--card .dv-hist__bars { padding: var(--s-3) var(--s-3) 0; }
.dv-hist__bar {
  flex: 1 1 0; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0; background: none; border: 0;
}
.dv-hist__stack {
  display: flex; flex-direction: column-reverse;
  width: 100%; overflow: hidden; border-radius: 2px 2px 0 0; opacity: 0.85;
  transition: opacity var(--dur) var(--ease);
}
.dv-hist__stack > i { display: block; width: 100%; }
.dv-hist__axis {
  position: relative; height: 1.2rem; margin-top: 2px;
  font-family: var(--font-mono); font-size: var(--t-3xs); color: var(--ink-mid);
}
.dv-hist--card .dv-hist__axis { padding: 0 var(--s-3); }
.dv-hist__tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
/* Interactive (dashboard): the whole day column is a clickable button. Non-selected days
   are muted so the picked day stands out by contrast; the selected day reads as a
   highlighted full-height column (accent-tinted background + a solid accent base + its
   colors at full strength), not just a hairline. */
/* Reserve room above the bars for the selected-day marker dot. */
.dv-hist--interactive { padding-top: 0.7rem; }
.dv-hist--interactive .dv-hist__bar {
  position: relative;
  cursor: pointer; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  transition: background var(--dur) var(--ease);
}
.dv-hist--interactive .dv-hist__stack { width: 72%; opacity: 0.5; }
.dv-hist--interactive .dv-hist__bar:hover { background: var(--paper-2); }
.dv-hist--interactive .dv-hist__bar:hover .dv-hist__stack { opacity: 0.85; }
.dv-hist--interactive .dv-hist__bar.is-selected { background: var(--accent-tint); }
.dv-hist--interactive .dv-hist__bar.is-selected .dv-hist__stack { opacity: 1; }
/* A blue dot centered just ABOVE the selected column: a marker that reads regardless
   of the bar's own colors. Placed above (not below) so it never collides with the
   calendar-day axis labels beneath the bars. */
.dv-hist--interactive .dv-hist__bar.is-selected::after {
  content: ""; position: absolute; bottom: calc(100% + 0.25rem); left: 50%;
  transform: translateX(-50%);
  width: 0.4rem; height: 0.4rem; border-radius: 50%;
  background: var(--accent);
}
