/* Browsa dashboard: design tokens inherited from index.html
   (the marketing landing) so the brand is consistent across both
   screens. Navy + emerald, JetBrains for code, Plus Jakarta for body. */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

:root {
  /* ── Vercel-harvested design tokens 2026-06-08 ──────────────────
     Captured live via getComputedStyle on vercel.com dashboard
     (signed-in dark theme). Two-tone canvas, single muted text
     color, 6px radius everywhere, borders implemented as inset
     box-shadows. See vercel-design-tokens.md for the full harvest. */
  --vercel-bg:           #000000;  /* page canvas */
  --vercel-surface:      #0a0a0a;  /* cards, inputs, sidebar bg */
  --vercel-elevated:     #1a1a1a;  /* popover, inline-code bg */
  --vercel-hover:        #1f1f1f;  /* nav hover, sidebar active */
  --vercel-pressed:      #292929;  /* dividers, deeper hover */
  --vercel-text:         #ededed;  /* primary text/headings */
  --vercel-muted:        #a1a1a1;  /* one muted tone — Vercel uses ONE */
  --vercel-disabled:     #7d7d7d;
  --vercel-border:       #1f1f1f;  /* default hairline */
  --vercel-border-strong:#2e2e2e;  /* button outlines */
  --vercel-focus: 0 0 0 1px #ffffff82, 0 0 0 4px #ffffff3d;
  --vercel-shadow-border: 0 0 0 1px #ffffff25, 0 1px 1px #00000005, 0 4px 8px #0000000a;

  /* ── Brand identity layer ──────────────────────────────────────
     We adopt Vercel's discipline (canvas + spacing + radius) but
     keep the emerald brand accent so the primary CTA
     and active states still read as Browsa, not "Vercel". */
  --emerald: #10b981;
  --emerald-2: #34d399;
  --emerald-hover: #0d9668;
  --emerald-glow: rgba(16,185,129,0.15);

  /* ── Map existing --navy-* tokens to the Vercel scale so all
        existing rules (cards, sidebars, inputs, modals, tables,
        webhooks, playground, account, …) adopt the new palette
        in one shot. Touching the tokens here means every selector
        that referenced --navy-700 etc. now reads Vercel-grade dark
        without the audit-flagged blue cast. */
  --navy-900: var(--vercel-bg);        /* page canvas → #000 */
  --navy-800: var(--vercel-surface);   /* cards/inputs → #0a0a0a */
  --navy-700: var(--vercel-elevated);  /* hover/secondary → #1a1a1a */
  --navy-600: var(--vercel-hover);     /* selected row → #1f1f1f */
  --navy-500: var(--vercel-pressed);   /* dividers → #292929 */
  --navy-400: var(--vercel-border-strong);

  --text:       var(--vercel-text);
  --text-muted: var(--vercel-muted);
  /* --text-dim collapsed onto the same muted tone — Vercel uses ONE
     muted tone everywhere and lets weight/size carry the hierarchy
     instead of three shades of gray (design audit 2026-06-08). */
  --text-dim:   var(--vercel-muted);

  --border:       var(--vercel-border);
  --border-light: var(--vercel-border-strong);

  --red: #ef4444;
  --amber: #f59e0b;
  --max-w: 1200px;

  /* Unified radius scale — Vercel uses 6px everywhere; 4px for
     inline code; full-pill for status dots. Audit-recommended
     collapse from our 4/8/10/12/14 mess. */
  --radius-sm: 4px;
  --radius:    6px;
  --radius-lg: 8px;
}

/* Global :focus-visible — keyboard-only focus ring. The pre-existing
   `outline:none` on inputs (plus an emerald glow only on text inputs)
   left buttons, links, nav items, model selectors, and template chips
   with NO visible focus state at all. Without this, keyboard users
   cannot see where focus is — WCAG 2.4.7 violation.
   Audit: 2026-06-08 a11y review. */
*:focus { outline: none; }
/* Vercel's double-layered focus ring (1px white-50% + 4px white-24%)
   — reads on both dark surfaces and bright CTAs without recoloring,
   and removes one source of emerald-overuse the audit flagged. */
*:focus-visible {
  outline: none;
  box-shadow: var(--vercel-focus);
  border-radius: inherit;
}
/* Programmatic-focus targets — headings with tabindex="-1" are focused
   by JS on view change so screen readers announce the new page. They are
   never reached by keyboard (not in the tab order), so they must NOT
   paint the keyboard focus ring; otherwise a big white box appears around
   the page title (e.g. "Playground") after every nav click. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
  outline: none;
  box-shadow: none;
}

/* Visually-hidden but available to screen readers. Used where we
   want to keep a heading semantically but the visual layout already
   communicates the same thing (e.g. dash-header h1 + card h2 with
   identical text reads as duplicated to sighted users). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip-link — bypass nav for keyboard users (WCAG 2.4.1). Hidden until
   focused; jumps the user past the sidebar's 11 nav items straight to
   the dashboard heading. */
.skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  background: var(--emerald);
  color: #fff;
  padding: 8px 12px;
  text-decoration: none;
  font-weight: 600;
  border-radius: 6px;
  z-index: 9999;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 8px; }

html { scroll-behavior: smooth; }

/* Font-family vars — Geist is Vercel's open-source UI font. Mono pairs
   with Geist Mono. Loaded from Google Fonts in <head>. All UI text
   below resolves through these vars; never re-declare 'Geist' inline. */
:root {
  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, SFMono-Regular,
               Menlo, Monaco, Consolas, "Liberation Mono", monospace;
}

body {
  /* Vercel baseline: 14px / 1.5 / -0.01em — measured live on their
     dashboard <main>. Geist + tight tracking is what makes the UI
     feel like a developer tool, not a marketing page. */
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  font-weight: 400;
  background: var(--vercel-bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
code, .mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  font-feature-settings: "ss01", "cv11";
}

/* ============ NAV ============ */
.app-nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
/* Auth-screen mode: hide the full marketing nav (Vercel pattern — the
   sign-in page should not be cluttered with Home / Sign in / Get
   started chrome). A small "Browsa" word-mark anchored top-left is
   injected by renderAuth() as .auth-corner-logo so the user still has
   one click back to the marketing site. */
body.is-auth > .app-nav { display: none !important; }
/* Absolute, not fixed: on a phone the sign-up page scrolls, and a fixed
   logo slid over the form fields. */
.auth-corner-logo {
  position: absolute;
  top: 28px;
  left: 32px;
  z-index: 60;
  color: var(--vercel-text);
  font-weight: 600;
  font-size: 17px;
  text-decoration: none;
  letter-spacing: -0.02em;
  border-radius: 6px;
  transition: opacity 150ms ease;
}
.auth-corner-logo:hover { opacity: 0.8; }
@media (max-width: 640px) { .auth-corner-logo { top: 20px; left: 20px; font-size: 16px; } }
.nav-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 16px 24px;
  display: flex; align-items: center; justify-content: space-between;
}
.logo {
  font-weight: 700; font-size: 17px;
  color: var(--text); text-decoration: none;
  display: flex; align-items: center; gap: 8px;
}
.logo .slash { color: var(--text-dim); font-weight: 400; }
.logo .accent { color: var(--text); font-weight: 600; }  /* Vercel-style: brand color stays out of the logo */
.nav-right { display: flex; align-items: center; gap: 12px; min-width: 0; }
@media (max-width: 560px) {
  .app-nav > div { padding-inline: 16px; }
  .nav-right { gap: 8px; }
  /* The signed-in email is in the dashboard's Account page; on a phone
     it pushed Sign out off screen. */
  .nav-user { display: none; }
}
.nav-link {
  color: var(--text-muted); text-decoration: none; font-size: 14px;
  font-weight: 500;
}
.nav-link:hover { color: var(--text); }
.nav-user {
  color: var(--text-muted);
  font-size: 13px;
  padding: 4px 8px;
  background: var(--navy-700);
  border-radius: 6px;
  border: 1px solid var(--border);
}

/* ============ BUTTONS — Vercel pattern ============
   Primary: white-on-black, 40px tall, 6px radius, weight 500.
            This is THE move — replaces the emerald CTA with the
            highest-contrast button in the industry. Brand emerald
            still lives in the logo + active-state highlights.
   Secondary: outlined via inset shadow, transparent bg.
   Ghost: same as secondary but no outline until hover.
   All buttons use Vercel's box-shadow-as-border so the outline
   can animate on hover without layout shift. */
.btn-primary, .btn-ghost, .btn-secondary, .btn-icon {
  font-family: inherit;
  font-weight: 500;
  font-size: 14px;
  letter-spacing: -0.01em;
  border-radius: var(--radius);
  border: none;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, box-shadow 150ms ease, filter 150ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-decoration: none;
  white-space: nowrap;
  height: 40px;
  padding: 0 12px;
  line-height: 1;
}
.btn-primary {
  background: var(--vercel-text);  /* #ededed — Vercel's signature white */
  color: var(--vercel-bg);
}
.btn-primary:hover { filter: brightness(0.94); }
.btn-primary:disabled {
  background: var(--vercel-elevated);
  color: var(--vercel-disabled);
  cursor: not-allowed;
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
}
.btn-ghost:hover {
  background: var(--vercel-elevated);
  color: var(--vercel-text);
}

.btn-secondary {
  background: var(--vercel-surface);
  color: var(--vercel-text);
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
}
.btn-secondary:hover { background: var(--vercel-elevated); }

.btn-full { width: 100%; padding: 12px 14px; font-size: 15px; }
.btn-danger {
  background: transparent;
  color: var(--red);
  padding: 4px 8px;
  border: 1px solid transparent;
}
.btn-danger:hover { background: rgba(239, 68, 68, 0.1); border-color: rgba(239, 68, 68, 0.3); }
.icon-btn {
  padding: 6px 10px;
  font-size: 16px;
  line-height: 1;
}

/* ============ AUTH SCREEN ============ */
main {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.auth-screen {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 104px 24px 64px;  /* room for the top-left corner logo */
}
/* Vercel-style auth: no card chrome. The form sits directly on the
   canvas with a large heading on top. Was a navy card with rounded
   corners before — restyled 2026-06-10 to match the dashboard's
   Vercel-grade language across the whole signed-out journey. */
.auth-card {
  width: 100%;
  max-width: 400px;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  flex-shrink: 0;
}

/* Inline form hints (e.g. password rules under the password field).
   Smaller, dimmer than the label — feels like a tooltip baked into
   the form rather than a separate paragraph. */
.field-hint {
  font-size: 11.5px;
  color: var(--text-dim);
  margin-top: 2px;
}
.field-hint[hidden] { display: none !important; }

/* Legal consent line below the submit button on signup. Stripe/Linear
   pattern — no checkbox, accepting the form constitutes consent. */
.auth-legal {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
  text-align: center;
  margin-top: 4px;
}
.auth-legal[hidden] { display: none !important; }
.auth-legal a {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.auth-legal a:hover { color: var(--text); }

.auth-title {
  /* Vercel-grade — large headline on the canvas, no card chrome. */
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
  margin-bottom: 8px;
  color: var(--vercel-text);
  text-wrap: balance;
}
.auth-subtitle {
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1.55;
  margin-bottom: 28px;
  text-wrap: pretty;
}
.auth-subtitle:empty { display: none; }
@media (max-width: 640px) { .auth-title { font-size: 26px; } }
.auth-form { display: flex; flex-direction: column; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field[hidden] { display: none !important; }
.field > span {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
}
.field input {
  font-family: inherit;
  background: var(--navy-800);
  border: 1px solid var(--border-light);
  color: var(--text);
  border-radius: 8px;
  padding: 11px 14px;
  font-size: 15px;
  transition: border-color 150ms;
}
.field input:focus {
  /* Vercel input focus — white border + double-layered white halo. */
  outline: none;
  border-color: var(--vercel-text);
  box-shadow: var(--vercel-focus);
}
.form-error {
  color: var(--red);
  font-size: 13px;
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.2);
  padding: 10px 12px;
  border-radius: 8px;
}
.form-success {
  color: var(--emerald-2);
  font-size: 13px;
  background: var(--emerald-glow);
  border: 1px solid rgba(16,185,129,0.35);
  padding: 10px 12px;
  border-radius: 8px;
  line-height: 1.5;
}
.auth-email {
  color: var(--emerald-2);
  font-weight: 600;
}
.auth-forgot {
  text-align: center;
  margin-top: 10px;
  font-size: 13px;
}
.auth-forgot a {
  color: var(--text-muted); text-decoration: none;
}
.auth-forgot a:hover { color: var(--text); text-decoration: underline; }
.auth-foot {
  margin-top: 18px;
  text-align: center;
  color: var(--text-muted);
  font-size: 14px;
}
.auth-foot a {
  /* Vercel link pattern: text inherits foreground, underline appears
     on hover — accent stays reserved for primary CTA. */
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
  margin-left: 4px;
}
.auth-foot a:hover { text-decoration: underline; }
.auth-skip { margin-top: 10px; }

/* Sign-in / sign-up additions (2026-11-05): Google button, divider,
   label row with the forgot link, show/hide password. */
.btn-google {
  width: 100%;
  height: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  /* Google's dark-theme button: #131314 fill, #8e918f outline, #e3e3e3 text. */
  background: #131314;
  color: #e3e3e3;
  border: 1px solid #8e918f;
  border-radius: 8px;
  font: 500 15px/1 inherit;
  font-family: inherit;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
}
.btn-google:hover { background: #1f1f20; border-color: #c4c7c5; }
.btn-google:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(46, 160, 67, 0.35); }
.btn-google:disabled { opacity: 0.7; cursor: progress; }
.auth-oauth[hidden] { display: none !important; }
.auth-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0;
  color: var(--text-dim);
  font-size: 12.5px;
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border-light);
}
.field > label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
}
.field-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.field-link { font-size: 13px; color: var(--text-muted); text-decoration: none; }
.field-link:hover { color: var(--text); text-decoration: underline; }
.field-link[hidden] { display: none !important; }
.field input::placeholder { color: var(--text-dim); opacity: 0.7; }
.pw-wrap { position: relative; display: flex; }
.pw-wrap input { flex: 1; min-width: 0; padding-right: 64px; }
.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  height: 30px; padding: 0 10px;
  background: transparent; border: 0; border-radius: 6px;
  color: var(--text-muted); font: 500 13px/1 inherit; font-family: inherit;
  cursor: pointer;
}
.pw-toggle:hover { color: var(--text); background: var(--vercel-elevated); }
.pw-toggle:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(46, 160, 67, 0.5); }
.form-error a { color: inherit; text-decoration: underline; text-underline-offset: 2px; font-weight: 500; }
.auth-corner-logo { display: inline-flex; align-items: center; gap: 8px; }
.auth-corner-logo .brand-mark { width: 22px; height: 22px; }

/* --------------------------------------------------------------------
   Auth-screen green brand — match the platform sign-in (app.browsa.io
   /auth/signin), which uses the shared Browsa green (#2ea043) instead of
   this app's Vercel-white CTA. Scoped to body.is-auth so ONLY the
   sign-in / sign-up / reset screens change; the dashboard and marketing
   site keep their existing palette. Same green tokens as the platform's
   --neo-primary (#2ea043) / hover (#238636).
   ------------------------------------------------------------------ */
body.is-auth .btn-primary {
  background: #2ea043;
  color: #ffffff;
}
body.is-auth .btn-primary:hover {
  background: #238636;
}
body.is-auth .field input:focus {
  border-color: #2ea043;
  box-shadow: 0 0 0 3px rgba(46, 160, 67, 0.15);
}
body.is-auth .auth-foot a,
body.is-auth .auth-forgot a,
body.is-auth .field-link {
  color: #3fb950;
}
body.is-auth .auth-foot a:hover,
body.is-auth .auth-forgot a:hover,
body.is-auth .field-link:hover {
  color: #46c157;
  text-decoration: underline;
}

/* ════════════════════════════════════════════════════════════════════
   Signed-out pages polish (2026-11-05). Everything below is scoped to
   .auth-screen / body.is-auth, so the dashboard's shared .field,
   .form-error and .btn-* rules are untouched.

   Layout
     /signin, /signup   .auth-split: form column + product panel from
                        1024px; single column below (sign-up keeps the
                        perks card under the form, sign-in hides it).
     everything else    one centred 400px column with an icon badge.

   Green: white text on #2ea043 is 3.4:1, under WCAG AA for 15px text,
   so the button rests on #238636 (4.6:1) and lifts to #2ea043 on hover,
   the same pairing GitHub uses. Links stay #3fb950 (7:1 on the canvas).
   ════════════════════════════════════════════════════════════════════ */
body.is-auth {
  --auth-green: #238636;
  --auth-green-hi: #2ea043;
  --auth-link: #3fb950;
  --auth-line: rgba(255, 255, 255, 0.08);
  --auth-field-border: rgba(255, 255, 255, 0.12);
  --auth-field-border-hover: rgba(255, 255, 255, 0.2);
  --auth-ring: 0 0 0 3px rgba(46, 160, 67, 0.25);
}

