]> git.amazingca.dev Git - autumn/todo/commitdiff
Add final touches
authorAmazingca <luzovich@cs.colostate.edu>
Mon, 4 May 2026 04:07:21 +0000 (22:07 -0600)
committerAmazingca <luzovich@cs.colostate.edu>
Mon, 4 May 2026 04:07:21 +0000 (22:07 -0600)
archived.html
archived.js
index.html
index.js
settings.html
settings.js
style.css

index 1cf4e009b9584b46b712e9b3b72be77e36b8e9f7..31d0acf769d00fb827504ed2b2b13991f6d2f283 100644 (file)
@@ -2,11 +2,11 @@
 <html lang="en">
   <head>
     <title>todo</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
     <link rel="stylesheet" type="text/css" href="./style.css">
     <script src="./archived.js" defer></script>
   </head>
-  <body>
+  <body class="default">
     <header>
       <div>
         <h3>todo</h3>
index 9996c476a34fe6a8a9924d2bcdd295d1b7646269..913cd04c2369defe6c6dd263efd7b80d1e84ee71 100644 (file)
@@ -105,3 +105,22 @@ const hydrateTodos = () => {
 };
 
 hydrateTodos();
+
+const updateTheme = (force = false) => {
+
+  if (theme.colorScheme != "default") {
+
+    document.getElementsByTagName("body")[0].className = theme.colorScheme;
+  }
+
+  if (theme.css != "" || force) {
+
+    const cssOverride = document.createElement("style");
+    cssOverride.setAttribute("id", "styleOverride");
+    cssOverride.innerHTML = theme.css.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+    if (document.getElementById("styleOverride")) document.getElementById("styleOverride").remove();
+    document.getElementsByTagName("head")[0].appendChild(cssOverride);
+  }
+}
+
+updateTheme();
index 915a93852d5cd3358aa97e72983c3993b1e89741..092a4ee11726778ca6ae66bf45f5dc09f987b23a 100644 (file)
@@ -2,11 +2,11 @@
 <html lang="en">
   <head>
     <title>todo</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
     <link rel="stylesheet" type="text/css" href="./style.css">
     <script src="./index.js" defer></script>
   </head>
-  <body>
+  <body class="default">
     <header>
       <div>
         <h3>todo</h3>
index 7ca7fa90ea36618af4a83cf8ca4c92b9b68299d3..8f11f5ad45d5de0675af1688c1f1efa013af0ea4 100644 (file)
--- a/index.js
+++ b/index.js
@@ -211,3 +211,22 @@ const hydrateTodos = () => {
 };
 
 hydrateTodos();
+
+const updateTheme = (force = false) => {
+
+  if (theme.colorScheme != "default") {
+
+    document.getElementsByTagName("body")[0].className = theme.colorScheme;
+  }
+
+  if (theme.css != "" || force) {
+
+    const cssOverride = document.createElement("style");
+    cssOverride.setAttribute("id", "styleOverride");
+    cssOverride.innerHTML = theme.css.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+    if (document.getElementById("styleOverride")) document.getElementById("styleOverride").remove();
+    document.getElementsByTagName("head")[0].appendChild(cssOverride);
+  }
+}
+
+updateTheme();
index 1403db17edf5ce1b502825a2d58001c0cbddd07d..a2c629bf6d7541ee6d88d0d3550bc5d9edc501b5 100644 (file)
@@ -2,11 +2,11 @@
 <html lang="en">
   <head>
     <title>todo</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
     <link rel="stylesheet" type="text/css" href="./style.css">
     <script src="./settings.js" defer></script>
   </head>
-  <body>
+  <body class="default">
     <header>
       <div>
         <h3>todo</h3>
           <p id="exportData_text">export as link</p>
         </button>
         <h3>theming</h3>
+        <div class="themes">
+          <label class="default"><input type="radio" class="themes_select" name="theme" value="default" active></label>
+          <label class="blue"><input type="radio" class="themes_select" name="theme" value="blue"></label>
+          <label class="green"><input type="radio" class="themes_select" name="theme" value="green"></label>
+          <label class="yellow"><input type="radio" class="themes_select" name="theme" value="yellow"></label>
+          <label class="red"><input type="radio" class="themes_select" name="theme" value="red"></label>
+          <label class="purple"><input type="radio" class="themes_select" name="theme" value="purple"></label>
+        </div>
         <h3>override css</h3>
         <textarea id="override_css"></textarea>
       </div>
