/* v3-base */
/**
 * Partner Portal v3 — design tokens + components.
 *
 * Scope: only loaded by /partner-portal.php (v3 shell). Other surfaces
 * (customer portal, admin) continue using legacy ui-standard + workspace_polish.
 *
 * Source-of-truth mockup: /Users/Khoamap/Dev/UI_STANDARD/hideads/partner-portal-v3.html
 *
 * Naming convention:
 *   .pv3-* prefix to avoid collision with legacy .ui-* + workspace_polish.
 *   HSL CSS variables (shadcn convention). Dark-only since 2026-06-11
 *   per owner — the light variant + theme toggle were dropped.
 */

:root, .pv3 {
  --pv3-background: 240 12% 4%;
  --pv3-foreground: 0 0% 98%;
  --pv3-card: 240 8% 6%;
  --pv3-card-foreground: 0 0% 98%;
  --pv3-popover: 240 8% 8%;
  --pv3-popover-foreground: 0 0% 98%;
  --pv3-primary: 0 0% 98%;
  --pv3-primary-foreground: 240 5.9% 10%;
  --pv3-secondary: 240 4% 11%;
  --pv3-secondary-foreground: 0 0% 98%;
  --pv3-muted: 240 4% 11%;
  --pv3-muted-foreground: 240 5% 65%;
  --pv3-accent: 240 4% 14%;
  --pv3-accent-foreground: 0 0% 98%;
  --pv3-destructive: 0 72% 51%;
  --pv3-success: 142 71% 45%;
  --pv3-warning: 38 92% 50%;
  --pv3-info: 199 89% 48%;
  --pv3-border: 240 4% 14%;
  --pv3-input: 240 4% 14%;
  --pv3-ring: 240 5% 70%;
  --pv3-sidebar: 240 10% 5%;
  --pv3-sidebar-foreground: 240 5% 80%;
  --pv3-sidebar-accent: 240 6% 10%;
  --pv3-sidebar-accent-foreground: 0 0% 98%;
  --pv3-sidebar-border: 240 4% 12%;
  --pv3-radius-sm: 4px;
  --pv3-radius: 7px;
  --pv3-radius-md: 10px;
  --pv3-radius-lg: 14px;
  --pv3-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.5);
  --pv3-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.4), 0 0 0 1px rgb(255 255 255 / 0.02) inset;
  --pv3-shadow-lg: 0 20px 50px -10px rgb(0 0 0 / 0.7), 0 0 0 1px rgb(255 255 255 / 0.03) inset;
  --pv3-sidebar-w: 260px;
  --pv3-sidebar-w-collapsed: 56px;
  --pv3-topbar-h: 56px;
}

/* Light theme block dropped 2026-06-11 per owner — never shipped a toggle. */

/* Reset within pv3 scope so legacy ui-* on other pages stays unaffected. */
.pv3, .pv3 *, .pv3 *::before, .pv3 *::after { box-sizing: border-box; }
/* Force [hidden] attribute to win over inline `style="display:flex"` so
   legacy modals (ui-modal-backdrop hidden style="display:flex") render
   collapsed until JS removes hidden — was leaking visible inside .pv3
   shell because workspace_polish had no equivalent guard. */
.pv3 [hidden] { display: none !important; }
.pv3 {
  font-family: 'Geist', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  background: hsl(var(--pv3-background));
  color: hsl(var(--pv3-foreground));
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
}
.pv3 code, .pv3 kbd, .pv3 .pv3-mono { font-family: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace; }
.pv3 button { font: inherit; cursor: pointer; }
/* Link reset — scoped exclusion so button classes keep their own color.
 * 2026-06-11: also exclude legacy ui-button (customer portal still uses
 * <a class="ui-button ui-button--primary"> via tab-tracker-summary etc.)
 * The previous regex `[class*="pv3-btn"]` only caught pv3 classes and
 * the ui-button--primary link inherited body color = #fafafa, giving
 * white text on white bg. */
.pv3 a:not([class*="pv3-btn"]):not([class*="ui-button"]) { color: inherit; }
.pv3 a { text-decoration: none; }
.pv3 :focus-visible { outline: 2px solid hsl(var(--pv3-ring)); outline-offset: 2px; border-radius: var(--pv3-radius-sm); }

/* Sprint 2026-07-26 audit — WCAG 2.3.3 (Animation from Interactions).
   Neutralize animations + transitions for users who set prefers-
   reduced-motion. Applies to every Tailwind `.transition-*`,
   `.animate-*`, and `active:translate-*` utility since it targets by
   property, not class. Scoped to .pv3 so legacy pages stay unaffected. */
@media (prefers-reduced-motion: reduce) {
  .pv3, .pv3 *, .pv3 *::before, .pv3 *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============ Shell ============ */
.pv3-shell {
  display: grid;
  grid-template-columns: var(--pv3-sidebar-w) 1fr;
  min-height: 100vh;
  transition: grid-template-columns 200ms ease;
}
.pv3-shell.is-collapsed { grid-template-columns: var(--pv3-sidebar-w-collapsed) 1fr; }

/* ============ Sidebar ============ */
.pv3-sidebar {
  background: hsl(var(--pv3-sidebar));
  border-right: 1px solid hsl(var(--pv3-sidebar-border));
  display: flex;
  flex-direction: column;
  height: 100vh;
  position: sticky;
  top: 0;
  overflow: hidden;
}
.pv3-sidebar__header { padding: 12px 12px 8px; }
.pv3-workspace {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: var(--pv3-radius);
  background: hsl(var(--pv3-sidebar-accent));
  cursor: pointer;
  width: 100%;
  border: 1px solid transparent;
  color: hsl(var(--pv3-sidebar-accent-foreground));
  transition: background 120ms ease;
}
.pv3-workspace:hover { background: hsl(var(--pv3-accent)); }
.pv3-workspace__logo {
  width: 32px; height: 32px;
  background: linear-gradient(135deg, #fafafa, #d4d4d8);
  color: #18181b;
  border-radius: var(--pv3-radius);
  display: grid; place-items: center;
  font-weight: 700; font-size: 13px;
  flex-shrink: 0;
}
.pv3-workspace__body {
  flex: 1; display: flex; flex-direction: column;
  text-align: left; min-width: 0;
}
.pv3-workspace__name {
  font-weight: 500; font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pv3-workspace__plan {
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.is-collapsed .pv3-workspace__body,
.is-collapsed .pv3-workspace__chev { display: none; }
.is-collapsed .pv3-workspace { padding: 8px 4px; justify-content: center; }
.pv3-workspace__chev { margin-left: auto; opacity: .6; }

.pv3-sidebar__content {
  flex: 1; overflow-y: auto;
  padding: 4px 8px 14px;
  /* UI audit 2026-08-11 PTR-1 — vertical scrolling shadows: when nav
     overflows (partner sidebar at 900px), the bottom edge shadow shows
     there are more items behind the pinned account bar. */
  background:
    linear-gradient(to bottom, hsl(var(--pv3-sidebar)) 30%, hsl(var(--pv3-sidebar) / 0)) top / 100% 24px,
    linear-gradient(to top, hsl(var(--pv3-sidebar)) 30%, hsl(var(--pv3-sidebar) / 0)) bottom / 100% 24px,
    radial-gradient(farthest-side at 50% 0, rgb(0 0 0 / 0.5), transparent) top / 100% 12px,
    radial-gradient(farthest-side at 50% 100%, rgb(0 0 0 / 0.5), transparent) bottom / 100% 12px;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.pv3-sidebar__content::-webkit-scrollbar { width: 6px; }
.pv3-sidebar__content::-webkit-scrollbar-thumb { background: hsl(var(--pv3-border)); border-radius: 3px; }

.pv3-nav-group { margin-top: 10px; }
.pv3-nav-group__label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: hsl(var(--pv3-muted-foreground));
  padding: 6px 10px 4px;
  font-weight: 500;
}
.is-collapsed .pv3-nav-group__label { display: none; }
.pv3-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--pv3-radius);
  color: hsl(var(--pv3-sidebar-foreground));
  font-size: 13px;
  font-weight: 500;
  position: relative;
  transition: background 120ms ease, color 120ms ease;
  border: 1px solid transparent;
  cursor: pointer;
  width: 100%;
  background: transparent;
  text-align: left;
}
.pv3-nav-item:hover { background: hsl(var(--pv3-sidebar-accent)); color: hsl(var(--pv3-sidebar-accent-foreground)); }
.pv3-nav-item.is-active {
  background: hsl(var(--pv3-sidebar-accent));
  color: hsl(var(--pv3-sidebar-accent-foreground));
  border-color: hsl(var(--pv3-sidebar-border));
}
.pv3-nav-item__icon { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.85; }
.pv3-nav-item.is-active .pv3-nav-item__icon { opacity: 1; }
.pv3-nav-item__label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.is-collapsed .pv3-nav-item__label,
.is-collapsed .pv3-nav-item__badge { display: none; }
.is-collapsed .pv3-nav-item { justify-content: center; padding: 8px 4px; }
.pv3-nav-item__badge {
  font-size: 10px;
  background: hsl(var(--pv3-warning) / 0.18);
  color: hsl(var(--pv3-warning));
  padding: 2px 6px;
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.pv3-nav-item__badge--info { background: hsl(var(--pv3-info) / 0.15); color: hsl(var(--pv3-info)); }
.pv3-nav-item__badge--success { background: hsl(var(--pv3-success) / 0.15); color: hsl(var(--pv3-success)); }
.pv3-nav-item__badge--soon { background: hsl(var(--pv3-muted) / 0.6); color: hsl(var(--pv3-muted-foreground)); }

.pv3-sidebar__footer {
  padding: 8px;
  border-top: 1px solid hsl(var(--pv3-sidebar-border));
  position: relative;
  flex-shrink: 0;
  background: hsl(var(--pv3-sidebar));
}
.pv3-user-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: var(--pv3-radius);
  cursor: pointer;
  background: transparent;
  width: 100%;
  border: none;
  color: inherit;
  transition: background 120ms ease;
}
.pv3-user-card:hover { background: hsl(var(--pv3-sidebar-accent)); }
.pv3-user-card__avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, hsl(199 89% 48%), hsl(263 70% 50%));
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600;
  color: #fff;
  flex-shrink: 0;
}
.pv3-user-card__body { flex: 1; min-width: 0; text-align: left; }
.pv3-user-card__name {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pv3-user-card__email {
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.is-collapsed .pv3-user-card__body,
.is-collapsed .pv3-user-card__chev { display: none; }
.is-collapsed .pv3-user-card { justify-content: center; padding: 6px 4px; }

/* ============ Topbar ============ */
.pv3-main { display: flex; flex-direction: column; min-width: 0; }
.pv3-topbar {
  height: var(--pv3-topbar-h);
  border-bottom: 1px solid hsl(var(--pv3-border));
  background: hsl(var(--pv3-background) / 0.98);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 12px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.pv3-topbar__trigger {
  width: 32px; height: 32px;
  border-radius: var(--pv3-radius);
  display: grid; place-items: center;
  background: transparent;
  border: none;
  color: hsl(var(--pv3-muted-foreground));
  transition: background 120ms ease, color 120ms ease;
}
.pv3-topbar__trigger:hover { background: hsl(var(--pv3-accent)); color: hsl(var(--pv3-foreground)); }
.pv3-topbar__divider { width: 1px; height: 18px; background: hsl(var(--pv3-border)); }
.pv3-breadcrumb { display: flex; align-items: center; gap: 8px; font-size: 13px; color: hsl(var(--pv3-muted-foreground)); }
.pv3-breadcrumb a:hover { color: hsl(var(--pv3-foreground)); }
.pv3-breadcrumb__sep { opacity: 0.4; }
/* .pv3-breadcrumb__current styling migrated to ui-tokens.ts::TOPBAR_TEXT
   (Tailwind class) 2026-07-16 — shared with topbar clock so shell chrome
   text is single-source. Class name kept as anchor for any downstream
   selector still referencing it. */

.pv3-topbar__spacer { flex: 1; }

.pv3-cmdk-trigger {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px 6px 8px;
  background: hsl(var(--pv3-secondary));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  color: hsl(var(--pv3-muted-foreground));
  font-size: 12px;
  min-width: 260px;
  transition: border-color 120ms ease;
}
.pv3-cmdk-trigger:hover { border-color: hsl(var(--pv3-ring) / 0.5); }
.pv3-cmdk-trigger__kbd {
  margin-left: auto;
  display: inline-flex; gap: 2px;
  font-family: 'Geist Mono', monospace;
  font-size: 10px;
}
.pv3-kbd {
  padding: 2px 5px;
  background: hsl(var(--pv3-background));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: 4px;
  font-size: 10px;
  font-family: 'Geist Mono', monospace;
  line-height: 1;
}
.pv3-icon-btn {
  width: 32px; height: 32px;
  border-radius: var(--pv3-radius);
  display: grid; place-items: center;
  background: transparent;
  border: none;
  color: hsl(var(--pv3-muted-foreground));
  position: relative;
  transition: background 120ms ease, color 120ms ease;
}
.pv3-icon-btn:hover { background: hsl(var(--pv3-accent)); color: hsl(var(--pv3-foreground)); }
.pv3-icon-btn__dot {
  position: absolute;
  top: 6px; right: 6px;
  width: 8px; height: 8px;
  background: hsl(var(--pv3-destructive));
  border: 2px solid hsl(var(--pv3-background));
  border-radius: 50%;
}

/* ============ Page ============ */
/* No flex:1 — a stretched page pins the footer to the viewport bottom and
   leaves a large dark void between short content and the footer (UI 2026-08-12).
   Without it the page collapses to content height; footer sits just below. */
.pv3-page { padding: 24px 28px 40px; max-width: 1480px; width: 100%; margin: 0 auto; }
.pv3-page__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.pv3-page__title { font-size: 22px; font-weight: 600; margin: 0 0 4px; letter-spacing: -0.01em; }
.pv3-page__sub { font-size: 13px; color: hsl(var(--pv3-muted-foreground)); margin: 0; max-width: 640px; }
.pv3-page__actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; flex-wrap: wrap; }

/* Tab panel host — only one visible at a time via JS */
[data-pv3-panel] { display: none; }
[data-pv3-panel].is-active { display: block; }

/* ============ Buttons — REMOVED Phase 10 (2026-06-19) ============ */
/* Migrated to UI tokens. See src/lib/ui-tokens.ts → BTN_PRIMARY / BTN_SECONDARY /
 * BTN_DESTRUCTIVE / BTN_OUTLINE / BTN_GHOST + helper button(). */

/* ============ Badge ============ */
.pv3-badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
  background: hsl(var(--pv3-secondary));
  color: hsl(var(--pv3-secondary-foreground));
  border: 1px solid hsl(var(--pv3-border));
  line-height: 1.4;
}
.pv3-badge--success { background: hsl(var(--pv3-success) / 0.15); color: hsl(var(--pv3-success)); border-color: hsl(var(--pv3-success) / 0.25); }
.pv3-badge--warning { background: hsl(var(--pv3-warning) / 0.15); color: hsl(var(--pv3-warning)); border-color: hsl(var(--pv3-warning) / 0.25); }
.pv3-badge--destructive { background: hsl(var(--pv3-destructive) / 0.15); color: hsl(var(--pv3-destructive)); border-color: hsl(var(--pv3-destructive) / 0.25); }
.pv3-badge--info { background: hsl(var(--pv3-info) / 0.15); color: hsl(var(--pv3-info)); border-color: hsl(var(--pv3-info) / 0.25); }
.pv3-badge__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  position: relative;
}
.pv3-badge__dot.is-pulse::after {
  content: ''; position: absolute; inset: -3px;
  border-radius: 50%; background: currentColor; opacity: 0.4;
  animation: pv3-pulse 2s ease-out infinite;
}
@keyframes pv3-pulse {
  0% { transform: scale(0.8); opacity: 0.6; }
  100% { transform: scale(2.2); opacity: 0; }
}

/* ============ Card ============ */
.pv3-card {
  background: hsl(var(--pv3-card));
  border-radius: var(--pv3-radius-lg);
  overflow: hidden;
}
.pv3-card__header {
  padding: 16px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.pv3-card__title { font-size: 14px; font-weight: 600; margin: 0; letter-spacing: -0.005em; }
.pv3-card__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 2px 0 0; }
.pv3-card__body { padding: 18px; }
.pv3-card__body--flush { padding: 0; }
.pv3-card__footer {
  padding: 12px 18px;
  display: flex; justify-content: space-between; align-items: center;
  background: hsl(var(--pv3-background) / 0.4);
}

/* ============ KPI ============ */
.pv3-kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}
.pv3-kpi {
  background: hsl(var(--pv3-card));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
}
.pv3-kpi__label {
  font-size: 12px;
  color: hsl(var(--pv3-muted-foreground));
  font-weight: 500;
  letter-spacing: 0.01em;
}
.pv3-kpi__value {
  font-size: 28px;
  font-weight: 600;
  font-family: 'Geist Mono', monospace;
  letter-spacing: -0.02em;
  margin: 8px 0 4px;
  line-height: 1.1;
}
.pv3-kpi__delta {
  font-size: 12px;
  color: hsl(var(--pv3-muted-foreground));
  display: flex; align-items: center; gap: 4px;
}
.pv3-kpi__delta--up { color: hsl(var(--pv3-success)); }
.pv3-kpi__delta--down { color: hsl(var(--pv3-destructive)); }
.pv3-kpi__sub {
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  margin-top: 2px;
}
.pv3-kpi--link {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 120ms ease, transform 120ms ease;
}
.pv3-kpi--link:hover {
  border-color: hsl(var(--pv3-foreground) / 0.3);
  transform: translateY(-1px);
}

/* ============ Grid ============ */
.pv3-grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.pv3-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

/* ============ Chart ============ */
.pv3-chart-canvas { width: 100%; height: 220px; display: block; }
.pv3-chart-line { fill: none; stroke: hsl(var(--pv3-primary)); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pv3-chart-area { fill: hsl(var(--pv3-primary) / 0.08); stroke: none; }
.pv3-chart-line--success { stroke: hsl(var(--pv3-success)); }
.pv3-chart-area--success { fill: hsl(var(--pv3-success) / 0.08); }
.pv3-chart-grid { stroke: hsl(var(--pv3-border)); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.5; }
.pv3-chart-axis { font-family: 'Geist Mono', monospace; font-size: 10px; fill: hsl(var(--pv3-muted-foreground)); }

.pv3-legend { display: flex; gap: 16px; padding: 12px 18px 16px; flex-wrap: wrap; }
.pv3-legend__item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: hsl(var(--pv3-muted-foreground)); }
.pv3-legend__dot { width: 8px; height: 8px; border-radius: 2px; }