/* ── Split layout (sign-in / sign-up) ───────────────────────────────── */
.auth-split {
  padding: 0;
  align-items: stretch;
}
.auth-main {
  flex: 1 1 50%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 104px 32px 64px;
}
.auth-aside {
  flex: 1 1 50%;
  min-width: 0;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 72px clamp(32px, 4vw, 64px);
  background: linear-gradient(180deg, #0a0e16 0%, #070a10 100%);
  border-left: 1px solid var(--auth-line);
}
/* Dot grid, faded out towards the edges. */
.auth-aside::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 75% 65% at 50% 45%, #000 25%, transparent 78%);
          mask-image: radial-gradient(ellipse 75% 65% at 50% 45%, #000 25%, transparent 78%);
}
/* One soft green glow behind the code window. */
.auth-aside::after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 640px;
  height: 640px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(46, 160, 67, 0.14), transparent);
  pointer-events: none;
}
.auth-aside-inner {
  width: 100%;
  max-width: 520px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.auth-aside-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  padding: 6px 11px;
  border-radius: 999px;
  font: 500 12px/1 var(--font-mono);
  letter-spacing: 0;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.03);
  box-shadow: inset 0 0 0 1px var(--auth-line);
}
.auth-live-dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--auth-link);
  box-shadow: 0 0 0 3px rgba(63, 185, 80, 0.18);
  animation: auth-pulse 2.4s ease-in-out infinite;
}
@keyframes auth-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(63, 185, 80, 0.18); }
  50%      { box-shadow: 0 0 0 5px rgba(63, 185, 80, 0.06); }
}
.auth-aside-title {
  margin: 18px 0 12px;
  font-size: 32px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.035em;
  color: var(--vercel-text);
  text-wrap: balance;
}
.auth-aside-lede {
  max-width: 46ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* Code window */
.auth-code {
  margin: 0;
  border-radius: 12px;
  overflow: hidden;
  background: rgba(8, 11, 18, 0.9);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.09),
    0 1px 0 rgba(255, 255, 255, 0.04),
    0 30px 60px -30px rgba(0, 0, 0, 0.9);
}
.auth-code-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 38px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.025);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.auth-code-dots { display: flex; gap: 6px; }
.auth-code-dots i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255, 255, 255, 0.12); }
.auth-code-file { font: 500 12px/1 var(--font-mono); color: var(--text-muted); letter-spacing: 0; }
.auth-code-body {
  margin: 0;
  padding: 16px 18px;
  overflow-x: auto;
  white-space: pre;
  font: 400 12.5px/1.75 var(--font-mono);
  letter-spacing: 0;
  color: #c3ccd8;
  tab-size: 2;
  scrollbar-width: none;
}
.auth-code-body::-webkit-scrollbar { display: none; }
.auth-code-body code { font: inherit; color: inherit; background: none; padding: 0; border-radius: 0; }
.tk-k { color: #8b97ff; }
.tk-s { color: #5ff0be; }
.tk-f { color: #eaf0f8; }
.tk-n { color: #f7b955; }
.tk-c { color: #6b7789; }
.auth-code-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(46, 160, 67, 0.05);
  font: 500 12px/1.4 var(--font-mono);
  letter-spacing: 0;
  color: var(--vercel-text);
}
.auth-code-meta { margin-left: auto; color: var(--text-muted); font-weight: 400; white-space: nowrap; }

/* Pricing facts (sign-in) */
.auth-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.015);
  box-shadow: inset 0 0 0 1px var(--auth-line);
}
.auth-stats > div { padding: 16px 18px; min-width: 0; }
.auth-stats > div + div { border-left: 1px solid var(--auth-line); }
.auth-stats dt { font-size: 18px; font-weight: 600; letter-spacing: -0.02em; color: var(--vercel-text); }
.auth-stats dd { margin: 4px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--text-muted); text-wrap: balance; }

/* What you get (sign-up) */
.auth-perks { display: flex; flex-direction: column; gap: 14px; }
.auth-perks-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.auth-perks-list { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.auth-perks-list li {
  position: relative;
  padding-left: 30px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
}
.auth-perks-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(46, 160, 67, 0.14) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%233fb950' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.6 6.3 5 8.6l4.4-5'/%3E%3C/svg%3E") center / 11px no-repeat;
  box-shadow: inset 0 0 0 1px rgba(63, 185, 80, 0.3);
}
.auth-perks-list b { color: var(--vercel-text); font-weight: 600; }
.auth-perks-foot {
  padding-top: 14px;
  border-top: 1px solid var(--auth-line);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}

/* Below 1024px: one column. */
@media (max-width: 1023px) {
  .auth-split { flex-direction: column; align-items: stretch; justify-content: flex-start; }
  .auth-main { flex: 0 0 auto; padding: 104px 24px 40px; }
  .auth-split[data-mode="signin"] .auth-main { flex: 1 0 auto; }
  .auth-split[data-mode="signin"] .auth-aside { display: none; }
  .auth-aside {
    flex: 0 0 auto;
    padding: 0 24px 56px;
    background: none;
    border-left: 0;
    overflow: visible;
  }
  .auth-aside::before, .auth-aside::after { display: none; }
  .auth-aside-inner { max-width: 400px; margin: 0 auto; }
  .auth-aside-head, .auth-code, .auth-stats { display: none !important; }
  .auth-perks {
    padding: 20px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.02);
    box-shadow: inset 0 0 0 1px var(--auth-line);
  }
}
@media (max-width: 640px) {
  .auth-screen { padding: 88px 20px 48px; }
  .auth-split { padding: 0; }
  .auth-main { padding: 88px 20px 32px; }
  .auth-aside { padding: 0 20px 48px; }
}
@media (min-width: 1024px) and (max-height: 760px) {
  .auth-aside { padding-block: 40px; }
  .auth-aside-inner { gap: 22px; }
  .auth-aside-title { font-size: 28px; }
}

/* ── Centred pages (forgot, reset, verify, Google return) ───────────── */
.auth-screen .auth-card { padding: 0; }
.auth-card-center > .auth-title,
.auth-card-center > .auth-subtitle { text-align: center; }
.auth-card-center .auth-foot { text-align: center; }
.auth-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin: 0 auto 22px;
  border-radius: 12px;
  color: var(--auth-link);
  background: linear-gradient(180deg, rgba(46, 160, 67, 0.16), rgba(46, 160, 67, 0.04));
  box-shadow:
    inset 0 0 0 1px rgba(63, 185, 80, 0.28),
    0 0 0 6px rgba(46, 160, 67, 0.05),
    0 10px 30px -10px rgba(46, 160, 67, 0.45);
}
.auth-icon:has([data-oauth-failed]:not([hidden])) {
  color: #ff8a96;
  background: linear-gradient(180deg, rgba(255, 92, 108, 0.14), rgba(255, 92, 108, 0.03));
  box-shadow: inset 0 0 0 1px rgba(255, 92, 108, 0.3), 0 0 0 6px rgba(255, 92, 108, 0.05);
}
.auth-spinner {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid rgba(63, 185, 80, 0.25);
  border-top-color: var(--auth-link);
  animation: auth-spin 0.8s linear infinite;
}
@keyframes auth-spin { to { transform: rotate(360deg); } }
.auth-icon-glyph { display: grid; place-items: center; }
.auth-card-center > .form-error { margin-top: 20px; }
.auth-actions { margin-top: 16px; }
.auth-alt {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--auth-line);
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: center;
}
.auth-note { font-size: 13px; line-height: 1.5; color: var(--text-muted); }
.auth-screen .auth-skip { margin-top: 0; }
.auth-screen .auth-email {
  color: var(--vercel-text);
  font-weight: 500;
  overflow-wrap: anywhere;
}

/* ── Form controls ──────────────────────────────────────────────────── */
.auth-screen .auth-form { gap: 18px; }
.auth-screen .field { gap: 8px; }
.auth-screen .field > label,
.auth-screen .field > span:not(.field-hint),
.auth-screen .field-row > label {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--vercel-text);
}
.auth-screen .field-row { align-items: center; }
.auth-screen .field input {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  font-size: 15px;
  line-height: 1.2;
  border-radius: 8px;
  color: var(--vercel-text);
  background: var(--vercel-surface);
  border: 1px solid var(--auth-field-border);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.auth-screen .field input:hover { border-color: var(--auth-field-border-hover); }
body.is-auth .auth-screen .field input:focus {
  border-color: var(--auth-green-hi);
  box-shadow: var(--auth-ring);
}
.auth-screen .field input::placeholder { color: var(--text-muted); opacity: 0.55; }
/* Keep browser autofill dark instead of Chrome's pale yellow/blue. */
.auth-screen .field input:-webkit-autofill {
  -webkit-text-fill-color: var(--vercel-text);
  caret-color: var(--vercel-text);
  box-shadow: 0 0 0 1000px var(--vercel-surface) inset;
}
body.is-auth .auth-screen .field input:-webkit-autofill:focus {
  box-shadow: 0 0 0 1000px var(--vercel-surface) inset, var(--auth-ring);
}
.auth-screen .pw-wrap input { padding-right: 68px; }
.auth-screen .pw-toggle {
  right: 6px;
  height: 32px;
  padding: 0 10px;
  font-size: 13px;
  border-radius: 6px;
}
.auth-screen .pw-toggle:focus-visible { box-shadow: 0 0 0 2px var(--auth-green-hi); }
.auth-screen .field-hint { font-size: 12.5px; color: var(--text-muted); margin-top: 0; }
.auth-screen .field .mono-input { font-family: var(--font-mono); font-size: 14px; letter-spacing: 0; }
/* 6-digit code: one big mono string. letter-spacing also trails the last
   digit, so the left padding gets the same extra to stay centred. */
.auth-screen .field .otp-input {
  height: 56px;
  padding: 0 14px 0 calc(14px + 0.45em);
  font: 600 24px/1 var(--font-mono);
  letter-spacing: 0.45em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.auth-screen .otp-input::placeholder { opacity: 0.3; }

/* Messages. Not flex: error HTML mixes text and links inline. */
.auth-screen .form-error,
.auth-screen .form-success {
  position: relative;
  padding: 10px 12px 10px 36px;
  font-size: 13.5px;
  line-height: 1.5;
  border-radius: 8px;
}
.auth-screen .form-error {
  color: #ffb3bb;
  background: rgba(255, 92, 108, 0.08);
  border: 1px solid rgba(255, 92, 108, 0.28);
}
.auth-screen .form-success {
  color: #a8f0c0;
  background: rgba(46, 160, 67, 0.08);
  border: 1px solid rgba(63, 185, 80, 0.3);
}
.auth-screen .form-error::before,
.auth-screen .form-success::before {
  content: "";
  position: absolute;
  left: 12px;
  top: 12px;
  width: 16px;
  height: 16px;
  background: center / 16px no-repeat;
}
.auth-screen .form-error::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23ff8a96' stroke-width='1.5' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.25'/%3E%3Cpath d='M8 4.75v3.75M8 11h.01'/%3E%3C/svg%3E");
}
.auth-screen .form-success::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%233fb950' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6.25'/%3E%3Cpath d='m5.4 8.2 1.8 1.8 3.4-3.8'/%3E%3C/svg%3E");
}

/* ── Buttons ────────────────────────────────────────────────────────── */
body.is-auth .auth-screen .btn-primary {
  height: 44px;
  padding: 0 16px;
  font-size: 15px;
  font-weight: 600;
  border-radius: 8px;
  color: #ffffff;
  background: var(--auth-green);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06),
    0 8px 20px -12px rgba(46, 160, 67, 0.8);
  filter: none;
}
body.is-auth .auth-screen .btn-primary:hover { background: var(--auth-green-hi); }
body.is-auth .auth-screen .btn-primary:focus-visible {
  box-shadow: 0 0 0 2px var(--vercel-bg), 0 0 0 4px var(--auth-link);
}
body.is-auth .auth-screen .btn-primary:disabled {
  background: var(--auth-green);
  color: rgba(255, 255, 255, 0.85);
  opacity: 0.7;
  box-shadow: none;
  cursor: default;
  transform: none;
}
.auth-screen [data-submit][aria-busy="true"] { cursor: progress; }
.auth-screen [data-submit][aria-busy="true"]::before {
  content: "";
  width: 14px;
  height: 14px;
  margin-right: 4px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #ffffff;
  animation: auth-spin 0.7s linear infinite;
}
.auth-screen .btn-secondary {
  height: 44px;
  font-size: 15px;
  border-radius: 8px;
  color: var(--vercel-text);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--auth-field-border);
}
.auth-screen .btn-secondary:hover {
  background: rgba(255, 255, 255, 0.04);
  box-shadow: inset 0 0 0 1px var(--auth-field-border-hover);
}

