*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg: #0d0d0f;
  --surface: #16161a;
  --surface2: #1e1e24;
  --border: #2a2a32;
  --text: #e0e0e8;
  --text-muted: #6b6b7e;
  --text-dim: #9a9aaa;
  --accent: #5c7cfa;
  --mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;

  --green: #2ecc71;
  --red: #e74c3c;
  --yellow: #f1c40f;
  --blue: #3498db;
  --gray: #4a4a5a;
  --purple: #9b59b6;

  --green-glow: 0 0 8px rgba(46, 204, 113, 0.4);
  --red-glow: 0 0 8px rgba(231, 76, 60, 0.35);
  --yellow-glow: 0 0 8px rgba(241, 196, 15, 0.35);
  --blue-glow: 0 0 8px rgba(52, 152, 219, 0.4);
}

html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  display: flex;
  flex-direction: column;
  font-size: 14px;
  line-height: 1.5;
}

/* ── Header ─────────────────────────────────────── */
header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  height: 48px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

header h1 {
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.03em;
}

.header-spacer { flex: 1; }

.user-info {
  font-size: 12px;
  color: var(--text-muted);
  font-family: var(--mono);
}

.back-link {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s;
}
.back-link:hover { color: var(--text); }

.header-sep {
  font-size: 12px;
  color: var(--border);
  user-select: none;
}

.logout-btn {
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: none;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 3px;
  transition: color 0.15s, border-color 0.15s;
}
.logout-btn:hover { color: var(--text); border-color: var(--text-dim); }

.lang-toggle {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.lang-toggle:hover { color: var(--text); border-color: var(--text-dim); }

/* ── Layout ─────────────────────────────────────── */
.app {
  display: flex;
  flex: 1;
  overflow: hidden;
}

/* ── Sidebar ─────────────────────────────────────── */
.sidebar {
  width: 220px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.sidebar-label {
  padding: 12px 16px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-family: var(--mono);
}

.project-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  cursor: pointer;
  border-left: 2px solid transparent;
  transition: background 0.1s;
  user-select: none;
}
.project-item:hover { background: var(--surface2); }
.project-item.active {
  background: var(--surface2);
  border-left-color: var(--accent);
}

.project-avatar {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  background: var(--surface2);
  flex-shrink: 0;
  object-fit: cover;
}

.project-name {
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* ── Main ─────────────────────────────────────── */
main {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-muted);
  font-family: var(--mono);
  font-size: 13px;
}

.load-error {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 0;
  color: var(--red);
  font-family: var(--mono);
  font-size: 13px;
  opacity: 0.7;
}

/* ── Loading dots ───────────────────────────────────── */
.pipeline-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 60px 0;
}
.pipeline-loading span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
  animation: dot-bounce 1.2s ease-in-out infinite;
}
.pipeline-loading span:nth-child(1) { animation-delay: 0s; }
.pipeline-loading span:nth-child(2) { animation-delay: 0.2s; }
.pipeline-loading span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot-bounce {
  0%, 60%, 100% { transform: translateY(0);    opacity: 0.3; }
  30%            { transform: translateY(-8px); opacity: 1;   }
}

/* ── Pipeline cards ─────────────────────────────────────── */
.pipeline-list {
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 1200px;
}

.pipeline-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 14px 16px;
  transition: border-color 0.2s;
}
.pipeline-card:hover { border-color: #3a3a46; }

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

/* Status badge */
.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-shrink: 0;
}

.status-badge.success  { background: rgba(46,204,113,.15); color: var(--green); box-shadow: var(--green-glow); }
.status-badge.failed   { background: rgba(231,76,60,.15);  color: var(--red);   box-shadow: var(--red-glow); }
.status-badge.running  { background: rgba(52,152,219,.15); color: var(--blue);  box-shadow: var(--blue-glow); }
.status-badge.pending  { background: rgba(241,196,15,.12); color: var(--yellow);}
.status-badge.canceled { background: rgba(74,74,90,.3);    color: var(--gray); }
.status-badge.skipped  { background: rgba(74,74,90,.3);    color: var(--gray); }
.status-badge.created  { background: rgba(74,74,90,.3);    color: var(--gray); }

