:root {
  --bg: #0b0e16;
  --bg2: #10141f;
  --panel: #151b2a;
  --panel2: #1a2136;
  --line: #26304a;
  --text: #e8ecf6;
  --muted: #8b95ad;
  --accent: #7c5cff;
  --accent2: #46c6ff;
  --ok: #2fbf71;
  --bad: #ff5470;
  --warn: #f4b740;
  --run: #46c6ff;
  --grad: linear-gradient(135deg, #7c5cff, #46c6ff);
  --radius: 16px;
  --r-sm: 10px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --glow1: rgba(124, 92, 255, .16);
  --glow2: rgba(70, 198, 255, .10);
  --topbar: rgba(11, 14, 22, .82);
  --hoverrow: rgba(124, 92, 255, .06);
  --steprow: rgba(255, 255, 255, .025);
  --shadow: rgba(0, 0, 0, .5);
}
:root[data-theme="light"] {
  --bg: #f4f5f9;
  --bg2: #ffffff;
  --panel: #ffffff;
  --panel2: #f7f8fc;
  --line: #e2e6f0;
  --text: #171c2b;
  --muted: #5f6b85;
  --ok: #148f4e;
  --bad: #d92b47;
  --run: #0d7fc4;
  --glow1: rgba(124, 92, 255, .10);
  --glow2: rgba(70, 198, 255, .08);
  --topbar: rgba(255, 255, 255, .85);
  --hoverrow: rgba(124, 92, 255, .05);
  --steprow: rgba(23, 28, 43, .035);
  --shadow: rgba(30, 40, 70, .18);
}
* { box-sizing: border-box; margin: 0; }
html, body { height: 100%; }
body {
  /* the glows live on the animated ::before aurora below, not here — two
     copies of the same gradients would double the haze */
  background: var(--bg);
  color: var(--text);
  font: 14px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  transition: background .25s, color .25s;
}
::selection { background: rgba(124, 92, 255, .35); }

/* ── the delight layer: the app should feel alive, never busy ──
   Every animation here is either (a) a one-shot on NAVIGATION, (b) driven by
   the user's own pointer, or (c) ambient and near-subliminal. Nothing loops
   at attention-grabbing amplitude, and all of it stands down for
   prefers-reduced-motion. */

/* ambient aurora: two glows drifting very slowly behind everything */
body::before {
  content: ""; position: fixed; inset: -20% -10%; z-index: -1; pointer-events: none;
  background:
    radial-gradient(600px 420px at 80% 10%, var(--glow1), transparent 65%),
    radial-gradient(520px 380px at 12% 85%, var(--glow2), transparent 60%);
  animation: aurora 26s ease-in-out infinite alternate;
}
@keyframes aurora {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(3%, -2%, 0) scale(1.06); }
}

/* each page ARRIVES — one soft rise per navigation, re-armed only by route() */
main.page-in > * { animation: rise .38s cubic-bezier(.22, .9, .3, 1) both; }
main.page-in > *:nth-child(2) { animation-delay: .04s; }
main.page-in > *:nth-child(3) { animation-delay: .08s; }
main.page-in > *:nth-child(4) { animation-delay: .12s; }
main.page-in > *:nth-child(n+5) { animation-delay: .16s; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }

/* the primary button carries a light sweep under the pointer */
.btn.primary { position: relative; overflow: hidden; }
.btn.primary::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -80%; width: 60%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .35), transparent);
  transform: skewX(-20deg); transition: left .45s ease;
}
.btn.primary:hover::after { left: 120%; }

/* modals pop into place instead of appearing */
.modal { animation: pop .26s cubic-bezier(.24, 1.2, .4, 1) both; }
@keyframes pop { from { opacity: 0; transform: translateY(14px) scale(.985); } }

/* only the NEWEST chat bubble animates — history stays still on repaint */
.chat-bubble:last-child { animation: bubble .22s ease-out both; }
@keyframes bubble { from { opacity: 0; transform: translateY(6px); } }

/* the brand answers a hover with a slow gradient shimmer */
.brand-name span { background-size: 200% 100%; }
.brand:hover .brand-name span { animation: shimmer 1.6s linear infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }

@media (prefers-reduced-motion: reduce) {
  body::before, main.page-in > *, .modal, .chat-bubble:last-child,
  .brand:hover .brand-name span { animation: none !important; }
  .btn.primary::after { display: none; }
}
/* one focus language everywhere — keyboard users get the same affordance
   mouse users get from hover */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }
/* quiet scrollbars that match the surface they live on */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 8px;
  border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--muted); }
::-webkit-scrollbar-track { background: transparent; }

