feat: one card title rule and a motion pass
Every card title now sits first inside its card under a mono registration plate; chapter titles stay outside, above the plate. Cards rise and unmask as they enter the reading window, lift on hover and focus, chapters settle in sequence on arrival and the gantry lane lamps light along the route. All motion is transform and clip-path, behind reduced-motion.
This commit is contained in:
BIN
docs/redesign/round5/cards-after-1440.webp
Normal file
BIN
docs/redesign/round5/cards-after-1440.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
BIN
docs/redesign/round5/cards-before-1440.webp
Normal file
BIN
docs/redesign/round5/cards-before-1440.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
@@ -13,6 +13,7 @@ import './styles/title-navigation.css';
|
|||||||
import './styles/wayfinding.css';
|
import './styles/wayfinding.css';
|
||||||
import './styles/route.css';
|
import './styles/route.css';
|
||||||
import './styles/gantry.css';
|
import './styles/gantry.css';
|
||||||
|
import './styles/cards.css';
|
||||||
import './styles/print.css';
|
import './styles/print.css';
|
||||||
|
|
||||||
defineProps<{ inputs: Readonly<ProductionInputs> }>();
|
defineProps<{ inputs: Readonly<ProductionInputs> }>();
|
||||||
|
|||||||
168
src/styles/cards.css
Normal file
168
src/styles/cards.css
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
Round 5: one card rule, and the motion pass.
|
||||||
|
|
||||||
|
The rule: a chapter title sits outside, above its plate. Every card title
|
||||||
|
sits inside its card, first, under a mono registration plate in the
|
||||||
|
form "EXIT.N / KIND", the same plate the project cards already carry.
|
||||||
|
Plates are decorative and generated by CSS (alt text ''), so the server
|
||||||
|
and hydrated text stay identical and screen readers hear titles only.
|
||||||
|
|
||||||
|
Motion is transform, clip-path and colour only, never on the chapter
|
||||||
|
headings (journey and audio measure them), and only with
|
||||||
|
prefers-reduced-motion: no-preference.
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* ---------- Registration plates for the cards that lacked one ---------- */
|
||||||
|
.experience-timeline { counter-reset: role; }
|
||||||
|
.experience-timeline > li { counter-increment: role; }
|
||||||
|
.toolkit-grid { counter-reset: stack; }
|
||||||
|
.toolkit-group { counter-increment: stack; }
|
||||||
|
|
||||||
|
.experience-record h3::before,
|
||||||
|
.systems-operations h3::before,
|
||||||
|
.infrastructure-case > h3::before,
|
||||||
|
.toolkit-group h3::before {
|
||||||
|
display: block;
|
||||||
|
inline-size: max-content;
|
||||||
|
max-inline-size: 100%;
|
||||||
|
margin-block-end: 0.85rem;
|
||||||
|
padding: 0.34rem 0.6rem 0.3rem;
|
||||||
|
border: 1px solid color-mix(in srgb, var(--chapter-accent, var(--accent)) 55%, transparent);
|
||||||
|
border-radius: 3px;
|
||||||
|
color: color-mix(in srgb, var(--chapter-accent, var(--accent)) 72%, var(--text));
|
||||||
|
font: 650 0.64rem/1.2 var(--mono);
|
||||||
|
letter-spacing: 0.14em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.experience-record h3::before { content: '03.' counter(role) ' / Role' / ''; }
|
||||||
|
.systems-operations h3::before { content: '03.S / Operations' / ''; }
|
||||||
|
.infrastructure-case > h3::before { content: '04.1 / Platform' / ''; }
|
||||||
|
.toolkit-group h3::before { content: '07.' counter(stack) ' / Stack' / ''; }
|
||||||
|
|
||||||
|
@media (forced-colors: active) {
|
||||||
|
.experience-record h3::before,
|
||||||
|
.systems-operations h3::before,
|
||||||
|
.infrastructure-case > h3::before,
|
||||||
|
.toolkit-group h3::before {
|
||||||
|
border-color: CanvasText;
|
||||||
|
color: CanvasText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
.experience-record h3::before,
|
||||||
|
.systems-operations h3::before,
|
||||||
|
.infrastructure-case > h3::before,
|
||||||
|
.toolkit-group h3::before { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Tailored cards ---------- */
|
||||||
|
/* Project cards and the operations card are panels: a lit top edge in the
|
||||||
|
chapter accent, which the hover draws out across the card. */
|
||||||
|
.project-card,
|
||||||
|
.systems-operations {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.project-card::after,
|
||||||
|
.systems-operations::after {
|
||||||
|
content: '' / '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0 0 auto;
|
||||||
|
block-size: 2px;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
color-mix(in srgb, var(--chapter-accent, var(--accent)) 85%, transparent),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
pointer-events: none;
|
||||||
|
transform: scaleX(0.34);
|
||||||
|
transform-origin: left;
|
||||||
|
}
|
||||||
|
@media (forced-colors: active) {
|
||||||
|
.project-card::after,
|
||||||
|
.systems-operations::after { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Motion ---------- */
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
/* Hover and focus: cards lift, their accent edge runs across. */
|
||||||
|
.project-card,
|
||||||
|
.systems-operations,
|
||||||
|
.experience-record,
|
||||||
|
.toolkit-group {
|
||||||
|
transition:
|
||||||
|
transform 420ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||||
|
box-shadow 420ms ease;
|
||||||
|
}
|
||||||
|
.project-card::after,
|
||||||
|
.systems-operations::after {
|
||||||
|
transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
}
|
||||||
|
.project-card:is(:hover, :focus-within)::after,
|
||||||
|
.systems-operations:is(:hover, :focus-within)::after {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
.project-card:is(:hover, :focus-within),
|
||||||
|
.systems-operations:is(:hover, :focus-within) {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 22px 48px -24px color-mix(in srgb, var(--chapter-accent, var(--accent)) 55%, transparent);
|
||||||
|
}
|
||||||
|
.experience-record:is(:hover, :focus-within),
|
||||||
|
.toolkit-group:is(:hover, :focus-within) {
|
||||||
|
transform: translateX(6px);
|
||||||
|
}
|
||||||
|
.toolkit-item svg,
|
||||||
|
.toolkit-item img {
|
||||||
|
transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
}
|
||||||
|
.toolkit-item:hover svg,
|
||||||
|
.toolkit-item:hover img {
|
||||||
|
transform: translateY(-2px) scale(1.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card reveals: each card rises and unmasks as it enters the reading
|
||||||
|
window. Scroll-linked, so it can never lag behind the reader. */
|
||||||
|
@supports (animation-timeline: view()) {
|
||||||
|
.reading-stage .project-card,
|
||||||
|
.reading-stage .systems-operations,
|
||||||
|
.reading-stage .experience-record,
|
||||||
|
.reading-stage .toolkit-group,
|
||||||
|
.reading-stage .infrastructure-node {
|
||||||
|
animation: card-reveal linear both;
|
||||||
|
animation-timeline: view();
|
||||||
|
animation-range: entry 0% entry 55%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chapter transitions: the arriving chapter's plate sweeps a light edge
|
||||||
|
across and its first cards settle in sequence. */
|
||||||
|
.reading-stage .portfolio-section[data-current] .chapter-body > :is(p, dl, ul, .experience-timeline, .toolkit-grid) {
|
||||||
|
animation: chapter-settle 900ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||||
|
}
|
||||||
|
.reading-stage .portfolio-section[data-current] .chapter-body > :nth-child(2) { animation-delay: 90ms; }
|
||||||
|
.reading-stage .portfolio-section[data-current] .chapter-body > :nth-child(3) { animation-delay: 180ms; }
|
||||||
|
.reading-stage .portfolio-section[data-current] .chapter-body > :nth-child(n + 4) { animation-delay: 270ms; }
|
||||||
|
|
||||||
|
/* The gantry's lane lamps light in sequence along the route. */
|
||||||
|
html .site-navigation li:nth-child(2)::after { transition-delay: 40ms; }
|
||||||
|
html .site-navigation li:nth-child(3)::after { transition-delay: 80ms; }
|
||||||
|
html .site-navigation li:nth-child(4)::after { transition-delay: 120ms; }
|
||||||
|
html .site-navigation li:nth-child(5)::after { transition-delay: 160ms; }
|
||||||
|
html .site-navigation li:nth-child(6)::after { transition-delay: 200ms; }
|
||||||
|
html .site-navigation li:nth-child(7)::after { transition-delay: 240ms; }
|
||||||
|
html .site-navigation li:nth-child(8)::after { transition-delay: 280ms; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes card-reveal {
|
||||||
|
from {
|
||||||
|
transform: translateY(36px);
|
||||||
|
clip-path: inset(0 0 22% 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: none;
|
||||||
|
clip-path: inset(-40px -40px -40px -40px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes chapter-settle {
|
||||||
|
from { transform: translateY(14px); }
|
||||||
|
to { transform: none; }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user