/* =========================================================
   BOS.Forge — Global stylesheet
   Design tokens sourced from docs/forge-ui.html mockup.
   All reusable styles live here. Do NOT add page-specific
   CSS files elsewhere — extend via utility classes below.
   ========================================================= */

/* ── Fonts ────────────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600&family=DM+Sans:wght@300;400;500;600;700&display=swap');

/* ── Design tokens (Dark theme — default) ─────────────── */
:root {
  --bg-deep: #060a1a;
  --bg-primary: #0b1028;
  --bg-surface: #111938;
  --bg-elevated: #162044;
  --bg-hover: #1a2650;

  --border: #1e2d5a;
  --border-subtle: #152040;

  --text-primary: #e2e8f4;
  --text-secondary: #7b8bb5;
  --text-muted: #4a5a85;

  --accent-blue: #4d8ef7;
  --accent-blue-dim: #3a6fd4;
  --accent-light: #7db4ff;
  --accent-glow: rgba(77, 142, 247, 0.12);
  --accent-glow-strong: rgba(77, 142, 247, 0.25);

  --success: #34d399;
  --success-dim: rgba(52, 211, 153, 0.15);
  --warning: #fbbf24;
  --warning-dim: rgba(251, 191, 36, 0.15);
  --danger: #f87171;
  --danger-dim: rgba(248, 113, 113, 0.15);

  --font-mono: 'JetBrains Mono', monospace;
  --font-sans: 'DM Sans', system-ui, -apple-system, sans-serif;

  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-xl: 12px;

  --transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  --slide-transition: 0.35s cubic-bezier(0.4, 0, 0.2, 1);

  --header-height: 44px;
  --footer-height: 32px;
}

/* ── Light theme ───────────────────────────────────────── */
[data-theme="light"] {
  --bg-deep:            #f4f5f7;
  --bg-primary:         #ffffff;
  --bg-surface:         #f0f1f4;
  --bg-elevated:        #e8eaef;
  --bg-hover:           #eceef2;

  --border:             #d8dbe3;
  --border-subtle:      #e2e5ec;

  --text-primary:       #1a1e2e;
  --text-secondary:     #555e75;
  --text-muted:         #8b93a8;

  --accent-blue:        #2b6fe6;
  --accent-blue-dim:    #2563c9;
  --accent-light:       #1d5bc2;
  --accent-glow:        rgba(43, 111, 230, 0.08);
  --accent-glow-strong: rgba(43, 111, 230, 0.14);

  --success:            #16a068;
  --success-dim:        rgba(22, 160, 104, 0.10);
  --warning:            #ca8a04;
  --warning-dim:        rgba(202, 138, 4, 0.10);
  --danger:             #dc4a4a;
  --danger-dim:         rgba(220, 74, 74, 0.10);
}

/* Light theme — component-level overrides for values that can't be expressed
   as simple token swaps (hardcoded rgba shadows, purple badge colours, etc.).
   Grouped here so all theme-specific rules are auditable in one place.     */

[data-theme="light"] .user-menu-dropdown,
[data-theme="light"] .ws-library-add-menu    { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10); }
[data-theme="light"] .conn-status-dropdown   { box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.08); }
[data-theme="light"] .ws-toolbar-overflow-menu { box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10); }
[data-theme="light"] .ws-preview-modal-panel,
[data-theme="light"] .ws-modal-panel         { box-shadow: 0 20px 60px rgba(0, 0, 0, 0.14); }
[data-theme="light"] .ws-preview-modal-overlay,
[data-theme="light"] .ws-modal-overlay       { background: rgba(0, 0, 0, 0.40); }
[data-theme="light"] .forge-help-panel       { box-shadow: 0 24px 60px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.07); }
[data-theme="light"] .forge-help-fab         { box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14), 0 2px 4px rgba(0, 0, 0, 0.10); }
[data-theme="light"] .forge-help-fab:hover   { box-shadow: 0 8px 22px rgba(0, 0, 0, 0.17), 0 3px 6px rgba(0, 0, 0, 0.12); }
[data-theme="light"] .vibe-attach-menu       { box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10); }

/* Glow colours — status dots use hardcoded dark-theme rgba values; remap to
   the light-theme success/accent equivalents.                               */
[data-theme="light"] .status-dot           { box-shadow: 0 0 6px rgba(22, 160, 104, 0.45); }
[data-theme="light"] .ws-step-dot.active   { box-shadow: 0 0 6px rgba(43, 111, 230, 0.35); }
[data-theme="light"] .conn-dot.ok          { box-shadow: 0 0 4px rgba(22, 160, 104, 0.40); }
[data-theme="light"] .conn-dot.bad         { box-shadow: 0 0 4px rgba(220, 74, 74, 0.40); }

/* Role badge border — hardcoded dark-theme blue; replace with light-theme blue. */
[data-theme="light"] .ws-msg-role-badge    { border-color: rgba(43, 111, 230, 0.20); }

/* Artifact type badge — purple tint at 15% opacity reads poorly on white;
   darken the text, lighten the fill, so WCAG AA contrast is preserved.     */
[data-theme="light"] .ws-artifact-type-badge {
  background:   rgba(109, 40, 217, 0.08);
  color:        #6d28d9;
  border-color: rgba(109, 40, 217, 0.18);
}

/* Jira auto-tag — hardcoded dark-blue background; use semantic glow token.  */
[data-theme="light"] .ws-jira-auto-tag     { background: var(--accent-glow); }

/* Mermaid zoom controls — glass backdrop is too dark on light backgrounds.  */
[data-theme="light"] .forge-sub-mermaid-zoom { background: rgba(0, 0, 0, 0.15); }

/* Forge Help messages scrollbar — rgba(255,255,255,0.15) is invisible on light. */
[data-theme="light"] .forge-help-messages::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

/* ── Smooth theme transitions ──────────────────────────── */
/* Scoped to chrome/container elements so existing animations (spinners,
   drags, slide panels) continue to use their own transition declarations. */
body,
.site-header,
.site-footer,
.app-main,
.ws-rail,
.ws-pane-toolbar,
.ws-chat-input-area,
.card-forge,
.surface,
.surface-elevated,
.input-forge,
.user-menu-dropdown,
.conn-status-dropdown,
.forge-help-panel {
  transition: background-color var(--transition), color var(--transition),
              border-color var(--transition);
}

/* ── Global reset + base ──────────────────────────────── */
* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

body {
  font-family: var(--font-sans);
  background: var(--bg-deep);
  color: var(--text-primary);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ── Scrollbars (global) ──────────────────────────────────
   One thin, token-coloured scrollbar for the whole app so the default
   OS scrollbar never leaks through. The chat and artifact preview panes
   keep their own explicit rules further below — this global default
   matches them, so there's no visual change to those. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
*::-webkit-scrollbar { width: 4px; height: 4px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 2px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
*::-webkit-scrollbar-corner { background: transparent; }

a { color: var(--accent-light); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--accent-blue); }

code, pre, .mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  color: var(--text-primary);
  margin: 0 0 0.5em;
}

p { margin: 0 0 1em; }

hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 24px 0;
}

.text-muted     { color: var(--text-muted) !important; }
.text-secondary { color: var(--text-secondary) !important; }

/* ── Layout shells ────────────────────────────────────── */
/* App-wide: header + footer pinned; only main scrolls */
.app-shell {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.app-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

/* ── Header / top nav ─────────────────────────────────── */
.site-header {
  height: var(--header-height);
  background: var(--bg-primary);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 16px;
  flex-shrink: 0;
  z-index: 100;
}

.site-header .brand {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 20px;
  border-right: 1px solid var(--border);
  margin-right: 4px;
  height: 100%;
  color: var(--text-primary);
}

.site-header .brand svg { width: 18px; height: 18px; color: var(--accent-blue); }

.site-header .brand-text {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-primary);
}

.site-nav {
  display: flex;
  align-items: center;
  height: 100%;
  gap: 0;
}

.site-nav-item {
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--transition), background var(--transition);
  position: relative;
  user-select: none;
  text-decoration: none;
}

.site-nav-item:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.site-nav-item.active {
  color: var(--accent-blue);
  background: var(--accent-glow);
}

.site-nav-item.active::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--accent-blue);
}

.site-header-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 100%;
}

/* ── Footer ───────────────────────────────────────────── */
.site-footer {
  height: var(--footer-height);
  background: var(--bg-primary);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 16px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.site-footer a { color: var(--text-muted); }
.site-footer a:hover { color: var(--text-secondary); }
.site-footer .spacer { flex: 1; }

/* Alpha-version chip — sits dead-center horizontally, independent of the surrounding flex
   children so the copyright on the left and links/widgets on the right don't shift it. */
.site-footer { position: relative; }
.site-footer-alpha {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  pointer-events: none;
}

/* ── Buttons ──────────────────────────────────────────── */
.btn-forge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all var(--transition);
  text-decoration: none;
  user-select: none;
  white-space: nowrap;
}

.btn-forge:hover {
  background: var(--bg-hover);
  border-color: var(--accent-blue-dim);
  color: var(--text-primary);
}

.btn-forge.primary {
  background: var(--accent-blue);
  border-color: var(--accent-blue);
  color: #fff;
}

.btn-forge.primary:hover {
  background: var(--accent-blue-dim);
  border-color: var(--accent-blue-dim);
  color: #fff;
}

.btn-forge.ghost {
  border-color: transparent;
  color: var(--text-secondary);
}

.btn-forge.ghost:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.btn-forge.lg {
  height: 40px;
  padding: 0 18px;
  font-size: 13px;
}

.btn-forge.block { width: 100%; }

.btn-forge svg { width: 14px; height: 14px; }

/* ── Icon button ──────────────────────────────────────── */
.icon-btn {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: all var(--transition);
  text-decoration: none;
}

.icon-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.icon-btn svg { width: 16px; height: 16px; }

/* ── Cards / surfaces ─────────────────────────────────── */
.surface {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.surface-elevated {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.card-forge {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
}

.card-title {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 12px;
}

/* ── Form controls ────────────────────────────────────── */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}

.field-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.field-hint {
  font-size: 11px;
  color: var(--text-muted);
}

.input-forge {
  height: 38px;
  width: 100%;
  padding: 0 12px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--text-primary);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
  transition: border-color var(--transition), box-shadow var(--transition);
}

.input-forge::placeholder { color: var(--text-muted); }

.input-forge:focus {
  border-color: var(--accent-blue);
  box-shadow: 0 0 0 3px var(--accent-glow);
}

.input-forge:disabled {
  opacity: 0.6;
  cursor: default;
}

.input-forge.has-error { border-color: var(--danger); }

.input-password-wrapper {
  position: relative;
  display: block;
}

.input-password-wrapper .input-forge {
  padding-right: 40px;
}

.input-password-toggle {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  transition: color var(--transition);
}

.input-password-toggle:hover {
  color: var(--text-primary);
}

textarea.input-forge {
  height: auto;
  min-height: 96px;
  padding: 10px 12px;
  line-height: 1.5;
  resize: vertical;
}

.check-forge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
}

.check-forge input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--accent-blue);
  cursor: pointer;
}

/* ── Auth — centered card over landing-style gradient ─── */
.auth-centered {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 64px 24px 48px;
  background:
    radial-gradient(ellipse at top, var(--accent-glow-strong), transparent 55%),
    var(--bg-deep);
}

.auth-centered-card {
  width: 100%;
  max-width: 440px;
  padding: 32px;
}

.auth-centered-alt {
  margin-top: 20px;
  font-size: 12px;
  color: var(--text-secondary);
  text-align: center;
}

.auth-centered-alt a {
  color: var(--accent-light);
  font-weight: 500;
  margin-left: 4px;
}

.auth-form-title {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 6px;
  background: linear-gradient(135deg, var(--text-primary), var(--accent-light));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.auth-form-subtitle {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 24px;
}

.auth-divider {
  text-align: center;
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1.5px;
  margin: 24px 0;
  position: relative;
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  position: absolute;
  top: 50%;
  width: calc(50% - 24px);
  height: 1px;
  background: var(--border);
}

.auth-divider::before { left: 0; }
.auth-divider::after  { right: 0; }

@media (max-width: 520px) {
  .auth-centered { padding: 32px 16px; }
  .auth-centered-card { padding: 24px; }
  .auth-form-title { font-size: 24px; }
}

/* ── Validation ───────────────────────────────────────── */
.validation-summary-valid { display: none; }

.validation-summary-errors {
  background: var(--danger-dim);
  border: 1px solid var(--danger);
  color: var(--danger);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  margin-bottom: 16px;
}

.validation-summary-errors ul {
  margin: 0;
  padding-left: 18px;
}

.field-validation-error {
  color: var(--danger);
  font-size: 11px;
  display: block;
  margin-top: 4px;
}

.input-validation-error { border-color: var(--danger) !important; }

/* Status messages passed via ?status / TempData */
.status-message {
  background: var(--accent-glow);
  border: 1px solid var(--accent-blue-dim);
  color: var(--accent-light);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  margin-bottom: 16px;
}

/* ── Status dot ──────────────────────────────────────── */
.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 6px rgba(52, 211, 153, 0.4);
  animation: pulse-dot 2s infinite;
  display: inline-block;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.5; }
}

/* Conference alpha QR — sits below the landing-hero CTAs. Two-column on wide viewports,
   stacks on narrow. The QR itself is a server-rendered inline SVG so there's no third-party
   image dependency to break at the booth. */
.landing-qr {
  display: flex;
  justify-content: center;
  margin: 40px auto 0;
  padding: 0 24px;
}
.landing-qr-card {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 20px 24px;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  max-width: 520px;
}
/* QR-only variant for the /alpha early-access card — drops the meta column so the QR
   sits alone, padded evenly. Larger QR since there's no neighboring content. */
.landing-qr-card--minimal {
  padding: 18px;
  gap: 0;
}
.landing-qr-card--minimal .landing-qr-img {
  width: 220px;
  height: 220px;
}
.landing-qr-img {
  flex-shrink: 0;
  width: 168px;
  height: 168px;
  background: #fff;
  border-radius: var(--radius-md);
  padding: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.landing-qr-img svg {
  display: block;
  width: 100%;
  height: 100%;
}
.landing-qr-meta {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.landing-qr-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.landing-qr-url {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--accent-blue);
  word-break: break-all;
}
.landing-qr-key-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 6px;
}
.landing-qr-key-label {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.landing-qr-key {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: 0.06em;
  padding: 3px 10px;
  border: 1px dashed var(--accent-blue-dim);
  border-radius: var(--radius-sm);
  background: var(--accent-glow);
}
.landing-qr-expires {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}
@media (max-width: 540px) {
  .landing-qr-card {
    flex-direction: column;
    text-align: center;
    align-items: center;
  }
  .landing-qr-meta { text-align: center; align-items: center; }
}

/* ── Landing page ─────────────────────────────────────── */
.landing-hero {
  padding: 56px 24px 32px;
  text-align: center;
  background:
    radial-gradient(ellipse at top, var(--accent-glow-strong), transparent 50%),
    var(--bg-deep);
}

.landing-hero h1 {
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
  background: linear-gradient(135deg, var(--text-primary), var(--accent-light));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.landing-hero p {
  font-size: 16px;
  color: var(--text-secondary);
  max-width: 620px;
  margin: 0 auto 32px;
  line-height: 1.6;
}

.landing-section {
  max-width: 960px;
  margin: 0 auto;
  padding: 32px 24px;
}

.landing-section h2 {
  font-size: 22px;
  margin-bottom: 8px;
}

.landing-section .lede {
  color: var(--text-secondary);
  margin-bottom: 24px;
}

.landing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 24px;
}

/* Force-3-up modifier — used on the Who-it's-for section where the "trio of role
   cards" reads better all on one row even at the section's tighter widths. Collapses
   to a single column on phones to avoid 100px cards. */
.landing-grid-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 600px) {
  .landing-grid-3 { grid-template-columns: 1fr; }
}

.landing-feature {
  padding: 20px;
}

.landing-feature h3 {
  font-size: 14px;
  margin-bottom: 8px;
}

.landing-feature p {
  font-size: 12px;
  color: var(--text-secondary);
  margin: 0;
}

/* ── Landing section variants — visual rhythm between sections ──────────────
   Default .landing-section sits on var(--bg-deep). To break the page into
   alternating bands, wrap a section in .landing-band; this paints the band
   edge-to-edge while the inner .landing-section keeps its max-width centered. */
