All notable changes to Gothic Lock Breaker are documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Release rule: bump VERSION in src/version.js, add a dated entry below,
and update the Current release line in README.md — one commit, one deploy.
- Footer Discuss on Reddit link back to the r/worldofgothic launch thread (community channel for updates), with a monochrome Snoo icon.
- Stacked full-width footer action rows: All locks, Report an issue, and Discuss on Reddit.
- Version + last-updated footer row is one changelog link (whole pill clickable) with an explicit accessible name.
- Browse locks: the search + place-filter row clipped off-screen on phone-width viewports (the filter dropdown was partly unreachable) — the overlay's grid track now resolves to the real viewport width instead of the sheet's own content width.
- Crawlable lock catalog at
/locks/— named in-game locks grouped by place, each linking into the solver via?lock=. - Web app manifest for home-screen install.
- JSON-LD freshness (
dateModified) and stronger authority signals (press, Reddit, author URL). - Visible "Updated" date and "All locks" link in the footer.
- Sitemap and
llms.txtnow include the lock catalog URL.
- Returning players now see a "NEW" badge on Browse locks until they open it.
- Internal catalog bootstrap tooling and unused entry fields. Catalog data remains the checked-in first-party JSON.
- Browse locks: open a searchable catalog of named in-game locks, filter by place, load one into the solver, and deep-link with
?lock=<id>. - When a catalog lock would replace mapped work or an active solution, confirm before overwriting.
- After loading from the catalog, The Sequence panel shows the lock name and place.
- Browse locks and Reset lock use clear icons; on narrow screens they collapse to icon-only buttons on the same row as the lock-count pills.
- Catalog place filter is a single dropdown (not a wall of chips), with result count and Clear filters / Retry recovery actions.
- Reset lock now opens its confirm dialog again.
- Choosing a catalog lock while you already have work no longer looks like a dead tap — the replace confirm was rendering behind the sheet.
- Minimizing The Sequence no longer shows
[object Object]in the step counter.
- Community feedback routing: GitHub Discussions replaced with the r/worldofgothic launch thread in README, CONTRIBUTING, and issue templates.
- GitHub issue templates for bugs, translation fixes, and feature ideas — footer Report an issue opens the chooser; the translation banner links straight to the translation form.
- CONTRIBUTING.md — where to report problems, privacy rules (no lock URL in issues), and how to open a PR.
- README adds a Feedback & issues section (templates, Discussions, Ko-fi).
- "NEW" badges now flag recently-added features for returning players: if a feature shipped after your first visit, its button wears a small "NEW" pill until you open it. First-time visitors don't see them, so the cue only points at what's genuinely new to you. The keyboard shortcuts panel is the first feature to carry one.
- Full keyboard control: map a lock without touching the mouse — arrow keys move the start hole and cycle a coupling, number keys set the start hole directly, and you can switch plates, break the lock, and tab between controls all from the keyboard.
- Keyboard navigation for the solution walkthrough — step forward and back through the moves with the arrow keys.
- A "Keyboard shortcuts" help panel, reachable from a header hint or a shortcut key, listing every walkthrough and mapping shortcut.
- Internal-only restructure of the source tree into cohesive subsystems and a split of the single stylesheet into cascade-ordered partials. No gameplay, solver, UI, or URL changes — this release exists purely as a clean rollback point for the reorganization.
- Polished the step-by-step sequence: the current turn now shows as a large, prominent step number alongside a clear "X / total" counter, and finishing every turn plays a small animated open-lock icon instead of a plain done count.
- Removed the redundant turn-count banner above the walkthrough; the solve result is now announced to screen readers as you reach it.
- Moved the "something feels off?" help link onto its own row beneath the current move so it no longer crowds the step counter.
- The thank-you / support prompt now appears once you're most of the way through a walkthrough rather than the instant a solution loads, so it lands after the tool has actually helped you.
- Lock-position warnings now use border style as well as color — a thick solid ring when a pin is against a wall and a dashed ring as it approaches one — so the danger cue stays visible for colorblind players.
- Hovering your selected camp banner now shows the camp's name in a styled Gothic tooltip that matches the rest of the header, instead of the browser's plain default tooltip.
- Refreshed the screaming Nameless Hero portrait (the face that appears when you hover the camp banner) and matched its styling to the calm face, dropping an inconsistent shadow.
- The Nameless Hero portrait no longer flickers while swapping from the calm to the screaming face on hover.
- The camp banners (Old, New, and Swamp Camp) now render at higher resolution, so they stay crisp on high-DPI / Retina screens instead of looking soft.
- Refreshed the Old Camp, New Camp, and Swamp Camp banner artwork with higher-detail designs.
- The camp picker now speaks in faction terms — "Join a camp", "Choose your camp", "Join the Old Camp", "Leave the camps" — instead of the old generic "theme" wording.
- The neutral (no camp) banner is brighter so it clearly reads as a tappable control rather than a disabled placeholder.
- The "pick your camp" nudge now reappears on later visits (up to three sessions) until you open the picker, stays visible a little longer, and no longer disappears the instant you scroll on mobile.
- Hovering the Swamp Camp banner no longer floods it with green — the glow now stays as a clean outer halo, keeping the banner readable.
- Removed the "share this lock" feature. Usage data showed it was effectively dead — only ~0.7% of players who solved a lock ever copied a share link — so the post-solve share button and its prompt are gone. Solving, the step-by-step walkthrough, language switching, and opening a shared link someone sends you all keep working.
- Fixed a rare crash that could occur when changing the language while the language menu was still open, which left the picker briefly unresponsive.
- Trimmed background usage analytics to a leaner set of events so the tool stays comfortably within its usage limits. No effect on solving, sharing, the step-by-step walkthrough, mastery selection, or language handling.
- The donate buttons now show a short hint on hover explaining that an optional tip keeps the solver free and ad-free.
- Shortened the support prompt shown after you solve a lock to a brief "keeps it free & ad-free" line, so it stays out of the way of the turn sequence.
- Corrected the Ukrainian wording describing how plates are positioned in the How-to-map guide.
- German, Polish, and Ukrainian now have their own dedicated pages at
/de/,/pl/, and/uk/, with translated titles, descriptions, and content baked into the HTML at build time. Search engines and AI tools can index the localized pages directly, so players land on a page already in their language instead of the English one.
- Visiting
/de/,/pl/, or/uk/now keeps the page in that language after it finishes loading, instead of briefly showing the translation and then snapping back to English.
- Lock artwork, camp banners, and the How-to-map diagram no longer appear broken on the German and Polish pages.
- The How-to-map diagram's callout labels (for example "Lock 6 · back") no longer overflow the image or overlap each other when shown in German or Polish.
- Error reporting no longer treats bare "No response" promise rejections — background noise from browser extensions and aborted requests — as real errors, so the error feed stays focused on genuine app failures.
- Retuned the neutral, no-camp look from warm bronze/gold to a calmer steel-grey, giving the default state its own identity instead of borrowing the Old Camp's gold.
- Translucent accents — glows, hover fills, focus rings — now follow the active camp's colour everywhere, so switching camps re-tints the whole UI consistently instead of leaving stray gold highlights.
- Warmed and brightened the Old Camp gold so its palette reads as distinctly Old Camp.
- A one-time, gentle hint now points out that the neutral header banner is a clickable camp theme switcher: the pennant softly pulses and its tip swaps to "Pick your camp" so first-time visitors notice the feature. It shows only when no camp is picked, never competes with the onboarding tour or the solve coachmark, and disappears for good once you interact with it or choose a camp. Localized across English, German, Polish, and Ukrainian.
- The camp banner picker is now a proper centered dialog: a dark scrim dims the page, each faction's banner shows under its name, and hovering a banner lights it with that camp's own colour so a pick feels deliberate. Leaving the camps is now its own blank-pennant "No Camp" banner instead of a stray text button, so the choices read as one coherent rack. Keyboard and focus handling are tighter — Escape and outside clicks close it, and focus returns to the trigger. Localized across English, German, Polish, and Ukrainian.
- Refreshed the Old Camp, New Camp, and neutral banner artwork.
- A camp banner theme switcher in the header: pick the Old Camp, New Camp, or Swamp Camp and the whole site re-tints to that faction's colours, with a smooth transition. Your choice is remembered between visits. The neutral state shows the Nameless Hero, who mutters his predicament on hover ("Damn... I belong to no camp?") and opens the camp picker when clicked. Camp names and all picker labels are localized across English, German, Polish, and Ukrainian.
- The page title and description now lead with "Lockpick Solver" — matching how players actually search — instead of calling the tool a "calculator" it explicitly out-performs.
- Error reporting no longer leaks known browser and extension noise that arrives with a PostHog
Error:/TypeError:type prefix — ignore patterns now match both the bare message and the prefixed form.
- The "share this lock" prompt now appears at most once per visit, and only after a genuinely tricky solve (a long solution, or a lock you cracked after a dead end) — instead of after every solve. Its button is honest about what it does ("Copy link for a friend"), the prompt reads "Stuck friend? Copy this exact lock and send it to them.", and it lays out cleanly without clipping the label. Localized across English, German, Polish, and Ukrainian. The post-solve tip-ore button is unaffected.
- Before a lock is solved, the mapping instructions no longer repeat themselves — you now see a single, concise hint instead of two near-identical lines.
- The help sections — How to map your lock, Lockpicking Guide, and About this tool — now open as centered modal dialogs with their own title and close (×) button, and the button you clicked stays in place instead of turning into the modal and disappearing. Close via the × button, the backdrop, or Escape. Added a localized Close label across English, German, Polish, and Ukrainian.
- The info icon in the About this tool button is now optically centered with its all-caps label.
- On phones the language dropdown is no longer hidden behind the lock — the menu now renders above it.
- The in-app Lockpicking Guide is no longer a wall of text. Couplings are now a With / Against / None definition list, the puzzle mechanics and hard-lock tips are scannable bullet lists, and each section is separated for easier reading. Body copy uses higher contrast and looser line spacing. Localized across English, German, Polish, and Ukrainian.
- On phones the Sequence panel stays hidden until you actually map a lock (set a coupling or move a pin), so the bottom bar no longer takes up space before there's anything to solve. It now rises into view instead of popping in.
- A partially mapped lock no longer claims "Lock mapped — crack it open." The ready hint only shows once the lock is fully mapped; partial maps keep the mapping guidance.
- Gothic language dropdown — the four flag buttons collapse into a single accessible listbox showing the active flag and short code (EN / DE / PL / UKR), with full keyboard support (arrow keys, Home/End, Enter, Escape, Tab) and screen-reader labels.
- Help sections open as modals — "How to map your lock" and the Lockpicking Guide now overlay the page instead of pushing it down, with a more distinguished circular close button.
- Consistent hover feedback across every interactive control — pills, link chips, holes, the Break/Next buttons, and the help links — on pointer devices.
- Header language dropdown, tip-ore button, and version badge aligned to a uniform height and spacing.
- Tumbler reference moved to a per-card legend; the Tumblers panel note rewritten as a scannable bullet list.
- New header portrait beside the Sleeper: a Gothic medallion that swaps to a screaming face on hover with the taunt "Really? Is that all you got?" (localized for German, Polish, and Ukrainian), linking to the tip jar.
- Header definition text brightened to full parchment for better contrast against the backdrop.
- Section titles dropped the Roman-numeral prefixes (I/II/III) to cut visual noise.
- Lockpicking tier description reformatted from a paragraph into a scannable bullet list.
- "Wipe lock" control relabeled Reset lock with a text button (no more ambiguous trash icon); confirm dialog copy updated to match.
- Sequence Share and Tip ore moved to their own full-width row, keeping text labels so they no longer truncate on mobile.
- Onboarding spotlight no longer throws when the tour is skipped or advanced during mobile scroll (
Cannot set properties of null (setting 'hidden')). - PostHog error tracking drops DuckDuckGo iOS
WKWebViewpostMessage noise via abefore_sendexception filter (defense in depth on top of client-side ignore rules).
- Lighthouse CI on pull requests — builds
dist/and gates SEO score (≥ 90); reports accessibility, performance, and best-practices as warnings.
- Invalid
aria-expandedon the sequence panel<section>(PageSpeed / Agentic Browsing). - Support-link accessible names — footer uses visible copy; header ore link keeps
aria-labelwhen the label is hidden on mobile. - Coupling chip contrast for the unset (
link-none) state. - Layout shift on first paint — reserve space for six default tumbler cards before JS hydrates
#tumblers.
- In-app Gothic Remake Lockpicking Guide — collapsed reference in II · Tumblers (puzzle mechanics, couplings, skill tiers, trainer, edge-safe solving, hard-lock tips); static HTML for crawlers, localized in en/de/pl/ukr.
- Visible inline H1 in the header definition sentence (replaces hidden sr-only title).
- Footer FAQ trimmed to four product questions under About this tool; game-mechanic Q&As live in the lockpicking guide instead.
llms.txt— lockpicking guide summary for AI crawlers; FAQ aligned with footer.<html lang="en">(wasen-GB); SEO checks for guide section, visible H1, and footer FAQ count.
- Sequence Share and Tip ore — hidden until a solve returns steps (no longer shown on the empty pre-solve panel).
- Sequence section — Share and Tip ore stay visible in the header as compact side-by-side pills; post-solve gratitude banner and dismiss removed.
- Share button label — "Share" in EN and "Teilen" in DE (was "Share link" / "Link teilen").
- Header and footer donation buttons — subtle blue glow on the ore and button chrome.
- Minimized sequence walkthrough — small top padding below header actions.
- Header Sleeper easter egg — slow red ember sparks around the medallion rim on idle, larger on hover when the Sleeper wakes; sparks sit behind the icon so they never cover the face.
- Header Sleeper icon — larger on desktop (128px); mobile size unchanged.
- Mobile header donation ore — icon-only (no pill chrome), aligned with locale switcher, larger tap target.
- Minimized Sequence minibar ore — moved to header icon row (first position), matches expand/clear tool styling.
- Minibar ore visibility — same eligibility as post-solve gratitude strip (share + donate); ore is the minimized mobile fallback.
- Gratitude-strip donation link opens Ko-fi via native navigation instead of a popup-blocked
window.open. - PostHog error capture filters password-manager extension noise (
standardSelectors).
- Post-solve gratitude strip — centered headline, icon dismiss, stacked share/donate CTAs, shorter copy in all locales.
- Ore donation buttons (header, footer, minibar, gratitude) share hover lift and ore shimmer; share link gets link-icon wiggle on hover.
- Graduated solve gate — block solve on empty mapping, amber warning on partial mapping,
mapping_completenessanalytics. - Post-solve gratitude strip in The Sequence — one-time share link + donation CTA with minibar ore fallback on mobile walkthrough.
- Onboarding tour step 5 targeting Break the Lock; hash-failure coachmark for shared locks that do not solve.
- Analytics:
support_surface_shown,hash_banner_shown,translation_feedback_clicked,locale_auto_applied; donationplate_count/locale; sharelanding_type. - German locale suggest from browser language before geo resolves.
- Fixed spotlight ring overlay for solve-button coachmarks (avoids breaking sticky mobile layout).
- Failure alerts persist until the next solve attempt; OOB failures get the same recovery CTAs as no-path.
- Tour completion scrolls to the solve button; i18n banner GitHub link tracks translation feedback separately from donations.
- PostHog error capture filters wallet and Firefox extension injection noise.
- Cloudflare worker snippet to serve
robots.txton the PostHog reverse-proxy subdomain (e.gothiclockbreaker.com). - SEO CI guards for single-URL sitemap with
xhtml:hreflangalternates.
- Sitemap lists one homepage URL with hreflang alternates instead of separate
?lang=entries — aligns with Google canonicalization for the SPA. - Locale switcher syncs
?lang=to the address bar so localized links are shareable.
- Wipe lock confirmation uses a Gothic-styled in-app dialog with icon pill actions instead of the browser confirm dialog.
- Header support ore glow toned down — smaller blur, lower opacity, deeper navy blue instead of bright royal blue.
- PostHog error capture no longer reports browser extension noise (
runtime.sendMessage(). Tab not found).
- Header Sleeper icon sits slightly higher on mobile (below the
900pxdesktop layout).
- Header Sleeper Ko-fi easter egg — top-right on desktop, sleep-to-awake hover, Gothic tooltip (Der Schläfer erwache!), transparent WebP assets.
- PostHog
support_link_clickedwithsource: header_sleeperwhen the Sleeper icon is opened.
- Press-referrer auto-locale: visitors from pcgames.de, buffed.de, gamestar.de, and ithardware.pl load German or Polish UI on first paint (respects locale suggest dismiss for the session).
- "Load example lock" recovery button on no-path solve failures — loads the Old Camp example and auto-solves.
- Share prompt CTA copy aligned with clipboard action ("Copy link" in all locales); suppressed while the shared-lock hash banner is visible.
- Footer Ko-fi tap target bumped to 44px on mobile with focus-visible parity.
- PostHog error capture no longer reports iOS in-app browser noise (
Error: he, DuckDuckGoWKWebViewpostMessage failures).
- Locale switcher and suggest-bar no longer throw unhandled
TypeError: Failed to fetchwhen the network is unavailable (offline, ad blocker, DNS failure).
- Support button moved from hidden top-right corner to an inline pill in the header bar — ore icon + "Toss an ore" label, visible in the natural reading flow on desktop and mobile.
- New ore icon asset with transparent background, trimmed to content.
- Ore glow shifted to deep royal blue across header pill, idle pulse animation, and footer strip hover.
- Removed web-presence
$pageviewping that fired every 45 s on visible tabs, inflating pageview metrics ~12× during peak traffic. Real once-per-load pageviews are unaffected.
- Footer "Featured in" shows only PC Games (Buffed link removed from noscript fallback, JS-rendered footer, and JSON-LD
subjectOf).
- Makefile
serveandcheck-versiontargets;servenpm dependency (88 packages);PORT/SERVE_BINvariables. Usemake previewinstead ofmake serve.
- Shortened header definition paragraph to prevent overlap with lang switcher and version on narrow viewports.
- Definition text vertically centered between the hero image title and the lang/version controls.
- Shortened the header definition paragraph so it no longer overlaps the lang switcher and version on narrow viewports.
- CI workflow fires on pull requests only; deploy workflow handles push-to-main (no more duplicate runs).
- Branch protection on
main: requirecistatus check, block direct/force pushes, enforced for admins. - Docs (AGENTS.md, README, release skill) updated for PR-based workflow.
- Cold-landing layout shift from the tour opt-in chip injecting on a second paint (Web Vitals CLS).
- Boot startup split into pure landing policy (
src/startup.js), DOM event binding, and phase-ordered appliers; cold chip eligibility lives inonboarding.enterColdLanding().
- Vite 6 production build (
vite build→dist/) with separate chunks for onboarding and analytics. - GitHub Actions CI (Biome lint + tests) and Pages deploy workflow.
public/symlinks so dev and build serveassets/,locales/, and root static files.- Self-hosted Cinzel WOFF2 fonts — no Google Fonts round trip on first load.
- Lazy onboarding how-to image (WebP) via
src/how-to-map-image.js. src/onboarding-stub.js— placeholder until the onboarding chunk loads on cold landing.src/analytics/posthog-init.js— PostHog stub + deferred SDK load after first paint.- Footer FAQ (
<details>) with three common questions in en/de/pl/ukr. hreflangalternates for en, de, pl, uk, and x-default.AGENTS.md, Cursor rule, andstophook (make lint && make testafter agent turns).- Biome linter (
biome.json) replacing ESLint.
- SEO title and meta repositioned as Gothic Remake Lockbreaker — Free Lockpicking Calculator; JSON-LD
alternateNamefor Gothic Remake Lockbreaker / Gothic Remake Lock Breaker. llms.txtbranding aligned with Gothic Remake Lock Breaker naming.- English locale bundled in
i18n.js; de/pl/ukr still fetched on demand. - Analytics and onboarding load via dynamic
import()after first render. - Footer layout: support strip, press mentions, FAQ, then version and issues.
Makefile:dev,build,preview,clean; README updated for Vite workflow.- Deploy docs: GitHub Pages source must be GitHub Actions, not branch root.
- ESLint and
eslint.config.js.
src/analytics/web-presence.js— 45s visibility$pageviewping so Web Analytics Live stays accurate during long solves (replaces autocapture activity).runWhenPostHogReadyintransport.js;landingwaits for SDKloaded.
- Re-enabled SDK
capture_pageview: true(one pageview on load with full$current_url/ referrer metadata). - Removed duplicate manual
$pageviewfromtrackLanding(was incomplete and raced SDK init).
src/analytics/attribution.js— first-touchreferrer,referrer_host, and UTM params onlandingand session props.- One manual
$pageviewper session (with$referring_domain) so PostHog Web Analytics Live referrers stay populated while auto pageviews remain off.
is-near-sloton walkthrough readout holes 2 and 6; CSS contract test for moving-hole glow styles.
- Walkthrough sequence panel: unified solid-fill active pins (parchment safe, amber near-edge, bronze notch, red wall).
- Moving pin on the current step: slow outer
drop-shadowpulse per danger state; static halo underprefers-reduced-motion. - Inactive groove landmarks (notch, wall, near-edge slots): faint rim and dim label so empty slots do not read as active pins.
- Tutor opt-in chip (bottom-left) instead of auto-starting the tour on cold landing.
no_pathfailure hint and Open guide button (guide_openedwithfailure_no_pathsource); en/de/pl/ukr copy.walkthrough_session_summary— one aggregated event per session instead of per-step navigation spam.src/walkthrough-summary.jswithpagehideflush from solve controller.
- Solve failure UX: scroll solution panel on all outcomes,
aria-liveon failure messages. - Locale suggest bar moved to top of page; visible during onboarding; decline stored in sessionStorage only.
- PostHog lean init: autocapture, pageview/pageleave, performance/web vitals, session replay, surveys, heatmaps, rageclick, dead clicks, and feature flags disabled;
stopSessionRecordingon load. - Removed high-volume custom events:
walkthrough_step_changed,walkthrough_ui_toggled,onboarding_step_viewed,tutor_next_clicked(funnel covered byonboarding_dismissed/tutor_skipped).
llms.txtcomparison table, “why players use” bullets, and query-shaped FAQ for beginner/best-tool LLM queries.- JSON-LD
featureListonWebApplication(compact UI, walkthrough, mobile, free).
- SEO title/description,
app.definition, and meta tags emphasize beginner-friendly compact UI and step-by-step walkthrough (en/de/pl/ukr). llms.txtpreferred citation and press blurbs highlight ease of use and mobile support.check-seo.jsguards comparison section, beginner positioning, andfeatureList.
- Footer Featured in PC Games · Buffed linking to German press coverage of the solver.
- Expanded
llms.txtfor AI crawlers: press links, FAQ, localized URLs, preferred citation. - Page-head link to
llms.txt; JSON-LDsubjectOf(PC Games, Buffed articles),HowTo, and language metadata onWebApplication. scripts/check-seo.js— CI guard for press URL parity, JSON-LD validity, andllms.txt/sitemap.xmldates vs changelog.
- README badges: PC Games and Buffed replace Reddit.
- Reddit removed from
index.htmlstructured data (sameAs); historical Reddit link kept inllms.txtonly.
- Locale suggest bar for first-time English-default visitors: opt-in DE/PL switch from referrer hints (
pcgames.de,buffed.de,gamestar.de,ithardware.pl) or async PostHog geo (DE/AT/CH/PL). src/locale-suggest.js,src/analytics/geo-hint.js;renderLocaleSuggestUI with English prompt copy.- PostHog
locale_suggest_shown,locale_suggest_accepted,locale_suggest_declined;LocaleChangeSource.SUGGEST_BAR;LocaleSource.SUGGESTon accept. StorageKeys.LOCALE_SUGGEST_DISMISSED;localeSuggeststrings inlocales/en.json.- Composition-root refactor:
solve-controller,lock-controller,locale-chrome-controller,app-renderer,ui-prefs,landing,app-elements.
app.jsis the composition root only; lock/solve/locale chrome logic moved into dedicated controllers.setLocaleacceptschangeSourceandlocaleSourcefor switcher vs suggest-bar tracking.- Onboarding and solve coachmark defer the locale suggest bar (same as i18n quality banner).
- i18n quality banner shows only on translated locales and stays hidden while locale suggest is visible.
- Geo locale hint is stored during onboarding/coachmark deferral and shown when eligible; geo poll retries after timeout.
- Locale suggest uses
role="region"instead of misusedrole="dialog".
- PostHog i18n instrumentation:
locale_resolved(initial query/storage/default resolution),i18n_banner_shown, andlocale+locale_sourceonlanding;locale_changedincludessource: switcher,change_direction, andlocale_switch_count. locale_session_endon page hide withstaying_on_translationandreverted_to_defaultfor retention vs revert analysis.- Session super-properties
initial_locale,initial_locale_source,ever_used_translation, andever_reverted_to_default. support_link_clickedwithsource: i18n_bannerfor the translation-feedback GitHub link.Localeconstants insrc/i18n.js; query?lang=persistence; canonical andog:urlsync on locale switch; sitemap entries for localized URLs.
- Locale switcher mounts once and updates in place (perf and keyboard focus).
- Solve coachmark and onboarding defer the i18n translation banner until they finish.
- Bootstrap survives failed non-English catalog fetch (falls back to English UI).
localesession property now registers on bootstrap (afterinitI18n), not only on switcher click — deeplink and stored-locale sessions are segmentable from the first event.
- Ukrainian (
ukr) locale: Tier C prose, UA flag in header switcher,hreflangand SEO meta (?lang=ukr).
- Hybrid i18n (v1): German and Polish Tier C prose; English frozen for compact UI chips (
With/Against/Gone, solve CTA, nav, mastery pills, turn labels). - Header language switcher with inline SVG flags (GB / DE / PL); opt-in only — English default, no browser auto-detect.
locales/en.json,locales/de.json,locales/pl.json;src/i18n.js,src/static-content.js,src/locale-switcher.js.- Dynamic SEO meta and
hreflangalternates on locale switch (en-GB/de/plon<html lang>). - PostHog
locale_changedevent andlocalesession property.
- Footer Discuss on Reddit replaced with Report an issue (GitHub Issues).
- Onboarding and solve coachmark use measured card height for mobile scroll margins.
- Solve button and sequence minimap label CSS hardened for longer translated copy.
- Social preview image: dedicated footer band with Gothic Lock Breaker title and Break the Lock CTA, Cinzel typography, and anchor-based alignment (1200×630).
- Added
scripts/generate-og-image.py,assets/og-screenshot-source.png, and bundled Cinzel font for reproducible OG image builds.
- Social and search metadata: shorter title (~53 chars) and description (~121 chars) so Google, X, and LinkedIn previews do not truncate.
- Open Graph:
og:site_name, dedicatedassets/og-image.pngat 1200×630 (1.91:1), andog:image:width/og:image:height; Twitter card uses the same image.
- PostHog error capture: re-entrancy guard stops capture feedback loops; cross-origin
Script error.and iOSshowSearchResultsnoise are no longer reported.
- PostHog ingestion uses the
e.gothiclockbreaker.comreverse proxy (ui_hoststill EU).
- Header support ore: subtle slow blue glow pulse; pauses on link hover/focus.
- Hash-arrival banner How to map your own lock link — guide stays in Section II; Open guide remains on solve failure.
- Custom domain
gothiclockbreaker.comvia GitHub PagesCNAMEand Cloudflare DNS.
- Canonical, Open Graph, Twitter, JSON-LD,
sitemap.xml,robots.txt, andllms.txtnow point athttps://gothiclockbreaker.com/. - README play badge and solver link use the custom domain.
- On-page and social SEO: document title, meta description, canonical URL, Open Graph / Twitter cards, and JSON-LD
WebApplicationschema. llms.txt,robots.txt, andsitemap.xmlfor search and AI crawlers.- Footer Discuss on Reddit link and README badge;
REDDIT_DISCUSS_URLinsrc/version.js.
- Hero scrim: removed duplicate tagline over in-image title; kept a single SEO definition line plus version badge.
- Mobile solution walkthrough no longer scrolls horizontally — walkthrough grids use
minmax(0, 1fr)and clip overflow on narrow screens.
src/analytics/values.jsandsrc/storage-keys.js— frozen enums for analytics property values and localStorage keys (no magic strings in touched modules).- Deferred solve coachmark for cold visitors: one-shot spotlight on Break the Lock when the lock first becomes mappable (
solve_coachmark_seen_v1); shown only after the onboarding tour ends if mapping completes during steps 3–4. failure_reasononlock_no_solution(oob_startvsno_path) with differentiated recovery UI and Open guide on unsolvable paths.is_first_solveproperty on firstlock_solvedper browser.- Onboarding dismiss key bumped to
onboarding_dismissed_v3so prior v2 skippers see the tour again.
- Share prompt dismisses only after a successful copy; banner scrolls into view after solve.
- Mobile touch targets: plate holes and toolbar icons at least 44px at ≤768px.
- Hash and example auto-solve scroll the sequence panel into view.
- Share prompt no longer dismisses when clipboard copy fails.
- Header ore link (icon-only, top-right on hero) — Gothic tooltip on hover/focus; opens Ko-fi. Footer support strip unchanged.
- PostHog
support_link_clickedsourceheader_orefor header placement.
- Footer Tip jar replaced with a visible support strip: ore icon (
assets/ore.webp), Toss an ore CTA, and Keeps the solver free subline — bronze banner styling, distinct from the version badge. - PostHog
support_link_clickedsource updated tofooter_strip.
- Optional Tip jar link in the footer (Ko-fi) and README badge row — voluntary tips for support and upkeep; solver stays free.
- PostHog event
support_link_clickedwhen the footer tip link is opened. - Header hero background (
assets/hero.webp) — compact band with tagline and version overlaid on a bottom scrim; artwork title in-image;<h1>for screen readers only.
- Share lock moved to Section III only: post-solve banner is the sole share affordance (shown after a walkthrough with steps).
- Share banner dismiss is session-scoped — re-solve brings it back; permanent localStorage dismiss removed.
- Wipe lock stays in Section I; toolbar still hidden on the pristine default lock.
- Section I Share lock button and
.controls-sharestyles.
- Share lock and Wipe lock toolbar icons hidden until the lock differs from the default setup (6 plates, untrained, no couplings, pins at notch).
- Lockpicking tier selector (Untrained / Trained / Master) with inline mistake-budget note; plate physics unchanged across tiers.
- Master pick-break modeling: stepper for picks snapped and per-coupling Gone control on tumbler cards; solver uses
effectiveMatrix()with dropped links cleared. - Walkthrough Something off? link with troubleshooting checklist in a mobile bottom sheet / desktop dialog (backdrop, Escape, auto-close on step change).
- Optional URL hash segments for mastery tier, break budget, and removed-link mask (legacy 3-part links still work).
- Analytics:
mastery_tier_changed,step_mismatch_clicked. - Onboarding tour: 4 steps (mastery tier, plate count, start holes, couplings) with fixed spotlight targets.
- Tests: store hash round-trip, mastery
effectiveMatrix, onboarding targets, view module smoke.
- Wipe lock resets mastery tier and Master link removals.
- Guide documents Fingers training tiers and Master link-removal workflow.
- Onboarding dismiss key bumped to v2 so the updated tour can show after the mastery UI landed.
- Locks count control grouped under its own label in the controls footer.
- PostHog UX analytics: mapping (
lock_became_mappable,example_lock_loaded,guide_opened), walkthrough (walkthrough_step_changed,walkthrough_ui_toggled), tutor (tutor_started,tutor_not_shown,tutor_next_clicked,tutor_skipped), and prompt dismissals (prompt_dismissed,share_link_copy_failed). solve_sourceon solve-outcome events (manual,hash,example);landing_typeandapp_versionas PostHog super properties.- Enriched
onboarding_dismissedwithstep_id,step_index,action, andtotal_steps.
- README analytics section updated for expanded event coverage.
- Dead
lock_solve_blockedevent (solve button is disabled until lock is mapped).
- Mobile onboarding coach marks on steps 2–3: spotlight and scroll now target Lock 1 correctly instead of leaving controls hidden under the sticky sequence panel.
- First-visit coach marks (3 steps) with mobile bottom-sheet layout; skipped on mapped hash arrivals.
- Collapsible How to map your lock guide with annotated in-game screenshot and Old Camp example lock.
- Hash arrival auto-solve for shared, mapped locks plus dismissible banner.
- Solve readiness gate: Break the Lock disabled until a coupling or start hole is set.
- Split analytics events:
landing,solve_button_clicked,lock_already_solved,lock_solve_blocked, onboarding and share-prompt events. - One-time share prompt after first successful solve; Share lock control with text label.
- Lightweight client error capture to PostHog on production.
- Shorter tumblers panel note; With/Against disambiguation in guide.
- Mobile: sticky solve button (≤768px), larger coupling chip touch targets.
- First-map transition (example button, first coupling or pin) no longer crashes render with stack overflow while still updating the URL hash.
- PostHog EU analytics: pageviews and autocaptured clicks on production; custom events for solve result, share-link copy, and lock wipe.
src/analytics/module — layered facade (events,transport,track,index); PostHog isolated totransport.js, init inindex.html.- Analytics disabled on
localhost/127.0.0.1during local dev.
- README: architecture table and short analytics section.
- Section III walkthrough: the lock being turned this step is highlighted with a bronze border and glow on its row, matching the focus card.
- Minimized sequence bar: single-line nav — Back, lock label, move arrow, and Next on one row; step counter centered above the arrow.
- Minimized bar: L1 label vertically aligned with chevrons and move arrow.
- Minimized bar: step label and move-arrow glow no longer clipped by panel overflow.
- Walkthrough readout: every active pin now shows a visible ring (was missing on safe positions).
- Walkthrough readout: pins at wall holes 1 and 7 use red danger styling even when that lock is the current turn; moving highlight no longer overrides edge danger.
- Walkthrough readout: 7-hole plate grooves per lock (read-only, matching Section II).
- Section I icon toolbar: link (copy) and trash (wipe lock, with confirm).
- Sequence panel icons: chevron minimize/expand and eraser clear (replaces confusing cross).
- Desktop: sticky sequence sidebar with scrollable solution; horizontal tumbler rows (title left, holes + chips right).
- Mobile: viewport-capped sequence panel; compact walkthrough grooves; internal
.solutionscroll. - Tumblers and walkthrough: locks shown back-to-front (N at top, 1 at bottom) to match in-game stack.
- Walkthrough styling: iron-bordered rows; raised bronze on active pin at hole 4; recessed elsewhere.
- Move-arrow badges sized up so the chevron fits inside the circle.
- Removed Reset pins control.
- README screenshots refreshed (mobile walkthrough + desktop layout).
- Gothic-style favicon (SVG, 32px PNG, apple-touch-icon) for browser tabs.
- Version badge in the page header (changelog link), in addition to the footer.
- Compact move commands with round arrow badges in the sequence panel.
- Minimizable sticky sequence bar with back/next step navigation.
- Icon toolbar buttons with hover tooltips on sequence panel actions.
- Makefile dev workflow (
make serve,make test,make check-version).
- Sequence walkthrough uses compact turn counts instead of verbose step copy.
- README: custom hero banner, refreshed screenshots, controls/danger-color docs, corrected architecture section.
- Local dev docs switched from
python3 -m http.serverto Makefile targets.
- Per-tumbler cards: start hole and couplings on one plate-style card (no separate matrix).
- Holes 1–7 labeling (hole 4 = notch, 1 and 7 = walls) matching in-game counting.
- Desktop two-column layout with sticky sequence panel; mobile single-column stack.
- Copy link button to share the current lock via URL hash.
- Version display in the footer with changelog link.
scripts/check-version.jsto catch version drift across files.
- Collapsed four panels into three: The Lock, Tumblers, The Sequence.
- Locks numbered 1 (front) through N (back), top to bottom.
- Wider responsive layout (up to 1100px) instead of a fixed 660px column.
- Edge-safe BFS solver: shortest path that never grinds a pin past the frame.
- Coupling matrix UI, per-tumbler position tracks, and step-through walkthrough.
- URL hash and localStorage persistence for bookmarking and sharing locks.