Temp: import themes from tuna

This commit is contained in:
2025-11-13 18:01:46 +01:00
parent 1b35c4ccc1
commit 1dc540582d
44 changed files with 1473 additions and 630 deletions

View File

@ -25,6 +25,7 @@
import { loadLastProjectId } from "./lib/project-system/persistence";
import { createAppContext, setAppContext } from "./lib/contexts/app-context";
import type { ProjectMode } from "./lib/project-system/types";
import { themes } from "./lib/themes";
import {
Save,
Share2,
@ -238,9 +239,52 @@
}
$effect(() => {
const theme = $editorSettings.theme;
if (typeof document !== 'undefined') {
document.documentElement.dataset.theme = theme;
const themeName = $editorSettings.theme;
const theme = themes[themeName];
if (theme) {
const root = document.documentElement.style;
root.setProperty('--bg-color', theme.colors.background);
root.setProperty('--surface-color', theme.colors.surface);
root.setProperty('--border-color', theme.colors.border);
root.setProperty('--text-color', theme.colors.text);
root.setProperty('--text-secondary', theme.colors.textSecondary);
root.setProperty('--accent-color', theme.colors.accent);
root.setProperty('--accent-hover', theme.colors.accentHover);
root.setProperty('--input-bg', theme.colors.input);
root.setProperty('--input-border', theme.colors.inputBorder);
root.setProperty('--button-bg', theme.colors.button);
root.setProperty('--button-hover', theme.colors.buttonHover);
root.setProperty('--danger-color', theme.colors.danger);
root.setProperty('--danger-hover', theme.colors.dangerHover);
root.setProperty('--editor-background', theme.editor.background);
root.setProperty('--editor-foreground', theme.editor.foreground);
root.setProperty('--editor-caret', theme.editor.caret);
root.setProperty('--editor-selection', theme.editor.selection);
root.setProperty('--editor-active-line', theme.editor.activeLine);
root.setProperty('--editor-gutter', theme.editor.gutter);
root.setProperty('--editor-gutter-text', theme.editor.gutterText);
root.setProperty('--editor-active-line-gutter', theme.editor.activeLineGutter);
root.setProperty('--editor-line-number', theme.editor.lineNumber);
root.setProperty('--syntax-keyword', theme.syntax.keyword);
root.setProperty('--syntax-operator', theme.syntax.operator);
root.setProperty('--syntax-string', theme.syntax.string);
root.setProperty('--syntax-number', theme.syntax.number);
root.setProperty('--syntax-boolean', theme.syntax.boolean);
root.setProperty('--syntax-comment', theme.syntax.comment);
root.setProperty('--syntax-function', theme.syntax.function);
root.setProperty('--syntax-class', theme.syntax.class);
root.setProperty('--syntax-variable', theme.syntax.variable);
root.setProperty('--syntax-property', theme.syntax.property);
root.setProperty('--syntax-constant', theme.syntax.constant);
root.setProperty('--syntax-type', theme.syntax.type);
root.setProperty('--syntax-tag', theme.syntax.tag);
root.setProperty('--syntax-attribute', theme.syntax.attribute);
}
}
});
@ -554,8 +598,8 @@
.icon-button {
padding: var(--space-sm);
background-color: var(--color-border-default);
color: var(--color-text-primary);
background-color: var(--border-color);
color: var(--text-color);
border: 1px solid #555;
cursor: pointer;
display: flex;
@ -566,7 +610,7 @@
.icon-button:hover:not(:disabled) {
background-color: #444;
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
.icon-button:disabled {
@ -575,7 +619,7 @@
}
.icon-button.has-changes {
color: var(--color-accent-primary);
color: var(--accent-color);
}
.icon-button.stop-button:not(:disabled) {
@ -589,11 +633,11 @@
h3 {
margin-top: 0;
color: var(--color-text-primary);
color: var(--text-color);
}
p {
color: var(--color-text-secondary);
color: var(--text-secondary);
line-height: 1.6;
}
@ -610,9 +654,9 @@
.share-url-input {
width: 100%;
padding: var(--space-md);
background-color: var(--color-surface-3);
border: 1px solid var(--color-border-default);
color: var(--color-text-primary);
background-color: var(--surface-color);
border: 1px solid var(--border-color);
color: var(--text-color);
font-size: var(--font-base);
font-family: monospace;
outline: none;
@ -620,12 +664,12 @@
}
.share-url-input:focus {
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
.share-instructions {
font-size: var(--font-base);
color: var(--color-text-tertiary);
color: var(--text-secondary);
margin: 0;
}
@ -651,7 +695,7 @@
.enable-audio-button {
margin-top: var(--space-lg);
padding: var(--space-md) var(--space-2xl);
background-color: var(--color-accent-primary);
background-color: var(--accent-color);
color: white;
border: none;
font-size: var(--font-lg);
@ -665,6 +709,6 @@
}
.enable-audio-button:active {
background-color: var(--color-accent-primary-active);
background-color: var(--accent-hover);
}
</style>

36
src/base.css Normal file
View File

@ -0,0 +1,36 @@
/* Base Design Tokens */
:root {
/* Spacing Scale */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 0.75rem;
--space-lg: 1rem;
--space-xl: 1.5rem;
--space-2xl: 2rem;
/* Font Sizes */
--font-xs: 0.6875rem;
--font-sm: 0.75rem;
--font-md: 0.8125rem;
--font-base: 0.875rem;
--font-lg: 1rem;
/* Font Families */
--font-mono: 'Courier New', Monaco, Consolas, monospace;
--font-sans: system-ui, -apple-system, sans-serif;
/* Line Heights */
--leading-tight: 1.4;
--leading-normal: 1.5;
--leading-relaxed: 1.6;
/* Transitions */
--transition-fast: 100ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
/* Shadows (theme-aware, will be overridden if needed) */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.3);
--shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4);
}

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { getAppContext } from '../../contexts/app-context';
import { themes } from '../../themes';
const { editorSettings } = getAppContext();
@ -12,27 +13,23 @@
function updateSetting(key: keyof typeof settings, value: any) {
editorSettings.updatePartial({ [key]: value });
}
const themeNames = Object.keys(themes).sort();
</script>
<div class="editor-settings">
<div class="setting">
<span class="label-text">Theme</span>
<div class="theme-toggle">
<button
class="theme-option"
class:active={settings.theme === 'dark'}
onclick={() => updateSetting('theme', 'dark')}
<label>
<span class="label-text">Theme</span>
<select
value={settings.theme}
onchange={(e) => updateSetting('theme', e.currentTarget.value)}
>
Dark
</button>
<button
class="theme-option"
class:active={settings.theme === 'light'}
onclick={() => updateSetting('theme', 'light')}
>
Light
</button>
</div>
{#each themeNames as themeName}
<option value={themeName}>{themes[themeName].name}</option>
{/each}
</select>
</label>
</div>
<div class="setting">
@ -122,7 +119,7 @@
<style>
.editor-settings {
padding: var(--space-sm);
color: var(--color-text-primary);
color: var(--text-color);
}
.setting {
@ -137,44 +134,10 @@
display: block;
font-size: var(--font-sm);
font-weight: 500;
color: var(--color-text-secondary);
color: var(--text-secondary);
margin-bottom: var(--space-xs);
}
.theme-toggle {
display: flex;
gap: 0;
border: 1px solid var(--color-border-default);
overflow: hidden;
}
.theme-option {
flex: 1;
padding: var(--space-sm) var(--space-lg);
background-color: transparent;
color: var(--color-text-secondary);
border: none;
cursor: pointer;
font-size: var(--font-sm);
font-weight: 500;
transition: all var(--transition-base);
border-right: 1px solid var(--color-border-default);
}
.theme-option:last-child {
border-right: none;
}
.theme-option:hover:not(.active) {
background-color: var(--color-hover-overlay);
color: var(--color-text-primary);
}
.theme-option.active {
background-color: var(--color-accent-primary);
color: white;
}
input[type="range"] {
width: 100%;
height: 8px;
@ -187,14 +150,14 @@
appearance: none;
width: 12px;
height: 12px;
background: var(--color-accent-primary);
background: var(--accent-color);
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
width: 12px;
height: 12px;
background: var(--color-accent-primary);
background: var(--accent-color);
cursor: pointer;
border: none;
}
@ -204,17 +167,17 @@
}
input[type="range"]::-webkit-slider-thumb:hover {
background: var(--color-accent-primary-hover);
background: var(--accent-hover);
}
input[type="range"]::-moz-range-thumb:hover {
background: var(--color-accent-primary-hover);
background: var(--accent-hover);
}
select {
width: 100%;
background-color: var(--color-bg-base);
color: var(--color-text-primary);
background-color: var(--bg-color);
color: var(--text-color);
border: 1px solid #555;
padding: 0.4rem;
font-size: var(--font-sm);
@ -222,12 +185,12 @@
}
select:hover {
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
select:focus {
outline: none;
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
.checkboxes {
@ -242,7 +205,7 @@
gap: var(--space-sm);
font-size: var(--font-sm);
font-weight: 500;
color: var(--color-text-secondary);
color: var(--text-secondary);
cursor: pointer;
}
@ -262,13 +225,13 @@
}
input[type="checkbox"]:checked {
background-color: var(--color-accent-primary);
border-color: var(--color-accent-primary);
background-color: var(--accent-color);
border-color: var(--accent-color);
}
input[type="checkbox"]:checked:hover {
background-color: var(--color-accent-primary-hover);
border-color: var(--color-accent-primary-hover);
background-color: var(--accent-hover);
border-color: var(--accent-hover);
}
input[type="checkbox"]:checked::before {

View File

@ -113,7 +113,7 @@
.resize-divider {
height: 4px;
background-color: var(--color-surface-3);
background-color: var(--surface-color);
cursor: ns-resize;
transition: background-color var(--transition-base);
z-index: 10;
@ -121,7 +121,7 @@
.resize-divider:hover,
.resize-divider:active {
background-color: var(--color-accent-primary);
background-color: var(--accent-color);
}
.logs-section {

View File

@ -188,7 +188,7 @@
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--color-bg-base);
background-color: var(--bg-color);
}
.log-header {
@ -196,14 +196,14 @@
justify-content: space-between;
align-items: center;
padding: var(--space-sm) var(--space-md);
background-color: var(--color-surface-3);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
cursor: pointer;
transition: background-color var(--transition-base);
}
.log-header:hover {
background-color: var(--color-hover-overlay);
background-color: var(--editor-active-line);
}
.search-bar {
@ -211,20 +211,20 @@
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-md);
background-color: var(--color-surface-2);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
}
.search-bar :global(.search-icon) {
color: var(--color-text-tertiary);
color: var(--text-secondary);
flex-shrink: 0;
}
.search-input {
flex: 1;
background-color: var(--color-bg-base);
color: var(--color-text-primary);
border: 1px solid var(--color-border-default);
background-color: var(--bg-color);
color: var(--text-color);
border: 1px solid var(--border-color);
padding: 0.375rem var(--space-sm);
font-size: var(--font-base);
font-family: var(--font-mono);
@ -233,17 +233,17 @@
}
.search-input:focus {
border-color: var(--color-text-tertiary);
border-color: var(--text-secondary);
}
.search-input::placeholder {
color: var(--color-text-disabled);
color: var(--text-secondary);
}
.log-title {
font-size: var(--font-sm);
font-weight: 600;
color: var(--color-text-secondary);
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
@ -256,7 +256,7 @@
.action-button {
padding: var(--space-xs);
background-color: transparent;
color: var(--color-text-secondary);
color: var(--text-secondary);
border: none;
cursor: pointer;
display: flex;
@ -266,8 +266,8 @@
}
.action-button:hover:not(:disabled) {
color: var(--color-text-primary);
background-color: var(--color-active-overlay);
color: var(--text-color);
background-color: var(--editor-active-line);
}
.action-button:disabled {
@ -304,7 +304,7 @@
}
.empty-state {
color: var(--color-text-tertiary);
color: var(--text-secondary);
text-align: center;
padding: var(--space-2xl);
}
@ -313,12 +313,12 @@
display: flex;
gap: var(--space-md);
padding: var(--space-xs) var(--space-sm);
color: var(--color-text-primary);
border-bottom: 1px solid var(--color-surface-3);
color: var(--text-color);
border-bottom: 1px solid var(--surface-color);
}
.log-entry:hover {
background-color: var(--color-surface-2);
background-color: var(--surface-color);
}
.log-entry.error {
@ -331,7 +331,7 @@
}
.log-timestamp {
color: var(--color-text-tertiary);
color: var(--text-secondary);
min-width: 6rem;
font-size: var(--font-sm);
}

View File

@ -172,19 +172,19 @@
align-items: center;
gap: var(--space-sm);
padding: var(--space-md);
background-color: var(--color-surface-2);
border-bottom: 1px solid var(--color-border-subtle);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
}
.search-bar :global(.search-icon) {
color: var(--color-text-tertiary);
color: var(--text-secondary);
flex-shrink: 0;
}
.search-input {
flex: 1;
background-color: var(--input-bg);
color: var(--color-text-primary);
color: var(--text-color);
border: 1px solid var(--input-border);
padding: var(--space-sm);
font-size: var(--font-base);
@ -198,14 +198,14 @@
}
.search-input::placeholder {
color: var(--color-text-disabled);
color: var(--text-secondary);
}
.collapse-button {
padding: var(--space-sm);
background-color: transparent;
color: var(--color-text-secondary);
border: 1px solid var(--color-border-default);
color: var(--text-secondary);
border: 1px solid var(--border-color);
cursor: pointer;
display: flex;
align-items: center;
@ -215,9 +215,9 @@
}
.collapse-button:hover {
color: var(--color-text-primary);
background-color: var(--color-hover-overlay);
border-color: var(--color-border-strong);
color: var(--text-color);
background-color: var(--editor-active-line);
border-color: var(--border-color);
}
.reference-content {
@ -243,7 +243,7 @@
padding: var(--space-md) var(--space-lg);
background-color: var(--accordion-header-bg);
border: none;
color: var(--color-text-primary);
color: var(--text-color);
cursor: pointer;
transition: background-color var(--transition-base);
font-size: var(--font-base);
@ -254,7 +254,7 @@
}
.category-header :global(svg) {
color: var(--color-text-tertiary);
color: var(--text-secondary);
flex-shrink: 0;
}
@ -266,8 +266,8 @@
.category-count {
font-size: var(--font-xs);
color: var(--color-text-primary);
background-color: var(--color-accent-primary-subtle);
color: var(--text-color);
background-color: var(--accent-color-subtle);
padding: 2px var(--space-sm);
border-radius: var(--radius-sm);
}
@ -280,7 +280,7 @@
background-color: transparent;
padding: var(--space-lg) 0;
margin-bottom: 0;
border-bottom: 1px solid var(--color-border-subtle);
border-bottom: 1px solid var(--border-color);
}
.opcode:last-child {
@ -298,38 +298,38 @@
font-family: var(--font-mono);
font-size: var(--font-base);
font-weight: 600;
color: var(--color-accent-primary);
color: var(--accent-color);
}
.opcode-type {
font-size: var(--font-xs);
color: var(--color-text-tertiary);
color: var(--text-secondary);
text-transform: lowercase;
}
.opcode-description {
color: var(--color-text-secondary);
color: var(--text-secondary);
font-size: var(--font-md);
line-height: var(--leading-relaxed);
margin: 0 0 var(--space-md) 0;
}
.opcode-syntax {
background-color: var(--color-surface-2);
color: var(--color-text-primary);
background-color: var(--surface-color);
color: var(--text-color);
padding: var(--space-md);
font-size: var(--font-sm);
font-family: var(--font-mono);
margin: 0 0 var(--space-md) 0;
overflow-x: auto;
white-space: pre;
border: 1px solid var(--color-border-subtle);
border: 1px solid var(--border-color);
line-height: var(--leading-normal);
}
.opcode-rates {
font-size: var(--font-sm);
color: var(--color-info);
color: var(--syntax-function);
margin-bottom: var(--space-md);
}
@ -339,7 +339,7 @@
.params-label {
font-size: var(--font-xs);
color: var(--color-text-tertiary);
color: var(--text-secondary);
margin-bottom: var(--space-sm);
text-transform: lowercase;
font-weight: 500;
@ -361,19 +361,19 @@
}
.param-name {
color: var(--color-text-primary);
color: var(--text-color);
font-family: var(--font-mono);
font-weight: 500;
font-size: var(--font-sm);
}
.param-type {
color: var(--color-text-tertiary);
color: var(--text-secondary);
font-size: var(--font-xs);
}
.param-desc {
color: var(--color-text-secondary);
color: var(--text-secondary);
font-size: var(--font-sm);
line-height: var(--leading-normal);
}
@ -385,7 +385,7 @@
justify-content: center;
padding: var(--space-2xl) var(--space-lg);
text-align: center;
color: var(--color-text-tertiary);
color: var(--text-secondary);
}
.empty-state :global(svg) {
@ -397,12 +397,12 @@
font-size: var(--font-lg);
font-weight: 500;
margin: 0 0 var(--space-sm) 0;
color: var(--color-text-secondary);
color: var(--text-secondary);
}
.empty-state p {
font-size: var(--font-base);
margin: 0;
color: var(--color-text-tertiary);
color: var(--text-secondary);
}
</style>

