3cd2c71bbf8d

fix light theme and rune density — transparent canvas, 8% density, theme-aware idle color

time
2026-04-28 05:38 UTC · 6 months ago
machine
koh2
parent
7581d519f206
3 files src/popup/components/LockRuneCanvas.tsx+27 −12src/popup/styles/popup.css+15 −6src/popup/styles/vars.css+2 −0
src/popup/components/LockRuneCanvas.tsx+27 −12
@@ -7,11 +7,12 @@77 const SPEEDS = [5, 7, 4];88 const GLOW_COUNT = 2;99 const FALLBACK_ACCENT = "#F49C70";10+const FALLBACK_RUNE_IDLE = "rgba(245,240,234,0.16)";1011 11-// 30% of string positions are runes; the rest are null (skipped in draw).12-// Same cyclic-scroll mechanic as RuneCanvas — no isolated-character weirdness.12+// 8% of string positions are runes; the rest are null (skipped).13+// Cyclic-scroll mechanic identical to RuneCanvas — smooth, not jumpy.1314 const RUNE_STRING_LEN = 80;14-const DENSITY = 0.30;15+const DENSITY = 0.08;1516 const RUNE_STRING: (string | null)[] = Array.from(1617   { length: RUNE_STRING_LEN },1718   (_, i) => {@@ -29,6 +30,14 @@2930   return FALLBACK_ACCENT;3031 }3132 33+function readRuneIdleColor(): string {34+  return (35+    getComputedStyle(document.documentElement)36+      .getPropertyValue("--peach-rune-idle")37+      .trim() || FALLBACK_RUNE_IDLE38+  );39+}40+3241 export function LockRuneCanvas() {3342   let canvas!: HTMLCanvasElement;3443 @@ -37,6 +46,7 @@3746     if (!ctx) return;3847 3948     let accentRgb: [number, number, number] = [0xf4, 0x9c, 0x70];49+    let runeIdleColor = readRuneIdleColor();4050 4151     function setAccent(hex: string) {4252       accentRgb = [@@ -48,10 +58,14 @@4858 4959     setAccent(readAccentHex());5060 51-    const accentObserver = new MutationObserver(() => setAccent(readAccentHex()));52-    accentObserver.observe(document.documentElement, {61+    // Watch both style (accent color) and class (light/dark theme) changes62+    const observer = new MutationObserver(() => {63+      setAccent(readAccentHex());64+      runeIdleColor = readRuneIdleColor();65+    });66+    observer.observe(document.documentElement, {5367       attributes: true,54-      attributeFilter: ["style"],68+      attributeFilter: ["style", "class"],5569     });5670 5771     const W = canvas.offsetWidth || 360;@@ -96,9 +110,8 @@96110       const dt = Math.min(now - lastTime, 64);97111       lastTime = now;98112 113+      // Transparent canvas — CSS handles the lock screen background per theme99114       ctx.clearRect(0, 0, W, H);100-      ctx.fillStyle = "#1a1410";101-      ctx.fillRect(0, 0, W, H);102115       ctx.font = `${FONT_SIZE}px PeachScript, monospace`;103116       ctx.textBaseline = "alphabetic";104117 @@ -124,9 +137,11 @@124137           if (x < -CELL_W || x > W + CELL_W) continue;125138 126139           const baseIdx = Math.floor(offsets[row] / CELL_W);127-          const strIdx = (((baseIdx + col) % RUNE_STRING_LEN) + RUNE_STRING_LEN) % RUNE_STRING_LEN;140+          const strIdx =141+            (((baseIdx + col) % RUNE_STRING_LEN) + RUNE_STRING_LEN) %142+            RUNE_STRING_LEN;128143           const char = RUNE_STRING[strIdx];129-          if (!char) continue; // sparse position — blank144+          if (!char) continue;130145 131146           const glowA = glowMap.get(`${row},${col}`) ?? 0;132147 @@ -138,7 +153,7 @@138153             ctx.fillText(char, x, y);139154             ctx.restore();140155           } else {141-            ctx.fillStyle = "rgba(245,240,234,0.18)";156+            ctx.fillStyle = runeIdleColor;142157             ctx.fillText(char, x, y);143158           }144159         }@@ -170,7 +185,7 @@170185 171186     onCleanup(() => {172187       stop();173-      accentObserver.disconnect();188+      observer.disconnect();174189       document.removeEventListener("visibilitychange", onVisibility);175190     });176191   });

view file

src/popup/styles/popup.css+15 −6
@@ -3364,8 +3364,9 @@33643364   }33653365 }33663366 3367-/* Lock panel inherits its own border-radius and box-shadow on top of glass */3367+/* Lock panel keeps its own border-radius over the generic glass token */33683368 .peach-lock-panel.peach-glass {3369+  border-radius: 18px;33693370   background: rgba(26, 20, 16, 0.65);33703371   border: 1px solid rgba(255, 255, 255, 0.08);33713372   box-shadow:@@ -3373,6 +3374,15 @@33733374     0 12px 28px rgba(0, 0, 0, 0.3);33743375 }33753376 3377+.light .peach-lock-panel.peach-glass,3378+[data-theme="light"] .peach-lock-panel.peach-glass {3379+  background: rgba(238, 227, 204, 0.75);3380+  border: 1px solid rgba(34, 24, 9, 0.10);3381+  box-shadow:3382+    inset 0 1px 0 rgba(255, 255, 255, 0.5),3383+    0 8px 24px rgba(80, 56, 32, 0.15);3384+}3385+33763386 @supports not (backdrop-filter: blur(1px)) {33773387   .peach-lock-panel.peach-glass {33783388     background: rgba(26, 20, 16, 0.92);@@ -3380,6 +3390,10 @@33803390       inset 0 1px 0 rgba(255, 255, 255, 0.05),33813391       0 12px 28px rgba(0, 0, 0, 0.4);33823392   }3393+  .light .peach-lock-panel.peach-glass,3394+  [data-theme="light"] .peach-lock-panel.peach-glass {3395+    background: rgba(238, 227, 204, 0.96);3396+  }33833397 }33843398 33853399 .peach-lock-panel--secondary {@@ -5867,10 +5881,5 @@58675881       ellipse at 30% 20%,58685882       color-mix(in srgb, var(--peach-accent) 8%, transparent) 0%,58695883       transparent 60%5870-    ),5871-    radial-gradient(5872-      ellipse at 70% 80%,5873-      rgba(30, 20, 10, 0.6) 0%,5874-      transparent 50%58755884     );58765885 }

view file

src/popup/styles/vars.css+2 −0
@@ -146,6 +146,7 @@146146   --peach-dur-500: 500ms;147147   --peach-dur-600: 600ms;148148   --peach-copy-clear: 1.4s;149+  --peach-rune-idle: rgba(245, 240, 234, 0.16);149150 }150151 151152 .light {@@ -168,6 +169,7 @@168169   --shell-accent-a: color-mix(in srgb, var(--peach-accent) 6%, transparent);169170   --shell-accent-b: color-mix(in srgb, var(--peach-accent) 3%, transparent);170171   --copy-shadow: 0 2px 8px rgba(80, 56, 32, 0.10), 0 14px 48px rgba(80, 56, 32, 0.10), 0 0 0 1px rgba(28,25,21,0.05);172+  --peach-rune-idle: rgba(34, 24, 9, 0.16);171173 }172174 173175 /* ─── Display font choice ──────────────────────────────────────────────

view file