commit b80a92005534b902ebbcac93958ee88b7eaf54c2
parent 59e85e2dee1a3ec6b5fee383e9e89d0b9941cb6d
Author: Hunter
Date: Tue, 21 Oct 2025 17:42:54 -0400
new feature: press F2 to cycle interface themes
Diffstat:
| M | index.html | | | 3 | ++- |
| M | script.js | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | style.css | | | 143 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
3 files changed, 168 insertions(+), 29 deletions(-)
diff --git a/index.html b/index.html
@@ -1,8 +1,9 @@
<!DOCTYPE html>
-<html lang="en">
+<html lang="en" data-theme="sky">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="theme-color" content="#a3d5ff">
<title>memori</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>✂️</text></svg>">
<link rel="stylesheet" href="style.css">
diff --git a/script.js b/script.js
@@ -639,3 +639,54 @@ window.addEventListener('afterprint', () => {
});
});
});
+
+// Theme system
+let currentThemeIndex = 0;
+let isF2Pressed = false;
+const themes = ['sea-breeze', 'grape-soda', 'coral', 'guac', 'mojito', 'toast'];
+
+function setTheme(theme) {
+ document.documentElement.setAttribute('data-theme', theme);
+ const backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--desk').trim();
+ document.querySelector('meta[name="theme-color"]').setAttribute('content', backgroundColor);
+}
+
+function cycleTheme() {
+ currentThemeIndex = (currentThemeIndex + 1) % themes.length;
+ const newTheme = themes[currentThemeIndex];
+ setTheme(newTheme);
+ saveThemeToLocalStorage(newTheme);
+}
+
+function saveThemeToLocalStorage(theme) {
+ localStorage.setItem('memori-theme', theme);
+}
+
+function loadThemeFromLocalStorage() {
+ const savedTheme = localStorage.getItem('memori-theme');
+ if (savedTheme && themes.includes(savedTheme)) {
+ currentThemeIndex = themes.indexOf(savedTheme);
+ setTheme(savedTheme);
+ } else {
+ // Use default theme
+ setTheme(themes[0]);
+ }
+}
+
+// F2 key handler for theme cycling
+document.addEventListener('keydown', (e) => {
+ if (e.key === 'F2' && !isF2Pressed) {
+ e.preventDefault();
+ isF2Pressed = true;
+ cycleTheme();
+ }
+});
+
+document.addEventListener('keyup', (e) => {
+ if (e.key === 'F2') {
+ isF2Pressed = false;
+ }
+});
+
+// Load theme on page load
+loadThemeFromLocalStorage();
diff --git a/style.css b/style.css
@@ -1,11 +1,47 @@
+/* Named color palette and default theme */
:root {
- --color-bg-body: #f5f5f0;
- --color-bg-page: #fafaf8;
- --color-grid-line: #d0d0d0;
- --color-accent: #79aeea;
- --color-white: white;
+ /* Default colors */
+ --white: white;
+ --black: black;
+ --default-grid: #d0d0d0;
--shadow: #00000044;
+ /* guac theme colors */
+ --onion: #a81d8f;
+ --garlic: #fefef4;
+ --lime: #a9cf51;
+ --avocado: #7a8520;
+
+ /* toast theme colors */
+ --butter: #ffe598;
+ --cream: #fffef9;
+ --crumb: #decca3;
+ --peanut-butter: #be852a;
+
+ /* mojito theme colors */
+ --mint: #9febaa;
+ --soda: #f8fffe;
+ --zest: #9ee3ad;
+ --watermelon: #f8599b;
+
+ /* grape-soda theme colors */
+ --natural-flavors: #d4c5f9;
+ --effervescence: #f9f7ff;
+ --concentrate: #b8a9dd;
+ --syrup: #7c5cbe;
+
+ /* coral theme colors */
+ --reef: #ff9b87;
+ --pearl: #fff8f6;
+ --sand: #f0bcb3;
+ --anemone: #ff6b51;
+
+ /* sea-breeze theme colors */
+ --cerulean: #a3d5ff;
+ --mist: #f7fcff;
+ --horizon: #85c0f5;
+ --lagoon: #2196f3;
+
/* Grid configuration */
--grid-cols: 50;
--grid-rows: 66;
@@ -16,6 +52,58 @@
/* Grid as percentage of page: 200/216 = 92.59%, 264/279.4 = 94.48% */
--grid-width-percent: 92.59%;
--grid-height-percent: 94.48%;
+
+ /* Default theme (sea-breeze) */
+ --desk: var(--cerulean);
+ --page: var(--mist);
+ --grid-line: var(--horizon);
+ --accent: var(--lagoon);
+
+ /* Set text color for all themes */
+ color: var(--white);
+}
+
+/* Theme definitions */
+:root[data-theme="guac"] {
+ --desk: var(--avocado);
+ --page: var(--garlic);
+ --grid-line: var(--lime);
+ --accent: var(--onion);
+}
+
+:root[data-theme="toast"] {
+ --desk: var(--butter);
+ --page: var(--cream);
+ --grid-line: var(--crumb);
+ --accent: var(--peanut-butter);
+}
+
+:root[data-theme="mojito"] {
+ --desk: var(--mint);
+ --page: var(--soda);
+ --grid-line: var(--zest);
+ --accent: var(--watermelon);
+}
+
+:root[data-theme="grape-soda"] {
+ --desk: var(--natural-flavors);
+ --page: var(--effervescence);
+ --grid-line: var(--concentrate);
+ --accent: var(--syrup);
+}
+
+:root[data-theme="coral"] {
+ --desk: var(--reef);
+ --page: var(--pearl);
+ --grid-line: var(--sand);
+ --accent: var(--anemone);
+}
+
+:root[data-theme="sea-breeze"] {
+ --desk: var(--cerulean);
+ --page: var(--mist);
+ --grid-line: var(--horizon);
+ --accent: var(--lagoon);
}
* {
@@ -25,7 +113,7 @@
}
body {
- background: var(--color-bg-body);
+ background: var(--desk);
display: flex;
justify-content: center;
align-items: flex-start;
@@ -40,9 +128,9 @@ body {
width: 100%;
/* Maintain 8.5:11 aspect ratio (11/8.5 = 1.294117647) */
aspect-ratio: 8.5 / 11;
- background: var(--color-bg-page);
+ background: var(--page);
position: relative;
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ box-shadow: 0 8px 24px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08);
display: flex;
align-items: center;
justify-content: center;
@@ -65,19 +153,19 @@ body {
width: 100%;
height: 100%;
box-sizing: border-box;
- border-right: 1px dashed var(--color-grid-line);
- border-bottom: 1px dashed var(--color-grid-line);
+ border-right: 1px dashed var(--grid-line);
+ border-bottom: 1px dashed var(--grid-line);
margin: 0;
padding: 0;
display: block;
}
.grid-cell:nth-child(-n+50) {
- border-top: 1px dashed var(--color-grid-line);
+ border-top: 1px dashed var(--grid-line);
}
.grid-cell:nth-child(50n+1) {
- border-left: 1px dashed var(--color-grid-line);
+ border-left: 1px dashed var(--grid-line);
}
.image-container {
@@ -86,7 +174,7 @@ body {
outline: 2px solid transparent;
outline-offset: -2px;
transition: outline-color 0.2s;
- background: var(--color-bg-page);
+ background: var(--page);
}
.image-container::after {
@@ -113,7 +201,7 @@ body {
}
.image-container:hover::after {
- border-color: var(--color-accent);
+ border-color: var(--accent);
}
.image-container.dragging {
@@ -121,11 +209,11 @@ body {
}
.image-container.dragging::after {
- border-color: var(--color-accent);
+ border-color: var(--accent);
}
.image-container.resizing::after {
- border-color: var(--color-accent);
+ border-color: var(--accent);
}
body.resizing *,
@@ -145,7 +233,7 @@ body.dragging * {
.resize-handle {
position: absolute;
- background: var(--color-accent);
+ background: var(--accent);
opacity: 0;
transition: opacity 0.2s;
z-index: 2;
@@ -157,14 +245,13 @@ body.dragging * {
.dimension-label {
position: absolute;
- background: var(--color-accent);
- color: var(--color-white);
+ background: var(--accent);
+ color: var(--text);
padding: 4px 10px;
border-radius: 12px;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
font-weight: 500;
- text-shadow: 1px 1px 1px var(--shadow);
line-height: 1;
opacity: 0;
transition: opacity 0.2s;
@@ -202,7 +289,7 @@ body.dragging * {
position: absolute;
width: 10px;
height: 10px;
- background: var(--color-accent);
+ background: var(--accent);
border-radius: 50%;
}
@@ -234,7 +321,7 @@ body.dragging * {
}
body {
- background: var(--color-white);
+ background: var(--white);
padding: 0;
margin: 0;
display: block;
@@ -249,7 +336,7 @@ body.dragging * {
box-shadow: none;
margin: 0;
padding: 0;
- background: var(--color-white);
+ background: var(--white);
display: flex !important;
align-items: center !important;
justify-content: center !important;
@@ -266,8 +353,8 @@ body.dragging * {
}
.grid-cell {
- border-right: 1px dashed var(--color-grid-line) !important;
- border-bottom: 1px dashed var(--color-grid-line) !important;
+ border-right: 1px dashed var(--default-grid) !important;
+ border-bottom: 1px dashed var(--default-grid) !important;
box-sizing: border-box !important;
width: 100% !important;
height: 100% !important;
@@ -276,17 +363,17 @@ body.dragging * {
}
.grid-cell:nth-child(-n+50) {
- border-top: 1px dashed var(--color-grid-line) !important;
+ border-top: 1px dashed var(--default-grid) !important;
}
.grid-cell:nth-child(50n+1) {
- border-left: 1px dashed var(--color-grid-line) !important;
+ border-left: 1px dashed var(--default-grid) !important;
}
.image-container {
outline: none !important;
position: absolute !important;
- background: var(--color-white) !important;
+ background: var(--white) !important;
/* Recalculate positions using cell coordinates and print cell size */
left: calc(var(--x-cell) * var(--cell-size-mm)) !important;
top: calc(var(--y-cell) * var(--cell-size-mm)) !important;