View File

@ -49,7 +49,7 @@
<style>
.confirm-dialog p {
margin: 0 0 var(--space-xl) 0;
color: var(--color-text-primary);
color: var(--text-color);
line-height: 1.5;
}
@ -68,22 +68,22 @@
}
.button-primary {
background-color: var(--color-accent-primary);
background-color: var(--accent-color);
color: white;
}
.button-primary:hover {
background-color: var(--color-accent-primary-active);
background-color: var(--accent-color-active);
}
.button-secondary {
background-color: transparent;
color: var(--color-text-secondary);
border: 1px solid var(--color-border-default);
color: var(--text-secondary);
border: 1px solid var(--border-color);
}
.button-secondary:hover {
background-color: var(--color-hover-overlay);
color: var(--color-text-primary);
background-color: var(--editor-active-line);
color: var(--text-color);
}
</style>

View File

@ -235,7 +235,7 @@
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--color-bg-base);
background-color: var(--bg-color);
}
.browser-header {
@ -243,14 +243,14 @@
justify-content: space-between;
align-items: center;
padding: var(--space-md);
background-color: var(--color-surface-3);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
}
.browser-title {
font-size: var(--font-sm);
font-weight: 600;
color: var(--color-text-secondary);
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
}
@ -263,7 +263,7 @@
.action-button {
padding: 0.375rem;
background-color: transparent;
color: var(--color-text-secondary);
color: var(--text-secondary);
border: none;
cursor: pointer;
display: flex;
@ -273,8 +273,8 @@
}
.action-button:hover {
color: var(--color-text-primary);
background-color: var(--color-active-overlay);
color: var(--text-color);
background-color: var(--editor-active-line);
}
.browser-content {
@ -285,7 +285,7 @@
.empty-state {
padding: var(--space-2xl) var(--space-lg);
text-align: center;
color: var(--color-text-tertiary);
color: var(--text-secondary);
}
.project-list {
@ -298,22 +298,22 @@
align-items: center;
gap: var(--space-md);
padding: var(--space-md);
border-bottom: 1px solid var(--color-surface-3);
border-bottom: 1px solid var(--surface-color);
cursor: pointer;
transition: background-color var(--transition-base);
}
.project-item:hover {
background-color: var(--color-surface-2);
background-color: var(--surface-color);
}
.project-item.selected {
background-color: rgba(100, 108, 255, 0.2);
border-left: 3px solid var(--color-accent-primary);
border-left: 3px solid var(--accent-color);
}
.project-icon {
color: var(--color-text-secondary);
color: var(--text-secondary);
display: flex;
align-items: center;
}
@ -325,7 +325,7 @@
.project-title {
font-size: var(--font-base);
color: var(--color-text-primary);
color: var(--text-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -334,7 +334,7 @@
.delete-button {
padding: var(--space-xs);
background-color: transparent;
color: var(--color-text-tertiary);
color: var(--text-secondary);
border: none;
cursor: pointer;
display: flex;
@ -354,15 +354,15 @@
}
.metadata-editor {
border-top: 1px solid var(--color-surface-3);
background-color: var(--color-bg-base);
border-top: 1px solid var(--surface-color);
background-color: var(--bg-color);
padding: var(--space-lg);
}
.metadata-header {
font-size: var(--font-sm);
font-weight: 600;
color: var(--color-text-secondary);
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: var(--space-lg);
@ -382,22 +382,22 @@
.field label {
font-size: var(--font-sm);
color: var(--color-text-secondary);
color: var(--text-secondary);
}
.field input,
.field select {
padding: var(--space-sm);
background-color: var(--color-surface-3);
border: 1px solid var(--color-border-default);
color: var(--color-text-primary);
background-color: var(--surface-color);
border: 1px solid var(--border-color);
color: var(--text-color);
font-size: var(--font-base);
outline: none;
}
.field input:focus,
.field select:focus {
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
.field select {
@ -406,9 +406,9 @@
.field.readonly .readonly-value {
padding: var(--space-sm);
background-color: var(--color-bg-base);
border: 1px solid var(--color-surface-3);
color: var(--color-text-secondary);
background-color: var(--bg-color);
border: 1px solid var(--surface-color);
color: var(--text-secondary);
font-size: var(--font-base);
font-family: monospace;
}

View File

@ -68,21 +68,21 @@
}
label {
color: var(--color-text-primary);
color: var(--text-color);
font-size: var(--font-base);
}
input {
padding: var(--space-sm);
background-color: var(--color-bg-base);
border: 1px solid var(--color-border-default);
color: var(--color-text-primary);
background-color: var(--bg-color);
border: 1px solid var(--border-color);
color: var(--text-color);
font-size: var(--font-base);
outline: none;
}
input:focus {
border-color: var(--color-accent-primary);
border-color: var(--accent-color);
}
.button-group {
@ -100,22 +100,22 @@
}
.button-primary {
background-color: var(--color-accent-primary);
background-color: var(--accent-color);
color: white;
}
.button-primary:hover {
background-color: var(--color-accent-primary-active);
background-color: var(--accent-color-active);
}
.button-secondary {
background-color: transparent;
color: var(--color-text-secondary);
border: 1px solid var(--color-border-default);
color: var(--text-secondary);
border: 1px solid var(--border-color);
}
.button-secondary:hover {
background-color: var(--color-hover-overlay);
color: var(--color-text-primary);
background-color: var(--editor-active-line);
color: var(--text-color);
}
</style>

View File

@ -52,8 +52,8 @@
}
.modal-content {
background-color: var(--color-surface-3);
border: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border: 1px solid var(--border-color);
min-width: 300px;
max-width: 500px;
max-height: 80vh;
@ -62,12 +62,12 @@
.modal-header {
padding: var(--space-lg) var(--space-xl);
border-bottom: 1px solid var(--color-border-default);
border-bottom: 1px solid var(--border-color);
}
.modal-header h3 {
margin: 0;
color: var(--color-text-primary);
color: var(--text-color);
font-size: var(--font-lg);
font-weight: 600;
}

View File

@ -83,8 +83,8 @@
.popup {
position: fixed;
z-index: 9999;
background-color: var(--color-bg-base);
border: 1px solid var(--color-border-default);
background-color: var(--bg-color);
border: 1px solid var(--border-color);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
@ -95,8 +95,8 @@
justify-content: space-between;
align-items: center;
padding: var(--space-md) var(--space-lg);
background-color: var(--color-surface-2);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
cursor: move;
user-select: none;
}
@ -104,13 +104,13 @@
.popup-title {
font-weight: 600;
font-size: var(--font-base);
color: var(--color-text-primary);
color: var(--text-color);
}
.close-button {
background: none;
border: none;
color: var(--color-text-secondary);
color: var(--text-secondary);
font-size: 1.5rem;
line-height: 1;
padding: 0;
@ -124,7 +124,7 @@
}
.close-button:hover {
color: var(--color-text-primary);
color: var(--text-color);
}
.popup-content {

View File

@ -148,8 +148,8 @@
.resizable-popup {
position: fixed;
z-index: 9999;
background-color: var(--color-bg-base);
border: 1px solid var(--color-border-default);
background-color: var(--bg-color);
border: 1px solid var(--border-color);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
display: flex;
flex-direction: column;
@ -160,8 +160,8 @@
justify-content: space-between;
align-items: center;
padding: var(--space-md) var(--space-lg);
background-color: var(--color-surface-2);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
cursor: move;
user-select: none;
}
@ -169,13 +169,13 @@
.popup-title {
font-weight: 600;
font-size: var(--font-base);
color: var(--color-text-primary);
color: var(--text-color);
}
.close-button {
background: none;
border: none;
color: var(--color-text-secondary);
color: var(--text-secondary);
font-size: 1.5rem;
line-height: 1;
padding: 0;
@ -189,7 +189,7 @@
}
.close-button:hover {
color: var(--color-text-primary);
color: var(--text-color);
}
.popup-content {

View File

@ -166,7 +166,7 @@
<style>
.side-panel {
position: relative;
background-color: var(--color-bg-base);
background-color: var(--bg-color);
display: flex;
flex-direction: column;
}
@ -177,16 +177,16 @@
}
.side-panel.left {
border-right: 1px solid var(--color-border-default);
border-right: 1px solid var(--border-color);
}
.side-panel.right {
border-left: 1px solid var(--color-border-default);
border-left: 1px solid var(--border-color);
}
.side-panel.bottom {
width: 100%;
border-top: 1px solid var(--color-border-default);
border-top: 1px solid var(--border-color);
}
.resize-handle {
@ -222,15 +222,15 @@
.resize-handle:hover,
.resize-handle:active {
background-color: var(--color-accent-primary);
background-color: var(--accent-color);
}
.tabs {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--color-border-default);
background-color: var(--color-surface-1);
border-bottom: 1px solid var(--border-color);
background-color: var(--surface-color);
}
.panel-controls {
@ -243,7 +243,7 @@
.control-button {
padding: var(--space-sm);
background-color: transparent;
color: var(--color-text-secondary);
color: var(--text-secondary);
border: none;
cursor: pointer;
display: flex;
@ -253,16 +253,16 @@
}
.control-button:hover {
color: var(--color-text-primary);
background-color: var(--color-hover-overlay);
color: var(--text-color);
background-color: var(--editor-active-line);
}
.panel-header-fallback {
display: flex;
justify-content: flex-end;
align-items: center;
border-bottom: 1px solid var(--color-border-default);
background-color: var(--color-surface-1);
border-bottom: 1px solid var(--border-color);
background-color: var(--surface-color);
padding: var(--space-sm) 0;
}
@ -270,7 +270,7 @@
padding: var(--space-md) var(--space-lg);
background: none;
border: none;
color: var(--color-text-secondary);
color: var(--text-secondary);
cursor: pointer;
font-size: var(--font-base);
font-weight: 500;
@ -279,12 +279,12 @@
}
.tab:hover {
color: var(--color-text-primary);
color: var(--text-color);
}
.tab.active {
color: var(--color-text-primary);
border-bottom-color: var(--color-accent-primary);
color: var(--text-color);
border-bottom-color: var(--accent-color);
}
.side-panel-content {

View File

@ -59,8 +59,8 @@
}
.modal-content {
background-color: var(--color-bg-base);
border: 1px solid var(--color-border-default);
background-color: var(--bg-color);
border: 1px solid var(--border-color);
width: 400px;
max-height: 80vh;
display: flex;
@ -72,21 +72,21 @@
justify-content: space-between;
align-items: center;
padding: var(--space-lg);
border-bottom: 1px solid var(--color-border-default);
border-bottom: 1px solid var(--border-color);
}
h2 {
margin: 0;
font-size: var(--font-lg);
font-weight: 600;
color: var(--color-text-primary);
color: var(--text-color);
}
.close-button {
background: none;
border: none;
font-size: 2rem;
color: var(--color-text-secondary);
color: var(--text-secondary);
cursor: pointer;
padding: 0;
width: 2rem;
@ -99,7 +99,7 @@
}
.close-button:hover {
color: var(--color-text-primary);
color: var(--text-color);
}
.template-list {
@ -111,8 +111,8 @@
padding: var(--space-lg);
background-color: transparent;
border: none;
border-bottom: 1px solid var(--color-surface-3);
color: var(--color-text-primary);
border-bottom: 1px solid var(--surface-color);
color: var(--text-color);
text-align: left;
cursor: pointer;
transition: background-color var(--transition-base);
@ -120,7 +120,7 @@
}
.template-item:hover {
background-color: var(--color-surface-3);
background-color: var(--surface-color);
}
.template-item:last-child {

View File

@ -29,8 +29,8 @@
justify-content: space-between;
align-items: center;
padding: var(--space-md) var(--space-lg);
background-color: var(--color-bg-base);
border-bottom: 1px solid var(--color-border-default);
background-color: var(--bg-color);
border-bottom: 1px solid var(--border-color);
height: 48px;
box-sizing: border-box;
}
@ -45,7 +45,7 @@
display: flex;
align-items: center;
gap: var(--space-sm);
color: var(--color-text-primary);
color: var(--text-color);
}
.title {

View File

@ -11,94 +11,99 @@ function getCSSVariable(name: string): string {
export function createCodeMirrorTheme(): Extension {
const editorTheme = EditorView.theme({
'&': {
backgroundColor: getCSSVariable('--color-bg-base'),
color: getCSSVariable('--color-text-primary'),
backgroundColor: getCSSVariable('--editor-background'),
color: getCSSVariable('--editor-foreground'),
},
'.cm-content': {
caretColor: getCSSVariable('--color-accent-primary'),
caretColor: getCSSVariable('--editor-caret'),
},
'.cm-cursor, .cm-dropCursor': {
borderLeftColor: getCSSVariable('--color-accent-primary'),
borderLeftColor: getCSSVariable('--editor-caret'),
},
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
backgroundColor: getCSSVariable('--editor-selection'),
},
'.cm-panels': {
backgroundColor: getCSSVariable('--color-surface-1'),
color: getCSSVariable('--color-text-primary'),
backgroundColor: getCSSVariable('--surface-color'),
color: getCSSVariable('--text-color'),
},
'.cm-panels.cm-panels-top': {
borderBottom: `1px solid ${getCSSVariable('--color-border-default')}`,
borderBottom: `1px solid ${getCSSVariable('--border-color')}`,
},
'.cm-panels.cm-panels-bottom': {
borderTop: `1px solid ${getCSSVariable('--color-border-default')}`,
borderTop: `1px solid ${getCSSVariable('--border-color')}`,
},
'.cm-searchMatch': {
backgroundColor: getCSSVariable('--color-warning'),
outline: `1px solid ${getCSSVariable('--color-border-accent')}`,
backgroundColor: getCSSVariable('--syntax-number'),
outline: `1px solid ${getCSSVariable('--accent-color')}`,
},
'.cm-searchMatch.cm-searchMatch-selected': {
backgroundColor: getCSSVariable('--color-accent-primary-subtle'),
backgroundColor: getCSSVariable('--accent-color'),
},
'.cm-activeLine': {
backgroundColor: getCSSVariable('--color-hover-overlay'),
backgroundColor: getCSSVariable('--editor-active-line'),
},
'.cm-selectionMatch': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
backgroundColor: getCSSVariable('--editor-selection'),
},
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
backgroundColor: getCSSVariable('--color-active-overlay'),
backgroundColor: getCSSVariable('--editor-selection'),
},
'.cm-gutters': {
backgroundColor: getCSSVariable('--color-surface-1'),
color: getCSSVariable('--color-text-tertiary'),
backgroundColor: getCSSVariable('--editor-gutter'),
color: getCSSVariable('--editor-gutter-text'),
border: 'none',
borderRight: `1px solid ${getCSSVariable('--color-border-subtle')}`,
borderRight: `1px solid ${getCSSVariable('--border-color')}`,
},
'.cm-activeLineGutter': {
backgroundColor: getCSSVariable('--color-hover-overlay'),
color: getCSSVariable('--color-text-secondary'),
backgroundColor: getCSSVariable('--editor-active-line-gutter'),
color: getCSSVariable('--editor-line-number'),
},
'.cm-foldPlaceholder': {
backgroundColor: getCSSVariable('--color-surface-2'),
border: `1px solid ${getCSSVariable('--color-border-default')}`,
color: getCSSVariable('--color-text-secondary'),
backgroundColor: getCSSVariable('--surface-color'),
border: `1px solid ${getCSSVariable('--border-color')}`,
color: getCSSVariable('--text-secondary'),
},
'.cm-tooltip': {
border: `1px solid ${getCSSVariable('--color-border-default')}`,
backgroundColor: getCSSVariable('--color-tooltip-bg'),
border: `1px solid ${getCSSVariable('--border-color')}`,
backgroundColor: getCSSVariable('--surface-color'),
},
'.cm-tooltip .cm-tooltip-arrow:before': {
borderTopColor: getCSSVariable('--color-border-default'),
borderTopColor: getCSSVariable('--border-color'),
},
'.cm-tooltip .cm-tooltip-arrow:after': {
borderTopColor: getCSSVariable('--color-tooltip-bg'),
borderTopColor: getCSSVariable('--surface-color'),
},
'.cm-tooltip-autocomplete': {
'& > ul > li[aria-selected]': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
color: getCSSVariable('--color-text-primary'),
backgroundColor: getCSSVariable('--editor-selection'),
color: getCSSVariable('--text-color'),
},
},
}, { dark: getCSSVariable('--color-bg-base').startsWith('#1') || getCSSVariable('--color-bg-base').startsWith('#2') });
}, { dark: getCSSVariable('--editor-background').startsWith('#1') || getCSSVariable('--editor-background').startsWith('#2') || getCSSVariable('--editor-background').startsWith('#0') });
const highlightStyle = HighlightStyle.define([
{ tag: t.keyword, color: getCSSVariable('--color-accent-primary') },
{ tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], color: getCSSVariable('--color-text-primary') },
{ tag: [t.function(t.variableName), t.labelName], color: getCSSVariable('--color-info') },
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: getCSSVariable('--color-warning') },
{ tag: [t.definition(t.name), t.separator], color: getCSSVariable('--color-text-primary') },
{ tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: getCSSVariable('--color-warning') },
{ tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: getCSSVariable('--color-accent-primary-hover') },
{ tag: [t.meta, t.comment], color: getCSSVariable('--color-text-tertiary'), fontStyle: 'italic' },
{ tag: t.keyword, color: getCSSVariable('--syntax-keyword') },
{ tag: [t.name, t.deleted, t.character, t.macroName], color: getCSSVariable('--syntax-variable') },
{ tag: [t.function(t.variableName), t.labelName], color: getCSSVariable('--syntax-function') },
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: getCSSVariable('--syntax-constant') },
{ tag: [t.definition(t.name), t.separator], color: getCSSVariable('--syntax-variable') },
{ tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: getCSSVariable('--syntax-class') },
{ tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: getCSSVariable('--syntax-operator') },
{ tag: [t.meta, t.comment], color: getCSSVariable('--syntax-comment'), fontStyle: 'italic' },
{ tag: t.strong, fontWeight: 'bold' },
{ tag: t.emphasis, fontStyle: 'italic' },
{ tag: t.strikethrough, textDecoration: 'line-through' },
{ tag: t.link, color: getCSSVariable('--color-info'), textDecoration: 'underline' },
{ tag: t.heading, fontWeight: 'bold', color: getCSSVariable('--color-accent-primary') },
{ tag: [t.atom, t.bool, t.special(t.variableName)], color: getCSSVariable('--color-warning') },
{ tag: [t.processingInstruction, t.string, t.inserted], color: getCSSVariable('--color-success') },
{ tag: t.invalid, color: getCSSVariable('--color-error') },
{ tag: t.link, color: getCSSVariable('--accent-color'), textDecoration: 'underline' },
{ tag: t.heading, fontWeight: 'bold', color: getCSSVariable('--syntax-keyword') },
{ tag: [t.atom, t.bool, t.special(t.variableName)], color: getCSSVariable('--syntax-boolean') },
{ tag: [t.processingInstruction, t.string, t.inserted], color: getCSSVariable('--syntax-string') },
{ tag: t.invalid, color: getCSSVariable('--danger-color') },
{ tag: t.number, color: getCSSVariable('--syntax-number') },
{ tag: [t.propertyName], color: getCSSVariable('--syntax-property') },
{ tag: [t.typeName], color: getCSSVariable('--syntax-type') },
{ tag: [t.tagName], color: getCSSVariable('--syntax-tag') },
{ tag: [t.attributeName], color: getCSSVariable('--syntax-attribute') },
]);
return [editorTheme, syntaxHighlighting(highlightStyle)];