/* ---------- top bar ---------- */
.topbar {
  display: flex; align-items: center; gap: 28px;
  padding: 14px 28px; position: sticky; top: 0; z-index: 20;
  background: var(--topbar); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand-logo { display: flex; }
/* official mark: white variant on dark, dark variant on light */
.brand-logo .logo-light { display: none; }
:root[data-theme="light"] .brand-logo .logo-light { display: block; }
:root[data-theme="light"] .brand-logo .logo-dark { display: none; }
.brand-name { font-size: 17px; font-weight: 700; letter-spacing: .2px; }
.brand-name span { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.brand-sub { font-size: 11.5px; color: var(--muted); }
#bundle-badge { color: var(--accent); font-family: var(--mono); }
.tabs { display: flex; gap: 4px; margin-left: 12px; }
.tabs a {
  color: var(--muted); text-decoration: none; font-weight: 600; font-size: 13.5px;
  padding: 8px 14px; border-radius: var(--r-sm); transition: all .15s;
  position: relative;
}
.tabs a:hover { color: var(--text); background: var(--panel2); }
/* the active tab is MARKED, not boxed: a gradient underline reads as "you are
   here" without adding yet another bordered rectangle to the bar */
.tabs a.active { color: var(--text); }
.tabs a.active::after { content: ""; position: absolute; left: 14px; right: 14px;
  bottom: 2px; height: 2.5px; border-radius: 2px; background: var(--grad); }
.top-right { margin-left: auto; display: flex; align-items: center; gap: 16px; }
.cluster-health { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); }
.dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.dot.ok { background: var(--ok); box-shadow: 0 0 8px rgba(47, 191, 113, .8); }
.dot.bad { background: var(--bad); box-shadow: 0 0 8px rgba(255, 84, 112, .8); }
.theme-btn {
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  width: 36px; height: 36px; border-radius: 10px; cursor: pointer; font-size: 16px;
  display: flex; align-items: center; justify-content: center; transition: transform .1s;
}
.theme-btn:hover { transform: scale(1.08); }

main { max-width: 1180px; margin: 26px auto 60px; padding: 0 24px; }
.footer { max-width: 1180px; margin: 0 auto 30px; padding: 0 24px; color: var(--muted); opacity: .7; font-size: 12px; }

h1.page-title { font-size: 24px; letter-spacing: -.015em; margin-bottom: 5px; }
p.page-sub { color: var(--muted); margin-bottom: 26px; font-size: 13.5px; max-width: 68ch; }

/* ---------- marketplace: selectable tiles + order bar ---------- */
.sku-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; }

.card {
  background: linear-gradient(180deg, var(--panel2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); padding: 20px;
  display: flex; flex-direction: column; gap: 12px; position: relative; overflow: hidden;
  box-shadow: 0 4px 24px var(--shadow);
}
/* the gradient strip is an ACCENT, not wallpaper: it appears when a card is
   interesting (hovered or selected), so selection state has somewhere to go */
.card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--grad); opacity: 0; transition: opacity .18s; }
.sku-card:hover::before, .sku-card.selected::before { opacity: .9; }
.card h3 { font-size: 16.5px; display: flex; align-items: center; gap: 10px; }
.card .desc { color: var(--muted); font-size: 13px; min-height: 34px; }

