d0ef3e2575
Implement a visually striking display for kind 62 vanish events with animated caution stripes, glitch effects, and a grand exit aesthetic. Since the user has nuked their account, the npub is shown instead of profile info. Supports both compact feed cards and full detail view with comments and sharing.
257 lines
6.5 KiB
CSS
257 lines
6.5 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@layer base {
|
|
:root {
|
|
--radius: 0.75rem;
|
|
}
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
*::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
.safe-area-top {
|
|
padding-top: env(safe-area-inset-top, 0px);
|
|
}
|
|
|
|
.safe-area-bottom {
|
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
|
}
|
|
|
|
.safe-area-inset-top {
|
|
top: env(safe-area-inset-top, 0px);
|
|
}
|
|
|
|
.safe-area-inset-bottom {
|
|
bottom: env(safe-area-inset-bottom, 0px);
|
|
}
|
|
|
|
/* FAB bottom offset: clears bottom nav + safe area inset on mobile */
|
|
.bottom-fab {
|
|
bottom: calc(1.5rem + 3.5rem + env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
/* Position above mobile bottom nav (h-14 = 3.5rem) + safe area */
|
|
.bottom-mobile-nav {
|
|
bottom: calc(3.5rem + env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
/* Bottom overscroll padding for the center column:
|
|
clears the mobile bottom nav + safe area + generous extra space
|
|
so content can be scrolled well past the bottom bar */
|
|
.pb-overscroll {
|
|
padding-bottom: calc(10vh + 3.5rem + env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
@media (min-width: 900px) {
|
|
.pb-overscroll {
|
|
padding-bottom: 10vh;
|
|
}
|
|
}
|
|
|
|
/* Mobile top bar height (48px) + safe area inset for sticky elements */
|
|
.top-mobile-bar {
|
|
top: calc(3rem + env(safe-area-inset-top, 0px));
|
|
}
|
|
|
|
/* AI chat height on mobile: full viewport minus top bar, bottom nav (3.5rem), and safe-area insets */
|
|
.ai-chat-height {
|
|
height: calc(100dvh - 3rem - 3.5rem - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
/* Live stream page height on mobile: full viewport minus top bar, bottom nav, and safe-area insets */
|
|
.livestream-height {
|
|
height: calc(100dvh - 3rem - 3.5rem - env(safe-area-inset-bottom, 0px));
|
|
max-height: calc(100dvh - 3rem - 3.5rem - env(safe-area-inset-bottom, 0px));
|
|
}
|
|
|
|
/* Vine feed slide height: full viewport minus top bar, tab bar, bottom nav, and safe-area insets */
|
|
.vine-slide-height {
|
|
height: calc(100dvh - env(safe-area-inset-top, 0px) - 3rem - 2.5rem - 3.5rem - env(safe-area-inset-bottom, 0px));
|
|
transition: height 300ms ease-in-out;
|
|
}
|
|
|
|
/* Expanded vine height when bottom nav is hidden */
|
|
.vine-slide-height-expanded {
|
|
height: calc(100dvh - env(safe-area-inset-top, 0px) - 3rem - 2.5rem);
|
|
transition: height 300ms ease-in-out;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@keyframes spin {
|
|
from { transform: rotate(0deg); }
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* 3-burst ping: pulses 3 times then stops */
|
|
@keyframes ping-3 {
|
|
0% { transform: scale(1); opacity: 0.6; }
|
|
11% { transform: scale(2); opacity: 0; }
|
|
22% { transform: scale(1); opacity: 0; }
|
|
33% { transform: scale(1); opacity: 0.6; }
|
|
44% { transform: scale(2); opacity: 0; }
|
|
55% { transform: scale(1); opacity: 0; }
|
|
66% { transform: scale(1); opacity: 0.6; }
|
|
77% { transform: scale(2); opacity: 0; }
|
|
100% { transform: scale(1); opacity: 0; }
|
|
}
|
|
|
|
.animate-ping-3 {
|
|
animation: ping-3 4s ease-out forwards;
|
|
}
|
|
|
|
/* Slow continuous pulse for nagging buttons */
|
|
@keyframes pulse-slow {
|
|
0%, 100% { transform: scale(1); opacity: 0.5; }
|
|
50% { transform: scale(1.8); opacity: 0; }
|
|
}
|
|
|
|
.animate-pulse-slow {
|
|
animation: pulse-slow 2.5s ease-in-out infinite;
|
|
}
|
|
|
|
/* Eerie sigil glow pulse */
|
|
@keyframes sigil-glow {
|
|
0%, 100% { opacity: 0.12; filter: drop-shadow(0 0 4px hsl(var(--primary) / 0.3)); }
|
|
50% { opacity: 0.28; filter: drop-shadow(0 0 12px hsl(var(--primary) / 0.6)) drop-shadow(0 0 24px hsl(var(--primary) / 0.25)); }
|
|
}
|
|
|
|
.animate-sigil-glow {
|
|
animation: sigil-glow 4s ease-in-out infinite;
|
|
}
|
|
|
|
/* Eyeball blink animation - eyelid sweeps down then back up */
|
|
@keyframes eyelid-blink {
|
|
0% { transform: translateY(-100%); }
|
|
50% { transform: translateY(0%); }
|
|
100% { transform: translateY(-100%); }
|
|
}
|
|
|
|
.animate-eyelid-blink {
|
|
animation: eyelid-blink 0.5s cubic-bezier(0.4, 0, 0.6, 1) forwards;
|
|
}
|
|
|
|
/* Landing hero staggered fade-in */
|
|
@keyframes landing-hero-fade-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.landing-hero-fade {
|
|
opacity: 0;
|
|
animation: landing-hero-fade-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
}
|
|
|
|
/* ── NIP-62 Request to Vanish ───────────────────────────────────────────────── */
|
|
|
|
/* Animated caution stripes — red/dark diagonal bands that scroll */
|
|
.vanish-stripes {
|
|
background: repeating-linear-gradient(
|
|
-45deg,
|
|
hsl(0 72% 51% / 0.7),
|
|
hsl(0 72% 51% / 0.7) 10px,
|
|
hsl(0 72% 51% / 0.25) 10px,
|
|
hsl(0 72% 51% / 0.25) 20px
|
|
);
|
|
background-size: 28.28px 28.28px;
|
|
animation: vanish-stripe-scroll 1.5s linear infinite;
|
|
}
|
|
|
|
:is(.dark) .vanish-stripes {
|
|
background: repeating-linear-gradient(
|
|
-45deg,
|
|
hsl(0 72% 51% / 0.6),
|
|
hsl(0 72% 51% / 0.6) 10px,
|
|
hsl(0 72% 51% / 0.15) 10px,
|
|
hsl(0 72% 51% / 0.15) 20px
|
|
);
|
|
background-size: 28.28px 28.28px;
|
|
animation: vanish-stripe-scroll 1.5s linear infinite;
|
|
}
|
|
|
|
@keyframes vanish-stripe-scroll {
|
|
from { background-position: 0 0; }
|
|
to { background-position: 28.28px 0; }
|
|
}
|
|
|
|
/* Glitch text effect on the /// symbol */
|
|
.vanish-glitch-text {
|
|
position: relative;
|
|
animation: vanish-glitch 3s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes vanish-glitch {
|
|
0%, 90%, 100% { opacity: 1; transform: translate(0); }
|
|
92% { opacity: 0.8; transform: translate(-2px, 1px); }
|
|
94% { opacity: 0.6; transform: translate(2px, -1px); }
|
|
96% { opacity: 0.9; transform: translate(-1px, -1px); }
|
|
98% { opacity: 1; transform: translate(1px, 0); }
|
|
}
|
|
|
|
/* Ring pulse animation for the icon */
|
|
.vanish-ring-pulse {
|
|
animation: vanish-ring 3s ease-out infinite;
|
|
}
|
|
|
|
.vanish-ring-pulse-delayed {
|
|
animation: vanish-ring 3s ease-out 1.5s infinite;
|
|
}
|
|
|
|
@keyframes vanish-ring {
|
|
0% { transform: scale(1); opacity: 0.4; }
|
|
50% { transform: scale(1.15); opacity: 0; }
|
|
100% { transform: scale(1); opacity: 0; }
|
|
}
|
|
|
|
/* Slow blink for the status dot */
|
|
.vanish-blink {
|
|
animation: vanish-blink-kf 2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes vanish-blink-kf {
|
|
0%, 40%, 100% { opacity: 1; }
|
|
50%, 90% { opacity: 0.2; }
|
|
}
|
|
|
|
/* Reduced motion: disable all vanish animations */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.vanish-stripes {
|
|
animation: none;
|
|
}
|
|
.vanish-glitch-text {
|
|
animation: none;
|
|
}
|
|
.vanish-ring-pulse,
|
|
.vanish-ring-pulse-delayed {
|
|
animation: none;
|
|
opacity: 0;
|
|
}
|
|
.vanish-blink {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
|