View File

@ -1,9 +1,8 @@
import { writable } from 'svelte/store';
import type { ThemeName } from '$lib/themes';
const STORAGE_KEY = 'editorSettings';
export type Theme = 'dark' | 'light';
export interface EditorSettings {
fontSize: number;
fontFamily: string;
@ -12,7 +11,7 @@ export interface EditorSettings {
tabSize: number;
vimMode: boolean;
enableHoverTooltips: boolean;
theme: Theme;
theme: ThemeName;
}
const defaultSettings: EditorSettings = {
@ -23,7 +22,7 @@ const defaultSettings: EditorSettings = {
tabSize: 2,
vimMode: false,
enableHoverTooltips: true,
theme: 'dark'
theme: 'monodark'
};
export interface EditorSettingsStore {

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const ayumirage: Theme = {
name: 'Ayu Mirage',
colors: {
background: '#1f2430',
surface: '#232834',
border: '#33415e',
text: '#cccac2',
textSecondary: '#707a8c',
accent: '#ffcc66',
accentHover: '#ffd580',
input: '#242936',
inputBorder: '#33415e',
button: '#33415e',
buttonHover: '#3e4b66',
danger: '#f28779',
dangerHover: '#f5a697',
},
editor: {
background: '#1f2430',
foreground: '#cccac2',
caret: '#ffcc66',
selection: '#33415e',
activeLine: '#232834',
gutter: '#1f2430',
gutterText: '#707a8c',
activeLineGutter: '#232834',
lineNumber: '#707a8c',
},
syntax: {
keyword: '#ffa759',
operator: '#f29e74',
string: '#d5ff80',
number: '#ffcc66',
boolean: '#ffcc66',
comment: '#5c6773',
function: '#ffd580',
class: '#73d0ff',
variable: '#cccac2',
property: '#5ccfe6',
constant: '#d4bfff',
type: '#73d0ff',
tag: '#5ccfe6',
attribute: '#ffd580',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const blue: Theme = {
name: 'Blue',
colors: {
background: '#0e1525',
surface: '#162032',
border: '#1f2d47',
text: '#c5d4eb',
textSecondary: '#7a8bb0',
accent: '#4d9fff',
accentHover: '#6eb0ff',
input: '#1a2840',
inputBorder: '#2a3d5f',
button: '#1a2840',
buttonHover: '#243554',
danger: '#ff6b6b',
dangerHover: '#ff5252',
},
editor: {
background: '#0e1525',
foreground: '#c5d4eb',
caret: '#ffffff',
selection: '#1e3a5f',
activeLine: '#1a2840',
gutter: '#0e1525',
gutterText: '#7a8bb0',
activeLineGutter: '#1a2840',
lineNumber: '#7a8bb0',
},
syntax: {
keyword: '#6eb0ff',
operator: '#c5d4eb',
string: '#d4a574',
number: '#b5e7a0',
boolean: '#6eb0ff',
comment: '#6b8299',
function: '#ffd57f',
class: '#5ccfe6',
variable: '#a6d9f7',
property: '#a6d9f7',
constant: '#7dd3fc',
type: '#5ccfe6',
tag: '#6eb0ff',
attribute: '#a6d9f7',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const bluescreen: Theme = {
name: 'Blue Screen',
colors: {
background: '#0000aa',
surface: '#0000cc',
border: '#5555ff',
text: '#ffffff',
textSecondary: '#aaaaff',
accent: '#ffffff',
accentHover: '#ddddff',
input: '#0000cc',
inputBorder: '#5555ff',
button: '#0000cc',
buttonHover: '#0000ee',
danger: '#ffffff',
dangerHover: '#dddddd',
},
editor: {
background: '#0000aa',
foreground: '#ffffff',
caret: '#ffffff',
selection: '#0000ee',
activeLine: '#0000cc',
gutter: '#0000aa',
gutterText: '#aaaaff',
activeLineGutter: '#0000cc',
lineNumber: '#aaaaff',
},
syntax: {
keyword: '#ffffff',
operator: '#ffffff',
string: '#dddddd',
number: '#ffffff',
boolean: '#ffffff',
comment: '#8888ff',
function: '#ffffff',
class: '#ffffff',
variable: '#eeeeee',
property: '#eeeeee',
constant: '#ffffff',
type: '#ffffff',
tag: '#ffffff',
attribute: '#eeeeee',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const catppuccin: Theme = {
name: 'Catppuccin Mocha',
colors: {
background: '#1e1e2e',
surface: '#181825',
border: '#45475a',
text: '#cdd6f4',
textSecondary: '#6c7086',
accent: '#89b4fa',
accentHover: '#b4befe',
input: '#181825',
inputBorder: '#45475a',
button: '#313244',
buttonHover: '#45475a',
danger: '#f38ba8',
dangerHover: '#eba0ac',
},
editor: {
background: '#1e1e2e',
foreground: '#cdd6f4',
caret: '#f5e0dc',
selection: '#45475a',
activeLine: '#313244',
gutter: '#1e1e2e',
gutterText: '#6c7086',
activeLineGutter: '#313244',
lineNumber: '#6c7086',
},
syntax: {
keyword: '#cba6f7',
operator: '#89dceb',
string: '#a6e3a1',
number: '#fab387',
boolean: '#fab387',
comment: '#6c7086',
function: '#89b4fa',
class: '#f5c2e7',
variable: '#cdd6f4',
property: '#89dceb',
constant: '#fab387',
type: '#f5c2e7',
tag: '#f38ba8',
attribute: '#f9e2af',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const darcula: Theme = {
name: 'Darcula',
colors: {
background: '#2b2b2b',
surface: '#313335',
border: '#3c3f41',
text: '#a9b7c6',
textSecondary: '#808080',
accent: '#4b6eaf',
accentHover: '#5b7ec5',
input: '#45494a',
inputBorder: '#555555',
button: '#3c3f41',
buttonHover: '#4c5052',
danger: '#c75450',
dangerHover: '#d96461',
},
editor: {
background: '#2b2b2b',
foreground: '#a9b7c6',
caret: '#bbbbbb',
selection: '#214283',
activeLine: '#323232',
gutter: '#313335',
gutterText: '#606366',
activeLineGutter: '#323232',
lineNumber: '#606366',
},
syntax: {
keyword: '#cc7832',
operator: '#a9b7c6',
string: '#6a8759',
number: '#6897bb',
boolean: '#cc7832',
comment: '#808080',
function: '#ffc66d',
class: '#a9b7c6',
variable: '#a9b7c6',
property: '#a9b7c6',
constant: '#9876aa',
type: '#a9b7c6',
tag: '#e8bf6a',
attribute: '#bababa',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const dracula: Theme = {
name: 'Dracula',
colors: {
background: '#282a36',
surface: '#21222c',
border: '#44475a',
text: '#f8f8f2',
textSecondary: '#6272a4',
accent: '#bd93f9',
accentHover: '#d4b5ff',
input: '#44475a',
inputBorder: '#6272a4',
button: '#44475a',
buttonHover: '#565869',
danger: '#ff5555',
dangerHover: '#ff6e6e',
},
editor: {
background: '#282a36',
foreground: '#f8f8f2',
caret: '#f8f8f0',
selection: '#44475a',
activeLine: '#343746',
gutter: '#282a36',
gutterText: '#6272a4',
activeLineGutter: '#343746',
lineNumber: '#6272a4',
},
syntax: {
keyword: '#ff79c6',
operator: '#ff79c6',
string: '#f1fa8c',
number: '#bd93f9',
boolean: '#bd93f9',
comment: '#6272a4',
function: '#50fa7b',
class: '#8be9fd',
variable: '#f8f8f2',
property: '#f8f8f2',
constant: '#bd93f9',
type: '#8be9fd',
tag: '#ff79c6',
attribute: '#50fa7b',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const georges: Theme = {
name: 'Georges',
colors: {
background: '#000000',
surface: '#0a0a0a',
border: '#1a1a1a',
text: '#e0e0e0',
textSecondary: '#808080',
accent: '#00d9ff',
accentHover: '#33e1ff',
input: '#0a0a0a',
inputBorder: '#1a1a1a',
button: '#1a1a1a',
buttonHover: '#2a2a2a',
danger: '#ff3366',
dangerHover: '#ff5580',
},
editor: {
background: '#000000',
foreground: '#e0e0e0',
caret: '#00d9ff',
selection: '#1a1a1a',
activeLine: '#0a0a0a',
gutter: '#000000',
gutterText: '#606060',
activeLineGutter: '#0a0a0a',
lineNumber: '#606060',
},
syntax: {
keyword: '#ff6bcb',
operator: '#00d9ff',
string: '#a5ff90',
number: '#ffb86c',
boolean: '#ff9d00',
comment: '#606060',
function: '#57c7ff',
class: '#ffd700',
variable: '#e0e0e0',
property: '#b4f1ff',
constant: '#ffb86c',
type: '#ffd700',
tag: '#ff6bcb',
attribute: '#a5ff90',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const gruvbox: Theme = {
name: 'Gruvbox',
colors: {
background: '#282828',
surface: '#3c3836',
border: '#504945',
text: '#ebdbb2',
textSecondary: '#a89984',
accent: '#fe8019',
accentHover: '#fe9720',
input: '#3c3836',
inputBorder: '#504945',
button: '#3c3836',
buttonHover: '#504945',
danger: '#fb4934',
dangerHover: '#cc241d',
},
editor: {
background: '#282828',
foreground: '#ebdbb2',
caret: '#ebdbb2',
selection: '#504945',
activeLine: '#3c3836',
gutter: '#282828',
gutterText: '#928374',
activeLineGutter: '#3c3836',
lineNumber: '#928374',
},
syntax: {
keyword: '#fb4934',
operator: '#fe8019',
string: '#b8bb26',
number: '#d3869b',
boolean: '#d3869b',
comment: '#928374',
function: '#b8bb26',
class: '#fabd2f',
variable: '#ebdbb2',
property: '#83a598',
constant: '#d3869b',
type: '#fabd2f',
tag: '#fb4934',
attribute: '#b8bb26',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const hacker: Theme = {
name: 'Hacker',
colors: {
background: '#0d0d0d',
surface: '#1a1a1a',
border: '#00ff00',
text: '#00ff00',
textSecondary: '#008800',
accent: '#00ff00',
accentHover: '#33ff33',
input: '#1a1a1a',
inputBorder: '#008800',
button: '#1a1a1a',
buttonHover: '#0f2f0f',
danger: '#ff0000',
dangerHover: '#ff3333',
},
editor: {
background: '#0d0d0d',
foreground: '#00ff00',
caret: '#00ff00',
selection: '#0f3f0f',
activeLine: '#1a1a1a',
gutter: '#0d0d0d',
gutterText: '#008800',
activeLineGutter: '#1a1a1a',
lineNumber: '#008800',
},
syntax: {
keyword: '#00ff00',
operator: '#00ff00',
string: '#00cc00',
number: '#00ff88',
boolean: '#00ff00',
comment: '#006600',
function: '#33ff33',
class: '#00ff88',
variable: '#00dd00',
property: '#00dd00',
constant: '#00ff88',
type: '#00ff88',
tag: '#00ff00',
attribute: '#00dd00',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const light: Theme = {
name: 'Light',
colors: {
background: '#ffffff',
surface: '#f5f5f5',
border: '#e0e0e0',
text: '#333333',
textSecondary: '#6e7681',
accent: '#0066cc',
accentHover: '#0052a3',
input: '#ffffff',
inputBorder: '#d0d0d0',
button: '#e8e8e8',
buttonHover: '#d0d0d0',
danger: '#d32f2f',
dangerHover: '#b71c1c',
},
editor: {
background: '#ffffff',
foreground: '#333333',
caret: '#000000',
selection: '#add6ff',
activeLine: '#f0f0f0',
gutter: '#f5f5f5',
gutterText: '#6e7681',
activeLineGutter: '#f0f0f0',
lineNumber: '#6e7681',
},
syntax: {
keyword: '#0000ff',
operator: '#333333',
string: '#a31515',
number: '#098658',
boolean: '#0000ff',
comment: '#008000',
function: '#795e26',
class: '#267f99',
variable: '#001080',
property: '#001080',
constant: '#0070c1',
type: '#267f99',
tag: '#800000',
attribute: '#ff0000',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const materialdarker: Theme = {
name: 'Material Darker',
colors: {
background: '#212121',
surface: '#292929',
border: '#3a3a3a',
text: '#eeffff',
textSecondary: '#616161',
accent: '#80cbc4',
accentHover: '#a1dbd5',
input: '#292929',
inputBorder: '#3a3a3a',
button: '#3a3a3a',
buttonHover: '#4a4a4a',
danger: '#f07178',
dangerHover: '#f49499',
},
editor: {
background: '#212121',
foreground: '#eeffff',
caret: '#ffcc00',
selection: '#3a3a3a',
activeLine: '#292929',
gutter: '#212121',
gutterText: '#616161',
activeLineGutter: '#292929',
lineNumber: '#616161',
},
syntax: {
keyword: '#c792ea',
operator: '#89ddff',
string: '#c3e88d',
number: '#f78c6c',
boolean: '#ff5370',
comment: '#616161',
function: '#82aaff',
class: '#ffcb6b',
variable: '#eeffff',
property: '#89ddff',
constant: '#f78c6c',
type: '#ffcb6b',
tag: '#f07178',
attribute: '#c792ea',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const monodark: Theme = {
name: 'MonoDark',
colors: {
background: '#000000',
surface: '#0a0a0a',
border: '#333333',
text: '#ffffff',
textSecondary: '#999999',
accent: '#ffffff',
accentHover: '#cccccc',
input: '#1a1a1a',
inputBorder: '#444444',
button: '#1a1a1a',
buttonHover: '#2a2a2a',
danger: '#ffffff',
dangerHover: '#cccccc',
},
editor: {
background: '#000000',
foreground: '#ffffff',
caret: '#ffffff',
selection: '#333333',
activeLine: '#1a1a1a',
gutter: '#0a0a0a',
gutterText: '#999999',
activeLineGutter: '#1a1a1a',
lineNumber: '#666666',
},
syntax: {
keyword: '#ffffff',
operator: '#ffffff',
string: '#ffffff',
number: '#ffffff',
boolean: '#ffffff',
comment: '#999999',
function: '#ffffff',
class: '#ffffff',
variable: '#ffffff',
property: '#ffffff',
constant: '#ffffff',
type: '#ffffff',
tag: '#ffffff',
attribute: '#ffffff',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const monokai: Theme = {
name: 'Monokai',
colors: {
background: '#272822',
surface: '#2e2f2a',
border: '#3e3d32',
text: '#f8f8f2',
textSecondary: '#75715e',
accent: '#66d9ef',
accentHover: '#a1efe4',
input: '#3e3d32',
inputBorder: '#5a5a47',
button: '#3e3d32',
buttonHover: '#49483e',
danger: '#f92672',
dangerHover: '#ff669d',
},
editor: {
background: '#272822',
foreground: '#f8f8f2',
caret: '#f8f8f0',
selection: '#49483e',
activeLine: '#3e3d32',
gutter: '#272822',
gutterText: '#8f908a',
activeLineGutter: '#3e3d32',
lineNumber: '#8f908a',
},
syntax: {
keyword: '#f92672',
operator: '#f92672',
string: '#e6db74',
number: '#ae81ff',
boolean: '#ae81ff',
comment: '#75715e',
function: '#a6e22e',
class: '#a6e22e',
variable: '#f8f8f2',
property: '#f8f8f2',
constant: '#ae81ff',
type: '#66d9ef',
tag: '#f92672',
attribute: '#a6e22e',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const monolight: Theme = {
name: 'MonoLight',
colors: {
background: '#ffffff',
surface: '#f8f8f8',
border: '#e0e0e0',
text: '#000000',
textSecondary: '#666666',
accent: '#000000',
accentHover: '#333333',
input: '#ffffff',
inputBorder: '#cccccc',
button: '#f0f0f0',
buttonHover: '#e0e0e0',
danger: '#000000',
dangerHover: '#333333',
},
editor: {
background: '#ffffff',
foreground: '#000000',
caret: '#000000',
selection: '#d0d0d0',
activeLine: '#f5f5f5',
gutter: '#f8f8f8',
gutterText: '#666666',
activeLineGutter: '#f0f0f0',
lineNumber: '#999999',
},
syntax: {
keyword: '#000000',
operator: '#000000',
string: '#000000',
number: '#000000',
boolean: '#000000',
comment: '#666666',
function: '#000000',
class: '#000000',
variable: '#000000',
property: '#000000',
constant: '#000000',
type: '#000000',
tag: '#000000',
attribute: '#000000',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const nightowl: Theme = {
name: 'Night Owl',
colors: {
background: '#011627',
surface: '#0b2942',
border: '#1d3b53',
text: '#d6deeb',
textSecondary: '#637777',
accent: '#80a4c2',
accentHover: '#9fb9d0',
input: '#0b2942',
inputBorder: '#1d3b53',
button: '#1d3b53',
buttonHover: '#2d4f6b',
danger: '#ef5350',
dangerHover: '#f27572',
},
editor: {
background: '#011627',
foreground: '#d6deeb',
caret: '#80a4c2',
selection: '#1d3b53',
activeLine: '#0b2942',
gutter: '#011627',
gutterText: '#4b6479',
activeLineGutter: '#0b2942',
lineNumber: '#4b6479',
},
syntax: {
keyword: '#c792ea',
operator: '#c792ea',
string: '#ecc48d',
number: '#f78c6c',
boolean: '#ff5874',
comment: '#637777',
function: '#82aaff',
class: '#ffcb8b',
variable: '#d6deeb',
property: '#7fdbca',
constant: '#82aaff',
type: '#addb67',
tag: '#7fdbca',
attribute: '#addb67',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const nord: Theme = {
name: 'Nord',
colors: {
background: '#2e3440',
surface: '#3b4252',
border: '#4c566a',
text: '#d8dee9',
textSecondary: '#81a1c1',
accent: '#88c0d0',
accentHover: '#8fbcbb',
input: '#3b4252',
inputBorder: '#4c566a',
button: '#434c5e',
buttonHover: '#4c566a',
danger: '#bf616a',
dangerHover: '#d08770',
},
editor: {
background: '#2e3440',
foreground: '#d8dee9',
caret: '#d8dee9',
selection: '#434c5e',
activeLine: '#3b4252',
gutter: '#2e3440',
gutterText: '#81a1c1',
activeLineGutter: '#3b4252',
lineNumber: '#81a1c1',
},
syntax: {
keyword: '#81a1c1',
operator: '#81a1c1',
string: '#a3be8c',
number: '#b48ead',
boolean: '#81a1c1',
comment: '#616e88',
function: '#88c0d0',
class: '#8fbcbb',
variable: '#d8dee9',
property: '#d8dee9',
constant: '#b48ead',
type: '#8fbcbb',
tag: '#81a1c1',
attribute: '#d8dee9',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const onedarkpro: Theme = {
name: 'One Dark Pro Darker',
colors: {
background: '#1e2127',
surface: '#282c34',
border: '#3e4451',
text: '#abb2bf',
textSecondary: '#5c6370',
accent: '#61afef',
accentHover: '#84c0f4',
input: '#282c34',
inputBorder: '#3e4451',
button: '#3e4451',
buttonHover: '#4b5362',
danger: '#e06c75',
dangerHover: '#e88388',
},
editor: {
background: '#1e2127',
foreground: '#abb2bf',
caret: '#528bff',
selection: '#3e4451',
activeLine: '#282c34',
gutter: '#1e2127',
gutterText: '#5c6370',
activeLineGutter: '#282c34',
lineNumber: '#5c6370',
},
syntax: {
keyword: '#c678dd',
operator: '#56b6c2',
string: '#98c379',
number: '#d19a66',
boolean: '#d19a66',
comment: '#5c6370',
function: '#61afef',
class: '#e5c07b',
variable: '#e06c75',
property: '#abb2bf',
constant: '#d19a66',
type: '#e5c07b',
tag: '#e06c75',
attribute: '#d19a66',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const solarizeddark: Theme = {
name: 'Solarized Dark',
colors: {
background: '#002b36',
surface: '#073642',
border: '#586e75',
text: '#839496',
textSecondary: '#657b83',
accent: '#268bd2',
accentHover: '#2aa198',
input: '#073642',
inputBorder: '#586e75',
button: '#073642',
buttonHover: '#094551',
danger: '#dc322f',
dangerHover: '#cb4b16',
},
editor: {
background: '#002b36',
foreground: '#839496',
caret: '#839496',
selection: '#073642',
activeLine: '#073642',
gutter: '#002b36',
gutterText: '#586e75',
activeLineGutter: '#073642',
lineNumber: '#586e75',
},
syntax: {
keyword: '#859900',
operator: '#859900',
string: '#2aa198',
number: '#d33682',
boolean: '#268bd2',
comment: '#586e75',
function: '#268bd2',
class: '#b58900',
variable: '#839496',
property: '#839496',
constant: '#cb4b16',
type: '#b58900',
tag: '#268bd2',
attribute: '#93a1a1',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const solarizedlight: Theme = {
name: 'Solarized Light',
colors: {
background: '#fdf6e3',
surface: '#eee8d5',
border: '#93a1a1',
text: '#657b83',
textSecondary: '#839496',
accent: '#268bd2',
accentHover: '#2aa198',
input: '#eee8d5',
inputBorder: '#93a1a1',
button: '#eee8d5',
buttonHover: '#e4ddc4',
danger: '#dc322f',
dangerHover: '#cb4b16',
},
editor: {
background: '#fdf6e3',
foreground: '#657b83',
caret: '#657b83',
selection: '#eee8d5',
activeLine: '#eee8d5',
gutter: '#fdf6e3',
gutterText: '#93a1a1',
activeLineGutter: '#eee8d5',
lineNumber: '#93a1a1',
},
syntax: {
keyword: '#859900',
operator: '#859900',
string: '#2aa198',
number: '#d33682',
boolean: '#268bd2',
comment: '#93a1a1',
function: '#268bd2',
class: '#b58900',
variable: '#657b83',
property: '#657b83',
constant: '#cb4b16',
type: '#b58900',
tag: '#268bd2',
attribute: '#586e75',
},
};

View File

@ -0,0 +1,47 @@
import type { Theme } from '../types';
export const tokyonight: Theme = {
name: 'Tokyo Night',
colors: {
background: '#1a1b26',
surface: '#16161e',
border: '#414868',
text: '#c0caf5',
textSecondary: '#565f89',
accent: '#7aa2f7',
accentHover: '#89b4fa',
input: '#1f2335',
inputBorder: '#414868',
button: '#1f2335',
buttonHover: '#24283b',
danger: '#f7768e',
dangerHover: '#ff9e64',
},
editor: {
background: '#1a1b26',
foreground: '#c0caf5',
caret: '#c0caf5',
selection: '#364a82',
activeLine: '#1f2335',
gutter: '#1a1b26',
gutterText: '#565f89',
activeLineGutter: '#1f2335',
lineNumber: '#565f89',
},
syntax: {
keyword: '#bb9af7',
operator: '#89ddff',
string: '#9ece6a',
number: '#ff9e64',
boolean: '#ff9e64',
comment: '#565f89',
function: '#7aa2f7',
class: '#2ac3de',
variable: '#c0caf5',
property: '#7dcfff',
constant: '#ff9e64',
type: '#2ac3de',
tag: '#f7768e',
attribute: '#bb9af7',
},
};

View File

@ -0,0 +1,49 @@
import type { Theme } from './types';
export function generateThemeCss(theme: Theme): string {
return `
/* ${theme.name} Theme */
/* UI Colors */
--bg-color: ${theme.colors.background};
--surface-color: ${theme.colors.surface};
--border-color: ${theme.colors.border};
--text-color: ${theme.colors.text};
--text-secondary: ${theme.colors.textSecondary};
--accent-color: ${theme.colors.accent};
--accent-hover: ${theme.colors.accentHover};
--input-bg: ${theme.colors.input};
--input-border: ${theme.colors.inputBorder};
--button-bg: ${theme.colors.button};
--button-hover: ${theme.colors.buttonHover};
--danger-color: ${theme.colors.danger};
--danger-hover: ${theme.colors.dangerHover};
/* Editor Colors */
--editor-background: ${theme.editor.background};
--editor-foreground: ${theme.editor.foreground};
--editor-caret: ${theme.editor.caret};
--editor-selection: ${theme.editor.selection};
--editor-active-line: ${theme.editor.activeLine};
--editor-gutter: ${theme.editor.gutter};
--editor-gutter-text: ${theme.editor.gutterText};
--editor-active-line-gutter: ${theme.editor.activeLineGutter};
--editor-line-number: ${theme.editor.lineNumber};
/* Syntax Highlighting */
--syntax-keyword: ${theme.syntax.keyword};
--syntax-operator: ${theme.syntax.operator};
--syntax-string: ${theme.syntax.string};
--syntax-number: ${theme.syntax.number};
--syntax-boolean: ${theme.syntax.boolean};
--syntax-comment: ${theme.syntax.comment};
--syntax-function: ${theme.syntax.function};
--syntax-class: ${theme.syntax.class};
--syntax-variable: ${theme.syntax.variable};
--syntax-property: ${theme.syntax.property};
--syntax-constant: ${theme.syntax.constant};
--syntax-type: ${theme.syntax.type};
--syntax-tag: ${theme.syntax.tag};
--syntax-attribute: ${theme.syntax.attribute};
`.trim();
}

50
src/lib/themes/index.ts Normal file
View File

@ -0,0 +1,50 @@
export type { Theme } from './types';
export { createHighlightStyle } from './utils';
export { generateThemeCss } from './exportCss';
import type { Theme } from './types';
import { light } from './definitions/light';
import { blue } from './definitions/blue';
import { monokai } from './definitions/monokai';
import { monolight } from './definitions/monolight';
import { monodark } from './definitions/monodark';
import { hacker } from './definitions/hacker';
import { dracula } from './definitions/dracula';
import { nord } from './definitions/nord';
import { darcula } from './definitions/darcula';
import { bluescreen } from './definitions/bluescreen';
import { gruvbox } from './definitions/gruvbox';
import { solarizeddark } from './definitions/solarizeddark';
import { solarizedlight } from './definitions/solarizedlight';
import { tokyonight } from './definitions/tokyonight';
import { catppuccin } from './definitions/catppuccin';
import { ayumirage } from './definitions/ayumirage';
import { onedarkpro } from './definitions/onedarkpro';
import { nightowl } from './definitions/nightowl';
import { materialdarker } from './definitions/materialdarker';
import { georges } from './definitions/georges';
export const themes: Record<string, Theme> = {
light,
blue,
monokai,
monolight,
monodark,
hacker,
dracula,
nord,
darcula,
bluescreen,
gruvbox,
solarizeddark,
solarizedlight,
tokyonight,
catppuccin,
ayumirage,
onedarkpro,
nightowl,
materialdarker,
georges,
};
export type ThemeName = keyof typeof themes;

45
src/lib/themes/types.ts Normal file
View File

@ -0,0 +1,45 @@
export interface Theme {
name: string;
colors: {
background: string;
surface: string;
border: string;
text: string;
textSecondary: string;
accent: string;
accentHover: string;
input: string;
inputBorder: string;
button: string;
buttonHover: string;
danger: string;
dangerHover: string;
};
editor: {
background: string;
foreground: string;
caret: string;
selection: string;
activeLine: string;
gutter: string;
gutterText: string;
activeLineGutter: string;
lineNumber: string;
};
syntax: {
keyword: string;
operator: string;
string: string;
number: string;
boolean: string;
comment: string;
function: string;
class: string;
variable: string;
property: string;
constant: string;
type: string;
tag: string;
attribute: string;
};
}

29
src/lib/themes/utils.ts Normal file
View File

@ -0,0 +1,29 @@
import { HighlightStyle } from '@codemirror/language';
import { tags as t } from '@lezer/highlight';
import type { Theme } from './types';
export function createHighlightStyle(theme: Theme): HighlightStyle {
return HighlightStyle.define([
{ tag: t.keyword, color: theme.syntax.keyword },
{ tag: [t.name, t.deleted, t.character, t.macroName], color: theme.syntax.variable },
{ tag: [t.function(t.variableName), t.labelName], color: theme.syntax.function },
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: theme.syntax.constant },
{ tag: [t.definition(t.name), t.separator], color: theme.syntax.variable },
{ tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: theme.syntax.class },
{ tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: theme.syntax.operator },
{ tag: [t.meta, t.comment], color: theme.syntax.comment },
{ tag: t.strong, fontWeight: 'bold' },
{ tag: t.emphasis, fontStyle: 'italic' },
{ tag: t.strikethrough, textDecoration: 'line-through' },
{ tag: t.link, color: theme.syntax.string, textDecoration: 'underline' },
{ tag: t.heading, fontWeight: 'bold', color: theme.syntax.keyword },
{ tag: [t.atom, t.bool, t.special(t.variableName)], color: theme.syntax.boolean },
{ tag: [t.processingInstruction, t.string, t.inserted], color: theme.syntax.string },
{ tag: t.invalid, color: theme.editor.foreground },
{ tag: t.number, color: theme.syntax.number },
{ tag: [t.propertyName], color: theme.syntax.property },
{ tag: [t.typeName], color: theme.syntax.type },
{ tag: [t.tagName], color: theme.syntax.tag },
{ tag: [t.attributeName], color: theme.syntax.attribute },
]);
}

View File

@ -1,16 +1,57 @@
import { mount } from 'svelte'
import './theme.css'
import './base.css'
import './app.css'
import App from './App.svelte'
import { themes } from './lib/themes'
// Apply saved theme before mounting app
// Apply saved theme before mounting app to prevent flash
const STORAGE_KEY = 'editorSettings';
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
try {
const settings = JSON.parse(stored);
if (settings.theme) {
document.documentElement.dataset.theme = settings.theme;
if (settings.theme && themes[settings.theme]) {
const theme = themes[settings.theme];
const root = document.documentElement.style;
root.setProperty('--bg-color', theme.colors.background);
root.setProperty('--surface-color', theme.colors.surface);
root.setProperty('--border-color', theme.colors.border);
root.setProperty('--text-color', theme.colors.text);
root.setProperty('--text-secondary', theme.colors.textSecondary);
root.setProperty('--accent-color', theme.colors.accent);
root.setProperty('--accent-hover', theme.colors.accentHover);
root.setProperty('--input-bg', theme.colors.input);
root.setProperty('--input-border', theme.colors.inputBorder);
root.setProperty('--button-bg', theme.colors.button);
root.setProperty('--button-hover', theme.colors.buttonHover);
root.setProperty('--danger-color', theme.colors.danger);
root.setProperty('--danger-hover', theme.colors.dangerHover);
root.setProperty('--editor-background', theme.editor.background);
root.setProperty('--editor-foreground', theme.editor.foreground);
root.setProperty('--editor-caret', theme.editor.caret);
root.setProperty('--editor-selection', theme.editor.selection);
root.setProperty('--editor-active-line', theme.editor.activeLine);
root.setProperty('--editor-gutter', theme.editor.gutter);
root.setProperty('--editor-gutter-text', theme.editor.gutterText);
root.setProperty('--editor-active-line-gutter', theme.editor.activeLineGutter);
root.setProperty('--editor-line-number', theme.editor.lineNumber);
root.setProperty('--syntax-keyword', theme.syntax.keyword);
root.setProperty('--syntax-operator', theme.syntax.operator);
root.setProperty('--syntax-string', theme.syntax.string);
root.setProperty('--syntax-number', theme.syntax.number);
root.setProperty('--syntax-boolean', theme.syntax.boolean);
root.setProperty('--syntax-comment', theme.syntax.comment);
root.setProperty('--syntax-function', theme.syntax.function);
root.setProperty('--syntax-class', theme.syntax.class);
root.setProperty('--syntax-variable', theme.syntax.variable);
root.setProperty('--syntax-property', theme.syntax.property);
root.setProperty('--syntax-constant', theme.syntax.constant);
root.setProperty('--syntax-type', theme.syntax.type);
root.setProperty('--syntax-tag', theme.syntax.tag);
root.setProperty('--syntax-attribute', theme.syntax.attribute);
}
} catch (e) {
console.error('Failed to parse editor settings:', e);

View File

@ -1,169 +0,0 @@
/* Theme System */
/* Dark Theme - Default */
:root,
[data-theme="dark"] {
/* Base Colors */
--color-bg-base: #1a1a1a;
--color-bg-elevated: #242424;
--color-bg-overlay: #2a2a2a;
--color-bg-input: #1e1e1e;
/* Surface Colors */
--color-surface-0: #1a1a1a;
--color-surface-1: #202020;
--color-surface-2: #252525;
--color-surface-3: #2a2a2a;
/* Text Colors */
--color-text-primary: rgba(255, 255, 255, 0.87);
--color-text-secondary: rgba(255, 255, 255, 0.6);
--color-text-tertiary: rgba(255, 255, 255, 0.4);
--color-text-disabled: rgba(255, 255, 255, 0.25);
/* Accent Colors */
--color-accent-primary: #646cff;
--color-accent-primary-hover: #818cf8;
--color-accent-primary-active: #535bf2;
--color-accent-primary-subtle: rgba(100, 108, 255, 0.1);
/* Semantic Colors */
--color-success: #10b981;
--color-warning: #fbbf24;
--color-error: #ef4444;
--color-info: #60a5fa;
/* Border Colors */
--color-border-subtle: rgba(255, 255, 255, 0.06);
--color-border-default: rgba(255, 255, 255, 0.1);
--color-border-strong: rgba(255, 255, 255, 0.2);
--color-border-accent: var(--color-accent-primary);
/* Interactive States */
--color-hover-overlay: rgba(255, 255, 255, 0.05);
--color-active-overlay: rgba(255, 255, 255, 0.08);
--color-selected-overlay: rgba(100, 108, 255, 0.15);
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.3);
--shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.4);
/* Component Specific */
--accordion-header-bg: transparent;
--accordion-header-hover: var(--color-hover-overlay);
--accordion-border: var(--color-border-subtle);
--input-bg: var(--color-bg-input);
--input-border: var(--color-border-default);
--input-border-focus: var(--color-accent-primary);
--tooltip-bg: rgba(32, 32, 32, 0.98);
--tooltip-border: var(--color-border-default);
--code-bg: transparent;
--code-border: var(--color-border-subtle);
--code-text: var(--color-text-secondary);
}
/* Light Theme */
[data-theme="light"] {
/* Base Colors */
--color-bg-base: #fafafa;
--color-bg-elevated: #ffffff;
--color-bg-overlay: #f5f5f5;
--color-bg-input: #ffffff;
/* Surface Colors */
--color-surface-0: #fafafa;
--color-surface-1: #ffffff;
--color-surface-2: #f5f5f5;
--color-surface-3: #eeeeee;
/* Text Colors */
--color-text-primary: rgba(0, 0, 0, 0.87);
--color-text-secondary: rgba(0, 0, 0, 0.6);
--color-text-tertiary: rgba(0, 0, 0, 0.4);
--color-text-disabled: rgba(0, 0, 0, 0.25);
/* Accent Colors */
--color-accent-primary: #5865f2;
--color-accent-primary-hover: #4752c4;
--color-accent-primary-active: #3c45a5;
--color-accent-primary-subtle: rgba(88, 101, 242, 0.1);
/* Semantic Colors */
--color-success: #059669;
--color-warning: #d97706;
--color-error: #dc2626;
--color-info: #2563eb;
/* Border Colors */
--color-border-subtle: rgba(0, 0, 0, 0.08);
--color-border-default: rgba(0, 0, 0, 0.12);
--color-border-strong: rgba(0, 0, 0, 0.24);
--color-border-accent: var(--color-accent-primary);
/* Interactive States */
--color-hover-overlay: rgba(0, 0, 0, 0.04);
--color-active-overlay: rgba(0, 0, 0, 0.08);
--color-selected-overlay: rgba(88, 101, 242, 0.12);
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.12);
--shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.15);
/* Component Specific */
--accordion-header-bg: transparent;
--accordion-header-hover: var(--color-hover-overlay);
--accordion-border: var(--color-border-subtle);
--input-bg: var(--color-bg-input);
--input-border: var(--color-border-default);
--input-border-focus: var(--color-accent-primary);
--tooltip-bg: rgba(255, 255, 255, 0.98);
--tooltip-border: var(--color-border-default);
--code-bg: transparent;
--code-border: var(--color-border-subtle);
--code-text: var(--color-text-secondary);
}
/* Shared Variables */
:root {
/* Spacing Scale */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 0.75rem;
--space-lg: 1rem;
--space-xl: 1.5rem;
--space-2xl: 2rem;
/* Border Radius */
--radius-sm: 2px;
--radius-md: 4px;
--radius-lg: 6px;
/* Font Sizes */
--font-xs: 0.6875rem;
--font-sm: 0.75rem;
--font-md: 0.8125rem;
--font-base: 0.875rem;
--font-lg: 1rem;
/* Font Families */
--font-mono: 'Courier New', Monaco, Consolas, monospace;
--font-sans: system-ui, -apple-system, sans-serif;
/* Line Heights */
--leading-tight: 1.4;
--leading-normal: 1.5;
--leading-relaxed: 1.6;
/* Transitions */
--transition-fast: 100ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
}