.landing-band {
  background: var(--bg-primary);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.landing-band-accent {
  background:
    radial-gradient(ellipse at center top, var(--accent-glow), transparent 70%),
    var(--bg-primary);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Small uppercase eyebrow above a section heading — same vocabulary as
   .config-card-title from the in-app surfaces, so the brand voice carries
   across marketing + product. */
.landing-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--accent-light);
  margin-bottom: 8px;
}

/* Centered-section variant — used for hero-style intros below the actual hero. */
.landing-section-centered { text-align: center; }
.landing-section-centered .lede { max-width: 640px; margin: 0 auto 24px; }

/* Hero tagline — bigger than .landing-hero p, smaller than h1. Headline-y
   one-liner that sits between the brand and any supporting copy. */
.landing-hero-tagline {
  font-size: 22px;
  font-weight: 500;
  color: var(--text-primary);
  max-width: 720px;
  margin: 0 auto 12px;
  line-height: 1.4;
}

/* SDLC phase card — eyebrow-style numeral, tighter copy than .landing-feature
   so 4 phases fit comfortably on a wide viewport. */
.landing-phase {
  padding: 24px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.landing-phase-num {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--accent-light);
  margin-bottom: 12px;
}
.landing-phase h3 { font-size: 16px; margin: 0 0 6px; color: var(--text-primary); }
.landing-phase p {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}

/* Process-flow row — the 4 themes in "How it works" rendered left-to-right with
   arrows between. On narrow viewports the row stacks vertically and the arrow
   rotates 90° so it still reads as a flow. */
.landing-flow {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin-top: 24px;
}
.landing-flow > .landing-phase { flex: 1; min-width: 0; }
.landing-flow-arrow {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  color: var(--accent-light);
}
.landing-flow-arrow svg { width: 20px; height: 20px; }
@media (max-width: 900px) {
  .landing-flow { flex-direction: column; gap: 8px; }
  .landing-flow-arrow { transform: rotate(90deg); padding: 4px 0; }
}

/* Feature rundown — icon + title + 1-line body, denser than .landing-feature
   cards so 6+ callouts fit without dominating the page. */
.landing-feature-rows {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  margin-top: 16px;
}
.landing-feature-row {
  display: flex;
  gap: 12px;
  padding: 16px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.landing-feature-row-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--accent-glow);
  color: var(--accent-light);
  display: flex;
  align-items: center;
  justify-content: center;
}
.landing-feature-row-icon svg { width: 16px; height: 16px; }
.landing-feature-row-body { flex: 1; min-width: 0; }
.landing-feature-row h3 {
  font-size: 13px;
  margin: 0 0 4px;
  color: var(--text-primary);
}
.landing-feature-row p {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}

/* Integrations chip strip — a single horizontal row at the foot of the
   features section. "We play nice with the tools you already use." */
.landing-integrations {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}
.landing-integration-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 500;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
}
.landing-integration-chip svg { width: 14px; height: 14px; color: var(--accent-light); }

/* ── Profile / Identity management shell ──────────────── */
.manage-shell {
  width: 100%;
  max-width: 560px;
  margin: 40px auto;
  padding: 0 24px;
}

.manage-nav {
  display: flex;
  gap: 2px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
}

.manage-nav a {
  display: block;
  padding: 8px 14px;
  font-size: 12px;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: all var(--transition);
}

.manage-nav a:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.manage-nav a.active {
  color: var(--accent-blue);
  background: var(--accent-glow);
}

.manage-content h1 {
  font-size: 22px;
  margin-bottom: 4px;
}

.manage-content .lede {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 24px;
}

.manage-content .card-forge {
  width: 100%;
}

.manage-content .input-forge {
  width: 100%;
}

/* ── User menu (header dropdown) ──────────────────────── */
.user-menu {
  position: relative;
  height: 100%;
  display: flex;
  align-items: center;
}

.user-menu-trigger {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent-blue-dim);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  transition: background var(--transition);
}

.user-menu-trigger:hover {
  background: var(--accent-blue);
}

.user-menu-trigger svg {
  width: 16px;
  height: 16px;
}

.user-menu-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 180px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 200;
  padding: 4px;
}

.user-menu-dropdown.open { display: block; }

.user-menu-dropdown .menu-label {
  padding: 8px 12px 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-menu-dropdown .menu-divider {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}

.user-menu-dropdown a,
.user-menu-dropdown button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-secondary);
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-decoration: none;
  transition: all var(--transition);
}

.user-menu-dropdown a:hover,
.user-menu-dropdown button:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.user-menu-dropdown a svg,
.user-menu-dropdown button svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}

/* ── Workspace connection-status widget (footer-anchored) ─────────────────
   Sits at the right of the footer on /Workspace pages. Trigger is a low-key
   "Connected" pill with a green dot; click pops a small upward-anchored menu
   listing the three integrations with green/red status balls. */
.conn-status {
  position: relative;
  margin-left: 12px;
}
.conn-status-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 2px 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-secondary);
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition);
}
.conn-status-trigger:hover {
  border-color: var(--accent-blue-dim);
  color: var(--text-primary);
}
.conn-status-dropdown {
  display: none;
  position: absolute;
  /* Anchor upward — the widget lives in the footer, so the menu opens above it. */
  bottom: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4);
  z-index: 200;
  padding: 4px;
}
.conn-status-dropdown.open { display: block; }
.conn-status-dropdown .menu-label {
  padding: 8px 12px 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.conn-status-dropdown .menu-divider {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}
.conn-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-secondary);
  /* Non-interactive — these are status indicators, not actions. No hover state. */
}
.conn-status-name { color: var(--text-secondary); }

/* Status ball — used in both the trigger and the dropdown rows. */
.conn-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}
.conn-dot.ok {
  background: var(--success);
  box-shadow: 0 0 4px var(--success);
}
.conn-dot.bad {
  background: var(--danger);
  box-shadow: 0 0 4px var(--danger);
}

/* ── Utilities ────────────────────────────────────────── */
.u-mono     { font-family: var(--font-mono); }
.u-muted    { color: var(--text-muted); }
.u-mt-sm    { margin-top: 8px; }
.u-mt-md    { margin-top: 16px; }
.u-mt-lg    { margin-top: 24px; }
.u-mb-sm    { margin-bottom: 8px; }
.u-mb-md    { margin-bottom: 16px; }
.u-mb-lg    { margin-bottom: 24px; }
.u-flex     { display: flex; }
.u-flex-col { display: flex; flex-direction: column; }
.u-gap-sm   { gap: 8px; }
.u-gap-md   { gap: 12px; }
.u-gap-lg   { gap: 16px; }
.u-center   { justify-content: center; align-items: center; }
.u-between  { justify-content: space-between; align-items: center; }
.u-right    { margin-left: auto; }
.u-full     { width: 100%; }
.u-hidden   { display: none !important; }

.u-team-select { flex: 0; min-width: 160px; }

/* ── Onboarding — centered column with sticky action bar ── */

.onboard-shell {
  flex: 1;
  background: var(--bg-deep);
}

.onboard-column {
  width: 100%;
  /* Matches the post-onboarding tab pages (.full-page-left-content > * max-width)
     so the visual column width is consistent across the org/team/project setup
     flow and the corresponding tabs the user lands on after onboarding. */
  max-width: 880px;
  margin: 0 auto;
  min-height: 100%;
  padding: 40px 24px 0;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.onboard-header {
  margin-bottom: 24px;
  flex-shrink: 0;
}

/* Actions always pinned to the bottom of the viewport */
.onboard-actions {
  margin-top: auto;
  position: sticky;
  bottom: 0;
  padding: 16px 0 24px;
  border-top: 1px solid var(--border);
  background: var(--bg-deep);
  display: flex;
  gap: 8px;
  align-items: center;
  z-index: 10;
}

.onboard-actions .spacer { flex: 1; }

/* Step indicator */
.step-indicator {
  display: flex;
  gap: 4px;
  margin-bottom: 28px;
}

.step-indicator-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.step-indicator-bar {
  width: 100%;
  height: 3px;
  border-radius: 2px;
  background: var(--border);
  transition: background var(--transition);
}

.step-indicator-item.active .step-indicator-bar,
.step-indicator-item.done .step-indicator-bar {
  background: var(--accent-blue);
}

.step-indicator-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color var(--transition);
}

.step-indicator-item.active .step-indicator-label { color: var(--accent-blue); }
.step-indicator-item.done .step-indicator-label   { color: var(--text-secondary); }

/* Inline input + button row */
.invite-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.invite-row .input-forge { flex: 1; }
.invite-row select.input-forge { flex: 0; min-width: 130px; }

/* Per-email failure list shown beneath the invite input after a bulk-invite call. Each
   <div> is one "email — reason" row. Same visual weight as a validation summary but tied
   to its specific invite-row so multiple regions on one page (team cards, project cards)
   don't bleed into each other. */
.invite-errors {
  margin-top: 8px;
  padding: 8px 10px;
  background: var(--danger-dim);
  border: 1px solid var(--danger);
  border-radius: var(--radius-sm);
  color: var(--danger);
  font-size: 12px;
}
.invite-errors > div + div { margin-top: 2px; }

/* Chip lists (invites, files) */
.invite-list, .file-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

.invite-chip, .file-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  font-size: 12px;
  color: var(--text-secondary);
}

/* Owner chip — accent border + small "Owner" badge. The badge replaces the × button so the
   chip can't be removed by accident; transferring ownership is the only way out. */
.invite-chip-owner {
  border-color: var(--accent-blue-dim);
  background: var(--accent-glow);
}
.invite-chip .chip-badge {
  margin-left: 8px;
  padding: 2px 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--accent-blue);
  background: var(--bg-primary);
  border: 1px solid var(--accent-blue-dim);
  border-radius: 999px;
}

/* Generic margin utility — pushes the next sibling to the right inside a flex container.
   Used by the "Transfer ownership" button in the Org Admins card title row. */
.u-ml-auto { margin-left: auto; }

.file-chip {
  font-family: var(--font-mono);
  font-size: 11px;
}

.file-chip .file-size {
  color: var(--text-muted);
  font-size: 10px;
  margin-left: 8px;
}

.chip-remove {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 0 4px;
  transition: color var(--transition);
}

.chip-remove:hover { color: var(--danger); }

/* Item list (teams, projects) */
.item-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.item-card {
  /* Matches .config-card's chrome so the team and project cards on the onboarding
     pages look like the section cards on the corresponding tab pages. */
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
}

.item-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.item-card-name {
  font-weight: 600;
  font-size: 13px;
  color: var(--text-primary);
}

.item-card-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.5px;
}

.item-remove {
  margin-left: auto;
  color: var(--text-muted);
  background: none;
  border: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  transition: color var(--transition);
}

.item-remove:hover { color: var(--danger); }

/* Sub-invite row (nested inside item cards) */
.sub-invite { margin-top: 10px; }

.input-forge.sm { height: 30px; font-size: 11px; padding: 0 8px; }
.btn-forge.sm   { height: 30px; font-size: 11px; padding: 0 10px; }

/* Toggle switch */
.toggle-switch {
  position: relative;
  width: 40px;
  height: 22px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 11px;
  cursor: pointer;
  transition: all var(--transition);
  flex-shrink: 0;
  user-select: none;
}

.toggle-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: var(--text-secondary);
  border-radius: 50%;
  transition: all var(--transition);
}

.toggle-switch.on::after {
  left: 20px;
}

.toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text-primary);
  font-weight: 500;
  margin-bottom: 10px;
}

.codebase-hints {
  list-style: disc;
  padding-left: 20px;
  margin: 0;
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.8;
}

.codebase-hints strong {
  color: var(--text-primary);
  font-weight: 600;
}

/* Policy checklist */
.policy-checklist {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  max-height: 260px;
  overflow-y: auto;
}

/* Drag-and-drop zone */
.drop-zone {
  border: 2px dashed var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
  cursor: pointer;
  transition: all var(--transition);
  margin-top: 10px;
}

.drop-zone:hover,
.drop-zone--active {
  border-color: var(--accent-blue-dim);
  background: var(--accent-glow);
  color: var(--text-secondary);
}

/* Onboarding section label */
.onboard-section-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 20px;
  margin-bottom: 8px;
}

@media (max-width: 680px) {
  .onboard-card { max-width: 100%; padding: 20px; }
  .invite-row { flex-wrap: wrap; }
}

/* ── Org chooser ─────────────────────────────────────── */
.org-chooser-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

.org-chooser-item-form { margin: 0; }

.org-chooser-item {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: all var(--transition);
}

.org-chooser-item:hover {
  background: var(--bg-hover);
  border-color: var(--accent-blue-dim);
  color: var(--text-primary);
}

.org-chooser-item-arrow {
  color: var(--text-muted);
  font-size: 16px;
  transition: transform var(--transition), color var(--transition);
}

.org-chooser-item:hover .org-chooser-item-arrow {
  color: var(--accent-blue);
  transform: translateX(2px);
}

/* =========================================================
   Workspace — three-pane SDLC shell
   All rules namespaced with `ws-` prefix to keep the layout
   scoped and avoid clashes with onboarding / auth / landing.
   Ported from docs/forge-ui.html.
   ========================================================= */

/* When the workspace is present, lock main scroll so inner panes can scroll. */
.app-main:has(.ws-layout) { overflow: hidden; }
.app-main:has(.ws-empty)  { overflow: hidden; }

.ws-layout {
  flex: 1;
  display: flex;
  overflow: hidden;
  min-height: 0;
  position: relative;
}

/* Empty-state landing — shown when the user has no accessible projects
   in the active org (e.g. after skipping Teams/Projects onboarding). */
.ws-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  min-height: 0;
}

.ws-empty-inner {
  max-width: 480px;
  text-align: center;
  /* Match the pane-empty-state styling used on the Projects tab. */
  font-size: 13px;
  color: var(--text-muted);
}

.ws-empty-inner svg {
  width: 48px;
  height: 48px;
  color: var(--text-muted);
  opacity: 0.5;
  margin: 0 auto 16px;
  display: block;
}

/* ── Rails (left SDLC + right Library) ─────────────────── */
.ws-rail {
  width: 260px;
  background: var(--bg-primary);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  transition: width var(--slide-transition);
  overflow: hidden;
}

.ws-rail-left  { border-right: 1px solid var(--border); }
.ws-rail-right { border-left:  1px solid var(--border); }

/* Visual Studio-style dock: collapsed rails keep a 28px column dedicated to
   the rotated reopen tab so the center pane never has a floating button
   overlapping its content. Border stays put — the column reads as the rail. */
.ws-rail.collapsed {
  width: 28px;
}

.ws-rail.collapsed > * {
  display: none;
}

.ws-rail-header {
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.ws-rail-header-title {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ws-rail-collapse-btn {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  background: transparent;
  border: none;
  transition: all var(--transition);
}

.ws-rail-collapse-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.ws-rail-collapse-btn svg { width: 14px; height: 14px; }

.ws-rail-content {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
}

.ws-rail-content::-webkit-scrollbar { width: 4px; }
.ws-rail-content::-webkit-scrollbar-track { background: transparent; }
.ws-rail-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* VS-style tab dock for collapsed rails. The dock fills a 28px column
   top-to-bottom; tabs stack from the top with small gaps so we can add more
   later (e.g. additional tool panes). Each tab is borderless prose with an
   accent-blue strip on the outer edge that fades in on hover — matches the
   .ws-library-tab.active::after underline used elsewhere in the app. */
.ws-rail-tabs {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 28px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 8px 0;
  gap: 4px;
  z-index: 2;
  pointer-events: none; /* let clicks pass through empty dock space below tabs */
}

.ws-rail-tabs-left  { left: 0; }
.ws-rail-tabs-right { right: 0; }

.ws-rail-tab {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px 0;
  background: transparent;
  color: var(--text-muted);
  border: none;
  cursor: pointer;
  transition: color var(--transition), background var(--transition);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  user-select: none;
  flex-shrink: 0;
}

.ws-rail-tab:hover {
  color: var(--accent-blue);
  background: var(--accent-glow);
}

/* Accent strip on the outer edge (the side facing the content area). Hidden
   by default, fades in on hover — same accent-blue used for active tabs in
   the library + workspace toolbar. */
.ws-rail-tab::after {
  content: '';
  position: absolute;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--accent-blue);
  opacity: 0;
  transition: opacity var(--transition);
}

.ws-rail-tab:hover::after { opacity: 1; }

.ws-rail-tabs-left  .ws-rail-tab::after { right: 0; }
.ws-rail-tabs-right .ws-rail-tab::after { left: 0; }

.ws-rail-tab-label {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  user-select: none;
}

/* ── Team + Project selector block ─────────────────────── */
/* Uses the unchanged .input-forge theme so both selects render identically to
 * every other dropdown in the app (OrgSetup, ProjectSetup, ChooseOrg). Labels
 * and meta are padded by 12px to align with .input-forge's internal padding. */
.ws-project-selector {
  margin: 8px 10px 14px;
}

.ws-project-selector .field-label {
  display: block;
  padding-left: 12px;
  margin: 10px 0 6px;
}

.ws-project-selector .field-label:first-child {
  margin-top: 0;
}

.ws-project-meta {
  margin-top: 8px;
  padding-left: 12px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.3px;
}

/* ── Phases & steps ────────────────────────────────────── */
.ws-phase-group { margin-bottom: 4px; }

.ws-phase-group-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  cursor: pointer;
  transition: background var(--transition);
  user-select: none;
}

.ws-phase-group-header:hover { background: var(--bg-hover); }

.ws-phase-chevron {
  width: 12px;
  height: 12px;
  color: var(--text-muted);
  transition: transform var(--transition);
  flex-shrink: 0;
}

.ws-phase-group.open .ws-phase-chevron { transform: rotate(90deg); }

.ws-phase-status-ring {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.ws-phase-status-ring.complete {
  border-color: var(--success);
  background: var(--success-dim);
}

.ws-phase-status-ring.complete::after {
  content: '\2713';
  font-size: 9px;
  color: var(--success);
  font-weight: 700;
}

.ws-phase-status-ring.active {
  border-color: var(--accent-blue);
  background: var(--accent-glow);
}

.ws-phase-status-ring.active::after {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-blue);
}

.ws-phase-name {
  font-size: 12px;
  font-weight: 500;
  /* Bumped from --text-secondary to --text-primary for readability — the active phase
     state is still signalled by .ws-phase-status-ring.active, so we don't lose the
     active/inactive distinction by brightening the inactive label. */
  color: var(--text-primary);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-phase-group.active .ws-phase-name   { color: var(--text-primary); }
.ws-phase-group.complete .ws-phase-name { color: var(--text-secondary); }

.ws-phase-steps {
  display: none;
  padding-left: 22px;
}

.ws-phase-group.open .ws-phase-steps { display: block; }

.ws-step-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 14px 4px 18px;
  transition: background var(--transition);
  position: relative;
  user-select: none;
}

.ws-step-item::before {
  content: '';
  position: absolute;
  left: 21px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border);
}

.ws-step-item:last-child::before { height: 50%; }

.ws-step-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  flex-shrink: 0;
  z-index: 1;
  background: var(--bg-primary);
}

.ws-step-dot.complete {
  border-color: var(--success);
  background: var(--success);
}

.ws-step-dot.active {
  border-color: var(--accent-blue);
  background: var(--accent-blue);
  box-shadow: 0 0 6px rgba(77, 142, 247, 0.4);
}

.ws-step-label {
  font-size: 11px;
  /* Bumped from --text-muted to --text-secondary — the muted tone against the dark bg
     was reading as illegible, especially at 11px. Active step still uses --accent-light
     so the highlighted step stays visually distinct. */
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-step-item.active .ws-step-label   { color: var(--accent-light); font-weight: 500; }
.ws-step-item.complete .ws-step-label { color: var(--text-secondary); }

/* Click-to-view affordance — any step that can be opened for read-only inspection. */
.ws-step-item.clickable { cursor: pointer; }
.ws-step-item.clickable:hover { background: var(--bg-hover); }

/* Currently-viewed step — subtle highlight + left accent stripe so the user can see
 * which step's artifact + history is displayed in the centre panes. */
.ws-step-item.viewed {
  background: var(--accent-glow);
  box-shadow: inset 2px 0 0 var(--accent-blue);
}
.ws-step-item.viewed .ws-step-label { color: var(--text-primary); }

.ws-step-role {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-muted);
  margin-left: auto;
  flex-shrink: 0;
  opacity: 0.6;
}

/* ── Center column (chat + preview) ────────────────────── */
.ws-center {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  position: relative;
}

.ws-center-split {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.ws-chat-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Separator between chat + preview is now the draggable .ws-pane-divider element */
}

/* ── Draggable divider between chat and preview ─────── */
.ws-pane-divider {
  width: 4px;
  flex-shrink: 0;
  background: var(--border);
  cursor: ew-resize;
  transition: background var(--transition);
  user-select: none;
}

.ws-pane-divider:hover,
.ws-pane-divider.dragging {
  background: var(--accent-blue);
}

/* Lock the cursor + prevent text selection across the whole page while a drag is in flight.
 * State class (no `u-` prefix) — matches the `.collapsed` / `.active` / `.open` pattern
 * used elsewhere for component state, rather than the `u-*` utility-class convention. */
body.ws-is-dragging,
body.ws-is-dragging * {
  cursor: ew-resize !important;
  user-select: none !important;
}

.ws-pane-toolbar {
  height: 36px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--bg-primary);
}

.ws-toolbar-btn {
  height: 26px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all var(--transition);
  white-space: nowrap;
  user-select: none;
}

.ws-toolbar-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.ws-toolbar-btn.active {
  color: var(--accent-blue);
  background: var(--accent-glow);
}

/* Static "Chat" / "Artifact" pane title — looks like an active toolbar button but is not
   interactive. Keep the default cursor and suppress hover so it doesn't pretend to be clickable. */
.ws-toolbar-pane-title,
.ws-toolbar-pane-title:hover {
  cursor: default;
  background: var(--accent-glow);
  color: var(--accent-blue);
}

/* ── Toolbar overflow (kebab + popup) ───────────────────
   When the chat pane is too narrow to fit every toolbar button, JS folds the lowest-priority
   foldable buttons into this kebab menu. The kebab is server-rendered hidden; JS reveals it
   when needed. The popup is anchored to the kebab and listed below the toolbar. */
.ws-toolbar-overflow {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

.ws-toolbar-overflow-menu {
  /* position: fixed so the menu escapes ancestor overflow: hidden clipping
     (the chat-pane / layout containers crop the kebab popup otherwise).
     JS sets top/left in viewport coordinates on each open. */
  position: fixed;
  min-width: 160px;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  z-index: 1100;
}

.ws-toolbar-overflow-menu .ws-toolbar-overflow-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 10px;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 12px;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
}
.ws-toolbar-overflow-menu .ws-toolbar-overflow-item:hover { background: var(--bg-hover); }
.ws-toolbar-overflow-menu .ws-toolbar-overflow-item svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--text-secondary); }

.ws-toolbar-btn.primary {
  color: #fff;
  background: var(--accent-blue);
}

.ws-toolbar-btn.primary:hover { background: var(--accent-blue-dim); color: #fff; }

.ws-toolbar-btn[disabled],
.ws-toolbar-btn.disabled {
  opacity: 0.5;
  pointer-events: none;
  cursor: default;
}

.ws-toolbar-btn svg { width: 13px; height: 13px; flex-shrink: 0; }

.ws-toolbar-separator {
  width: 1px;
  height: 16px;
  background: var(--border);
  margin: 0 4px;
}

.ws-toolbar-spacer { flex: 1; }

.ws-toolbar-label {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.5px;
  /* Stay on one line and don't be flex-shrunk. Without these, the label wraps internally
     when the pane is narrow, which keeps the toolbar's scrollWidth equal to clientWidth and
     defeats the overflow detection — the label looks ugly and the JS never hides it. */
  white-space: nowrap;
  flex-shrink: 0;
}

/* ── Chat messages ─────────────────────────────────────── */
.ws-chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ws-chat-messages::-webkit-scrollbar { width: 4px; }
.ws-chat-messages::-webkit-scrollbar-track { background: transparent; }
.ws-chat-messages::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* Center-of-pane Start CTA — shown in the chat thread when the viewed step has never
   been started. Sits alongside (but not instead of) the toolbar Start button so the
   call-to-action is unmissable. Uses margin:auto inside the flex-column messages list
   to center both axes regardless of pane height. */
.ws-chat-start-hero {
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  max-width: 480px;
  padding: 24px;
}
.ws-chat-start-hero-icon {
  width: 40px;
  height: 40px;
  color: var(--text-muted);
  opacity: 0.45;
}
.ws-chat-start-hero-hint {
  color: var(--text-muted);
  font-size: 13px;
  margin: 0;
}

.ws-msg {
  display: flex;
  gap: 10px;
  max-width: 100%;
  animation: ws-msg-in 0.3s ease-out;
}

@keyframes ws-msg-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.ws-msg-avatar {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  margin-top: 2px;
}
/* Avatars now use SVG icons (person for user, brain for Forge) instead of letter glyphs.
   Size + center inside the 24px avatar tile; stroke color comes from the parent's `color`
   so the user/forge variants keep their existing color treatment. */
.ws-msg-avatar svg {
  width: 14px;
  height: 14px;
}

.ws-msg-avatar.user {
  background: var(--accent-glow-strong);
  color: var(--accent-blue);
  border: 1px solid var(--accent-blue-dim);
}

.ws-msg-avatar.forge {
  background: var(--bg-surface);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}

.ws-msg-body { flex: 1; min-width: 0; }

.ws-msg-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.ws-msg-sender {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.ws-msg-time {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
}

.ws-msg-role-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--accent-glow);
  color: var(--accent-blue);
  border: 1px solid rgba(77, 142, 247, 0.2);
}

.ws-msg-text {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* "Forge didn't respond" text inside a failed assistant bubble. Styled lightly italic so it
 * reads as a system-y status rather than something the AI said. The Retry button doesn't sit
 * inside the bubble — see .ws-msg-retry-row below. */
.ws-msg-failed-text {
  font-style: italic;
  color: var(--text-muted);
}

/* Centered Retry row that gets appended to the chat messages list under a failed assistant
 * message. The button uses the existing btn-forge ghost styling so it matches every other
 * action button in the app (Add knowledge, Save to Confluence, etc.) — only the layout is
 * specific to this surface. */
.ws-msg-retry-row {
  display: flex;
  justify-content: center;
  padding: 4px 0 12px;
}
.ws-msg-retry-row .btn-forge svg {
  width: 12px;
  height: 12px;
}

/* Pre-first-token indicator — single brand verb with an ellipsis that animates the word
 * itself. Single signal, no separate spinner element, brand-coherent. */
.ws-thinking-indicator {
  display: inline-block;
  color: var(--text-muted);
  font-style: italic;
  font-size: 13px;
  line-height: 1;
  padding: 2px 0;
}

.ws-thinking-indicator::after {
  /* Three separate periods, NOT the single U+2026 horizontal-ellipsis glyph. The width
     animation reveals one period at a time via steps(4, end); slicing a single glyph
     produces partial-character artifacts that look like weird shapes between dots. */
  content: '...';
  display: inline-block;
  width: 0;
  overflow: hidden;
  vertical-align: bottom;
  animation: ws-thinking-ellipsis 1.4s steps(4, end) infinite;
}

@keyframes ws-thinking-ellipsis {
  to { width: 1em; }
}

/* Mid-stream indicator — sibling of the streaming text container so it stays stable
 * across chunk re-renders (animation doesn't restart). Removed on content_final. */
.ws-stream-indicator {
  padding: 6px 0 0;
}

/* Loading state for primary toolbar buttons — pulses the icon + text so the user
 * sees activity even when the server is taking time to respond. */
.ws-toolbar-btn.is-loading {
  cursor: wait;
  animation: ws-btn-pulse 1.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes ws-btn-pulse {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1; }
}

/* Rendered-Markdown elements inside assistant bubbles. Mirrors the artifact-body rules so
 * the formatting language is consistent across chat and preview — headings, bullets, code. */
.ws-msg-text h1,
.ws-msg-text h2,
.ws-msg-text h3,
.ws-msg-text h4 {
  color: var(--text-primary);
  font-weight: 600;
  margin: 10px 0 6px;
}
.ws-msg-text h1 { font-size: 15px; }
.ws-msg-text h2 { font-size: 14px; }
.ws-msg-text h3 { font-size: 13px; }
.ws-msg-text h4 { font-size: 12px; }
.ws-msg-text h1:first-child,
.ws-msg-text h2:first-child,
.ws-msg-text h3:first-child,
.ws-msg-text h4:first-child { margin-top: 0; }

.ws-msg-text p { margin: 0 0 8px; }
.ws-msg-text p:last-child { margin-bottom: 0; }

.ws-msg-text ul,
.ws-msg-text ol {
  padding-left: 18px;
  margin: 4px 0 8px;
}
.ws-msg-text li { margin: 2px 0; }

.ws-msg-text pre {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 8px 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  overflow-x: auto;
  margin: 6px 0;
}
.ws-msg-text pre code {
  padding: 0;
  background: none;
  border: none;
  color: inherit;
}

.ws-msg-text blockquote {
  margin: 6px 0;
  padding-left: 10px;
  border-left: 2px solid var(--accent-blue-dim);
  color: var(--text-muted);
}

.ws-msg-text a {
  color: var(--accent-light);
  text-decoration: underline;
}

.ws-msg-text code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 1px 5px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--accent-light);
}

.ws-msg-tool-call {
  margin-top: 8px;
  padding: 8px 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.ws-msg-tool-call .ws-tool-icon { color: var(--accent-blue); }
.ws-msg-tool-call .ws-tool-name { color: var(--accent-light); font-weight: 500; }

/* ── Chat input (static) ─────────────────────────────── */
.ws-chat-input-area {
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-primary);
}

.ws-chat-input-box {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  transition: border-color var(--transition);
}

.ws-chat-input-box:focus-within { border-color: var(--accent-blue-dim); }

.ws-chat-input-box textarea {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 13px;
  resize: none;
  line-height: 1.5;
  /* 8 rows × 13px × 1.5 line-height ≈ 156px. JS sizes to content up to this cap. */
  max-height: 156px;
  min-height: 20px;
  overflow-y: auto;
}

.ws-chat-input-box textarea::placeholder { color: var(--text-muted); }

.ws-send-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--accent-blue);
  color: #fff;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--transition);
}

.ws-send-btn:hover:not(:disabled) { background: var(--accent-light); }
.ws-send-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
.ws-send-btn svg   { width: 14px; height: 14px; }

/* ── Preview / artifact pane ─────────────────────────── */
.ws-preview-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ws-preview-content {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: var(--bg-deep);
}

.ws-preview-content::-webkit-scrollbar { width: 4px; }
.ws-preview-content::-webkit-scrollbar-track { background: transparent; }
.ws-preview-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.ws-artifact-card {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  animation: ws-card-in 0.4s ease-out;
}

@keyframes ws-card-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

.ws-artifact-card-header {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-surface);
}

.ws-artifact-type-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: rgba(139, 92, 246, 0.15);
  color: #a78bfa;
  border: 1px solid rgba(139, 92, 246, 0.25);
}

.ws-artifact-card-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-artifact-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
}

/* Toolbar above the artifact body in the preview modal — Download / Save to Confluence.
   Sits between the header (title row) and the body so it's the first set of affordances
   the user sees on opening the preview. */
.ws-artifact-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
}
.ws-artifact-toolbar .btn-forge {
  font-size: 11px;
  padding: 4px 10px;
}
.ws-artifact-toolbar .btn-forge svg { width: 12px; height: 12px; }

/* "Saved to Confluence at …" panel rendered above the body when the artifact has a link.
   Same low-key inline-info styling as the chat info-chips — a small banner of metadata,
   not a primary action. */
.ws-artifact-link-panel {
  padding: 8px 14px;
  font-size: 12px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elevated);
}
.ws-artifact-link-row { line-height: 1.5; }
.ws-artifact-link-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.ws-artifact-link-meta {
  font-size: 11px;
  color: var(--text-muted);
}

/* Vertical action grid inside the "Save to Confluence" modal when an artifact is linked —
   stacks Update / Save-as-new / Unlink as full-width buttons so each option reads cleanly. */
.ws-modal-action-grid {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ws-modal-action-grid .btn-forge {
  width: 100%;
  justify-content: flex-start;
}

.ws-artifact-body {
  padding: 16px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-secondary);
}

.ws-artifact-body h1,
.ws-artifact-body h2,
.ws-artifact-body h3,
.ws-artifact-body h4 {
  color: var(--text-primary);
  font-weight: 600;
  margin: 16px 0 8px;
}

.ws-artifact-body h1 { font-size: 16px; }
.ws-artifact-body h2 { font-size: 14px; }
.ws-artifact-body h3 { font-size: 13px; }
.ws-artifact-body h4 { font-size: 12px; }
.ws-artifact-body h1:first-child,
.ws-artifact-body h2:first-child,
.ws-artifact-body h3:first-child,
.ws-artifact-body h4:first-child { margin-top: 0; }

