Merge pull request #964 from willmiao/design-token-system

Design token system phase1
This commit is contained in:
pixelpaws
2026-06-09 11:38:31 +08:00
committed by GitHub
32 changed files with 661 additions and 294 deletions

View File

@@ -1,21 +1,20 @@
@import 'tokens/index.css';
html,
body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
/* Disable default scrolling */
}
/* 针对Firefox */
* {
scrollbar-width: thin;
scrollbar-color: var(--border-color) transparent;
scrollbar-color: var(--border-base) transparent;
}
/* 针对Webkit browsers (Chrome, Safari等) */
::-webkit-scrollbar {
width: 8px;
width: var(--scrollbar-width, 8px);
}
::-webkit-scrollbar-track {
@@ -24,116 +23,128 @@ body {
}
::-webkit-scrollbar-thumb {
background-color: var(--border-color);
border-radius: 4px;
background-color: var(--border-base);
border-radius: var(--radius-xs);
}
:root {
--bg-color: #ffffff;
--text-color: #333333;
--text-muted: #6c757d;
--card-bg: #ffffff;
--border-color: #e0e0e0;
--header-height: 48px;
/* Color Components */
--lora-accent-l: 68%;
--lora-accent-c: 0.28;
--lora-accent-h: 256;
--lora-warning-l: 75%;
--lora-warning-c: 0.25;
--lora-warning-h: 80;
--lora-success-l: 70%;
--lora-success-c: 0.2;
--lora-success-h: 140;
/* Composed Colors */
--lora-accent: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h));
--lora-surface: oklch(97% 0 0 / 0.95);
--lora-border: oklch(72% 0.03 256 / 0.45);
--lora-text: oklch(95% 0.02 256);
--lora-error: oklch(75% 0.32 29);
--lora-error-bg: color-mix(in oklch, var(--lora-error) 20%, transparent);
--lora-error-border: color-mix(in oklch, var(--lora-error) 50%, transparent);
--lora-warning: oklch(var(--lora-warning-l) var(--lora-warning-c) var(--lora-warning-h));
--lora-success: oklch(var(--lora-success-l) var(--lora-success-c) var(--lora-success-h));
--badge-update-bg: oklch(72% 0.2 220);
--badge-update-text: oklch(28% 0.03 220);
--badge-update-glow: oklch(72% 0.2 220 / 0.28);
--badge-skip-refresh-bg: oklch(82% 0.12 45);
--badge-skip-refresh-text: oklch(35% 0.02 45);
--badge-skip-refresh-glow: oklch(82% 0.12 45 / 0.15);
/* Spacing Scale */
--space-1: calc(8px * 1);
--space-2: calc(8px * 2);
--space-3: calc(8px * 3);
--space-4: calc(8px * 4);
/* Z-index Scale */
--z-base: 10;
--z-header: 100;
--z-modal: 1000;
--z-overlay: 2000;
/* Border Radius */
--border-radius-base: 12px;
--border-radius-md: 12px;
--border-radius-sm: 8px;
--border-radius-xs: 4px;
--scrollbar-width: 8px;
/* 添加滚动条宽度变量 */
/* Shortcut styles */
--shortcut-bg: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.12);
--shortcut-border: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.25);
--shortcut-text: var(--text-color);
--shortcut-bg: var(--color-accent-subtle);
--shortcut-border: var(--color-accent-border);
--shortcut-text: var(--text-primary);
--lora-accent-transparent: var(--color-accent-transparent);
/* Legacy spacing aliases: 8px base grid to match existing component usage */
--space-1: 8px;
--space-2: 16px;
--space-3: 24px;
--space-4: 32px;
/* Legacy border-radius aliases to match existing component usage */
--border-radius-xs: 4px;
--border-radius-sm: 6px;
--border-radius-base: 8px;
--border-radius-md: 12px;
--border-radius-lg: 16px;
}
:root {
--bg-color: var(--bg-base);
--text-color: var(--text-primary);
--text-muted: var(--text-secondary);
--card-bg: var(--surface-base);
--border-color: var(--border-base);
--lora-accent: var(--color-accent);
--lora-surface: var(--bg-elevated);
--lora-border: var(--border-subtle);
--lora-text: var(--text-primary);
--lora-error: var(--color-error);
--lora-error-bg: var(--color-error-bg);
--lora-error-border: var(--color-error-border);
--lora-warning: var(--color-warning);
--lora-success: var(--color-success);
--badge-update-bg: var(--color-info-bg);
--badge-update-text: var(--color-info-text);
--badge-update-glow: var(--color-info-glow);
--badge-skip-refresh-bg: var(--color-skip-refresh-bg);
--badge-skip-refresh-text: var(--color-skip-refresh-text);
--badge-skip-refresh-glow: var(--color-skip-refresh-glow);
}
[data-theme="dark"] {
--bg-color: var(--bg-base);
--text-color: var(--text-primary);
--text-muted: var(--text-secondary);
--card-bg: var(--surface-base);
--border-color: var(--border-base);
--lora-accent: var(--color-accent);
--lora-surface: var(--bg-elevated);
--lora-border: var(--border-subtle);
--lora-text: var(--text-primary);
--lora-error: var(--color-error);
--lora-error-bg: var(--color-error-bg);
--lora-error-border: var(--color-error-border);
--lora-warning: var(--color-warning);
--lora-success: var(--color-success);
--badge-update-bg: var(--color-info-bg);
--badge-update-text: var(--color-info-text);
--badge-update-glow: var(--color-info-glow);
--badge-skip-refresh-bg: var(--color-skip-refresh-bg);
--badge-skip-refresh-text: var(--color-skip-refresh-text);
--badge-skip-refresh-glow: var(--color-skip-refresh-glow);
}
html[data-theme="dark"] {
background-color: #1a1a1a !important;
background-color: var(--bg-base) !important;
color-scheme: dark;
}
html[data-theme="light"] {
background-color: #ffffff !important;
background-color: var(--bg-base) !important;
color-scheme: light;
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
--text-muted: #a0a0a0;
--card-bg: #2d2d2d;
--border-color: #404040;
--lora-accent: oklch(68% 0.28 256);
--lora-surface: oklch(25% 0.02 256 / 0.98);
--lora-border: oklch(90% 0.02 256 / 0.15);
--lora-text: oklch(98% 0.02 256);
--lora-warning: oklch(75% 0.25 80);
/* Modified to be used with oklch() */
--lora-error-bg: color-mix(in oklch, var(--lora-error) 15%, transparent);
--lora-error-border: color-mix(in oklch, var(--lora-error) 40%, transparent);
--badge-update-bg: oklch(62% 0.18 220);
--badge-update-text: oklch(98% 0.02 240);
--badge-update-glow: oklch(62% 0.18 220 / 0.4);
--badge-skip-refresh-bg: oklch(82% 0.12 45);
--badge-skip-refresh-text: oklch(98% 0.02 45);
--badge-skip-refresh-glow: oklch(82% 0.12 45 / 0.15);
}
body {
font-family: 'Segoe UI', sans-serif;
background: var(--bg-color);
color: var(--text-color);
font-family: var(--font-body);
background: var(--bg-base);
color: var(--text-primary);
display: flex;
flex-direction: column;
padding-top: 0;
/* Remove the padding-top */
}
.hidden {
display: none !important;
}
}
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
button:focus:not(:focus-visible),
input:focus:not(:focus-visible),
select:focus:not(:focus-visible) {
outline: none;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
html {
scroll-behavior: auto !important;
}
}

