aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-04-22 09:09:27 +0530
committerBobby <[email protected]>2026-04-22 09:09:27 +0530
commitbbb8a51490f98dfc02ab9a0fd79248806c80e705 (patch)
tree3ab7941d74eaff2b01990f42a253d9c02b9d1196
parent2c89a4173b5705e329d6a1e1dbdb408ac5a43811 (diff)
downloadhollowdark-bbb8a51490f98dfc02ab9a0fd79248806c80e705.tar.xz
hollowdark-bbb8a51490f98dfc02ab9a0fd79248806c80e705.zip
Expand Settings with Display and About sections and a reduce-motion override for the leaf scene
-rw-r--r--lib/components/LeafScene.svelte5
-rw-r--r--lib/display/state.ts9
-rw-r--r--lib/screens/SettingsScreen.svelte57
3 files changed, 70 insertions, 1 deletions
diff --git a/lib/components/LeafScene.svelte b/lib/components/LeafScene.svelte
index d60b555..53dce6b 100644
--- a/lib/components/LeafScene.svelte
+++ b/lib/components/LeafScene.svelte
@@ -1,6 +1,7 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte'
import { createRNG } from '@hollowdark/rng/seeded'
+ import { reduceMotion } from '@hollowdark/lib/display/state'
import { LEAF_VARIANTS } from '@hollowdark/lib/leaves/variants'
import { spawnLeaf } from '@hollowdark/lib/leaves/spawn'
import { isLeafOffscreen, stepLeaf } from '@hollowdark/lib/leaves/physics'
@@ -17,7 +18,7 @@
const rng = createRNG(Math.floor(performance.now() * 1000) | 0)
- let container: HTMLDivElement | null = null
+ let container: HTMLDivElement | null = $state(null)
let scene: SceneDimensions = $state({ width: 0, height: 0, groundY: 0 })
let leaves: Leaf[] = $state([])
let wind: WindSystem = $state(initialWindSystem(rng))
@@ -92,6 +93,7 @@
})
</script>
+{#if !$reduceMotion}
<div class="leaf-scene" bind:this={container} aria-hidden="true">
<svg class="defs" width="0" height="0" focusable="false">
<defs>
@@ -139,6 +141,7 @@
</svg>
{/each}
</div>
+{/if}
<style>
.leaf-scene {
diff --git a/lib/display/state.ts b/lib/display/state.ts
new file mode 100644
index 0000000..d768e6c
--- /dev/null
+++ b/lib/display/state.ts
@@ -0,0 +1,9 @@
+import { writable, type Writable } from 'svelte/store'
+
+/**
+ * User-facing override for motion-heavy visuals. When true, the leaf
+ * scene is suppressed and long transitions are skipped even on systems
+ * that do not signal `prefers-reduced-motion`. The CSS media query still
+ * applies independently — this store only strengthens it.
+ */
+export const reduceMotion: Writable<boolean> = writable(false)
diff --git a/lib/screens/SettingsScreen.svelte b/lib/screens/SettingsScreen.svelte
index 3d502f1..434b9c9 100644
--- a/lib/screens/SettingsScreen.svelte
+++ b/lib/screens/SettingsScreen.svelte
@@ -2,6 +2,8 @@
import Slider from '@hollowdark/lib/components/Slider.svelte'
import ToggleSwitch from '@hollowdark/lib/components/ToggleSwitch.svelte'
import { ambientVolume, masterMuted } from '@hollowdark/lib/audio/state'
+ import { reduceMotion } from '@hollowdark/lib/display/state'
+ import { APP_VERSION_FULL } from '@hollowdark/lib/version/version'
interface Props {
onBack: () => void
@@ -18,6 +20,10 @@
function setVolume(next: number): void {
ambientVolume.set(next)
}
+
+ function setReduceMotion(next: boolean): void {
+ reduceMotion.set(next)
+ }
</script>
<section class="settings">
@@ -56,6 +62,35 @@
</div>
</div>
</section>
+
+ <section class="group">
+ <h2 class="group-label">Display</h2>
+
+ <div class="row">
+ <div class="row-label">
+ <p class="row-name">Reduce motion</p>
+ <p class="row-hint">
+ Hide the falling leaves and trim long transitions. Overrides
+ the system preference.
+ </p>
+ </div>
+ <ToggleSwitch
+ value={$reduceMotion}
+ label="Reduce motion"
+ onChange={setReduceMotion}
+ />
+ </div>
+ </section>
+
+ <section class="group">
+ <h2 class="group-label">About</h2>
+
+ <div class="about">
+ <p class="about-title">Hollowdark</p>
+ <p class="about-line">Version {APP_VERSION_FULL}</p>
+ <p class="about-line">A literary life simulation.</p>
+ </div>
+ </section>
</div>
</section>
@@ -163,4 +198,26 @@
min-width: 3.5ch;
text-align: right;
}
+
+ .about {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1);
+ padding: var(--space-3) 0;
+ }
+
+ .about-title {
+ font-family: var(--font-body);
+ font-size: var(--text-md);
+ font-style: italic;
+ color: var(--color-text);
+ margin: 0;
+ }
+
+ .about-line {
+ font-family: var(--font-ui);
+ font-size: var(--text-sm);
+ color: var(--color-text-tertiary);
+ margin: 0;
+ }
</style>