/* ============ Queue list ============ */
.pv3-queue { list-style: none; padding: 0; margin: 0; }
.pv3-queue__item {
  display: flex;
  padding: 14px 18px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  gap: 12px;
  align-items: center;
}
.pv3-queue__item:last-child { border-bottom: none; }
.pv3-queue__icon {
  width: 32px; height: 32px;
  border-radius: var(--pv3-radius);
  display: grid; place-items: center;
  background: hsl(var(--pv3-accent));
  flex-shrink: 0;
  color: hsl(var(--pv3-muted-foreground));
}
.pv3-queue__icon--warning { background: hsl(var(--pv3-warning) / 0.15); color: hsl(var(--pv3-warning)); }
.pv3-queue__icon--info { background: hsl(var(--pv3-info) / 0.15); color: hsl(var(--pv3-info)); }
.pv3-queue__icon--success { background: hsl(var(--pv3-success) / 0.15); color: hsl(var(--pv3-success)); }
.pv3-queue__body { flex: 1; min-width: 0; }
.pv3-queue__title { font-size: 13px; font-weight: 500; margin: 0 0 2px; }
.pv3-queue__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 0; }

/* ============ Horizontal bars ============ */
.pv3-hbars { display: flex; flex-direction: column; gap: 14px; }
.pv3-hbar {
  display: grid;
  grid-template-columns: 90px 1fr 60px;
  gap: 12px;
  align-items: center;
  font-size: 12px;
}
.pv3-hbar__label { color: hsl(var(--pv3-muted-foreground)); }
.pv3-hbar__track {
  height: 8px;
  background: hsl(var(--pv3-accent));
  border-radius: 999px;
  overflow: hidden;
}
.pv3-hbar__fill {
  height: 100%;
  background: hsl(var(--pv3-primary));
  border-radius: 999px;
  transition: width 400ms ease;
}
.pv3-hbar__fill--success { background: hsl(var(--pv3-success)); }
.pv3-hbar__fill--warning { background: hsl(var(--pv3-warning)); }
.pv3-hbar__val { font-family: 'Geist Mono', monospace; font-size: 12px; font-weight: 500; text-align: right; }

/* ============ Alert — REMOVED Phase 10 (2026-06-19) ============ */
/* Migrated to UI tokens. See ALERT_BASE / ALERT_INFO / ALERT_OK / ALERT_WARN /
 * ALERT_ERROR + helper alertBox(). */

/* ============ Cloak URL pill (ads-paste affordance per portal_ui_spec) ============ */
.pv3-cloak-url {
  font-family: 'Geist Mono', monospace;
  font-size: 12px;
  padding: 4px 8px;
  background: hsl(var(--pv3-info) / 0.1);
  color: hsl(var(--pv3-info));
  border: 1px solid hsl(var(--pv3-info) / 0.25);
  border-radius: var(--pv3-radius);
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
  transition: background 120ms ease;
  max-width: 320px;
}
.pv3-cloak-url:hover { background: hsl(var(--pv3-info) / 0.18); }
.pv3-cloak-url__copy { opacity: 0.6; flex-shrink: 0; }
.pv3-cloak-url:hover .pv3-cloak-url__copy { opacity: 1; }

/* ============ Cmdk overlay ============ */
.pv3-cmdk-overlay {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: none;
  align-items: flex-start;
  justify-content: center;
  z-index: 100;
  padding-top: 12vh;
}
.pv3-cmdk-overlay.is-open { display: flex; }
.pv3-cmdk {
  width: 100%;
  max-width: 580px;
  background: hsl(var(--pv3-popover));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  box-shadow: var(--pv3-shadow-lg);
  overflow: hidden;
}
.pv3-cmdk__input-wrap {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
}
.pv3-cmdk__input {
  font: inherit; font-size: 15px;
  width: 100%;
  border: none;
  background: transparent;
  color: hsl(var(--pv3-foreground));
  outline: none;
}
.pv3-cmdk__input::placeholder { color: hsl(var(--pv3-muted-foreground)); }
.pv3-cmdk__list { max-height: 420px; overflow-y: auto; padding: 8px; }
.pv3-cmdk__group { padding: 4px 0; }
.pv3-cmdk__group-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: hsl(var(--pv3-muted-foreground));
  padding: 6px 10px;
  font-weight: 500;
}
.pv3-cmdk__item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-radius: var(--pv3-radius);
  cursor: pointer;
  font-size: 13px;
  transition: background 80ms ease;
  background: transparent;
  border: none;
  color: inherit;
  width: 100%;
  text-align: left;
}
.pv3-cmdk__item:hover, .pv3-cmdk__item.is-active { background: hsl(var(--pv3-accent)); }
.pv3-cmdk__item-icon { color: hsl(var(--pv3-muted-foreground)); flex-shrink: 0; }
.pv3-cmdk__item-label { flex: 1; }
.pv3-cmdk__footer {
  border-top: 1px solid hsl(var(--pv3-border));
  padding: 8px 14px;
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  background: hsl(var(--pv3-background) / 0.4);
}

/* ============ Popover ============ */
.pv3-popover {
  position: absolute;
  background: hsl(var(--pv3-popover));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  box-shadow: var(--pv3-shadow-lg);
  z-index: 50;
  min-width: 360px;
  overflow: hidden;
  display: none;
}
.pv3-popover.is-open { display: block; }
.pv3-popover__header {
  padding: 14px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.pv3-popover__title { font-size: 14px; font-weight: 600; margin: 0; }
.pv3-popover__list { max-height: 380px; overflow-y: auto; }
.pv3-popover__footer {
  padding: 8px 14px;
  border-top: 1px solid hsl(var(--pv3-border));
  text-align: center;
  background: hsl(var(--pv3-background) / 0.4);
}
.pv3-notif {
  padding: 12px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  display: flex;
  gap: 10px;
  cursor: pointer;
  transition: background 120ms ease;
}
.pv3-notif:hover { background: hsl(var(--pv3-accent)); }
.pv3-notif:last-child { border-bottom: none; }
.pv3-notif__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: hsl(var(--pv3-info));
  margin-top: 6px;
  flex-shrink: 0;
}
.pv3-notif__dot--warning { background: hsl(var(--pv3-warning)); }
.pv3-notif__dot--read { background: transparent; border: 1px solid hsl(var(--pv3-border)); }
.pv3-notif__body { flex: 1; min-width: 0; }
.pv3-notif__title { font-size: 13px; font-weight: 500; margin: 0; }
.pv3-notif__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 2px 0 0; }
.pv3-notif__time { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); margin: 4px 0 0; font-family: 'Geist Mono', monospace; }

/* ============ User menu ============ */
.pv3-user-menu {
  position: absolute;
  background: hsl(var(--pv3-popover));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  box-shadow: var(--pv3-shadow-lg);
  z-index: 50;
  min-width: 220px;
  padding: 4px;
  display: none;
}
.pv3-user-menu.is-open { display: block; }
.pv3-user-menu__header { padding: 8px 10px; }
.pv3-user-menu__name { font-weight: 500; font-size: 13px; }
.pv3-user-menu__email { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); }
.pv3-user-menu__sep { height: 1px; background: hsl(var(--pv3-border)); margin: 4px 0; }
.pv3-user-menu__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: var(--pv3-radius-sm);
  font-size: 13px;
  cursor: pointer;
  transition: background 80ms ease;
  background: transparent;
  border: none;
  color: inherit;
  width: 100%;
  text-align: left;
  text-decoration: none;
}
.pv3-user-menu__item:hover { background: hsl(var(--pv3-accent)); }
.pv3-user-menu__item-icon { color: hsl(var(--pv3-muted-foreground)); flex-shrink: 0; }
.pv3-user-menu__shortcut { margin-left: auto; font-size: 10px; color: hsl(var(--pv3-muted-foreground)); font-family: 'Geist Mono', monospace; }
.pv3-user-menu__item--danger { color: hsl(var(--pv3-destructive)); }
.pv3-user-menu__item--danger .pv3-user-menu__item-icon { color: hsl(var(--pv3-destructive)); }

/* ============ Toaster ============ */
.pv3-toaster {
  position: fixed;
  bottom: 20px; right: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
  pointer-events: none;
}
.pv3-toast {
  background: hsl(var(--pv3-popover));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  padding: 12px 14px;
  box-shadow: var(--pv3-shadow-lg);
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 280px;
  max-width: 380px;
  pointer-events: auto;
  animation: pv3-toast-in 200ms ease-out;
}
@keyframes pv3-toast-in {
  from { transform: translateX(20px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
.pv3-toast__icon { flex-shrink: 0; margin-top: 1px; }
.pv3-toast--success .pv3-toast__icon { color: hsl(var(--pv3-success)); }
.pv3-toast--info .pv3-toast__icon { color: hsl(var(--pv3-info)); }
.pv3-toast--warning .pv3-toast__icon { color: hsl(var(--pv3-warning)); }
.pv3-toast--destructive .pv3-toast__icon { color: hsl(var(--pv3-destructive)); }
.pv3-toast__body { flex: 1; min-width: 0; }
.pv3-toast__title { font-size: 13px; font-weight: 500; margin: 0; }
.pv3-toast__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 2px 0 0; }
.pv3-toast__close { background: transparent; border: none; color: hsl(var(--pv3-muted-foreground)); padding: 2px; cursor: pointer; }

/* ============ Inline tabs (segmented) ============ */
.pv3-tabs {
  display: flex;
  gap: 4px;
  background: hsl(var(--pv3-secondary));
  padding: 3px;
  border-radius: var(--pv3-radius);
  border: 1px solid hsl(var(--pv3-border));
}
.pv3-tabs__btn {
  background: transparent;
  border: none;
  color: hsl(var(--pv3-muted-foreground));
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 5px;
  transition: background 120ms ease, color 120ms ease;
  text-decoration: none;
}
.pv3-tabs__btn:hover { color: hsl(var(--pv3-foreground)); }
.pv3-tabs__btn.is-active { background: hsl(var(--pv3-background)); color: hsl(var(--pv3-foreground)); box-shadow: var(--pv3-shadow-sm); }

/* ============ Detail tabs — REMOVED Phase 10 (2026-06-19) ============ */
/* Migrated to UI tokens. See TAB_NAV / TAB_ITEM / TAB_ITEM_ACTIVE + helper
 * detailTabs() — now pill-style active state (font-semibold + bg-foreground/10). */

/* ============ Integration tile (linked card with hover state) ============ */
/* Sprint Tile Refactor (2026-06-18) — was inline-styled <a> with onmouseover/ */
/* onmouseout setting borderColor via JS. CSS hover is cleaner + no SSR JS. */
/* v2 polish (2026-06-18) — added 44px rounded icon container with bg tint */
/* so SVG icons match the visual weight emoji had. */
.pv3-tile { display: block; background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: 12px; padding: 22px; text-decoration: none; color: inherit; transition: border-color 150ms, background 150ms; }
.pv3-tile:hover { border-color: hsl(var(--pv3-primary)); background: hsl(var(--pv3-card) / 0.85); }
.pv3-tile__icon { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 12px; background: hsl(var(--pv3-primary) / 0.1); color: hsl(var(--pv3-foreground)); margin-bottom: 14px; transition: background 150ms; }
.pv3-tile:hover .pv3-tile__icon { background: hsl(var(--pv3-primary) / 0.18); }
.pv3-tile__icon svg { width: 22px; height: 22px; }
.pv3-tile__header { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 6px; }
.pv3-tile__title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.pv3-tile__sub { font-size: 13px; color: hsl(var(--pv3-muted-foreground)); margin-bottom: 14px; line-height: 1.45; }
.pv3-tile__action { color: hsl(var(--pv3-primary)); font-size: 12px; font-weight: 600; letter-spacing: 0.02em; }

/* ============ Table ============ */
.pv3-data-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  gap: 12px;
  flex-wrap: wrap;
}
.pv3-data-toolbar__left { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pv3-data-toolbar__right { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pv3-input {
  font: inherit;
  font-size: 13px;
  padding: 6px 10px;
  background: hsl(var(--pv3-background));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  color: hsl(var(--pv3-foreground));
  width: 100%;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.pv3-input:focus { outline: none; border-color: hsl(var(--pv3-ring) / 0.6); box-shadow: 0 0 0 3px hsl(var(--pv3-ring) / 0.15); }
.pv3-input::placeholder { color: hsl(var(--pv3-muted-foreground)); }
.pv3-input--sm { padding: 4px 8px; font-size: 12px; }
.pv3-input-with-icon { position: relative; }
.pv3-input-with-icon .pv3-input { padding-left: 30px; }
.pv3-input-with-icon__icon {
  position: absolute;
  left: 9px; top: 50%; transform: translateY(-50%);
  color: hsl(var(--pv3-muted-foreground));
  pointer-events: none;
}
.pv3-table-wrap { overflow-x: auto; }
.pv3-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.pv3-table thead th {
  text-align: left;
  font-weight: 500;
  color: hsl(var(--pv3-muted-foreground));
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 10px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  background: hsl(var(--pv3-background) / 0.4);
}
.pv3-table tbody td {
  padding: 12px 16px;
  border-bottom: 1px solid hsl(var(--pv3-border));
  vertical-align: middle;
}
.pv3-table tbody tr:last-child td { border-bottom: none; }
.pv3-table tbody tr { transition: background 120ms ease; }
.pv3-table tbody tr:hover { background: hsl(var(--pv3-accent) / 0.5); }
.pv3-table__id { font-family: 'Geist Mono', monospace; font-size: 12px; color: hsl(var(--pv3-muted-foreground)); }
.pv3-table__name { font-weight: 500; }
.pv3-table__name a:hover { text-decoration: underline; }

/* ============ Empty + skeleton ============ */
.pv3-empty {
  padding: 48px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
}
.pv3-empty__icon {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: hsl(var(--pv3-accent));
  display: grid; place-items: center;
  color: hsl(var(--pv3-muted-foreground));
}
.pv3-empty__title { font-size: 14px; font-weight: 500; margin: 4px 0 0; }
.pv3-empty__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 0; max-width: 320px; }
.pv3-skeleton {
  display: block;
  background: linear-gradient(90deg,
    hsl(var(--pv3-accent)) 0%,
    hsl(var(--pv3-accent) / 0.5) 40%,
    hsl(var(--pv3-accent)) 80%);
  background-size: 200% 100%;
  animation: pv3-shimmer 1.6s linear infinite;
  border-radius: var(--pv3-radius-sm);
  height: 12px;
  width: 100%;
}
.pv3-skeleton + .pv3-skeleton { margin-top: 8px; }
@keyframes pv3-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}


/* ============ Horizontal-scroll affordance ============ */
/* UI audit 2026-08-11 Phase 2 — wide tables already scroll inside      */
/* overflow-x:auto wrappers, but at mobile widths nothing signalled     */
/* that more columns exist. Lea Verou scrolling-shadows: cover layers   */
/* (background-attachment: local) slide with the content and hide the  */
/* edge shadows when that edge is fully scrolled into view.            */
.pv3-scroll-x {
  overflow-x: auto;
  background:
    linear-gradient(to right, hsl(var(--pv3-card)) 30%, hsl(var(--pv3-card) / 0)) left / 32px 100%,
    linear-gradient(to left, hsl(var(--pv3-card)) 30%, hsl(var(--pv3-card) / 0)) right / 32px 100%,
    radial-gradient(farthest-side at 0 50%, rgb(0 0 0 / 0.55), transparent) left / 14px 100%,
    radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / 0.55), transparent) right / 14px 100%;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
/* ============ Legacy SVG icon sizing guards ============ */
/* Legacy ui-* partials reference inline <svg class="ui-icon"> without
   intrinsic sizing. Outside layout_head.php the browser renders the SVG
   at its default size (huge). Force a sane default scoped to pv3. */
.pv3 .ui-icon { width: 16px; height: 16px; flex-shrink: 0; vertical-align: -3px; }
.pv3 .ui-alert .ui-icon,
.pv3 .ui-alert__icon { width: 16px; height: 16px; }
.pv3 svg[width][height] { /* explicit author sizes win — no-op rule */ }
.pv3 .ui-button .ui-icon,
.pv3 .ui-btn .ui-icon { width: 14px; height: 14px; }

/* Legacy metric strip / panel small touch-ups so wrapped partials don't
   look TOO out of place. Phase 5b will properly migrate each partial. */
.pv3-legacy-panel .ui-metric-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.pv3-legacy-panel .ui-metric { background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius); padding: 14px; display: flex; flex-direction: column; gap: 4px; }
.pv3-legacy-panel .ui-metric__label { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); text-transform: uppercase; letter-spacing: 0.04em; }
.pv3-legacy-panel .ui-metric__value { font-size: 22px; font-weight: 600; font-family: 'Geist Mono', monospace; }
.pv3-legacy-panel .ui-metric__meta { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); }
.pv3-legacy-panel .ui-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.pv3-legacy-panel .ui-toolbar__group { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pv3-legacy-panel .ui-panel { background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius-lg); padding: 18px; }
.pv3-legacy-panel .ui-panel + .ui-panel { margin-top: 14px; }
.pv3-legacy-panel .ui-section + .ui-section { margin-top: 14px; }

@media (max-width: 1024px) {
  .pv3-legacy-panel .ui-metric-strip { grid-template-columns: repeat(2, 1fr); }
}

/* ============ Legacy ui-* bridge inside .pv3 scope ============
   For surfaces that still ship legacy ui-* markup (partner-onboard
   wizard 6 steps, customer tab-settings, customer tab-health). Maps
   legacy classes to pv3 visual equivalents so partials don't need
   per-file rewrites for owner's "đồng bộ" ask. */

/* Sections + panels */
.pv3 .ui-section { display: block; }
.pv3 .ui-section + .ui-section { margin-top: 14px; }
.pv3 .ui-panel,
.pv3 .ui-panel--roomy {
  background: hsl(var(--pv3-card));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  padding: 18px;
}
.pv3 .ui-panel + .ui-panel { margin-top: 14px; }
.pv3 .ui-box {
  background: hsl(var(--pv3-secondary) / 0.4);
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  padding: 12px 14px;
}
.pv3 .ui-box--muted { background: hsl(var(--pv3-secondary) / 0.4); }

/* Toolbar (header rows in legacy panels) */
.pv3 .ui-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.pv3 .ui-toolbar__group {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pv3 .ui-toolbar strong, .pv3 .ui-toolbar__group strong { font-size: 14px; font-weight: 600; letter-spacing: -0.005em; }

/* Forms — fields + labels */
.pv3 .ui-form { display: flex; flex-direction: column; gap: 14px; }
.pv3 .ui-field { display: flex; flex-direction: column; gap: 4px; }
.pv3 .ui-label { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); font-weight: 400; }
.pv3 .ui-help { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); line-height: 1.55; margin: 0; }
.pv3 .ui-cell-sub { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); }
.pv3 .ui-cell-title { font-weight: 500; }
.pv3 .ui-cell-strong { font-weight: 500; font-size: 14px; }

