Files
KoalaSync/website/style.css
T
2026-07-11 11:21:47 +02:00

6577 lines
160 KiB
CSS

/* KoalaSync Design System - Privacy-Focused (No External Assets) */
@font-face {
font-family: 'Twemoji Country Flags';
unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
src: url('assets/TwemojiCountryFlags.woff2') format('woff2');
font-display: swap;
}
:root {
/* v3.0.0 "The Greens Update" nature palette */
--bg-base: oklch(0.20 0.025 140);
--surface: oklch(0.27 0.035 130);
--surface-deep: oklch(0.16 0.025 135);
--surface-alt: oklch(0.23 0.03 130);
--border-soft: rgba(255, 255, 255, 0.06);
--border-strong: oklch(0.32 0.03 125);
--text-primary: oklch(0.96 0.01 90);
--text-secondary: oklch(0.78 0.02 90);
--accent-green: oklch(0.68 0.13 150);
--accent-green-hover: oklch(0.75 0.13 150);
--accent-terracotta: oklch(0.62 0.14 45);
--danger: oklch(0.55 0.15 25);
--text-on-green: oklch(0.14 0.02 90);
/* Legacy aliases used throughout the stylesheet */
--bg: var(--bg-base);
--card: var(--surface);
--accent: var(--accent-green);
--accent-glow: oklch(0.68 0.13 150 / 0.3);
--text: var(--text-primary);
--text-muted: var(--text-secondary);
--success: var(--accent-green);
--glass: oklch(0.27 0.035 130 / 0.4);
--glass-border: var(--border-soft);
--section-tint: transparent;
--section-tint-strong: oklch(0.20 0.025 140 / 0.28);
--card-surface: oklch(0.27 0.035 130 / 0.45);
--card-border: rgba(255, 255, 255, 0.08);
color-scheme: dark;
}
.extension-mockup,
.illus-popup-card,
.illus-player-card {
--bg: oklch(0.20 0.025 140) !important;
--card: oklch(0.27 0.035 130) !important;
--accent: oklch(0.68 0.13 150) !important;
--accent-glow: oklch(0.68 0.13 150 / 0.3) !important;
--text: oklch(0.96 0.01 90) !important;
--text-muted: oklch(0.78 0.02 90) !important;
--success: oklch(0.68 0.13 150) !important;
--error: oklch(0.55 0.15 25) !important;
--glass: oklch(0.27 0.035 130 / 0.4) !important;
--glass-border: rgba(255, 255, 255, 0.05) !important;
--section-tint: rgba(255, 255, 255, 0.02) !important;
--section-tint-strong: oklch(0.20 0.025 140 / 0.4) !important;
--card-surface: oklch(0.27 0.035 130 / 0.45) !important;
--card-border: rgba(255, 255, 255, 0.08) !important;
}
.invite-banner {
background: var(--accent);
color: var(--text-on-green);
padding: 0.75rem 0;
text-align: center;
font-weight: 600;
font-size: 0.9rem;
position: relative;
z-index: 2000;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.btn-banner {
background: white;
color: var(--accent);
padding: 4px 12px;
border-radius: 6px;
text-decoration: none;
font-size: 0.8rem;
font-weight: 700;
margin-left: 12px;
cursor: pointer;
border: none;
transition: transform 0.2s;
}
.btn-banner:hover {
transform: scale(1.05);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 6px;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Twemoji Country Flags', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
background-color: var(--bg);
color: var(--text);
line-height: 1.6;
overflow-x: hidden;
position: relative;
}
/* --- Animated Bamboo Forest Background (v3 Greens Update) --- */
/* Registered so wind gusts can TRANSITION these instead of jumping */
@property --sway {
syntax: '<angle>';
initial-value: 1.2deg;
inherits: true;
}
@property --leaf-drift {
syntax: '<length>';
initial-value: 26px;
inherits: true;
}
.bg-nature {
--sway: 1.2deg;
--leaf-drift: 26px;
transition: --sway 1.6s ease-in-out, --leaf-drift 1.6s ease-in-out;
}
.bg-nature.gusting {
--sway: 3.4deg;
--leaf-drift: 68px;
}
.bg-nature {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
pointer-events: none;
background:
radial-gradient(circle at 18% 10%, oklch(0.26 0.05 145 / 0.35), transparent 34rem),
radial-gradient(circle at 78% 68%, oklch(0.24 0.04 140 / 0.3), transparent 38rem),
linear-gradient(180deg, oklch(0.20 0.025 140) 0%, oklch(0.17 0.03 142) 45%, oklch(0.19 0.03 140) 100%);
}
/* (a) Distant bamboo layer: blurred, scroll-parallaxed by app.js */
#bamboo-far {
position: absolute;
inset: 0;
will-change: transform;
}
#bamboo-far .bamboo-stalk {
position: absolute;
/* 200% covers the upward parallax drift (max 0.55vh on the near layer)
with margin while keeping the blurred layer smaller than the old
240% overscan. Spare coverage sits below, where the drift needs it. */
top: -40%;
height: 200%;
border-radius: 999px;
filter: blur(4.5px);
transition: filter 1.2s ease;
background:
repeating-linear-gradient(180deg,
transparent 0, transparent 108px,
oklch(0.40 0.06 145 / 0.22) 108px, oklch(0.40 0.06 145 / 0.22) 112px),
linear-gradient(180deg, oklch(0.34 0.05 145 / 0.4), oklch(0.24 0.04 140 / 0.16));
}
#bamboo-far .far-1 { left: 2%; width: 26px; }
#bamboo-far .far-2 { left: 7.5%; width: 18px; }
#bamboo-far .far-3 { right: 4%; width: 30px; }
#bamboo-far .far-4 { left: 13%; width: 20px; }
#bamboo-far .far-5 { right: 10.5%; width: 16px; }
/* Two whisper-quiet trunks soften the empty centre without touching the
content: wide apart, thin, and at the lowest opacity in the scene. */
#bamboo-far .far-6 { left: 39%; width: 12px; opacity: 0.55; }
#bamboo-far .far-7 { right: 42%; width: 14px; opacity: 0.6; }
/* Two barely-there trunks break up the empty middle without competing with
the content. They share the far layer's single parallax transform. */
#bamboo-far::before,
#bamboo-far::after {
content: '';
position: absolute;
top: -40%;
height: 200%;
border-radius: 999px;
filter: blur(6.5px);
opacity: 0.3;
background: linear-gradient(180deg, oklch(0.34 0.05 145 / 0.3), oklch(0.23 0.04 140 / 0.1));
}
#bamboo-far::before { left: 24%; width: 13px; }
#bamboo-far::after { right: 25%; width: 17px; }
/* Depth of field: the far layer blurs further as you descend (stepped by
JS on threshold crossings, never per frame) */
.bg-nature.depth-mid #bamboo-far .bamboo-stalk { filter: blur(5.5px); }
.bg-nature.depth-deep #bamboo-far .bamboo-stalk { filter: blur(6.5px); }
/* (a2) Mid bamboo layer: sits between far and near with its own parallax
rate (app.js) and half the near layer's sway, so the three layers drift
apart subtly instead of moving as one sheet. Landing page only — the
static pages keep the lighter two-layer scene. */
#bamboo-mid {
position: absolute;
inset: 0;
will-change: transform;
}
#bamboo-mid .bamboo-stalk {
position: absolute;
top: -40%;
height: 200%;
border-radius: 999px;
filter: blur(2px);
transition: filter 1.2s ease;
/* Segment rings + a soft left-of-centre sheen give the stalks culm
structure without any extra elements; the blur keeps both faint. */
background:
repeating-linear-gradient(180deg,
transparent 0, transparent 84px,
oklch(0.46 0.075 145 / 0.28) 84px, oklch(0.46 0.075 145 / 0.28) 87px),
linear-gradient(90deg, transparent 14%, oklch(0.58 0.07 145 / 0.14) 38%, transparent 68%),
linear-gradient(180deg, oklch(0.36 0.06 145 / 0.45), oklch(0.25 0.045 140 / 0.2));
transform-origin: bottom center;
animation: bambooSwayHalf 13s ease-in-out infinite;
}
#bamboo-mid .mid-1 { left: 17%; width: 15px; animation-duration: 12s; }
#bamboo-mid .mid-2 { left: 31%; width: 9px; animation-delay: -5s; opacity: 0.55; }
#bamboo-mid .mid-3 { right: 15.5%; width: 17px; animation-duration: 14.5s; animation-delay: -8s; }
#bamboo-mid .mid-4 { right: 30%; width: 8px; animation-duration: 11.5s; animation-delay: -2.5s; opacity: 0.5; }
/* A few leaves sprout from the mid stalks (pseudo-elements, so they ride
the stalk's sway for free). The slim centre stalks stay bare. */
#bamboo-mid .bamboo-stalk::before,
#bamboo-mid .bamboo-stalk::after {
content: '';
position: absolute;
width: 24px;
height: 11px;
border-radius: 0 100% 0 100%;
background: oklch(0.5 0.1 145 / 0.32);
}
#bamboo-mid .mid-1::before { top: 31%; left: 13px; transform: rotate(20deg); }
#bamboo-mid .mid-1::after { top: 55%; left: -26px; transform: rotate(-158deg); width: 20px; height: 9px; }
#bamboo-mid .mid-3::before { top: 26%; left: -27px; transform: rotate(-156deg); }
#bamboo-mid .mid-3::after { top: 49%; left: 15px; transform: rotate(24deg); width: 21px; height: 10px; }
#bamboo-mid .mid-2::before,
#bamboo-mid .mid-2::after,
#bamboo-mid .mid-4::before,
#bamboo-mid .mid-4::after {
display: none;
}
.bg-nature.depth-mid #bamboo-mid .bamboo-stalk { filter: blur(3px); }
.bg-nature.depth-deep #bamboo-mid .bamboo-stalk { filter: blur(4px); }
@keyframes bambooSwayHalf {
0%, 100% { transform: rotate(0); }
50% { transform: rotate(calc(var(--sway, 1.2deg) * 0.5)); }
}
/* (b) Near bamboo layer: sharp stalks with nodes and leaves, gentle sway */
#bamboo-near {
position: absolute;
inset: 0;
will-change: transform;
}
#bamboo-near .bamboo-stalk {
position: absolute;
top: -40%;
height: 200%;
border-radius: 999px;
/* Vertical sheen over the culm gradient: reads as light from the
canopy catching the rounded stalk instead of a flat strip. */
background:
linear-gradient(90deg, transparent 12%, oklch(0.64 0.08 145 / 0.22) 36%, transparent 64%),
linear-gradient(180deg, oklch(0.42 0.075 145 / 0.6), oklch(0.27 0.05 140 / 0.3));
transform-origin: bottom center;
animation: bambooSway 10s ease-in-out infinite;
}
#bamboo-near .near-1 { left: 4.5%; width: 15px; animation-duration: 9.2s; }
#bamboo-near .near-2 { right: 7%; width: 13px; animation-duration: 11s; animation-delay: -3.5s; }
#bamboo-near .near-3 { left: 10%; width: 10px; animation-duration: 12.5s; animation-delay: -6s; opacity: 0.75; }
#bamboo-near .bamboo-node {
position: absolute;
left: -1px;
right: -1px;
height: 3px;
border-radius: 2px;
background: oklch(0.52 0.085 145 / 0.6);
}
#bamboo-near .node-1 { top: 28%; }
#bamboo-near .node-2 { top: 48%; }
#bamboo-near .node-3 { top: 68%; }
#bamboo-near .bamboo-leaf {
position: absolute;
width: 26px;
height: 12px;
border-radius: 0 100% 0 100%;
background: oklch(0.55 0.11 145 / 0.4);
}
#bamboo-near .near-1 .leaf-1 { top: 27.5%; left: 12px; transform: rotate(18deg); }
#bamboo-near .near-1 .leaf-2 { top: 47.5%; left: -28px; transform: rotate(-160deg); width: 22px; height: 10px; }
#bamboo-near .near-2 .leaf-1 { top: 44%; left: -26px; transform: rotate(-155deg); }
#bamboo-near .near-2 .leaf-2 { top: 61%; left: 11px; transform: rotate(21deg); width: 20px; height: 9px; }
#bamboo-near .near-3 .leaf-1 { top: 33%; left: 8px; transform: rotate(24deg); width: 18px; height: 9px; }
@keyframes bambooSway {
0%, 100% { transform: rotate(0); }
50% { transform: rotate(var(--sway, 1.2deg)); }
}
/* (d) Falling leaves: outer element falls + rotates, inner leaf sways */
.fall-leaf {
position: absolute;
top: 0;
animation: leafFall 17s linear infinite;
opacity: 0;
}
.fall-leaf i {
display: block;
width: 10px;
height: 14px;
border-radius: 0 70% 0 70%;
background: oklch(0.68 0.13 150 / 0.55);
animation: leafSway 3.2s ease-in-out infinite;
}
.fall-leaf:nth-child(even) i {
background: oklch(0.62 0.14 45 / 0.55);
}
.fall-leaf-1 { left: 6%; animation-duration: 15s; animation-delay: -2s; }
.fall-leaf-2 { left: 16%; animation-duration: 19s; animation-delay: -9s; }
.fall-leaf-2 i { animation-duration: 2.7s; background: oklch(0.62 0.14 45 / 0.6); }
.fall-leaf-3 { left: 28%; animation-duration: 14s; animation-delay: -5s; }
.fall-leaf-3 i { background: oklch(0.68 0.13 150 / 0.5); }
.fall-leaf-4 { left: 41%; animation-duration: 21s; animation-delay: -13s; }
.fall-leaf-4 i { animation-duration: 4s; }
.fall-leaf-5 { left: 55%; animation-duration: 16s; animation-delay: -7s; }
.fall-leaf-5 i { background: oklch(0.68 0.13 150 / 0.6); }
.fall-leaf-6 { left: 68%; animation-duration: 20s; animation-delay: -16s; }
.fall-leaf-6 i { animation-duration: 3.6s; background: oklch(0.62 0.14 45 / 0.5); }
.fall-leaf-7 { left: 81%; animation-duration: 14.5s; animation-delay: -3s; }
.fall-leaf-7 i { animation-duration: 2.9s; }
.fall-leaf-8 { left: 92%; animation-duration: 18s; animation-delay: -11s; }
@keyframes leafFall {
0% { transform: translateY(-40px) rotate(0); opacity: 0; }
8% { opacity: 0.65; }
92% { opacity: 0.5; }
100% { transform: translateY(110vh) translateX(120px) rotate(280deg); opacity: 0; }
}
@keyframes leafSway {
0%, 100% { margin-left: 0; }
50% { margin-left: var(--leaf-drift, 26px); }
}
/* Scroll journey: JS drives the opacity of these two groups so the page
travels from sunlit canopy (top) into misty dusk (bottom). Static
defaults below keep the scene balanced without JS. */
.bg-depth-day,
.bg-depth-dusk {
position: absolute;
inset: 0;
}
.bg-depth-dusk {
opacity: 0.6;
}
/* Dusk tint: darkens and warms the whole scene as you descend */
.bg-dusk-tint {
position: absolute;
inset: 0;
opacity: 0;
background: linear-gradient(180deg,
oklch(0.10 0.03 145 / 0.15) 0%,
oklch(0.12 0.045 142 / 0.5) 65%,
oklch(0.16 0.07 55 / 0.35) 100%);
}
/* God rays: soft light shafts falling through the canopy */
.bg-godrays {
position: absolute;
top: -10%;
left: 0;
right: 0;
height: 75%;
}
.godray {
position: absolute;
top: 0;
height: 115%;
background: linear-gradient(180deg, oklch(0.85 0.06 130 / 0.10), transparent 78%);
filter: blur(10px);
transform: rotate(14deg);
transform-origin: top center;
animation: rayShimmer 9s ease-in-out infinite alternate;
}
.godray-1 { left: 16%; width: 120px; animation-duration: 8s; }
.godray-2 { left: 33%; width: 70px; animation-delay: -3s; background: linear-gradient(180deg, oklch(0.85 0.06 130 / 0.07), transparent 78%); }
.godray-3 { left: 56%; width: 140px; animation-duration: 13s; animation-delay: -6s; background: linear-gradient(180deg, oklch(0.85 0.05 110 / 0.08), transparent 75%); }
@keyframes rayShimmer {
0% { opacity: 0.45; }
100% { opacity: 1; }
}
/* (e) Canopy: dark vignette at the top plus hanging leaf arcs */
.bg-canopy {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 150px;
background:
radial-gradient(ellipse 70% 100% at 30% 0%, oklch(0.14 0.03 145 / 0.55), transparent 70%),
radial-gradient(ellipse 60% 90% at 80% 0%, oklch(0.14 0.03 145 / 0.45), transparent 70%);
}
.canopy-arc {
position: absolute;
border-radius: 0 0 100% 100%;
background: oklch(0.32 0.06 145 / 0.45);
}
.canopy-arc-1 { top: -3px; left: 12%; width: 52px; height: 16px; transform: rotate(-6deg); background: oklch(0.30 0.06 145 / 0.5); }
.canopy-arc-2 { top: -2px; left: 34%; width: 38px; height: 12px; transform: rotate(4deg); background: oklch(0.34 0.06 145 / 0.35); }
.canopy-arc-3 { top: -4px; left: 61%; width: 46px; height: 14px; transform: rotate(-3deg); }
.canopy-arc-4 { top: -2px; left: 84%; width: 30px; height: 10px; transform: rotate(7deg); background: oklch(0.33 0.06 145 / 0.4); }
/* (f) Undergrowth: grass blades in the lower corners. Each blade carries a
shorter companion blade (::before) so the corners read as small tufts. */
.bg-grass {
position: absolute;
bottom: -4px;
transform-origin: bottom;
}
.bg-grass::before {
content: '';
position: absolute;
bottom: 0;
width: 72%;
height: 55%;
border-radius: inherit;
background: inherit;
opacity: 0.7;
transform-origin: bottom;
}
.bg-grass-1::before { left: -5px; transform: rotate(-13deg); }
.bg-grass-2::before { left: 4px; transform: rotate(11deg); }
.bg-grass-3::before { right: -5px; transform: rotate(12deg); }
.bg-grass-4::before { right: 4px; transform: rotate(-9deg); }
.bg-grass-1 { left: 1.5%; width: 6px; height: 52px; border-radius: 100% 0 0 0; background: oklch(0.38 0.07 145 / 0.4); transform: rotate(-9deg); }
.bg-grass-2 { left: 3.2%; width: 5px; height: 38px; border-radius: 100% 0 0 0; background: oklch(0.35 0.07 145 / 0.3); transform: rotate(-12deg); }
.bg-grass-3 { right: 2%; width: 6px; height: 56px; border-radius: 0 100% 0 0; background: oklch(0.4 0.07 145 / 0.4); transform: rotate(8deg); }
.bg-grass-4 { right: 3.8%; width: 5px; height: 40px; border-radius: 0 100% 0 0; background: oklch(0.36 0.07 145 / 0.32); transform: rotate(11deg); }
/* (g) Ground mist: soft drifting ellipses at the bottom edge */
.bg-mist {
position: absolute;
bottom: -40px;
height: 130px;
filter: blur(19px);
will-change: transform;
}
.bg-mist-1 {
left: -6%;
width: 75%;
background: radial-gradient(ellipse, oklch(0.85 0.03 145 / 0.07), transparent 70%);
animation: mistDrift 22s ease-in-out infinite alternate;
}
.bg-mist-2 {
right: -6%;
width: 70%;
background: radial-gradient(ellipse, oklch(0.85 0.03 145 / 0.06), transparent 70%);
animation: mistDrift 27s ease-in-out infinite alternate-reverse;
}
@keyframes mistDrift {
0% { transform: translateX(-8%); }
100% { transform: translateX(8%); }
}
/* (h) Breathing horizon glow */
.bg-horizon {
position: absolute;
inset: 0;
background: radial-gradient(ellipse 60% 100% at 50% 100%, oklch(0.62 0.14 45 / 0.14), transparent 70%);
animation: horizonBreathe 10s ease-in-out infinite;
}
@keyframes horizonBreathe {
0%, 100% { opacity: 0.5; }
50% { opacity: 0.85; }
}
/* Theme switch to light: the horizon flares up once like a sunrise */
.bg-nature.sunrise .bg-horizon {
animation:
horizonBreathe 10s ease-in-out infinite,
sunriseFlash 1.6s ease-out;
}
@keyframes sunriseFlash {
0% { opacity: 0.5; }
30% { opacity: 1; }
100% { opacity: 0.5; }
}
/* (i) Fireflies: the wrapper holds the base position and is what the JS
pushes away from the cursor; the inner dot pulses (transform) and
wanders (translate) independently. */
.firefly-wrap {
position: absolute;
width: 4px;
height: 4px;
}
.firefly {
display: block;
width: 4px;
height: 4px;
border-radius: 50%;
background: oklch(0.68 0.13 150);
box-shadow: 0 0 8px oklch(0.68 0.13 150);
animation:
fireflyPulse 3.8s ease-in-out infinite,
fireflyWander 21s ease-in-out infinite alternate;
}
.fw-2 .firefly,
.fw-4 .firefly,
.fw-6 .firefly {
width: 3px;
height: 3px;
background: oklch(0.62 0.14 45);
box-shadow: 0 0 8px oklch(0.62 0.14 45);
}
.fw-1 { top: 32%; left: 12%; }
.fw-2 { top: 58%; left: 22%; }
.fw-3 { top: 44%; left: 46%; }
.fw-4 { top: 70%; left: 64%; }
.fw-5 { top: 26%; left: 78%; }
.fw-6 { top: 62%; left: 90%; }
.fw-1 .firefly { animation-delay: -0.4s, -4s; }
.fw-2 .firefly { animation-duration: 4.4s, 26s; animation-delay: -2.1s, -11s; }
.fw-3 .firefly { animation-duration: 3.4s, 18s; animation-delay: -1.2s, -7s; }
.fw-4 .firefly { animation-duration: 4.1s, 29s; animation-delay: -3s, -19s; }
.fw-5 .firefly { animation-duration: 3.6s, 23s; animation-delay: -1.8s, -14s; }
.fw-6 .firefly { animation-duration: 4.2s, 17s; animation-delay: -0.9s, -2s; }
/* One firefly greets you when a new section scrolls into view */
.firefly-wrap.firefly-hello {
animation: fireflyHello 1.2s ease-out;
}
@keyframes fireflyHello {
0%, 100% { transform: scale(1); filter: brightness(1); }
35% { transform: scale(2.4); filter: brightness(1.7); }
}
@keyframes fireflyPulse {
0%, 100% { opacity: 0.2; transform: scale(1); }
50% { opacity: 0.9; transform: scale(1.35); }
}
@keyframes fireflyWander {
0% { translate: 0 0; }
25% { translate: 38px -26px; }
50% { translate: -20px 16px; }
75% { translate: 26px 30px; }
100% { translate: -14px -18px; }
}
/* Day/night: fireflies belong to the dark theme. By daylight the same six
spots are visited by small butterflies instead — the wrapper (and with it
the cursor-shy push and the section greeting) is shared, only the inner
dot is redressed. Only animation-name is swapped so the per-firefly
duration/delay variety above keeps applying to the butterflies. */
html.theme-light .firefly {
position: relative;
width: 2px;
height: 9px;
border-radius: 1px;
background: oklch(0.35 0.05 140 / 0.8);
box-shadow: none;
opacity: 0.85;
animation-name: butterflyBob, fireflyWander;
}
html.theme-light .firefly::before,
html.theme-light .firefly::after {
content: '';
position: absolute;
top: -2px;
width: 7px;
height: 10px;
background: oklch(0.62 0.14 45 / 0.7);
animation: wingFlap 0.5s ease-in-out infinite alternate;
}
html.theme-light .firefly::before {
left: -6px;
border-radius: 90% 10% 60% 40%;
transform-origin: 100% 55%;
}
html.theme-light .firefly::after {
right: -6px;
border-radius: 10% 90% 40% 60%;
transform-origin: 0% 55%;
animation-name: wingFlapR;
}
/* Every other butterfly wears the sage of the canopy and flaps lazier */
html.theme-light .fw-2 .firefly::before,
html.theme-light .fw-2 .firefly::after,
html.theme-light .fw-4 .firefly::before,
html.theme-light .fw-4 .firefly::after,
html.theme-light .fw-6 .firefly::before,
html.theme-light .fw-6 .firefly::after {
background: oklch(0.52 0.12 150 / 0.55);
animation-duration: 0.62s;
}
@keyframes butterflyBob {
0%, 100% { transform: translateY(0) rotate(-4deg); }
50% { transform: translateY(-8px) rotate(5deg); }
}
@keyframes wingFlap {
from { transform: scaleX(1) rotate(-6deg); }
to { transform: scaleX(0.3) rotate(8deg); }
}
@keyframes wingFlapR {
from { transform: scaleX(1) rotate(6deg); }
to { transform: scaleX(0.3) rotate(-8deg); }
}
/* By day the dusk layer must not dim the butterflies with scroll depth
(the JS crossfade keeps writing inline opacity for the dark theme), and
the warm horizon glow steps back so it reads as haze, not dusk. */
html.theme-light .bg-depth-dusk {
opacity: 1 !important;
}
html.theme-light .bg-horizon {
background: radial-gradient(ellipse 60% 100% at 50% 100%, oklch(0.8 0.08 60 / 0.1), transparent 70%);
}
/* (j) Wandering light sweep */
.bg-light-sweep {
position: absolute;
top: -30%;
left: -30%;
width: 160%;
height: 160%;
background: linear-gradient(115deg, transparent 42%, oklch(0.68 0.13 150 / 0.05) 50%, transparent 58%);
animation: lightSweep 26s ease-in-out infinite alternate;
will-change: transform;
}
@keyframes lightSweep {
0% { transform: translate(-20%, -20%) rotate(8deg); }
100% { transform: translate(20%, 20%) rotate(8deg); }
}
/* (j2) Corner vignette: pulls the eye toward the content and grounds the
scene — the forest darkens gently toward the edges like real depth. */
.bg-nature::after {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(ellipse 120% 90% at 50% 38%, transparent 55%, oklch(0.10 0.025 142 / 0.4) 100%);
}
html.theme-light .bg-nature::after {
background: radial-gradient(ellipse 120% 90% at 50% 38%, transparent 62%, oklch(0.78 0.03 120 / 0.3) 100%);
}
/* (k) Film grain (SVG feTurbulence, no external assets) */
.bg-grain {
position: absolute;
inset: 0;
opacity: 0.05;
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='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 160px 160px;
}
@media (max-width: 768px) {
/* Half the leaves, no god rays / light sweep / extra stalks: the scene
stays recognisable while the animation count roughly halves. */
.fall-leaf-5,
.fall-leaf-6,
.fall-leaf-7,
.fall-leaf-8,
.bg-godrays,
.bg-light-sweep,
#bamboo-mid,
#bamboo-far .far-4,
#bamboo-far .far-5,
#bamboo-far .far-6,
#bamboo-far .far-7,
#bamboo-near .near-3 {
display: none;
}
}
/* --- UI/UX cohesion pass -------------------------------------------------
Shared rhythm and interaction rules for the landing page. Component-specific
responsive refinements are repeated at the end of the cascade. */
html {
scroll-padding-top: 96px;
}
body {
text-rendering: optimizeLegibility;
}
.footer-disclaimer {
color: oklch(0.72 0.015 90);
}
html.theme-light .footer-disclaimer {
color: var(--text-muted);
}
.logo-area {
text-decoration: none;
border-radius: 12px;
}
.logo-area:focus-visible,
.nav-links a:focus-visible,
.theme-toggle:focus-visible,
.lang-dropdown:focus-visible,
.hamburger:focus-visible,
.btn:focus-visible,
.faq-item summary:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 4px;
}
.nav-links a {
position: relative;
padding: 0.55rem 0;
}
.nav-links a::after {
content: "";
position: absolute;
right: 0;
bottom: 0.25rem;
left: 0;
height: 2px;
border-radius: 999px;
background: var(--accent);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.25s ease;
}
.nav-links a:hover::after,
.nav-links a:focus-visible::after {
transform: scaleX(1);
transform-origin: left;
}
.hero-text {
max-width: 42rem;
}
.hero-text h1 {
text-wrap: balance;
}
.hero-subtitle,
.section-subtitle,
.use-cases-subtitle {
text-wrap: pretty;
}
.cta-group {
align-items: stretch;
}
.cta-group .btn {
min-height: 48px;
box-sizing: border-box;
}
.cta-trust {
max-width: 44rem;
line-height: 1.55;
}
section[id] {
scroll-margin-top: 96px;
}
.section-title,
#how-it-works h2,
#self-hosting h2,
#faq h2 {
text-wrap: balance;
letter-spacing: -0.035em;
}
.use-case-card,
.feature-card,
.faq-item,
.comparison-table-wrapper {
box-shadow: 0 18px 46px rgba(0, 0, 0, 0.12);
}
html.theme-light :is(.use-case-card, .feature-card, .faq-item, .comparison-table-wrapper) {
box-shadow: 0 18px 46px oklch(0.22 0.035 140 / 0.09);
}
.use-case-card,
.feature-card {
height: 100%;
}
.use-case-card p,
.feature-card p,
.faq-item p {
line-height: 1.7;
}
.faq-item summary {
min-height: 52px;
display: flex;
align-items: center;
}
.comparison-table tbody tr {
transition: background-color 0.2s ease;
}
@media (max-width: 768px) {
html {
scroll-padding-top: 76px;
}
.container {
padding-inline: 1.15rem;
}
section {
padding-block: 4.25rem;
}
.hero-text {
max-width: none;
}
.hero-text h1,
.section-title,
#how-it-works h2,
#self-hosting h2,
#faq h2 {
font-size: clamp(2rem, 9vw, 2.65rem) !important;
}
.cta-group {
display: grid;
grid-template-columns: 1fr 1fr;
width: 100%;
}
.cta-group .btn {
width: 100%;
justify-content: center;
}
.cta-group .btn-primary,
.cta-group .btn-firefox {
grid-column: span 1;
}
.hero-github-cta,
.btn-demo-mobile {
grid-column: span 1;
}
.use-case-card,
.feature-card,
.faq-item,
.comparison-table-wrapper {
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.1);
}
}
@media (max-width: 430px) {
.cta-group {
grid-template-columns: 1fr;
}
.cta-group .btn-primary,
.cta-group .btn-firefox,
.hero-github-cta,
.btn-demo-mobile {
grid-column: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.nav-links a::after,
.use-case-card,
.feature-card,
.faq-item,
.btn {
transition-duration: 0.01ms !important;
}
}
/* (l) Click confetti: a small handful of eucalyptus leaves bursts from
wherever the visitor presses (spawned by app.js). Built like the falling
leaves above — the outer span owns the flight path (fast burst that
brakes at its peak, then sinks), the inner leaf rocks around its stem
the whole way down. Deliberately subtle: few, tiny, short-lived. */
.click-leaf {
position: fixed;
z-index: 3000;
margin: -6px 0 0 -4px;
pointer-events: none;
opacity: 0;
animation: leafBurst var(--leaf-dur, 1.1s) forwards;
will-change: transform, opacity;
}
.click-leaf i {
display: block;
width: 8px;
height: 12px;
border-radius: 0 70% 0 70%;
background: linear-gradient(135deg, oklch(0.62 0.12 150 / 0.95), oklch(0.45 0.09 145 / 0.85));
transform: rotate(var(--leaf-rot, 0deg));
animation: leafRock var(--flutter-dur, 0.6s) ease-in-out infinite alternate;
}
.click-leaf-sage i {
background: linear-gradient(135deg, oklch(0.72 0.09 140 / 0.9), oklch(0.55 0.08 145 / 0.8));
}
.click-leaf-amber i {
background: linear-gradient(135deg, oklch(0.68 0.14 55 / 0.95), oklch(0.55 0.13 40 / 0.85));
}
/* Two-phase flight: --leaf-x/--leaf-y is the burst PEAK; from there each
leaf loses momentum and sinks past it while fading. Per-segment timing
functions give the fast pop and the gentle fall. */
@keyframes leafBurst {
0% {
opacity: 0;
transform: translate(0, 0) scale(var(--leaf-scale, 1));
animation-timing-function: cubic-bezier(0.16, 0.84, 0.44, 1);
}
10% { opacity: 1; }
45% {
opacity: 1;
transform: translate(var(--leaf-x, 0), var(--leaf-y, -20px)) scale(var(--leaf-scale, 1));
animation-timing-function: cubic-bezier(0.55, 0.06, 0.68, 0.19);
}
100% {
opacity: 0;
transform: translate(calc(var(--leaf-x, 0) * 1.4), calc(var(--leaf-y, -20px) + 44px)) scale(calc(var(--leaf-scale, 1) * 0.92));
}
}
@keyframes leafRock {
from { transform: rotate(calc(var(--leaf-rot, 0deg) - 24deg)); }
to { transform: rotate(calc(var(--leaf-rot, 0deg) + 24deg)); }
}
@media (prefers-reduced-motion: reduce) {
.click-leaf { display: none; }
.bg-nature *,
.bg-nature *::before,
.bg-nature *::after {
animation: none !important;
}
.fall-leaf { opacity: 0; }
}
/* --- Layout --- */
.container {
max-width: 1100px;
margin: 0 auto;
padding: 0 2rem;
}
section {
padding: 6rem 0;
}
#how-it-works {
padding: 4.5rem 0;
}
/* Content-visibility for offscreen sections to improve INP */
.use-cases-section,
#self-hosting,
.comparison-section {
content-visibility: auto;
contain-intrinsic-size: auto 1400px;
}
/* --- Navigation --- */
nav {
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
background: var(--glass);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--glass-border);
padding: 1rem 0;
transition: padding 0.3s ease, background 0.3s ease;
}
nav.nav-scrolled {
padding: 0.75rem 0;
background: oklch(0.20 0.025 140 / 0.9);
}
html.theme-light nav.nav-scrolled {
background: oklch(0.95 0.01 100 / 0.92);
}
.nav-content {
display: flex;
align-items: center;
}
.logo-area {
display: flex;
align-items: center;
gap: 0.75rem;
font-weight: 800;
font-size: 1.5rem;
letter-spacing: -0.5px;
}
/* Logo can be a plain <a>; without this it falls back to the UA link blue,
which clashed silently with the old indigo theme and visibly with green. */
a.logo-area {
color: var(--text);
}
.logo-area picture {
display: contents;
}
.logo-area img {
height: 64px;
width: 64px;
object-fit: contain;
border-radius: 8px;
margin: -4px 0;
}
.nav-ext-status {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
background: oklch(0.68 0.13 150 / 0.15);
border: 1px solid oklch(0.68 0.13 150 / 0.3);
color: oklch(0.68 0.13 150);
border-radius: 12px;
font-size: 0.55rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.1);
animation: fade-in 0.4s ease-out;
margin-left: 0.2rem;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(-5px); }
to { opacity: 1; transform: translateY(0); }
}
.nav-links {
display: flex;
gap: 2rem;
margin-left: auto;
}
.nav-links a {
color: var(--text-muted);
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
.nav-links a:hover {
color: var(--accent);
}
.nav-right {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: 2rem;
flex-shrink: 0;
}
/* --- Theme Toggle (sun/moon) --- */
.theme-toggle {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
padding: 0;
background: transparent;
border: none;
border-radius: 10px;
color: var(--text-muted);
cursor: pointer;
flex-shrink: 0;
transition: color 0.3s, transform 0.3s;
overflow: hidden;
}
.theme-toggle:hover {
color: var(--accent);
transform: scale(1.15);
}
.theme-toggle:active {
transform: scale(0.9);
}
.theme-toggle svg {
position: absolute;
width: 18px;
height: 18px;
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease;
}
/* Default (Dark mode): Sun visible, Moon hidden & rotated */
.theme-toggle .theme-icon-sun {
opacity: 1;
transform: scale(1) rotate(0deg);
}
.theme-toggle .theme-icon-moon {
opacity: 0;
transform: scale(0) rotate(-90deg);
}
/* Light mode: Moon visible, Sun hidden & rotated */
html.theme-light .theme-toggle .theme-icon-sun {
opacity: 0;
transform: scale(0) rotate(90deg);
}
html.theme-light .theme-toggle .theme-icon-moon {
opacity: 1;
transform: scale(1) rotate(0deg);
}
/* --- Light Theme --- */
html.theme-light {
--accent-green: oklch(0.52 0.12 150);
--accent-green-hover: oklch(0.58 0.12 150);
--text-on-green: #ffffff;
--bg: oklch(0.95 0.01 100);
--card: #ffffff;
--accent: var(--accent-green);
--accent-glow: oklch(0.52 0.12 150 / 0.25);
--text: oklch(0.20 0.025 140);
--text-muted: oklch(0.45 0.02 110);
--glass: rgba(255, 255, 255, 0.7);
--glass-border: oklch(0.20 0.025 140 / 0.08);
--section-tint: transparent;
--section-tint-strong: oklch(0.88 0.015 90 / 0.5);
--card-surface: rgba(255, 255, 255, 0.75);
--card-border: oklch(0.20 0.025 140 / 0.08);
color-scheme: light;
}
html.theme-light .bg-nature {
background:
radial-gradient(circle at 16% 10%, oklch(0.85 0.06 150 / 0.3), transparent 34rem),
radial-gradient(circle at 78% 68%, oklch(0.85 0.06 60 / 0.2), transparent 38rem),
linear-gradient(180deg, oklch(0.96 0.01 90) 0%, oklch(0.93 0.025 140) 46%, oklch(0.96 0.01 90) 100%);
}
html.theme-light .bg-canopy,
html.theme-light .canopy-arc,
html.theme-light .bg-grass {
opacity: 0.45;
}
/* By day the stalks get their own fresh-green recipes — the dark-theme
gradients faded to 45% read as grey smears on the light backdrop and
stopped looking like bamboo at all. */
html.theme-light #bamboo-far .bamboo-stalk {
opacity: 0.55;
background:
repeating-linear-gradient(180deg,
transparent 0, transparent 108px,
oklch(0.55 0.09 145 / 0.4) 108px, oklch(0.55 0.09 145 / 0.4) 112px),
linear-gradient(180deg, oklch(0.68 0.11 145 / 0.6), oklch(0.62 0.09 140 / 0.35));
}
html.theme-light #bamboo-far::before,
html.theme-light #bamboo-far::after {
background: linear-gradient(180deg, oklch(0.7 0.1 145 / 0.5), oklch(0.64 0.08 140 / 0.25));
}
html.theme-light #bamboo-mid .bamboo-stalk {
opacity: 0.65;
background:
repeating-linear-gradient(180deg,
transparent 0, transparent 84px,
oklch(0.5 0.1 145 / 0.45) 84px, oklch(0.5 0.1 145 / 0.45) 87px),
linear-gradient(90deg, transparent 14%, oklch(0.85 0.08 130 / 0.35) 38%, transparent 68%),
linear-gradient(180deg, oklch(0.63 0.115 145 / 0.65), oklch(0.57 0.09 140 / 0.4));
}
html.theme-light #bamboo-mid .bamboo-stalk::before,
html.theme-light #bamboo-mid .bamboo-stalk::after {
background: oklch(0.55 0.13 145 / 0.5);
}
html.theme-light #bamboo-near .bamboo-stalk {
opacity: 0.75;
background:
linear-gradient(90deg, transparent 12%, oklch(0.88 0.07 130 / 0.4) 36%, transparent 64%),
linear-gradient(180deg, oklch(0.59 0.12 145 / 0.75), oklch(0.52 0.1 140 / 0.5));
}
html.theme-light #bamboo-near .bamboo-node {
background: oklch(0.45 0.1 145 / 0.65);
}
html.theme-light #bamboo-near .bamboo-leaf {
background: oklch(0.55 0.13 145 / 0.6);
}
/* The centre trunks stay whisper-quiet by daylight too */
html.theme-light #bamboo-far .far-6,
html.theme-light #bamboo-far .far-7 {
opacity: 0.26;
}
html.theme-light .bg-mist {
display: none;
}
html.theme-light .bg-dusk-tint {
display: none;
}
html.theme-light .godray {
filter: blur(12px);
opacity: 0.5;
}
html.theme-light .bg-grain {
opacity: 0.035;
}
html.theme-light .feature-card,
html.theme-light .faq-item {
background: var(--card-surface);
border-color: var(--card-border);
box-shadow: 0 8px 24px oklch(0.20 0.025 140 / 0.06);
}
html.theme-light .feature-card::before {
background: linear-gradient(to bottom right, oklch(0.20 0.025 140 / 0.08), transparent);
}
html.theme-light .use-case-card {
background: var(--card-surface);
}
html.theme-light .use-case-card h3 {
color: var(--text);
}
html.theme-light .use-case-card:hover {
box-shadow: 0 12px 30px oklch(0.20 0.025 140 / 0.12);
border-color: oklch(0.20 0.025 140 / 0.15);
}
html.theme-light .faq-item[open] {
background: #ffffff;
}
html.theme-light .faq-item p {
border-top-color: oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .btn-secondary {
background: #ffffff;
border-color: oklch(0.20 0.025 140 / 0.12);
}
html.theme-light .btn-secondary:hover {
background: oklch(0.88 0.015 90);
}
html.theme-light .btn-firefox {
background: oklch(0.62 0.14 45);
color: #ffffff;
box-shadow: 0 10px 18px oklch(0.62 0.14 45 / 0.24);
}
html.theme-light .btn-firefox:hover {
background: oklch(0.55 0.13 45);
box-shadow: 0 18px 26px oklch(0.62 0.14 45 / 0.28);
}
html.theme-light .btn-firefox img {
filter: brightness(0) saturate(100%) invert(13%) sepia(38%) saturate(1084%) hue-rotate(177deg) brightness(89%) contrast(96%);
}
html.theme-light .btn-firefox-secondary img {
filter: brightness(0) saturate(100%) invert(13%) sepia(38%) saturate(1084%) hue-rotate(177deg) brightness(89%) contrast(96%);
}
html.theme-light .comparison-section {
background: transparent;
}
html.theme-light .comparison-table-wrapper {
background: rgba(255, 255, 255, 0.75);
box-shadow: 0 10px 30px oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .comparison-table th {
background: oklch(0.20 0.025 140 / 0.06);
color: var(--text);
}
html.theme-light .comparison-table th,
html.theme-light .comparison-table td {
border-bottom-color: oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .comparison-table tbody tr:hover {
background: oklch(0.20 0.025 140 / 0.03);
}
html.theme-light .feat-name strong {
color: var(--text);
}
html.theme-light .table-footnotes {
background: oklch(0.20 0.025 140 / 0.04);
border-top-color: oklch(0.20 0.025 140 / 0.06);
}
@media (max-width: 900px) {
html.theme-light .comparison-table tbody tr {
background: rgba(255, 255, 255, 0.85);
box-shadow: 0 6px 18px oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .comparison-table td.feat-name {
background: oklch(0.20 0.025 140 / 0.05);
}
html.theme-light .comparison-table td {
border-bottom-color: oklch(0.20 0.025 140 / 0.08);
}
}
html.theme-light .compat-logo img,
html.theme-light .compat-logo {
filter: none;
}
/* --- Hero Section --- */
.hero {
min-height: 100vh;
display: flex;
align-items: flex-start;
padding-top: clamp(8rem, 12vh, 10rem);
padding-bottom: clamp(2rem, 5vh, 4rem);
}
.hero-grid {
display: grid;
/* Single column until the interactive demo appears (1024px). Below that the
headline gets the full width and the install CTAs stay prominent while the
demo stacks underneath, matching the demo's own 1024px breakpoint. */
grid-template-columns: minmax(0, 1fr);
align-content: center;
/* Keep the whole hero vertically centered. Do not use grid alignment to fix
the demo top edge; that moves the headline and breaks the hero balance. */
align-items: center;
gap: 3rem;
text-align: left;
width: 100%;
min-height: calc(100svh - 12.5rem);
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
.hero-grid {
grid-template-columns: 1.35fr 1fr;
gap: 3.5rem;
}
.cta-group {
gap: 0.75rem;
}
.cta-group .btn {
padding: 0.8rem 1.35rem;
}
}
.hero-text h1 {
font-size: clamp(2.9rem, 4.1vw, 4rem);
font-weight: 800;
line-height: 1.12;
margin-bottom: 1.4rem;
padding-bottom: 0.1em;
color: var(--text);
letter-spacing: -0.02em;
}
.hero-text h1 .hero-highlight {
background: linear-gradient(90deg, var(--accent-green), var(--accent-terracotta), var(--accent-green));
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
white-space: nowrap;
animation: hero-gradient-pan 10s linear infinite;
/* background-clip: text only paints inside the layout box; with the
negative h1 letter-spacing the last glyph overhangs it and gets cut
off. Invisible padding extends the paint area without moving text. */
padding-right: 0.08em;
margin-right: -0.08em;
}
@keyframes hero-gradient-pan {
from { background-position: 0% 50%; }
to { background-position: 300% 50%; }
}
@media (prefers-reduced-motion: reduce) {
.hero-text h1 .hero-highlight {
animation: none;
}
}
.hero-text p, .hero-subtitle {
font-size: 1.25rem;
color: var(--text-muted);
margin-bottom: 1.9rem;
max-width: 600px;
font-weight: 400;
line-height: 1.6;
}
.hero-mascot-container {
position: relative;
display: block;
margin-bottom: -0.5rem;
margin-left: 2.2rem;
}
.hero-lookdown-mascot {
display: block;
width: 90px;
height: auto;
}
/* Changelog link as the koala's comic speech bubble. Absolutely positioned
so it never moves the koala out of its spot above the install buttons. */
.koala-speech-bubble {
position: absolute;
left: 108px;
top: 0.2rem;
width: max-content;
max-width: min(240px, calc(100% - 120px));
display: block;
text-decoration: none;
text-align: left;
background: oklch(0.27 0.035 130 / 0.95);
border: 1px solid oklch(0.68 0.13 150 / 0.45);
border-radius: 14px;
border-bottom-left-radius: 4px;
padding: 0.6rem 0.9rem;
line-height: 1.35;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
animation: bubble-float 4s ease-in-out infinite;
transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
/* Tail: outline triangle + fill triangle so it reads as part of the bubble */
.koala-speech-bubble::before,
.koala-speech-bubble::after {
content: '';
position: absolute;
width: 0;
height: 0;
}
.koala-speech-bubble::before {
left: -11px;
bottom: 10px;
border-top: 8px solid transparent;
border-bottom: 4px solid transparent;
border-right: 11px solid oklch(0.68 0.13 150 / 0.45);
}
.koala-speech-bubble::after {
left: -9px;
bottom: 11px;
border-top: 7px solid transparent;
border-bottom: 3px solid transparent;
border-right: 10px solid oklch(0.27 0.035 130 / 0.95);
}
.koala-speech-bubble:hover {
border-color: oklch(0.68 0.13 150 / 0.85);
box-shadow: 0 8px 28px oklch(0.68 0.13 150 / 0.35);
}
.koala-speech-bubble .version-text-en,
.koala-speech-bubble .version-text-de {
display: block;
}
.koala-speech-bubble .bubble-title {
display: block;
font-size: 0.85rem;
font-weight: 800;
color: var(--text);
letter-spacing: 0;
white-space: nowrap;
}
.koala-speech-bubble .bubble-sub {
display: block;
font-size: 0.72rem;
font-weight: 600;
color: var(--accent);
margin-top: 2px;
}
html.theme-light .koala-speech-bubble {
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 8px 24px oklch(0.20 0.025 140 / 0.12);
}
html.theme-light .koala-speech-bubble::after {
border-right-color: rgba(255, 255, 255, 0.96);
}
@keyframes bubble-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
.koala-speech-bubble {
animation: none;
}
}
@media (max-width: 768px) {
/* The koala keeps standing on the active install CTA; app.js updates the
offset from the real button geometry when the row wraps. */
.hero-mascot-container {
--hero-mascot-offset: 0px;
margin-left: 0;
display: flex;
justify-content: center;
}
.hero-lookdown-mascot {
transform: translateX(var(--hero-mascot-offset));
}
.koala-speech-bubble {
left: calc(50% + var(--hero-mascot-offset) + 50px);
right: 0.75rem;
top: 0.3rem;
max-width: 240px;
padding: 0.5rem 0.75rem;
}
.koala-speech-bubble .bubble-title {
font-size: 0.8rem;
}
.koala-speech-bubble .bubble-sub {
font-size: 0.68rem;
}
/* The relative release time is too much text for the small mobile bubble */
.koala-speech-bubble .bubble-ago {
display: none;
}
}
.cta-group {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
/* Quiet trust line under the install buttons; answers "is it free, is it
legit, do I need an account" right at the moment of the click decision. */
.hero-text .cta-trust {
margin-top: 0.85rem;
margin-bottom: 0;
font-size: 0.8rem;
font-weight: 500;
color: var(--text-muted);
opacity: 0.75;
letter-spacing: 0.01em;
max-width: none;
}
.btn {
padding: 0.85rem 1.75rem;
border-radius: 12px;
font-weight: 600;
text-decoration: none;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-size: 0.95rem;
}
.btn-primary {
background: linear-gradient(135deg, oklch(0.48 0.13 150), oklch(0.39 0.10 145));
color: #fff;
border: 1px solid oklch(0.72 0.11 95 / 0.24);
box-shadow: 0 12px 24px -8px oklch(0.38 0.11 148 / 0.65), 0 0 0 1px oklch(0.80 0.08 90 / 0.06) inset;
}
.btn-primary:hover {
background: linear-gradient(135deg, oklch(0.54 0.14 150), oklch(0.44 0.11 145));
transform: translateY(-2px);
box-shadow: 0 18px 32px -8px oklch(0.38 0.11 148 / 0.75), 0 0 18px oklch(0.68 0.13 150 / 0.18);
}
.btn-firefox {
background: oklch(0.62 0.14 45);
color: white;
box-shadow: 0 10px 15px -3px oklch(0.62 0.14 45 / 0.3);
}
.btn-firefox:hover {
background: oklch(0.68 0.14 45);
transform: translateY(-2px);
box-shadow: 0 20px 25px -5px oklch(0.62 0.14 45 / 0.4);
}
.btn-secondary {
background: var(--card);
color: var(--text);
border: 1px solid var(--glass-border);
}
.btn-secondary:hover {
background: oklch(0.30 0.03 125);
transform: translateY(-2px);
}
.btn-demo-mobile {
display: none;
border: 1px solid oklch(0.68 0.13 150 / 0.34);
cursor: pointer;
font: inherit;
}
.btn-demo-mobile svg {
flex-shrink: 0;
}
/* Install buttons: compact by default (just the browser name) so all three
CTAs fit one line; the detected browser expands to the full call to action.
The GitHub button stays compact always. */
.btn-label-full { display: none; }
.btn-install:not(.is-detected),
.btn-compact {
padding: 0.62rem 1.05rem;
font-size: 0.9rem;
gap: 0.4rem;
}
.btn-install.is-detected .btn-label-short { display: none; }
.btn-install.is-detected .btn-label-full { display: inline; }
.version-badge {
display: inline-block;
background: oklch(0.68 0.13 150 / 0.1);
color: var(--accent);
padding: 0.4rem 1rem;
border-radius: 99px;
font-size: 0.8rem;
font-weight: 700;
margin-bottom: 1.5rem;
border: 1px solid oklch(0.68 0.13 150 / 0.3);
letter-spacing: 0.05em;
text-transform: uppercase;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
}
.version-badge-below {
margin-bottom: 0;
margin-top: 1.5rem;
}
.version-badge:hover {
background: oklch(0.68 0.13 150 / 0.2);
box-shadow: 0 0 16px oklch(0.68 0.13 150 / 0.3);
transform: translateY(-1px);
}
/* --- Interactive CSS Extension Mockup --- */
.hero-mockup-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.extension-mockup {
width: 100%;
max-width: 320px;
height: 528px;
background: oklch(0.20 0.025 140);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), 0 0 20px oklch(0.68 0.13 150 / 0.15);
display: flex;
flex-direction: column;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
overflow: hidden;
position: relative;
user-select: none;
padding: 14px;
padding-bottom: 0;
box-sizing: border-box;
}
.mock-header-row {
display: flex;
align-items: center;
margin-bottom: 12px;
flex-shrink: 0;
}
.mock-header-title {
font-size: 18px;
margin: 0;
color: var(--accent);
letter-spacing: 1px;
text-transform: uppercase;
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 800;
}
.mock-header-title picture {
display: contents;
}
.mock-header-title img {
width: 28px;
height: 28px;
object-fit: contain;
border-radius: 6px;
}
.mock-version-link {
margin-left: auto;
display: flex;
align-items: center;
gap: 4px;
font-size: 10px;
color: var(--text-muted);
text-decoration: none;
opacity: 0.5;
transition: opacity 0.2s, color 0.2s;
cursor: pointer;
}
.mock-version-link:hover {
opacity: 1;
color: var(--accent);
}
/* Close button for the hero demo popup (hidden in the static mobile mockup) */
.mock-close-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
margin-left: 8px;
padding: 0;
flex-shrink: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
cursor: pointer;
transition: color 0.2s, background 0.2s;
}
.mock-close-btn:hover {
color: #fff;
background: rgba(255, 255, 255, 0.1);
}
@media (max-width: 1024px) {
.mock-close-btn {
display: none;
}
}
.mock-tabs {
display: flex;
gap: 4px;
background: oklch(0.27 0.035 130);
padding: 4px;
border-radius: 12px;
margin-bottom: 14px;
flex-shrink: 0;
}
.mock-tab {
flex: 1;
background: none;
border: none;
color: var(--text-muted);
font-size: 0.75rem;
font-weight: 600;
padding: 7px 4px;
cursor: pointer;
border-radius: 8px;
transition: color 0.2s, background-color 0.2s;
text-align: center;
}
.mock-tab:hover {
color: var(--text);
}
.mock-tab.active {
background: var(--accent);
color: var(--text-on-green);
}
.mock-body {
flex: 1;
overflow-y: auto;
padding: 0;
padding-bottom: 12px;
display: flex;
flex-direction: column;
font-size: 0.8rem;
scrollbar-width: none; /* Firefox */
}
.mock-body::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
}
.mock-screen {
display: none;
flex-direction: column;
gap: 10px;
}
.mock-screen.active {
display: flex;
}
/* Common Mockup Components */
.mock-card {
background: oklch(0.27 0.035 130);
border: 1px solid oklch(0.32 0.03 125);
border-radius: 8px;
padding: 10px;
}
.mock-label {
font-size: 0.65rem;
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 0.3rem;
}
.mock-section-label {
display: block;
font-size: 11px;
text-transform: uppercase;
color: var(--text-muted);
margin-bottom: 4px;
font-weight: 700;
}
.mock-input {
background: oklch(0.27 0.035 130);
border: 1px solid oklch(0.32 0.03 125);
border-radius: 8px;
color: white;
padding: 8px 10px;
font-size: 0.75rem;
width: 100%;
outline: none;
}
.mock-btn {
background: var(--accent);
color: var(--text-on-green);
border: none;
border-radius: 6px;
padding: 0.5rem;
font-weight: 600;
font-size: 0.75rem;
cursor: pointer;
transition: background 0.2s;
text-align: center;
}
.mock-btn:hover {
background: oklch(0.60 0.12 150);
}
/* Room Tab Details */
.mock-joined-room {
display: flex;
justify-content: space-between;
align-items: center;
background: oklch(0.68 0.13 150 / 0.1);
border: 1px solid oklch(0.68 0.13 150 / 0.2);
border-radius: 8px;
padding: 0.6rem 0.75rem;
}
.mock-room-name {
font-weight: 700;
color: var(--accent);
font-size: 0.85rem;
}
.mock-server-badge {
background: oklch(0.68 0.13 150 / 0.2);
color: var(--accent);
font-size: 0.6rem;
font-weight: 700;
padding: 2px 6px;
border-radius: 4px;
}
.mock-invite-box {
display: flex;
gap: 0.35rem;
}
.mock-invite-box input {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.demo-room-empty {
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
padding: 24px 10px;
text-align: center;
}
.demo-room-empty img {
border-radius: 10px;
opacity: 0.85;
box-shadow: 0 4px 12px oklch(0.68 0.13 150 / 0.2);
}
.demo-room-empty-text {
font-size: 0.8rem;
color: var(--text-muted);
font-weight: 600;
}
.demo-create-room-btn {
background: var(--accent);
border: none;
color: var(--text-on-green);
font-weight: 700;
padding: 10px 18px;
border-radius: 10px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.demo-create-room-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px oklch(0.68 0.13 150 / 0.4);
}
.demo-create-room-btn:active {
transform: scale(0.96);
}
.mock-peer-list {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
.mock-peer-item {
display: flex;
flex-direction: column;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.03);
border-radius: 8px;
padding: 0.45rem 0.55rem;
}
.mock-peer-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.2rem;
}
.mock-peer-name {
font-weight: 700;
color: var(--text);
}
.mock-peer-meta {
font-size: 0.65rem;
color: var(--text-muted);
}
.mock-peer-tab {
font-size: 0.7rem;
color: var(--accent);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mock-peer-status {
font-size: 0.65rem;
color: var(--text-muted);
display: flex;
align-items: center;
gap: 0.25rem;
}
/* Sync Tab Details */
.mock-target-box {
display: flex;
align-items: center;
gap: 0.4rem;
background: oklch(0.62 0.14 45 / 0.1);
border: 1px solid oklch(0.62 0.14 45 / 0.2);
color: oklch(0.72 0.13 50);
padding: 0.5rem 0.6rem;
border-radius: 8px;
font-weight: 600;
font-size: 0.7rem;
}
.mock-ctrl-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
}
.mock-btn-play { background: oklch(0.68 0.13 150); }
.mock-btn-play:hover { background: oklch(0.60 0.12 150); }
.mock-btn-pause { background: oklch(0.55 0.15 25); color: #fff; }
.mock-btn-pause:hover { background: oklch(0.48 0.14 25); }
.mock-btn-force { background: var(--accent); grid-column: span 2; }
/* Contrast-safe palette for the decorative hero demo. Lighthouse/axe audits
sighted text contrast even inside aria-hidden, so every walkthrough state
must meet WCAG AA. Accent shown as text gets a lighter indigo; buttons that
put white text on a colour get a darker shade (these beat inline styles). */
.hero-demo-scene {
--accent: oklch(0.80 0.10 150);
--demo-sky-top: oklch(0.22 0.055 152);
--demo-sky-mid: oklch(0.145 0.035 150);
--demo-sky-bottom: oklch(0.075 0.018 145);
--demo-glow: oklch(0.76 0.13 150 / 0.34);
--demo-stars: oklch(0.94 0.025 95);
--demo-moon: oklch(0.97 0.025 92);
--demo-mountain: oklch(0.18 0.055 148 / 0.9);
--demo-midground: oklch(0.22 0.065 145 / 0.88);
--demo-foreground: oklch(0.065 0.025 145);
--demo-card: oklch(0.18 0.032 142);
--demo-toolbar: oklch(0.12 0.025 142);
--demo-control-fade: oklch(0.055 0.015 145 / 0.94);
--demo-track: oklch(0.92 0.02 95 / 0.2);
}
.hero-demo-scene .mock-tab.active,
.hero-demo-scene .mock-btn-force,
.hero-demo-scene #demo-force-sync,
.hero-demo-scene .demo-create-room-btn {
background: oklch(0.42 0.09 150) !important;
color: #fff;
}
.hero-demo-scene .mock-btn-play {
background: oklch(0.50 0.11 150) !important;
}
.hero-demo-scene .mock-btn-pause,
.hero-demo-scene #demo-room-joined > button.mock-btn {
background: oklch(0.45 0.14 25) !important;
}
.hero-demo-scene .mock-version-link {
opacity: 0.85;
}
html.theme-light .hero-demo-scene {
--accent: oklch(0.60 0.12 150);
--demo-sky-top: oklch(0.86 0.085 78);
--demo-sky-mid: oklch(0.76 0.095 112);
--demo-sky-bottom: oklch(0.54 0.10 150);
--demo-glow: oklch(0.92 0.13 72 / 0.44);
--demo-stars: oklch(0.98 0.025 90);
--demo-moon: oklch(0.99 0.025 88);
--demo-mountain: oklch(0.48 0.095 150 / 0.82);
--demo-midground: oklch(0.40 0.10 148 / 0.8);
--demo-foreground: oklch(0.24 0.075 145);
--demo-card: oklch(0.985 0.008 95);
--demo-toolbar: oklch(0.955 0.014 100);
--demo-control-fade: oklch(0.16 0.035 145 / 0.88);
--demo-track: oklch(0.98 0.01 95 / 0.34);
}
html.theme-light .hero-demo-scene .demo-tab-card {
background: var(--demo-card);
border-color: oklch(0.20 0.025 140 / 0.1);
box-shadow:
0 18px 38px oklch(0.20 0.025 140 / 0.16),
0 0 28px oklch(0.82 0.10 85 / 0.14),
inset 0 1px rgba(255, 255, 255, 0.9);
}
html.theme-light .hero-demo-scene .demo-tab-titlebar {
background: var(--demo-toolbar);
border-bottom-color: oklch(0.88 0.015 90);
color: oklch(0.45 0.02 110);
}
html.theme-light .hero-demo-scene .demo-tab-dots i {
background: oklch(0.78 0.02 90);
}
html.theme-light .hero-demo-scene .demo-ext-launcher {
background: #ffffff;
border-color: oklch(0.78 0.02 90);
}
html.theme-light .hero-demo-scene .demo-sync-chip {
background: oklch(0.55 0.12 150 / 0.1);
border-color: oklch(0.55 0.12 150 / 0.26);
color: oklch(0.40 0.10 150);
}
.mock-status-display {
display: flex;
align-items: center;
justify-content: space-between;
}
.mock-status-pill {
display: inline-flex;
align-items: center;
gap: 0.3rem;
background: oklch(0.68 0.13 150 / 0.1);
border: 1px solid oklch(0.68 0.13 150 / 0.2);
color: oklch(0.68 0.13 150);
padding: 2px 8px;
border-radius: 99px;
font-size: 0.65rem;
font-weight: 700;
}
.mock-log-item {
font-size: 0.7rem;
color: var(--text-muted);
border-left: 2px solid var(--accent);
padding-left: 0.4rem;
margin-top: 0.4rem;
}
/* Settings Tab Details */
.mock-settings-row {
display: flex;
align-items: flex-start;
gap: 0.5rem;
margin-bottom: 0.6rem;
}
.mock-settings-row input[type="checkbox"] {
margin-top: 0.2rem;
cursor: pointer;
}
.mock-settings-row label {
cursor: pointer;
font-weight: 600;
}
.mock-settings-row p {
font-size: 0.65rem;
color: var(--text-muted);
margin-top: 0.1rem;
}
/* Mock Toggle Switch Details */
.mock-toggle-switch {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
flex-shrink: 0;
}
.mock-toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.mock-slider {
position: absolute;
cursor: default;
top: 0; left: 0; right: 0; bottom: 0;
background-color: oklch(0.32 0.03 125);
transition: .3s;
border-radius: 20px;
}
.mock-slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background-color: oklch(0.68 0.02 100);
transition: .3s;
border-radius: 50%;
}
input:checked + .mock-slider {
background-color: var(--accent);
}
input:checked + .mock-slider:before {
transform: translateX(16px);
background-color: white;
}
/* Dev Tab Details */
.mock-diagnostic-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem;
}
.mock-diag-box {
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.04);
border-radius: 6px;
padding: 0.4rem;
}
.mock-diag-box .diag-val {
font-family: monospace;
font-weight: 700;
color: var(--accent);
font-size: 0.75rem;
}
/* --- Features --- */
/* Bento Grid Layout Configuration */
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
margin-top: 4rem;
}
.feature-card.feature-card-compact {
padding: 1.8rem;
border-radius: 16px;
}
.feature-card.feature-card-compact::before {
border-radius: 16px;
}
.feature-card.feature-card-compact h3 {
font-size: 1.1rem;
margin-bottom: 0.75rem;
}
.feature-card.feature-card-compact p {
font-size: 0.9rem;
}
.feature-card {
background: oklch(0.27 0.035 130 / 0.45);
backdrop-filter: blur(16px) saturate(120%);
-webkit-backdrop-filter: blur(16px) saturate(120%);
padding: 2.5rem;
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.feature-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
border-radius: 24px;
padding: 1px;
background: linear-gradient(to bottom right, rgba(255, 255, 255, 0.12), transparent);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.feature-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 30px oklch(0.68 0.13 150 / 0.2);
border-color: oklch(0.68 0.13 150 / 0.3);
}
.feature-card:hover::before {
background: linear-gradient(to bottom right, oklch(0.68 0.13 150 / 0.3), transparent);
}
/* Feature Icon with Inline SVG Wrapper */
.feature-icon-svg {
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
background: oklch(0.68 0.13 150 / 0.12);
color: var(--accent);
border-radius: 12px;
margin-right: 14px;
transition: background 0.3s ease, color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.feature-card:hover .feature-icon-svg {
background: var(--accent);
color: var(--text-on-green);
box-shadow: 0 0 15px var(--accent-glow);
transform: scale(1.05);
}
.bento-icon {
width: 22px;
height: 22px;
display: block;
flex-shrink: 0;
}
.feature-card h3 {
margin-bottom: 1rem;
font-size: 1.25rem;
font-weight: 700;
display: flex;
align-items: center;
}
.feature-card p {
color: var(--text-muted);
font-size: 0.95rem;
line-height: 1.6;
}
/* Bento Asymmetric Spanning */
.feature-card.bento-large {
grid-column: span 2;
background: linear-gradient(135deg, oklch(0.27 0.035 130 / 0.45) 0%, oklch(0.68 0.13 150 / 0.08) 100%);
padding: 3rem 3.5rem;
display: grid;
grid-template-columns: 1fr 2fr;
gap: 3rem;
align-items: center;
}
.feature-card.bento-large h3 {
flex-direction: column;
align-items: center;
text-align: center;
gap: 1rem;
margin-bottom: 0;
font-size: 1.25rem;
}
.feature-card.bento-large .feature-icon,
.feature-card.bento-large .feature-icon-svg {
width: 52px;
height: 52px;
border-radius: 14px;
margin-right: 0;
flex-shrink: 0;
}
.feature-card.bento-large .bento-icon {
width: 24px;
height: 24px;
}
.feature-card.bento-large p {
font-size: 1rem;
line-height: 1.7;
margin: 0;
}
.feature-card.bento-large::after {
content: '';
position: absolute;
top: 0;
left: 2.5rem;
right: 2.5rem;
height: 2px;
background: linear-gradient(90deg, transparent, oklch(0.68 0.13 150 / 0.4), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}
.feature-card.bento-large:hover::after {
opacity: 1;
}
@media (max-width: 900px) {
.features-grid {
/* Keep the Why KoalaSync grid at either three columns or one column.
The two-column in-between makes compact cards stretch unevenly. */
grid-template-columns: 1fr;
gap: 1.25rem;
}
.feature-card.bento-large {
grid-column: span 1;
padding: 2.5rem;
gap: 2rem;
}
.feature-card.bento-large h3 {
font-size: 1.15rem;
}
}
@media (max-width: 600px) {
.features-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.feature-card.bento-large {
grid-column: span 1;
display: flex;
flex-direction: column;
padding: 1.75rem;
gap: 1rem;
}
.feature-card.bento-large h3 {
flex-direction: row;
align-items: center;
text-align: left;
gap: 0.75rem;
margin-bottom: 0;
font-size: 1.15rem;
}
.feature-card.bento-large .feature-icon,
.feature-card.bento-large .feature-icon-svg {
width: 40px;
height: 40px;
border-radius: 10px;
margin-right: 0;
}
.feature-card.bento-large .bento-icon {
width: 18px;
height: 18px;
}
.feature-card.bento-large p {
font-size: 0.9rem;
line-height: 1.6;
}
.feature-card.bento-large::after {
display: none;
}
.feature-card {
padding: 1.75rem;
}
.feature-card h3 {
font-size: 1.1rem;
}
.feature-icon-svg {
width: 40px;
height: 40px;
border-radius: 10px;
margin-right: 12px;
}
.bento-icon {
width: 18px;
height: 18px;
}
}
/* --- How it works --- */
.steps {
display: flex;
flex-direction: column;
gap: 4rem;
}
.step {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
align-items: center;
}
.step:nth-child(even) .step-text {
order: 2;
}
.step-num {
font-size: 3.25rem;
font-weight: 900;
background: linear-gradient(135deg, oklch(0.68 0.13 150 / 0.5), oklch(0.62 0.14 45 / 0.15));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
line-height: 1;
margin-bottom: 0.5rem;
font-family: inherit;
letter-spacing: 0;
}
.step-text h3 {
font-size: 1.65rem;
margin-bottom: 0.75rem;
font-weight: 850;
color: var(--text-main);
letter-spacing: 0;
}
.step-text p {
color: var(--text-muted);
font-size: 1rem;
line-height: 1.55;
}
/* Custom CSS Mockups for step illustrations */
.step-illustration-1, .step-illustration-2, .step-illustration-3 {
background: radial-gradient(circle at 10% 10%, oklch(0.20 0.04 145), oklch(0.10 0.015 138));
height: 240px;
border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.06);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 20px 45px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.05);
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (max-width: 900px) {
#how-it-works {
padding: 3.5rem 0;
}
.steps {
gap: 2.75rem;
}
.step {
grid-template-columns: minmax(0, 1fr);
gap: 1.1rem;
text-align: left;
}
#how-it-works .step .step-text {
order: 1;
}
#how-it-works .step-illustration-1,
#how-it-works .step-illustration-2,
#how-it-works .step-illustration-3 {
order: 2;
height: 220px;
}
.step-num {
font-size: 2.5rem;
}
.step-text h3 {
font-size: 1.45rem;
}
}
.step-illustration-1:hover, .step-illustration-2:hover, .step-illustration-3:hover {
transform: translateY(-6px) scale(1.02);
border-color: oklch(0.68 0.13 150 / 0.25);
box-shadow: 0 25px 50px oklch(0.68 0.13 150 / 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
/* ==========================================================================
Step 1 Illustration: Browser & Installed Success Popup
========================================================================== */
.illus-browser-container {
width: 90%;
height: 80%;
background: oklch(0.11 0.015 138);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.6);
display: flex;
flex-direction: column;
}
.illus-browser-header {
background: oklch(0.20 0.025 140 / 0.8);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
padding: 0.6rem 0.8rem;
display: flex;
align-items: center;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.illus-browser-dots {
display: flex;
gap: 6px;
margin-right: 1.5rem;
}
.illus-browser-dot {
width: 8px;
height: 8px;
border-radius: 50%;
opacity: 0.6;
}
.illus-browser-dot:nth-child(1) { background: oklch(0.55 0.15 25); }
.illus-browser-dot:nth-child(2) { background: oklch(0.68 0.14 45); }
.illus-browser-dot:nth-child(3) { background: oklch(0.68 0.13 150); }
.illus-browser-address-bar {
background: oklch(0.13 0.02 138);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 6px;
color: var(--text-muted);
font-size: 0.68rem;
padding: 3px 12px;
flex-grow: 1;
max-width: 60%;
text-align: center;
font-family: monospace;
letter-spacing: 0.2px;
}
.illus-browser-address-bar .url-protocol {
color: oklch(0.68 0.13 150);
font-weight: 600;
}
.illus-browser-toolbar {
display: flex;
margin-left: auto;
}
.illus-extension-btn {
width: 22px;
height: 22px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.3s, box-shadow 0.3s;
}
.illus-extension-btn.active {
background: oklch(0.68 0.13 150 / 0.2);
border: 1px solid var(--accent);
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.4);
animation: active-pulse 2s infinite alternate;
}
@keyframes active-pulse {
0% { transform: scale(1); box-shadow: 0 0 5px oklch(0.68 0.13 150 / 0.4); }
100% { transform: scale(1.08); box-shadow: 0 0 12px oklch(0.68 0.13 150 / 0.7); }
}
.illus-browser-content {
flex-grow: 1;
padding: 1rem;
position: relative;
display: flex;
align-items: flex-start;
}
.illus-store-card {
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.04);
border-radius: 12px;
padding: 0.8rem;
width: 65%;
display: flex;
flex-direction: column;
gap: 10px;
}
.illus-store-card-header {
display: flex;
align-items: center;
gap: 8px;
}
.illus-large-logo {
width: 30px;
height: 30px;
object-fit: contain;
border-radius: 6px;
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.2);
}
.illus-store-info {
display: flex;
flex-direction: column;
}
.illus-store-title {
font-size: 0.88rem;
font-weight: 800;
color: var(--text);
line-height: 1.1;
}
.illus-store-desc {
font-size: 0.58rem;
color: var(--text-muted);
line-height: 1.2;
margin-top: 2px;
}
.illus-store-buttons {
display: flex;
flex-direction: column;
gap: 6px;
}
.illus-store-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 8px;
border-radius: 8px;
font-size: 0.58rem;
font-weight: 700;
color: white;
border: 1px solid rgba(255, 255, 255, 0.05);
background: rgba(255, 255, 255, 0.03);
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
cursor: default;
transition: opacity 0.2s, transform 0.2s;
}
.illus-store-btn img {
width: 11px;
height: 11px;
display: block;
}
.illus-store-btn.chrome {
border-color: oklch(0.68 0.13 150 / 0.25);
background: oklch(0.68 0.13 150 / 0.08);
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.05);
}
.illus-store-btn.firefox {
border-color: oklch(0.62 0.14 45 / 0.25);
background: oklch(0.62 0.14 45 / 0.08);
box-shadow: 0 0 10px oklch(0.62 0.14 45 / 0.05);
}
.install-breathe {
animation: install-breathe 2.5s ease-in-out infinite;
z-index: 2;
position: relative;
}
@keyframes install-breathe {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 15px oklch(0.68 0.13 150 / 0.2);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 25px oklch(0.68 0.13 150 / 0.5);
}
}
.install-breathe.firefox,
.btn-firefox.install-breathe {
animation-name: install-breathe-ff;
}
@keyframes install-breathe-ff {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 15px oklch(0.62 0.14 45 / 0.2);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 25px oklch(0.62 0.14 45 / 0.5);
}
}
/* Glassmorphic Dropping Success Card */
.illus-extension-popup {
position: absolute;
top: 0.6rem;
right: 0.6rem;
width: 145px;
background: oklch(0.20 0.025 140 / 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid oklch(0.68 0.13 150 / 0.25);
border-radius: 12px;
padding: 0.6rem 0.8rem;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.55), 0 0 15px oklch(0.68 0.13 150 / 0.15);
animation: popup-float 4s ease-in-out infinite;
z-index: 5;
}
@keyframes popup-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-4px); }
}
.illus-extension-popup .popup-title {
display: flex;
align-items: center;
gap: 5px;
font-size: 0.72rem;
font-weight: 700;
color: var(--text);
margin-bottom: 6px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
padding-bottom: 4px;
}
.illus-extension-popup .popup-title img {
width: 12px;
height: 12px;
}
.illus-extension-popup .popup-status {
margin-bottom: 4px;
}
.status-badge-success {
background: oklch(0.68 0.13 150 / 0.12);
color: oklch(0.68 0.13 150);
font-size: 0.6rem;
font-weight: 700;
padding: 2px 6px;
border-radius: 4px;
border: 1px solid oklch(0.68 0.13 150 / 0.2);
display: inline-flex;
align-items: center;
gap: 3px;
animation: status-glow 2s infinite alternate;
}
@keyframes status-glow {
0% { box-shadow: 0 0 0 oklch(0.68 0.13 150 / 0); }
100% { box-shadow: 0 0 6px oklch(0.68 0.13 150 / 0.3); }
}
.illus-extension-popup .popup-quick-start {
font-size: 0.55rem;
color: var(--text-muted);
font-weight: 500;
line-height: 1.2;
}
/* ==========================================================================
Step 2 Illustration: Highly Realistic Extension Popup (Create Room View)
========================================================================== */
.illus-popup-card {
width: 220px;
background: oklch(0.20 0.025 140 / 0.85);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 16px;
padding: 0.8rem;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.1);
display: flex;
flex-direction: column;
gap: 0.55rem;
animation: popup-float 4s ease-in-out infinite;
animation-delay: -1s;
}
.illus-popup-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
padding-bottom: 8px;
}
.illus-popup-brand {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.82rem; /* Scaled up font */
font-weight: 800;
letter-spacing: -0.2px;
}
.illus-popup-version {
font-size: 0.58rem;
color: var(--text-muted);
}
.illus-popup-tabs {
display: flex;
gap: 4px;
background: oklch(0.12 0.015 135 / 0.4);
padding: 3px;
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.03);
}
.illus-popup-tab {
flex: 1;
text-align: center;
font-size: 0.62rem; /* Scaled up font */
padding: 4px 0;
border-radius: 6px;
color: var(--text-muted);
font-weight: 600;
}
.illus-popup-tab.active {
background: var(--card);
color: var(--accent);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.illus-popup-body {
display: flex;
flex-direction: column;
gap: 0.55rem;
position: relative;
}
.illus-popup-btn {
background: linear-gradient(135deg, var(--accent-green), var(--accent-terracotta));
border-radius: 8px;
padding: 7px 9px;
color: var(--text-on-green);
font-weight: 700;
font-size: 0.68rem;
text-align: center;
box-shadow: 0 4px 12px oklch(0.68 0.13 150 / 0.3);
position: relative;
overflow: hidden;
cursor: default;
animation: create-btn-pulse 2s infinite alternate;
}
@keyframes create-btn-pulse {
0% { transform: scale(1); box-shadow: 0 4px 12px oklch(0.68 0.13 150 / 0.3); }
100% { transform: scale(1.03); box-shadow: 0 6px 16px oklch(0.68 0.13 150 / 0.5); }
}
.illus-btn-shine {
position: absolute;
top: 0;
left: -100%;
width: 50%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);
transform: skewX(-20deg);
animation: shimmer-sweep 3s infinite ease-in-out;
}
@keyframes shimmer-sweep {
0% { left: -100%; }
50%, 100% { left: 150%; }
}
.illus-collapsed-details {
background: oklch(0.12 0.015 135 / 0.4);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 8px;
padding: 6px 11px;
font-size: 0.54rem;
color: var(--text-muted);
font-weight: 700;
text-transform: uppercase;
display: flex;
align-items: center;
gap: 6px;
letter-spacing: 0.2px;
}
.details-arrow {
font-size: 0.48rem;
color: var(--text-muted);
opacity: 0.7;
}
/* Floating Success Badge */
.illus-floating-success {
position: absolute;
/* Fully below the card so the toast never straddles its border */
bottom: -2.4rem;
left: 50%;
transform: translateX(-50%);
background: oklch(0.12 0.015 135 / 0.92);
border: 1px solid oklch(0.68 0.13 150 / 0.35);
border-radius: 20px;
padding: 3px 10px;
display: flex;
align-items: center;
gap: 4px;
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.45), 0 0 12px oklch(0.68 0.13 150 / 0.18);
animation: floating-success-fade 5s infinite;
white-space: nowrap;
z-index: 10;
}
@keyframes floating-success-fade {
0%, 100%, 75% { opacity: 0; transform: translate(-50%, 5px) scale(0.9); }
15%, 60% { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
.illus-floating-success .success-icon {
font-size: 0.65rem;
}
.illus-floating-success span[lang] {
font-size: 0.58rem;
color: oklch(0.68 0.13 150);
font-weight: 700;
}
/* ==========================================================================
Step 3 Illustration: Dual Screen Theater Sync Setup
========================================================================= */
.illus-sync-theater {
width: 95%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
gap: 0.6rem;
}
.illus-player-card {
width: 145px;
background: oklch(0.20 0.025 140 / 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
padding: 6px;
box-shadow: 0 12px 30px rgba(0,0,0,0.5);
display: flex;
flex-direction: column;
gap: 4px;
position: relative;
z-index: 2;
}
.illus-player-card.player-a {
animation: popup-float 4s ease-in-out infinite;
animation-delay: -2s;
}
.illus-player-card.player-b {
animation: popup-float 4s ease-in-out infinite;
animation-delay: -3s;
}
.player-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.55rem;
}
.player-user {
font-weight: 700;
color: var(--text);
}
.player-badge {
font-size: 0.42rem;
font-weight: 800;
padding: 1px 3px;
border-radius: 3px;
}
.player-badge.active {
background: oklch(0.68 0.13 150 / 0.15);
color: oklch(0.68 0.13 150);
border: 1px solid oklch(0.68 0.13 150 / 0.25);
}
.player-video-canvas {
height: 70px;
border-radius: 8px;
background: linear-gradient(135deg, oklch(0.20 0.04 145), oklch(0.22 0.05 45));
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.02);
}
.player-video-overlay {
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background: linear-gradient(to bottom, transparent, oklch(0.68 0.13 150 / 0.15), transparent);
background-size: 100% 200%;
animation: playerScrollScanline 3s linear infinite;
}
@keyframes playerScrollScanline {
0% { background-position: 0% 0%; }
100% { background-position: 0% 200%; }
}
.player-play-pulse {
width: 24px;
height: 24px;
border-radius: 50%;
background: oklch(0.68 0.13 150 / 0.85);
color: var(--text-on-green);
font-size: 0.65rem;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.5);
z-index: 3;
animation: play-pulse 2s infinite alternate;
}
@keyframes play-pulse {
0% { transform: scale(1); box-shadow: 0 0 6px oklch(0.68 0.13 150 / 0.4); }
100% { transform: scale(1.15); box-shadow: 0 0 15px oklch(0.68 0.13 150 / 0.8); }
}
.player-controls {
display: flex;
align-items: center;
gap: 4px;
padding: 2px 2px 0 2px;
}
.control-btn {
font-size: 0.58rem;
color: var(--accent);
}
.player-timeline {
flex-grow: 1;
height: 3px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
position: relative;
}
.timeline-fill {
position: absolute;
top: 0; left: 0;
height: 100%;
background: var(--accent);
border-radius: 2px;
width: 60%;
animation: theater-grow 6s infinite linear;
}
.timeline-knob {
position: absolute;
top: -2px;
left: 60%;
width: 7px;
height: 7px;
border-radius: 50%;
background: white;
box-shadow: 0 0 4px rgba(0,0,0,0.5);
transform: translateX(-50%);
animation: theater-knob-grow 6s infinite linear;
}
@keyframes theater-grow {
0% { width: 0%; }
100% { width: 100%; }
}
@keyframes theater-knob-grow {
0% { left: 0%; }
100% { left: 100%; }
}
.control-time {
font-size: 0.5rem;
color: var(--text-muted);
font-family: monospace;
}
/* Glowing Connection Sync Bridge */
.illus-sync-bridge {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
position: relative;
z-index: 1;
}
.illus-sync-bridge .sync-line {
width: 100%;
height: 2px;
background: rgba(255,255,255,0.06);
position: relative;
overflow: hidden;
}
.illus-sync-bridge .sync-beam {
position: absolute;
top: 0;
left: -100%;
width: 50px;
height: 100%;
background: linear-gradient(90deg, transparent, var(--accent), var(--success), transparent);
animation: sync-flow 2.5s infinite linear;
}
@keyframes sync-flow {
0% { left: -100%; }
100% { left: 100%; }
}
.sync-status-badge {
background: oklch(0.68 0.13 150 / 0.12);
border: 1px solid oklch(0.68 0.13 150 / 0.25);
color: oklch(0.68 0.13 150);
font-size: 0.5rem;
font-weight: 800;
letter-spacing: 0.5px;
padding: 2px 6px;
border-radius: 6px;
white-space: nowrap;
animation: active-pulse-green 2s infinite alternate;
}
@keyframes active-pulse-green {
0% { box-shadow: 0 0 3px oklch(0.68 0.13 150 / 0.1); }
100% { box-shadow: 0 0 8px oklch(0.68 0.13 150 / 0.4); }
}
/* --- Self Hosters Terminal --- */
.terminal-container {
max-width: 850px;
margin: 3rem auto 0 auto;
background: oklch(0.20 0.025 140);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 16px;
overflow: hidden;
box-shadow: 0 20px 45px rgba(0,0,0,0.5);
text-align: left;
}
.terminal-header {
background: oklch(0.27 0.035 130);
padding: 0.85rem 1.25rem;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.terminal-dots {
display: flex;
gap: 6px;
}
.terminal-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.terminal-dot.red { background: oklch(0.55 0.15 25); }
.terminal-dot.yellow { background: oklch(0.68 0.14 45); }
.terminal-dot.green { background: oklch(0.68 0.13 150); }
.terminal-tabs {
display: flex;
gap: 0.5rem;
}
.terminal-tab-btn {
background: none;
border: none;
color: var(--text-muted);
font-weight: 600;
font-size: 0.8rem;
padding: 0.35rem 0.75rem;
border-radius: 6px;
cursor: pointer;
transition: color 0.2s, background-color 0.2s;
}
.terminal-tab-btn:hover {
color: var(--text);
background: rgba(255, 255, 255, 0.03);
}
.terminal-tab-btn.active {
color: var(--accent);
background: oklch(0.68 0.13 150 / 0.1);
border: 1px solid oklch(0.68 0.13 150 / 0.2);
}
.terminal-body {
position: relative;
padding: 1.5rem;
}
.terminal-pane {
display: none;
margin: 0;
}
.terminal-pane.active {
display: block;
}
.terminal-pane pre {
margin: 0;
overflow-x: auto;
}
.terminal-pane code {
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size: 0.85rem;
line-height: 1.6;
color: oklch(0.88 0.015 90);
}
/* Syntax Highlighting */
.t-comment { color: oklch(0.55 0.02 110); font-style: italic; }
.t-key { color: oklch(0.72 0.12 45); }
.t-val { color: oklch(0.75 0.10 150); }
.t-str { color: oklch(0.80 0.12 155); }
.t-num { color: oklch(0.75 0.12 50); }
.terminal-copy-btn {
position: absolute;
top: 1rem;
right: 1.5rem;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
color: var(--text-muted);
padding: 0.35rem 0.75rem;
font-size: 0.75rem;
font-weight: 600;
border-radius: 6px;
cursor: pointer;
transition: background-color 0.2s, color 0.2s, opacity 0.2s;
display: flex;
align-items: center;
gap: 0.3rem;
}
.terminal-copy-btn:hover {
background: rgba(255, 255, 255, 0.08);
color: var(--text);
border-color: rgba(255, 255, 255, 0.15);
}
.terminal-copy-btn:active {
transform: scale(0.97);
}
/* --- Footer --- */
footer {
padding: 4rem 0;
border-top: 0;
text-align: center;
color: var(--text-muted);
}
footer a {
color: var(--text-muted);
text-decoration: none;
transition: color 0.2s ease;
}
footer a:hover {
color: var(--text);
}
/* --- Animations --- */
[data-reveal] {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1), transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
[data-reveal].revealed {
opacity: 1;
transform: translateY(0);
}
html.theme-light .hero-demo-scene .demo-user-a,
html.theme-light .hero-demo-scene .demo-user-b {
color: oklch(0.36 0.105 150);
background: oklch(0.60 0.12 150 / 0.13);
}
html.theme-light .hero-demo-scene .extension-mockup {
--bg: oklch(0.935 0.018 110) !important;
--card: oklch(0.995 0.006 100) !important;
--accent: oklch(0.56 0.13 150) !important;
--accent-glow: oklch(0.56 0.13 150 / 0.22) !important;
--text: oklch(0.21 0.03 140) !important;
--text-muted: oklch(0.43 0.03 135) !important;
--success: oklch(0.56 0.13 150) !important;
--error: oklch(0.57 0.17 25) !important;
--glass-border: oklch(0.28 0.035 140 / 0.10) !important;
background: oklch(0.935 0.018 110) !important;
border-color: oklch(0.28 0.035 140 / 0.12);
box-shadow:
0 20px 42px oklch(0.20 0.025 140 / 0.16),
0 0 26px oklch(0.82 0.10 85 / 0.12);
}
html.theme-light .hero-demo-scene .mock-tabs,
html.theme-light .hero-demo-scene .mock-card,
html.theme-light .hero-demo-scene .mock-input {
background: oklch(0.995 0.006 100);
border-color: oklch(0.28 0.035 140 / 0.14);
color: oklch(0.21 0.03 140);
}
html.theme-light .hero-demo-scene .mock-peer-item {
background: oklch(0.28 0.035 140 / 0.035);
border-color: oklch(0.28 0.035 140 / 0.09);
}
html.theme-light .hero-demo-scene .mock-joined-room,
html.theme-light .hero-demo-scene .mock-status-pill {
background: oklch(0.56 0.13 150 / 0.10);
border-color: oklch(0.56 0.13 150 / 0.24);
}
html.theme-light .hero-demo-scene .mock-close-btn:hover {
color: oklch(0.21 0.03 140);
background: oklch(0.28 0.035 140 / 0.08);
}
/* A direct hash destination is content, not an entrance animation. Keep it
readable from the first paint even before app.js has initialized. */
section:target [data-reveal],
section:target[data-reveal] {
opacity: 1;
transform: translateY(0);
}
/* --- Legal Pages --- */
.legal-content {
max-width: 800px;
margin: 8rem auto 4rem auto;
padding: 0 2rem;
}
.legal-card {
background: var(--card);
padding: 3rem;
border-radius: 24px;
border: 1px solid var(--glass-border);
}
.legal-card h1 {
font-size: 2.5rem;
margin-bottom: 2rem;
text-align: center;
}
.legal-card h2 {
font-size: 1.25rem;
margin-top: 1rem;
margin-bottom: 0.5rem;
color: var(--accent);
}
.legal-card p {
color: var(--text-muted);
margin-bottom: 0.5rem;
font-size: 0.95rem;
}
/* Reset global section padding for legal sections specifically */
.legal-card section {
padding: 0 !important;
margin-bottom: 0.75rem;
}
/* --- Join Page Specifics --- */
.join-card {
max-width: 450px;
margin: 6rem auto;
text-align: center;
}
.room-badge {
display: inline-block;
background: oklch(0.68 0.13 150 / 0.1);
color: var(--accent);
padding: 0.5rem 1rem;
border-radius: 99px;
font-size: 0.8rem;
font-weight: 700;
margin-bottom: 1rem;
border: 1px solid oklch(0.68 0.13 150 / 0.2);
}
@media (max-width: 768px) {
.hero {
align-items: center;
padding-top: 5.5rem;
padding-bottom: 3.5rem;
min-height: 100svh;
}
.hero-grid {
min-height: auto;
}
.hero-grid {
grid-template-columns: minmax(0, 1fr);
text-align: center;
}
.step {
grid-template-columns: minmax(0, 1fr);
text-align: left;
}
.hero-text h1 {
font-size: 2.5rem;
max-width: none;
}
.cta-group {
justify-content: center;
flex-wrap: wrap;
}
.nav-links {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
flex-direction: column;
background: oklch(0.20 0.025 140 / 0.95);
backdrop-filter: blur(12px);
padding: 1rem 2rem;
gap: 1rem;
border-bottom: 1px solid var(--glass-border);
margin-left: 0;
}
.nav-links.open {
display: flex;
}
.nav-right {
margin-left: auto;
}
.hamburger {
display: inline-flex !important;
}
nav .container {
padding: 0 0.5rem;
}
.logo-area {
gap: 0.25rem;
font-size: 1.1rem;
}
.logo-area img {
height: 40px;
width: 40px;
margin: 0;
}
.lang-select-container {
padding: 4px 10px;
gap: 4px;
}
.lang-select-container .globe-icon {
width: 14px;
height: 14px;
}
.lang-dropdown {
font-size: 0.7rem;
padding: 0 6px 0 0;
}
.lang-select-container .chevron-icon {
width: 10px;
height: 10px;
}
.legal-card {
padding: 1.5rem;
}
}
@media (min-width: 769px) and (max-height: 920px) {
.hero {
padding-top: clamp(7.5rem, 10vh, 9rem);
padding-bottom: clamp(1.5rem, 3vh, 2.75rem);
}
.hero-grid {
min-height: calc(100svh - 9.5rem);
}
}
/* Extra-narrow phones: make sure logo, language picker and the menu button
never crowd each other in the header (kept comfortable down to ~320px). */
@media (max-width: 380px) {
nav .container {
padding: 0 0.4rem;
}
.nav-right {
gap: 0.35rem;
}
.logo-area {
font-size: 1rem;
gap: 0.4rem;
}
}
/* --- Language Toggle --- */
html.lang-de [lang="en"] {
display: none !important;
}
html:not(.lang-de) [lang="de"] {
display: none !important;
}
/* --- Modern Glassmorphic Language Selector --- */
.lang-select-container {
position: relative;
display: inline-flex;
align-items: center;
gap: 8px;
background: oklch(0.27 0.035 130 / 0.4);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 9999px;
padding: 6px 14px;
transition: background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
color: var(--text-muted);
}
.lang-select-container:hover {
background: oklch(0.27 0.035 130 / 0.6);
border-color: oklch(0.68 0.13 150 / 0.3);
color: var(--text);
box-shadow: 0 0 15px oklch(0.68 0.13 150 / 0.1);
}
.lang-select-container .globe-icon {
width: 16px;
height: 16px;
flex-shrink: 0;
opacity: 0.8;
transition: transform 0.5s ease;
}
.lang-select-container:hover .globe-icon {
transform: rotate(15deg);
opacity: 1;
}
.lang-select-container .chevron-icon {
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
width: 12px;
height: 12px;
pointer-events: none;
opacity: 0.6;
}
.lang-select-container:hover .chevron-icon {
opacity: 1;
}
.lang-dropdown {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background: transparent;
border: none;
outline: none;
font-family: inherit;
font-size: 0.8rem;
font-weight: 600;
color: currentColor;
cursor: pointer;
padding: 0 28px 0 0;
margin: 0;
width: auto;
min-width: 110px;
overflow: hidden;
}
@supports (appearance: base-select) {
.lang-dropdown::picker(select) {
appearance: base-select;
background-color: oklch(0.20 0.025 140);
border: 1px solid oklch(0.32 0.03 125);
border-radius: 8px;
padding: 4px;
font-family: 'Twemoji Country Flags', inherit;
}
}
.lang-dropdown option {
background: oklch(0.20 0.025 140);
color: white;
font-family: inherit;
font-size: 0.9rem;
}
/* Light theme: the pill was designed on the dark glass recipe — by day it
becomes frosted white so it sits in the same family as the buttons. */
html.theme-light .lang-select-container {
background: rgba(255, 255, 255, 0.6);
border-color: oklch(0.28 0.035 140 / 0.14);
}
html.theme-light .lang-select-container:hover {
background: rgba(255, 255, 255, 0.85);
border-color: oklch(0.56 0.13 150 / 0.35);
box-shadow: 0 0 15px oklch(0.56 0.13 150 / 0.12);
}
html.theme-light .lang-dropdown option {
background: #ffffff;
color: oklch(0.21 0.03 140);
}
@supports (appearance: base-select) {
html.theme-light .lang-dropdown::picker(select) {
background-color: #ffffff;
border-color: oklch(0.28 0.035 140 / 0.18);
}
}
/* --- Hamburger Menu --- */
.hamburger {
display: none;
align-items: center;
justify-content: center;
background: none;
border: none;
color: var(--text);
font-size: 1.5rem;
cursor: pointer;
padding: 0.25rem;
line-height: 1;
}
/* --- Feature Cards: subtle differentiation --- */
.feature-card:nth-child(1) { --card-accent: oklch(0.68 0.13 150 / 0.06); }
.feature-card:nth-child(2) { --card-accent: oklch(0.62 0.14 45 / 0.06); }
.feature-card:nth-child(3) { --card-accent: oklch(0.68 0.13 150 / 0.06); }
.feature-card:nth-child(4) { --card-accent: oklch(0.75 0.10 150 / 0.06); }
.feature-card:nth-child(5) { --card-accent: oklch(0.68 0.14 45 / 0.06); }
.feature-card:nth-child(6) { --card-accent: oklch(0.62 0.14 45 / 0.06); }
.feature-card:nth-child(7) { --card-accent: oklch(0.62 0.14 45 / 0.06); }
.feature-card:nth-child(8) { --card-accent: oklch(0.68 0.13 150 / 0.06); }
.feature-card {
background: linear-gradient(135deg, var(--card-accent, transparent), oklch(0.27 0.035 130 / 0.45));
}
/* --- Compatibility Section --- */
.compat-section {
padding: 0.5rem 0 2.5rem 0;
text-align: center;
background: transparent;
border-bottom: 0;
}
.compat-mascot {
display: block;
margin: 0 auto 0.3rem auto;
max-width: 270px;
width: 100%;
height: auto;
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.compat-mascot:hover {
transform: scale(1.05) translateY(-5px) rotate(1deg);
}
.compat-heading {
font-size: 1rem;
font-weight: 600;
color: var(--text-muted);
letter-spacing: 0.08em;
text-transform: uppercase;
margin-bottom: 1.4rem;
}
.compat-row {
display: flex;
justify-content: center;
align-items: center;
gap: 2.4rem 3rem;
flex-wrap: wrap;
}
.compat-logo {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
font-size: 0.75rem;
font-weight: 700;
color: var(--text-muted);
transition: opacity 0.3s;
opacity: 0.55;
}
.compat-logo:hover {
opacity: 0.85;
}
.compat-logo img {
width: 28px;
height: 28px;
display: block;
}
.compat-logo img.compat-logo-wide {
width: 52px;
height: 28px;
object-fit: contain;
}
.compat-logo img.compat-logo-disneyplus-mark {
width: 60px;
height: 30px;
object-fit: contain;
filter: brightness(0) saturate(100%) invert(63%) sepia(12%) saturate(621%) hue-rotate(203deg) brightness(92%) contrast(88%);
}
html.theme-light .compat-logo img.compat-logo-disneyplus-mark {
filter: none;
}
@media (max-width: 700px) {
.compat-section {
padding: 0 0 1.6rem;
}
.compat-mascot {
max-width: 220px;
margin-bottom: 0.1rem;
}
.compat-heading {
font-size: 0.92rem;
line-height: 1.55;
margin-bottom: 1rem;
}
.compat-row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1.55rem 0.75rem;
align-items: start;
}
.compat-logo {
gap: 0.35rem;
font-size: 0.72rem;
}
.compat-logo img {
width: 26px;
height: 26px;
}
.compat-logo img.compat-logo-wide {
width: 48px;
height: 26px;
}
.compat-logo img.compat-logo-disneyplus-mark {
width: 56px;
height: 28px;
}
.compat-logo-jellyfin {
display: none;
}
.compat-more {
grid-column: 1 / -1;
justify-self: center;
white-space: nowrap;
}
}
.compat-more {
opacity: 0.4;
cursor: help;
flex-direction: row;
gap: 0.35rem;
position: relative;
}
.compat-more:hover {
opacity: 0.6;
}
.compat-more-icon {
font-size: 1.1rem;
font-weight: 700;
color: var(--accent);
line-height: 1;
}
.compat-tooltip {
display: none;
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
transform: translateX(-50%);
background: var(--card);
color: var(--text-muted);
padding: 0.6rem 0.9rem;
border-radius: 8px;
font-size: 0.72rem;
font-weight: 500;
white-space: nowrap;
border: 1px solid var(--glass-border);
box-shadow: 0 8px 20px rgba(0,0,0,0.4);
z-index: 10;
line-height: 1.4;
}
.compat-tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: var(--glass-border);
}
.compat-more:hover .compat-tooltip {
display: block;
}
/* --- Join Page Loading Spinner --- */
.join-spinner {
width: 36px;
height: 36px;
border: 3px solid oklch(0.68 0.13 150 / 0.2);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin: 0 auto 0.75rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* --- Reduced Motion --- */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
[data-reveal] {
opacity: 1;
transform: none;
}
.illus-typing-text::after {
animation: none;
}
.illus-timeline-progress {
animation: none;
width: 60%;
}
.illus-sync-pulse {
animation: none;
}
.illus-extension-icon {
animation: none;
}
}
/* --- Use Cases / Anwendungsszenarien Section --- */
.use-cases-section {
padding: 6rem 0;
position: relative;
border-bottom: 0;
}
.use-cases-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 2rem;
margin-top: 1rem;
}
.use-cases-feature-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 900px) {
.use-cases-feature-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1.25rem;
}
}
@media (max-width: 600px) {
.use-cases-feature-grid {
grid-template-columns: minmax(0, 1fr);
gap: 1rem;
}
}
.use-case-card {
background: oklch(0.27 0.035 130 / 0.4);
border: 1px solid var(--glass-border);
border-radius: 16px;
padding: 1.2rem 1.6rem 1.7rem 1.6rem;
text-align: left;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s ease;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
display: flex;
flex-direction: column;
gap: 0.8rem;
position: relative;
overflow: hidden;
}
.use-case-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, transparent, var(--card-accent-border, var(--accent)), transparent);
opacity: 0;
transition: opacity 0.3s ease;
}
.use-case-card:nth-child(1) { --card-accent-border: oklch(0.68 0.13 150); }
.use-case-card:nth-child(2) { --card-accent-border: oklch(0.62 0.14 45); }
.use-case-card:nth-child(3) { --card-accent-border: oklch(0.75 0.10 150); }
.use-case-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35);
border-color: rgba(255, 255, 255, 0.15);
}
.use-case-card:hover::before {
opacity: 1;
}
.use-case-image {
display: block;
width: 100%;
max-width: 272px;
height: 150px;
object-fit: contain;
border-radius: 8px;
margin: 0 auto 0 auto;
}
.cta-github-mascot {
display: block;
width: 100%;
max-width: 250px;
height: auto;
margin: 1.5rem auto;
}
.features-questions-mascot {
display: block;
width: 100%;
max-width: 250px;
height: auto;
margin: -1.5rem auto 0.2rem auto;
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.features-questions-mascot:hover {
transform: scale(1.05) translateY(-4px) rotate(-1.5deg);
}
.comparison-mascot {
display: block;
width: 100%;
max-width: 260px;
height: auto;
margin: -2.2rem auto 0.2rem auto;
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.comparison-mascot:hover {
transform: scale(1.05) translateY(-4px) rotate(1deg);
}
.use-case-icon {
font-size: 1.6rem;
margin-right: 0.6rem;
display: inline-block;
vertical-align: middle;
filter: drop-shadow(0 2px 8px rgba(0,0,0,0.2));
}
.use-case-card h3 {
font-size: 1.25rem;
font-weight: 700;
margin: 0;
color: white;
}
.use-case-card p {
font-size: 0.9rem;
line-height: 1.6;
color: var(--text-muted);
margin: 0;
}
/* --- Comparison Section --- */
.comparison-section {
padding: 6rem 0;
background: transparent;
border-bottom: 0;
}
#self-hosting,
#faq,
#faq + section,
footer {
background: var(--section-tint-strong);
}
#self-hosting {
border-top: 1px solid var(--glass-border);
}
.comparison-table-wrapper {
overflow-x: auto;
background: oklch(0.27 0.035 130 / 0.35);
border: 1px solid var(--glass-border);
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
margin-top: 1rem;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
text-align: left;
font-size: 0.95rem;
}
.comparison-table th,
.comparison-table td {
padding: 1.25rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.comparison-table th {
background: oklch(0.20 0.025 140 / 0.6);
font-weight: 700;
color: white;
text-transform: uppercase;
font-size: 0.8rem;
letter-spacing: 0.08em;
}
.comparison-table th.highlight,
.comparison-table td.highlight {
background: oklch(0.68 0.13 150 / 0.08);
}
.comparison-table tbody tr:hover {
background: rgba(255, 255, 255, 0.02);
}
.comparison-table tbody tr:last-child td {
border-bottom: none;
}
.feat-name {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.feat-name strong {
color: white;
font-weight: 600;
}
.feat-desc {
font-size: 0.8rem;
color: var(--text-muted);
}
.check {
color: oklch(0.68 0.13 150);
font-weight: 700;
}
.cross {
color: oklch(0.68 0.17 25);
font-weight: 600;
opacity: 1;
}
@media (max-width: 768px) {
.comparison-table th,
.comparison-table td {
padding: 1rem;
font-size: 0.85rem;
}
}
/* On phones the 3-column table is turned into stacked cards so there is
no horizontal scrolling — one card per feature, KoalaSync above Teleparty. */
@media (max-width: 600px) {
.comparison-table-wrapper {
overflow-x: visible;
background: transparent;
border: none;
box-shadow: none;
backdrop-filter: none;
-webkit-backdrop-filter: none;
margin-top: 0;
}
.comparison-table {
display: block;
font-size: 0.95rem;
}
/* Visually hide the header row but keep it for screen readers. */
.comparison-table thead {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.comparison-table tbody,
.comparison-table tr,
.comparison-table td {
display: block;
width: 100%;
}
.comparison-table tbody tr {
background: oklch(0.27 0.035 130 / 0.35);
border: 1px solid var(--glass-border);
border-radius: 14px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
margin-bottom: 1rem;
overflow: hidden;
}
.comparison-table tbody tr:last-child {
margin-bottom: 0;
}
.comparison-table td {
padding: 0.85rem 1.1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.comparison-table tbody tr td:last-child {
border-bottom: none;
}
/* Feature name acts as the card header. */
.comparison-table td.feat-name {
background: oklch(0.20 0.025 140 / 0.55);
padding: 0.9rem 1.1rem;
}
/* Room is back on the card, so show the description again. */
.feat-desc {
display: block;
margin-top: 0.15rem;
}
/* Label each value cell with the product it belongs to. */
.comparison-table td.check,
.comparison-table td.cross {
display: flex;
align-items: baseline;
gap: 0.4rem;
}
.comparison-table td.check::before,
.comparison-table td.cross::before {
flex: 0 0 5.5rem;
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
opacity: 0.85;
}
.comparison-table td.check::before,
.comparison-table td.cross::before {
content: attr(data-label);
}
/* Keep the KoalaSync row subtly highlighted, like on desktop. */
.comparison-table td.check.highlight {
background: oklch(0.68 0.13 150 / 0.08);
}
}
@media (max-width: 600px) {
html.theme-light .comparison-section {
background: transparent;
}
html.theme-light .comparison-table tbody tr {
background: #ffffff;
border-color: oklch(0.20 0.025 140 / 0.1);
box-shadow: 0 8px 20px oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .comparison-table tbody tr:hover {
background: #ffffff;
}
html.theme-light .comparison-table td {
border-bottom-color: oklch(0.20 0.025 140 / 0.08);
}
html.theme-light .comparison-table td.feat-name {
background: #ffffff;
}
html.theme-light .comparison-table td.check.highlight {
background: oklch(0.52 0.12 150 / 0.07);
}
}
/* --- Footnotes & Source Links --- */
.source-link {
color: var(--accent);
text-decoration: none;
font-size: 0.72rem;
font-weight: 700;
margin-left: 0.25rem;
display: inline-flex;
align-items: center;
vertical-align: super;
opacity: 0.82;
transition: opacity 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.source-link:hover {
opacity: 1;
color: oklch(0.75 0.10 150);
transform: translateY(-1px);
}
.table-footnotes {
padding: 0.8rem 1.25rem;
background: oklch(0.20 0.025 140 / 0.45);
border-top: 1px solid rgba(255, 255, 255, 0.05);
font-size: 0.72rem;
color: var(--text-muted);
line-height: 1.5;
opacity: 0.65;
transition: opacity 0.2s ease;
}
/* Link from the comparison table to the fuller guides/alternatives hub */
.comparison-guides-link {
text-align: center;
margin: 2rem 0 0;
}
.comparison-guides-link a {
display: inline-flex;
align-items: center;
gap: 0.45rem;
color: var(--accent);
text-decoration: none;
font-weight: 600;
font-size: 0.95rem;
transition: gap 0.2s ease, opacity 0.2s ease;
}
.comparison-guides-link a:hover {
gap: 0.7rem;
opacity: 0.85;
}
.table-footnotes:hover {
opacity: 0.95;
}
.table-footnotes p {
margin: 0;
display: flex;
align-items: baseline;
gap: 0.4rem;
}
.table-footnotes p:not(:last-child) {
margin-bottom: 0.4rem;
}
.table-footnotes a {
color: var(--accent);
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease, text-decoration 0.2s ease;
}
.table-footnotes a:hover {
color: oklch(0.75 0.10 150);
text-decoration: underline;
}
.table-footnotes sup {
font-weight: 700;
color: var(--accent);
}
@media (max-width: 768px) {
.table-footnotes {
padding: 0.75rem 1rem;
font-size: 0.68rem;
}
}
/* --- Join & Invitation Page Visuals --- */
.join-status-visual {
margin-bottom: 2rem;
position: relative;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.join-status-mascot {
display: block;
width: 140px;
height: auto;
z-index: 2;
filter: drop-shadow(0 4px 12px rgba(0,0,0,0.15));
}
.join-status-mascot.searching-mascot {
width: 175px; /* Slightly wider due to antenna to keep main body scale identical */
}
.join-status-pulse {
animation: mascot-gentle-pulse 2s ease-in-out infinite;
}
@keyframes mascot-gentle-pulse {
0% {
transform: scale(0.96);
filter: drop-shadow(0 4px 10px oklch(0.68 0.13 150 / 0.15));
}
50% {
transform: scale(1.04);
filter: drop-shadow(0 8px 20px oklch(0.68 0.13 150 / 0.35));
}
100% {
transform: scale(0.96);
filter: drop-shadow(0 4px 10px oklch(0.68 0.13 150 / 0.15));
}
}
.legal-mascot {
display: block;
width: 180px;
height: auto;
margin: -0.75rem auto 0.4rem auto;
filter: drop-shadow(0 4px 12px rgba(0,0,0,0.15));
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.legal-mascot:hover {
transform: scale(1.06) translateY(-4px) rotate(1.5deg);
}
.selfhost-mascot {
display: block;
width: 300px;
height: auto;
margin: 0 auto;
filter: drop-shadow(0 4px 12px rgba(0,0,0,0.15));
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.selfhost-mascot:hover {
transform: scale(1.05) translateY(-4px) rotate(-1deg);
}
.status-ring {
position: absolute;
width: 90px;
height: 90px;
border-radius: 50%;
background: oklch(0.68 0.13 150 / 0.05);
border: 2px dashed oklch(0.68 0.13 150 / 0.25);
z-index: 1;
}
.status-ring.active-pulse {
animation: radar-pulse 3s cubic-bezier(0.25, 0.8, 0.25, 1) infinite;
}
@keyframes radar-pulse {
0% {
transform: scale(0.85);
opacity: 0.9;
border-color: oklch(0.68 0.13 150 / 0.3);
box-shadow: 0 0 0 0px oklch(0.68 0.13 150 / 0.15);
}
50% {
transform: scale(1.18);
opacity: 0.35;
border-color: oklch(0.75 0.10 150 / 0.2);
box-shadow: 0 0 0 15px oklch(0.75 0.10 150 / 0);
}
100% {
transform: scale(0.85);
opacity: 0.9;
border-color: oklch(0.68 0.13 150 / 0.3);
box-shadow: 0 0 0 0px oklch(0.68 0.13 150 / 0.15);
}
}
.join-card-actions {
display: flex;
flex-direction: column;
gap: 0.75rem;
width: 100%;
}
.join-card-actions .btn {
width: 100%;
justify-content: center;
padding: 1.1rem;
font-size: 0.88rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.join-card-actions .btn svg {
margin-right: 0.3rem;
flex-shrink: 0;
}
.join-card-actions .btn img {
margin-right: 0.3rem;
flex-shrink: 0;
}
.btn-success {
background: var(--accent-green);
color: var(--text-on-green) !important;
box-shadow: 0 10px 15px -3px oklch(0.68 0.13 150 / 0.3);
}
.btn-success:hover {
background: oklch(0.60 0.12 150);
transform: translateY(-2px);
box-shadow: 0 20px 25px -5px oklch(0.68 0.13 150 / 0.4);
}
/* --- Section collapse (FAQ, self-hosting): closed by default to keep the page short --- */
.section-collapse {
margin: 0 auto;
}
.faq-section-collapse {
max-width: 800px;
}
.collapse-summary {
display: flex;
align-items: center;
justify-content: center;
gap: 0.6rem;
list-style: none;
cursor: pointer;
font-weight: 700;
font-size: 1rem;
color: var(--accent);
background: oklch(0.68 0.13 150 / 0.08);
border: 1px solid oklch(0.68 0.13 150 / 0.3);
border-radius: 99px;
padding: 0.85rem 2rem;
max-width: 360px;
margin: 0 auto;
transition: background 0.3s, box-shadow 0.3s, transform 0.3s;
}
.collapse-summary::-webkit-details-marker {
display: none;
}
.collapse-summary:hover {
background: oklch(0.68 0.13 150 / 0.16);
box-shadow: 0 0 20px oklch(0.68 0.13 150 / 0.25);
transform: translateY(-2px);
}
.collapse-summary .collapse-chevron {
flex-shrink: 0;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.section-collapse[open] .collapse-chevron {
transform: rotate(180deg);
}
.collapse-label-hide { display: none; }
.section-collapse[open] .collapse-label-show { display: none; }
.section-collapse[open] .collapse-label-hide { display: inline; }
.section-collapse[open] .collapse-summary {
margin-bottom: 2rem;
}
.section-collapse[open] .collapse-content {
animation: collapse-content-in 0.4s ease-out;
}
@keyframes collapse-content-in {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
.section-collapse[open] .collapse-content {
animation: none;
}
}
/* --- FAQ Section --- */
.faq-grid {
display: flex;
flex-direction: column;
gap: 1rem;
max-width: 800px;
margin: 0 auto;
}
.faq-item {
background: oklch(0.27 0.035 130 / 0.45);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 16px;
padding: 1.5rem 2rem;
cursor: pointer;
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
overflow: hidden;
}
.faq-item:hover {
border-color: oklch(0.68 0.13 150 / 0.3);
box-shadow: 0 8px 20px oklch(0.68 0.13 150 / 0.1);
}
.faq-item[open] {
border-color: oklch(0.68 0.13 150 / 0.4);
background: oklch(0.27 0.035 130 / 0.65);
}
.faq-item summary {
font-weight: 700;
font-size: 1.05rem;
color: var(--text);
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.faq-item summary::-webkit-details-marker {
display: none;
}
.faq-item summary::after {
content: '+';
font-size: 1.4rem;
color: var(--accent);
font-weight: 300;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
flex-shrink: 0;
transform-origin: center;
}
.faq-item[open] summary::after {
transform: rotate(45deg);
}
.faq-item p {
color: var(--text-muted);
font-size: 0.95rem;
line-height: 1.6;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.06);
}
/* --- Focus states for interactive cards --- */
.feature-card:focus-visible,
.use-case-card:focus-visible,
.compat-logo:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 4px;
transform: translateY(-5px);
}
.feature-card,
.use-case-card,
.compat-logo,
section[id],
header[id] {
scroll-margin-top: 100px;
}
/* --- Screen-reader-only (also crawlable by search engines) --- */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* --- Skip-to-content accessibility link --- */
.skip-link {
position: absolute;
left: -9999px;
top: 0;
background: var(--accent);
color: var(--text-on-green);
padding: 0.75rem 1.25rem;
border-radius: 0 0 8px 0;
font-weight: 700;
z-index: 9999;
text-decoration: none;
}
.skip-link:focus {
left: 0;
}
/* --- Reduced motion support --- */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.join-status-pulse { animation: none; }
.status-ring.active-pulse { animation: none; }
}
/* --- will-change hints for animated elements --- */
.join-status-pulse,
.status-ring.active-pulse,
.hero-mockup-wrapper,
.cta-group .btn {
will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
.join-status-pulse,
.status-ring.active-pulse,
.hero-mockup-wrapper,
.cta-group .btn {
}
}
/* --- Alternatives Hub Styles --- */
.guide-card {
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.25s ease, border-color 0.25s ease !important;
}
.guide-card:hover {
transform: translateY(-4px);
background-color: rgba(255, 255, 255, 0.07) !important;
border-color: rgba(255, 255, 255, 0.22) !important;
box-shadow: 0 12px 24px -10px rgba(0, 0, 0, 0.4);
}
.guide-card .btn-primary {
transition: background-color 0.2s ease, transform 0.1s ease;
}
.guide-card .btn-primary:active {
transform: scale(0.97);
}
@media (max-width: 640px) {
.guides-grid {
grid-template-columns: 1fr !important;
gap: 1.25rem !important;
}
}
/* --- Hero Live Demo Scene (two synced tabs + extension popup) --- */
.hero-mockup-wrapper {
flex-direction: column;
gap: 0.9rem;
container-type: inline-size;
}
/* Fixed height that already fits the open popup, so toggling it never changes
layout (the vertically centered hero never jumps). The empty lower area is
the invisible room the popup drops into.
Do not move .hero-mockup-wrapper down to align the headline and demo tops:
the extension popup is bottom-anchored inside this scene, so moving the whole
wrapper destroys the vertical balance and leaves no breathing room below. */
.hero-demo-scene {
--demo-content-y: 0px;
position: relative;
width: 100%;
height: max(calc(59cqw + 100px), 548px);
}
.demo-tab-stack {
position: relative;
width: 100%;
height: calc(59cqw + 100px + var(--demo-content-y));
}
@media (min-width: 1025px) {
.hero-demo-scene {
/* Balance the demo inside the visible hero area below the fixed navbar.
Shift the scene content, not the hero text or grid. */
--demo-content-y: 2.75rem;
}
}
/* While initializing, suppress all transitions so the popup can start closed
without a visible open->closed animation on page load. */
.hero-demo-scene.demo-no-anim,
.hero-demo-scene.demo-no-anim * {
transition-duration: 0s !important;
}
/* Sync status chip: green "in sync" at rest, flashes the broadcast event */
.demo-sync-chip {
position: absolute;
top: var(--demo-content-y);
left: 2px;
z-index: 8;
display: inline-flex;
align-items: center;
gap: 7px;
padding: 5px 12px;
border-radius: 99px;
background: oklch(0.68 0.13 150 / 0.12);
border: 1px solid oklch(0.68 0.13 150 / 0.35);
color: #86efac;
font-family: inherit;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.06em;
text-transform: uppercase;
cursor: default;
transition: background 0.3s, border-color 0.3s, color 0.3s;
}
.demo-chip-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: oklch(0.68 0.13 150);
box-shadow: 0 0 8px oklch(0.68 0.13 150);
transition: background 0.3s, box-shadow 0.3s;
}
.demo-sync-chip .demo-chip-event { display: none; }
.demo-sync-chip.event {
background: oklch(0.68 0.13 150 / 0.14);
border-color: oklch(0.68 0.13 150 / 0.45);
color: oklch(0.85 0.07 150);
}
.demo-sync-chip.event .demo-chip-dot {
background: oklch(0.75 0.13 150);
box-shadow: 0 0 8px oklch(0.75 0.13 150);
}
.demo-sync-chip.event .demo-chip-label-sync { display: none; }
.demo-sync-chip.event .demo-chip-event { display: inline; }
@keyframes demoBlink {
50% { opacity: 0.35; }
}
/* Video tab cards: a clean window cascade — the right one is in front */
.demo-tab-card {
position: absolute;
width: 310px;
width: 70cqw;
background: var(--demo-card);
border: 1px solid rgba(255, 255, 255, 0.09);
border-radius: 14px;
box-shadow: 0 18px 36px rgba(0, 0, 0, 0.45), inset 0 1px rgba(255, 255, 255, 0.05);
overflow: hidden;
cursor: pointer;
user-select: none;
transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), border-color 0.25s;
}
.demo-tab-card:hover,
.demo-tab-card:focus-visible {
border-color: oklch(0.68 0.13 150 / 0.55);
}
/* Card A = the foreground window at the top right ("your" browser,
hosts the extension icon in its toolbar) */
.demo-tab-a {
top: calc(49px + var(--demo-content-y));
right: -3%;
transform: rotate(1.2deg);
transform-origin: top right;
z-index: 3;
}
.demo-tab-a:hover {
z-index: 4;
transform: rotate(1.2deg) scale(1.02);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.65), 0 0 20px oklch(0.68 0.13 150 / 0.2);
}
/* Card B = the friend's window, lower left, tucked behind */
.demo-tab-b {
top: 142px;
top: calc(20cqw + 67px + var(--demo-content-y));
left: -3%;
transform: rotate(-1.6deg);
transform-origin: top left;
z-index: 2;
}
.demo-tab-b:hover {
z-index: 4;
transform: rotate(-1.6deg) scale(1.02);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.65), 0 0 20px oklch(0.68 0.13 150 / 0.2);
}
/* When the popup slides in from the right edge, the tabs step aside */
.hero-demo-scene.popup-open .demo-tab-a {
top: calc(22px + var(--demo-content-y));
transform: rotate(1deg) translate(-44%, 20%) scale(0.88);
}
.hero-demo-scene.popup-open .demo-tab-a:hover {
z-index: 4;
transform: rotate(1deg) translate(-44%, 20%) scale(0.92);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.65), 0 0 20px oklch(0.68 0.13 150 / 0.2);
}
.hero-demo-scene.popup-open .demo-tab-b {
top: calc(20cqw + 40px + var(--demo-content-y));
transform: rotate(-1.6deg) translate(0, 14%) scale(0.94);
}
.hero-demo-scene.popup-open .demo-tab-b:hover {
z-index: 4;
transform: rotate(-1.6deg) translate(0, 14%) scale(0.98);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.65), 0 0 20px oklch(0.68 0.13 150 / 0.2);
}
.demo-tab-titlebar {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px 6px 10px;
background: var(--demo-toolbar);
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
font-size: 10.5px;
color: var(--text-muted);
font-weight: 600;
}
.demo-tab-dots {
display: flex;
gap: 4px;
flex-shrink: 0;
}
.demo-tab-dots i {
display: block;
width: 7px;
height: 7px;
border-radius: 50%;
background: oklch(0.32 0.03 125);
}
.demo-tab-title {
display: flex;
align-items: center;
gap: 5px;
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.demo-tab-title svg { flex-shrink: 0; }
.demo-tab-user {
flex-shrink: 0;
font-size: 9.5px;
font-weight: 700;
padding: 2px 7px;
border-radius: 99px;
}
.demo-user-a {
color: oklch(0.80 0.10 150);
background: oklch(0.68 0.13 150 / 0.15);
}
.demo-user-b {
color: #86efac;
background: oklch(0.68 0.13 150 / 0.12);
}
/* Extension launcher pinned in the foreground window's toolbar */
.demo-ext-launcher {
position: relative;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
border-radius: 7px;
background: oklch(0.30 0.03 130);
border: 1px solid rgba(255, 255, 255, 0.12);
cursor: pointer;
transition: border-color 0.25s, box-shadow 0.25s, transform 0.15s;
}
.demo-ext-launcher img {
display: block;
width: 16px;
height: 16px;
border-radius: 4px;
}
.demo-ext-launcher:hover {
border-color: var(--accent);
transform: translateY(-1px);
}
.demo-ext-launcher:active {
transform: scale(0.94);
}
.hero-demo-scene.popup-open .demo-ext-launcher {
border-color: oklch(0.68 0.13 150 / 0.7);
box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.45);
}
.demo-ext-launcher::after {
content: '';
position: absolute;
top: -3px;
right: -3px;
width: 8px;
height: 8px;
border-radius: 50%;
background: oklch(0.68 0.13 150);
box-shadow: 0 0 8px oklch(0.68 0.13 150);
opacity: 0;
transition: opacity 0.3s;
}
.hero-demo-scene:not(.popup-open) .demo-ext-launcher:not(.demo-ext-static)::after {
opacity: 1;
animation: demoBlink 1.4s ease-in-out infinite;
}
/* Card B shows the same extension icon, purely to signal the friend has it
installed too. It is not interactive and does not blink or glow. */
.demo-ext-static,
.demo-ext-static:hover {
cursor: default;
border-color: rgba(255, 255, 255, 0.12);
transform: none;
box-shadow: none;
}
.demo-ext-static::after { display: none; }
/* Abstract "video" artwork with a slow cinematic pan/zoom while playing */
.demo-video {
position: relative;
aspect-ratio: 16 / 9;
background: var(--demo-sky-bottom);
overflow: hidden;
}
.demo-video::after {
content: '';
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
/* Cinematic vignette: soft edge falloff + heavier floor for the controls */
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.05),
inset 0 0 34px oklch(0.04 0.015 145 / 0.32),
inset 0 -26px 40px oklch(0.04 0.015 145 / 0.26);
}
html.theme-light .hero-demo-scene .demo-video::after {
box-shadow:
inset 0 0 0 1px oklch(0.30 0.04 145 / 0.13),
inset 0 18px 32px oklch(0.98 0.03 90 / 0.1),
inset 0 -22px 34px oklch(0.18 0.05 145 / 0.16);
}
.demo-video-art {
position: absolute;
inset: 0;
background:
radial-gradient(30% 42% at 76% 29%, var(--demo-glow), transparent 64%),
radial-gradient(90% 85% at 18% 5%, var(--demo-glow), transparent 66%),
linear-gradient(160deg, var(--demo-sky-top) 0%, var(--demo-sky-mid) 52%, var(--demo-sky-bottom) 100%);
transform-origin: 60% 40%;
animation:
demoKenBurns 9s ease-in-out infinite alternate,
demoArtShift 7s ease-in-out infinite alternate;
animation-play-state: paused;
}
/* Soft light drifting through the scene */
.demo-video-art::before {
content: '';
position: absolute;
top: -25%;
left: -12%;
width: 70%;
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle, var(--demo-glow), transparent 65%);
animation: demoGlowDrift 7s ease-in-out infinite alternate;
animation-play-state: paused;
}
.demo-video-art::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(105deg, transparent 30%, oklch(0.75 0.13 150 / 0.14) 45%, oklch(0.75 0.10 150 / 0.1) 55%, transparent 70%);
transform: translateX(-100%);
animation: demoSheen 2.8s linear infinite;
animation-play-state: paused;
}
/* Playing runs the animations; pausing freezes them mid-frame, so a synced
pause is visible at a glance */
.demo-tab-card.playing .demo-video-art,
.demo-tab-card.playing .demo-video-art::before,
.demo-tab-card.playing .demo-video-art::after {
animation-play-state: running;
}
@keyframes demoKenBurns {
from { transform: scale(1) translate(0, 0); }
to { transform: scale(1.18) translate(-3%, 2%); }
}
@keyframes demoArtShift {
from { filter: hue-rotate(0deg) brightness(1); }
to { filter: hue-rotate(40deg) brightness(1.15); }
}
@keyframes demoGlowDrift {
from { transform: translate(0, 0); }
to { transform: translate(65%, 30%); }
}
@keyframes demoSheen {
to { transform: translateX(100%); }
}
/* Play / pause overlay */
.demo-play-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: oklch(0.10 0.01 135 / 0.35);
transition: opacity 0.25s, background 0.25s;
}
.demo-icon-wrap {
display: flex;
align-items: center;
justify-content: center;
width: 46px;
height: 46px;
border-radius: 50%;
background: oklch(0.20 0.025 140 / 0.75);
border: 1px solid rgba(255, 255, 255, 0.25);
color: white;
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
transition: transform 0.2s;
}
.demo-tab-card:hover .demo-icon-wrap { transform: scale(1.1); }
.demo-play-overlay .icon-pause { display: none; }
.demo-tab-card.playing .icon-play { display: none; }
.demo-tab-card.playing .icon-pause { display: block; }
.demo-tab-card.playing .demo-play-overlay {
opacity: 0;
background: transparent;
}
.demo-tab-card.playing:hover .demo-play-overlay,
.demo-tab-card.playing:focus-visible .demo-play-overlay {
opacity: 1;
}
/* Timestamp + seekable progress bar */
.demo-video-controls {
position: absolute;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
gap: 8px;
padding: 14px 10px 8px;
background: linear-gradient(transparent, var(--demo-control-fade));
font-size: 9.5px;
color: oklch(0.88 0.015 90);
z-index: 1;
}
.demo-time,
.demo-duration {
flex-shrink: 0;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-weight: 700;
letter-spacing: 0.03em;
font-variant-numeric: tabular-nums;
}
.demo-duration {
font-weight: 600;
opacity: 0.7;
}
/* Decorative player chrome: play state glyph, volume, HD, fullscreen */
.demo-ctrl-icon {
display: flex;
align-items: center;
flex-shrink: 0;
opacity: 0.85;
}
.demo-ctrl-play .icon-pause { display: none; }
.demo-tab-card.playing .demo-ctrl-play .icon-play { display: none; }
.demo-tab-card.playing .demo-ctrl-play .icon-pause { display: block; }
.demo-ctrl-badge {
flex-shrink: 0;
font-size: 7px;
font-weight: 800;
letter-spacing: 0.06em;
line-height: 1;
padding: 2px 3px;
border: 1px solid currentColor;
border-radius: 3px;
opacity: 0.65;
}
.demo-progress {
position: relative;
flex: 1;
height: 5px;
border-radius: 99px;
background: var(--demo-track);
cursor: pointer;
}
/* Generous invisible hit area for seeking */
.demo-progress::before {
content: '';
position: absolute;
inset: -8px 0;
}
/* Buffered range behind the playhead, like a real player */
.demo-progress-buffer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 56%;
border-radius: 99px;
background: oklch(0.92 0.02 95 / 0.14);
pointer-events: none;
}
.demo-progress-fill {
position: relative;
height: 100%;
width: 30%;
border-radius: 99px;
background: linear-gradient(90deg, oklch(0.68 0.13 150), oklch(0.62 0.14 45));
pointer-events: none;
}
/* Scrub thumb, revealed on hover */
.demo-progress-fill::after {
content: '';
position: absolute;
right: -5px;
top: 50%;
width: 11px;
height: 11px;
margin-top: -5.5px;
border-radius: 50%;
background: oklch(0.88 0.015 90);
box-shadow: 0 0 6px oklch(0.68 0.13 150 / 0.8);
opacity: 0;
transform: scale(0.6);
transition: opacity 0.2s, transform 0.2s;
}
.demo-tab-card:hover .demo-progress-fill::after {
opacity: 1;
transform: scale(1);
}
/* Sync pulse ring on both cards */
.demo-tab-card.sync-pulse {
animation: demoCardPulse 0.9s ease-out;
}
@keyframes demoCardPulse {
0% { box-shadow: 0 18px 36px rgba(0, 0, 0, 0.45), 0 0 0 0 oklch(0.68 0.13 150 / 0.65); }
100% { box-shadow: 0 18px 36px rgba(0, 0, 0, 0.45), 0 0 0 22px oklch(0.68 0.13 150 / 0); }
}
/* The existing popup mockup slides in at the right edge, dropping out of
the toolbar icon of the foreground window */
.hero-demo-scene .extension-mockup {
position: absolute;
bottom: 0;
right: 0;
z-index: 5;
width: 292px;
width: min(320px, 66cqw);
margin: 0;
transform-origin: top right;
transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s, visibility 0.45s;
}
@media (min-width: 1025px) {
.hero-demo-scene .extension-mockup {
/* Counter the content shift so the opened panel is balanced below nav. */
bottom: 0.625rem;
}
}
.hero-demo-scene:not(.popup-open) .extension-mockup {
transform: translate(2%, -3%) scale(0.5);
opacity: 0;
visibility: hidden;
pointer-events: none;
}
/* Ghost cursor for the automated walkthrough */
.demo-cursor {
position: absolute;
top: 52%;
left: 46%;
z-index: 20;
width: 22px;
height: 22px;
opacity: 0;
pointer-events: none;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6));
transition: top 0.65s cubic-bezier(0.45, 0.05, 0.25, 1), left 0.65s cubic-bezier(0.45, 0.05, 0.25, 1), opacity 0.35s;
}
.demo-cursor.visible { opacity: 1; }
.demo-cursor svg {
display: block;
width: 100%;
height: 100%;
}
.demo-cursor::before {
content: '';
position: absolute;
top: -6px;
left: -8px;
width: 32px;
height: 32px;
border-radius: 50%;
border: 2px solid oklch(0.75 0.13 150);
opacity: 0;
transform: scale(0.35);
}
.demo-cursor.clicking::before {
animation: demoClickRipple 0.45s ease-out;
}
@keyframes demoClickRipple {
0% { opacity: 0.9; transform: scale(0.35); }
100% { opacity: 0; transform: scale(1.25); }
}
/* Caption below the scene */
.demo-hint {
margin: 0.75rem auto 0;
max-width: min(100%, 34rem);
text-align: center;
font-size: 0.82rem;
line-height: 1.45;
color: var(--text-muted);
opacity: 0;
transition: opacity 0.6s;
}
.demo-hint.show { opacity: 0.75; }
/* Tablet/Small Desktop: fall back to the classic static popup mockup */
@media (max-width: 1023px) {
.hero-demo-scene,
.hero-demo-scene.popup-open {
height: auto;
max-width: 320px;
margin: 0 auto;
}
.demo-tab-card,
.demo-tab-stack,
.demo-sync-chip,
.demo-cursor,
.demo-hint {
display: none !important;
}
.hero-demo-scene .extension-mockup,
.hero-demo-scene:not(.popup-open) .extension-mockup {
position: static;
width: 100%;
transform: none;
opacity: 1;
visibility: visible;
pointer-events: auto;
}
}
@media (prefers-reduced-motion: reduce) {
.hero-demo-scene:not(.popup-open) .demo-ext-launcher::after {
animation: none;
}
}
/* --- Story walkthrough additions: room creation, invite flight, film --- */
/* The stick-figure film carries the motion now — keep only the color drift
on the backdrop (the animation shorthand resets play-state, so re-pause) */
.demo-video-art {
animation: demoArtShift 7s ease-in-out infinite alternate;
animation-play-state: paused;
}
.demo-film {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.hero-demo-scene .film-stars { fill: var(--demo-stars) !important; }
.hero-demo-scene .film-clouds { fill: var(--demo-stars) !important; }
.hero-demo-scene .film-mist-scroll { fill: var(--demo-stars) !important; }
.hero-demo-scene .film-shooting-star { stroke: var(--demo-stars) !important; }
.hero-demo-scene .film-moon {
fill: var(--demo-moon) !important;
filter: drop-shadow(0 0 6px var(--demo-moon));
}
.hero-demo-scene .film-mtn-scroll { fill: var(--demo-mountain) !important; }
.hero-demo-scene .film-mid-scroll > * { fill: var(--demo-midground) !important; }
.hero-demo-scene .film-fore-scroll > * { fill: var(--demo-foreground) !important; }
/* By day the birds read as silhouettes, not chalk marks */
html.theme-light .hero-demo-scene .film-birds { stroke: oklch(0.32 0.06 145 / 0.65); }
html.theme-light :is(.hero-demo-scene, .step-illustration-3) .film-hero-bird { stroke: oklch(0.32 0.06 145 / 0.75); }
/* Stars: staggered twinkle so the sky feels alive */
.film-star {
transform-box: fill-box;
transform-origin: center;
animation: filmTwinkle 2.8s ease-in-out infinite;
}
.film-star:nth-child(2) { animation-duration: 3.4s; animation-delay: 0.5s; }
.film-star:nth-child(3) { animation-duration: 2.4s; animation-delay: 1.1s; }
.film-star:nth-child(4) { animation-duration: 3.6s; animation-delay: 0.3s; }
.film-star:nth-child(5) { animation-duration: 2.6s; animation-delay: 1.6s; }
.film-star:nth-child(6) { animation-duration: 3.2s; animation-delay: 0.8s; }
.film-star:nth-child(7) { animation-duration: 2.2s; animation-delay: 1.3s; }
@keyframes filmTwinkle {
0%, 100% { opacity: 0.25; transform: scale(0.85); }
50% { opacity: 1; transform: scale(1.15); }
}
/* Moon: gentle glow pulse + slow arc drift. The drift lives on the wrapper
group so the craters travel with the disc; the glow stays on the circle.
(Step-3 uses a bare .film-moon without wrapper — filmMoon still covers it.) */
.film-moon-g {
transform-box: fill-box;
transform-origin: center;
animation: filmMoonDrift 6s ease-in-out infinite alternate;
animation-play-state: paused;
}
.film-moon-g .film-moon {
animation-name: filmMoonGlow;
}
@keyframes filmMoonDrift {
from { transform: translate(0, 0); }
to { transform: translate(-6px, 3px); }
}
@keyframes filmMoonGlow {
from { filter: drop-shadow(0 0 4px oklch(0.95 0.01 100 / 0.5)); }
to { filter: drop-shadow(0 0 10px oklch(0.95 0.01 100 / 0.95)); }
}
.film-moon {
transform-box: fill-box;
transform-origin: center;
animation: filmMoon 6s ease-in-out infinite alternate;
animation-play-state: paused;
}
@keyframes filmMoon {
from { transform: translate(0, 0); filter: drop-shadow(0 0 4px oklch(0.95 0.01 100 / 0.5)); }
to { transform: translate(-6px, 3px); filter: drop-shadow(0 0 10px oklch(0.95 0.01 100 / 0.95)); }
}
.film-mtn-scroll {
transform: translateX(var(--scroll-back, 0px));
}
.film-mid-scroll {
transform: translateX(var(--scroll-mid, 0px));
}
.film-fore-scroll {
transform: translateX(var(--scroll-fore, 0px));
}
/* A single gliding bird carries the scene: the outer group rides the
JS-driven drift vars, the inner group flaps its wings via scaleY. */
.film-hero-bird-drift {
transform: translate(var(--lantern-x, 0px), var(--bounce-y, 0px));
}
.film-hero-bird {
transform-box: fill-box;
transform-origin: center;
animation: filmWingFlap 0.85s ease-in-out infinite alternate;
animation-play-state: paused;
}
@keyframes filmWingFlap {
from { transform: scaleY(1); }
to { transform: scaleY(0.5); }
}
/* Twinkle & Glow play state bindings */
.film-star {
transform-box: fill-box;
transform-origin: center;
animation: filmTwinkle 2.8s ease-in-out infinite;
animation-play-state: paused;
}
.demo-tab-card.playing :is(.film-star, .film-moon, .film-moon-g, .film-cloud, .film-shooting-star, .film-birds, .film-hero-bird) {
animation-play-state: running;
}
/* Drifting clouds: gentle back-and-forth so there is no wrap pop */
.film-cloud {
transform-box: fill-box;
animation: filmCloudDrift 26s ease-in-out infinite alternate;
animation-play-state: paused;
}
.film-cloud-2 {
animation-duration: 34s;
animation-delay: -12s;
}
@keyframes filmCloudDrift {
from { transform: translateX(-6px); }
to { transform: translateX(10px); }
}
/* A shooting star streaks across the sky every few loops */
.film-shooting-star {
opacity: 0;
animation: filmShoot 11s linear infinite;
animation-play-state: paused;
}
@keyframes filmShoot {
0%, 87% { opacity: 0; transform: translate(0, 0); }
89% { opacity: 0.9; }
95%, 100% { opacity: 0; transform: translate(-46px, 20px); }
}
/* A distant flock crosses the valley, fading out mid-flight */
.film-birds {
animation: filmBirds 16s linear infinite;
animation-play-state: paused;
}
@keyframes filmBirds {
0% { transform: translate(0, 0); opacity: 0; }
4% { opacity: 0.75; }
42% { opacity: 0.75; }
48%, 100% { transform: translate(185px, -12px); opacity: 0; }
}
/* Valley mist rides the slow background parallax between tree layers */
.film-mist-scroll {
transform: translateX(var(--scroll-back, 0px));
}
/* Play button pulsing indicator at the end of the walkthrough */
.hero-demo-scene.demo-complete #demo-tab-a:not(.playing) .demo-icon-wrap {
animation: playButtonPulse 1.6s ease-in-out infinite;
border-color: oklch(0.68 0.13 150);
box-shadow: 0 0 15px oklch(0.68 0.13 150 / 0.8);
}
@keyframes playButtonPulse {
0%, 100% { transform: scale(1); box-shadow: 0 0 10px oklch(0.68 0.13 150 / 0.5); }
50% { transform: scale(1.12); box-shadow: 0 0 20px oklch(0.68 0.13 150 / 0.9); }
}
/* Seek-reset: scrubbing restarts animations from frame zero */
.demo-film.demo-reset * {
animation: none !important;
}
/* Seek-break: scrubbing the timeline visibly glitches both videos so the
jump reads as a real cut instead of an invisible time update. A scanline
sweep + brightness pop, and the film animations restart mid-stride. */
.demo-video-art { transition: filter 0.12s ease-out; }
.demo-tab-card.demo-seeking .demo-video-art {
animation-play-state: paused;
filter: brightness(1.9) saturate(1.4) blur(0.6px);
}
.demo-tab-card .demo-seek-sweep {
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
opacity: 0;
background: linear-gradient(90deg,
transparent 0%,
oklch(0.75 0.13 150 / 0.35) 20%,
rgba(255, 255, 255, 0.55) 50%,
oklch(0.75 0.13 150 / 0.35) 80%,
transparent 100%);
mix-blend-mode: screen;
transform: translateX(-100%);
}
.demo-tab-card.demo-seeking .demo-seek-sweep {
animation: demoSeekSweep 0.34s ease-out;
}
@keyframes demoSeekSweep {
0% { opacity: 0; transform: translateX(-100%); }
20% { opacity: 1; }
100% { opacity: 0; transform: translateX(100%); }
}
/* The sync chip only appears once the room is connected (story progression) */
.demo-sync-chip {
opacity: 0;
transform: translateY(-4px);
pointer-events: none;
transition: background 0.3s, border-color 0.3s, color 0.3s, opacity 0.4s, transform 0.4s;
}
.hero-demo-scene.connected .demo-sync-chip {
opacity: 1;
transform: none;
pointer-events: auto;
}
/* Toast on the friend's window ("Room joined", "Tab selected") */
.demo-tab-toast {
position: absolute;
top: 36px;
left: 50%;
transform: translate(-50%, -6px);
z-index: 2;
padding: 4px 10px;
border-radius: 99px;
background: oklch(0.20 0.025 140 / 0.92);
border: 1px solid oklch(0.68 0.13 150 / 0.5);
color: oklch(0.85 0.07 150);
font-size: 9.5px;
font-weight: 700;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s, transform 0.3s;
}
.demo-tab-toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
/* Invite link pill flying from the popup to the friend's window */
.demo-invite-fly {
position: absolute;
z-index: 30;
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
border-radius: 99px;
background: var(--accent);
color: var(--text-on-green);
font-size: 9.5px;
font-weight: 700;
white-space: nowrap;
box-shadow: 0 6px 18px oklch(0.68 0.13 150 / 0.5);
opacity: 0;
pointer-events: none;
transition: left 0.75s cubic-bezier(0.3, 0.7, 0.4, 1), top 0.75s cubic-bezier(0.3, 0.7, 0.4, 1), opacity 0.3s;
}
/* Attention flash (e.g. on the video select while "choosing the tab") */
.demo-attn {
animation: demoAttn 0.7s ease-in-out 2;
}
@keyframes demoAttn {
50% { box-shadow: 0 0 0 3px oklch(0.68 0.13 150 / 0.75); }
}
/* --- Bento Card Host Control Mockup Additions --- */
.bento-content-wrap {
display: flex;
flex-direction: column;
gap: 1.2rem;
width: 100%;
}
.bento-host-control-mockup {
background: oklch(0.20 0.025 140 / 0.6);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 0.75rem 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
width: 100%;
box-sizing: border-box;
}
.bento-mockup-header {
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-muted);
font-weight: 700;
}
.bento-mockup-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
font-size: 0.75rem;
color: white;
font-weight: 600;
margin-top: 2px;
}
/* Custom switch toggle representation */
.bento-switch-wrap {
position: relative;
display: inline-block;
width: 28px;
height: 16px;
flex-shrink: 0;
}
.bento-switch-wrap input {
opacity: 0;
width: 0;
height: 0;
}
.bento-switch-slider {
position: absolute;
cursor: default;
top: 0; left: 0; right: 0; bottom: 0;
background-color: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 16px;
transition: .3s;
}
.bento-switch-slider:before {
position: absolute;
content: "";
height: 10px;
width: 10px;
left: 2px;
bottom: 2px;
background-color: oklch(0.68 0.02 100);
border-radius: 50%;
transition: .3s;
}
.bento-switch-wrap input:checked + .bento-switch-slider {
background-color: oklch(0.68 0.13 150 / 0.25);
border-color: oklch(0.68 0.13 150 / 0.6);
box-shadow: 0 0 8px oklch(0.68 0.13 150 / 0.3);
}
.bento-switch-wrap input:checked + .bento-switch-slider:before {
transform: translateX(12px);
background-color: var(--accent);
box-shadow: 0 0 6px var(--accent-glow);
}
/* --- Step 2 & Step 3 Visual Redesign Styles --- */
/* Step 2 Browser video player mock */
.illus-video-player-mock {
width: 85%;
height: 65%;
background: linear-gradient(135deg, oklch(0.20 0.04 145), oklch(0.12 0.02 138));
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
margin-top: 15px;
}
.video-mock-play-button {
width: 32px;
height: 32px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
cursor: default;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.video-mock-timeline {
position: absolute;
bottom: 8px;
left: 8px;
right: 8px;
height: 3px;
background: rgba(255, 255, 255, 0.15);
border-radius: 2px;
}
.video-mock-timeline-fill {
width: 35%;
height: 100%;
background: var(--accent);
border-radius: 2px;
}
/* Step 2 extension popup dropdown alignment */
.illus-extension-popup.drop-down {
top: 2.2rem;
right: 0.6rem;
width: 145px;
animation: popup-dropdown-float 4s ease-in-out infinite;
}
@keyframes popup-dropdown-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-3px); }
}
.status-badge-select {
background: oklch(0.68 0.13 150 / 0.12);
color: oklch(0.85 0.07 150);
font-size: 0.58rem;
font-weight: 700;
padding: 2px 6px;
border-radius: 4px;
border: 1px solid oklch(0.68 0.13 150 / 0.2);
display: inline-flex;
align-items: center;
text-transform: uppercase;
letter-spacing: 0.2px;
}
.popup-form-group {
margin-top: 6px;
width: 100%;
text-align: left;
}
.popup-form-label {
display: block;
font-size: 0.6rem;
color: var(--text-muted);
margin-bottom: 4px;
font-weight: 700;
}
.popup-select-wrapper {
position: relative;
width: 100%;
}
.popup-select-mock {
width: 100%;
background: var(--card);
border: 1px solid rgba(255, 255, 255, 0.12);
color: white;
padding: 6px;
border-radius: 6px;
font-family: inherit;
font-size: 0.62rem;
outline: none;
appearance: none;
-webkit-appearance: none;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: default;
display: block;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
}
.popup-cursor-pointer {
position: absolute;
bottom: -15px;
right: 15px;
font-size: 1.1rem;
pointer-events: none;
z-index: 10;
animation: pointer-click 1.6s infinite ease-in-out;
}
@keyframes pointer-click {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-3px, -3px) scale(0.9); }
}
/* Step 3 forest movie continuous animation bindings */
.step-illustration-3 .film-mtn-scroll {
animation: scrollBack 12s linear infinite !important;
}
.step-illustration-3 .film-mid-scroll {
animation: scrollMid 6s linear infinite !important;
}
.step-illustration-3 .film-fore-scroll {
animation: scrollFore 3s linear infinite !important;
}
.step-illustration-3 .film-hero-bird {
animation: filmWingFlap 0.85s ease-in-out infinite !important;
animation-direction: alternate !important;
}
@keyframes scrollBack {
0% { transform: translateX(0); }
100% { transform: translateX(-160px); }
}
@keyframes scrollMid {
0% { transform: translateX(0); }
100% { transform: translateX(-160px); }
}
@keyframes scrollFore {
0% { transform: translateX(0); }
100% { transform: translateX(-160px); }
}
/* --- High Fidelity Micro-Animations & Identity additions --- */
/* Scroll progress bar glowing line at the top */
.scroll-progress-bar {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: linear-gradient(90deg, var(--accent), oklch(0.62 0.14 45), oklch(0.62 0.14 45));
z-index: 9999;
width: 0%;
transition: width 0.1s ease-out;
box-shadow: 0 0 8px var(--accent-glow);
}
.scroll-progress-bar::after {
content: '';
position: absolute;
right: -3px;
top: 50%;
width: 10px;
height: 7px;
border-radius: 0 70% 0 70%;
background: var(--accent-green);
box-shadow: 0 0 6px var(--accent-glow);
transform: translateY(-50%) rotate(24deg);
}
/* Navigation logo pop & spin */
.nav-logo-img {
animation: logo-entrance 1.2s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
transform-origin: center;
transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
will-change: transform, opacity;
}
.nav-logo-img:hover {
transform: scale(1.15) rotate(360deg);
}
@keyframes logo-entrance {
0% {
transform: scale(0) rotate(-180deg);
opacity: 0;
}
100% {
transform: scale(1) rotate(0deg);
opacity: 1;
}
}
/* Glowing reflection sweep on buttons */
.btn-primary, .btn-firefox, .btn-secondary {
position: relative;
overflow: hidden;
}
.btn-primary::after, .btn-firefox::after, .btn-secondary::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.25) 50%,
rgba(255, 255, 255, 0) 100%
);
transform: skewX(-25deg);
transition: none;
pointer-events: none;
}
.btn-primary:hover::after, .btn-firefox:hover::after, .btn-secondary:hover::after {
left: 100%;
transition: left 0.8s ease-in-out;
}
/* Step 2 mockup control panel styles */
.popup-mock-controls {
display: flex;
gap: 8px;
margin-top: 4px;
width: 100%;
}
.popup-mock-btn {
flex: 1;
text-align: center;
padding: 6px;
border-radius: 6px;
font-size: 0.62rem;
font-weight: 700;
color: white;
cursor: default;
opacity: 0.75;
}
.popup-mock-btn.play {
background: oklch(0.68 0.13 150);
color: var(--text-on-green);
}
.popup-mock-btn.pause {
background: oklch(0.55 0.15 25);
}
/* Phone and portrait-tablet widths: keep the full hero demo out of the page
flow. The demo modal mounts the same node in its own fixed layer. */
@media (max-width: 900px) {
.hero-grid > .hero-mockup-wrapper {
display: none !important;
}
}
@media (max-width: 900px) {
.hero-github-cta {
display: none;
}
.btn-demo-mobile {
display: inline-flex;
}
}
body.mobile-demo-open {
overflow: hidden;
}
.mobile-demo-modal[hidden] {
display: none;
}
.mobile-demo-modal {
position: fixed;
inset: 0;
z-index: 2400;
display: flex;
flex-direction: column;
padding: 0 !important;
}
.mobile-demo-backdrop {
position: absolute;
inset: 0;
background: oklch(0.10 0.01 135 / 0.25);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
}
.mobile-demo-panel {
position: relative;
z-index: 1;
width: 100% !important;
height: 100% !important;
max-height: none !important;
display: flex;
flex-direction: column;
overflow: hidden;
background: transparent !important;
backdrop-filter: none !important;
-webkit-backdrop-filter: none !important;
border: none !important;
border-radius: 0 !important;
box-shadow: none !important;
}
.mobile-demo-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.85rem 0.95rem;
border-bottom: none !important;
flex-shrink: 0;
}
.mobile-demo-header h2 {
margin: 0;
font-size: 0.95rem;
line-height: 1.2;
color: oklch(0.96 0.01 90);
}
.mobile-demo-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
padding: 0;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 10px;
background: oklch(0.27 0.035 130 / 0.72);
color: oklch(0.88 0.015 90);
cursor: pointer;
flex-shrink: 0;
}
.mobile-demo-stage {
position: relative;
flex: 1;
min-height: 0;
overflow: hidden !important;
padding: 1rem 0.75rem 1.25rem;
overscroll-behavior: contain;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
align-items: center !important;
}
/* Ensure the demo scene canvas is transparent inside the modal to let the glass backdrop blend */
.mobile-demo-stage .hero-demo-scene {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
/* Ensure the close button hover stays consistent in dark glass theme */
.mobile-demo-close:hover {
background: rgba(51, 65, 85, 0.85) !important;
}
/* Light Mode Frosted Glass overrides */
html.theme-light .mobile-demo-backdrop {
background: oklch(0.95 0.01 100 / 0.2) !important;
}
html.theme-light .mobile-demo-panel {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
html.theme-light .mobile-demo-header {
border-bottom: none !important;
}
html.theme-light .mobile-demo-header h2 {
color: var(--text) !important;
}
html.theme-light .mobile-demo-close {
background: rgba(255, 255, 255, 0.4) !important;
border-color: oklch(0.20 0.025 140 / 0.1) !important;
color: var(--text) !important;
}
html.theme-light .mobile-demo-close:hover {
background: rgba(255, 255, 255, 0.75) !important;
}
.mobile-demo-stage .hero-mockup-wrapper {
display: flex !important;
position: relative;
width: min(100%, 560px);
margin: 0 auto;
will-change: transform;
}
/* Mobile S / short screens */
@media (max-height: 600px) {
.mobile-demo-stage .hero-mockup-wrapper {
transform: scale(0.68) !important;
transform-origin: top center !important;
height: 380px !important;
}
}
/* Mobile M/L / medium screens */
@media (min-height: 601px) and (max-height: 740px) {
.mobile-demo-stage .hero-mockup-wrapper {
transform: scale(0.82) !important;
transform-origin: top center !important;
height: 460px !important;
}
}
/* Default / tall screens */
@media (min-height: 741px) {
.mobile-demo-stage .hero-mockup-wrapper {
transform: scale(1) !important;
transform-origin: top center !important;
height: 550px !important;
}
}
.mobile-demo-stage .hero-demo-scene,
.mobile-demo-stage .hero-demo-scene.popup-open {
position: relative;
width: 100%;
height: 100% !important;
max-width: none;
margin: 0 auto;
}
.mobile-demo-stage .demo-tab-stack {
display: block !important;
position: static !important;
height: auto !important;
}
.mobile-demo-stage .demo-tab-card {
display: block !important;
}
.mobile-demo-stage .demo-sync-chip {
display: inline-flex !important;
}
.mobile-demo-stage .demo-cursor {
display: block !important;
}
.mobile-demo-stage .demo-hint {
display: block !important;
position: absolute !important;
left: 0 !important;
right: 0 !important;
top: auto !important;
bottom: 12px !important;
margin: 0 auto !important;
padding-inline: 1rem;
max-width: 90%;
z-index: 10;
}
.mobile-demo-stage .hero-demo-scene .extension-mockup {
position: absolute;
bottom: 0 !important;
right: 0;
z-index: 15 !important;
width: min(320px, 66cqw);
transform: none !important;
transform-origin: top right !important;
transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s, visibility 0.45s;
}
.mobile-demo-stage .hero-demo-scene:not(.popup-open) .extension-mockup {
bottom: 0 !important;
transform: translate(2%, -3%) scale(0.5) !important;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
@media (max-width: 380px) {
.mobile-demo-modal {
padding: 0 !important;
}
.mobile-demo-stage {
padding-inline: 0.45rem !important;
}
}
/* Performance optimization for off-screen sections (below the fold) */
.lazy-section {
content-visibility: auto;
}
.use-cases-section {
contain-intrinsic-block-size: auto 600px;
}
.comparison-section {
contain-intrinsic-block-size: auto 800px;
}
#self-hosting {
contain-intrinsic-block-size: auto 400px;
}
#faq {
contain-intrinsic-block-size: auto 450px;
}
@media (max-width: 768px) {
.use-cases-section {
contain-intrinsic-block-size: auto 900px;
}
.comparison-section {
contain-intrinsic-block-size: auto 1100px;
}
#self-hosting {
contain-intrinsic-block-size: auto 550px;
}
#faq {
contain-intrinsic-block-size: auto 700px;
}
}
/* Final responsive hierarchy overrides. Keep these last: the landing page has
several component-level media blocks above that intentionally own geometry. */
@media (max-width: 768px) {
.container {
padding-inline: 1.15rem;
}
section {
padding-block: 4.25rem;
}
.hero-text h1,
.section-title,
#how-it-works h2,
#self-hosting h2,
#faq h2 {
font-size: clamp(2rem, 9vw, 2.65rem) !important;
text-wrap: balance;
}
.cta-group {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: stretch;
width: 100%;
}
.cta-group .btn {
width: 100%;
min-height: 48px;
justify-content: center;
}
}
@media (max-width: 430px) {
.cta-group {
grid-template-columns: 1fr;
}
}