Three field-reported bugs, all root-caused on the isolated test server:
1+2. FilePond's stylesheet never loaded — the filepond field registers it via
assets.addCss() during body render, too late for the theme's head-only
{{ assets.css() }}. Photo tiles rendered as giant unstyled boxes that
stacked and overlapped the rest of the form (Get Location/Weather, Submit),
making it unusable and looking like upload errors. Load filepond.min.css +
image-preview CSS in the head_assets block; hide the PQINA credit.
3. The success notice rendered at the top of a long, reset form (off-screen
after submitting from the bottom) and .notices was unstyled on the dark
theme. Style .notices; on load, scroll the confirmation into view and inject
a 'View your journal' link (to site.active_trip) + 'Post another' CTA.
Verified in a browser: 3 photos render compact without overlap; post-submit
shows the confirmation + working view link.
Runtime verification showed the custom picker uploaded to Grav's flash but
never attached photos to the entry — attachment needs FilePond's exact
(undocumented) submit contract. Reverting to type:filepond and hooking its
beforeAddFile: a HEIC item is rejected, converted to JPEG via the lazy heic-to
chunk, then re-added with pond.addFile() so FilePond owns upload + page-attach
(the proven path). Web-format photos pass through; conversion failures fail
closed (inline status, original never added). Removes the custom photos field
template + AJAX uploader.
Verified end-to-end in a browser: HEIC posts as JPEG, corrupt HEIC is skipped,
Submit gated while converting, draft photos-reselect hint intact.
Refs R8, R9, R16, R17, AE1, AE4, KTD4.
Migrate Get Location/Weather + required-field validation out of the
template's inline scripts into the bundle: generalize the field lookup so
weather_desc (now a <select>) is found, gate Get Weather until coords exist,
and add idle/loading/success/error states. Build the 'More options' <details>
(native, KTD5) around the advanced trio, auto-open when any has a value.
Add Field Notes CSS: select/number styling, EasyMDE dark theme, disclosure,
button spinner, and server form-message states.
Refs R5, R11, R12, R18, R19, AE3, KTD5.
Replace /post's managed filepond field with a controlled 'photos' field
(theme forms/fields/photos) + picker logic in post-form.js: magic-byte
sniff (ISO-BMFF ftyp brands, not filename/MIME), lazy import('heic-to')
only for real HEIC (deferred 3MB chunk via ESM splitting), per-thumbnail
converting/uploading/done/error states, in-flight counter gating Submit,
and fail-closed skip on conversion failure. Converted JPEGs POST to Grav's
AJAX file-upload route into the form flash (the only path copyFiles reads),
so add-page-by-form attaches them on submit. Web-format photos pass through.
Refs R8, R9, R16, R17, AE1, AE4, KTD4.
Add a page-scoped js/src/post-form.js bundle (built ESM + code-splitting
so U4's heic-to becomes a deferred chunk) loaded only by post-form.html.twig
via a new base head_assets block. EasyMDE replaces the bare textarea with a
minimal toolbar (bold/italic/list/link/preview), FA-free via CSS glyphs, and
syncs codemirror.save() on change + capture-phase submit so the inline
required-field validator and payload see the live value.
Refs R7, R15, KTD2, KTD3.