.ws-artifact-body p { margin: 6px 0 10px; }

.ws-artifact-body ul,
.ws-artifact-body ol {
  padding-left: 18px;
  margin: 6px 0 10px;
}

.ws-artifact-body li { margin: 3px 0; }

.ws-artifact-body code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 1px 5px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--accent-light);
}

.ws-artifact-body pre {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 10px 12px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  overflow-x: auto;
  margin: 8px 0;
}

.ws-artifact-body pre code {
  padding: 0;
  background: none;
  border: none;
  color: inherit;
}

.ws-artifact-body blockquote {
  margin: 10px 0;
  padding-left: 12px;
  border-left: 2px solid var(--accent-blue-dim);
  color: var(--text-muted);
}

.ws-artifact-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
  font-family: var(--font-mono);
}

.ws-artifact-empty-title {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

/* ── Library (right rail) ─────────────────────────────── */
.ws-library-tabs {
  display: flex;
  padding: 0 10px;
  gap: 0;
  border-bottom: 1px solid var(--border);
}

.ws-library-tab {
  padding: 6px 10px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: all var(--transition);
  position: relative;
  user-select: none;
}

.ws-library-tab:hover { color: var(--text-secondary); }

.ws-library-tab.active { color: var(--accent-blue); }

.ws-library-tab.active::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--accent-blue);
}

/* "Add knowledge" dropdown sits between the tab strip and the item list. The trigger is a
   ghost btn-forge with a caret; the menu uses the same styling as the user-menu dropdown so
   the visual language stays consistent across the app. */
.ws-library-add {
  position: relative;
  padding: 6px 10px 0;
}
.ws-library-add-btn {
  width: 100%;
  justify-content: center;
  font-size: 11px;
  padding: 4px 10px;
}
.ws-library-add-btn svg { width: 12px; height: 12px; }
.ws-library-add-caret { margin-left: auto; }

.ws-library-add-menu {
  display: none;
  position: absolute;
  top: calc(100% + 2px);
  left: 10px;
  right: 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 200;
  padding: 4px;
}
.ws-library-add-menu.open { display: block; }

.ws-library-add-menu .menu-label {
  padding: 8px 12px 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--text-muted);
}
.ws-library-add-menu .menu-divider {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}
.ws-library-add-menu button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--text-secondary);
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
  transition: all var(--transition);
}
.ws-library-add-menu button:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.ws-checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-primary);
  cursor: pointer;
}

.ws-library-items {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}

.ws-library-items::-webkit-scrollbar { width: 4px; }
.ws-library-items::-webkit-scrollbar-track { background: transparent; }
.ws-library-items::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.ws-library-section {
  display: block;
}

.ws-library-section-label {
  padding: 8px 14px 4px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.ws-library-subgroup-label {
  padding: 6px 14px 2px 22px;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.2px;
}

.ws-library-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  transition: background var(--transition);
  user-select: none;
}

.ws-library-item:hover { background: var(--bg-hover); }

.ws-library-item-icon {
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.ws-library-item-icon svg { width: 14px; height: 14px; }

.ws-library-item-icon.knowledge { color: var(--success); }
.ws-library-item-icon.policy    { color: var(--warning); }
.ws-library-item-icon.template  { color: #a78bfa; }
.ws-library-item-icon.doc       { color: var(--accent-blue); }

.ws-library-item-name {
  font-size: 12px;
  color: var(--text-secondary);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-library-item-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.ws-library-empty {
  padding: 16px 14px;
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
}

/* Inline "auto" badge next to a Jira required-field label — signals that Forge will fill the
   field in per story rather than asking the user to provide a value. Visual treatment matches
   the lightweight badges used elsewhere (library item kinds, conn-dot adjacents). */
.ws-jira-auto-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--accent-blue);
  background: rgba(77, 142, 247, 0.12);
  border-radius: 3px;
  vertical-align: middle;
}

.ws-banner { margin: 8px 12px; }

/* Small-screen adjustments — mirror mockup's behaviour. */
@media (max-width: 1200px) {
  .ws-rail { width: 220px; }
}

/* ── Config pages (Organization / Teams / Projects) ───── */
/* Class vocabulary and visual treatment mirror docs/forge-ui.html mock. */

.u-p-sm { padding: 8px 12px; }

/* Tab-view shell — full-page, stretched, no centering. */
.tab-view {
  flex: 1;
  display: flex;
  overflow: hidden;
  min-height: 0;
}

/* Left nav (Teams/Projects) */
.left-nav {
  width: 260px;
  background: var(--bg-primary);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
}

.nav-header {
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.nav-header-title {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}

.nav-add-btn {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  cursor: pointer;
  background: transparent;
  border: none;
  transition: all var(--transition);
}
.nav-add-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}
.nav-add-btn svg { width: 14px; height: 14px; }

.nav-content {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}
.nav-content::-webkit-scrollbar { width: 4px; }
.nav-content::-webkit-scrollbar-track { background: transparent; }
.nav-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* Team list items (Teams nav) */
.group-tree-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin: 0 6px 2px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
  color: inherit;
}
.group-tree-item:hover { background: var(--bg-hover); }
.group-tree-item.active { background: var(--accent-glow); }
.group-tree-item svg { width: 16px; height: 16px; color: var(--text-muted); flex-shrink: 0; }
.group-tree-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-primary);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Project list (grouped by team, collapsible) */
.project-list-group {
  margin: 0 6px 4px;
}
.project-list-group-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
  user-select: none;
}
.project-list-group-header:hover { background: var(--bg-hover); }
.project-list-group-header svg { width: 12px; height: 12px; color: var(--text-muted); flex-shrink: 0; }
.project-list-group-header .plg-chevron { transition: transform var(--transition); }
.project-list-group.open .plg-chevron { transform: rotate(90deg); }
.project-list-group-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  flex: 1;
}
.project-list-group-children {
  display: none;
  padding-left: 8px;
}
.project-list-group.open > .project-list-group-children { display: block; }

.project-list-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 24px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
  color: inherit;
}
.project-list-item:hover { background: var(--bg-hover); }
.project-list-item.active { background: var(--accent-glow); }
.project-list-item-name {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Tree actions (hover-reveal delete icons) */
.tree-actions {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--transition);
}
.group-tree-item:hover .tree-actions,
.project-list-item:hover .tree-actions { opacity: 1; }

.tree-action-btn {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  background: transparent;
  border: none;
  transition: all var(--transition);
}
.tree-action-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

/* Main pane: full-page-split > full-page-left > (pane-toolbar + full-page-left-content) */
.full-page-split {
  flex: 1;
  display: flex;
  overflow: hidden;
}
.full-page-left {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.full-page-left-content {
  flex: 1;
  overflow-y: auto;
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Constrain content to a comfortable column width on the Org/Teams/Projects
   tabs. Cards remain full-width within this cap; the surrounding scroll area
   centers them so the page reads as a focused settings column rather than a
   wall of cards stretching to the rails. */
.full-page-left-content > * {
  width: 100%;
  max-width: 880px;
  margin-left: auto;
  margin-right: auto;
}
.full-page-left-content::-webkit-scrollbar { width: 4px; }
.full-page-left-content::-webkit-scrollbar-track { background: transparent; }
.full-page-left-content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* Pane toolbar with Save / Delete / etc. */
.pane-toolbar {
  height: 36px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--bg-primary);
}

.toolbar-btn {
  height: 26px;
  padding: 0 8px;
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  cursor: pointer;
  background: transparent;
  border: none;
  transition: all var(--transition);
  white-space: nowrap;
  user-select: none;
}
.toolbar-btn:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}
.toolbar-btn.active {
  color: var(--accent-blue);
  background: var(--accent-glow);
}
.toolbar-btn.primary {
  color: var(--accent-blue);
}
.toolbar-btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.toolbar-btn svg { width: 13px; height: 13px; flex-shrink: 0; }

.toolbar-separator {
  width: 1px;
  height: 16px;
  background: var(--border);
  margin: 0 4px;
}
.toolbar-spacer { flex: 1; }

.toolbar-label {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.5px;
  padding: 0 8px;
}
.toolbar-label.saved { color: var(--success); }

/* Bordered section cards */
.config-card {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
}
.config-card.expand {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.config-card-title {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.config-card-title svg { width: 14px; height: 14px; }

.config-card-divider {
  height: 1px;
  background: var(--border);
  margin: 16px 0;
}

.config-field {
  margin-bottom: 10px;
}
.config-card .config-field:last-child { margin-bottom: 0; }

.config-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 4px;
  display: block;
}

.config-input {
  width: 100%;
  height: 32px;
  padding: 0 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 12px;
  font-weight: 400;
  font-family: var(--font-sans);
  line-height: 1.5;
  outline: none;
  transition: border-color var(--transition);
}
.config-input:focus { border-color: var(--accent-blue-dim); }
.config-input[readonly] { opacity: 0.6; cursor: default; }
.config-input::placeholder { color: var(--text-muted); font-weight: 400; }

select.config-input { padding: 0 8px; }

/* Textareas can't honour rows= when a fixed height is set, so let them grow
   to whatever the rows attribute asks for and allow vertical resize. */
textarea.config-input {
  height: auto;
  min-height: 80px;
  padding: 8px 10px;
  line-height: 1.5;
  resize: vertical;
}

.config-meta-row {
  display: flex;
  gap: 20px;
  margin-top: 4px;
}
.config-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.config-meta-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.config-meta-value {
  font-size: 12px;
  color: var(--text-primary);
}

/* Empty state for "no selection" */
.pane-empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}
.pane-empty-state-inner {
  text-align: center;
  font-size: 13px;
}
.pane-empty-state-inner svg {
  width: 32px;
  height: 32px;
  margin: 0 auto 10px;
  display: block;
  opacity: 0.4;
}

/* Build step pane — replaces the chat thread for steps where Kind=Build. Lives inside the
   ws-chat-pane shell. The pane itself is a non-scrolling flex column; the active-build
   child handles its own top/bottom split with a draggable horizontal divider. */
.ws-build-pane {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-size: 13px;
}
.ws-build-no-build { padding: 16px 20px; }

/* Active build — flex column with two children + a divider. Top holds meta/plan/actions,
   bottom holds the live event log; both scroll internally so neither blows out the layout. */
.ws-build-active {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.ws-build-top {
  flex: 0 0 50%;       /* initial split: 50/50; JS sets pixel basis when user drags */
  min-height: 80px;
  overflow: hidden;    /* header is pinned, body scrolls — no scroll on the wrapper */
  display: flex;
  flex-direction: column;
}
/* Non-scrolling header — holds meta block + action buttons. Stays visible regardless of
   how far the user scrolls in the plan-step list below. Without this, a long plan list
   pushed Next / Abort / Open-PR off-screen and the user had to scroll to find them. */
.ws-build-top-header {
  flex: 0 0 auto;
  padding: 16px 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-bottom: 1px solid var(--border);
}
/* Scrollable body — currently just the plan-step list, may grow later. */
.ws-build-top-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 20px 16px;
}
.ws-build-bottom {
  flex: 1;
  min-height: 80px;
  overflow-y: auto;
  padding: 12px 20px 16px;
  display: flex;
  flex-direction: column;
}
.ws-build-bottom .ws-build-events { flex: 1; max-height: none; }

/* Horizontal divider between top and bottom — same vocabulary as the chat/preview ws-pane-divider
   but rotates the cursor for vertical drag. JS sets ws-build-pane.style.userSelect during drag. */
.ws-build-divider-h {
  height: 4px;
  flex-shrink: 0;
  background: var(--border);
  cursor: ns-resize;
  transition: background var(--transition);
  user-select: none;
}
.ws-build-divider-h:hover { background: var(--accent, var(--text-muted)); }
.ws-build-loading { color: var(--text-muted); }
.ws-build-section-title { font-size: 14px; font-weight: 600; margin: 0 0 4px; }
.ws-build-meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 12px;
  padding: 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.ws-build-meta-row { display: contents; }
.ws-build-meta-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.ws-build-meta-value { color: var(--text-primary); font-family: var(--font-mono); font-size: 12px; }
.ws-build-plan-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ws-build-plan-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
}
.ws-build-plan-item.current { border-color: var(--success); }
.ws-build-plan-num {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  min-width: 50px;
}
.ws-build-plan-title { flex: 1; }
.ws-build-plan-badge {
  font-size: 10px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  color: var(--text-muted);
}
.ws-build-plan-badge.completed { background: var(--success-dim); color: var(--success); }
.ws-build-plan-badge.running { background: var(--success-dim); color: var(--success); }
.ws-build-plan-badge.failed { background: var(--danger-dim); color: var(--danger); }
.ws-build-events {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  max-height: 280px;
  overflow-y: auto;
}
.ws-build-event-line {
  color: var(--text-secondary);
  margin-bottom: 4px;
  white-space: pre-wrap;
}

/* "Forge is working…" indicator — sits above the event log while a sidecar run streams.
   Three pulsing dots + a label, so the user has visible feedback that the agent is doing
   something even while events are still being decoded. */
.ws-build-running {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin-bottom: 12px;  /* breathing room above the event log */
  background: var(--success-dim);
  border: 1px solid var(--success);
  color: var(--success);
  border-radius: var(--radius-md);
  font-size: 12px;
}
.ws-build-running-text { font-weight: 500; }
.ws-build-running-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
  display: inline-block;
  animation: ws-build-running-pulse 1.2s infinite ease-in-out both;
}
.ws-build-running-dot:nth-child(1) { animation-delay: -0.32s; }
.ws-build-running-dot:nth-child(2) { animation-delay: -0.16s; }
@keyframes ws-build-running-pulse {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
  40% { transform: scale(1); opacity: 1; }
}

/* ── Build pane — bottom tabs (AI output / Refactor chat) ─────────────────
   Bottom-aligned tabs (Visual Studio style): the selected panel fills the column,
   tab strip sits below with a top border. Refactor tab is disabled until the plan
   step completes — JS toggles the `disabled` attribute. We keep the cursor at
   the default arrow on disabled tabs (no `not-allowed` icon) per UX feedback. */
.ws-build-bottom {
  padding: 0;
}
.ws-build-tab-panel {
  flex: 1;
  min-height: 0;
  /* Inner content owns its own scrolling. The panel itself stays fixed so anything
     pinned within (input box, Apply button) stays visible while the thread scrolls. */
  overflow: hidden;
  padding: 12px 20px 12px;
  display: flex;
  flex-direction: column;
}
.ws-build-tab-panel .ws-build-events {
  flex: 1;
  max-height: none;
  overflow-y: auto;
}
.ws-build-tabs {
  flex: 0 0 auto;
  display: flex;
  gap: 0;
  border-top: 1px solid var(--border);
  background: var(--bg-primary);
  padding: 0 12px;
}
.ws-build-tab {
  background: transparent;
  border: none;
  border-top: 2px solid transparent;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  padding: 8px 14px;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ws-build-tab:hover:not(:disabled) { color: var(--text-secondary); }
.ws-build-tab.active {
  color: var(--text-primary);
  border-top-color: var(--accent-blue);
}
.ws-build-tab:disabled { opacity: 0.5; cursor: default; }
.ws-build-tab-count {
  display: inline-block;
  min-width: 18px;
  padding: 1px 5px;
  border-radius: 10px;
  background: var(--accent-glow);
  color: var(--accent-light);
  font-family: var(--font-mono);
  font-size: 10px;
  text-align: center;
}

/* ── Refactor chat — reuses .ws-msg / .ws-msg-avatar / .ws-msg-body / .ws-msg-text
   so messages match the main step-chat exactly. The pane itself just stacks a
   scrollable thread, the staged-attachments row, the input box, and a sticky
   Apply button at the bottom so it stays accessible regardless of scroll. */
.ws-build-refactor {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: 10px;
}
.ws-build-refactor-thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 4px 0;
}
.ws-build-refactor-thread::-webkit-scrollbar { width: 4px; }
.ws-build-refactor-thread::-webkit-scrollbar-track { background: transparent; }
.ws-build-refactor-thread::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
.ws-build-refactor-staged {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex: 0 0 auto;
}
.ws-build-refactor-staged:empty { display: none; }
.ws-build-refactor-staged-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  font-size: 11px;
  font-family: var(--font-mono);
}
.ws-build-refactor-staged-chip button {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  font-size: 14px;
  line-height: 1;
}
.ws-build-refactor-staged-chip button:hover { color: var(--danger); }

