feat: refresh landing page with glow animation, SVG icons, interop diagram
Restore personality from old Next.js landing: animated hero glow, playful "MySpace → (you)rSpace" copy, SVG feature cards with teal/indigo accents, shield graphic for EncryptID, interoperability ASCII diagram, sharper philosophy copy, ecosystem grid with r*.online domains, richer footer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
53c757e68e
commit
2f4258aa32
|
|
@ -17,10 +17,11 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
const ecosystemCards = modules
|
||||
.map(
|
||||
(m) => `
|
||||
<a href="/${escapeAttr(m.id)}" class="rl-card rl-card--center" style="text-decoration:none;color:inherit">
|
||||
<div class="rl-icon-box">${m.icon}</div>
|
||||
<h3>${escapeHtml(m.name)}</h3>
|
||||
<p>${escapeHtml(m.description)}</p>
|
||||
<a href="/${escapeAttr(m.id)}" class="eco-card" style="text-decoration:none;color:inherit">
|
||||
<div class="eco-card__icon">${m.icon}</div>
|
||||
<h3 class="eco-card__name">${escapeHtml(m.name)}</h3>
|
||||
${m.standaloneDomain ? `<span class="eco-card__domain">${escapeHtml(m.standaloneDomain)}</span>` : ""}
|
||||
<p class="eco-card__desc">${escapeHtml(m.description)}</p>
|
||||
</a>`,
|
||||
)
|
||||
.join("\n");
|
||||
|
|
@ -76,22 +77,31 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
</header>
|
||||
|
||||
<!-- Hero -->
|
||||
<div class="rl-hero">
|
||||
<div class="rl-hero hero-glow-wrap">
|
||||
<div class="hero-glow"></div>
|
||||
<span class="rl-tagline">Community Platform</span>
|
||||
<h1 class="rl-heading main-wordmark">(you)r<span class="main-wordmark__accent">Space</span></h1>
|
||||
<p class="rl-subtitle">Remember back when the internet was cool?</p>
|
||||
<p class="rl-subtitle">
|
||||
Remember back when the internet was <span class="accent-cool">cool</span>?
|
||||
</p>
|
||||
<p class="rl-subtext" style="font-style:italic;opacity:0.85;margin-bottom:0.75rem">
|
||||
We may not have <em>My</em>Space anymore, but we have <strong>(you)rSpace</strong>.
|
||||
</p>
|
||||
<p class="rl-subtext">
|
||||
A collaborative, local-first platform with ${modules.length}+ interoperable tools.
|
||||
Own your data, run your community, connect your world — no landlords required.
|
||||
Build digital spaces to collaborate on improving your physical world.
|
||||
Local-first, zero-knowledge privacy, outside the walls of big tech.
|
||||
</p>
|
||||
<div class="rl-cta-row">
|
||||
<a href="${demoUrl}" class="rl-cta-primary" id="ml-primary">Try the Demo</a>
|
||||
<a href="${demoUrl}" class="rl-cta-primary" id="ml-primary">Start (you)rSpace</a>
|
||||
<a href="/create-space" class="rl-cta-secondary">Create a Space</a>
|
||||
</div>
|
||||
<div class="main-badges">
|
||||
<span class="rl-badge">Local-First</span>
|
||||
<span class="badge-sep" aria-hidden="true">★</span>
|
||||
<span class="rl-badge">Self-Hosted</span>
|
||||
<span class="badge-sep" aria-hidden="true">★</span>
|
||||
<span class="rl-badge">Open Source</span>
|
||||
<span class="badge-sep" aria-hidden="true">★</span>
|
||||
<span class="rl-badge">Offline-Ready</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -104,33 +114,45 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
Each tool works on its own, and they all work together.
|
||||
</p>
|
||||
<div class="rl-grid-3">
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">💰</div>
|
||||
<div class="feat-card feat-card--teal">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
|
||||
</div>
|
||||
<h3>Community Funds</h3>
|
||||
<p>Budget rivers, revenue splits, and enoughness thresholds. Transparent finances with quadratic funding built in.</p>
|
||||
</div>
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">💬</div>
|
||||
<div class="feat-card feat-card--indigo">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
|
||||
</div>
|
||||
<h3>Messaging & Forum</h3>
|
||||
<p>Real-time chat, threaded discussions, and async forums. All synced across devices with CRDT magic.</p>
|
||||
</div>
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">📁</div>
|
||||
<div class="feat-card feat-card--teal">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
|
||||
</div>
|
||||
<h3>Files & Media</h3>
|
||||
<p>Upload, organize, and share with memory cards. Public links, folder trees, and metadata that travels with content.</p>
|
||||
</div>
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">🔐</div>
|
||||
<div class="feat-card feat-card--indigo">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
</div>
|
||||
<h3>Passkey Identity</h3>
|
||||
<p>One passwordless login for the entire ecosystem. EncryptID uses WebAuthn — no passwords to leak, no accounts to hack.</p>
|
||||
</div>
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">📊</div>
|
||||
<div class="feat-card feat-card--teal">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></svg>
|
||||
</div>
|
||||
<h3>Dashboards & Data</h3>
|
||||
<p>Community analytics, voting results, spatial canvases. See everything at a glance and drill into what matters.</p>
|
||||
</div>
|
||||
<div class="rl-card rl-card--center">
|
||||
<div class="rl-icon-box">🛡</div>
|
||||
<div class="feat-card feat-card--indigo">
|
||||
<div class="feat-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
</div>
|
||||
<h3>Privacy by Design</h3>
|
||||
<p>Your data lives on your device first. End-to-end encrypted sync, per-document keys, zero-knowledge architecture.</p>
|
||||
</div>
|
||||
|
|
@ -145,23 +167,31 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
<div>
|
||||
<span class="rl-tagline">EncryptID</span>
|
||||
<h2 class="rl-heading">One Passkey for Everything</h2>
|
||||
<p class="rl-subtext" style="margin-bottom:0.5rem;font-weight:500;color:var(--rs-text-primary)">
|
||||
Secure by default, not by opt-in.
|
||||
</p>
|
||||
<p class="rl-subtext" style="margin-bottom:1.5rem">
|
||||
Sign in once with your fingerprint or device PIN. Your passkey works
|
||||
across every rApp — no passwords, no email verification loops,
|
||||
no third-party auth providers.
|
||||
across every rApp — no passwords, no email loops,
|
||||
no third-party auth providers watching over your shoulder.
|
||||
</p>
|
||||
<ul class="rl-check-list">
|
||||
<li><strong>WebAuthn passkeys</strong> — phishing-resistant by default</li>
|
||||
<li><strong>WebAuthn passkeys</strong> — phishing-resistant, device-bound credentials</li>
|
||||
<li><strong>Guardian recovery</strong> — 2-of-3 trusted contacts restore access</li>
|
||||
<li><strong>Device linking</strong> — QR scan adds your phone or tablet</li>
|
||||
<li><strong>One RP ID</strong> — shared across all r*.online domains</li>
|
||||
<li><strong>Device linking</strong> — scan a QR to add your phone or tablet</li>
|
||||
<li><strong>One RP ID</strong> — works across all r*.online domains</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;justify-content:center">
|
||||
<div class="rl-card" style="max-width:320px;text-align:center">
|
||||
<div class="rl-icon-box" style="margin:0 auto 1rem;font-size:2rem">🔒</div>
|
||||
<h3 style="margin-bottom:0.5rem">Passwordless Login</h3>
|
||||
<p>Touch your fingerprint sensor, tap your security key, or use your device PIN. That’s it.</p>
|
||||
<div class="encryptid-visual">
|
||||
<svg class="encryptid-shield" viewBox="0 0 120 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M60 8L10 30v40c0 32 22 55 50 62 28-7 50-30 50-62V30L60 8z" stroke="currentColor" stroke-width="3" fill="rgba(20,184,166,0.08)"/>
|
||||
<path d="M60 40a14 14 0 1 0 0 28 14 14 0 0 0 0-28z" stroke="currentColor" stroke-width="2.5"/>
|
||||
<circle cx="60" cy="54" r="4" fill="currentColor"/>
|
||||
<path d="M48 80h24v8a12 12 0 0 1-24 0v-8z" stroke="currentColor" stroke-width="2.5" fill="rgba(20,184,166,0.12)"/>
|
||||
<line x1="60" y1="80" x2="60" y2="92" stroke="currentColor" stroke-width="2"/>
|
||||
</svg>
|
||||
<p class="encryptid-visual__label">Touch. Tap. Done.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -193,17 +223,52 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
<p>Only changed bytes travel over the wire. Reconnect after days offline and catch up in seconds.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="offline-explain">
|
||||
Under the hood: <strong>Automerge CRDTs</strong> model every document as a mergeable data structure.
|
||||
<strong>IndexedDB</strong> persists the full state locally so you never lose work.
|
||||
A <strong>Service Worker</strong> caches the app shell for instant loads — even without a network connection.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Interoperable by Design -->
|
||||
<section class="rl-section rl-section--alt">
|
||||
<div class="rl-container" style="max-width:820px;text-align:center">
|
||||
<h2 class="rl-heading">Interoperable by Design</h2>
|
||||
<p class="rl-subtext">
|
||||
Every rApp reads and writes to the same sync layer.
|
||||
No import/export rituals — data flows between tools automatically.
|
||||
</p>
|
||||
<div class="interop-diagram">
|
||||
<pre class="interop-pre"><code> rDocs rCal rTasks rMaps rWallet ...
|
||||
| | | | |
|
||||
v v v v v
|
||||
+--------------------------------------+
|
||||
| Automerge Sync Layer |
|
||||
| (encrypted, per-document keys) |
|
||||
+--------------------------------------+
|
||||
| | | | |
|
||||
v v v v v
|
||||
Your Your Your Your Your
|
||||
Device Phone Laptop Server Backup</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Philosophy -->
|
||||
<section class="rl-section rl-section--alt">
|
||||
<section class="rl-section">
|
||||
<div class="rl-container" style="max-width:720px;text-align:center">
|
||||
<h2 class="rl-heading">The Internet as It Was Always Meant to Be</h2>
|
||||
<p class="rl-subtext">
|
||||
<p class="rl-subtext" style="font-size:1.2rem;line-height:1.7">
|
||||
No algorithms deciding what you see. No ads. No data harvesting.
|
||||
Just tools that work for you, run by you, owned by you.
|
||||
rSpace is infrastructure for communities who refuse to rent their digital commons.
|
||||
</p>
|
||||
<p class="rl-subtext">
|
||||
rSpace is infrastructure for communities who refuse to rent their digital commons
|
||||
from landlords who read the mail, count the footsteps, and sell the maps.
|
||||
</p>
|
||||
<p class="philosophy-punch">
|
||||
Your space. Your community. Your rules.
|
||||
</p>
|
||||
<div class="rl-cta-row">
|
||||
<a href="/about" class="rl-cta-secondary">Learn More</a>
|
||||
|
|
@ -212,7 +277,7 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
</section>
|
||||
|
||||
<!-- Ecosystem Grid (dynamic) -->
|
||||
<section class="rl-section">
|
||||
<section class="rl-section rl-section--alt">
|
||||
<div class="rl-container">
|
||||
<h2 class="rl-heading" style="text-align:center">${modules.length} rApps and Growing</h2>
|
||||
<p class="rl-subtext" style="text-align:center">
|
||||
|
|
@ -227,14 +292,25 @@ export function renderMainLanding(modules: ModuleInfo[]): string {
|
|||
<!-- Footer -->
|
||||
<footer class="main-footer">
|
||||
<div class="rl-container" style="text-align:center">
|
||||
<p style="color:#64748b;font-size:0.85rem;margin-bottom:0.5rem">
|
||||
<div class="footer-quicklinks">
|
||||
<a href="/rcal">rCal</a>
|
||||
<a href="/rtasks">rTasks</a>
|
||||
<a href="/rdocs">rDocs</a>
|
||||
<a href="/rmaps">rMaps</a>
|
||||
<a href="/rwallet">rWallet</a>
|
||||
<a href="/rphotos">rPhotos</a>
|
||||
<a href="/rflows">rFlows</a>
|
||||
<a href="/rchoices">rChoices</a>
|
||||
</div>
|
||||
<p class="footer-tagline">Local-first · Zero-knowledge · Community-owned</p>
|
||||
<div class="footer-links">
|
||||
<a href="/about">About</a>
|
||||
<a href="/create-space">Create a Space</a>
|
||||
<a href="https://auth.rspace.online">EncryptID</a>
|
||||
</div>
|
||||
<p class="footer-tech">
|
||||
Built with Bun, Hono, Automerge & WebAuthn
|
||||
</p>
|
||||
<div style="display:flex;gap:1.5rem;justify-content:center;flex-wrap:wrap">
|
||||
<a href="/about" style="color:#94a3b8;font-size:0.8rem;text-decoration:none">About</a>
|
||||
<a href="/create-space" style="color:#94a3b8;font-size:0.8rem;text-decoration:none">Create a Space</a>
|
||||
<a href="https://auth.rspace.online" style="color:#94a3b8;font-size:0.8rem;text-decoration:none">EncryptID</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
|
@ -432,7 +508,9 @@ const SPACE_DASHBOARD_CSS = `
|
|||
`;
|
||||
|
||||
const MAIN_LANDING_CSS = `
|
||||
/* Main landing page extras (on top of rl-* utilities) */
|
||||
/* ── Main landing page extras (on top of rl-* utilities) ── */
|
||||
|
||||
/* Background + diagonal stripe overlay */
|
||||
body {
|
||||
background: linear-gradient(
|
||||
170deg,
|
||||
|
|
@ -445,8 +523,57 @@ body {
|
|||
);
|
||||
background-attachment: fixed;
|
||||
}
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed; inset: 0;
|
||||
background: repeating-linear-gradient(
|
||||
-45deg,
|
||||
transparent,
|
||||
transparent 60px,
|
||||
rgba(20,184,166,0.015) 60px,
|
||||
rgba(20,184,166,0.015) 61px
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
[data-theme="light"] body {
|
||||
background: linear-gradient(170deg, #f8fafc 0%, #f1f5f9 50%, #e2e8f0 100%);
|
||||
}
|
||||
[data-theme="light"] body::before {
|
||||
background: repeating-linear-gradient(
|
||||
-45deg,
|
||||
transparent,
|
||||
transparent 60px,
|
||||
rgba(20,184,166,0.03) 60px,
|
||||
rgba(20,184,166,0.03) 61px
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Hero ── */
|
||||
.hero-glow-wrap { position: relative; overflow: hidden; }
|
||||
.hero-glow {
|
||||
position: absolute;
|
||||
top: 50%; left: 50%;
|
||||
width: 600px; height: 600px;
|
||||
transform: translate(-50%, -60%);
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(20,184,166,0.15) 0%, transparent 70%);
|
||||
animation: hero-pulse 4s ease-in-out infinite;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
[data-theme="light"] .hero-glow {
|
||||
background: radial-gradient(circle, rgba(20,184,166,0.1) 0%, transparent 70%);
|
||||
}
|
||||
@keyframes hero-pulse {
|
||||
0%, 100% { opacity: 0.6; transform: translate(-50%, -60%) scale(1); }
|
||||
50% { opacity: 1; transform: translate(-50%, -60%) scale(1.08); }
|
||||
}
|
||||
.rl-hero > * { position: relative; z-index: 1; }
|
||||
|
||||
.main-wordmark {
|
||||
font-size: 3.5rem;
|
||||
text-shadow: 0 0 40px rgba(20,184,166,0.2);
|
||||
}
|
||||
@media (min-width: 640px) { .main-wordmark { font-size: 4.5rem; } }
|
||||
.main-wordmark__accent {
|
||||
|
|
@ -454,12 +581,218 @@ body {
|
|||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.accent-cool {
|
||||
color: var(--rs-accent);
|
||||
font-weight: 700;
|
||||
-webkit-text-fill-color: var(--rs-accent);
|
||||
}
|
||||
|
||||
/* Badge bar with star separators */
|
||||
.main-badges {
|
||||
display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.main-badges .rl-badge {
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.badge-sep {
|
||||
color: var(--rs-accent);
|
||||
font-size: 0.5rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* ── Feature Cards (SVG icons, border glow) ── */
|
||||
.feat-card {
|
||||
background: var(--rs-card-bg);
|
||||
border: 2px solid var(--rs-card-border);
|
||||
border-radius: 1rem;
|
||||
padding: 1.75rem;
|
||||
text-align: center;
|
||||
transition: border-color 0.25s, box-shadow 0.25s, transform 0.2s;
|
||||
}
|
||||
.feat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.feat-card--teal:hover {
|
||||
border-color: rgba(20,184,166,0.5);
|
||||
box-shadow: 0 0 20px rgba(20,184,166,0.12);
|
||||
}
|
||||
.feat-card--indigo:hover {
|
||||
border-color: rgba(99,102,241,0.5);
|
||||
box-shadow: 0 0 20px rgba(99,102,241,0.12);
|
||||
}
|
||||
.feat-card__icon {
|
||||
width: 3rem; height: 3rem; border-radius: 0.75rem;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
margin: 0 auto 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.feat-card--teal .feat-card__icon {
|
||||
background: rgba(20,184,166,0.12); color: #14b8a6;
|
||||
}
|
||||
.feat-card--indigo .feat-card__icon {
|
||||
background: rgba(99,102,241,0.12); color: #6366f1;
|
||||
}
|
||||
.feat-card h3 {
|
||||
font-size: 0.95rem; font-weight: 600; color: var(--rs-text-primary); margin-bottom: 0.5rem;
|
||||
}
|
||||
.feat-card p {
|
||||
font-size: 0.875rem; color: var(--rs-text-secondary); line-height: 1.6;
|
||||
}
|
||||
|
||||
/* ── EncryptID Visual ── */
|
||||
.encryptid-visual {
|
||||
text-align: center;
|
||||
}
|
||||
.encryptid-shield {
|
||||
width: 140px; height: 160px;
|
||||
color: var(--rs-accent);
|
||||
filter: drop-shadow(0 0 20px rgba(20,184,166,0.2));
|
||||
}
|
||||
.encryptid-visual__label {
|
||||
font-size: 0.9rem; font-weight: 600;
|
||||
color: var(--rs-text-secondary);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
/* ── Offline-First Explainer ── */
|
||||
.offline-explain {
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
color: var(--rs-text-muted);
|
||||
line-height: 1.65;
|
||||
max-width: 640px;
|
||||
margin: 2rem auto 0;
|
||||
border-top: 1px solid var(--rs-border-subtle);
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
.offline-explain strong {
|
||||
color: var(--rs-text-secondary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ── Interop Diagram ── */
|
||||
.interop-diagram {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
.interop-pre {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
font-family: "SF Mono", "Fira Code", "Cascadia Code", monospace;
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.6;
|
||||
color: var(--rs-text-secondary);
|
||||
background: var(--rs-card-bg);
|
||||
border: 1px solid var(--rs-card-border);
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.5rem 2rem;
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.15);
|
||||
}
|
||||
[data-theme="light"] .interop-pre {
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
/* ── Philosophy Punch ── */
|
||||
.philosophy-punch {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
background: var(--rs-gradient-brand);
|
||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
margin: 1.5rem 0 0;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
/* ── Ecosystem Cards ── */
|
||||
.eco-card {
|
||||
background: var(--rs-card-bg);
|
||||
border: 2px solid var(--rs-card-border);
|
||||
border-radius: 1rem;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
transition: border-color 0.25s, box-shadow 0.25s, transform 0.2s;
|
||||
display: flex; flex-direction: column; align-items: center;
|
||||
}
|
||||
.eco-card:hover {
|
||||
border-color: rgba(20,184,166,0.4);
|
||||
box-shadow: 0 0 16px rgba(20,184,166,0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.eco-card__icon {
|
||||
font-size: 1.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.eco-card__name {
|
||||
font-size: 0.9rem; font-weight: 600;
|
||||
color: var(--rs-text-primary);
|
||||
margin: 0 0 0.15rem;
|
||||
}
|
||||
.eco-card__domain {
|
||||
font-size: 0.65rem; font-weight: 600;
|
||||
color: var(--rs-accent);
|
||||
opacity: 0.75;
|
||||
letter-spacing: 0.02em;
|
||||
margin-bottom: 0.4rem;
|
||||
display: block;
|
||||
}
|
||||
.eco-card__desc {
|
||||
font-size: 0.78rem; color: var(--rs-text-secondary);
|
||||
line-height: 1.5; margin: 0;
|
||||
}
|
||||
|
||||
/* ── Footer ── */
|
||||
.main-footer {
|
||||
border-top: 1px solid var(--rs-border-subtle);
|
||||
padding: 2.5rem 1.5rem;
|
||||
padding: 2.5rem 1.5rem 2rem;
|
||||
}
|
||||
.footer-quicklinks {
|
||||
display: flex; gap: 1.25rem; justify-content: center; flex-wrap: wrap;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.footer-quicklinks a {
|
||||
font-size: 0.75rem; font-weight: 600;
|
||||
color: var(--rs-text-muted);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.footer-quicklinks a:hover { color: var(--rs-accent); }
|
||||
.footer-tagline {
|
||||
font-size: 0.8rem; font-weight: 700;
|
||||
color: var(--rs-accent);
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
margin: 0 0 1rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.footer-links {
|
||||
display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.footer-links a {
|
||||
color: #94a3b8; font-size: 0.8rem; text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.footer-links a:hover { color: var(--rs-text-primary); }
|
||||
.footer-tech {
|
||||
color: #64748b; font-size: 0.75rem; margin: 0;
|
||||
}
|
||||
|
||||
/* ── Retro Shadow Utility ── */
|
||||
.retro-shadow {
|
||||
box-shadow: 2px 2px 0 var(--rs-card-border);
|
||||
}
|
||||
|
||||
/* ── Responsive ── */
|
||||
@media (max-width: 480px) {
|
||||
.main-wordmark { font-size: 2.75rem; }
|
||||
.hero-glow { width: 350px; height: 350px; }
|
||||
.interop-pre { font-size: 0.65rem; padding: 1rem; }
|
||||
.philosophy-punch { font-size: 1.1rem; }
|
||||
.footer-quicklinks { gap: 0.75rem; }
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
Loading…
Reference in New Issue