View File

@@ -1,12 +1,12 @@
/* 卡片网格布局 */
/* Card grid layout */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); /* Base size */
gap: 12px; /* Consistent gap for both row and column spacing */
row-gap: 20px; /* Increase vertical spacing between rows */
margin-top: var(--space-2);
padding-top: 4px; /* 添加顶部内边距,为悬停动画提供空间 */
padding-bottom: 4px; /* 添加底部内边距,为悬停动画提供空间 */
padding-top: 4px;
padding-bottom: 4px;
width: 100%; /* Ensure it takes full width of container */
max-width: 1400px; /* Base container width */
margin-left: auto;
@@ -353,21 +353,26 @@
}
.card-actions {
flex-shrink: 0;
display: flex;
gap: var(--space-1); /* Use gap instead of margin for spacing between icons */
align-items: center;
gap: var(--space-1);
align-items: flex-end;
align-self: flex-end;
}
.card-actions i:hover {
.card-actions i:hover,
.card-actions i:focus-visible {
opacity: 0.9;
transform: scale(1.1);
background-color: rgba(255, 255, 255, 0.1);
outline: 2px solid var(--lora-accent);
outline-offset: 2px;
border-radius: var(--border-radius-xs);
}
/* Style for active favorites */
.favorite-active {
color: #ffc107 !important; /* Gold color for favorites */
text-shadow: 0 0 5px rgba(255, 193, 7, 0.5);
color: var(--favorite-color) !important;
text-shadow: 0 0 5px var(--favorite-glow);
}
@media (max-width: 1200px) {
@@ -391,14 +396,6 @@
}
}
.card-actions {
flex-shrink: 0; /* Prevent actions from shrinking */
display: flex;
gap: var(--space-1);
align-items: flex-end; /* 将图标靠下对齐 */
align-self: flex-end; /* 将整个actions容器靠下对齐 */
}
.model-link {
margin-top: var(--space-1);
}
@@ -411,9 +408,13 @@
text-shadow: none;
}
.model-link a:hover {
.model-link a:hover,
.model-link a:focus-visible {
opacity: 0.8;
text-decoration: none;
outline: 2px solid var(--lora-accent);
outline-offset: 2px;
border-radius: var(--border-radius-xs);
}
/* Updated model name to fix text cutoff issues */
@@ -438,7 +439,7 @@
.base-model {
display: inline-block;
background: #f0f0f0;
background: var(--surface-hover, oklch(95% 0 0));
padding: 2px 6px;
border-radius: var(--border-radius-xs);
margin-right: 6px;

View File

@@ -191,9 +191,11 @@
}
.header-search .search-options-toggle:hover,
.header-search .search-filter-toggle:hover {
background: var(--lora-surface-hover, oklch(95% 0.02 256));
color: var(--lora-accent);
.header-search .search-filter-toggle:hover,
.header-search .search-filter-toggle:focus-visible {
background: var(--lora-surface-hover, oklch(95% 0.02 256));
color: var(--lora-accent);
outline: none;
}
.header-search .filter-badge {
@@ -366,9 +368,18 @@
flex-shrink: 0;
}
.hamburger-menu-btn:hover {
background: var(--lora-accent);
color: white;
.hamburger-menu-btn:hover,
.hamburger-menu-btn:focus-visible {
background: var(--lora-surface-hover, oklch(95% 0.02 256));
color: var(--lora-accent);
outline: none;
}
.hamburger-dropdown .dropdown-item:hover,
.hamburger-dropdown .dropdown-item:focus-visible {
background: var(--lora-surface-hover, oklch(95% 0.02 256));
color: var(--lora-accent);
outline: none;
}
/* Hamburger dropdown menu */

View File

@@ -18,7 +18,7 @@
border-radius: var(--border-radius-base);
text-align: center;
border: 1px solid var(--lora-border);
width: min(400px, 90vw); /* 固定最大宽度,但保持响应式 */
width: min(400px, 90vw);
}
.loading-spinner {
@@ -33,7 +33,7 @@
.loading-status {
margin-bottom: 1rem;
color: var(--text-color); /* 使用主题文本颜色 */
color: var(--text-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -42,11 +42,11 @@
}
.progress-container {
width: 280px; /* 固定进度条宽度 */
background-color: var(--lora-border); /* 使用主题边框颜色 */
width: 280px;
background-color: var(--lora-border);
border-radius: 4px;
overflow: hidden;
margin: 0 auto; /* 居中显示 */
margin: 0 auto;
}
.progress-bar {

View File

@@ -105,14 +105,14 @@
.info-item {
padding: var(--space-2);
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
}
/* 调整深色主题下的样式 */
/* Dark theme info item styles */
[data-theme="dark"] .info-item {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}
@@ -271,13 +271,13 @@
}
}
/* 修改 back-to-top 按钮样式,使其固定在 modal 内部 */
/* Back-to-top button pinned inside modal */
.modal-content .back-to-top {
position: sticky; /* 改用 sticky 定位 */
float: right; /* 使用 float 确保按钮在右侧 */
bottom: 20px; /* 距离底部的距离 */
margin-right: 20px; /* 右侧间距 */
margin-top: -56px; /* 负边距确保不占用额外空间 */
position: sticky;
float: right;
bottom: 20px;
margin-right: 20px;
margin-top: -56px;
width: 36px;
height: 36px;
border-radius: 50%;
@@ -334,7 +334,7 @@
outline: none;
}
/* 合并编辑按钮样式 */
/* Consolidated edit button styles */
.edit-model-name-btn,
.edit-file-name-btn,
.edit-base-model-btn,
@@ -369,7 +369,7 @@
.edit-base-model-btn:hover,
.edit-model-description-btn:hover,
.edit-version-name-btn:hover {
opacity: 0.8 !important;
opacity: 0.8;
background: rgba(0, 0, 0, 0.05);
}
@@ -387,7 +387,7 @@
}
.base-wrapper {
flex: 2; /* 分配更多空间给base model */
flex: 2; /* Allocate more space to base model */
}
/* Base model display and editing styles */
@@ -447,7 +447,7 @@
margin: 0;
padding: var(--space-1);
border-radius: var(--border-radius-xs);
font-size: 1.5em !important;
font-size: 1.5em;
font-weight: 600;
line-height: 1.2;
color: var(--text-color);
@@ -888,7 +888,7 @@
align-items: center;
gap: 10px;
padding: 2px 10px;
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
max-width: fit-content;
@@ -899,7 +899,7 @@
[data-theme="dark"] .creator-info,
[data-theme="dark"] .civitai-view,
[data-theme="dark"] .modal-send-btn {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}
@@ -958,7 +958,7 @@
align-items: center;
gap: 6px;
padding: 6px 12px;
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
color: var(--text-color);
@@ -981,7 +981,7 @@
align-items: center;
gap: 6px;
padding: 6px 12px;
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
color: var(--text-color);
@@ -992,7 +992,7 @@
}
[data-theme="dark"] .modal-send-btn {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}

View File

@@ -455,9 +455,9 @@
}
.import-formats {
font-size: 0.8em !important;
opacity: 0.6 !important;
margin-top: var(--space-2) !important;
font-size: 0.8em;
opacity: 0.6;
margin-top: var(--space-2);
}
.select-files-btn {
@@ -481,7 +481,7 @@
/* For dark theme */
[data-theme="dark"] .import-container {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
}
/* Setup Guidance State - When example images path is not configured */

View File

@@ -21,7 +21,7 @@
.model-tag-compact {
/* Updated styles to match info-item appearance */
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-xs);
padding: 2px 8px;
@@ -45,7 +45,7 @@
/* Adjust dark theme tag styles */
[data-theme="dark"] .model-tag-compact {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}
@@ -101,7 +101,7 @@
.tooltip-tag {
/* Updated styles to match info-item appearance */
background: rgba(0, 0, 0, 0.03);
background: var(--surface-hover);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-xs);
padding: 3px 8px;
@@ -111,7 +111,7 @@
/* Adjust dark theme tooltip tag styles */
[data-theme="dark"] .tooltip-tag {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-hover);
border: 1px solid var(--lora-border);
}