/* Google (dark theme per Google's branding guide). */
.auth-screen .btn-google { font-size: 15px; letter-spacing: -0.01em; }
.auth-screen .btn-google svg { flex: none; }
.auth-screen .auth-divider {
  margin: 22px 0;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.auth-screen .auth-divider::before,
.auth-screen .auth-divider::after { background: var(--auth-line); }

/* ── Footers ────────────────────────────────────────────────────────── */
.auth-screen .auth-legal {
  margin-top: -4px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
  text-align: left;
}
.auth-screen .auth-legal a { color: var(--vercel-text); text-decoration-color: rgba(255, 255, 255, 0.3); }
.auth-screen .auth-legal a:hover { text-decoration-color: currentColor; }
.auth-screen .auth-foot {
  margin-top: 28px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
}
.auth-split .auth-foot {
  text-align: left;
  padding-top: 20px;
  border-top: 1px solid var(--auth-line);
}
.auth-screen .auth-foot a { margin-left: 0; font-weight: 500; }
body.is-auth .auth-screen a:focus-visible { box-shadow: 0 0 0 2px var(--auth-link); border-radius: 4px; }
body.is-auth .auth-corner-logo:focus-visible { box-shadow: 0 0 0 2px var(--auth-link); }

@media (max-width: 640px) {
  /* 16px stops iOS Safari zooming the page when an input gets focus. */
  .auth-screen .field input,
  .auth-screen .mono-input { font-size: 16px; }
  .auth-screen .field .otp-input { font-size: 22px; }
}

/* ============ DASHBOARD LAYOUT (Hyperbrowser pattern) ============ */
/* The dashboard switches off the global top nav and replaces it with
   a persistent left sidebar + scrollable main area. The body gets
   .has-sidebar class via JS while the dashboard route is active. */
body.has-sidebar > .app-nav { display: none; }
body.has-sidebar { background: var(--navy-900); }

/* Sidebar — Vercel's exact dimensions measured live:
   256px column, 36px-tall items, 6px radius, no left-accent-bar.
   Active state is just bg #1f1f1f — cleaner than the trendy
   left-rule-marker. */
.dash-layout {
  display: grid;
  grid-template-columns: 256px 1fr;
  min-height: 100vh;
}
.dash-sidebar {
  background: var(--vercel-bg);
  border-right: 1px solid var(--vercel-border);
  padding: 18px 12px 12px;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
/* After the base .dash-sidebar rule: at equal specificity the later rule
   wins, so placed before it the sidebar never hid on phones. */
@media (max-width: 880px) {
  .dash-layout { grid-template-columns: minmax(0, 1fr); }
  .dash-sidebar { display: none; }
  body.has-sidebar > .app-nav { display: block; }
}
.dash-logo {
  font-weight: 600; font-size: 15px;
  letter-spacing: -0.02em;
  color: var(--text); text-decoration: none;
  padding: 4px 12px 16px;
  display: inline-flex; align-items: center; gap: 8px;
}
.brand-mark { flex: 0 0 auto; display: block; }
.dash-logo .slash { color: var(--text-muted); font-weight: 400; }
.dash-logo .accent { color: var(--text); }  /* was emerald — Vercel keeps brand color out of the logo lockup */

.dash-nav {
  display: flex; flex-direction: column; gap: 1px;
  margin-bottom: auto;
}
.dash-nav-item {
  display: flex; align-items: center; gap: 10px;
  height: 36px;            /* Vercel spec exact */
  padding: 0 12px;
  color: var(--text-muted); font-size: 14px; font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none; border-radius: var(--radius);
  transition: background-color 120ms ease, color 120ms ease;
  white-space: nowrap;
}
.dash-nav-item:hover { background: var(--vercel-hover); color: var(--text); }
.dash-nav-item.active {
  background: var(--vercel-hover);
  color: var(--text);
}
/* No ::before left-bar — Vercel uses pure bg shift for active state. */
.dash-nav-item.ghost { color: var(--text-dim); font-size: 13px; }
.dash-nav-item.ghost:hover { color: var(--text-muted); }
.dash-nav-ico {
  display: inline-flex; align-items: center; justify-content: center;
  /* Sized to match Vercel/Linear sidebar icons (16px box, 1.5 stroke).
     Was 18px with mono-font glyph chars; replaced with inline SVG on
     2026-06-10 — chars rendered inconsistently across fonts and read
     as decoration instead of nav affordances. */
  width: 16px; height: 16px;
  color: var(--text-dim); flex-shrink: 0;
  transition: color 120ms ease;
}
svg.dash-nav-ico { stroke-width: 1.6; }
.dash-nav-item:hover .dash-nav-ico { color: var(--text); }
.dash-nav-item.active .dash-nav-ico { color: var(--text); }
.dash-nav-item .ext { margin-left: auto; font-size: 11px; color: var(--text-dim); }

.dash-sidebar-footer {
  margin-top: 24px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 2px;
}

/* Persistent credit-balance pill in the sidebar — competitor-audit
   2026-06-09 (persona A): browser-use cloud's '9 free tasks' counter
   is a clean activation nudge that's always visible. We mirror the
   pattern but use real credit balance instead of free-task count. */
.dash-credits-pill {
  display: flex; align-items: center; gap: 8px;
  margin-top: 16px; padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  text-decoration: none;
  color: var(--text);
  background: var(--vercel-card, rgba(255,255,255,0.02));
  transition: border-color 120ms, background 120ms;
  font-size: 13px;
}
.dash-credits-pill:hover {
  border-color: var(--emerald, #10b981);
  background: rgba(16,185,129,0.05);
}
.dash-credits-num {
  font-size: 16px; font-weight: 700;
  color: var(--emerald, #10b981);
  font-variant-numeric: tabular-nums;
}
.dash-credits-label {
  color: var(--text-dim, #94a3b8);
  font-size: 12px;
  letter-spacing: 0.04em;
}
/* Low / empty states — softened from full amber/red border to a tiny
   leading dot indicator. The previous bright amber clashed with the
   monochrome Vercel canvas (audit 2026-06-10 flagged it as an off-
   brand accent). The dot keeps the warning signal where it belongs
   (next to the number) without dyeing the whole pill chrome. */
.dash-credits-pill.low { border-color: var(--vercel-border-strong); }
.dash-credits-pill.low .dash-credits-num { color: var(--vercel-text); }
.dash-credits-pill.low .dash-credits-num::before {
  content: ""; display: inline-block;
  width: 6px; height: 6px; border-radius: 50%;
  background: #fbbf24;
  margin-right: 8px; vertical-align: 1px;
}
.dash-credits-pill.empty { border-color: var(--vercel-border-strong); }
.dash-credits-pill.empty .dash-credits-num { color: var(--vercel-text); }
.dash-credits-pill.empty .dash-credits-num::before {
  content: ""; display: inline-block;
  width: 6px; height: 6px; border-radius: 50%;
  background: #f87171;
  margin-right: 8px; vertical-align: 1px;
}

.dash-user {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 10px 4px;
  margin-top: 6px;
  border-top: 1px solid var(--border);
}
.dash-user-avatar {
  /* Vercel-style neutral avatar — emerald-fill was loudest non-CTA
     element on screen. Now: surface bg + hairline border + foreground
     letter, matching the team-row avatars in Vercel Settings. */
  width: 32px; height: 32px; border-radius: var(--radius);
  background: var(--vercel-elevated);
  color: var(--vercel-text);
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  display: flex; align-items: center; justify-content: center;
  font-weight: 500; font-size: 13px;
  text-transform: uppercase; flex-shrink: 0;
}
.dash-user-meta {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.dash-user-name {
  color: var(--text); font-size: 13px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-user-email {
  color: var(--text-dim); font-size: 11px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-user-signout {
  background: transparent; border: 1px solid var(--border-light);
  color: var(--text-muted); cursor: pointer;
  width: 26px; height: 26px; border-radius: 6px;
  font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
}
.dash-user-signout:hover { color: var(--red); border-color: rgba(239,68,68,0.4); }

.dash-main {
  padding: 28px 36px 64px;
  /* Centered within the content cell. Was 1240px left-aligned, which
     dumped all the slack on the right as a lopsided void on wide monitors.
     Centering balances it; 1340 keeps both the two-pane Playground and the
     table views comfortable without sprawling on ultrawide displays. */
  max-width: 1340px;
  width: 100%;
  margin-inline: auto;
}
@media (max-width: 880px) {
  .dash-main { padding: 20px 16px 48px; }
}

/* Mobile-only horizontal nav. Replaces the hidden sidebar on
   narrow viewports so users still have a way to switch dashboard
   views. Scrolls horizontally when the 7 pills don't fit. */
.dash-mobile-nav { display: none; }
@media (max-width: 880px) {
  .dash-mobile-nav {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    overflow-y: hidden;
    margin: -4px -16px 16px;
    padding: 4px 16px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    border-bottom: 1px solid var(--border);
  }
  .dash-mobile-nav::-webkit-scrollbar { display: none; }
}
.dmn-item {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  background: var(--navy-700);
  white-space: nowrap;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.dmn-item:hover { color: var(--text); }
.dmn-item.active {
  /* Mobile nav active pill — inverted, matches sidebar active pattern. */
  background: var(--vercel-text);
  color: var(--vercel-bg);
  border-color: var(--vercel-text);
  font-weight: 500;
}

.dash-shell {
  /* Legacy outer wrapper, retained for compatibility with the old
     single-column layout if .dash-layout is ever absent. */
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 32px 24px 64px;
  width: 100%;
}
.dash-header {
  margin-bottom: 24px;
}
.dash-header-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.dash-header h1 {
  /* Vercel/Linear tight-tracking ramp — 600 weight + negative tracking
     does the hierarchical work that 700+ used to do, but reads as
     calmer and more deliberate. Design audit 2026-06-08. */
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin-bottom: 6px;
}
.dash-header p {
  color: var(--text-muted);
  font-size: 13.5px;
  line-height: 1.5;
  max-width: 640px;
}
.dash-actions {
  display: flex; gap: 8px; align-items: center;
}
.dash-actions .btn-ghost {
  font-size: 13px; padding: 6px 12px;
}

/* Onboarding banner — fresh-user 3-step guide.
   Design audit 2026-06-08: previously a gradient hero card that
   consumed ~25% of viewport above the fold and crowded out KPIs.
   Shrunk to a compact strip — same content, half the visual weight,
   no gradient. Emerald accent narrowed to the left-edge rule + step
   numbers, not the whole card. */
.onboarding {
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-left: 2px solid var(--vercel-border-strong);
  border-radius: 8px;
  padding: 14px 18px;
  margin-bottom: 20px;
  position: relative;
}
.onboarding-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 10px;
}
.onboarding-head h2 {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 1px;
  color: var(--text);
}
.onboarding-head p {
  font-size: 12.5px;
  color: var(--text-muted);
}
.onboarding-dismiss {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 20px;
  cursor: pointer;
  line-height: 1;
  padding: 0 6px;
  font-family: inherit;
}
.onboarding-dismiss:hover { color: var(--text); }
/* Steps row — compact inline strip, not 3 full sub-cards.
   Visual QA 2026-06-08 found my previous outer-container shrink
   didn't actually slim the banner because the 3 child cards still
   each had padding+borders+circular numbers. This converts them to
   a single horizontal row of pill-like badges with no per-step
   border/bg — the rule on the parent banner does the visual work. */
.onboarding-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
}
@media (max-width: 720px) {
  .onboarding-steps { gap: 10px; }
}
.onboarding-step {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  text-decoration: none;
  color: var(--text);
  transition: opacity 120ms;
}
.onboarding-step:hover { opacity: 0.85; }
.onboarding-num {
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--vercel-elevated);
  color: var(--text-muted);
  border: 1px solid var(--border);
  font-weight: 600; font-size: 11px;
  flex-shrink: 0;
}
.onboarding-step-label {
  font-size: 12.5px; font-weight: 500; color: var(--text);
  letter-spacing: -0.01em;
}
/* Sub-line dropped on the compact strip — the label alone communicates
   the step. Re-enable later if we re-introduce a verbose variant. */
.onboarding-step-sub { display: none; }
/* Done state: step 2/3 turn into checkmark + strikethrough so the user
   can see "one more to go". Wired by setupOnboarding (.done class
   toggled on each .onboarding-step). QA 2026-06-08. */
.onboarding-step.done .onboarding-num {
  /* Done-state uses Vercel's "ready" cyan (#50e3c2) — matches the
     Deployment Ready status pill on Vercel's dashboard. Keeps the
     emerald brand color from leaking into a sub-success indicator. */
  background: #50e3c2;
  color: transparent;
  border-color: #50e3c2;
  position: relative;
}
.onboarding-step.done .onboarding-num::after {
  content: '✓';
  color: #0a0a0a;
  font-size: 11px;
  font-weight: 700;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.onboarding-step.done .onboarding-step-label {
  text-decoration: line-through;
  color: var(--text-muted);
}

/* Metrics row */
.metrics-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
@media (max-width: 1100px) {
  .metrics-row { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 680px) {
  .metrics-row { grid-template-columns: repeat(2, 1fr); }
}
/* Cards lift one step above page canvas (#000 → #0a0a0a body
   → #1a1a1a card). Audit 2026-06-10 flagged dashboard cards as
   "floaty/undefined" because they sat at #0a0a0a (same as body on
   most pages) with only a 1px hairline. Bumping the surface to
   --vercel-elevated gives proper visual depth and matches the
   landing-page card pattern. */
.metric {
  background: var(--vercel-elevated);
  border: none;
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  min-height: 92px;
  display: flex; flex-direction: column; justify-content: space-between;
  transition: box-shadow 150ms ease, transform 150ms ease;
}
.metric:hover { box-shadow: inset 0 0 0 1px var(--vercel-border-strong); transform: translateY(-1px); }
.metric-head {
  display: flex; align-items: center; gap: 8px;
  color: var(--text-dim); font-size: 11px;
}
.metric-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  /* Icons recede — design audit said per-stat colored icons fight the
     numbers for attention. Single mono-color stroke across the row.
     Was unicode glyphs (◐ ▦ ✓ ✕ ⌁) — upgraded to inline SVG 2026-06-10
     for consistency with sidebar nav. */
  color: var(--text-dim);
  flex-shrink: 0;
}
svg.metric-ico { stroke-width: 1.6; }
.metric-label {
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: 10.5px;
}
.metric-num {
  font-size: 32px; font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.1;
  margin-top: 8px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
/* Vercel discipline: metric numbers stay white. Color is reserved
   for warning/error states ONLY. The previous `.metric.good →
   emerald` rule was tinting Credits emerald just because it had
   a positive balance — which made the most-prominent number on
   the dashboard the wrong color. */
.metric.warn .metric-num { color: var(--amber); }
.metric.bad  .metric-num { color: var(--red); }
.metric.good .metric-num { color: var(--text); }
.metric-sub {
  color: var(--text-dim); font-size: 11.5px;
  margin-top: 4px;
}

/* Cards */
/* Card chrome — Vercel pattern: elevated surface (one step above page
   canvas) + inset 1px shadow as "border" (animates without layout shift
   on hover), 6px radius. Was using --vercel-surface (#0a0a0a) which is
   identical to the body bg → cards looked floaty against the canvas.
   Lifting to --vercel-elevated (#1a1a1a) restores depth (audit 2026-06-10). */
.card {
  background: var(--vercel-elevated);
  border: none;
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  border-radius: var(--radius);
  margin-bottom: 20px;
  overflow: hidden;
  transition: box-shadow 150ms ease;
}
.card:hover {
  /* Outline brightens on hover — Vercel's signature card interaction.
     No transform, no scale, no shadow lift — just a hairline glow. */
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
}
.card-head {
  padding: 16px 16px 6px;
}
.card-head.row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.card-head h2 {
  /* Vercel section-heading ramp: 14px / 500 / -0.28px tracking.
     The tight letter-spacing at small sizes is the optical move that
     makes the UI read as deliberate. */
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: 4px;
  color: var(--text);
}
.card-head p {
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}
/* Links inside card intros were the browser's default dark blue, which
   is unreadable on this background. */
.card-head p a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
.card-head p a:hover { color: var(--emerald-2); }
.card-body { padding: 12px 16px 16px; }

/* Generic helpers */
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.small { font-size: 12px; }
code {
  background: var(--vercel-elevated);
  border: none;
  padding: 1px 5px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.92em;
}

/* ============ PLAYGROUND ============ */
.playground .card-head.row { align-items: center; }
.pg-status {
  font-size: 11px; font-weight: 600;
  padding: 4px 10px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.5px;
  background: var(--navy-800); color: var(--text-muted);
  border: 1px solid var(--border);
  display: inline-flex; align-items: center; gap: 6px;
  white-space: nowrap;
}
.pg-status.idle { color: var(--text-muted); }
.pg-status.queued { background: rgba(99,102,241,0.15); color: #a5b4fc; border-color: rgba(99,102,241,0.3); }
.pg-status.running {
  background: rgba(245,158,11,0.15); color: #fbbf24; border-color: rgba(245,158,11,0.3);
}
.pg-status.running::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: #fbbf24; animation: pulse 1.5s ease-in-out infinite;
}
.pg-status.completed { background: rgba(80,227,194,0.08); color: #50e3c2; border-color: rgba(80,227,194,0.24); }
.pg-status.failed { background: rgba(239,68,68,0.15); color: #fca5a5; border-color: rgba(239,68,68,0.35); }
.pg-status.warn { background: rgba(245,158,11,0.13); color: #fbbf24; border-color: rgba(245,158,11,0.35); }

.pg-grid {
  display: grid;
  /* Balanced two-pane split — form on the left, live preview slightly
     larger on the right (it's the "watch the browser" view). Bounded by
     the centered .dash-main so neither pane sprawls on ultrawide. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 18px;
  margin-top: 10px;
  align-items: start;   /* preview must NOT stretch to the tall form's height */
}
/* Stack sooner — below this the two-column split crams the form. */
@media (max-width: 1200px) {
  /* minmax(0, …): a plain 1fr track grows to the one-row template chips
     (nowrap), which made the Playground 1400px wide on phones. */
  .pg-grid { grid-template-columns: minmax(0, 1fr); }
  /* Stacked: don't force the viewport-fill height (it would make the preview a
     full screen tall below the form). Static flow with a sane fixed height. */
  .pg-preview { position: static !important; height: auto !important; min-height: 440px; }
}
/* Cards clip with overflow:hidden by default, which scopes sticky children
   to the card instead of the viewport. The Playground/Scrape cards need the
   live preview (sticky top) and Run bar (sticky bottom) to pin to the
   VIEWPORT, so opt these cards out of clipping. Safe: nothing in them bleeds
   to the rounded edge (toolbar + grid children are inset by padding/gap). */
.card:has(.pg-grid) { overflow: visible; }

.pg-form { display: flex; flex-direction: column; gap: 14px; }
.pg-field { display: flex; flex-direction: column; gap: 6px; }
.pg-field > span {
  font-size: 12.5px; font-weight: 500; color: var(--text-muted);
  display: flex; align-items: baseline; gap: 8px;
}
.pg-hint { color: var(--text-dim); font-size: 11px; font-weight: 400; }
.pg-field input,
.pg-field select,
.pg-field textarea {
  font-family: inherit;
  background: var(--navy-800);
  border: 1px solid var(--border-light);
  color: var(--text);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 14px;
  resize: vertical;
  transition: border-color 120ms;
}
.pg-field textarea { font-family: inherit; line-height: 1.45; }
.pg-field input:focus,
.pg-field select:focus,
.pg-field textarea:focus {
  outline: none; border-color: var(--vercel-text);
  box-shadow: var(--vercel-focus);
}
.pg-field select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='%2394a3b8'><path d='M3 4l3 3 3-3'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
  padding-right: 32px;
}
.pg-row-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 12px; }

/* Collapsible "Browser fingerprint" block — OS type + Country
   pickers, our realism knobs. Hidden by default so the form
   stays calm for the 90%-case; one click opens the advanced view. */
.pg-advanced {
  margin: 4px 0 4px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: rgba(255,255,255,0.015);
}
.pg-advanced > summary {
  list-style: none;
  cursor: pointer;
  padding: 10px 14px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  user-select: none;
  border-radius: 8px;
}
.pg-advanced > summary::-webkit-details-marker { display: none; }
.pg-advanced > summary::before {
  content: "▸";
  color: var(--text-dim);
  font-size: 10px;
  transition: transform 120ms;
  width: 12px;
}
.pg-advanced[open] > summary::before {
  transform: rotate(90deg);
}
.pg-advanced > summary:hover { background: rgba(255,255,255,0.025); }
.pg-advanced > .pg-row-2 {
  padding: 4px 14px 14px;
  grid-template-columns: 1fr 1fr;
}
.pg-advanced > .pg-advanced-body {
  padding: 8px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pg-advanced-help {
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
  background: rgba(16,185,129,0.05);
  border: 1px solid rgba(16,185,129,0.15);
  border-radius: 6px;
  padding: 8px 10px;
}
.pg-advanced-help strong { color: var(--text); font-weight: 600; }

/* When the custom-provider section has a saved value (auto-opened
   on page load via JS), give it a faint emerald tint so the user
   sees it's active. */
.pg-llm-custom[open] > summary {
  background: rgba(16,185,129,0.05);
  border-radius: 8px 8px 0 0;
}
.pg-llm-custom[open] {
  border-color: rgba(16,185,129,0.25);
}

/* Inline link in the model selector hint — jumps to the custom
   provider disclosure when the user wants to point at a proxy. */
/* Vercel link pattern — text inherits foreground, underline on hover. */
.pg-link-inline {
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
}
.pg-link-inline:hover {
  color: var(--text);
  text-decoration: underline;
}

/* Inline geo-mismatch warning — appears when the task text strongly
   implies a country that doesn't match the Egress region selector.
   Stops users from running OpenTable/Amazon tasks through Hetzner DE. */
.pg-geo-warn {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.55;
  color: #fbbf24;
  background: rgba(245,158,11,0.08);
  border: 1px solid rgba(245,158,11,0.3);
  border-radius: 6px;
  padding: 8px 10px;
}
.pg-geo-warn a {
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
  margin-left: 6px;
}
.pg-geo-warn a:hover { text-decoration: underline; color: var(--text); }

/* Inline action button rows (Playground: agt_live + Generate, etc.) */
.pg-input-row {
  display: flex; gap: 8px; align-items: stretch;
}
.pg-input-row input { flex: 1; }
.pg-inline-action {
  white-space: nowrap;
  font-size: 13px;
  padding: 0 14px;
}

/* Task templates */
.pg-templates {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 4px 0 8px;
}
.pg-tpl {
  font-family: inherit;
  background: var(--navy-800);
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 120ms;
  white-space: nowrap;
}
.pg-tpl:hover {
  color: var(--text);
  border-color: var(--vercel-border-strong);
  background: var(--vercel-elevated);
}

/* Team invite form — email field grows, button stays compact. */
.team-invite-form {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.team-invite-form .pg-field { margin-bottom: 0; }

/* Flagship template — the cross-retailer price-compare. Marketed
   above the rest because it's the demo that no competitor can run
   end-to-end (5 distinct bot walls in one task). Distinction is
   carried by ⚡ icon + emerald border + bold weight; no background
   fill so it can't be confused with the .active "selected" state.
   QA re-verify 2026-06-08 — previously a gradient background made
   the flagship LOOK selected even when another chip was active. */
/* Flagship base — neutral chip with a slight foreground lift; the ⚡
   icon does the "this is special" work, not the color. Active state
   below adopts Vercel's white-on-black inversion. */
.pg-tpl.flagship {
  background: var(--vercel-surface);
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
  border-color: transparent;
  color: var(--text);
  font-weight: 500;
}
.pg-tpl.flagship:hover {
  background: var(--vercel-elevated);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
}

/* Active chip — inverted (white-on-black) so it reads as the selected
   one without burning the brand emerald. Matches the primary-CTA
   color discipline. */
.pg-tpl.active,
.pg-tpl.flagship.active {
  background: var(--vercel-text);    /* #ededed */
  color: var(--vercel-bg);           /* #000 */
  border-color: var(--vercel-text);
  box-shadow: none;
  font-weight: 500;
}

/* Hide step counter when idle to reduce visual noise. */
.playground:has(.pg-status.idle) .pg-step { display: none; }

/* Running-state summary (Hyperbrowser pattern) — replaces the form
   when a task is queued/running/completed/failed so the user sees a
   stable, read-only view of the config their agent is operating on. */
.pg-summary {
  display: flex; flex-direction: column; gap: 18px;
}
.pg-summary-row { display: flex; flex-direction: column; gap: 6px; }
.pg-summary-label {
  font-size: 11.5px; font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .06em;
}
.pg-summary-task {
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap; word-break: break-word;
}
.pg-summary-id {
  display: flex; align-items: center; gap: 8px;
}
.pg-summary-id code {
  font-family: var(--font-mono);
  font-size: 13px; color: var(--text);
  background: var(--navy-800); border: 1px solid var(--border);
  padding: 6px 10px; border-radius: 6px;
  flex: 1; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
.pg-copy-btn {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--navy-800);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 6px; cursor: pointer;
  font-size: 13px; font-family: inherit;
  text-decoration: none;
  transition: color 120ms, border-color 120ms;
}
.pg-copy-btn:hover { color: var(--text); border-color: var(--vercel-border-strong); }

.pg-summary-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
}
.pg-summary-value {
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13.5px;
  color: var(--text);
  font-family: var(--font-mono);
}
/* Live Activity Console — the narrated per-step log the task-runner
   streams into agents.jobs.activity, rendered incrementally during a run
   (see pgRenderActivity). Reads like a compact terminal feed. */
.pg-activity {
  margin-top: 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--navy-800);
  overflow: hidden;
}
.pg-activity-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.pg-activity-title {
  font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--text-muted);
}
.pg-activity-count {
  font-size: 11px; color: var(--on-accent);
  background: var(--accent); border-radius: 999px;
  padding: 1px 8px; font-weight: 700;
}
.pg-activity-log {
  list-style: none; margin: 0; padding: 6px 0;
  max-height: 260px; overflow-y: auto;
}
.pg-activity-item {
  display: flex; gap: 10px;
  padding: 7px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}
.pg-activity-item:last-child { border-bottom: none; }
.pg-activity-n {
  flex-shrink: 0;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
  background: var(--accent-faint); color: var(--accent);
  font-family: ui-monospace, 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 700;
}
.pg-activity-body { min-width: 0; flex: 1; }
.pg-activity-line {
  font-size: 13px; color: var(--text);
  line-height: 1.45; overflow-wrap: anywhere;
}
.pg-activity-meta {
  display: flex; gap: 8px; margin-top: 3px;
  font-size: 11px; color: var(--text-muted);
  font-family: ui-monospace, 'JetBrains Mono', monospace;
}
.pg-activity-action { color: var(--accent-2); }
.pg-activity-url { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pg-summary-actions {
  display: flex; gap: 10px; margin-top: 4px;
}

/* Browser-realism fingerprint panel — visible during a task run after
   the burner is provisioned. Reuses .pg-summary-value styling for
   the cells so it looks like a sibling of the existing summary
   grid, but has its own emerald-tinted header to call out that
   THIS is the platform's real differentiator. */
.pg-fingerprint {
  margin-top: 10px;
  border: 1px solid rgba(16, 185, 129, 0.25);
  background: linear-gradient(180deg, rgba(16,185,129,0.04), transparent 70%);
  border-radius: 10px;
  padding: 12px 14px;
}
.pg-fp-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
  margin-bottom: 10px;
}
.pg-fp-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  font-family: var(--font-mono); font-size: 12px;
  color: var(--emerald);
}
.pg-fp-link {
  margin-left: auto;
  font-size: 12px;
  color: var(--emerald-2);
  text-decoration: none;
  padding: 2px 8px;
  border: 1px solid rgba(16, 185, 129, 0.25);
  border-radius: 999px;
  transition: background 120ms;
}
.pg-fp-link:hover {
  background: rgba(16, 185, 129, 0.12);
  color: var(--emerald);
}
.pg-fp-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
}
@media (max-width: 880px) {
  .pg-fp-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Trust-score color bands. Thresholds match server-side
   trust_score.go: ≥850 OK, ≥700 suspicious, <700 flagged. */
.pg-fp-trust {
  font-weight: 700;
  font-size: 18px;
  font-family: var(--font-mono);
  line-height: 1.2;
}
.pg-fp-trust.ok   { color: var(--emerald-2); }
.pg-fp-trust.warn { color: #fbbf24; }
.pg-fp-trust.bad  { color: #f87171; }
.pg-fp-trust-label {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  color: var(--text-dim);
  /* Render on its own line so it doesn't wrap mid-cell */
  display: block;
  margin-top: 1px;
}
.pg-fp-id code {
  font-size: 11.5px;
  color: var(--text-muted);
  background: transparent;
  padding: 0;
}

/* Stronger Stop button — red when actually running, calmer otherwise. */
.btn-danger {
  background: #ef4444;
  color: white;
  border: 1px solid #ef4444;
  font-family: inherit; font-weight: 600; font-size: 14px;
  padding: 10px 18px;
  border-radius: 8px; cursor: pointer;
  transition: background 120ms, transform 120ms;
}
.btn-danger:hover { background: #dc2626; transform: translateY(-1px); }
.btn-danger:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.pg-actions { display: flex; gap: 10px; align-items: center; margin-top: 4px; }
.pg-link {
  color: var(--text-muted); font-size: 12.5px; text-decoration: none;
  padding: 6px 10px; border-radius: 6px; border: 1px solid var(--border);
}
.pg-link:hover { color: var(--text); border-color: var(--vercel-border-strong); }
.pg-error {
  background: rgba(239,68,68,0.08);
  border: 1px solid rgba(239,68,68,0.3);
  color: #fca5a5;
  padding: 10px 12px; border-radius: 8px;
  font-size: 13px;
}

.pg-preview {
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex; flex-direction: column;
  overflow: hidden;
  /* Fill the viewport height and stick, so the live "watch the browser" view
     stays in view the whole time the long config form scrolls past on the
     left — instead of a short 360px block that left a huge dead void beneath
     it (the grid cell is as tall as the ~1400px form). align-self:start keeps
     it from stretching to the full row height; the explicit viewport height +
     sticky give it a real, balanced panel size. */
  height: calc(100vh - 32px);
  min-height: 520px;
  align-self: start;
  position: sticky;
  top: 16px;
}
.pg-preview-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 12px; color: var(--text-muted); font-weight: 500;
}
.pg-step { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-dim); }
.pg-preview-body {
  flex: 1; min-height: 320px;
  position: relative;
  background: var(--navy-900);
}
.pg-preview-body iframe {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; background: white;
}
.pg-preview-empty {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 12px;
  color: var(--text-dim); font-size: 13px;
  padding: 32px 24px;
  text-align: center;
}
.pg-preview-icon {
  font-size: 28px; opacity: 0.55;
  font-family: var(--font-mono);
  color: var(--emerald);
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--emerald-glow);
  display: flex; align-items: center; justify-content: center;
}
.pg-preview-empty-title {
  font-size: 15px; font-weight: 600; color: var(--text);
  margin-bottom: 4px;
}
.pg-preview-bullets {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
  text-align: left;
  font-size: 12.5px;
  color: var(--text-muted);
  max-width: 360px;
}
.pg-preview-bullets li {
  display: flex; gap: 8px;
  line-height: 1.45;
}
.pg-preview-bullets li::before {
  content: "✓";
  color: var(--emerald);
  font-weight: 700;
  flex-shrink: 0;
}
.pg-result {
  padding: 14px 16px;
  border-top: 1px solid var(--border);
  background: var(--navy-900);
  max-height: 320px; overflow: auto;
  position: relative;
}
.pg-result::before {
  content: "RESULT";
  display: block;
  font-size: 10.5px; font-weight: 700;
  color: var(--emerald);
  letter-spacing: 0.08em;
  margin-bottom: 8px;
}
.pg-result pre {
  font-family: var(--font-mono); font-size: 12px;
  line-height: 1.55; white-space: pre-wrap; word-break: break-word;
  color: var(--text);
}

/* Loading shimmer */
.skel {
  background: linear-gradient(90deg, var(--navy-600) 0%, var(--navy-500) 50%, var(--navy-600) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.5s linear infinite;
  border-radius: 6px;
  height: 16px;
}
@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Key list */
.key-list { display: flex; flex-direction: column; gap: 10px; }
.key-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 14px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.key-meta { flex: 1; min-width: 0; }
.key-name { font-weight: 600; font-size: 14px; }
.key-prefix { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.key-dates { font-size: 12px; color: var(--text-dim); white-space: nowrap; }

/* Revoked-keys history. Collapsible <details> below the active
   key list — the row visually de-emphasizes (faded) and shows a
   "revoked" pill where the active row had a Revoke button. */
.revoked-keys {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.revoked-keys > summary {
  list-style: none;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 4px 0 10px;
  user-select: none;
  display: flex; align-items: center; gap: 8px;
}
.revoked-keys > summary::-webkit-details-marker { display: none; }
.revoked-keys > summary::before {
  content: "▸";
  color: var(--text-dim);
  font-size: 10px;
  transition: transform 120ms;
  width: 12px;
}
.revoked-keys[open] > summary::before { transform: rotate(90deg); }
.revoked-keys > summary:hover { color: var(--text); }
.key-row.revoked {
  opacity: 0.6;
  background: transparent;
  border-style: dashed;
}
.key-row.revoked .key-name,
.key-row.revoked .key-prefix {
  text-decoration: line-through;
  text-decoration-color: var(--text-dim);
  text-decoration-thickness: 1px;
}
.key-row .pill.bad {
  background: rgba(248, 113, 113, 0.12);
  color: #f87171;
  border: 1px solid rgba(248, 113, 113, 0.25);
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Minted-key banner */
.minted {
  background: var(--emerald-glow);
  border: 1px solid rgba(16, 185, 129, 0.35);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.minted-label {
  display: flex; align-items: center; gap: 6px;
  color: var(--emerald-2);
  font-weight: 600;
  font-size: 14px;
}
.minted-key {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
}
.minted-key code {
  flex: 1;
  font-size: 13px;
  background: transparent;
  border: none;
  padding: 0;
  word-break: break-all;
}
.minted-actions { display: flex; gap: 8px; }

/* Mint form */
.mint-form {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  align-items: stretch;
}
.mint-form input {
  flex: 1;
  font-family: inherit;
  background: var(--navy-800);
  border: 1px solid var(--border-light);
  color: var(--text);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 14px;
}
.mint-form input:focus {
  outline: none;
  border-color: var(--vercel-text);
  box-shadow: var(--vercel-focus);
}

/* Quick actions row */
.quick-links {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.quick-links a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: 6px;
}
.quick-links a:hover { color: var(--text); background: var(--vercel-elevated); }

/* Balance */
.balance {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.balance .unit {
  color: var(--text-muted);
  font-weight: 500;
  font-size: 13px;
  margin-left: 4px;
}

/* Credits card header: balance first, left-aligned */
.credits-head { padding: 20px 16px 8px; }
.credits-head-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.credits-head .balance { font-size: 36px; line-height: 1.1; }
.credits-head-hint {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 6px;
}

/* Credit ledger ("Activity") */
.ledger {
  margin-top: 24px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.ledger-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}
.ledger-table {
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.ledger-head, .ledger-row {
  display: grid;
  grid-template-columns: 140px 1fr 80px 90px;
  gap: 12px;
  padding: 8px 12px;
  font-size: 12.5px;
}
.ledger-head {
  background: var(--navy-900);
  color: var(--text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: 11px;
  border-bottom: 1px solid var(--border);
}
.ledger-row + .ledger-row { border-top: 1px solid var(--border); }
.ledger-row { color: var(--text); }
.ledger-row .right { text-align: right; }
.ledger-row .dim { color: var(--text-dim); }
.ledger-row .pos { color: #50e3c2; font-weight: 600; }  /* Vercel ready-cyan, not brand emerald */
.ledger-row .neg { color: var(--red); font-weight: 600; }
.ledger-sub {
  font-size: 11px; color: var(--text-dim);
  font-family: var(--font-mono);
  margin-top: 2px;
}
@media (max-width: 720px) {
  .ledger-head, .ledger-row {
    grid-template-columns: 100px minmax(0, 1fr) 60px 70px;
    font-size: 11.5px;
    padding: 8px;
  }
}
@media (max-width: 480px) {
  .ledger-head, .ledger-row { grid-template-columns: 72px minmax(0, 1fr) 52px 56px; gap: 8px; }
  .ledger-head { font-size: 10px; letter-spacing: 0; }
}

/* Pack grid */
.pack-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.pack {
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px;
  display: flex;
  flex-direction: column;
}
.pack-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 22px;
}
.pack-name { font-weight: 600; font-size: 14px; }
.pack-badge {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--emerald-2);
  background: var(--emerald-glow);
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}
.pack-credits {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 14px;
  font-variant-numeric: tabular-nums;
}
.pack-credits span {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  margin-left: 6px;
}
.pack-price {
  font-size: 14px;
  font-weight: 500;
  margin: 4px 0 16px;
}
.pack .btn-full { margin-top: auto; }
.pack-note { margin-top: 14px; }

/* Signing-secret block */
.secret-block {
  margin-top: 16px;
  padding: 14px 16px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.secret-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.secret-label {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 180px;
}
.secret-label > span:first-child {
  font-size: 13px; font-weight: 600; color: var(--text);
}
.secret-label .hint {
  font-size: 11.5px; color: var(--text-dim);
}
.secret-label code {
  background: transparent; border: 0; padding: 0; color: inherit;
  font-family: var(--font-mono); font-size: 11px;
}
.secret-value {
  display: flex; align-items: center; gap: 6px; flex: 1; min-width: 280px;
}
.secret-input {
  flex: 1;
  font-family: var(--font-mono); font-size: 12px;
  background: var(--navy-900);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 7px 10px;
  width: 100%;
}
.secret-snippet { margin-top: 12px; }
.secret-snippet summary {
  font-size: 12px; font-weight: 600; color: var(--text-muted);
  cursor: pointer; list-style: none;
  padding: 4px 0;
}
.secret-snippet summary::-webkit-details-marker { display: none; }
.secret-snippet summary::before {
  content: "+ "; color: var(--text-dim);
}
.secret-snippet[open] summary::before { content: "− "; }
.secret-snippet pre {
  margin-top: 8px;
  background: var(--navy-900);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--text);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Account section */
.acct-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: start;
  margin-bottom: 20px;
}
@media (max-width: 880px) {
  .acct-grid { grid-template-columns: 1fr; }
}
.acct-info { display: flex; flex-direction: column; gap: 10px; }
.acct-row {
  display: grid; grid-template-columns: 130px 1fr; gap: 10px; align-items: center;
}
.acct-label {
  font-size: 12px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.acct-value {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; color: var(--text);
}
.acct-value.mono code {
  font-family: var(--font-mono); font-size: 12.5px;
  background: var(--navy-800); border: 1px solid var(--border);
  padding: 4px 8px; border-radius: 6px;
}
.acct-actions {
  display: flex; flex-direction: column; gap: 8px; min-width: 200px;
}
.acct-actions .btn-secondary { text-align: center; text-decoration: none; }
.acct-pw {
  border-top: 1px solid var(--border);
  padding-top: 16px;
  margin-top: 8px;
}
.acct-pw > summary {
  font-size: 14px; font-weight: 600; color: var(--text);
  cursor: pointer; list-style: none; padding: 6px 0;
}
.acct-pw > summary::-webkit-details-marker { display: none; }
.acct-pw > summary::before {
  content: "+ "; color: var(--text-dim); font-weight: 400;
}
.acct-pw[open] > summary::before { content: "− "; }
.acct-pw-form {
  display: flex; flex-direction: column; gap: 12px;
  margin-top: 12px;
  max-width: 420px;
}
/* Legacy .pill.ok rule REMOVED — was emerald glow. New Vercel-aligned
   rules live at the bottom of the file with the Geist palette
   (cyan #50e3c2 for ready) and supersede this. */

/* Webhook list */
.webhook-list { display: flex; flex-direction: column; gap: 10px; }
.webhook-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.webhook-meta { flex: 1; min-width: 0; }
.webhook-url {
  font-weight: 600;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.webhook-events { display: flex; gap: 5px; margin-top: 4px; flex-wrap: wrap; }
.chip {
  background: var(--navy-700);
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
}
.webhook-status { font-size: 12px; color: var(--text-dim); }

/* Jobs table */
.jobs-table {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.thead, .trow {
  display: grid;
  grid-template-columns: 120px 90px 110px 90px 80px 70px 1fr 150px;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
}
.col-trust { font-size: 12px; }
.trow .col-trust .trow-trust {
  font-family: var(--font-mono);
  color: var(--text-dim);
}

/* Identities view filter pills — same shape as the mobile-nav pill
   bar but inline in the card head. */
.ident-filter {
  display: flex; gap: 6px; align-items: center;
}
.ident-pill {
  background: var(--navy-700);
  border: 1px solid var(--border);
  color: var(--text-muted);
  padding: 6px 12px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12.5px; font-weight: 500;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.ident-pill:hover { color: var(--text); }
.ident-pill.active {
  /* Vercel segmented-control active state — inverted (white-on-black). */
  background: var(--vercel-text);
  color: var(--vercel-bg);
  border-color: var(--vercel-text);
  font-weight: 500;
}
.thead {
  background: var(--navy-800);
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  font-weight: 600;
}
.trow + .trow { border-top: 1px solid var(--border); }
.trow { cursor: pointer; }
.trow:hover { background: var(--navy-800); }
.trow.active { background: var(--navy-800); border-left: 3px solid var(--emerald); padding-left: 11px; }
.trow .mono { font-family: var(--font-mono); font-size: 12px; }
.trow .actions { display: flex; gap: 4px; justify-content: flex-end; }

/* Job drawer: opens below the table when a row is clicked. */
.card-drawer {
  margin: 0 22px 20px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

/* Full-page job detail (/dashboard/jobs/<id>, opened in a new tab). */
.job-detail-page { max-width: 940px; margin: 0 auto; padding: 26px 24px 64px; }
.jdp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 26px; }
.jdp-logo { font-weight: 700; font-size: 18px; color: var(--text); text-decoration: none; letter-spacing: -0.02em; }
.jdp-logo:hover { opacity: 0.85; }
.jdp-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.jdp-title .mono { font-size: 12.5px; color: var(--text-muted); }
.jdp-actions { margin-left: auto; display: flex; gap: 6px; }
.jdp-body { background: var(--navy-800); border: 1px solid var(--border); border-radius: 12px; padding: 20px 22px; }
.jdp-body .drawer-section { margin-top: 18px; }
.card-drawer-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.card-drawer-head > div {
  display: flex; align-items: center; gap: 10px;
}
.card-drawer-head .mono { font-size: 12px; color: var(--text-muted); }
.card-drawer-body { padding: 14px; }
.card-drawer-body .kv {
  display: grid; grid-template-columns: 110px 1fr; gap: 6px 14px;
  font-size: 13px;
  margin-bottom: 12px;
}
.card-drawer-body .kv .k { color: var(--text-muted); }
.card-drawer-body .kv .v { color: var(--text); word-break: break-word; }
.card-drawer-body .kv .v.dim { color: var(--text-muted); }
.card-drawer-body pre {
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.5;
  background: var(--navy-900);
  padding: 12px; border-radius: 8px;
  max-height: 360px; overflow: auto;
  white-space: pre-wrap; word-break: break-word;
}
.card-drawer-body .drawer-section {
  margin-top: 12px;
}
.card-drawer-body .drawer-section h4 {
  font-size: 12px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em;
  margin-bottom: 6px;
}
.trow .actions button {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 3px 8px;
  border-radius: 5px;
  font-size: 11px;
  cursor: pointer;
  font-family: inherit;
}
.trow .actions button:hover { color: var(--text); border-color: var(--vercel-border-strong); }
.trow .actions a {
  color: var(--emerald);
  text-decoration: none;
  font-size: 11px;
  border: 1px solid var(--border);
  padding: 3px 8px;
  border-radius: 5px;
}

/* Status pill base — the comprehensive .pill.* color variants live
   near the bottom of the file (Vercel-aligned Geist palette: cyan
   ready, amber building, red error, muted idle). Only base shape
   declared here. The legacy emerald `.pill.completed` rule has
   been removed; .completed now resolves through the cyan "ready"
   variant via the bottom-of-file rule. */
.pill {
  /* shape only — colors come from .pill.ok/.warn/.bad/.idle at EOF */
}
/* Map run-state class names onto the canonical Vercel-aligned set
   so the existing JS that emits class="pill running" etc. keeps
   working without code changes. */
.pill.running   { color: #f5a623; background: rgba(245, 166, 35, 0.08); border: 1px solid rgba(245, 166, 35, 0.24); }
.pill.completed { color: #50e3c2; background: rgba(80, 227, 194, 0.08); border: 1px solid rgba(80, 227, 194, 0.24); }
.pill.queued    { color: var(--text-muted); background: var(--vercel-elevated); border: 1px solid var(--vercel-border-strong); }

/* Empty state — Vercel pattern. Lifted surface (#1a1a1a) matches
   the card hierarchy, solid hairline replaces the prior dashed
   border (dashed read as "construction zone" not as a friendly
   empty), generous vertical padding gives the content room to
   breathe. Icon block accepts either an inline SVG (preferred,
   styles below) or the legacy unicode glyph. */
.empty {
  text-align: center;
  padding: 56px 24px;
  color: var(--text-muted);
  background: var(--vercel-elevated);
  border: none;
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  border-radius: var(--radius);
}
.empty-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  margin: 0 auto 14px;
  border-radius: 10px;
  background: var(--vercel-hover);
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  color: var(--text-muted);
  font-size: 22px;
}
.empty-icon svg { width: 22px; height: 22px; stroke-width: 1.5; }
.empty h3 {
  font-size: 15px; font-weight: 600;
  color: var(--vercel-text);
  margin: 0 0 6px;
  letter-spacing: -0.005em;
}
.empty p {
  font-size: 13.5px; line-height: 1.6;
  max-width: 360px;
  margin: 0 auto 18px;
  color: var(--text-muted);
}
.empty pre {
  text-align: left;
  background: var(--navy-900);
  color: var(--text);
  padding: 12px 14px;
  border-radius: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  margin-top: 14px;
  overflow-x: auto;
}
/* Empty-state docs link — was inheriting browser-default dark blue
   which sat under the WCAG AA threshold against navy-700/800.
   Use emerald-2 (already meets contrast) so the call-to-docs is
   readable. QA 2026-06-08 (Identities view). */
.empty a,
.empty p a {
  /* Vercel link pattern in empty-states: foreground text + underline. */
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.empty a:hover { color: var(--text); }

/* Dashboard footer */
.dash-footer {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
}
.dash-footer a {
  color: var(--text-muted);
  text-decoration: none;
}
.dash-footer a:hover { color: var(--text); }

/* Toasts */
.toasts {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.toast {
  background: var(--navy-700);
  border: 1px solid var(--border-light);
  color: var(--text);
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 14px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  animation: toast-in 200ms ease-out;
}
.toast.ok { border-left: 3px solid var(--emerald); }
.toast.warn { border-left: 3px solid #f59e0b; }
.toast.err { border-left: 3px solid var(--red); }
@keyframes toast-in {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* Responsive */
/* Intermediate breakpoint — the dashboard sidebar steals ~220px of
   horizontal real estate, so the 8-column jobs grid overflows from
   ~1100px down until the existing 720px override fires. Without this
   middle step the table introduced horizontal scroll on every common
   laptop width. UX audit 2026-06-08. Drops the lower-priority columns
   (credits + trust) early; the higher-info columns (job id, status,
   age, actions) keep their full layout. */
@media (max-width: 1100px) and (min-width: 721px) {
  .thead, .trow {
    grid-template-columns: 110px 80px 100px 80px 1fr 140px;
  }
  .thead .col-credits, .trow .col-credits { display: none; }
  .thead .col-trust,   .trow .col-trust   { display: none; }
}

@media (max-width: 720px) {
  .thead, .trow {
    grid-template-columns: 90px 70px 90px 70px 1fr 110px;
    gap: 8px;
    font-size: 12px;
    padding: 8px 10px;
  }
  .thead .col-credits, .trow .col-credits { display: none; }
  .thead .col-trust,   .trow .col-trust   { display: none; }
  .mint-form { flex-direction: column; }
  .auth-card { padding: 24px; }
}

/* Small-mobile header + playground summary tweaks. Pre-fix h1 sat at
   26px on a 16px-padded viewport — on 320px screens that's ~80% of
   the available row width and the subtitle wrapped to 4 lines.
   Playground summary grid stayed 3-column on phones, cramming LLM /
   Max steps / Steps taken into <120px each. UX audit 2026-06-08. */
@media (max-width: 560px) {
  .dash-header h1 { font-size: 20px; }
  .dash-header p  { font-size: 12.5px; }
  .pg-summary-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 380px) {
  .pg-summary-grid { grid-template-columns: 1fr; }
}

/* ---------- Multi-view dashboard (sub-routes) ----------
   Each .dash-view is a "page" shown when its data-view matches the
   active sidebar item. The global [hidden] rule already takes care
   of suppressing the non-active ones; this block adds the Overview
   quick-actions grid so the landing view has real content instead
   of just the metrics row. */
.dash-view { display: block; }

.quick-actions {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}
@media (max-width: 1100px) {
  .quick-actions { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .quick-actions { grid-template-columns: 1fr; }
}
.qa-card {
  background: var(--vercel-elevated);
  border: none;
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.qa-card:hover {
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
  background: var(--vercel-elevated);
  transform: translateY(-1px);
}
.qa-ico {
  /* Vercel quick-action icon — neutral tinted tile, not emerald wash.
     Icon glyph picks up muted-foreground so the title carries the
     hierarchical weight, not the icon color. */
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--vercel-elevated);
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 14px;
}
.qa-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
}
.qa-sub {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.4;
}
.qa-sub code {
  font-size: 12px;
  background: rgba(255,255,255,0.04);
  padding: 1px 5px;
  border-radius: 4px;
}

/* Playground toolbar — replaces the redundant card-head title.
   The page-level header (h1 + subtitle from VIEW_META) already names
   the view; the card just needs the status pill and nothing else. */
.pg-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 14px 22px 0;
}

/* ============ PLAYGROUND IMPROVEMENTS ============ */

/* Visual model selector — replaces the boring LLM <select>.
   Horizontally scrollable so all 5 buttons fit on narrow viewports. */
.pg-model-selector {
  display: flex;
  gap: 7px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
  /* Fade the right edge so a clipped model card reads as "scroll for more"
     rather than a cut-off bug (matches the templates strip). */
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 22px), transparent);
  mask-image: linear-gradient(to right, black calc(100% - 22px), transparent);
}
.pg-model-selector::-webkit-scrollbar { display: none; }
.pg-model-btn {
  flex: 0 0 auto;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 13px;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color 120ms, background 120ms;
  min-width: 100px;
}
.pg-model-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.pg-model-sub {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
  white-space: nowrap;
}
.pg-model-btn:hover {
  border-color: var(--vercel-border-strong);
  background: var(--vercel-elevated);
}
.pg-model-btn.active {
  /* Vercel inversion — selected model reads as the inverted CTA color
     so it can't be confused with brand emerald. Same pattern as
     .pg-tpl.active and .ident-pill.active. */
  border-color: var(--vercel-text);
  background: var(--vercel-text);
}
.pg-model-btn.active .pg-model-name { color: var(--vercel-bg); }
.pg-model-btn.active .pg-model-sub { color: rgba(0,0,0,0.7); opacity: 1; }

/* Visual separator between task/model section and credentials. */
.pg-divider {
  height: 1px;
  background: var(--border);
  margin: 2px 0;
}

/* ─── Redesigned Playground (2026-06-10) ──────────────────────────────
   Goals:
   - Task is the hero, not a label squeezed between a chip-grid and a
     model picker. Bigger, framed, more breathing room.
   - Secondary knobs (steps / egress / OS) live on ONE horizontal row.
   - Credentials in their own paired row — same density.
   - Cost estimate next to Run so customers see what they're about to
     spend.
   - Tighter overall vertical rhythm — fits on a 13" laptop without
     scrolling, used to spill below the fold.
*/

/* Templates strip — one horizontal scroll line, quieter than the
   wrapping grid which used to fight the textarea for attention. */
.pg-templates-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
}
.pg-templates-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  position: relative;
}
.pg-templates-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
}

/* Recent tasks menu — appears next to the templates label once the
   user has run at least one task. Stores the last 6 prompts in
   localStorage so reload-and-tweak is one click. */
.pg-recent-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: border-color 120ms, color 120ms;
}
.pg-recent-btn:hover {
  border-color: var(--vercel-border-strong);
  color: var(--text);
}
.pg-recent-count {
  background: var(--navy-700);
  color: var(--text);
  padding: 0 6px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  min-width: 16px;
  text-align: center;
}
.pg-recent-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  background: var(--navy-800);
  border: 1px solid var(--border-light);
  border-radius: 10px;
  padding: 6px;
  min-width: 320px;
  max-width: 480px;
  z-index: 60;
  box-shadow: 0 12px 32px rgba(0,0,0,0.45);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pg-recent-item {
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 8px 10px;
  text-align: left;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  transition: background 120ms;
}
.pg-recent-item:hover { background: var(--vercel-elevated); }
.pg-recent-item .pg-recent-time {
  font-size: 10.5px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.pg-recent-item .pg-recent-preview {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pg-recent-empty {
  padding: 12px;
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
}

/* Keyboard hint inside the Run task button — small subtle chip on
   the right of the label. Visible at all times so the shortcut is
   discoverable without hovering. */
.pg-kbd-hint {
  display: inline-block;
  margin-left: 10px;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 500;
  padding: 1.5px 6px;
  border-radius: 4px;
  background: rgba(0,0,0,0.15);
  color: rgba(0,0,0,0.5);
  letter-spacing: .04em;
}
.btn-primary:hover .pg-kbd-hint { color: rgba(0,0,0,0.7); }
.btn-primary:disabled .pg-kbd-hint { opacity: 0.6; }
.pg-templates {
  /* Override the old wrap behavior — keep it one row, scroll
     horizontally when the chips overflow. Hide the scrollbar
     because the user navigates by clicking, not scrolling.   */
  flex-wrap: nowrap !important;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
  margin: 0;
  /* Fade the right edge so a partially-clipped chip clearly
     reads as "scroll for more" instead of a layout bug. The
     CSS audit 2026-06-10 flagged "X Tw…" as looking broken. */
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 32px), transparent);
  mask-image: linear-gradient(to right, black calc(100% - 32px), transparent);
}
.pg-templates::-webkit-scrollbar { display: none; }

/* Task hero — frames the textarea so it's visually unmissable. The
   textarea itself keeps the existing .pg-field input styling for
   focus state. */
.pg-hero {
  background: var(--navy-800);
  border: 1px solid var(--border-light);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 8px;
  transition: border-color 120ms;
}
.pg-hero:focus-within {
  border-color: var(--vercel-border-strong);
}
.pg-hero-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
}
.pg-hero textarea {
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  resize: vertical;
  min-height: 110px;
  outline: none;
}
.pg-hero textarea::placeholder {
  color: var(--text-dim);
  opacity: 1;
}

/* Flat field — no big gap, smaller label. Used everywhere except the
   task hero. */
.pg-field-flat { gap: 4px; }
.pg-mini-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .07em;
  display: flex; align-items: center; gap: 8px;
}
.pg-mini-label .pg-hint {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.pg-tag-mini {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(16,185,129,0.10);
  color: var(--emerald-2);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
}
.pg-mini-link {
  margin-left: auto;
  background: transparent;
  border: 0;
  padding: 0;
  color: var(--emerald-2);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  font-size: 11px;
  cursor: pointer;
  font-family: inherit;
}
.pg-mini-link:hover { color: var(--text); }

/* Compact horizontal config row — Egress / Max steps / OS fingerprint
   on one line. Collapses to stacked at narrow widths. */
.pg-config-strip {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1.3fr);
  gap: 12px;
}
@media (max-width: 720px) {
  .pg-config-strip { grid-template-columns: 1fr; }
}
/* Two-knob variant (Max steps + OS) after the managed Egress region was
   removed — Browsa no longer provides proxies, so egress is BYO/direct. */
.pg-config-strip.pg-config-2 { grid-template-columns: minmax(0,1fr) minmax(0,1.6fr); }
@media (max-width: 720px) {
  .pg-config-strip.pg-config-2 { grid-template-columns: 1fr; }
}

/* Credentials pair — LLM key + Agents key side-by-side. Two columns
   that collapse to one on narrow widths. */
.pg-creds {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 720px) {
  .pg-creds { grid-template-columns: 1fr; }
}

/* Run area — cost estimate sits next to the primary CTA. */
.pg-run-area {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Wrap the actions onto their own row instead of crushing the cost
     estimate into a per-word vertical column when the form is narrow —
     the Schedule control pushed the row over the column width. */
  flex-wrap: wrap;
  gap: 12px 16px;
  /* Sit inline as the clear final step of the form. It was previously
     position:sticky/bottom (viewport-pinned) so Run stayed reachable, but a
     pinned bar floats OVER the Advanced-settings / egress fields as you scroll
     through them — obscuring inputs. Inline is cleaner; ⌘↵ from the task box
     already runs without scrolling to the button. */
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 10px;
}
@media (max-width: 720px) {
  .pg-run-area { flex-direction: column; align-items: stretch; }
}
/* Below the stacked breakpoint the form is one column and the preview sits
   under it — a viewport-pinned Run would float over the preview, so let it
   sit inline again. */
@media (max-width: 1200px) {
  .pg-run-area { position: static; box-shadow: none; }
}
.pg-cost-estimate {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
}
.pg-cost-line {
  display: flex; gap: 8px; align-items: baseline;
  font-size: 12px;
}
.pg-cost-label {
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 10.5px;
  font-weight: 600;
  min-width: 96px;
}
.pg-cost-val { color: var(--text); font-weight: 500; white-space: nowrap; }

/* Run area button alignment override — keep the primary CTA right-
   aligned and at a comfortable size against the cost estimate. */
.pg-run-area .pg-actions {
  margin-top: 0;
  flex-shrink: 0;
  flex-wrap: wrap;
  /* Right-align — including when wrapped onto its own row below the cost. */
  margin-left: auto;
  justify-content: flex-end;
}
.pg-run-area .btn-primary {
  padding: 0 22px;
  height: 38px;
  font-size: 14px;
}

/* Extra empty-state copy below the bullets. */
.pg-preview-empty-sub {
  font-size: 12.5px;
  color: var(--text-dim);
  max-width: 360px;
  margin-bottom: 8px;
}
.pg-preview-tips {
  margin-top: 10px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
  max-width: 360px;
  width: 100%;
}
.pg-preview-tips-head {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--text-muted);
  margin-bottom: 8px;
  text-align: left;
}
.pg-preview-tips-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
  text-align: left;
  font-size: 12px;
  color: var(--text-dim);
}
.pg-preview-tips-list li {
  display: flex; gap: 8px;
  line-height: 1.45;
}
.pg-preview-tips-list li::before {
  content: "·";
  color: var(--text-muted);
  font-weight: 700;
  flex-shrink: 0;
}

/* Browser chrome bar above the live preview iframe.
   Traffic-light dots + pill address bar make the preview look like
   a real desktop browser — reinforces that this is a real Chromium
   session, not a headless API call. */
.pg-preview-chrome {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--navy-900);
  flex-shrink: 0;
}
.pg-chrome-dots {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}
.pg-chrome-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}
.pg-chrome-dot:nth-child(1) { background: #ff5f57; opacity: 0.65; }
.pg-chrome-dot:nth-child(2) { background: #ffbd2e; opacity: 0.65; }
.pg-chrome-dot:nth-child(3) { background: #28c940; opacity: 0.65; }
.pg-chrome-bar {
  flex: 1;
  background: var(--navy-700);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 14px;
  font-size: 11.5px;
  font-family: var(--font-mono);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  transition: color 200ms, background 200ms;
}
.pg-chrome-bar.live {
  color: var(--emerald-2);
  background: rgba(16,185,129,0.05);
  border-color: rgba(16,185,129,0.3);
}
.pg-chrome-bar.done { color: var(--emerald-2); }
.pg-chrome-bar.warn { color: #fbbf24; }
.pg-chrome-bar.err  { color: #fca5a5; }

/* Live-session iframe overlay — sits on top of the embedded stream
   iframe and fades out once the iframe finishes its first load.
   Avoids the ~1s blank-white-flash while the Angular SPA boots
   inside the frame. */
.pg-live-overlay {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 14px;
  background: var(--navy-900);
  transition: opacity 350ms ease-out;
  pointer-events: none;
}
.pg-live-pulse {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: rgba(16,185,129,0.1);
  border: 2px solid var(--emerald);
  animation: live-pulse 2s ease-in-out infinite;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.pg-live-pulse::after {
  content: '';
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--emerald);
}
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0.35); }
  50%       { box-shadow: 0 0 0 14px rgba(16,185,129,0); }
}
.pg-live-label {
  font-size: 14px; font-weight: 600; color: var(--text);
}

/* Terminal-state icon shown in the preview after a task completes
   or fails. Replaces the live noVNC pulse with a static, color-coded
   check / X so the iframe area doesn't sit on "Failed to connect"
   from the dead noVNC client. */
.pg-done-icon {
  width: 56px; height: 56px;
  border-radius: 50%;
  font-size: 28px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.pg-done-icon.ok  { background: rgba(16,185,129,0.15); color: var(--emerald-2);
                    border: 2px solid rgba(16,185,129,0.4); }
.pg-done-icon.err { background: rgba(239,68,68,0.12);  color: #fca5a5;
                    border: 2px solid rgba(239,68,68,0.4); }
.pg-done-icon.warn { background: rgba(245,158,11,0.12); color: #fbbf24;
                    border: 2px solid rgba(245,158,11,0.42); }

/* Pop-out button — floats top-right of the iframe so power users
   can pop the live view into a full tab without scrolling. */
.pg-live-popout {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(15,23,41,0.75);
  border: 1px solid var(--border-light);
  color: var(--text);
  border-radius: 6px;
  text-decoration: none;
  font-size: 14px; font-weight: 700;
  backdrop-filter: blur(8px);
  transition: background 120ms, color 120ms, border-color 120ms;
}
.pg-live-popout:hover {
  background: var(--emerald);
  color: var(--navy-900);
  border-color: var(--emerald);
}

/* Step counter moves into the chrome bar row */
.pg-preview-chrome .pg-step {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
}

/* ─── Design overhaul 2026-06-08 ────────────────────────────────────
   Bottom-of-file shipped together by the design pass. Includes:
     (a) Status pill component (Vercel-style capsule + dot)
     (b) Monospace ID pill (Linear-style)
     (c) Row + button micro-transitions
     (d) Shimmer keyframe for skeleton loaders
   All ADDITIONS — no existing rules touched, so this layers on top
   without breaking the current visual tree. */

/* ── Status pills — capsule with leading colored dot.
   Reuse for run states (queued/running/succeeded/failed) and any
   semantic state we surface (active/disabled/expired). Border + bg
   are tinted with the accent's own hue so the pill carries meaning
   without screaming. */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 10px;
  border-radius: 9999px;
  font: 600 11px/1 var(--font-sans), system-ui, sans-serif;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  white-space: nowrap;
  vertical-align: middle;
}
.pill::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}
/* Pill palette discipline (Vercel pattern):
   • .ready / .success / .completed — cyan #50e3c2 (Geist "Ready")
   • .ok (generic "this is fine" badge for static labels like a plan
     tier, role, or account-status) — NEUTRAL muted gray. Vercel uses
     gray badges for non-runtime labels; cyan is reserved for live
     deployment states. Using cyan on "Pay-as-you-go" / "OWNER" was
     making static labels read as runtime status indicators. */
.pill.ready,
.pill.success {
  color: #50e3c2;
  background: rgba(80, 227, 194, 0.08);
  border-color: rgba(80, 227, 194, 0.24);
}
.pill.ok {
  color: var(--text-muted);
  background: var(--vercel-elevated);
  border-color: var(--vercel-border-strong);
}
.pill.warn,
.pill.queued,
.pill.pending {
  color: #f5a623;
  background: rgba(245, 166, 35, 0.08);
  border-color: rgba(245, 166, 35, 0.24);
}
.pill.bad,
.pill.error,
.pill.failed {
  color: #ff4d4f;
  background: rgba(255, 77, 79, 0.08);
  border-color: rgba(255, 77, 79, 0.20);
}
.pill.idle,
.pill.neutral {
  color: var(--text-muted);
  background: var(--vercel-elevated);
  border-color: var(--vercel-border-strong);
}

/* ── Monospace ID pill — render UUIDs, job IDs, key prefixes, and
   webhook IDs in this style. Linear ships this for every `ENG-2703`
   reference; it's what makes a developer platform feel like one. */
.mono-pill,
code.mono-pill,
.id-pill {
  font-family: var(--font-mono), ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text-muted);
  background: var(--navy-800);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
  vertical-align: baseline;
}
.mono-pill:hover, .id-pill:hover { color: var(--text); border-color: var(--border-light); }

/* ── Micro-transitions baseline — buttons, links, table rows, and
   nav items pick up a 120ms ease on color/background so the app
   stops feeling static. No transform, no scale — just calm fades. */
.btn-primary, .btn-secondary, .btn-ghost, .btn-danger,
a.dash-nav-item, .dmn-item, .pg-tpl, .ident-pill,
button[data-test-hook], button[data-del-hook] {
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}
/* Table-row hover bg lift — replaces the static-feeling default. */
.trow { transition: background-color 120ms ease; }
.trow:hover { background: var(--navy-700); }

/* ── Shimmer keyframe for skeleton loaders.
   Audit: current skeletons are flat gray bars — page visibly reflows
   when data arrives. This adds a 1.5s gradient sweep so loading
   reads as progress instead of broken. Apply via the .skel class
   that the JS skeleton helper already emits. */
@keyframes neoa-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.skel, .skeleton {
  position: relative;
  background: linear-gradient(
    90deg,
    var(--navy-800) 0%,
    var(--navy-700) 50%,
    var(--navy-800) 100%
  );
  background-size: 200% 100%;
  animation: neoa-shimmer 1.5s ease-in-out infinite;
  border-radius: 4px;
}

/* ─── Cmd-K command palette ────────────────────────────────────────────
   The stretch move from design audit 2026-06-08: "what makes a developer
   platform feel like a developer platform" — Linear's cmd-K plus monospace
   id treatment. Opens on ⌘K / Ctrl-K from any dashboard view; closes on
   esc / click-outside / command-select. Surfaces:
     • Jump-to-view  (Overview / Playground / Identities / Keys / …)
     • Quick actions (Mint a key, Register webhook, Buy credits)
     • UUID detection (paste a job id → "View job <id>")
     • Recent jobs (last 10, mono-pill styled) */
.cmdk-overlay {
  position: fixed; inset: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, 0.55);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 14vh;
  animation: cmdk-fade-in 100ms ease-out;
}
@keyframes cmdk-fade-in { from { opacity: 0; } to { opacity: 1; } }
.cmdk-modal {
  width: min(640px, calc(100vw - 32px));
  background: var(--vercel-surface);
  box-shadow:
    inset 0 0 0 1px var(--vercel-border-strong),
    0 32px 64px rgba(0, 0, 0, 0.65);
  border-radius: 10px;
  overflow: hidden;
  display: flex; flex-direction: column;
  max-height: 70vh;
}
.cmdk-input-row {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--vercel-border);
}
.cmdk-prompt {
  font: 500 11px var(--font-mono);
  color: var(--text-muted);
  padding: 3px 6px;
  background: var(--vercel-elevated);
  border-radius: 4px;
  letter-spacing: 0.04em;
}
#cmdk-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font: 400 15px/1.4 var(--font-sans);
  letter-spacing: -0.01em;
}
#cmdk-input::placeholder { color: var(--text-muted); }
.cmdk-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}
.cmdk-section {
  font: 500 10.5px var(--font-sans);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 8px 16px 4px;
}
.cmdk-item {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px;
  cursor: pointer;
  color: var(--text);
  font: 400 14px/1.3 var(--font-sans);
  letter-spacing: -0.01em;
  user-select: none;
  border-left: 2px solid transparent;
}
.cmdk-item.active,
.cmdk-item:hover {
  background: var(--vercel-elevated);
  border-left-color: var(--text);
}
.cmdk-item-glyph {
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.cmdk-item-label { flex: 1; }
.cmdk-item-sub {
  color: var(--text-muted);
  font-size: 12.5px;
  font-family: var(--font-mono);
}
.cmdk-empty {
  padding: 16px;
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
}
.cmdk-footer {
  display: flex; gap: 14px;
  padding: 8px 16px;
  border-top: 1px solid var(--vercel-border);
  color: var(--text-muted);
  font-size: 11.5px;
}
.cmdk-footer kbd {
  font: 500 10px var(--font-mono);
  background: var(--vercel-elevated);
  border: 1px solid var(--vercel-border-strong);
  border-radius: 3px;
  padding: 1px 5px;
  margin-right: 4px;
  color: var(--text);
}

/* Mono ID pill helper for inline rendering of UUIDs / key prefixes /
   job ids anywhere in the dashboard. Linear ships this pattern for
   `ENG-2703` — we apply it to every UUID + agent_id + key prefix. */
.id-pill {
  display: inline-flex; align-items: center;
  font: 500 11.5px/1 var(--font-mono);
  background: var(--vercel-elevated);
  color: var(--text);
  padding: 3px 6px;
  border-radius: 4px;
  letter-spacing: -0.01em;
  vertical-align: baseline;
  cursor: copy;
  transition: background 120ms;
}
.id-pill:hover { background: var(--vercel-hover); }
.id-pill.copied { background: rgba(80, 227, 194, 0.15); color: #50e3c2; }

/* ── Accessibility: respect prefers-reduced-motion (WCAG 2.3.3) ──────
   Several dashboard elements use infinite animations (skeleton shimmer,
   live-pulse status dots, toast slide-ins). For users who request
   reduced motion, collapse all animations/transitions to a single
   near-instant frame and disable smooth scrolling. Static content is
   unaffected; loaders still render, they just don't sweep. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ════════════════════════════════════════════════════════════════════
   Dashboard polish pass — structural skeletons, accessible confirm
   dialog, standardized empty/error states, and copy affordances.
   Added 2026-06-11. All within the existing Vercel-aligned token set.
   ════════════════════════════════════════════════════════════════════ */

/* ── Structural skeletons ──────────────────────────────────────────
   Mirror the shape of a real list row (avatar + two text lines + a
   trailing pill) so data arrival doesn't visibly reflow the layout.
   Reuses the existing .skel shimmer gradient + keyframes. */
.skel-list { display: flex; flex-direction: column; gap: 10px; }
.skel-row {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px;
  background: var(--vercel-surface);
  box-shadow: inset 0 0 0 1px var(--vercel-border);
  border-radius: var(--radius);
}
.skel-avatar { width: 34px; height: 34px; border-radius: 8px; flex: 0 0 auto; }
.skel-lines { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.skel-line { height: 11px; }
.skel-line.w60 { width: 60%; }
.skel-line.w40 { width: 38%; }
.skel-pill { width: 64px; height: 22px; border-radius: 999px; flex: 0 0 auto; }
.skel-balance {
  display: inline-block; width: 96px; height: 30px;
  border-radius: 6px; vertical-align: middle;
}

/* ── Standardized empty-state actions row ─────────────────────────── */
.empty-actions {
  display: flex; flex-wrap: wrap; gap: 10px;
  align-items: center; justify-content: center;
  margin-top: 4px;
}
/* Buttons inside .empty must not inherit the .empty a underline. */
.empty-actions .btn-primary,
.empty-actions .btn-secondary {
  text-decoration: none;
}
.empty-actions .btn-secondary { color: var(--vercel-text); }
.empty-actions .btn-secondary:hover { color: var(--vercel-text); }
/* Error variant of the empty card — amber icon, retry affordance. */
.empty-error .empty-icon { color: #f5a623; }

/* ── Accessible confirm dialog (replaces window.confirm) ──────────── */
.confirm-overlay {
  position: fixed; inset: 0;
  z-index: 10001;
  background: rgba(0, 0, 0, 0.6);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: cmdk-fade-in 120ms ease-out;
}
.confirm-overlay.closing { animation: cmdk-fade-in 120ms ease-out reverse; }
.confirm-modal {
  width: min(420px, calc(100vw - 48px));
  background: var(--vercel-surface);
  box-shadow:
    inset 0 0 0 1px var(--vercel-border-strong),
    0 24px 56px rgba(0, 0, 0, 0.6);
  border-radius: 12px;
  padding: 22px 22px 18px;
  animation: confirm-pop 140ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes confirm-pop {
  from { transform: translateY(6px) scale(0.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.confirm-title {
  font-size: 16px; font-weight: 600;
  color: var(--vercel-text);
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}
.confirm-body {
  font-size: 13.5px; line-height: 1.6;
  color: var(--text-muted);
  margin: 0 0 20px;
}
.confirm-actions {
  display: flex; justify-content: flex-end; gap: 10px;
}
.confirm-actions .btn-primary,
.confirm-actions .btn-secondary,
.confirm-actions .btn-danger-solid {
  min-width: 92px; justify-content: center;
}

/* Solid danger button — for destructive confirm CTAs where a filled
   red reads as the consequence (revoke/delete). Distinct from the
   ghost .btn-danger used inline in tables. */
.btn-danger-solid {
  display: inline-flex; align-items: center; justify-content: center;
  height: 34px; padding: 0 14px;
  font-size: 13px; font-weight: 500; font-family: inherit;
  border-radius: var(--radius);
  background: var(--red);
  color: #fff;
  border: none; cursor: pointer;
  transition: filter 120ms ease, transform 80ms ease;
}
.btn-danger-solid:hover { filter: brightness(1.08); }
.btn-danger-solid:active { transform: translateY(1px); }

/* ── btn-small — was used in the Identities "Connect" cell but never
   styled, so it fell back to the raw UA button. Bring it into the
   system as a compact secondary. ─────────────────────────────────── */
.btn-small {
  display: inline-flex; align-items: center; gap: 4px;
  height: 26px; padding: 0 9px;
  font-size: 12px; font-weight: 500; font-family: inherit;
  border-radius: var(--radius);
  background: var(--vercel-surface);
  color: var(--vercel-text);
  box-shadow: inset 0 0 0 1px var(--vercel-border-strong);
  border: none; cursor: pointer;
  transition: background 120ms ease;
}
.btn-small:hover { background: var(--vercel-elevated); }

/* ── Copy-button "copied" confirmation state ──────────────────────── */
.pg-copy-btn.copied {
  color: #50e3c2;
  border-color: rgba(80, 227, 194, 0.4);
  background: rgba(80, 227, 194, 0.1);
}

/* ── Key-row prefix: mono code + inline copy chip ─────────────────── */
.key-prefix {
  display: flex; align-items: center; gap: 6px;
}
.key-prefix code.mono {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
}
.key-prefix .pg-copy-btn { width: 24px; height: 24px; font-size: 11px; }

/* Press affordance on primary/secondary/ghost buttons — cheap
   perceived-quality win, respects reduced-motion via the global block. */
.btn-primary:active,
.btn-secondary:active,
.btn-ghost:active { transform: translateY(1px); }

/* ════════════════════════════════════════════════════════════════════
   Playground focus pass — 2026-06-11 (revised: calmer)
   Earlier version added glows/texture/animation and read as too busy.
   Reverted to a quiet treatment: ONE emerald action to anchor the eye,
   a single soft static glow behind the idle preview, and hover-only lift
   on the pickable controls. No resting decoration, no looping motion.
   Additive (end of cascade) so no existing rule is edited.
   ════════════════════════════════════════════════════════════════════ */

/* ── The one focal action: emerald Run CTA ────────────────────────────
   Scoped to #pg-run so no other .btn-primary turns green. The Playground
   has many controls; giving exactly ONE element the brand color tells the
   eye where the path ends. A flat fill (no gradient/glow/animation) keeps
   it calm — it leads by color alone, not decoration. */
#pg-run {
  background: var(--emerald);
  color: #04140d;
  font-weight: 600;
  transition: background 150ms ease, transform 100ms ease;
}
#pg-run:hover:not(:disabled) { background: var(--emerald-2); filter: none; }
#pg-run:active:not(:disabled) { transform: translateY(1px); }
#pg-run:disabled {
  background: var(--vercel-elevated);
  color: var(--vercel-disabled);
}
/* kbd chip legible on the emerald fill */
#pg-run .pg-kbd-hint {
  background: rgba(4,20,13,0.16);
  color: rgba(4,20,13,0.6);
}
#pg-run:hover .pg-kbd-hint { color: rgba(4,20,13,0.78); }

.pg-cost-val { font-variant-numeric: tabular-nums; }
.pg-cost-line:first-child .pg-cost-val { color: var(--text); font-weight: 600; }

/* ── Calm idle preview ────────────────────────────────────────────────
   One soft, static brand glow behind the play disc — enough to signal
   "live session warms up here" without texture or motion. No dot-grid,
   no animation; a waiting screen should feel quiet, not busy. */
.pg-preview-empty::before {
  content: "";
  position: absolute;
  width: 320px; height: 320px;
  top: 50%; left: 50%;
  transform: translate(-50%, -60%);
  background: radial-gradient(circle, rgba(16,185,129,0.08) 0%, transparent 68%);
  pointer-events: none;
  z-index: 0;
}
.pg-preview-empty > * { position: relative; z-index: 1; }
.pg-preview-icon {
  opacity: 1;
  width: 56px; height: 56px;
  font-size: 20px;
  background: rgba(16,185,129,0.10);
  box-shadow: 0 0 0 1px rgba(16,185,129,0.28);
  padding-left: 3px; /* optically center the ▶ */
}

/* ── Quiet interaction affordances (only on hover, never at rest) ─────── */
.pg-tpl:hover { transform: translateY(-1px); }
.pg-model-btn:hover { transform: translateY(-1px); }

/* ════════════════════════════════════════════════════════════════════
   BYO proxy + Custom fingerprint — 2026-06-11
   Multilogin-style segmented controls for the per-dimension fingerprint
   overrides the API already honors. Lives inside collapsed disclosures,
   so the default Playground stays calm; power users opt in.
   ════════════════════════════════════════════════════════════════════ */

/* Proxy field uses mono so a pasted URL stays legible. */
#pg-proxy { font-family: var(--font-mono); font-size: 12.5px; width: 100%; }

/* BYO proxy block — provider dropdown reveals one pane at a time, so the
   form only shows the fields the chosen mode needs (stays calm). */
.pg-proxy-block { display: flex; flex-direction: column; gap: 8px; }
.pg-proxy-pane {
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px;
  background: var(--vercel-surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.pg-proxy-row2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.pg-proxy-row-thpp {
  display: grid; grid-template-columns: minmax(0,0.8fr) minmax(0,2fr) minmax(0,0.8fr); gap: 10px;
}
@media (max-width: 560px) {
  .pg-proxy-row2, .pg-proxy-row-thpp { grid-template-columns: 1fr; }
}
.pg-proxy-block input,
.pg-proxy-block select { font-size: 12.5px; }
#pg-proxy-host, #pg-proxy-user { font-family: var(--font-mono); }

/* Sticky-session checkbox aligns its baseline with the country select. */
.pg-proxy-sticky {
  display: flex; align-items: center; gap: 8px;
  align-self: end;
  padding-bottom: 9px;
  font-size: 12.5px; color: var(--text); cursor: pointer;
  user-select: none;
}
.pg-proxy-sticky input { width: 15px; height: 15px; accent-color: var(--emerald); cursor: pointer; flex: 0 0 auto; }
.pg-proxy-sticky .pg-hint { display: block; }

/* Live preview of the assembled gateway — makes the encoding transparent
   so a customer can eyeball it against their provider dashboard. */
.pg-proxy-preview {
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--text-muted);
  background: var(--vercel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  word-break: break-all;
}
.pg-proxy-preview b { color: var(--emerald-2); font-weight: 600; }
.pg-proxy-preview .k { color: var(--text-dim); }

/* Honest "this can lower trust" preamble — amber, low-key. */
.pg-fp-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
  background: rgba(245,158,11,0.06);
  border: 1px solid rgba(245,158,11,0.18);
  border-radius: 8px;
  padding: 9px 12px;
  margin: 0 0 4px;
}

.pg-fp-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.pg-fp-row {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

/* Segmented control — the screenshot's pill row. A track that holds
   equal-weight options; the active one lifts to an elevated surface
   with the brand accent. */
.pg-seg {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 3px;
  background: var(--vercel-surface);
  border: 1px solid var(--border);
  border-radius: 9px;
  width: fit-content;
  max-width: 100%;
}
.pg-seg-opt {
  flex: 0 0 auto;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 6px 14px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
.pg-seg-opt:hover { color: var(--text); }
.pg-seg-opt.active {
  background: var(--vercel-elevated);
  color: var(--emerald-2);
  box-shadow: 0 1px 2px rgba(0,0,0,0.35);
}

/* Custom sub-input revealed under a "Custom" segment (lat,lng / screen
   preset). Matches the dark .pg-field input styling — without this it fell
   back to the browser default (white box) and broke the OLED theme. */
.pg-fp-sub {
  margin-top: 2px;
  width: 100%;
  max-width: 320px;
  font-family: inherit;
  background-color: var(--navy-800);
  border: 1px solid var(--border-light);
  color: var(--text);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  transition: border-color 120ms, box-shadow 120ms;
}
.pg-fp-sub:focus {
  outline: none;
  border-color: var(--vercel-text);
  box-shadow: var(--vercel-focus);
}
.pg-fp-sub::placeholder { color: var(--text-dim); }
.pg-fp-sub[type="text"] { font-family: var(--font-mono); font-size: 12.5px; }
select.pg-fp-sub {
  appearance: none; -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='%2394a3b8'><path d='M3 4l3 3 3-3'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
  padding-right: 32px;
}

/* Effective-LLM resolver line — sits under the model cards and states, in
   plain language, the model + endpoint that will actually run. Resolves the
   ambiguity between the model dropdown, a jot_ auto-route, and the custom
   provider section. */
.pg-llm-resolved {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.pg-llm-resolved:empty { display: none; }
.pg-llm-resolved .k { color: var(--text-dim); }
.pg-llm-resolved b { color: var(--text); font-weight: 600; }
.pg-llm-resolved .via { color: var(--emerald-2); font-weight: 500; }
.pg-llm-resolved .ep { color: var(--text-dim); }

/* Provider-first selector. The segmented control spans wider segments so
   the three providers read as primary choices, not chips. */
.pg-provider-seg { width: 100%; }
.pg-provider-seg .pg-seg-opt { flex: 1 1 0; text-align: center; }
/* Custom-provider pane — contained surface like the proxy panes. */
.pg-custom-pane {
  gap: 10px;
  padding: 12px;
  background: var(--vercel-surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.pg-custom-pane .pg-advanced-help { margin: 0; }
.pg-custom-pane input { font-size: 12.5px; }
#pg-llm-base-url, #pg-llm-model-override { font-family: var(--font-mono); }
.pg-custom-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 10px;
}
@media (max-width: 560px) { .pg-custom-grid { grid-template-columns: 1fr; } }

/* ── Scrape view — one-shot quick endpoints ─────────────────────────── */
.sc-url-input {
  background: transparent !important; border: 0 !important; padding: 0 !important;
  font-family: var(--font-mono); font-size: 15px; color: var(--text);
  outline: none; width: 100%;
}
.sc-url-input::placeholder { color: var(--text-dim); }
.sc-extract-prompt {
  width: 100%; background: var(--vercel-surface); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; font-family: inherit; font-size: 13px;
  line-height: 1.5; color: var(--text); resize: vertical; min-height: 64px; outline: none;
}
.sc-extract-prompt:focus { border-color: var(--vercel-text); }
.sc-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.sc-chip {
  padding: 6px 12px; border-radius: 999px; font-family: inherit; font-size: 12.5px;
  font-weight: 500; color: var(--text-muted); background: var(--vercel-surface);
  border: 1px solid var(--border); cursor: pointer; transition: all 120ms;
}
.sc-chip:hover { color: var(--text); }
.sc-chip.active { background: var(--vercel-elevated); color: var(--emerald-2); box-shadow: inset 0 0 0 1px rgba(16,185,129,0.3); }
.sc-result-tabs { display: flex; gap: 2px; margin-left: auto; }
.sc-rtab {
  background: transparent; border: 0; color: var(--text-dim); font-family: var(--font-mono);
  font-size: 11.5px; padding: 4px 10px; border-radius: 6px; cursor: pointer;
}
.sc-rtab:hover { color: var(--text); }
.sc-rtab.active { background: var(--vercel-elevated); color: var(--emerald-2); }
/* Scraped output — scrollable mono/markdown panel filling the preview. */
.sc-output {
  position: absolute; inset: 0; overflow: auto; padding: 16px 18px;
  font-family: var(--font-mono); font-size: 12px; line-height: 1.6;
  color: var(--text); white-space: pre-wrap; word-break: break-word; background: var(--navy-900);
}
.sc-output img { max-width: 100%; height: auto; border-radius: 6px; display: block; }
.sc-output a { color: var(--emerald-2); text-decoration: none; }
.sc-output a:hover { text-decoration: underline; }
/* Emerald run button — same focal treatment as the Playground's. */
#sc-run { background: var(--emerald); color: #04140d; font-weight: 600; }
#sc-run:hover:not(:disabled) { background: var(--emerald-2); filter: none; }
#sc-run:active:not(:disabled) { transform: translateY(1px); }
#sc-run:disabled { background: var(--vercel-elevated); color: var(--vercel-disabled); }
#sc-run .pg-kbd-hint { background: rgba(4,20,13,0.16); color: rgba(4,20,13,0.6); }

/* ── Identity Quality drawer — trust / fingerprint / detection / connect ─ */
.idq-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 900px) { .idq-row { grid-template-columns: 1fr; } }
.idq-section { margin-bottom: 18px; }
.idq-h { font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 10px; display: flex; align-items: center; gap: 8px; }
.idq-h .idq-h-note { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--text-dim); }

/* Trust score block */
.idq-score { display: flex; align-items: baseline; gap: 10px; }
.idq-score-num { font-size: 34px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.idq-score-num.ok { color: var(--emerald-2); }
.idq-score-num.warn { color: var(--amber); }
.idq-score-num.bad { color: var(--red); }
.idq-score-max { font-size: 13px; color: var(--text-dim); }
.idq-score-band { font-size: 12.5px; font-weight: 600; }
.idq-bar { height: 6px; border-radius: 999px; background: var(--vercel-elevated); overflow: hidden; margin: 10px 0 14px; }
.idq-bar > span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--red), var(--amber) 70%, var(--emerald) 85%); }
.idq-factor { display: flex; align-items: center; gap: 10px; padding: 5px 0; border-top: 1px solid var(--border); font-size: 12.5px; }
.idq-factor:first-of-type { border-top: 0; }
.idq-factor .f-label { color: var(--text); flex: 1; }
.idq-factor .f-explain { color: var(--text-dim); font-size: 11px; }
.idq-factor .f-delta { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: 600; min-width: 42px; text-align: right; }
.idq-factor .f-delta.pos { color: var(--emerald-2); }
.idq-factor .f-delta.neg { color: var(--red); }
.idq-factor .f-delta.zero { color: var(--text-dim); }

/* Fingerprint kv list */
.idq-fp { display: flex; flex-direction: column; }
.idq-fp .kv { display: grid; grid-template-columns: 130px 1fr; gap: 10px; padding: 6px 0; border-top: 1px solid var(--border); font-size: 12px; }
.idq-fp .kv:first-child { border-top: 0; }
.idq-fp .kv .k { color: var(--text-muted); }
.idq-fp .kv .v { color: var(--text); font-family: var(--font-mono); word-break: break-word; }
.idq-warn { margin-top: 10px; font-size: 12px; line-height: 1.5; color: var(--text-muted); background: rgba(245,158,11,0.06); border: 1px solid rgba(245,158,11,0.18); border-radius: 8px; padding: 9px 12px; }

/* Detection harness meter */
.idq-detect-top { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.idq-detect-num { font-size: 22px; font-weight: 700; color: var(--emerald-2); font-variant-numeric: tabular-nums; }
.idq-detect-sub { font-size: 12px; color: var(--text-dim); }
.idq-verdicts { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.idq-verdict { font-size: 11px; font-family: var(--font-mono); padding: 3px 8px; border-radius: 6px; background: var(--vercel-surface); border: 1px solid var(--border); }
.idq-verdict.pass { color: var(--emerald-2); box-shadow: inset 0 0 0 1px rgba(16,185,129,0.2); }
.idq-verdict.fail { color: #fca5a5; box-shadow: inset 0 0 0 1px rgba(239,68,68,0.25); }

/* Connect block */
.idq-connect-note { font-size: 12.5px; color: var(--text-muted); margin: 0 0 10px; line-height: 1.5; }
.idq-snippet { position: relative; background: var(--vercel-bg); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; font-family: var(--font-mono); font-size: 11.5px; line-height: 1.6; color: var(--text); white-space: pre; overflow-x: auto; }
.idq-snippet-copy { position: absolute; top: 8px; right: 8px; }
.idq-snippet .tok-c { color: var(--text-dim); }
.idq-snippet .tok-s { color: var(--emerald-2); }
.idq-tabs { display: flex; gap: 2px; margin-bottom: 8px; }
.idq-tab { background: transparent; border: 0; color: var(--text-dim); font-family: var(--font-mono); font-size: 11.5px; padding: 4px 10px; border-radius: 6px; cursor: pointer; }
.idq-tab.active { background: var(--vercel-elevated); color: var(--emerald-2); }
.idq-skel { color: var(--text-dim); font-size: 12.5px; }

/* Webhook delivery history */
.wh-deliveries { padding: 0 2px 8px; }
.wh-deliv-list { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; margin-top: 4px; }
.wh-deliv-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-top: 1px solid var(--border); font-size: 12px; }
.wh-deliv-row:first-child { border-top: 0; }
.wh-deliv-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.wh-deliv-dot.ok { background: var(--emerald); }
.wh-deliv-dot.bad { background: var(--red); }
.wh-deliv-ev { font-family: var(--font-mono); color: var(--text); }
.wh-deliv-code { font-family: var(--font-mono); font-weight: 600; min-width: 38px; }
.wh-deliv-code.ok { color: var(--emerald-2); }
.wh-deliv-code.bad { color: #fca5a5; }
.wh-deliv-time { color: var(--text-dim); margin-left: auto; }
.wh-deliv-err { color: #fca5a5; font-family: var(--font-mono); max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Human-in-the-loop ask-user banner (Playground) */
.pg-ask {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  background: linear-gradient(180deg, rgba(16,185,129,0.14), rgba(16,185,129,0.06));
  border-bottom: 1px solid rgba(16,185,129,0.3);
  padding: 14px 16px; backdrop-filter: blur(6px);
}
.pg-ask-q { font-size: 13.5px; font-weight: 600; color: var(--text); margin-bottom: 10px; line-height: 1.45; }
.pg-ask-row { display: flex; gap: 8px; }
.pg-ask-row input {
  flex: 1; background: var(--vercel-bg); border: 1px solid var(--vercel-border-strong);
  border-radius: 8px; padding: 8px 12px; color: var(--text); font-family: inherit; font-size: 13px; outline: none;
}
.pg-ask-row input:focus { border-color: var(--emerald); }
.pg-ask-row .btn-primary { background: var(--emerald); color: #04140d; font-weight: 600; }

/* ════════════════════════════════════════════════════════════════════
   PHANTOM CONSOLE — dashboard redesign layer (2026). Appended last so its
   :root override wins the cascade. Because the navy, text and border
   tokens derive from the vercel tokens via var(), recoloring the base repaints
   every panel, table, input, badge and modal in one shot. Compact 6px
   radius is kept on purpose — this is a data-dense tool, not a hero.
   ════════════════════════════════════════════════════════════════════ */
:root{
  /* phantom surfaces */
  --vercel-bg:#06080D; --vercel-surface:#0B0F18; --vercel-elevated:#10141E;
  --vercel-hover:#161B28; --vercel-pressed:#1B2130;
  --vercel-text:#EAF0F8; --vercel-muted:#98A4B6; --vercel-disabled:#5C6878;
  --vercel-border:rgba(255,255,255,.07); --vercel-border-strong:rgba(255,255,255,.13);
  /* accent focus ring (replaces white double-ring, on-brand) */
  --vercel-focus:0 0 0 1px rgba(45,227,160,.55), 0 0 0 4px rgba(45,227,160,.22);
  --vercel-shadow-border:0 0 0 1px rgba(255,255,255,.07), 0 1px 1px rgba(0,0,0,.2), 0 4px 10px rgba(0,0,0,.25);
  /* phantom signal-green */
  --emerald:#2DE3A0; --emerald-2:#5FF0BE; --emerald-hover:#15B583; --emerald-glow:rgba(45,227,160,.16);
  --red:#FF5C6C; --amber:#F7B955;
  /* new tokens used by the layer below */
  --accent:#2DE3A0; --accent-2:#5FF0BE; --accent-glow:rgba(45,227,160,.18);
  --accent-faint:rgba(45,227,160,.08); --border-accent:rgba(45,227,160,.32);
  --on-accent:#04231A; --iris:#8B97FF;
  /* JetBrains Mono first for the technical type */
  --font-mono:"JetBrains Mono","Geist Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}
body{
  background-color:var(--vercel-bg);
  background-image:radial-gradient(58% 30% at 50% -10%, var(--accent-faint), transparent 72%);
  background-attachment:fixed; background-repeat:no-repeat;
}
::selection{ background:var(--accent-glow); color:var(--vercel-text); }
/* primary action → glowing signal-green (matches marketing CTA) */
.btn-primary{
  background:linear-gradient(180deg,var(--accent-2),var(--accent));
  color:var(--on-accent); font-weight:600;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 0 0 1px var(--accent-faint), 0 6px 16px -8px var(--accent-glow);
}
.btn-primary:hover{ filter:brightness(1.05); }
.btn-primary:disabled{
  background:var(--vercel-elevated); color:var(--vercel-disabled);
  box-shadow:none; filter:none;
}
.skip-link{ background:var(--accent); color:var(--on-accent); }
/* thin accent scrollbar */
*::-webkit-scrollbar{ height:10px; width:10px; }
*::-webkit-scrollbar-thumb{ background:var(--vercel-border-strong); border-radius:8px; }
*::-webkit-scrollbar-track{ background:transparent; }
@media (prefers-reduced-motion: reduce){ *,*::before,*::after{ animation-duration:.001ms!important; transition-duration:.001ms!important; } }

/* ====================================================================
   OVERVIEW REDESIGN (Vercel-inspired control plane) — 2026-06-20.
   Command bar + two-column (recent runs / sticky usage rail) + SVG
   quick actions. Appended last so the metrics/quick-action overrides
   win the cascade. All colors resolve through Phantom Console tokens.
   ==================================================================== */

/* command bar */
.ov-command{ display:flex; align-items:center; gap:12px; margin-bottom:20px; }
.ov-ws{ display:flex; align-items:center; gap:8px; padding:5px 8px 5px 5px; border-radius:var(--radius); box-shadow:inset 0 0 0 1px var(--vercel-border); text-decoration:none; color:var(--text); flex-shrink:0; transition:box-shadow 120ms ease; }
.ov-ws:hover{ box-shadow:inset 0 0 0 1px var(--vercel-border-strong); }
.ov-ws-avatar{ width:26px; height:26px; border-radius:var(--radius-sm); background:var(--vercel-surface); box-shadow:inset 0 0 0 1px var(--vercel-border); display:inline-flex; align-items:center; justify-content:center; font-size:12px; font-weight:600; color:var(--vercel-text); text-transform:uppercase; }
.ov-ws-name{ font-size:13px; font-weight:600; max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ov-ws svg{ width:14px; height:14px; color:var(--text-muted); }
.ov-search{ flex:1; min-width:0; display:flex; align-items:center; gap:8px; height:34px; padding:0 10px; background:var(--vercel-surface); box-shadow:inset 0 0 0 1px var(--vercel-border); border:none; border-radius:var(--radius); color:var(--text-muted); cursor:text; text-align:left; transition:box-shadow 120ms ease; }
.ov-search svg{ width:15px; height:15px; color:var(--text-muted); flex-shrink:0; }
.ov-search-ph{ flex:1; font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ov-kbd{ font-family:var(--font-mono); font-size:11px; padding:1px 6px; border-radius:var(--radius-sm); background:var(--vercel-elevated); color:var(--text-muted); box-shadow:inset 0 0 0 1px var(--vercel-border); flex-shrink:0; }
.ov-search:hover{ box-shadow:inset 0 0 0 1px var(--vercel-border-strong); }
.ov-search:focus-visible{ box-shadow:var(--vercel-focus), inset 0 0 0 1px var(--accent); }
.ov-run{ display:inline-flex; align-items:center; gap:7px; flex-shrink:0; }
.ov-run svg{ width:15px; height:15px; }
@media (max-width:880px){ .ov-command{ flex-wrap:wrap; } .ov-search{ order:3; flex-basis:100%; } .ov-run{ margin-left:auto; } }

/* densify the KPI strip (overrides .metrics-row / .metric / .metric-num) */
.metrics-row{ gap:10px; margin-bottom:16px; }
.metric{ min-height:76px; padding:14px; }
.metric-num{ font-size:26px; margin-top:6px; }

/* two-column grid + shared panel primitive */
.ov-grid{ display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:16px; align-items:start; margin-bottom:24px; }
.ov-main{ display:flex; flex-direction:column; gap:16px; min-width:0; }
.ov-rail{ position:sticky; top:16px; display:flex; flex-direction:column; gap:16px; }
@media (max-width:1100px){ .ov-grid{ grid-template-columns:1fr; } .ov-rail{ position:static; } }
.ov-panel{ background:var(--vercel-elevated); box-shadow:inset 0 0 0 1px var(--vercel-border); border-radius:var(--radius); overflow:hidden; }
.ov-panel-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 14px; box-shadow:inset 0 -1px 0 var(--vercel-border); }
.ov-panel-title{ font-size:12px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--text-muted); }
.ov-panel-link{ font-size:12px; color:var(--accent); text-decoration:none; display:inline-flex; align-items:center; gap:4px; }
.ov-panel-link:hover{ text-decoration:underline; }
.ov-panel-link svg{ width:13px; height:13px; }

/* recent runs list */
.ov-recent{ display:flex; flex-direction:column; }
.ovr-row{ display:grid; grid-template-columns:10px minmax(96px,1fr) auto auto auto; align-items:center; gap:10px; padding:9px 14px; text-decoration:none; color:inherit; box-shadow:inset 0 -1px 0 var(--vercel-border); transition:background 120ms ease; }
.ovr-row:last-child{ box-shadow:none; }
.ovr-row:hover{ background:var(--vercel-hover); }
.ovr-row:focus-visible{ box-shadow:var(--vercel-focus); border-radius:var(--radius-sm); }
.ovr-dot{ width:9px; height:9px; border-radius:50%; }
.ovr-completed{ background:#50e3c2; }
.ovr-running{ background:#f5a623; }
.ovr-input_required{ background:#f5a623; }
.ovr-failed{ background:#ff4d4f; }
.ovr-cancelled,.ovr-queued{ background:var(--vercel-disabled); }
.ovr-id{ font-family:var(--font-mono); font-size:12px; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ovr-kind{ font-size:11.5px; color:var(--text-muted); text-transform:uppercase; letter-spacing:.04em; }
.ovr-cost{ font-family:var(--font-mono); font-size:11.5px; color:var(--text-muted); font-variant-numeric:tabular-nums; }
.ovr-time{ font-size:11.5px; color:var(--text-muted); white-space:nowrap; }
.ovr-empty{ display:block; padding:30px 14px; text-align:center; color:var(--accent); font-size:13px; text-decoration:none; }
.ovr-empty:hover{ text-decoration:underline; }
.ovr-skel{ display:flex; flex-direction:column; gap:1px; padding:6px 0; }
.ovr-skel .skel{ height:20px; margin:9px 14px; border-radius:5px; }

/* usage health bars */
.usage-bars{ padding:14px; display:flex; flex-direction:column; gap:14px; }
.ub-top{ display:flex; justify-content:space-between; margin-bottom:6px; }
.ub-label{ font-size:12px; color:var(--text-muted); }
.ub-frac{ font-family:var(--font-mono); font-size:11.5px; color:var(--text); font-variant-numeric:tabular-nums; }
.ub-track{ height:8px; border-radius:999px; background:var(--vercel-pressed); overflow:hidden; }
.ub-fill{ display:block; height:100%; border-radius:999px; transition:width 480ms cubic-bezier(.4,0,.2,1); }
.ub-ok{ background:#50e3c2; }
.ub-bad{ background:#ff4d4f; }
.ub-run{ background:#f5a623; }
.ub-accent{ background:var(--accent); }
.ub-divider{ padding-top:14px; box-shadow:inset 0 1px 0 var(--vercel-border); }
@media (prefers-reduced-motion:reduce){ .ub-fill{ transition:none; } }

/* getting started list */
.gs-list{ display:flex; flex-direction:column; }
.gs-item{ display:grid; grid-template-columns:18px 1fr 14px; align-items:center; gap:10px; padding:13px 14px; text-decoration:none; color:var(--text); box-shadow:inset 0 -1px 0 var(--vercel-border); transition:background 120ms ease; }
.gs-item:last-child{ box-shadow:none; }
.gs-item:hover{ background:var(--vercel-hover); }
.gs-item:focus-visible{ box-shadow:var(--vercel-focus); border-radius:var(--radius-sm); }
.gs-ico{ width:16px; height:16px; color:var(--text-muted); }
.gs-text{ font-size:13px; }
.gs-chev{ width:14px; height:14px; color:var(--text-muted); }

/* quick actions — horizontal rows + green SVG icon tiles (was unicode glyphs) */
.quick-actions{ grid-template-columns:1fr 1fr; gap:12px; margin-bottom:0; }
@media (max-width:880px){ .quick-actions{ grid-template-columns:1fr; } }
.qa-card{ flex-direction:row; align-items:flex-start; gap:12px; padding:12px 14px; }
.qa-ico{ width:30px; height:30px; flex-shrink:0; border-radius:var(--radius-sm); background:var(--accent-faint); color:var(--accent); }
.qa-ico svg{ width:16px; height:16px; }
.qa-body{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.qa-title{ font-weight:600; font-size:14px; color:var(--text); }
.qa-sub{ font-size:12.5px; color:var(--text-muted); line-height:1.4; }

/* ════════════════════════════════════════════════════════════════════
   PLAYGROUND + FORM REFINEMENT (Phantom Console, 2026-06-22)
   Lifts the dense tool forms across Playground + Scrape + modals:
   scannable section labels, calmer vertical rhythm, zone separation,
   a contained custom-provider pane, balanced two-pane layout.
   Appended last so it wins over the base pg-* rules.
   ════════════════════════════════════════════════════════════════════ */

/* Scannable microcopy labels — uppercase, tracked, clear hierarchy. */
.pg-mini-label,
.pg-field > span,
.pg-templates-label,
.pg-hero-label {
  text-transform: uppercase;
  letter-spacing: .055em;
  font-size: 10.5px;
  font-weight: 650;
  color: var(--text-muted);
}
.pg-hint { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--faint); }
.pg-tag-mini { text-transform: none; letter-spacing: .02em; }

/* Calmer vertical rhythm so the long stack reads as grouped zones. */
.pg-form { gap: 20px; }

/* Task hero gets real presence — it's the thing customers think about. */
.pg-hero-label { font-size: 11px; }
.pg-hero textarea { min-height: 104px; }

/* Zone separation: a hairline before credentials marks
   "engine config" → "your keys" without adding chrome. */
.pg-creds {
  margin-top: 4px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 560px){ .pg-creds { grid-template-columns: 1fr; } }

/* Custom-provider pane: a contained, calm note instead of a wall of
   text dumped inline. Lower visual weight than the primary path. */
.pg-custom-pane {
  padding: 14px;
  background: var(--vercel-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  display: flex; flex-direction: column; gap: 12px;
}
.pg-advanced-help {
  font-size: 11.5px; line-height: 1.55; color: var(--faint);
  background: var(--accent-faint);
  border: 1px solid var(--border-accent);
  border-radius: var(--radius);
  padding: 10px 12px; margin: 0;
}
.pg-advanced-help strong { color: var(--text); }
.pg-advanced-help code { background: var(--elevated); }
.pg-custom-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px){ .pg-custom-grid { grid-template-columns: 1fr; } }

/* Resolved-LLM line: a quiet confirmation chip, not noise. */
.pg-llm-resolved:not(:empty) {
  font-size: 12px; color: var(--text-muted);
  font-family: var(--font-mono);
  background: var(--vercel-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 11px;
}

/* Input polish (all dashboard forms): accent focus already from tokens;
   add a hover affordance + slightly larger hit area. */
.pg-field input, .pg-field select, .pg-field textarea { padding: 11px 12px; }
.pg-field input:hover, .pg-field select:hover, .pg-field textarea:hover { border-color: var(--border-strong); }

/* Compact, less-empty idle preview. */
.pg-preview { min-height: 320px; }
.pg-preview-bullets { gap: 8px; }

/* Run area: clear primary anchor at the end of the form. */
.pg-run-area { margin-top: 6px; padding-top: 18px; border-top: 1px solid var(--border); }

/* Data-view coherence: table column headers adopt the same uppercase
   microcopy as the refined form labels, so tables + forms read as one
   system across Jobs / Identities / API Keys / Credits / Webhooks. */
.thead {
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 10.5px;
  font-weight: 650;
  color: var(--text-muted);
}

/* Account view labels join the uppercase-microcopy system too. */
.acct-label {
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 10.5px;
  font-weight: 650;
  color: var(--text-muted);
}

/* ════════════════════════════════════════════════════════════════════
   PLAYGROUND COMPONENT POLISH (Phantom Console, 2026-06-22b)
   Kills the jarring white "inversion" selected-state; unifies selection
   to one accent-tint language; calms the custom note; makes the idle
   preview an inviting ambient field instead of a flat void.
   ════════════════════════════════════════════════════════════════════ */

/* Selected = accent-tint (faint bg + accent ring + accent text) everywhere. */
.pg-model-btn.active {
  border-color: var(--border-accent);
  background: var(--accent-faint);
  box-shadow: inset 0 0 0 1px var(--border-accent);
}
.pg-model-btn.active .pg-model-name { color: var(--accent); }
.pg-model-btn.active .pg-model-sub  { color: var(--text-muted); opacity: 1; }

.pg-tpl.active, .pg-tpl.flagship.active {
  background: var(--accent-faint);
  color: var(--accent);
  border-color: var(--border-accent);
  box-shadow: inset 0 0 0 1px var(--border-accent);
  font-weight: 600;
}

.pg-seg-opt.active {
  background: var(--accent-faint);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--border-accent);
}

/* Custom-provider note: calm neutral panel, not a loud green box. */
.pg-advanced-help {
  background: var(--vercel-elevated);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.pg-advanced-help code { background: var(--vercel-surface); color: var(--accent); }

/* Idle preview: subtle ambient glow behind the play icon — inviting, not
   a flat dark void. The iframe (when running) sits on top and covers it. */
.pg-preview-body {
  background:
    radial-gradient(58% 48% at 50% 40%, var(--accent-faint), transparent 70%),
    var(--vercel-bg);
}
.pg-preview-icon {
  width: 56px; height: 56px; font-size: 24px;
  box-shadow: 0 0 44px -8px var(--accent-glow);
}

/* ── Scheduled tasks ─────────────────────────────────────────────────── */
/* Playground "Schedule" control — sits at the end of the run-action row. */
.pg-sched-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.pg-sched-select {
  background-color: var(--navy-800, #0d0d0d);
  border: 1px solid var(--border-light, #222);
  color: var(--text, #eee);
  border-radius: 8px;
  padding: 7px 10px;
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.pg-sched-select:focus { outline: none; border-color: var(--vercel-text); box-shadow: var(--vercel-focus); }

/* Scheduled view list rows. */
.sched-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 2px;
  border-bottom: 1px solid var(--border);
}
.sched-row:last-child { border-bottom: 0; }
.sched-main { flex: 1; min-width: 0; }
.sched-name { font-size: 14px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; }
.sched-task {
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sched-meta { margin-top: 5px; font-size: 11.5px; color: var(--text-dim); }
.sched-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.sched-actions .btn-ghost { padding: 6px 12px; font-size: 12.5px; }

/* Job output files (Browser Use "Files" panel) */
.job-files { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.job-file-dl {
  display: inline-flex; align-items: center; gap: 8px;
  background-color: var(--navy-800, #0d0d0d);
  border: 1px solid var(--border-light, #222);
  color: var(--text, #eee);
  border-radius: 8px; padding: 8px 12px;
  font-family: var(--font-mono); font-size: 12.5px;
  cursor: pointer; text-align: left; width: fit-content; max-width: 100%;
  transition: border-color 120ms ease, background 120ms ease;
}
.job-file-dl:hover { border-color: var(--emerald); }
.job-file-name { overflow: hidden; text-overflow: ellipsis; }
.job-recording-slot { margin-top: 8px; }
.job-recording-img {
  max-width: 100%; border-radius: 8px;
  border: 1px solid var(--border-light, #222);
  display: block;
}
