kilo-loop/public/styles.css
Vitali sharp8n d7c22ca452 visual fixes
2026-09-14 01:20:42 +03:00

549 lines
18 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

:root {
--bg: #0d1117;
--bg-2: #161b22;
--bg-3: #1c2330;
--border: #2a3240;
--fg: #e6edf3;
--muted: #8b949e;
--accent: #58a6ff;
--green: #3fb950;
--yellow: #d29922;
--red: #f85149;
--purple: #bc8cff;
--mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
height: 100%;
background: var(--bg);
color: var(--fg);
font-family: var(--sans);
font-size: 14px;
}
body { display: flex; flex-direction: column; }
/* ---------- top bar ---------- */
.topbar {
display: flex;
align-items: center;
gap: 16px;
padding: 12px 18px;
background: var(--bg-2);
border-bottom: 1px solid var(--border);
position: sticky;
top: 0;
z-index: 10;
overflow: hidden;
}
/* ---------- top-bar activity indicator (pure CSS) ----------
::after = dim track sitting on the bottom border
::before = the moving / solid segment that signals the state
JS only toggles a `topbar--<state>` class.
All durations below are integer multiples of a 1.4s beat. Two infinite
animations with an arbitrary ratio (e.g. 4.6s vs 2.8s = 23:14) only re-align
every 64s, so they visibly drift; keeping every animation on the same beat
grid makes the pair repeat exactly and stay phase-locked. */
.topbar::before,
.topbar::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
height: 4px;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.topbar::after { right: 0; background: rgba(88, 166, 255, 0.16); }
.topbar::before { width: 46%; transform: translateX(-100%); }
/* running / starting — blue→green sweep + travelling sheen */
.topbar--running {
background-image: linear-gradient(100deg,
rgba(88, 166, 255, 0) 0%,
rgba(88, 166, 255, 0.13) 34%,
rgba(63, 185, 80, 0.18) 50%,
rgba(88, 166, 255, 0.13) 66%,
rgba(88, 166, 255, 0) 100%);
background-size: 240% 100%;
animation: topbar-sheen 5.6s linear infinite; /* 4 × beat = 2 × sweep → locked */
}
.topbar--running::after { opacity: 1; background: rgba(88, 166, 255, 0.22); }
.topbar--running::before {
opacity: 1;
background: linear-gradient(90deg, rgba(88, 166, 255, 0) 0%, var(--accent) 22%, #7ee787 56%, var(--green) 80%, rgba(63, 185, 80, 0) 100%);
box-shadow: 0 0 12px rgba(88, 166, 255, 0.8), 0 0 5px rgba(126, 231, 135, 0.95);
animation: topbar-sweep 2.8s cubic-bezier(0.45, 0, 0.35, 1) infinite; /* 2 × beat */
}
/* waiting for operator input — pulsing purple */
.topbar--waiting {
background-image: linear-gradient(90deg, rgba(188, 140, 255, 0.07), rgba(188, 140, 255, 0.12), rgba(188, 140, 255, 0.07));
background-size: 220% 100%;
animation: topbar-sheen 2.8s linear infinite; /* 2 × beat */
}
.topbar--waiting::before {
opacity: 1;
width: 100%;
transform: none;
background: linear-gradient(90deg, rgba(188, 140, 255, 0.15), var(--purple), rgba(188, 140, 255, 0.15));
animation: topbar-breathe 1.4s ease-in-out infinite; /* 1 × beat (2 per sheen) */
}
/* paused — static amber baseline (deliberately not animating) */
.topbar--paused::before {
opacity: 1;
width: 100%;
transform: none;
background: linear-gradient(90deg, rgba(210, 153, 34, 0.12), var(--yellow), rgba(210, 153, 34, 0.12));
}
/* finished cleanly — static green line */
.topbar--done::before {
opacity: 1;
width: 100%;
transform: none;
background: linear-gradient(90deg, rgba(63, 185, 80, 0.12), var(--green), rgba(63, 185, 80, 0.12));
}
/* stopped / stale-ish warnings — light amber tint */
.topbar--warn {
background-image: linear-gradient(180deg, rgba(210, 153, 34, 0.13), rgba(210, 153, 34, 0.04) 72%, transparent);
animation: topbar-warn-pulse 2.8s ease-in-out infinite; /* 2 × beat */
}
.topbar--warn::before {
opacity: 1;
width: 100%;
transform: none;
background: var(--yellow);
box-shadow: 0 0 10px rgba(210, 153, 34, 0.5);
}
/* error / done-with-errors / stale — light red tint + pulsing red line */
.topbar--error {
background-image: linear-gradient(180deg, rgba(248, 81, 73, 0.17), rgba(248, 81, 73, 0.05) 74%, transparent);
animation: topbar-error-pulse 2.8s ease-in-out infinite; /* 2 × beat */
}
.topbar--error::before {
opacity: 1;
width: 100%;
transform: none;
background: var(--red);
box-shadow: 0 0 12px rgba(248, 81, 73, 0.8);
animation: topbar-breathe 1.4s ease-in-out infinite; /* 1 × beat (2 per pulse) */
}
@keyframes topbar-sweep {
0% { transform: translateX(-100%); }
100% { transform: translateX(218%); }
}
@keyframes topbar-sheen {
0% { background-position: 125% 0; }
100% { background-position: -125% 0; }
}
@keyframes topbar-breathe {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}
@keyframes topbar-error-pulse {
0%, 100% { box-shadow: inset 0 0 0 rgba(248, 81, 73, 0); }
50% { box-shadow: inset 0 0 26px rgba(248, 81, 73, 0.22); }
}
@keyframes topbar-warn-pulse {
0%, 100% { box-shadow: inset 0 0 0 rgba(210, 153, 34, 0); }
50% { box-shadow: inset 0 0 22px rgba(210, 153, 34, 0.14); }
}
/* Respect reduced-motion: keep the state visible, drop the movement. */
@media (prefers-reduced-motion: reduce) {
.topbar,
.topbar::before,
.topbar::after { animation: none !important; }
.topbar--running { background-image: none; }
.topbar--running::before { opacity: 1; width: 100%; transform: none; background: var(--accent); }
.topbar--waiting::before { opacity: 1; }
}
.brand { display: flex; align-items: center; gap: 12px; }
.logo {
display: grid;
place-items: center;
width: 34px; height: 34px;
border-radius: 9px;
background: linear-gradient(135deg, #1f6feb, #8957e5);
font-size: 20px;
}
.title { font-weight: 650; letter-spacing: 0.2px; }
.sub { color: var(--muted); font-size: 12px; font-family: var(--mono); }
.spacer { flex: 1; }
.status {
padding: 5px 12px;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.4px;
border: 1px solid var(--border);
background: var(--bg-3);
}
.status.running { color: var(--accent); border-color: #1f6feb55; background: #1f6feb1a; }
.status.paused { color: var(--yellow); border-color: #d2992255; background: #d299221a; }
.status.waiting-answer { color: var(--purple); border-color: #bc8cff55; background: #bc8cff1a; }
.status.done { color: var(--green); border-color: #3fb95055; background: #3fb9501a; }
.status.done-with-errors, .status.error { color: var(--red); border-color: #f8514955; background: #f851491a; }
.status.aborted { color: var(--yellow); border-color: #d2992255; background: #d299221a; }
.status.stopped-budget, .status.stalled, .status.stopped-guard { color: var(--yellow); border-color: #d2992255; background: #d299221a; }
#toggle-shared.hidden { display: none; }
.controls { display: flex; gap: 8px; }
.toggle {
display: inline-flex;
align-items: center;
gap: 7px;
padding: 6px 11px;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg-3);
color: var(--muted);
font-size: 12px;
cursor: pointer;
user-select: none;
white-space: nowrap;
}
.toggle:hover { border-color: #3a4456; }
.toggle.on { color: var(--accent); border-color: #1f6feb55; background: #1f6feb1a; }
.toggle input { accent-color: var(--accent); margin: 0; }
.toggle input:disabled { cursor: not-allowed; }
.toggle:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
button {
font: inherit;
font-size: 13px;
color: var(--fg);
background: var(--bg-3);
border: 1px solid var(--border);
border-radius: 7px;
padding: 7px 12px;
cursor: pointer;
transition: background 0.12s, border-color 0.12s;
}
button:hover { background: #232c3a; border-color: #3a4456; }
button.danger { color: #ffb4ae; border-color: #f8514955; }
button.danger:hover { background: #f851491a; }
button.primary { background: #1f6feb; border-color: #1f6feb; color: #fff; }
button.primary:hover { background: #2f7cf6; }
button:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-link {
display: inline-flex;
align-items: center;
font-size: 13px;
color: var(--fg);
background: var(--bg-3);
border: 1px solid var(--border);
border-radius: 7px;
padding: 7px 12px;
text-decoration: none;
}
.btn-link:hover { background: #232c3a; border-color: #3a4456; }
#btn-new-run.hidden { display: none; }
/* ---------- stats ---------- */
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 10px;
padding: 14px 18px;
border-bottom: 1px solid var(--border);
background: var(--bg-2);
}
.stat {
background: var(--bg-3);
border: 1px solid var(--border);
border-radius: 10px;
padding: 10px 12px;
min-width: 0;
}
.stat .k { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat .v { font-size: 18px; font-weight: 650; margin-top: 3px; font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat .v small { font-size: 12px; color: var(--muted); font-weight: 400; }
.bar { height: 6px; border-radius: 4px; background: #263041; margin-top: 8px; overflow: hidden; }
.bar > i { display: block; height: 100%; background: linear-gradient(90deg, #1f6feb, #8957e5); }
/* ---------- main ---------- */
main {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: minmax(360px, 44%) 1fr;
gap: 14px;
padding: 14px 18px 18px;
}
.panel {
min-height: 0;
display: flex;
flex-direction: column;
background: var(--bg-2);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
}
.panel h2 {
margin: 0;
padding: 12px 14px;
font-size: 13px;
font-weight: 600;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 10px;
background: var(--bg-2);
}
.hint { color: var(--muted); font-weight: 400; font-size: 11px; }
.hint b { color: var(--accent); }
/* ---------- stages strip ---------- */
.stages-panel {
padding: 12px 18px 0;
}
.stages-panel h2 {
margin: 0 0 8px;
font-size: 13px;
font-weight: 600;
display: flex;
align-items: center;
gap: 10px;
}
.stages {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.stage-chip {
display: inline-flex;
align-items: center;
gap: 7px;
padding: 6px 11px;
border: 1px solid var(--border);
border-radius: 999px;
background: var(--bg-3);
font-size: 12px;
color: var(--muted);
max-width: 420px;
}
.stage-chip .n {
font-family: var(--mono);
font-size: 11px;
color: #6e7681;
}
.stage-chip .t {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.stage-chip.done { color: var(--green); border-color: #3fb95055; background: #3fb9501a; }
.stage-chip.current { color: var(--accent); border-color: #1f6feb77; background: #1f6feb1a; }
.stage-verify {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.4px;
padding: 1px 6px;
border-radius: 999px;
border: 1px solid var(--border);
color: var(--purple);
}
/* ---------- iterations ---------- */
.iterations { overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.iter {
border: 1px solid var(--border);
border-radius: 10px;
background: var(--bg-3);
padding: 11px 12px;
}
.iter.running { border-color: #1f6feb88; box-shadow: 0 0 0 1px #1f6feb33 inset; }
.iter.failed { border-color: #f8514977; }
.iter .head { display: flex; align-items: baseline; gap: 8px; }
.iter .num { font-family: var(--mono); color: var(--muted); font-size: 12px; }
.iter .topic { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); }
.badge.completed { color: var(--green); border-color: #3fb95055; }
.badge.failed { color: var(--red); border-color: #f8514955; }
.badge.interrupted { color: var(--yellow); border-color: #d2992255; }
.badge.retrying { color: var(--yellow); border-color: #d2992255; }
.badge.running { color: var(--accent); border-color: #1f6feb55; }
.badge.mode { color: #a5b3c4; border-color: #3a4456; }
.vb { font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); }
.vb.ok { color: var(--green); border-color: #3fb95055; }
.vb.bad { color: var(--red); border-color: #f8514955; }
.vb.warn { color: var(--yellow); border-color: #d2992255; }
.iter .actions { margin-top: 8px; display: flex; gap: 8px; }
.iter .actions .revert { font-size: 12px; padding: 4px 10px; color: var(--yellow); border-color: #d2992255; }
.iter .actions .revert:hover { background: #d299221a; }
.iter .meta .sess { color: #6e7681; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.iter .meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 7px; color: var(--muted); font-size: 12px; font-family: var(--mono); }
.iter .stage { margin-top: 6px; font-size: 12px; }
.iter .stage .lbl { color: var(--muted); }
.iter .summary { margin-top: 7px; color: #c9d1d9; font-size: 12.5px; line-height: 1.45; }
.iter .files { margin-top: 7px; display: flex; flex-wrap: wrap; gap: 5px; }
.chip { font-family: var(--mono); font-size: 11px; background: #202a38; border: 1px solid var(--border); border-radius: 6px; padding: 2px 7px; color: #a5b3c4; }
.iter .bar { margin-top: 8px; }
.qlist { margin: 7px 0 0; padding-left: 16px; color: var(--purple); font-size: 12px; }
.empty { color: var(--muted); padding: 16px; text-align: center; }
/* ---------- log ---------- */
.log {
flex: 1;
overflow-y: auto;
padding: 12px 14px;
font-family: var(--mono);
font-size: 12.5px;
line-height: 1.55;
white-space: pre-wrap;
word-break: break-word;
}
.log .line { padding: 1px 0; }
.log .t { color: #4d5866; margin-right: 8px; }
.log .section {
color: var(--purple);
font-weight: 650;
border-top: 1px solid #232c3a;
margin-top: 8px;
padding-top: 6px;
}
.log .tool { color: var(--accent); }
.log .metric { color: var(--muted); }
.log .agent { color: #d5dee7; }
.log .reasoning { color: #6e7681; font-style: italic; }
.log .warn { color: var(--yellow); }
.log .error { color: var(--red); }
.log .answer { color: var(--green); }
.log .system { color: #6cb6ff; }
.log .stderr { color: #b98a00; }
/* ---------- modal ---------- */
.modal {
position: fixed;
inset: 0;
background: #000000aa;
display: grid;
place-items: center;
z-index: 50;
backdrop-filter: blur(2px);
}
.modal.hidden { display: none; }
.modal-card {
width: min(680px, 92vw);
max-height: 86vh;
overflow-y: auto;
background: var(--bg-2);
border: 1px solid var(--border);
border-radius: 14px;
padding: 20px 22px;
}
.modal-card h3 { margin: 0 0 4px; }
.muted { color: var(--muted); margin: 0 0 14px; font-size: 12.5px; }
.q { margin-bottom: 14px; }
.q label { display: block; margin-bottom: 6px; font-weight: 550; }
.q .opts { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.q input[type="text"] {
width: 100%;
font: inherit;
font-family: var(--mono);
font-size: 13px;
color: var(--fg);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 9px 11px;
}
.q input[type="text"]:focus { outline: none; border-color: var(--accent); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
/* ---------- launcher ---------- */
.launcher { padding: 18px; overflow-y: auto; }
.launcher.hidden { display: none; }
.launcher-card {
max-width: 940px;
margin: 0 auto;
background: var(--bg-2);
border: 1px solid var(--border);
border-radius: 12px;
padding: 18px 20px 20px;
}
.launcher-card h2 { margin: 0 0 4px; font-size: 15px; }
.launcher-card > .muted { margin: 0 0 16px; }
#run-view { display: flex; flex-direction: column; flex: 1; min-height: 0; }
#run-view.hidden { display: none; }
.field { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--muted); }
.field > span { text-transform: uppercase; letter-spacing: 0.4px; font-size: 11px; }
.field input,
.field select,
.field textarea {
font: inherit;
font-size: 13px;
color: var(--fg);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 8px 10px;
}
.field input:focus,
.field select:focus,
.field textarea:focus { outline: none; border-color: var(--accent); }
.field textarea {
font-family: var(--mono);
font-size: 12.5px;
resize: vertical;
min-height: 56px;
}
.prompt-extra { margin-bottom: 16px; }
.field.grow { flex: 1; }
.field.checkbox { flex-direction: row; align-items: center; gap: 7px; }
.field.checkbox span { text-transform: none; font-size: 13px; color: var(--fg); }
.field.checkbox input { width: auto; accent-color: var(--accent); }
.goal-meta { margin: 10px 0 14px; font-size: 12.5px; font-family: var(--mono); }
.goal-actions { display: flex; gap: 8px; align-items: center; margin-bottom: 16px; }
.goal-actions .spacer { flex: 1; }
.verify-global { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 16px; }
.goal-stages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; max-height: 40vh; overflow-y: auto; }
.goal-stage {
display: flex;
gap: 10px;
align-items: center;
border: 1px solid var(--border);
border-radius: 9px;
padding: 8px 10px;
background: var(--bg-3);
}
.goal-stage.done { border-color: #3fb95055; }
.goal-stage .st-title { flex: 1; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.goal-stage .st-state { font-size: 11px; padding: 2px 7px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); flex: none; }
.goal-stage.done .st-state { color: var(--green); border-color: #3fb95055; }
.goal-stage input {
flex: 1.2;
font: inherit;
font-family: var(--mono);
font-size: 12px;
color: var(--fg);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 7px;
padding: 6px 9px;
}
.goal-stage input:focus { outline: none; border-color: var(--accent); }
.run-options { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 16px; }
.run-options .field { min-width: 120px; }
.launcher-actions { display: flex; justify-content: flex-end; gap: 8px; }
.launcher-error { color: var(--red); font-size: 12.5px; margin-top: 10px; min-height: 16px; }
@media (max-width: 980px) {
.stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
main { grid-template-columns: 1fr; }
}