From af331ca00da8a3b937c496076f3f7297b3a5283c Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 2 Dec 2025 15:40:38 +0000 Subject: landing added light mode --- src/http/landing.rs | 206 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 17 deletions(-) (limited to 'src/http') diff --git a/src/http/landing.rs b/src/http/landing.rs index 8b416f1..b978851 100644 --- a/src/http/landing.rs +++ b/src/http/landing.rs @@ -24,9 +24,136 @@ fn get_footer_script() -> &'static str { "# } +/// Generate the theme toggle HTML button +fn get_theme_toggle_html() -> &'static str { + r##""## +} + +/// Generate the theme toggle JavaScript +fn get_theme_script() -> &'static str { + r#""# +} + /// Generate the common base CSS used across all pages fn get_base_css() -> &'static str { - r#":root { + r#"/* Dark mode (default) */ + :root { + --brand: #4434FF; + --brand-light: #6b5fff; + --bg: #0a0a0f; + --surface: #12121a; + --border: #1e1e2e; + --text: #e4e4eb; + --text-muted: #a8a8bd; + --error: #ff4444; + --success: #22c55e; + --logo-bg: #4434FF; + --logo-icon: white; + } + /* Light mode - system preference */ + @media (prefers-color-scheme: light) { + :root:not([data-theme="dark"]) { + --brand: #4434FF; + --brand-light: #3525cc; + --bg: #f8f9fa; + --surface: #ffffff; + --border: #e1e4e8; + --text: #1a1a2e; + --text-muted: #586069; + --error: #dc3545; + --success: #28a745; + --logo-bg: #4434FF; + --logo-icon: white; + } + } + /* Manual light mode override */ + :root[data-theme="light"] { + --brand: #4434FF; + --brand-light: #3525cc; + --bg: #f8f9fa; + --surface: #ffffff; + --border: #e1e4e8; + --text: #1a1a2e; + --text-muted: #586069; + --error: #dc3545; + --success: #28a745; + --logo-bg: #4434FF; + --logo-icon: white; + } + /* Manual dark mode override */ + :root[data-theme="dark"] { --brand: #4434FF; --brand-light: #6b5fff; --bg: #0a0a0f; @@ -36,6 +163,8 @@ fn get_base_css() -> &'static str { --text-muted: #a8a8bd; --error: #ff4444; --success: #22c55e; + --logo-bg: #4434FF; + --logo-icon: white; } * { margin: 0; padding: 0; box-sizing: border-box; } body { @@ -44,6 +173,7 @@ fn get_base_css() -> &'static str { background: var(--bg); color: var(--text); min-height: 100vh; + transition: background-color 0.3s ease, color 0.3s ease; } a { color: var(--brand-light); text-decoration: none; } a:hover { text-decoration: underline; } @@ -55,6 +185,44 @@ fn get_base_css() -> &'static str { font-size: 0.875rem; color: var(--brand-light); } + /* Theme toggle button */ + .theme-toggle { + position: fixed; + top: 16px; + right: 16px; + z-index: 1000; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 50%; + width: 44px; + height: 44px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + } + .theme-toggle:hover { + transform: scale(1.1); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + .theme-toggle svg { + width: 20px; + height: 20px; + fill: var(--text); + transition: fill 0.3s ease; + } + .theme-toggle .sun-icon { display: none; } + .theme-toggle .moon-icon { display: block; } + :root[data-theme="light"] .theme-toggle .sun-icon, + :root:not([data-theme="dark"]) .theme-toggle .sun-icon { display: block; } + :root[data-theme="light"] .theme-toggle .moon-icon, + :root:not([data-theme="dark"]) .theme-toggle .moon-icon { display: none; } + @media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) .theme-toggle .sun-icon { display: none; } + :root:not([data-theme="light"]) .theme-toggle .moon-icon { display: block; } + } .footer { margin-top: 48px; padding-top: 24px; @@ -78,6 +246,12 @@ fn get_base_css() -> &'static str { height: 48px; flex-shrink: 0; } + .software-logo rect { + fill: var(--logo-bg); + } + .software-logo path { + fill: var(--logo-icon); + } .software-content { flex: 1; } @@ -100,22 +274,6 @@ fn get_base_css() -> &'static str { }"# } -/// Generate the software-box HTML component -fn get_software_box_html() -> &'static str { - r##"
-
- -
-

Grasp Server Powered by ngit-grasp

-

Git hosting distributed across relays using Nostr for authorization. Find out more...

-
-
-
"## -} - /// Generate the HTML landing page pub fn get_html(config: &Config) -> String { // Curation matches NIP-11 document - currently None for this relay @@ -128,6 +286,8 @@ pub fn get_html(config: &Config) -> String { relay_description = config.relay_description, version = get_version(), curation = curation, + theme_toggle = get_theme_toggle_html(), + theme_script = get_theme_script(), ) } @@ -180,6 +340,7 @@ pub fn get_generic_404_html(config: &Config, path: &str) -> String { + {theme_toggle}
404

Page Not Found

@@ -192,6 +353,7 @@ pub fn get_generic_404_html(config: &Config, path: &str) -> String {
{footer_script} + {theme_script} "##, base_css = get_base_css(), @@ -199,6 +361,8 @@ pub fn get_generic_404_html(config: &Config, path: &str) -> String { path = path, version = get_version(), footer_script = get_footer_script(), + theme_toggle = get_theme_toggle_html(), + theme_script = get_theme_script(), ) } @@ -268,6 +432,7 @@ pub fn get_404_html(config: &Config, npub: &str, identifier: &str) -> String { + {theme_toggle}
404

Repository Not Found

@@ -287,6 +452,7 @@ pub fn get_404_html(config: &Config, npub: &str, identifier: &str) -> String {
{footer_script} + {theme_script} "##, base_css = get_base_css(), @@ -295,6 +461,8 @@ pub fn get_404_html(config: &Config, npub: &str, identifier: &str) -> String { identifier = identifier, version = get_version(), footer_script = get_footer_script(), + theme_toggle = get_theme_toggle_html(), + theme_script = get_theme_script(), ) } @@ -377,6 +545,7 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String { + {theme_toggle}