summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-27 17:57:04 +0530
committerBobby <[email protected]>2026-02-27 17:57:04 +0530
commiteb332a9697e80d8ba138e51cc8de234dad59b0bd (patch)
tree6b2f59a67b1ccebcb28727a3af8db5a9c87e8979
parentf2c9b615129c4842bdaa9bdc7b33f99e873b772e (diff)
downloadpagoda-eb332a9697e80d8ba138e51cc8de234dad59b0bd.tar.xz
pagoda-eb332a9697e80d8ba138e51cc8de234dad59b0bd.zip
feat(layout): enhance layout with navigation, search bar, and footer links
style(theme): update color variables for improved aesthetics fix(NavSection): replace variant prop with accent for better styling chore(tsconfig): enforce consistent casing in file names add(background): include background image for enhanced visual appeal
-rw-r--r--garden/public/images/background.webpbin0 -> 940 bytes
-rw-r--r--garden/src/components/Layout.tsx77
-rw-r--r--garden/src/components/NavSection.tsx14
-rw-r--r--garden/src/styles/layout.css256
-rw-r--r--garden/src/styles/theme.css33
-rw-r--r--garden/tsconfig.json1
6 files changed, 276 insertions, 105 deletions
diff --git a/garden/public/images/background.webp b/garden/public/images/background.webp
new file mode 100644
index 0000000..9e37b7f
--- /dev/null
+++ b/garden/public/images/background.webp
Binary files differ
diff --git a/garden/src/components/Layout.tsx b/garden/src/components/Layout.tsx
index 5d1374e..7c3a56a 100644
--- a/garden/src/components/Layout.tsx
+++ b/garden/src/components/Layout.tsx
@@ -15,16 +15,40 @@ export default function Layout(props: LayoutProps) {
<p>A community for the small web</p>
</header>
+ <nav class="top-nav">
+ <A href="/" class="top-nav-link" data-accent="cyan" activeClass="active" end>Home</A>
+ <A href="/districts" class="top-nav-link" data-accent="green" activeClass="active">Districts</A>
+ <A href="/forums" class="top-nav-link" data-accent="pink" activeClass="active">Forums</A>
+ <A href="/chat" class="top-nav-link" data-accent="yellow" activeClass="active">Chat</A>
+ <A href="/bazaar" class="top-nav-link" data-accent="purple" activeClass="active">Bazaar</A>
+ </nav>
+
+ <div class="search-bar">
+ <input type="text" placeholder="Search members, posts, districts..." />
+ </div>
+
<div class="site-main">
<Sidebar>
- <NavSection title="Navigation">
- <li><A href="/">Home</A></li>
- <li><A href="/districts">Districts</A></li>
- <li><A href="/forums">Forums</A></li>
- <li><A href="/chat">Chat</A></li>
+ <NavSection title="Account" accent="pink">
+ <ul>
+ <li><A href="/login">Log In</A></li>
+ <li><A href="/register">Register</A></li>
+ </ul>
</NavSection>
- <NavSection title="Resources" variant="alternate">
- <li><A href="/bazaar">Bazaar</A></li>
+ <NavSection title="Community" accent="cyan">
+ <ul>
+ <li><A href="/members">Members</A></li>
+ <li><A href="/online">Who's Online</A></li>
+ <li><A href="/buttons">Button Wall</A></li>
+ <li><A href="/random">Random Member</A></li>
+ </ul>
+ </NavSection>
+ <NavSection title="Services" accent="green">
+ <ul>
+ <li><A href="/webring">Webring</A></li>
+ <li><A href="/guestbook">Guestbook</A></li>
+ <li><A href="/hitcounter">Hit Counter</A></li>
+ </ul>
</NavSection>
</Sidebar>
@@ -33,16 +57,47 @@ export default function Layout(props: LayoutProps) {
</main>
<Sidebar>
- <NavSection title="Account" variant="alternate">
- <li><A href="/login">Log In</A></li>
- <li><A href="/register">Register</A></li>
+ <NavSection title="Statistics" accent="yellow">
+ <ul>
+ <li>Members: —</li>
+ <li>Online: —</li>
+ <li>Posts Today: —</li>
+ <li>Newest: —</li>
+ </ul>
+ </NavSection>
+ <NavSection title="New Members" accent="cyan">
+ <ul>
+ <li class="placeholder">Be the first to join!</li>
+ </ul>
+ </NavSection>
+ <NavSection title="Birthdays" accent="green">
+ <ul>
+ <li class="placeholder">No birthdays today.</li>
+ </ul>
+ </NavSection>
+ <NavSection title="Top Posters" accent="yellow">
+ <ul>
+ <li class="placeholder">No posts yet.</li>
+ </ul>
+ </NavSection>
+ <NavSection title="Staff Online" accent="purple">
+ <ul>
+ <li class="placeholder">No staff online.</li>
+ </ul>
</NavSection>
</Sidebar>
</div>
<footer class="site-footer">
+ <nav class="footer-links">
+ <A href="/about">About</A>
+ <A href="/rules">Rules</A>
+ <A href="/privacy">Privacy</A>
+ <A href="/terms">Terms</A>
+ <A href="/contact">Contact</A>
+ </nav>
<p>&copy; {new Date().getFullYear()} Pagoda. Brought to you by <a href="https://shi.foo" target="_blank" rel="noopener noreferrer">shi.foo</a>.</p>
</footer>
</>
);
-} \ No newline at end of file
+}
diff --git a/garden/src/components/NavSection.tsx b/garden/src/components/NavSection.tsx
index 2e2fc6a..230873c 100644
--- a/garden/src/components/NavSection.tsx
+++ b/garden/src/components/NavSection.tsx
@@ -2,22 +2,16 @@ import type { JSX } from "solid-js";
interface NavSectionProps {
title: string;
- variant?: "primary" | "alternate";
+ accent?: "cyan" | "green" | "pink" | "purple" | "yellow";
children: JSX.Element;
}
export default function NavSection(props: NavSectionProps) {
- const variant = () => props.variant ?? "primary";
-
return (
- <section class={`nav-section ${variant()}`}>
- <div class="nav-section-header">
- <div class="bar-left" />
- <h3>{props.title}</h3>
- <div class="bar-right" />
- </div>
+ <section class="nav-section" data-accent={props.accent || "purple"}>
+ <div class="nav-section-header">{props.title}</div>
<div class="nav-section-body">
- <ul>{props.children}</ul>
+ {props.children}
</div>
</section>
);
diff --git a/garden/src/styles/layout.css b/garden/src/styles/layout.css
index 8ccd956..527ca12 100644
--- a/garden/src/styles/layout.css
+++ b/garden/src/styles/layout.css
@@ -7,151 +7,273 @@
body {
font-family: var(--font-body);
background-color: var(--color-bg);
+ background-image: url("/images/background.webp");
+ background-repeat: repeat;
color: var(--color-text);
min-width: var(--width-container);
+ font-size: 13px;
+ line-height: 1.5;
}
a {
color: var(--color-link);
- text-decoration: none;
+ text-decoration: underline;
}
a:hover {
color: var(--color-link-hover);
- text-decoration: underline;
- text-decoration-style: dotted;
}
.site-header {
- width: var(--width-container);
- margin: 0 auto;
- padding: 20px 0;
+ padding: 16px 0 8px;
text-align: center;
+ position: relative;
+}
+
+.site-header::before {
+ content: "";
+ position: absolute;
+ top: 40%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 490px;
+ height: 154px;
+ background: radial-gradient(ellipse, rgba(155, 109, 255, 0.2) 0%, rgba(140, 90, 255, 0.08) 40%, transparent 70%);
+ pointer-events: none;
+ z-index: 0;
}
.site-header h1 {
+ position: relative;
+ z-index: 1;
font-family: var(--font-display);
- font-size: 48px;
- font-weight: 700;
+ font-size: 58px;
+ font-weight: 800;
text-transform: uppercase;
- letter-spacing: 8px;
- color: var(--color-purple-light);
+ letter-spacing: 10px;
+ color: rgba(224, 212, 245, 0.88);
margin: 0;
}
.site-header p {
+ position: relative;
+ z-index: 1;
+ font-family: var(--font-display);
+ font-size: 15px;
+ text-transform: uppercase;
+ letter-spacing: 5px;
+ color: #a898c0;
+}
+
+.top-nav {
+ width: var(--width-container);
+ margin: 0 auto;
+ display: flex;
+ background: var(--color-panel);
+ border: 1px solid var(--color-border);
+}
+
+.top-nav-link {
+ flex: 1;
+ padding: 6px 0;
+ text-align: center;
font-family: var(--font-display);
- font-size: 18px;
+ font-size: 13px;
+ font-weight: 600;
text-transform: uppercase;
- letter-spacing: 4px;
+ letter-spacing: 2px;
+ color: var(--color-text-bright);
+ text-decoration: none;
+ border-right: 1px solid var(--color-border);
+ border-top: 2px solid transparent;
+ transition: border-top-color 0.15s, color 0.15s, background 0.15s;
+}
+
+.top-nav-link:last-child {
+ border-right: none;
+}
+
+.top-nav-link[data-accent="cyan"]:hover { border-top-color: var(--color-cyan); color: var(--color-cyan); background: rgba(34, 211, 238, 0.06); }
+.top-nav-link[data-accent="green"]:hover { border-top-color: var(--color-green); color: var(--color-green); background: rgba(163, 230, 53, 0.06); }
+.top-nav-link[data-accent="pink"]:hover { border-top-color: var(--color-pink); color: var(--color-pink); background: rgba(255, 110, 180, 0.06); }
+.top-nav-link[data-accent="yellow"]:hover { border-top-color: var(--color-yellow); color: var(--color-yellow); background: rgba(251, 191, 36, 0.06); }
+.top-nav-link[data-accent="purple"]:hover { border-top-color: var(--color-purple); color: var(--color-purple); background: rgba(155, 109, 255, 0.06); }
+
+.top-nav-link[data-accent="cyan"].active { border-top-color: var(--color-cyan); color: var(--color-cyan); background: rgba(34, 211, 238, 0.1); }
+.top-nav-link[data-accent="green"].active { border-top-color: var(--color-green); color: var(--color-green); background: rgba(163, 230, 53, 0.1); }
+.top-nav-link[data-accent="pink"].active { border-top-color: var(--color-pink); color: var(--color-pink); background: rgba(255, 110, 180, 0.1); }
+.top-nav-link[data-accent="yellow"].active { border-top-color: var(--color-yellow); color: var(--color-yellow); background: rgba(251, 191, 36, 0.1); }
+.top-nav-link[data-accent="purple"].active { border-top-color: var(--color-purple); color: var(--color-purple); background: rgba(155, 109, 255, 0.1); }
+
+.search-bar {
+ width: var(--width-container);
+ margin: 0 auto 6px;
+ background: var(--color-panel);
+ border: 1px solid var(--color-border);
+ border-top: none;
+ padding: 6px 10px;
+}
+
+.search-bar input {
+ width: 100%;
+ background: var(--color-bg);
+ border: 1px solid var(--color-border);
+ padding: 4px 8px;
+ font-family: var(--font-body);
+ font-size: 12px;
+ color: var(--color-text);
+ outline: none;
+}
+
+.search-bar input::placeholder {
color: var(--color-text-muted);
}
+.search-bar input:focus {
+ border-color: var(--color-cyan);
+}
+
.site-main {
width: var(--width-container);
margin: 0 auto;
display: flex;
- gap: var(--gap-columns);
+ gap: 6px;
+ align-items: flex-start;
}
.sidebar {
width: var(--width-sidebar);
flex-shrink: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
}
.content {
flex-grow: 1;
- background: var(--color-surface);
- padding: 20px;
+ background: var(--color-panel);
+ background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.02) 0%, transparent 100px);
+ border: 1px solid var(--color-border);
+ padding: 10px 12px;
+ min-height: 300px;
+}
+
+.content p {
+ margin-bottom: 6px;
+}
+
+.content p:last-child {
+ margin-bottom: 0;
}
.site-footer {
width: var(--width-container);
- margin: 0 auto;
- padding: 20px 0;
+ margin: 8px auto 0;
+ padding: 8px 0 16px;
text-align: center;
- border-top: 1px solid var(--color-border);
- margin-top: 20px;
}
-.site-footer p {
- font-size: 12px;
- color: var(--color-text-muted);
+.footer-links {
+ margin-bottom: 4px;
}
-.nav-section {
- margin-bottom: 16px;
+.footer-links a {
+ font-size: 11px;
+ color: var(--color-text-muted);
+ text-decoration: none;
+ margin: 0 6px;
}
-.nav-section-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 4px;
+.footer-links a:hover {
+ color: var(--color-text);
+ text-decoration: underline;
}
-.nav-section-header .bar-left {
- width: 16px;
- height: 24px;
- border-radius: 12px 0 0 12px;
- flex-shrink: 0;
+.site-footer p {
+ font-size: 10px;
+ color: var(--color-text-muted);
}
-.nav-section-header .bar-right {
- flex-grow: 1;
- height: 24px;
- border-radius: 0 12px 12px 0;
+.nav-section {
+ background: var(--color-panel);
+ border: 1px solid var(--color-border);
}
-.nav-section-header h3 {
+.nav-section[data-accent="cyan"] { border-top: 2px solid var(--color-cyan); }
+.nav-section[data-accent="green"] { border-top: 2px solid var(--color-green); }
+.nav-section[data-accent="pink"] { border-top: 2px solid var(--color-pink); }
+.nav-section[data-accent="yellow"] { border-top: 2px solid var(--color-yellow); }
+.nav-section[data-accent="purple"] { border-top: 2px solid var(--color-purple); }
+
+.nav-section-header {
+ background: var(--color-panel-header);
+ background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent);
+ padding: 5px 8px;
font-family: var(--font-display);
- font-size: 20px;
- font-weight: 600;
+ font-size: 12px;
+ font-weight: 700;
text-transform: uppercase;
- white-space: nowrap;
+ letter-spacing: 2px;
color: var(--color-text-bright);
}
-.nav-section-body {
- margin-left: 32px;
- border-right: 6px solid;
- border-bottom: 2px solid;
- border-radius: 0 0 8px 0;
- padding: 4px 8px;
-}
+.nav-section[data-accent="cyan"] .nav-section-header { color: var(--color-cyan); }
+.nav-section[data-accent="green"] .nav-section-header { color: var(--color-green); }
+.nav-section[data-accent="pink"] .nav-section-header { color: var(--color-pink); }
+.nav-section[data-accent="yellow"] .nav-section-header { color: var(--color-yellow); }
+.nav-section[data-accent="purple"] .nav-section-header { color: var(--color-purple); }
.nav-section-body ul {
list-style: none;
}
.nav-section-body li {
- padding: 2px 0;
+ padding: 3px 8px 3px 16px;
+ font-size: 12px;
+ position: relative;
}
-.nav-section-body a {
- font-size: 14px;
+.nav-section-body li::before {
+ content: "\25B8";
+ position: absolute;
+ left: 6px;
+ font-size: 10px;
+ color: var(--color-text-muted);
}
-.nav-section.primary .bar-left {
- background: var(--color-purple);
-}
+.nav-section[data-accent="cyan"] .nav-section-body li::before { color: var(--color-cyan); }
+.nav-section[data-accent="green"] .nav-section-body li::before { color: var(--color-green); }
+.nav-section[data-accent="pink"] .nav-section-body li::before { color: var(--color-pink); }
+.nav-section[data-accent="yellow"] .nav-section-body li::before { color: var(--color-yellow); }
+.nav-section[data-accent="purple"] .nav-section-body li::before { color: var(--color-purple); }
-.nav-section.primary .bar-right {
- background: var(--color-pink);
+.nav-section-body li a {
+ color: var(--color-link);
+ text-decoration: none;
}
-.nav-section.primary .nav-section-body {
- border-color: var(--color-pink);
-}
+.nav-section[data-accent="cyan"] .nav-section-body li a:hover { color: var(--color-cyan); }
+.nav-section[data-accent="green"] .nav-section-body li a:hover { color: var(--color-green); }
+.nav-section[data-accent="pink"] .nav-section-body li a:hover { color: var(--color-pink); }
+.nav-section[data-accent="yellow"] .nav-section-body li a:hover { color: var(--color-yellow); }
+.nav-section[data-accent="purple"] .nav-section-body li a:hover { color: var(--color-purple); }
-.nav-section.alternate .bar-left {
- background: var(--color-pink);
+.nav-section-body li a.active {
+ font-weight: 600;
}
-.nav-section.alternate .bar-right {
- background: var(--color-purple);
-}
+.nav-section[data-accent="cyan"] .nav-section-body li a.active { color: var(--color-cyan); }
+.nav-section[data-accent="green"] .nav-section-body li a.active { color: var(--color-green); }
+.nav-section[data-accent="pink"] .nav-section-body li a.active { color: var(--color-pink); }
+.nav-section[data-accent="yellow"] .nav-section-body li a.active { color: var(--color-yellow); }
+.nav-section[data-accent="purple"] .nav-section-body li a.active { color: var(--color-purple); }
-.nav-section.alternate .nav-section-body {
- border-color: var(--color-purple);
+.nav-section-body li.placeholder {
+ color: var(--color-text-muted);
+ font-style: italic;
+ padding: 3px 8px;
}
+
+.nav-section-body li.placeholder::before {
+ display: none;
+} \ No newline at end of file
diff --git a/garden/src/styles/theme.css b/garden/src/styles/theme.css
index e64ef1a..0c00b71 100644
--- a/garden/src/styles/theme.css
+++ b/garden/src/styles/theme.css
@@ -1,36 +1,35 @@
:root {
color-scheme: dark;
- --color-bg: #0e0e14;
- --color-surface: rgba(0, 0, 0, 0.5);
- --color-surface-raised: rgba(255, 255, 255, 0.04);
+ --color-bg: #08080f;
+ --color-panel: #14142a;
+ --color-panel-header: #1c1c38;
+ --color-surface-hover: rgba(255, 255, 255, 0.05);
- --color-text: #d4d4d8;
- --color-text-muted: #71717a;
- --color-text-bright: #fafafa;
+ --color-text: #c8c8d8;
+ --color-text-muted: #707088;
+ --color-text-bright: #e8e8f0;
- --color-purple: #8853e7;
- --color-purple-light: #d4c5ff;
- --color-pink: #e42b8f;
- --color-pink-light: #ffc8f0;
- --color-green: #91d027;
- --color-green-light: #cff294;
+ --color-purple: #9b6dff;
+ --color-pink: #ff6eb4;
+ --color-green: #a3e635;
+ --color-cyan: #22d3ee;
+ --color-yellow: #fbbf24;
- --color-link: var(--color-pink);
- --color-link-hover: var(--color-purple);
+ --color-link: #b0b0cc;
+ --color-link-hover: #fff;
- --color-border: rgba(255, 255, 255, 0.08);
+ --color-border: #2a2a3e;
--font-body: "IBM Plex Sans", sans-serif;
--font-display: "Saira Extra Condensed", sans-serif;
--width-container: 1200px;
--width-sidebar: 200px;
- --gap-columns: 20px;
}
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
-}
+} \ No newline at end of file
diff --git a/garden/tsconfig.json b/garden/tsconfig.json
index 8b4ebee..5c9ca6c 100644
--- a/garden/tsconfig.json
+++ b/garden/tsconfig.json
@@ -15,6 +15,7 @@
// Type Checking & Safety
"strict": true,
+ "forceConsistentCasingInFileNames": true,
"types": ["vite/client"]
}
}