/* Inputs (text, url, email, password, number, date) */
.pv3 .ui-input {
  font: inherit; font-size: 13px;
  padding: 6px 10px;
  background: hsl(var(--pv3-background));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  color: hsl(var(--pv3-foreground));
  width: 100%;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.pv3 .ui-input:focus { outline: none; border-color: hsl(var(--pv3-ring) / 0.6); box-shadow: 0 0 0 3px hsl(var(--pv3-ring) / 0.15); }
.pv3 .ui-input::placeholder { color: hsl(var(--pv3-muted-foreground)); }
.pv3 .ui-input--compact { padding: 4px 8px; font-size: 12px; }
.pv3 .ui-search-control { padding-left: 10px; }
.pv3 .ui-select { font: inherit; font-size: 13px; padding: 6px 10px; background: hsl(var(--pv3-background)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius); color: hsl(var(--pv3-foreground)); width: 100%; cursor: pointer; }
.pv3 .ui-textarea { font: inherit; font-size: 13px; padding: 8px 10px; background: hsl(var(--pv3-background)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius); color: hsl(var(--pv3-foreground)); width: 100%; min-height: 80px; }

/* Buttons */
.pv3 .ui-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-size: 13px; font-weight: 500;
  padding: 7px 12px;
  border-radius: var(--pv3-radius);
  border: 1px solid transparent;
  background: transparent;
  color: hsl(var(--pv3-foreground));
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
  white-space: nowrap;
  text-decoration: none;
}
.pv3 .ui-button:hover { background: hsl(var(--pv3-accent)); }
.pv3 .ui-button:disabled, .pv3 .ui-button[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }
.pv3 .ui-button--primary { background: hsl(var(--pv3-primary)); color: hsl(var(--pv3-primary-foreground)); border-color: hsl(var(--pv3-primary)); }
.pv3 .ui-button--primary:hover { background: hsl(var(--pv3-primary) / 0.9); }
.pv3 .ui-button--surface { background: hsl(var(--pv3-secondary)); border-color: hsl(var(--pv3-border)); }
.pv3 .ui-button--secondary { background: hsl(var(--pv3-secondary)); border-color: hsl(var(--pv3-border)); }
.pv3 .ui-button--danger { background: hsl(var(--pv3-destructive)); color: #fff; border-color: hsl(var(--pv3-destructive)); }
.pv3 .ui-button--sm { padding: 5px 9px; font-size: 12px; }
.pv3 .ui-button--icon { padding: 0; width: 32px; height: 32px; }
.pv3 .ui-icon-button { padding: 6px; }

/* Badges */
.pv3 .ui-badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 500;
  padding: 2px 8px;
  border-radius: 999px;
  background: hsl(var(--pv3-secondary)); color: hsl(var(--pv3-foreground));
  border: 1px solid hsl(var(--pv3-border));
  line-height: 1.4;
}
.pv3 .ui-badge--lg { padding: 4px 10px; font-size: 12px; }
.pv3 .ui-badge--success { background: hsl(var(--pv3-success) / 0.15); color: hsl(var(--pv3-success)); border-color: hsl(var(--pv3-success) / 0.25); }
.pv3 .ui-badge--warning { background: hsl(var(--pv3-warning) / 0.15); color: hsl(var(--pv3-warning)); border-color: hsl(var(--pv3-warning) / 0.25); }
.pv3 .ui-badge--danger { background: hsl(var(--pv3-destructive) / 0.15); color: hsl(var(--pv3-destructive)); border-color: hsl(var(--pv3-destructive) / 0.25); }
.pv3 .ui-badge--info { background: hsl(var(--pv3-info) / 0.15); color: hsl(var(--pv3-info)); border-color: hsl(var(--pv3-info) / 0.25); }
.pv3 .ui-status { /* legacy pulse-dot marker — visual hint only */ }

/* Alerts */
.pv3 .ui-alert {
  display: flex; gap: 12px; padding: 14px 18px;
  border-radius: var(--pv3-radius-md);
  border: 1px solid hsl(var(--pv3-border));
  background: hsl(var(--pv3-secondary) / 0.5);
  align-items: flex-start;
}
.pv3 .ui-alert--neutral { background: hsl(var(--pv3-secondary) / 0.5); }
.pv3 .ui-alert--info { background: hsl(var(--pv3-info) / 0.08); border-color: hsl(var(--pv3-info) / 0.3); }
.pv3 .ui-alert--warning { background: hsl(var(--pv3-warning) / 0.08); border-color: hsl(var(--pv3-warning) / 0.3); }
.pv3 .ui-alert--success { background: hsl(var(--pv3-success) / 0.08); border-color: hsl(var(--pv3-success) / 0.3); }
.pv3 .ui-alert--danger { background: hsl(var(--pv3-destructive) / 0.08); border-color: hsl(var(--pv3-destructive) / 0.3); }
.pv3 .ui-alert__icon { flex-shrink: 0; margin-top: 1px; }
.pv3 .ui-alert--info .ui-alert__icon { color: hsl(var(--pv3-info)); }
.pv3 .ui-alert--warning .ui-alert__icon { color: hsl(var(--pv3-warning)); }
.pv3 .ui-alert--success .ui-alert__icon { color: hsl(var(--pv3-success)); }
.pv3 .ui-alert--danger .ui-alert__icon { color: hsl(var(--pv3-destructive)); }
.pv3 .ui-alert__title { font-weight: 500; font-size: 13px; margin: 0 0 2px; display: block; }
.pv3 .ui-alert__desc { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 0; }
.pv3 .ui-alert__content { display: flex; flex-direction: column; gap: 2px; }

/* Tabs (legacy ui-tab-strip / ui-tabs) */
.pv3 .ui-tabs,
.pv3 .ui-tab-strip {
  display: flex; gap: 4px;
  background: hsl(var(--pv3-secondary));
  padding: 3px;
  border-radius: var(--pv3-radius);
  border: 1px solid hsl(var(--pv3-border));
  margin-bottom: 14px;
}
.pv3 .ui-tab,
.pv3 .ui-tab-button {
  background: transparent; border: none;
  color: hsl(var(--pv3-muted-foreground));
  padding: 5px 12px; font-size: 12px; font-weight: 500;
  border-radius: 5px;
  transition: background 120ms ease, color 120ms ease;
  cursor: pointer;
}
.pv3 .ui-tab:hover, .pv3 .ui-tab-button:hover { color: hsl(var(--pv3-foreground)); }
.pv3 .ui-tab.is-active,
.pv3 .ui-tab-button.is-active {
  background: hsl(var(--pv3-background));
  color: hsl(var(--pv3-foreground));
  box-shadow: var(--pv3-shadow-sm);
}

/* Grids (legacy ui-grid-primitive) */
.pv3 .ui-grid-primitive { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.pv3 .ui-grid-primitive--three { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 768px) {
  .pv3 .ui-grid-primitive,
  .pv3 .ui-grid-primitive--three { grid-template-columns: 1fr; }
}

/* Stacks (legacy ui-stack) */
.pv3 .ui-stack { display: flex; flex-direction: column; gap: 12px; }
.pv3 .ui-stack--sm { gap: 6px; }
.pv3 .ui-stack--lg { gap: 18px; }

/* Cluster (button rows) */
.pv3 .ui-cluster { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* Public-hero shell + tab strip from /report.php + auth pages */
.pv3 .ui-public-content { display: block; }
.pv3 .ui-public-hero { display: flex; justify-content: space-between; gap: 24px; padding: 0; margin-bottom: 16px; flex-wrap: wrap; }
.pv3 .ui-public-hero__copy { display: flex; flex-direction: column; gap: 6px; max-width: 720px; }
.pv3 .ui-public-hero__eyebrow { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 500; }
.pv3 .ui-public-hero__title { font-size: 22px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.pv3 .ui-public-hero__desc { font-size: 13px; color: hsl(var(--pv3-muted-foreground)); margin: 0; max-width: 640px; line-height: 1.55; }

/* Switch (legacy ui-switch) */
.pv3 .ui-switch { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 13px; }
.pv3 .ui-switch input[type="checkbox"] { accent-color: hsl(var(--pv3-info)); }

/* Radio (legacy ui-radio) */
.pv3 .ui-radio { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; padding: 8px 10px; border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius); transition: border-color 120ms ease, background 120ms ease; }
.pv3 .ui-radio:has(input:checked) { border-color: hsl(var(--pv3-info)); background: hsl(var(--pv3-info) / 0.06); }
.pv3 .ui-radio input[type="radio"] { accent-color: hsl(var(--pv3-info)); margin-top: 4px; }

/* Truncate (legacy ui-truncate) */
.pv3 .ui-truncate { display: inline-block; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

/* Tables (legacy ui-table) — full pv3 styling */
.pv3 .ui-table-wrap { overflow-x: auto; }
.pv3 .ui-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.pv3 .ui-table thead th { text-align: left; font-weight: 500; color: hsl(var(--pv3-muted-foreground)); font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; padding: 10px 16px; border-bottom: 1px solid hsl(var(--pv3-border)); background: hsl(var(--pv3-background) / 0.4); }
.pv3 .ui-table tbody td { padding: 12px 16px; border-bottom: 1px solid hsl(var(--pv3-border)); vertical-align: middle; }
.pv3 .ui-table tbody tr:last-child td { border-bottom: none; }
.pv3 .ui-table tbody tr:hover { background: hsl(var(--pv3-accent) / 0.5); }

/* Metric strip (legacy ui-metric-strip) */
.pv3 .ui-metric-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 14px 0; }
.pv3 .ui-metric { background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius-lg); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
.pv3 .ui-metric__label { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); text-transform: uppercase; letter-spacing: 0.04em; }
.pv3 .ui-metric__value { font-size: 22px; font-weight: 600; font-family: 'Geist Mono', monospace; }
.pv3 .ui-metric__meta { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); }

/* Chart panel (legacy ui-chart-panel) */
.pv3 .ui-chart-panel { background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius-lg); padding: 18px; }
.pv3 .ui-chart-panel__header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 12px; }
.pv3 .ui-chart-panel__title { display: flex; flex-direction: column; gap: 2px; }
.pv3 .ui-chart-panel__title strong { font-size: 14px; font-weight: 600; }