.sku-card { cursor: pointer; transition: transform .16s ease, box-shadow .16s, border-color .16s; user-select: none; }
.sku-card:hover { transform: translateY(-3px); box-shadow: 0 14px 38px var(--shadow); }
.sku-card .tick {
  position: absolute; top: 14px; right: 14px; width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid var(--line); display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; color: transparent; transition: all .15s; background: var(--panel);
}
.sku-card.selected { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(124, 92, 255, .25), 0 14px 38px var(--shadow); }
.sku-card.selected .tick { background: var(--grad); border-color: transparent; color: #fff; }
.sku-card .hint { color: var(--muted); font-size: 11.5px; }
.sku-card.selected .hint { color: var(--accent); font-weight: 600; }

.orderbar {
  position: fixed; left: 50%; transform: translateX(-50%) translateY(140%);
  bottom: 26px; z-index: 30;
  display: flex; align-items: center; gap: 18px;
  background: var(--bg2); border: 1px solid var(--line); border-radius: 16px;
  padding: 12px 14px 12px 22px; box-shadow: 0 18px 60px var(--shadow);
  transition: transform .28s cubic-bezier(.34,1.4,.64,1); max-width: 92vw;
}
.orderbar.show { transform: translateX(-50%) translateY(0); }
.orderbar .sum { font-weight: 700; font-size: 14px; white-space: nowrap; }
.orderbar .note { color: var(--muted); font-size: 11.5px; margin-top: 1px; }
.platform-line { color: var(--muted); font-size: 12.5px; margin: -12px 0 20px; }
.platform-line b { color: var(--run); font-weight: 600; }

/* ---------- stats / table / badges (shared) ---------- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 22px; }
.stat { background: linear-gradient(180deg, var(--panel2), var(--panel));
  border: 1px solid var(--line); border-radius: var(--radius); padding: 15px 18px;
  transition: transform .15s, box-shadow .15s; }
.stat:hover { transform: translateY(-2px); box-shadow: 0 10px 30px var(--shadow); }
.stat .n { font-size: 28px; font-weight: 750; font-variant-numeric: tabular-nums;
  letter-spacing: -.02em; line-height: 1.2; }
.stat .l { color: var(--muted); font-size: 11.5px; margin-top: 3px;
  text-transform: uppercase; letter-spacing: .05em; font-weight: 600; }
.stat.ok .n { color: var(--ok); } .stat.bad .n { color: var(--bad); } .stat.run .n { color: var(--run); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 18px; }

.btn {
  border-radius: var(--r-sm); padding: 9px 16px; font-weight: 650; font-size: 13.5px;
  cursor: pointer; transition: transform .08s, opacity .15s, box-shadow .15s,
  border-color .15s, filter .15s; color: var(--text);
  background: var(--panel2); border: 1px solid var(--line);
}
.btn:hover { transform: translateY(-1px); border-color: var(--accent); }
.btn:active { transform: translateY(0); }
.btn.primary { background: var(--grad); border: 0; color: #fff; box-shadow: 0 4px 18px rgba(124, 92, 255, .35); }
.btn.primary:hover { filter: brightness(1.08); box-shadow: 0 6px 22px rgba(124, 92, 255, .45); }
.btn.danger { background: rgba(255, 84, 112, .10); color: var(--bad); border: 1px solid rgba(255, 84, 112, .4); }
.btn.ghost { background: transparent; color: var(--muted); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn.sm { padding: 6px 12px; font-size: 12.5px; }
.btn.block { width: 100%; padding: 12px; font-size: 14.5px; }

.tablewrap { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th { text-align: left; color: var(--muted); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .07em; font-weight: 700; padding: 11px 16px;
  border-bottom: 1px solid var(--line); background: var(--panel2);
  position: sticky; top: 0; }
td { padding: 12px 16px; border-bottom: 1px solid var(--line); }
tbody tr { cursor: pointer; transition: background .12s, box-shadow .12s; }
/* row hover: a tinted surface plus an accent edge, so the eye tracks the row */
tbody tr:hover { background: var(--hoverrow); box-shadow: inset 3px 0 0 var(--accent); }
tbody tr:last-child td { border-bottom: 0; }
.mono { font-family: var(--mono); font-size: 12.5px; }
.muted { color: var(--muted); }

.badge { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700; padding: 3px 10px; border-radius: 999px; letter-spacing: .3px; }
.badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.badge.SUCCEEDED { color: var(--ok); background: rgba(47, 191, 113, .12); }
.badge.FAILED { color: var(--bad); background: rgba(255, 84, 112, .12); }
.badge.RUNNING, .badge.PENDING { color: var(--run); background: rgba(70, 198, 255, .12); }
.badge.RUNNING::before, .badge.PENDING::before { animation: pulse 1.2s infinite; }
.badge.SKIPPED { color: var(--muted); background: rgba(139, 149, 173, .15); }
.badge.WARNED { color: var(--warn, #d08700); background: rgba(208, 135, 0, .14); }
/* UNKNOWN is a real answer: the installer is gone and never said how it ended.
   It must not read as "in progress" (that is the lie this replaces) nor as a
   clean failure. */
.badge.UNKNOWN { color: var(--warn, #d08700); background: rgba(208, 135, 0, .14); }
/* Waiting on a person, not on a machine — so it must not pulse like RUNNING.
   APPROVED is equally not "in progress": it is ready and still needs someone to
   press Launch. */
.badge.AWAITING_APPROVAL { color: var(--warn, #d08700); background: rgba(208, 135, 0, .14); }
.badge.APPROVED { color: var(--accent2); background: rgba(70, 198, 255, .12); }
@keyframes pulse { 50% { opacity: .3; } }

/* ---------- identity, provenance, approval ---------- */
.identity { display: flex; align-items: center; gap: 8px; }
.who { display: flex; flex-direction: column; line-height: 1.25; text-align: right; cursor: help; }
.who-name { font-size: 12.5px; font-weight: 700; }
.who-perms { font-size: 10.5px; color: var(--muted); letter-spacing: .2px; }
/* Authentication is OFF on the API. This is not a neutral status chip: whoever
   is looking at the console needs to see that nothing they do is attributed. */
.identity-warn {
  font-size: 11px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
  color: var(--bad); background: rgba(255, 84, 112, .14);
  border: 1px solid var(--bad); padding: 3px 9px; border-radius: 999px;
}
.empty.signin { padding: 60px 20px; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.empty.signin h2 { font-size: 20px; }
.empty.signin p { max-width: 520px; text-align: center; }
/* The old free-text "Requested by" box, replaced by the verified identity. It
   is styled as a field so the form still reads as a form, but it is plainly not
   an input — the whole point is that it cannot be typed into. */
.readonly-id {
  padding: 9px 12px; border: 1px dashed var(--line); border-radius: 10px;
  background: var(--panel2); color: var(--muted); font-size: 13px;
}
.target-line, .prov, .approval {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 10px 0; padding: 9px 13px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel); font-size: 12.5px;
}
.target-line .k, .prov .k {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted);
}
.envclass { font-weight: 800; padding: 2px 9px; border-radius: 999px; font-size: 11px; letter-spacing: .3px; }
.envclass.prod { color: var(--bad); background: rgba(255, 84, 112, .14); }
.envclass.qa { color: var(--warn, #d08700); background: rgba(208, 135, 0, .14); }
.envclass.dev { color: var(--ok); background: rgba(47, 191, 113, .12); }
.envclass.unknown { color: var(--muted); background: rgba(139, 149, 173, .15); }
.prov.warn { border-color: var(--warn, #d08700); background: rgba(208, 135, 0, .07); }
.prov-warn { color: var(--warn, #d08700); font-weight: 700; }
.prov-ok { color: var(--ok); font-weight: 700; }
.approval { display: block; line-height: 1.5; }
.approval.pending { border-color: var(--warn, #d08700); background: rgba(208, 135, 0, .07); }
.approval.granted { border-color: var(--ok); background: rgba(47, 191, 113, .07); }
/* A disabled action must explain itself on hover rather than looking broken. */
.btn[disabled] { cursor: not-allowed; }

/* ---------- stage pipeline ---------- */
.pipeline { display: flex; align-items: center; margin: 18px 0 24px; flex-wrap: wrap; }
.pipe-node { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 110px; }
.pipe-circle {
  width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--line); background: var(--panel); font-size: 15px; font-weight: 800; color: var(--muted);
}
.pipe-node.SUCCEEDED .pipe-circle { border-color: var(--ok); color: var(--ok); background: rgba(47, 191, 113, .08); }
.pipe-node.FAILED .pipe-circle { border-color: var(--bad); color: var(--bad); background: rgba(255, 84, 112, .08); }
.pipe-node.RUNNING .pipe-circle { border-color: var(--run); color: var(--run); animation: ring 1.4s infinite; }
@keyframes ring { 50% { box-shadow: 0 0 0 7px rgba(70, 198, 255, .12); } }
.pipe-label { font-size: 12px; font-weight: 600; }
.pipe-time { font-size: 10.5px; color: var(--muted); font-family: var(--mono); }
.pipe-link { flex: 1; height: 2px; min-width: 26px; background: var(--line); margin: 0 4px 34px; }
.pipe-link.done { background: var(--ok); }

.prod { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 20px; margin-bottom: 14px; }
.prod-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.prod-head h4 { font-size: 15px; }
.prod-head .spacer { flex: 1; }
.timebar { height: 6px; border-radius: 4px; background: var(--grad); margin-top: 10px; opacity: .8; }
.steps { margin-top: 12px; display: grid; gap: 6px; }
.step { display: flex; align-items: center; gap: 10px; font-size: 12.5px; padding: 7px 12px; border-radius: 9px; background: var(--steprow); }
.step .phase { font-size: 10px; font-weight: 800; letter-spacing: .8px; color: var(--muted); width: 46px; text-transform: uppercase; }
.step .name { font-family: var(--mono); }
.step .spacer { flex: 1; }
.step .secs { color: var(--muted); font-family: var(--mono); font-size: 11.5px; }
.errorbox {
  background: rgba(255, 84, 112, .08); border: 1px solid rgba(255, 84, 112, .35);
  color: var(--bad); border-radius: 10px; padding: 12px 16px; font-family: var(--mono);
  font-size: 12.5px; white-space: pre-wrap; word-break: break-word; margin: 14px 0;
}

/* a state the API worked out afterwards — informative, not an error */
.reconciled {
  background: rgba(208, 135, 0, .07); border: 1px solid rgba(208, 135, 0, .35);
  border-radius: 10px; padding: 12px 16px; font-size: 12.5px; margin: 14px 0;
}
/* the preview no longer describes what the button would send */
.drift {
  background: rgba(208, 135, 0, .1); border: 1px solid rgba(208, 135, 0, .4);
  color: var(--warn, #d08700); border-radius: 10px; padding: 10px 14px;
  font-size: 12.5px; margin: 12px 0;
}
.manual-note { display: flex; align-items: center; gap: 12px; font-size: 12px;
  color: var(--warn, #d08700); margin: -6px 0 12px; }
.curl-block { margin-bottom: 10px; }
.curl-block.danger { color: var(--bad); }
.curl-cap { font-family: var(--mono); font-size: 11px; letter-spacing: .3px;
  text-transform: uppercase; opacity: .8; margin-bottom: 4px; }
.plan-existing {
  border: 1px solid rgba(208, 135, 0, .4); background: rgba(208, 135, 0, .07);
  border-radius: 10px; padding: 12px 14px; margin: 10px 0; font-size: 12.5px;
}
.plan-existing .adopt { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; }

/* ---------- modal ---------- */
.modal-bg { position: fixed; inset: 0; background: rgba(5, 7, 12, .6); backdrop-filter: blur(4px); z-index: 40; display: flex; align-items: flex-start; justify-content: center; overflow: auto; padding: 40px 16px; }
.modal { background: var(--bg2); border: 1px solid var(--line); border-radius: 18px; width: 720px; max-width: 100%; padding: 26px 28px; box-shadow: 0 30px 80px var(--shadow); }
.modal h2 { font-size: 19px; margin-bottom: 4px; }
.modal .sub { color: var(--muted); font-size: 13px; margin-bottom: 18px; }
.formgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; }
.field label { display: block; font-size: 11.5px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; margin-bottom: 5px; }
.field input, .field select, textarea {
  width: 100%; background: var(--panel2); color: var(--text); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 9px 12px; font-size: 13.5px; outline: none;
  transition: border .15s, box-shadow .15s;
}
.field input:focus, .field select:focus, textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(124, 92, 255, .16); }
textarea { font-family: var(--mono); font-size: 12px; line-height: 1.5; min-height: 180px; resize: vertical; }
.modal-actions { display: flex; gap: 10px; margin-top: 20px; align-items: center; }
.collapse-head { cursor: pointer; color: var(--run); font-size: 12.5px; font-weight: 700; margin: 16px 0 8px; user-select: none; }
.sku-pick { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 14px; }
.sku-pick .opt {
  padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel2);
  font-weight: 600; font-size: 13px; cursor: pointer; color: var(--muted); transition: all .12s;
}
.sku-pick .opt:hover { border-color: var(--accent); color: var(--text); }
/* selected state must be readable from across the room, not a tinted border */
.sku-pick .opt.on { color: #fff; border-color: transparent; background: var(--grad);
  box-shadow: 0 2px 10px rgba(124, 92, 255, .35); }
.sku-pick .opt.on::before { content: "✓ "; font-weight: 800; }
/* tri-state, same language as the marketplace cards: dashed = part of what
   this SKU sells is selected */
.sku-pick .opt.some { color: var(--text); border-color: var(--accent); border-style: dashed; }

#toast-root { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 10px; z-index: 60; }
.toast {
  background: var(--bg2); border: 1px solid var(--line); border-left: 3px solid var(--run);
  border-radius: 12px; padding: 12px 18px; font-size: 13.5px; max-width: 420px;
  box-shadow: 0 12px 40px var(--shadow); animation: slidein .18s ease-out;
}
.toast.err { border-left-color: var(--bad); }
.toast.ok { border-left-color: var(--ok); }
@keyframes slidein { from { transform: translateX(30px); opacity: 0; } }

.empty { text-align: center; color: var(--muted); padding: 60px 0; }
.empty .big { font-size: 40px; margin-bottom: 10px; }
.section-head { display: flex; align-items: center; margin: 26px 0 14px; gap: 12px; }
.section-head h2 { font-size: 16px; }
.section-head .spacer { flex: 1; }
code.inline { background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px; font-family: var(--mono); font-size: 12px; }
.curl { background: var(--panel2); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; font-family: var(--mono); font-size: 11.5px; color: var(--muted); white-space: pre-wrap; word-break: break-all; }
.back { color: var(--run); text-decoration: none; font-weight: 700; font-size: 13px; }

@media (max-width: 900px) { .market { grid-template-columns: 1fr; } .tray { position: static; } }

/* ---- plan preview (the step before anything changes) ---- */
.plan { margin: 14px 0; padding: 12px 14px; border: 1px solid var(--line);
        border-radius: 10px; background: var(--panel2); max-height: 46vh; overflow: auto; }
.plan-head { font-size: 13px; margin-bottom: 8px; }
.plan-head .ok { color: var(--ok); font-weight: 600; }
.plan-head .err { color: var(--bad); font-weight: 600; }
.plan-problems { margin: 6px 0 10px 18px; color: var(--bad); font-size: 12px; }
.plan-stage { margin: 10px 0 4px; font-size: 12px; letter-spacing: .08em;
              text-transform: uppercase; color: var(--muted); }
.plan-prod { padding: 6px 0 8px 10px; border-left: 2px solid var(--line); margin-bottom: 4px; }
.plan-steps { font-family: var(--mono); font-size: 11.5px; color: var(--muted);
              margin: 3px 0 3px 8px; }
.small { font-size: 11.5px; }
.btn.danger { background: var(--bad); color: #fff; border-color: transparent; }
.btn.danger:disabled { opacity: .45; cursor: not-allowed; }
.warn { color: var(--warn, #d08700); }

/* ---- sub-product (component) picker ---- */
.comp-pick { display: flex; flex-direction: column; gap: 6px; }
.comp-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.comp-prod { font-family: var(--mono); font-size: 11.5px; color: var(--muted);
             min-width: 92px; }
.comp { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
        padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
        cursor: pointer; user-select: none; background: var(--panel2);
        color: var(--muted); transition: all .12s; }
.comp:hover { border-color: var(--accent); color: var(--text); }
.comp.on { border-color: var(--accent); color: var(--text);
           background: rgba(124, 92, 255, .13); }

/* ── the stepped install modal: numbered sections, quiet prose, loud state ── */
.modal.m-stepped { padding: 0; overflow: hidden; width: 780px; }
.m-head { padding: 22px 28px 16px; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--panel2), transparent); }
.modal.m-stepped .sub { margin-bottom: 0; }
.mstep { padding: 18px 28px 20px; border-bottom: 1px solid var(--line); }
.mstep.m-tail { border-bottom: 0; padding-bottom: 12px; }
.mshead { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 14px; }
.mn { width: 24px; height: 24px; border-radius: 50%; background: var(--grad);
  color: #fff; font-weight: 800; font-size: 12.5px; display: flex; flex: none;
  align-items: center; justify-content: center; margin-top: 1px; }
.mshead h3 { font-size: 14.5px; margin: 0 0 2px; }
.msub { color: var(--muted); font-size: 12.5px; line-height: 1.45; }
/* labels inside the stepped modal: quiet sentence case, not shouty caps */
.modal.m-stepped .field label { text-transform: none; letter-spacing: .2px;
  font-size: 12.5px; font-weight: 650; }
.lbl-hint { font-weight: 400; color: var(--muted); opacity: .8;
  font-family: var(--mono); font-size: 11px; margin-left: 6px; }
.m-summary { background: var(--panel2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 13px; font-size: 12.5px; line-height: 1.55;
  margin-bottom: 10px; }
.m-summary:empty { display: none; }
.note-warn { display: flex; gap: 9px; align-items: flex-start;
  background: rgba(208, 135, 0, .09); border: 1px solid rgba(208, 135, 0, .35);
  border-radius: 10px; padding: 9px 12px; font-size: 12.5px; line-height: 1.5;
  color: var(--text); margin-bottom: 10px; }
/* actions stay in reach however long the form gets */
.modal.m-stepped .modal-actions { position: sticky; bottom: 0; margin-top: 0;
  padding: 14px 28px 18px; background: var(--bg2);
  border-top: 1px solid var(--line); }
/* the hand-edited JSON is the request now — these pickers no longer feed it,
   so they must not answer to a click either */
.locked { opacity: .4; pointer-events: none; filter: grayscale(1); }

/* ---- SKU card identity ---- */
.sku-card .sku-id { font-family: var(--mono); font-size: 11px; color: var(--muted);
                    margin: -4px 0 6px; }
.sku-card.featured { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }

/* ---- console additions ---- */
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; }
pre.report { max-height: 40vh; overflow: auto; background: var(--panel2);
             border: 1px solid var(--line); border-radius: 8px; padding: 10px;
             font-family: var(--mono); font-size: 11.5px; }
/* The BASE chip, which nothing ever declared. `.chip` is used on nearly every
   screen — envClass, chart versions, "platform", "already at …", the supplyIn
   file next to a value you must type — and the only rules for it were the two
   MODIFIERS below, both of which set `border-color` on a border that did not
   exist. So every chip in this console rendered as bare text, and the wizard's
   panels (which lean on them to say "dev", "secrets.gen.yaml", "optional") read
   as run-on sentences without it. Tokens only, so it follows the theme. */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; letter-spacing: .2px; white-space: nowrap;
  padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel2); color: var(--muted);
}
/* var(--bad) was never defined anywhere in this file, so BOTH declarations were
   invalid and a "you must supply this" chip was styled exactly like a neutral
   one. --bad is the red this theme actually defines, in light and dark. */
.chip.warnchip { border-color: var(--bad); color: var(--bad); }
/* "typed" marker on a supplied value — the input itself is a password field, so
   this is the only feedback that a value is present without revealing it. */
.chip.okchip { border-color: var(--ok, #2e7d32); color: var(--ok, #2e7d32); }

/* ---- card information architecture ---- */
.sku-card .includes { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 8px 0 4px; }
.sku-card .partof { font-size: 12px; color: var(--muted); margin: 8px 0 4px; }
.sku-card .meta { font-size: 10.5px; color: var(--muted); opacity: .75; margin-top: 8px; }
.sku-card.included { opacity: .72; border-style: dashed; }
.sku-card.included .tick { opacity: .5; }

/* ---- new-environment wizard ----
   Everything here is drawn from the theme tokens at the top of this file: the
   wizard is opened over a modal that already themes itself, and a panel that
   ignores the light/dark swap is the one that looks broken. */
.profile-row { display: flex; gap: 8px; align-items: center; }
.profile-row select { flex: 1; min-width: 0; }
.profile-row .btn { white-space: nowrap; }

/* Stacks ON TOP of the New-installation modal (z-index 40) rather than
   replacing it, and stays under the toasts (60) that report what it did. */
.envwiz-bg { z-index: 50; }
.envwiz { width: 640px; }

.wizsteps { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.wizstep {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12px;
  color: var(--muted); border: 1px solid var(--line); background: var(--panel2);
  border-radius: 999px; padding: 4px 12px 4px 6px;
}
.wizstep b {
  width: 18px; height: 18px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: 11px;
  background: var(--panel); border: 1px solid var(--line); color: var(--muted);
}
.wizstep.on { color: var(--text); border-color: var(--accent); }
.wizstep.on b { background: var(--grad); border-color: transparent; color: #fff; }
.wizstep.done { color: var(--text); }
.wizstep.done b { color: var(--ok); border-color: var(--ok); }

.envtargets { display: flex; flex-direction: column; gap: 8px; }
.envtarget {
  border: 1px solid var(--line); background: var(--panel); border-radius: 10px;
  padding: 10px 14px; cursor: pointer; transition: border-color .12s, background .12s;
}
.envtarget:hover { background: var(--hoverrow); }
.envtarget:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.envtarget .row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.envtarget .row .spacer { flex: 1; }
.envtarget .tname { font-weight: 700; }
.envtarget .why { margin-top: 4px; }
.envtarget.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* A cluster the registry disabled is not a choice — it is shown so the operator
   can see it exists and read why it is refused, not so they can click it. */
.envtarget.off { opacity: .5; cursor: not-allowed; }
.envtarget.off:hover { background: var(--panel); }

.ew-problems { margin: 10px 0 0 18px; padding: 0; color: var(--bad); font-size: 12px; }
.ew-notes { margin: 0 0 0 18px; padding: 0; font-size: 12.5px; }
.ew-preview .kv {
  display: grid; grid-template-columns: 110px 1fr; gap: 6px 12px; align-items: baseline;
}
.ew-preview .kv .k {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted);
}
.field input.bad { border-color: var(--bad); }

/* Not an error and not a note. An environment that exists only in a working tree
   installs on dev-class clusters and nowhere else, and that has to survive being
   skim-read on a success panel. */
.warnbox {
  border: 1px solid var(--warn); background: var(--panel); color: var(--text);
  border-left-width: 4px; border-radius: 10px; padding: 12px 16px;
  font-size: 12.5px; margin: 12px 0; line-height: 1.5;
}
.warnbox b { color: var(--warn); }
.warnbox .prov-note {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted);
  white-space: pre-wrap; word-break: break-word; margin: 6px 0;
}
.okline { color: var(--ok); font-size: 13.5px; font-weight: 600; margin-bottom: 4px; }
.okline b, .okline code { color: var(--text); }
.filelist {
  border: 1px solid var(--line); background: var(--panel2); border-radius: 10px;
  padding: 10px 14px; max-height: 30vh; overflow: auto;
}
.filelist > div { padding: 2px 0; word-break: break-all; }

/* ---- live installer log ---- */
pre.report.log {
  background: var(--panel2); max-height: 52vh; min-height: 140px;
  white-space: pre-wrap; word-break: break-word; color: var(--text);
}

/* ---- hierarchical selection ---- */
.comp-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
.comp-tick { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
             padding: 3px 9px 3px 6px; border: 1px solid var(--line);
             border-radius: 999px; cursor: pointer; user-select: none; }
.comp-tick .box { width: 12px; height: 12px; border: 1px solid var(--line);
                  border-radius: 3px; display: inline-block; }
.comp-tick.on { border-color: var(--accent); }
.comp-tick.on .box { background: var(--accent); border-color: var(--accent);
                     box-shadow: inset 0 0 0 2px var(--panel); }
.sku-card.partial { border-color: var(--accent); border-style: dashed; }
.sku-grid.compact .card { padding: 12px 14px; }

/* ---------- deploy assistant (chat) ---------- */
.chat-log { display: flex; flex-direction: column; gap: 8px; max-height: 46vh;
  overflow: auto; padding: 8px 2px; margin-bottom: 12px; }
.chat-bubble { max-width: 78%; padding: 9px 13px; border-radius: 12px;
  white-space: pre-wrap; line-height: 1.5; font-size: 14px; }
.chat-bubble.you { align-self: flex-end; background: var(--grad); color: #fff;
  border-bottom-right-radius: 4px; }
.chat-bubble.bot { align-self: flex-start; background: var(--panel2);
  border: 1px solid var(--line); border-bottom-left-radius: 4px; }
.chat-input { display: flex; gap: 8px; }
.chat-input input { flex: 1; }

/* ── Assistant: a Gemini/Copilot-style panel docked down the right edge,
      available from EVERY tab (✦ button in the topbar toggles it). ── */
.ai-toggle { border: 1px solid var(--line); background: var(--panel);
  color: var(--text); border-radius: 8px; padding: 7px 12px; cursor: pointer;
  font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.ai-toggle:hover, .ai-toggle.on { border-color: #7C5CFF; color: #7C5CFF; }
.ai-panel { position: fixed; top: 63px; right: 0; bottom: 0; width: 420px;
  background: var(--panel); border-left: 1px solid var(--line); z-index: 15;
  display: flex; flex-direction: column;
  transform: translateX(100%); visibility: hidden;
  transition: transform .18s ease, visibility .18s; }
body.ai-open .ai-panel { transform: none; visibility: visible; }
/* content steps aside instead of hiding under the panel */
body.ai-open main { margin-left: 24px; margin-right: 444px; }
body.ai-open .footer { margin-left: 24px; margin-right: 444px; }
.ai-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid var(--line); }
.ai-ctx { font-size: 11px; color: var(--muted); white-space: nowrap; }
.ai-title { font-weight: 700; font-size: 13.5px; flex: 1;
  background: var(--grad); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; }
.ai-panel .chat-log { flex: 1 1 auto; min-height: 110px; max-height: none;
  overflow: auto; padding: 12px 14px; margin: 0; }
.ai-panel .chat-bubble { max-width: 92%; font-size: 13px; }
.ai-form { flex: 0 1 auto; overflow-y: auto; max-height: 52%;
  border-top: 1px solid var(--line); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 10px; }
.ai-form h3 { font-size: 13px; display: flex; align-items: center; gap: 8px; }
.ai-panel .chat-input { padding: 10px 14px; border-top: 1px solid var(--line);
  position: relative; }
/* slash-command palette, Claude-Code style: anchored above the input */
.chat-cmds { display: none; position: absolute; bottom: calc(100% + 4px);
  left: 10px; right: 10px; background: var(--panel2);
  border: 1px solid var(--line); border-radius: 10px; overflow-y: auto;
  max-height: 220px; z-index: 5; box-shadow: 0 8px 24px rgba(0,0,0,.25); }
.cmd-row { display: flex; align-items: center; gap: 10px; padding: 7px 11px;
  font-size: 12.5px; cursor: pointer; }
.cmd-row.sel, .cmd-row:hover { background: rgba(124, 92, 255, .16); }
.cmd-name { font-weight: 700; font-family: ui-monospace, monospace; }
.cmd-hint { color: var(--muted); margin-left: auto; font-size: 11.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* combo: an input whose dropdown always shows the FULL option list on focus —
   unlike <datalist>, which filters by the current text and so hides every
   other option once a value is filled in */
.combo { position: relative; }
.combo input { width: 100%; }
.combo-menu { display: none; position: absolute; top: calc(100% + 4px);
  left: 0; right: 0; background: var(--panel2); border: 1px solid var(--line);
  border-radius: 10px; z-index: 40; max-height: 190px; overflow-y: auto;
  box-shadow: 0 8px 24px rgba(0,0,0,.25); }
.combo-item { padding: 7px 11px; font-size: 13px; cursor: pointer; }
.combo-item:hover, .combo-item.sel { background: rgba(124, 92, 255, .16); }

/* vault: store-a-secret / list references */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .grid2 { grid-template-columns: 1fr; } }
.vault-ref { margin-top: 12px; padding: 11px 13px; border: 1px solid var(--ok);
  background: rgba(47, 191, 113, .08); border-radius: 10px; font-size: 13px; }
.vault-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.vault-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel2); }
.vault-name { font-weight: 600; font-size: 13px; min-width: 130px; flex: none; }
code.copyable { cursor: pointer; word-break: break-all; }
code.copyable:hover { border-color: var(--accent); color: var(--accent); }

/* the read-only summary shown when an EXISTING environment is picked */
.env-summary { background: var(--panel2); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 12px; display: flex;
  flex-direction: column; gap: 5px; }
.env-summary div { display: flex; gap: 10px; font-size: 12.5px; min-width: 0; }
.env-summary span { color: var(--muted); width: 118px; flex: none;
  text-transform: uppercase; font-size: 10.5px; letter-spacing: .04em;
  padding-top: 2px; }
.env-summary b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* history: overlays the panel body below the header until a pick is made */
.chat-history { display: none; position: absolute; top: 50px; left: 0; right: 0;
  bottom: 0; z-index: 3; background: var(--panel); overflow-y: auto;
  padding: 12px 14px; flex-direction: column; gap: 8px; }
.hist-head { font-size: 11px; color: var(--muted); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; }
.hist-empty { color: var(--muted); font-size: 12.5px; }
.hist-row { display: flex; align-items: center; gap: 8px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 10px; cursor: pointer;
  background: var(--panel2); }
.hist-row:hover, .hist-row.current { border-color: #7C5CFF; }
.hist-body { flex: 1; min-width: 0; }
.hist-title { font-size: 13px; font-weight: 600; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.hist-when { font-size: 11px; color: var(--muted); margin-top: 2px; }
.ai-panel .chat-input input { background: var(--panel2);
  border: 1px solid var(--line); color: var(--text); border-radius: 8px;
  padding: 8px 10px; font-size: 13px; min-width: 0; }
.afield { display: flex; flex-direction: column; gap: 4px; }
.afield label { font-size: 11px; color: var(--muted); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; }
.afield input, .afield select { background: var(--panel2); border: 1px solid var(--line);
  color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13.5px;
  width: 100%; font-family: inherit; }
.afield input:focus, .afield select:focus { outline: none;
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(124, 92, 255, .16); }
.afield.bad input, .afield.bad select { border-color: #e5534b; }
.afield .ferr, .aside-foot .ferr { color: #e5534b; font-size: 11.5px; }
.sku-list { display: flex; flex-wrap: wrap; gap: 6px; }
.sku-pill { display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px;
  font-size: 12.5px; cursor: pointer; background: var(--panel2); user-select: none; }
.sku-pill input { accent-color: #7C5CFF; margin: 0; }
.sku-pill.on { border-color: #7C5CFF; }
.aside-foot { display: flex; flex-direction: column; gap: 8px;
  padding-top: 12px; border-top: 1px solid var(--line); }
.aside-status { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.aside-foot .btn[disabled] { opacity: .45; cursor: not-allowed; }
@media (max-width: 900px) {
  .ai-panel { width: 100vw; }
  body.ai-open main, body.ai-open .footer { margin-left: auto; margin-right: auto; }
}
