feat(glass): per-scheme background images + glass-over-image mode

Land the UAT-approved backdrop direction as a real feature (replacing the dev
thumbnail prototype):
- 6 generated abstract SVG backdrops in public/backdrops/, one tuned to each
  accent scheme (dark, mixed-colour, few light areas). Non-figurative + generated
  = repo-safe, tiny, accent-matched.
- New data-backdrop="on" state (dark theme + the setting + not perf) paints the
  per-scheme image on <body> (app root now transparent so it shows app-wide and
  the glass refracts it) AND switches the glass to its translucent tier (the
  user's tuned values: surface 50 / card 60 / scrim 30 / blur 10 / edge 25).
  Off / light / perf -> flat colour + solid glass (the readable fallback).
- Settings > Appearance 'Background image' toggle (bgImage pref, dark-only),
  trilingual. Flat is the fallback + opt-out.
- Remove the FeedBackdrop prototype + its tuner controls; tuner baseline resynced
  to the glass-over-image tier, add a Backdrop-fade slider.
GOTCHA fixed: the dark-mode ambient 'background' shorthand reset background-size
to auto (image rendered un-covered); out-specified it with [data-theme="dark"].
This commit is contained in:
npeter83 2026-07-12 21:20:40 +02:00
parent 036e2fe7ea
commit f9f90cf609
15 changed files with 191 additions and 162 deletions

View file

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 1000" preserveAspectRatio="xMidYMid slice">
<defs>
<radialGradient id="a" cx="20%" cy="18%" r="55%"><stop offset="0%" stop-color="#7a4d18" stop-opacity=".95"/><stop offset="100%" stop-color="#7a4d18" stop-opacity="0"/></radialGradient>
<radialGradient id="b" cx="86%" cy="26%" r="52%"><stop offset="0%" stop-color="#e8913c" stop-opacity=".45"/><stop offset="100%" stop-color="#e8913c" stop-opacity="0"/></radialGradient>
<radialGradient id="c" cx="68%" cy="92%" r="60%"><stop offset="0%" stop-color="#5a2f14" stop-opacity=".9"/><stop offset="100%" stop-color="#5a2f14" stop-opacity="0"/></radialGradient>
<radialGradient id="d" cx="8%" cy="88%" r="55%"><stop offset="0%" stop-color="#403820" stop-opacity=".85"/><stop offset="100%" stop-color="#403820" stop-opacity="0"/></radialGradient>
<filter id="s"><feGaussianBlur stdDeviation="60"/></filter>
<filter id="g"><feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="2" stitchTiles="stitch"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .5 0"/></filter>
</defs>
<rect width="1600" height="1000" fill="#141009"/>
<g filter="url(#s)">
<rect width="1600" height="1000" fill="url(#a)"/>
<rect width="1600" height="1000" fill="url(#c)"/>
<rect width="1600" height="1000" fill="url(#d)"/>
<rect width="1600" height="1000" fill="url(#b)"/>
</g>
<rect width="1600" height="1000" filter="url(#g)" opacity="0.05"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB