# VAKTIN — The Front-Desk Toolbelt for Opera Cloud

*One software, many tools. Built for Íslandshótel today, built to travel tomorrow.*

> **Vaktin** (Icelandic: "the shift" / "the watch") — a suite of calm, single-purpose tools
> that make everyday Opera Cloud front-desk work faster and harder to get wrong.
> Every tool runs entirely in the browser, offline, client-side. No guest data ever
> leaves the machine. No account, no server, nothing to leak.
>
> **Tagline:** *Tools that stand the watch with you.*

---

## 1. Where this starts

Two tools already exist and are loved (preserved unchanged in [`original/`](original/)):

| Tool | What it does | What it proves |
|---|---|---|
| **ARRIVALS·AUDIT** | Parses the Opera `RES_DETAIL` XML, classifies every reservation's payment path (VCC / POA / invoice / OTA-prepaid / card-guaranteed…), flags money-losing gaps (unrouted VCC, OTA with no card), extracts bed & special requests, cross-checks against YieldPlanet | The **domain brain**: a payment classifier that catches real money before the guest reaches the desk |
| **KEY·ENVELOPES** | Turns arrivals exports into printed key envelopes, luggage tags, welcome letters, group cover sheets and room lists — 18 properties, IS/EN, mm-accurate print, offline fonts, session resume, print history | The **platform template**: multi-property registry, brand packs, i18n, setup export/import, a serious print engine |

They share a foundation that is the product, not an accident:

- **Zero-install, single-file, offline.** A receptionist opens it and drops a file. No IT, no login, no deployment.
- **Provable privacy.** *"Runs entirely in this browser — no guest data leaves this machine."* True today; a hard invariant forever.
- **Print fidelity that survives a real front-desk printer.** mm/pt geometry, calibration grid, fit-to-page math that never clips a room.
- **Domain fluency.** "No payment path", "tonight's standouts", hjónarúm vs twin, the Guide on the rooming list, kr with de-locale grouping. Staff-made for staff.
- **Forgiving ingestion.** Three Opera export shapes, tag-name fallback chains, re-export merging, undo, resume — it never punishes a messy real-world file.

The plan below turns these two siblings into **one platform** without trading any of that away.

---

## 2. The vision

**One URL. A launcher. A shelf of sharp tools that share one brain.**