/* Onboard wizard layout (legacy ui-onboard-*) */
.pv3 .ui-onboard-summary { background: hsl(var(--pv3-card)); border: 1px solid hsl(var(--pv3-border)); border-radius: var(--pv3-radius-lg); padding: 16px; }
.pv3 .ui-onboard-nav-rail { display: flex; gap: 8px; align-items: center; padding: 12px 0; }
.pv3 .ui-onboard-step-list { display: flex; flex-direction: column; gap: 8px; }
.pv3 .ui-onboard-step { display: flex; gap: 10px; align-items: center; padding: 8px 10px; border-radius: var(--pv3-radius); }
.pv3 .ui-onboard-step__num { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: hsl(var(--pv3-secondary)); color: hsl(var(--pv3-muted-foreground)); font-size: 11px; font-weight: 600; flex-shrink: 0; }
.pv3 .ui-onboard-step.is-active { background: hsl(var(--pv3-accent)); }
.pv3 .ui-onboard-step.is-active .ui-onboard-step__num { background: hsl(var(--pv3-info)); color: #fff; }

/* Brand mark + avatar (legacy ui-brand-mark / ui-avatar) */
.pv3 .ui-brand-mark, .pv3 .ui-avatar { width: 32px; height: 32px; border-radius: 50%; background: hsl(var(--pv3-accent)); color: hsl(var(--pv3-foreground)); display: grid; place-items: center; font-weight: 600; font-size: 12px; flex-shrink: 0; }

/* Modal backdrop (legacy ui-modal-backdrop) */
.pv3 .ui-modal-backdrop { position: fixed; inset: 0; background: rgb(0 0 0 / 0.65); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; }
.pv3 .ui-modal-backdrop[hidden] { display: none !important; }

/* ============ Legacy panel passthrough ============ */
/* Other tabs (clients, reports, trackers, brand, billing, audit) still
   render via their existing partials in _partials/partner-portal/.
   Wrap them in .pv3-legacy-panel so internal ui-* classes inherit dark
   surface but legacy markup stays intact for Phase 2 incremental migration. */
.pv3-legacy-panel {
  background: hsl(var(--pv3-card));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  padding: 18px;
}
.pv3-legacy-panel .ui-section + .ui-section { margin-top: 16px; }

/* ============ Responsive ============ */
@media (max-width: 1024px) {
  .pv3-kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .pv3-grid-2, .pv3-grid-3 { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
  .pv3-shell { grid-template-columns: var(--pv3-sidebar-w-collapsed) 1fr; }
  .pv3-shell .pv3-sidebar { width: var(--pv3-sidebar-w-collapsed); }
  .pv3-shell.is-collapsed { grid-template-columns: 0 1fr; }
  .pv3-shell.is-collapsed .pv3-sidebar { width: 0; }
  .pv3-cmdk-trigger { min-width: auto; padding: 6px; }
  .pv3-cmdk-trigger__placeholder, .pv3-cmdk-trigger__kbd { display: none; }
  .pv3-page { padding: 16px; }
}

/* v3-portal-page */
/* 2026-06-10 — V2-Pro alignment: same dark surface family as /login + /register
   (auth_shell.php). Brand-aware accent retained so partner colour still drives
   active tabs + primary CTA — only the neutral surface tokens shifted. */
:root {
    --bg: #08090c;
    --card: #0e0f12;
    --card-2: #131418;
    --border: #232326;
    --border-soft: #1b1b1e;
    --text: #fafafa;
    --muted: #a4a4a8;
    --subtle: #71717a;
    --accent: var(--brand-primary, #60a5fa);
    --accent-soft: rgba(96,165,250,0.12);
    --green: #4ade80; --green-soft: rgba(74,222,128,0.12);
    --amber: #fbbf24; --red: #f87171; --red-soft: rgba(248,113,113,0.12);
    color-scheme: dark;
}
* { box-sizing: border-box; }
body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 14px/1.5 'Geist', 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-feature-settings: "cv11", "ss01", "ss03";
}
code, pre, .mono { font-family: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace; }
/* 2026-06-08 — match report.php 1280px so customer doesn't see two
   different content widths between portal.php and report.php. */
.wrap {
    max-width: 1280px;
    width: 100%;
    margin: 0 auto;
    padding: 32px 24px 60px;
    box-sizing: border-box;
    /* 2026-06-09 — explicit flex-grow so the wrap fills the body's flex
       column and pushes the footer to viewport bottom on short tabs.
       Overrides the generic `body > .wrap { flex: 1 0 auto }` from
       site_footer.php by being in the same <style> block (later source). */
    flex: 1 0 auto;
}
/* Phase 7 — portal header polish, mirrors the report.php batch-3 pass.
   Bigger H1, bottom-border separation. Brand-accent flows via PM-6 so
   partner themes apply automatically. */
header.portal-header {
    display: flex; justify-content: space-between; align-items: flex-end;
    gap: 16px; flex-wrap: wrap;
    margin-bottom: 28px;
    padding-bottom: 22px;
    border-bottom: 1px solid var(--border-soft, rgba(255,255,255,0.06));
}
.eyebrow {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 4px 11px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent);
    font-size: 11.5px; font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: none;
    margin-bottom: 12px;
}
.eyebrow::before {
    content: ''; width: 6px; height: 6px;
    border-radius: 50%; background: currentColor;
    box-shadow: 0 0 0 0 currentColor;
    animation: portal-status-pulse 2s infinite;
}
@keyframes portal-status-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in oklab, currentColor 45%, transparent); }
    70%  { box-shadow: 0 0 0 6px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}
