Fig. 6 / 6

Après-Ski

One shared link for a chalet week: who, what, where, how much.

A no-login trip organizer for a group of friends renting a ski chalet. It shortlists chalets from pasted listings, tracks daily attendance, meals and shopping, and splits expenses, offline-tolerant on a mountain connection.

  • 8 Playwright end-to-end suites, offline included
  • 3 server-side Claude features, all optional
  • 4 s polling interval for shared state

Figures read from the repositories on 24 Oct 2026.

Platform
Web app · PWA
Status
Live, in use by one group of friends
For
A group of 4 to 12 friends sharing a ski chalet
Year
2026
Role
Product and design direction. Built with Claude Code agents.
Stack
Next.js 16, React 19, TypeScript, Tailwind v4, PocketBase, Claude API, Framer Motion, Playwright
Typeface
Bricolage Grotesque
Commits
337 · 188 co-authored by agents · read 24 Oct 2026
See it
Private print. Built for one group of friends.
Colour bar sampled from the film: #0f1923, #232d37, #f5f5f5, #cd550f, #f59155.

The film · 0:27

Dark week grid with one coloured presence bar per person, ten crew members arriving and leaving on different days.

Full film withheld: it shows where and when a private group stays, and is being re-cut.

Chapters

  1. 0:00 Countdown and snow report
  2. 0:04 Title card
  3. 0:06 Repérage: paste a listing, vote
  4. 0:09 The chalet is chosen
  5. 0:11 Crew and daily attendance
  6. 0:15 Meals and the shopping list
  7. 0:19 Expense split
  8. 0:22 Works offline, sign-off
Shot list: every frame, described
Frame Time Shot On screen English
Frame 01 0:00 Phone card in dark blue: a large orange "136" day countdown above a snow forecast, -4°C and 85 cm of snow. Withheld: shows private travel dates. 136 jours avant de chausser les skis 136 days until we put on our skis
Frame 02 0:02 Close-up of the countdown card, the orange number blurring as it ticks down to 2, forecast row below. Withheld: shows private travel dates. 2 jours avant de chausser les skis 2 days until we put on our skis
Frame 03 0:04 First-person view of two skis on a freshly groomed slope facing snowy peaks, the title in large white type. Withheld: shows where and when the group stays. Après-Ski — Le cerveau partagé de votre semaine au ski. Après-Ski. The shared brain of your ski week.
Frame 04 0:06 Pale screen with a big title and a chalet-link field: a pasted listing URL, an AI step and a card outline. Withheld: shows where the group stays. Repérage — Colle les annonces, l'IA remplit la carte, l'équipe vote. Scouting: paste the listings, the AI fills in the card, the team votes.
Frame 05 0:08 Four chalet cards side by side with photo grids, prices and vote scores; the top-voted card is marked +12. Withheld: shows where the group stays. Un « non » pèse plus qu'un « oui » : le tableau remonte le chalet que personne ne bloque. One "no" outweighs one "yes": the board surfaces the chalet nobody blocks.
Frame 06 0:10 Alpine valley and a snowy hot tub; the chosen chalet’s name in huge white type with amenity chips. Withheld: shows where the group stays. Le chalet est choisi. The chalet is chosen.
Frame 07 0:12 Dark week grid with one coloured presence bar per person, ten crew members arriving and leaving on different days. Équipe — Qui est là, jour par jour. Team: who is there, day by day.
Frame 08 0:14 Dark meal planner with seven day tiles, Monday highlighted in orange, a dinner card and a shopping list beside it. Repas — Qui cuisine et la liste de courses de chaque soir. Meals: who cooks, and each evening’s shopping list.
Frame 09 0:16 Pale shopping-list screen: ten unchecked items in two columns, a counter card and a sort-by-aisle button. Courses — Tout ce qu'il faut acheter, regroupé pour le séjour. Groceries: everything to buy, grouped for the stay.
Frame 10 0:18 Plain full-frame orange, a colour wipe between two scenes.
Frame 11 0:20 Dark expense screen: one payer is owed, others owe, shown as green and red bars across ten crew members. Withheld: shows where the group stays. Tricount — Qui a payé quoi et qui doit combien. Tricount: who paid what and who owes how much.
Frame 12 0:22 Tilted wall of dozens of phone screens in the app, with a large white French headline over the middle. Withheld: shows where the group stays. Pas de tableur No spreadsheet
Frame 13 0:24 The same tilted wall of phone screens, now dimmer, with a new white headline across the centre. Withheld: shows where the group stays. Un lien pour toute l'équipe. One link for the whole team.
Frame 14 0:26 Dark end card: a mountain-and-clinking-glasses logo beside the product name and a one-line tagline. Après-Ski — Votre semaine au ski, sans tableur. Après-Ski. Your ski week, no spreadsheet.