/* Running pulse dot */
.pulse-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%       { opacity: 0.5; transform: scale(0.75); }
}

.card-ref {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  color: var(--text-muted);
}

.card-id {
  font-family: var(--mono);
  color: var(--text-muted);
}

.card-link {
  color: var(--accent);
  text-decoration: none;
  font-size: 12px;
  opacity: 0.8;
}
.card-link:hover { opacity: 1; }

.card-duration {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-dim);
}

/* Triggered by */
.triggered-by {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 8px;
}

.trigger-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--surface2);
  flex-shrink: 0;
  object-fit: cover;
}

.trigger-name {
  font-size: 12px;
  color: var(--text-muted);
}

/* MR info */
.mr-info {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 3px;
}

.mr-title {
  font-size: 13px;
  color: var(--text);
  margin-bottom: 5px;
}

.mr-branches {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.mr-branches .branch { color: var(--accent); }
.mr-branches .arrow  { color: var(--text-muted); }

.commits-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.commit-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
}

.commit-sha {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.commit-msg {
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Filter bar ─────────────────────────────────────── */
.filter-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 0 14px;
  width: 100%;
}

.filter-btn {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.filter-btn:hover { color: var(--text); border-color: var(--text-dim); }
.filter-btn.active {
  background: var(--surface2);
  color: var(--text);
  border-color: var(--accent);
}

.subscribe-btn {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  padding: 3px 12px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.subscribe-btn:hover {
  color: var(--text);
  border-color: var(--text-dim);
}
.subscribe-btn.subscribed {
  color: var(--green);
  border-color: rgba(46,204,113,.4);
  background: rgba(46,204,113,.08);
}

/* ── Stages row ─────────────────────────────────────── */
.stages-row {
  margin-top: 10px;
  overflow: visible;
}

/* Scroll container is separate from the row so overflow-x:auto does not force
   overflow-y:auto, which would clip the absolutely-positioned stage tooltip and
   swallow its pointer events — making the play button unclickable. */
.stages-row-scroll {
  display: flex;
  align-items: center;
  gap: 0;
  overflow-x: auto;
}

.stage-item {
  display: flex;
  align-items: center;
  gap: 0;
}

.stage-pill {
  font-family: var(--mono);
  font-size: 11px;
  padding: 2px 9px;
  border-radius: 2px;
  border: 1px solid transparent;
  white-space: nowrap;
  cursor: default;
  position: relative;
}
.stage-pill:hover .stage-tooltip { display: block; }

.stage-pill.success  { background: rgba(46,204,113,.12);  color: var(--green);  border-color: rgba(46,204,113,.25); }
.stage-pill.failed   { background: rgba(231,76,60,.12);   color: var(--red);    border-color: rgba(231,76,60,.25); }
.stage-pill.running  { background: rgba(52,152,219,.12);  color: var(--blue);   border-color: rgba(52,152,219,.25); }
.stage-pill.pending,
.stage-pill.created  { background: rgba(74,74,90,.2);     color: var(--gray);   border-color: rgba(74,74,90,.4); }
.stage-pill.canceled { background: rgba(74,74,90,.2);     color: var(--gray);   border-color: rgba(74,74,90,.4); }

/* Stage has at least one triggerable manual job */
.stage-pill.has-manual {
  cursor: pointer;
  border-style: dashed;
}
.stage-pill.has-manual::after                      { content: ' ▶'; font-size: 9px; opacity: 0.7; }
.stage-pill.has-manual[data-trigger-state=pending]::after { content: ' …'; opacity: 1; }
.stage-pill.has-manual[data-trigger-state=ok]::after      { content: ' ✓'; opacity: 1; }

.stage-arrow {
  color: var(--border);
  font-size: 12px;
  padding: 0 2px;
  flex-shrink: 0;
}

.stage-tooltip {
  display: none;
  position: absolute;
  /* No gap between pill and tooltip — the tooltip is a child of the pill,
     so the mouse stays within .stage-pill the whole time; no hover flicker.
     The 6px visual gap is achieved with padding-bottom instead. */
  bottom: 100%;
  padding-bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
}
.stage-tooltip-inner {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 6px 10px;
  min-width: 160px;
}

.stage-tooltip-job {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
  padding: 1px 0;
}

.stage-tooltip-job .dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.dot.success  { background: var(--green); }
.dot.failed   { background: var(--red); }
.dot.running  { background: var(--blue); }
.dot.pending,
.dot.created  { background: var(--gray); }
.dot.canceled { background: var(--gray); }

/* ── "What this introduces" block ───────────────────── */
.introduces {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 3px;
}

.introduces-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

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

.mr-link {
  font-size: 12px;
  color: var(--accent);
  text-decoration: none;
  font-weight: 500;
}
.mr-link:hover { text-decoration: underline; }

.mr-branches {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.mr-branches .branch { color: var(--accent); }

.trigger-commit {
  margin-bottom: 3px;
}

.commit-body {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--mono);
  white-space: pre-wrap;
  margin: 2px 0 6px 0;
  padding-left: 56px;
  line-height: 1.4;
}

.introduces-divider {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--mono);
  margin: 6px 0 4px;
}

/* ── Branch subscribe bell ──────────────────────────── */
.branch-bell {
  font-size: 11px;
  cursor: pointer;
  opacity: 0.3;
  margin-left: 4px;
  transition: opacity 0.15s;
  user-select: none;
}
.branch-bell:hover, .branch-bell.subscribed { opacity: 1; }

/* Connection indicator */
.conn-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gray);
  flex-shrink: 0;
}
.conn-dot.connected { background: var(--green); box-shadow: var(--green-glow); }
.conn-dot.error     { background: var(--red);   box-shadow: var(--red-glow); }

