The list menu on desktop and phone gets "Sharing for Whole List": pick
Shared, Personal or Shared with people once and every item of yours in
that list moves there through the existing per-item sharing write. Items
other people added stay as they are, and the dialog says so up front.
A new app setting oidc_auto_redirect (default on) is part of the admin form
and the public app config. Off, an instance without password login no longer
sends visitors straight to the IdP: the login page shows its SSO button,
also while the cached config is read. Admin toggle on desktop and phone.
On the road a stop's picture is often what decides whether it is worth the
detour. The phone's stop sheet shows the place's picture full width under its
name and the desktop stop dialog shows it in place of the kind tile; both open
the place's photos on tap. The picture is the place's own image, else the
provider photo for its Google or OSM id through the shared photo cache.
Google Maps takes no list from outside, but My Maps imports a KML layer.
The trip export dialog and the phone export sheet get "Places for Google
My Maps" (GET places/export.kml, MCP export_trip_kml), and a list's export
menu gets KML next to GPX. The KML codec gains a pin writer; the list file
mapping moves to collections.helpers to keep the service within its size.
A fourth status after visited, for a place already seen that the user wants
to go back to. It joins the one-tap cycle, the filters, the pickers, the
assistant cards and the MCP status tool, and counts as visited wherever
visits are counted (isVisitedCollectionStatus), so "visited everywhere"
keeps it. The status pickers go two by two where four would not fit.
The phone toolbar gets a category chip beside the status and label chips,
fed by the same categoryOptions the desktop dropdown uses, and no longer
clears a category picked on desktop. Managing labels moves into the label
panel so the row keeps four chips at phone width.
Mapbox Standard labels shops, restaurants and sights of its own; they look like trip
places but cannot be picked. A Hide Points of Interest switch next to the other Mapbox
options, on the desktop and the phone, turns them off on the trip map and the preview
without a rebuild. The Standard config handling moves into useStandardBasemapConfig.
A place saved with a typed address and no search pick, link or map point gets no
coordinates, so it never shows on the map, and nothing said why. The place form warns
under the address while that is so, and the inspector, the phone's place sheet and
both place lists mark such a place. No geocoding on save; the form stays unchanged
for a service stop, which explains a missing position itself.
Costs always converted to the display currency from Settings, so a trip
that moves on to another country could not be read in its new local
currency. A picker in the Costs bar (beside the Expenses heading on the
phone) now reads one trip in any currency; the server already settles in
any base. The pick is per trip and kept in this browser, nothing stored.
Seeing what a trip cost without, say, food meant adding it up by hand. A
click (or tap) on a category in the breakdown now leaves it out of the
total, your share and what you paid, dimmed in place with a line naming it
and Count all to undo. View only: nothing is saved, and what is owed, open
or settled stays whole. The desktop breakdown moves into its own component.
Travellers who track what a trip costs but never split it saw an
Unfinished warning on every expense and a settle-up they had no use for.
A trip now has a costs mode (appended migration, trips.costs_mode, split
by default); totals leaves payers, shares and settling up out of Costs on
desktop and phone through the same gate as a trip of one, and saves new
expenses without a payer. PUT /api/trips/:id and update_trip take it on
budget_edit. The split chips move into their own component.
With one traveler every share is the whole amount, yet Costs showed owe,
owed, outstanding, settle-up, balances and the final budget. A shared gate
(showsSplitting) now hides that side on desktop and phone, unless the ledger
still names someone else; the expense editor drops who paid and the split
while the expense holds nothing more. The payment dialog moves into its own
file to keep the panel under the size ratchet.
A booking confirmation that is also the invoice had to be uploaded a second
time to sit on the expense. The expense editor (desktop and phone) now lists
the trip's files to link, the booking's own first; the save sends the id in
receipt_file_ids, which the server already links. The desktop receipts block
moves into its own component.
A stay shared by people who slept a different number of nights had to be
worked out by hand. The custom split now takes shares next to amounts and
percent: five nights against four split the total 5/9 to 4/9, cent-exact by
largest remainder. Only the amounts are saved, so server and MCP are
unchanged; the phone sheet gains the same unit switch, percent included.
lint:i18n-keys took the spread in front of t() for a member call and did not
see native.provisioning.sub; the sentence is its own constant now. The
shell chrome test asks for the logical margins and their right-to-left swap.
The iOS app hands the page the safe area it measures, a floor under env() where WebKit reports none, and on a phone the floating bars keep clear of the side insets as well.
The dim faded in on the sheet's own parent, and opacity multiplies down the tree, so for its first frames even the opaque sheet let the list behind read through as ghost text (Android tester, expense editor). The dim now fades on a layer of its own beside the sheet, and the card is opaque halfway through its pop.
A tester could not tell which settings follow the account to every device and which stay on the phone, and looked for offline mode for a while. The section list and dropdown now stand under two headings, "Your account" and "This device". The server the app opens, the app lock and a client certificate move out of Account into a section of their own, "App", shown only in the app, next to Offline; About stands under TREK. Labels in all locales. TestFlight feedback, 5.1.3.
The two new test files mocked the db module and built VacayService by hand,
which the test-mocks and new-service ratchets refuse for files without a
baseline entry. The cases move back into vacay.service.test.ts and
vacay.test.ts unchanged; VACAY-037 asks for a year no other case caches. The
unrelated admin addon test change is reverted and two comments name the new
provider.
Bookings in the Bookings tab, the day sheet, a place's sheet and the road trip
opened their editor straight away, while a transport showed its details with
a pencil to edit. Every booking now opens the same detail sheet; its edit and
delete follow the booking's own permission (reservation_edit for a stay, a
table or a ticket, day_edit for a transport). Notes keep opening for editing,
as on the desktop.
The wallet button reads "Wallet" (its accessible name still says which one),
and "On map" reads "Map" in every language.
In the app the keyboard resizes only the body, which leaves the trip shell's fixed layers as they were, so the composer sat under the keys. The keyboard inset now also follows the height the app reports, and the chat lifts its composer by it. A picture in the chat opens full screen on a tap and zooms on a second; it sits below its bubble, keeps the long press for the message's actions, and a picture sent alone has no empty bubble beside it.
The import sheet no longer sets state from its preset effect and is below the complexity limit; the trip shell's splash tests await their timers. The iOS and watch builds resolve their Swift packages first on a clean artifact cache, up to three times: a failed download from GitHub left a partial Capacitor xcframework behind and every later attempt stopped on it.
The touch shell waited for the desktop's minimum splash of a second and a half after every trip load. It no longer does: while the trip loads it shows only its background, marked as a route fallback, so the page transition holds the dashboard until the trip is there and the trip slides in whole, as the dashboard slides back on the way out. The splash only comes up when a load takes longer than a second. The trip opened before, still in the store for a frame, is never shown for the one opening.
On the wide and split size classes the touch shell no longer sends the tours tab back to the plan. It gets the desktop's tour editor, wired over the shell's own planner (useTripPlannerPageOf): on split the trip's tours and the editor share a pane beside the map, on wide the pane and the map take turns. A phone keeps its tours in the places browser.
Studio is a child route of the journey, opened on top of it. The touch
shell's journey now renders that child in the split size class, where the
header offers Studio beside the menu, as the desktop's bar does. The editor
is the desktop's: tapping a panel, adding an element and dragging it with a
finger work through its pointer events. On the phone and in a single pane
the journey stays alone, whatever the address says, and offers no Studio.
The desktop's import dialog keeps its markup and moves its logic into
useGoogleRouteImport, unchanged: the link previewed, its stops in order with
the unresolved ones named, and the resolved ones appended to the day picked,
at least two, under one request id per opening and day. The large screens
get the same flow as a sheet, offered on the stage card under the track
offer to a member who may add places to days. The phone has no entry to it.
The desktop's track dialog comes to the large screens as a sheet over the
planner's followTrack, the hook RoadtripTrackModal runs on: the trip's tracks
nearest to the day first, the drive fitted to the one picked with via points,
and those vias dropped again. The stage card offers it in the wide and split
size classes, to an editor of days, on a trip that holds a track, and names
the track the day follows. The phone and the folded Duo have no entry to it.
On the phone the road trip's driving figures stay a read-out, set at the
desktop. A large screen is that table, so in the wide and split size classes
the same sheet edits the two driving limits, the day's window and where it
ends, the vehicle with its range and fill, and what the route may avoid,
through the planner's saveRoadtripLimit, the desktop dialog's own save. A
range worked out from the vehicle's own figures stays read-only, as on the
desktop, and a reader without the right to edit days sees every field
disabled. The phone and the folded Duo are unchanged.
Scrolled up, a day's head showed at a third of its strength between the
back button and the segment, because the feed's mask let content through
from 22px below the safe area while the pills reach 38px. It is now
transparent down to 40px and whole from 60px, where the first day's head
starts.
On a wide window too short for every entry (a folded Duo on its side) the
rail's list scrolls with its scrollbar hidden, and settings and
administration at its foot were cut off without a sign. The list now fades
at the edge with more behind it, as other scrolling lists do.
watch-screens.sh names the step that failed (launch, not ready,
screenshot) and tries once more after 20 seconds before it gives up.
The folded Duo on its side is over 500px high and so in the wide size
class, whose large cards won over the short window's compact ones. Short
is now asked first.
- Dashboard: crossing the split size keeps every widget in the same parent
(the columns dissolve into one ordered stack below it), so the currency
converter is not remounted and keeps its amount and rates.
- Trip dock: More is marked with the main dock's ring while one of its
sections (chat, notes, links, polls, files) is on show or it is open,
instead of the filled circle of a tab.
- Transport cards: the status button is a flex box, so its dot shows when
the card may be edited.
- Day header: the stay chip's name keeps its own direction, so a Latin name
in an Arabic header is cut at its end.
- Journey: a folded Duo on its side (about 540px high) gets the compact
cards, so the map keeps its room.
- Rail: a test pins settings and administration marking their own entry.
- The trip's segmented control writes its fit through a ref, not into the
element held in state (react-hooks/immutability).
- The amount field of a payment uses the body type tier, which follows the
text size setting, instead of a raw size.
- The form sheet tests wait the frame the edge fade now measures on, and read
the wide variant from the size class the shell writes.
- The native dashes spec lists its locales through node:fs, so shared needs no
vite types for it (knip).
- Baselines lowered where the fixes removed warnings: no-misused-promises,
no-non-null-assertion in tests, the MSheet rtl entry.
- Top bar: the segmented control keeps to the room between the back button
and the trailing button, draws its segments tighter and then scrolls with
faded edges instead of covering the back button. On a wide window every
list tab puts its primary pill in the middle and its round buttons at the
trailing end, so the pill no longer jumps between tabs.
- Day strip: a chevron over the faded end pages the days along on a wide
window, and the fade reaches further; the chips keep clear of it.
- Plan pane: the day card ends on the rail's bottom line beside the map (as
tall as its day across the page), scrolls inside a frame and fades the
rows at its edges. Addresses and the hotel chip end in an ellipsis instead
of being cut mid-letter; the weather chip keeps its width.
- Map: in the dark theme the map beside the pane takes the dark basemap.
- Places: the All / Unplanned / Planned chips are never narrower than their
names and scroll with a faded edge; on a short screen Places/Tours shares
their row.
- Chat: the list fades out under the floating controls instead of cutting a
bubble. Notes and to-do chip rows fade at their edges and New Note stays
outside the scrolling chips.
- Costs: the balance amounts share a line, the settle-up action wraps to a
line of its own, the totals stand under their labels.
- Bookings and transports: one column until two cards fit, titles take two
lines with the type under them, the time cell is never cut and a range
names its unit once.
- Files: the preview pane shows a type tile beside the name where no PDF can
be drawn in place, its actions keep their labels on one line and wrap as a
row, link labels are badges, and a tile that opens its file is no toggle.
- Polls get a fill that differs from card and track, packing filters are two
segmented controls, empty checkboxes get an edge with 3:1 contrast, and the
middle dots between values are gone.
- useCollabChatData: the resize observer that keeps the chat at its newest
message attaches when the list is drawn (after the messages load), not at
mount when there is no list yet. The test renders the real list after load.
- MCollabTab: the chat stays mounted, hidden, while a board fills the page on
its own, so leaving two panes with Notes picked keeps the half typed
message and the scroll position. The links card hugs its links on a wide
window instead of a page-high empty card.
- openingView: the floored opening zoom and the second fit for the map's own
size apply only beside the pane in the touch shell; the desktop planner
and the phone open at Leaflet's nearest level again.
In the touch shell the back, forward, disclosure, date-range and flow
arrows kept pointing right in Arabic, so Settle up showed the debt the
wrong way round and Vacay's year arrows pointed inward. The shell now
mirrors lucide's direction arrows in right-to-left languages; an icon
that names its own treatment keeps it, and the lightbox arrows stay on
their physical sides.
Latin user text in Arabic rows lost its beginning when cut and moved its
punctuation to the wrong end. Names, titles, addresses and file names take
their direction from their own text (dir=auto) and still line up with the
row; markdown paragraphs, chat messages, poll options and journal stories
are isolated; signed balances, amounts, sizes, rates and leg figures read
as one left-to-right run; URL fields read left to right. Name pairs joined
by an arrow isolate each name and point from the first to the second.
The hero progress and poll result bars fill from the start edge. Arabic
and Hebrew uppercase caption labels grow a step and take the muted ink,
and a todo's due date in a notification is written in the reader's
language instead of as YYYY-MM-DD.
From the large-screen review (visual findings of the shell and the top-level
screens):
- Rail: 80px wide, one caption size for every name (no shrinking per item),
balanced two-line names with every entry as tall as the tallest, short rail
names where a language's word is too long (mobileNav.rail*, all locales),
and near-opaque glass so a map's colours no longer smear through it.
- Rail head: always one 56px circle, so the entries never jump between pages:
the create action, the screen's own action (the vacation calendar's
year/editor switch moves there instead of floating over the days) or the
quiet logo on settings and administration. It stays put while a short rail
scrolls.
- Vacation calendar: weekday letters over each month on a wide window; the
editor's mode switch sits at the foot with room kept for it.
- Docks: More is marked with a ring rather than the centre button's fill, the
dock glass is denser, and lists fade out under the dock instead of showing
in the gap below it.
- Dashboard: trip names get the card's width with the dates under them, the
hero's facts wrap as whole chips, the filter chips scroll with a fade, the
hero ends above the dock on a phone on its side and its buttons sit on a
dark ground; the header bar stands in the content's column.
- Journeys: on a wide window the header is the same glass bar, in the column
of the cards, and the other journeys' label starts with them.
- Notifications: the round chevron back button, in the list's column.
- Settings and administration share one frame and width. Admin's new-user
action sits under the section list's title, the users card header wraps
inside the card, stat labels ellipsize, role badges read in dark mode.
- Collections: one card per place with the status inside it, worded in a
readable mix of its colour.
- Atlas and the journey map frame clear of the rail and the header; the
journey's day bar sits on a glass plate, and a phone on its side gets
smaller cards.
- Rail label tests rewritten for the new rule; FE-MOB-PANES-016 duplicate
renumbered to 017.
From the large-screen review (code findings H1, M1, M2, M3, M4, M7, L1, L3, L4, L6, L7):
- The size class is one value in JavaScript (hooks/sizeClass.ts) and the
stylesheet follows it: MobileShell writes it to the shell as data-size, the
wide:/split: variants and mobile.css key on that instead of media queries of
their own. A window that only grows shorter at the same width while a field
has focus is Android's soft keyboard, not a new window, so the rail, the form
sheets and the panes no longer fold away (and take the focused field with
them) while one types.
- The large-screen layout is the app's only. In a browser the touch shell is
the phone's below 768px and stays compact there, as before this branch.
- Shortcuts are the app's only, so a browser keeps Ctrl+1 and Alt+Left. The
command key is the platform's own (Cmd on Apple, Ctrl elsewhere), digits are
matched by the key's place as well (AZERTY), and nothing runs while a sheet
or another modal dialog is open: the page listens to nothing and the app is
handed no key commands, so Cmd+[ can no longer drop an unsaved form.
- Inside a trip Cmd+N belongs to the trip shell and creates what the tab on
show creates, named after it.
- Inside the touch shell the desktop navbar of the few PageShell routes is
hidden and --nav-h is 0.
- The rail comes before the page in the DOM, so a keyboard reaches it first.
- The phone's deep day colour for a journey card without a photo stays the
phone's; the desktop and shared timelines keep their faint wash. Its card is
opaque, a suggestion included, so the map's names do not read through.
- The trip widget's iPad mini layout keys on the iPad mini's width alone.
- The trip dock gets the scroll-edge strip and the denser dock glass the
global dock has.
- Duplicate test id FE-MOB-PANES-016 renumbered.
Expense, payment, booking, transport, day note, place edit, new trip,
journey entry, collab note, poll, task, packing item and packing import
use the form sheet: one header with its icon tile, a body that scrolls
with a fade, the footer, and full height with the actions beside the
title on a short window. Create New Trip loses its nested section cards.
Details:
- Add payment gets its icon tile and the currency inside the amount field.
- The expense's category field has the same fill as every other field.
- Day and date fields keep their year at phone width; From and To stack
in a narrow form.
- The place sheet's category chip sits under the name, uncut, the photo
on the cards' leading edge, labels in the sheets' small capitals.
- Stars no longer keep a hover preview after a tap.
- A hotel booking shows its stay's check-in and check-out when it has
none of its own, instead of the grey hint reading as a saved time.
- The collab note's title field is labelled Title (common.title).
- Shorter airport hint in German and Russian; long hints end in an ellipsis.
- The journey story grows with its lines (useAutoGrow).
- Member avatars show the member's initial, yours too, and turn over on
a selected chip.
- The trip's More sheet scrolls, dims a short window and is marked in
the dock while open; long titles wrap to two lines.
Every sheet now stands on the opaque sheet surface: the frosting the
translucent one relied on is dropped while the scrim fades, so the page
read through the fields as sharp ghost text.
On a wide window a sheet is centred in the content beside the navigation
rail instead of on the whole window, so it never lies on the rail, and it
grows to the window's height instead of stopping at 880px. On a phone the
card stands between the status bar and the dock rather than across the
dock. A sheet marked as a form fills the height of a window as short as a
phone on its side, with Cancel and Save beside the title (new `short:`
variant, m-form-sheet grid in mobile.css).
The form chrome gains a scrolling body that fades at the edges with more
behind them (useEdgeFade on the vertical axis), a date field whose
keyboard entry moves into the picker, a field wrapper for amounts with a
currency, and two-line titles. The focused sheet no longer draws the
app-wide focus frame or loses its corners, and the desktop's dark field
paint stays out of the touch shell, which painted a dark box inside every
rounded field.