/* codemesh sidebar. Hybrid theming: surfaces, text and borders follow the
   editor theme through the --vscode-* variables VS Code injects into every
   webview (near-black fallbacks for outside-the-editor previews); the brand
   accent and status colors from the approved v3 mockups stay fixed. */
:root {
  --bg: var(--vscode-sideBar-background, #000000);
  /* Cards lift off the themed background with a translucent tint of the
     opposite pole (theme surface tokens like editorWidget-background can be
     identical to the sidebar background, which made cards invisible). */
  --card: rgba(255, 255, 255, 0.06);
  --border: rgba(255, 255, 255, 0.16);
  --divider: var(--vscode-panel-border, #1c1c1c);
  --text: var(--vscode-sideBar-foreground, var(--vscode-foreground, #f5f5f5));
  --body: var(--vscode-foreground, #dddddd);
  --dim: var(--vscode-descriptionForeground, #9a9a9a);
  --faint: var(--vscode-disabledForeground, #6f6f6f);
  --accent: #4f8ff7;
  --accent-soft: #8fb4f2;
  --label: #5d8fdb;
  --ok: #34d399;
  --warn: #fbbf24;
  --error: #f28b8b;
  --toggle-off: var(--vscode-input-background, #2a2a2a);
  --chip-border: rgba(79, 143, 247, 0.35);
  --raised: var(--vscode-menu-background, var(--vscode-editorWidget-background, #161616));
  --mono: ui-monospace, Menlo, Consolas, monospace;
}
/* Light editor themes: same brand hues, darkened so text and status colors
   stay legible on light surfaces. */
body.vscode-light,
body.vscode-high-contrast-light {
  --card: rgba(0, 0, 0, 0.05);
  --border: rgba(0, 0, 0, 0.18);
  --accent: #3b74d9;
  --accent-soft: #2e63c0;
  --label: #3a6cbf;
  --ok: #0f8a63;
  --warn: #9a6b00;
  --error: #c94f4f;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--body);
  font-family: var(--vscode-font-family, system-ui, sans-serif);
  font-size: 13px;
}
#app { display: flex; flex-direction: column; }

.row { display: flex; align-items: center; gap: 8px; }
.col { display: flex; flex-direction: column; gap: 10px; }
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.hero { background: linear-gradient(135deg, rgba(79, 143, 247, 0.12), rgba(79, 143, 247, 0.04)), var(--card); }
/* An allowance running out is not decoration: a plain grey tile reading
   "487 of 500" is exactly as loud as one reading "12 of 500", which is how a
   user reaches a ceiling without ever having been told they were near it. The
   border carries it rather than the number's colour, so the figure stays
   readable in both themes. */
.card.nearlimit { border-color: var(--warn); background: linear-gradient(0deg, rgba(251, 191, 36, 0.07), rgba(251, 191, 36, 0.07)), var(--card); }
.card.atlimit { border-color: var(--error); background: linear-gradient(0deg, rgba(242, 139, 139, 0.09), rgba(242, 139, 139, 0.09)), var(--card); }
.card.nearlimit .stat { color: var(--warn); }
.card.atlimit .stat { color: var(--error); }
.label {
  font: 600 10px var(--mono);
  letter-spacing: 0.1em;
  color: var(--label);
}
.title { font-weight: 700; color: var(--text); }
.dim { color: var(--dim); font-size: 12px; line-height: 1.5; }
.faint { color: var(--faint); font-size: 11px; }
.mono { font-family: var(--mono); font-size: 11px; }

.btn {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 8px;
  font: 600 12px var(--vscode-font-family, system-ui);
  padding: 9px 16px;
  cursor: pointer;
}
.btn.block { width: 100%; padding: 11px 0; font-size: 13px; }
.btn.quiet {
  background: transparent;
  border: 1px solid var(--chip-border);
  color: var(--accent-soft);
  font-size: 11px;
  padding: 4px 11px;
}
.btn.danger {
  background: transparent;
  border: 1px solid rgba(242, 139, 139, 0.35);
  color: var(--error);
}
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 99px;
}
.pill .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.pill.ok { background: rgba(52, 211, 153, 0.1); color: var(--ok); }
.pill.warn { background: rgba(251, 191, 36, 0.1); color: var(--warn); }
.pill.info { background: rgba(79, 156, 249, 0.1); color: var(--accent-soft); }

.toggle {
  width: 34px; height: 20px;
  border-radius: 99px;
  padding: 2px;
  background: var(--toggle-off);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  flex: none;
  transition: background 0.15s;
}
.toggle .knob {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
  transition: margin 0.15s;
}
.toggle.on { background: var(--accent); }
.toggle.on .knob { margin-left: auto; }

.progress { height: 5px; border-radius: 99px; background: var(--divider); overflow: hidden; }
.progress > span { display: block; height: 100%; background: var(--accent); transition: width 0.4s; }

.tabs { display: flex; gap: 4px; padding: 10px 14px; border-bottom: 1px solid var(--divider); }
.tab {
  flex: 1;
  text-align: center;
  font-weight: 600;
  font-size: 12px;
  padding: 7px 0;
  border-radius: 8px;
  color: var(--dim);
  border: 1px solid transparent;
  cursor: pointer;
}
.tab.active { background: rgba(79, 143, 247, 0.14); color: var(--accent-soft); border-color: var(--chip-border); }

.header { padding: 12px 14px; border-bottom: 1px solid var(--divider); }
/* Inline SVG mark: transparent background, ring inherits the theme foreground. */
/* 30px: the panel header is the extension's own brand line and had the mark
   smaller than the row of agent logos beneath it. Grown with the wordmark
   so the lockup keeps its proportions. */
.header .logo { width: 30px; height: 30px; flex: none; color: var(--text); }
.wordmark { font-weight: 600; font-size: 17px; color: var(--text); }
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); }
.status-dot.down { background: var(--warn); }
.avatar {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 11px; font-weight: 700;
  display: grid; place-items: center;
  margin-left: auto;
  cursor: pointer;
  border: 2px solid transparent;
}
.avatar:hover { border-color: var(--accent-soft); }

.backbar { padding: 10px 14px; border-bottom: 1px solid var(--divider); cursor: pointer; }
.backbar .crumb { margin-left: auto; font: 600 9.5px var(--mono); letter-spacing: 0.08em; color: var(--faint); }

.listrow { padding: 9px 0; border-bottom: 1px solid var(--divider); }
.listrow:last-child { border-bottom: none; }
.navrow { cursor: pointer; }
.navrow:hover { border-color: var(--chip-border); }

.spinner {
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  border-top-color: transparent;
  animation: spin 1s linear infinite;
  flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

.stepdot {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: rgba(79, 143, 247, 0.12);
  border: 1px solid var(--chip-border);
  color: var(--accent-soft);
  font-weight: 700; font-size: 10px;
  display: grid; place-items: center;
  flex: none;
}
.stepdot.done { background: rgba(52, 211, 153, 0.12); border-color: transparent; color: var(--ok); }

.section { padding: 12px 14px 14px; }
/* Column counts are a floor on the width, not a fixed number: the side bar can
   be dragged to ~170px, where two columns cannot hold a tile. auto-fit drops to
   the columns that actually fit, so every tile stays aligned and readable
   instead of overflowing the panel. */
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
/* Hero tiles carry an icon box and a 22px figure, so they need more room
   before they earn a second column. */
.hero .grid2 { grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
.stat { font: 700 20px var(--mono); color: var(--text); }
.stat.lg { font-size: 22px; }
.agent-icon { width: 14px; height: 14px; flex: none; border-radius: 4px; }
.agent-icon.placeholder { background: var(--toggle-off); }
.agent-icon img { width: 100%; height: 100%; object-fit: contain; border-radius: 4px; background: #fff; }

.iconbox {
  width: 32px; height: 32px;
  border-radius: 9px;
  background: rgba(79, 143, 247, 0.12);
  display: grid; place-items: center;
  flex: none;
}
.iconbox.ok { background: rgba(52, 211, 153, 0.12); }
.ctxchip {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(52, 211, 153, 0.08);
  border: 1px solid rgba(52, 211, 153, 0.3);
  border-radius: 99px; padding: 3px 10px;
  font-size: 11px; white-space: nowrap;
}
.ctxchip b { color: var(--body); font-weight: 600; }
.ctxchip span { font-size: 9.5px; color: var(--faint); }
.ctxchip.warn { background: rgba(251, 191, 36, 0.08); border-color: rgba(251, 191, 36, 0.3); color: var(--warn); font-weight: 600; }
.sechdr { display: flex; align-items: baseline; gap: 7px; margin-top: 2px; }
.sechdr > span:first-child { font: 600 10px var(--mono); letter-spacing: 0.08em; color: var(--dim); }
.sechdr .cnt { background: var(--divider); color: var(--dim); font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 99px; }
.sechdr .hint { margin-left: auto; color: var(--faint); font-size: 10.5px; }
.chip {
  border: 1px solid var(--chip-border);
  border-radius: 99px; padding: 3px 10px;
  font-size: 10.5px; color: var(--dim);
  white-space: nowrap;
}
.chip b { color: var(--body); }
.menu {
  position: absolute; right: 12px; top: 34px;
  background: var(--raised); border: 1px solid var(--chip-border);
  border-radius: 9px; padding: 4px;
  display: flex; flex-direction: column; z-index: 5;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.menu span { font-size: 12px; color: var(--body); padding: 7px 12px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 7px; }
.menu span:hover { background: rgba(79, 143, 247, 0.1); }
.menu span.disabled { opacity: .45; cursor: not-allowed; }
.menu span.disabled:hover { background: none; }
.menu .danger { color: var(--error); }
.badge {
  background: rgba(79, 156, 249, 0.15); color: var(--accent-soft);
  font-size: 9px; font-weight: 700; padding: 2px 7px;
  border-radius: 99px; letter-spacing: 0.05em; flex: none;
}
.filter {
  width: 100%; box-sizing: border-box;
  background: var(--vscode-input-background, var(--card));
  border: 1px solid var(--vscode-input-border, var(--border));
  border-radius: 9px; padding: 9px 12px;
  color: var(--vscode-input-foreground, var(--body));
  font-size: 12px; font-family: inherit;
}

/* -- additions for the live data the prototype stubbed ------------------- */
/* Red is reserved for sign out, delete and failed pushes (design rule). */
.pill.err { background: rgba(242, 139, 139, 0.12); color: var(--error); }
.pill.dim { background: rgba(128, 128, 128, 0.16); color: var(--dim); }
.errline { color: var(--error); font-size: 11px; line-height: 1.45; word-break: break-word; }
.warnline { color: var(--warn); font-size: 11px; line-height: 1.45; word-break: break-word; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
.stat.sm { font-size: 15px; }
.mono-block {
  font-family: var(--mono); font-size: 10.5px; color: var(--dim);
  white-space: pre-wrap; word-break: break-all; line-height: 1.5; margin: 0;
}
textarea.filter { resize: vertical; min-height: 74px; }
select.filter { appearance: none; }
.unreadn {
  background: var(--error); color: #fff;
  font-size: 9px; font-weight: 700; padding: 1px 6px;
  border-radius: 99px; flex: none;
}
/* A repo this window's agents cannot read is dimmed, but stays fully legible
   and clickable on hover: the toggle on it is the one control that ungates
   it, so it must not read as a disabled card. */
.card.gated { opacity: 0.62; transition: opacity 0.15s; }
.card.gated:hover, .card.gated:focus-within { opacity: 1; }
/* -- narrow side bar ------------------------------------------------------
   VS Code lets the side bar be dragged down to ~170px. At that width the old
   layout pushed its own content out of view: a flex child defaults to
   min-width:auto, so it refuses to shrink below its text and overflows the
   panel rather than truncating. These rules make every module degrade
   predictably down to the smallest width the editor allows; the wide layout
   is unchanged. */
body { overflow-x: hidden; overflow-wrap: break-word; }
#app, .section, .card, .col, .row { min-width: 0; }
.row > *, .col > * { min-width: 0; }
/* Atoms that must keep their size rather than be squashed by a long
   neighbour. Text beside them shrinks and truncates instead. */
.pill, .chip, .badge, .btn, .avatar, .unreadn, .toggle, .stepdot,
.spinner, .iconbox, .agent-icon, .status-dot { flex: none; }
/* A button never grows past its row: below its label width it wraps the label
   instead of hanging off the panel. */
.btn { max-width: 100%; }
.btn.block { width: 100%; }
/* The control at the end of a row, kept as one group so it moves to the
   second line intact when the row wraps. */
.endgroup { margin-left: auto; }
/* One-line names: take the room available, then ellipsis. display:block
   matters: `overflow` is ignored on a non-replaced inline box, so an inline
   <b> would set nowrap and then overflow visibly instead of truncating.
   Flex items are blockified already. */
.trunc { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wordmark { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tab { min-width: 0; overflow: hidden; }
.chip { max-width: 100%; }
/* Wraps rather than shrinks: side by side in a narrow chip the qualifier
   would be squeezed to zero width and vanish, so it takes its own line
   inside the chip instead. At full width nothing wraps and the chip is
   unchanged. */
.ctxchip { max-width: 100%; flex-wrap: wrap; row-gap: 1px; }
.ctxchip b, .ctxchip span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* The repo name is the point of the chip, so where the chip has to shrink the
   "this window" qualifier gives up its width first. */
.ctxchip b { flex-shrink: 1; }
.ctxchip span { flex-shrink: 12; }
/* Rows of unshrinkable controls (buttons, status dots) get a second line
   instead of overflowing. Text rows are deliberately NOT wrapped: shrinking
   them reflows the text in place, which reads better than dropping the
   value onto its own line. */
.row.wrapped { flex-wrap: wrap; row-gap: 8px; }
.sechdr { flex-wrap: wrap; row-gap: 3px; }
/* Declared here rather than inline: `flex:1` in a style attribute also sets
   flex-basis:0, and an inline shorthand cannot be overridden by a media
   query. With basis 0 a name always "fits" beside the pill and gets squeezed
   to a few pixels instead of pushing the pill onto the next line. */
.namecol { flex: 1; min-width: 0; }
.ctxchips { flex: 1; }
/* Card menus are absolutely positioned inside their card, so they need a
   clamp or they hang off the panel edge. */
.menu { max-width: calc(100% - 16px); }
.menu span { white-space: normal; line-height: 1.35; }

/* Narrow. Card headers pair a name with a status pill, and the pill cannot
   shrink: below this width it would leave the name a few pixels and the
   branch would break one character per line. Wrapping hands the name the
   full row and drops the pill underneath. The gutters also give back the
   width that fixed 14px padding was spending. Wider than this, nothing here
   applies and the layout is exactly as it was. */
@media (max-width: 340px) {
  .row.wrapnarrow { flex-wrap: wrap; row-gap: 6px; }
  /* A readable floor for the name. Flex breaks lines on each item's
     hypothetical size, so the floor is what pushes the pill or hint onto the
     second line instead of letting it squeeze the name to nothing. min()
     keeps the floor from overflowing a container narrower than it. */
  .row.wrapnarrow .namecol { min-width: min(84px, 100%); }
  .ctxrow { flex-wrap: wrap; row-gap: 8px; }
  .ctxrow .ctxchips { flex-basis: 100%; }
  .section { padding: 12px 10px 14px; }
  .card { padding: 11px 11px; }
  .header, .backbar { padding: 12px 10px; }
  .tabs { padding: 10px 10px; }
  .sechdr .hint { margin-left: 0; flex-basis: 100%; }
}
/* Minimum: the width the side bar snaps to. Tabs no longer fit three labels
   at 12px, and the crumb duplicates the tab the back link already names. */
@media (max-width: 240px) {
  .section { padding: 10px 8px 12px; }
  .card { padding: 10px 9px; }
  .header, .backbar { padding: 10px 8px; }
  /* Three labels have to sit on one line each: "Connect" is the widest, and
     at 12px it wrapped to two lines in a 170px panel. */
  .tabs { padding: 8px 6px; gap: 3px; }
  .tab { font-size: 10.5px; padding: 6px 2px; white-space: nowrap; }
  .btn { padding: 9px 12px; }
  .btn.block { padding: 11px 0; }
  .backbar .crumb { display: none; }
  .stat { font-size: 18px; }
  .stat.lg { font-size: 19px; }
  .menu { right: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
