6ee4087a29
- Centralize `useAgents` and `useModels` state within the Nuxt app context to prevent data leaks and improve initialization. - Migrate virtualization from `vue-virtual-scroller` to `@tanstack/vue-virtual` with new `RowVirtualizerFixed` and `RowVirtualizerDynamic` components. - Upgrade Nuxt to v4.3.1 and remove `@vue-macros/nuxt`. - Replace `big.js` with an optimized custom `lshDecimal` string manipulation logic for pricing calculations in the provider API. - Implement automatic focus redirection in `ChatInput` to capture standard keyboard input. - Refactor Sidenav and Settings components to utilize virtualization for long lists (topics, agents, models). - Enhance theme colors and mobile experience. More work to come on both of these.
475 lines
13 KiB
CSS
475 lines
13 KiB
CSS
:root {
|
|
--spacing: 0.25rem;
|
|
|
|
--color-accent-text: #232625;
|
|
|
|
--reasoning-accent: #a62bcb;
|
|
|
|
/* Accent Color Options */
|
|
|
|
/* violet (current default) */
|
|
--accent-violet: #a010ff;
|
|
--accent-violet-hover: #8d00e8;
|
|
|
|
/* volcanic heat - orange-red */
|
|
--accent-volcano: #ef4410;
|
|
--accent-volcano-hover: #dc2626;
|
|
|
|
/* neon lime */
|
|
--accent-lime: #29e154;
|
|
--accent-lime-hover: #53e475;
|
|
|
|
/* electric sky */
|
|
--accent-sky: #38d3fa;
|
|
--accent-sky-hover: #2bc7ee;
|
|
|
|
/* crushed coral - warm pink-orange */
|
|
--accent-coral: #ff6b6b;
|
|
--accent-coral-hover: #e55555;
|
|
|
|
/* deep emerald - rich green */
|
|
--accent-emerald: #10b981;
|
|
--accent-emerald-hover: #059669;
|
|
|
|
/* golden hour - warm amber */
|
|
--accent-amber: #f59e0b;
|
|
--accent-amber-hover: #d97706;
|
|
|
|
/* rose quartz - soft pink-red */
|
|
--accent-rose: #f43f5e;
|
|
--accent-rose-hover: #e11d48;
|
|
|
|
/* arctic cyan - crisp blue */
|
|
--accent-cyan: #06b6d4;
|
|
--accent-cyan-hover: #0891b2;
|
|
|
|
/* midnight indigo - deep blue-purple */
|
|
--accent-indigo: #6366f1;
|
|
--accent-indigo-hover: #4f46e5;
|
|
|
|
/* sunset magenta - vibrant pink-purple */
|
|
--accent-magenta: #ec4899;
|
|
--accent-magenta-hover: #db2777;
|
|
|
|
--bg-base: color-mix(in srgb, var(--neutral-100), var(--color-accent) var(--accent-hinting));
|
|
--bg-surface: color-mix(in srgb, var(--neutral-200), var(--color-accent) var(--accent-hinting));
|
|
--bg-container: color-mix(in srgb, var(--neutral-300), var(--color-accent) var(--accent-hinting));
|
|
}
|
|
|
|
:root.dark {
|
|
--palette-zinc-100: #09080D;
|
|
--palette-zinc-200: #1a191E;
|
|
--palette-zinc-300: #2e2d32;
|
|
--palette-slate-100: #0f171c;
|
|
--palette-slate-200: #1e252b;
|
|
--palette-slate-300: #333b44;
|
|
--palette-obsidian-100: #050307;
|
|
--palette-obsidian-200: #0f0e11;
|
|
--palette-obsidian-300: #1e1d20;
|
|
|
|
--text-primary: color-mix(in srgb, #fafafa, var(--color-accent) var(--accent-hinting));
|
|
/* Selected topics */
|
|
--text-secondary: color-mix(in srgb, #a1a1aa, var(--color-accent) var(--accent-hinting));
|
|
/* Selected topics */
|
|
--text-tertiary: color-mix(in srgb, #71717a, var(--color-accent) var(--accent-hinting));
|
|
/* Tokens/s, Info */
|
|
--text-dim: color-mix(in srgb, #52525b, var(--color-accent) var(--accent-hinting));
|
|
/* Unselected/Disabled */
|
|
|
|
--color-hover: color-mix(in srgb, rgba(255, 255, 255, 0.08), var(--color-accent) var(--accent-hinting));
|
|
--color-active: color-mix(in srgb, rgba(255, 255, 255, 0.12), var(--color-accent) var(--accent-hinting));
|
|
|
|
--color-border: color-mix(in srgb, rgba(255, 255, 255, 0.1), var(--color-accent) var(--accent-hinting));
|
|
--color-border-active: color-mix(in srgb, rgba(255, 255, 255, 0.16), var(--color-accent) var(--accent-hinting));
|
|
}
|
|
|
|
:root.light {
|
|
/* --palette-zinc-100: #f4f4f5; --palette-zinc-200: #e4e4e7; --palette-zinc-300: #d4d4d8;
|
|
--palette-slate-100: #f1f5f9; --palette-slate-200: #e2e8f0; --palette-slate-300: #cbd5e1;
|
|
--palette-obsidian-100: #fafafa; --palette-obsidian-200: #f5f5f5; --palette-obsidian-300: #e5e5e5; */
|
|
--palette-zinc-100: #d4d4d8;
|
|
--palette-zinc-200: #e4e4e7;
|
|
--palette-zinc-300: #f4f4f5;
|
|
--palette-slate-100: #cbd5e1;
|
|
--palette-slate-200: #e2e8f0;
|
|
--palette-slate-300: #f1f5f9;
|
|
--palette-obsidian-100: #e5e5e5;
|
|
--palette-obsidian-200: #ededed;
|
|
--palette-obsidian-300: #fcfcfc;
|
|
|
|
--text-primary: color-mix(in srgb, #09090b, var(--color-accent) var(--accent-hinting));
|
|
--text-secondary: color-mix(in srgb, #52525b, var(--color-accent) var(--accent-hinting));
|
|
--text-tertiary: color-mix(in srgb, #71717a, var(--color-accent) var(--accent-hinting));
|
|
--text-dim: color-mix(in srgb, #a1a1aa, var(--color-accent) var(--accent-hinting));
|
|
|
|
--color-hover: color-mix(in srgb, rgba(0, 0, 0, 0.08), var(--color-accent) var(--accent-hinting));
|
|
--color-active: color-mix(in srgb, rgba(0, 0, 0, 0.12), var(--color-accent) var(--accent-hinting));
|
|
|
|
--color-border: color-mix(in srgb, rgba(0, 0, 0, 0.08), var(--color-accent) var(--accent-hinting));
|
|
--color-border-active: color-mix(in srgb, rgba(0, 0, 0, 0.14), var(--color-accent) var(--accent-hinting));
|
|
}
|
|
|
|
/* :root.dark {
|
|
--neutral-zinc: color-mix(in srgb, var(--base-hinting) #171619, var(--accent-hinting) var(--color-accent));
|
|
--neutral-charcoal: color-mix(in srgb, var(--base-hinting) #0a0a0a, var(--accent-hinting) var(--color-accent));
|
|
|
|
--color-base: color-mix(in srgb, var(--base-hinting) #040305, var(--accent-hinting) var(--color-accent));
|
|
--color-highlight-low: color-mix(in srgb,
|
|
var(--base-hinting) rgba(255, 255, 255, 0.05),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-highlight: color-mix(in srgb,
|
|
var(--base-hinting) rgba(255, 255, 255, 0.1),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-highlight-high: color-mix(in srgb,
|
|
var(--base-hinting) rgba(255, 255, 255, 0.15),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-text: color-mix(in srgb, var(--base-hinting) #fafafa, var(--accent-hinting) var(--color-accent));
|
|
--color-muted: color-mix(in srgb, var(--base-hinting) #a1a1a0, var(--accent-hinting) var(--color-accent));
|
|
--color-subtle: color-mix(in srgb, var(--base-hinting) #d1d1d0, var(--accent-hinting) var(--color-accent));
|
|
--color-input: color-mix(in srgb, var(--base-hinting) #222124, var(--accent-hinting) var(--color-accent));
|
|
--color-reasoning: color-mix(in srgb, var(--base-hinting) #66666a, var(--accent-hinting) var(--color-accent));
|
|
}
|
|
|
|
:root.light {
|
|
--neutral-zinc: color-mix(in srgb, var(--base-hinting) #fbfafd, var(--accent-hinting) var(--color-accent));
|
|
--neutral-charcoal: color-mix(in srgb, var(--base-hinting) #fefdff, var(--accent-hinting) var(--color-accent));
|
|
|
|
--color-base: color-mix(in srgb, var(--base-hinting) #f2f0f0, var(--accent-hinting) var(--color-accent));
|
|
--color-highlight-low: color-mix(in srgb,
|
|
var(--base-hinting) rgba(0, 0, 0, 0.06),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-highlight: color-mix(in srgb,
|
|
var(--base-hinting) rgba(0, 0, 0, 0.08),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-highlight-high: color-mix(in srgb,
|
|
var(--base-hinting) rgba(0, 0, 0, 0.13),
|
|
var(--accent-hinting) var(--color-accent));
|
|
--color-text: color-mix(in srgb, var(--base-hinting) #1a1a1a, var(--accent-hinting) var(--color-accent));
|
|
--color-muted: color-mix(in srgb, var(--base-hinting) #6b7270, var(--accent-hinting) var(--color-accent));
|
|
--color-subtle: color-mix(in srgb, var(--base-hinting) #9ba2a0, var(--accent-hinting) var(--color-accent));
|
|
--color-input: color-mix(in srgb, var(--base-hinting) #ffffff, var(--accent-hinting) var(--color-accent));
|
|
--color-reasoning: color-mix(in srgb, var(--base-hinting) #99979c, var(--accent-hinting) var(--color-accent));
|
|
} */
|
|
|
|
html,
|
|
body {
|
|
font-family: "Geist", ui-sans-serif, system-ui, -apple-system,
|
|
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
|
|
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
|
"Noto Color Emoji";
|
|
padding: 0;
|
|
margin: 0;
|
|
background-color: var(--bg-base);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.font-mono {
|
|
font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
}
|
|
|
|
html.dark {
|
|
color-scheme: dark;
|
|
}
|
|
|
|
html.light {
|
|
color-scheme: light;
|
|
}
|
|
|
|
html {
|
|
height: 100vh;
|
|
/* something something progressive enhancement */
|
|
height: 100dvh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
button {
|
|
color: inherit;
|
|
display: flex;
|
|
}
|
|
|
|
button.accent {
|
|
display: flex;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
background-color: var(--color-accent);
|
|
color: var(--color-accent-text);
|
|
border-radius: calc(var(--spacing) * 1.5);
|
|
padding-inline: calc(var(--spacing) * 2);
|
|
padding-block: calc(var(--spacing) * 1);
|
|
transition: background-color 150ms cubic-bezier(0.45, 0, 0.55, 1);
|
|
}
|
|
|
|
button.accent:hover {
|
|
background-color: var(--color-accent-hover);
|
|
}
|
|
|
|
.capitalize {
|
|
text-transform: capitalize;
|
|
}
|
|
|
|
.has-obtrusive-scrollbars .chat-scroll-container {
|
|
scrollbar-gutter: stable;
|
|
}
|
|
|
|
.has-obtrusive-scrollbars .chatPane {
|
|
margin-right: calc(-1 * var(--thin-scrollbar-width));
|
|
width: calc(100% + var(--thin-scrollbar-width));
|
|
}
|
|
|
|
.animate-blink {
|
|
animation: blink 1s step-end infinite;
|
|
}
|
|
|
|
@keyframes blink {
|
|
|
|
0%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.animate-rotate {
|
|
animation: rotate 1s linear infinite;
|
|
}
|
|
|
|
@keyframes rotate {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
|
|
100% {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.vl-toggle-switch[aria-disabled="true"] div {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.vl-toggle-switch[data-state="checked"] {
|
|
background: var(--color-accent);
|
|
}
|
|
|
|
.vl-toggle-switch[data-state="checked"] div {
|
|
transform-origin: center right;
|
|
transform: translateX(calc(2.5em - 1em - 0.5rem));
|
|
}
|
|
|
|
.vl-toggle-switch:active div {
|
|
width: 1.3em;
|
|
}
|
|
|
|
.vl-toggle-switch[data-state="checked"]:active div {
|
|
transform: translateX(calc(2.5em - 1.3em - 0.5rem));
|
|
}
|
|
|
|
:where(.i-tabler\:dots) {
|
|
background-color: currentColor;
|
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0'/%3E%3C/svg%3E");
|
|
}
|
|
|
|
.reasoning-contaizner.middle {
|
|
mask-image: linear-gradient(#000, #000, transparent 0, #000 12%, #000 88%, transparent)
|
|
}
|
|
|
|
.reasoning-contaizner.top {
|
|
mask-image: linear-gradient(#000, transparent, #000 0, #000 12%, #000 88%, transparent)
|
|
}
|
|
|
|
.reasoning-contaizner.bottom {
|
|
mask-image: linear-gradient(transparent, #000, transparent 0, #000 12%, #000 88%, #000)
|
|
}
|
|
|
|
/* Markdown renderer */
|
|
article>* {
|
|
margin-top: 0.25rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
article>*:first-child {
|
|
margin-top: 0.5rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
article>*:last-child {
|
|
margin-top: 0.25rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
article>*:only-child {
|
|
margin-top: 0.25rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
article math {
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
article mtd {
|
|
padding: 0.25rem 0.5rem;
|
|
}
|
|
|
|
article hr {
|
|
border: 1px solid var(--text-dim);
|
|
margin-top: 1.25rem;
|
|
margin-bottom: 1.25rem;
|
|
}
|
|
|
|
article li {
|
|
min-height: 24px;
|
|
}
|
|
|
|
article ul {
|
|
list-style: none;
|
|
margin-left: 1.25rem;
|
|
margin-top: 1.25rem;
|
|
}
|
|
|
|
article ul>li {
|
|
position: relative;
|
|
padding-bottom: 0.75rem;
|
|
padding-left: 1.5rem;
|
|
}
|
|
|
|
article ul>li::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0.5rem;
|
|
width: 7px;
|
|
height: 7px;
|
|
background-color: var(--text-tertiary);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
article ul>li::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: 3px;
|
|
top: 23px;
|
|
bottom: 0;
|
|
width: 1px;
|
|
background-color: var(--text-dim);
|
|
}
|
|
|
|
article ul>li:last-child::after {
|
|
display: none;
|
|
}
|
|
|
|
article ol {
|
|
list-style: none;
|
|
margin-left: 1.25rem;
|
|
margin-top: 1.25rem;
|
|
counter-reset: ordered-list-counter var(--start-value, 0);
|
|
}
|
|
|
|
article ol[start] {
|
|
--start-value: calc(attr(start type(<number>)) - 1);
|
|
}
|
|
|
|
article ol>li {
|
|
position: relative;
|
|
padding-bottom: 0.75rem;
|
|
padding-left: 1.5rem;
|
|
counter-increment: ordered-list-counter;
|
|
}
|
|
|
|
article ol>li::before {
|
|
content: counter(ordered-list-counter) ".";
|
|
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
color: var(--color-muted);
|
|
font-weight: 500;
|
|
width: 1.25rem;
|
|
}
|
|
|
|
html.dark .shiki,
|
|
html.dark .shiki span {
|
|
color: var(--shiki-dark) !important;
|
|
background-color: var(--shiki-dark-bg) !important;
|
|
}
|
|
|
|
article ol:only-child,
|
|
article ul:only-child {
|
|
margin-top: 0 !important;
|
|
}
|
|
|
|
article code:not(pre code) {
|
|
background-color: var(--color-hover);
|
|
padding: 0.125rem 0.25rem;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
article blockquote {
|
|
color: var(--text-secondary);
|
|
border-left: 4px solid var(--text-tertiary);
|
|
padding-left: 0.5rem;
|
|
}
|
|
|
|
/* TODO: make these tables better, this is literally the first attempt from Gemini 3 flash */
|
|
article table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 0.95rem;
|
|
text-align: left;
|
|
background-color: var(--bg-base);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
article table thead tr {
|
|
background-color: var(--color-hover);
|
|
}
|
|
|
|
article table th {
|
|
padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
font-size: 0.8rem;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
article table td {
|
|
padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
|
|
}
|
|
|
|
article table tbody tr {
|
|
background-color: var(--color-hover);
|
|
transition: background-color 250ms cubic-bezier(0.5, 1, 0.89, 1);
|
|
}
|
|
|
|
article table tbody tr:nth-of-type(even) {
|
|
background-color: var(--color-hover);
|
|
}
|
|
|
|
/* Hover effect */
|
|
article table tbody tr:hover {
|
|
background-color: var(--color-active);
|
|
}
|
|
|
|
|
|
article h1,
|
|
article h2,
|
|
article h3,
|
|
article h4,
|
|
article h5,
|
|
article h6 {
|
|
margin-top: 0.75rem;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
article .checkbox {
|
|
width: min-content;
|
|
}
|
|
|
|
/* end markdown renderer */ |