commit e9af99f3d799c1c25c22c082af54be2e02a0e344
parent 3b8310f7150a42b958b2a214c60bc9869712156f
Author: Hunter
Date: Wed, 29 Jul 2026 16:44:59 -0400
smoothly transition colors when changing theme
Diffstat:
3 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/index.html b/index.html
@@ -7,6 +7,7 @@
<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="resources/style.css">
+ <script src="resources/theme.js"></script>
</head>
<body>
<div class="page">
@@ -25,7 +26,6 @@
<script src="resources/pointer.js"></script>
<script src="resources/input.js"></script>
<script src="resources/print.js"></script>
- <script src="resources/theme.js"></script>
<script src="resources/app.js"></script>
<script src="resources/pdf.js"></script>
</body>
diff --git a/resources/style.css b/resources/style.css
@@ -1,3 +1,29 @@
+/* Registered so theme swaps can be transitioned — plain custom properties don't animate.
+ Everything downstream (borders, color-mix, scrollbars) follows for free. */
+@property --desk {
+ syntax: '<color>';
+ inherits: true;
+ initial-value: #7a8520;
+}
+
+@property --page {
+ syntax: '<color>';
+ inherits: true;
+ initial-value: #fefef4;
+}
+
+@property --grid-line {
+ syntax: '<color>';
+ inherits: true;
+ initial-value: #a9cf51;
+}
+
+@property --accent {
+ syntax: '<color>';
+ inherits: true;
+ initial-value: #a81d8f;
+}
+
:root {
/* Default colors */
--white: white;
@@ -69,6 +95,19 @@
/* Set font */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+
+ --theme-transition: 250ms ease;
+ transition:
+ --desk var(--theme-transition),
+ --page var(--theme-transition),
+ --grid-line var(--theme-transition),
+ --accent var(--theme-transition);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ :root {
+ transition: none;
+ }
}
/* Theme definitions */
@@ -626,7 +665,7 @@ body.selecting .image-container {
-webkit-tap-highlight-color: transparent;
user-select: none;
-webkit-user-select: none;
- transition: transform 0.1s ease, box-shadow 0.1s ease;
+ transition: transform 0.1s ease, box-shadow 0.1s ease, color var(--theme-transition);
}
.add-images-btn:active {
diff --git a/resources/theme.js b/resources/theme.js
@@ -5,12 +5,22 @@ const themes = ['sea-breeze', 'grape-soda', 'grapefruit', 'guac', 'mojito', 'ban
const DEFAULT_THEME = 'guac';
const DEFAULT_DARK_THEME = 'pantry';
-function setTheme(theme) {
- document.documentElement.setAttribute('data-theme', theme);
+function syncThemeColorMeta() {
const backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--desk').trim();
document.querySelector('meta[name="theme-color"]').setAttribute('content', backgroundColor);
}
+function setTheme(theme) {
+ document.documentElement.setAttribute('data-theme', theme);
+ syncThemeColorMeta();
+}
+
+document.documentElement.addEventListener('transitionend', (e) => {
+ if (e.propertyName === '--desk') {
+ syncThemeColorMeta();
+ }
+});
+
function cycleTheme() {
currentThemeIndex = (currentThemeIndex + 1) % themes.length;
const newTheme = themes[currentThemeIndex];