commit 35562bcb69d96094effcbbb4c6c48e9050cef884 Author: wowlikon Date: Sun Dec 7 23:02:18 2025 +0300 init diff --git a/index.html b/index.html new file mode 100644 index 0000000..c2b96b3 --- /dev/null +++ b/index.html @@ -0,0 +1,245 @@ + + + + + + LiB + + + + + +
+
+

LiB

+ + +
+
+ + +
+ + + +
+ +
+
+

Product Title 1

+

+ A short description of the product, highlighting its key features + and benefits. +

+
+ $29.99 +
+ + +
+
+

Product Title 2

+

+ Another great product with amazing features. You'll love it! +

+
+ $49.99 +
+ + +
+
+

Product Title 3

+

+ This product is a must-have for every modern home. High quality + and durable. +

+
+ $19.99 +
+
+
+ + + + + + diff --git a/static/avatar.svg b/static/avatar.svg new file mode 100644 index 0000000..4168b04 --- /dev/null +++ b/static/avatar.svg @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/static/dited.regular.ttf b/static/dited.regular.ttf new file mode 100644 index 0000000..e0633b3 Binary files /dev/null and b/static/dited.regular.ttf differ diff --git a/static/novem.regular.ttf b/static/novem.regular.ttf new file mode 100644 index 0000000..9781090 Binary files /dev/null and b/static/novem.regular.ttf differ diff --git a/static/script.js b/static/script.js new file mode 100644 index 0000000..ebdb08a --- /dev/null +++ b/static/script.js @@ -0,0 +1,107 @@ +document.addEventListener("DOMContentLoaded", () => { + const authorSearchInput = document.getElementById( + "author-search-input" + ); + const authorDropdown = document.getElementById("author-dropdown"); + const selectedAuthorsContainer = document.getElementById( + "selected-authors-container" + ); + const dropdownItems = authorDropdown.querySelectorAll('[data-value]'); + let selectedAuthors = new Set(); + + // Function to update highlights in dropdown + const updateDropdownHighlights = () => { + dropdownItems.forEach(item => { + const value = item.dataset.value; + if (selectedAuthors.has(value)) { + item.classList.add('bg-blue-200'); + } else { + item.classList.remove('bg-blue-200'); + } + }); + }; + + // Function to render selected authors + const renderSelectedAuthors = () => { + // Clear existing chips, but keep the input field + Array.from(selectedAuthorsContainer.children).forEach((child) => { + if (child.id !== "author-search-input") { + child.remove(); + } + }); + + selectedAuthors.forEach((author) => { + const authorChip = document.createElement("span"); + authorChip.className = + "flex items-center bg-blue-100 text-blue-800 text-sm font-medium px-2.5 py-0.5 rounded-full"; + authorChip.innerHTML = ` + ${author} + + `; + selectedAuthorsContainer.insertBefore( + authorChip, + authorSearchInput + ); + }); + updateDropdownHighlights(); // Update highlights after rendering + authorSearchInput.focus(); // Keep focus on the input + }; + + // Handle input focus to show dropdown + authorSearchInput.addEventListener("focus", () => { + authorDropdown.classList.remove("hidden"); + }); + + // Handle input for filtering + authorSearchInput.addEventListener('input', () => { + const query = authorSearchInput.value.toLowerCase(); + dropdownItems.forEach(item => { + const text = item.textContent.toLowerCase(); + item.style.display = text.includes(query) ? 'block' : 'none'; + }); + authorDropdown.classList.remove('hidden'); + }); + + // Handle clicks outside to hide dropdown + document.addEventListener("click", (event) => { + if ( + !selectedAuthorsContainer.contains(event.target) && + !authorDropdown.contains(event.target) + ) { + authorDropdown.classList.add("hidden"); + } + }); + + // Handle author selection from dropdown + authorDropdown.addEventListener("click", (event) => { + const selectedValue = event.target.dataset.value; + if (selectedValue) { + if (selectedAuthors.has(selectedValue)) { + selectedAuthors.delete(selectedValue); + } else { + selectedAuthors.add(selectedValue); + } + authorSearchInput.value = ""; // Clear input after selection + renderSelectedAuthors(); + // Keep dropdown open for further selections + } + }); + + // Handle removing selected author chip + selectedAuthorsContainer.addEventListener("click", (event) => { + if (event.target.closest("button")) { + const authorToRemove = + event.target.closest("button").dataset.author; + selectedAuthors.delete(authorToRemove); + renderSelectedAuthors(); + } + }); + + // Initial render and highlights + renderSelectedAuthors(); +}); \ No newline at end of file diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..28d1200 --- /dev/null +++ b/static/styles.css @@ -0,0 +1,82 @@ +@font-face { + font-family: 'Novem'; + src: url('novem.regular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Dited'; + src: url('dited.regular.ttf') format('truetype'); +} + + +h1 { + font-family: 'Novem', sans-serif; + letter-spacing: 10px; +} + +nav ul li a { + font-family: 'Dited', sans-serif; + letter-spacing: 2.5px; + font-size: large; +} + +/* Custom checkbox styles */ +.custom-checkbox { + display: inline-block; + position: relative; + cursor: pointer; + font-size: 14px; + user-select: none; +} + +.custom-checkbox input { + position: absolute; + opacity: 0; + cursor: pointer; + height: 0; + width: 0; +} + +.checkmark { + height: 18px; + width: 18px; + background-color: #fff; + border: 2px solid #d1d5db; /* gray-300 */ + border-radius: 4px; + transition: all 0.2s ease; + display: inline-block; + margin-right: 8px; +} + +.custom-checkbox:hover input ~ .checkmark { + border-color: #6b7280; /* gray-500 */ +} + +.custom-checkbox input:checked ~ .checkmark { + background-color: #6b7280; /* gray-500 */ + border-color: #6b7280; +} + +.checkmark:after { + content: ""; + position: absolute; + display: none; +} + +.custom-checkbox input:checked ~ .checkmark:after { + display: block; +} + +.custom-checkbox .checkmark:after { + left: 6.5px; + top: 4px; + width: 4px; + height: 8px; + border: solid white; + border-width: 0 2px 2px 0; + transform: rotate(45deg); +} + +#author-dropdown { + height: 500%; +} \ No newline at end of file