Open Vaktin, pick your property (or it's remembered), and see a grid of tools that cover the
whole front-desk day — pre-arrival prep, the arrivals rush, in-house service, departures,
night audit, and the estate view across properties. Drop today's export once; every tool
reads from the same parsed book. Mark a routing fixed in the Audit and the envelope for that
guest loses its "see front desk" seal. Print the night pack at 03:00 and the morning
handover writes itself.

Three product promises:

1. **The second pair of hands on every shift.** Every tool exists to catch what a tired
   human at hour nine of a rush would miss — and to say exactly what to do about it.
2. **Guest data physically cannot leak.** The architecture makes the privacy promise
   structural: parsing, classification, even the future AI layer run in the browser.
3. **Onboarding a new hotel group is a config file, not a fork.** Everything
   hotel-specific — market codes, payment rules, logos, letter text, language — is data.

---

## 3. Non-negotiable principles (the constitution)

1. **Offline is a feature.** Every tool fully works with the network unplugged. Any glyph
   that reaches paper comes from an embedded font. (The current Audit violates this with
   CDN fonts — fixing that is Phase 0.)
2. **Guest PII never touches a server.** If a backend ever exists, its schema must be
   *incapable* of holding a guest's name — counts and operational notes only.
3. **Every tool is still a single page you could email.** The build emits a fat
   self-contained `.html` per tool alongside the hosted version. USB-stick deployment
   stays possible forever.
4. **Data-in is forgiving; data-out is precise.** Accept messy exports, emit mm-accurate
   paper and clean CSV.
5. **The desk's language, not the PMS's.** Buttons say "set up routing", not "modify
   folio window association".
6. **Feature availability is per-property.** Opera Controls differ across the estate;
   every capability sits behind a per-property flag.
7. **State survives the shift.** Done-marks, sessions, and print history persist locally,
   namespaced by arrival day, so work is incremental and hand-over-able.
8. **Icelandic and English are equals.** UI, letters, and generated text ship IS/EN;
   new languages are dictionary files.

---

## 4. Architecture: one spine, many thin tools

**Monorepo of static tools + one shared library + one config format, delivered as an
installable PWA with a launcher.** No framework, no module federation, no backend by
default. The full analysis is in the appendix; the shape:

```
vaktin/
  packages/
    core/            # shared runtime: Opera XML parser (3 export shapes, fallback chains),
                     # payment classifier AS DATA, requests/beds digest, niceName(),
                     # date/ISK helpers, localStorage store, CSV export, fuzzy matcher,
                     # i18n T(), config loader, setup-bundle import/export
    ui/              # design system: tokens.css, drop-zone, record row, triage rack,
                     # segmented bar, chips/badges, data table, banners, print sheets
  tools/
    arrivals-audit/  # each tool = thin entry that imports core+ui
    key-envelopes/
    guest-cockpit/
    ...
  properties/        # per-property + per-group config JSON (see §5)
  shell/             # PWA launcher, manifest, service worker
  scripts/build.mjs  # esbuild (~40 lines): emits BOTH a hosted thin build
                     # AND a fat single-file .html per tool (fonts/config inlined)
```

**Why this shape** (and not the alternatives):

- **Not a SPA/framework rewrite** — the envelope app proves a rich UI is maintainable in
  vanilla JS at ~1.8k lines; a framework adds a runtime and an upgrade treadmill to solve
  problems these tools don't have. If one future tool genuinely needs reactivity, it may
  adopt a ~10 KB micro-lib *for that tool only*.
- **Not module federation** — it actively fights offline and solves a many-teams problem
  a one-builder platform doesn't have.
- **esbuild and nothing heavier** — the single build step that ends copy-paste drift
  (the two tools already diverged: only one has offline fonts, only one has setup bundles).

**Delivery — four modes, one artifact:**

1. **Single URL** (e.g. `vaktin.islandshotel.is`) — the 90 % path.
2. **Installable PWA** — Add to Home Screen, instant open, cache-first with background
   update ("updated to vX" toast; never a reload mid-print).
3. **Kiosk** — same PWA fullscreen on a dedicated desk terminal.
4. **Fat single-file .html** — email / USB / air-gapped desks.

**The shared day-book.** The launcher owns one parsed, normalized reservation model per
day (the canonical flat record both tools already build, with its fallback-chain field
mapping) cached locally. Tools subscribe to it — drop the export once, every tool is fed.
Cross-tool events (audit says "payment unresolved" → envelope prints the settlement seal)
flow through this shared local store, never a server.

**When a backend earns its place** (and not before): cross-device shift handover, estate
dashboards, durable print/action logs. Then: Cloudflare Pages + one Worker + KV, behind
Cloudflare Access SSO — receiving **only** records like
`{property, tool, date, shift, counts:{arrivals:84, flagged:6, cleared:6}}` —
structurally incapable of identifying a guest. Offline-first stays intact: writes queue
in a local outbox and flush when connectivity returns.

---

## 5. Multi-hotel from day one — as data, not forks

The single highest-value platform move: **the Audit's hardcoded rulebook becomes config.**

```jsonc
// properties/fh-reykjavik.json  (inherits properties/_group-islandshotel.json)
{
  "schemaVersion": 1,
  "id": "fh-reykjavik",
  "group": "islandshotel",
  "name": "Fosshotel Reykjavík",
  "locale": "is",
  "brand": { "lockup": ["FOSSHOTEL", "REYKJAVÍK"], "logoRef": "fosshotel.png",
             "colors": { "accent": "#4599B4" } },
  "features": { "audit.crossCheck.yieldplanet": true, "envelopes.welcomeLetter": true },
  "audit": {
    "cardPaymentMethods": ["VI","MC","AX","DC","JC","CU","DS","VA","MA","EC","CP"],
    "invoiceMarkets": ["TO-GRP","TO-FIT","MICE-I","MICE","STAFF"],
    "noteMarkets":    ["TO-GRP","TO-FIT","MICE-I","MICE","CORP","GULL"],
    "otaMarketCode": "OTA",
    "patterns": { "vcc": "…", "poa": "…", "invoice": "…", "paymentLink": "…" }
  },
  "tax": { "accommodationPerNight": "…" },
  "letters": { "welcome": "…" }
}
```

- **Group defaults + property overrides** (shallow merge). Onboarding hotel group #2 =
  writing one `_group-*.json` with their market codes and payment rules.
- **Three load paths, one format:** fetched by the hosted shell · inlined into fat builds ·
  carried in the **setup bundle** — the envelope app's export/import JSON promoted to
  platform scope (`{platform:"vaktin", version, properties, brandOverrides, uiPrefs}`).
  A manager configures once and every desk imports one file. This is the distribution
  mechanism for air-gapped desks and the killer onboarding path — it already exists.
- **The envelope app's 18-property registry, logo resolver, and RESORT auto-detection**
  generalize into this layer unchanged in behavior.
- **Playbook governance** (later): version-stamped config packs with drift detection —
  "Fosshotel Höfn is 2 playbook versions behind" is visible, not silent.

---

## 6. One design language

Full token spec in the appendix; the reconciliation of the two apps' sibling styles:

- **Warm paper, cool ink.** Canvas `--paper #EEEDE0` (the envelope's oatmeal); screen ink
  `#16222E` (the audit's midnight slate) — a deliberate navy-on-cream editorial pairing.
  Dark mode themes the five screen neutrals only.
- **Two accents, re-roled.** Teal `#4599B4` = brand & interactive. Rescue orange
  `#E4572E` = critical/needs-action only. The severity ladder (S1/S2 critical,
  S3/S4 warn `#C08A00`, S5 note `#4A6B8A`, ok `#3E7C59`) is a platform signature.
- **Three type layers.** Familjen Grotesk (UI) · Spline Sans Mono (every ID, count, and
  data field) · Raleway **embedded** (everything that reaches paper). Print ink is soft
  `#404041` — letterpress, not laser-harsh.
- **Wordmark rule.** Every tool is `WORD·WORD`, the middot in accent teal:
  ARRIVALS·AUDIT, KEY·ENVELOPES, GUEST·COCKPIT, NIGHT·WATCH…
- **The print system is a component library** — DL/C6-C5 envelope, A4 cover, tag sheet,
  letter, flowing list, and the 10 mm calibration sheet as a standing feature of every
  print tool.
- **Trust as UX.** The ⛨ privacy line is a first-class element of every empty state.
- **A11y floor:** focus rings never removed, `prefers-reduced-motion` everywhere,
  keyboard cursor model (↑/↓, S/E/?, Ctrl+Z/P) standardized across tools.

---

## 7. The tool catalog

Curated from a 43-idea, six-persona ideation pass, feasibility-graded against how data
*actually* leaves Opera Cloud, and gap-checked against the full front-desk day. The core
insight from that pass: **don't ship ten arrival tools — ship two loved tools upgraded,
then cover the rest of the day nothing covers yet** (departures, night audit, room moves,
the unhappy path).

Feasibility legend: 🟢 export-ready today · 🟡 needs manual paste/typed input ·
🔵 needs OHIP APIs (later) · effort S/M/L · impact ●1–5

### 7a. The two flagships, upgraded (Wave 1)

**ARRIVALS·AUDIT 2.0** — *one tool, new superpowers as feature flags* 🟢 S–M ●5

- **kr-at-risk:** every flag carries its ISK exposure (rate × nights − deposit); the
  triage rack shows *money*, falling live as the desk clears items — so the 300 000 kr
  group gets fixed before the 6 000 kr walk-in.
- **Explain-&-fix:** each flag ships the exact Opera click-path to resolve it, plus a
  one-tap draft of the payment-link / card-request message (IS/EN, amount filled in) —
  the awkward conversation is killed *before* the guest arrives.
- **Day-memory:** conf-hashed local history surfaces *"flagged yesterday, still open"* —
  chronic risks stop hiding inside each morning's fresh-looking list.
- **Audit-hour mode:** drop the In-House list at night and arrivals split into
  checked-in-clean / checked-in-open-payment / never-arrived → feeds NIGHT·WATCH.
- **Concierge lane:** parsed requests get a department (HK / kitchen / FO), an owner, and
  a checkbox — "crib to 214" lives on housekeeping's printable run-sheet, not in one
  person's head.
- **Audit summary out:** emits a tiny local JSON (counts, flags, done-state) that every
  other tool consumes. The audit becomes the suite's data source, not a dead-end screen.

**KEY·ENVELOPES 2.0** — *the print engine learns the whole warm welcome* 🟢 S ●4

- **ETA sequencing & pre-cut wave:** print in the order the night actually arrives;
  a "cut these now" filter for keys due in the next two hours.
- **Pre-print manifest QA:** refuses to waste 90 envelopes on a rooming list with three
  unassigned rooms — names the broken rows first.
- **Settlement seal:** envelopes for unresolved-payment guests get a discreet "see front
  desk" mark, straight from the Audit summary. The night auditor's findings physically
  travel to the morning desk.
- **Warm print pack:** celebration cards, VIP amenity dockets, discreet dietary table
  cards, room-move tickets — one A4 tray run, in the guest's language.
- **Tomorrow-prep:** registration cards for room-assigned arrivals in the same batch.
- **Team mode (TEAM·KEYS):** per-group sports-team rules — one envelope *per person*
  (twins explode instead of merging), N keys per person, surname A–Z sort, name-first
  envelope face, utility-room keys (physio/kit), key-expiry marks, hospitality-desk
  handout manifest + cutting sheet. Full plan: [docs/features/team-keys.md](docs/features/team-keys.md).
- **De-grouping (ENVELOPES FOR EVERYONE):** guest-level selection picker, a Quick Print
  walk-in lane, per-guest occasion letters with auto-suggest, named print styles,
  per-group profiles, and saveable run presets.
  Full plan: [docs/features/custom-runs.md](docs/features/custom-runs.md).
- **North star — VAKTIN·STUDIO, the Canva of the front desk:** a visual template
  gallery of hotel print documents (signage, name cards, door hangers, table cards,
  program posters — plus everything above), block-based in-place editing, brand kit +
  live guest-data merge. *"Canva knows design; VAKTIN knows your guests."*
  Vision plan: [docs/features/studio.md](docs/features/studio.md).

### 7b. The arrivals rush (Wave 2)

| Tool | Pitch | Feas. | E | I |
|---|---|---|---|---|
| **GUEST·COCKPIT** | One search box → the one reservation (typo-tolerant, accent-folded, matches OTA ref / conf / company / card-tail) → one non-scrolling card: identity, requests that matter, **and the exact money sentence** — *"Prepaid through Expedia — nothing to collect but the accommodation tax of X"* — in the guest's language. The five-panel Opera check-in becomes one screen. | 🟢 | M | ●5 |
| **ARRIVAL·WAVES** | The shift as a timeline: ETA histogram by 30-min slot, flight numbers mined from notes → realistic landing waves, the early-arrival lane ("their room won't be ready — pre-print their luggage tags"), guaranteed-no-ETA flagged *expect after night audit*. | 🟢 | M | ●4 |
| **ROOM·FIT** | Every assigned room checked against its own guest's request — twin-asked-got-king, split families needing connecting rooms, and **accessibility as a hard compliance flag**, with a proposed swap from rooms actually free. Calm re-rooming at 22:00, not frantic at the desk. Needs a one-time Room Master CSV. | 🟢🟡 | M | ●5 |
| **MOMENTS·BOARD** | The 5-star gesture engine: celebrations (IS+EN, "brúðkaupsferð" included), VIP landing run-sheet with per-tier amenity dockets and ready-by countdowns, and the allergy/dietary breakfast brief **split by severity** — nut anaphylaxis in red at the top, oat-milk preference in grey at the bottom. Gestures get an owner and a "delivered" tick; cards print via the envelope engine. | 🟢 | M | ●5 |
| **GROUP·COMMAND** | Paste the organizer's spreadsheet next to Opera's rooming list → instant name-level diff (missing rooms, pax mismatches, not-in-block), cutoff vs pickup, welcome-desk one-pager, badges to the print engine. The two worlds finally line up *before* the bus arrives. | 🟢 | M | ●4 |

### 7c. In-house & the unhappy path (Wave 3)

| Tool | Pitch | Feas. | E | I |
|---|---|---|---|---|
| **MOVE·MATE** | Every room move as one card: vacate → clean → new key → luggage → billing-window continuity → notify. The friction cluster Opera makes you choreograph by memory. | 🟢 | S | ●4 |
| **TRACE·CHASER** | Every trace, wake-up and timed task due *this shift* in one closable list, overdue in red. The "night shift never saw the note" killer. | 🟢 | S | ●4 |
| **WALK·LIST** | Oversold? Ranked walk decisions before the lobby fills: who is cheapest and safest to relocate (rate, VIP, LOS, loyalty), where to, and what it costs. | 🟢 | M | ●4 |
| **READY·OR·NOT** | Tonight's arrivals × housekeeping status: no key handed to a dirty or OOO room. Honest limit: HK status is PDF-ish today — starts as a paste/manual board, becomes live with OHIP. | 🟡🔵 | M | ●4 |
| **MAKE·IT·RIGHT** | Incident & service-recovery log: complaint, comp, cost, owner, follow-up — survives shift change, feeds the handover. | 🟡 | S | ●3 |
| **FOUND·IT** | Lost & found: item → auto-matched to the room's last departed guest → shipped/claimed/closed. | 🟡 | S | ●3 |

### 7d. Departures & the money chain (Wave 3–4)

| Tool | Pitch | Feas. | E | I |
|---|---|---|---|---|
| **CHECKOUT·CLOSER** | The biggest gap in the day: every due-out with open balance, unsettled routing, and folio pre-checked *before* they hit the desk; express-checkout batch; invoice ready to send. | 🟢 | M | ●5 |
| **DEPOSIT·WATCHDOG** | Deposit ledger × arrivals × cancels: required-but-unpaid, paid-but-unapplied, and the **Forfeiture Finder** — a kr-totalled list of deposits the hotel is entitled to keep that would otherwise quietly refund. Found revenue. | 🟢 | M | ●4 |
| **VCC·COCKPIT** | Every virtual card on a charge-window calendar: "CHARGE TODAY OR LOSE IT", exact net kr pre-computed. Honest: activation truth lives with the OTA/processor → paste-assisted today, API later. | 🟡 | M | ●5 |
| **CLAWBACK** | Paste the OTA statement → per-line dispute memos: commission billed on no-shows, stayed rooms never remitted, wrong commission base. Recovers real money quarterly. | 🟡 | M | ●5 |
| **CHARGEBACK·SHIELD** | Pre-arrival risk list ("get a signed auth from these three tonight") + one-click dispute dossier assembling the evidence a bank wants. Prevention today, settlement history via OHIP later. | 🟢🔵 | M | ●4 |
| **COMPANY·INVOICE** | Reads the human billing sentence ("company pays room & breakfast") next to the machine routing and highlights the gap — killing "the company got charged for the minibar" at the source. Pro-forma pack per company. | 🟢 | L | ●4 |

### 7e. NIGHT·WATCH — the 03:00 companion (Wave 4)

One runbook tool with stations, because the night auditor works alone:

1. **Pre-flight:** who the date-roll is about to hurt — due-outs still in house, open
   folios, no-charge in-house rooms, predicted bad auto-settles — cleared *before* run.
2. **No-show adjudicator:** every unarrived reservation with the right decision computed
   (charge first night / forfeit deposit / hit the VCC within its window / waive) using
   the same loved payment classifier. Never touches a do-not-charge card.
3. **Cashier reconciler:** per-cashier expected totals, an ISK/EUR/USD denomination count
   pad, over/short stored for the morning; a "who hasn't closed yet" watchlist. 🟡
4. **The night pack:** occupancy/ADR/RevPAR, the Icelandic VAT breakout, tomorrow's
   VIP/group summary, OOO rooms — one document, and a **bilingual morning handover that
   writes itself**: *"122 arrivals incl. group of 40, 3 VIPs, ledger balanced, cashier 4
   short 300 kr — see note."*

(Trial-balance "find the exact bad posting" is graded **hard** — transaction-granular
ledger data doesn't cleanly export. It stays on the OHIP-era list rather than being
over-promised now.)

### 7f. The estate layer (Wave 5 — when hotel #2+ arrives)

| Tool | Pitch | Feas. |
|---|---|---|
| **ESTATE·BOARD** | Every hotel's morning on one screen: drop all properties' exports → per-property risk counts, OTA mix, blocks, a *who-do-I-call-first* ribbon sorted by open money risk — and it names the property that sent no file today. | 🟢 (one export per property) |
| **PASS·DOWN** | The shift-change note that writes itself from audit done-state + traces + deposits; a pending item nags on every handover until cleared. | 🟢 |
| **PLAYBOOK** | Config governance: edit shared rules once, export a signed version-stamped pack, see drift per property. | 🟢 |
| **DATA·RADAR** | A spell-checker for the PMS: completeness/quality rules scored 0–100 per property, a coachable league table where every finding is a conf-no fix-list, not a scold. | 🟢 |
| **TRAINER** | New hires practice on last week's *real* (client-side anonymized) arrivals: "VCC with no routing — what do you do?" Flashcards from this property's actual booking mix, quiz scores for onboarding. | 🟢 |

### 7g. The AI-native layer (Wave 6 — outside the box, PII still in the browser)

- **ASK·YOUR·DAY** — talk to tomorrow's book like a colleague: *"who arrives after 22:00
  with no card?"* A deterministic query compiler answers the structured 90 % instantly
  offline; fuzzy questions go to an in-browser WebGPU model or a redact-first gateway.
  Every answer is a live filter you can act on; pinned questions auto-answer against each
  morning's file before you ask.
- **MESSAGE·STUDIO** — every surfaced request becomes a drafted, tone-matched guest
  message (pre-arrival email, late-arrival key instructions, welcome letter) in IS/EN.
  Names never enter a prompt — they stay local `{{first_name}}` merges. Two clicks from
  request to printed letter via the envelope engine.
- **ÞEKKI·ÞIG ("I recognise you")** — the moonshot: a private, browser-only guest memory
  quietly accumulated from the exports the desk already loads every day. When a returning
  guest appears in tonight's arrivals it whispers: *"4th stay · last March asked for a
  feather-free duvet, high floor away from the lift · nut allergy · always lands off the
  late Flybus"* — and pre-fills Moments, Room-Fit, and the Cockpit. Recognition is the
  soul of concierge work; this delivers it offline, without waiting for Opera's CRM,
  and backfills from OHIP profiles when they open up.
- **The 30-second check-in** (OHIP era) — search box → passport MRZ / OTA QR scan →
  Cockpit opens → exact amount stated in the guest's language → one confirm cuts the key,
  prints the envelope, posts the check-in. Four minutes and five panels become forty
  seconds and one screen. Runs from the morning export when the network is down.
- **Estate autopilot** (OHIP era) — scheduled per-property pulls land nightly, the suite
  runs headless, and 06:00 delivers one ranked portfolio brief: KPIs, risk, hygiene
  score, playbook drift, money-left-on-the-table — worst property and highest-value
  action first.

---

## 8. The honest data story

Everything above is graded against how data *actually* leaves Opera Cloud:

- **Proven today:** the reservation-side reports the tools already parse —
  `res_detail`, `grprmlist`, `arrchkinbyroom` — plus arrivals/departures/in-house lists
  and the ledger reports with real Excel/CSV (Deposit Ledger, AR Aging). Caveat: BI
  Publisher defaults to PDF; getting structured output is a **one-time admin setup per
  property** (report config + Role Manager grants). Plan for that in onboarding.
- **Exports are snapshots.** Walk-ins and mid-shift changes drift between drops. Tools
  say when their data was loaded; the Waves/Cockpit tools show a "book age" stamp.
- **Manual-paste tier:** OTA commission statements, VCC processor windows, cash counts,
  the Room Master. The tools make the paste worth it (dispute memos, found revenue).
- **OHIP is the strategic path, not a toggle:** self-service partner registration is easy,
  but go-live is organizational — chain-level enablement, per-property authorization,
  metered usage. Design for it now (every tool lists its OHIP upgrade), start the
  enablement conversation with Íslandshótel IT early, build nothing that *requires* it
  before Wave 6. Streaming (business events over WebSockets) + the Reservation Async
  bulk pull are the right primitives; chatty polling is not.
- **Structural limits stated plainly:** card numbers are masked (card-tail matching =
  last-4, by design); free-text recall equals data-entry discipline; some report fields
  (NATIONALITY, MEMBERSHIP…) need the report template customized once.

---

## 9. Roadmap

| Phase | Scope | Exit test |
|---|---|---|
| **0 — Stop the bleeding** (days) | Embed the Audit's fonts (offline bug). Repo hygiene: `original/` preserved, monorepo skeleton, esbuild fat/thin build, both tools moved in **unchanged** as build targets. | Both tools byte-identical in behavior, genuinely offline, built not hand-maintained. |
| **1 — The spine** (2–4 wks) | Extract `ui/tokens.css` → shared widgets → `core/` runtime → **classifier as data**. `properties/*.json` with group inheritance. Platform-wide setup bundle. PWA shell + launcher + service worker. | Audit runs on envelope-grade multi-property config; one URL launches both tools; a setup bundle configures a fresh machine in one import. |
| **2 — Flagships 2.0** (3–5 wks) | ARRIVALS·AUDIT 2.0 (kr-at-risk, explain-&-fix, day-memory, audit-hour, concierge lane, summary-out) + KEY·ENVELOPES 2.0 (ETA sequencing, manifest QA, settlement seal, warm pack, tomorrow-prep). Shared day-book store. | The audit's findings visibly flow into the envelope run. Staff feel both tools got better without relearning anything. |
| **3 — The rush** (per tool: 1–3 wks) | GUEST·COCKPIT → ARRIVAL·WAVES → MOMENTS·BOARD → ROOM·FIT → GROUP·COMMAND, in feedback-driven order. First new-tool proof that the platform makes tool #3 cheap. | A check-in answered from one screen; a group day prepped from one diff. |
| **4 — The whole day** | CHECKOUT·CLOSER, NIGHT·WATCH, DEPOSIT·WATCHDOG, MOVE·MATE, TRACE·CHASER, then VCC·COCKPIT / CLAWBACK / CHARGEBACK·SHIELD / WALK·LIST as demand dictates. | The suite covers arrival→departure→date-roll; the morning handover writes itself. |
| **5 — The estate** (with hotel #2) | ESTATE·BOARD, PASS·DOWN, PLAYBOOK, DATA·RADAR, TRAINER. *Optional, trigger-gated:* the PII-free metadata Worker for cross-device handover & dashboards. | A second hotel group onboards via one config file + one setup bundle. |
| **6 — Live & smart** | OHIP enablement → live day-book (streaming + async bulk) under the same tools; ASK·YOUR·DAY, MESSAGE·STUDIO, ÞEKKI·ÞIG; the 30-second check-in. | The same UI, now real-time; the copilot has done the first pass before the shift sits down. |

Ship order within every phase follows one rule: **the thing a real shift asks for next.**

---

## 10. Name & positioning

Recommended: **VAKTIN** — *the shift, the watch*. It names the condition staff are in,
its vigilance sense maps exactly onto audit-and-cross-check tooling, it's ownable, and it
carries the editorial-Scandinavian soul the tools already have. Runner-up for a purely
international read: **Foyer**; plain-English alternative: **Front Bench**.

Trademark note: keep "Opera" out of the product name and repo eventually — Opera Cloud
appears only as a nominative descriptor (*"works alongside Opera Cloud"*). The wordmark
convention (`ARRIVALS·AUDIT`, teal middot), Familjen Grotesk, and the standing ⛨ privacy
line carry the brand across every tool.

---

## 11. What success looks like

- **Minutes:** pre-arrival audit + prep time per 100 arrivals, halved.
- **Money:** ISK-at-risk cleared before arrival; forfeitures captured; commission clawed
  back; chargebacks prevented — the suite reports these numbers itself.
- **Misses:** celebrations/allergies/accessibility requests fulfilled vs. found —
  tracked by the gesture board's own tick-offs.
- **Handover:** zero "the note wasn't seen" incidents; pass-down produced every shift.
- **Adoption:** tools opened per shift per property — the only vanity metric allowed,
  because an unopened tool catches nothing.
- **Onboarding:** hotel group #2 live in under a week, no code fork.

## 12. Risks, named

| Risk | Mitigation |
|---|---|
| Report/export access differs per property (PDF-only defaults, permissions) | Onboarding checklist per property; tools degrade gracefully and say exactly which export/setting is missing |
| OHIP enablement stalls organizationally | Nothing before Wave 6 requires it; every export-based tool is complete on its own |
| Free-text parsing misses what staff never typed | Confidence markers on fuzzy parses; DATA·RADAR coaches entry discipline upstream |
| Scope creep — 43 ideas is a trap | The catalog is a menu, not a promise; every wave ships only what a real shift asked for next |
| Platform work stalls the loved tools | Phase 0–1 changes zero behavior; flagship upgrades land before any new tool |
| Solo-maintainer bus factor | No framework, tiny build, boring tech, this document |

---

*Appendices — full research behind this plan (domain briefing & sources, architecture
analysis, 43-tool ideation with feasibility grades, design-token spec) are preserved in
[`docs/research/`](docs/research/).*
