/* ============================================================================================
   The Crucible in Vibe Coder mode: Crucible App Launcher.
   Fred's hand-drawn layout (docs/VIBE-CODER-SOW.md), 2026-07-25.

   THE COLOUR SYSTEM IS THE POINT. Three planning windows, three tints: Main is the house blue
   glass, Second is copper, Third is green. A message that crosses windows keeps its SENDER'S
   tint in the receiving log, so a three-way audit can be followed by eye alone. The tints are
   deliberately quiet — background washes, not paint — because the conversation still has to
   read as one surface.

   Scoped under #ide-root / .vb- so nothing leaks into chat, the dial, or the forge.
   ============================================================================================ */

/* The classic starter stands down while the Vibe surface is up. The lens area (#cru) STAYS: it is
   the Live Preview / Results / Files-Diffs the studio checkboxes gate, and it keeps its place
   below the Vibe sections. Same absent-not-disabled discipline as the beginner surface. */
#ide-root.vb-on #ide-start { display: none !important; }
#ide-root:not(.vb-on) #vb-shell { display: none; }
/* Grid declarations on Vibe panels must never override the browser's native hidden state. */
#ide-root .vb-shell [hidden] { display: none !important; }

.vb-shell {
  display: grid;
  gap: 16px;
  min-width: 0;
  /* Domine carries the conversations (Fred's ruling); the machinery stays on the console faces. */
  --vb-main: 210;    /* hue: house blue   */
  --vb-second: 28;   /* hue: copper       */
  --vb-third: 120;   /* hue: energy green */
}
.vb-h {
  margin: 0;
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--copper-hot, #d4823c);
}
.vb-note { font-size: 11px; color: var(--muted, #8ba0ae); }

/* ---------- 1. App Project Slider --------------------------------------------------------- */
.vb-strip { display: grid; gap: 8px; min-width: 0; }
.vb-slider {
  display: flex; gap: 10px;
  overflow-x: auto; overscroll-behavior-x: contain;
  padding: 4px 2px 10px;
  scrollbar-width: thin;
  cursor: grab;
  touch-action: pan-x;
}
.vb-slider:active { cursor: grabbing; }
.vb-card {
  flex: 0 0 auto;
  display: grid; align-content: center; justify-items: center; gap: 4px;
  width: 118px; min-height: 74px;
  padding: 8px;
  font: inherit; cursor: pointer;
  color: var(--ink, #e8f6ff);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .18));
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(14, 33, 54, .9), rgba(4, 11, 20, .95));
  box-shadow: inset 0 1px 0 rgba(225, 247, 255, .12), 0 6px 16px rgba(0, 0, 0, .4);
}
.vb-card small { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted, #8ba0ae); }
.vb-card .vb-card-name { font-size: 12.5px; font-weight: 650; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vb-card.on { border-color: rgba(118, 255, 104, .55); box-shadow: inset 0 0 16px rgba(118, 255, 104, .1), 0 6px 16px rgba(0, 0, 0, .4); }
.vb-card:hover { border-color: rgba(185, 107, 50, .55); }
/* The project row (Fred, 2026-07-31): filled boxes for projects, wordless blanks for the rest. */
.vb-card-ws { position: relative; cursor: pointer; }
.vb-card-blank { border-style: dashed; background: rgba(4, 11, 20, .45); opacity: .6; cursor: pointer; }
.vb-card-blank:hover { opacity: 1; border-color: rgba(185, 107, 50, .55); }
.vb-card-staged { border-color: rgba(255, 196, 138, .7); box-shadow: inset 0 0 14px rgba(212, 130, 60, .15), 0 6px 16px rgba(0, 0, 0, .4); }
.vb-card-input {
  width: 100%; padding: 6px 8px;
  font: inherit; font-size: 12.5px; text-align: center;
  color: var(--ink, #e8f6ff);
  border: 1px solid rgba(185, 107, 50, .55); border-radius: 6px;
  background: rgba(2, 8, 14, .8);
}
.vb-card-x {
  position: absolute; top: 3px; right: 5px;
  width: 18px; height: 18px; display: grid; place-items: center;
  font: inherit; font-size: 13px; line-height: 1; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 0; border-radius: 4px; background: transparent;
}
.vb-card-x:hover { color: #ffb49a; background: rgba(255, 117, 105, .12); }
/* The Save to: selector lights up when a freshly named project needs its folder. */
.vb-saveto.vb-pulse { animation: vb-saveto-pulse 1.1s ease 3; border-radius: 8px; }
@keyframes vb-saveto-pulse {
  0%, 100% { box-shadow: none; }
  50% { box-shadow: 0 0 0 3px rgba(255, 196, 138, .55); }
}

/* ---------- 2. the small controls --------------------------------------------------------- */
.vb-controls { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.vb-square {
  display: grid; place-content: center; gap: 4px; justify-items: center;
  width: 74px; height: 74px;
  font: inherit; font-size: 11px; letter-spacing: .08em;
  color: var(--ink, #e8f6ff); cursor: pointer;
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .18));
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(14, 33, 54, .9), rgba(4, 11, 20, .95));
}
.vb-square svg { width: 22px; height: 22px; fill: none; stroke: var(--copper-hot, #d4823c); stroke-width: 2; stroke-linecap: round; }
.vb-square:hover { border-color: rgba(185, 107, 50, .55); }
/* The reserved slot looks reserved: present, inert, honest about it. */
.vb-tbd { cursor: default; border-style: dashed; opacity: .5; }
.vb-small {
  align-self: center;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 12px;
  font: inherit; font-size: 11.5px; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .16));
  border-radius: 6px; background: rgba(3, 10, 18, .6);
}
.vb-small:hover { color: var(--ink, #e8f6ff); }
.vb-saveto { cursor: default; }
.vb-saveto select { font: inherit; font-size: 11.5px; color: var(--ink, #e8f6ff); background: rgba(3, 10, 18, .8); border: 1px solid var(--glass-line, rgba(150, 200, 230, .2)); border-radius: 4px; padding: 4px 6px; max-width: 180px; }

/* ---------- 2b. Adopt an App (docs/ADOPT-EXISTING-SOW.md) --------------------------------- */
/* The prominent door: copper-lit beside New, the placement ruling made visible. */
.vb-adopt {
  border-color: rgba(212, 130, 60, .6);
  box-shadow: inset 0 0 16px rgba(212, 130, 60, .12), 0 6px 16px rgba(0, 0, 0, .4);
}
.vb-adopt:hover { border-color: var(--copper-hot, #d4823c); box-shadow: inset 0 0 22px rgba(212, 130, 60, .2), 0 6px 16px rgba(0, 0, 0, .45); }
.vb-adopt span { color: var(--copper-hot, #d4823c); font-weight: 650; }
.vb-adopt-panel { border-color: rgba(212, 130, 60, .5); }
.vb-adopt-x {
  font: inherit; font-size: 16px; line-height: 1; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .16));
  border-radius: 6px; background: rgba(3, 10, 18, .6);
  padding: 4px 10px;
}
.vb-adopt-x:hover { color: var(--ink, #e8f6ff); }
.vb-adopt-intro { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-soft, #d9c9b8); }
.vb-adopt-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vb-adopt-lab { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted, #8ba0ae); }
.vb-adopt-lab select { font: inherit; font-size: 11.5px; color: var(--ink, #e8f6ff); background: rgba(3, 10, 18, .8); border: 1px solid var(--glass-line, rgba(150, 200, 230, .2)); border-radius: 4px; padding: 4px 6px; max-width: 220px; }
.vb-adopt-tree { display: grid; gap: 4px; max-height: 240px; overflow-y: auto; padding: 8px; border: 1px solid var(--glass-line, rgba(150, 200, 230, .14)); border-radius: 8px; background: rgba(2, 7, 14, .7); }
.vb-adopt-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted, #8ba0ae); padding-bottom: 4px; }
.vb-adopt-bar button, .vb-adopt-dir {
  font: inherit; font-size: 11.5px; text-align: left; cursor: pointer;
  color: var(--ink, #e8f6ff);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .16));
  border-radius: 5px; background: rgba(3, 10, 18, .6);
  padding: 6px 9px;
}
.vb-adopt-bar .vb-adopt-use { border-color: rgba(118, 255, 104, .45); color: #d8ffcd; }
.vb-adopt-dir:hover, .vb-adopt-bar button:hover { border-color: rgba(185, 107, 50, .55); }
/* Both gestures per row (Fred, 2026-07-26): the name steps inside; This one chooses directly. */
.vb-adopt-dirrow { display: flex; align-items: stretch; gap: 6px; min-width: 0; }
.vb-adopt-dirrow .vb-adopt-dir { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vb-adopt-pickone {
  flex: none; font: inherit; font-size: 11px; cursor: pointer;
  color: #d8ffcd; border: 1px solid rgba(118, 255, 104, .4);
  border-radius: 5px; background: rgba(3, 10, 18, .6);
  padding: 6px 10px;
}
.vb-adopt-pickone:hover { border-color: rgba(118, 255, 104, .7); }
/* Fresh start (Fred, 2026-07-26): advisor windows only; quiet until hovered. */
.vb-win-fresh {
  font: inherit; font-size: 10.5px; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .16));
  border-radius: 5px; background: rgba(3, 10, 18, .6);
  padding: 4px 8px; margin-left: auto;
}
.vb-win-fresh:hover { color: var(--ink, #e8f6ff); border-color: rgba(185, 107, 50, .55); }
.vb-win-toprow .vb-win-toggle { margin-left: 8px; }
/* The destinations hint: plain words where the tick boxes appear. */
.vb-adopt-empty { font-size: 11.5px; color: var(--muted, #8ba0ae); padding: 4px 2px; }
/* The note is the panel's voice; failure and success both speak up (quiet success was the bug). */
#vb-adopt-note { font-size: 12px; }
#vb-adopt-note.is-bad { color: #ff9d8a; font-size: 12.5px; font-weight: 650; }
#vb-adopt-note.is-good { color: #a9f29b; font-size: 12.5px; font-weight: 650; }
/* Three slow copper pulses on Analyze once a folder is chosen: the next press, made unmissable. */
.vb-pulse { animation: vb-pulse 1.1s ease-in-out 3; }
@keyframes vb-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212, 130, 60, 0); }
  50% { box-shadow: 0 0 0 7px rgba(212, 130, 60, .35); }
}

/* ---------- 3. Customize Your Workspace --------------------------------------------------- */
.vb-box {
  display: grid; gap: 12px; min-width: 0;
  padding: 14px;
  border: 1px solid rgba(185, 107, 50, .35);
  border-radius: 10px;
  background: radial-gradient(80% 60% at 50% 0%, rgba(185, 107, 50, .08), transparent 70%),
    linear-gradient(180deg, rgba(8, 20, 34, .92), rgba(2, 7, 14, .96));
}
.vb-box-head, .vb-box-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.vb-presets { display: flex; gap: 8px; flex-wrap: wrap; }
.vb-presets button {
  padding: 9px 16px;
  font: inherit; font-size: 12px; letter-spacing: .06em; cursor: pointer;
  color: var(--ink, #e8f6ff);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .2));
  border-radius: 6px; background: rgba(3, 10, 18, .6);
}
.vb-presets button.on { border-color: rgba(118, 255, 104, .5); color: #d8ffcd; box-shadow: inset 0 0 12px rgba(118, 255, 104, .08); }
.vb-mods { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.vb-mod { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-soft, #d9c9b8); cursor: pointer; }
/* Active module designations (Fred, 2026-07-25): normal-flow tiles, wrap on any width — they can
   never overlap other content and are never pinned anywhere. */
/* Custom's tick boxes carry their own explanations now; the separate explainer tiles are gone. */
.vb-mod-words { display: inline-grid; gap: 1px; }
.vb-mod-words b { font-size: 12px; color: var(--ink, #e8f6ff); }
.vb-mod-words small { font-size: 10.5px; color: var(--muted, #8ba0ae); line-height: 1.35; }

/* The chosen folder's real address, said out loud under the selector. */
.vb-saveto-where {
  margin: -6px 0 2px;
  font: 500 11px/1.5 ui-monospace, Consolas, monospace;
  color: var(--muted, #8ba0ae);
  overflow-wrap: anywhere;
}
/* What is actually inside it, and whether the planners can open it (Fred, 2026-08-01). Lit rather
   than muted, because "the AI can see my folder" is the fact he could not previously tell. */
.vb-saveto-peek { display: inline-block; margin-top: 2px; color: var(--energy, #66ff5b); }
.vb-saveto-peek.is-bad { color: #ffb08a; }

/* ---------- the plan-from-chat button and the shared modal --------------------------------- */
.vb-plan-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.vb-plan-view {
  padding: 6px 12px;
  font: inherit; font-size: 11px; letter-spacing: .06em; cursor: pointer;
  color: #ffd9ae;
  border: 1px solid rgba(214, 150, 90, .5); border-radius: 6px;
  background: rgba(13, 17, 23, .72);
}
.vb-plan-view:hover { border-color: rgba(255, 196, 138, .8); }
.vb-modal {
  position: fixed; inset: 0; z-index: 2147479000;
  display: flex; align-items: center; justify-content: center;
  padding: 18px;
  background: rgba(0, 3, 8, .6); backdrop-filter: blur(6px);
}
.vb-modal-card {
  display: grid; gap: 10px;
  width: min(680px, 100%); max-height: 82vh;
  padding: 16px;
  border: 1px solid rgba(214, 150, 90, .5); border-radius: 12px;
  background: #0d1117;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .65);
}
.vb-modal-head { display: flex; align-items: center; gap: 10px; }
.vb-modal-head .vb-h { flex: 1 1 auto; }
.vb-modal-copy {
  padding: 5px 12px; font: inherit; font-size: 11px; cursor: pointer;
  color: var(--ink, #e8f6ff);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .3)); border-radius: 6px; background: transparent;
}
.vb-modal-x {
  width: 28px; height: 28px; display: grid; place-items: center;
  font: inherit; font-size: 18px; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 0; border-radius: 6px; background: transparent;
}
.vb-modal-x:hover { color: #ffb49a; }
.vb-modal-body {
  overflow: auto; min-height: 0;
  padding: 4px 2px;
  font-family: "Domine", Georgia, serif; font-size: 13.5px; line-height: 1.55;
  color: var(--ink, #eaf6ff);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.vb-modal .vb-adopt-tree { max-height: 60vh; overflow: auto; }

/* ---------- the per-window note: feedback beside the control, never only page-bottom ------- */
.vb-win-note {
  margin: 4px 12px 0;
  padding: 7px 10px;
  font-size: 12px; line-height: 1.45;
  color: #cfe4f2;
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .35);
  border-radius: 8px;
  background: hsla(var(--vb-hue), 45%, 14%, .75);
}
.vb-win-note.is-bad { color: #ffc0ba; border-color: rgba(255, 117, 105, .45); background: rgba(67, 18, 16, .5); }
/* The receiving window announces the arrival: one bright pulse of its own hue. */
.vb-win.vb-flash { animation: vb-win-flash 1.2s ease 2; }
@keyframes vb-win-flash {
  0%, 100% { box-shadow: none; }
  50% { box-shadow: 0 0 0 3px hsla(var(--vb-hue), 70%, 60%, .65); }
}

/* ---------- Copy all + the per-bubble clipboard glyph -------------------------------------- */
.vb-copyall-row { display: flex; justify-content: flex-end; padding: 0 12px; }
.vb-copyall {
  padding: 3px 10px;
  font: inherit; font-size: 10.5px; letter-spacing: .06em; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .2)); border-radius: 5px; background: transparent;
}
.vb-copyall:hover { color: var(--ink, #e8f6ff); border-color: rgba(185, 107, 50, .5); }
.vpb-vision-done { margin: 8px 0 0; font-size: 12px; color: var(--lime, #8fe08a); }
.vb-mod input { cursor: pointer; accent-color: var(--energy, #76ff68); }
.vb-apply {
  padding: 9px 22px;
  font: inherit; font-weight: 700; letter-spacing: .1em; font-size: 12px; cursor: pointer;
  color: #06180c;
  border: 1px solid rgba(160, 255, 133, .7); border-radius: 6px;
  background: linear-gradient(180deg, #b8ff9d, #4fd35f 65%);
}

/* ---------- 4. Plan with AI --------------------------------------------------------------- */
.vb-plan { display: grid; gap: 12px; min-width: 0; }
/* Fred, 2026-07-26: the Plan with AI heading is the section's banner, three times the standard
   heading size and centered, and the Assign Your Troops banner divides planning from building at
   the same size. Only these banners; the window names keep their own treatment. */
.vb-plan > .vb-h, .vb-banner { font-size: 36px; text-align: center; }
.vb-plan-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; min-width: 0; }
@media (max-width: 760px) { .vb-plan-row { grid-template-columns: 1fr; } }

.vb-win {
  /* minmax(0,1fr): the implicit auto track otherwise grows to the widest child's natural width
   * (grid children keep min-width:auto), which at phone width pushed the log to 415px inside a
   * 343px window and clipped it off-screen. The column must be allowed to shrink below content. */
  display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0;
  border-radius: 12px;
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .3);
  background: linear-gradient(180deg, hsla(var(--vb-hue), 45%, 16%, .82), hsla(var(--vb-hue), 50%, 7%, .94));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 10px 26px rgba(0, 0, 0, .45);
  overflow: hidden;
}
.vb-win-main { --vb-hue: var(--vb-main); }
.vb-win-second { --vb-hue: var(--vb-second); }
.vb-win-third { --vb-hue: var(--vb-third); }

.vb-win-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px;
  border-bottom: 1px solid hsla(var(--vb-hue), 60%, 60%, .22);
}
/* Army ranks (Fred, 2026-07-26): the name is the window's badge now. Twice the old size, on a
   plate in the window's own hue bright enough to contrast with the dark body, with the rank's
   insignia beside it. The sub-label keeps the plain AI-planner wording so nobody has to decode
   military shorthand. */
.vb-win-head b.vb-win-title {
  display: inline-flex; align-items: center; gap: 9px; min-width: 0;
  font-size: 24px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink, #e8f6ff);
  padding: 5px 14px; border-radius: 8px;
  background: linear-gradient(180deg, hsla(var(--vb-hue), 72%, 42%, .55), hsla(var(--vb-hue), 78%, 28%, .55));
  border: 1px solid hsla(var(--vb-hue), 80%, 66%, .6);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
}
.vb-rank { height: 15px; width: auto; flex: none; fill: hsla(var(--vb-hue), 92%, 80%, .95); }
.vb-win-title .vb-rank-name { white-space: nowrap; }
.vb-win-title .vb-rank-sub { font-style: normal; font-size: 10.5px; color: var(--ink-soft, #d9c9b8); text-transform: none; letter-spacing: .04em; }
@media (max-width: 620px) { .vb-win-head b.vb-win-title { font-size: 19px; } }
/* The Captain and the Sergeant stack rank first, seat under (Fred, 2026-07-26): the header goes
   column, the top row holds the plate and the Open toggle, the picker sits just below the title. */
.vb-win-head-col { flex-direction: column; align-items: stretch; gap: 8px; }
.vb-win-head-col .vb-win-toprow { display: flex; align-items: center; gap: 10px; min-width: 0; }
.vb-win-head-col .vb-win-model { max-width: 62%; align-self: flex-start; }

/* Silent message selection: the tick boxes exist only while the Send destinations are open, and
   nothing on screen explains them (the guide does). Copper accent, corner of each bubble. */
.vpb { position: relative; }
.vpb-pick { display: none; position: absolute; top: 6px; right: 8px; }
.vb-log.vb-selecting .vpb-pick { display: inline-flex; }
.vpb-pick input { width: 15px; height: 15px; accent-color: var(--copper-hot, #d4823c); cursor: pointer; }
/* Upper left is the model selector, per the drawing's margin note. */
.vb-win-model {
  max-width: 46%;
  font: inherit; font-size: 11px;
  color: var(--ink, #e8f6ff);
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .35);
  border-radius: 5px; padding: 5px 6px;
  background: rgba(2, 8, 14, .75);
}
.vb-win-toggle {
  margin-left: auto;
  padding: 5px 12px;
  font: inherit; font-size: 11px; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .18));
  border-radius: 5px; background: transparent;
}
.vb-win-body { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; }
.vb-win-body > * { min-width: 0; }
.vb-win-body[hidden] { display: none; }

.vb-log {
  height: 240px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px 12px 6px;
  font-family: "Domine", Georgia, "Times New Roman", serif;
  font-size: 14.5px; line-height: 1.55;
}
.vb-win-main .vb-log { height: 300px; }
.vpb { max-width: 88%; padding: 10px 13px; border-radius: 12px; min-width: 0; overflow-wrap: anywhere; }
.vpb p { margin: 0; white-space: pre-wrap; }
.vpb-user {
  align-self: flex-end;
  color: #06180c;
  background: linear-gradient(180deg, #cdf7c2, #8fe08a);
  border-bottom-right-radius: 4px;
}
.vpb-ai {
  align-self: flex-start;
  color: var(--ink, #eaf6ff);
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .28);
  background: hsla(var(--vb-hue), 40%, 14%, .75);
  border-bottom-left-radius: 4px;
}
/* A turn that crossed windows wears its SENDER'S colour here, and says which AI it came from.
   That one visual rule is what makes the three-way audit followable at a glance. */
.vpb-from { align-self: flex-start; color: var(--ink, #eaf6ff); border-bottom-left-radius: 4px; border: 1px solid; }
.vpb-from-main { background: hsla(var(--vb-main), 45%, 16%, .85); border-color: hsla(var(--vb-main), 60%, 60%, .45); }
.vpb-from-second { background: hsla(var(--vb-second), 45%, 16%, .85); border-color: hsla(var(--vb-second), 60%, 60%, .45); }
.vpb-from-third { background: hsla(var(--vb-third), 45%, 16%, .85); border-color: hsla(var(--vb-third), 60%, 60%, .45); }
.vpb-tag { display: block; margin-bottom: 5px; font-family: "Cascadia Mono", Consolas, monospace; font-size: 9px; letter-spacing: .12em; text-transform: uppercase; opacity: .7; }
.vpb-err { border-color: rgba(255, 120, 96, .5); color: #ffb49a; }
.vpb-thinking { display: flex; gap: 6px; }
.vpb-thinking i { width: 8px; height: 8px; border-radius: 50%; background: #79ff52; box-shadow: 0 0 5px 1px rgba(121, 255, 82, .7); animation: vb-blink 1.2s infinite; }
.vpb-thinking i:nth-child(2) { animation-delay: .18s; }
.vpb-thinking i:nth-child(3) { animation-delay: .36s; }
@keyframes vb-blink { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .vpb-thinking i { animation-duration: 3s; } }
.vpb-vision {
  align-self: stretch; max-width: 100%;
  border: 1px solid rgba(160, 255, 133, .4);
  background: linear-gradient(180deg, rgba(24, 60, 30, .55), rgba(6, 20, 10, .8));
}
.vpb-vision h4 { margin: 0 0 7px; font-family: "Cascadia Mono", Consolas, monospace; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--lime-hot, #b9ff9d); }
.vpb-vision div { white-space: pre-wrap; }

/* The bottom-edge grab bar: drag it down and the window grows, the page moves down (Fred's
   customize-what-you-concentrate-on rule). Full width so it can actually be found. */
.vb-grab {
  display: grid; place-items: center;
  height: 14px;
  cursor: ns-resize;
  touch-action: none;
}
.vb-grab i { width: 44px; height: 4px; border-radius: 999px; background: hsla(var(--vb-hue), 60%, 60%, .4); }
.vb-grab:hover i { background: hsla(var(--vb-hue), 60%, 70%, .7); }

/* ---------- the reading desk (Fred, 2026-08-01) --------------------------------------------
   Documents attached to the CONVERSATION, listed above the typing field so the person can see
   exactly what the rank is holding and take any of it back off. Each chip states how the file was
   read and how much of it landed, because "did my PDF actually go through?" is the whole worry. */
.vb-desk { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 12px 6px; min-width: 0; }
.vb-doc {
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
  padding: 5px 6px 5px 10px;
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .38); border-radius: 8px;
  background: rgba(2, 10, 16, .72);
}
.vb-doc b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; font-weight: 600; color: var(--ink, #eaf6ff); }
.vb-doc small { white-space: nowrap; font-size: 9.5px; letter-spacing: .02em; color: var(--muted, #8ba0ae); }
.vb-doc.is-stale { border-color: rgba(255, 176, 138, .5); }
.vb-doc.is-stale small { color: #ffb08a; }
.vb-doc-x {
  flex: 0 0 auto; width: 20px; height: 20px; padding: 0; cursor: pointer;
  font: 600 14px/1 system-ui, sans-serif; color: var(--muted, #8ba0ae);
  border: 1px solid transparent; border-radius: 5px; background: transparent;
}
.vb-doc-x:hover { color: #ffc0ba; border-color: rgba(255, 117, 105, .45); }
.vb-clip {
  flex: 0 0 auto; width: 38px; height: 38px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .3); border-radius: 9px;
  background: rgba(2, 8, 14, .7);
}
.vb-clip svg { width: 19px; height: 19px; fill: none; stroke: var(--muted, #8ba0ae); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.vb-clip:hover svg { stroke: var(--energy, #66ff5b); }
.vb-clip.is-busy { pointer-events: none; }
.vb-clip.is-busy svg { stroke: var(--energy, #66ff5b); animation: vb-clip-pulse 1s ease-in-out infinite; }
@keyframes vb-clip-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
/* A file dragged anywhere over the window is a valid drop, so the whole body lights up. */
.vb-win-body.is-dropping { outline: 2px dashed hsla(var(--vb-hue), 70%, 62%, .7); outline-offset: -4px; }

.vb-row { display: flex; align-items: flex-end; gap: 8px; padding: 8px 12px 12px; min-width: 0; }
.vb-row textarea {
  flex: 1 1 0; min-width: 0; resize: none;
  padding: 10px 12px;
  font-family: "Domine", Georgia, serif; font-size: 13.5px; line-height: 1.4;
  color: var(--ink, #eaf6ff);
  border: 1px solid hsla(var(--vb-hue), 60%, 60%, .3);
  border-radius: 9px;
  background: rgba(2, 8, 14, .7);
}
/* The split Send (Fred, 2026-07-31): Send on top, Advisors underneath, one control cut in half. */
.vb-sendstack { position: relative; flex: 0 0 auto; }
.vb-split { display: grid; gap: 0; }
.vb-send {
  min-width: 74px; padding: 10px 16px;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .08em; cursor: pointer;
  color: #06180c;
  border: 1px solid rgba(160, 255, 133, .7); border-radius: 9px;
  background: linear-gradient(180deg, #b8ff9d, #4fd35f 65%);
}
.vb-split .vb-send-top { border-radius: 9px 9px 0 0; padding: 8px 16px; }
.vb-send-adv {
  min-width: 74px; padding: 5px 16px;
  font: inherit; font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; cursor: pointer;
  color: var(--muted, #8ba0ae);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .3)); border-top: 0; border-radius: 0 0 9px 9px;
  background: rgba(3, 10, 18, .8);
}
.vb-send-adv.on { color: #ffc48a; border-color: rgba(185, 107, 50, .6); background: rgba(185, 107, 50, .16); }
/* The two insignia buttons, a third of the Send button each, wearing the OTHER ranks' colours. */
.vb-adv-btns { display: flex; gap: 6px; align-items: flex-end; }
.vb-adv-btn {
  display: grid; place-items: center;
  width: 44px; height: 40px; padding: 4px;
  cursor: pointer; border-radius: 8px;
}
.vb-adv-btn .vb-rank { height: 12px; width: auto; }
.vb-adv-main { border: 1px solid hsla(var(--vb-main), 60%, 60%, .6); background: hsla(var(--vb-main), 45%, 18%, .9); }
.vb-adv-main .vb-rank { fill: hsl(var(--vb-main), 70%, 72%); }
.vb-adv-second { border: 1px solid hsla(var(--vb-second), 60%, 60%, .6); background: hsla(var(--vb-second), 45%, 18%, .9); }
.vb-adv-second .vb-rank { fill: hsl(var(--vb-second), 70%, 68%); }
.vb-adv-third { border: 1px solid hsla(var(--vb-third), 60%, 60%, .6); background: hsla(var(--vb-third), 45%, 18%, .9); }
.vb-adv-third .vb-rank { fill: hsl(var(--vb-third), 70%, 68%); }
.vb-adv-btn:hover { filter: brightness(1.25); }

/* ---------- 5. Agent Army ----------------------------------------------------------------- */
#vb-plan-tasks {
  padding: 8px 16px;
  font: inherit; font-size: 12px; cursor: pointer;
  color: var(--copper-hot, #d4823c);
  border: 1px solid rgba(185, 107, 50, .45); border-radius: 6px;
  background: rgba(3, 10, 18, .6);
}
#vb-plan-tasks:hover { color: #ffc48a; }
/* The orchestrator seat: one row, one model, above every task it will divide. */
.vb-orch {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid rgba(185, 107, 50, .5);
  border-radius: 8px;
  background: linear-gradient(90deg, rgba(185, 107, 50, .12), transparent 60%);
}
.vb-orch-label { font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--copper-hot, #d4823c); }
#vb-orch-model { font: inherit; font-size: 12px; color: var(--ink, #e8f6ff); background: rgba(2, 8, 14, .8); border: 1px solid rgba(185, 107, 50, .4); border-radius: 5px; padding: 6px 8px; max-width: 300px; }
.vb-orch-note { flex: 1 1 220px; font-size: 11px; line-height: 1.45; color: var(--muted, #8ba0ae); }
/* The fallback notice: the seat changed hands and the row says so until the next plan. */
.vb-orch-note.is-fallback { color: #ffc48a; }

/* An author display beats the [hidden] attribute (the beginner-views lesson): without this line
 * the empty header row shows before any plan exists. */
.vb-army-grid[hidden], .vb-army-total[hidden] { display: none; }
.vb-army-grid {
  display: grid;
  grid-template-columns: minmax(200px, 2.2fr) minmax(150px, 1.4fr) auto auto auto;
  gap: 6px 12px;
  align-items: center;
  min-width: 0;
  overflow-x: auto;
}
.vb-army-head { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted, #8ba0ae); padding-bottom: 2px; border-bottom: 1px solid var(--glass-line, rgba(150, 200, 230, .14)); }
.vb-army-cell { min-width: 0; font-size: 12.5px; color: var(--ink, #e8f6ff); padding: 4px 0; }
.vb-c-task b { display: block; font-size: 12.5px; font-weight: 650; }
.vb-c-task small { display: block; color: var(--muted, #8ba0ae); font-size: 10.5px; overflow-wrap: anywhere; }
.vb-c-model select { width: 100%; font: inherit; font-size: 11.5px; color: var(--ink, #e8f6ff); background: rgba(2, 8, 14, .8); border: 1px solid var(--glass-line, rgba(150, 200, 230, .2)); border-radius: 4px; padding: 5px 6px; }
.vb-agents { display: inline-flex; align-items: center; gap: 7px; }
.vb-agents button {
  width: 26px; height: 26px; display: grid; place-items: center;
  font: inherit; font-size: 14px; cursor: pointer;
  color: var(--ink, #e8f6ff);
  border: 1px solid var(--glass-line, rgba(150, 200, 230, .25)); border-radius: 5px;
  background: rgba(3, 10, 18, .7);
}
.vb-agents span { min-width: 18px; text-align: center; font-weight: 700; }
.vb-c-cost, .vb-c-time { font-family: "Cascadia Mono", Consolas, monospace; font-size: 11.5px; color: var(--lime, #8fe08a); white-space: nowrap; }
.vb-reduce { display: block; margin-top: 3px; font-size: 10.5px; }
.vb-reduce-irr { color: #ffb49a; }
.vb-reduce-ok { color: var(--muted, #8ba0ae); }
.vb-army-total { font-size: 12px; color: var(--ink-soft, #d9c9b8); border-top: 1px solid var(--glass-line, rgba(150, 200, 230, .14)); padding-top: 8px; }

/* ---------- 6. Begin Building ------------------------------------------------------------- */
/* ---- The spend limit, immediately above the button that starts spending. Deliberately plain and
   close to BEGIN BUILDING: this is the one control standing between an optimistic estimate and a
   real bill, so it reads as part of the same decision rather than a setting somewhere else. ---- */
.vb-budget {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 0 0 10px; padding: 10px 12px;
  border: 1px solid rgba(212, 130, 60, .38); border-radius: 10px;
  background: rgba(10, 6, 2, .45);
}
/* Ship to GitHub (Fred, 2026-08-01), beside the spend limit because both answer the same
   question: what is this build allowed to do on my behalf. Cooler than the money row on purpose,
   so the two never read as one control. */
.vb-ship {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 0 0 10px; padding: 10px 12px;
  border: 1px solid hsla(var(--vb-hue), 55%, 58%, .34); border-radius: 10px;
  background: rgba(2, 8, 14, .5);
}
.vb-ship.is-idle { opacity: .55; }
.vb-ship-switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; }
.vb-ship.is-idle .vb-ship-switch { cursor: default; }
.vb-ship-switch input { width: 17px; height: 17px; accent-color: var(--energy, #66ff5b); cursor: inherit; }
.vb-ship-switch span { font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--ink, #eaf6ff); }
.vb-ship-note { flex: 1 1 240px; min-width: 0; font-size: 11px; line-height: 1.45; color: var(--muted, #8ba0ae); }
.vb-ship-note.is-good { color: var(--energy, #66ff5b); }
.vb-ship-note.is-bad { color: #ffb08a; }
.vb-budget-label { font-size: 12px; font-weight: 700; letter-spacing: .04em; color: #e8d3ba; }
.vb-budget-input {
  width: 110px; min-width: 0; padding: 7px 9px;
  font: inherit; font-size: 14px; color: #ffe9c4;
  border: 1px solid rgba(212, 130, 60, .5); border-radius: 8px;
  background: rgba(0, 0, 0, .45);
}
.vb-budget-input:focus { outline: 1px solid rgba(255, 176, 74, .8); outline-offset: 1px; }
.vb-budget-unit { font-size: 12px; color: #e8d3ba; }
/* The note carries the consequence, and it is the whole point of the row: a blank field is a
   legitimate choice and must still say what it means. */
.vb-budget-note { flex: 1 1 100%; font-size: 11px; color: var(--muted, #8ba0ae); }

.vb-begin {
  width: 100%;
  padding: 18px;
  font: inherit; font-size: 17px; font-weight: 800; letter-spacing: .16em; cursor: pointer;
  color: #06180c;
  border: 1px solid rgba(160, 255, 133, .8); border-radius: 12px;
  background: linear-gradient(180deg, #b8ff9d, #4fd35f 60%, #2ea347);
  box-shadow: 0 10px 30px rgba(80, 220, 90, .28), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.vb-begin:hover { filter: brightness(1.06); }
.vb-begin:active { transform: translateY(1px); }
.vb-status { min-height: 18px; font-size: 12px; color: var(--muted, #8ba0ae); }
.vb-status.is-bad { color: #ffb49a; }

@media (max-width: 620px) {
  .vb-square { width: 64px; height: 64px; }
  .vb-log { height: 220px; }
  .vb-win-main .vb-log { height: 260px; }
  .vb-army-grid { grid-template-columns: minmax(160px, 2fr) minmax(130px, 1.3fr) auto auto auto; font-size: 11.5px; }
}

/* ---- Phones (Fred, 2026-07-30): the advisor windows LOOKED chat-less. The rank subtitle pushed
   the Open toggle 15px past the window frame (title carries nowrap, so the top row could not
   shrink), and the Send destination stack extended DOWNWARD from a composer that sits just above
   the on-screen keyboard, i.e. straight behind it. Subtitle folds away, the top row is allowed to
   shrink, and the destinations open UPWARD where the eye and the thumb already are. ---- */
@media (max-width: 620px) {
  .vb-win-title .vb-rank-sub { display: none; }
  .vb-win-head-col .vb-win-toprow { min-width: 0; }
  .vb-win-head-col .vb-win-toprow .vb-win-title { min-width: 0; overflow: hidden; }
  @keyframes vb-drop { from { opacity: 0; transform: translateY(4px); } }
}

/* ---- Copy (Fred, 2026-07-31). The main chat has had per-message Copy for months; these three
   windows, where the plan is actually written, had no way to lift text at all. Per bubble and per
   window, because a plan worth keeping is usually the conversation rather than one reply.

   The per-bubble button is quiet until the bubble is touched: a Copy on every line would compete
   with the words, and the words are the point. Keyboard focus reveals it too, so it is reachable
   without a pointer. ---- */
.vpb { position: relative; padding-bottom: 20px; }
/* The traditional quiet clipboard glyph, bottom-right of every bubble (Fred, 2026-07-31). It
   never fights the tick boxes, which live top-right. */
.vpb-copy {
  position: absolute; bottom: 4px; right: 6px;
  display: grid; place-items: center;
  width: 22px; height: 22px; padding: 0; border-radius: 6px;
  cursor: pointer; opacity: 0; transition: opacity .13s ease, color .13s ease;
  color: #9db4c4; border: 0; background: transparent;
}
.vpb-copy svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.vpb:hover .vpb-copy, .vpb-copy:focus-visible { opacity: 1; }
.vpb-copy:hover { color: #fff; background: rgba(126, 231, 255, .12); }
.vpb-copy.is-done { opacity: 1; color: #b8ffc4; }
/* Coarse pointers get no hover, so the glyph is simply always there on a phone. */
@media (pointer: coarse) { .vpb-copy { opacity: .6; } }
