Skip to content

Repository files navigation

Soft Focus

Open Soft Focus

TypeScript 6.0.3 Phaser 4.2.1 Vite 8.2.1

Soft Focus is a small guided-practice app for short, quiet attention resets. It offers simple visual and written cues, then gives you a place to pause, finish, and reflect.

Soft Focus is not a medical tool, a diagnosis tool, or a substitute for care from a qualified professional. It does not make health claims. It is meant to support brief personal practice in a calm, low-pressure way.

Practices

  • Phrase Anchor: choose a short phrase and return to it as a steady point of attention.
  • Moving Ball: follow a slow visual sweep with optional gaze guidance.
  • Breathing Reset: use a paced breathing cue with gentle preset rhythms.
  • Bilateral Rhythm: follow a simple left-right rhythm.
  • Orienting: look around slowly and notice what is present in the space around you.
  • Completion / Reflection: close a round, optionally write a short note, and decide what to do next.

Preferences

Soft Focus includes a few preferences for making practice feel less intense:

  • Low intensity softens the presentation where available.
  • Reduced motion uses calmer movement or guidance where available.
  • Gaze guidance can be adjusted for practices that use visual following.
  • Ambient music plays one bundled playlist of two local MP3 tracks in filename order, looping for longer practices. It is off by default; only its enabled state and volume are configurable.

Architecture

The app is a static Vite site with a DOM shell around a Phaser canvas. The welcome screen, exercise setup, preferences, recent results, completion, and reflection interactions use native DOM controls. Phaser renders the active practice, while native DOM pause/resume and stop controls and live status are positioned over the canvas for keyboard and assistive-technology access. Phaser scenes and practice presenters are loaded as dynamic Vite chunks when needed.

Keyboard Controls

During practice, the Phaser canvas controls also have keyboard fallbacks: press Space or Enter to pause or resume, and press Escape to stop the practice and move to completion.

Recent Results

Recent result metadata is saved locally on your device in this browser. Soft Focus persists the selected exercise, practice preferences, and up to five summaries containing exercise/session mode, outcome, scene, timestamps, and duration. Theme preference is stored under its own local key. Typed phrases and reflection notes remain in memory for the current page session only: they are removed from persisted summaries, legacy stored text is stripped during load, and a reload does not restore it.

You can clear saved recent results from the Recent results area.

Run Locally

Soft Focus uses Bun.

  • bun install --frozen-lockfile: install exactly the dependency graph in bun.lock; CI, deploy, release, and Vercel builds use this frozen install.
  • bun audit: check the frozen dependency graph against the current advisory database; the final local gate reports no known vulnerabilities.
  • bun run dev: start the local development server.
  • bun run build: typecheck and create a production build.
  • bun run preview: preview the production build locally.
  • bun run typecheck: run TypeScript checks.
  • bun run smoke:test: run focused smoke checks.
  • bun run validate: run typecheck, smoke checks, and a production build.
  • bun run validate:full: run full validation plus Playwright against the production preview server.
  • bun run e2e:install: install the local Chromium browser used by Playwright.
  • bun run e2e:test: run Playwright end-to-end tests against the Vite dev server.
  • bun run e2e:test:preview: build and run Playwright end-to-end tests against vite preview.

bun run smoke:test uses Node's test runner through tsx and the explicit tests/smoke.ts index. It runs the named suites ambientAudio, fullFlowSmoke, navigation, practiceRunner, practiceSceneImmediateComplete, preloadRecovery, sessionPanelActions, sessionPersistence, sessionRestartLifecycle, and themePreference.

The Playwright suites cover the session shell and full flows, breathing reset, native practice controls, keyboard behavior, reduced motion, production chunk loading, and axe accessibility scans of setup, preferences, practice, completion, and reflection. validate:full, CI, deploy, and release use the production-preview path. The final local bun audit gate reports no known vulnerabilities in the frozen graph against the current advisory database, but CI does not run an automated dependency-audit gate.

For production-preview compatibility testing, ?softFocusRenderer=canvas|webgl is a test seam; absent or unsupported values use Phaser AUTO. The suite combines geometry and ownership checks for every presenter with one shared containment pixel canary per renderer.

Deploy to Vercel

Soft Focus deploys as a static Vite app to the existing Vercel project named soft-focus.

  • Vercel settings are captured in vercel.json: Vite framework, bun install --frozen-lockfile, bun run build, and dist output.
  • vercel.json keeps / and /index.html uncached so stale HTML does not point at removed lazy chunks, while built /assets/* files use long-lived immutable caching.
  • All deployed responses receive a same-origin CSP plus MIME sniffing, referrer, framing, and permissions protections. The CSP uses an exact SHA-256 allowlist entry for the inline early-theme bootstrap, permits same-origin Vite modules and chunks, local images and MP3 media, runtime inline styles, and same-origin/blob workers without allowing external services.
  • Git-based Vercel deployments are disabled in vercel.json; production deploys are handled by the dedicated Vercel Deploy GitHub Actions workflow on pushes to main or manual workflow dispatch, matching space-explorer.
  • The workflow requires these repository secrets: VERCEL_TOKEN, VERCEL_ORG_ID, and VERCEL_PROJECT_ID.
  • Get VERCEL_ORG_ID and VERCEL_PROJECT_ID by linking the local repo to the existing Vercel project with vercel link, then reading .vercel/project.json. Keep .vercel/ local; it is ignored by git.
  • The workflow runs bun run validate, installs Playwright Chromium, runs production-preview E2E, then uses a pinned Vercel CLI for vercel pull, vercel build --prod, and vercel deploy --prebuilt --prod.

Releases

Releases are published intentionally by the manual Release GitHub Actions workflow.

  • Merges to main and direct pushes to main run CI and production deployment, but they do not create releases automatically.
  • Release requests use the Release workflow's workflow_dispatch trigger from main. The manual trigger accepts an optional version input and optional notes override. A release-${{ github.ref }} concurrency group with cancel-in-progress: false serializes release runs instead of cancelling an in-flight publication.
  • Release tags use vMAJOR.MINOR.PATCH. If no version is provided, the workflow creates v0.1.0 for the first release and then increments the latest v* patch version for later releases.
  • Release notes are generated by GitHub unless the manual notes input is provided.
  • The release workflow runs bun run validate, installs Playwright Chromium, runs bun run e2e:test:preview, and uses the repository GITHUB_TOKEN with contents: write so it can create the tag and GitHub release.

To request a release manually, ask for a release and include the version only when you want to override the automatic next patch version, for example v0.2.0. Before requesting a manual release, make sure the intended commit is on main; the workflow will run the same local validation and browser E2E checks before publishing.

About

Guided Soft Focus app for breathing, awareness, and eye movement exercises

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages