Commit Graph
422 Commits
Author SHA1 Message Date
m038andClaude Opus 5 e81c73a9ba Fix story scrolly text rendering; story/trip blueprint media upload
Scrolly-section text never rendered: the inline Scrollama block ran before
the main.js bundle published window.scrollama, so it always hit its guard
and the panel text stayed display:none, leaving a blank column beside the
pinned image. Defer to DOMContentLoaded, and build the step panels before
the scrollama check so a missing bundle costs the animation, not the text.

Also fixes an invalid calc(-(...)) that dropped the mobile scrolly offset,
and drops the duplicate inline back-to-top in favour of main.js's version
(which pushes a history entry).

Blueprint changes carried over from an earlier session: story.yaml and
trip.yaml now extend the default page form so both can upload media.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 23:12:45 +02:00
m038andClaude Opus 5 0ebb770bc7 Add Vestkustryten reflection story; correct Denmark 2026 trip facts
New story for the Denmark 2026 trip with 9 photos, plus trip.md updates:
route length 560 → 650 km and end date 2026-07-20 → 2026-07-18.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 23:07:03 +02:00
m038andClaude Opus 5 dd19995973 Merge feat/post-location-override into main
Post-form location override: search + map + drag pin (U1-U6), hardened by a
multi-agent code review — server-side cleanCoordinate() guard, strict
coordinate parsing, three closed gate-bypass paths, pin removal on blanked
fields, visible geocode failures.

Also carries maplibre's stylesheet moved to a lazy <link> at panel-open
(post-form.css 92,244 -> 26,784 raw; 14,528 -> 5,631 gzip), the test-entry
leak fix into real trip content, the GPX leg-connection fix, and the U+200E
coordinate strip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 23:48:00 +02:00
m038andClaude Opus 5 8a5cc5246c Merge branch 'main' into feat/post-location-override
Picks up the two fixes committed via the main checkout's submodule git dir:
the leg-connection map fix and the U+200E coordinate strip. The outer repo is
one directory (~/Projects is a symlink to ~/Nextcloud/Projects), but a
worktree gets its own submodule git dir — .git/worktrees/<name>/modules/user
vs .git/modules/user — so those commits were not reachable here until a local
fetch. No push was needed, so git-sync did not deploy.

