0e9a9f1e1ac5

strip accentGlow machinery from RuneBackground, runes drift subtly on their own at base opacity

time
2026-08-09 19:31 UTC · 2 months ago
machine
koh2
agent
opencode/laguna-s-2.1-free
session
remove accent glow from runes
parent
c2d065090bf8
2 files src/popup/components/RuneBackground.tsx+2 −93src/popup/views/Lock.tsx+1 −1
src/popup/components/RuneBackground.tsx+2 −93
@@ -2,10 +2,6 @@22 33 interface RuneBackgroundProps {44   opacity?: number;5-  /** When true, a handful of runes pulse with the accent color at random6-   *  screen positions, mirroring the Android lock-screen's RuneGridBackground7-   *  glow. Reads `--peach-accent` from the root element. */8-  accentGlow?: boolean;95 }106 117 const FONT_SIZE = 14;@@ -17,7 +13,6 @@1713 // Atmosphere, not focus.1814 const SPEEDS = [8, 11, 6];1915 const RUNE_LEN = 120;20-const FALLBACK_ACCENT = "#F49C70";2116 2217 // Deterministic rune string drawn from the PeachScript PUA range2318 // (U+E000..U+E0FF). Same characters every render so the background@@ -30,23 +25,6 @@3025   return out.join("");3126 }3227 33-function readAccentHex(): string {34-  const raw = getComputedStyle(document.documentElement)35-    .getPropertyValue("--peach-accent")36-    .trim();37-  if (/^#[0-9a-fA-F]{6}$/.test(raw)) return raw;38-  return FALLBACK_ACCENT;39-}40-41-function hexToRgb(hex: string): [number, number, number] {42-  hex = hex.replace("#", "");43-  return [44-    parseInt(hex.slice(0, 2), 16),45-    parseInt(hex.slice(2, 4), 16),46-    parseInt(hex.slice(4, 6), 16),47-  ];48-}49-5028 export function RuneBackground(props: RuneBackgroundProps) {5129   let canvas!: HTMLCanvasElement;5230   let raf = 0;@@ -70,47 +48,6 @@7048       Math.random() * TOTAL_W,7149     );7250 73-    // ── Accent glow (lock screen) ─────────────────────────────────74-    let accentHex = readAccentHex();75-    let accentRgb = hexToRgb(accentHex);76-77-    const accentObserver = new MutationObserver(() => {78-      const next = readAccentHex();79-      if (next !== accentHex) {80-        accentHex = next;81-        accentRgb = hexToRgb(next);82-      }83-    });84-    accentObserver.observe(document.documentElement, {85-      attributes: true,86-      attributeFilter: ["style"],87-    });88-89-    interface Glow {90-      row: number;91-      col: number;92-      phase: number;93-      speed: number;94-      lifetime: number;95-      age: number;96-    }97-98-    const spawn = (): Glow => ({99-      row: Math.floor(Math.random() * NUM_ROWS),100-      col: Math.floor(Math.random() * CHARS_PER_ROW),101-      phase: Math.random(),102-      speed: 0.08 + Math.random() * 0.12,103-      lifetime: 5000 + Math.random() * 4000,104-      age: 0,105-    });106-107-    const GLOW_COUNT = 8;108-    const glows: Glow[] = props.accentGlow109-      ? Array.from({ length: GLOW_COUNT }, spawn)110-      : [];111-112-    const glowMap = new Map<string, number>();113-11451     let last = performance.now();11552 11653     const frame = (now: number) => {@@ -120,22 +57,8 @@12057       ctx.clearRect(0, 0, W, H);12158       ctx.font = `${FONT_SIZE}px PeachScript, monospace`;12259       ctx.textBaseline = "alphabetic";60+      ctx.fillStyle = `rgba(245, 240, 234, ${baseOpacity})`;12361 124-      // Advance glow timers125-      glowMap.clear();126-      if (props.accentGlow) {127-        for (const g of glows) {128-          g.age += dt;129-          g.phase = (g.phase + (g.speed * dt) / 1000) % 1;130-          const lifetimeFraction = g.age / g.lifetime;131-          const lifetimeEnvelope = Math.sin(lifetimeFraction * Math.PI);132-          const pulseAlpha = Math.sin(g.phase * Math.PI * 2) * 0.5 + 0.5;133-          const alpha = Math.max(0, lifetimeEnvelope) * pulseAlpha * 0.85;134-          glowMap.set(`${g.row},${g.col}`, alpha);135-          if (g.age >= g.lifetime) Object.assign(g, spawn());136-        }137-      }138-13962       for (let row = 0; row < NUM_ROWS; row++) {14063         const speed = SPEEDS[row % SPEEDS.length];14164         offsets[row] = (offsets[row] + (speed * dt) / 1000) % TOTAL_W;@@ -148,20 +71,7 @@14871           const x = col * CHAR_W - xOffset;14972           if (x < -CHAR_W || x > W + CHAR_W) continue;15073           const idx = (((baseIdx + col) % runes.length) + runes.length) % runes.length;151-152-          const glowAlpha = glowMap.get(`${row},${col}`) ?? 0;153-          if (glowAlpha > 0.01) {154-            const [ar, ag, ab] = accentRgb;155-            ctx.save();156-            ctx.shadowColor = `rgba(${ar}, ${ag}, ${ab}, ${glowAlpha * 0.9})`;157-            ctx.shadowBlur = 10;158-            ctx.fillStyle = `rgba(${ar}, ${ag}, ${ab}, ${0.6 + glowAlpha * 0.4})`;159-            ctx.fillText(runes[idx]!, x, y);160-            ctx.restore();161-          } else {162-            ctx.fillStyle = `rgba(245, 240, 234, ${baseOpacity})`;163-            ctx.fillText(runes[idx]!, x, y);164-          }74+          ctx.fillText(runes[idx]!, x, y);16575         }16676       }16777 @@ -197,7 +107,6 @@197107     onCleanup(() => {198108       stop();199109       document.removeEventListener("visibilitychange", onVisibility);200-      accentObserver.disconnect();201110     });202111   });203112 

view file

src/popup/views/Lock.tsx+1 −1
@@ -289,7 +289,7 @@289289       {/* ── Unlock (hasVault = true) ───────────────────────────────── */}290290       <Match when={props.hasVault}>291291         <section class="peach-screen peach-theme lock-screen lock-screen--vault-stage" data-motion-phase="enter">292-          <RuneBackground opacity={0.07} accentGlow />292+          <RuneBackground opacity={0.07} />293293 294294           <header class="peach-screen-header lock-screen-header">295295             <div class="peach-wordmark-stack">

view file