index f2500844443c51ce497f645f12b0382036bf34d2..16233578b711e21f1be01b13b87d9d3238f73328 100644 (file)
@@ -35,7 +35,7 @@ document.getElementById("exportData").addEventListener("click", async (event) =>
 
   const exportURL = window.location.href.replace("settings.html", "") + "index.html#" + btoa(JSON.stringify(dataExport));
 
-  if (!window.navigator.userAgent.includes("Firefox")) {
+  if (!window.navigator.userAgent.includes("Firefox") && !/(Linux|Windows|Mac)/g.test(window.navigator.platform)) {
     
     try {
     
@@ -84,15 +84,43 @@ override_css.addEventListener("input", (event) => {
 
   theme.css = event.target.value;
   backupData();
-  update(true);
+  updateTheme(true);
 });
 
-const update = (force = false) => {
+const themes_select = document.getElementsByClassName("themes_select");
 
-  if (theme.colorScheme != "default") {
+for (const option of themes_select) {
 
-    document.getElementByTagName("body")[0].classList.add(theme.colorScheme);
+  option.addEventListener("click", (event) => {
+
+    if (event.target.checked) {
+
+      theme.colorScheme = event.target.getAttribute("value");
+      backupData();
+      updateTheme(true);
+    }
+  })
+}
+
+const dispatchThemesSelectUpdate = () => {
+
+  for (const option of themes_select) {
+
+    if (option.getAttribute("value") == theme.colorScheme) {
+
+     option.checked = true; 
+    }
   }
+}
+
+const updateTheme = (force = false) => {
+
+  if (theme.colorScheme != "default" || true) {
+
+    document.getElementsByTagName("body")[0].className = theme.colorScheme;
+  }
+
+  dispatchThemesSelectUpdate();
 
   if (theme.css != "" || force) {
 
@@ -106,4 +134,4 @@ const update = (force = false) => {
   }
 }
 
-update();
+updateTheme();
index 2e831461151e39bb45bc3e38e832c0bf6dc21453..d788701fc6e0559e3059f7858efa2756e43f24a5 100644 (file)
--- a/style.css
+++ b/style.css
@@ -1,8 +1,5 @@
 :root {
-  --text-primary: #000;
-  --background-primary: #fff;
-  --background-secondary: #eee;
-  --background-tertiary: #ccc;
+  color-scheme: light dark;
 }
 
 body {
@@ -12,6 +9,53 @@ body {
   color: var(--text-primary);
   background-color: var(--background-primary);
   font-family: Arial;
+  
+  --text-primary: var(--tp);
+  --background-primary: var(--bp);
+  --background-secondary: var(--bs);
+  --background-tertiary: var(--bt);
+}
+
+.default {
+  --tp: light-dark(#000, #fff);
+  --bp: light-dark(#fff, #000);
+  --bs: light-dark(#eee, #111);
+  --bt: light-dark(#ccc, #333);
+}
+
+.blue {
+  --tp: light-dark(#001, #eef);
+  --bp: light-dark(#eef, #001);
+  --bs: light-dark(#cce, #224);
+  --bt: light-dark(#99c, #559);
+}
+
+.green {
+  --tp: light-dark(#010, #efe);
+  --bp: light-dark(#efe, #010);
+  --bs: light-dark(#cec, #242); /* Maybe step by 2 in the middle, so "#232" */
+  --bt: light-dark(#9c9, #464);
+}
+
+.yellow {
+  --tp: light-dark(#110, #ffe);
+  --bp: light-dark(#ffe, #110);
+  --bs: light-dark(#eec, #442);
+  --bt: light-dark(#cc9, #664);
+}
+
+.red {
+  --tp: light-dark(#100, #fee);
+  --bp: light-dark(#fee, #100);
+  --bs: light-dark(#ecc, #422);
+  --bt: light-dark(#c99, #644);
+}
+
+.purple {
+  --tp: light-dark(#101, #fef);
+  --bp: light-dark(#fef, #101);
+  --bs: light-dark(#ece, #424);
+  --bt: light-dark(#c9c, #646);
 }
 
 h3 {
@@ -29,7 +73,7 @@ header {
     gap: 0.5rem;
   }
   & > hr {
-    border: 1px solid var(--text-primary);
+    border: 1px solid var(--background-tertiary);
   }
 }
 
@@ -44,7 +88,8 @@ nav {
   width: 100%;
   justify-content: center;
   & > div, #todos, #todos-completed, #archived {
-    width: 400px;
+    max-width: 400px;
+    width: 100%;
     display: flex;
     flex-direction: column;
     gap: 0.25rem;
@@ -55,19 +100,19 @@ todo {
   background-color: var(--background-secondary);
   border-radius: 0.5rem;
   display: flex;
-  /* align-items: center; */
   padding: 0.5rem;
   gap: 0.5rem;
   & .completion {
     cursor: pointer;
   }
   & .data {
-    flex-grow: 0.97;
+    flex-grow: 1;
     & textarea {
-      width: 100%;
+      width: -webkit-fill-available;
       resize: none;
       border: unset;
       border-radius: 0.25rem;
+      background-color: var(--background-primary);
       &:focus-visible {
         outline: unset;
       }
@@ -92,6 +137,7 @@ todo {
 }
 
 button {
+  color: var(--text-primary);
   background-color: var(--background-secondary);
   border: unset;
   border-radius: 0.5rem;
@@ -103,6 +149,38 @@ button {
   cursor: pointer;
 }
 
+.themes {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  gap: 0.5rem;
+  & > label {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex: 0 0 30%;
+    width: 40%;
+    aspect-ratio: 3 / 2;
+    background-image: linear-gradient(to right, light-dark(var(--bs), var(--tp)), light-dark(var(--tp), var(--bs)));
+    border-radius: 0.5rem;
+    border: 0.25rem solid color-mix(in oklab, var(--bs), var(--tp) 50%);
+    cursor: pointer;
+    &:active {
+      filter: brightness(75%);
+    }
+    & > input[type="radio"] {
+      accent-color: color-mix(in oklab, var(--bs), var(--tp) 50%);
+      opacity: 0;
+      margin: 0;
+    }
+    &:has(> input[type="radio"]:checked) > input[type="radio"] {
+      opacity: unset;
+      width: 2rem;
+      height: 2rem;
+    }
+  }
+}
+
 #override_css {
   font-family: monospace;
   border-radius: 0.5rem;
@@ -135,3 +213,22 @@ div:has(> #todos-completed.hidden),
 #main div:not(:has(#todos-completed.hidden)) show {
   display: none;
 }
+
+@media screen and (max-width: 400px) {
+  h3 {
+    font-size: 1.5rem !important;
+  }
+  p {
+    font-size: 1rem !important;
+  }
+  button {
+    font-size: 1rem !important;
+  }
+}
+
+@media screen and (max-width: 250px) {
+  .themes > label > input[type="radio"] {
+    width: unset !important;
+    height: unset !important;
+  }
+}