- Hooks ([[hooks]]): pre_tool, post_tool, user_prompt, stop; sandboxed, exit 2 blocks - @file mentions with autocomplete; mentioned files/folders are attached to the prompt - Session full-text search in the sidebar, fork into a copy, export as Markdown/JSON - Chat follows the newest message until the user scrolls up; jump-to-latest button - SVG activity spark and thinking icon instead of Unicode/emoji glyphs - File search ranks name matches first and returns relative paths Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2320 lines
40 KiB
CSS
2320 lines
40 KiB
CSS
/* 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 {
|
||
font-size: 11px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
color: var(--muted);
|
||
padding: 10px 8px 4px;
|
||
}
|
||
.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;
|
||
}
|
||
.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;
|
||
}
|
||
.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);
|
||
}
|