View File

@@ -1,14 +1,14 @@
/* Update Trigger Words styles */
.info-item.trigger-words {
padding: var(--space-2);
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
}
/* 调整 trigger words 样式 */
/* Trigger words styles */
[data-theme="dark"] .info-item.trigger-words {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}

View File

@@ -186,7 +186,7 @@
height: 88px;
border-radius: var(--border-radius-xs);
overflow: hidden;
background: rgba(0, 0, 0, 0.03);
background: var(--surface-hover);
display: flex;
align-items: center;
justify-content: center;

View File

@@ -21,9 +21,11 @@
background: var(--lora-surface);
}
.context-menu-item:hover {
.context-menu-item:hover,
.context-menu-item:focus-visible {
background-color: var(--lora-accent);
color: var(--lora-text);
outline: none;
}
.context-menu-separator {

View File

@@ -1,4 +1,4 @@
/* modal 基础样式 */
/* Modal base styles */
.modal {
display: none;
position: fixed;
@@ -6,19 +6,19 @@
left: 0;
width: 100%;
height: calc(100% - var(--header-height, 48px)); /* Adjust height to exclude header */
background: rgba(0, 0, 0, 0.2); /* 调整为更淡的半透明黑色 */
background: rgba(0, 0, 0, 0.2);
z-index: var(--z-modal);
overflow: auto; /* Change from hidden to auto to allow scrolling */
}
/* 当模态窗口打开时禁止body滚动 */
/* Prevent body scroll when modal is open */
body.modal-open {
position: fixed;
width: 100%;
padding-right: var(--scrollbar-width, 0px); /* 补偿滚动条消失导致的页面偏移 */
padding-right: var(--scrollbar-width, 0px);
}
/* modal-content 样式 */
/* Modal content styles */
.modal-content {
position: relative;
max-width: 800px;
@@ -29,12 +29,9 @@ body.modal-open {
border-radius: var(--border-radius-base);
padding: var(--space-3);
border: 1px solid var(--lora-border);
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06),
0 10px 15px -3px rgba(0, 0, 0, 0.05);
box-shadow: var(--shadow-md);
overflow-y: auto;
overflow-x: hidden; /* 防止水平滚动条 */
overflow-x: hidden;
scrollbar-gutter: stable both-edges; /* Reserve space to prevent layout shift when scrollbar toggles */
}
@@ -42,10 +39,10 @@ body.modal-open {
min-height: 480px;
}
/* 当 modal 打开时锁定 body */
/* Lock body when modal is open */
body.modal-open {
overflow: hidden !important; /* 覆盖 base.css 中的 scroll */
padding-right: var(--scrollbar-width, 8px); /* 使用滚动条宽度作为补偿 */
overflow: hidden !important;
padding-right: var(--scrollbar-width, 8px);
}
@keyframes modalFadeIn {
@@ -67,12 +64,18 @@ body.modal-open {
}
.cancel-btn, .delete-btn, .exclude-btn, .confirm-btn {
padding: 8px var(--space-2);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-1);
padding: var(--space-1) var(--space-2);
border-radius: var(--border-radius-sm);
border: none;
cursor: pointer;
font-weight: 500;
font-size: 0.95em;
min-width: 100px;
transition: background-color 0.2s, opacity 0.2s;
}
.cancel-btn {
@@ -92,16 +95,20 @@ body.modal-open {
color: white;
}
.cancel-btn:hover {
.cancel-btn:hover,
.cancel-btn:focus-visible {
background: var(--lora-border);
}
.delete-btn:hover {
opacity: 0.9;
.delete-btn:hover,
.delete-btn:focus-visible {
background: oklch(from var(--lora-error) l c h / 85%);
}
.exclude-btn:hover, .confirm-btn:hover {
opacity: 0.9;
.exclude-btn:hover,
.exclude-btn:focus-visible,
.confirm-btn:hover,
.confirm-btn:focus-visible {
background: oklch(from var(--lora-accent, #4f46e5) l c h / 85%);
}
@@ -125,43 +132,37 @@ body.modal-open {
z-index: 10;
}
.close:hover {
.close:hover,
.close:focus-visible {
opacity: 1;
outline: 2px solid var(--lora-accent);
outline-offset: 2px;
border-radius: var(--border-radius-xs);
}
/* 统一各个 section 的样式 */
/* Unified section styles */
.support-section,
.changelog-section,
.update-info,
.info-item,
.path-preview {
background: rgba(0, 0, 0, 0.03);
border: 1px solid rgba(0, 0, 0, 0.1);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-2);
}
/* 深色主题统一样式 */
/* Dark theme unified styles */
[data-theme="dark"] .modal-content {
background: var(--lora-surface);
border: 1px solid var(--lora-border);
}
[data-theme="dark"] .support-section,
[data-theme="dark"] .changelog-section,
[data-theme="dark"] .update-info,
[data-theme="dark"] .info-item,
[data-theme="dark"] .path-preview,
[data-theme="dark"] #bulkDownloadMissingLorasModal .bulk-download-loras-preview {
background: rgba(255, 255, 255, 0.03);
border: 1px solid var(--lora-border);
}
.primary-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
padding: var(--space-1) var(--space-2);
background-color: var(--lora-accent);
color: var(--lora-text);
border: none;
@@ -171,9 +172,11 @@ body.modal-open {
font-size: 0.95em;
}
.primary-btn:hover {
.primary-btn:hover,
.primary-btn:focus-visible {
background-color: oklch(from var(--lora-accent) l c h / 85%);
color: var(--lora-text);
outline: none;
}
/* Secondary button styles */
@@ -181,9 +184,9 @@ body.modal-open {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
padding: var(--space-1) var(--space-2);
background-color: var(--card-bg);
color: var (--text-color);
color: var(--text-color);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-sm);
cursor: pointer;
@@ -191,9 +194,11 @@ body.modal-open {
font-size: 0.95em;
}
.secondary-btn:hover {
.secondary-btn:hover,
.secondary-btn:focus-visible {
background-color: var(--border-color);
color: var(--text-color);
outline: none;
}
/* Disabled button styles */
@@ -244,7 +249,7 @@ button:disabled,
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
padding: var(--space-1) var(--space-2);
background-color: var(--lora-error);
color: white;
border: none;
@@ -254,25 +259,22 @@ button:disabled,
font-size: 0.95em;
}
.danger-btn:hover {
.danger-btn:hover,
.danger-btn:focus-visible {
background-color: oklch(from var(--lora-error) l c h / 85%);
color: white;
outline: none;
}
/* Metadata archive status styles */
.metadata-archive-status {
background: rgba(0, 0, 0, 0.03);
border: 1px solid rgba(0, 0, 0, 0.1);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-2);
margin-bottom: var(--space-2);
}
[data-theme="dark"] .metadata-archive-status {
background: rgba(255, 255, 255, 0.03);
border: 1px solid var(--lora-border);
}
.archive-status-item {
display: flex;
justify-content: space-between;
@@ -312,17 +314,12 @@ button:disabled,
}
.backup-status {
background: rgba(0, 0, 0, 0.03);
border: 1px solid rgba(0, 0, 0, 0.1);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-3);
}
[data-theme="dark"] .backup-status {
background: rgba(255, 255, 255, 0.03);
border: 1px solid var(--lora-border);
}
.backup-summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
@@ -331,17 +328,12 @@ button:disabled,
}
.backup-summary-card {
background: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(0, 0, 0, 0.06);
background: var(--lora-surface);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-2);
}
[data-theme="dark"] .backup-summary-card {
background: rgba(255, 255, 255, 0.02);
border-color: rgba(255, 255, 255, 0.05);
}
.backup-summary-label {
color: var(--text-color);
font-size: 0.85rem;
@@ -404,14 +396,9 @@ button:disabled,
}
.backup-location-details {
border: 1px solid rgba(0, 0, 0, 0.1);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
background: rgba(0, 0, 0, 0.02);
}
[data-theme="dark"] .backup-location-details {
border-color: var(--lora-border);
background: rgba(255, 255, 255, 0.02);
background: var(--surface-subtle);
}
.backup-location-details summary {
@@ -442,16 +429,12 @@ button:disabled,
max-width: 100%;
padding: 6px 8px;
border-radius: var(--border-radius-sm);
background: rgba(0, 0, 0, 0.05);
background: var(--surface-subtle);
color: var(--text-color);
overflow-wrap: anywhere;
word-break: break-word;
}
[data-theme="dark"] .backup-location-path {
background: rgba(255, 255, 255, 0.05);
}
@media (max-width: 768px) {
.backup-status-row {
grid-template-columns: 1fr;
@@ -519,8 +502,8 @@ button:disabled,
}
#bulkDownloadMissingLorasModal .bulk-download-loras-preview {
background: rgba(0, 0, 0, 0.03);
border: 1px solid rgba(0, 0, 0, 0.1);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-3);
margin-bottom: var(--space-3);
@@ -578,7 +561,7 @@ button:disabled,
align-items: flex-start;
gap: var(--space-2);
padding: var(--space-2);
background: rgba(59, 130, 246, 0.1);
background: oklch(from var(--lora-accent) l c h / 0.1);
border-radius: var(--border-radius-sm);
font-size: 0.9em;
color: var(--text-color);

View File

@@ -48,8 +48,7 @@
padding: var(--space-3);
border-radius: var(--border-radius-sm);
border: 1px solid var(--lora-border);
background: rgba(0, 0, 0, 0.03);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
}
.doctor-kicker {
@@ -128,7 +127,7 @@
.doctor-issue-card {
border: 1px solid rgba(0, 0, 0, 0.1);
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border-radius: var(--border-radius-sm);
padding: var(--space-3);
box-shadow: none;
@@ -242,7 +241,7 @@
[data-theme="dark"] .doctor-hero,
[data-theme="dark"] .doctor-issue-card {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border-color: var(--lora-border);
box-shadow: none;
}

View File

@@ -303,5 +303,5 @@
/* Dark theme adjustments */
[data-theme="dark"] .video-container {
background-color: rgba(255, 255, 255, 0.03);
background-color: var(--surface-hover);
}

View File

@@ -927,7 +927,7 @@ input:checked + .toggle-slider:before {
/* Path Template Settings Styles */
.template-preview {
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-xs);
padding: var(--space-1);
@@ -939,7 +939,7 @@ input:checked + .toggle-slider:before {
}
[data-theme="dark"] .template-preview {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}

View File

@@ -58,8 +58,6 @@
}
.support-section {
background: rgba(0, 0, 0, 0.02);
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: var(--border-radius-sm);
padding: var(--space-2);
margin-bottom: var(--space-2);
@@ -258,7 +256,7 @@
color: white; /* Icon color changes to white on hover */
}
/* 增强hover状态的视觉反馈 */
/* Enhanced hover visual feedback */
.social-link:hover,
.update-link:hover,
.folder-item:hover {

View File

@@ -171,7 +171,7 @@
/* Update progress styles */
.update-progress {
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
border-radius: var(--border-radius-sm);
padding: var(--space-2);
@@ -179,7 +179,7 @@
}
[data-theme="dark"] .update-progress {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
}
.progress-info {
@@ -234,8 +234,6 @@
/* Changelog section */
.changelog-section {
background: rgba(0, 0, 0, 0.02);
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: var(--border-radius-sm);
padding: var(--space-3);
}
@@ -429,7 +427,7 @@
}
[data-theme="dark"] .banner-history-item {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
}
.banner-history-title {

View File

@@ -67,9 +67,17 @@
position: relative;
}
.icon-button:hover {
opacity: 1;
background: rgba(0, 0, 0, 0.05);
.icon-button:hover,
.icon-button:focus-visible {
background: var(--lora-surface-hover, oklch(95% 0.02 256));
color: var(--lora-accent);
transform: scale(1.05);
outline: none;
}
[data-theme="dark"] .icon-button:hover,
[data-theme="dark"] .icon-button:focus-visible {
background: oklch(35% 0.02 256 / 0.98);
}
[data-theme="dark"] .icon-button:hover {

View File

@@ -99,7 +99,7 @@
font-size: 0.9em;
}
/* 删除不再需要的按钮样式 */
/* Remove obsolete button styles */
.editor-actions {
display: none;
}
@@ -144,7 +144,7 @@
}
.recipe-tag-compact {
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-xs);
padding: 2px 8px;
@@ -154,7 +154,7 @@
}
[data-theme="dark"] .recipe-tag-compact {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}
@@ -203,7 +203,7 @@
}
.tooltip-tag {
background: rgba(0, 0, 0, 0.03);
background: var(--surface-hover);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-xs);
padding: 3px 8px;
@@ -212,7 +212,7 @@
}
[data-theme="dark"] .tooltip-tag {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-hover);
border: 1px solid var(--lora-border);
}
@@ -251,7 +251,7 @@
align-items: center;
gap: 6px;
padding: 6px 12px;
background: rgba(0, 0, 0, 0.03);
background: var(--surface-subtle);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
color: var(--text-color);
@@ -263,7 +263,7 @@
}
[data-theme="dark"] .recipe-source-url-btn {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-subtle);
border: 1px solid var(--lora-border);
}
@@ -1114,9 +1114,9 @@
color: #777;
}
/* 标题输入框特定的样式 */
/* Title input specific styles */
.title-input {
font-size: 1.2em !important; /* 调整为更合适的大小 */
font-size: 1.2em;
line-height: 1.2;
font-weight: 500;
}

