Dynamic Theme Update

This commit is contained in:
2025-11-28 19:44:11 +00:00
parent c29ad517c5
commit e7fa0547b7
26 changed files with 116 additions and 53 deletions

View File

@@ -52,12 +52,13 @@
} }
.cursor { .cursor {
width: 8px; width: 0.5em;
height: 1em; height: 1.1em;
background: var(--nav-primary); background: var(--nav-primary);
animation: blink 1s step-end infinite; animation: blink 1s step-end infinite;
margin-left: 0.25rem; margin-left: 0.25rem;
vertical-align: text-bottom; vertical-align: baseline;
transform: translateY(0.15em);
} }
@keyframes blink { @keyframes blink {

View File

@@ -191,12 +191,13 @@
.cursor { .cursor {
display: inline-block; display: inline-block;
width: 8px; width: 0.5em;
height: 1em; height: 1.1em;
background: var(--terminal-primary); background: var(--terminal-primary);
animation: cursorBlink 1s step-end infinite; animation: cursorBlink 1s step-end infinite;
margin-left: 2px; margin-left: 2px;
vertical-align: text-bottom; vertical-align: baseline;
transform: translateY(0.15em);
} }
@keyframes cursorBlink { @keyframes cursorBlink {

View File

@@ -151,12 +151,13 @@
.cursor { .cursor {
display: inline-block; display: inline-block;
width: 8px; width: 0.5em;
height: 1em; height: 1.1em;
background: var(--terminal-primary); background: var(--terminal-primary);
animation: cursorBlink 1s step-end infinite; animation: cursorBlink 1s step-end infinite;
margin-left: 2px; margin-left: 2px;
vertical-align: text-bottom; vertical-align: baseline;
transform: translateY(0.15em);
} }
@keyframes cursorBlink { @keyframes cursorBlink {

View File

@@ -195,12 +195,13 @@
/* Cursor */ /* Cursor */
.cursor { .cursor {
display: inline-block; display: inline-block;
width: 8px; width: 0.5em;
height: 1em; height: 1.1em;
background: var(--terminal-primary); background: var(--terminal-primary);
animation: cursorBlink 1s step-end infinite; animation: cursorBlink 1s step-end infinite;
margin-left: 2px; margin-left: 2px;
vertical-align: text-bottom; vertical-align: baseline;
transform: translateY(0.15em);
} }
@keyframes cursorBlink { @keyframes cursorBlink {

View File

@@ -38,9 +38,6 @@
"mauve": "#cea5fb", "mauve": "#cea5fb",
"flamingo": "#e06c75", "flamingo": "#e06c75",
"rosewater": "#e8b4b8", "rosewater": "#e8b4b8",
"primary": "var(--terminal-primary)",
"accent": "var(--terminal-accent)",
"muted": "var(--terminal-muted)",
"error": "#fa7970", "error": "#fa7970",
"success": "#23d18b", "success": "#23d18b",
"warning": "#faa356", "warning": "#faa356",
@@ -84,9 +81,6 @@
"mauve": "#602090", "mauve": "#602090",
"flamingo": "#901040", "flamingo": "#901040",
"rosewater": "#a05040", "rosewater": "#a05040",
"primary": "var(--terminal-primary)",
"accent": "var(--terminal-accent)",
"muted": "var(--terminal-muted)",
"error": "#a6101d", "error": "#a6101d",
"success": "#005a2b", "success": "#005a2b",
"warning": "#945b00", "warning": "#945b00",

View File

@@ -38,9 +38,6 @@
"mauve": "#cba6f7", "mauve": "#cba6f7",
"flamingo": "#f2cdcd", "flamingo": "#f2cdcd",
"rosewater": "#f5e0dc", "rosewater": "#f5e0dc",
"primary": "var(--terminal-primary)",
"accent": "var(--terminal-accent)",
"muted": "var(--terminal-muted)",
"error": "#f38ba8", "error": "#f38ba8",
"success": "#a6e3a1", "success": "#a6e3a1",
"warning": "#f9e2af", "warning": "#f9e2af",
@@ -84,9 +81,6 @@
"mauve": "#8839ef", "mauve": "#8839ef",
"flamingo": "#dd7878", "flamingo": "#dd7878",
"rosewater": "#dc8a78", "rosewater": "#dc8a78",
"primary": "var(--terminal-primary)",
"accent": "var(--terminal-accent)",
"muted": "var(--terminal-muted)",
"error": "#d20f39", "error": "#d20f39",
"success": "#40a02b", "success": "#40a02b",
"warning": "#df8e1d", "warning": "#df8e1d",

View File

@@ -2,7 +2,7 @@
import { mode, colorTheme, toggleMode, setColorTheme, themeOptions, themeColors, type ColorTheme } from '$lib/stores/theme'; import { mode, colorTheme, toggleMode, setColorTheme, themeOptions, themeColors, type ColorTheme } from '$lib/stores/theme';
import { page } from '$app/stores'; import { page } from '$app/stores';
import { fly, fade, slide } from 'svelte/transition'; import { fly, fade, slide } from 'svelte/transition';
import { user, navigation, colorPalette } from '$lib/config'; import { user, navigation } from '$lib/config';
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { onMount, onDestroy } from 'svelte'; import { onMount, onDestroy } from 'svelte';
import '$lib/assets/css/navbar-waybar.css'; import '$lib/assets/css/navbar-waybar.css';
@@ -100,9 +100,9 @@
--bar-primary: {$themeColors.primary}; --bar-primary: {$themeColors.primary};
--bar-accent: {$themeColors.accent}; --bar-accent: {$themeColors.accent};
--bar-muted: {$themeColors.textMuted}; --bar-muted: {$themeColors.textMuted};
--bar-success: {colorPalette.success}; --bar-success: {$themeColors.colorMap.success};
--bar-warning: {colorPalette.warning}; --bar-warning: {$themeColors.colorMap.warning};
--bar-error: {colorPalette.error}; --bar-error: {$themeColors.colorMap.error};
" "
> >
<!-- Left modules --> <!-- Left modules -->

View File

@@ -117,7 +117,9 @@
--terminal-user: {$themeColors.terminalUser}; --terminal-user: {$themeColors.terminalUser};
--terminal-path: {$themeColors.terminalPath}; --terminal-path: {$themeColors.terminalPath};
--terminal-primary: {$themeColors.primary}; --terminal-primary: {$themeColors.primary};
--terminal-secondary: {$themeColors.secondary};
--terminal-accent: {$themeColors.accent}; --terminal-accent: {$themeColors.accent};
--terminal-bg-light: {$themeColors.backgroundLight};
" "
bind:this={terminalElement} bind:this={terminalElement}
> >

View File

@@ -152,6 +152,7 @@
--terminal-user: {$themeColors.terminalUser}; --terminal-user: {$themeColors.terminalUser};
--terminal-path: {$themeColors.terminalPath}; --terminal-path: {$themeColors.terminalPath};
--terminal-primary: {$themeColors.primary}; --terminal-primary: {$themeColors.primary};
--terminal-secondary: {$themeColors.secondary};
--terminal-accent: {$themeColors.accent}; --terminal-accent: {$themeColors.accent};
--terminal-bg-light: {$themeColors.backgroundLight}; --terminal-bg-light: {$themeColors.backgroundLight};
" "

View File

@@ -38,10 +38,13 @@
typeof speed === 'number' ? speed : (speedPresets[speed] ?? 1) typeof speed === 'number' ? speed : (speedPresets[speed] ?? 1)
); );
// Get colorMap from current theme
const colorMap = $derived($themeColors.colorMap);
// Pre-parse all lines upfront (segments + plain text) // Pre-parse all lines upfront (segments + plain text)
const parsedLines = $derived<ParsedLine[]>( const parsedLines = $derived<ParsedLine[]>(
lines.map(line => { lines.map(line => {
const segments = parseColorText(line.content); const segments = parseColorText(line.content, colorMap);
return { return {
line, line,
segments, segments,
@@ -337,6 +340,7 @@
--terminal-user: {$themeColors.terminalUser}; --terminal-user: {$themeColors.terminalUser};
--terminal-path: {$themeColors.terminalPath}; --terminal-path: {$themeColors.terminalPath};
--terminal-primary: {$themeColors.primary}; --terminal-primary: {$themeColors.primary};
--terminal-secondary: {$themeColors.secondary};
--terminal-accent: {$themeColors.accent}; --terminal-accent: {$themeColors.accent};
--terminal-bg-light: {$themeColors.backgroundLight}; --terminal-bg-light: {$themeColors.backgroundLight};
" "

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import '$lib/assets/css/tui-accordion.css'; import '$lib/assets/css/tui-accordion.css';
@@ -22,7 +23,7 @@
<div class="tui-accordion" style="--accordion-accent: {getButtonStyle(line.style)}"> <div class="tui-accordion" style="--accordion-accent: {getButtonStyle(line.style)}">
{#each items as item, i} {#each items as item, i}
{@const contentSegments = parseColorText(item.content)} {@const contentSegments = parseColorText(item.content, $themeColors.colorMap)}
<div class="accordion-item" class:open={openItems.has(i)}> <div class="accordion-item" class:open={openItems.has(i)}>
<button class="accordion-header" on:click={() => toggleItem(i)}> <button class="accordion-header" on:click={() => toggleItem(i)}>
<Icon <Icon

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import '$lib/assets/css/tui-button.css'; import '$lib/assets/css/tui-button.css';
@@ -14,8 +15,8 @@
// Determine if this is an external link // Determine if this is an external link
$: isExternal = line.external || (line.href && (line.href.startsWith('http://') || line.href.startsWith('https://'))); $: isExternal = line.external || (line.href && (line.href.startsWith('http://') || line.href.startsWith('https://')));
// Parse color formatting in content // Parse color formatting in content using theme colorMap
$: segments = parseColorText(line.content); $: segments = parseColorText(line.content, $themeColors.colorMap);
</script> </script>
<button <button

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-checkbox.css'; import '$lib/assets/css/tui-checkbox.css';
@@ -13,7 +14,7 @@
change: boolean; change: boolean;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;
$: indeterminate = line.checkboxIndeterminate || false; $: indeterminate = line.checkboxIndeterminate || false;

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-input.css'; import '$lib/assets/css/tui-input.css';
@@ -16,7 +17,7 @@
blur: void; blur: void;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: placeholder = line.inputPlaceholder || ''; $: placeholder = line.inputPlaceholder || '';
$: inputType = line.inputType || 'text'; $: inputType = line.inputType || 'text';
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import '$lib/assets/css/tui-link.css'; import '$lib/assets/css/tui-link.css';
@@ -10,8 +11,8 @@
// Determine if this is an external link // Determine if this is an external link
$: isExternal = line.external || (line.href && (line.href.startsWith('http://') || line.href.startsWith('https://'))); $: isExternal = line.external || (line.href && (line.href.startsWith('http://') || line.href.startsWith('https://')));
// Parse color formatting in content // Parse color formatting in content using theme colorMap
$: segments = parseColorText(line.content); $: segments = parseColorText(line.content, $themeColors.colorMap);
</script> </script>
<span class="tui-link" style="--link-color: {getButtonStyle(line.style)}"> <span class="tui-link" style="--link-color: {getButtonStyle(line.style)}">

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import '$lib/assets/css/tui-progress.css'; import '$lib/assets/css/tui-progress.css';
@@ -9,8 +10,8 @@
$: progress = Math.min(100, Math.max(0, line.progress ?? 0)); $: progress = Math.min(100, Math.max(0, line.progress ?? 0));
$: label = line.progressLabel || `${progress}%`; $: label = line.progressLabel || `${progress}%`;
$: contentSegments = parseColorText(line.content); $: contentSegments = parseColorText(line.content, $themeColors.colorMap);
$: labelSegments = parseColorText(label); $: labelSegments = parseColorText(label, $themeColors.colorMap);
</script> </script>
<div class="tui-progress" class:inline={inline} style="--progress-color: {getButtonStyle(line.style)}"> <div class="tui-progress" class:inline={inline} style="--progress-color: {getButtonStyle(line.style)}">

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine, FormOption } from './types'; import type { TerminalLine, FormOption } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-radio.css'; import '$lib/assets/css/tui-radio.css';
@@ -13,7 +14,7 @@
change: string; change: string;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: options = line.radioOptions || []; $: options = line.radioOptions || [];
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;
$: isHorizontal = line.radioHorizontal || false; $: isHorizontal = line.radioHorizontal || false;
@@ -63,7 +64,7 @@
<div class="radio-options" class:horizontal={isHorizontal}> <div class="radio-options" class:horizontal={isHorizontal}>
{#each options as option} {#each options as option}
{@const isSelected = value === option.value} {@const isSelected = value === option.value}
{@const optionSegments = parseColorText(option.label)} {@const optionSegments = parseColorText(option.label, $themeColors.colorMap)}
<div <div
class="radio-option" class="radio-option"
class:selected={isSelected} class:selected={isSelected}

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine, FormOption } from './types'; import type { TerminalLine, FormOption } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-select.css'; import '$lib/assets/css/tui-select.css';
@@ -15,7 +16,7 @@
blur: void; blur: void;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: options = line.selectOptions || []; $: options = line.selectOptions || [];
$: placeholder = line.inputPlaceholder || 'Select an option...'; $: placeholder = line.inputPlaceholder || 'Select an option...';
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;

View File

@@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import '$lib/assets/css/tui-table.css'; import '$lib/assets/css/tui-table.css';
@@ -27,7 +28,7 @@
{#each rows as row, i} {#each rows as row, i}
<tr class:alt={i % 2 === 1}> <tr class:alt={i % 2 === 1}>
{#each row as cell} {#each row as cell}
{@const cellSegments = parseColorText(cell)} {@const cellSegments = parseColorText(cell, $themeColors.colorMap)}
<td> <td>
{#each cellSegments as segment} {#each cellSegments as segment}
{#if getSegmentStyle(segment)} {#if getSegmentStyle(segment)}

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-textarea.css'; import '$lib/assets/css/tui-textarea.css';
@@ -16,7 +17,7 @@
blur: void; blur: void;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: placeholder = line.inputPlaceholder || ''; $: placeholder = line.inputPlaceholder || '';
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;
$: hasError = line.inputError; $: hasError = line.inputError;

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import { getButtonStyle, parseColorText, getSegmentStyle } from './utils'; import { getButtonStyle, parseColorText, getSegmentStyle } from './utils';
import { themeColors } from '$lib/stores/theme';
import type { TerminalLine } from './types'; import type { TerminalLine } from './types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import '$lib/assets/css/tui-toggle.css'; import '$lib/assets/css/tui-toggle.css';
@@ -13,7 +14,7 @@
change: boolean; change: boolean;
}>(); }>();
$: labelSegments = line.content ? parseColorText(line.content) : []; $: labelSegments = line.content ? parseColorText(line.content, $themeColors.colorMap) : [];
$: isDisabled = line.inputDisabled || false; $: isDisabled = line.inputDisabled || false;
$: onLabel = line.toggleOnLabel || 'ON'; $: onLabel = line.toggleOnLabel || 'ON';
$: offLabel = line.toggleOffLabel || 'OFF'; $: offLabel = line.toggleOffLabel || 'OFF';

View File

@@ -21,8 +21,9 @@ export interface TextSegment {
// Color maps for each theme // Color maps for each theme
export type ThemeColorMap = Record<string, string>; export type ThemeColorMap = Record<string, string>;
// Default color map (fallback) // Default color map (fallback) - includes theme colors for backwards compatibility
export const defaultColorMap: ThemeColorMap = { export const defaultColorMap: ThemeColorMap = {
// Basic colors
'red': '#f38ba8', 'red': '#f38ba8',
'green': '#a6e3a1', 'green': '#a6e3a1',
'yellow': '#f9e2af', 'yellow': '#f9e2af',
@@ -35,6 +36,17 @@ export const defaultColorMap: ThemeColorMap = {
'pink': '#f5c2e7', 'pink': '#f5c2e7',
'black': '#1e1e2e', 'black': '#1e1e2e',
'surface': '#313244', 'surface': '#313244',
// Catppuccin extended colors
'teal': '#94e2d5',
'sky': '#89dceb',
'sapphire': '#74c7ec',
'lavender': '#b4befe',
'peach': '#fab387',
'maroon': '#eba0ac',
'mauve': '#cba6f7',
'flamingo': '#f2cdcd',
'rosewater': '#f5e0dc',
// Semantic colors
'primary': 'var(--terminal-primary)', 'primary': 'var(--terminal-primary)',
'accent': 'var(--terminal-accent)', 'accent': 'var(--terminal-accent)',
'muted': 'var(--terminal-muted)', 'muted': 'var(--terminal-muted)',
@@ -42,6 +54,16 @@ export const defaultColorMap: ThemeColorMap = {
'success': '#a6e3a1', 'success': '#a6e3a1',
'warning': '#f9e2af', 'warning': '#f9e2af',
'info': '#89b4fa', 'info': '#89b4fa',
// Theme colors (for using text, textMuted, etc. in formatter)
'text': '#cdd6f4',
'textMuted': '#a6adc8',
'background': '#1e1e2e',
'backgroundLight': '#313244',
'border': '#45475a',
'terminal': '#1e1e2e',
'terminalPrompt': '#cba6f7',
'terminalUser': '#a6e3a1',
'terminalPath': '#89b4fa',
}; };
// Legacy alias for backwards compatibility // Legacy alias for backwards compatibility

View File

@@ -15,7 +15,7 @@ export interface Project {
export const projects: Project[] = [ export const projects: Project[] = [
{ {
name: 'PokemonTCGAPI', name: 'PokemonTCGAPI',
description: 'Official NPM package wrapper for the PokemonTCG API — utilities and helpers for working with Pokemon TCG data.', description: 'UnOfficial NPM package wrapper for the PokemonTCG API.',
tech: ['TypeScript', 'Node.js'], tech: ['TypeScript', 'Node.js'],
live: 'https://www.npmjs.com/package/@bosstop/pokemontcgapi', live: 'https://www.npmjs.com/package/@bosstop/pokemontcgapi',
image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png', image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png',
@@ -23,7 +23,7 @@ export const projects: Project[] = [
}, },
{ {
name: 'MCSS TS API', name: 'MCSS TS API',
description: 'TypeScript API for MCServersSoft services, published to NPM.', description: 'TypeScript API for MC Server Soft services, published to NPM.',
tech: ['TypeScript', 'Node.js'], tech: ['TypeScript', 'Node.js'],
live: 'https://www.npmjs.com/package/@mcserversoft/mcss-api', live: 'https://www.npmjs.com/package/@mcserversoft/mcss-api',
image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png', image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png',
@@ -35,7 +35,7 @@ export const projects: Project[] = [
tech: ['TypeScript', 'Selenium'], tech: ['TypeScript', 'Selenium'],
live: 'https://www.npmjs.com/package/@sirblob/mcp-selenium', live: 'https://www.npmjs.com/package/@sirblob/mcp-selenium',
image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png', image: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/1200px-Npm-logo.svg.png',
featured: false featured: true
}, },
{ {
name: 'Pkit', name: 'Pkit',

View File

@@ -1,8 +1,9 @@
// ============================================================================ // ============================================================================
// COLOR PALETTE // COLOR PALETTE (DEPRECATED)
// ============================================================================ // ============================================================================
// These colors are used for terminal text formatting and UI elements // NOTE: This is deprecated. Use themeColors.colorMap from $lib/stores/theme instead.
// Colors follow Catppuccin Mocha theme by default // The colorMap in theme JSON files is the source of truth and supports dynamic themes.
// This is kept for backward compatibility only.
export const colorPalette = { export const colorPalette = {
// Basic colors // Basic colors

View File

@@ -30,4 +30,12 @@ export const lines: TerminalLine[] = [
inline: true inline: true
})), })),
{ type: 'blank', content: '' }, { type: 'blank', content: '' },
{ type: 'divider', content: 'Website Keybinds' },
{ type: 'blank', content: '' },
{ type: 'output', content: '(&orange)Toggle Light/Dark Mode(&) (&text, bold)(T)(&)' , inline: true },
{ type: 'output', content: '(&muted)•(&)' , inline: true },
{ type: 'output', content: '(&orange)Skip typing animation(&) (&text, bold)(Y)(&)' , inline: true },
{ type: 'output', content: '(&muted)•(&)' , inline: true },
{ type: 'output', content: '(&orange)Open/Close Navbar(&) (&text, bold)(N)(&)' , inline: true },
{ type: 'blank', content: '' },
]; ];

View File

@@ -48,9 +48,31 @@ const themes: Record<ColorTheme, ThemeJson> = {
// Export themes for external access // Export themes for external access
export { themes }; export { themes };
// Build theme colors from JSON // CSS variable mappings for theme colors - these update dynamically with mode changes
const themeColorVars: Record<string, string> = {
'primary': 'var(--terminal-primary)',
'secondary': 'var(--terminal-secondary)',
'accent': 'var(--terminal-accent)',
'background': 'var(--terminal-bg)',
'backgroundLight': 'var(--terminal-bg-light)',
'text': 'var(--terminal-text)',
'textMuted': 'var(--terminal-muted)',
'border': 'var(--terminal-border)',
'terminal': 'var(--terminal-bg)',
'terminalPrompt': 'var(--terminal-prompt)',
'terminalUser': 'var(--terminal-user)',
'terminalPath': 'var(--terminal-path)',
};
// Build theme colors from JSON - merges colors into colorMap so formatter can use both
function buildThemeColors(theme: ThemeJson, mode: Mode): ThemeColors { function buildThemeColors(theme: ThemeJson, mode: Mode): ThemeColors {
const modeData = theme[mode]; const modeData = theme[mode];
// Merge colors and colorMap - use CSS variables for theme colors so they update dynamically
const mergedColorMap: ThemeColorMap = {
...defaultColorMap, // Fallback defaults
...(modeData.colorMap ?? {}), // Theme's color palette
...themeColorVars // Theme colors as CSS variables - update with mode changes
};
return { return {
primary: modeData.colors.primary, primary: modeData.colors.primary,
secondary: modeData.colors.secondary, secondary: modeData.colors.secondary,
@@ -64,7 +86,7 @@ function buildThemeColors(theme: ThemeJson, mode: Mode): ThemeColors {
terminalPrompt: modeData.colors.terminalPrompt, terminalPrompt: modeData.colors.terminalPrompt,
terminalUser: modeData.colors.terminalUser, terminalUser: modeData.colors.terminalUser,
terminalPath: modeData.colors.terminalPath, terminalPath: modeData.colors.terminalPath,
colorMap: modeData.colorMap ?? defaultColorMap colorMap: mergedColorMap
}; };
} }