From 5d5ed1155bff36a615bbd069e5056afe6e09fffe Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 13 Aug 2025 13:14:32 -0700 Subject: [PATCH] added dark mode --- src/components/Header.astro | 8 +- src/components/Layout.astro | 107 +++++++++++++ src/styles/styles.css | 306 ++++++++++++++++++++++++++---------- 3 files changed, 341 insertions(+), 80 deletions(-) diff --git a/src/components/Header.astro b/src/components/Header.astro index f5ec109..30cec9a 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -2,7 +2,7 @@ // Header.astro ---
-
diff --git a/src/components/Layout.astro b/src/components/Layout.astro index 503d37b..2cfa0da 100644 --- a/src/components/Layout.astro +++ b/src/components/Layout.astro @@ -20,6 +20,34 @@ const { title } = Astro.props; + + + +
@@ -31,5 +59,84 @@ const { title } = Astro.props;
+ + + diff --git a/src/styles/styles.css b/src/styles/styles.css index ea0c31b..a3ee1ae 100644 --- a/src/styles/styles.css +++ b/src/styles/styles.css @@ -13,6 +13,72 @@ --light-accent4: #dd6b20; --light-border: #cbd5e0; --light-shadow: rgba(0, 0, 0, 0.1); + + /* Current theme variables (will be overridden by dark mode) */ + --current-bg: var(--light-bg); + --current-bg-soft: var(--light-bg-soft); + --current-bg-alt: var(--light-bg-alt); + --current-fg: var(--light-fg); + --current-fg-alt: var(--light-fg-alt); + --current-primary: var(--light-primary); + --current-secondary: var(--light-secondary); + --current-accent1: var(--light-accent1); + --current-accent2: var(--light-accent2); + --current-accent3: var(--light-accent3); + --current-accent4: var(--light-accent4); + --current-border: var(--light-border); + --current-shadow: var(--light-shadow); + + /* Dark theme color palette */ + --dark-bg: #1a202c; + --dark-bg-soft: #2d3748; + --dark-bg-alt: #4a5568; + --dark-fg: #f7fafc; + --dark-fg-alt: #e2e8f0; + --dark-primary: #63b3ed; + --dark-secondary: #90cdf4; + --dark-accent1: #4299e1; + --dark-accent2: #68d391; + --dark-accent3: #b794f6; + --dark-accent4: #f6ad55; + --dark-border: #4a5568; + --dark-shadow: rgba(0, 0, 0, 0.3); +} + +/* Dark theme overrides when explicitly set */ +[data-theme="dark"] { + --current-bg: var(--dark-bg); + --current-bg-soft: var(--dark-bg-soft); + --current-bg-alt: var(--dark-bg-alt); + --current-fg: var(--dark-fg); + --current-fg-alt: var(--dark-fg-alt); + --current-primary: var(--dark-primary); + --current-secondary: var(--dark-secondary); + --current-accent1: var(--dark-accent1); + --current-accent2: var(--dark-accent2); + --current-accent3: var(--dark-accent3); + --current-accent4: var(--dark-accent4); + --current-border: var(--dark-border); + --current-shadow: var(--dark-shadow); +} + +/* Auto dark mode based on system preference */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + --current-bg: var(--dark-bg); + --current-bg-soft: var(--dark-bg-soft); + --current-bg-alt: var(--dark-bg-alt); + --current-fg: var(--dark-fg); + --current-fg-alt: var(--dark-fg-alt); + --current-primary: var(--dark-primary); + --current-secondary: var(--dark-secondary); + --current-accent1: var(--dark-accent1); + --current-accent2: var(--dark-accent2); + --current-accent3: var(--dark-accent3); + --current-accent4: var(--dark-accent4); + --current-border: var(--dark-border); + --current-shadow: var(--dark-shadow); + } } * { @@ -23,19 +89,20 @@ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - background-color: var(--light-bg); - color: var(--light-fg); + background-color: var(--current-bg); + color: var(--current-fg); line-height: 1.6; + transition: background-color 0.3s ease, color 0.3s ease; } a { - color: var(--light-primary); + color: var(--current-primary); text-decoration: none; transition: color 0.3s; } a:hover { - color: var(--light-accent1); + color: var(--current-accent1); } .container { @@ -48,15 +115,17 @@ a:hover { min-height: 100vh; max-width: 1200px; margin: 0 auto; - box-shadow: 0 0 20px var(--light-shadow); + box-shadow: 0 0 20px var(--current-shadow); + transition: box-shadow 0.3s ease; } /* Header styles */ header { grid-area: header; - background-color: var(--light-primary); + background-color: var(--current-primary); padding: 1rem; - box-shadow: 0 2px 4px var(--light-shadow); + box-shadow: 0 2px 4px var(--current-shadow); + transition: background-color 0.3s ease, box-shadow 0.3s ease; } /* Navigation Menu with Dropdowns */ @@ -98,7 +167,7 @@ header { } .main-menu > li > a:hover { - color: var(--light-bg-soft); + color: var(--current-bg-soft); } /* Make sure hover state is properly triggered */ @@ -111,10 +180,10 @@ header { /* Dropdown menu */ .dropdown, .submenu { position: absolute; - background-color: white; - border: 1px solid var(--light-border); + background-color: var(--current-bg); + border: 1px solid var(--current-border); min-width: 180px; - box-shadow: 0 8px 16px var(--light-shadow); + box-shadow: 0 8px 16px var(--current-shadow); z-index: 100; opacity: 0; visibility: hidden; @@ -142,8 +211,8 @@ header { .dropdown > li > a, .submenu > li > a { padding: 0.7rem 1rem; font-size: 0.95rem; - border-bottom: 1px solid var(--light-bg-soft); - color: var(--light-fg); + border-bottom: 1px solid var(--current-bg-soft); + color: var(--current-fg); } .dropdown > li:last-child > a, .submenu > li:last-child > a { @@ -151,8 +220,8 @@ header { } .dropdown > li > a:hover, .submenu > li > a:hover { - background-color: var(--light-bg-soft); - color: var(--light-primary); + background-color: var(--current-bg-soft); + color: var(--current-primary); } /* Submenu (third level) */ @@ -179,9 +248,10 @@ header { /* Sidebar styles */ .sidebar { grid-area: sidebar; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); padding: 1.5rem; - border-right: 1px solid var(--light-border); + border-right: 1px solid var(--current-border); + transition: background-color 0.3s ease, border-color 0.3s ease; } .sidebar-section { @@ -189,16 +259,18 @@ header { } .sidebar-section h2 { - color: var(--light-primary); + color: var(--current-primary); margin-bottom: 1rem; padding-bottom: 0.5rem; - border-bottom: 1px solid var(--light-border); + border-bottom: 1px solid var(--current-border); + transition: color 0.3s ease, border-color 0.3s ease; } .news-item { margin-bottom: 1rem; padding-bottom: 1rem; - border-bottom: 1px dashed var(--light-border); + border-bottom: 1px dashed var(--current-border); + transition: border-color 0.3s ease; } .news-item:last-child { @@ -207,7 +279,8 @@ header { .news-date { font-size: 0.8rem; - color: var(--light-accent2); + color: var(--current-accent2); + transition: color 0.3s ease; } .news-title { @@ -229,32 +302,37 @@ header { content: 'ยป'; position: absolute; left: 0; - color: var(--light-accent4); + color: var(--current-accent4); + transition: color 0.3s ease; } /* Main content styles */ main { grid-area: main; padding: 2rem; - background-color: white; + background-color: var(--current-bg); + transition: background-color 0.3s ease; } .main-content h1 { - color: var(--light-primary); + color: var(--current-primary); margin-bottom: 1.5rem; font-size: 2rem; + transition: color 0.3s ease; } .main-content h2 { - color: var(--light-accent1); + color: var(--current-accent1); margin: 1.5rem 0 1rem; font-size: 1.5rem; + transition: color 0.3s ease; } .main-content h3 { - color: var(--light-secondary); + color: var(--current-secondary); margin: 1.2rem 0 0.8rem; font-size: 1.2rem; + transition: color 0.3s ease; } .main-content p { @@ -271,64 +349,70 @@ main { } .highlight { - color: var(--light-accent1); + color: var(--current-accent1); font-weight: 600; + transition: color 0.3s ease; } .cta-button { display: inline-block; - background-color: var(--light-primary); + background-color: var(--current-primary); color: white; padding: 0.7rem 1.5rem; border-radius: 4px; margin-top: 1.5rem; font-weight: 600; - transition: background-color 0.3s; + transition: all 0.3s ease; } .cta-button:hover { - background-color: var(--light-accent1); + background-color: var(--current-accent1); color: white; + transform: translateY(-1px); } .service-card { - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 4px; padding: 1.5rem; margin-bottom: 1.5rem; - border-left: 3px solid var(--light-primary); + border-left: 3px solid var(--current-primary); position: relative; + transition: all 0.3s ease; } .service-card h3 { - color: var(--light-accent2); + color: var(--current-accent2); margin-top: 0; + transition: color 0.3s ease; } .learn-more-link { display: inline-block; margin-top: 1rem; - color: var(--light-primary); + color: var(--current-primary); font-weight: 600; text-decoration: none; padding: 0.3rem 0.8rem; - border: 1px solid var(--light-primary); + border: 1px solid var(--current-primary); border-radius: 4px; transition: all 0.3s ease; } .learn-more-link:hover { - background-color: var(--light-primary); + background-color: var(--current-primary); color: white; + transform: translateY(-1px); } /* Contact page styles */ .contact-info-section { margin-bottom: 2rem; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; - border-left: 4px solid var(--light-primary); + border-left: 4px solid var(--current-primary); + transition: all 0.3s ease; } .contact-form-container { @@ -347,19 +431,28 @@ main { display: block; margin-bottom: 0.5rem; font-weight: bold; - color: var(--light-fg-alt); + color: var(--current-fg-alt); + transition: color 0.3s ease; } .form-group input, .form-group textarea { width: 100%; padding: 0.75rem; - border: 1px solid var(--light-border); + border: 1px solid var(--current-border); border-radius: 4px; font-family: inherit; font-size: 1rem; - background-color: white; - color: var(--light-fg); + background-color: var(--current-bg); + color: var(--current-fg); + transition: all 0.3s ease; +} + +.form-group input:focus, +.form-group textarea:focus { + outline: none; + border-color: var(--current-primary); + box-shadow: 0 0 0 2px rgba(99, 179, 237, 0.2); } .form-group textarea { @@ -368,39 +461,41 @@ main { .submit-button { padding: 0.75rem 1.5rem; - background-color: var(--light-primary); + background-color: var(--current-primary); color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; - transition: background-color 0.3s; + transition: all 0.3s ease; } .submit-button:hover { - background-color: var(--light-accent1); + background-color: var(--current-accent1); + transform: translateY(-1px); } .form-status { margin-top: 1rem; padding: 1rem; border-radius: 4px; + transition: all 0.3s ease; } .form-status.sending { - background-color: var(--light-bg-soft); - color: var(--light-primary); - border-left: 4px solid var(--light-primary); + background-color: var(--current-bg-soft); + color: var(--current-primary); + border-left: 4px solid var(--current-primary); } .form-status.success { - background-color: var(--light-bg-soft); - color: var(--light-accent2); - border-left: 4px solid var(--light-accent2); + background-color: var(--current-bg-soft); + color: var(--current-accent2); + border-left: 4px solid var(--current-accent2); } .form-status.error { - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); color: #e53e3e; border-left: 4px solid #e53e3e; } @@ -410,9 +505,10 @@ main { font-size: 1.2rem; margin: 1.5rem 0; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; - border-left: 4px solid var(--light-primary); + border-left: 4px solid var(--current-primary); + transition: all 0.3s ease; } .service-description { @@ -422,23 +518,26 @@ main { .service-feature { margin: 1.5rem 0; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; - box-shadow: 0 2px 4px var(--light-shadow); + box-shadow: 0 2px 4px var(--current-shadow); + transition: all 0.3s ease; } .service-feature h3 { - color: var(--light-accent2); + color: var(--current-accent2); margin-top: 0; + transition: color 0.3s ease; } .service-cta { margin: 2rem 0; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; text-align: center; - box-shadow: 0 2px 4px var(--light-shadow); + box-shadow: 0 2px 4px var(--current-shadow); + transition: all 0.3s ease; } .service-cta .cta-button { @@ -449,21 +548,22 @@ main { .intro-section, .mission-section, .services-highlight { margin-bottom: 2rem; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; - box-shadow: 0 2px 4px var(--light-shadow); + box-shadow: 0 2px 4px var(--current-shadow); + transition: all 0.3s ease; } .intro-section { - border-left: 4px solid var(--light-primary); + border-left: 4px solid var(--current-primary); } .mission-section { - border-left: 4px solid var(--light-accent3); + border-left: 4px solid var(--current-accent3); } .services-highlight { - border-left: 4px solid var(--light-accent2); + border-left: 4px solid var(--current-accent2); } .cta-container { @@ -473,45 +573,82 @@ main { } .cta-button.secondary { - background-color: var(--light-secondary); + background-color: var(--current-secondary); } .cta-button.secondary:hover { - background-color: var(--light-accent1); + background-color: var(--current-accent1); } /* About page specific styles */ .vision-mission-section, .privacy-section, .concepts-section { margin: 2rem 0; padding: 1.5rem; - background-color: var(--light-bg-soft); + background-color: var(--current-bg-soft); border-radius: 5px; - box-shadow: 0 2px 4px var(--light-shadow); + box-shadow: 0 2px 4px var(--current-shadow); + transition: all 0.3s ease; } .vision-mission-section { - border-left: 4px solid var(--light-accent4); + border-left: 4px solid var(--current-accent4); } .privacy-section { - border-left: 4px solid var(--light-accent3); + border-left: 4px solid var(--current-accent3); } .concepts-section { - border-left: 4px solid var(--light-primary); + border-left: 4px solid var(--current-primary); } .concept-card { margin-bottom: 1rem; padding: 1rem; - background-color: white; + background-color: var(--current-bg); border-radius: 4px; - box-shadow: 0 1px 3px var(--light-shadow); + box-shadow: 0 1px 3px var(--current-shadow); + transition: all 0.3s ease; } .concept-card h3 { - color: var(--light-accent2); + color: var(--current-accent2); margin-top: 0; + transition: color 0.3s ease; +} + +/* Theme toggle button */ +.theme-toggle { + background: none; + border: 2px solid rgba(255, 255, 255, 0.3); + color: white; + padding: 0.5rem 0.75rem; + border-radius: 8px; + cursor: pointer; + font-size: 0.9rem; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 0.5rem; + margin-left: 1rem; +} + +.theme-toggle:hover { + border-color: rgba(255, 255, 255, 0.6); + background-color: rgba(255, 255, 255, 0.1); + transform: translateY(-1px); +} + +.theme-toggle:active { + transform: translateY(0); +} + +/* Navigation container for header layout */ +.nav-container { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; } /* Back to Top Button */ @@ -519,7 +656,7 @@ main { position: fixed; bottom: 2rem; right: 2rem; - background-color: var(--light-primary); + background-color: var(--current-primary); color: white; width: 3rem; height: 3rem; @@ -533,7 +670,7 @@ main { opacity: 0; visibility: hidden; transition: all 0.3s ease; - box-shadow: 0 2px 5px var(--light-shadow); + box-shadow: 0 2px 5px var(--current-shadow); z-index: 1000; } @@ -543,9 +680,10 @@ main { } .back-to-top:hover { - background-color: var(--light-accent1); + background-color: var(--current-accent1); transform: translateY(-3px); } + @media (max-width: 768px) { .container { grid-template-columns: 1fr; @@ -557,10 +695,15 @@ main { .sidebar { border-right: none; - border-top: 1px solid var(--light-border); + border-top: 1px solid var(--current-border); } /* Mobile menu adjustments */ + .nav-container { + flex-direction: column; + gap: 1rem; + } + .main-menu { flex-direction: column; align-items: center; @@ -589,7 +732,7 @@ main { width: 100%; display: none; box-shadow: none; - border-left: 2px solid var(--light-accent2); + border-left: 2px solid var(--current-accent2); opacity: 1; visibility: visible; } @@ -601,4 +744,9 @@ main { .cta-container { flex-direction: column; } + + .theme-toggle { + margin-left: 0; + margin-top: 0.5rem; + } }