View File

@@ -7,7 +7,7 @@
gap: 4px;
}
/* 调整搜索框样式以匹配其他控件 */
/* Match search input styles to other controls */
.search-container input {
width: 100%;
padding: 6px 35px 6px 12px; /* Reduced right padding */
@@ -35,7 +35,7 @@
line-height: 1;
}
/* 修改清空按钮样式 */
/* Clear button styles */
.search-clear {
position: absolute;
right: 105px; /* Adjusted further left to avoid overlapping */

View File

@@ -31,7 +31,7 @@
/* Edit Container */
.metadata-edit-container {
padding: var(--space-2);
background: rgba(0, 0, 0, 0.03);
background: var(--surface-hover);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius-sm);
margin-top: var(--space-2);
@@ -42,7 +42,7 @@
}
[data-theme="dark"] .metadata-edit-container {
background: rgba(255, 255, 255, 0.03);
background: var(--surface-hover);
border: 1px solid var(--lora-border);
}

View File

@@ -707,19 +707,25 @@
color: var(--text-muted);
}
.sidebar-create-folder-btn:hover {
.sidebar-create-folder-btn:hover,
.sidebar-create-folder-btn:focus-visible {
background: var(--lora-surface);
color: var(--text-color);
outline: none;
}
.sidebar-create-folder-confirm:hover {
.sidebar-create-folder-confirm:hover,
.sidebar-create-folder-confirm:focus-visible {
background: oklch(from var(--success-color) l c h / 0.15);
color: var(--success-color);
outline: none;
}
.sidebar-create-folder-cancel:hover {
.sidebar-create-folder-cancel:hover,
.sidebar-create-folder-cancel:focus-visible {
background: oklch(from var(--error-color) l c h / 0.15);
color: var(--error-color);
outline: none;
}
.sidebar-create-folder-hint {

View File

@@ -15,18 +15,18 @@
/* Toast Notifications */
.toast {
position: fixed;
top: 20px; /* 改为从顶部显示 */
right: 20px; /* 改为右对齐 */
left: auto; /* 移除左对齐 */
transform: translateX(120%); /* 初始位置在屏幕右侧外 */
min-width: 300px; /* 设置最小宽度 */
max-width: 400px; /* 设置最大宽度 */
top: 20px;
right: 20px;
left: auto;
transform: translateX(120%);
min-width: 300px;
max-width: 400px;
background: var(--lora-surface);
color: var(--text-color);
padding: 12px 16px;
border-radius: var(--border-radius-sm);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
z-index: calc(var(--z-overlay) + 10); /* 让toast显示在最上层 */
z-index: calc(var(--z-overlay) + 10);
opacity: 0;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
@@ -36,11 +36,10 @@
}
.toast.show {
transform: translateX(0); /* 显示时滑入到正确位置 */
transform: translateX(0);
opacity: 1;
}
/* 添加图标容器 */
.toast::before {
content: '';
width: 20px;
@@ -51,7 +50,7 @@
background-size: contain;
}
/* 不同类型的toast样式 */
/* Toast type variants */
.toast-success {
border-left: 4px solid oklch(65% 0.2 142);
}
@@ -76,15 +75,15 @@
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%232196f3'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z'/%3E%3C/svg%3E");
}
/* 多个toast堆叠显示 */
/* Stacked toast spacing */
.toast + .toast {
margin-top: 10px;
}
/* 响应式调整 */
/* Responsive adjustments */
@media (max-width: 768px) {
.toast {
width: calc(100% - 40px); /* 左右各留20px间距 */
width: calc(100% - 40px);
max-width: none;
right: 20px;
}

View File

@@ -22,7 +22,7 @@
z-index: calc(var(--z-header) - 1);
background: var(--bg-color);
padding: var(--space-1) 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
box-shadow: var(--shadow-xs);
}
/* Responsive container for larger screens */
@@ -80,19 +80,21 @@
font-size: 0.85em;
transition: all 0.2s ease;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: var(--shadow-xs);
}
.control-group button:hover {
.control-group button:hover,
.control-group button:focus-visible {
border-color: var(--lora-accent);
background: var(--bg-color);
transform: translateY(-1px);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.08);
box-shadow: var(--shadow-lg);
outline: none;
}
.control-group button:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: var(--shadow-xs);
}
.control-group button i {
@@ -100,7 +102,8 @@
transition: opacity 0.2s ease;
}
.control-group button:hover i {
.control-group button:hover i,
.control-group button:focus-visible i {
opacity: 1;
}
@@ -131,7 +134,7 @@
.control-group button.favorite-filter i {
margin-right: 4px;
color: #ffc107;
color: var(--favorite-color);
}
.control-group button.update-filter i {
@@ -220,7 +223,7 @@
background-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: var(--shadow-xs);
}
/* Style for optgroups */
@@ -252,7 +255,7 @@
border-color: var(--lora-accent);
background-color: var(--bg-color);
transform: translateY(-1px);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.08);
box-shadow: var(--shadow-lg);
}
.control-group select:focus {
@@ -294,7 +297,7 @@
transform: translateY(10px);
transition: all 0.3s ease;
z-index: var(--z-overlay);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
box-shadow: var(--shadow-sm);
}
.back-to-top.visible {
@@ -307,7 +310,7 @@
background: var(--lora-accent);
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
box-shadow: var(--shadow-md);
}
/* Prevent text selection in control and header areas */
@@ -336,7 +339,7 @@
.dropdown-main {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 1px solid rgba(0, 0, 0, 0.1);
border-right: 1px solid var(--border-color);
}
.dropdown-toggle {
@@ -364,7 +367,7 @@
background-color: var(--card-bg);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-xs);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: var(--shadow-xl);
}
.dropdown-group.active .dropdown-menu {

View File

@@ -54,7 +54,7 @@
text-align: center;
}
/* 使用已有的loading-spinner样式 */
/* Reuse existing loading-spinner styles */
.initialization-notice .loading-spinner {
margin-bottom: var(--space-2);
}