maplibre-utils.js auto-merged, keeping main's prevNear leg logic alongside
this branch's MAP_STYLE extraction. js/map.js conflicted as a generated
bundle and was resolved by rebuilding, not hand-merging.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 23:44:37 +02:00
m038andClaude Opus 5 7903432634 Merge branch 'main' into feat/post-location-override
Brings the branch up to user/main, which was ahead on both content and
theme fixes. Notably e17a5dc ("block submit on unfinished photo uploads;
un-squeeze EXIF portraits in lightbox") — the branch point predated it, and
its absence is why UG1, UG2 and LD1 failed here: the upload gate and the
oriented-derivative slide dims those specs assert simply were not on this
branch. Also picks up denmark-2026 `published: true`, so the local testing
flip is no longer needed.

js/src/post-form.js auto-merged cleanly, keeping both main's upload gate and
this branch's location-override panel + lazy maplibre CSS link. The only
conflict was js/post/post-form.js, a generated bundle — resolved by
rebuilding via make build-assets rather than hand-merging minified output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 23:36:41 +02:00
m038andClaude Opus 5 285ae37209 fix(content): strip U+200E from the Jerup entry's coordinates
lat/lng carried a leading LEFT-TO-RIGHT MARK (e2 80 8e), pasted in from a
system that decorates coordinates for bidi text. It renders invisibly, so
the values looked correct while parseFloat saw a non-numeric prefix.

This is the exact input cleanCoordinate() now rejects server-side; the
scan for further occurrences across pages/ comes back empty, so this was
the only affected entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 23:27:09 +02:00
m038andClaude Opus 5 47ec72fa1d fix(map): connect legs whose endpoints sit on different GPX files
intelligent_gpx mode required BOTH endpoints of a leg to be near the SAME
GPX file before treating it as covered. This trip's routes are one
contiguous chain recorded a day per file (…-to-X.gpx, X-to-….gpx), so any
leg spanning a file boundary — an unblogged intermediate stop — read as
uncovered and got a straight connector drawn over an already-GPX-covered
path.

Each endpoint now only has to be near some file. The trade is that a real
gap (flight, train transfer) whose endpoints each sit on their own track
also reads as covered and gets no connector; that case is not detectable
from proximity alone, and `force_connect: true` on the entry after the gap
already handles it.

js/map.js is the rebuilt bundle (make build-assets), not a hand-edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 23:27:01 +02:00
m038 2b91aa30c3 fix(demo): stop demo-load reverting the real italy-2025 trip
docs/demo/trips/italy-2025/ shares its slug with a real trip (deliberately —
the fixture supplies that trip's GPX and dailies), so demo-load copies this
trip.md straight over the live page. The fixture was a snapshot from before the
trip gained a tagline, so every `make test` silently deleted that tagline from
real content, showing up as an unexplained dirty submodule afterwards.

Re-sync it byte-identically to the live page. The note about keeping colliding
fixtures in sync goes in the Makefile recipe, not here — anything added to this
file lands in real content on the next demo-load.
2026-07-24 22:33:27 +02:00
m038 e0e68a9ac3 perf(post): lazy-link maplibre's stylesheet instead of bundling it
The engine was already a lazy import(), but its CSS was a static one — the
usual workaround for esbuild never emitting a <link> for a code-split chunk's
stylesheet (R10). That folded the whole vendor sheet into post-form.css, so
every /post load paid for a panel most submits never open, and ~78% of those
bytes were rules for controls this map never creates (popups, geolocate, zoom,
compass, fullscreen, terrain, scale).

Build the vendor sheet as its own css-compiled/maplibre-gl.css and have
location-map.js <link> it at panel-open, concurrently with the engine's
import(). Keeping the file intact rather than hand-picking the ~16 selectors
in use means a maplibre upgrade can't silently un-style the map.

  post-form.css  92,244 → 26,784 raw   (14,528 → 5,631 gzip)

The href resolves from import.meta.url, so it is correct under any Grav base
path without threading a URL through the template — the panel is built entirely
in JS, so there is no element to hang a data-attr on. A failed stylesheet load
resolves rather than rejects: the map degrades to unstyled, never to absent.

The existing lazy-load guard spec already matched every maplibre-gl URL, so it
covers the stylesheet too; its message now says so, and a new test asserts the
other half — that opening the panel does link and apply the sheet.
2026-07-24 22:33:19 +02:00
m038andClaude Opus 5 e873a9cb23 fix(review): land cleanCoordinate server-side guard; surface geocode failures
Two code-review follow-ups.

cleanCoordinate() — the server-side coordinate sanitizer the design doc and
plan both describe as already shipped — had never actually been committed; it
existed only as uncommitted work in another checkout, so this branch had no
server-side validation of lat/lng at all (the blueprint fields are plain
`type: text` with no `validate:` key). Landing it here makes the spec's stated
safety net real. Also corrected its onAdminSave comment, which justified that
hook by saying the public form's lat/lng inputs are CSS-hidden and GPS-filled
— true before this feature, inverted by it. Both hooks are needed: this branch
makes /post the primary hand-entry path, not Admin2.

The geocode lookup swallowed every failure and reset the button, leaving the
DOM byte-identical to the pre-click state — a traveller on flaky mobile data
could not distinguish a failed lookup from a broken button. It now shows a
distinct hint, and checks r.ok first so a 4xx/5xx body no longer parses as
"no results" and tells the traveller their city does not exist. R8's actual
guarantee (fields untouched on failure) is preserved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 21:48:20 +02:00
m038andClaude Opus 5 a5993b2091 fix(review): strict coordinate parse, close the gate bypass, drop the stale pin
Code-review fixes to the location-override panel.

parseFloat is a prefix parser, so '48abc', '48,85' (comma-decimal paste) and
'35.0116S' (hemisphere suffix, silently flipped to the wrong side of the
equator) all passed the isFinite + range check, cleared the mismatch flag and
were POSTed verbatim — the same silent-corruption class this feature exists to
end. Replaced with a whole-value decimal check, and the valid branch now
normalises to the 6dp the GPS handler and onDragEnd already write, so the pin
and the submitted value cannot disagree.

The submit gate keyed on the .location-field--mismatch class, which was only
ever set by syncFields() on blur / debounced input / toggle-open-success / GPS
— never at init. Three paths therefore reached the server unflagged: a draft
restored by initDraft() (which runs before initLocationDetails() and assigns
.value directly, firing no events), an edit-mode async prefill, and an open
panel whose maplibre chunk failed to load. syncFields() now runs once at the
end of initLocationDetails(), in the toggle handler's catch arm, and after the
edit prefill writes lat/lng.

Blanking both fields left the marker behind, presenting a stale coordinate as
if it were still the entry's — added clearPin() to the map handle and call it.
Removed hasPin(), which had no caller. Corrected two comments that named the
wrong stylesheet and claimed .field-invalid reuse the code does not do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 21:34:17 +02:00
m038andClaude Sonnet 5 13c76b29a8 fix(post): close location-map race, block submit on bad coords
Code review (4 independent reviewers) converged on the same bug: the
maplibre-gl singleton cached its handle only after import() resolved,
so a fast close/reopen of the "More location details" panel could
race two Map instances onto one container. Cache the in-flight promise
synchronously instead, and propagate/handle import rejection so a
failed map load surfaces a hint instead of hanging silently.

Also closes a submit-time hole the adversarial pass found: the
mismatch flag on lat/lng was purely cosmetic and never blocked
form submission, so out-of-range coordinates could be saved. The
flag now gates submit like the other required fields, and clears
itself when both fields are blanked back out instead of sticking.

The geocode fetch gets a 10s timeout via AbortController so a hung
response can't leave the lookup button disabled forever.

Also moves the location-details CSS out of the site-wide style.css
into post-form's own code-split stylesheet, since none of it is used
outside the post form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 20:03:01 +02:00
m038 797b472a60 feat(post): add "More location details" panel — search, map, sync
Closed-by-default disclosure below City/Country holding a city/country
geocode lookup (Open-Meteo, city-only query with client-side country
ranking), a single-marker draggable MapLibre preview (lazy-loaded via
location-map.js), and the relocated lat/lng fields. GPS button, search
pick, pin drag, and typed values all stay in sync via syncPinFromFields(),
with a visual mismatch flag for unparseable typed input.

Built entirely in JS (mirrors the existing 'More options' disclosure
pattern) so post-form.html.twig needs no template change.
2026-07-24 19:38:24 +02:00
m038 52e9fbadf2 refactor(map): extract MAP_STYLE into a shared map-style.js module
Single source of truth for the MapLibre style URL, shared between
maplibre-utils.js (multi-marker/GPX maps) and the new location-map.js
preview module — no behavior change.
2026-07-24 19:38:10 +02:00
m038 a00690fbde feat(post): unhide lat/lng fields, style the location-details panel
Removes the CSS rule hiding data[lat]/data[lng] and adds styling for the
new 'More location details' disclosure, search results list, map preview
container, and mismatch-flag state.
2026-07-24 19:38:05 +02:00
m038 4721af6452 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-19 09:58:44 +00:00
m038 1f1001df07 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-19 09:18:50 +00:00
m038 bf34d698aa (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-17 13:28:37 +00:00
m038 3b89e207ef (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-17 09:58:13 +00:00
m038 723b77ae0d (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-15 19:39:04 +00:00
m038 c6402aa320 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-15 06:44:13 +00:00
m038 55bc890c32 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-15 06:41:49 +00:00
m038 1f638897e6 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-12 18:58:46 +00:00
m038 5727766ba8 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-11 18:32:40 +00:00
m038 b412a6e782 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-11 06:21:43 +00:00
m038 01487e3672 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-11 06:21:24 +00:00
m038 93f0a03b84 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-11 05:01:14 +00:00
m038 005dc4a157 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-10 16:47:08 +00:00
m038 c407ea010f (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 18:44:20 +00:00
m038 894593d74f Merge branch 'main' of https://git.gorinskat.nl/m038/intotheeast-com-content 2026-07-09 18:20:27 +00:00
m038 259130cd3c (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 18:20:26 +00:00
m038andClaude Fable 5 790c3deb26 fix(theme): hide the map fullscreen button when the map never initialises
The entry-map partial always rendered .feed-map-fullscreen-btn, but the
MapLibre init AND the button's click wiring only run when entries exist —
so on the home pre-departure state (active trip, no published posts) mobile
showed a dead button floating over an empty 40vh map area. Gate the button
on the same entries|length condition as the init script; it reappears with
the first published post, exactly when it becomes functional. Covers any
zero-entry trip page too (shared partial).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0195b3cDdMeize2Mm1FgC2aU
2026-07-09 20:20:20 +02:00
m038 36211a96ef Merge branch 'main' of ssh://m038-nas.tail63ee39.ts.net:222/m038/intotheeast-com-content 2026-07-09 17:56:42 +02:00
m038andClaude Fable 5 e17a5dc972 fix(theme): block submit on unfinished photo uploads; un-squeeze EXIF portraits in lightbox
Two prod bugs from the 2026-07-09 owner test:

- post-form.js: complete upload gate on create submit. The form plugin's
  guard only blocks PROCESSING/QUEUED, so a failed upload (processing-error)
  or a just-picked file (loading) submitted silently and the entry saved
  without its photo. Submit is now blocked unless every FilePond item is
  processing-complete, with a visible status message for the failed vs
  still-uploading cases. (Bundle rebuilt via make build-assets.)

- entry-journal partial: PhotoSwipe slides now link to a 2000px fit-within
  derivative and measure THAT file for data-pswp-width/height. The old
  img.width/height came from raw getimagesize() of the original, which
  ignores EXIF orientation, so stored-rotated portrait JPEGs got landscape
  slide boxes and rendered squeezed. Derivatives are re-encoded (EXIF
  stripped, orientation baked in server-side), so declared dims always match
  rendering. Also fixes the wrapper aspect-ratio pick for portrait-first
  entries. Note: Medium 'path' must be called as path() in Twig — the
  ArrayAccess 'path' item (page folder) shadows the method.

Covered by tests/ui/post/upload-gate.spec.js and lightbox-dims.spec.js in
the dev repo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0195b3cDdMeize2Mm1FgC2aU
2026-07-09 17:56:01 +02:00
m038 f72ca2f024 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:56:43 +00:00
m038 2112df3b7f (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:56:35 +00:00
m038 945732aade (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:56:26 +00:00
m038 5ebf925ca7 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:56:20 +00:00
m038 a6749547bd (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:56:04 +00:00
m038 35d82b0484 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:55:57 +00:00
m038 d4b5050616 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:55:49 +00:00
m038 e02c10e67a (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-09 14:55:29 +00:00
m038andClaude Opus 4.8 874645db32 fix(theme): dark-theme login box, feedback messages, and nav logout link
- Override the Login plugin's white #grav-login box to use dark theme tokens
- Style flash/form notices (.notices, #messages .toast) globally on-theme;
  override markdown-notices' bright per-colour variant backgrounds so error/
  success/warning messages stay dark with a coloured left border
- Add a Logout link to the main nav (authenticated-only, plain nav style);
  no login link in the menu

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rw9Tceo6DSzVqWKkjVJpHZ
2026-07-08 23:56:04 +02:00
m038andClaude Opus 4.8 02fa4e94a7 content(theme): rename nav/heading/CTA 'Past Trips' to 'Trips'
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 23:29:05 +02:00
m038andClaude Opus 4.8 df0e00937e content(trip): add taglines for all trips; refine Denmark tagline
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 23:22:11 +02:00
m038 fae364585c Merge branch 'main' of https://git.gorinskat.nl/m038/intotheeast-com-content 2026-07-08 21:18:45 +00:00
m038 3cb50a298a (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-08 21:18:44 +00:00
m038andClaude Opus 4.8 125f9e6131 content(trip): add Denmark 2026 description
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 23:18:32 +02:00
m038 4a40dc9c18 (Grav GitSync) Automatic Commit from into-the-east-grav-sync 2026-07-08 20:55:32 +00:00
m038andClaude Opus 4.8 f4ab73070b content: feature 3 entries as homepage highlights; publish Denmark 2026
- featured: true on Central Asia 2023, Italy 2025, and US/Canada/Mexico 2024 entries
  (surface in the between-trips homepage highlights grid)
- Denmark 2026 trip: published: true + Vestkystruten GPX track

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mpdu3Dt1iVoozHwAMyjrbn
2026-07-08 22:28:18 +02:00