Files
codecraft/web/src/styles.css
T
Richard ZinkandClaude Opus 5.5 bd896794fd Answer budget within the context window; enforced reviews of completed todos
Context window
- Requests asked for the model's full max_output, but providers count
  input + output against the window: long chats with large-output models
  (DeepSeek V4.1 Flash, 384k) failed with "input too long" before automatic
  compaction (85 %) kicked in. max_tokens is now what the window leaves
  (estimated input = last usage + messages since), the chat is compacted when
  less than 32k would remain for an answer, and a context-overflow error
  compacts and retries once.
- ModelConfig.max_input (catalogue limit.input, editable in the provider
  settings) lowers the compaction threshold for models with an input limit.

Enforced reviews (modes with refine.rounds > 0, refine.after_todos default on)
- Every todo marked completed is reviewed against the work since the last
  review; with findings it is reopened and the feedback goes to the agent
  (max. rounds per todo). Passed reviews leave a visible note.
- Ending the turn with open todos sends the agent back to work while it makes
  progress (max. 10 reminders in a row without progress); such modes may take
  up to 2,000 steps per turn. Reaching the step limit is reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 23:12:49 +01:00

4188 lines
73 KiB
CSS
Raw 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.
/* CodeCraft – layout and components. Colours come exclusively from the theme
variables defined in src/themes/*.css. */
* {
box-sizing: border-box;
}
html,
body,
#root {
height: 100%;
margin: 0;
}
body {
background: var(--bg0);
color: var(--fg1);
font: 14px/1.5 var(--font);
-webkit-font-smoothing: antialiased;
}
a {
color: var(--blue);
}
code,
pre,
.mono {
font-family: var(--mono);
font-size: 12.5px;
}
button,
input,
select,
textarea {
font: inherit;
color: inherit;
}
button {
cursor: pointer;
border: 1px solid var(--bg3);
background: var(--bg2);
border-radius: 6px;
padding: 5px 12px;
}
button:hover:not(:disabled) {
border-color: var(--fg3);
}
button:disabled {
opacity: 0.5;
cursor: default;
}
button.primary {
background: var(--accent);
border-color: var(--accent);
color: var(--on-accent);
font-weight: 600;
}
button.danger {
color: var(--red);
}
button.ghost {
background: transparent;
border-color: transparent;
}
button.ghost:hover:not(:disabled) {
background: var(--bg2);
}
button.small {
padding: 2px 8px;
font-size: 12px;
}
input,
select,
textarea {
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: 6px;
padding: 5px 8px;
outline: none;
}
input:focus,
select:focus,
textarea:focus {
border-color: var(--accent);
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 1px;
}
/* --- layout ---------------------------------------------------------------- */
.app {
display: flex;
height: 100%;
}
.sidebar {
width: 280px;
flex-shrink: 0;
background: var(--bg1);
border-right: 1px solid var(--bg2);
display: flex;
flex-direction: column;
min-height: 0;
}
.sidebar-head {
display: flex;
align-items: center;
gap: 8px;
padding: 12px;
padding-top: max(12px, env(safe-area-inset-top));
}
.sidebar-head .logo {
font-weight: 700;
font-size: 16px;
color: var(--fg0);
flex: 1;
display: flex;
align-items: center;
gap: 8px;
}
.sidebar-head .logo img {
width: 22px;
height: 22px;
}
/* --- status LEDs (sidebar) ------------------------------------------------------ */
/* Theme hues, pushed to a vivid chroma and a readable lightness so the state is
obvious in every theme; warn takes the red's lightness/chroma at an amber hue. */
:root {
--led-ok: #22c55e;
--led-warn: #f5a700;
--led-err: #ef4444;
}
@supports (color: oklch(from red l c h)) {
:root {
--led-ok: oklch(from var(--green) clamp(0.7, l, 0.8) max(c, 0.2) clamp(138, h, 158));
--led-warn: oklch(from var(--red) clamp(0.78, l, 0.85) max(c, 0.17) 75);
--led-err: oklch(from var(--red) clamp(0.6, l, 0.7) max(c, 0.21) h);
}
}
.status-leds {
position: relative;
}
.status-leds-btn {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 7px;
border-radius: 999px;
background: var(--bg2);
}
.led {
width: 9px;
height: 9px;
border-radius: 50%;
flex: none;
display: inline-block;
}
.led-ok {
background: var(--led-ok);
box-shadow: 0 0 6px color-mix(in srgb, var(--led-ok) 70%, transparent);
}
.led-warn {
background: var(--led-warn);
box-shadow: 0 0 6px color-mix(in srgb, var(--led-warn) 70%, transparent);
}
.led-err {
background: var(--led-err);
box-shadow: 0 0 7px color-mix(in srgb, var(--led-err) 80%, transparent);
}
.status-leds-btn .led-err {
animation: led-blink 1.6s ease-in-out infinite;
}
.led-off {
background: transparent;
box-shadow: inset 0 0 0 1.5px var(--muted);
}
@keyframes led-blink {
50% {
opacity: 0.45;
}
}
@media (prefers-reduced-motion: reduce) {
.status-leds-btn .led-err {
animation: none;
}
}
.status-pop {
position: fixed;
z-index: 40;
width: min(320px, calc(100vw - 24px));
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 6px;
font-size: 13px;
}
.status-section + .status-section {
border-top: 1px solid var(--bg3);
margin-top: 4px;
padding-top: 4px;
}
.status-head {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px 4px;
font-weight: 600;
color: var(--fg0);
}
.status-row {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px 4px 25px;
color: var(--fg1);
}
.status-row .led {
width: 7px;
height: 7px;
margin-left: -15px;
}
.status-row .grow {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.status-row .hint {
white-space: nowrap;
}
.status-foot {
display: flex;
gap: 6px;
border-top: 1px solid var(--bg3);
margin-top: 4px;
padding: 6px 4px 2px;
}
.session-list {
flex: 1;
overflow-y: auto;
padding: 4px 8px;
}
.session-group {
display: flex;
align-items: center;
gap: 5px;
width: 100%;
border: none;
background: transparent;
text-align: left;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
padding: 10px 8px 4px;
}
button.session-group:hover {
color: var(--fg2);
}
.session-group .grow {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.session-group .count {
text-transform: none;
letter-spacing: 0;
}
.session-view {
display: flex;
justify-content: flex-end;
padding: 0 0 2px;
}
.session-view button {
display: inline-flex;
align-items: center;
font-size: 11.5px;
color: var(--muted);
gap: 5px;
}
.session-row {
position: relative;
}
.session-row .session-item {
padding-right: 30px;
}
/* Group headers (folders, projects): menu button, drag and drop. */
.group-row .session-group {
padding-right: 30px;
}
.group-row .session-more {
top: 4px;
}
.group-row[draggable="true"] .session-group {
cursor: grab;
}
.group-row.drop-before {
box-shadow: inset 0 2px 0 var(--accent);
}
.group-row.drop-after {
box-shadow: inset 0 -2px 0 var(--accent);
}
.session-group .group-pin {
color: var(--accent);
}
.session-more {
position: absolute;
top: 6px;
right: 4px;
padding: 2px 4px;
opacity: 0;
color: var(--muted);
}
.session-row:hover .session-more,
.session-row.menu-open .session-more,
.session-more:focus-visible {
opacity: 1;
}
@media (pointer: coarse) {
.session-more {
opacity: 1;
}
}
.session-menu {
position: absolute;
right: 4px;
top: 30px;
z-index: 20;
min-width: 200px;
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: 8px;
box-shadow: var(--shadow);
padding: 4px;
display: flex;
flex-direction: column;
}
.session-menu button {
display: flex;
align-items: center;
gap: 8px;
border: none;
background: transparent;
text-align: left;
padding: 7px 8px;
border-radius: 5px;
font-size: 13px;
}
.session-menu button:hover {
background: var(--bg2);
}
.session-item {
display: block;
width: 100%;
text-align: left;
border: none;
background: transparent;
padding: 7px 8px;
border-radius: 6px;
margin-bottom: 1px;
}
.session-item:hover {
background: var(--bg2);
}
.session-item.active {
background: var(--bg3);
}
.session-item .title {
display: flex;
align-items: center;
gap: 6px;
color: var(--fg0);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.session-item .title span {
overflow: hidden;
text-overflow: ellipsis;
}
.session-item .sub {
font-size: 11.5px;
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.busy-dot {
flex-shrink: 0;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--accent);
animation: pulse 1.2s infinite;
}
.attn-dot {
flex-shrink: 0;
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--accent2);
}
@keyframes pulse {
50% {
opacity: 0.3;
}
}
.sidebar-foot {
border-top: 1px solid var(--bg2);
padding: 8px;
padding-bottom: max(8px, env(safe-area-inset-bottom));
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4px;
}
.sidebar-foot button {
flex: 1;
}
.sidebar-foot button.active {
background: var(--bg3);
}
.main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
min-height: 0;
}
.topbar {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
padding-top: max(8px, env(safe-area-inset-top));
border-bottom: 1px solid var(--bg2);
min-height: 48px;
flex-wrap: wrap;
}
.topbar .grow {
flex: 1;
min-width: 0;
}
.topbar h1 {
font-size: 15px;
margin: 0;
color: var(--fg0);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.topbar .path {
font-size: 11.5px;
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.menu-btn {
display: none;
}
.chip {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
padding: 2px 8px;
border-radius: 999px;
background: var(--bg2);
color: var(--fg2);
white-space: nowrap;
}
.chip.warn {
color: var(--accent2);
}
.page {
flex: 1;
overflow-y: auto;
padding: 20px;
}
.page-inner {
max-width: 1100px;
margin: 0 auto;
}
/* --- chat ------------------------------------------------------------------ */
.chat-scroll {
flex: 1;
overflow-y: auto;
overscroll-behavior: contain;
}
.chat {
max-width: 900px;
margin: 0 auto;
padding: 16px 16px 24px;
}
.msg {
margin-bottom: 14px;
}
.msg-user {
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: var(--radius);
padding: 8px 12px;
white-space: pre-wrap;
word-break: break-word;
position: relative;
}
/* User messages are Markdown too; the line breaks come from keepLineBreaks. */
.msg-user .markdown {
white-space: normal;
}
.composer-preview {
min-height: 44px;
max-height: 40vh;
overflow-y: auto;
padding: 10px 12px;
border-radius: var(--radius);
border: 1px dashed var(--bg3);
background: var(--bg1);
cursor: text;
}
.msg-user .msg-actions {
position: absolute;
top: 4px;
right: 4px;
display: none;
}
.msg-user:hover .msg-actions {
display: block;
}
.msg-user img {
max-height: 160px;
border-radius: 6px;
margin: 6px 6px 0 0;
}
.msg-meta {
font-size: 11px;
color: var(--muted);
margin-top: 2px;
}
.markdown {
word-break: break-word;
}
.markdown > :first-child {
margin-top: 0;
}
.markdown > :last-child {
margin-bottom: 0;
}
.markdown pre {
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: 6px;
padding: 10px;
overflow-x: auto;
}
.markdown code {
background: var(--bg1);
padding: 1px 4px;
border-radius: 4px;
}
.markdown pre code {
background: none;
padding: 0;
}
.markdown table {
border-collapse: collapse;
}
.markdown th,
.markdown td {
border: 1px solid var(--bg3);
padding: 4px 8px;
}
.markdown blockquote {
border-left: 3px solid var(--bg3);
margin-left: 0;
padding-left: 12px;
color: var(--fg2);
}
.reasoning {
color: var(--muted);
font-size: 13px;
border-left: 2px solid var(--bg3);
padding-left: 10px;
margin: 6px 0;
}
.reasoning-head {
display: inline-flex;
align-items: center;
gap: 8px;
border: none;
background: transparent;
padding: 2px 0;
color: var(--muted);
font-size: 12.5px;
}
.reasoning-head:hover {
color: var(--fg2);
}
.reasoning .body {
white-space: pre-wrap;
margin-top: 4px;
font-style: italic;
line-height: 1.5;
}
.reasoning.live .body {
max-height: 260px;
overflow-y: auto;
}
.reasoning.live {
border-left-color: var(--accent);
}
.streaming-text::after {
content: "";
display: inline-block;
width: 0.5em;
height: 1em;
margin-left: 2px;
vertical-align: text-bottom;
background: var(--muted);
animation: blink 1s steps(1) infinite;
}
.tool {
border: 1px solid var(--bg2);
border-radius: var(--radius);
margin: 6px 0;
background: var(--bg1);
overflow: hidden;
}
.tool > summary {
list-style: none;
cursor: pointer;
padding: 6px 10px;
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
}
.tool > summary::-webkit-details-marker {
display: none;
}
.tool .tool-name {
font-family: var(--mono);
font-size: 12px;
color: var(--accent);
}
.tool .tool-title {
color: var(--fg2);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.tool .status {
font-size: 12px;
}
.tool .status.ok {
color: var(--green);
}
.tool .status.err {
color: var(--red);
}
.tool .status.run {
color: var(--accent);
}
.tool-body {
border-top: 1px solid var(--bg2);
padding: 8px 10px;
}
.tool-body pre {
margin: 0;
white-space: pre-wrap;
word-break: break-word;
max-height: 420px;
overflow: auto;
}
.tool-body img {
max-width: 100%;
border-radius: 6px;
margin-top: 6px;
}
.tool-body .label {
font-size: 11px;
color: var(--muted);
text-transform: uppercase;
margin: 6px 0 2px;
}
.diff {
font-family: var(--mono);
font-size: 12px;
overflow-x: auto;
max-height: 480px;
overflow-y: auto;
border-radius: 6px;
background: var(--bg0);
}
.diff div {
white-space: pre;
padding: 0 8px;
}
.diff .add {
background: var(--diff-add);
}
.diff .del {
background: var(--diff-del);
}
.diff .hunk {
color: var(--blue);
}
.diff .meta {
color: var(--muted);
}
.summary-divider {
border: 1px dashed var(--bg3);
border-radius: var(--radius);
padding: 8px 12px;
color: var(--muted);
font-size: 13px;
margin: 14px 0;
}
.todos {
border: 1px solid var(--bg2);
border-radius: var(--radius);
padding: 8px 12px;
margin: 8px 0;
font-size: 13px;
}
.todos-head {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
min-width: 0;
padding: 0;
background: none;
border: none;
color: var(--muted);
font: inherit;
font-size: 12px;
text-align: left;
cursor: pointer;
}
.todos-head:hover {
color: var(--fg1);
}
.todos-count {
font-variant-numeric: tabular-nums;
}
.todos-current {
flex: 1;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--accent);
font-weight: 600;
}
.todos.collapsed {
padding-block: 6px;
}
.todos ul {
list-style: none;
padding: 0;
margin: 4px 0 0;
}
.todos li {
display: flex;
gap: 8px;
}
.todos li.completed {
color: var(--muted);
text-decoration: line-through;
}
.todos li.in_progress {
color: var(--accent);
font-weight: 600;
}
.card {
border: 1px solid var(--accent);
background: var(--bg1);
border-radius: var(--radius);
padding: 12px;
margin: 10px 0;
box-shadow: var(--shadow);
}
.card h3 {
margin: 0 0 6px;
font-size: 14px;
color: var(--fg0);
display: flex;
gap: 8px;
align-items: center;
}
.card .actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 10px;
}
.card .from {
font-size: 11.5px;
color: var(--muted);
}
.q-options {
display: grid;
gap: 6px;
margin: 8px 0;
}
.q-option {
display: flex;
gap: 8px;
align-items: flex-start;
text-align: left;
padding: 8px 10px;
border: 1px solid var(--bg3);
border-radius: 6px;
background: var(--bg0);
cursor: pointer;
}
.q-option.selected {
border-color: var(--accent);
background: var(--bg2);
}
.q-option .desc {
font-size: 12.5px;
color: var(--fg3);
}
.q-header {
display: inline-block;
font-size: 11px;
padding: 1px 6px;
border-radius: 4px;
background: var(--bg3);
color: var(--fg1);
margin-bottom: 4px;
}
.error-box {
border: 1px solid var(--red);
color: var(--red);
border-radius: var(--radius);
padding: 8px 12px;
margin: 8px 0;
display: flex;
gap: 8px;
align-items: flex-start;
word-break: break-word;
}
.error-box span {
flex: 1;
}
/* --- composer -------------------------------------------------------------- */
.composer-wrap {
border-top: 1px solid var(--bg2);
padding: 8px 12px;
padding-bottom: max(8px, env(safe-area-inset-bottom));
background: var(--bg0);
}
.composer {
max-width: 900px;
margin: 0 auto;
position: relative;
}
.composer textarea {
width: 100%;
resize: none;
min-height: 44px;
max-height: 40vh;
padding: 10px 12px;
border-radius: var(--radius);
background: var(--bg1);
display: block;
}
.composer-bar {
display: flex;
align-items: center;
gap: 6px;
margin-top: 6px;
flex-wrap: wrap;
}
.composer-bar select {
max-width: 220px;
font-size: 12.5px;
padding: 3px 6px;
}
.composer-options {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
flex: 1;
min-width: 0;
}
.composer-options > * {
flex-shrink: 0;
}
.composer-actions {
display: flex;
gap: 6px;
margin-left: auto;
}
.todo-line {
font-size: 12.5px;
color: var(--muted);
margin: 4px 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mode-tabs {
display: inline-flex;
border: 1px solid var(--bg3);
border-radius: 6px;
overflow: hidden;
}
.mode-tabs button {
border: none;
border-radius: 0;
background: transparent;
padding: 3px 10px;
font-size: 12.5px;
}
.mode-tabs button.active {
background: var(--accent);
color: var(--on-accent);
font-weight: 600;
}
.attachments {
display: flex;
gap: 6px;
margin-bottom: 6px;
flex-wrap: wrap;
}
.attachments .att {
position: relative;
}
.attachments .att.file {
display: flex;
align-items: center;
gap: 6px;
height: 36px;
padding: 0 22px 0 10px;
border: 1px solid var(--bg3);
border-radius: 6px;
background: var(--bg1);
font-size: 12.5px;
max-width: 260px;
}
.attachments .att.file span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.attachments .att.file small {
color: var(--muted);
white-space: nowrap;
}
.attachments img {
height: 56px;
border-radius: 6px;
border: 1px solid var(--bg3);
}
.attachments button {
position: absolute;
top: -6px;
right: -6px;
padding: 0 5px;
font-size: 11px;
border-radius: 50%;
}
.suggest {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: var(--radius);
box-shadow: var(--shadow);
max-height: 260px;
overflow-y: auto;
margin-bottom: 4px;
z-index: 5;
}
.suggest div {
padding: 6px 10px;
cursor: pointer;
display: flex;
gap: 10px;
}
.suggest div.active,
.suggest div:hover {
background: var(--bg2);
}
.suggest .name {
font-family: var(--mono);
color: var(--accent);
}
.suggest .desc {
color: var(--fg3);
font-size: 12.5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* --- forms, settings ------------------------------------------------------- */
.tabs {
display: flex;
gap: 4px;
border-bottom: 1px solid var(--bg2);
margin-bottom: 16px;
flex-wrap: wrap;
}
.tabs button {
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
background: transparent;
padding: 8px 12px;
}
.tabs button.active {
border-bottom-color: var(--accent);
color: var(--fg0);
}
.form {
display: grid;
grid-template-columns: minmax(140px, 220px) 1fr;
gap: 10px 16px;
align-items: center;
max-width: 820px;
}
.form label {
color: var(--fg2);
}
.form label.check {
grid-column: 2;
display: flex;
align-items: center;
gap: 8px;
color: var(--fg1);
}
.form .hint {
grid-column: 2;
font-size: 12px;
color: var(--muted);
margin-top: -6px;
}
.panel {
border: 1px solid var(--bg2);
border-radius: var(--radius);
padding: 14px;
margin-bottom: 14px;
background: var(--bg1);
}
.panel h3 {
margin: 0 0 10px;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
color: var(--fg0);
}
.row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.spacer {
flex: 1;
}
table.grid {
border-collapse: collapse;
width: 100%;
font-size: 13px;
}
table.grid th {
text-align: left;
color: var(--muted);
font-weight: 500;
font-size: 12px;
border-bottom: 1px solid var(--bg3);
padding: 6px;
}
table.grid td {
border-bottom: 1px solid var(--bg2);
padding: 5px 6px;
}
table.grid td.num,
table.grid th.num {
text-align: right;
font-variant-numeric: tabular-nums;
}
table.grid input {
width: 100%;
min-width: 60px;
}
table.grid input[type="number"] {
min-width: 92px;
}
.raw-editor {
width: 100%;
min-height: 60vh;
font-family: var(--mono);
font-size: 12.5px;
line-height: 1.5;
tab-size: 2;
}
.notice {
padding: 8px 12px;
border-radius: var(--radius);
background: var(--bg2);
margin-bottom: 12px;
font-size: 13px;
}
.notice.ok {
color: var(--green);
}
.notice.err {
color: var(--red);
}
.empty {
color: var(--muted);
text-align: center;
padding: 40px 0;
}
.dir-list {
border: 1px solid var(--bg2);
border-radius: var(--radius);
max-height: 340px;
overflow-y: auto;
}
.dir-list button {
display: flex;
width: 100%;
gap: 8px;
border: none;
border-bottom: 1px solid var(--bg2);
border-radius: 0;
background: transparent;
text-align: left;
padding: 7px 10px;
}
.dir-list button:hover {
background: var(--bg2);
}
/* --- stats ----------------------------------------------------------------- */
.kpis {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 10px;
margin-bottom: 16px;
}
.kpi {
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: var(--radius);
padding: 12px;
}
.kpi .k-label {
font-size: 12px;
color: var(--fg3);
}
.kpi .k-value {
font-size: 22px;
font-weight: 650;
color: var(--fg0);
font-variant-numeric: tabular-nums;
}
.kpi .k-sub {
font-size: 11.5px;
color: var(--muted);
}
.chart {
position: relative;
}
.chart svg {
display: block;
width: 100%;
overflow: visible;
}
.chart .axis text {
fill: var(--muted);
font-size: 11px;
}
.chart .grid-line {
stroke: var(--bg2);
stroke-width: 1;
}
.legend {
display: flex;
gap: 12px;
flex-wrap: wrap;
font-size: 12px;
color: var(--fg2);
margin-bottom: 8px;
}
.legend span {
display: inline-flex;
align-items: center;
gap: 5px;
}
.legend i {
width: 10px;
height: 10px;
border-radius: 3px;
display: inline-block;
}
.legend i.heat-scale {
width: 120px;
}
.tooltip {
position: absolute;
pointer-events: none;
background: var(--bg2);
border: 1px solid var(--bg3);
border-radius: 6px;
padding: 6px 9px;
font-size: 12px;
box-shadow: var(--shadow);
white-space: nowrap;
z-index: 10;
color: var(--fg1);
}
.tooltip b {
color: var(--fg0);
}
.tooltip .tt-row {
display: flex;
gap: 8px;
align-items: center;
justify-content: space-between;
}
.tooltip i {
width: 8px;
height: 8px;
border-radius: 2px;
display: inline-block;
}
.two-col {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
/* --- login ----------------------------------------------------------------- */
.login {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.login form {
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: 12px;
padding: 28px;
width: min(360px, 92vw);
display: grid;
gap: 12px;
text-align: center;
}
.login img {
width: 56px;
margin: 0 auto;
}
/* --- responsive ------------------------------------------------------------ */
@media (max-width: 800px) {
.sidebar {
position: fixed;
inset: 0 auto 0 0;
z-index: 20;
transform: translateX(-100%);
transition: transform 0.18s ease;
box-shadow: var(--shadow);
width: min(300px, 86vw);
}
.sidebar.open {
transform: none;
}
.backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 15;
}
.menu-btn {
display: inline-block;
}
.form {
grid-template-columns: 1fr;
}
.form .hint {
grid-column: 1;
}
.two-col {
grid-template-columns: 1fr;
}
.page {
padding: 12px;
}
.chat {
padding: 12px 10px 20px;
}
.hide-mobile {
display: none !important;
}
.topbar {
flex-wrap: nowrap;
gap: 4px;
padding-left: 6px;
padding-right: 6px;
}
.topbar .path {
display: none;
}
.topbar button.small {
padding: 2px 5px;
}
/* One scrollable row of options, actions stay visible. */
.composer-bar {
flex-wrap: nowrap;
}
.composer-options {
flex-wrap: nowrap;
overflow-x: auto;
scrollbar-width: none;
}
.composer-options::-webkit-scrollbar {
display: none;
}
.composer-options select {
max-width: 150px;
}
/* Avoid iOS zoom on focus. */
.composer textarea,
input,
select,
textarea {
font-size: 16px;
}
}
/* --- syntax highlighting (highlight.js classes, Gruvbox colours) ----------- */
.hljs-keyword,
.hljs-selector-tag,
.hljs-built_in {
color: var(--syntax-keyword);
}
.hljs-string,
.hljs-attr,
.hljs-regexp {
color: var(--syntax-string);
}
.hljs-number,
.hljs-literal {
color: var(--syntax-number);
}
.hljs-comment,
.hljs-quote {
color: var(--syntax-comment);
font-style: italic;
}
.hljs-title,
.hljs-section,
.hljs-function {
color: var(--syntax-function);
}
.hljs-type,
.hljs-class,
.hljs-tag {
color: var(--syntax-type);
}
.hljs-variable,
.hljs-template-variable,
.hljs-params {
color: var(--syntax-variable);
}
.hljs-meta,
.hljs-symbol {
color: var(--syntax-meta);
}
.hljs-addition {
background: var(--diff-add);
}
.hljs-deletion {
background: var(--diff-del);
}
a.button {
display: inline-block;
text-align: center;
text-decoration: none;
color: var(--fg1);
border: 1px solid var(--bg3);
background: var(--bg2);
border-radius: 6px;
padding: 5px 12px;
}
a.button:hover {
border-color: var(--fg3);
}
.sidebar-user {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 6px 12px;
border-top: 1px solid var(--bg2);
font-size: 13px;
color: var(--fg2);
}
.sidebar-user > span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 30;
padding: 16px;
}
.modal {
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: 12px;
padding: 18px;
width: min(440px, 100%);
max-height: 80vh;
overflow-y: auto;
box-shadow: var(--shadow);
}
.modal h3 {
margin: 0 0 10px;
}
.check-list label {
display: flex;
gap: 8px;
align-items: center;
padding: 6px 0;
border-bottom: 1px solid var(--bg2);
}
.readonly-bar {
border-top: 1px solid var(--bg2);
padding: 10px 14px;
text-align: center;
color: var(--muted);
padding-bottom: max(10px, env(safe-area-inset-bottom));
}
/* --- activity animations ---------------------------------------------------- */
.activity {
display: flex;
align-items: center;
gap: 10px;
margin: 10px 0;
font-size: 13px;
color: var(--fg3);
}
.activity.paused {
color: var(--accent2);
}
.dots {
display: inline-flex;
gap: 4px;
}
.dots i {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--accent);
animation: dot-bounce 1.2s infinite ease-in-out;
}
.dots i:nth-child(2) {
animation-delay: 0.15s;
}
.dots i:nth-child(3) {
animation-delay: 0.3s;
}
@keyframes dot-bounce {
0%,
80%,
100% {
transform: translateY(0);
opacity: 0.35;
}
40% {
transform: translateY(-5px);
opacity: 1;
}
}
.pause-icon {
width: 10px;
height: 12px;
border-left: 3px solid var(--accent2);
border-right: 3px solid var(--accent2);
}
.spinner {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 50%;
border: 2px solid var(--bg3);
border-top-color: var(--accent);
animation: spin 0.8s linear infinite;
flex-shrink: 0;
}
.spinner.small {
width: 12px;
height: 12px;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.tool.running {
border-color: var(--accent);
animation: glow 1.6s ease-in-out infinite;
}
@keyframes glow {
50% {
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
}
.busy-ring {
flex-shrink: 0;
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid var(--bg3);
border-top-color: var(--accent);
animation: spin 0.8s linear infinite;
}
/* Blinking caret at the end of streaming text. */
.streaming .markdown > :last-child::after {
content: "";
display: inline-block;
width: 0.55em;
height: 1.05em;
margin-left: 2px;
vertical-align: text-bottom;
background: var(--accent);
animation: blink 1s steps(1) infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
/* Indeterminate progress bar under the top bar. */
.workbar {
height: 2px;
flex-shrink: 0;
position: relative;
overflow: hidden;
}
.workbar.on::before {
content: "";
position: absolute;
inset: 0;
width: 35%;
background: linear-gradient(90deg, transparent, var(--accent), transparent);
animation: slide 1.4s ease-in-out infinite;
}
@keyframes slide {
from {
transform: translateX(-100%);
}
to {
transform: translateX(300%);
}
}
@media (prefers-reduced-motion: reduce) {
.dots i,
.spinner,
.star line,
.star-spin,
.busy-ring,
.tool.running,
.streaming .markdown > :last-child::after,
.streaming-text::after,
.workbar.on::before {
animation: none;
}
.dots i {
opacity: 1;
}
.workbar.on::before {
width: 100%;
opacity: 0.6;
}
}
/* --- image gallery --------------------------------------------------------- */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 12px;
}
.gallery.small {
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
margin-top: 6px;
}
.gallery-item {
margin: 0;
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: var(--radius);
overflow: hidden;
display: flex;
flex-direction: column;
}
.gallery-item img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
display: block;
cursor: zoom-in;
background: var(--bg2);
margin: 0;
border-radius: 0;
}
.gallery-item.placeholder {
aspect-ratio: 4 / 3;
align-items: center;
justify-content: center;
}
.gallery-item figcaption {
padding: 8px;
display: grid;
gap: 4px;
font-size: 12.5px;
}
.gallery-item .prompt {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
color: var(--fg1);
}
.gallery-item .meta,
.viewer .meta {
color: var(--muted);
font-size: 11.5px;
}
a.button.small {
padding: 2px 8px;
font-size: 12px;
}
.viewer {
margin: 0;
max-width: min(1200px, 96vw);
max-height: 92vh;
display: flex;
flex-direction: column;
gap: 8px;
color: var(--fg0);
}
.viewer img {
max-width: 100%;
max-height: 80vh;
object-fit: contain;
border-radius: var(--radius);
}
.budget-bar {
height: 8px;
border-radius: 4px;
background: var(--bg2);
overflow: hidden;
}
.budget-bar > div {
height: 100%;
border-radius: 4px;
}
.muted {
color: var(--muted);
}
/* --- message queue --------------------------------------------------------- */
.queue {
max-width: 900px;
margin: 0 auto;
padding: 6px 12px 0;
width: 100%;
}
.queue-head {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: var(--muted);
margin-bottom: 4px;
}
.queue-item {
display: flex;
align-items: center;
gap: 8px;
border: 1px dashed var(--bg3);
border-radius: var(--radius);
padding: 5px 8px;
margin-bottom: 4px;
font-size: 13px;
background: var(--bg1);
}
.queue-text {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--fg2);
}
.queue-item img {
height: 28px;
border-radius: 4px;
}
/* --- file manager ------------------------------------------------------------ */
.files-layout {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: minmax(260px, 360px) 1fr;
}
.files-side {
border-right: 1px solid var(--bg2);
display: flex;
flex-direction: column;
min-height: 0;
overflow-y: auto;
}
.files-main {
min-width: 0;
min-height: 0;
display: flex;
}
.files-list {
display: flex;
flex-direction: column;
min-height: 100%;
}
.files-list.drag {
outline: 2px dashed var(--accent);
outline-offset: -4px;
}
.files-toolbar {
display: flex;
gap: 4px;
padding: 8px;
flex-wrap: wrap;
align-items: center;
}
.files-toolbar button.active {
border-color: var(--accent);
color: var(--accent);
}
.files-search {
flex: 1;
min-width: 100px;
}
.crumbs {
padding: 0 10px 6px;
font-size: 12.5px;
color: var(--muted);
word-break: break-all;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 2px;
}
.crumbs-up {
margin-right: 6px;
padding: 3px 8px;
}
.crumbs-up .icon {
width: 18px;
height: 18px;
}
.entries {
flex: 1;
}
.entry {
display: flex;
align-items: center;
width: 100%;
border: none;
border-radius: 0;
background: transparent;
padding: 0;
text-align: left;
}
button.entry {
padding: 6px 10px;
gap: 8px;
}
.entry:hover,
.entry.active {
background: var(--bg2);
}
.entry-main {
flex: 1;
min-width: 0;
display: flex;
gap: 8px;
align-items: center;
border: none;
background: transparent;
border-radius: 0;
padding: 6px 4px 6px 10px;
text-align: left;
}
.entry .name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.entry .size {
font-size: 11px;
color: var(--muted);
}
.entry-menu {
position: relative;
}
.entry-menu summary {
list-style: none;
cursor: pointer;
padding: 4px 10px;
color: var(--muted);
}
.entry-menu summary::-webkit-details-marker {
display: none;
}
.entry-menu .menu {
position: absolute;
right: 4px;
top: 100%;
z-index: 5;
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: var(--radius);
box-shadow: var(--shadow);
display: grid;
min-width: 150px;
padding: 4px;
}
.entry-menu .menu > * {
text-align: left;
border: none;
background: transparent;
padding: 6px 10px;
}
.entry-menu .menu > *:hover {
background: var(--bg2);
}
.drop-hint {
font-size: 11.5px;
color: var(--muted);
padding: 8px 10px;
text-align: center;
}
.git-mark {
font-family: var(--mono);
font-size: 11px;
font-weight: 700;
min-width: 14px;
text-align: center;
color: var(--accent2);
}
.git-mark.m-A,
.git-mark.m-U {
color: var(--green);
}
.git-mark.m-D {
color: var(--red);
}
.git-mark.m-dot {
color: var(--muted);
}
.editor-pane {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.editor-pane.empty {
align-items: center;
justify-content: center;
}
.editor-bar {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
border-bottom: 1px solid var(--bg2);
}
.editor-bar .grow {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dirty {
color: var(--accent);
}
.code-editor {
flex: 1;
min-height: 0;
overflow: hidden;
}
.code-editor .cm-editor {
height: 100%;
}
.pane-scroll {
flex: 1;
min-height: 0;
overflow: auto;
}
.image-preview {
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
background: repeating-conic-gradient(var(--bg1) 0% 25%, var(--bg0) 0% 50%) 50% / 20px 20px;
}
.image-preview img {
max-width: 100%;
max-height: 100%;
}
.files-status {
position: fixed;
right: 12px;
bottom: 8px;
font-size: 11px;
color: var(--muted);
pointer-events: none;
}
.git-init {
display: flex;
gap: 6px;
padding: 8px 10px;
border-top: 1px solid var(--bg2);
}
.mobile-only {
display: none;
}
/* git panel */
.git-panel {
padding: 8px 10px;
}
.git-branch {
display: flex;
gap: 4px;
align-items: center;
flex-wrap: wrap;
}
.git-branch select {
max-width: 160px;
}
.git-output {
font-size: 12px;
background: var(--bg1);
border: 1px solid var(--bg2);
border-radius: 6px;
padding: 6px 8px;
white-space: pre-wrap;
max-height: 160px;
overflow: auto;
margin: 6px 0 0;
}
.git-output.err {
color: var(--red);
border-color: var(--red);
}
.git-section {
margin-bottom: 10px;
}
.git-head {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11.5px;
text-transform: uppercase;
color: var(--muted);
padding: 4px 0;
}
.git-file {
display: flex;
align-items: center;
gap: 4px;
}
.git-name {
flex: 1;
min-width: 0;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 3px 4px;
font-size: 13px;
}
.git-commit textarea {
width: 100%;
margin-bottom: 6px;
}
.git-log {
display: grid;
}
.git-commit-row {
display: grid;
text-align: left;
border: none;
border-bottom: 1px solid var(--bg2);
border-radius: 0;
background: transparent;
padding: 6px 2px;
}
.git-commit-row:hover {
background: var(--bg2);
}
.git-commit-row .subject {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.git-commit-row .meta {
font-size: 11.5px;
color: var(--muted);
}
@media (max-width: 800px) {
.files-layout {
grid-template-columns: 1fr;
}
.files-main {
display: none;
}
.files-layout.show-editor .files-side {
display: none;
}
.files-layout.show-editor .files-main {
display: flex;
}
.mobile-only {
display: inline-block;
}
}
/* --- images in chat ------------------------------------------------------------ */
.markdown img.inline-image,
.svg-block img,
.image-result img {
max-width: min(100%, 640px);
max-height: 480px;
border-radius: 6px;
display: block;
margin: 6px 0;
background: repeating-conic-gradient(var(--bg1) 0% 25%, var(--bg0) 0% 50%) 50% / 16px 16px;
}
.svg-block {
margin: 8px 0;
}
.image-refs {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin: 6px 0;
}
.image-refs img {
height: 140px;
max-width: 260px;
object-fit: contain;
border-radius: 6px;
border: 1px solid var(--bg2);
background: repeating-conic-gradient(var(--bg1) 0% 25%, var(--bg0) 0% 50%) 50% / 16px 16px;
}
.image-result {
padding: 0 10px 8px;
}
.tool-head {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 0;
font-size: 13px;
}
/* --- usage overlay ------------------------------------------------------------- */
.modal.wide {
width: min(1100px, 100%);
max-height: 90vh;
}
.kv-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 6px 20px;
}
.kv-title {
font-size: 11px;
text-transform: uppercase;
color: var(--muted);
margin: 4px 0 2px;
}
.kv {
display: flex;
justify-content: space-between;
gap: 10px;
font-size: 13px;
padding: 2px 0;
border-bottom: 1px dashed var(--bg2);
}
.kv span {
color: var(--fg3);
}
.kv b {
font-weight: 500;
color: var(--fg0);
text-align: right;
font-variant-numeric: tabular-nums;
overflow: hidden;
text-overflow: ellipsis;
}
/* --- file previews ------------------------------------------------------------- */
.pdf-preview {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.pdf-nav {
padding: 6px 10px;
border-bottom: 1px solid var(--bg2);
font-size: 13px;
}
.pdf-preview .image-preview img {
background: #fff;
box-shadow: var(--shadow);
}
.doc-text {
margin: 0;
padding: 16px;
white-space: pre-wrap;
font-size: 13px;
}
.sheet-tabs {
margin: 6px 10px;
flex-wrap: wrap;
align-self: flex-start;
}
table.grid.sheet td,
table.grid.sheet th {
white-space: nowrap;
border-right: 1px solid var(--bg2);
}
.audio-preview {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
padding: 24px;
}
.audio-preview audio {
width: min(520px, 100%);
}
.model-viewer {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.model-canvas {
flex: 1;
min-height: 300px;
touch-action: none;
}
.model-info {
font-size: 12px;
color: var(--muted);
padding: 4px 10px;
border-top: 1px solid var(--bg2);
}
.star {
width: 16px;
height: 16px;
flex-shrink: 0;
vertical-align: -3px;
overflow: visible;
}
.star line {
stroke: var(--accent2);
stroke-width: 2.6;
stroke-linecap: round;
opacity: 0.25;
animation: star-ray 0.9s linear infinite;
}
.star-spin {
transform-origin: 0 0;
animation: spin 6s linear infinite;
}
@keyframes star-ray {
0% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}
.think-icon {
width: 15px;
height: 15px;
vertical-align: -2px;
fill: none;
stroke: var(--fg3);
stroke-width: 1.6;
stroke-linejoin: round;
}
.think-icon circle {
fill: var(--fg3);
stroke: none;
}
.activity-text {
color: var(--accent2);
}
.activity-meta {
color: var(--muted);
font-variant-numeric: tabular-nums;
}
tr.audit-warn td {
color: var(--accent2);
}
a.button.primary {
background: var(--accent);
border-color: var(--accent);
color: var(--on-accent);
font-weight: 600;
}
.mode-tabs button.active.deep {
background: var(--accent2);
}
.rewind-files {
max-height: 200px;
overflow-y: auto;
font-size: 12.5px;
padding-left: 18px;
}
/* --- in-app dialogs and toasts --------------------------------------------------- */
.modal.dialog {
width: min(420px, 100%);
z-index: 40;
}
.dialog-message {
white-space: pre-wrap;
font-size: 14px;
color: var(--fg1);
margin: 0 0 12px;
}
.dialog-actions {
justify-content: flex-end;
margin-top: 14px;
}
button.danger-solid {
background: var(--red);
border-color: var(--red);
color: var(--bg0);
font-weight: 600;
}
.toasts {
position: fixed;
right: 16px;
bottom: 16px;
display: grid;
gap: 8px;
z-index: 50;
max-width: min(420px, calc(100vw - 32px));
padding-bottom: env(safe-area-inset-bottom);
}
.toast {
background: var(--bg1);
border: 1px solid var(--bg3);
border-left: 4px solid var(--blue);
border-radius: var(--radius);
padding: 10px 14px;
box-shadow: var(--shadow);
font-size: 13px;
cursor: pointer;
animation: toast-in 0.18s ease-out;
word-break: break-word;
}
.toast.error {
border-left-color: var(--red);
}
.toast.success {
border-left-color: var(--green);
}
@keyframes toast-in {
from {
transform: translateY(8px);
opacity: 0;
}
}
.shell-output {
background: var(--bg0);
border: 1px solid var(--bg2);
border-radius: 6px;
padding: 8px 10px;
max-height: 55vh;
overflow: auto;
white-space: pre-wrap;
font-size: 12px;
margin: 0;
}
.segmented {
display: inline-flex;
gap: 2px;
background: var(--bg1);
border-radius: 8px;
padding: 2px;
width: fit-content;
}
.segmented button.active {
background: var(--accent);
color: var(--on-accent);
}
.sidebar-user .theme-toggle {
margin-left: auto;
font-size: 15px;
min-width: 32px;
}
.form .stack {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
/* --- files in chat (preview + type/size badges + name) ------------------------- */
.file-figure {
display: inline-flex;
flex-direction: column;
gap: 4px;
margin: 6px 8px 6px 0;
max-width: min(100%, 640px);
vertical-align: top;
}
.file-preview {
min-width: 128px;
position: relative;
display: inline-block;
max-width: 100%;
}
.file-preview img {
margin: 0 !important;
display: block;
}
.file-badge {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.03em;
line-height: 1;
padding: 3px 6px;
border-radius: 4px;
background: color-mix(in srgb, var(--bg0) 82%, transparent);
color: var(--fg1);
border: 1px solid var(--bg3);
white-space: nowrap;
}
.file-preview .file-badge {
position: absolute;
top: 6px;
pointer-events: none;
backdrop-filter: blur(4px);
}
.file-preview .file-badge.left {
left: 6px;
}
.file-preview .file-badge.right {
right: 6px;
}
.file-figure figcaption {
font-size: 12px;
color: var(--fg3);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.file-figure figcaption a {
color: inherit;
}
.file-figure.thumb img {
height: 140px;
max-width: 260px;
object-fit: contain;
}
.msg-user .file-figure img {
max-height: 160px;
border-radius: 6px;
}
.user-files {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 6px;
}
.file-chip {
display: inline-flex;
align-items: center;
gap: 6px;
max-width: 100%;
padding: 4px 8px;
border-radius: 6px;
border: 1px solid var(--bg3);
background: var(--bg1);
color: var(--fg1);
font-size: 12px;
text-decoration: none;
white-space: nowrap;
margin: 2px 0;
}
.file-chip:hover {
border-color: var(--accent);
}
.file-chip-name {
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.file-chip-size {
color: var(--muted);
}
.file-chip .file-badge {
background: var(--bg2);
border: none;
}
.gallery .file-figure { margin: 0; max-width: none; display: flex; }
.nav-icon {
display: inline-block;
width: 1.3em;
margin-right: 6px;
text-align: center;
font-size: 0.95em;
}
.sidebar-foot button {
display: flex;
align-items: center;
justify-content: flex-start;
}
/* --- jump to latest message ---------------------------------------------------- */
.jump-latest {
position: sticky;
bottom: 14px;
height: 0;
display: flex;
justify-content: center;
pointer-events: none;
z-index: 4;
}
.jump-latest button {
pointer-events: auto;
transform: translateY(-100%);
width: 40px;
height: 40px;
border-radius: 50%;
font-size: 20px;
line-height: 1;
padding: 0;
box-shadow: var(--shadow);
}
/* --- session search -------------------------------------------------------------- */
.session-search {
padding: 0 12px 8px;
}
.session-search input {
width: 100%;
}
.session-item .snippet {
white-space: normal;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
color: var(--fg2);
}
/* --- small popup menu (export) ---------------------------------------------- */
.menu-pop {
position: relative;
}
.menu-pop > summary {
list-style: none;
cursor: pointer;
padding: 4px 8px;
border-radius: 6px;
}
.menu-pop > summary::-webkit-details-marker {
display: none;
}
.menu-pop > summary:hover {
background: var(--bg2);
}
.menu-pop-body {
position: absolute;
right: 0;
top: calc(100% + 4px);
z-index: 20;
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: var(--radius);
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
min-width: 160px;
padding: 4px;
}
.menu-pop-body a {
padding: 6px 10px;
border-radius: 6px;
color: var(--fg1);
text-decoration: none;
white-space: nowrap;
}
.menu-pop-body a:hover {
background: var(--bg2);
}
/* --- new session wizard ------------------------------------------------------------ */
.wizard {
max-width: 980px;
}
.wiz-title {
font-size: 30px;
margin: 8px 0 4px;
color: var(--fg0);
}
.wiz-sub {
color: var(--fg3);
margin: 0 0 18px;
}
.wiz-panel {
padding: 22px 24px;
}
.wiz-step {
margin-bottom: 26px;
}
.wiz-step h3 {
display: flex;
align-items: center;
gap: 12px;
font-size: 19px;
margin: 0 0 14px;
color: var(--fg0);
}
.wiz-num {
display: inline-grid;
place-items: center;
width: 30px;
height: 30px;
border-radius: 50%;
border: 1px solid var(--bg3);
background: var(--bg2);
font-size: 14px;
font-weight: 600;
color: var(--fg1);
flex-shrink: 0;
}
.wiz-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
gap: 12px;
}
.wiz-cards.five {
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}
.wiz-cards.two {
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.wiz-card {
position: relative;
display: flex;
align-items: center;
gap: 12px;
text-align: left;
padding: 14px 16px;
min-height: 64px;
border-radius: 10px;
border: 1px solid var(--bg3);
background: var(--bg0);
color: var(--fg1);
font-size: 15px;
cursor: pointer;
transition: border-color 0.15s, background 0.15s;
}
.wiz-card:hover {
border-color: var(--fg3);
}
.wiz-card.active {
border: 2px solid var(--accent);
padding: 13px 15px;
background: color-mix(in srgb, var(--accent) 12%, var(--bg0));
}
.wiz-card-text {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
padding-right: 18px;
}
.wiz-card-title {
font-weight: 600;
color: var(--fg0);
}
.wiz-card-desc {
font-size: 12.5px;
color: var(--fg3);
line-height: 1.35;
}
.wiz-icon {
width: 26px;
height: 26px;
flex-shrink: 0;
fill: none;
stroke: currentColor;
stroke-width: 1.6;
stroke-linecap: round;
stroke-linejoin: round;
}
.wiz-card .wiz-icon {
color: var(--fg2);
}
.wiz-card.active .wiz-icon {
color: var(--accent);
}
.wiz-check {
position: absolute;
top: 10px;
right: 10px;
width: 18px;
height: 18px;
fill: none;
stroke: var(--accent);
stroke-width: 2.4;
stroke-linecap: round;
stroke-linejoin: round;
}
.wiz-url {
width: 100%;
margin-bottom: 10px;
font-size: 15px;
}
.wiz-input {
border: 1px solid var(--bg3);
border-radius: 12px;
background: var(--bg0);
padding: 12px 14px 8px;
}
.wiz-input:focus-within {
border-color: var(--accent);
}
.wiz-input textarea {
width: 100%;
min-height: 96px;
border: none;
background: transparent;
resize: vertical;
font-size: 15px;
outline: none;
padding: 0;
}
.wiz-input-foot {
display: flex;
align-items: center;
gap: 8px;
font-size: 12.5px;
color: var(--fg3);
}
.wiz-input-foot .wiz-icon {
width: 20px;
height: 20px;
}
.wiz-ideas {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-top: 12px;
color: var(--fg2);
}
.chip-btn {
border: 1px solid var(--bg3);
border-radius: 8px;
background: var(--bg0);
color: var(--fg1);
padding: 6px 12px;
cursor: pointer;
}
.chip-btn:hover {
border-color: var(--accent);
}
.wiz-foot {
display: flex;
flex-direction: column;
gap: 14px;
border-top: 1px solid var(--bg2);
padding-top: 18px;
}
.wiz-foot-row {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.wiz-foot-row label {
color: var(--fg2);
}
.wiz-folder {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
color: var(--fg2);
}
.wiz-folder .wiz-icon {
width: 20px;
height: 20px;
}
.wiz-folder-text {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.wiz-folder-name {
width: 220px;
font-family: var(--mono);
}
.link-btn {
background: none;
border: none;
color: var(--blue);
cursor: pointer;
padding: 0;
text-decoration: underline;
text-underline-offset: 3px;
}
.wiz-picker .dir-list button .wiz-icon {
width: 18px;
height: 18px;
color: var(--fg3);
}
.wiz-start-row {
display: flex;
justify-content: flex-end;
}
.wiz-start {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 16px;
padding: 12px 26px;
border-radius: 10px;
}
.wiz-start .wiz-icon {
width: 20px;
height: 20px;
}
@media (max-width: 700px) {
.wiz-panel {
padding: 16px;
}
.wiz-title {
font-size: 24px;
}
.wiz-cards,
.wiz-cards.five,
.wiz-cards.two {
grid-template-columns: 1fr 1fr;
}
.wiz-card {
padding: 10px 12px;
}
.wiz-card-desc {
display: none;
}
}
/* --- craft phase bar ----------------------------------------------------------------- */
.phase-bar {
display: flex;
align-items: center;
gap: 0;
padding: 8px 16px;
border-bottom: 1px solid var(--bg2);
overflow-x: auto;
font-size: 12.5px;
}
.phase-bar .phase {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--fg3);
white-space: nowrap;
}
.phase-bar .phase .dot {
width: 18px;
height: 18px;
border-radius: 50%;
border: 1.5px solid var(--bg3);
display: inline-grid;
place-items: center;
font-size: 10px;
}
.phase-bar .phase.done {
color: var(--fg2);
}
.phase-bar .phase.done .dot {
background: var(--green);
border-color: var(--green);
}
.phase-bar .phase.done .dot svg {
width: 11px;
height: 11px;
fill: none;
stroke: var(--bg0);
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
}
.phase-bar .phase.current {
color: var(--accent);
font-weight: 600;
}
.phase-bar .phase.current .dot {
border-color: var(--accent);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
animation: glow 1.6s ease-in-out infinite;
}
.phase-bar .sep {
flex: 1;
min-width: 18px;
max-width: 60px;
height: 1.5px;
background: var(--bg3);
margin: 0 8px;
}
.phase-bar .sep.done {
background: var(--green);
}
.wiz-drop {
display: flex;
align-items: center;
gap: 14px;
margin-top: 14px;
padding: 18px;
border: 2px dashed var(--bg3);
border-radius: 12px;
cursor: pointer;
color: var(--fg1);
}
.wiz-drop:hover {
border-color: var(--accent);
}
.wiz-drop .wiz-icon {
width: 32px;
height: 32px;
color: var(--accent);
}
.wiz-originals {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 10px;
}
.wiz-original {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 10px;
border-radius: 8px;
background: var(--bg1);
font-size: 13px;
}
.wiz-original .name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.wiz-original .size {
color: var(--muted);
}
.wiz-original .bar {
width: 120px;
height: 6px;
border-radius: 3px;
background: var(--bg3);
overflow: hidden;
}
.wiz-original .bar i {
display: block;
height: 100%;
background: var(--accent);
transition: width 0.2s;
}
.wiz-folder-modes {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.wiz-folder-mode {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
border-radius: 8px;
border: 1px solid var(--bg3);
background: var(--bg0);
color: var(--fg1);
cursor: pointer;
}
.wiz-folder-mode .wiz-icon {
width: 18px;
height: 18px;
}
.wiz-folder-mode.active {
border-color: var(--accent);
color: var(--accent);
background: color-mix(in srgb, var(--accent) 10%, var(--bg0));
}
/* --- icons (SVG, coloured by the theme via currentColor) --------------------- */
.icon {
width: 1.15em;
height: 1.15em;
vertical-align: -0.2em;
fill: none;
stroke: currentColor;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
flex-shrink: 0;
}
.icon .fill {
fill: currentColor;
stroke: none;
}
.icon.tiny {
width: 0.85em;
height: 0.85em;
vertical-align: -0.08em;
}
.icon.ok {
color: var(--green);
}
.icon.ficon {
color: var(--fg3);
}
.icon.ficon.dir {
color: var(--accent);
}
.icon.nav-icon {
width: 1.15em;
margin-right: 8px;
}
.file-chip .icon.file-chip-icon {
color: var(--fg3);
}
.theme-toggle .icon {
width: 17px;
height: 17px;
}
.title-edit {
margin-left: 6px;
opacity: 0;
transition: opacity 0.15s;
vertical-align: middle;
padding: 2px 6px;
}
.topbar h1:hover .title-edit,
.title-edit:focus-visible {
opacity: 0.8;
}
@media (pointer: coarse) {
.title-edit {
opacity: 0.6;
}
}
.rename-gen {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin-top: 12px;
}
.rename-gen button {
display: inline-flex;
align-items: center;
gap: 6px;
}
/* --- web terminal -------------------------------------------------------------- */
.term-tabs {
display: flex;
align-items: center;
gap: 4px;
overflow-x: auto;
min-width: 0;
}
.term-tab {
display: inline-flex;
align-items: center;
border-radius: 8px;
white-space: nowrap;
}
.term-tab.active {
background: var(--bg2);
}
.term-tab.dead {
opacity: 0.6;
}
.term-wrap {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
position: relative;
background: var(--bg0);
}
.term-host {
flex: 1;
min-height: 0;
padding: 6px 8px;
}
.term-host .xterm {
height: 100%;
}
.term-state {
position: absolute;
top: 8px;
right: 12px;
font-size: 12px;
color: var(--fg3);
background: var(--bg1);
padding: 3px 8px;
border-radius: 6px;
}
.term-keys {
display: none;
gap: 4px;
padding: 6px;
border-top: 1px solid var(--bg2);
overflow-x: auto;
padding-bottom: max(6px, env(safe-area-inset-bottom));
}
.term-keys button {
flex: 1;
min-width: 42px;
padding: 8px 6px;
font-family: var(--mono);
font-size: 13px;
}
.term-keys button.active {
background: var(--accent);
color: var(--on-accent);
}
@media (pointer: coarse), (max-width: 700px) {
.term-keys {
display: flex;
}
}
.gitcred-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.gitcred-row {
display: grid;
grid-template-columns: 2fr 1.3fr 1.6fr auto;
gap: 6px;
align-items: center;
}
@media (max-width: 700px) {
.gitcred-row {
grid-template-columns: 1fr 1fr auto;
}
.gitcred-row input:first-child {
grid-column: 1 / -1;
}
}
.refine-card {
border-color: var(--purple);
}
.refine-card summary .icon {
color: var(--purple);
}
.harness-note {
display: flex;
align-items: baseline;
gap: 8px;
margin: 6px 0;
padding: 6px 10px;
border-left: 3px solid var(--blue);
border-radius: 4px;
background: var(--bg1);
font-size: 12.5px;
color: var(--fg2);
}
.harness-note .icon {
color: var(--blue);
flex-shrink: 0;
}
.harness-note.ok {
border-left-color: var(--green);
}
.harness-note.ok .icon {
color: var(--green);
}
/* --- automations ---------------------------------------------------------------- */
.job.off {
opacity: 0.65;
}
.job-head {
display: flex;
align-items: flex-start;
gap: 12px;
}
.job-head h3 {
margin: 0;
}
.job-icon {
width: 26px;
height: 26px;
color: var(--accent);
margin-top: 2px;
}
.job-grid {
display: grid;
grid-template-columns: 120px 1fr;
gap: 6px 12px;
margin-top: 12px;
font-size: 13.5px;
}
.job-grid > span:nth-child(odd) {
color: var(--fg3);
}
.job-grid select {
max-width: 100%;
font-size: 13px;
padding: 2px 6px;
}
.job-prompt {
margin-top: 10px;
}
.job-prompt pre,
.job-example {
white-space: pre-wrap;
background: var(--bg1);
padding: 10px;
border-radius: 8px;
font-size: 12.5px;
}
.switch {
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
font-size: 13px;
}
.chip.ok {
color: var(--green);
}
/* --- worktree ------------------------------------------------------------------- */
.wt-wrap {
position: relative;
}
.wt-chip {
border: 1px solid var(--accent);
color: var(--accent);
cursor: pointer;
}
.wt-panel {
width: 340px;
padding: 12px;
gap: 6px;
}
.wt-stats {
display: flex;
flex-wrap: wrap;
gap: 10px;
font-size: 13px;
}
.wt-log {
font-size: 12px;
background: var(--bg0);
padding: 6px 8px;
border-radius: 6px;
max-height: 140px;
overflow: auto;
margin: 0;
}
.menu-pop-body a .icon {
margin-right: 6px;
}
.wiz-check-row {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
/* --- per-hunk review ----------------------------------------------------------- */
.hunk-block {
border-top: 1px dashed var(--bg3);
}
.hunk-block.off > div {
opacity: 0.35;
text-decoration: line-through;
}
.hunk-head {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
color: var(--blue);
background: var(--bg1);
padding: 2px 6px;
}
/* --- regenerate / effort --------------------------------------------------------- */
.regen {
margin-top: 6px;
}
.regen > button {
opacity: 0.7;
}
.regen > button:hover {
opacity: 1;
}
.regen-panel {
margin-top: 6px;
padding: 10px;
border: 1px solid var(--bg3);
border-radius: var(--radius);
background: var(--bg1);
display: flex;
flex-direction: column;
gap: 8px;
}
.effort-select {
max-width: 150px;
}
.voice-btn.on {
color: var(--red);
animation: glow 1.2s ease-in-out infinite;
}
.token-value {
word-break: break-all;
background: var(--bg0);
padding: 4px 8px;
border-radius: 6px;
flex: 1;
}
.token-example {
margin: 8px 0 0;
white-space: pre-wrap;
word-break: break-all;
font-size: 12px;
}
.cli-steps {
margin: 0 0 10px;
padding-left: 20px;
display: flex;
flex-direction: column;
gap: 10px;
}
.memory-card .icon {
color: var(--purple);
}
.update-chip {
display: flex;
align-items: center;
gap: 6px;
margin: 0 12px 8px;
padding: 6px 10px;
border-radius: 8px;
background: color-mix(in srgb, var(--accent) 18%, var(--bg1));
color: var(--fg0);
font-size: 13px;
text-decoration: none;
}
.whatsnew {
margin: 10px 0 16px;
padding-left: 20px;
display: flex;
flex-direction: column;
gap: 6px;
}
.job-hook {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin-top: 10px;
font-size: 13px;
color: var(--fg2);
}
/* --- share target ------------------------------------------------------------- */
.share-target textarea {
width: 100%;
resize: vertical;
margin-bottom: 10px;
}
.share-new {
width: 100%;
justify-content: center;
}
.share-sep {
margin: 14px 0 6px;
font-size: 12px;
color: var(--muted);
}
.share-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.share-list button {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
text-align: left;
background: var(--bg2);
}
.share-list button:hover:not(:disabled) {
background: var(--bg3);
}
.share-title {
font-weight: 600;
color: var(--fg1);
}
.share-meta {
font-size: 12px;
color: var(--muted);
}
/* --- prompt templates ---------------------------------------------------------- */
.tpl-picker {
width: min(560px, 100%);
}
.tpl-list {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 10px;
max-height: 50vh;
overflow-y: auto;
}
.tpl-list button {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
text-align: left;
background: var(--bg2);
}
.tpl-list button.active {
background: var(--bg3);
}
.tpl-name {
display: flex;
gap: 6px;
align-items: center;
font-weight: 600;
color: var(--fg1);
}
.tpl-preview {
font-size: 12px;
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.tpl-field {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 10px;
}
.tpl-field span {
font-size: 13px;
font-weight: 600;
}
.tpl-field textarea,
.tpl-edit textarea {
width: 100%;
resize: vertical;
}
.tpl-edit {
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px 0;
border-bottom: 1px solid var(--bg2);
}
.tpl-ph {
display: flex;
gap: 4px;
flex-wrap: wrap;
}
/* --- command palette ----------------------------------------------------------- */
.palette-backdrop {
align-items: flex-start;
padding-top: 12vh;
}
.palette {
width: min(600px, 100%);
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
max-height: 70vh;
}
.palette > input {
width: 100%;
font-size: 15px;
padding: 10px 12px;
}
.palette-list {
display: flex;
flex-direction: column;
gap: 2px;
overflow-y: auto;
min-height: 0;
}
.palette-list button {
display: flex;
align-items: center;
gap: 10px;
text-align: left;
background: transparent;
border-color: transparent;
}
.palette-list button.active {
background: var(--bg2);
}
.palette-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--fg1);
}
.palette-hint {
font-size: 12px;
color: var(--muted);
white-space: nowrap;
}
.palette kbd {
font: 11px var(--mono, monospace);
padding: 1px 5px;
border-radius: 4px;
border: 1px solid var(--bg3);
background: var(--bg0);
color: var(--fg2);
margin-right: 2px;
}
.palette kbd .tiny {
vertical-align: -1px;
}
.palette-foot {
display: flex;
flex-wrap: wrap;
gap: 12px;
font-size: 11px;
color: var(--muted);
padding: 4px 4px 0;
border-top: 1px solid var(--bg2);
}
@media (pointer: coarse) {
.palette-foot {
display: none;
}
}
/* --- backups ------------------------------------------------------------------- */
.backup-s3 {
margin-top: 12px;
}
.backup-s3 summary {
cursor: pointer;
font-weight: 600;
}
.field-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 10px;
}
.field {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 13px;
}
.field input {
width: 100%;
}
.backup-list {
margin-top: 10px;
max-height: 260px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 2px;
}
.backup-file {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: 6px;
color: var(--fg1);
text-decoration: none;
font-size: 13px;
}
.backup-file:hover {
background: var(--bg2);
}
.backup-file .grow {
flex: 1;
}
.backup-file button,
.backup-file .button {
padding: 2px 6px;
}
/* --- automation templates ------------------------------------------------------ */
.job-tpl {
width: min(720px, 100%);
display: flex;
flex-direction: column;
gap: 10px;
max-height: 88vh;
}
.job-tpl h3 {
display: flex;
align-items: center;
gap: 8px;
}
.job-tpl-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 8px;
}
.job-tpl-card {
display: flex;
align-items: flex-start;
gap: 10px;
text-align: left;
padding: 12px;
background: var(--bg2);
}
.job-tpl-card:hover {
background: var(--bg3);
}
.job-tpl-card span {
display: flex;
flex-direction: column;
gap: 3px;
}
.job-tpl-card small {
color: var(--muted);
}
.job-tpl textarea {
width: 100%;
resize: vertical;
}
.chip-btn.active {
border-color: var(--accent);
color: var(--accent);
}
.job-tpl-card.active {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
.job-tpl .job-tpl-grid {
max-height: 40vh;
overflow-y: auto;
}
.job-title {
font: inherit;
color: inherit;
text-align: left;
}
/* --- automation editor ------------------------------------------------------ */
.job-tabs {
display: none;
border-bottom: 1px solid var(--bg2);
}
.job-tabs button {
flex: 1;
border: none;
border-radius: 0;
background: transparent;
padding: 8px 6px;
color: var(--muted);
border-bottom: 2px solid transparent;
}
.job-tabs button.active {
color: var(--fg0);
border-bottom-color: var(--accent);
}
.job-editor {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(340px, 1fr);
}
.job-editor-main {
min-height: 0;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
padding: 12px;
}
.job-editor-settings {
display: flex;
flex-direction: column;
gap: 10px;
margin: 0;
}
.job-editor-row {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: flex-end;
}
.job-editor-row .field {
flex: 1;
min-width: 150px;
margin: 0;
}
.job-editor-row select,
.job-editor-row input {
width: 100%;
}
.job-editor-status {
display: flex;
flex-direction: column;
gap: 2px;
font-size: 12.5px;
color: var(--fg3);
padding-bottom: 4px;
}
.job-editor-prompt {
flex: 1;
min-height: 360px;
display: flex;
flex-direction: column;
border: 1px solid var(--bg2);
border-radius: var(--radius);
overflow: hidden;
}
.job-editor-prompt-head {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 8px;
padding: 8px 12px;
border-bottom: 1px solid var(--bg2);
background: var(--bg1);
}
.job-editor-prompt .notice {
margin: 8px;
}
.job-editor-chat {
min-height: 0;
min-width: 0;
display: flex;
flex-direction: column;
border-left: 1px solid var(--bg3);
}
.job-editor-chat .topbar {
flex-wrap: nowrap;
}
.job-assistant-start {
margin: auto;
max-width: 340px;
padding: 24px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
color: var(--fg2);
}
.job-assistant-start .icon {
width: 32px;
height: 32px;
color: var(--accent);
}
@media (max-width: 900px) {
.job-tabs {
display: flex;
}
.job-editor {
grid-template-columns: minmax(0, 1fr);
}
.job-editor-chat {
border-left: none;
}
.job-editor.tab-prompt .job-editor-settings,
.job-editor.tab-settings .job-editor-prompt,
.job-editor.tab-prompt .job-editor-chat,
.job-editor.tab-settings .job-editor-chat,
.job-editor.tab-assistant .job-editor-main {
display: none;
}
.job-editor.tab-prompt .job-editor-main {
padding: 0;
}
.job-editor.tab-prompt .job-editor-prompt {
border: none;
border-radius: 0;
min-height: 0;
}
}
/* --- schedule builder ---------------------------------------------------------- */
.cron-builder {
display: flex;
flex-direction: column;
gap: 8px;
}
.cron-modes,
.cron-days {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.cron-modes .chip-btn,
.cron-days .chip-btn {
padding: 4px 10px;
font-size: 13px;
}
.cron-days .chip-btn {
min-width: 44px;
}
.cron-fields {
display: flex;
flex-wrap: wrap;
gap: 8px 16px;
align-items: center;
}
.cron-fields label {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 13.5px;
}
.cron-fields input[type="number"] {
width: 70px;
}
.cron-custom {
flex-direction: column;
align-items: stretch !important;
flex: 1;
}
.cron-custom input {
width: 100%;
max-width: 260px;
}
.cron-preview {
display: flex;
flex-wrap: wrap;
gap: 4px 12px;
align-items: baseline;
font-size: 12.5px;
color: var(--fg3);
}
.cron-preview code {
background: var(--bg2);
padding: 1px 6px;
border-radius: 4px;
color: var(--fg1);
}
.cron-preview .err {
color: var(--red);
}
.chip.price-extra {
margin-left: 4px;
font-size: 11px;
cursor: help;
}
.plan-row td {
border-top: none;
padding-top: 0;
}
.plan-usage {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.plan-window {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
min-width: 170px;
}
.plan-window .budget-bar {
flex: 1;
min-width: 60px;
}
.plan-label {
color: var(--muted);
white-space: nowrap;
}
.plan-pct {
font-variant-numeric: tabular-nums;
}
/* --- chat tabs (chat + terminals) ---------------------------------------------- */
.chat-tabs {
display: flex;
align-items: center;
gap: 2px;
padding: 4px 10px 0;
border-bottom: 1px solid var(--bg3);
overflow-x: auto;
flex: none;
}
.chat-tab {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border: none;
border-bottom: 2px solid transparent;
border-radius: 6px 6px 0 0;
background: none;
color: var(--fg2);
font-size: 13px;
white-space: nowrap;
cursor: pointer;
}
span.chat-tab {
padding: 0 4px 0 0;
}
span.chat-tab > button {
padding: 6px 4px 6px 12px;
color: inherit;
font-size: 13px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.chat-tab .close {
padding: 2px 4px;
opacity: 0.6;
}
.chat-tab .close:hover {
opacity: 1;
}
.chat-tab:hover {
background: var(--bg1);
color: var(--fg0);
}
.chat-tab.active {
color: var(--fg0);
border-bottom-color: var(--accent);
background: var(--bg1);
}
.chat-tab.dead {
opacity: 0.55;
}
.chat-tab-add {
padding: 4px 8px;
}
.chat-pane {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.chat-pane[hidden] {
display: none;
}
.files-embed-bar {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
border-bottom: 1px solid var(--bg3);
flex: none;
}
.files-embed-bar .path {
font-size: 12px;
color: var(--fg3);
font-family: var(--mono);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tool-picker .hint {
margin-bottom: 6px;
}
.tool-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
gap: 4px 12px;
}
.tool-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
cursor: pointer;
}
.tool-item.disabled {
opacity: 0.45;
cursor: default;
}
.mode-select {
font-weight: 600;
color: var(--accent);
}
.compacting-card {
display: flex;
align-items: center;
gap: 10px;
margin: 10px 0;
padding: 10px 14px;
border: 1px dashed var(--bg3);
border-radius: var(--radius);
background: var(--bg1);
font-size: 13px;
}
.compacting-card.auto {
border-color: color-mix(in srgb, var(--accent) 60%, var(--bg3));
}
.status-meter .budget-bar {
width: 70px;
flex: none;
}
.status-meter .pct {
width: 38px;
text-align: right;
font-variant-numeric: tabular-nums;
}
/* --- split view (chats side by side) ------------------------------------------- */
.split-view {
flex: 1;
min-height: 0;
display: flex;
}
.split-pane {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.split-pane + .split-pane {
border-left: 1px solid var(--bg3);
}
.split-pane .topbar {
flex-wrap: nowrap;
}
.split-pane .topbar .grow {
min-width: 90px;
}
.split-pane .topbar h1 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Narrow columns: the context chip moves out (the cost chip opens the usage overlay). */
.split-pane .topbar span.chip.hide-mobile {
display: none;
}
@media (max-width: 900px) {
.split-pane + .split-pane {
display: none;
}
}
.instructions-modal {
width: min(640px, calc(100vw - 32px));
}
/* --- short screens ----------------------------------------------------------
* Square phones (e.g. Clicks Communicator, ~393x400 CSS px with a hardware
* keyboard) and phones in landscape: height is the scarce dimension, so bars,
* the composer and the new-chat wizard get tighter and the chat keeps the room. */
@media (max-height: 560px) {
.topbar {
min-height: 40px;
padding: 4px 10px;
padding-top: max(4px, env(safe-area-inset-top));
gap: 4px;
}
.topbar button.ghost {
padding: 4px 6px;
}
.chat {
padding: 10px 12px 14px;
}
.msg {
margin-bottom: 10px;
}
.composer-wrap {
padding: 6px 10px;
padding-bottom: max(6px, env(safe-area-inset-bottom));
}
.composer textarea {
min-height: 38px;
max-height: 30vh;
padding: 8px 10px;
}
/* One placeholder line instead of two (the textarea grows with its content). */
.composer textarea::placeholder {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.composer-bar {
margin-top: 4px;
gap: 4px;
}
.composer-bar select {
max-width: 150px;
padding: 2px 4px;
}
.composer-actions button {
padding: 4px 10px;
}
.todos {
margin: 4px 0;
padding: 6px 10px;
}
.page {
padding: 12px;
}
.wiz-title {
font-size: 19px;
margin: 0 0 8px;
}
.wiz-sub {
display: none;
}
.wiz-panel {
padding: 12px;
}
.wiz-step {
margin-bottom: 16px;
}
.wiz-step h3 {
font-size: 16px;
margin-bottom: 8px;
}
.wiz-cards,
.wiz-cards.five {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 8px;
}
.wiz-card {
padding: 8px 10px;
gap: 8px;
min-height: 44px;
font-size: 14px;
}
.wiz-card.active {
padding: 7px 9px;
}
.wiz-card-text {
padding-right: 14px;
}
.wiz-card-desc {
display: none;
}
.wiz-icon {
width: 20px;
height: 20px;
}
.wiz-num {
width: 24px;
height: 24px;
font-size: 12px;
}
}