View File

@@ -0,0 +1,142 @@
# Lora-Manager UI Token Migration Guide
## Overview
The design token system has been created in `static/css/tokens/`. `base.css` now imports the tokens and provides backward-compatible aliases for existing component CSS.
## Token Files
| File | Purpose |
|------|---------|
| `tokens/colors.css` | OKLch color primitives + semantic light/dark tokens |
| `tokens/typography.css` | Font stacks, type scale, weights, line heights |
| `tokens/spacing.css` | 4px-base grid with legacy aliases |
| `tokens/effects.css` | Border radius, shadows, transitions |
| `tokens/breakpoints.css` | Named breakpoint variables |
| `tokens/z-index.css` | Stacking context scale |
| `tokens/index.css` | Aggregator that imports all token files |
## Backward Compatibility
Old variable names in component CSS still work via aliases in `base.css`:
| Old Name | Maps To |
|----------|---------|
| `--bg-color` | `--bg-base` |
| `--text-color` | `--text-primary` |
| `--text-muted` | `--text-secondary` |
| `--card-bg` | `--surface-base` |
| `--border-color` | `--border-base` |
| `--lora-accent` | `--color-accent` |
| `--lora-surface` | `--bg-elevated` |
| `--lora-border` | `--border-subtle` |
| `--space-1` (8px) | `--space-1-legacy` |
| `--border-radius-base` | `--radius-lg` |
## Phase 2: Component Audit Checklist
Below are the hardcoded values found across component CSS that should be replaced with tokens.
### Critical Fixes (P0)
- [ ] **card.css line 441**: `.base-model { background: #f0f0f0; }` → use `--bg-hover` or new `--surface-variant`
- [ ] **card.css line 369**: `.favorite-active { color: #ffc107 !important; }` → use `--favorite-color` (already defined in tokens)
- [ ] **layout.css line 134**: `.control-group button.favorite-filter i { color: #ffc107; }` → use `--favorite-color`
- [ ] **header.css lines 233-250**: Hardcoded dark theme colors (`#3a3a3a`, `#888888`, `#555555`) → use `--bg-disabled`, `--text-secondary`, `--border-base`
### Spacing Normalization (P1)
Replace hard pixel values with token equivalents:
- [ ] `padding: 4px 10px``padding: var(--space-1) var(--space-3)`
- [ ] `gap: 6px``gap: var(--space-1-legacy)` or `gap: var(--space-2)`
- [ ] `gap: 8px``gap: var(--space-2)`
- [ ] `gap: 12px``gap: var(--space-3)`
- [ ] `padding: 15px``padding: var(--space-4)`
- [ ] `padding: 16px``padding: var(--space-4)`
- [ ] `margin-top: 2px``margin-top: var(--space-0-5)`
- [ ] `padding: 2px 6px``padding: var(--space-0-5) var(--space-2)`
- [ ] `border-radius: 50%``border-radius: var(--radius-full)`
### Shadow Standardization (P1)
Replace hardcoded shadows with token equivalents:
- [ ] `box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05)``box-shadow: var(--shadow-xs)`
- [ ] `box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05)``box-shadow: var(--shadow-sm)`
- [ ] `box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)``box-shadow: var(--shadow-md)`
- [ ] `box-shadow: 0 3px 5px rgba(0, 0, 0, 0.08)``box-shadow: var(--shadow-lg)`
- [ ] `box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15)``box-shadow: var(--shadow-xl)`
- [ ] `box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08)` → combine or add new token
### Typography Normalization (P1)
Replace scattered font sizes with type scale:
- [ ] `font-size: 0.8em``font-size: var(--text-xs)`
- [ ] `font-size: 0.85em``font-size: var(--text-sm)`
- [ ] `font-size: 0.9em``font-size: var(--text-sm)`
- [ ] `font-size: 0.95em``font-size: var(--text-md)`
- [ ] `font-size: 1.1em``font-size: var(--text-lg)`
- [ ] `font-size: 11px``font-size: var(--text-xs)`
### Breakpoint Normalization (P2)
Replace magic numbers with named breakpoints:
- [ ] `@media (min-width: 2150px)``@media (min-width: var(--bp-ultrawide))`
- [ ] `@media (min-width: 3000px)``@media (min-width: var(--bp-4k))`
- [ ] `@media (max-width: 768px)``@media (max-width: var(--bp-mobile))`
- [ ] `@media (max-width: 1200px)``@media (max-width: var(--bp-desktop))`
### Z-Index Cleanup (P2)
Replace magic z-index values with tokens:
- [ ] `z-index: 2` / `z-index: 3` / `z-index: 4` in card.css → use `--z-base` + calc
- [ ] `z-index: 200` in header.css (hamburger dropdown) → use `--z-dropdown`
### Remaining Hardcoded Colors (P2)
- [ ] `rgba(0, 184, 122, 0.05)` and `#00B87A` in import-modal.css → use `--color-success`
- [ ] `rgba(255, 255, 255, 0.12)` in card.css (base-model-label background) → use token
- [ ] `rgba(255, 255, 255, 0.25)` in card.css (separator) → use `--border-inverse`
- [ ] `rgba(0, 0, 0, 0.5)` and `rgba(0, 0, 0, 0.7)` in card.css (toggle blur btn) → use `--bg-overlay` variants
- [ ] `rgba(46, 204, 113, 0.3)` and `rgba(231, 76, 60, 0.3)` in card.css → use success/error tokens
## New Tokens Added
The following tokens were added beyond the existing system:
| Token | Value | Use Case |
|-------|-------|----------|
| `--color-accent-hover` | oklch(58% 0.28 256) | Hover states for accent buttons |
| `--color-accent-subtle` | accent @ 12% opacity | Subtle accent backgrounds |
| `--color-accent-border` | accent @ 25% opacity | Accent borders |
| `--color-accent-transparent` | accent @ 60% opacity | Glow effects, pulse animations |
| `--bg-hover` | oklch(95% 0.02 256) / dark: oklch(35% 0.02 256) | Hover backgrounds |
| `--bg-disabled` | #f5f5f5 / dark: #3a3a3a | Disabled input backgrounds |
| `--bg-overlay` | oklch(0% 0 0 / 0.75) | Modal overlays, gradients |
| `--surface-hover` | oklch(95% 0.02 256) / dark: oklch(35% 0.02 256) | Card/panel hover |
| `--favorite-color` | #d4a017 | Accessible gold for favorites |
| `--shadow-focus` | 0 0 0 1px accent | Focus ring shadow |
| `--shadow-glow` | 0 2px 6px info-glow | Badge glow effects |
| `--transition-bounce` | 200ms cubic-bezier | Playful hover transitions |
## Migration Order Recommendation
1. **Start with colors**: Replace `#ffc107` and `#f0f0f0` (highest visual impact)
2. **Then spacing**: Unify padding/gap values (biggest consistency win)
3. **Then shadows**: Replace rgba shadows with tokens
4. **Then typography**: Standardize font sizes
5. **Finally breakpoints + z-index**: Lower priority but good for maintainability
## Testing Checklist
After each component file is migrated:
- [ ] Light theme renders correctly
- [ ] Dark theme renders correctly
- [ ] No visual regressions in card grid, header, modals
- [ ] Focus states still visible
- [ ] Hover transitions still work (unless prefers-reduced-motion)