/* Scrollbar */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #3a3a46; }

/* ── Issue chips (inline in commit messages) ─────────── */
.issue-chip {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent);
  background: rgba(92,124,250,.1);
  border: 1px solid rgba(92,124,250,.2);
  border-radius: 3px;
  padding: 0 4px;
  white-space: nowrap;
}
.issue-chip.has-data {
  cursor: pointer;
}
.issue-chip.has-data:hover {
  background: rgba(92,124,250,.22);
  border-color: rgba(92,124,250,.45);
}

/* ── Issue refs list (below commits) ─────────────────── */
.issue-refs-list {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.issue-ref-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 3px;
  transition: background 0.1s;
}
.issue-ref-item:hover { background: rgba(92,124,250,.08); }

.issue-subject {
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.1s;
}
.issue-ref-item:hover .issue-subject { color: var(--text-dim); }

/* ── Issue panel ─────────────────────────────────────── */
.issue-panel {
  flex-shrink: 0;
  width: 0;
  min-width: 0;
  overflow: hidden;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  border-left: 1px solid transparent;
  /* width slides open; border appears after */
  transition: width 0.22s cubic-bezier(0.4,0,0.2,1),
              min-width 0.22s cubic-bezier(0.4,0,0.2,1),
              border-color 0s 0.22s;
}
.issue-panel.open {
  width: 360px;
  min-width: 360px;
  border-color: var(--border);
  transition: width 0.22s cubic-bezier(0.4,0,0.2,1),
              min-width 0.22s cubic-bezier(0.4,0,0.2,1);
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 8px;
}

.panel-header-id {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  min-width: 0;
}

.panel-tracker-badge {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 6px;
  white-space: nowrap;
}
.panel-tracker-badge:empty { display: none; }

.panel-close {
  font-size: 15px;
  line-height: 1;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 3px 7px;
  border-radius: 3px;
  flex-shrink: 0;
  transition: color 0.15s, background 0.15s;
}
.panel-close:hover { color: var(--text); background: var(--surface2); }

.panel-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}

.panel-empty, .panel-loading {
  color: var(--text-muted);
  font-family: var(--mono);
  font-size: 12px;
  text-align: center;
  padding: 32px 0;
}

.panel-subject {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.45;
  margin-bottom: 14px;
  word-break: break-word;
}

