From 970972b01bcd5720bd5d41e0979197b313018469 Mon Sep 17 00:00:00 2001 From: Ben Boonstra Date: Sun, 20 Oct 2024 23:36:26 -0500 Subject: [PATCH] Complete landing page [docs] --- docs/docs/docs.css | 0 docs/home.css | 83 +++++++++++++++++++++++++++++ docs/home.js | 108 +++++++++++++++++++++++++++++++++++++ docs/index.html | 44 ++++++++++++++-- docs/styles.css | 84 +++++++++++++++++++++++++---- docs/templating.js | 129 +++++++++++++++++++++++++++++++++------------ 6 files changed, 400 insertions(+), 48 deletions(-) create mode 100644 docs/docs/docs.css create mode 100644 docs/home.css create mode 100644 docs/home.js diff --git a/docs/docs/docs.css b/docs/docs/docs.css new file mode 100644 index 0000000..e69de29 diff --git a/docs/home.css b/docs/home.css new file mode 100644 index 0000000..cdee485 --- /dev/null +++ b/docs/home.css @@ -0,0 +1,83 @@ +html, +body { + height: 100%; /* Ensure the body takes full height */ + overflow: hidden; /* Prevent default scrolling */ +} + +.section { + height: 100vh; /* Each section takes full viewport height */ + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + scroll-snap-align: start; /* Align sections for snapping */ + padding: 20px; + text-align: center; +} + +.section * { + max-width: 80%; +} + +.section h2 { + font-size: 2rem; + margin-bottom: 1rem; +} + +.section p { + font-size: 1.2rem; + margin: 0.5rem 0; +} + +.section ul { + list-style-type: none; + padding: 0; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +.section ul li { + font-size: 1.1rem; + margin: 0.5rem 0; + text-align: center; + width: 100%; +} + +.cta-button { + background-color: var(--background-color); + color: var(--text-color); + padding: 10px 20px; + text-decoration: none; + border-radius: 5px; + transition: background-color 0.3s; +} + +.cta-button:hover { + background-color: color-mix(in srgb, var(--hover-color) 80%, var(--effortless-white)); +} + +.arrow { + font-size: 2rem; + color: var(--primary-color); + cursor: pointer; + position: fixed; + z-index: 1000; + opacity: 0; + transition: opacity 0.3s ease, color 0.3s ease; +} +.up-arrow { + top: 90px; + left: 50%; + transform: translateX(-50%); +} +.down-arrow { + bottom: 20px; + left: 50%; + transform: translateX(-50%); +} + +.show { + opacity: 1; +} diff --git a/docs/home.js b/docs/home.js new file mode 100644 index 0000000..2ca156a --- /dev/null +++ b/docs/home.js @@ -0,0 +1,108 @@ +document.addEventListener("templateConstructed", function () { + const sections = document.querySelectorAll(".section"); + const upArrow = document.getElementById("upArrow"); + const downArrow = document.getElementById("downArrow"); + let currentSection = 0; + let isScrolling = false; + let scrollTimer = null; + + function updateSectionColors() { + sections.forEach((section, index) => { + section.style.backgroundColor = + index % 2 === 0 + ? "var(--background-color)" + : "var(--effortless-blue)"; + }); + } + + function updateArrowColors() { + var currentSectionColor = getComputedStyle(sections[currentSection]).backgroundColor; + var backgroundColorHex = getComputedStyle(document.documentElement).getPropertyValue("--background-color").trim(); + var backgroundColorRgb = hexToRgb(backgroundColorHex); + console.log(currentSectionColor); + var arrowColor = currentSectionColor === backgroundColorRgb + ? "var(--primary-color)" + : "var(--background-color)"; + + upArrow.style.color = arrowColor; + downArrow.style.color = arrowColor; + } + + function updateArrowVisibility() { + upArrow.classList.toggle("show", currentSection > 0); + downArrow.classList.toggle("show", currentSection < sections.length - 1); + } + + function scrollToSection(index) { + if (index < 0 || index >= sections.length || isScrolling) return; + + sections[index].scrollIntoView({ behavior: "smooth" }); + isScrolling = true; + setTimeout(() => { + isScrolling = false; + currentSection = index; + updateArrowVisibility(); + updateArrowColors(); + }, 750); + } + + function handleScroll(direction) { + const newSection = currentSection + direction; + scrollToSection(newSection); + } + + function queueScroll(direction) { + if (!scrollTimer) { + handleScroll(direction); + } + clearTimeout(scrollTimer); + scrollTimer = setTimeout(() => { + scrollTimer = null; + }, 50); + } + + window.addEventListener("wheel", (event) => { + const direction = event.deltaY > 0 ? 1 : -1; + queueScroll(direction); + }); + + let touchStartY = 0; + window.addEventListener("touchstart", (event) => { + touchStartY = event.touches[0].clientY; + }); + + window.addEventListener("touchmove", (event) => { + const touchEndY = event.touches[0].clientY; + const difference = touchStartY - touchEndY; + if (Math.abs(difference) > 50) { + const direction = difference > 0 ? 1 : -1; + queueScroll(direction); + } + }); + + window.addEventListener("keydown", (event) => { + if (event.key === "ArrowUp") { + handleScroll(-1); + } else if (event.key === "ArrowDown") { + handleScroll(1); + } + }); + + upArrow.addEventListener("click", () => handleScroll(-1)); + downArrow.addEventListener("click", () => handleScroll(1)); + updateSectionColors(); + setTimeout(() => { + updateArrowVisibility(); + updateArrowColors(); + }, 750); +}); + +// Helper function to convert hex to rgb +function hexToRgb(hex) { + hex = hex.replace(/^#/, ""); + var bigint = parseInt(hex, 16); + var r = (bigint >> 16) & 255; + var g = (bigint >> 8) & 255; + var b = bigint & 255; + return `rgb(${r}, ${g}, ${b})`; +} diff --git a/docs/index.html b/docs/index.html index 3bd0c52..31a547b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,12 +5,50 @@ Effortless - Home + + -
+
+
-

Databases should be Effortless.

-
+

Databases should be Effortless.

+ +
+

What is Effortless?

+

Effortless is a user-friendly database solution designed to simplify data management for everyone. It's a powerful tool that makes working with databases accessible to beginners while providing advanced features for experienced developers.

+
+
+

Why Choose Effortless?

+

Effortless stands out from other database solutions for several reasons:

+ +
+
+

Who Can Benefit from Effortless?

+

Effortless is designed for a wide range of users, including:

+ +
+
+

Getting Started

+

Getting started with Effortless is simple. While it's primarily a Python library, its concepts can be understood by anyone interested in data management. For those ready to dive in, Effortless can be installed and set up in just a few minutes.

+
+
+

Join the Effortless Community

+

Become part of the growing Effortless community. Share your experiences, ask questions, and contribute to the development of this innovative database solution.

+ Get Involved +
+
diff --git a/docs/styles.css b/docs/styles.css index 1790010..8cc3938 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -1,14 +1,28 @@ +@import url("https://fonts.googleapis.com/css2?family=Exo:ital,wght@1,100&display=swap"); + :root { + --effortless-blue: #6a8eff; + --effortless-gray: #373737; + --effortless-white: #f4f4f4; --primary-color: #6a8eff; + --header-color: #6a8eff; --secondary-color: #373737; --text-color: #373737; + --hover-color: #6a8eff; --background-color: #f4f4f4; + --navbar-color: #373737; --sidebar-width: 20%; --sidebar-collapsed-width: 0px; + --feature-font: "Exo", sans-serif; + --body-font: "Arial", sans-serif; /* Add your body font here */ +} + +* { /* Change colors smoothly for theme changes */ + transition: color 0.3s ease, background-color 0.3s ease; } body { - font-family: "Arial", sans-serif; + font-family: var(--body-font); /* Use the body font */ line-height: 1.6; color: var(--text-color); background-color: var(--background-color); @@ -18,7 +32,7 @@ body { } nav { - background-color: var(--secondary-color); + background-color: var(--navbar-color); padding: 1rem; display: flex; justify-content: space-between; @@ -47,11 +61,10 @@ nav ul li a { color: white; text-decoration: none; font-weight: bold; - transition: color 0.3s ease; } nav ul li a:hover { - color: var(--primary-color); + color: var(--hover-color); } main { @@ -64,16 +77,18 @@ h1, h2, h3 { color: var(--secondary-color); + font-family: var(--feature-font); text-align: center; } -.effortless { +.feature { + font-family: var(--feature-font); /* Use the feature font */ font-size: 2.5rem; text-align: center; margin-bottom: 2rem; } -.effortless i { +.feature i { color: var(--primary-color); } @@ -119,22 +134,24 @@ a:hover { top: 0; bottom: 0; width: var(--sidebar-width); - background-color: var(--text-color); - color: var(--background-color); - padding: 1rem; + background-color: var(--navbar-color); + color: var(--text-color); + padding: 0px; padding-top: 5rem; overflow-y: auto; transition: all 0.3s ease; z-index: 999; + border-right: 2px solid var(--navbar-color); + box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1); } #sidebar.collapsed { width: var(--sidebar-collapsed-width); padding: 0; + border: none; } -#sidebar.collapsed h3, -#sidebar.collapsed ul { +#sidebar.collapsed * { display: none; } @@ -142,6 +159,21 @@ a:hover { color: var(--background-color); } +#sidebar ul { + display: flex; /* Use flexbox for the ul */ + flex-direction: column; /* Stack items vertically */ + align-items: center; /* Center items horizontally */ + padding: 0; /* Remove default padding */ + margin: 0; /* Remove default margin */ +} + +#sidebar ul li { + width: 100%; /* Make li take full width */ + text-align: center; /* Center text within li */ + margin: 0.5rem 0; /* Add some vertical spacing between items */ + list-style: none; +} + main { padding: 1rem; } @@ -169,3 +201,33 @@ main { pointer-events: none; } } + +#themeToggle { + background: none; + border: none; + color: var(--text-color); + font-size: 1.5rem; + cursor: pointer; + margin-top: 1rem; +} + +#themeToggle:hover { + color: var(--primary-color); +} + +/* Add this to your existing styles.css */ +.dropdown { + display: none; + list-style-type: none; + padding-left: 1rem; +} + +.dropdown-toggle { + cursor: pointer; + color: var(--header-color); + font-weight: bold; +} + +.dropdown-toggle:hover { + text-decoration: underline; +} diff --git a/docs/templating.js b/docs/templating.js index bbfbef1..1d7da6f 100644 --- a/docs/templating.js +++ b/docs/templating.js @@ -4,7 +4,7 @@ document.addEventListener("DOMContentLoaded", function () { @@ -13,13 +13,23 @@ document.addEventListener("DOMContentLoaded", function () { const sidebar = ` `; @@ -29,30 +39,20 @@ document.addEventListener("DOMContentLoaded", function () { const sidebarToggle = document.getElementById("sidebarToggle"); const sidebarElement = document.getElementById("sidebar"); const body = document.body; + const themeToggle = document.getElementById("themeToggle"); function updateToggleButton() { - if (window.innerWidth <= 768) { - sidebarToggle.textContent = sidebarElement.classList.contains( - "active" - ) - ? "×" - : "☰"; - } else { - sidebarToggle.textContent = sidebarElement.classList.contains( - "collapsed" - ) - ? "☰" - : "▼"; - } - sidebarToggle.classList.toggle( - "open", - sidebarElement.classList.contains("active") || - !sidebarElement.classList.contains("collapsed") - ); + const isMobile = window.innerWidth <= 768; + sidebarToggle.textContent = isMobile + ? (sidebarElement.classList.contains("active") ? "×" : "☰") + : (sidebarElement.classList.contains("collapsed") ? "☰" : "▼"); + sidebarToggle.classList.toggle("open", + sidebarElement.classList.contains("active") || !sidebarElement.classList.contains("collapsed")); } - sidebarToggle.addEventListener("click", function () { - if (window.innerWidth <= 768) { + function toggleSidebar() { + const isMobile = window.innerWidth <= 768; + if (isMobile) { sidebarElement.classList.toggle("active"); body.classList.toggle("sidebar-active"); } else { @@ -60,20 +60,81 @@ document.addEventListener("DOMContentLoaded", function () { body.classList.toggle("sidebar-collapsed"); } updateToggleButton(); - }); + } - // Handle window resize - window.addEventListener("resize", function () { - if (window.innerWidth > 768) { - sidebarElement.classList.remove("active"); - body.classList.remove("sidebar-active"); - } else { + function handleResize() { + const isMobile = window.innerWidth <= 768; + if (isMobile) { sidebarElement.classList.remove("collapsed"); body.classList.remove("sidebar-collapsed"); + } else { + sidebarElement.classList.remove("active"); + sidebarElement.classList.add("collapsed"); + body.classList.remove("sidebar-active"); + body.classList.add("sidebar-collapsed"); } updateToggleButton(); + } + + sidebarToggle.addEventListener("click", toggleSidebar); + window.addEventListener("resize", handleResize); + + handleResize(); + + let currentTheme = localStorage.getItem("theme") || "dark"; + document.documentElement.setAttribute("data-theme", currentTheme); + + function updateTheme(theme) { + const themeProperties = { + dark: { + "--background-color": "var(--effortless-gray)", + "--text-color": "var(--effortless-white)", + "--secondary-color": "var(--effortless-white)", + "--navbar-color": "var(--effortless-blue)", + "--header-color": "var(--effortless-white)", + "--hover-color": "var(--effortless-gray)", + icon: "☀️" + }, + light: { + "--background-color": "var(--effortless-white)", + "--text-color": "var(--effortless-gray)", + "--secondary-color": "var(--effortless-gray)", + "--navbar-color": "var(--effortless-gray)", + "--header-color": "var(--effortless-blue)", + "--hover-color": "var(--effortless-blue)", + icon: "🌙" + } + }; + + const properties = themeProperties[theme]; + Object.entries(properties).forEach(([property, value]) => { + if (property !== "icon") { + document.documentElement.style.setProperty(property, value); + } + }); + themeToggle.textContent = properties.icon; + } + + function toggleTheme() { + currentTheme = currentTheme === "light" ? "dark" : "light"; + document.documentElement.setAttribute("data-theme", currentTheme); + updateTheme(currentTheme); + localStorage.setItem("theme", currentTheme); + } + + themeToggle.addEventListener("click", toggleTheme); + + document.querySelectorAll(".dropdown-toggle").forEach(toggle => { + toggle.addEventListener("click", function() { + const dropdown = this.nextElementSibling; + dropdown.style.display = dropdown.style.display === "block" ? "none" : "block"; + }); }); - // Initial button state + updateTheme(currentTheme); updateToggleButton(); + + setTimeout(() => { + document.dispatchEvent(new Event('templateConstructed')); + }, 100); });