The sheet · 14 frames, one every 2 s

The problem

A chalet week for ten friends runs on a group chat and one person’s spreadsheet. Dates change, people arrive a day late, someone books the cheese twice, and nobody can say who owes what on the last evening.

The context makes it harder. On the mountain the phone is in a glove, in glare, on lift-line signal. In the chalet it is passed around a table.

The product

Après-Ski answers the questions a chalet group asks on repeat, in French, from one link. There are no accounts: a visitor picks their name from the roster, or adds the whole group in one go, and is in.

Before the trip exists, Repérage (scouting) collects candidate chalets. Paste a listing link and the card fills itself with photo, price as quoted, beds, distance to the lifts. Everyone votes oui, bof or non, and choosing a chalet seeds the trip.

During the trip, the Hub shows the countdown, weather and snow depth. Équipe is a per-day attendance timeline, Repas assigns a cook and a menu to each evening, and Courses merges every meal’s shopping into one list with quantities summed. Comptes logs shared purchases and settles who owes whom.

How it’s made

The app is a Next.js 16 and React 19 PWA with PocketBase as the store. The browser never talks to the database; everything goes through the app’s own API routes. Shared state is polled every 4 seconds, pauses when the tab is hidden, and refreshes when it returns.

Three optional server-side features call Claude: quantity estimates for the shopping list, a multilingual merge that groups items by aisle, and the listing reader. Food calls run on Haiku; the listing reader needs a model that supports domain-filtered web tools. Every endpoint is rate-limited, validates the model’s JSON, and degrades to a plain manual flow.

The project was built with Claude Code agents against written specs: a functional spec, a product strategy and a design system. Unit tests cover the expense maths and URL safety, and Playwright specs cover onboarding, attendance, offline and the repérage board.

Details

The visual system is deliberately not a SaaS dashboard. Navy is the structure, orange is the single celebratory accent, and ice blue is reserved for snow and weather. Headings use Bricolage Grotesque; body text uses the native system stack.

Trust is the model: anyone with the link can edit, and the only friction is a confirmation before actions that affect others, such as marking someone else absent. Removing a member cascades to their attendance and votes, so no orphan row skews a headcount.

The app holds a real group’s trip, so the live instance is not linked here.

Decisions

  1. Fig. 6.1

    A veto outweighs a cheer

    Chalet votes score +2 for a yes and -3 for a no, so the board ranks the place nobody blocks above the one two people loved and three vetoed.

  2. Fig. 6.2

    Nothing invented

    Claude reads a pasted listing in the background and fills only what the page states. A missing price stays a visible gap, and hand edits always win.

  3. Fig. 6.3

    Three offline layers

    A localStorage read cache, a queued write outbox and a service worker, each useful alone. Cold starts paint last-known data instead of a skeleton.

  4. Fig. 6.4

    Expenses as weights

    Splits store integer shares, not percentages, so “pays double” is a weight of 2 and rounding never drifts. Balances are pure client-side functions.

  5. Fig. 6.5

    Built for gloves and glare

    Light and dark themes in OKLCH, tap targets of 44 px or more, tabular numerals on the countdown, and reduced-motion fallbacks everywhere.

Production notes

Commits on the default branch, read 24 Oct 2026
Span 9 Feb to 22 Oct 2026, 256 days
Commits 337
Co-authored by Claude Code agents 188
Share 56%
Read on 24 Oct 2026

Credits

Product and final cut
Sven Borden
Built with
Claude Code agents · 188 of 337 commits co‑authored, read 24 Oct 2026
Film
Motion and sound by Claude
Printed by
Coolify on a Synology in Vaud

Next print · Fig. 1 / 6

Popote