🐾 Latch ?

Guide › Customise

Customise your experience

Everything adjustable lives on one Settings page — the clock, the stamps, each module's rules and editors — plus a handful of environment variables for the instance itself.

/settings is the one place every rule and every editor lives. The play pages stay clean and carry a ⚙ that jumps to the right section. Each section here has a 📖 back to this page.

Clock

  • Quick-adjust buttons — the four ± buttons on the dashboard, in minutes, comma-separated. Default 15,60,360,1440. Any count works; four fit the row best.
  • Undo window — how far back undo reaches, in minutes. Default 15; 0 means no limit. Stamped photos quote the clock as it was, which is why the default is short.

Stamps

  • Stamped photo layout — auto (by aspect ratio), or bar Hairline · hero Collar · badge Tag · dossier Case File · rail Strip. See Photos.
  • Stamped photo: stats to overlay — an ordered list of token ids. Default streak_current,tasks_verified,session_id,session_task.
  • Case File grid — the tokens the dossier layout lays out in its grid.
  • Session recap card — the tokens in the recap card's grid. Default base_seconds,adjust_seconds,frozen_seconds,sess_tasks,sess_spins,sess_photos.
  • Share card — the grid on a right now card. Default time_locked_d,streak_current,level,tasks_verified,total_locked,sessions_n.
  • Share card, the last stretch — the grid on a week card. Every id here is from the window group, because a grid mixing "3 locks this week" with "41 locks ever" is a grid nobody can read once the labels are abbreviated to fit. Default win_sessions,win_tasks,win_spins,win_reflections,win_photos,win_xp.
  • Share card, one badge — the grid on a milestone card, resolved as the numbers stood when the badge was earned. Default total_locked,streak_current,level,sessions_n,tasks_verified,longest_lock.
  • Share card: theme — which palette a share card starts in: midnight (the app's own colours), steel, moss, sapphire, amethyst, gold, plate. See Themes.

These are the starting lists. The Share page can add, remove and reorder stats for one card without touching any of them — the choice lives in the link.

A token that has no value at that moment (a session token on a photo taken while unlocked, a rate on a one-day-old log, a window token on a card that has no window) is simply dropped, so a list can be generous.

Token reference

Group Token Prints
moment date_long · time_hm · datetime_full · weekday when the photo was taken
moment status LOCKED / FROZEN / TIME SERVED / UNLOCKED at that moment
session time_locked · time_locked_d elapsed in the lock (short / with days)
session day_n · day_n_cal day N of the lock (by 24 h / by calendar day)
session time_remaining · pct_served to go · percent served
session base_seconds the sentence — hidden while a hidden lock runs
session adjust_seconds · frozen_seconds net adjustments · time frozen
session session_id · session_task lock number · the task this photo verified
session sess_tasks · sess_spins · sess_photos · sess_xp counts inside this lock
lifetime total_locked · sessions_n · longest_lock lifetime locked · locks · longest
lifetime tasks_verified · tasks_failed training done / failed
lifetime reflections_n · checkins_n · spins_n · photos_n counts
lifetime time_added · time_removed totals
streak streak_current · streak_best days
rate tasks_per_week · task_fails_per_week · spins_per_week · locks_per_week per week
rate reflect_days_per_week · checkin_days_per_week · reflect_compliance days per week · % of locked days reflected
rate locked_hours_per_week · locked_pct_28d hours per week · % of the last 28 days
game level · rank · xp as of that moment
window win_days · win_locked · win_locked_pct the span · locked in it · % of it
window win_active_days · win_sessions days with something logged · locks begun
window win_tasks · win_task_fails · win_spins counts inside the span
window win_photos · win_reflections · win_checkins · win_badges counts inside the span
window win_xp · win_added · win_removed xp earned · time added · time removed

Every value is computed as of the photo's timestamp — see the overlay is as-of the shutter.

The window group is the exception, and the only one that reads two moments: it counts what happened between them. Those tokens only mean anything on a week share card, so everywhere else they say nothing and are left out — the same treatment as a stat that has no value yet, rather than a zero that would claim a quiet week.

Activities

An activity is a thing you want to count — reflections, sits, walkies, anything. Latch ships with a starter set and you can add your own at the bottom of Settings.

The important part: an activity selects events you already have. It is a lens over your log, not a second log. Add one today and it is filled in from your whole history immediately — and removing one deletes nothing, because it never owned any of those events in the first place.

Each activity has:

  • icon and colour — the colour is what the Calendar draws. Two activities should not share one, or a day's colours stop telling you what you did.
  • slug — lower-case, no spaces. It becomes an event kind and the tail of five stat ids, so it is the one field worth thinking about before you save.
  • match module / match kind — which events belong to this activity. Leave module blank for any; put several kinds in, comma-separated, to fold them together. Both blank matches nothing, deliberately — a blank activity that matched everything would quietly claim your entire log.
  • streak — what a run is judged against: | cadence | a run continues while | |---|---| | daily | you do it every day. Today is grace — an empty today does not break it | | weekly_n | every week carries target separate days or more. The current week is grace | | every_n_days | you never leave a gap bigger than target days | | none | this has no streak, and none is shown | That last row is not a cop-out. A wheel-spin counter has no run to break, so showing it a 0 would be claiming one was broken.
  • time from — where "time doing this" is read: entry (headspace), media (recordings), trance (sits), kit (bouts), habit (a hand-logged, timed or calendar-imported bout — see Habits). Blank means this has no duration, and none is shown rather than 0s.
  • one-tap button — gives it a button on the dashboard and puts it on the Habits page, where it can be logged with minutes, run on a timer, or fed from a calendar. A habit is an activity with this ticked.
  • xp — awarded for a log made within two days of the thing happening. Older logs count everywhere and earn nothing.

Tracking something Latch already does? Put that module's kind in match kind and untick one-tap button. Tracking something of your own? Leave match module as activity, set match kind to your slug, tick one-tap button, and set time from to habit if minutes matter — or just add it from the Habits page, which fills those in for you.

The five stats every activity gets

Saving an activity adds five ids to the token lists above, with no restart:

id prints absent when
since_<slug> how long since the last one it has never happened — never 0s, which would read as just now
days_<slug> days you have done it — (a genuine 0 is printed)
streak_<slug> the current run its cadence is none
total_<slug> time spent doing it it declares no time from
count_<slug> how many altogether —

So a new activity is shareable the moment it exists: put streak_walkies in the share-card list and it appears. The full list of ids your instance has right now is at the bottom of the Activities section in Settings.

Handler

The name, the reflection minimums, the check-in cadence, the missed-day penalty, and the whole prompt library. Full detail on The Handler. Three presets, if you want a starting point:

Gentle Firm (default) Strict
Minimum reflection 60 chars 120 300
Check-in every 8 h 4 h 2 h
Missed-reflection penalty 0 min 30 120
Minimum spoken reflection 15 s 30 60

Then rewrite the prompts in the voice you want. The seeded lines are firm but clean; the library is where the Handler's personality lives.

Wheel

The cooldown (minutes; 0 while testing) and the segment table — label, weight, effect, value, colour, enabled. See Wheel of Fortune.

Training

The default deadline for a task that has none (hours, default 24) and the task library — rewards, penalties, XP, photo required, per-task deadline, enabled. See Training.

Display name and other instance settings

These are environment variables on the container, not fields on the page:

Variable Meaning Default
LATCH_APP_NAME the name in the header, the tab title, the footer Latch
LATCH_TZ the timezone every date is shown in and every when is typed in (events are stored as UTC epochs) America/Detroit
LATCH_API_TOKEN the bearer token for /api/v1. Empty means the API is off. (empty)
LATCH_TICK_SECONDS how often the scheduler sweeps freezes and deadlines 30
LATCH_DATA_DIR where the database and media live /data in the container
LATCH_DOCS_DIR where this guide's markdown lives /app/docs in the container

Set them in .env next to docker-compose.yml and recreate the container. Renaming the app is a one-line change: LATCH_APP_NAME=Kennel.

Themes

There is one look — dark, game-like, no build pipeline. app/latch/web/static/style.css is a single file with CSS variables at the top (--accent, --accent2, --cyan, --bg) if you want to fork the palette. A theme system and a curated gallery look are on the roadmap.

This page is docs/customise.md in the repo. Spotted a mistake? Tell us how to report it →