feat: polish spectra lab editorial details
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
spectra-lab-local.png
|
spectra-lab-local.png
|
||||||
spectra-lab-redesign.png
|
spectra-lab-redesign.png
|
||||||
|
spectra-lab-polish.png
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
38
app.js
38
app.js
@@ -4,12 +4,41 @@ const workItems = document.querySelectorAll('.work-item');
|
|||||||
const workIndex = document.getElementById('workIndex');
|
const workIndex = document.getElementById('workIndex');
|
||||||
const workTitle = document.getElementById('workTitle');
|
const workTitle = document.getElementById('workTitle');
|
||||||
const workCopy = document.getElementById('workCopy');
|
const workCopy = document.getElementById('workCopy');
|
||||||
|
const stageCard = document.querySelector('.stage-card');
|
||||||
const revealBlocks = document.querySelectorAll('.reveal');
|
const revealBlocks = document.querySelectorAll('.reveal');
|
||||||
|
const storedMode = window.localStorage.getItem('spectra-mode');
|
||||||
|
|
||||||
|
if (storedMode === 'light') {
|
||||||
|
document.body.classList.add('light-mode');
|
||||||
|
}
|
||||||
|
|
||||||
function applyMode() {
|
function applyMode() {
|
||||||
const isLight = document.body.classList.contains('light-mode');
|
const isLight = document.body.classList.contains('light-mode');
|
||||||
modeToggle.textContent = isLight ? 'Dark Mode' : 'Light Mode';
|
modeToggle.textContent = isLight ? 'Dark Mode' : 'Light Mode';
|
||||||
modeLabel.textContent = isLight ? 'Editorial Light' : 'Editorial Dark';
|
modeLabel.textContent = isLight ? 'Editorial Light' : 'Editorial Dark';
|
||||||
|
window.localStorage.setItem('spectra-mode', isLight ? 'light' : 'dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateWorkStage(item) {
|
||||||
|
workItems.forEach((button) => {
|
||||||
|
button.classList.remove('is-active');
|
||||||
|
button.setAttribute('aria-selected', 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
item.classList.add('is-active');
|
||||||
|
item.setAttribute('aria-selected', 'true');
|
||||||
|
|
||||||
|
stageCard?.classList.remove('is-refreshing');
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
stageCard?.classList.add('is-refreshing');
|
||||||
|
window.setTimeout(() => {
|
||||||
|
stageCard?.classList.remove('is-refreshing');
|
||||||
|
}, 340);
|
||||||
|
});
|
||||||
|
|
||||||
|
workIndex.textContent = item.dataset.index || '';
|
||||||
|
workTitle.textContent = item.dataset.title || '';
|
||||||
|
workCopy.textContent = item.dataset.copy || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
modeToggle?.addEventListener('click', () => {
|
modeToggle?.addEventListener('click', () => {
|
||||||
@@ -19,11 +48,7 @@ modeToggle?.addEventListener('click', () => {
|
|||||||
|
|
||||||
workItems.forEach((item) => {
|
workItems.forEach((item) => {
|
||||||
item.addEventListener('click', () => {
|
item.addEventListener('click', () => {
|
||||||
workItems.forEach((button) => button.classList.remove('is-active'));
|
updateWorkStage(item);
|
||||||
item.classList.add('is-active');
|
|
||||||
workIndex.textContent = item.dataset.index || '';
|
|
||||||
workTitle.textContent = item.dataset.title || '';
|
|
||||||
workCopy.textContent = item.dataset.copy || '';
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -40,4 +65,7 @@ const observer = new IntersectionObserver(
|
|||||||
);
|
);
|
||||||
|
|
||||||
revealBlocks.forEach((block) => observer.observe(block));
|
revealBlocks.forEach((block) => observer.observe(block));
|
||||||
|
if (workItems[0]) {
|
||||||
|
updateWorkStage(workItems[0]);
|
||||||
|
}
|
||||||
applyMode();
|
applyMode();
|
||||||
|
|||||||
18
index.html
18
index.html
@@ -61,6 +61,20 @@
|
|||||||
</p>
|
</p>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hero-ledger">
|
||||||
|
<article class="ledger-item">
|
||||||
|
<span>Design principle</span>
|
||||||
|
<strong>Less gesture, more judgment.</strong>
|
||||||
|
</article>
|
||||||
|
<article class="ledger-item">
|
||||||
|
<span>Material cue</span>
|
||||||
|
<strong>纸感、墨感、少量暗红,而不是数字炫光。</strong>
|
||||||
|
</article>
|
||||||
|
<article class="ledger-item">
|
||||||
|
<span>Reading rhythm</span>
|
||||||
|
<strong>先标题,再说明,再留下停顿。</strong>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="statement" class="statement section reveal">
|
<section id="statement" class="statement section reveal">
|
||||||
@@ -187,6 +201,10 @@
|
|||||||
<p>
|
<p>
|
||||||
如果第一页就把所有招式用完,观者只会记得“效果很多”。但如果页面知道何时收、何时留白、何时只用一条线和一块色面说话,它才更像真正完成度高的作品。
|
如果第一页就把所有招式用完,观者只会记得“效果很多”。但如果页面知道何时收、何时留白、何时只用一条线和一块色面说话,它才更像真正完成度高的作品。
|
||||||
</p>
|
</p>
|
||||||
|
<div class="closing-signoff">
|
||||||
|
<span>Spectra Lab / Editorial pass</span>
|
||||||
|
<span>Built for calm impact.</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
89
styles.css
89
styles.css
@@ -86,11 +86,16 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topbar {
|
.topbar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
padding: 28px 0 20px;
|
padding: 22px 0 18px;
|
||||||
|
background: linear-gradient(180deg, color-mix(in srgb, var(--bg) 82%, transparent 18%), color-mix(in srgb, var(--bg) 58%, transparent 42%));
|
||||||
|
backdrop-filter: blur(14px);
|
||||||
|
z-index: 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand {
|
.brand {
|
||||||
@@ -141,10 +146,47 @@ a {
|
|||||||
color: var(--text);
|
color: var(--text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mode-toggle:hover {
|
||||||
|
border-color: var(--line-strong);
|
||||||
|
background: var(--accent-soft);
|
||||||
|
}
|
||||||
|
|
||||||
.hero {
|
.hero {
|
||||||
padding: 42px 0 72px;
|
padding: 42px 0 72px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero-ledger {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 30px;
|
||||||
|
padding-top: 18px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ledger-item {
|
||||||
|
padding: 18px 18px 20px;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01));
|
||||||
|
}
|
||||||
|
|
||||||
|
.ledger-item span,
|
||||||
|
.closing-signoff span {
|
||||||
|
display: block;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.16em;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ledger-item strong {
|
||||||
|
display: block;
|
||||||
|
margin-top: 14px;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.hero-meta,
|
.hero-meta,
|
||||||
.section-head,
|
.section-head,
|
||||||
.footer {
|
.footer {
|
||||||
@@ -274,6 +316,11 @@ a {
|
|||||||
background: var(--accent-soft);
|
background: var(--accent-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.work-item.is-active .work-number,
|
||||||
|
.work-item.is-active small {
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
.work-number {
|
.work-number {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
@@ -299,17 +346,32 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stage-card {
|
.stage-card {
|
||||||
|
position: relative;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding: 34px;
|
padding: 34px;
|
||||||
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.06) 100%),
|
linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.06) 100%),
|
||||||
linear-gradient(135deg, rgba(255,255,255,0.02), transparent 48%),
|
linear-gradient(135deg, rgba(255,255,255,0.02), transparent 48%),
|
||||||
linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--panel) 80%, black 20%));
|
linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--panel) 80%, black 20%));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stage-card::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background: linear-gradient(180deg, transparent 0%, rgba(255, 255, 255, 0.04) 100%);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stage-card.is-refreshing {
|
||||||
|
animation: stageRefresh 320ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
.stage-index {
|
.stage-index {
|
||||||
font-size: clamp(4.2rem, 8vw, 8rem);
|
font-size: clamp(4.2rem, 8vw, 8rem);
|
||||||
line-height: 0.92;
|
line-height: 0.92;
|
||||||
@@ -354,6 +416,15 @@ a {
|
|||||||
color: rgba(20, 20, 20, 0.7);
|
color: rgba(20, 20, 20, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.closing-signoff {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 30px;
|
||||||
|
padding-top: 18px;
|
||||||
|
border-top: 1px solid rgba(20, 20, 20, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
padding: 22px 0 42px;
|
padding: 22px 0 42px;
|
||||||
border-top: 1px solid var(--line);
|
border-top: 1px solid var(--line);
|
||||||
@@ -370,12 +441,24 @@ a {
|
|||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes stageRefresh {
|
||||||
|
0% {
|
||||||
|
transform: translateY(8px);
|
||||||
|
opacity: 0.86;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1100px) {
|
@media (max-width: 1100px) {
|
||||||
.topbar,
|
.topbar,
|
||||||
.hero-meta,
|
.hero-meta,
|
||||||
.section-head,
|
.section-head,
|
||||||
.works-layout,
|
.works-layout,
|
||||||
.hero-grid,
|
.hero-grid,
|
||||||
|
.hero-ledger,
|
||||||
.statement-grid,
|
.statement-grid,
|
||||||
.system-grid,
|
.system-grid,
|
||||||
.footer {
|
.footer {
|
||||||
@@ -435,4 +518,8 @@ a {
|
|||||||
.closing-panel {
|
.closing-panel {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.closing-signoff {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user