feat: implement Material 3 expressive design

This commit is contained in:
ws50529
2026-05-13 17:31:16 +08:00
parent caaccbd760
commit edec4e6db6
5 changed files with 476 additions and 28 deletions
+1 -2
View File
@@ -5,8 +5,7 @@
class="bg-white dark:bg-dark border-b border-slate-200 dark:border-gray-800 p-4 shadow-md flex justify-between items-center z-10"> class="bg-white dark:bg-dark border-b border-slate-200 dark:border-gray-800 p-4 shadow-md flex justify-between items-center z-10">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<img :src="'/ui/logo.png'" alt="Logo" class="h-10 w-10 object-contain rounded-lg shadow-sm"> <img :src="'/ui/logo.png'" alt="Logo" class="h-10 w-10 object-contain rounded-lg shadow-sm">
<h1 <h1 class="text-xl font-bold text-slate-900 dark:text-gray-100">
class="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-emerald-600 dark:from-blue-400 dark:to-emerald-400">
差分方程式分析 (Difference Equation Analyzer)</h1> 差分方程式分析 (Difference Equation Analyzer)</h1>
</div> </div>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
+23 -23
View File
@@ -34,7 +34,7 @@ export default {
systemGain: 1.0, systemGain: 1.0,
params: cloneDefaultParams(), params: cloneDefaultParams(),
// 模式切換 // 模式切換
isDarkMode: true, isDarkMode: false,
// 係數倍率微調 // 係數倍率微調
baseB: [0.5, 0.5, 0, 0, 0, 0, 0], baseB: [0.5, 0.5, 0, 0, 0, 0, 0],
baseA: [1, 0, 0, 0, 0, 0, 0], baseA: [1, 0, 0, 0, 0, 0, 0],
@@ -846,13 +846,13 @@ export default {
shapes.push({ shapes.push({
type: 'line', x0: xVal, x1: xVal, y0: 0, y1: 1, type: 'line', x0: xVal, x1: xVal, y0: 0, y1: 1,
xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain',
line: { color: isDark ? 'rgba(255,0,0,0.5)' : 'rgba(220,0,0,0.6)', width: 1.5, dash: 'dash' } line: { color: isDark ? 'rgba(242,184,181,0.72)' : 'rgba(186,26,26,0.72)', width: 1.4, dash: 'dash' }
}); });
if (text) { if (text) {
annotations.push({ annotations.push({
x: Math.log10(xVal), y: 1, text: text, x: Math.log10(xVal), y: 1, text: text,
xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain', xref: row === 1 ? 'x' : 'x2', yref: yref + ' domain',
showarrow: false, font: { color: isDark ? 'rgba(255,100,100,0.8)' : 'rgba(180,50,50,1)', size: isSmallScreen ? 10 : 12 }, showarrow: false, font: { color: isDark ? '#f2b8b5' : '#ba1a1a', size: isSmallScreen ? 10 : 12 },
yshift: isSmallScreen ? 15 : 12, yshift: isSmallScreen ? 15 : 12,
xanchor: 'center', xanchor: 'center',
yanchor: isSmallScreen ? 'middle' : 'bottom', yanchor: isSmallScreen ? 'middle' : 'bottom',
@@ -869,7 +869,7 @@ export default {
for (let p = pStart; p <= pEnd; p++) { for (let p = pStart; p <= pEnd; p++) {
const v = Math.pow(10, p); const v = Math.pow(10, p);
if (v >= fMin && v <= fMax) { if (v >= fMin && v <= fMax) {
const gridColor = isDark ? 'rgba(128,128,128,0.5)' : 'rgba(100,100,100,0.3)'; const gridColor = isDark ? 'rgba(198,204,216,0.24)' : 'rgba(63,95,159,0.14)';
shapes.push( shapes.push(
{ type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x', yref: 'y domain', line: { color: gridColor, width: 1.5 } }, { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x', yref: 'y domain', line: { color: gridColor, width: 1.5 } },
{ type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x2', yref: 'y2 domain', line: { color: gridColor, width: 1.5 } } { type: 'line', x0: v, x1: v, y0: 0, y1: 1, xref: 'x2', yref: 'y2 domain', line: { color: gridColor, width: 1.5 } }
@@ -877,10 +877,10 @@ export default {
} }
} }
const gridColor = isDark ? 'rgba(128,128,128,0.2)' : 'rgba(0,0,0,0.1)'; const gridColor = isDark ? 'rgba(198,204,216,0.14)' : 'rgba(63,95,159,0.08)';
const zeroLineColor = isDark ? '#4b5563' : '#cbd5e1'; const zeroLineColor = isDark ? 'rgba(198,204,216,0.24)' : 'rgba(70,75,85,0.18)';
const textColor = isDark ? '#9ca3af' : '#475569'; const textColor = isDark ? '#c6ccd8' : '#38404c';
const titleColor = isDark ? '#d1d5db' : '#1e293b'; const titleColor = isDark ? '#e4e7ef' : '#1a1b1f';
const xAxisCommon = { const xAxisCommon = {
type: 'log', title: { text: 'Freq (Hz)', font: { size: isSmallScreen ? 12 : 14 } }, type: 'log', title: { text: 'Freq (Hz)', font: { size: isSmallScreen ? 12 : 14 } },
@@ -896,21 +896,21 @@ export default {
margin: isSmallScreen ? { t: 80, b: 120, l: 55, r: 15 } : { t: 70, b: 120, l: 70, r: 30 }, margin: isSmallScreen ? { t: 80, b: 120, l: 55, r: 15 } : { t: 70, b: 120, l: 70, r: 30 },
showlegend: false, showlegend: false,
grid: { rows: 2, columns: 1, pattern: 'independent', roworder: 'top to bottom', ygap: isSmallScreen ? 0.35 : 0.3 }, grid: { rows: 2, columns: 1, pattern: 'independent', roworder: 'top to bottom', ygap: isSmallScreen ? 0.35 : 0.3 },
font: { color: textColor, family: 'Inter, sans-serif' }, font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' },
annotations: [ annotations: [
{ text: 'Magnitude Response (dB)', xref: 'x domain', yref: 'y domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } }, { text: 'Magnitude Response (dB)', xref: 'x domain', yref: 'y domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } },
{ text: 'Phase Response (Deg)', xref: 'x2 domain', yref: 'y2 domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } }, { text: 'Phase Response (Deg)', xref: 'x2 domain', yref: 'y2 domain', x: 0.5, y: isSmallScreen ? 1.25 : 1.15, showarrow: false, font: { size: isSmallScreen ? 14 : 16, color: titleColor, weight: 'bold' } },
// 手動 Magnitude 圖例 (位於上方圖表下方) // 手動 Magnitude 圖例 (位於上方圖表下方)
{ xref: 'paper', yref: 'paper', x: 0.35, y: isSmallScreen ? 0.52 : 0.54, text: '一一一', font: { color: isDark ? '#3b82f6' : '#2563eb', size: 10 }, showarrow: false }, { xref: 'paper', yref: 'paper', x: 0.35, y: isSmallScreen ? 0.52 : 0.54, text: '一一一', font: { color: isDark ? '#b9c6ff' : '#3f5f9f', size: 10 }, showarrow: false },
{ xref: 'paper', yref: 'paper', x: 0.42, y: isSmallScreen ? 0.52 : 0.54, text: 'Ideal (Float)', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, { xref: 'paper', yref: 'paper', x: 0.42, y: isSmallScreen ? 0.52 : 0.54, text: 'Ideal (Float)', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' },
{ xref: 'paper', yref: 'paper', x: 0.58, y: isSmallScreen ? 0.52 : 0.54, text: '· · · ·', font: { color: isDark ? '#10b981' : '#059669', size: 14 }, showarrow: false }, { xref: 'paper', yref: 'paper', x: 0.58, y: isSmallScreen ? 0.52 : 0.54, text: '· · · ·', font: { color: isDark ? '#d7da7d' : '#6d702b', size: 14 }, showarrow: false },
{ xref: 'paper', yref: 'paper', x: 0.63, y: isSmallScreen ? 0.52 : 0.54, text: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, { xref: 'paper', yref: 'paper', x: 0.63, y: isSmallScreen ? 0.52 : 0.54, text: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' },
// 手動 Phase 圖例 (位於下方圖表下方) // 手動 Phase 圖例 (位於下方圖表下方)
{ xref: 'paper', yref: 'paper', x: 0.35, y: -0.15, text: '一一一', font: { color: isDark ? '#f97316' : '#ea580c', size: 10 }, showarrow: false }, { xref: 'paper', yref: 'paper', x: 0.35, y: -0.15, text: '一一一', font: { color: isDark ? '#c4c9d8' : '#4f6f80', size: 10 }, showarrow: false },
{ xref: 'paper', yref: 'paper', x: 0.42, y: -0.15, text: 'Ideal Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, { xref: 'paper', yref: 'paper', x: 0.42, y: -0.15, text: 'Ideal Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' },
{ xref: 'paper', yref: 'paper', x: 0.58, y: -0.15, text: '· · · ·', font: { color: isDark ? '#f43f5e' : '#e11d48', size: 14 }, showarrow: false }, { xref: 'paper', yref: 'paper', x: 0.58, y: -0.15, text: '· · · ·', font: { color: isDark ? '#f2b8b5' : '#ba1a1a', size: 14 }, showarrow: false },
{ xref: 'paper', yref: 'paper', x: 0.63, y: -0.15, text: 'Fixed Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' }, { xref: 'paper', yref: 'paper', x: 0.63, y: -0.15, text: 'Fixed Phase', font: { color: textColor, size: 11 }, showarrow: false, xanchor: 'left' },
...annotations ...annotations
@@ -922,11 +922,11 @@ export default {
shapes: shapes shapes: shapes
}; };
const traceMagIdeal = { x: freq, y: magIdeal, name: 'Ideal (Float)', type: 'scatter', line: { color: isDark ? '#3b82f6' : '#2563eb', width: 2.5 } }; const traceMagIdeal = { x: freq, y: magIdeal, name: 'Ideal (Float)', type: 'scatter', line: { color: isDark ? '#b9c6ff' : '#3f5f9f', width: 2.8 } };
const traceMagFixed = { x: freq, y: magFixed, name: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, type: 'scatter', line: { color: isDark ? '#10b981' : '#059669', width: 2, dash: 'dot' } }; const traceMagFixed = { x: freq, y: magFixed, name: `Fixed (b Q${this.shiftBitsB}, a Q${this.shiftBitsA})`, type: 'scatter', line: { color: isDark ? '#d7da7d' : '#6d702b', width: 2.4, dash: 'dot' } };
const tracePhaseIdeal = { x: freq, y: phaseIdeal, name: 'Ideal Phase', type: 'scatter', line: { color: isDark ? '#f97316' : '#ea580c', width: 2.5 }, xaxis: 'x2', yaxis: 'y2' }; const tracePhaseIdeal = { x: freq, y: phaseIdeal, name: 'Ideal Phase', type: 'scatter', line: { color: isDark ? '#c4c9d8' : '#4f6f80', width: 2.8 }, xaxis: 'x2', yaxis: 'y2' };
const tracePhaseFixed = { x: freq, y: phaseFixed, name: 'Fixed Phase', type: 'scatter', line: { color: isDark ? '#f43f5e' : '#e11d48', width: 2, dash: 'dot' }, xaxis: 'x2', yaxis: 'y2' }; const tracePhaseFixed = { x: freq, y: phaseFixed, name: 'Fixed Phase', type: 'scatter', line: { color: isDark ? '#f2b8b5' : '#ba1a1a', width: 2.4, dash: 'dot' }, xaxis: 'x2', yaxis: 'y2' };
Plotly.react('bodePlot', [traceMagIdeal, traceMagFixed, tracePhaseIdeal, tracePhaseFixed], layout, { responsive: true }); Plotly.react('bodePlot', [traceMagIdeal, traceMagFixed, tracePhaseIdeal, tracePhaseFixed], layout, { responsive: true });
}, },
@@ -1077,21 +1077,21 @@ export default {
drawTimePlot(data) { drawTimePlot(data) {
const isDark = this.isDarkMode; const isDark = this.isDarkMode;
const isSmallScreen = window.innerWidth < 768; const isSmallScreen = window.innerWidth < 768;
const gridColor = isDark ? 'rgba(128,128,128,0.2)' : 'rgba(0,0,0,0.1)'; const gridColor = isDark ? 'rgba(198,204,216,0.14)' : 'rgba(63,95,159,0.08)';
const zeroLineColor = isDark ? '#4b5563' : '#cbd5e1'; const zeroLineColor = isDark ? 'rgba(198,204,216,0.24)' : 'rgba(70,75,85,0.18)';
const textColor = isDark ? '#9ca3af' : '#475569'; const textColor = isDark ? '#c6ccd8' : '#38404c';
const layout = { const layout = {
paper_bgcolor: 'transparent', plot_bgcolor: 'transparent', paper_bgcolor: 'transparent', plot_bgcolor: 'transparent',
margin: isSmallScreen ? { t: 60, b: 60, l: 45, r: 15 } : { t: 40, b: 55, l: 60, r: 20 }, margin: isSmallScreen ? { t: 60, b: 60, l: 45, r: 15 } : { t: 40, b: 55, l: 60, r: 20 },
font: { color: textColor, family: 'Inter, sans-serif' }, font: { color: textColor, family: 'Google Sans, Roboto, sans-serif' },
xaxis: { title: { text: 'Sample Index', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, xaxis: { title: { text: 'Sample Index', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } },
yaxis: { title: { text: 'Amplitude', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } }, yaxis: { title: { text: 'Amplitude', font: { size: isSmallScreen ? 10 : 11 } }, gridcolor: gridColor, zerolinecolor: zeroLineColor, tickfont: { color: textColor, size: isSmallScreen ? 9 : 11 } },
legend: { orientation: 'h', y: 1.02, yanchor: 'bottom', x: 1, xanchor: 'right', font: { color: textColor, size: isSmallScreen ? 9 : 10 } } legend: { orientation: 'h', y: 1.02, yanchor: 'bottom', x: 1, xanchor: 'right', font: { color: textColor, size: isSmallScreen ? 9 : 10 } }
}; };
Plotly.react('timePlot', [ Plotly.react('timePlot', [
{ x: data.index, y: data.original, name: '原始輸入訊號 (Input)', type: 'scatter', line: { color: isDark ? '#00cc96' : '#059669' }, opacity: 0.7 }, { x: data.index, y: data.original, name: '原始輸入訊號 (Input)', type: 'scatter', line: { color: isDark ? '#b9c6ff' : '#3f5f9f', width: 2.4 }, opacity: 0.9 },
{ x: data.index, y: data.filtered, name: '濾波後輸出 (Output)', type: 'scatter', line: { color: isDark ? '#ef553b' : '#dc2626' }, opacity: 0.9 } { x: data.index, y: data.filtered, name: '濾波後輸出 (Output)', type: 'scatter', line: { color: isDark ? '#d7da7d' : '#6d702b', width: 2.4 }, opacity: 0.95 }
], layout, { responsive: true }); ], layout, { responsive: true });
}, },
Regular → Executable
+449
View File
@@ -3,3 +3,452 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
/* Material 3 Expressive readability pass.
Keep this after Tailwind so these focused overrides win without changing app logic. */
:root {
--m3-primary: #3f5f9f;
--m3-on-primary: #ffffff;
--m3-primary-container: #dbe4ff;
--m3-on-primary-container: #001947;
--m3-secondary: #5b6172;
--m3-on-secondary: #ffffff;
--m3-secondary-container: #e0e5f2;
--m3-on-secondary-container: #181c26;
--m3-tertiary: #6d702b;
--m3-on-tertiary: #ffffff;
--m3-tertiary-container: #ecefa7;
--m3-on-tertiary-container: #202200;
--m3-error: #b3261e;
--m3-on-error: #ffffff;
--m3-error-container: #f9dedc;
--m3-success: #4f7a29;
--m3-success-container: #d2efb2;
--m3-warning: #755b00;
--m3-warning-container: #ffe19a;
--m3-background: #fbfbff;
--m3-surface: #fbfbff;
--m3-surface-container-lowest: #ffffff;
--m3-surface-container-low: #f4f6fb;
--m3-surface-container: #eef2f8;
--m3-surface-container-high: #e7ebf3;
--m3-surface-container-highest: #dde4ef;
--m3-on-surface: #1a1b1f;
--m3-on-surface-variant: #464b55;
--m3-outline: #737986;
--m3-outline-variant: #c6ccd8;
--m3-shadow: 0 1px 2px rgba(29, 27, 32, 0.14), 0 2px 6px rgba(29, 27, 32, 0.10);
--m3-elevated-shadow: 0 3px 8px rgba(29, 27, 32, 0.13), 0 12px 24px rgba(29, 27, 32, 0.08);
}
.dark {
--m3-primary: #b9c6ff;
--m3-on-primary: #0a2f68;
--m3-primary-container: #28477f;
--m3-on-primary-container: #dbe4ff;
--m3-secondary: #c4c9d8;
--m3-on-secondary: #2d313b;
--m3-secondary-container: #434754;
--m3-on-secondary-container: #e0e5f2;
--m3-tertiary: #d7da7d;
--m3-on-tertiary: #363800;
--m3-tertiary-container: #535611;
--m3-on-tertiary-container: #ecefa7;
--m3-error: #f2b8b5;
--m3-on-error: #601410;
--m3-error-container: #8c1d18;
--m3-success: #b7dda0;
--m3-success-container: #385421;
--m3-warning: #e7c16d;
--m3-warning-container: #5d4100;
--m3-background: #111318;
--m3-surface: #111318;
--m3-surface-container-lowest: #0b0d12;
--m3-surface-container-low: #1a1c22;
--m3-surface-container: #1f2229;
--m3-surface-container-high: #292d35;
--m3-surface-container-highest: #343941;
--m3-on-surface: #e4e7ef;
--m3-on-surface-variant: #c6ccd8;
--m3-outline: #9096a3;
--m3-outline-variant: #464b55;
--m3-shadow: 0 1px 2px rgba(0, 0, 0, 0.36), 0 4px 12px rgba(0, 0, 0, 0.28);
--m3-elevated-shadow: 0 4px 12px rgba(0, 0, 0, 0.45), 0 16px 32px rgba(0, 0, 0, 0.32);
}
html,
body,
#dea-root {
background: var(--m3-background);
color: var(--m3-on-surface);
}
body {
font-family: "Google Sans", Roboto, "Noto Sans TC", system-ui, -apple-system, sans-serif;
letter-spacing: 0;
}
header,
aside,
footer,
main > div,
section,
details,
.js-plotly-plot,
#bodePlot,
#timePlot {
color: var(--m3-on-surface);
}
header.bg-white,
header.dark\:bg-dark,
footer.bg-white,
footer.dark\:bg-dark {
background: var(--m3-surface-container-low) !important;
border-color: var(--m3-outline-variant) !important;
box-shadow: var(--m3-shadow);
}
aside.bg-white,
aside.dark\:bg-dark,
main.bg-slate-50,
main.dark\:bg-\[\#0f0f0f\] {
background: var(--m3-background) !important;
border-color: var(--m3-outline-variant) !important;
}
header h1 {
background: none !important;
color: var(--m3-on-surface) !important;
-webkit-text-fill-color: var(--m3-on-surface);
font-weight: 700;
}
header h1.text-transparent {
color: var(--m3-on-surface) !important;
}
h2,
h3,
label,
summary {
color: var(--m3-on-surface-variant) !important;
}
h3.font-bold,
h4.font-bold {
color: var(--m3-on-surface) !important;
}
hr {
border-color: var(--m3-outline-variant) !important;
}
select,
input[type="number"],
textarea {
background: var(--m3-surface-container-lowest) !important;
border-color: var(--m3-outline) !important;
border-radius: 12px !important;
color: var(--m3-on-surface) !important;
box-shadow: none;
}
select:focus,
input[type="number"]:focus,
textarea:focus {
border-color: var(--m3-primary) !important;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--m3-primary) 28%, transparent) !important;
}
button,
[role="button"],
label.cursor-pointer {
border-color: transparent !important;
border-radius: 999px !important;
box-shadow: none !important;
font-weight: 650;
transition: background-color 140ms ease, color 140ms ease, box-shadow 140ms ease, transform 120ms ease;
}
button:hover,
[role="button"]:hover,
label.cursor-pointer:hover {
transform: translateY(-1px);
}
button:active,
[role="button"]:active,
label.cursor-pointer:active {
transform: translateY(0);
}
button.bg-blue-600,
button.bg-emerald-600,
button.bg-slate-700,
label.bg-blue-600 {
background: var(--m3-primary) !important;
color: var(--m3-on-primary) !important;
box-shadow: var(--m3-shadow) !important;
}
button.bg-blue-600:hover,
button.bg-emerald-600:hover,
button.bg-slate-700:hover,
label.bg-blue-600:hover {
background: color-mix(in srgb, var(--m3-primary) 88%, var(--m3-on-primary) 12%) !important;
box-shadow: var(--m3-elevated-shadow) !important;
}
button.bg-slate-200,
button.dark\:bg-gray-800,
button.bg-amber-100,
button.bg-blue-100,
button.bg-orange-100,
button.bg-indigo-100,
button.bg-emerald-100 {
background: var(--m3-secondary-container) !important;
color: var(--m3-on-secondary-container) !important;
}
button.bg-slate-200:hover,
button.dark\:bg-gray-800:hover,
button.bg-amber-100:hover,
button.bg-blue-100:hover,
button.bg-orange-100:hover,
button.bg-indigo-100:hover,
button.bg-emerald-100:hover {
background: color-mix(in srgb, var(--m3-secondary-container) 86%, var(--m3-primary) 14%) !important;
}
.bg-white,
.dark .dark\:bg-dark,
.dark .lg\:dark\:bg-dark,
.bg-slate-50,
.dark .dark\:bg-gray-900,
.dark .dark\:bg-gray-900\/50,
.dark .dark\:bg-gray-900\/30 {
background-color: var(--m3-surface-container-low) !important;
}
.bg-slate-50\/50,
.bg-slate-100,
.dark .dark\:bg-gray-800,
.dark .dark\:bg-gray-800\/50,
.dark .dark\:bg-gray-800\/30 {
background-color: var(--m3-surface-container) !important;
}
.border,
.border-b,
.border-r,
.border-t,
.lg\:border {
border-color: var(--m3-outline-variant) !important;
}
.shadow-md,
.shadow-lg,
.lg\:shadow-md,
.shadow-inner {
box-shadow: var(--m3-shadow) !important;
}
.text-slate-900,
.text-slate-800,
.dark .dark\:text-gray-100,
.dark .dark\:text-gray-200 {
color: var(--m3-on-surface) !important;
}
.text-slate-700,
.text-slate-600,
.text-slate-500,
.text-slate-400,
.dark .dark\:text-gray-300,
.dark .dark\:text-gray-400,
.dark .dark\:text-gray-500 {
color: var(--m3-on-surface-variant) !important;
}
.text-blue-600,
.text-blue-700,
.text-blue-800,
.dark .dark\:text-blue-300,
.dark .dark\:text-blue-400 {
color: var(--m3-primary) !important;
}
.text-emerald-600,
.text-emerald-700,
.dark .dark\:text-emerald-300,
.dark .dark\:text-emerald-400 {
color: var(--m3-success) !important;
}
.text-orange-600,
.text-orange-700,
.text-orange-800,
.dark .dark\:text-orange-300,
.dark .dark\:text-orange-400,
.text-indigo-600,
.text-indigo-700,
.dark .dark\:text-indigo-300,
.dark .dark\:text-indigo-400 {
color: var(--m3-secondary) !important;
}
.text-red-600,
.text-red-700,
.dark .dark\:text-red-400 {
color: var(--m3-error) !important;
}
.bg-blue-50,
.bg-blue-100,
.dark .dark\:bg-blue-900\/20,
.dark .dark\:bg-blue-900\/30 {
background-color: var(--m3-primary-container) !important;
border-color: color-mix(in srgb, var(--m3-primary) 24%, transparent) !important;
color: var(--m3-on-primary-container) !important;
}
.bg-emerald-50,
.bg-emerald-100,
.dark .dark\:bg-emerald-900\/20,
.dark .dark\:bg-emerald-900\/30 {
background-color: color-mix(in srgb, var(--m3-success-container) 72%, var(--m3-surface-container-low)) !important;
border-color: color-mix(in srgb, var(--m3-success) 24%, transparent) !important;
}
.bg-orange-50,
.bg-orange-100,
.bg-indigo-50,
.bg-indigo-100,
.dark .dark\:bg-orange-900\/20,
.dark .dark\:bg-orange-900\/30,
.dark .dark\:bg-indigo-900\/20,
.dark .dark\:bg-indigo-900\/30 {
background-color: color-mix(in srgb, var(--m3-secondary-container) 76%, var(--m3-surface-container-lowest)) !important;
border-color: color-mix(in srgb, var(--m3-secondary) 24%, transparent) !important;
color: var(--m3-on-secondary-container) !important;
}
.bg-amber-50,
.bg-amber-100,
.dark .dark\:bg-amber-900\/20,
.dark .dark\:bg-amber-900\/30 {
background-color: var(--m3-warning-container) !important;
border-color: color-mix(in srgb, var(--m3-warning) 24%, transparent) !important;
color: var(--m3-warning) !important;
}
input[type=range] {
background: color-mix(in srgb, var(--m3-primary) 22%, var(--m3-surface-container-high)) !important;
border-radius: 999px;
height: 6px;
}
input[type=range]::-webkit-slider-thumb {
background: var(--m3-primary);
border: 3px solid var(--m3-surface-container-lowest);
box-shadow: var(--m3-shadow);
}
.dark input[type=range]::-webkit-slider-thumb {
background: var(--m3-primary);
border-color: var(--m3-surface-container-lowest);
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: color-mix(in srgb, var(--m3-outline) 52%, transparent);
}
.rounded,
.rounded-lg,
.rounded-xl,
details,
select,
textarea,
input[type="number"] {
border-radius: 16px !important;
}
.rounded-full {
border-radius: 999px !important;
}
details,
main > div,
.overflow-x-auto.rounded-xl,
.space-y-3.bg-slate-100,
.flex.items-center.flex-wrap.gap-4 {
background-color: var(--m3-surface-container) !important;
border-color: var(--m3-outline-variant) !important;
}
tr.bg-slate-50,
.hover\:bg-slate-50\/50:hover,
.dark .dark\:hover\:bg-gray-800\/30:hover {
background-color: var(--m3-surface-container-high) !important;
}
.bg-gradient-to-r,
.from-blue-600,
.to-emerald-600 {
background-image: linear-gradient(90deg, var(--m3-primary), var(--m3-tertiary)) !important;
}
.from-blue-500\/5,
.to-purple-500\/5 {
--tw-gradient-from: color-mix(in srgb, var(--m3-primary) 7%, transparent) !important;
--tw-gradient-to: color-mix(in srgb, var(--m3-tertiary) 7%, transparent) !important;
}
.accent-blue-500 {
accent-color: var(--m3-primary);
}
.accent-orange-500 {
accent-color: var(--m3-secondary);
}
details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div {
background: #ffffff !important;
border-color: var(--m3-outline-variant) !important;
color: var(--m3-on-surface) !important;
}
.dark details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] > div {
background: var(--m3-surface-container-lowest) !important;
}
details .grid.grid-cols-\[3\.25rem_1fr_3\.25rem\] span,
details .grid.grid-cols-\[2rem_1fr_2rem\] input,
details .grid.grid-cols-\[2rem_1fr_2rem\] + span,
details button.touch-none span:last-child {
color: var(--m3-primary) !important;
}
details .grid.grid-cols-\[2rem_1fr_2rem\] input {
background: #ffffff !important;
border-color: var(--m3-outline-variant) !important;
}
.dark details .grid.grid-cols-\[2rem_1fr_2rem\] input {
background: var(--m3-surface-container-lowest) !important;
}
details .grid.grid-cols-\[2rem_1fr_2rem\] button {
background: var(--m3-secondary-container) !important;
color: var(--m3-on-secondary-container) !important;
}
details button.touch-none {
background: #ffffff !important;
border-color: var(--m3-outline-variant) !important;
}
.dark details button.touch-none {
background: var(--m3-surface-container-lowest) !important;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long