@font-face { font-family: "Comic Code"; src: url(fonts/ComicCode-Regular.ttf); font-weight: normal; } @font-face { font-family: "Comic Code"; src: url(fonts/ComicCode-Bold.ttf); font-weight: 700; } @font-face { font-family: "Comic Code"; src: url(fonts/ComicCode-Italic.ttf); font-weight: normal; font-style: italic; } @font-face { font-family: "Comic Code"; src: url(fonts/ComicCode-BoldItalic.ttf); font-weight: 700; font-style: italic; } * { box-sizing: border-box; } :-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background-color: #cad3f5; border: none; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background-color: #cad3f5; } * { scrollbar-width: thin; scrollbar-color: #cad3f5 transparent; } html, body { font-family: "Work Sans", sans-serif; font-size: 15px; background: #181926; color: #cad3f5; height: 100%; width: 100%; margin: 0; } body { display: flex; overflow: hidden; } #version { position: absolute; font-size: 12px; font-style: italic; top: 3px; right: 6px; color: #a5adcb; } #version a { color: #a5adcb; text-decoration: none; } body.loading #version { font-size: 0; animation: rotating 1.2s linear infinite; background-image: url(icons/spinner.svg); width: 16px; height: 16px; top: 6px; } #page { display: flex; flex-direction: column; gap: 5px; background: #1e2030; margin: auto; margin-top: 30px; width: 100%; max-width: 1200px; height: calc(100% - 30px); border-top-left-radius: 6px; border-top-right-radius: 6px; } .hidden { opacity: 0 !important; pointer-events: none !important; } .none { display: none !important; } #messages { display: flex; flex-direction: column; gap: 40px; height: 100%; overflow-y: auto; padding: 14px 12px; padding-bottom: 20px; } #messages:empty::before { content: "whiskr - no messages"; color: #a5adcb; font-style: italic; align-self: center; margin-top: 5px; } #message, .message { border: none; border-radius: 6px; background: #24273a; font: inherit; color: inherit; } .message { position: relative; max-width: 700px; min-width: 280px; width: max-content; padding-top: 28px; background: #363a4f; flex-shrink: 0; } .message::after { content: ""; position: absolute; pointer-events: none; background: rgba(237, 135, 150, 0.2); opacity: 0; left: 0; right: 0; top: 0; bottom: 0; transition: opacity 150ms; border-radius: 6px; } .message.marked::after { opacity: 1; } .message.user { align-self: end; } .message.system { align-self: center; } .message .role { position: absolute; display: flex; gap: 4px; align-items: center; font-family: "Comic Code", ui-monospace, "Cascadia Mono", "Segoe UI Mono", "Ubuntu Mono", "Roboto Mono", Menlo, Monaco, Consolas, monospace; font-size: 12px; line-height: 12px; top: 6px; left: 6px; } .statistics .provider::after, .statistics .ttft::after, .statistics .tps::after, .message .tags::before { content: ""; position: absolute; top: 7px; left: -10px; height: 2px; width: 6px; background: #939ab7; } .message .tags { display: flex; gap: 4px; position: relative; margin-left: 12px; } .message:not(.has-tags) .tags { display: none; } .message .tag-json { background-image: url(icons/json-mode.svg); } .message .tag-search { background-image: url(icons/search-tool.svg); } .message.user .role::before { background-image: url(icons/user.svg); } .message.system .role::before { background-image: url(icons/system.svg); } .message.assistant .role::before { background-image: url(icons/assistant.svg); } .message.assistant { max-width: 800px; } .message .reasoning, .message .tool, .message .text { display: block; background: transparent; padding: 10px 12px; width: 100%; } .message .reasoning { padding-top: 14px; } .message:not(.editing) textarea.text, .message.editing div.text { display: none; } .message .reasoning, .message .tool, .message div.text { background: #24273a; } .message textarea.text { background: #181926; min-width: 480px; min-height: 100px; } .message .text .error { color: #ed8796; } .message.errored { border: 2px solid #ed8796; } .reasoning-text pre { background: #1b1d2a; } .message .tool .result, .message .reasoning-text { background: #1e2030; border-radius: 6px; padding: 10px 12px; } .message .reasoning-wrapper { --height: auto; height: calc(var(--height) + 20px); overflow: hidden; transition: 150ms; } .message:not(.expanded) .reasoning-wrapper { height: 0; } .message.expanded .reasoning-text { margin-top: 10px; } .message.has-reasoning:not(.has-text):not(.errored) div.text, .message.has-tool:not(.has-text):not(.errored) div.text, .message.has-files:not(.has-text):not(.errored) div.text, .message:not(.has-tool) .tool, .message:not(.has-reasoning) .reasoning { display: none; } .message .body { border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; overflow: hidden; } .message.has-reasoning .text { padding-top: 4px; } .tool .call, .reasoning .toggle { position: relative; padding: 0 22px; padding-left: 26px; font-weight: 600; font-size: 14px; } .tool .call .name::after, .tool .call::before, .reasoning .toggle::after, .reasoning .toggle::before { content: ""; background-image: url(icons/reasoning.svg); position: absolute; top: -2px; left: -2px; width: 20px; height: 20px; } .tool .call .name::after, .reasoning .toggle::after { background-image: url(icons/chevron.svg); left: unset; right: -2px; transition: 150ms; } .message.expanded .reasoning .toggle::after { transform: rotate(180deg); } .message.has-tool .text { padding-bottom: 4px; } .message .tool { --height: 0px; overflow: hidden; transition: 150ms; height: calc(90px + var(--height)); } .message .tool:not(.expanded) { height: 62px; } .tool .call { display: flex; flex-direction: column; width: 100%; cursor: pointer; font-family: "Comic Code", ui-monospace, "Cascadia Mono", "Segoe UI Mono", "Ubuntu Mono", "Roboto Mono", Menlo, Monaco, Consolas, monospace; font-size: 13px; } .tool .call .arguments { font-style: italic; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .tool .call .name::after, .tool .call::before { top: 50%; transform: translateY(-50%); } .tool .call .name::after { right: -22px; } .tool.expanded .call .name::after { transform: translateY(-50%) rotate(180deg); } .tool .call::before { background-image: url(icons/tool.svg); } .tool .call .name { position: relative; width: max-content; } .message .tool .result { margin-top: 16px; } .message .options { display: flex; gap: 4px; position: absolute; top: 4px; right: 6px; opacity: 0; pointer-events: none; transition: 150ms; } .message:hover .options { opacity: 1; pointer-events: all; } .message.errored .options .copy, .message.errored .options .edit, .message.errored .options .retry, .message.waiting .options, .message.reasoning .options, .message.tooling .options, .message.receiving .options { display: none; } .message.reasoning .reasoning button.toggle::before { animation: rotating 1.2s linear infinite; background-image: url(icons/spinner.svg); top: -1px; width: 18px; height: 18px; } .message.tooling .tool .call::before { animation: rotating-y 1.2s linear infinite; background-image: url(icons/spinner.svg); width: 18px; height: 18px; } .message .text::before { font-style: italic; } .message:empty.receiving .text::before, .message.waiting .text::before { content: ". . ."; } .statistics { position: absolute; transition: 150ms; top: calc(100% + 5px); left: 8px; display: flex; align-items: center; gap: 20px; white-space: nowrap; font-size: 13px; line-height: 13px; pointer-events: none; } .statistics .provider, .statistics .ttft, .statistics .tps, .statistics .tokens { position: relative; display: flex; align-items: center; gap: 3px; } .statistics .provider::after, .statistics .ttft::after, .statistics .tps::after { left: unset; right: -14px; } .statistics .provider::before { background-image: url(icons/provider.svg); } .statistics .ttft::before { background-image: url(icons/ttft.svg); } .statistics .tps::before { background-image: url(icons/tps.svg); } .statistics .tokens::before { background-image: url(icons/amount.svg); } .message:not(:hover) .statistics { opacity: 0; } .message:not(.has-statistics) .statistics { display: none; } #chat { display: flex; position: relative; justify-content: center; padding: 0 12px; height: 320px; padding-bottom: 36px; } #chat::after { content: ""; position: absolute; bottom: 0; left: 12px; right: 12px; height: 36px; background: #24273a; } #chat:has(.has-files) { padding-top: 50px; } #attachments { position: absolute; top: 2px; left: 12px; } .files { display: flex; gap: 6px; } .files:not(.has-files) { display: none; } .message .files { background: #181926; padding: 10px 12px; } .files .file { position: relative; display: flex; gap: 4px; align-items: center; background: #24273a; box-shadow: 0px 0px 10px 6px rgba(0, 0, 0, 0.1); padding: 8px 10px; padding-right: 14px; border-radius: 6px; border: 1px solid #363a4f; } .files .file::before { content: ""; background-image: url(icons/file.svg); } .files .file button.remove { content: ""; position: absolute; background-image: url(icons/remove.svg); width: 16px; height: 16px; top: 1px; right: 1px; opacity: 0; transition: 150ms; } .files .file:hover button.remove { opacity: 1; } #message { border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; width: 100%; height: 100%; padding: 14px 16px; padding-bottom: 8px; } .dropdown, textarea, button, input, select { border: none; font: inherit; color: inherit; outline: none; margin: 0; } textarea { resize: none; font-size: 15px; line-height: 23px; } button { background: transparent; cursor: pointer; } input, select { background: #363a4f; padding: 2px 5px; font-size: 14px; } #chat button { position: absolute; } #chat .options { position: absolute; bottom: 6px; left: 20px; width: max-content; display: flex; align-items: center; gap: 12px; z-index: 10; } #chat .option { display: flex; align-items: center; gap: 4px; } #chat .option+.option::before { content: ""; display: block; width: 2px; height: 12px; background: #5b6078; margin-right: 4px; } body.loading #version, .modal.loading .content::after, .reasoning .toggle::before, .reasoning .toggle::after, #bottom, .files .file::before, .files .file .remove, .message .role::before, .message .tag-json, .message .tag-search, .message .copy, .message .edit, .message .retry, .message .delete, .pre-copy, .tool .call .name::after, .tool .call::before, .message .statistics .provider::before, .message .statistics .ttft::before, .message .statistics .tps::before, .message .statistics .tokens::before, #json, #search, #scrolling, #import, #export, #clear, #upload, #add, #send, #chat .option label { display: block; width: 20px; height: 20px; background-position: center; background-size: contain; background-repeat: no-repeat; } .message .statistics .provider::before, .message .statistics .ttft::before, .message .statistics .tps::before, .message .statistics .tokens::before, .message .tag-json, .message .tag-search, .message .role::before { content: ""; width: 16px; height: 16px; } input.invalid { border: 1px solid #ed8796; } .pre-copy, .message .copy { background-image: url(icons/copy.svg); } .pre-copy.copied, .message .copy.copied { background-image: url(icons/check.svg); } .message .retry { background-image: url(icons/retry.svg); } .message .edit { background-image: url(icons/edit.svg); } .message.editing .edit { background-image: url(icons/save.svg); } .message .delete { background-image: url(icons/delete.svg); } #chat .option label { background-size: 18px; } #model { width: 180px; padding: 2px 4px; } #reasoning-tokens, #temperature { appearance: textfield; width: 48px; padding: 2px 4px; text-align: right; } label[for="role"] { background-image: url(icons/user.svg); } label[for="model"] { background-image: url(icons/model.svg); } label[for="prompt"] { background-image: url(icons/prompt.svg); } label[for="temperature"] { background-image: url(icons/temperature.svg); } label[for="reasoning-effort"] { background-image: url(icons/reasoning.svg); } label[for="reasoning-tokens"] { background-image: url(icons/amount.svg); } #bottom { top: -38px; right: 20px; width: 28px; height: 28px; background-image: url(icons/down.svg); transition: 150ms; } #upload, #add, #send { bottom: 4px; right: 20px; width: 28px; height: 28px; background-image: url(icons/send.svg); z-index: 10; } #add { right: 52px; background-image: url(icons/add.svg); } #upload { right: 84px; background-image: url(icons/attach.svg); } #json, #search, #scrolling, #import, #export, #clear { position: unset !important; } #scrolling { background-image: url(icons/screen-slash.svg); } #scrolling.on { background-image: url(icons/screen.svg); } #json { background-image: url(icons/json-off.svg); } #json.on { background-image: url(icons/json-on.svg); } #search { background-image: url(icons/search-off.svg); } #search.on { background-image: url(icons/search-on.svg); } #import { background-image: url(icons/import.svg); } #export { background-image: url(icons/export.svg); } #clear { background-image: url(icons/trash.svg); } .completing #upload, .completing #add { display: none; } .completing #send { background-image: url(icons/stop.svg); } .modal .background, .modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 20; } .modal:not(.open) { display: none; } .modal .background { background: rgba(24, 25, 38, 0.25); backdrop-filter: blur(10px); } .modal .content, .modal .body { display: flex; flex-direction: column; gap: 6px; overflow: hidden; } .modal .content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); gap: 14px; background: #24273a; padding: 18px 20px; border-radius: 6px; box-shadow: 0px 0px 15px 5px rgba(0, 0, 0, 0.1); z-index: 30; } .modal .header { background: #363a4f; height: 42px; margin: -18px -20px; padding: 10px 20px; margin-bottom: 0; font-weight: 500; font-size: 18px; } .modal.loading .content::after, .modal.loading .content::before { content: ""; position: absolute; top: 42px; left: 0; z-index: 10; } .modal.loading .content::before { right: 0; bottom: 0; backdrop-filter: blur(4px); } .modal.loading .content::after { top: 85px; left: 50%; transform: translateX(-50%); animation: rotating 1.2s linear infinite; background-image: url(icons/spinner.svg); } .modal .error { background: #ed8796; font-weight: 500; font-style: italic; margin-bottom: 6px; font-size: 14px; color: #11111b; padding: 5px 10px; border-radius: 2px; } .modal:not(.errored) .error { display: none; } .modal.errored input { border: 1px solid #ed8796; } .modal .form-group { display: flex; gap: 6px; } .modal .form-group label { width: 80px; } .modal .form-group input { padding: 4px 6px; } .modal .buttons { display: flex; justify-content: end; } #login { background: #a6da95; color: #11111b; padding: 4px 10px; border-radius: 2px; font-weight: 500; transition: 150ms; } #login:hover { background: #89bb77; } @keyframes rotating { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes rotating-y { from { transform: translateY(-50%) rotate(0deg); } to { transform: translateY(-50%) rotate(360deg); } }