From fd79069bf76e32e53cde825afeaa815b705d6f97 Mon Sep 17 00:00:00 2001 From: Dorian Date: Tue, 17 Mar 2026 00:57:14 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20splash=20redesign=20=E2=80=94=20logo=20?= =?UTF-8?q?crossfade=20to=20viewport-filling=20tagline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Logo draws in centered, then fades out - Tagline replaces logo in viewport center - Bebas Neue (condensed hipster block) for main words - Playfair Display italic 900 for PSYOP in Bitcoin orange - Desktop: one line. Tablet (900px): 2 lines. Mobile (500px): 4 lines - Words slam in with blur-to-sharp + scaleY bounce - PSYOP lands with extra bounce-slam keyframes Co-Authored-By: Claude Opus 4.6 (1M context) --- index.html | 3 + src/components/splash/LogoSplash.vue | 220 ++++++++++++++------------- 2 files changed, 121 insertions(+), 102 deletions(-) diff --git a/index.html b/index.html index 4004402..714b706 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,9 @@ Antonym + + +
diff --git a/src/components/splash/LogoSplash.vue b/src/components/splash/LogoSplash.vue index a9109f6..a4e19b4 100644 --- a/src/components/splash/LogoSplash.vue +++ b/src/components/splash/LogoSplash.vue @@ -4,6 +4,7 @@ import { ref, onMounted } from 'vue' const emit = defineEmits<{ complete: [] }>() const isAnimating = ref(false) +const logoGone = ref(false) const showTagline = ref(false) const showPsyop = ref(false) const isFading = ref(false) @@ -12,72 +13,77 @@ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce) onMounted(() => { if (prefersReducedMotion) { - isAnimating.value = true + logoGone.value = true showTagline.value = true showPsyop.value = true setTimeout(() => emit('complete'), 800) return } - // Phase 1: Logo draws in + // Phase 1: Logo draws in (0–1700ms) requestAnimationFrame(() => { isAnimating.value = true }) - // Phase 2: Logo shrinks up, tagline words slam in one by one + // Phase 2: Logo fades out (1800ms) setTimeout(() => { - showTagline.value = true + logoGone.value = true }, 1800) - // Phase 3: "PSYOP" lands last with extra punch + // Phase 3: Tagline words slam in (2200ms) + setTimeout(() => { + showTagline.value = true + }, 2200) + + // Phase 4: PSYOP lands (3200ms) setTimeout(() => { showPsyop.value = true - }, 2800) + }, 3200) - // Phase 4: Hold, then fade + // Phase 5: Fade out (4600ms) setTimeout(() => { isFading.value = true - }, 4200) + }, 4600) setTimeout(() => { emit('complete') - }, 4700) + }, 5100) }) @@ -100,28 +106,10 @@ onMounted(() => { pointer-events: none; } -.splash-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 2rem; - transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1); -} - -.splash-content.logo-shrunk { - transform: translateY(-8vh); -} - +/* --- Logo --- */ .splash-logo { width: min(60vw, 340px); height: auto; - transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1), - opacity 600ms ease; -} - -.logo-shrunk .splash-logo { - transform: scale(0.7); - opacity: 0.6; } .logo-path { @@ -149,84 +137,97 @@ onMounted(() => { /* --- Tagline --- */ .tagline-block { + display: flex; + flex-direction: column; + align-items: center; + gap: 0; + padding: 0 3vw; + text-align: center; +} + +.tagline-line { display: flex; flex-wrap: nowrap; justify-content: center; - gap: 0 0.3em; - width: 92vw; - max-width: 1100px; - text-align: center; - line-height: 1.05; + gap: 0 0.25em; + white-space: nowrap; } .word { - font-family: system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif; - font-size: clamp(2rem, 5.5vw, 5rem); - font-weight: 900; + font-family: 'Bebas Neue', 'Impact', 'Arial Black', sans-serif; + font-size: clamp(1.8rem, 4.2vw, 4.5rem); + font-weight: 400; /* Bebas Neue only has 400 but looks ultra bold */ color: var(--text-primary); text-transform: uppercase; - letter-spacing: -0.02em; + letter-spacing: 0.04em; + line-height: 1; opacity: 0; - transform: translateY(40px) scale(1.1); - filter: blur(8px); + transform: translateY(50px) scaleY(1.3); + filter: blur(10px); } .tagline-block.visible .word { - animation: slamIn 400ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--w) * 150ms) forwards; + animation: slamIn 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--w) * 120ms) forwards; } @keyframes slamIn { 0% { opacity: 0; - transform: translateY(40px) scale(1.1); - filter: blur(8px); + transform: translateY(50px) scaleY(1.3); + filter: blur(10px); } - 60% { + 50% { opacity: 1; - transform: translateY(-4px) scale(1.0); + transform: translateY(-3px) scaleY(0.97); filter: blur(0); } + 75% { + transform: translateY(1px) scaleY(1.01); + } 100% { opacity: 1; - transform: translateY(0) scale(1.0); + transform: translateY(0) scaleY(1); filter: blur(0); } } -/* PSYOP — different font, extra punch */ +/* PSYOP — italic serif, massive, Bitcoin orange */ .psyop { - font-family: 'Georgia', 'Times New Roman', 'Playfair Display', serif; + font-family: 'Playfair Display', 'Georgia', 'Times New Roman', serif; font-style: italic; + font-weight: 900; color: var(--accent); - display: block; - width: 100%; - font-size: clamp(3.5rem, 15vw, 10rem); - letter-spacing: 0.08em; - margin-top: 0.1em; - transform: translateY(60px) scale(1.3); - filter: blur(12px); + font-size: clamp(4rem, 13vw, 11rem); + letter-spacing: 0.06em; + line-height: 0.9; + margin-top: 0.05em; + transform: translateY(80px) scale(1.4); + filter: blur(16px); } .psyop.landed { - animation: psyopSlam 600ms cubic-bezier(0.16, 1, 0.3, 1) forwards; + animation: psyopSlam 700ms cubic-bezier(0.16, 1, 0.3, 1) forwards; } @keyframes psyopSlam { 0% { opacity: 0; - transform: translateY(60px) scale(1.3); - filter: blur(12px); + transform: translateY(80px) scale(1.4); + filter: blur(16px); } - 40% { + 35% { opacity: 1; - transform: translateY(-6px) scale(1.02); + transform: translateY(-8px) scale(1.02); filter: blur(0); } - 55% { - transform: translateY(2px) scale(0.99); + 50% { + transform: translateY(4px) scale(0.99); } - 70% { - transform: translateY(-1px) scale(1.0); + 65% { + transform: translateY(-2px) scale(1.005); + } + 80% { + transform: translateY(1px) scale(1.0); } 100% { opacity: 1; @@ -235,19 +236,36 @@ onMounted(() => { } } -/* Mobile: wrap to multiple lines */ -@media (max-width: 600px) { - .tagline-block { +/* Tablet: 2 lines — "EVERYTHING YOU" / "LOVE IS A" */ +@media (max-width: 900px) { + .tagline-line { flex-wrap: wrap; - width: 95vw; + white-space: normal; + gap: 0 0.25em; } .word { - font-size: clamp(2rem, 12vw, 3.5rem); + font-size: clamp(2rem, 7vw, 3.5rem); } .psyop { - font-size: clamp(3rem, 22vw, 5.5rem); + font-size: clamp(3.5rem, 18vw, 7rem); + } +} + +/* Mobile: 4 lines — each word on its own line */ +@media (max-width: 500px) { + .tagline-line { + flex-direction: column; + align-items: center; + } + + .word { + font-size: clamp(2.2rem, 13vw, 3.5rem); + } + + .psyop { + font-size: clamp(3rem, 20vw, 5rem); } } @@ -265,9 +283,7 @@ onMounted(() => { animation: none !important; } - .splash-overlay, - .splash-content, - .splash-logo { + .splash-overlay { transition: none; } }