Files
codecraft/web/src/styles.css
T
Richard ZinkandClaude Opus 5.5 e693bb196f Stats: heatmap uses the theme accent with a continuous color ramp
Cells blend in OKLab from a neutral empty color to the theme's accent on a
square-root scale instead of seven fixed blue steps; the legend shows the
gradient.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 07:57:59 +01:00

3462 lines
60 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;
}
.conn-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--red);
}
.conn-dot.on {
background: var(--green);
}
.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;
}
.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;
}
.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 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 .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);
}
/* --- 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-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;
}
/* --- 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);
}