/* Apply button — lives inline with the send button so the whole "send + commit" row stays
   pinned, no scrolling required. Sized to match the 28px send button so the row doesn't
   look ragged; tighter padding than the default .btn-forge so it doesn't dominate. */
.ws-build-refactor-apply-btn {
  flex-shrink: 0;
  height: 28px;
  padding: 0 12px;
  font-size: 12px;
  line-height: 1;
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
}

/* Visible feedback when a file is dragged over the refactor input box. Mirrors
   .ws-chat-input-box.is-drop-target styling vocabulary so both chats feel the same. */
.ws-build-refactor-input-box.is-drop-target {
  border-color: var(--accent-blue);
  background: var(--accent-glow);
}

/* Hide Apply while a chat send is streaming — same idea as the send button getting
   swapped for the spinner. The user shouldn't (and can't) commit mid-thought, so the
   button visually disappears until the agent comes back. */
.ws-chat-input-box.is-streaming .ws-build-refactor-apply-btn {
  display: none;
}

/* Per-message attachment chips (rendered inside .ws-msg-text). Pulled out of the bubble
   styling above — the main chat doesn't use bubbles, so neither do we. */
.ws-msg-attachment-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 6px 6px 0 0;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-secondary);
}

/* Back-link used at the top of sub-pages (e.g. settings detail screens) to return to the
   parent index. Visually quiet — same vocabulary as .field-hint with a small chevron. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: none;
  margin-bottom: 12px;
}
.back-link:hover { color: var(--text-primary); }
.back-link svg { width: 14px; height: 14px; }

/* Success-flavored sibling of .validation-summary-errors. Same shape and rhythm so the
   two read as a matched pair on settings/integration pages. */
.notice-success {
  background: var(--success-dim);
  border: 1px solid var(--success);
  color: var(--success);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  margin-bottom: 16px;
}
.notice-success strong { color: var(--text-primary); }

/* Compact key/value row used for read-only metadata blocks (e.g. installed-app details on
   the GitHub Integration page). Label sits left, value right; stacks on narrow screens. */
.kv-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid var(--border);
}
.kv-row:first-of-type { border-top: 0; padding-top: 0; }
.kv-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  min-width: 120px;
}
.kv-value { color: var(--text-primary); font-size: 13px; }
@media (max-width: 540px) {
  .kv-row { flex-direction: column; gap: 2px; }
  .kv-label { min-width: 0; }
}

/* Repository chip + list — codegen targets registered against a project. Mirrors the
   .invite-chip / .file-chip vocabulary the rest of the project page already uses. */
.repo-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.repo-chip {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 6px 10px;
}
.repo-chip-name {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--text-primary);
}
.repo-chip-branch {
  font-size: 11px;
  color: var(--text-muted);
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}
.repo-chip .chip-remove { margin-left: auto; }

/* Picker rows used inside the Add Repository modal. One row per available repo. */
.picker-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 320px;
  overflow-y: auto;
  padding-right: 4px;
}
.picker-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.picker-row:hover { background: var(--bg-secondary); }
.picker-row input[type=radio],
.picker-row input[type=checkbox] { margin: 0; }
.picker-row-name { font-family: var(--font-mono); font-size: 13px; }
.picker-row-meta { font-size: 11px; color: var(--text-muted); margin-left: auto; }

/* Multi-select variant of .picker-row used by the project repo picker. Adds an inline
   branch <select> between the name and the meta column so a project can register the
   same repo against multiple branches in one submit. The checkbox stays disabled until
   a real branch is selected — already-mapped branches are filtered out of the dropdown,
   so an empty dropdown means "fully registered, nothing left to add". */
.picker-row-multi { cursor: default; }
.picker-row-branch {
  width: auto;
  min-width: 140px;
  max-width: 240px;
  padding: 4px 8px;
  font-size: 12px;
}

/* Integration row — used inside the Integrations config-card on the Organization page.
   Each row pairs a label/description block with a single right-aligned action button. */
.integration-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}
.integration-row:first-of-type { border-top: 0; padding-top: 4px; }
.integration-row-text { flex: 1; min-width: 0; }
.integration-row-title { font-weight: 600; color: var(--text-primary); }
.integration-row-sub {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* Subsection heading inside a config-card (e.g., "Baselines" within a Policies card). */
.config-subsection-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-top: 12px;
  margin-bottom: 6px;
}
.config-card > .config-subsection-label:first-of-type { margin-top: 0; }

/* One level deeper than a subsection — groups toggles inside a subsection
   (e.g., "Backend" / "Frontend" within the Technology Stack subsection). */
.policy-subgroup-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  margin-top: 8px;
  margin-bottom: 4px;
}
.policy-toggle-grid + .policy-subgroup-label { margin-top: 10px; }

/* ── Policy toggle grid (Organization / Project settings) ─ */
.policy-toggle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px;
}

.policy-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
  user-select: none;
}
.policy-toggle:hover { border-color: var(--accent-blue-dim); }

.policy-toggle.readonly {
  cursor: default;
  background: var(--bg-elevated);
}
.policy-toggle.readonly:hover { border-color: var(--border); }

/* Cloud-locked: child tech disabled because its required cloud parent isn't selected.
   CosmosDB needs Azure; DynamoDB needs AWS. Toggle is non-interactive and dimmed; the JS
   click handler skips these rows. Hover doesn't change anything so the disabled state reads
   clearly. */
.policy-toggle.cloud-locked {
  cursor: default;
  opacity: 0.45;
  pointer-events: none;
}

.policy-toggle-label {
  flex: 1;
  font-size: 12px;
  color: var(--text-primary);
  /* Stack a short subtext under the name when present. Single-line toggles
     (no .policy-toggle-sub child) still render identically because flex-column
     on a single text node behaves like a plain block. */
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Optional secondary line under the toggle label — short cue text like "Payment
   cards" under "PCI-DSS". Muted and slightly smaller so the primary name stays
   the focus. */
.policy-toggle-sub {
  font-size: 10px;
  color: var(--text-muted);
  font-weight: 400;
  letter-spacing: 0.3px;
}

.policy-toggle-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--bg-primary);
}

/* Stronger visual when ON — the base .toggle-switch.on rule only shifts the knob,
   which is hard to scan. Fill the track + brighten the knob for both grid toggles
   (.policy-toggle) and standalone toggles inside .toggle-row (codebase picker,
   include-refiners picker, etc.). */
.policy-toggle .toggle-switch.on,
.toggle-row .toggle-switch.on {
  background: var(--accent-blue-dim);
  border-color: var(--accent-blue);
}
.policy-toggle .toggle-switch.on::after,
.toggle-row .toggle-switch.on::after {
  background: #fff;
}

/* Locked baseline: show an on-state that can't be toggled, no cursor pointer. */
.policy-toggle .toggle-switch.locked {
  cursor: default;
  opacity: 0.75;
}
.policy-toggle .toggle-switch.locked.on {
  background: var(--text-muted);
  border-color: var(--text-muted);
}

/* ─────────────────────────────────────────────────────────────────────
   Sub-artifacts (mermaid, json, svg, html, markdown attached to a parent
   artifact). Rendered below the parent in the preview pane and listed
   indented in the library tree.
   ───────────────────────────────────────────────────────────────────── */
.ws-subartifacts {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ws-subartifacts-header {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0 4px;
}
.ws-subartifact-card {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-secondary);
  overflow: hidden;
}
.ws-subartifact-card-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-primary);
}
.ws-subartifact-name {
  font-weight: 600;
  font-size: 13px;
  color: var(--text-primary);
}
.ws-subartifact-format {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 3px;
}
.ws-subartifact-body {
  padding: 12px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-primary);
  overflow-x: auto;
}
.ws-subartifact-body pre {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
}
/* Mermaid frame — outer container with relative positioning so the zoom toolbar
   stays anchored in the top-right regardless of how far the user pans inside
   the inner scroll wrap. */
.forge-sub-mermaid-frame {
  position: relative;
  max-height: 600px;
}
/* Inner scroll wrap — clips and scrolls when the diagram is zoomed past the
   visible area. Grab cursor signals drag-to-pan; flips to grabbing while a
   pan is active. */
.forge-sub-mermaid-wrap {
  overflow: auto;
  max-height: 600px;
  cursor: grab;
}
.forge-sub-mermaid-wrap.is-panning {
  cursor: grabbing;
  user-select: none;
}
.forge-sub-mermaid {
  display: block;
  text-align: center;
}
/* Floating zoom controls — anchored to the FRAME (not the wrap) so they stay
   fixed in the top-right while the user pans the diagram. Right offset is large
   enough to clear the scrollbar that appears on the wrap when the diagram is
   zoomed past the visible area. Subtle backdrop so the buttons read on light
   or dark mermaid themes. */
.forge-sub-mermaid-zoom {
  position: absolute;
  top: 6px;
  right: 20px;
  display: flex;
  gap: 2px;
  z-index: 2;
  padding: 2px;
  background: rgba(0, 0, 0, 0.35);
  border-radius: 4px;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.forge-sub-mermaid-zoom button {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-secondary);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
  font-family: var(--font-sans, inherit);
  transition: background var(--transition), color var(--transition);
}
.forge-sub-mermaid-zoom button:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.forge-sub-mermaid-zoom button:active {
  background: var(--accent-glow);
}
.forge-sub-svg {
  display: block;
}
.forge-sub-svg svg {
  max-width: 100%;
  height: auto;
}
.forge-sub-html {
  width: 100%;
  min-height: 240px;
  border: 0;
  background: #fff;
}

/* Library: indented sub-artifact rows under a parent artifact.
 * Deeper indent + dimmed icon make hierarchy obvious without implying interactivity. */
.ws-library-item-sub {
  padding-left: 32px;
}
.ws-library-item-sub .ws-library-item-name {
  color: var(--text-muted);
}
.ws-library-item-icon.subartifact {
  color: var(--text-muted);
  opacity: 0.6;
}

/* Clickable library items (artifacts + sub-artifacts open the preview modal). */
.ws-library-item-clickable { cursor: pointer; }

/* ── Library preview modal ─────────────────────────────────────
 * Center-stage modal showing a server-rendered artifact (or single sub-artifact)
 * without disturbing the active step's chat + preview. Mermaid runs after content
 * lands so diagram sub-artifacts render the same as the artifact pane. */
.ws-preview-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ws-preview-modal-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
}

.ws-preview-modal-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(900px, calc(100vw - 48px));
  /* Fixed height so the dialog reads the same regardless of artifact size —
     short artifacts get extra empty body space, long ones scroll within. */
  height: calc(100vh - 64px);
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

.ws-preview-modal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.ws-preview-modal-titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.ws-preview-modal-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-preview-modal-subtitle {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

.ws-preview-modal-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  transition: background var(--transition), color var(--transition);
}
.ws-preview-modal-close:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.ws-preview-modal-close svg { width: 16px; height: 16px; }

.ws-preview-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
}
.ws-preview-modal-body::-webkit-scrollbar       { width: 6px; }
.ws-preview-modal-body::-webkit-scrollbar-track { background: transparent; }
.ws-preview-modal-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.ws-preview-modal-loading,
.ws-preview-modal-error {
  text-align: center;
  color: var(--text-muted);
  font-size: 13px;
  padding: 32px 16px;
}
.ws-preview-modal-error { color: var(--danger, #ef4444); }

/* Streaming state on the chat input box.
   - Hides the send button entirely (no background, no tooltip surface)
   - Hides the textarea placeholder so it doesn't read like "Message Forge…" while
     the user is waiting for a response
   - Shows a 12-tick activity spinner where the send button used to live
   The spinner is a classic Apple-style indicator: 12 small rounded bars arranged
   in a circle, each bar fades from full to faint as it travels round, giving the
   illusion of a leading "head" with a fading tail. Single tone (uses --text-muted),
   no background — appears directly on the dark input box. */
.ws-chat-input-box.is-streaming .ws-send-btn {
  display: none;
}
.ws-chat-input-box.is-streaming textarea::placeholder {
  /* During streaming the JS swaps the placeholder text to a "please wait" message; keep it
     visible (just slightly muted) so the user has a clear cue that something's in flight. */
  color: var(--text-muted);
  font-style: italic;
}

.ws-stream-spinner {
  display: none;
  position: relative;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.ws-chat-input-box.is-streaming .ws-stream-spinner {
  display: block;
}
.ws-stream-spinner > div {
  position: absolute;
  top: 0;
  left: 50%;
  width: 2px;
  height: 6px;
  margin-left: -1px;
  background: var(--text-muted);
  border-radius: 1px;
  transform-origin: 50% 11px;
  animation: ws-stream-tick-fade 1.8s linear infinite;
}
.ws-stream-spinner > div:nth-child(1)  { transform: rotate(0deg);   animation-delay: -1.650s; }
.ws-stream-spinner > div:nth-child(2)  { transform: rotate(30deg);  animation-delay: -1.500s; }
.ws-stream-spinner > div:nth-child(3)  { transform: rotate(60deg);  animation-delay: -1.350s; }
.ws-stream-spinner > div:nth-child(4)  { transform: rotate(90deg);  animation-delay: -1.200s; }
.ws-stream-spinner > div:nth-child(5)  { transform: rotate(120deg); animation-delay: -1.050s; }
.ws-stream-spinner > div:nth-child(6)  { transform: rotate(150deg); animation-delay: -0.900s; }
.ws-stream-spinner > div:nth-child(7)  { transform: rotate(180deg); animation-delay: -0.750s; }
.ws-stream-spinner > div:nth-child(8)  { transform: rotate(210deg); animation-delay: -0.600s; }
.ws-stream-spinner > div:nth-child(9)  { transform: rotate(240deg); animation-delay: -0.450s; }
.ws-stream-spinner > div:nth-child(10) { transform: rotate(270deg); animation-delay: -0.300s; }
.ws-stream-spinner > div:nth-child(11) { transform: rotate(300deg); animation-delay: -0.150s; }
.ws-stream-spinner > div:nth-child(12) { transform: rotate(330deg); animation-delay: 0s; }
@keyframes ws-stream-tick-fade {
  0%   { opacity: 1.00; }
  20%  { opacity: 0.65; }
  40%  { opacity: 0.35; }
  60%  { opacity: 0.20; }
  100% { opacity: 0.10; }
}
@media (prefers-reduced-motion: reduce) {
  .ws-stream-spinner > div { animation: none; opacity: 0.4; }
}

/* ─────────────────────────────────────────────────────────────────────
   Public marketing/auth pages — Contact link in header + Privacy link
   in footer. Quiet, unobtrusive, matches the IDE theme.
   ───────────────────────────────────────────────────────────────────── */
.site-public-link {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  text-decoration: none;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  transition: color var(--transition), background var(--transition);
}
.site-public-link:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

/* Long-form prose pages (Privacy, Contact). Centered, comfortable
   reading width. Section headings tighter than the default cards. */
.prose-page {
  max-width: 760px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}
.prose-page h1 {
  font-size: 28px;
  margin: 0 0 8px;
}
.prose-page h2 {
  font-size: 18px;
  margin: 32px 0 12px;
  color: var(--text-primary);
}
.prose-page p,
.prose-page ul,
.prose-page ol {
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-secondary);
}
.prose-page ul,
.prose-page ol {
  padding-left: 22px;
  margin: 0 0 14px;
}
.prose-page ul li,
.prose-page ol li {
  margin: 4px 0;
}
.prose-page a {
  color: var(--accent-blue);
}
.prose-page a:hover {
  text-decoration: underline;
}
.prose-page .prose-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 24px;
}

.contact-list {
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.contact-list li {
  font-size: 15px;
  margin: 0;
}

/* ── Contact page ──────────────────────────────────────────
   Hero uses the same radial-glow + bg-deep pairing as the auth + landing-hero so the page
   feels like part of the same surface family. Cards below are clickable anchors styled to
   match card-forge with hover + arrow-on-right affordance. */
.contact-hero {
  padding: 72px 24px 32px;
  text-align: center;
  background:
    radial-gradient(ellipse at top, var(--accent-glow-strong), transparent 55%),
    var(--bg-deep);
}
.contact-hero-title {
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
  background: linear-gradient(135deg, var(--text-primary), var(--accent-light));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.contact-hero-subtitle {
  font-size: 16px;
  color: var(--text-secondary);
  max-width: 560px;
  margin: 0 auto;
  line-height: 1.6;
}

.contact-cards {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 24px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.contact-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 20px 22px;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color var(--transition), background var(--transition), transform var(--transition);
}
.contact-card:hover {
  border-color: var(--accent-blue-dim);
  background: var(--bg-elevated);
  text-decoration: none;
  transform: translateY(-1px);
}

.contact-card-icon {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--accent-glow);
  color: var(--accent-blue);
}
.contact-card-icon svg { width: 22px; height: 22px; }

.contact-card-body { flex: 1; min-width: 0; }
.contact-card-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.contact-card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 4px;
  word-break: break-word;
}
.contact-card-desc {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.55;
}

.contact-card-arrow {
  flex-shrink: 0;
  color: var(--text-muted);
  transition: color var(--transition), transform var(--transition);
}
.contact-card-arrow svg { width: 16px; height: 16px; }
.contact-card:hover .contact-card-arrow {
  color: var(--accent-blue);
  transform: translateX(2px);
}

.contact-footer {
  max-width: 720px;
  margin: 0 auto;
  padding: 8px 24px 64px;
  font-size: 13px;
  color: var(--text-muted);
  text-align: center;
  line-height: 1.6;
}

/* ── Contact-page beta signup card ──────────────────────────────
   Sits between the hero and the contact-cards stack. Uses the same card chrome
   vocabulary as card-forge / auth-centered-card so it reads as part of the same
   surface family. Two-column grid on wide viewports, collapses to a single column
   on narrow screens. */
.contact-beta {
  max-width: 720px;
  margin: 0 auto;
  padding: 16px 24px 8px;
}
.contact-beta-card {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px 28px 32px;
}
.contact-beta-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--accent-blue);
  margin-bottom: 6px;
}
.contact-beta-title {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
  color: var(--text-primary);
}
.contact-beta-subtitle {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0 0 20px;
  line-height: 1.6;
}
.contact-beta-form .notice-success { margin-bottom: 16px; }
.contact-beta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 16px;
}
.contact-beta-form .field { margin-bottom: 14px; }
.contact-beta-form .field:last-of-type { margin-bottom: 18px; }
.contact-beta-form textarea.input-forge {
  min-height: 96px;
  resize: vertical;
}
.field-optional {
  color: var(--text-muted);
  font-weight: 400;
  font-size: 12px;
  margin-left: 4px;
}

