From 7f3d9accde872acf112c2e650c40a7ce32f02ba1 Mon Sep 17 00:00:00 2001 From: Agent Date: Fri, 10 Jul 2026 13:44:36 +0000 Subject: [PATCH] redesign as responsive Nostr OS --- src/AppRouter.tsx | 4 +- src/components/navigation/OsShell.tsx | 107 ++++++++++ src/index.css | 60 +++++- src/pages/Dashboard.tsx | 35 ++-- src/pages/DashboardEvents.tsx | 35 ++-- src/pages/DashboardExport.tsx | 35 ++-- src/pages/Explore.tsx | 34 ++-- src/pages/Index.tsx | 270 ++++++-------------------- src/pages/NIP19Page.tsx | 63 +++--- src/pages/Network.tsx | 59 ++++++ src/pages/NotFound.tsx | 21 +- src/pages/Privacy.tsx | 40 ++-- src/pages/Terms.tsx | 36 ++-- 13 files changed, 426 insertions(+), 373 deletions(-) create mode 100644 src/components/navigation/OsShell.tsx create mode 100644 src/pages/Network.tsx diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index e3bb12e..47ef3f5 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -6,6 +6,7 @@ import { Explore } from "./pages/Explore"; import { Dashboard } from "./pages/Dashboard"; import { DashboardEvents } from "./pages/DashboardEvents"; import { DashboardExport } from "./pages/DashboardExport"; +import { Network } from "./pages/Network"; import { NIP19Page } from "./pages/NIP19Page"; import { Terms } from "./pages/Terms"; import { Privacy } from "./pages/Privacy"; @@ -21,6 +22,7 @@ export function AppRouter() { } /> } /> } /> + } /> } /> } /> {/* NIP-19 route for npub1, note1, naddr1, nevent1, nprofile1 */} @@ -31,4 +33,4 @@ export function AppRouter() { ); } -export default AppRouter; \ No newline at end of file +export default AppRouter; diff --git a/src/components/navigation/OsShell.tsx b/src/components/navigation/OsShell.tsx new file mode 100644 index 0000000..fe23fee --- /dev/null +++ b/src/components/navigation/OsShell.tsx @@ -0,0 +1,107 @@ +import type { ReactNode } from 'react'; +import { Activity, Archive, Compass, Grid2X2, Network, Radio, Sparkles } from 'lucide-react'; +import { Link, NavLink } from 'react-router-dom'; +import { LoginArea } from '@/components/auth/LoginArea'; +import { cn } from '@/lib/utils'; + +const apps = [ + { name: 'Home', path: '/', icon: Grid2X2, short: 'Home' }, + { name: 'Discover', path: '/explore', icon: Compass, short: 'Find' }, + { name: 'Activity', path: '/dashboard', icon: Activity, short: 'Me' }, + { name: 'Studio', path: '/dashboard/events', icon: Sparkles, short: 'Studio' }, + { name: 'Archive', path: '/dashboard/export', icon: Archive, short: 'Save' }, + { name: 'Network', path: '/network', icon: Network, short: 'Relay' }, +]; + +interface OsShellProps { + children: ReactNode; + title: string; + eyebrow?: string; + className?: string; +} + +export function OsShell({ children, title, eyebrow = 'Nostr operating system', className }: OsShellProps) { + return ( +
+ + +
+
+
+
+

{eyebrow}

+

{title}

+
+
+ + + relay.layer.systems + + +
+
+
+ +
{children}
+
+ + +
+ ); +} diff --git a/src/index.css b/src/index.css index 78a8649..68e3d55 100644 --- a/src/index.css +++ b/src/index.css @@ -120,4 +120,62 @@ body { @apply bg-background text-foreground; } -} \ No newline at end of file +} + +@layer base { + :root { + --radius: 0.875rem; + } + + body { + min-width: 320px; + background: + radial-gradient(circle at 88% -8%, hsl(var(--primary) / 0.09), transparent 30rem), + hsl(var(--background)); + font-feature-settings: "ss01", "ss02", "cv02"; + } + + ::selection { + background: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + } +} + +@layer components { + .os-shell { + background-image: + linear-gradient(hsl(var(--foreground) / 0.025) 1px, transparent 1px), + linear-gradient(90deg, hsl(var(--foreground) / 0.025) 1px, transparent 1px); + background-size: 36px 36px; + } + + .os-rail { + background: + radial-gradient(circle at 30% 0%, hsl(var(--primary) / 0.12), transparent 14rem), + hsl(220 18% 8% / 0.9); + backdrop-filter: blur(24px); + } + + .os-hero { + background: + linear-gradient(120deg, hsl(222 28% 11% / 0.98), hsl(220 22% 15% / 0.96)), + hsl(var(--card)); + } + + .dark .os-shell { + background-image: + linear-gradient(hsl(0 0% 100% / 0.025) 1px, transparent 1px), + linear-gradient(90deg, hsl(0 0% 100% / 0.025) 1px, transparent 1px); + } +} + +@media (prefers-reduced-motion: no-preference) { + .os-hero { + animation: os-rise 640ms cubic-bezier(0.16, 1, 0.3, 1) both; + } +} + +@keyframes os-rise { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 171e108..a4045ec 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -1,5 +1,3 @@ -import { SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; -import { AppSidebar } from '@/components/navigation/AppSidebar'; import { DashboardStats } from '@/components/dashboard/DashboardStats'; import { EventKindsChart } from '@/components/dashboard/EventKindsChart'; import { RecentActivityChart } from '@/components/dashboard/RecentActivityChart'; @@ -10,29 +8,25 @@ import { Alert, AlertDescription } from '@/components/ui/alert'; import { InfoIcon } from 'lucide-react'; import { Account, useLoggedInAccounts } from '@/hooks/useLoggedInAccounts'; import { genUserName } from '@/lib/genUserName'; +import { OsShell } from '@/components/navigation/OsShell'; +import { useSeoMeta } from '@unhead/react'; export function Dashboard() { const { user } = useCurrentUser(); const { currentUser } = useLoggedInAccounts(); + useSeoMeta({ title: 'Activity · Nostr OS', description: 'Your Nostr activity at a glance.' }); + const getDisplayName = (account: Account): string => { return account.metadata.name ?? genUserName(account.pubkey); } return ( - -
- -
-
- -

Dashboard

-
- -
+ +
{!user ? ( - - + +
@@ -45,14 +39,15 @@ export function Dashboard() { ) : ( <> -
-

+
+

Identity dashboard

+

Welcome back {currentUser ? getDisplayName(currentUser) : ''}!

-

+

Here's an overview of your Nostr activity and statistics.

-

+ @@ -64,10 +59,8 @@ export function Dashboard() {
)} -
-
-
+ ); } diff --git a/src/pages/DashboardEvents.tsx b/src/pages/DashboardEvents.tsx index 4fe2d21..529aeb6 100644 --- a/src/pages/DashboardEvents.tsx +++ b/src/pages/DashboardEvents.tsx @@ -1,28 +1,22 @@ -import { SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; -import { AppSidebar } from '@/components/navigation/AppSidebar'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { Card, CardContent } from '@/components/ui/card'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { InfoIcon } from 'lucide-react'; import { EventExplorer } from '@/components/dashboard/EventExplorer'; +import { OsShell } from '@/components/navigation/OsShell'; +import { useSeoMeta } from '@unhead/react'; export function DashboardEvents() { const { user } = useCurrentUser(); - return ( - -
- -
-
- -

My Events

-
+ useSeoMeta({ title: 'Studio · Nostr OS', description: 'Browse and manage your published Nostr events.' }); -
+ return ( + +
{!user ? ( - - + +
@@ -35,23 +29,22 @@ export function DashboardEvents() { ) : (
-
-

+
+

Personal event index

+

Your Nostr events

-

+

Browse all events you have published on Nostr, search through their content, and publish deletion requests when you want something removed.

-

+
)} -
-
-
+ ); } diff --git a/src/pages/DashboardExport.tsx b/src/pages/DashboardExport.tsx index 0255a8c..b131a69 100644 --- a/src/pages/DashboardExport.tsx +++ b/src/pages/DashboardExport.tsx @@ -1,7 +1,5 @@ import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; -import { SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; -import { AppSidebar } from '@/components/navigation/AppSidebar'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useNostr } from '@nostrify/react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; @@ -9,12 +7,16 @@ import { Alert, AlertDescription } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { InfoIcon, Download, Users, Calendar } from 'lucide-react'; import { Skeleton } from '@/components/ui/skeleton'; +import { OsShell } from '@/components/navigation/OsShell'; +import { useSeoMeta } from '@unhead/react'; export function DashboardExport() { const { user } = useCurrentUser(); const { nostr } = useNostr(); const [isExporting, setIsExporting] = useState(false); + useSeoMeta({ title: 'Archive · Nostr OS', description: 'Export and preserve your Nostr following list.' }); + // Fetch the user's contact list (kind 3 event) const { data: contactListEvent, isLoading } = useQuery({ queryKey: ['contact-list', user?.pubkey], @@ -88,19 +90,11 @@ export function DashboardExport() { }; return ( - -
- -
-
- -

Export Following List

-
- -
+ +
{!user ? ( - - + +
@@ -113,7 +107,12 @@ export function DashboardExport() { ) : (
- +
+

Portable social graph

+

Keep your follows close.

+

Your Nostr social graph belongs to you. Export a signed copy whenever you need it.

+
+ Backup Your Following List @@ -224,7 +223,7 @@ export function DashboardExport() { - + About Your Following List @@ -243,9 +242,7 @@ export function DashboardExport() {
)} -
-
-
+ ); } diff --git a/src/pages/Explore.tsx b/src/pages/Explore.tsx index 0250d76..f9b4b85 100644 --- a/src/pages/Explore.tsx +++ b/src/pages/Explore.tsx @@ -9,6 +9,8 @@ import { Badge } from '@/components/ui/badge'; import { Skeleton } from '@/components/ui/skeleton'; import { NoteContent } from '@/components/NoteContent'; import { genUserName } from '@/lib/genUserName'; +import { OsShell } from '@/components/navigation/OsShell'; +import { useSeoMeta } from '@unhead/react'; function TextNoteCard({ event }: { event: NostrEvent }) { const author = useAuthor(event.pubkey); @@ -160,22 +162,22 @@ export function Explore() { const [activeTab, setActiveTab] = useState('notes'); const { data, isLoading, isError } = useExploreEvents(); - return ( -
-
- {/* Header */} -
-

- Explore -

-

- Discover the latest text notes and profiles from the Nostr -

-
+ useSeoMeta({ + title: 'Discover · Nostr OS', + description: 'Explore notes and profiles through the Nostr network.', + }); + + return ( + +
+
+

Public network scan

+

Follow the live signal.

+

A quiet window into the notes and profiles moving through your configured Nostr relays.

+
- {/* Tabs */} - + Notes ({data?.textNotes?.length || 0}) @@ -184,7 +186,6 @@ export function Explore() { - {/* Text Notes Tab */} {isLoading && } @@ -213,7 +214,6 @@ export function Explore() { ))} - {/* Profiles Tab */}
{isLoading && ( @@ -265,6 +265,6 @@ export function Explore() {
-
+
); } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index fb16a26..b998b5f 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,241 +1,87 @@ import { useSeoMeta } from '@unhead/react'; +import { ArrowUpRight, Boxes, Copy, Fingerprint, Network, Orbit, Sparkles, Terminal, Waves } from 'lucide-react'; +import { Link } from 'react-router-dom'; import { useState } from 'react'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { CheckCircle2, Copy, Server, Gift, Users, Globe } from 'lucide-react'; +import { OsShell } from '@/components/navigation/OsShell'; import { useToast } from '@/hooks/useToast'; -import { LoginArea } from '@/components/auth/LoginArea'; +import { useCurrentUser } from '@/hooks/useCurrentUser'; + +const workspaces = [ + { title: 'Discover', detail: 'Live notes & people', path: '/explore', icon: Orbit, tone: 'from-cyan-400/20 to-blue-500/5', index: '01' }, + { title: 'Activity', detail: 'Your Nostr footprint', path: '/dashboard', icon: Waves, tone: 'from-amber-300/20 to-orange-500/5', index: '02' }, + { title: 'Studio', detail: 'Browse your events', path: '/dashboard/events', icon: Sparkles, tone: 'from-fuchsia-400/20 to-violet-500/5', index: '03' }, + { title: 'Archive', detail: 'Export your follows', path: '/dashboard/export', icon: Boxes, tone: 'from-emerald-300/20 to-teal-500/5', index: '04' }, +]; const Index = () => { const [copied, setCopied] = useState(false); const { toast } = useToast(); + const { user } = useCurrentUser(); const relayUrl = 'wss://relay.layer.systems'; useSeoMeta({ - title: 'LAYER.systems - Public Nostr Relay', - description: 'A fast, reliable, and open Nostr relay serving the decentralized social network.', + title: 'Nostr OS · Layer Systems', + description: 'A beautiful operating system for your Nostr identity.', }); - const copyToClipboard = async () => { + const copyRelay = async () => { try { await navigator.clipboard.writeText(relayUrl); setCopied(true); - toast({ - title: 'Copied!', - description: 'Relay URL copied to clipboard', - }); - setTimeout(() => setCopied(false), 2000); + window.setTimeout(() => setCopied(false), 1600); + toast({ title: 'Relay address copied', description: 'Paste it into any Nostr client.' }); } catch { - toast({ - title: 'Failed to copy', - description: 'Please copy the URL manually', - variant: 'destructive', - }); + toast({ title: 'Could not copy relay address', description: relayUrl, variant: 'destructive' }); } }; - const features = [ - { - icon: Gift, - title: 'Free', - description: 'No cost to use - accessible for everyone', - }, - { - icon: Users, - title: 'Community driven', - description: 'Built and maintained by the Nostr community', - }, - { - icon: Globe, - title: 'Global Network', - description: 'Part of the decentralized Nostr ecosystem', - }, - { - icon: Server, - title: 'Open Access', - description: 'Free to use for all Nostr clients', - }, - ]; - return ( -
- {/* Header */} -
-
-
- -
-
-
- - {/* Hero Section */} -
- {/* Animated Background Elements */} -
-
-
-
- -
- {/* Status Badge */} - {/*
- -
- Relay Online - -
*/} - - {/* Main Heading */} -
-

- - LAYER.systems - -

-

- Your gateway to the decentralized social network -

-

- A fast, reliable, and open Nostr relay connecting you to the future of social media -

-
- - {/* Relay URL Card */} -
- - -
-
-
-

Relay URL

- - {relayUrl} - -
- -
-

- Add this URL to your Nostr client to connect to LAYER.systems -

-
-
-
-
- - {/* Features Grid */} -
-

Why Choose LAYER.systems?

-
- {features.map((feature, index) => ( - - -
- -
-
-

{feature.title}

-

{feature.description}

-
-
-
- ))} + +
+
+
+
+
+
+ Personal signal online +
+

One place for the network that belongs to you.

+

A calm control surface for your Nostr identity: discover public conversations, inspect your signal, and keep your network portable.

+
+ + {user ? 'Open my activity' : 'Enter discover'} + + + Network routes +
-
-
- - {/* How to Connect Section */} -
-
-

Getting Started

-
- - -
-
-
- 1 -
-
-

Choose Your Client

-

- Pick a Nostr client like Damus, Amethyst, Snort, or any other compatible application -

-
-
-
-
- 2 -
-
-

Add the Relay

-

- In your client settings, add {relayUrl} to your relay list -

-
-
-
-
- 3 -
-
-

Start Connecting

-

- You're all set! Start posting, following, and connecting with the Nostr network -

-
-
-
-
-
+
+
Identity
+

{user ? 'Signer connected' : 'Your Nostr key is waiting'}

+

{user ? `${user.pubkey.slice(0, 12)}…${user.pubkey.slice(-8)}` : 'Use a signer extension or nsec login to begin.'}

+
Your identity never leaves your signer
-
+
- {/* Footer */} -
-
-
-

- © {new Date().getFullYear()} LAYER.systems. Powered by Nostr. -

-
-
- - Open and free for all -
- -
-
+
+

Your desktop

Open an app

04 MODULES READY
+
+ {workspaces.map((workspace) => ( + +
+
{workspace.index}

{workspace.title}

{workspace.detail}

+ + ))}
-
-
+ + +
+

Bring Layer Systems with you

A preferred relay, ready for any Nostr client.

{relayUrl}
+

Your route table

Control what carries your signal.

Manage read and write relays from one focused network app.

Open Network +
+ ); }; diff --git a/src/pages/NIP19Page.tsx b/src/pages/NIP19Page.tsx index 5aa4439..e7b2344 100644 --- a/src/pages/NIP19Page.tsx +++ b/src/pages/NIP19Page.tsx @@ -1,42 +1,55 @@ import { nip19 } from 'nostr-tools'; +import { Copy, Fingerprint, MapPin, Radio } from 'lucide-react'; import { useParams } from 'react-router-dom'; +import { Card, CardContent } from '@/components/ui/card'; +import { OsShell } from '@/components/navigation/OsShell'; +import { useToast } from '@/hooks/useToast'; import NotFound from './NotFound'; +const labels: Record = { + npub: { title: 'Profile pointer', detail: 'A public key that identifies a person or service on Nostr.' }, + nprofile: { title: 'Profile pointer', detail: 'A profile pointer with relay hints for faster discovery.' }, + note: { title: 'Note pointer', detail: 'A pointer to a short text note on the Nostr network.' }, + nevent: { title: 'Event pointer', detail: 'A portable pointer to a Nostr event and its relay hints.' }, + naddr: { title: 'Address pointer', detail: 'A durable address for a replaceable Nostr event.' }, +}; + export function NIP19Page() { const { nip19: identifier } = useParams<{ nip19: string }>(); + const { toast } = useToast(); - if (!identifier) { - return ; - } + if (!identifier) return ; - let decoded; + let decoded: ReturnType; try { decoded = nip19.decode(identifier); } catch { return ; } - const { type } = decoded; + const presentation = labels[decoded.type]; + if (!presentation) return ; - switch (type) { - case 'npub': - case 'nprofile': - // AI agent should implement profile view here - return
Profile placeholder
; + const detail = typeof decoded.data === 'string' ? decoded.data : JSON.stringify(decoded.data, null, 2); - case 'note': - // AI agent should implement note view here - return
Note placeholder
; + const copyPointer = async () => { + try { + await navigator.clipboard.writeText(identifier); + toast({ title: 'Nostr pointer copied' }); + } catch { + toast({ title: 'Could not copy pointer', variant: 'destructive' }); + } + }; - case 'nevent': - // AI agent should implement event view here - return
Event placeholder
; - - case 'naddr': - // AI agent should implement addressable event view here - return
Addressable event placeholder
; - - default: - return ; - } -} \ No newline at end of file + return ( + +
+
+

Resolved {decoded.type}

{presentation.title}

{presentation.detail}

+
+
Nostr address
{identifier}
+
Decoded route
{detail}
+
+
+ ); +} diff --git a/src/pages/Network.tsx b/src/pages/Network.tsx new file mode 100644 index 0000000..2ca1e41 --- /dev/null +++ b/src/pages/Network.tsx @@ -0,0 +1,59 @@ +import { useSeoMeta } from '@unhead/react'; +import { ExternalLink, Radio, ShieldCheck, Zap } from 'lucide-react'; +import { OsShell } from '@/components/navigation/OsShell'; +import { RelayListManager } from '@/components/RelayListManager'; + +export function Network() { + useSeoMeta({ + title: 'Network · Nostr OS', + description: 'Manage the relays that connect your Nostr OS.', + }); + + return ( + +
+
+
+
+ +
+

Layer systems relay

+

Your signal starts here.

+

Nostr OS ships with Layer Systems as its preferred relay. Keep it enabled for a fast, simple default, then add the relays your identity already trusts.

+
+ + Visit relay + +
+
+ +
+
+
+
+

Relay routes

+

Read, write, and publish your NIP-65 relay preferences.

+
+ Ready +
+ +
+ + +
+
+ ); +} + +export default Network; diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx index 85e429d..acdc31a 100644 --- a/src/pages/NotFound.tsx +++ b/src/pages/NotFound.tsx @@ -1,6 +1,9 @@ import { useSeoMeta } from "@unhead/react"; import { useLocation } from "react-router-dom"; import { useEffect } from "react"; +import { Link } from 'react-router-dom'; +import { ArrowLeft, Radar } from 'lucide-react'; +import { OsShell } from '@/components/navigation/OsShell'; const NotFound = () => { const location = useLocation(); @@ -18,15 +21,17 @@ const NotFound = () => { }, [location.pathname]); return ( -
-
-

404

-

Oops! Page not found

- - Return to Home - + +
+
+
+

404 / NO ROUTE

+

That signal isn’t here.

+

The route may have moved, expired, or never existed in this Nostr OS.

+ Return home +
-
+ ); }; diff --git a/src/pages/Privacy.tsx b/src/pages/Privacy.tsx index 39240c6..bc36b93 100644 --- a/src/pages/Privacy.tsx +++ b/src/pages/Privacy.tsx @@ -2,6 +2,7 @@ import { useSeoMeta } from '@unhead/react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Shield } from 'lucide-react'; import { Link } from 'react-router-dom'; +import { OsShell } from '@/components/navigation/OsShell'; export function Privacy() { useSeoMeta({ @@ -10,19 +11,8 @@ export function Privacy() { }); return ( -
- {/* Header */} -
-
- - - LAYER.systems - -
-
- - {/* Main Content */} -
+ +
{/* Hero Section */}
@@ -36,7 +26,7 @@ export function Privacy() {
{/* Introduction */} - + Introduction @@ -48,7 +38,7 @@ export function Privacy() { {/* Information We Collect */} - + 1. Information We Collect @@ -88,7 +78,7 @@ export function Privacy() { {/* How We Use Information */} - + 2. How We Use Information @@ -107,7 +97,7 @@ export function Privacy() { {/* Data Storage and Security */} - + 3. Data Storage and Security @@ -131,7 +121,7 @@ export function Privacy() { {/* Data Retention */} - + 4. Data Retention @@ -152,7 +142,7 @@ export function Privacy() { {/* Third-Party Services */} - + 5. Third-Party Services @@ -173,7 +163,7 @@ export function Privacy() { {/* Your Rights */} - + 6. Your Rights and Choices @@ -191,7 +181,7 @@ export function Privacy() { {/* Cookies and Tracking */} - + 7. Cookies and Tracking @@ -211,7 +201,7 @@ export function Privacy() { {/* Children's Privacy */} - + 8. Children's Privacy @@ -223,7 +213,7 @@ export function Privacy() { {/* International Users */} - + 9. International Users @@ -235,7 +225,7 @@ export function Privacy() { {/* Changes to Privacy Policy */} - + 10. Changes to This Privacy Policy @@ -271,7 +261,7 @@ export function Privacy() {
-
+ ); } diff --git a/src/pages/Terms.tsx b/src/pages/Terms.tsx index a52efa0..5bf1cd5 100644 --- a/src/pages/Terms.tsx +++ b/src/pages/Terms.tsx @@ -2,6 +2,7 @@ import { useSeoMeta } from '@unhead/react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { ScrollText } from 'lucide-react'; import { Link } from 'react-router-dom'; +import { OsShell } from '@/components/navigation/OsShell'; export function Terms() { useSeoMeta({ @@ -10,19 +11,8 @@ export function Terms() { }); return ( -
- {/* Header */} -
-
- - - LAYER.systems - -
-
- - {/* Main Content */} -
+ +
{/* Hero Section */}
@@ -36,7 +26,7 @@ export function Terms() {
{/* Introduction */} - + Introduction @@ -48,7 +38,7 @@ export function Terms() { {/* Service Description */} - + 1. Service Description @@ -65,7 +55,7 @@ export function Terms() { {/* User Conduct */} - + 2. User Conduct @@ -88,7 +78,7 @@ export function Terms() { {/* Content Policy */} - + 3. Content Policy @@ -109,7 +99,7 @@ export function Terms() { {/* Limitation of Liability */} - + 4. Limitation of Liability @@ -131,7 +121,7 @@ export function Terms() { {/* Privacy */} - + 5. Privacy @@ -147,7 +137,7 @@ export function Terms() { {/* Changes to Terms */} - + 6. Changes to Terms @@ -159,7 +149,7 @@ export function Terms() { {/* Termination */} - + 7. Termination @@ -171,7 +161,7 @@ export function Terms() { {/* Governing Law */} - + 8. Governing Law @@ -207,7 +197,7 @@ export function Terms() {
-
+ ); }