diff --git a/.gitignore b/.gitignore index 76c9f06..7c78a60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ spectra-lab-local.png spectra-lab-redesign.png spectra-lab-polish.png +spectra-lab-refine-v2-desktop.png +spectra-lab-refine-v2-mobile.png .DS_Store diff --git a/app.js b/app.js index c0da016..84ea88a 100644 --- a/app.js +++ b/app.js @@ -6,12 +6,54 @@ const workTitle = document.getElementById('workTitle'); const workCopy = document.getElementById('workCopy'); const stageCard = document.querySelector('.stage-card'); const revealBlocks = document.querySelectorAll('.reveal'); +const toneChips = document.querySelectorAll('.tone-chip'); +const swatches = document.querySelectorAll('.swatch'); +const noteItems = document.querySelectorAll('.note-item'); +const densityRange = document.getElementById('densityRange'); +const densityValue = document.getElementById('densityValue'); +const previewCard = document.getElementById('previewCard'); +const previewTone = document.getElementById('previewTone'); +const previewDensity = document.getElementById('previewDensity'); +const previewTitle = document.getElementById('previewTitle'); +const previewText = document.getElementById('previewText'); +const previewAccentLabel = document.getElementById('previewAccentLabel'); +const previewNote = document.getElementById('previewNote'); const storedMode = window.localStorage.getItem('spectra-mode'); if (storedMode === 'light') { document.body.classList.add('light-mode'); } +const toneMap = { + quiet: { + label: 'Quiet tone', + title: 'A layout that leaves more breathing room.', + text: '较安静的版式语气会减少冲突感,让留白、边框与小字说明承担更多秩序工作。', + }, + balanced: { + label: 'Balanced tone', + title: 'A layout that knows where to stop.', + text: '平衡模式维持标题、说明与边框之间的中段张力,更适合作为正式落地页的默认状态。', + }, + dramatic: { + label: 'Dramatic tone', + title: 'A layout with sharper contrast and pacing.', + text: '更强对比的语气不会增加花哨效果,而是把标题权重、信息落差和段落收束做得更明显。', + }, +}; + +const densityMap = { + '1': 'Airy', + '2': 'Balanced', + '3': 'Dense', +}; + +const accentNames = { + '#7f2f2f': 'Accent / Oxblood', + '#3f5a73': 'Accent / Slate Blue', + '#6c6250': 'Accent / Warm Taupe', +}; + function applyMode() { const isLight = document.body.classList.contains('light-mode'); modeToggle.textContent = isLight ? 'Dark Mode' : 'Light Mode'; @@ -41,15 +83,56 @@ function updateWorkStage(item) { workCopy.textContent = item.dataset.copy || ''; } +function updatePreviewTone(tone) { + toneChips.forEach((chip) => chip.classList.toggle('is-active', chip.dataset.tone === tone)); + previewCard.dataset.tone = tone; + previewTone.textContent = toneMap[tone].label; + previewTitle.textContent = toneMap[tone].title; + previewText.textContent = toneMap[tone].text; +} + +function updatePreviewDensity(level) { + previewCard.dataset.density = level; + previewCard.style.padding = level === '1' ? '20px' : level === '3' ? '30px' : '24px'; + densityValue.textContent = densityMap[level]; + previewDensity.textContent = `Density 0${level}`; +} + +function updatePreviewAccent(accent) { + swatches.forEach((swatch) => swatch.classList.toggle('is-active', swatch.dataset.accent === accent)); + document.documentElement.style.setProperty('--accent', accent); + document.documentElement.style.setProperty('--accent-soft', `${accent}22`); + previewAccentLabel.textContent = accentNames[accent] || 'Accent / Custom'; +} + +function updatePreviewNote(note) { + noteItems.forEach((item) => item.classList.toggle('is-active', item.dataset.note === note)); + previewNote.textContent = note; +} + modeToggle?.addEventListener('click', () => { document.body.classList.toggle('light-mode'); applyMode(); }); workItems.forEach((item) => { - item.addEventListener('click', () => { - updateWorkStage(item); - }); + item.addEventListener('click', () => updateWorkStage(item)); +}); + +toneChips.forEach((chip) => { + chip.addEventListener('click', () => updatePreviewTone(chip.dataset.tone || 'balanced')); +}); + +swatches.forEach((swatch) => { + swatch.addEventListener('click', () => updatePreviewAccent(swatch.dataset.accent || '#7f2f2f')); +}); + +noteItems.forEach((item) => { + item.addEventListener('click', () => updatePreviewNote(item.dataset.note || '')); +}); + +densityRange?.addEventListener('input', (event) => { + updatePreviewDensity(event.target.value); }); const observer = new IntersectionObserver( @@ -65,7 +148,13 @@ const observer = new IntersectionObserver( ); revealBlocks.forEach((block) => observer.observe(block)); + if (workItems[0]) { updateWorkStage(workItems[0]); } + +updatePreviewTone('balanced'); +updatePreviewDensity(densityRange?.value || '2'); +updatePreviewAccent('#7f2f2f'); +updatePreviewNote('封面对齐决定第一印象。'); applyMode(); diff --git a/index.html b/index.html index bd0bfbb..95575d8 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ Spectra Lab