chore: scaffold Astro 5 project with token/style layer
- Astro 5 static config (trailing-slash canonical, i18n en-root/no-prefixed) - Tailwind 4 over CSS custom-property tokens (both themes via [data-theme]) - design tokens: colour/spacing/type/radius/motion per Phase 1 specs - motion layer with reduced-motion overrides - strict TypeScript, ESLint flat config, Prettier - self-hosted variable fonts (Space Grotesk / Inter / JetBrains Mono) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Motion layer (ANIMATION_SPEC). Only transform / opacity / stroke-dashoffset animate.
|
||||
Reduced-motion is a single global override — not per-component JS (ANIMATION_SPEC §1).
|
||||
*/
|
||||
|
||||
/* ---- Reveal (A2): opacity + 12px rise, staggered by --reveal-index ---- */
|
||||
[data-reveal] {
|
||||
opacity: 0;
|
||||
transform: translateY(12px);
|
||||
transition:
|
||||
opacity var(--dur-entrance) var(--ease-out),
|
||||
transform var(--dur-entrance) var(--ease-out);
|
||||
transition-delay: calc(var(--reveal-index, 0) * 60ms);
|
||||
}
|
||||
[data-reveal].is-revealed {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* ---- Trace draw (A1) ---- */
|
||||
@keyframes trace-draw {
|
||||
from {
|
||||
stroke-dashoffset: var(--trace-len, 600);
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
@keyframes dot-blink {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
40% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
.trace-line {
|
||||
stroke-dasharray: var(--trace-len, 600);
|
||||
stroke-dashoffset: var(--trace-len, 600);
|
||||
animation: trace-draw var(--dur-signature) var(--ease-in-out) forwards;
|
||||
}
|
||||
[data-seen] .trace-line {
|
||||
animation: none;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
.trace-dot {
|
||||
animation: dot-blink 900ms var(--ease-out) 700ms 1;
|
||||
}
|
||||
|
||||
/* ---- Status chip pulse (A4): 2 iterations, ~1Hz ---- */
|
||||
@keyframes chip-pulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.4);
|
||||
opacity: 0.55;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.is-revealed .status-dot--active {
|
||||
animation: chip-pulse 900ms var(--ease-out) 2;
|
||||
}
|
||||
|
||||
/* ---- Timeline spine grow (A8) ---- */
|
||||
.timeline-spine {
|
||||
transform: scaleY(0);
|
||||
transform-origin: top;
|
||||
transition: transform var(--dur-entrance) var(--ease-out);
|
||||
}
|
||||
.is-revealed .timeline-spine {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
/* ---- 404 fray (A10) ---- */
|
||||
@keyframes fray {
|
||||
from {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
to {
|
||||
stroke-dashoffset: 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Check-draw for form success (A9) ---- */
|
||||
@keyframes check-draw {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
.check-path {
|
||||
stroke-dasharray: 24;
|
||||
stroke-dashoffset: 24;
|
||||
animation: check-draw var(--dur-standard) var(--ease-out) forwards;
|
||||
}
|
||||
|
||||
/* ---- View-transition language/route cross-fade (A6/A7) ---- */
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation-duration: var(--dur-quick);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Reduced motion: durations collapse, translations disabled,
|
||||
animated states render at their final frame (no content lost).
|
||||
============================================================ */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 1ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 1ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
[data-reveal] {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
.trace-line {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
.timeline-spine {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user