View File

@@ -0,0 +1,8 @@
:root {
--bp-mobile: 768px;
--bp-tablet: 1024px;
--bp-desktop: 1400px;
--bp-wide: 1920px;
--bp-ultrawide: 2150px;
--bp-4k: 3000px;
}

View File

@@ -0,0 +1,117 @@
:root {
--color-accent-l: 68%;
--color-accent-c: 0.28;
--color-accent-h: 256;
--color-warning-l: 75%;
--color-warning-c: 0.25;
--color-warning-h: 80;
--color-success-l: 70%;
--color-success-c: 0.2;
--color-success-h: 140;
--color-error-l: 75%;
--color-error-c: 0.32;
--color-error-h: 29;
--color-info-l: 72%;
--color-info-c: 0.2;
--color-info-h: 220;
--color-neutral-h: 250;
}
:root {
--color-accent: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h));
--color-accent-hover: oklch(58% var(--color-accent-c) var(--color-accent-h));
--color-accent-subtle: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.12);
--color-accent-border: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.25);
--color-accent-transparent: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.6);
--color-warning: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h));
--color-warning-bg: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h) / 0.15);
--color-warning-border: oklch(var(--color-warning-l) var(--color-warning-c) var(--color-warning-h) / 0.3);
--color-success: oklch(var(--color-success-l) var(--color-success-c) var(--color-success-h));
--color-success-bg: oklch(var(--color-success-l) var(--color-success-c) var(--color-success-h) / 0.2);
--color-success-border: oklch(var(--color-success-l) var(--color-success-c) var(--color-success-h) / 0.3);
--color-error: oklch(var(--color-error-l) var(--color-error-c) var(--color-error-h));
--color-error-bg: color-mix(in oklch, var(--color-error) 20%, transparent);
--color-error-border: color-mix(in oklch, var(--color-error) 50%, transparent);
--color-info: oklch(var(--color-info-l) var(--color-info-c) var(--color-info-h));
--color-info-bg: oklch(72% 0.2 220);
--color-info-text: oklch(28% 0.03 220);
--color-info-glow: oklch(72% 0.2 220 / 0.28);
--color-skip-refresh-bg: oklch(82% 0.12 45);
--color-skip-refresh-text: oklch(35% 0.02 45);
--color-skip-refresh-glow: oklch(82% 0.12 45 / 0.15);
}
:root {
--bg-base: #ffffff;
--bg-elevated: oklch(97% 0 0 / 0.95);
--bg-overlay: oklch(0% 0 0 / 0.75);
--bg-hover: oklch(95% 0.02 256);
--bg-disabled: #f5f5f5;
--text-primary: #333333;
--text-secondary: #6c757d;
--text-inverse: #ffffff;
--text-muted-on-dark: rgba(255, 255, 255, 0.8);
--surface-base: #ffffff;
--surface-elevated: oklch(97% 0 0 / 0.95);
--surface-hover: oklch(95% 0.02 256);
--surface-subtle: oklch(0% 0 0 / 0.03);
--border-base: #e0e0e0;
--border-subtle: oklch(72% 0.03 256 / 0.45);
--border-inverse: rgba(255, 255, 255, 0.25);
--status-success-text: oklch(75% 0.12 230);
--status-success-bg: oklch(55% 0.15 240 / 0.25);
--status-success-border: oklch(60% 0.18 250 / 0.3);
--status-info-text: oklch(78% 0.10 185);
--status-info-bg: oklch(50% 0.10 190 / 0.25);
--status-info-border: oklch(55% 0.12 195 / 0.3);
--favorite-color: #d4a017;
--favorite-glow: oklch(65% 0.15 85 / 0.5);
}
[data-theme="dark"] {
--bg-base: #1a1a1a;
--bg-elevated: oklch(25% 0.02 256 / 0.98);
--bg-overlay: oklch(0% 0 0 / 0.75);
--bg-hover: oklch(35% 0.02 256);
--bg-disabled: #3a3a3a;
--text-primary: #e0e0e0;
--text-secondary: #a0a0a0;
--text-inverse: #1a1a1a;
--text-muted-on-dark: rgba(255, 255, 255, 0.8);
--surface-base: #2d2d2d;
--surface-elevated: oklch(25% 0.02 256 / 0.98);
--surface-hover: oklch(35% 0.02 256);
--surface-subtle: oklch(100% 0 0 / 0.03);
--border-base: #404040;
--border-subtle: oklch(90% 0.02 256 / 0.15);
--border-inverse: rgba(255, 255, 255, 0.25);
--status-success-text: oklch(75% 0.12 230);
--status-success-bg: oklch(55% 0.15 240 / 0.25);
--status-success-border: oklch(60% 0.18 250 / 0.3);
--status-info-text: oklch(78% 0.10 185);
--status-info-bg: oklch(50% 0.10 190 / 0.25);
--status-info-border: oklch(55% 0.12 195 / 0.3);
--color-info-bg: oklch(62% 0.18 220);
--color-info-text: oklch(98% 0.02 240);
--color-info-glow: oklch(62% 0.18 220 / 0.4);
--color-error-bg: color-mix(in oklch, var(--color-error) 15%, transparent);
--color-error-border: color-mix(in oklch, var(--color-error) 40%, transparent);
--favorite-color: #ffc107;
}