.panel-open-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--accent);
  text-decoration: none;
  margin-bottom: 14px;
  opacity: 0.85;
}
.panel-open-link:hover { opacity: 1; text-decoration: underline; }

.panel-meta-grid {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 5px 10px;
  margin-bottom: 16px;
  font-size: 12px;
}
.panel-meta-key {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted);
  align-self: start;
  padding-top: 1px;
}
.panel-meta-val { color: var(--text-dim); word-break: break-word; }

.panel-section-label {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 7px;
}

.panel-desc {
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-word;
  border-top: 1px solid var(--border);
  padding-top: 14px;
}

/* ── Panel backdrop (mobile only) ───────────────────── */
.panel-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 199;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
.panel-backdrop.visible {
  pointer-events: auto;
  opacity: 1;
}

/* ── Responsive ──────────────────────────────────────── */

/* Tablet: sidebar shrinks, panel narrower */
@media (max-width: 900px) {
  .sidebar { width: 180px; }
  .issue-panel.open { width: 300px; min-width: 300px; }
}

/* Mobile: sidebar becomes a horizontal project strip at the top */
@media (max-width: 640px) {
  html, body { height: 100%; }

  .app { flex-direction: column; }

  /* Sidebar → horizontal scrollable tab strip */
  .sidebar {
    width: 100%;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    border-right: none;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
    /* prevent iOS bounce from stealing scroll */
    -webkit-overflow-scrolling: touch;
  }

  .sidebar-label { display: none; }

  .project-item {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 8px 16px;
    border-left: none;
    border-bottom: 2px solid transparent;
    flex-shrink: 0;
  }
  .project-item.active {
    border-left-color: transparent;
    border-bottom-color: var(--accent);
  }

  .project-avatar { width: 26px; height: 26px; }
  .project-name   { font-size: 11px; }
  .project-notify { margin-left: 0; font-size: 11px; }

  /* Main area */
  main { padding: 12px; overflow-y: auto; }

  .pipeline-list { max-width: 100%; gap: 8px; }

  /* Card top: badge+ref on row 1, meta+link on row 2 */
  .card-top {
    flex-wrap: wrap;
    row-gap: 6px;
    margin-bottom: 6px;
  }

  /* refWrap already has flex:1 — it and badge fill row 1 */
  /* Push meta to its own row */
  .card-meta {
    order: 3;
    flex: 1;
    gap: 10px;
  }
  .card-link {
    order: 4;
    align-self: center;
  }

  /* Filter bar wraps */
  .filter-bar {
    flex-wrap: wrap;
    row-gap: 6px;
    padding-bottom: 10px;
  }

  /* Introduces: remove left padding on commit body */
  .commit-body { padding-left: 0; margin-top: 4px; }

  /* Header: hide user-info to save space */
  .user-info { display: none; }

  header { padding: 0 14px; gap: 10px; }

  /* Panel: bottom sheet on mobile */
  .issue-panel {
    position: fixed !important;
    inset: auto 0 0 0 !important;
    width: 100% !important;
    min-width: 0 !important;
    height: 68vh;
    border-left: none !important;
    border-top: 2px solid var(--border);
    border-radius: 14px 14px 0 0;
    /* override width transition with transform */
    transform: translateY(100%);
    transition: transform 0.26s cubic-bezier(0.4,0,0.2,1) !important;
    z-index: 200;
    overflow: hidden;
  }
  .issue-panel.open {
    transform: translateY(0) !important;
    width: 100% !important;
  }
  /* Show backdrop on mobile */
  .panel-backdrop { display: block; }
}

/* Very small screens */
@media (max-width: 400px) {
  header h1 { font-size: 13px; }
  main       { padding: 8px; }

  .pipeline-card { padding: 11px 12px; }

  .status-badge  { font-size: 10px; padding: 2px 6px; }
  .card-ref      { font-size: 12px; }
  .card-meta     { font-size: 11px; gap: 8px; }

  .stages-row    { gap: 0; }
  .stage-pill    { font-size: 10px; padding: 2px 7px; }
}