@media (max-width: 560px) {
  .contact-beta-grid { grid-template-columns: 1fr; }
  .contact-beta-card { padding: 22px 20px 24px; }
}

/* ── Phase header action icons (edit / delete) ──────────────────
 * Hover-revealed pencil + trash on each phase row in the workflow rail. Stay flush right
 * inside the existing header layout; appear only when the user hovers the header so the
 * default reading state stays clean. */
.ws-phase-action-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  opacity: 0;
  transition: opacity var(--transition), background var(--transition), color var(--transition);
  margin-left: 4px;
}
.ws-phase-action-btn svg { width: 13px; height: 13px; }
.ws-phase-group-header:hover .ws-phase-action-btn { opacity: 0.85; }
.ws-phase-action-btn:hover {
  opacity: 1;
  background: var(--bg-hover);
  color: var(--text-primary);
}

/* ── Step lock indicator ────────────────────────────────────────
 * Tiny lock glyph beside a step's status dot when the step is currently locked. Keeps the
 * row layout intact — position is between the label and the role badge, sized small enough
 * to read as a status hint rather than a primary control. */
.ws-step-lock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-left: 6px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.ws-step-lock svg { width: 11px; height: 11px; }
.ws-step-lock.by-self  { color: var(--accent-blue, #3b82f6); }
.ws-step-lock.by-other { color: #f59e0b; }

.ws-step-item.locked-by-other {
  /* Subtle visual cue: locked-by-other rows feel "in-flight" by another user */
  opacity: 0.85;
}

/* ── Rail bottom actions (Add Phase, Generate from Plan) ───────
 * Sit below the phase list in the workflow rail. Stack vertically with consistent spacing.
 * Use the existing .btn-forge.ghost styling so they read as secondary actions. */
.ws-rail-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 16px 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.ws-rail-actions .btn-forge {
  font-size: 12px;
  padding: 8px 12px;
}

/* ── Generic workspace modal (Phase add/edit, confirm, changelog) ──
 * Smaller and lighter than .ws-preview-modal — used for forms and confirmations rather than
 * full artifact previews. Same overlay treatment for consistency, narrower panel, no fixed
 * height (panels size to content within a max).
 *
 * Three structural elements:
 *   .ws-modal-header  — title + close button
 *   .ws-modal-body    — fields, hints, errors
 *   .ws-modal-footer  — primary + secondary action buttons */
.ws-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ws-modal-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
}
.ws-modal-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(560px, calc(100vw - 48px));
  max-height: calc(100vh - 64px);
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.ws-modal-panel-narrow { width: min(420px, calc(100vw - 48px)); }

/* Wide variant — matches the .ws-preview-modal-panel sizing so document-style content
   (activity log, future reports lists) reads at the same width as the report viewer. */
.ws-modal-panel-wide {
  width: min(900px, calc(100vw - 48px));
  height: calc(100vh - 64px);
  max-height: calc(100vh - 64px);
}

.ws-modal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.ws-modal-title {
  flex: 1;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}
.ws-modal-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  transition: background var(--transition), color var(--transition);
}
.ws-modal-close:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.ws-modal-close svg { width: 16px; height: 16px; }

.ws-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ws-modal-body::-webkit-scrollbar       { width: 6px; }
.ws-modal-body::-webkit-scrollbar-track { background: transparent; }
.ws-modal-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.ws-modal-hint {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.45;
}

.ws-modal-error {
  font-size: 12px;
  color: var(--danger, #ef4444);
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
}

/* Activity Log dialog */
.activity-log-header {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.activity-log-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.activity-log-meta-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.activity-log-meta-value {
  font-size: 12px;
  color: var(--text-primary);
}

.activity-log-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
}
.activity-log-row {
  display: grid;
  grid-template-columns: 130px 110px 1fr;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  align-items: baseline;
}
.activity-log-row:last-child { border-bottom: none; }
.activity-log-row-time {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
}
.activity-log-row-type {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-primary);
}
.activity-log-row-desc {
  color: var(--text-primary);
  line-height: 1.4;
}
.activity-log-row-actor {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}
.activity-log-empty {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  padding: 12px 0;
}

.ws-modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

.ws-radio-row {
  display: flex;
  gap: 16px;
}
.ws-radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-primary);
  cursor: pointer;
}
.ws-radio input { margin: 0; }

.field-hint {
  font-weight: 400;
  color: var(--text-muted);
  font-size: 11px;
  margin-left: 4px;
}

/* ── Artifact pane "jump to document" dropdown ──────────────────
 * Borderless select that lets the user scroll the preview pane to a specific sub-artifact.
 * Reads as a label with a chevron rather than a form control — sits next to the "Artifact"
 * pill in the pane toolbar. */
.ws-artifact-jump {
  background: transparent;
  border: none;
  color: var(--text-secondary);
  font-size: 12px;
  padding: 4px 22px 4px 8px;
  margin-left: 8px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition), color var(--transition);
  max-width: 220px;
  /* Shrink + truncate on narrow panes so the dropdown never pushes other toolbar items
     off-screen. min-width: 0 lets a flex item ignore its intrinsic min-content width. */
  min-width: 0;
  flex-shrink: 1;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
.ws-artifact-jump:hover { background-color: var(--bg-hover); color: var(--text-primary); }
.ws-artifact-jump:focus { outline: none; background-color: var(--bg-hover); color: var(--text-primary); }

/* Popup options match the rail's input-forge select popup (dark elevated bg + primary text)
   so the open dropdown reads consistently across the app. The trigger stays borderless to
   blend with the toolbar — only the popup menu gets the rail-style treatment. */
.ws-artifact-jump option {
  background: var(--bg-elevated);
  color: var(--text-primary);
  padding: 6px 12px;
}

/* ── Chat toolbar breadcrumb (phase → step) ─────────────────────
 * Sits between the "Chat" pill and the spacer so users always know which step they're on
 * without scanning the rail. Phase reads slightly muted; step pops as the primary identifier. */
.ws-toolbar-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: 12px;
  font-size: 12px;
  color: var(--text-muted);
  min-width: 0;
}
.ws-toolbar-breadcrumb-phase {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  max-width: 220px;
}
.ws-toolbar-breadcrumb-sep {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  opacity: 0.6;
}
.ws-toolbar-breadcrumb-step {
  color: var(--text-primary);
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  max-width: 220px;
}

/* ── Project guidance edit button (left rail) ───────────────────
 * Compact icon-button that lives in the project meta area. Visible only to project admins. */
.ws-rail-edit-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  font-size: 11px;
  margin-left: 8px;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.ws-rail-edit-btn svg { width: 11px; height: 11px; }
.ws-rail-edit-btn:hover {
  background: var(--bg-hover);
  border-color: var(--text-muted);
  color: var(--text-primary);
}

/* ── Step history list ──────────────────────────────────────────
 * Inside the history modal — vertical list of changelog entries, each card showing
 * the summary plus author + relative time. */
.ws-history-empty {
  text-align: center;
  padding: 24px 12px;
  color: var(--text-muted);
  font-size: 13px;
}
.ws-history-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ws-history-entry {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  background: var(--bg-secondary, var(--bg-primary));
}
.ws-history-entry-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.ws-history-entry-summary {
  font-size: 13px;
  color: var(--text-primary);
  white-space: pre-wrap;
  line-height: 1.5;
}

/* ── Knowledge document raw embeds ──────────────────────────────
 * Images / PDFs / SVG / HTML render inside the preview modal via <img> or <iframe>.
 * For images we re-use the mermaid zoom frame so users get pan + zoom on big screenshots.
 * For PDFs / SVG / HTML the iframe takes the available height of the modal body. */
.forge-knowledge-raw-body {
  height: calc(100vh - 220px);
  display: flex;
  flex-direction: column;
}
.forge-knowledge-image {
  display: block;
  max-width: 100%;
  max-height: none;
  height: auto;
  margin: 0 auto;
}
.forge-knowledge-iframe {
  flex: 1;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  min-height: 360px;
}
.forge-knowledge-download {
  display: inline-block;
  padding: 10px 16px;
  margin: 16px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  text-decoration: none;
}
.forge-knowledge-download:hover { background: var(--bg-hover); }

/* ── CSV table ──────────────────────────────────────────────────
 * Server-rendered table for previewing CSV knowledge docs. */
.forge-csv-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-family: var(--font-mono);
}
.forge-csv-table th,
.forge-csv-table td {
  border: 1px solid var(--border);
  padding: 6px 10px;
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
}
.forge-csv-table th {
  background: var(--bg-elevated);
  color: var(--text-primary);
  font-weight: 600;
}
.forge-csv-table tbody tr:nth-child(even) td {
  background: var(--bg-secondary, var(--bg-primary));
}

/* ── Policy rule cards ──────────────────────────────────────────
 * Friendly view of a policy's rules — each rule a stacked card with name + instructions
 * and an optional fenced example. Used inside the preview modal for policy library items. */
.forge-policy-rules {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.forge-policy-rule {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  background: var(--bg-secondary, var(--bg-primary));
}
.forge-policy-rule-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.forge-policy-rule-instructions {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.55;
  white-space: pre-wrap;
}
.forge-policy-rule-example {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.forge-policy-rule-example-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.forge-policy-rule-example pre {
  margin: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: 12px;
  overflow-x: auto;
}

/* ── Upstream changes group ─────────────────────────────────────
 * Each artifact that has changes gets its own header (artifact name + phase) followed by the
 * stack of new changelog entries beneath it. Visually grouped to make multi-artifact diffs
 * scannable. */
.ws-upstream-group {
  margin-bottom: 16px;
}
.ws-upstream-group:last-child { margin-bottom: 0; }
.ws-upstream-group-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 0 6px 0;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-primary);
}
.ws-upstream-group-header strong { font-weight: 600; }
.ws-upstream-phase {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

/* ── Step knowledge attachments ──────────────────────────
   The "+" button mirrors ws-send-btn but on the left of the chat input. Stays subtle so
   the primary affordance (Send) remains visually dominant. */
.ws-attach-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  cursor: pointer;
  flex-shrink: 0;
  transition: all var(--transition);
}
.ws-attach-btn:hover:not(:disabled) {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border-color: var(--accent-blue-dim);
}
.ws-attach-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
.ws-attach-btn svg { width: 14px; height: 14px; }

.ws-chat-input-box.is-streaming .ws-attach-btn {
  visibility: hidden;
}

/* Drop highlight — appears when a file is being dragged over the chat input box. */
.ws-chat-input-box.is-drop-target {
  border-color: var(--accent-blue);
  background: var(--bg-elevated);
  outline: 2px dashed var(--accent-blue-dim);
  outline-offset: -4px;
}

/* Inline info-chip used for system events in the chat thread (file attached, file removed).
   Centered, narrow, no avatar — visually distinct from user/assistant turns. */
.ws-msg-info-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 8px auto;
  padding: 4px 12px;
  max-width: 80%;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-secondary);
}
.ws-msg-info-chip-text { line-height: 1.4; }
.ws-msg-info-chip-text strong { color: var(--text-primary); font-weight: 600; }
.ws-msg-info-chip-text p { margin: 0; display: inline; }
.ws-msg-info-chip-time {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
}

/* Right-pane × button on a step-knowledge chip. Hidden by default; reveals on hover of
   the row so the chip stays clean when not interacting. */
.ws-library-item-remove {
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  opacity: 0;
  transition: all var(--transition);
}
.ws-library-item:hover .ws-library-item-remove { opacity: 1; }
.ws-library-item-remove:hover {
  background: var(--bg-hover);
  color: var(--danger, #f87171);
}
.ws-library-item-remove svg { width: 12px; height: 12px; }

/* ── Blueprint empty state (artifact pane, pre-draft) ────
   Shown when the step's artifact body still equals the workflow template — the user hasn't
   iterated yet. Mirrors the landing-hero gradient (radial accent glow over bg-deep) plus a
   dotted grid overlay so the pane reads as "ready to draft" rather than blank. The card is
   centered and minimal — the empty state is signal, not noise. */
.ws-blueprint-empty {
  flex: 1;
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 24px;
  background:
    radial-gradient(ellipse at top, var(--accent-glow-strong), transparent 55%),
    /* Dotted grid — subtle bluish dots on a 22px lattice. Goes UNDER the radial glow so the
       grid fades into the brighter top while staying crisp toward the bottom. */
    radial-gradient(circle, rgba(120, 160, 220, 0.12) 1px, transparent 1.4px),
    var(--bg-deep);
  background-size: auto, 22px 22px, auto;
  background-position: center top, 0 0, 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  /* Clip the gradient to the rounded corners so the dotted grid doesn't square off the edges. */
  overflow: hidden;
}

.ws-blueprint-empty-inner {
  text-align: center;
  max-width: 380px;
  padding: 24px;
}

.ws-blueprint-empty-icon {
  width: 56px;
  height: 56px;
  margin-bottom: 16px;
  color: var(--accent-light);
  opacity: 0.85;
}

.ws-blueprint-empty-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.01em;
  margin-bottom: 6px;
}

.ws-blueprint-empty-text {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   CENTER TAB SCENES (Workflow / Facilitator / Instructor)
   Each scene owns a full chat-pane + artifact-pane pair; the bottom tab strip
   spans the full center width below all three. Visual-Studio-style: tab strip
   anchored to the bottom, panels above.
   ────────────────────────────────────────────────────────────────────────── */

/* ws-center is already flex column; the scenes fill the space above the tabs. */
.ws-tab-scene {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Hidden scene retains its layout state (chat scroll, divider position) so the
   user returns to it exactly where they left off. */
.ws-tab-scene.u-hidden {
  display: none;
}

.ws-chat-tabs {
  flex: 0 0 auto;
  display: flex;
  gap: 0;
  border-top: 1px solid var(--border);
  background: var(--bg-primary);
  padding: 0 12px;
}

.ws-chat-tab {
  background: transparent;
  border: none;
  border-top: 2px solid transparent;
  /* Use --text-secondary (medium gray-blue) for inactive tabs rather than --text-muted
     (dark gray-blue) — the latter reads as "disabled" and made users hesitate to click
     vibe / facilitator / instructor. Inactive tabs are always available; the active-state
     contrast still comes through via --text-primary + accent-blue underline. */
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  padding: 8px 14px;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.ws-chat-tab svg {
  width: 14px;
  height: 14px;
}

.ws-chat-tab:hover { color: var(--text-primary); }
.ws-chat-tab.active {
  color: var(--text-primary);
  border-top-color: var(--accent-blue);
}

/* ──────────────────────────────────────────────────────────────────────────
   FACILITATOR + INSTRUCTOR PANELS
   Three states swapped via .u-hidden: loading / catalog / chat.
   The chat state reuses .ws-chat-messages + .ws-chat-input-area so message
   bubbles + send box look identical to the workflow chat.
   ────────────────────────────────────────────────────────────────────────── */
.ws-session-loading {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  color: var(--text-muted);
  font-size: 13px;
}

.ws-session-catalog {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 24px 24px;
}

.ws-session-catalog-header {
  margin-bottom: 18px;
}

.ws-session-catalog-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 4px;
}

.ws-session-catalog-hint {
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.5;
  max-width: 60ch;
}

.ws-session-catalog-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ws-session-category {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ws-session-category-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0 2px;
}

.ws-session-type-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
  text-align: left;
}

.ws-session-type-card:hover {
  background: var(--bg-hover);
  border-color: var(--accent-blue);
}

.ws-session-type-card-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}