.eyebrow.adv { background: rgba(251,191,36,0.12); color: var(--amber); border-color: rgba(251,191,36,0.30); }
.portal-expiry-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; margin-left: 10px; vertical-align: middle; text-transform: none; letter-spacing: 0; }
.portal-expiry-badge.info   { background: rgba(13,110,253,0.14); color: #80b6ff; }
.portal-expiry-badge.warn   { background: rgba(255,176,0,0.16); color: #ffd061; }
.portal-expiry-badge.danger { background: rgba(255,80,80,0.16); color: #ff8e8e; }
h1 {
    font-size: clamp(26px, 2.2vw + 14px, 34px);
    font-weight: 700;
    margin: 0 0 8px;
    letter-spacing: -0.02em;
    line-height: 1.15;
}
.lead { color: var(--muted); margin: 0; font-size: 14px; }
.btn {
    background: var(--accent);
    border: 0;
    color: #0a0a0a;
    padding: 0 16px;
    height: 38px;
    border-radius: 7px;
    font-weight: 500;
    font-size: 13.5px;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex; align-items: center; gap: 7px;
    transition: opacity .12s, background .12s, transform .08s;
}
.btn:hover { opacity: 0.92; }
.btn:active { transform: translateY(1px); }
.btn-outline {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
}
.btn-outline:hover {
    background: var(--card-2);
    border-color: var(--border-strong, color-mix(in oklab, var(--text) 14%, transparent));
}
.btn-danger { background: var(--red-soft); border: 1px solid var(--red); color: var(--red); }
.btn-danger:hover { background: var(--red); color: #fff; }
.card-box {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 22px 24px;
    margin-bottom: 16px;
    box-shadow: 0 1px 2px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.08);
}
.card-box h2 { font-size: 16px; margin: 0 0 4px; letter-spacing: -0.012em; font-weight: 600; }
.card-box p.sub { color: var(--muted); font-size: 12.5px; margin: 0 0 18px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 720px) { .form-grid { grid-template-columns: 1fr; } }
.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field.full { grid-column: 1 / -1; }
.form-field label { color: var(--muted); font-size: 12.5px; text-transform: none; letter-spacing: 0; font-weight: 500; }
.form-field input, .form-field select {
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0 12px;
    height: 38px;
    border-radius: 7px;
    font: inherit;
    font-size: 13.5px;
    transition: border-color .12s, box-shadow .12s;
}
.form-field input:focus, .form-field select:focus { outline: none; border-color: color-mix(in oklab, var(--accent) 60%, var(--border)); box-shadow: 0 0 0 3px var(--accent-soft); }
.form-field .hint { color: var(--subtle); font-size: 11.5px; font-style: italic; line-height: 1.5; }
.form-field .hint code { background: var(--card-2, rgba(255,255,255,0.05)); color: var(--fg); padding: 1px 5px; border-radius: 3px; font-style: normal; font-size: 11px; font-family: ui-monospace, Menlo, monospace; }
.form-field .hint b { color: var(--fg); font-style: normal; font-weight: 600; }

/* Admin-bypass read-only banner + Save-disabled treatment. */
.admin-bypass-banner {
    display: flex; align-items: flex-start; gap: 12px;
    margin: 0 0 22px;
    padding: 14px 18px;
    border-radius: 12px;
    background: color-mix(in oklab, #fbbf24 8%, var(--card, #16171b));
    border: 1px solid color-mix(in oklab, #fbbf24 32%, var(--border));
    color: var(--fg);
    font-size: 13px; line-height: 1.55;
}
.admin-bypass-ico { font-size: 20px; flex-shrink: 0; opacity: 0.9; line-height: 1.2; }
.admin-bypass-msg { flex: 1; }
.admin-bypass-msg strong { display: block; color: #fbbf24; margin-bottom: 4px; }
.admin-bypass-toggle {
    flex-shrink: 0; align-self: center;
    padding: 7px 14px; border-radius: 8px;
    background: rgba(251,191,36,0.16);
    border: 1px solid rgba(251,191,36,0.4);
    color: #fde68a; text-decoration: none;
    font-size: 12.5px; font-weight: 600;
    transition: background 120ms ease;
}
.admin-bypass-toggle:hover { background: rgba(251,191,36,0.28); }
/* Disable every input + Save button inside an admin-bypass body. The
   server-side gate stays the real guard; this just prevents the operator
   from typing and submitting only to get an authentication_required toast. */
body.admin-bypass .camp-box input,
body.admin-bypass .camp-box select,
body.admin-bypass .camp-box textarea,
body.admin-bypass .camp-box button[type="submit"] {
    pointer-events: none; opacity: 0.5; cursor: not-allowed;
}
body.admin-bypass .camp-box .form-actions::after {
    content: "Read-only — switch off admin bypass to edit";
    color: var(--subtle); font-size: 11.5px; font-style: italic;
}
.form-actions { margin-top: 16px; display: flex; gap: 10px; align-items: center; }
.status-msg { font-size: 12.5px; color: var(--muted); }
.status-msg.ok { color: var(--green); }
.status-msg.err { color: var(--red); }
.camp-list { display: flex; flex-direction: column; gap: 14px; }
.camp-box {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 20px 22px;
    min-width: 0;
    overflow-wrap: anywhere;
    box-shadow: 0 1px 2px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.08);
}
/* 2026-06-09 — long country ISO lists + long URLs were overflowing the
   camp-box panel by ~70px. Constrain inner code blocks so they wrap. */
.camp-box code, .camp-box pre { word-break: break-all; overflow-wrap: anywhere; max-width: 100%; }
.camp-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border-soft); }
.camp-head h3 { font-size: 16px; margin: 0; }
.camp-head code { background: var(--card-2); padding: 2px 8px; border-radius: 4px; font-size: 11.5px; color: var(--muted); margin-left: 8px; }
.divider { height: 1px; background: var(--border-soft); margin: 18px 0; }
.pwd-area { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.pwd-area .form-field { flex: 1; min-width: 200px; }
footer { margin-top: 40px; padding-top: 18px; border-top: 1px solid var(--border-soft); color: var(--subtle); font-size: 11.5px; text-align: center; }

/* Phase E (2026-05-26) — Customer Portal tab chrome. */
.portal-tabs {
    display: flex; gap: 4px;
    margin: 0 0 22px;
    padding: 4px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    flex-wrap: wrap;
}
.portal-tab {
    flex: 1; min-width: 110px;
    background: transparent; border: 0;
    color: var(--muted);
    padding: 8px 14px; border-radius: 8px;
    font: inherit; font-size: 13px; font-weight: 500;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.portal-tab:hover { color: var(--text); background: var(--card-2); }
.portal-tab.is-active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
    box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 25%, transparent);
}
.portal-tab-panel { display: none; }
/* 2026-06-09 — uniform tab content width. .wrap rule above already
   sets width:100% + max-width:1280px + flex:1 0 auto. Just force
   every direct child panel to fill the wrap horizontally so tabs
   don't visually snap between Report (long) → Share (form-shaped). */
.wrap > .ui-section,
.wrap > .portal-tab-panel,
.wrap > [data-tab-panel],
.wrap > .portal-tracker-sub {
    width: 100%;
    box-sizing: border-box;
}
.portal-tab-panel.is-active { display: block; }

/* 2026-06-04 — right-rail aside removed; tab panels render full-width. */

/* Read-only viewer treatment — same shape as admin-bypass but with a
   blue (informational) banner instead of amber (operator override).
   Share tab inputs are EXEMPT — viewer can still mint partner links. */
body.viewer-mode .camp-box input,
body.viewer-mode .camp-box select,
body.viewer-mode .camp-box textarea,
body.viewer-mode .camp-box button[type="submit"],
body.viewer-mode .camp-box .btn-toggle-status,
body.viewer-mode .pwd-area input,
body.viewer-mode .pwd-area button[type="submit"] {
    pointer-events: none; opacity: 0.55; cursor: not-allowed;
}
.viewer-banner {
    display: flex; align-items: flex-start; gap: 12px;
    margin: 0 0 22px;
    padding: 14px 18px;
    border-radius: 12px;
    background: var(--accent-soft);
    border: 1px solid color-mix(in oklab, var(--accent) 32%, var(--border));
    font-size: 13px; line-height: 1.55;
}
.viewer-banner-ico { font-size: 20px; flex-shrink: 0; opacity: 0.9; }
.viewer-banner strong { color: var(--accent); display: block; margin-bottom: 3px; }

/* Share tab */
.share-list { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.share-row {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 12px 14px;
    background: var(--card-2); border: 1px solid var(--border);
    border-radius: 12px;
    flex-wrap: wrap;
}
.share-row-info { flex: 1; min-width: 220px; }
.share-row-info .share-label { font-weight: 600; font-size: 13.5px; margin-bottom: 4px; }
.share-row-info code { font-size: 11.5px; background: var(--bg); padding: 2px 7px; border-radius: 4px; word-break: break-all; color: var(--muted); }
.share-row-meta { color: var(--subtle); font-size: 11.5px; margin-top: 4px; }
.share-row-actions { display: flex; gap: 8px; align-items: center; }
.share-empty {
    text-align: center; padding: 28px 18px;
    color: var(--muted);
    background: var(--card-2);
    border: 1px dashed var(--border);
    border-radius: 12px;
    font-size: 13px;
}
.share-create-form {
    display: grid; grid-template-columns: 2fr 1fr auto; gap: 10px; align-items: end;
    margin-top: 8px;
}
@media (max-width: 720px) { .share-create-form { grid-template-columns: 1fr; } }

/* Phase E (2026-05-26) — routing preview block, buyer-language card at
   the top of each campaign in Settings. Same shape/colour palette as
   admin campsettings Targeting preview for visual consistency. */
.routing-preview {
    margin: 0 0 16px;
    padding: 12px 14px;
    background: var(--card-2);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.routing-preview-title {
    font-size: 11.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--subtle);
    margin-bottom: 8px;
    display: inline-flex; align-items: center; gap: 6px;
}
.routing-preview-list {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: 8px;
}
.routing-preview-list li {
    display: flex; align-items: flex-start; gap: 10px;
    font-size: 13px; line-height: 1.5; color: var(--text);
}
.rp-tag {
    flex: 0 0 auto;
    display: inline-block;
    min-width: 110px; text-align: center;
    padding: 3px 8px; border-radius: 4px;
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.04em;
}
.rp-tag-money { background: var(--green-soft); color: var(--green); border: 1px solid color-mix(in oklab, var(--green) 30%, transparent); }
.rp-tag-safe  { background: var(--accent-soft); color: var(--accent); border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent); }
.rp-tag-check { background: rgba(251,191,36,0.12); color: var(--amber); border: 1px solid color-mix(in oklab, var(--amber) 30%, transparent); }
.rp-desc { flex: 1; min-width: 0; color: var(--muted); }
.rp-url {
    display: inline-block; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis;
    vertical-align: bottom;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px; color: var(--text); word-break: break-all;
}
@media (max-width: 640px) {
    .routing-preview-list li { flex-direction: column; gap: 4px; }
    .rp-tag { min-width: 0; align-self: flex-start; }
}

/* Phase H2 (2026-05-26) — Domains tab. Customer self-service for
   traffic domains. Status badges mirror the readiness state machine
   from portal_domain_api: needs_dns / waiting_https / ready / error. */
.domain-add-block { margin: 6px 0 18px; padding: 14px 16px; background: var(--card-2); border: 1px solid var(--border); border-radius: 12px; }
.domain-add-form { display: grid; grid-template-columns: 2fr auto; gap: 12px; align-items: end; }
@media (max-width: 640px) { .domain-add-form { grid-template-columns: 1fr; } }
.domain-dns-instructions {
    margin: 0 0 18px;
    padding: 14px 16px;
    background: rgba(96,165,250,0.06);
    border: 1px solid color-mix(in oklab, var(--accent) 28%, var(--border));
    border-radius: 12px;
}
.domain-dns-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 8px; }
@media (max-width: 640px) { .domain-dns-grid { grid-template-columns: 1fr; } }
.domain-dns-card { background: var(--card); border: 1px solid var(--border-soft); border-radius: 8px; padding: 10px 12px; }
.domain-dns-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--subtle); margin-bottom: 6px; }
.domain-dns-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 12.5px; }
.domain-dns-row .k { display: inline-block; width: 56px; color: var(--muted); font-size: 11.5px; }
.domain-dns-row code { flex: 1; background: var(--bg); padding: 4px 8px; border-radius: 4px; font-size: 11.5px; color: var(--text); word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.domain-dns-row .btn-copy { padding: 3px 9px; font-size: 11px; flex-shrink: 0; }
.domain-list { display: flex; flex-direction: column; gap: 10px; }
.domain-empty { text-align: center; padding: 28px 18px; color: var(--muted); background: var(--card-2); border: 1px dashed var(--border); border-radius: 12px; font-size: 13px; }
.domain-row {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 12px 14px;
    background: var(--card-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    flex-wrap: wrap;
}
.domain-row-info { flex: 1; min-width: 220px; }
.domain-row-info .domain-name { font-weight: 600; font-size: 14px; margin-bottom: 4px; display: inline-flex; align-items: center; gap: 8px; }
.domain-row-info code { font-size: 12px; background: var(--bg); padding: 2px 7px; border-radius: 4px; color: var(--muted); }
.domain-row-meta { color: var(--subtle); font-size: 11.5px; margin-top: 6px; line-height: 1.55; }
.domain-row-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.domain-status {
    display: inline-block; padding: 3px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.04em;
}
.domain-status.needs_dns      { background: rgba(245,158,11,0.14); color: var(--amber); border: 1px solid color-mix(in oklab, var(--amber) 30%, transparent); }
.domain-status.waiting_https  { background: rgba(96,165,250,0.14); color: var(--accent); border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent); }
.domain-status.ready          { background: var(--green-soft); color: var(--green); border: 1px solid color-mix(in oklab, var(--green) 30%, transparent); }
.domain-status.error          { background: var(--red-soft); color: var(--red); border: 1px solid color-mix(in oklab, var(--red) 30%, transparent); }

/* Guide tab — flat help content */
.guide-section { margin-top: 16px; }
.guide-section h3 { font-size: 14px; color: var(--text); margin: 0 0 6px; }
.guide-section p, .guide-section li { color: var(--muted); font-size: 13px; line-height: 1.65; }
.guide-section ul { margin: 6px 0 16px; padding-left: 20px; }
.guide-section code { background: var(--card-2); padding: 1px 6px; border-radius: 4px; font-size: 12px; color: var(--text); }

/* v3-portal */
/**
 * Customer Portal v3 — customer-specific additions on top of
 * partner-portal-v3/styles.css (shared design tokens + components).
 *
 * Loaded AFTER /partial/partner-portal-v3/styles.css. All new classes
 * prefixed `.pv3-cu-*` to keep customer surface decoupled.
 */

/* ===== Project card (sidebar header) — gradient logo ===== */
.pv3-cu-project-logo {
  width: 32px; height: 32px;
  border-radius: var(--pv3-radius);
  display: grid; place-items: center;
  font-weight: 700; font-size: 13px;
  color: #fff;
  background: linear-gradient(135deg, hsl(28 95% 60%), hsl(348 95% 60%));
  flex-shrink: 0;
}

/* ===== Tracker hero — customer's primary surface ===== */
.pv3-cu-tracker-hero {
  background: linear-gradient(135deg, hsl(var(--pv3-card)), hsl(240 8% 7%));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius-lg);
  padding: 22px 26px;
  margin-bottom: 16px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px;
  align-items: center;
}
.pv3-cu-tracker-hero__title { font-size: 16px; font-weight: 600; margin: 0 0 6px; }
.pv3-cu-tracker-hero__meta { font-size: 12px; color: hsl(var(--pv3-muted-foreground)); margin: 0; }
.pv3-cu-tracker-hero__urls { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.pv3-cu-url-row { display: flex; align-items: center; gap: 10px; }
.pv3-cu-url-row__label {
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  width: 72px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 500;
  flex-shrink: 0;
}
.pv3-cu-url-row__value {
  flex: 1;
  background: hsl(var(--pv3-background));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  padding: 8px 12px;
  font-family: 'Geist Mono', monospace;
  font-size: 12px;
  color: hsl(var(--pv3-foreground));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.pv3-cu-url-row__value.is-cloak {
  background: hsl(var(--pv3-info) / 0.08);
  border-color: hsl(var(--pv3-info) / 0.3);
  color: hsl(var(--pv3-info));
}
.pv3-cu-url-row__value.is-empty {
  color: hsl(var(--pv3-muted-foreground));
  font-style: italic;
}
.pv3-cu-url-row__copy {
  padding: 6px 10px;
  font-size: 11px;
  background: hsl(var(--pv3-secondary));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  color: hsl(var(--pv3-muted-foreground));
  cursor: pointer;
  font-family: 'Geist Mono', monospace;
  white-space: nowrap;
}
.pv3-cu-url-row__copy:hover {
  background: hsl(var(--pv3-accent));
  color: hsl(var(--pv3-foreground));
}
.pv3-cu-url-row__copy:disabled { opacity: 0.4; cursor: default; pointer-events: none; }

.pv3-cu-tracker-hero__side {
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
}
.pv3-cu-tracker-hero__status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  background: hsl(var(--pv3-success) / 0.15);
  color: hsl(var(--pv3-success));
  border: 1px solid hsl(var(--pv3-success) / 0.3);
  border-radius: 999px;
  font-size: 12px; font-weight: 500;
  white-space: nowrap;
}
.pv3-cu-tracker-hero__status--warning {
  background: hsl(var(--pv3-warning) / 0.15);
  color: hsl(var(--pv3-warning));
  border-color: hsl(var(--pv3-warning) / 0.3);
}
.pv3-cu-tracker-hero__status--info {
  background: hsl(var(--pv3-info) / 0.15);
  color: hsl(var(--pv3-info));
  border-color: hsl(var(--pv3-info) / 0.3);
}

/* ===== Live check probe strip ===== */
.pv3-cu-probe-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.pv3-cu-probe {
  background: hsl(var(--pv3-card));
  border: 1px solid hsl(var(--pv3-border));
  border-radius: var(--pv3-radius);
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.pv3-cu-probe__label {
  font-size: 11px;
  color: hsl(var(--pv3-muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 500;
}
.pv3-cu-probe__verdict { font-size: 16px; font-weight: 600; font-family: 'Geist Mono', monospace; }
.pv3-cu-probe__verdict--money { color: hsl(var(--pv3-success)); }
.pv3-cu-probe__verdict--safe { color: hsl(var(--pv3-info)); }
.pv3-cu-probe__verdict--block { color: hsl(var(--pv3-destructive)); }
.pv3-cu-probe__verdict--unknown { color: hsl(var(--pv3-muted-foreground)); }
.pv3-cu-probe__meta { font-size: 11px; color: hsl(var(--pv3-muted-foreground)); font-family: 'Geist Mono', monospace; }

@media (max-width: 1024px) {
  .pv3-cu-tracker-hero { grid-template-columns: 1fr; }
  .pv3-cu-tracker-hero__side { align-items: flex-start; }
  .pv3-cu-probe-strip { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .pv3-cu-probe-strip { grid-template-columns: 1fr; }
  .pv3-cu-url-row { flex-wrap: wrap; }
  .pv3-cu-url-row__label { width: 100%; }
}

@media (max-width: 767.98px) {
  /* Owner 2026-06-25 — bump selector specificity to (0,2,0) to override the
   * legacy "(max-width:768px)" block in v3-css.ts which collapses width to
   * 56px. Both selectors target .pv3-shell .pv3-sidebar so source order
   * decides; mobile-sidebar.ts is appended LAST in src/index.ts. */
  .pv3-shell, .pv3-shell.is-collapsed {
    grid-template-columns: 1fr;
  }
  .pv3-shell .pv3-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 200ms ease;
    z-index: 60;
    box-shadow: 0 0 0 1px hsl(var(--pv3-sidebar-border)), 4px 0 24px rgba(0,0,0,0.4);
  }
  body:has(#pv3-sidebar-toggle:checked) .pv3-shell .pv3-sidebar {
    transform: translateX(0);
  }
  .pv3-sidebar-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 55;
    display: none;
    cursor: pointer;
  }
  body:has(#pv3-sidebar-toggle:checked) .pv3-sidebar-overlay {
    display: block;
  }
  .pv3-mobile-hamburger {
    position: fixed;
    top: 10px;
    left: 12px;
    z-index: 70;
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--pv3-radius);
    border: 1px solid hsl(var(--pv3-border));
    background: hsl(var(--pv3-card));
    color: hsl(var(--pv3-foreground));
    cursor: pointer;
  }
  .pv3-mobile-hamburger:hover {
    background: hsl(var(--pv3-muted) / 0.4);
  }
  .pv3-topbar { padding-left: 56px; }
}
@media (min-width: 768px) {
  .pv3-mobile-hamburger,
  .pv3-sidebar-overlay,
  #pv3-sidebar-toggle { display: none; }
}

/* Force dark popup surface on every native <select> in the app.
   INPUT_BASE + SELECT_BASE tokens already carry [color-scheme:dark]
   inline; this covers the remaining .pv3-input + raw <select> paths
   without duplicating the token. Safe app-wide because the whole
   app is dark-themed (--pv3-background locked at 240 12% 4%). */
select {
  color-scheme: dark;
}
/* Explicit option rendering — some UAs (older Chromium, Firefox on
   certain Linux/Windows) ignore color-scheme and paint the popup
   with a light system surface, then the option text (inherited
   white from parent) becomes white-on-white. Setting background +
   color on <option> directly is the reliable fallback.

   Uses --pv3-popover (240 8% 8%) NOT --pv3-background (240 12% 4%)
   — popover token is the canonical surface for floating popups per
   the token registry at v3-css.ts:24. Slightly lighter than base
   gives visual separation when the dropdown opens over an already
   dark card. */
select option {
  background: hsl(var(--pv3-popover));
  color: hsl(var(--pv3-popover-foreground));
}
/* Textarea has the same white-text token but no popup — cover for
   consistency with color-scheme so native scrollbar + resize handle
   pick the dark rendering path. */
textarea.pv3-input,
textarea.ui-textarea {
  color-scheme: dark;
}

/* --- Audit follow-ups (2026-07-05, code-reviewer sweep) --- */

/* Q1 [MED] Portal-page forms (v3-css.ts:1306) define .form-field input
   without color-scheme, so <input type="date"> renders the native
   calendar picker on a light system surface. DATE_INPUT token in
   ui-tokens.ts fixes this for SSR routes, but portal-page forms build
   markup manually. Cover here since v3-css.ts is at hard block. */
.form-field input[type="date"] {
  color-scheme: dark;
}

/* Q3 [LOW] .pv3-text-muted is referenced by routes (portal.ts:337 +
   auth/forms.ts) but never defined in v3-css.ts — the styled element
   silently inherits parent color today. Define here mapping to the
   existing muted-foreground token so contributors don't clean it up
   as dead markup. */
.pv3-text-muted {
  color: hsl(var(--pv3-muted-foreground));
}
