From 41c0d05f7e4968dff021debd848f32bca48b1afd Mon Sep 17 00:00:00 2001 From: navin10sharma <3096611+navin10sharma@users.noreply.github.com> Date: Fri, 25 Sep 2026 13:37:30 +0530 Subject: [PATCH] Docs: specific README intro, plain punctuation, neutral spec and code comments --- README.md | 77 +++++++++++----------- design/picker-spec.md | 25 ++++--- lib/src/picker/picker_adaptive_layout.dart | 2 +- lib/src/picker/picker_cart_list.dart | 6 +- lib/src/picker/picker_cart_sheet.dart | 5 +- lib/src/picker/picker_checkout_cta.dart | 4 +- lib/src/picker/picker_dock_bar.dart | 2 +- lib/src/picker/picker_header.dart | 2 +- lib/src/picker/picker_layout.dart | 2 +- lib/src/picker/picker_map_controls.dart | 5 +- lib/src/picker/picker_system_overlay.dart | 2 +- test/design_tokens_test.dart | 2 +- test/picker_cart_card_test.dart | 2 +- test/picker_cart_sheet_test.dart | 4 +- test/picker_chrome_test.dart | 6 +- test/picker_components_test.dart | 4 +- test/picker_dock_bar_test.dart | 2 +- test/picker_system_overlay_test.dart | 2 +- test/picker_zoom_corner_test.dart | 8 +-- 19 files changed, 78 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index b08995a..4a4086a 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,11 @@ [![Dart](https://img.shields.io/badge/Dart-%E2%89%A53.4-0175C2.svg)](https://dart.dev/) [![License: MIT](https://img.shields.io/badge/license-MIT-111827.svg)](LICENSE) -SeatLayer is interactive seating chart software built for stadium scale. Platforms embed the white-label seat picker with their own checkout; organizers sell seated events on their own website with their own payment gateway. - -The official SeatLayer Flutter package adds an interactive seating chart and -seat picker to iOS and Android ticketing apps. Use Dart APIs and customizable +The official SeatLayer Flutter seat map SDK adds an interactive seating chart +and seat picker to Flutter ticketing apps on iOS and Android. Use Dart APIs and customizable Flutter widgets for live availability, best-available seats, and temporary -holds, then confirm bookings on your trusted backend. +holds, then confirm bookings on your trusted backend. SeatLayer is seating chart +and reserved-seat ticketing software built for venues up to stadium scale. [SeatLayer Flutter package on pub.dev](https://pub.dev/packages/seatlayer) · [Flutter seat-map documentation](https://docs.seatlayer.io/buyer-sdk/flutter/) · @@ -40,13 +39,13 @@ Benchmarked on public 100,000-, 150,000- and 200,000-seat venue fixtures on 15 S **Every piece of chrome is a Flutter widget.** The header, price rail, floor strip, section dock, seat confirm card, cart sheet, checkout button and the captions over the 3D scene and the seat-view -panorama are all Dart — drawn in your palette, laid out by Flutter, replaceable +panorama are all Dart: drawn in your palette, laid out by Flutter, replaceable one at a time. The SeatLayer venue map draws the geometry: seats, labels, section shells, the immersive scene and the panorama photograph. It knows Flutter owns the furniture, so it draws none of its own: no second tooltip, no second test badge, no duplicate button under a native one. -Three ways in, and they are a ladder — each level keeps what the one below gave +Three ways in, and they are a ladder: each level keeps what the one below gave you. Level 2 is not an escape hatch and level 3 is not a rewrite: the drop-in is built from exactly the widgets level 3 hands you. @@ -91,7 +90,7 @@ SeatLayerPicker( That is the whole flow: live inventory, price and accessibility filters, section and floor navigation, seat confirmation, GA and table prompts, Best Available, the cart, a hold with its countdown, real venue 3D, the seat-view panorama and -the checkout handoff. It fills the bounded space its parent gives it — do not +the checkout handoff. It fills the bounded space its parent gives it, so do not nest it in a gesture-driven `ListView` or `SingleChildScrollView`. `SeatLayerPickerPage(configuration:, onCheckout:)` is the same widget as a route @@ -99,11 +98,11 @@ you push; `showSeatLayerPicker(context, configuration:, presentation:)` is it as a modal returning the handoff, or `null` if the buyer closes it. `adaptive` is edge-to-edge on a phone and a constrained dialog at 700 logical pixels or wider; `.fullScreen` / `.dialog` force one. Both intercept close and system back and -release a picker-owned hold before the route leaves — a hold already handed to +release a picker-owned hold before the route leaves. A hold already handed to you is never released. **The renderer pin.** Each SDK release is pinned to a matching SeatLayer -renderer version — exported as `seatLayerHostedWebVersion` — so an app on a +renderer version (exported as `seatLayerHostedWebVersion`), so an app on a given `seatlayer` version always gets the same renderer, and `SeatLayerConfiguration(assetPath:)` points it elsewhere while you validate a pre-release. @@ -150,7 +149,7 @@ any other failed hold, and the seats are left selected and unheld rather than claimed. Add `SeatLayerPicker.routeObserver` so the same thing happens when your own -checkout screen pops back — that path never backgrounds the application, so +checkout screen pops back; that path never backgrounds the application, so nothing else can notice it: ```dart @@ -163,12 +162,12 @@ MaterialApp( It is optional: without it the lifecycle trigger still works and nothing complains. `SeatLayerPickerOptions(refreshOnResume: false)` turns both triggers off, and `announceHoldLapse: false` keeps the refresh but leaves the lapse -message to you — `onHoldExpired` fires either way. Call +message to you; `onHoldExpired` fires either way. Call `controller.refreshAvailability()` yourself from a composed layout. `refreshOnResume: false` stops the SDK *asking* for a read; it does not make it ignore one the runtime volunteers. Coming to the foreground re-reads -availability inside the runtime, and that answer is always applied — the +availability inside the runtime, and that answer is always applied: the runtime has already released a hold that ran out, so discarding what it reports would leave the buyer with an emptied cart and no explanation. Use `announceHoldLapse: false` when what you want is silence. @@ -177,14 +176,14 @@ would leave the buyer with an emptied cart and no explanation. Use Four levels, cheapest first. None of them rebuilds the layout or the flow. -**Colours and type — a theme.** One line adopts an app palette whole — before, +**Colours and type: a theme.** One line adopts an app palette whole. Before, the SeatLayer palette; after, yours, on the chrome and the drawn map together: ```dart theme: SeatLayerPickerThemeData.fromColorScheme(Theme.of(context).colorScheme), ``` -**One control's shape — a style slot.** Every surface the picker draws has a +**One control's shape: a style slot.** Every surface the picker draws has a slot on the theme, so one control changes without replacing the widget: ```dart @@ -202,10 +201,10 @@ Slots: `primaryButtonStyle`, `secondaryButtonStyle`, `continueButtonStyle`, `seatViewChromeStyle`, `dockBarStyle`, `confirmCardStyle`, `sheetStyle`, `headerStyle`, `pillStyle`. Button slots take a Material `ButtonStyle`; surface slots take a `SeatLayerSurfaceStyle` (colour, shape, elevation, padding, type). -Every widget owning a slot also takes `style:`, which wins for that one instance -— `SeatLayerDockBar(style: SeatLayerSurfaceStyle(shape: …))`. +Every widget owning a slot also takes `style:`, which wins for that one instance, +for example `SeatLayerDockBar(style: SeatLayerSurfaceStyle(shape: …))`. -**Sizes, visibility and words — layout, chrome switches, strings.** The spec's +**Sizes, visibility and words: layout, chrome switches, strings.** The spec's numbers are defaults, not constants, and every buyer-facing string is an override: @@ -224,12 +223,12 @@ options: SeatLayerPickerOptions( Or take the thirty-seven translations SeatLayer already ships, from the same reviewed dictionaries the drawn map uses: `strings: SeatLayerPickerStrings.forLocale(Localizations.localeOf(context))`. -It resolves by language, and by script for Chinese; an untranslated locale — and -any entry with no runtime wording, currently just `allFloors` — keeps its +It resolves by language, and by script for Chinese; an untranslated locale (and +any entry with no runtime wording, currently just `allFloors`) keeps its English default, and the result is an ordinary `SeatLayerPickerStrings` you can still override on top of. -**One whole part — a builder slot.** The builder receives the live state, the +**One whole part: a builder slot.** The builder receives the live state, the controller and the widget the drop-in would have rendered: ```dart @@ -246,7 +245,7 @@ Slots: `map`, `header`, `legend`, `floorStrip`, `sectionNavigator`, `dockBar`, The test badge and the required attribution have no builder slot: colours and type follow your theme, but required chrome cannot be returned as an empty -widget — a white-label entitlement turns attribution off, server-side. Organizer +widget; a white-label entitlement turns attribution off, server-side. Organizer ticket categories are likewise never rebranded, because they mean a price. ## Build your own layout @@ -309,8 +308,8 @@ await picker.setViewportInsets(insets); // frame clear of your own chrome Dispose a controller you created, and `await picker.close()` first so a picker-owned hold is acknowledged as released. -**Cover the map safely.** An `IgnorePointer` is not enough on iOS — UIKit can -hit-test the venue map beneath composited Flutter chrome — so bracket your own +**Cover the map safely.** An `IgnorePointer` is not enough on iOS: UIKit can +hit-test the venue map beneath composited Flutter chrome, so bracket your own overlay with `await picker.setMapInteractionEnabled(false)` and `true` in a `finally`, which makes the map itself inert. The turnkey layout already does this around its decision chrome. Do not wrap the map in an app-level drag or @@ -328,7 +327,7 @@ off the snapshot so they never buzz twice for one seat; `themeMode` resolves in one order: **your `themeMode` → your app's theme → the device.** `auto` reads `Theme.of(context).brightness` first, so it tracks the -dark-mode switch inside your app — the setting the buyer actually chose — and +dark-mode switch inside your app (the setting the buyer actually chose) and falls back to `MediaQuery.platformBrightness` only when no Material or Cupertino theme sits above the picker. Either reading is live: flip your app's theme or the device appearance and the chrome **and the drawn map** repaint together, no @@ -342,18 +341,18 @@ theme: const SeatLayerPickerThemeData(accent: Color(0xFFE54558)), The default constructor sets only the roles you name, so every ground role still comes from `themeMode`. Name `accent` alone and the ink on it is derived for you: white, the colour a brand already puts on its own, unless the accent is -pale enough that white cannot be read on it — a yellow, a mint, a near-white -tint — where it turns black. Pass `onAccent` to say it yourself and the picker +pale enough that white cannot be read on it (a yellow, a mint, a near-white +tint), where it turns black. Pass `onAccent` to say it yourself and the picker uses exactly that, whatever it reads like. **A preset pins the mode:** -`SeatLayerPickerThemeData.light()` and `.dark()` are complete ground palettes — +`SeatLayerPickerThemeData.light()` and `.dark()` are complete ground palettes; each also sends a contrast-paired `SeatLayerMapThemeData` for the canvas -background, row labels, free text and the selection ring — and an explicit +background, row labels, free text and the selection ring, and an explicit ground outranks a resolved mode, so `themeMode: auto` with `.light()` never goes dark. Reach for a preset when you want one fixed side; pick the preset yourself if you want both. The status and navigation bars are the picker's surface, so the picker dresses -them — light glyphs on a dark picker, dark on a light one, dark for the +them: light glyphs on a dark picker, dark on a light one, dark for the immersive scene either way, re-evaluated on every `auto` flip. `SeatLayerPickerChromeOptions(manageSystemOverlays: false)` opts out; `seatLayerPickerOverlayStyle(resolvedTheme)` still says what it would have set. @@ -379,7 +378,7 @@ Checkout transfers ownership: closing the picker afterwards must not release the hold, while closing *before* handoff releases a picker-owned one. Process termination cannot guarantee a release, so the server TTL is the final boundary. If a turnkey `onCheckout` throws, the picker rejects the handoff before -surfacing your error — it can release only the exact hold that session just +surfacing your error; it can release only the exact hold that session just handed over. A custom flow rolls back the same way: ```dart @@ -463,7 +462,7 @@ haptic map and `SeatLayerPickerStrings` all read the file, and ### How do I add a seat map to a Flutter app? Add the [`seatlayer` package](https://pub.dev/packages/seatlayer) and place a -`SeatLayerPicker` with your event key on a route. That is the whole buyer flow — +`SeatLayerPicker` with your event key on a route. That is the whole buyer flow: map, filters, seat confirmation, cart, holds and the checkout handoff. The quick start above is complete; the [Flutter seat-map integration guide](https://docs.seatlayer.io/buyer-sdk/flutter/) @@ -472,7 +471,7 @@ app that wants only the raw map and owns every control itself. ### Is SeatLayer a Flutter widget or only a JavaScript snippet? -It is a native Flutter picker — every control is a Flutter widget. +It is a native Flutter picker: every control is a Flutter widget. ### Which Flutter platforms are supported? @@ -490,8 +489,8 @@ book with a stable `bookingRef`. When a buyer selects seats, the SDK creates a temporary hold that reserves the inventory against concurrent buyers for a limited window. The hold expires -automatically if checkout does not complete — `onHoldExpired` tells the app to -return the buyer to the map — and `extendHold` and `resumeHold` cover longer +automatically if checkout does not complete (`onHoldExpired` tells the app to +return the buyer to the map), and `extendHold` and `resumeHold` cover longer checkouts and app restarts. This prevents double-selling without locking seats forever. @@ -504,14 +503,14 @@ back whichever of their seats are still free. Yes. SeatLayer never processes payment inside the seat map. The app hands the `holdId` to your backend, and your backend charges through any payment -provider you already use — Stripe, Adyen, Razorpay, or your own — before +provider you already use (Stripe, Adyen, Razorpay, or your own) before booking the hold through the [server-side checkout flow](https://docs.seatlayer.io/buyer-sdk/holds-and-checkout/). ### Can I try the Flutter seat map without a SeatLayer account or API key? -Yes. The repository's example app runs on a packaged offline fixture — no -account, event key or backend needed — and exercises the real Flutter view, +Yes. The repository's example app runs on a packaged offline fixture (no +account, event key or backend needed) and exercises the real Flutter view, venue map, commands and event streams. The fixture lives with the example rather than in the published package, so it costs your app nothing. Create a free SeatLayer test event when you are ready to validate live @@ -535,7 +534,7 @@ inventory, holds, snapshots and the checkout handoff. See ### Does the Flutter seat map support light and dark mode? Yes, live. `SeatLayerThemeMode.auto` follows your app's theme first and the -device second, and repaints the Flutter chrome and the drawn map together — +device second, and repaints the Flutter chrome and the drawn map together, without reloading, without losing the selection and without moving the camera. A `.light()` or `.dark()` preset pins one side deliberately. diff --git a/design/picker-spec.md b/design/picker-spec.md index 8698388..8b6ecf8 100644 --- a/design/picker-spec.md +++ b/design/picker-spec.md @@ -235,8 +235,8 @@ gate them, and the reference file. ### 3.1 Header -The header's hold pill is drawn for as long as a hold is live (owner call, -2026-09-05): it is the picker's ONE clock. There is no hold clock anywhere on +The header's hold pill is drawn for as long as a hold is live: it is the +picker's ONE clock. There is no hold clock anywhere on the cart sheet, in either state, and no "display buffer" on it — the pill shows the full server hold. This deliberately departs from the web's `data-peek-clock` rule, under which the pill stepped aside while a peek bar @@ -265,13 +265,13 @@ is the identity. `size.minimumHitTarget` centred on it. Copy `strings.close`. **Hold pill.** Drawn for as long as a live hold exists, whoever owns it -(owner call 2026-09-05: the clock is always in the header; a host that draws +(the clock is always in the header; a host that draws its own clock turns it off with the `showHoldPill` option). A true pill (`radius.pill`), a dot and `m:ss` in `type.pill`, tabular figures, with a `size.minimumHitTarget` reach. Resting look is the accent mixed lightly into the surface with accent- toned ink; while expiring it inverts to the full accent with `color.*.onAccent` and its dot pulses. Copy `strings.heldFor`. It is never hidden while the hold -lives — the countdown is said once, here (owner call, 2026-09-05). +lives: the countdown is said once, here. **Sales-closed pill.** Same pill geometry, deliberately neutral — the text colour on a lightly text-tinted surface, never the accent. Copy @@ -482,7 +482,7 @@ inset `size.mapAnchorInset` from the map's edges, with `size.mapAnchorGap` between members. Regions do not receive presses; their children do. Nothing free-floats. -**One column, bottom-right, on both compositions** (owner call, 2026-09-06). +**One column, bottom-right, on both compositions.** The ♿ filter disc heads it; the zoom discs follow. It used to stand alone in the bottom-left region — one control facing a stack of them, in the corner the floor rail already owns — and read as something the layout had forgotten. Who @@ -502,7 +502,7 @@ Every disc is `size.mapControlSize` across, the ♿ disc `size.zoomColumnGap`; the head disc's stepper rides beside it at `size.accessStepGap` (§3.4.1). -**There is no `−` disc on the phone** (owner call, 2026-09-06). It only ever +**There is no `−` disc on the phone.** It only ever had a rung of its own while the buyer was already among the seats: at a section's own frame the one step back is the whole venue, and that is the disc below it. Two discs for one move reads as a puzzle, and a disc that only @@ -1625,8 +1625,7 @@ Full entry: `components.md` › HoverCard. **Name** `SeatLayerCartSheet` · **slots** `sheetStyle`, `continueButtonStyle` · **file** `lib/src/picker/picker_cart_sheet.dart` -**THE COLLAPSED SHEET IS THE FOOTER BLOCK, AND NOTHING ELSE** (owner call -2026-09-06): the total line, the call to action and the by-line, in one set of +**THE COLLAPSED SHEET IS THE FOOTER BLOCK, AND NOTHING ELSE**: the total line, the call to action and the by-line, in one set of rules shared with the wide panel. **The cards wait behind the handle.** A list that unrolled itself every time a seat was added read as a panel the buyer had not opened, so the collapsed cart region has height zero (`_collapsedCart = 0`) @@ -1764,8 +1763,8 @@ seat (§3.10.2) leaves the sheet where the buyer put it. **Name** `SeatLayerCartList` / `SeatLayerCartCard` · **file** `lib/src/picker/picker_cart_list.dart` -ONE CARD PER TICKET, AND THE SAME CARD ON EVERY WIDTH (owner call 2026-09-06: -"cards should be the same design as desktop"). The phone used to draw a second +ONE CARD PER TICKET, AND THE SAME CARD ON EVERY WIDTH: the phone draws the same +card design as desktop. The phone used to draw a second cart — a bordered plate of `44` pt hairline-divided lines, with consecutive seats folded into runs behind a `+N more`. It saved real pixels and it cost the sheet its coherence: a bordered list on its own surface between a band of @@ -2358,7 +2357,7 @@ stepper, a range caption `strings.chooseMinMaxGuests`, and the action pair `strings.fewerGuests` / `strings.moreGuests`. Accessible name for the whole sheet: `strings.chooseTableGuests`. Capability `table-quantity-v1`. -#### 3.13.13 Seats already in checkout (N1, owner decision 2026-09-05: option B) +#### 3.13.13 Seats already in checkout The hold belongs to the host from the moment it is handed off, and the runtime refuses to grow or shrink it from the picker: `hold_owned_by_host` (a cart @@ -2728,7 +2727,7 @@ from the wrong one. ## 5. Capability index -| Capability | What it unlocks | +| Capability | What it enables | | --- | --- | | `native-chrome-contract-v1` | the runtime suppresses its own buyer chrome; native owns header, rail, dock, tray, prompts | | `viewport-insets-v1` | native reports the bands its chrome covers, so framing lands inside them | @@ -2758,7 +2757,7 @@ snapshot reports; their presence in the `hello` **command table** is the whole contract, and a runtime answering `unsupported_command` for one of them anyway leaves nothing on screen for the buyer to read (runtime 0.80.2+): -| Command | What it unlocks | +| Command | What it enables | | --- | --- | | `picker.setSelectionFocus { seatId \| null }` | the seat a card is asking about is painted as the candidate — thick double ring, halo, neighbours paled (§3.8.2) | | `picker.setBlockedRegions { rects }` | the runtime's own tap guard under native chrome over the map (§2.4) | diff --git a/lib/src/picker/picker_adaptive_layout.dart b/lib/src/picker/picker_adaptive_layout.dart index 8fa6253..5e4c221 100644 --- a/lib/src/picker/picker_adaptive_layout.dart +++ b/lib/src/picker/picker_adaptive_layout.dart @@ -228,7 +228,7 @@ class _SeatLayerPickerAdaptiveLayoutState final immersiveUp = panoramaUp || venue3DUp; // Whether the scene has finished diving to a seat. final targeted = state.snapshot?.map.view3DTargetSeatId != null; - // NO DOCK ON THE PHONE by default (owner call, 2026-09-04). The bar + // NO DOCK ON THE PHONE by default. The bar // is auto-resolved wide-only, and the drop-in mounts it only in the // narrow branch, so by default nothing docks anywhere and a phone's // bottom-corner controls sit at the map's own edge. A host that asks diff --git a/lib/src/picker/picker_cart_list.dart b/lib/src/picker/picker_cart_list.dart index 2600123..491d1e8 100644 --- a/lib/src/picker/picker_cart_list.dart +++ b/lib/src/picker/picker_cart_list.dart @@ -7,8 +7,8 @@ /// footer reads as three blocks stacked in a panel rather than as one panel — /// and it was a second rendering of one cart to keep in step with the first. /// -/// So there is one card now (owner call 2026-09-06: "cards should be the same -/// design as desktop"): a colour dot, the name, the position and type in grey +/// So there is one card now, the same design as desktop: a colour dot, the +/// name, the position and type in grey /// under it, whatever the organizer has said about the seat, the price, and the /// two actions. The collapsed sheet caps the list at three of them and scrolls /// (see `picker_cart_sheet.dart`), which is the same answer folding gave @@ -187,7 +187,7 @@ class _SeatLayerCartListState extends State { /// mark is dropped by the snapshot that no longer carries the line, or /// restored here if the mutation fails. /// The map frames the seat at its resting place. The sheet STAYS where the - /// buyer put it (owner call 2026-09-06): it used to step down to peek on + /// buyer put it: it used to step down to peek on /// every card tap, so checking three or four seats meant opening the sheet /// three or four times. The phone map sits above the sheet in the same /// column, so the seat lands in the room the open sheet leaves it. diff --git a/lib/src/picker/picker_cart_sheet.dart b/lib/src/picker/picker_cart_sheet.dart index 0e7f78f..3070aa3 100644 --- a/lib/src/picker/picker_cart_sheet.dart +++ b/lib/src/picker/picker_cart_sheet.dart @@ -26,9 +26,8 @@ import 'seat_layer_picker_theme.dart'; /// The buyer's cart, docked at the bottom of the phone. /// -/// ONE SURFACE, AND THE COLLAPSED SHEET IS THE FOOTER (owner call -/// 2026-09-06). It used to be three stacked blocks that had each been designed -/// well on its own and none of which agreed with the others: a chrome band +/// ONE SURFACE, AND THE COLLAPSED SHEET IS THE FOOTER. It used to be three +/// stacked blocks that had each been designed well on its own and none of which agreed with the others: a chrome band /// carrying a bespoke one-liner — `From €25 · Find seats` with nothing picked, /// `2 tickets · Continue €60` once seats existed — then a bordered list on its /// own ground, then a shadowed foot. Two summaries of one cart is two things diff --git a/lib/src/picker/picker_checkout_cta.dart b/lib/src/picker/picker_checkout_cta.dart index 4371670..f02a8c4 100644 --- a/lib/src/picker/picker_checkout_cta.dart +++ b/lib/src/picker/picker_checkout_cta.dart @@ -162,8 +162,8 @@ SeatLayerCheckoutCtaState seatLayerCheckoutCtaState({ return reason(strings.adjustSelection); } - // 6. THE EMPTY PHONE CART HAS A DOOR, NOT A DEAD BUTTON (owner call - // 2026-09-05). The same button offers the best-seats form instead, gated + // 6. THE EMPTY PHONE CART HAS A DOOR, NOT A DEAD BUTTON. The same button + // offers the best-seats form instead, gated // exactly as the tray's own card is: a performance group or an existing // hold means no card would render, and a door into an empty room is // worse than none. The caller decides that and passes [canOfferFind]. diff --git a/lib/src/picker/picker_dock_bar.dart b/lib/src/picker/picker_dock_bar.dart index e6cdc28..81556e2 100644 --- a/lib/src/picker/picker_dock_bar.dart +++ b/lib/src/picker/picker_dock_bar.dart @@ -15,7 +15,7 @@ import 'seat_layer_picker_theme.dart'; /// Where the buyer is, and the two ways out, docked under the map. /// -/// THE DROP-IN MOUNTS NO DOCK ON A PHONE (owner call, 2026-09-04). Pinch-out +/// THE DROP-IN MOUNTS NO DOCK ON A PHONE. Pinch-out /// and the zoom-out stepper already walk a buyer back to the venue, so the /// prev/next arrows bought a two-tap version of a gesture the finger does /// better, and the bar's height plus the home-indicator inset pushed every diff --git a/lib/src/picker/picker_header.dart b/lib/src/picker/picker_header.dart index c4b22df..74242fe 100644 --- a/lib/src/picker/picker_header.dart +++ b/lib/src/picker/picker_header.dart @@ -100,7 +100,7 @@ class SeatLayerPickerHeader extends StatelessWidget { SeatLayerPickerSalesClosedPill(compact: compact)), gap, ], - // The one clock in the picker (owner call, 2026-09-05): it + // The one clock in the picker: it // stands here for as long as the hold does, and the Continue // pill below stays a button. It used to step aside while the // collapsed cart's pill carried the clock, the web's diff --git a/lib/src/picker/picker_layout.dart b/lib/src/picker/picker_layout.dart index 47f72c4..30522b5 100644 --- a/lib/src/picker/picker_layout.dart +++ b/lib/src/picker/picker_layout.dart @@ -6,7 +6,7 @@ import 'picker_tokens.g.dart'; /// /// Every number the phone layout depends on lives here rather than inside a /// widget, so an integrator can retune the chrome without forking it. The -/// defaults are the owner-approved phone specification and are what the +/// defaults are the approved phone specification and are what the /// zero-configuration [SeatLayerPicker] renders. @immutable class SeatLayerPickerLayout { diff --git a/lib/src/picker/picker_map_controls.dart b/lib/src/picker/picker_map_controls.dart index e75c64b..d9ddc15 100644 --- a/lib/src/picker/picker_map_controls.dart +++ b/lib/src/picker/picker_map_controls.dart @@ -223,7 +223,7 @@ class _CornerControls extends StatelessWidget { const SeatLayerPickerAccessibilityFilters(compact: true), ], ), - // "+" and the whole-venue disc, nothing between them (owner, 2026-09-06): + // "+" and the whole-venue disc, nothing between them: // a "−" that only sometimes had a step to take read as a control that // sometimes worked. Pinch steps out; the disc below goes home. // "+" retires once the buyer is among the seats or at the zoom ceiling @@ -520,8 +520,7 @@ class SeatLayerPickerZoomOutButton extends StatelessWidget { tooltip: SeatLayerPickerScope.stringsOf(context).zoomOut, // Live only once the buyer is in among the seats: at a section's own // frame the only step back is the whole venue, and that is the disc - // below this one. Two discs for one move read as a puzzle (owner, - // 2026-09-06). + // below this one. Two discs for one move read as a puzzle. onPressed: map?.canStepBack == false || map?.rung != 'seats' ? null : controller.zoomOut, diff --git a/lib/src/picker/picker_system_overlay.dart b/lib/src/picker/picker_system_overlay.dart index 8e96330..0aa20da 100644 --- a/lib/src/picker/picker_system_overlay.dart +++ b/lib/src/picker/picker_system_overlay.dart @@ -12,7 +12,7 @@ import 'seat_layer_picker_theme.dart'; /// The bars are the host operating system's, but the surface behind them is /// the picker's, so the picker is the only thing that can know what colour /// the clock has to be. A dark picker with the platform's default dark icons -/// is what the owner reported: a clock, a wifi glyph and a battery drawn in +/// is what was reported: a clock, a wifi glyph and a battery drawn in /// near-black on a near-black header, invisible until the buyer tilts the /// phone into the light. /// diff --git a/test/design_tokens_test.dart b/test/design_tokens_test.dart index c5fae3d..01ad044 100644 --- a/test/design_tokens_test.dart +++ b/test/design_tokens_test.dart @@ -83,7 +83,7 @@ void main() { expect(light.radius, radius['base']); expect(light.buttonRadius, radius['button']); expect(dark.buttonRadius, radius['button']); - // The owner's decision, pinned: the picker's actions round like the web + // The design decision, pinned: the picker's actions round like the web // picker's (~8 pt), and only the hold pill, the legend chips and the // Map/3D control are true pills. expect(radius['button'], lessThan(radius['base']! as num)); diff --git a/test/picker_cart_card_test.dart b/test/picker_cart_card_test.dart index eee0b59..48458d2 100644 --- a/test/picker_cart_card_test.dart +++ b/test/picker_cart_card_test.dart @@ -240,7 +240,7 @@ void main() { testWidgets('tapping a card takes the map to the seat and keeps the sheet', (tester) async { // The sheet used to step down to peek on every card tap, so checking - // three seats meant opening the cart three times (owner, 2026-09-06). + // three seats meant opening the cart three times. final map = FakePickerMap( bundle: nativeChromeBundle( commands: const ['picker.frameSeat'], diff --git a/test/picker_cart_sheet_test.dart b/test/picker_cart_sheet_test.dart index 25e1e35..b79a7cd 100644 --- a/test/picker_cart_sheet_test.dart +++ b/test/picker_cart_sheet_test.dart @@ -856,7 +856,7 @@ void main() { map.emit(pickerSnapshot(holdOwner: 'picker')); await tester.pump(); - // Shut or open, no `m:ss` on the bar (owner call, 2026-09-05): the + // Shut or open, no `m:ss` on the bar: the // header's hold pill is the picker's one clock, and the Continue pill // stays a button. expect(find.textContaining(RegExp(r'\d:\d\d')), findsNothing); @@ -1044,7 +1044,7 @@ void _clockTests() { final button = tester.getRect(find.byType(FilledButton)); expect(button.top, greaterThan(sheet.top)); expect(button.bottom, lessThanOrEqualTo(sheet.bottom - _safeBottom + .01)); - // And no `m:ss` anywhere on it (owner call, 2026-09-05): the header's hold + // And no `m:ss` anywhere on it: the header's hold // pill is the picker's one clock. expect(find.textContaining(RegExp(r'\d:\d\d')), findsNothing); }); diff --git a/test/picker_chrome_test.dart b/test/picker_chrome_test.dart index 9c7a100..dafbfc4 100644 --- a/test/picker_chrome_test.dart +++ b/test/picker_chrome_test.dart @@ -476,7 +476,7 @@ void main() { // Two discs in the column now: "+" above the whole-venue disc. expect(stepIn.bottom, lessThan(wholeVenue.top + .5)); // THE ♿ DISC IS THE HEAD OF THAT COLUMN, not a lone control in the - // opposite corner (owner call 2026-09-06). Same right edge as the + // opposite corner. Same right edge as the // discs, and above `+`. expect(access.right, closeTo(screen.right - inset, .5)); expect(access.bottom, lessThan(stepIn.top + .5)); @@ -722,9 +722,7 @@ void main() { } void _headerClockTests() { - testWidgets( - 'the header keeps the one clock, shut or open (owner call, 2026-09-05)', - (tester) async { + testWidgets('the header keeps the one clock, shut or open', (tester) async { final map = FakePickerMap(); addTearDown(map.dispose); usePhoneSurface(tester); diff --git a/test/picker_components_test.dart b/test/picker_components_test.dart index 2164970..120aba1 100644 --- a/test/picker_components_test.dart +++ b/test/picker_components_test.dart @@ -586,9 +586,9 @@ void main() { expect(interactionCalls.last.$2, {'enabled': true}); }); - // N1 (owner decision 2026-09-05, option B): a buyer back from checkout who + // §3.13.13: a buyer back from checkout who // tries to change their seats meets a state with a way out, in their own - // words — not the bridge's `hold_owned_by_host` sentence. + // words, not the bridge's `hold_owned_by_host` sentence. testWidgets('a hold the host owns is a state with a way out, not an error', (tester) async { final map = _FakeMapController( diff --git a/test/picker_dock_bar_test.dart b/test/picker_dock_bar_test.dart index 1c9abb5..65830ff 100644 --- a/test/picker_dock_bar_test.dart +++ b/test/picker_dock_bar_test.dart @@ -244,7 +244,7 @@ void main() { }); group('the name never loses letters before anything else does', () { - // The owner's screenshot: `Sponsor Ta… · 72 left`. A truncated place name + // A reported screenshot: `Sponsor Ta… · 72 left`. A truncated place name // is the one thing in the dock a buyer cannot reconstruct, and it was // being cut while the count still spelled out its own word. testWidgets('a long name keeps its letters and the count keeps its word', diff --git a/test/picker_system_overlay_test.dart b/test/picker_system_overlay_test.dart index 591582b..c23dbbc 100644 --- a/test/picker_system_overlay_test.dart +++ b/test/picker_system_overlay_test.dart @@ -1,6 +1,6 @@ // The device's clock, wifi glyph and battery are drawn by the operating // system on a surface the picker owns, so the picker has to say what colour -// they should be. The owner's screenshot of the dark picker showed the iOS +// they should be. A screenshot of the dark picker showed the iOS // defaults: near-black glyphs on a near-black header, invisible. import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; diff --git a/test/picker_zoom_corner_test.dart b/test/picker_zoom_corner_test.dart index f54d934..fdbdff1 100644 --- a/test/picker_zoom_corner_test.dart +++ b/test/picker_zoom_corner_test.dart @@ -108,7 +108,7 @@ void main() { ); expect(find.byType(SeatLayerPickerZoomInButton), findsOneWidget); - // No "−" on the phone (owner, 2026-09-06): pinch steps out, the disc goes home. + // No "−" on the phone: pinch steps out, the disc goes home. expect(find.byType(SeatLayerPickerZoomOutButton), findsNothing); expect(find.byType(SeatLayerPickerShowWholeVenueButton), findsOneWidget); }); @@ -280,9 +280,9 @@ void main() { }); group('the ♿ disc heads the column', () { - // Owner call 2026-09-06. It stood alone in the map's bottom-left corner — - // one control facing a stack of them, in the corner the floor selector - // owns — and read as something the layout had forgotten. It is the top + // It used to stand alone in the map's bottom-left corner (one control + // facing a stack of them, in the corner the floor selector owns) and read + // as something the layout had forgotten. It is the top // disc of the right-hand column now, on BOTH layouts, because who can sit // where is an earlier question than how close the camera is. testWidgets('on the phone, above `+` and off the opposite corner',