@font-face { font-family: "InterVariable"; src: local("Inter Variable"), local("InterVariable"), url("/fonts/inter/InterVariable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; } @font-face { font-family: "InterVariable"; src: local("Inter Variable Italic"), local("InterVariableItalic"), url("/fonts/inter/InterVariable-Italic.woff2") format("woff2"); font-weight: 100 900; font-style: italic; font-display: swap; } @supports (font-variation-settings: normal) { @font-face { font-family: "iocgnMonoVariable"; src: url("/fonts/iocgnMono/iocgnMono-Variable.woff2") format("woff2"); font-weight: 200 800; font-style: normal; font-display: swap; } } @font-face { font-family: "iocgnMono"; src: url("/fonts/iocgnMono/iocgnMono-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; } @font-face { font-family: "iocgnMono"; src: url("/fonts/iocgnMono/iocgnMono-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; } @font-face { font-family: "iocgnMono"; src: url("/fonts/iocgnMono/iocgnMono-SemiBold.woff2") format("woff2"); font-weight: 600; font-display: swap; } @font-face { font-family: "iocgnMono"; src: url("/fonts/iocgnMono/iocgnMono-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; } /* palette & syntax colours as sorcery's, lifted from char.lt */ :root { --bg: #100e11; --panel: #181419; --raised: #211a22; --text: #f3eef2; --muted: #958792; --accent: #ff9df5; --accent-fade: #ffd0fb; /* rules: --line between rows, --line-strong where structure divides */ --line: #493045; --line-strong: #b86caf; --hl-comment: #9da8bb; --hl-keyword: #9bedff; --hl-builtin: #ff94d1; --hl-string: #95ffc3; --hl-ident: #d8a8ff; --hl-number: var(--hl-string); --ok: var(--hl-string); /* the terminal palette's red and yellow, so a failure never reads as the accent */ --error: #fa5565; --warn: #fde965; --running: var(--accent); /* what a diff adds and removes */ --added: var(--ok); --removed: var(--hl-builtin); /* a chosen row, as a completion or the tree's focus; hover stays neutral, on --raised */ --selected: color-mix(in srgb, var(--accent) 18%, transparent); --selected-hover: color-mix(in srgb, var(--accent-fade) 18%, transparent); --selection: #6d3567; /* what floats over the page, and what dims it behind a dialog */ --shadow: 0 8px 24px rgb(0 0 0 / 0.4); --scrim: rgb(0 0 0 / 0.5); --mono: "iocgnMonoVariable", "iocgnMono", ui-monospace, "SF Mono", "Cascadia Code", monospace; /* type in even pixels, where iocgn Mono's half-em cells are whole */ --text-small: 12px; --text-ui: 14px; --text-body: 16px; --text-title: 20px; --text-display: 24px; /* a line 1.4 times its text, on the 4px grid: 12/16, 14/20, 16/24, 20/28, 24/32 */ --leading: round(nearest, 1.4em, 4px); /* space is in pixels on a 4px grid (2px where something only needs nudging); and the sidebar, the transcript's column (its text 48px narrower), and a finger's target */ --sidebar: 320px; --column: 800px; --target: 44px; color-scheme: dark; font-family: "InterVariable", "Inter", sans-serif; font-size: var(--text-body); text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; color: var(--text); background: var(--bg); scrollbar-color: var(--line) transparent; } * { box-sizing: border-box; } /* each element's own rather than inherited, so it holds whatever size the element's text is; a block takes more room with padding rather than a taller line */ *, ::before, ::after { line-height: var(--leading); } body { margin: 0; height: 100dvh; overflow: hidden; } ::selection { background-color: var(--selection); } [hidden] { display: none !important; } /* chrome links are bare and signal with colour; only prose underlines */ a { color: var(--accent); text-decoration: none; } a:hover { color: var(--accent-fade); } :where(button, input, select, textarea) { font: inherit; line-height: var(--leading); color: inherit; border-radius: 0; } input, select, textarea { background: var(--raised); border: 1px solid var(--line); padding: 4px 8px; } /* firefox lays a select's line out at its font's own height, so it would sit shorter than a field beside it */ select { height: calc(var(--leading) + 10px); } /* a button is the words for what it does, quiet until pointed at, and a form's main action is in the accent. at no specificity, so that a component's own buttons are what it says they are */ :where(button) { padding: 5px 0; background: none; border: 0; color: var(--muted); cursor: pointer; } :where(button:hover:not(:disabled)) { color: var(--accent); } :where(button.danger:hover:not(:disabled)) { color: var(--error); } :where(button.primary) { color: var(--accent); font-weight: 600; } :where(button.primary:hover:not(:disabled)) { color: var(--accent-fade); } /* a form's only action, alone beside its fields, takes an underline to aim at */ :where(button.primary:only-of-type) { color: var(--text); text-decoration: underline 2px var(--accent); text-underline-offset: 5px; } :where(button.primary:only-of-type:hover:not(:disabled)) { color: var(--accent); } :where(button:disabled) { opacity: 0.4; cursor: default; } :is(input, select, textarea):focus { outline: none; border-color: var(--line-strong); } :is(button, a, summary):focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; } input:is([type="checkbox"], [type="radio"]) { padding: 0; accent-color: var(--accent); } /* a button among words, as tall as they are */ :where(button.link) { padding: 0; } /* ioskeley-alike mono has a larger x-height than inter, so it sits a step down */ /* on an even pixel: 16 to 14, 14 to 12 */ pre, code, kbd { font-family: var(--mono); font-size: round(nearest, 0.875em, 2px); font-weight: 500; } pre { margin: 8px 0; padding: 8px 16px; background: var(--panel); border-left: 2px solid var(--line-strong); overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; } /* source, as sorcery's blob view: each line shares a grid row with its gutter, so wrapped source makes its row taller without displacing the gutter below */ pre.code { display: grid; grid-template-columns: max-content minmax(0, 1fr); padding: 8px 0; } pre.code.bare { grid-template-columns: minmax(0, 1fr); } .code-line { display: contents; } pre.code .ln { padding: 0 8px 0 12px; text-align: right; color: var(--muted); white-space: pre; user-select: none; border-right: 1px solid var(--line); } .code-text { min-width: 0; min-height: 1lh; padding: 0 16px; white-space: pre-wrap; overflow-wrap: anywhere; } /* syntax highlighting, as sorcery's and char.lt */ a-c, a-cd, a-er { color: var(--hl-comment); } a-k, a-kc, a-ko, a-kd, a-ke, a-kf, a-ki, a-kp, a-kr, a-kt, a-ky, a-km, a-dr, a-in, a-sc, a-rp, a-cn, a-ex, a-pp, a-co, a-cb, a-m, a-tu, a-tr { color: var(--hl-keyword); font-weight: 600; } /* builtins & types */ a-t, a-tb, a-tq, a-tf, a-fb { color: var(--hl-builtin); } a-s, a-ss, a-se, a-rx, a-ch, a-cs { color: var(--hl-string); } a-n { color: var(--hl-number); } a-f, a-fm, a-fd, a-fc, a-cr, a-ns, a-tg, a-td, a-at, a-pr, a-vm, a-l { color: var(--hl-ident); } a-da { color: var(--hl-string); } a-dd { color: var(--hl-comment); } a-em { font-style: italic; } a-st, a-tt { font-weight: 600; } a-tx { text-decoration: line-through; } /* a key, a step below code; its line is its own size, so a line of small hints keeps its height */ kbd { font-size: round(nearest, 0.75em, 2px); line-height: 1; background: var(--raised); border: 1px solid var(--line); padding: 0 4px; } time { font-variant-numeric: tabular-nums; } .error { color: var(--error); } /* an error's place takes no room until there is one */ .error:empty { display: none; } /* a chevron, as sorcery's diffs and chordpad's disclosures */ details > summary { list-style: none; cursor: pointer; } details > summary::-webkit-details-marker { display: none; } details > summary::before { content: ""; display: inline-block; position: relative; top: -0.25em; flex: none; width: 0.4em; height: 0.4em; margin-right: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); } details:not([open]) > summary::before { top: -0.05em; transform: rotate(-45deg); } /* login */ .login { display: flex; flex-direction: column; gap: 12px; width: 288px; margin: 30vh auto 0; } .login h1 { margin: 0; font-size: var(--text-display); font-weight: 520; } /* layout */ /* one grid: the bars share a row, so they share a height */ .app { display: grid; grid-template: "brand bar" auto "side pane" minmax(0, 1fr) / var(--sidebar) minmax(0, 1fr); height: 100dvh; } /* a view's bar and pane are the app's grid items */ .view { display: contents; } /* toolbars, as chordpad's */ .brand-bar, .bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 8px; padding: 8px 12px; background: var(--panel); border-bottom: 1px solid var(--line); font-size: var(--text-ui); } .brand-bar { grid-area: brand; gap: 8px; padding-left: 16px; border-right: 1px solid var(--line); } .bar { grid-area: bar; min-width: 0; } .bar-title { font-weight: 650; } .start-blank { margin-left: auto; } .pane { grid-area: pane; min-width: 0; min-height: 0; } /* an extension's view takes the main pane, and its conversation the sidebar's place */ .app.viewing { grid-template-columns: clamp(352px, 30vw, 544px) minmax(0, 1fr); } .app.viewing > .sidebar { display: none; } .app.viewing .pane.conversation { grid-area: side; border-right: 1px solid var(--line); } .extension-view { overflow: auto; } .view-missing { margin: 32px; color: var(--muted); } .view-links { display: inline-flex; gap: 8px; } .view-links a { color: var(--muted); } .view-links a:hover, .view-links a[aria-current="page"] { color: var(--accent); } .view-links a[aria-current="page"]:hover { color: var(--accent-fade); } .sidebar { grid-area: side; display: flex; flex-direction: column; min-height: 0; background: var(--panel); border-right: 1px solid var(--line); font-size: var(--text-ui); } .brand { flex: 1; font-size: var(--text-title); font-weight: 520; } .brand-bar a { color: var(--muted); } .brand-bar a:hover, .brand-bar a.active { color: var(--accent); } .brand-bar a.active:hover { color: var(--accent-fade); } /* hollow while the socket is down */ .dot { width: 7px; height: 7px; border: 1.5px solid var(--muted); border-radius: 50%; } .dot.up { border-color: var(--ok); background: var(--ok); } /* the way to a new conversation, at the top of the list */ .sidebar > .new { display: flex; align-items: baseline; padding: 8px 16px; border-bottom: 1px solid var(--line); } .sidebar > .new::before { content: "+"; width: 16px; color: var(--muted); } .sidebar > .new.active { background: var(--raised); box-shadow: inset 2px 0 var(--accent); } /* what the chosen extensions ask of a new conversation */ :is(.seed, .configuration, .project-picker) { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; border: 0; } :is(.seed, .configuration) legend { margin-bottom: 4px; padding: 0; color: var(--hl-ident); font-family: var(--mono); font-weight: 500; } :is(.seed, .configuration, .project-picker, .project-dialog, .system-prompt) .field { display: flex; flex-direction: column; gap: 2px; } :is(.seed, .configuration, .project-picker, .project-dialog, .system-prompt) .field > :is(span, label) { color: var(--muted); } :is(.seed, .configuration) .toggle { display: flex; gap: 4px; align-items: center; } /* a long list of choices, such as every model, scrolls rather than pushing the form away */ :is(.seed, .configuration) .choices { max-height: 160px; overflow-y: auto; margin: 0; padding: 4px 8px; border: 1px solid var(--line); } .toggles { display: flex; flex-wrap: wrap; gap: 4px 12px; } .toggles label { display: flex; gap: 4px; align-items: center; } /* rows carry their top edge, as sorcery's catalog; forks sit under their parents, a step in */ .conversations { overflow-y: auto; padding: 0 0 16px; } .conversations .item { position: relative; display: flex; align-items: center; /* a step of 16px puts a fork's text under its project's name */ padding-left: calc(var(--depth) * 16px); border-top: 1px solid var(--line); } .conversations .item:first-child { border-top: 0; } @media (hover: hover) { .conversations .item:hover { background: var(--raised); } } .conversations .item.active { background: var(--raised); box-shadow: inset 2px 0 var(--accent); } .conversations .item.active:hover { box-shadow: inset 2px 0 var(--accent-fade); } .conversations a { flex: 1; min-width: 0; display: flex; gap: 8px; align-items: baseline; padding: 4px 8px 4px 0; color: var(--text); } .conversations .item:not(.active, .unread):not(:has(.busy.on)) > a { opacity: 0.4; } .conversations .conversation-name { flex: 1; min-width: 0; width: 0; margin: 2px 8px 2px 0; } .conversations .conversation-name[aria-invalid="true"] { border-color: var(--error); } .conversations .item > .conversation-name:not([hidden]) ~ .archive { display: none; } .conversations .tid { font-family: var(--mono); font-weight: 500; color: var(--hl-ident); } .conversations .forks { color: var(--muted); font-variant-numeric: tabular-nums; } .conversations time { margin-left: auto; color: var(--muted); } .conversations .preview { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .conversations time, .conversations .forks { flex: none; } /* there while it answers */ .conversations .busy { display: none; flex: none; align-self: center; width: 6px; height: 6px; margin-left: auto; border-radius: 50%; background: var(--accent); } .conversations .busy:is(.on, .unread) { display: block; } .conversations .busy:is(.on, .unread) + time { margin-left: 0; } .conversations .busy.on { background: transparent; box-shadow: inset 0 0 0 1px var(--accent); } .conversations .item.unread .preview { font-weight: 600; } /* over the row's end, where its time is, while the pointer is on it */ .conversations .archive { display: none; position: absolute; top: 0; right: 0; bottom: 0; border: 0; padding: 0 8px 0 16px; background: linear-gradient(to right, transparent, var(--raised) 12px); color: var(--muted); font-size: var(--text-small); } @media (hover: hover) { .conversations .item:hover .archive { display: block; } } .conversations .archive:hover { color: var(--accent); } .conversations .conversation-actions { display: none; } /* a project's conversations under its name, which a little air sets apart */ .project-group { display: flex; align-items: baseline; border-top: 1px solid var(--line); } .project-group[data-drop="before"] { box-shadow: inset 0 2px var(--accent); } .project-group[data-drop="after"] { box-shadow: inset 0 -2px var(--accent); } .conversations > .project-group:first-child { border-top: 0; } .conversations .project-group + .item { border-top: 0; } .project-toggle { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; padding: 8px 8px 8px 16px; border: 0; background: none; text-align: left; color: var(--text); } /* the mark and the name line up with the new conversation's */ .project-toggle::before { margin-right: 0; color: var(--muted); } .project-toggle:hover::before { color: var(--accent); } .project-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; } .project-count { flex: none; color: var(--muted); font-variant-numeric: tabular-nums; } .conversations .project-toggle .busy { margin-left: 0; } .project-action { flex: none; width: 28px; padding: 8px 0 4px; font-size: var(--text-body); } @media (hover: hover) { .project-group:not(:hover, :focus-within) .project-action { visibility: hidden; } } /* a fork that left its parent's project, with the way back to it */ .conversations .item > .parent-link { flex: none; padding: 4px; color: var(--muted); } .conversations .item > .parent-link:hover { color: var(--accent); } .sidebar-footer { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: auto; padding: 8px 16px 12px; border-top: 1px solid var(--line); } /* the disclosures' chevron, on a button: a row is a link, which may not hold one */ .chevron { align-self: stretch; /* so a row's text starts on the sidebar's 16px line, under its project's chevron, hanging out from the name */ width: 16px; padding: 0; border: 0; background: none; color: var(--muted); } .chevron:disabled { visibility: hidden; } .chevron:hover { color: var(--accent); } /* a background subagent's mark, ahead of its name: delegated from the conversation above, which a chevron * on a nested row would not say */ .conversations .delegated { flex: none; color: var(--muted); } .chevron::before, .project-toggle::before, .tool-header::before { content: ""; flex: none; display: inline-block; position: relative; top: -0.17em; width: 0.4em; height: 0.4em; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); } .chevron[aria-expanded="false"]::before, .project-toggle[aria-expanded="false"]::before, .tool-header[aria-expanded="false"]::before { top: -0.05em; transform: rotate(-45deg); } /* a project's mark sits on the baseline rather than centred in a button, so it is raised to the capitals' middle */ .project-toggle::before { top: -0.27em; } .project-toggle[aria-expanded="false"]::before { top: -0.17em; } /* the list, from a view, on screens too narrow for both */ .back { display: none; grid-area: back; align-items: center; gap: 8px; padding: 0 8px 0 16px; background: var(--panel); border-bottom: 1px solid var(--line); color: var(--muted); } .back::before { content: ""; width: 8px; height: 8px; border-left: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); } /* another conversation has something new */ .back.unread::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); } .empty { display: grid; place-items: center; color: var(--muted); } .empty p { margin: 0; } /* a new conversation: where it works, how it thinks, and with what, from the top, so that options appearing below move nothing above them; and the composer that starts it, where a conversation's is */ .start-pane { display: flex; flex-direction: column; } .start { display: flex; flex-direction: column; gap: 24px; font-size: var(--text-ui); max-width: var(--column); margin: 0 auto; padding: 32px 24px; } .start-row { display: flex; flex-direction: column; gap: 8px; } .start-row > h3 { margin: 0; color: var(--muted); font-size: var(--text-ui); font-weight: 600; } .start-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; min-width: 0; } .start-hint { margin: 0; color: var(--muted); } .start-where:not(:has(.project-picker:not([hidden]), .start-environment:not(:empty))) { display: none; } /* a place is a line of fields, the folder taking what room is left */ .start :is(.project-picker, .start-environment, .start-environment .seed) { display: flex; flex-direction: row; flex-wrap: wrap; align-items: flex-end; gap: 12px; } .start-environment { flex: 1 1 320px; } .start-environment .seed { flex: 1; } .start-environment .field:has(.folder-input) { flex: 1 1 240px; } .start .model { max-width: 320px; } .start-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px 24px; width: 100%; } .start-options:empty, /* an extension's own view of its options, while it has nothing to ask */ .start-options > div:not(:has(> :not([hidden]))) { display: none; } /* conversation */ .conversation { display: flex; flex-direction: column; } .conversation-header :is(.model, .thinking-level) { font-size: var(--text-small); } .conversation-header .model { max-width: 320px; } /* the right-hand group moves to a second row as a unit, flush right wherever it lands */ .conversation-header .trailing { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; margin-left: auto; } .draft-header .spacer { flex: 1; } .draft-header .tid { font-family: var(--mono); font-weight: 500; color: var(--hl-ident); } .draft-header .note { color: var(--muted); } .extension-headers { display: inline-flex; align-items: center; gap: 8px; } .extension-headers > :empty, .extension-headers:not(:has(> :not(:empty, [hidden]))) { display: none; } .view-links, .extension-headers { font-size: var(--text-small); } .conversation-header .usage { color: var(--muted); font-family: var(--mono); font-variant-numeric: tabular-nums; } .conversation-header .usage .ctx-warn { color: var(--warn); } .conversation-header .usage .ctx-high { color: var(--error); } .conversation-header .extensions { position: relative; } .conversation-header .extensions > summary { color: var(--muted); } .conversation-header .extensions > summary:hover { color: var(--accent); } .conversation-header .extensions .extension-options { position: absolute; z-index: 2; top: calc(100% + 8px); left: 0; flex-direction: column; display: flex; gap: 8px; min-width: 288px; max-height: min(70vh, 576px); overflow-y: auto; padding: 8px 12px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); white-space: nowrap; } .extension-choice > label { display: flex; gap: 4px; align-items: center; } .extension-choice > label + .configuration { margin: 4px 0 0 20px; } .configuration-status { font-size: var(--text-small); white-space: normal; } .configuration-status:empty { display: none; } .scroller { container: transcript-pane / inline-size; flex: 1; min-height: 0; overflow-y: auto; /* the transcript keeps its place whether or not it is long enough to scroll */ scrollbar-gutter: stable both-edges; } /* takes no room after the transcript, and holds its button to the bottom of the view */ .jump-to-bottom { position: sticky; bottom: 0; height: 0; } .jump-to-bottom > button { position: absolute; bottom: 24px; /* in the margin just past the transcript's text where there is room, else at the pane's edge */ left: min(50% + var(--column) / 2 - 16px, 100% - var(--target) - 8px); width: var(--target); height: var(--target); padding: 0; font-size: var(--text-title); background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); } .jump-to-bottom > button::before { content: "↓"; } .jump-to-bottom > button:hover { border-color: var(--line-strong); color: var(--accent); } /* the transcript fades out above the composer, rather than stopping at its edge */ .pane.conversation > .scroller { mask-image: linear-gradient(to top, transparent, black 24px); } .transcript { max-width: var(--column); margin: 0 auto; padding: 16px 24px 32px; } .entries > * { contain: layout style; } /* which keeps their content's margins from collapsing through their own, so a message's content has none at its edges */ .message > .blocks > :first-child, .message > .blocks > :first-child > :first-child { margin-top: 0; } .message > .blocks > :last-child, .message > .blocks > :last-child > :last-child { margin-bottom: 0; } .message { position: relative; margin: 16px 0; } .message-time { display: block; margin-top: 4px; color: var(--muted); font-size: var(--text-small); line-height: 16px; white-space: nowrap; } @container transcript-pane (min-width: 960px) { .message-time { position: absolute; right: calc(100% + 12px); bottom: 4px; width: 80px; margin: 0; text-align: right; } .message.user > .message-time { bottom: 12px; } } .message.user { padding: 8px 16px; background: var(--panel); border-left: 2px solid var(--accent); } .message.user .text { white-space: pre-wrap; } .message .image { max-width: 100%; max-height: 320px; } .message .note { color: var(--muted); font-size: var(--text-ui); } .message > .error { font-size: var(--text-ui); } /* prose, as sorcery's readmes */ .markdown { overflow-wrap: anywhere; } .markdown > :first-child { margin-top: 0; } .markdown > :last-child { margin-bottom: 0; } .markdown a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; } .markdown :is(h1, h2, h3, h4) { font-weight: 650; line-height: round(nearest, 1.2em, 4px); margin: 24px 0 8px; } .markdown h1 { font-size: var(--text-display); } .markdown h2 { font-size: var(--text-title); } .markdown :is(h3, h4) { font-size: var(--text-body); } .markdown code { background: var(--panel); padding: 2px 4px; margin: 0 2px; } .markdown pre code { background: none; padding: 0; margin: 0; font-size: inherit; } .markdown blockquote { margin: 12px 0; padding-left: 16px; border-left: 2px solid var(--line-strong); color: var(--muted); } /* wide tables scroll rather than widen the transcript */ .markdown table { display: block; overflow-x: auto; border-collapse: collapse; } .markdown :is(th, td) { border: 1px solid var(--line); padding: 4px 8px; } .markdown img { max-width: 100%; } .thinking, .system { margin: 8px 0; color: var(--muted); font-size: var(--text-ui); } .thinking > summary:hover, .system > summary:hover { color: var(--accent); } .thinking .markdown { margin: 8px 0 0 16px; } .thinking-pending { margin: 8px 0; color: var(--muted); font-size: var(--text-ui); } .thinking-pending > span { display: inline-block; animation: thinking-wave 1s ease-in-out infinite alternate; } @keyframes thinking-wave { from { transform: translateY(0.18em); } to { transform: translateY(-0.18em); } } /* a flex row, so the groups sit beside the chevron rather than wrapping under it */ .system > summary { display: flex; align-items: baseline; } .system-label { margin-right: 12px; font-weight: 600; } .system-groups { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; align-items: baseline; min-width: 0; } .system-kind { text-align: right; } .system-name { font-family: var(--mono); white-space: nowrap; color: color-mix(in srgb, var(--text) 55%, var(--muted)); } .system h4 { margin: 8px 0 0; font-size: var(--text-small); font-weight: 650; } .event { margin: 8px 0; color: var(--muted); font-size: var(--text-ui); } .event .event-ext { margin-right: 8px; color: var(--hl-ident); } /* a background subagent's report: not a message, but what it was asked and how it ended */ .report { margin: 8px 0; padding: 8px 12px; border: 1px solid var(--line); font-size: var(--text-ui); } .report .subagent-meta { color: var(--muted); } .report-task { white-space: pre-wrap; overflow-wrap: anywhere; } .report .markdown { margin-top: 4px; } .divider { margin: 24px 0; padding-top: 8px; border-top: 1px solid var(--line-strong); color: var(--muted); font-size: var(--text-ui); text-align: center; } /* tool cards, as sorcery's file diffs */ .tool { position: relative; margin: 8px 0; border: 1px solid var(--line); } .tool + .tool { margin-top: 8px; } .tool-header { display: flex; align-items: baseline; gap: 8px; width: 100%; padding: 4px 12px; border: 0; border-bottom: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: var(--text-ui); text-align: left; } .tool-header:hover { color: var(--text); } /* a preview, faded where it is cut off, until the reader expands it */ .tool-preview { position: relative; } .tool[data-view="preview"] > .tool-preview { max-height: 120px; overflow: hidden; } .tool[data-view="closed"] > .tool-preview { display: none; } .tool[data-view="closed"] > .tool-header { border-bottom: 0; } .tool-blur { position: absolute; bottom: 0; left: 0; width: 100%; height: 64px; overflow: hidden; pointer-events: none; } .tool-blur > span { --blur: 1px; --start: 0%; --end: 40%; position: absolute; inset: 0; backdrop-filter: blur(var(--blur)); mask-image: linear-gradient(to bottom, transparent var(--start), black var(--end)); } .tool-blur > span:nth-child(2) { --blur: 2px; --start: 20%; --end: 60%; } .tool-blur > span:nth-child(3) { --blur: 4px; --start: 40%; --end: 80%; } .tool-blur > span:nth-child(4) { --blur: 8px; --start: 60%; --end: 100%; } .tool-more { position: absolute; inset: 0; display: flex; align-items: flex-end; justify-content: center; padding: 2px; border: 0; /* the label reads over the page rather than over the text it cuts off */ background: linear-gradient(to bottom, transparent 50%, var(--bg)); color: var(--muted); font-size: var(--text-small); } .tool-less { display: block; width: 100%; padding: 2px; border: 0; background: none; color: var(--muted); font-size: var(--text-small); } .tool-more:hover, .tool-less:hover { color: var(--accent); } .tool-images { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; padding: 12px; } .tool-images:empty { display: none; } .tool-name { font-family: var(--mono); font-weight: 600; color: var(--text); } .tool-summary { flex: 1; min-width: 0; font-family: var(--mono); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tool-status { font-variant-numeric: tabular-nums; } .tool-time { color: var(--muted); font-variant-numeric: tabular-nums; } .tool[data-status="ok"] > .tool-header .tool-status { color: var(--ok); } .tool[data-status="error"] > .tool-header .tool-status { color: var(--error); } .tool:is([data-status="running"], [data-status="streaming"], [data-status="pending"]) > .tool-header .tool-status { color: var(--running); } .tool:is([data-status="running"], [data-status="streaming"]) { border-color: var(--line-strong); } .tool-body { padding: 4px 12px 8px; } .tool-body pre { margin: 8px 0; } .tool-body .note { margin: 4px 0 0; color: var(--muted); font-size: var(--text-ui); } .tool-body pre.error { color: var(--error); border-left-color: var(--error); } /* a script's calls read as one list */ .nested { margin: 8px 0; } .nested > .tool, .nested > .tool + .tool { margin: 0; } .nested > .tool + .tool { border-top: 0; } .nested > .tool > .tool-header { background: none; } .subagent-meta { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; padding: 0 0 4px; font-size: var(--text-ui); } .subagent-meta .tid { margin-left: auto; } .subagent-history { max-height: 384px; overscroll-behavior: contain; border-top: 1px solid var(--line); } .subagent-history .transcript { padding: 0 4px 8px; } .codemode-text[data-view="preview"] > .tool-preview { max-height: 96px; } .codemode-text pre { margin: 0; border-left: 0; } /* composer */ .inbox { flex-shrink: 0; max-height: 35vh; overflow-y: auto; } .queued-content { white-space: pre-wrap; overflow-wrap: anywhere; } .queued-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0; } .queued-editor textarea { width: 100%; resize: vertical; min-height: 64px; } .queued-error { color: var(--error); overflow-wrap: anywhere; } .working { display: flex; align-items: center; flex-shrink: 0; gap: 8px; width: 100%; max-width: var(--column); margin: 0 auto; padding: 4px 24px; color: var(--muted); font-size: var(--text-ui); } .working-spinner { width: 12px; height: 12px; border: 2px solid var(--line); border-top-color: var(--running); border-radius: 50%; animation: working-spin 0.8s linear infinite; } @keyframes working-spin { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .working-spinner, .tree-entry[aria-busy="true"] .tree-row::after, .thinking-pending > span { animation: none; } } .inbox .queued { max-width: var(--column); margin: 0 auto; padding: 4px 24px; color: var(--muted); font-size: var(--text-ui); } /* a queued message keeps what can be done to it at its line's end */ .inbox .queued:has(> .queued-actions) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-items: baseline; } .inbox .queued > :is(.queued-editor, .queued-error) { grid-column: 1 / -1; } .inbox .queued > .queued-actions { margin: 0; } .inbox .queued > .queued-actions button { padding: 0; font-size: var(--text-small); } .inbox .mode { margin-right: 8px; color: var(--hl-ident); } .notice { align-self: center; width: calc(100% - 48px); max-width: calc(var(--column) - 48px); margin-bottom: 8px; padding: 8px 12px; background: var(--panel); border-left: 2px solid var(--line-strong); font-family: var(--mono); font-size: var(--text-small); white-space: pre-wrap; } .notice.error { border-left-color: var(--error); } .composer { position: relative; display: flex; flex-direction: column; gap: 4px; width: 100%; max-width: var(--column); margin: 0 auto; padding: 0 24px 12px; } .attachments { display: flex; gap: 8px; overflow-x: auto; padding: 4px 0; } .attachment { position: relative; flex: 0 0 112px; display: flex; flex-direction: column; gap: 4px; padding: 4px; border: 1px solid var(--line); background: var(--panel); font-size: var(--text-small); } .attachment img { width: 100%; height: 72px; object-fit: contain; } .attachment-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); } .attachment button { position: absolute; top: 0; right: 0; width: 28px; height: 28px; padding: 0; background: var(--panel); line-height: 1; } .attachment-status { overflow-wrap: anywhere; color: var(--muted); } .attachment[data-status="error"] { border-color: var(--error); } .attachment[data-status="error"] .attachment-status, .attachment-error { color: var(--error); font-size: var(--text-small); } .composer-input { display: flex; /* a one-row text area is shorter than the controls, and its text should sit centered against them */ align-items: center; gap: 8px; padding: 4px; background: var(--panel); border: 1px solid var(--line); } .composer-input:focus-within { border-color: var(--line-strong); } .composer-input.stacked { flex-direction: column; align-items: stretch; gap: 0; } .composer-controls { display: none; flex: none; align-self: flex-end; gap: 8px; } .composer-input:has(.abort:not([hidden])) .composer-controls { display: flex; } .composer-input .abort { flex: none; display: grid; place-items: center; width: var(--target); height: var(--target); padding: 0; background: var(--panel); border: 1px solid var(--line); color: var(--muted); } .composer-input .abort::before { content: ""; width: 10px; height: 10px; background: currentColor; border-radius: 1px; } .composer-input .abort:hover:not(:disabled) { border-color: var(--error); color: var(--error); } .composer textarea { flex: 1; min-width: 0; resize: none; max-height: 40vh; padding: 8px 8px; border: 0; background: none; } .composer textarea.shell { font-family: var(--mono); } .composer-input.stacked textarea { flex: none; width: 100%; } /* the keys' work, for screens without them */ .composer .actions { display: none; flex: none; gap: 8px; } /* a finger's targets, so boxes */ .composer .actions button { height: var(--target); padding: 4px 12px; border: 1px solid var(--line); white-space: nowrap; } .composer .actions :is(.primary, .send-more) { border-color: var(--accent); } .composer .actions .send { width: var(--target); padding: 0; font-size: 0; } .composer .actions .send::before { content: "↑"; font-size: var(--text-title); } .send-options { position: relative; display: flex; } .composer .actions .send-more { width: var(--target); padding: 0; border-left: 0; } .composer .actions .send-more[aria-expanded="true"] { color: var(--accent); } .send-menu { position: absolute; z-index: 3; right: 0; bottom: calc(100% + 8px); min-width: 160px; padding: 4px; background: var(--panel); border: 1px solid var(--line-strong); box-shadow: var(--shadow); } .composer .actions .send-menu button { display: block; width: 100%; border: 0; background: none; text-align: left; } .composer .actions .send-menu button:hover { background: var(--raised); color: var(--accent); } /* keys and what they do, as chordpad's */ .hints { display: flex; flex-wrap: wrap; gap: 2px 16px; color: var(--muted); font-size: var(--text-small); } .hints kbd + kbd { margin-left: 2px; } .suggestions { position: absolute; bottom: calc(100% - 4px); left: 24px; right: 24px; z-index: 2; max-height: 288px; overflow-y: auto; display: flex; flex-direction: column; padding: 4px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); } .suggestions button { display: flex; gap: 16px; align-items: center; border: 0; background: none; padding: 4px 12px; text-align: left; } .suggestions button:hover { background: var(--raised); } .suggestions button.selected { background: var(--selected); } .suggestions button.selected:hover { background: var(--selected-hover); } .suggestions .command { flex: none; max-width: 50%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-weight: 600; color: var(--text); } .suggestions .description { min-width: 0; overflow-wrap: anywhere; color: var(--muted); font-size: var(--text-ui); } /* a folder field's completions, as the composer's */ .folder-input { position: relative; } .folder-input > input { width: 100%; } .folder-menu { position: absolute; z-index: 20; top: calc(100% + 2px); left: 0; right: 0; max-height: 240px; overflow-y: auto; padding: 4px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow); white-space: normal; } /* in the bar's options, which scroll, they push down what follows rather than scroll within */ .extension-options .folder-menu { position: static; margin-top: 2px; box-shadow: none; } .folder-options { display: flex; flex-direction: column; } .folder-options > button { display: flex; gap: 12px; align-items: baseline; border: 0; background: none; padding: 4px 8px; text-align: left; color: var(--text); } .folder-options > button:hover { background: var(--raised); } .folder-options > button[aria-selected="true"] { background: var(--selected); } .folder-options > button[aria-selected="true"]:hover { background: var(--selected-hover); } .folder-path { flex: 1; min-width: 0; overflow-wrap: anywhere; } .folder-project { flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--text-small); } .folder-status { margin: 0; padding: 4px 8px; color: var(--muted); font-size: var(--text-small); overflow-wrap: anywhere; } .folder-status:empty { display: none; } /* settings, as sorcery's pages: a heading, a description, rows that carry their top edge */ /* the pane scrolls; its content is centred by padding, so the scrollbar stays at the edge */ .settings { overflow-y: auto; padding: 8px max(24px, calc((100% - var(--column)) / 2 + 24px)) 64px; } .settings h2 { margin: 24px 0 4px; font-size: var(--text-title); font-weight: 650; } .settings .desc { margin: 0 0 12px; color: var(--muted); } .settings > fieldset { border: 0; padding: 0; margin: 0; min-width: 0; } .system-prompt { display: flex; flex-direction: column; gap: 12px; } .system-prompt textarea { field-sizing: content; min-height: 2lh; resize: none; } .system-prompt :is(input, textarea) { background: transparent; } .settings .filter { width: 100%; margin-bottom: 8px; } .settings .desc kbd { margin: 0 1px; } /* the enabled models, in order: rows with a grip, as chordpad's tracks are dragged by their heads */ .enabled-list { margin: 0 0 16px; padding: 0; list-style: none; border-bottom: 1px solid var(--line); } .enabled-list .model-row { grid-template-columns: auto auto 240px minmax(0, 1fr) 240px; cursor: grab; } .enabled-list .model-row:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; } .grip { align-self: center; /* a touch on it drags the row, rather than scrolling the page */ touch-action: none; width: 7px; height: 12px; background-image: radial-gradient(circle, var(--muted) 1px, transparent 1.4px); background-size: 4px 4px; } .model-row:hover .grip { background-image: radial-gradient(circle, var(--accent) 1px, transparent 1.4px); } .model-row.dragging { opacity: 0.4; } /* keep the grabbing cursor wherever the drag goes, as chordpad does */ body.reordering, body.reordering * { cursor: grabbing !important; user-select: none; } /* where the row lands, as chordpad's reorder line */ .model-row.drop-before { box-shadow: inset 0 2px var(--accent); } .model-row.drop-after { box-shadow: inset 0 -2px var(--accent); } .provider { margin-top: 8px; } .provider > summary { padding: 4px 0; font-weight: 650; } .provider > summary:hover { color: var(--accent); } .provider .count { margin-left: 12px; color: var(--muted); font-size: var(--text-ui); font-weight: 400; } /* fixed, not auto: each row is its own grid, so its columns line up only at fixed widths, as sorcery's catalog */ .model-row { display: grid; grid-template-columns: auto 240px minmax(0, 1fr) 240px; gap: 12px; align-items: baseline; padding: 4px 8px; border-top: 1px solid var(--line); cursor: pointer; } .model-row:hover { background: var(--panel); } .notify-row { display: flex; gap: 12px; align-items: center; padding: 4px 8px; border-top: 1px solid var(--line); cursor: pointer; } .notify-row:hover { background: var(--panel); } .model-row code { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* small circle separators between segments, as sorcery's */ .model-meta { display: inline-flex; justify-content: flex-end; align-items: center; gap: 8px; color: var(--muted); font-size: var(--text-small); font-variant-numeric: tabular-nums; white-space: nowrap; } .model-meta > span { display: inline-flex; align-items: center; } .model-meta > span + span::before { content: ""; width: 3px; height: 3px; margin-right: 8px; border: 1.5px solid var(--muted); border-radius: 50%; background: var(--muted); } .ok { color: var(--ok); } /* providers, as the model rows */ .provider-list { margin-bottom: 8px; border-bottom: 1px solid var(--line); } .provider-row { display: grid; grid-template-columns: 240px minmax(0, 1fr) auto auto; gap: 12px; align-items: center; padding: 4px 8px; border-top: 1px solid var(--line); } .provider-list > .provider-row:first-child { border-top: 0; } .provider-row code { color: var(--muted); } .provider-row .actions { display: flex; justify-content: flex-end; gap: 8px; } /* a row's action is a button, so it takes a box rather than sitting as a bare word among the row's labels */ .provider-row button { padding: 2px 8px; background: var(--raised); border: 1px solid var(--line); color: var(--text); font-size: var(--text-small); } .provider-row button:hover:not(:disabled) { border-color: var(--line-strong); color: var(--accent); } .provider-row button.danger:hover:not(:disabled) { color: var(--error); } .provider-list > .provider { margin: 4px 0; } /* dialogs, as chordpad's */ .dialog { width: min(560px, 90vw); padding: 16px; color: var(--text); background: var(--panel); border: 1px solid var(--line); } .dialog::backdrop { background: var(--scrim); } .dialog h2 { margin: 0; font-size: var(--text-title); font-weight: 650; } .dialog .desc { margin: 4px 0 12px; color: var(--muted); } .dialog p { margin: 8px 0; overflow-wrap: anywhere; } .dialog .user-code { padding: 2px 8px; font-size: var(--text-display); letter-spacing: 0.1em; color: var(--accent); } .dialog .question { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; } .dialog input.secret { -webkit-text-security: disc; } /* one of several answers, which a box keeps together */ .dialog .question .option { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 12px; background: var(--raised); border: 1px solid var(--line); color: var(--text); text-align: left; } .dialog .question .option:hover { border-color: var(--line-strong); } .dialog .question .option span { color: var(--muted); font-size: var(--text-ui); } .dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; } .dialog .question .primary { align-self: flex-end; } /* a project: its name, then its workspaces a row each, the marked one where new conversations start; unclipped, so a folder's completions can hang below it */ .project-dialog { overflow: visible; } .project-controls { display: flex; flex-direction: column; gap: 12px; min-width: 0; margin: 12px 0 0; padding: 0; border: 0; } .project-details { display: flex; flex-direction: column; gap: 12px; } .project-dialog-header { display: flex; justify-content: space-between; align-items: baseline; } .project-order .link { width: 32px; font-size: var(--text-body); } .project-dialog .desc { margin: 0 0 4px; } .project-roots { display: flex; flex-direction: column; gap: 8px; } .project-root { display: grid; grid-template-columns: auto auto minmax(0, 1fr) 24px; gap: 8px; align-items: center; } .project-root > .link { align-self: stretch; font-size: var(--text-body); } .project-root > .link:disabled { visibility: hidden; } .project-roots + .link { align-self: flex-start; margin-top: 2px; } .project-dialog .error { margin: 0; } .project-dialog .dialog-actions { margin-top: 4px; } .project-delete { margin-right: auto; } /* where a move along the tree went: the notice's column, the tree's row */ .continuation { display: flex; align-items: baseline; gap: 8px; align-self: center; width: calc(100% - 48px); max-width: calc(var(--column) - 48px); margin-bottom: 8px; padding: 4px 4px 4px 12px; background: var(--panel); border-left: 2px solid var(--accent); font-size: var(--text-ui); } .continuation .point { display: flex; align-items: baseline; gap: 8px; flex: 1; min-width: 0; white-space: nowrap; } .continuation :is(.verb, .label) { flex: none; color: var(--muted); } .continuation .text { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .continuation button { flex: none; padding: 0 8px; } /* the tree: one line per entry, tree(1)'s rules in the mono face so they meet */ .tree-dialog { width: min(960px, 94vw); } .tree-filters { display: flex; gap: 12px; margin-bottom: 8px; } .tree-filters label { display: flex; gap: 4px; align-items: center; } .tree-rows { display: flex; flex-direction: column; max-height: 65vh; overflow-y: auto; margin-bottom: 8px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); font-size: var(--text-ui); } .tree-entry { display: flex; align-items: baseline; flex: none; } .tree-regenerate { flex: none; margin: 2px 4px; padding: 0 4px; font-size: var(--text-small); } .tree-row { display: flex; align-items: baseline; flex: 1; min-width: 0; padding: 0 8px; border: 0; background: none; text-align: left; white-space: nowrap; padding-block: 2px; color: var(--text); } .tree-row:hover { background: var(--raised); } .tree-row:focus { outline: none; background: var(--selected); } .tree-row:focus:hover { background: var(--selected-hover); } .tree-row .lead { font-family: var(--mono); white-space: pre; color: var(--line-strong); } .tree-row .label { flex: none; margin-right: 8px; color: var(--muted); } :is(.tree-row, .continuation)[data-kind="pi.user"] .label { color: var(--accent); } :is(.tree-row, .continuation)[data-kind="pi.assistant"] .label { color: var(--ok); } .tree-row[data-error="true"] .text { color: var(--error); } .tree-row:not([data-kind="pi.user"], [data-kind="pi.assistant"]) .text { color: var(--muted); } .tree-row .text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; } .tree-row.here .text { font-weight: 600; } .tree-row .branch { flex: none; margin-left: 8px; padding: 0 4px; border: 1px solid var(--line); color: var(--muted); font-size: var(--text-small); } .tree-entry .time { flex: none; margin: 0 8px; color: var(--muted); font-size: var(--text-small); font-variant-numeric: tabular-nums; } .tree-row .branch.current { border-color: var(--accent); color: var(--accent); } .tree-rows:has([aria-busy="true"]) { cursor: progress; } .tree-entry[aria-busy="true"] .tree-row::after { content: ""; flex: none; align-self: center; width: 12px; height: 12px; margin-left: 8px; border: 2px solid var(--line); border-top-color: var(--running); border-radius: 50%; animation: working-spin 0.8s linear infinite; } .dialog .tree-error { margin: 0 0 8px; color: var(--error); } /* environments, as the providers, with a form for another */ .environments { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) auto; column-gap: 8px; } .environment-list, .environment-row, .environment-form { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; align-items: center; } .environment-row { padding: 4px 0; } .environment-row + .environment-row { border-top: 1px solid var(--line); } .environment-row > :is(span, code), .environment-form input { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .environment-row code { color: var(--muted); } .environment-row button { padding: 2px 0; font-size: var(--text-small); } .environment-form { margin: 8px 0; } .environments > :is(.local-environment, .desc, .error) { grid-column: 1 / -1; } .local-environment { display: flex; gap: 4px; align-items: center; cursor: pointer; } .environments > .desc { margin: 2px 0 12px; } /* extensions, as the providers, but one grid so that the names take only the room they need */ .extension-list { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto auto; column-gap: 12px; } .extension, .extension .provider-row { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; } .extension + .extension { border-top: 1px solid var(--line); } .extension .provider-row { grid-template-areas: "name description timing status actions" "name directory timing status actions"; border-top: 0; row-gap: 0; } .extension .provider-row > .model-name { grid-area: name; } .extension .provider-row > .description { grid-area: description; } .extension .provider-row > :is(.ok, .error) { grid-area: status; } .extension .provider-row > .actions { grid-area: actions; } .extension .provider-row > :is(.description, code) { overflow: hidden; color: var(--muted); text-overflow: ellipsis; white-space: nowrap; } .extension .provider-row > code { grid-area: directory; font-size: var(--text-small); opacity: 0.8; } .extension-startup { grid-area: timing; color: var(--muted); font-size: var(--text-small); } .extension-startup > summary { cursor: pointer; white-space: nowrap; } .extension-startup dl { display: grid; grid-template-columns: auto auto; gap: 4px 12px; margin: 8px 0; } .extension-startup dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; } .extension pre.error { grid-column: 1 / -1; margin: 0 8px 8px; border-left-color: var(--error); max-height: 256px; overflow-y: auto; } /* an extension's editable prose, collapsed so long defaults don't dominate the list */ .extension > details { grid-column: 1 / -1; margin: 0 8px 8px; } .extension > details > summary { cursor: pointer; color: var(--muted); } .extension .system-prompt textarea { width: 100%; resize: vertical; } /* touch screens: room for fingers, and no hover to reveal things */ @media (pointer: coarse) { .conversations a { padding-top: 8px; padding-bottom: 8px; user-select: none; } .chevron { width: 36px; } .tool-header { padding-top: 8px; padding-bottom: 8px; } .tool-more { padding: 8px; } .grip { padding: 0 8px; background-clip: content-box; } .tree-row { padding-block: 8px; } .composer-controls, .composer .actions { display: flex; } .hints { display: none; } } @media (pointer: coarse), (hover: none) { .conversations .item { flex-wrap: wrap; padding-right: var(--target); touch-action: manipulation; } .conversations .archive { display: none; } .project-action { width: var(--target); } .conversations .conversation-actions { display: block; flex-basis: 100%; min-width: 0; } .conversations .conversation-actions > summary { position: absolute; top: 0; right: 0; display: flex; align-items: center; justify-content: center; width: var(--target); min-height: var(--target); color: var(--muted); font-size: var(--text-title); } .conversations .conversation-actions > summary::before { content: none; } .conversations .conversation-menu { display: flex; gap: 16px; padding: 0 8px 8px 36px; } .conversations .conversation-menu button { min-height: var(--target); } .conversations .conversation-name { font-size: var(--text-body); min-height: var(--target); } } /* narrow screens: the list, or a view, with a way back to the list */ @media (max-width: 700px) { .app { grid-template: "back bar" auto "pane pane" minmax(0, 1fr) / auto minmax(0, 1fr); } .app.listing { grid-template: "brand" auto "side" minmax(0, 1fr) / minmax(0, 1fr); } .app.listing > :is(.view, .back), .app:not(.listing) > :is(.brand-bar, .sidebar) { display: none; } /* the view alone; its link in the bar goes back to the conversation */ .app.viewing { grid-template-columns: auto minmax(0, 1fr); } .app.viewing .pane.conversation { display: none; } .back { display: flex; } .brand-bar, .sidebar { border-right: 0; } /* the extensions' options drop below the whole bar */ .bar { position: relative; } .conversation-header > label { display: none; } .conversation-header > label + :is(input, select) { margin-right: 0; } .conversation-header .model { flex: 1 1 112px; min-width: 0; } .conversation-header .extensions { position: static; } .conversation-header .extensions .extension-options { left: 8px; right: 8px; min-width: 0; white-space: normal; } .transcript { padding: 8px 12px 24px; } .start { padding: 24px 12px; } .message.user { padding: 8px 12px; } pre { padding: 8px 12px; } pre.code .ln { padding: 0 8px 0 8px; } .code-text { padding: 0 8px; } .tool-header { padding-left: 8px; padding-right: 8px; } .tool-body { padding: 4px 8px 8px; } .inbox .queued { padding: 4px 12px; } .working { padding: 4px 12px; } .notice, .continuation { width: calc(100% - 24px); } .composer { padding: 0 12px 8px; } .suggestions { left: 12px; right: 12px; } /* settings' rows put their ids on a line of their own */ .settings { padding: 8px 12px 48px; } .model-row { grid-template-columns: auto minmax(0, 1fr) auto; row-gap: 0; } .enabled-list .model-row { grid-template-columns: auto auto minmax(0, 1fr) auto; } .model-row code { grid-row: 2; grid-column: -3 / -1; } .provider-row { grid-template-columns: minmax(0, 1fr) auto auto; row-gap: 0; } .provider-row > :is(code, .description) { grid-row: 2; grid-column: 1 / -1; } .extension-list { grid-template-columns: minmax(0, 1fr) auto auto; } .extension .provider-row { grid-template-areas: "name status actions" "description description description" "directory directory directory" "timing timing timing"; } }