diff --git a/packages/frontend/index.html b/packages/frontend/index.html index 7323683..70cdfeb 100644 --- a/packages/frontend/index.html +++ b/packages/frontend/index.html @@ -5,6 +5,9 @@ + + + Recommender @@ -13,4 +16,4 @@ - \ No newline at end of file + diff --git a/packages/frontend/src/components/Cards.css b/packages/frontend/src/components/Cards.css index 444d391..301bdc9 100644 --- a/packages/frontend/src/components/Cards.css +++ b/packages/frontend/src/components/Cards.css @@ -3,20 +3,30 @@ .cards-grid { display: flex; flex-direction: column; - gap: 12px; - margin-bottom: 32px; + gap: var(--sp-3); + margin-bottom: var(--sp-8); } .card { - background: var(--bg-surface); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent 100%), + rgba(28, 25, 42, 0.7); + backdrop-filter: blur(14px) saturate(150%); border: 1px solid var(--border); - border-radius: var(--radius); - padding: 16px; - transition: border-color 0.15s; + border-radius: var(--radius-md); + padding: var(--sp-4); + box-shadow: + 0 8px 28px rgba(0, 0, 0, 0.18), + inset 0 1px 0 rgba(255, 255, 255, 0.04); + transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease; } .card:hover { - border-color: var(--bg-surface-3); + border-color: rgba(232, 168, 124, 0.28); + transform: translateY(-1px); + box-shadow: + 0 12px 36px rgba(0, 0, 0, 0.24), + inset 0 1px 0 rgba(255, 255, 255, 0.05); } .card-header { @@ -31,35 +41,41 @@ font-size: 11px; font-weight: 600; padding: 2px 8px; - border-radius: 100px; + border-radius: var(--radius-pill); text-transform: uppercase; - letter-spacing: 0.04em; + letter-spacing: 0.08em; flex-shrink: 0; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04); } .badge-green { - background: rgba(34, 197, 94, 0.15); + background: rgba(34, 197, 94, 0.14); color: #4ade80; + box-shadow: 0 0 18px rgba(34, 197, 94, 0.14); } .badge-blue { background: rgba(59, 130, 246, 0.15); color: #60a5fa; + box-shadow: 0 0 18px rgba(59, 130, 246, 0.14); } .badge-yellow { background: rgba(234, 179, 8, 0.15); color: #facc15; + box-shadow: 0 0 18px rgba(234, 179, 8, 0.12); } .badge-red { background: rgba(239, 68, 68, 0.15); color: #f87171; + box-shadow: 0 0 18px rgba(239, 68, 68, 0.12); } .badge-magenta { background: rgba(217, 70, 239, 0.15); color: #e879f9; + box-shadow: 0 0 18px rgba(217, 70, 239, 0.14); } .badge-verified { @@ -81,16 +97,16 @@ } .card-explanation { - font-size: 13px; + font-size: 14px; color: var(--text-muted); - line-height: 1.5; - margin-bottom: 8px; + line-height: 1.6; + margin-bottom: 10px; } .genre-badge { font-size: 10px; font-weight: 500; - background: rgba(148, 163, 184, 0.12); + background: rgba(245, 240, 232, 0.08); color: var(--text-dim); display: inline-block; text-transform: none; @@ -182,7 +198,7 @@ .btn-rerank { padding: 12px 28px; - background: var(--bg-surface-2); + background: rgba(255, 255, 255, 0.05); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); @@ -193,9 +209,9 @@ } .btn-rerank:hover:not(:disabled) { - background: var(--bg-surface-3); - border-color: var(--accent); - color: var(--accent); + background: rgba(255, 255, 255, 0.09); + border-color: rgba(232, 168, 124, 0.24); + color: var(--text); } .btn-rerank:disabled { diff --git a/packages/frontend/src/components/Modal.css b/packages/frontend/src/components/Modal.css index e537d9a..2b9b624 100644 --- a/packages/frontend/src/components/Modal.css +++ b/packages/frontend/src/components/Modal.css @@ -7,9 +7,9 @@ justify-content: center; padding: 24px; background: - radial-gradient(circle at top, rgba(56, 189, 248, 0.12), transparent 32%), - radial-gradient(circle at bottom right, rgba(251, 191, 36, 0.12), transparent 28%), - rgba(6, 8, 12, 0.76); + radial-gradient(circle at top, rgba(232, 168, 124, 0.12), transparent 32%), + radial-gradient(circle at bottom right, rgba(245, 240, 232, 0.08), transparent 28%), + rgba(10, 8, 15, 0.78); backdrop-filter: blur(12px); } @@ -21,7 +21,7 @@ border-radius: 28px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 18%), - linear-gradient(145deg, rgba(15, 23, 42, 0.97), rgba(17, 24, 39, 0.96)); + linear-gradient(145deg, rgba(28, 25, 42, 0.96), rgba(22, 19, 34, 0.97)); box-shadow: 0 32px 90px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.05); @@ -41,13 +41,13 @@ font-size: clamp(1.8rem, 3vw, 2.35rem); line-height: 1.05; letter-spacing: -0.03em; - color: #f8fafc; + color: var(--text); } .modal-hero-copy { max-width: 560px; margin-top: 12px; - color: rgba(226, 232, 240, 0.72); + color: rgba(245, 240, 232, 0.7); font-size: 1rem; line-height: 1.6; } @@ -58,8 +58,8 @@ margin-bottom: 14px; padding: 6px 10px; border-radius: 999px; - background: rgba(56, 189, 248, 0.14); - color: #7dd3fc; + background: rgba(232, 168, 124, 0.14); + color: var(--accent); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; @@ -84,9 +84,9 @@ .modal-close:hover:not(:disabled), .modal-back:hover:not(:disabled) { transform: translateY(-1px); - color: #f8fafc; - border-color: rgba(125, 211, 252, 0.34); - background: rgba(56, 189, 248, 0.08); + color: var(--text); + border-color: rgba(232, 168, 124, 0.34); + background: rgba(232, 168, 124, 0.08); } .modal-close:disabled, @@ -118,7 +118,8 @@ border-radius: 24px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent 100%), - rgba(15, 23, 42, 0.58); + rgba(28, 25, 42, 0.58); + backdrop-filter: blur(16px) saturate(160%); } .modal-section-header { @@ -131,7 +132,7 @@ .modal-section-header h3, .settings-card-header h3 { font-size: 1.08rem; - color: #f8fafc; + color: var(--text); } .modal-section-header p, @@ -148,8 +149,8 @@ width: 32px; height: 32px; border-radius: 50%; - background: linear-gradient(135deg, rgba(56, 189, 248, 0.18), rgba(251, 191, 36, 0.16)); - color: #f8fafc; + background: linear-gradient(135deg, rgba(232, 168, 124, 0.22), rgba(245, 240, 232, 0.14)); + color: var(--text); font-weight: 700; } @@ -177,7 +178,7 @@ border-radius: 22px; background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 100%), - rgba(30, 41, 59, 0.68); + rgba(36, 33, 56, 0.68); color: inherit; text-align: left; cursor: pointer; @@ -187,17 +188,17 @@ .type-card:hover, .mode-card:hover { transform: translateY(-2px); - border-color: rgba(125, 211, 252, 0.4); + border-color: rgba(232, 168, 124, 0.36); box-shadow: 0 18px 32px rgba(2, 8, 23, 0.25); } .type-card--selected, .mode-card--active { - border-color: rgba(125, 211, 252, 0.55); + border-color: rgba(232, 168, 124, 0.55); background: - linear-gradient(180deg, rgba(56, 189, 248, 0.12), rgba(251, 191, 36, 0.06)), - rgba(17, 24, 39, 0.92); - box-shadow: inset 0 0 0 1px rgba(125, 211, 252, 0.14); + linear-gradient(180deg, rgba(232, 168, 124, 0.12), rgba(245, 240, 232, 0.04)), + rgba(28, 25, 42, 0.92); + box-shadow: inset 0 0 0 1px rgba(232, 168, 124, 0.16); } .type-card-icon { @@ -211,7 +212,7 @@ .type-card-label, .mode-card-label { - color: #f8fafc; + color: var(--text); font-size: 1.04rem; font-weight: 700; } @@ -224,7 +225,7 @@ .type-card-desc, .mode-card-desc { - color: rgba(226, 232, 240, 0.72); + color: rgba(245, 240, 232, 0.66); line-height: 1.55; font-size: 0.92rem; } @@ -234,8 +235,8 @@ align-items: center; padding: 4px 10px; border-radius: 999px; - background: rgba(251, 191, 36, 0.14); - color: #fcd34d; + background: rgba(232, 168, 124, 0.14); + color: var(--accent); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; @@ -263,15 +264,15 @@ border-radius: 999px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.08); - color: #e2e8f0; + color: var(--text); font-size: 0.8rem; font-weight: 600; } .summary-pill--accent { - background: rgba(56, 189, 248, 0.12); - border-color: rgba(125, 211, 252, 0.22); - color: #7dd3fc; + background: rgba(232, 168, 124, 0.12); + border-color: rgba(232, 168, 124, 0.22); + color: var(--accent); } .summary-caption { @@ -304,7 +305,7 @@ } .form-group label { - color: #e2e8f0; + color: var(--text); font-size: 0.92rem; font-weight: 600; } @@ -321,8 +322,8 @@ padding: 13px 14px; border: 1px solid rgba(255, 255, 255, 0.09); border-radius: 16px; - background: rgba(15, 23, 42, 0.66); - color: #f8fafc; + background: rgba(18, 16, 26, 0.85); + color: var(--text); font: inherit; outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease; @@ -330,14 +331,14 @@ .form-input::placeholder, .form-textarea::placeholder { - color: #64748b; + color: var(--text-dim); } .form-input:focus, .form-textarea:focus { - border-color: rgba(125, 211, 252, 0.52); - box-shadow: 0 0 0 4px rgba(56, 189, 248, 0.12); - background: rgba(15, 23, 42, 0.86); + border-color: rgba(232, 168, 124, 0.52); + box-shadow: 0 0 0 4px rgba(232, 168, 124, 0.12); + background: rgba(18, 16, 26, 0.94); } .form-input[type='range'] { @@ -365,15 +366,15 @@ border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 24px; background: - radial-gradient(circle at top right, rgba(56, 189, 248, 0.07), transparent 28%), - rgba(15, 23, 42, 0.58); + radial-gradient(circle at top right, rgba(232, 168, 124, 0.08), transparent 28%), + rgba(28, 25, 42, 0.58); } .slider-card { padding: 16px 18px; border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.08); - background: rgba(15, 23, 42, 0.72); + background: rgba(18, 16, 26, 0.72); } .slider-card--compact { @@ -390,7 +391,7 @@ .slider-label { display: block; - color: #f8fafc; + color: var(--text); font-weight: 600; } @@ -406,8 +407,8 @@ min-width: 48px; padding: 8px 10px; border-radius: 12px; - background: rgba(56, 189, 248, 0.12); - color: #7dd3fc; + background: rgba(232, 168, 124, 0.12); + color: var(--accent); font-weight: 700; text-align: center; } @@ -422,7 +423,7 @@ padding: 15px 16px; border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.07); - background: rgba(15, 23, 42, 0.6); + background: rgba(28, 25, 42, 0.6); } .toggle-card--disabled { @@ -443,7 +444,7 @@ } .toggle-title { - color: #f8fafc; + color: var(--text); font-weight: 600; } @@ -466,8 +467,8 @@ } .toggle-switch.on { - background: linear-gradient(135deg, rgba(56, 189, 248, 0.95), rgba(14, 165, 233, 0.85)); - border-color: rgba(125, 211, 252, 0.4); + background: rgba(232, 168, 124, 0.3); + border-color: rgba(232, 168, 124, 0.4); } .toggle-switch-disabled { @@ -481,12 +482,14 @@ width: 22px; height: 22px; border-radius: 50%; - background: #fff; + background: var(--text-muted); transition: transform 0.2s ease; } .toggle-switch.on .toggle-knob { transform: translateX(22px); + background: var(--accent); + box-shadow: 0 0 8px rgba(232, 168, 124, 0.4); } .expansive-options { @@ -495,8 +498,8 @@ gap: 14px; padding: 16px; border-radius: 18px; - border: 1px solid rgba(125, 211, 252, 0.14); - background: rgba(8, 47, 73, 0.15); + border: 1px solid rgba(232, 168, 124, 0.14); + background: rgba(232, 168, 124, 0.08); } .segmented-control { @@ -509,7 +512,7 @@ padding: 12px 14px; border-radius: 14px; border: 1px solid rgba(255, 255, 255, 0.08); - background: rgba(15, 23, 42, 0.66); + background: rgba(18, 16, 26, 0.66); color: var(--text-muted); cursor: pointer; font: inherit; @@ -518,9 +521,9 @@ } .segmented-control-btn--active { - background: rgba(56, 189, 248, 0.12); - border-color: rgba(125, 211, 252, 0.34); - color: #7dd3fc; + background: rgba(232, 168, 124, 0.12); + border-color: rgba(232, 168, 124, 0.34); + color: var(--accent); } .modal-actions { diff --git a/packages/frontend/src/components/PipelineProgress.css b/packages/frontend/src/components/PipelineProgress.css index d03f3e0..101d329 100644 --- a/packages/frontend/src/components/PipelineProgress.css +++ b/packages/frontend/src/components/PipelineProgress.css @@ -1,14 +1,14 @@ /* ── Pipeline Progress ──────────────────────────────────── */ .pipeline-progress { - padding: 40px 0; + padding: var(--sp-8) 0; } .pipeline-title { font-size: 18px; font-weight: 600; color: var(--text); - margin-bottom: 24px; + margin-bottom: var(--sp-6); } .pipeline-steps { @@ -23,15 +23,21 @@ align-items: center; gap: 12px; padding: 12px 16px; - background: var(--bg-surface); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 100%), + var(--bg-surface); + backdrop-filter: blur(14px) saturate(150%); border: 1px solid var(--border); - border-radius: var(--radius); + border-radius: var(--radius-md); font-size: 14px; + box-shadow: 0 10px 24px rgba(0, 0, 0, 0.16); } .pipeline-step--running { - border-color: var(--accent); - background: var(--accent-dim); + border-color: rgba(232, 168, 124, 0.3); + background: + linear-gradient(180deg, rgba(232, 168, 124, 0.08), transparent 100%), + rgba(28, 25, 42, 0.82); } .pipeline-step--done { diff --git a/packages/frontend/src/components/Sidebar.css b/packages/frontend/src/components/Sidebar.css index cd9e37c..75d8534 100644 --- a/packages/frontend/src/components/Sidebar.css +++ b/packages/frontend/src/components/Sidebar.css @@ -2,16 +2,20 @@ .sidebar { width: var(--sidebar-width); - background: var(--bg-surface); - border-right: 1px solid var(--border); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent 100%), + rgba(28, 25, 42, 0.82); + backdrop-filter: blur(20px) saturate(160%); + border-right: 1px solid rgba(255, 255, 255, 0.07); display: flex; flex-direction: column; overflow: hidden; flex-shrink: 0; + box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.02); } .sidebar-header { - padding: 20px 16px 12px; + padding: var(--sp-5) var(--sp-4) var(--sp-3); border-bottom: 1px solid var(--border); text-align: center; } @@ -20,7 +24,7 @@ font-size: 24px; font-weight: 700; color: var(--text); - letter-spacing: -0.3px; + letter-spacing: -0.03em; text-decoration: none; display: inline-block; transition: color 0.15s ease; @@ -32,28 +36,31 @@ } .btn-new { - margin: 12px; + margin: var(--sp-3); padding: 10px 14px; background: var(--accent); - color: #fff; + color: #1a141f; border: none; border-radius: var(--radius); font-size: 13px; font-weight: 600; cursor: pointer; - transition: background 0.15s; + transition: background 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease; text-align: left; + box-shadow: 0 8px 24px rgba(232, 168, 124, 0.18); } .btn-new:hover { background: var(--accent-hover); + transform: translateY(-1px); + box-shadow: 0 12px 30px rgba(232, 168, 124, 0.22); } .sidebar-section-label { padding: 8px 16px 4px; font-size: 11px; font-weight: 600; - letter-spacing: 0.06em; + letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); } @@ -76,21 +83,27 @@ align-items: center; gap: 8px; padding: 8px 10px; - border-radius: var(--radius-sm); + border-radius: 10px; cursor: pointer; color: var(--text-muted); font-size: 13px; - transition: background 0.1s, color 0.1s; + border: 1px solid transparent; + transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease; user-select: none; } .sidebar-item:hover { - background: var(--bg-surface-2); + background: rgba(255, 255, 255, 0.05); + border-color: rgba(255, 255, 255, 0.06); color: var(--text); + transform: translateX(1px); } .sidebar-item.selected { - background: var(--accent-dim); + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent 100%), + rgba(232, 168, 124, 0.12); + border-color: rgba(232, 168, 124, 0.22); color: var(--text); } @@ -129,7 +142,7 @@ font-size: 10px; font-weight: 600; padding: 2px 5px; - border-radius: 4px; + border-radius: var(--radius-xs); text-transform: uppercase; letter-spacing: 0.04em; } @@ -163,4 +176,13 @@ .sidebar-item-delete:hover { color: var(--red); -} \ No newline at end of file +} + +@media (max-width: 720px) { + .sidebar { + width: 100%; + max-height: 42vh; + border-right: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.07); + } +} diff --git a/packages/frontend/src/components/Sidebar.tsx b/packages/frontend/src/components/Sidebar.tsx index 92762a8..d7c292c 100644 --- a/packages/frontend/src/components/Sidebar.tsx +++ b/packages/frontend/src/components/Sidebar.tsx @@ -1,4 +1,5 @@ import './Sidebar.css'; +import { route } from 'preact-router'; import type { RecommendationSummary } from '../types/index.js'; interface SidebarProps { @@ -30,10 +31,27 @@ export function Sidebar({ list, selectedId, onSelect, onNewClick }: SidebarProps return (