.ws-session-type-card-desc {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.45;
}

/* Active session — chat thread + input fill the panel below the toolbar. */
.ws-session-chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.ws-session-chat .ws-chat-messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* Reference chip strip — sits between the facilitator chat pane toolbar and the
   content area, listing prior session reports the user attached as AI context.
   Each chip shows the type name + remove (×) button. Hidden when no refs attached. */
.ws-session-refs {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-secondary);
}

.ws-session-ref-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 10px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-secondary);
}

.ws-session-ref-chip-name {
  font-weight: 500;
  color: var(--text-primary);
}

.ws-session-ref-chip-meta {
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 10px;
}

.ws-session-ref-chip-remove {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-muted);
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.ws-session-ref-chip-remove:hover {
  background: var(--bg-hover);
  color: var(--danger, #ef4444);
}
.ws-session-ref-chip-remove svg { width: 11px; height: 11px; }

/* Empty-list placeholder used when ListMine returns 0 sessions on the My
   Instructor Sessions page. Kept tonally similar to .ws-empty-inner so the
   page reads like the rest of the app. */
.ws-session-empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-muted);
  font-size: 13px;
}

/* ──────────────────────────────────────────────────────────────────────────
   FACILITATOR SESSIONS MODAL (Projects tab) + INSTRUCTOR SESSIONS PAGE
   Both reuse the existing .ws-modal shell or main page shell — these styles
   cover only the session-specific table/list shape.
   ────────────────────────────────────────────────────────────────────────── */
.ws-session-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ws-session-list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.ws-session-list-row-main {
  flex: 1;
  min-width: 0;
}

.ws-session-list-row-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}

.ws-session-list-row-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}

.ws-session-list-row-actions {
  display: flex;
  gap: 6px;
}

.ws-session-report-card {
  margin-top: 16px;
  padding: 16px 18px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  max-height: 60vh;
  overflow-y: auto;
}

.ws-session-report-card .forge-md {
  font-size: 13px;
  line-height: 1.6;
}

/* Picker bar inside the facilitator preview modal — sits between header and the
   scrolling report body. Holds only the session-select dropdown; action buttons
   live inside the artifact-card toolbar in the body so this matches the workspace
   library's report viewer 1:1. */
.fac-picker-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-primary);
  flex-shrink: 0;
}

.fac-picker-bar .input-forge {
  flex: 1;
  max-width: 480px;
}

/* ─── Repos page ──────────────────────────────────────────────────────────
   Org-scoped Repos tab. Three-column shell built on top of the workspace's
   ws-rail-* classes so the rails inherit the same dark/blue theme. Design
   tokens (--bg-primary, --bg-surface, --accent-blue, etc.) are sourced from
   :root in the design-system block at the top of this file. */

.repos-page {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  background: var(--bg-deep);
  color: var(--text-primary);
}

/* No-install empty state ─────────────────────────────── */
.repos-no-install {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.repos-no-install-inner {
  text-align: center;
  max-width: 480px;
  padding: 32px;
  color: var(--text-secondary);
}
.repos-no-install-inner svg {
  width: 48px;
  height: 48px;
  color: var(--accent-blue);
  opacity: 0.7;
  margin-bottom: 16px;
}
.repos-no-install-inner h2 {
  margin: 0 0 12px;
  font-size: 1.25rem;
  color: var(--text-primary);
}
.repos-no-install-inner p {
  margin: 0 0 24px;
  line-height: 1.5;
}

/* Three-column shell — uses flex (NOT grid) to mirror the workspace's .ws-layout. With grid,
   collapsing a rail to 28px would leave the original 260px column slot empty since grid columns
   don't redistribute on element width changes; flex with the center pane on `flex: 1` absorbs
   reclaimed space automatically. position: relative is required so the absolute-positioned
   .ws-rail-tabs reopen docks anchor to this shell rather than the page. */
.repos-shell {
  display: flex;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
}

/* Repos-specific overrides on top of .ws-rail. The workspace's .ws-rail is 260px by default
   and 28px when .collapsed — both rails on this page inherit those widths verbatim. We only
   tweak content padding here so list items get a bit more horizontal breathing room. */
.repos-rail .ws-rail-content { padding: 6px; }

/* Cluster the rail-header buttons (refresh + collapse) on the right edge. The base
   .ws-rail-header uses justify-content: space-between and assumes two children (title +
   collapse); wrapping our two buttons in this container preserves that layout. */
.repos-rail-header-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Right rail uses border-left from .ws-rail-right (already in workspace CSS); both rails are
   flex-shrink: 0 via .ws-rail. Nothing to add. */

/* Left rail: repo picker rows ─────────────────────────── */
.repos-rail-list { display: flex; flex-direction: column; gap: 2px; }
.repos-rail-loading,
.repos-rail-empty,
.repos-rail-error {
  padding: 16px 12px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
}
.repos-rail-error { color: var(--danger); }

.repos-rail-item {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: 8px 10px;
  cursor: pointer;
  color: var(--text-primary);
  transition: all var(--transition);
  font-family: var(--font-sans);
}
.repos-rail-item:hover {
  background: var(--bg-hover);
}
.repos-rail-item.active {
  background: var(--accent-glow);
  border-color: var(--accent-blue-dim);
}
.repos-rail-item-name {
  font-size: 13px;
  font-weight: 600;
  word-break: break-word;
}
.repos-rail-item-owner {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  margin-top: 2px;
}
.repos-rail-item-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.repos-rail-chip {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  font-size: 10px;
  font-family: var(--font-mono);
  background: var(--bg-elevated);
  color: var(--text-secondary);
}
.repos-rail-chip.index {
  background: var(--success-dim);
  color: var(--success);
}
.repos-rail-chip.running {
  background: var(--warning-dim);
  color: var(--warning);
}

/* Center main pane — flex: 1 makes it absorb whatever width the rails leave behind,
   so collapsing either side automatically widens this pane. min-width: 0 lets it shrink
   below content width when both rails are open on a small viewport. */
.repos-main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
  background: var(--bg-deep);
  overflow: hidden;
}
.repos-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 24px;
}
.repos-view-empty {
  align-items: center;
  justify-content: center;
}

/* Run view goes edge-to-edge — the padding that gives the picker / actions / recovery views
   their breathing room would create a thick frame around the chat + artifact panes that the
   workspace doesn't have, so we strip it here. */
.repos-view-run {
  padding: 0;
}
.repos-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: var(--text-muted);
  text-align: center;
  font-size: 14px;
}
.repos-empty-state svg {
  width: 48px;
  height: 48px;
  opacity: 0.5;
}

/* Actions view ─────────────────────────────────────────── */
.repos-actions-header { margin-bottom: 24px; }
.repos-actions-title {
  margin: 0 0 4px;
  font-size: 1.4rem;
  color: var(--text-primary);
  font-family: var(--font-sans);
}
.repos-actions-meta {
  color: var(--text-secondary);
  font-size: 13px;
  font-family: var(--font-mono);
}
.repos-actions-meta strong { color: var(--text-primary); font-weight: 500; }

.repos-actions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.repos-action-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  gap: 12px;
}
.repos-action-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  background: var(--accent-glow);
  color: var(--accent-blue);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.repos-action-icon svg { width: 18px; height: 18px; }
.repos-action-body h3 {
  margin: 0 0 4px;
  font-size: 1.05rem;
  color: var(--text-primary);
}
.repos-action-body p {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
}
.repos-action-disabled-note {
  margin-top: 6px;
  font-size: 12px;
  color: var(--warning);
}
.repos-action-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Running view — chat pane (left) + artifact pane (right) split. The two children are
   .ws-chat-pane / .ws-preview-pane so they pick up the workspace's pane styling for free
   (toolbar height, background, scrollbars, divider). The shell flexes so the divider sits
   between them like the workspace's pane-divider does. */
.repos-run-shell {
  flex: 1;
  display: flex;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}

/* The chat pane on the Repos surface stacks toolbar + working-pill + events. The events
   wrap fills the remaining height so the .ws-build-events list grows to fill the pane
   instead of being capped at the workspace's 280px max-height (which is sized for the
   build step where the plan-step list shares the column). No padding on the wrap itself
   — .ws-build-events already has interior padding, so doubling it just made the event
   text feel cramped against a thick frame. */
.repos-run-events-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  padding: 0;
  overflow: hidden;
}
.repos-run-events-wrap > .ws-build-events {
  flex: 1;
  min-height: 0;
  max-height: none;        /* override workspace's 280px cap — we want full pane height */
  border: none;            /* the chat pane border-bottom on the toolbar is the visual frame */
  border-radius: 0;
}

/* The "Forge is working…" pill sits between the toolbar and the events log. Equal margin on
   all four sides — the bottom gap is what separates the pill from the streaming chat below. */
.repos-run-chat-pane > .ws-build-running {
  margin: 12px;
}

/* No per-sender accent on event lines — the build chat uses uniform .ws-build-event-line
   styling and lets the leading glyph (· system, 💬 assistant, 🔧 tool, ↩ result, ⚠ error,
   ✗ failure) tell the user what kind of event it is. Adding colours would just add noise. */

/* Index runs render their JSON inventory in a code block inside the artifact body. */
.repos-run-index-pre {
  background: var(--bg-elevated);
  padding: 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 12px;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
  color: var(--text-primary);
}

/* The right rail reuses the workspace's .ws-library-tabs / .ws-library-tab / .ws-library-item
   /.ws-library-item-icon / .ws-library-item-name classes directly so the rail reads identically
   to the workspace library. The compact-row pattern (icon + name only, metadata in the modal)
   is the workspace's house style. The repos-library-row class is just a hook for the click
   handler — no extra styling needed beyond what .ws-library-item already provides.

   In-progress runs get a subtle dimming so the user can tell they haven't finished yet, and
   the .ws-library-item-badge fills in the "running" hint without resorting to a coloured pill. */
.repos-library-row.is-running { opacity: 0.65; }

/* Library viewer modal — body is built dynamically into a .ws-artifact-card shell so the
   styling cascades from the workspace's existing artifact-preview rules (.ws-artifact-card,
   .ws-artifact-card-header, .ws-artifact-toolbar, .ws-artifact-body). No Repos-specific
   modal CSS needed beyond the small error message used in the promote/confluence sub-modals. */
.repos-modal-error {
  color: var(--danger);
  margin-top: 8px;
  font-size: 13px;
}

/* Version-history list — used inside the history sub-dialog. Each row is a click target that
   opens that version in the preview modal. Same compact-row rhythm as the workspace's history
   dialog: when on the left, who/badges on the right. */
.repos-history-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 360px;
  overflow-y: auto;
}
.repos-history-list::-webkit-scrollbar { width: 4px; }
.repos-history-list::-webkit-scrollbar-track { background: transparent; }
.repos-history-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.repos-history-row {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) max-content;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
  color: var(--text-primary);
  font-family: var(--font-sans);
  transition: all var(--transition);
}
.repos-history-row:hover {
  background: var(--bg-hover);
  border-color: var(--accent-blue-dim);
}
.repos-history-row-when {
  font-size: 12px;
  font-family: var(--font-mono);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.repos-history-row-who {
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.repos-history-row-who strong { color: var(--text-secondary); font-weight: 500; }
.repos-history-row-badges {
  display: flex;
  gap: 4px;
}

/* Locked action cards: applied to the Document and Review cards while the repo has no
   completed Index. Greys out the card visually and prevents pointer events on the controls
   so even if a stray click reaches a select or button, nothing changes. */
.repos-action-card.locked {
  opacity: 0.55;
  background: var(--bg-elevated);
}
.repos-action-card.locked .repos-action-controls {
  pointer-events: none;
}

/* Recovery card — replaces the action grid when the selected repo has an in-progress run.
   Warning-tinted accent so the user spots it instantly and reaches for View / Abort rather
   than wondering why the action buttons are disabled. */
.repos-recovery-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--warning);
  border-radius: var(--radius-lg);
  padding: 20px;
  max-width: 720px;
}
.repos-recovery-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  background: var(--warning-dim);
  color: var(--warning);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.repos-recovery-icon svg { width: 18px; height: 18px; }
.repos-recovery-body { flex: 1; min-width: 0; }
.repos-recovery-body h3 {
  margin: 0 0 6px;
  font-size: 1.05rem;
  color: var(--text-primary);
}
.repos-recovery-body p {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
}
.repos-recovery-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-shrink: 0;
}

/* Disabled state for the global Forge controls — these were missing visual cues before,
   so disabled buttons looked identical to enabled ones. Scoped to :disabled (and the
   [disabled] attribute) so it applies anywhere across the app, not just the Repos page.
   Cursor stays as the default arrow (matches the disabled-tab pattern noted in the
   ws-build-tab block) — the `not-allowed` icon is intentionally avoided. */
.btn-forge:disabled,
.btn-forge[disabled] {
  opacity: 0.5;
  background: var(--bg-elevated);
  color: var(--text-muted);
  cursor: default;
}
.btn-forge:disabled:hover,
.btn-forge[disabled]:hover {
  background: var(--bg-elevated);
  border-color: var(--border);
  color: var(--text-muted);
}
.input-forge:disabled,
.input-forge[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* ─── Static rails (Org/Teams/Projects/Repos) ─────────────────────────────
   Same width and chrome as the workspace's .ws-rail, but no collapse button
   and no rotated reopen-tab dock. Layered on top of .ws-rail so the
   background, border, header strip, and scrollbars all track the workspace
   rails automatically — only collapse-related styles get neutralized. */
.ws-rail-static.collapsed { width: 260px; }
.ws-rail-static.collapsed > * { display: flex; }

/* ─── Section-bookmark rail (right side of Org/Teams/Projects) ─────────────
   List of in-page anchor links the user clicks to jump to a config-card.
   Same monospace mood as ws-library-tab; active state mirrors the
   .ws-library-tab.active accent rule used elsewhere. */
.bookmarks-list {
  display: flex;
  flex-direction: column;
  padding: 4px 0;
}

.bookmark-link {
  position: relative;
  display: flex;
  align-items: center;
  padding: 8px 16px;
  font-size: 12px;
  color: var(--text-secondary);
  text-decoration: none;
  border-left: 2px solid transparent;
  transition: all var(--transition);
  cursor: pointer;
  user-select: none;
}

.bookmark-link:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}

.bookmark-link.active {
  color: var(--accent-blue);
  border-left-color: var(--accent-blue);
  background: var(--accent-glow);
}

/* Anchor targets inside .full-page-left-content sit under the 36px pane
   toolbar; offset their scroll target so the title isn't hidden by it when
   a bookmark click scrolls them into view. */
.full-page-left-content .config-card[id] {
  scroll-margin-top: 12px;
}

/* ─── Vibe pane (chat-only, ephemeral session) ────────────────────────────
   Layered on top of .ws-chat-pane so the toolbar / event-log / composer
   chrome inherits from the workspace's pane vocabulary. Only the view-swap
   layout and the start-card styling are local. */
.vibe-pane {
  /* Without min-height: 0 the chat-pane sizes itself to its content (events
     log + input), pushing the input below the visible area as the log grows.
     min-height: 0 lets the column-flex chain shrink children and gives the
     events log a real "fill remaining space + scroll" behaviour. */
  min-height: 0;
}

.vibe-pane .vibe-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.vibe-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.vibe-view-start {
  align-items: center;
  justify-content: center;
  padding: 32px 24px;
  overflow-y: auto;
}

.vibe-start-card {
  width: 100%;
  max-width: 540px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  color: var(--text-secondary);
}

.vibe-start-card svg {
  width: 40px;
  height: 40px;
  color: var(--accent-blue);
  opacity: 0.85;
}