View File

@@ -0,0 +1,25 @@
:root {
--radius-none: 0px;
--radius-xs: 4px;
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.05);
--shadow-md: 0 2px 4px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 3px 5px rgba(0, 0, 0, 0.08);
--shadow-xl: 0 4px 16px rgba(0, 0, 0, 0.15);
--shadow-focus: 0 0 0 1px var(--color-accent);
--shadow-glow: 0 2px 6px var(--color-info-glow);
--transition-fast: 150ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
--transition-bounce: 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
--border-width-thin: 1px;
--border-width-thick: 2px;
}

View File

@@ -0,0 +1,6 @@
@import 'colors.css';
@import 'typography.css';
@import 'spacing.css';
@import 'effects.css';
@import 'breakpoints.css';
@import 'z-index.css';

View File

@@ -0,0 +1,19 @@
:root {
--space-0-5: 2px;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
--space-20: 80px;
--space-1-legacy: calc(8px * 1);
--space-2-legacy: calc(8px * 2);
--space-3-legacy: calc(8px * 3);
--space-4-legacy: calc(8px * 4);
}

View File

@@ -0,0 +1,20 @@
:root {
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, Menlo, monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-md: 0.95rem;
--text-lg: 1.1rem;
--text-xl: 1.25rem;
--leading-tight: 1.2;
--leading-normal: 1.4;
--leading-relaxed: 1.5;
--weight-normal: 400;
--weight-medium: 500;
--weight-semibold: 600;
--weight-bold: 700;
}

View File

@@ -0,0 +1,11 @@
:root {
--z-base: 10;
--z-sticky: 50;
--z-header: 100;
--z-dropdown: 200;
--z-modal-backdrop: 500;
--z-modal: 1000;
--z-overlay: 2000;
--z-toast: 3000;
--z-tooltip: 4000;
}