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 screens the app ships itself (welcome, plans, address, own server and
the states between) move from the dark card layout to a light design on an
animated aerial landscape drawn by a WebGL shader (native-shell/scenery.ts):
an island, a coastal town, farmland and mountains in one world.
- Welcome: the landscape with the TREK wordmark, three perks in one card,
"Explore cloud plans" and "I already have a TREK" as two buttons.
- Plans: one tab per plan; choosing one flies the camera to its place,
further inland with every plan. Each plan reads as a kind of trip, the
price sits in a card with a monthly/yearly switch and counts to its new
amount in the store's own format (native-shell/amount.ts), and a yearly
price shows what it makes a month. Restore purchases, the renewal terms
and the links stay as the store rules require.
- Address: the address writes itself on a glass card over the landscape;
free, the password rules and the agreement sit on white cards.
- Own server: the server address on the glass card; a failed check turns
the card red with what went wrong, proxy sign-in and client certificate
panels in the same style.
- States: server not reachable, certificate needed, already subscribed,
setting up (with its steps, then "Arrived") and the slow setup.
- iPad, an unfolded phone and a phone on its side get two columns, the
landscape beside the content; on a dual-screen device each half takes
one screen. Arabic and Hebrew mirror through logical sides only.
- The shader caps the pixel ratio at 2, drops to a lower resolution on a
slow device, stops in the background and is one still frame with
reduced motion.
- The sign-in and error page bars over a proxy's page (iOS and Android)
take the same look: a white card and a dark button.
- Plus Jakarta Sans is bundled for the text, with Montserrat standing in
for Cyrillic; the wordmark fonts and the old preview images are gone.
- New strings in all 28 languages; the keys of the old screens removed.
- The dev sample plans follow the cloud's plans (start, basis, plus, pro).
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.
Every file under assets/ was compressed again on each download, at the low
level a request path can afford. They carry their content hash in the name
and never change, so the client build now writes a Brotli copy beside each
compressible one (postbuild, scripts/precompress.mjs) and production points
a browser that accepts Brotli at that copy before express.static serves it.
Measured on a production build of 5.1.2, fetching the 652 precached files
the way a service worker install does: 16.3 MB -> 13.9 MB on the wire and
about 1.0 s -> 0.2 s of server CPU per install. A client without Brotli, a
range request and a build without copies are served exactly as before.
Every lucide icon is its own module, and the plugin icon lookup reaches all
of them by name from the navigation. The bundler therefore put each icon
another chunk also uses into a chunk of its own: 187 files of a few hundred
bytes, each one a request on a first visit and an entry in the precache.
A `vendor-icons` group collects them. The first load asks for 32 script
files instead of 224 (the bytes stay the same, 3.9 MB before compression),
and the service worker installs 460 files instead of 652. With 50 ms added
to every response the login page reaches DOMContentLoaded in 0.5 s
instead of 3.8 s.
The app's browser sign-in opens /native-handoff, which sends the user on to
the identity provider by itself. The page was not on the list of public auth
pages, so the 401 from loading the user sent the browser to /login with the
hand-off as its return path first. On a server that also offers passwords the
user then had to pick SSO a second time before getting back to the app.
A PDF, image or document opened in the app went straight to the share sheet.
It now opens in Quick Look on iOS, to page through and zoom with its own share
button, and in the app that views its type on Android. An app without the
viewer (feature filePreview), or a type nothing on the device shows, gets the
share sheet as before.
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.
After a tap, WebKit and Chrome keep :hover on what was tapped and send a
made-up mouseover, so buttons and rows stayed tinted until the next tap.
While a finger drives the app <html> carries data-touch-input: a PostCSS
step guards every :hover rule with it (no specificity change), and the
made-up mouseover and mouseout stop before any handler. A trackpad or mouse
clears the mark and gets hover back; a browser never sets it.
A control without a press of its own dims the moment a finger lands on it,
after a 60 ms wait so a scroll does not flash rows, and only the innermost
pressed control. A focus: ring no longer stays round a tapped button.
Fields get a fitting return key ("done", "go" in a form, "search" on the
search fields), and addresses, codes and numbers are no longer capitalised
or corrected. Ticking off packing items and tasks, a picker chip, a select
option, a picked date and dragging a plan row now give the haptics a native
list gives.
Confirmations ask through the system where the binary has the new
@capacitor/action-sheet and @capacitor/dialog plugins: a sheet with the
action in red when it destroys something, an alert otherwise, also for
"discard changes" in a sheet. An older app, a browser and a question with a
list under it keep the HTML dialog, as does a system that could not ask.
iOS no longer lifts a page preview on a long press on a link.
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.
On a phone or a folded foldable turned landscape the welcome, address,
TREK Cloud and plan screens were taller than the glass: the second choice
and the main button sat below the edge and Back was cut at the top. There
the explanation and the choices now stand side by side, the explanation
pinned while a long plan list scrolls. Every screen centres while it fits
and starts at the top when it does not.
Upright on an iPad, half of one in Split View and an unfolded foldable,
the photo spans the full width and fades only downwards, and the choices
stand centred in the room below it. Buttons and fields are pills like the
app's, choice cards take the app's card radius, and headings and subtitles
balance their lines.
In Arabic (and Hebrew, which never ran right to left here) chevrons point
along the reading direction and sit at the far edge of their card, the
Cloud lockup stays unmirrored on the leading edge, prices and addresses
read left to right, and a plan's period no longer touches its price. The
slides follow the reading direction. Russian gets Cyrillic stand-ins under
the same family names, so the headline keeps a rounded face.
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.
From a screen by screen pass over the iPad and foldable sizes:
- Card lists (transports, bookings, tasks, polls) flow down their columns
instead of filling rows, so the columns start level and a short card no
longer ends above its neighbour in a ragged row. The cards' own top
margin gives way to an even gap under each, so every column starts on
one line.
- A booking's or transport's title may take two lines in a column of a wide
window instead of being cut after a few words.
- The map beside the plan opened too close: the opening frame was worked
out for the window, not the narrower map, and Leaflet rounded its zoom up
to the next whole level, so the day ran off the top and bottom. The map
now opens at the whole level that fits and, once it knows its own size,
works the frame out again for it (OpeningFrameFit). On a wide window the
touch shell frames a day clear of its floating toolbar and corner
buttons.
- Costs and to-dos in two panes are one element tree with the stacked
arrangement, so a rotation or a fold between them keeps what is typed or
open in either pane, and the row at the top of the list stays at the top.
- The place sheet's category pill has room for its name on a wide window.
The Android shell now reports keyCommands and windowLayout, so the large
screen layout no longer assumes an iPad:
- The keyboard host hands the shortcuts to the app whenever the shell has
the keyCommands feature, whatever the platform. Before it also required
iOS, so an Android tablet with a keyboard answered the keys in the page
and never listed them in the system's shortcuts.
- useWindowFold follows the layout the Android shell reports (feature
windowLayout). When a vertical fold separates the window, a foldable half
open like a book, MobileShell marks it with data-fold and its place, and
the leading pane (the trip's plan, a tab's summary, a list beside its
detail) ends at the fold while the trailing one starts there, on either
reading direction. A flat fold that does not separate stays one screen.
- The split size class starts at 840pt, Android's expanded width, instead
of 900pt, so a foldable unfolded on its side (about 841dp) gets two panes
like an iPad does. An 11" iPad upright (834pt) stays a single pane. The
address screen of the native shell follows the same width.
- TrekShell exports NativeWindowLayout for it.
Also: the sheet's width and anchor types and the collab board type stay
private to their modules, which nothing else imports (knip).
On an iPad or an unfolded foldable the list screens kept one phone-wide
column in the middle of the page. They now lay out for the room they have:
- Transports, bookings, polls and tasks put their cards in a grid of as many
phone-wide columns as the page holds (CardGrid), three on a 13" iPad on
its side, two upright, one in a narrow Split View.
- Costs: with room for two panes (split size class) the summary (total,
owe and owed, settle up, final budget, categories) stands in a pane of its
own beside the expenses, each scrolling on its own (TabPanes). The search
field sits in the expenses' column again instead of running past it.
- Files: a grid of tiles with each photo's picture; with room for two panes
the picked file is previewed beside the grid with what it belongs to and
its actions, the way Files on an iPad does. The signed preview address
comes through fileRepo.previewUrl.
- Packing: the categories stand in columns, each card whole in its column;
the action menu drops from its button at a popover's width.
- To-dos: the four smart filters as tiles and the trip's lists in a pane
beside the tasks, which take the filter's name as their head.
- Collab: the chat stays in view at the trailing edge beside the notes,
links or polls, and the header switches only the board. The chat keeps its
place in the tree, so a fold or a rotation into two panes keeps the draft;
a chat at its newest message stays there when its box changes size. Notes
stand as a board in columns.
- Administration and settings share a section list beside the page
(MSectionNav); the stats grid takes four columns.
- Collections: the lists stand in a column beside the places, which take two
columns, and the head names the list on show.
- Journal: the entries become a feed beside the map, under their days, with
photo, place and the start of the story, in step with the map like the
strip of cards it replaces; it fades out under the header.
- The assistant opens as a tall panel at the trailing edge over a dimmed
page, as Slide Over would, instead of covering the whole screen.
- The rail fits every name: a word too wide for it shrinks the label before
it is hyphenated, and the admin entry uses its short name.
- The journeys and notifications headers keep to their column.
- The address screen of the native shell sets the photo as a panel beside
the choices on a large screen on its side.
On a foldable that reports its fold, a leading pane ends at the fold and a
trailing one starts there. Phones keep their layout.
With the plan beside the map, the map frames the day once the splash has
gone, and again once its box has settled after the pane opens or hides, a
rotation or a fold: a frame fitted to the old box left the day half outside
the new one. On a wide window the atlas country search stands as a centred
panel instead of a band across the screen.
The app shows the touch shell at every size now, an iPad's and an unfolded
foldable's included, instead of switching to the desktop pages from 768px.
One route tree survives rotation, Split View, Stage Manager and folding, and
the app's own features (Wallet, sharing into a trip, the edge swipe back)
are there on the big screen too.
Two size classes drive the layout (hooks/sizeClass.ts, Tailwind variants
wide: and split:):
- wide (600pt and taller than a phone on its side): a glass navigation rail
on the leading edge replaces the dock and holds every destination with its
name; sheets become centred form sheets; the trip's More menu is a popover
beside the rail; lists keep a readable measure; dashboard, journey and
vacay get columns; full-bleed maps run under the floating rail.
- split (900pt): the trip's plan, places or road trip chain sit in a pane
beside the map, which follows the plan's day; the list/map switch hides
and shows the pane like a sidebar; on a foldable that reports its fold the
pane ends at the fold. Settings show their sections beside the page and the
dashboard keeps its widgets in a column of their own.
A hardware keyboard gets the shortcuts an iPad app has (⌘1 to ⌘9 for the
sections, ⌘N, ⌘, , ⌥←/⌥→ through the days, ⌃⌘S for the pane, ⌘[ back),
answered by the page or, with a binary that has the keyCommands feature,
handed to it as native key commands.
The day strip fades at an edge that runs on, journey cards grow on a wide
window and a card without a photo takes the day's colour, and the Leaflet
map measures itself again when its box changes size.