.vibe-start-card h3 {
  margin: 4px 0 0;
  font-size: 16px;
  color: var(--text-primary);
}

.vibe-start-card p {
  margin: 0;
  line-height: 1.5;
}

.vibe-start-form {
  width: 100%;
  text-align: left;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.vibe-start-empty {
  width: 100%;
  text-align: left;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.vibe-events-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Bottom padding gives breathing room between the events log and the chat input
     box below — without it the bordered events frame and input frame sit hard
     against each other and read as one cluttered shape. */
  padding: 12px 16px;
}

.vibe-events-wrap > .ws-build-events {
  /* Override the workspace's max-height on .ws-build-events — Vibe is the only thing
     in the chat view, so it gets all the available vertical space. min-height: 0 plus
     flex: 1 1 0 means the events log shrinks/grows with the available column space and
     scrolls internally rather than pushing the input box below the visible area. */
  flex: 1 1 0;
  min-height: 0;
  max-height: none;
  overflow-y: auto;
}

/* User messages get a slight accent so they stand out against assistant + tool lines. */
.vibe-events .ws-build-event-line.vibe-event-user {
  color: var(--text-primary);
  font-weight: 500;
}

/* ─── Vibe attach button + 3-way popover menu ─────────────────────────────
   The + button sits left of the textarea (mirrors workflow's .ws-attach-btn).
   Clicking it pops a small menu with Upload / Project knowledge / Repo review.
   Anchored to the wrap (position: relative) so positioning stays correct
   regardless of where the input box sits in the page. */
.vibe-attach {
  position: relative;
  display: flex;
  align-items: flex-end;
  flex-shrink: 0;
}

.vibe-attach-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  min-width: 180px;
  padding: 4px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.vibe-attach-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-size: 12px;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  font-family: var(--font-sans);
}

.vibe-attach-menu-item:hover { background: var(--bg-hover); }

.vibe-attach-menu-item svg {
  width: 13px;
  height: 13px;
  color: var(--text-secondary);
  flex-shrink: 0;
}

/* ─── Vibe review checklist panel ─────────────────────────────────────────
   Inline panel that appears above the input box when the user selects a repo
   review. The user picks findings to address; clicking Apply dispatches a
   synthesized user message and collapses the panel back to a chip. */
.vibe-review-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 10px;
  padding: 12px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-blue);
  border-radius: var(--radius-md);
  max-height: 360px;
  overflow: hidden;
}

.vibe-review-panel-header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.vibe-review-panel-title {
  flex: 1;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.vibe-review-panel-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.vibe-review-panel-close:hover { color: var(--text-primary); }

.vibe-review-panel-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 0;
}

.vibe-review-finding {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: border-color var(--transition);
}

.vibe-review-finding:hover { border-color: var(--accent-blue-dim); }

.vibe-review-finding.is-non-actionable {
  opacity: 0.55;
  cursor: default;
}

.vibe-review-finding-checkbox {
  margin-top: 2px;
  cursor: pointer;
}

.vibe-review-finding.is-non-actionable .vibe-review-finding-checkbox {
  pointer-events: none;
}

.vibe-review-finding-body {
  flex: 1;
  min-width: 0;
}

.vibe-review-finding-titlerow {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.vibe-review-finding-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.vibe-review-severity-pill {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 3px;
  flex-shrink: 0;
}
.vibe-review-severity-pill.critical,
.vibe-review-severity-pill.high   { background: var(--danger-dim);  color: var(--danger); }
.vibe-review-severity-pill.medium { background: var(--warning-dim); color: var(--warning); }
.vibe-review-severity-pill.low    { background: var(--accent-glow); color: var(--accent-light); }
.vibe-review-severity-pill.info   { background: var(--bg-hover);    color: var(--text-secondary); }

.vibe-review-finding-meta {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vibe-review-finding-summary {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 4px;
  line-height: 1.45;
}

.vibe-review-sent-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--success);
  margin-left: 4px;
}

.vibe-review-panel-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding-top: 4px;
  border-top: 1px solid var(--border);
}

.vibe-review-panel-summary {
  flex: 1;
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

/* Loading + error states for the review panel — extraction is a 10–20s call so
   we need clear feedback during the wait, and a visible "try again" path on
   failure. */
.vibe-review-panel-loading {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 4px;
  color: var(--text-secondary);
  font-size: 12px;
}

.vibe-review-panel-loading .ws-stream-spinner {
  position: relative;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.vibe-review-panel-loading-text {
  flex: 1;
}

.vibe-review-panel-error-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--danger-dim);
  border: 1px solid rgba(248, 113, 113, 0.3);
  border-radius: var(--radius-sm);
}

.vibe-review-panel-error-text {
  font-size: 12px;
  color: var(--danger);
  line-height: 1.45;
}

/* Review chips look the same as attachment chips but click-to-toggle the panel
   instead of doing nothing. The × button still removes the selection from the
   session. */
.vibe-attachment-chip.is-review { cursor: pointer; }
.vibe-attachment-chip.is-review:hover { border-color: var(--accent-blue-dim); }

/* ─── Vibe attachment chips ───────────────────────────────────────────────
   Strip above the input box. Empty by default; chips render here as the
   user attaches files. Chips show a small icon for the source (upload /
   knowledge doc / review report) so the user remembers what they pulled in. */
.vibe-attachment-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 0 8px;
}

.vibe-attachment-strip:empty { display: none; }

.vibe-attachment-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--text-secondary);
  max-width: 280px;
}

.vibe-attachment-chip svg {
  width: 11px;
  height: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.vibe-attachment-chip-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vibe-attachment-chip-remove {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 2px;
  font-size: 14px;
  line-height: 1;
}

.vibe-attachment-chip-remove:hover { color: var(--danger); }

/* ─── Vibe picker modal rows (knowledge + review picker share this) ────────
   List of clickable rows; each row attaches the corresponding source on click.
   Mirrors the .group-tree-item / .repo-list visual feel without inheriting
   their nav-specific behaviour. */
.vibe-picker-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 360px;
  overflow-y: auto;
}

.vibe-picker-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
  text-align: left;
  width: 100%;
  color: inherit;
}

.vibe-picker-row:hover {
  background: var(--bg-hover);
  border-color: var(--accent-blue-dim);
}

.vibe-picker-row:disabled,
.vibe-picker-row.is-attached {
  opacity: 0.5;
  cursor: default;
  pointer-events: none;
}

.vibe-picker-row svg {
  width: 14px;
  height: 14px;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.vibe-picker-row-text {
  flex: 1;
  min-width: 0;
}

.vibe-picker-row-title {
  font-size: 13px;
  color: var(--text-primary);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vibe-picker-row-meta {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  margin-top: 2px;
}

.vibe-picker-empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
}

/* ─── Vibe assistant message blocks ───────────────────────────────────────
   Match the workflow chat's prose treatment so Vibe reads as the same kind of
   chat the user already knows. The body inherits .ws-msg-text styling (13px,
   1.6 line-height, --text-secondary), and the small "Forge" sender label
   mirrors .ws-msg-sender so the visual rhythm of label-then-prose feels the
   same as the rest of the workspace's chat surfaces. */
.vibe-events .vibe-msg-assistant {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 12px 0;
}

.vibe-events .vibe-msg-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

/* Input area is a fixed-size sibling — never shrink it, even when the events log is
   taller than it can render. Without flex-shrink: 0 the column flex would happily
   squash the textarea + send button down to nothing under heavy events output. */
.vibe-input-area {
  flex-shrink: 0;
}

/* Working banner — sit it inset from the panel edges so it reads as a callout rather
   than spanning the whole pane width. Mirrors the visual weight of similar callouts
   on the workspace build pane, with slightly less bottom padding to keep the chat
   start text close to its banner. */
.vibe-pane .ws-build-running {
  margin: 12px 12px 8px;
}

/* ─── Org Config — left-rail tabs (versioned-config CRUD) ──────────────────
   Vertical adaptation of .header-nav-item — same blue accent rule, just on
   the left edge instead of the bottom. Used on the Organization tab to swap
   between Settings, Workflows, Sequences, Roles, Policies, Categories,
   Templates, and Activity sub-views. Reuses .ws-rail / .ws-rail-static for
   the column chrome. */
.org-nav {
  display: flex;
  flex-direction: column;
  padding: 8px 0;
  gap: 1px;
}
.org-nav-group-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 10px 16px 4px;
}
.org-nav-tab {
  position: relative;
  display: flex;
  align-items: center;
  padding: 8px 16px 8px 16px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
  border-right: 2px solid transparent;
  transition: color var(--transition), background var(--transition), border-color var(--transition);
}
.org-nav-tab:hover {
  color: var(--text-primary);
  background: var(--bg-hover);
}
.org-nav-tab.active {
  color: var(--accent-blue);
  border-right-color: var(--accent-blue);
  background: var(--accent-glow);
}
.org-nav-divider {
  height: 1px;
  background: var(--border);
  margin: 6px 12px;
}

/* ─── Org Config — sub-view shell ─────────────────────────────────────────
   Each sub-view is a sibling div toggled by data-subview. When active, the
   subview itself acts as the 880px-constrained container (inherits
   .full-page-left-content > * centering) and its child cards stack inside
   with a 16px gap + bottom padding. CRUD sub-views additionally grow to
   fill remaining vertical space so the centered empty state can center. */
.org-subview { display: none; }
.org-subview.active {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-bottom: 24px;
}
.org-subview.active:not([data-subview="settings"]) {
  flex: 1;
  min-height: 0;
}

/* Empty-state message shown when nothing is selected in a CRUD sub-view.
   Sits directly on the dark bg (no card chrome) so it matches the Teams/
   Projects empty patterns. */
.org-editor-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
  padding: 32px;
}
.org-editor-empty-inner svg {
  width: 36px; height: 36px;
  margin: 0 auto 10px;
  display: block;
  opacity: 0.4;
}

/* ─── Right-rail item picker (replaces bookmarks rail on CRUD sub-views) ──
   List of existing aggregates the user can click to load into the center
   editor. Hover-reveal delete icon mirrors .group-tree-item / .tree-actions. */
.org-config-list {
  display: flex;
  flex-direction: column;
  padding: 6px 0;
}
.org-config-list-empty {
  padding: 18px 16px;
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
}
.org-config-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin: 0 6px 1px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
  position: relative;
}
.org-config-item:hover { background: var(--bg-hover); }
.org-config-item.active { background: var(--accent-glow); }
.org-config-item.archived { opacity: 0.55; }

.org-config-item-name {
  flex: 1;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.org-config-item-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

/* Compact mono-cap badges used on item rows + editor headers. Mirror the
   existing .policy-toggle-badge vocabulary for consistency. */
.config-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--bg-primary);
}
.config-badge.bos {
  color: var(--accent-light);
  border-color: var(--accent-blue-dim);
  background: var(--accent-glow);
}
.config-badge.version { letter-spacing: 0.3px; }
.config-badge.archived {
  color: var(--text-muted);
  border-color: var(--border-subtle);
}
.config-badge.stale {
  color: var(--warning);
  border-color: rgba(251, 191, 36, 0.4);
  background: var(--warning-dim);
  cursor: pointer;
}

/* ─── Clone-mode picker (modal) ──────────────────────────────────────────
   Three radio cards explaining each clone mode in plain language. The user
   picks one before the Clone action proceeds. */
.clone-modes {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}
.clone-mode-card {
  display: flex;
  gap: 10px;
  padding: 10px 12px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.clone-mode-card:hover { border-color: var(--accent-blue-dim); }
.clone-mode-card.selected {
  border-color: var(--accent-blue);
  background: var(--accent-glow);
}
.clone-mode-radio {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid var(--text-muted);
  flex-shrink: 0;
  margin-top: 2px;
  background: var(--bg-deep);
  transition: border-color var(--transition);
}
.clone-mode-card.selected .clone-mode-radio {
  border-color: var(--accent-blue);
  background: var(--accent-blue);
  box-shadow: inset 0 0 0 3px var(--bg-deep);
}
.clone-mode-text { flex: 1; min-width: 0; }
.clone-mode-title { font-size: 12px; font-weight: 600; color: var(--text-primary); }
.clone-mode-desc { font-size: 11px; color: var(--text-secondary); margin-top: 2px; line-height: 1.4; }

/* ─── Auto-activation condition chips (policy editor) ────────────────────
   Rendered in the policy editor when the policy carries
   PolicyAutoActivationCondition rows. Each chip names the trigger (another
   policy or a whole category). Hover-reveal × removes the condition before
   save. */
.condition-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}
.condition-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-secondary);
}
.condition-chip-kind {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.condition-chip-remove {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0;
  font-size: 14px;
  line-height: 1;
}
.condition-chip-remove:hover { color: var(--danger); }

/* ─── Activity log feed ──────────────────────────────────────────────────
   Chronological list shown on the Activity sub-view. Each row is one
   OrgConfigActivityLog entry. */
.activity-feed {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.activity-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-subtle);
}
.activity-row:last-child { border-bottom: 0; }
.activity-when {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
  width: 130px;
  padding-top: 2px;
}
.activity-action {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  flex-shrink: 0;
  width: 72px;
  padding-top: 2px;
}
.activity-action.create   { color: var(--success); }
.activity-action.edit     { color: var(--accent-light); }
.activity-action.clone    { color: var(--accent-light); }
.activity-action.archive  { color: var(--warning); }
.activity-action.unarchive{ color: var(--text-secondary); }
.activity-action.upgrade  { color: var(--accent-light); }
.activity-body { flex: 1; min-width: 0; font-size: 12px; color: var(--text-primary); }
.activity-meta { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* Workflow step rows + sequence item rows — each renders as its own elevated
   card so the list reads as a stack of distinct items rather than a flat
   run-on. The drag handle on the left signals reorderability; drag-over-*
   classes draw a blue insertion line. */
[data-step-row],
[data-item-row] {
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 10px 12px !important;
  margin-bottom: 8px;
  position: relative;
}
[data-step-row]:last-child,
[data-item-row]:last-child { margin-bottom: 0; }
[data-step-row][draggable="true"],
[data-item-row][draggable="true"] { cursor: default; }

.config-step-drag-handle {
  cursor: grab;
  color: var(--text-muted);
  padding: 0 4px;
  user-select: none;
  flex-shrink: 0;
}
.config-step-drag-handle:hover { color: var(--text-secondary); }
.config-step-drag-handle:active { cursor: grabbing; }
[data-step-row].drag-over-top,
[data-item-row].drag-over-top {
  border-top: 2px solid var(--accent-blue);
  padding-top: 9px !important;
}
[data-step-row].drag-over-bottom,
[data-item-row].drag-over-bottom {
  border-bottom: 2px solid var(--accent-blue);
  padding-bottom: 9px !important;
}
[data-step-row].dragging,
[data-item-row].dragging {
  opacity: 0.4;
}

/* Template editor: stretch the editor card + content textarea to fill the
   remaining vertical space of the templates sub-view so authors get the full
   pane to work in rather than a 300px scroll box. The chain needs flex:1 at
   every level (subview → editor host → card → textarea) plus min-height:0 so
   flexbox actually shrinks instead of overflowing the viewport. */
/* Override the generic .org-subview.active padding-bottom on this one subview —
   the surrounding .full-page-left-content already pads 24px below; without the
   override the stretched textarea visibly sits two gaps above the bottom edge. */
.org-subview.active[data-subview="templates"] {
  padding-bottom: 0;
}
.org-subview.active[data-subview="templates"] [data-editor-host].editor-host-active {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.org-subview.active[data-subview="templates"] [data-editor-host].editor-host-active .config-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.config-template-editor {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  gap: 0;
}
.config-template-editor textarea[data-tmpl-content] {
  flex: 1;
  min-height: 240px;
  resize: none;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
}

/* Policy rule rows — same elevated-mini-card treatment as workflow steps. The
   previous styling was a thin border-bottom which read as a tight list; users
   asked for stronger separation between rules so each renders as its own block. */
.config-rule-row {
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  margin-bottom: 8px;
}
.config-rule-row:last-child { margin-bottom: 0; }
.config-rule-row-head {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 6px;
}
.config-rule-row-name {
  display: block;
  color: var(--text-primary);
  font-weight: 600;
  font-size: 13px;
}
.config-rule-row-body {
  color: var(--text-secondary);
  font-size: 12px;
  white-space: pre-wrap;
  margin-top: 4px;
}
.config-rule-row-example-label {
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 8px;
}
.config-rule-row-example {
  color: var(--text-secondary);
  font-size: 12px;
  white-space: pre-wrap;
  margin-top: 2px;
}
