slide animation
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 13s
CI/CD Pipeline / i18n Catalog Check (push) Successful in 31s
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 3m25s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 8m29s
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 13s
CI/CD Pipeline / i18n Catalog Check (push) Successful in 31s
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 3m25s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 8m29s
This commit is contained in:
+72
-28
@@ -50,62 +50,97 @@ textarea,
|
|||||||
transform: scale(0.90) translateY(-4px);
|
transform: scale(0.90) translateY(-4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* keep the page tappable mid-transition (rapid tab switching) */
|
||||||
|
::view-transition {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Theme texture overlays (scanlines, rays, grain) paint ABOVE all content; a
|
||||||
|
real element with its own transition group keeps them on top and static
|
||||||
|
mid-transition — a body::before overlay sinks into the root snapshot and
|
||||||
|
blinks off the content for the duration of every transition. */
|
||||||
|
.flxn-theme-overlay {
|
||||||
|
position: fixed;
|
||||||
|
pointer-events: none;
|
||||||
|
view-transition-name: theme-overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Root (wallpaper + tab bar) is identical across routes — swap it instantly
|
||||||
|
instead of crossfading; Safari's plus-lighter blend of the pair dims the
|
||||||
|
whole backdrop mid-fade. Same explicit-state treatment for the header and
|
||||||
|
theme overlay. */
|
||||||
::view-transition-old(root),
|
::view-transition-old(root),
|
||||||
::view-transition-new(root),
|
|
||||||
::view-transition-old(page),
|
|
||||||
::view-transition-new(page),
|
|
||||||
::view-transition-old(app-header),
|
::view-transition-old(app-header),
|
||||||
::view-transition-new(app-header) {
|
::view-transition-old(theme-overlay) {
|
||||||
|
animation: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
::view-transition-new(root),
|
||||||
|
::view-transition-new(app-header),
|
||||||
|
::view-transition-new(theme-overlay) {
|
||||||
|
animation: none;
|
||||||
|
opacity: 1;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
::view-transition-image-pair(root),
|
||||||
|
::view-transition-image-pair(app-header),
|
||||||
|
::view-transition-image-pair(theme-overlay),
|
||||||
|
::view-transition-image-pair(page) {
|
||||||
|
isolation: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-old(page),
|
||||||
|
::view-transition-new(page) {
|
||||||
animation-duration: 180ms;
|
animation-duration: 180ms;
|
||||||
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
|
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
|
||||||
|
mix-blend-mode: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* content pushes edge-to-edge over the static theme background; panes stay
|
||||||
|
transparent so the background never appears to move. The header is not in
|
||||||
|
these rules on purpose: it crossfades in place (its own group's default) —
|
||||||
|
sliding its chrome reads as a band appearing on continuous-bg themes */
|
||||||
html[data-nav-direction="forward"]::view-transition-old(page) {
|
html[data-nav-direction="forward"]::view-transition-old(page) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-under-out;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-left;
|
||||||
}
|
}
|
||||||
html[data-nav-direction="forward"]::view-transition-new(page) {
|
html[data-nav-direction="forward"]::view-transition-new(page) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-in;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-right;
|
||||||
}
|
}
|
||||||
html[data-nav-direction="back"]::view-transition-old(page) {
|
html[data-nav-direction="back"]::view-transition-old(page) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-out;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-right;
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
html[data-nav-direction="back"]::view-transition-new(page) {
|
html[data-nav-direction="back"]::view-transition-new(page) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-under-in;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* a header appearing or disappearing rides with its page instead of popping;
|
||||||
|
opacity overrides the pinned instant-swap defaults above */
|
||||||
html[data-nav-direction="forward"][data-header-vt="exit"]::view-transition-old(app-header) {
|
html[data-nav-direction="forward"][data-header-vt="exit"]::view-transition-old(app-header) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-header-out;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-left;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
html[data-nav-direction="back"][data-header-vt="exit"]::view-transition-old(app-header) {
|
html[data-nav-direction="back"][data-header-vt="exit"]::view-transition-old(app-header) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-out;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-out-right;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
html[data-nav-direction="forward"][data-header-vt="enter"]::view-transition-new(app-header) {
|
html[data-nav-direction="forward"][data-header-vt="enter"]::view-transition-new(app-header) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-over-in;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-right;
|
||||||
}
|
}
|
||||||
html[data-nav-direction="back"][data-header-vt="enter"]::view-transition-new(app-header) {
|
html[data-nav-direction="back"][data-header-vt="enter"]::view-transition-new(app-header) {
|
||||||
animation: 300ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-header-in;
|
animation: 250ms cubic-bezier(0.32, 0.72, 0, 1) both flxn-page-in-left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes flxn-page-over-in {
|
@keyframes flxn-page-out-left {
|
||||||
|
to { transform: translateX(-100%); }
|
||||||
|
}
|
||||||
|
@keyframes flxn-page-in-right {
|
||||||
from { transform: translateX(100%); }
|
from { transform: translateX(100%); }
|
||||||
}
|
}
|
||||||
@keyframes flxn-page-over-out {
|
@keyframes flxn-page-out-right {
|
||||||
to { transform: translateX(100%); }
|
to { transform: translateX(100%); }
|
||||||
}
|
}
|
||||||
@keyframes flxn-page-under-out {
|
@keyframes flxn-page-in-left {
|
||||||
to { transform: translateX(-25%); opacity: 0.8; }
|
from { transform: translateX(-100%); }
|
||||||
}
|
|
||||||
@keyframes flxn-page-under-in {
|
|
||||||
from { transform: translateX(-25%); opacity: 0.8; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes flxn-header-out {
|
|
||||||
45% { opacity: 0; }
|
|
||||||
to { transform: translateX(-25%); opacity: 0; }
|
|
||||||
}
|
|
||||||
@keyframes flxn-header-in {
|
|
||||||
from { transform: translateX(-25%); opacity: 0; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes flxn-vt-fade-out {
|
@keyframes flxn-vt-fade-out {
|
||||||
@@ -130,6 +165,15 @@ html[data-nav-direction="back"][data-header-vt="enter"]::view-transition-new(app
|
|||||||
animation: 120ms ease both flxn-vt-fade-in !important;
|
animation: 120ms ease both flxn-vt-fade-in !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::view-transition-old(root),
|
||||||
|
::view-transition-old(app-header),
|
||||||
|
::view-transition-old(theme-overlay),
|
||||||
|
::view-transition-new(root),
|
||||||
|
::view-transition-new(app-header),
|
||||||
|
::view-transition-new(theme-overlay) {
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.app,
|
.app,
|
||||||
[data-drawer-level] {
|
[data-drawer-level] {
|
||||||
transition: none;
|
transition: none;
|
||||||
|
|||||||
@@ -183,7 +183,19 @@ function RootComponent() {
|
|||||||
ensureSuperTokensFrontend();
|
ensureSuperTokensFrontend();
|
||||||
initTelemetry(router);
|
initTelemetry(router);
|
||||||
if (import.meta.env.PROD && 'serviceWorker' in navigator) {
|
if (import.meta.env.PROD && 'serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker.register('/sw.js').catch(() => track('sw_register_failed'));
|
// first install claims the page too; only reload on real updates
|
||||||
|
const hadController = !!navigator.serviceWorker.controller;
|
||||||
|
let reloading = false;
|
||||||
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||||
|
if (!hadController || reloading) return;
|
||||||
|
reloading = true;
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
navigator.serviceWorker.register('/sw.js').then((registration) => {
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (document.visibilityState === 'visible') registration.update().catch(() => {});
|
||||||
|
});
|
||||||
|
}).catch(() => track('sw_register_failed'));
|
||||||
}
|
}
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
@@ -243,6 +255,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="app">{children}</div>
|
<div className="app">{children}</div>
|
||||||
|
<div className="flxn-theme-overlay" aria-hidden="true" />
|
||||||
<Scripts />
|
<Scripts />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -48,11 +48,9 @@ function SwipeableTabs({
|
|||||||
}, [search?.tab, tabs, defaultTab]);
|
}, [search?.tab, tabs, defaultTab]);
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState(getActiveTabFromUrl);
|
const [activeTab, setActiveTab] = useState(getActiveTabFromUrl);
|
||||||
const [mountAll, setMountAll] = useState(false);
|
const [visitedTabs, setVisitedTabs] = useState<ReadonlySet<number>>(
|
||||||
useEffect(() => {
|
() => new Set([getActiveTabFromUrl()])
|
||||||
const timeoutId = setTimeout(() => startTransition(() => setMountAll(true)), 400);
|
);
|
||||||
return () => clearTimeout(timeoutId);
|
|
||||||
}, []);
|
|
||||||
const [stuck, setStuck] = useState(false);
|
const [stuck, setStuck] = useState(false);
|
||||||
const sentinelRef = useRef<HTMLDivElement>(null);
|
const sentinelRef = useRef<HTMLDivElement>(null);
|
||||||
const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null);
|
const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null);
|
||||||
@@ -65,6 +63,9 @@ function SwipeableTabs({
|
|||||||
if (index === activeTab || index < 0 || index >= tabs.length) return;
|
if (index === activeTab || index < 0 || index >= tabs.length) return;
|
||||||
|
|
||||||
setActiveTab(index);
|
setActiveTab(index);
|
||||||
|
startTransition(() => {
|
||||||
|
setVisitedTabs((prev) => (prev.has(index) ? prev : new Set(prev).add(index)));
|
||||||
|
});
|
||||||
embla?.scrollTo(index);
|
embla?.scrollTo(index);
|
||||||
onTabChange?.(index, tabs[index]);
|
onTabChange?.(index, tabs[index]);
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ function SwipeableTabs({
|
|||||||
{tabs.map((tab, index) => (
|
{tabs.map((tab, index) => (
|
||||||
<Carousel.Slide key={`${tab.label}-content-${index}`}>
|
<Carousel.Slide key={`${tab.label}-content-${index}`}>
|
||||||
<Box ref={setSlideRef(index)} style={{ height: "auto", width: "100%", maxWidth: "100vw", overflow: "hidden" }}>
|
<Box ref={setSlideRef(index)} style={{ height: "auto", width: "100%", maxWidth: "100vw", overflow: "hidden" }}>
|
||||||
{(mountAll || index === activeTab) ? tab.content : null}
|
{(visitedTabs.has(index) || index === activeTab) ? tab.content : null}
|
||||||
</Box>
|
</Box>
|
||||||
</Carousel.Slide>
|
</Carousel.Slide>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -52,11 +52,10 @@ const Layout: React.FC<PropsWithChildren> = ({ children }) => {
|
|||||||
maw='100dvw'
|
maw='100dvw'
|
||||||
style={{ overflow: 'hidden' }}
|
style={{ overflow: 'hidden' }}
|
||||||
>
|
>
|
||||||
{/* pane box must be opaque and route-invariant or slides drift */}
|
{/* pane box must be route-invariant or slides drift */}
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
viewTransitionName: 'page',
|
viewTransitionName: 'page',
|
||||||
backgroundColor: 'var(--mantine-color-body)',
|
|
||||||
marginTop: 'calc(-1 * var(--app-shell-header-offset, 0px))',
|
marginTop: 'calc(-1 * var(--app-shell-header-offset, 0px))',
|
||||||
paddingTop: 'var(--app-shell-header-offset, 0px)',
|
paddingTop: 'var(--app-shell-header-offset, 0px)',
|
||||||
height: 'calc(100% + var(--app-shell-header-offset, 0px))',
|
height: 'calc(100% + var(--app-shell-header-offset, 0px))',
|
||||||
|
|||||||
@@ -178,15 +178,14 @@
|
|||||||
/* 3. Fixed sky backdrop with static bubbles (below all content) */
|
/* 3. Fixed sky backdrop with static bubbles (below all content) */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
[data-theme="aero"] body::before {
|
[data-theme="aero"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="aero"][data-mantine-color-scheme="light"] body::before {
|
[data-theme="aero"][data-mantine-color-scheme="light"] .flxn-theme-overlay {
|
||||||
background-color: #e9f6fe;
|
background-color: #e9f6fe;
|
||||||
background-image:
|
background-image:
|
||||||
radial-gradient(circle 0.6rem at 13.5% 20%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0) 70%),
|
radial-gradient(circle 0.6rem at 13.5% 20%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0) 70%),
|
||||||
@@ -198,7 +197,7 @@
|
|||||||
linear-gradient(180deg, #a5daf6 0%, #c9e9fa 32%, #e9f6fe 60%, #ffffff 100%);
|
linear-gradient(180deg, #a5daf6 0%, #c9e9fa 32%, #e9f6fe 60%, #ffffff 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="aero"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="aero"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
background-color: #071e2d;
|
background-color: #071e2d;
|
||||||
background-image:
|
background-image:
|
||||||
radial-gradient(circle 4rem at 16% 24%, rgba(120, 205, 245, 0) 60%, rgba(120, 205, 245, 0.2) 67%, rgba(120, 205, 245, 0) 74%),
|
radial-gradient(circle 4rem at 16% 24%, rgba(120, 205, 245, 0) 60%, rgba(120, 205, 245, 0.2) 67%, rgba(120, 205, 245, 0) 74%),
|
||||||
|
|||||||
@@ -203,8 +203,7 @@
|
|||||||
|
|
||||||
/* ---------- 4. Backdrop — studio key light + clay grain ---------- */
|
/* ---------- 4. Backdrop — studio key light + clay grain ---------- */
|
||||||
|
|
||||||
[data-theme="clay"] body::before {
|
[data-theme="clay"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: -1; /* behind content — never tints text or surfaces */
|
z-index: -1; /* behind content — never tints text or surfaces */
|
||||||
@@ -212,7 +211,7 @@
|
|||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="clay"][data-mantine-color-scheme="light"] body::before {
|
[data-theme="clay"][data-mantine-color-scheme="light"] .flxn-theme-overlay {
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
120% 70% at 50% 0%,
|
120% 70% at 50% 0%,
|
||||||
rgba(255, 252, 244, 0.65),
|
rgba(255, 252, 244, 0.65),
|
||||||
@@ -221,7 +220,7 @@
|
|||||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="clay"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="clay"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
110% 65% at 50% 0%,
|
110% 65% at 50% 0%,
|
||||||
rgba(255, 208, 158, 0.09),
|
rgba(255, 208, 158, 0.09),
|
||||||
|
|||||||
@@ -363,8 +363,7 @@
|
|||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* 4. Sunburst fan — faint gold rays from top center */
|
/* 4. Sunburst fan — faint gold rays from top center */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
[data-theme="deco"] body::before {
|
[data-theme="deco"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
|
|||||||
@@ -409,8 +409,7 @@
|
|||||||
* 3. Full-page decoration: candlelit vignette (dark scheme only)
|
* 3. Full-page decoration: candlelit vignette (dark scheme only)
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
[data-theme="gothic"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="gothic"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
|
|||||||
@@ -153,8 +153,7 @@
|
|||||||
/* 3. Fixed backdrop (below all content) */
|
/* 3. Fixed backdrop (below all content) */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
[data-theme="ocean"] body::before {
|
[data-theme="ocean"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
@@ -163,7 +162,7 @@
|
|||||||
|
|
||||||
/* Abyssal descent: deep teal fading to ink navy, sparse static bubbles
|
/* Abyssal descent: deep teal fading to ink navy, sparse static bubbles
|
||||||
rising (bigger and brighter near the sea floor, fading toward the top). */
|
rising (bigger and brighter near the sea floor, fading toward the top). */
|
||||||
[data-theme="ocean"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="ocean"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
background-color: #062632;
|
background-color: #062632;
|
||||||
background-image:
|
background-image:
|
||||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='640' viewBox='0 0 260 640'%3E%3Cg fill='none' stroke='%239beee2'%3E%3Ccircle cx='36' cy='584' r='5' stroke-opacity='.13'/%3E%3Ccircle cx='44' cy='512' r='3' stroke-opacity='.1'/%3E%3Ccircle cx='210' cy='612' r='4' stroke-opacity='.12'/%3E%3Ccircle cx='202' cy='540' r='2.5' stroke-opacity='.09'/%3E%3Ccircle cx='128' cy='430' r='3.5' stroke-opacity='.1'/%3E%3Ccircle cx='120' cy='360' r='2' stroke-opacity='.08'/%3E%3Ccircle cx='232' cy='300' r='3' stroke-opacity='.09'/%3E%3Ccircle cx='60' cy='250' r='2.5' stroke-opacity='.08'/%3E%3Ccircle cx='150' cy='160' r='2' stroke-opacity='.07'/%3E%3Ccircle cx='90' cy='80' r='1.5' stroke-opacity='.06'/%3E%3C/g%3E%3Cg fill='%239beee2'%3E%3Ccircle cx='70' cy='470' r='1.2' fill-opacity='.1'/%3E%3Ccircle cx='180' cy='390' r='1' fill-opacity='.09'/%3E%3Ccircle cx='40' cy='330' r='1' fill-opacity='.08'/%3E%3Ccircle cx='222' cy='190' r='1' fill-opacity='.07'/%3E%3Ccircle cx='140' cy='40' r='1' fill-opacity='.05'/%3E%3C/g%3E%3C/svg%3E"),
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='640' viewBox='0 0 260 640'%3E%3Cg fill='none' stroke='%239beee2'%3E%3Ccircle cx='36' cy='584' r='5' stroke-opacity='.13'/%3E%3Ccircle cx='44' cy='512' r='3' stroke-opacity='.1'/%3E%3Ccircle cx='210' cy='612' r='4' stroke-opacity='.12'/%3E%3Ccircle cx='202' cy='540' r='2.5' stroke-opacity='.09'/%3E%3Ccircle cx='128' cy='430' r='3.5' stroke-opacity='.1'/%3E%3Ccircle cx='120' cy='360' r='2' stroke-opacity='.08'/%3E%3Ccircle cx='232' cy='300' r='3' stroke-opacity='.09'/%3E%3Ccircle cx='60' cy='250' r='2.5' stroke-opacity='.08'/%3E%3Ccircle cx='150' cy='160' r='2' stroke-opacity='.07'/%3E%3Ccircle cx='90' cy='80' r='1.5' stroke-opacity='.06'/%3E%3C/g%3E%3Cg fill='%239beee2'%3E%3Ccircle cx='70' cy='470' r='1.2' fill-opacity='.1'/%3E%3Ccircle cx='180' cy='390' r='1' fill-opacity='.09'/%3E%3Ccircle cx='40' cy='330' r='1' fill-opacity='.08'/%3E%3Ccircle cx='222' cy='190' r='1' fill-opacity='.07'/%3E%3Ccircle cx='140' cy='40' r='1' fill-opacity='.05'/%3E%3C/g%3E%3C/svg%3E"),
|
||||||
@@ -175,7 +174,7 @@
|
|||||||
|
|
||||||
/* Sunlit shallows: seafoam fading to a sandy floor, with a faint white
|
/* Sunlit shallows: seafoam fading to a sandy floor, with a faint white
|
||||||
caustic ripple tile — refracted light, kept very subtle. */
|
caustic ripple tile — refracted light, kept very subtle. */
|
||||||
[data-theme="ocean"][data-mantine-color-scheme="light"] body::before {
|
[data-theme="ocean"][data-mantine-color-scheme="light"] .flxn-theme-overlay {
|
||||||
background-color: #eaf6f6;
|
background-color: #eaf6f6;
|
||||||
background-image:
|
background-image:
|
||||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='220' viewBox='0 0 320 220'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.4'%3E%3Cpath d='M0 40 Q 40 10 80 42 T 160 44 T 240 38 T 320 42' stroke-opacity='.4'/%3E%3Cpath d='M0 110 Q 45 82 90 112 T 180 110 T 268 114 T 320 108' stroke-opacity='.3'/%3E%3Cpath d='M0 180 Q 50 152 100 182 T 200 178 T 300 184 T 320 180' stroke-opacity='.35'/%3E%3C/g%3E%3C/svg%3E"),
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='220' viewBox='0 0 320 220'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.4'%3E%3Cpath d='M0 40 Q 40 10 80 42 T 160 44 T 240 38 T 320 42' stroke-opacity='.4'/%3E%3Cpath d='M0 110 Q 45 82 90 112 T 180 110 T 268 114 T 320 108' stroke-opacity='.3'/%3E%3Cpath d='M0 180 Q 50 152 100 182 T 200 178 T 300 184 T 320 180' stroke-opacity='.35'/%3E%3C/g%3E%3C/svg%3E"),
|
||||||
|
|||||||
@@ -414,8 +414,7 @@
|
|||||||
* 3. Full-page decoration: worn parchment edges / torchlight
|
* 3. Full-page decoration: worn parchment edges / torchlight
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
[data-theme="quest"][data-mantine-color-scheme="light"] body::before {
|
[data-theme="quest"][data-mantine-color-scheme="light"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
@@ -426,8 +425,7 @@
|
|||||||
radial-gradient(55% 38% at 95% 98%, rgba(122, 91, 42, 0.07), transparent 70%);
|
radial-gradient(55% 38% at 95% 98%, rgba(122, 91, 42, 0.07), transparent 70%);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="quest"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="quest"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
|
|||||||
@@ -151,8 +151,7 @@
|
|||||||
/* 3. Paper grain / chalk dust — one fixed overlay, feTurbulence */
|
/* 3. Paper grain / chalk dust — one fixed overlay, feTurbulence */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
[data-theme="sketch"] body::before {
|
[data-theme="sketch"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
@@ -163,11 +162,19 @@
|
|||||||
opacity: 0.05;
|
opacity: 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="sketch"][data-mantine-color-scheme="dark"] body::before {
|
[data-theme="sketch"][data-mantine-color-scheme="dark"] .flxn-theme-overlay {
|
||||||
mix-blend-mode: screen;
|
mix-blend-mode: screen;
|
||||||
opacity: 0.07;
|
opacity: 0.07;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-theme="sketch"]::view-transition-new(theme-overlay) {
|
||||||
|
mix-blend-mode: multiply;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="sketch"][data-mantine-color-scheme="dark"]::view-transition-new(theme-overlay) {
|
||||||
|
mix-blend-mode: screen;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/* 4. Surfaces — every card its own doodle */
|
/* 4. Surfaces — every card its own doodle */
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
|||||||
@@ -575,8 +575,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 4. Decoration: fixed scanline overlay + faint RGB aperture mask */
|
/* 4. Decoration: fixed scanline overlay + faint RGB aperture mask */
|
||||||
[data-theme="terminal"] body::before {
|
[data-theme="terminal"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 9998;
|
z-index: 9998;
|
||||||
@@ -589,7 +588,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
[data-theme="terminal"] body::before {
|
[data-theme="terminal"] .flxn-theme-overlay {
|
||||||
animation: terminal-phosphor-drift 9s ease-in-out infinite;
|
animation: terminal-phosphor-drift 9s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
@keyframes terminal-phosphor-drift {
|
@keyframes terminal-phosphor-drift {
|
||||||
|
|||||||
@@ -150,8 +150,7 @@
|
|||||||
|
|
||||||
/* ---------- 3. Decoration: static perspective floor-grid hint ---------- */
|
/* ---------- 3. Decoration: static perspective floor-grid hint ---------- */
|
||||||
|
|
||||||
[data-theme="wireframe"] body::before {
|
[data-theme="wireframe"] .flxn-theme-overlay {
|
||||||
content: "";
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: -30vw;
|
left: -30vw;
|
||||||
right: -30vw;
|
right: -30vw;
|
||||||
|
|||||||
Reference in New Issue
Block a user