mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
refactor(landing): replace star ratings with flowing text summary
Removes all star ratings from the features page. Replaces the card grid summary with a flowing paragraph of clickable keyword links that scroll to each feature section. Both simple and tech views updated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca3087446b
commit
e97d7d10e2
1 changed files with 72 additions and 224 deletions
|
|
@ -36,7 +36,6 @@ const simpleUsps = [
|
|||
'Aufgaben, Kalender, Kontakte, Notizen, Finanzen, Fitness, Musik, KI-Assistent und vieles mehr — alles in einer einzigen App. Ein Login, fertig.',
|
||||
icon: icons.unified,
|
||||
gradient: 'from-blue-500 to-cyan-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Nie wieder zwischen 10 verschiedenen Apps wechseln',
|
||||
'Alles teilt sich dieselben Daten — keine doppelte Eingabe',
|
||||
|
|
@ -52,7 +51,6 @@ const simpleUsps = [
|
|||
'Mana speichert alles direkt auf deinem Gerät. Die App reagiert sofort, auch im Flugzeug oder bei schlechtem Empfang. Sobald du wieder online bist, wird automatisch synchronisiert.',
|
||||
icon: icons.localFirst,
|
||||
gradient: 'from-emerald-500 to-teal-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Keine Ladezeiten — alles reagiert sofort',
|
||||
'Funktioniert komplett ohne Internetverbindung',
|
||||
|
|
@ -68,7 +66,6 @@ const simpleUsps = [
|
|||
'Deine persönlichen Inhalte werden verschlüsselt, bevor sie gespeichert werden. Optional kannst du den Zero-Knowledge-Modus aktivieren — dann kann selbst unser Team nichts lesen.',
|
||||
icon: icons.encryption,
|
||||
gradient: 'from-violet-500 to-purple-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Alle sensiblen Daten werden automatisch verschlüsselt',
|
||||
'Zero-Knowledge-Modus: Nur du hast den Schlüssel',
|
||||
|
|
@ -84,7 +81,6 @@ const simpleUsps = [
|
|||
'Mana hat einen eingebauten KI-Assistenten und Spracherkennung, die komplett auf deinem Gerät laufen. Deine Gespräche und Notizen verlassen nie deinen Computer.',
|
||||
icon: icons.localAi,
|
||||
gradient: 'from-pink-500 to-rose-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'KI-Chat direkt im Browser — ohne Server',
|
||||
'Sprachnotizen werden lokal in Text umgewandelt',
|
||||
|
|
@ -100,7 +96,6 @@ const simpleUsps = [
|
|||
'1 Mana = 1 Cent. Deine Credits laden sich jeden Tag automatisch auf und verfallen nie. Keine versteckten Kosten, keine 10 verschiedenen Abos.',
|
||||
icon: icons.credits,
|
||||
gradient: 'from-amber-500 to-orange-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Credits regenerieren sich jeden Tag automatisch',
|
||||
'Einmal kaufen, kein Abo nötig',
|
||||
|
|
@ -116,7 +111,6 @@ const simpleUsps = [
|
|||
'Ändere etwas auf dem Laptop und es erscheint sofort auf dem Handy. Mana hält alle deine Geräte automatisch auf dem gleichen Stand.',
|
||||
icon: icons.sync,
|
||||
gradient: 'from-cyan-500 to-blue-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Änderungen erscheinen in Echtzeit auf allen Geräten',
|
||||
'Nur das Nötigste wird übertragen — spart Datenvolumen',
|
||||
|
|
@ -132,7 +126,6 @@ const simpleUsps = [
|
|||
'Mana trackt dich nicht, verkauft keine Daten und zeigt keine Werbung. Unsere Server stehen in Deutschland, und wir erfüllen die strengsten Datenschutz-Standards.',
|
||||
icon: icons.privacy,
|
||||
gradient: 'from-green-500 to-emerald-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Keine Tracking-Cookies, keine Werbung, nie',
|
||||
'Server in Deutschland, DSGVO-konform',
|
||||
|
|
@ -148,7 +141,6 @@ const simpleUsps = [
|
|||
'Wähle aus über 40 Modulen genau die aus, die zu deinem Leben passen. Von Aufgaben über Fitness bis Musik — du bestimmst, was auf deinem Dashboard erscheint.',
|
||||
icon: icons.modules,
|
||||
gradient: 'from-indigo-500 to-blue-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Produktivität, Kreativität, Gesundheit, Finanzen & mehr',
|
||||
'Jedes Modul funktioniert eigenständig und zusammen',
|
||||
|
|
@ -164,7 +156,6 @@ const simpleUsps = [
|
|||
'Die wichtigsten Module wie Aufgaben, Kalender und Kontakte sind kostenlos nutzbar. Neue Features probierst du als Early Adopter zuerst aus.',
|
||||
icon: icons.tiers,
|
||||
gradient: 'from-yellow-500 to-amber-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'Kernmodule dauerhaft kostenlos',
|
||||
'Neue Features früher testen als Early Adopter',
|
||||
|
|
@ -180,7 +171,6 @@ const simpleUsps = [
|
|||
'Mana spricht Deutsch, Englisch und Italienisch — weitere Sprachen folgen. Die App erkennt deine Sprache automatisch.',
|
||||
icon: icons.i18n,
|
||||
gradient: 'from-teal-500 to-cyan-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'Automatische Spracherkennung',
|
||||
'Aktuell: Deutsch, Englisch, Italienisch',
|
||||
|
|
@ -196,7 +186,6 @@ const simpleUsps = [
|
|||
'Verknüpfe einen Kontakt mit einer Aufgabe, erstelle aus einer Sprachnotiz automatisch To-Dos, oder plane ein Event direkt aus deinem Rezeptbuch. Alles greift ineinander.',
|
||||
icon: icons.crossmodule,
|
||||
gradient: 'from-rose-500 to-pink-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Per Drag & Drop Dinge zwischen Modulen verbinden',
|
||||
'Dashboard-Widgets aus allen Bereichen kombinieren',
|
||||
|
|
@ -212,7 +201,6 @@ const simpleUsps = [
|
|||
'Unser Entwicklungs-Tagebuch ist öffentlich. Du siehst jede Änderung, jeden Plan, und kannst aktiv mitgestalten, welche Features als nächstes kommen.',
|
||||
icon: icons.opensource,
|
||||
gradient: 'from-gray-400 to-slate-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'Öffentliches Entwicklungstagebuch (Devlog)',
|
||||
'Roadmap zeigt, was als nächstes kommt',
|
||||
|
|
@ -232,7 +220,6 @@ const techUsps = [
|
|||
'40+ Module unter einer SvelteKit 2 + Svelte 5 (Runes) App. Ein Dexie.js IndexedDB, ein EdDSA JWT Auth-Token, Deployment auf Cloudflare Pages. Turborepo-Monorepo mit pnpm Workspaces.',
|
||||
icon: icons.unified,
|
||||
gradient: 'from-blue-500 to-cyan-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'SvelteKit 2, Svelte 5 Runes, TailwindCSS, Vite',
|
||||
'120+ Dexie Collections in einer IndexedDB ("mana")',
|
||||
|
|
@ -248,7 +235,6 @@ const techUsps = [
|
|||
'Alle Reads/Writes gehen direkt an IndexedDB via Dexie.js. Dexie-Hooks stampen userId und __fieldTimestamps, tracken _pendingChanges mit appId-Tag. Debounced Sync (1s) POST an mana-sync.',
|
||||
icon: icons.localFirst,
|
||||
gradient: 'from-emerald-500 to-teal-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Dexie.js liveQuery Hooks fur reaktive UI via $derived',
|
||||
'Field-Level Last-Write-Wins Merge in mana-sync (Go)',
|
||||
|
|
@ -264,7 +250,6 @@ const techUsps = [
|
|||
'27 sensitive Tabellen werden mit AES-GCM-256 vor dem IndexedDB-Write verschlüsselt. Master Key aus mana-auth ist KEK-wrapped (MANA_AUTH_KEK env). Explizites encryptRecord()/decryptRecords() per Store — kein Auto-Hook (Web Crypto ist async).',
|
||||
icon: icons.encryption,
|
||||
gradient: 'from-violet-500 to-purple-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Web Crypto API nativ — keine Drittanbieter-Crypto-Libs',
|
||||
'Zero-Knowledge: Recovery Code only, Server sieht nichts',
|
||||
|
|
@ -280,7 +265,6 @@ const techUsps = [
|
|||
'@mana/local-llm: Gemma 4 E2B via Transformers.js v4, WebGPU-beschleunigt. @mana/local-stt: Whisper-basierte Spracherkennung. Kein Server-Roundtrip, CSP-safe, volle In-Browser Inferenz.',
|
||||
icon: icons.localAi,
|
||||
gradient: 'from-pink-500 to-rose-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Transformers.js v4 mit WebGPU Compute Shaders',
|
||||
'@mana/local-llm: Gemma 4 E2B, ~2B Parameter im Browser',
|
||||
|
|
@ -296,7 +280,6 @@ const techUsps = [
|
|||
'Credit-basiertes Billing via mana-credits Service. Tägliche Regeneration bis zum Speicherlimit, One-Time Mana-Tränke, transparente Cost-Breakdown. JWT tier Claim gated den Zugang.',
|
||||
icon: icons.credits,
|
||||
gradient: 'from-amber-500 to-orange-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'mana-credits Service mit REST API',
|
||||
'Tier-Gating via JWT tier Claim + AuthGate Client-Side',
|
||||
|
|
@ -312,7 +295,6 @@ const techUsps = [
|
|||
'Sync-Engine in Go (Port 3050). Debounced 1s, gruppiert _pendingChanges nach appId, POST an mana-sync. Field-Level LWW Merge in PostgreSQL (mana_sync Schema) mit Row-Level Security. SSE Push an verbundene Clients.',
|
||||
icon: icons.sync,
|
||||
gradient: 'from-cyan-500 to-blue-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'Go-Backend auf Port 3050, PostgreSQL mana_sync Schema',
|
||||
'Field-Level LWW: Nur geänderte Felder mergen',
|
||||
|
|
@ -328,7 +310,6 @@ const techUsps = [
|
|||
'Eigene Infrastruktur auf Mac Mini (Production) via Cloudflare Tunnel. GPU-Server (RTX 3090, LAN) für STT/TTS/Image-Gen. Umami statt Google Analytics. Keine Cookies, keine Ad-Networks.',
|
||||
icon: icons.privacy,
|
||||
gradient: 'from-green-500 to-emerald-500',
|
||||
rating: 5,
|
||||
details: [
|
||||
'Mac Mini Production via ssh mana-server (Cloudflare Tunnel)',
|
||||
'GPU-Server: Windows, RTX 3090, 192.168.178.11 (LAN)',
|
||||
|
|
@ -344,7 +325,6 @@ const techUsps = [
|
|||
'Jedes Modul unter apps/web/src/lib/modules/{name}/. Drei Dateien: collections.ts (Dexie Tables + Seeds), queries.ts (liveQuery Hooks + Type Converter), stores/*.svelte.ts (Mutations mit explizitem encrypt/decrypt).',
|
||||
icon: icons.modules,
|
||||
gradient: 'from-indigo-500 to-blue-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'collections.ts: Dexie Table Refs, Schema, Seed Data',
|
||||
'queries.ts: useLiveQueryWithDefault(), decryptRecords(), toEntity()',
|
||||
|
|
@ -360,7 +340,6 @@ const techUsps = [
|
|||
'5-stufiges Tier-System. requiredTier in MANA_APPS Registry (shared-branding), JWT tier Claim, AuthGate Client-Side Enforcement. Admin API: PUT /api/v1/admin/users/:id/tier.',
|
||||
icon: icons.tiers,
|
||||
gradient: 'from-yellow-500 to-amber-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'MANA_APPS Registry mit requiredTier pro Modul',
|
||||
'JWT Claim: { sub, email, role, sid, tier, exp, iss, aud }',
|
||||
|
|
@ -376,7 +355,6 @@ const techUsps = [
|
|||
'Landing: Astro i18n mit URL-Prefix Routing (/de/, /en/, /it/). Web App: SvelteKit i18n mit Translation Keys. Content Collections unterstützen Übersetzungen per Locale-Ordner.',
|
||||
icon: icons.i18n,
|
||||
gradient: 'from-teal-500 to-cyan-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'Astro i18n Config: defaultLang "de", 5 Sprachen',
|
||||
'getLangFromUrl() + useTranslations(lang) Pattern',
|
||||
|
|
@ -392,7 +370,6 @@ const techUsps = [
|
|||
'App Registry (apps.ts) deklariert entityCapabilities, viewConfigs und DnD-Targets pro Modul. Shared Dexie DB erlaubt Cross-Referenzen über gemeinsame UUIDs. Dashboard Widget-Grid aus allen Modulen.',
|
||||
icon: icons.crossmodule,
|
||||
gradient: 'from-rose-500 to-pink-500',
|
||||
rating: 4,
|
||||
details: [
|
||||
'App Registry mit Entity Capabilities + View Configs',
|
||||
'Drag & Drop: entityCapabilities.dragTargets pro Modul',
|
||||
|
|
@ -408,7 +385,6 @@ const techUsps = [
|
|||
'Devlog als Astro Content Collection mit Frontmatter (date, category, commits, readTime). Blueprints dokumentieren Architektur-Entscheidungen. CI: GitHub Actions, CD: Mac Mini self-hosted Runner.',
|
||||
icon: icons.opensource,
|
||||
gradient: 'from-gray-400 to-slate-500',
|
||||
rating: 3,
|
||||
details: [
|
||||
'Devlog: Astro Content Collection + Frontmatter Schema',
|
||||
'CI: GitHub Actions (svelte-check, build, test)',
|
||||
|
|
@ -417,49 +393,6 @@ const techUsps = [
|
|||
],
|
||||
},
|
||||
];
|
||||
|
||||
// Rating breakdown for simple view
|
||||
const simpleRatingGroups = [
|
||||
{
|
||||
stars: 5,
|
||||
label: 'Unser Herzstück',
|
||||
color: 'text-emerald-400',
|
||||
items: simpleUsps.filter((u) => u.rating === 5),
|
||||
},
|
||||
{
|
||||
stars: 4,
|
||||
label: 'Richtig stark',
|
||||
color: 'text-blue-400',
|
||||
items: simpleUsps.filter((u) => u.rating === 4),
|
||||
},
|
||||
{
|
||||
stars: 3,
|
||||
label: 'Solides Extra',
|
||||
color: 'text-amber-400',
|
||||
items: simpleUsps.filter((u) => u.rating === 3),
|
||||
},
|
||||
];
|
||||
|
||||
const techRatingGroups = [
|
||||
{
|
||||
stars: 5,
|
||||
label: 'Core Architecture',
|
||||
color: 'text-emerald-400',
|
||||
items: techUsps.filter((u) => u.rating === 5),
|
||||
},
|
||||
{
|
||||
stars: 4,
|
||||
label: 'Key Systems',
|
||||
color: 'text-blue-400',
|
||||
items: techUsps.filter((u) => u.rating === 4),
|
||||
},
|
||||
{
|
||||
stars: 3,
|
||||
label: 'Supporting',
|
||||
color: 'text-amber-400',
|
||||
items: techUsps.filter((u) => u.rating === 3),
|
||||
},
|
||||
];
|
||||
---
|
||||
|
||||
<Layout title="Mana Features - Was Mana besonders macht">
|
||||
|
|
@ -507,34 +440,26 @@ const techRatingGroups = [
|
|||
<div id="view-simple">
|
||||
<section class="summary-section">
|
||||
<div class="summary-container">
|
||||
<h2 class="summary-title">Auf einen Blick</h2>
|
||||
<div class="summary-grid">
|
||||
{
|
||||
simpleRatingGroups.map((group) => (
|
||||
<div class="summary-card">
|
||||
<div class="summary-stars">
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<svg
|
||||
class={`summary-star ${i < group.stars ? group.color : 'text-gray-600'}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
<span class={`summary-label ${group.color}`}>{group.label}</span>
|
||||
<div class="summary-items">
|
||||
{group.items.map((item) => (
|
||||
<a href={`#s-${item.id}`} class="summary-tag">
|
||||
{item.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<p class="summary-flow">
|
||||
Mana vereint <a href="#s-unified" class="flow-link">alles in einer App</a> — <a
|
||||
href="#s-local-first"
|
||||
class="flow-link">blitzschnell und offline nutzbar</a
|
||||
>, mit <a href="#s-encryption" class="flow-link">starker Verschlüsselung</a> und <a
|
||||
href="#s-local-ai"
|
||||
class="flow-link">KI direkt auf deinem Gerät</a
|
||||
>. Du zahlst nur was du brauchst dank <a href="#s-credits" class="flow-link"
|
||||
>fairem Credit-System</a
|
||||
>, bleibst <a href="#s-sync" class="flow-link">auf allen Geräten synchron</a> und behältst
|
||||
die volle Kontrolle mit <a href="#s-privacy" class="flow-link">echtem Datenschutz</a>.
|
||||
Wähle aus <a href="#s-modules" class="flow-link">über 40 Modulen</a> genau das, was zu dir
|
||||
passt — <a href="#s-tiers" class="flow-link">kostenlos zum Starten</a>, <a
|
||||
href="#s-i18n"
|
||||
class="flow-link">mehrsprachig</a
|
||||
>, <a href="#s-crossmodule" class="flow-link">intelligent verknüpft</a> und <a
|
||||
href="#s-opensource"
|
||||
class="flow-link">offen entwickelt</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -563,17 +488,6 @@ const techRatingGroups = [
|
|||
<span class="usp-subtitle">{usp.subtitle}</span>
|
||||
<h3 class="usp-title">{usp.title}</h3>
|
||||
</div>
|
||||
<div class="usp-rating" title={`${usp.rating} von 5`}>
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<svg
|
||||
class={`usp-star ${i < usp.rating ? 'star-filled' : 'star-empty'}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p class="usp-description">{usp.description}</p>
|
||||
<ul class="usp-details">
|
||||
|
|
@ -602,7 +516,6 @@ const techRatingGroups = [
|
|||
<div id="view-tech" class="hidden">
|
||||
<section class="summary-section">
|
||||
<div class="summary-container">
|
||||
<h2 class="summary-title">Architecture Overview</h2>
|
||||
<div class="tech-stack-bar">
|
||||
<span class="tech-tag">SvelteKit 2</span>
|
||||
<span class="tech-tag">Svelte 5 Runes</span>
|
||||
|
|
@ -617,33 +530,24 @@ const techRatingGroups = [
|
|||
<span class="tech-tag">Turborepo</span>
|
||||
<span class="tech-tag">Cloudflare Pages</span>
|
||||
</div>
|
||||
<div class="summary-grid">
|
||||
{
|
||||
techRatingGroups.map((group) => (
|
||||
<div class="summary-card">
|
||||
<div class="summary-stars">
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<svg
|
||||
class={`summary-star ${i < group.stars ? group.color : 'text-gray-600'}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
<span class={`summary-label ${group.color}`}>{group.label}</span>
|
||||
<div class="summary-items">
|
||||
{group.items.map((item) => (
|
||||
<a href={`#t-${item.id}`} class="summary-tag">
|
||||
{item.title.split(' ').slice(0, 3).join(' ')}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<p class="summary-flow summary-flow-tech">
|
||||
<a href="#t-unified" class="flow-link flow-link-tech">Unified SvelteKit Monolith</a> mit <a
|
||||
href="#t-local-first"
|
||||
class="flow-link flow-link-tech">Dexie.js Local-First</a
|
||||
> und <a href="#t-encryption" class="flow-link flow-link-tech">AES-GCM-256 Encryption</a
|
||||
>. <a href="#t-local-ai" class="flow-link flow-link-tech">WebGPU AI</a> via Transformers.js,
|
||||
<a href="#t-credits" class="flow-link flow-link-tech">Credit System</a> mit JWT Tier-Gating,
|
||||
<a href="#t-sync" class="flow-link flow-link-tech">Go Sync Engine</a> mit Field-Level LWW.
|
||||
<a href="#t-privacy" class="flow-link flow-link-tech">Self-Hosted Infra</a>, <a
|
||||
href="#t-modules"
|
||||
class="flow-link flow-link-tech">Module Pattern</a
|
||||
> (collections/queries/stores), <a href="#t-tiers" class="flow-link flow-link-tech"
|
||||
>Access Tiers</a
|
||||
>, <a href="#t-i18n" class="flow-link flow-link-tech">i18n</a>, <a
|
||||
href="#t-crossmodule"
|
||||
class="flow-link flow-link-tech">Cross-Module Entities</a
|
||||
>, <a href="#t-opensource" class="flow-link flow-link-tech">Public Devlog</a>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -672,17 +576,6 @@ const techRatingGroups = [
|
|||
<span class="usp-subtitle usp-subtitle-mono">{usp.subtitle}</span>
|
||||
<h3 class="usp-title">{usp.title}</h3>
|
||||
</div>
|
||||
<div class="usp-rating" title={`${usp.rating} von 5`}>
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<svg
|
||||
class={`usp-star ${i < usp.rating ? 'star-filled' : 'star-empty'}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p class="usp-description usp-description-tech">{usp.description}</p>
|
||||
<ul class="usp-details">
|
||||
|
|
@ -940,78 +833,57 @@ const techRatingGroups = [
|
|||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||||
}
|
||||
|
||||
/* ==================== Rating Summary ==================== */
|
||||
/* ==================== Summary Flow ==================== */
|
||||
.summary-section {
|
||||
padding: calc(var(--grid-unit) * 2) calc(var(--grid-unit) * 2);
|
||||
padding: calc(var(--grid-unit) * 1) calc(var(--grid-unit) * 2) calc(var(--grid-unit) * 1);
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.summary-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: #f1f5f9;
|
||||
.summary-flow {
|
||||
font-size: 1.1875rem;
|
||||
line-height: 2;
|
||||
color: #94a3b8;
|
||||
text-align: center;
|
||||
margin-bottom: calc(var(--grid-unit) * 1);
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.summary-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: calc(var(--grid-unit) * 0.75);
|
||||
.summary-flow-tech {
|
||||
font-size: 1.0625rem;
|
||||
line-height: 1.9;
|
||||
margin-top: calc(var(--grid-unit) * 0.5);
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 16px;
|
||||
padding: calc(var(--grid-unit) * 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.summary-stars {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.summary-star {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.summary-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.summary-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
.flow-link {
|
||||
color: #e2e8f0;
|
||||
text-decoration: none;
|
||||
padding: 2px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
font-size: 0.75rem;
|
||||
color: #cbd5e1;
|
||||
text-decoration: none;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.summary-tag:hover {
|
||||
.flow-link:hover {
|
||||
background: rgba(59, 130, 246, 0.15);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
border-color: rgba(59, 130, 246, 0.4);
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
.flow-link-tech {
|
||||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||||
font-size: 0.9375rem;
|
||||
color: #60a5fa;
|
||||
background: rgba(59, 130, 246, 0.08);
|
||||
border-color: rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.flow-link-tech:hover {
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
border-color: rgba(59, 130, 246, 0.5);
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
|
|
@ -1119,26 +991,6 @@ const techRatingGroups = [
|
|||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.usp-rating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.usp-star {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.star-filled {
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.star-empty {
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.usp-description {
|
||||
font-size: 1rem;
|
||||
color: #94a3b8;
|
||||
|
|
@ -1432,10 +1284,6 @@ const techRatingGroups = [
|
|||
padding: calc(var(--grid-unit) * 4) calc(var(--grid-unit) * 1) calc(var(--grid-unit) * 1.5);
|
||||
}
|
||||
|
||||
.summary-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.usp-card {
|
||||
padding: calc(var(--grid-unit) * 0.75);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue