@seatlayer/core 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -267,7 +267,32 @@ interface TextObject {
267
267
  rotation: number;
268
268
  color?: string;
269
269
  }
270
- type ChartObject = RowObject | GAAreaObject | ShapeObject | TableObject | BoothObject | TextObject | SectionObject;
270
+ /**
271
+ * A raster/vector decor graphic drawn IN the chart, beneath the seats and
272
+ * sections (ice rink, basketball court, stage art, pitch markings). Purely
273
+ * visual venue context — never bookable, never hit-tested, so it never steals a
274
+ * seat click. `href` is a self-contained data URL (image or SVG) produced by the
275
+ * same client-side downscale used for row photos, so it travels with the doc and
276
+ * caches as a single bitmap blit (zero per-frame cost). Placed by top-left
277
+ * (x,y) + size, rotated about its centre — the same handles a shape rect uses.
278
+ */
279
+ interface DecorImageObject {
280
+ type: 'decorImage';
281
+ id: string;
282
+ /** Image or SVG data URL. */
283
+ href: string;
284
+ x: number;
285
+ y: number;
286
+ width: number;
287
+ height: number;
288
+ /** Degrees clockwise about the image centre (default 0). */
289
+ rotation?: number;
290
+ /** 0–1 (default 1). Multiplied by any chart-theme dimming at render time. */
291
+ opacity?: number;
292
+ /** Optional caption for the designer inspector / accessibility (not drawn). */
293
+ label?: string;
294
+ }
295
+ type ChartObject = RowObject | GAAreaObject | ShapeObject | TableObject | BoothObject | TextObject | SectionObject | DecorImageObject;
271
296
  /**
272
297
  * One floor / level of a multi-floor venue (Batch 5). Each floor owns its own
273
298
  * geometry, stage focal point, and trace image; categories/zones/tiers stay
@@ -423,8 +448,41 @@ interface ISeatmapRenderer {
423
448
  setAccessibilityFilter(types: AccessibilityType[] | null): void;
424
449
  /** Legend hover-highlight: dim free seats of other categories (null clears). */
425
450
  setCategoryHighlight?(key: string | null): void;
451
+ /** Price-band filter (F4): dim free seats whose category is NOT in `keys`
452
+ * (null clears). The widget resolves which categories fall in the band. */
453
+ setCategoryFilter?(keys: string[] | null): void;
426
454
  /** Dim the seats of these section/zone ids (organizer manager: held-back inventory). */
427
455
  setDimmedSections?(ids: string[] | null): void;
456
+ /**
457
+ * Phase 2 event-level section states: mark these section/zone ids `closed` —
458
+ * flat grey block, seats greyed + not pickable, section stays rendered.
459
+ * `null`/empty clears. (Distinct from the buyer's applyHidden seat-strip.)
460
+ */
461
+ setClosedSections?(ids: string[] | null): void;
462
+ /**
463
+ * AXS section-focus: dim + desaturate every other section, draw a calm backdrop
464
+ * behind this section, and glide the camera to frame it. Seat-picking is gated
465
+ * until seats are large enough on screen (≥ LABEL_SCALE). Slice 5 / Phase 2 §4.
466
+ */
467
+ focusSection?(id: string): void;
468
+ /** Clear an AXS section focus (restore full-bowl brightness + drop backdrop). */
469
+ clearSectionFocus?(): void;
470
+ /** The currently AXS-focused section id, or null. */
471
+ getFocusedSection?(): string | null;
472
+ /** World-space rect currently visible in the viewport (minimap viewport frame). */
473
+ getVisibleWorldRect?(): {
474
+ x: number;
475
+ y: number;
476
+ width: number;
477
+ height: number;
478
+ };
479
+ /** Axis-aligned world bounds of all seats + section outlines (minimap frame). */
480
+ getWorldBounds?(): {
481
+ x: number;
482
+ y: number;
483
+ width: number;
484
+ height: number;
485
+ };
428
486
  /**
429
487
  * Colorblind-safe mode: category hues switch to an Okabe-Ito palette and
430
488
  * booked seats render hollow (a non-color cue), so seat state never relies
@@ -579,11 +637,13 @@ declare const UNGROUPED_ID = "__ungrouped__";
579
637
  * 'hidden' — manual: hidden until the organizer reveals it (3.3).
580
638
  * 'timed' — hidden until `revealAt` (epoch ms), then auto-reveals.
581
639
  * 'threshold' — auto-reveals once the on-sale inventory is `thresholdPct`% sold.
640
+ * 'closed' — visible to buyers but not purchasable (rendered flat grey);
641
+ * unlike 'hidden', the seats stay on the map, just off sale.
582
642
  * `labels` are the seat labels the id governs, so a threshold's denominator can
583
643
  * exclude still-hidden seats.
584
644
  */
585
645
  interface AvailabilityRule {
586
- mode: 'hidden' | 'timed' | 'threshold';
646
+ mode: 'hidden' | 'timed' | 'threshold' | 'closed';
587
647
  revealAt?: number;
588
648
  thresholdPct?: number;
589
649
  labels?: string[];
@@ -678,6 +738,8 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
678
738
  private accessFilter;
679
739
  /** Category highlight (legend hover): dims free seats NOT of this category. */
680
740
  private categoryHighlight;
741
+ /** Price-band filter (F4): dim free seats whose category is NOT in this set. */
742
+ private categoryFilter;
681
743
  private sections;
682
744
  private zones;
683
745
  private seatSection;
@@ -686,6 +748,13 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
686
748
  private currency;
687
749
  /** Section/zone ids to render dimmed (organizer manager: held-back inventory). */
688
750
  private dimmedSections;
751
+ /** Phase 2: section/zone ids in the event-level `closed` state — flat grey
752
+ * block, seats greyed + not pickable, but the section stays rendered. */
753
+ private closedSections;
754
+ /** AXS section-focus: the currently-focused section id (others dim), or null. */
755
+ private focusedSectionId;
756
+ /** Light backdrop panel drawn behind the focused section (removed on clear). */
757
+ private focusBackdrop;
689
758
  /** Object id → floor id (multi-floor only) — resolves a deck tap in the 3D stack. */
690
759
  private objectFloor;
691
760
  /** Zone id → colour (drives extruded side faces in iso view). */
@@ -769,6 +838,12 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
769
838
  setAccessibleFilter(on: boolean): void;
770
839
  setAccessibilityFilter(types: AccessibilityType[] | null): void;
771
840
  private sameAccessFilter;
841
+ /**
842
+ * Price-band filter (F4): dim free, unselected seats whose category key is NOT
843
+ * in `keys`. `null` clears the filter (all categories fully visible). The
844
+ * widget resolves which categories fall inside the buyer's chosen band.
845
+ */
846
+ setCategoryFilter(keys: string[] | null): void;
772
847
  /**
773
848
  * Switch the projection between flat top-down and the isometric "3D" view
774
849
  * (rotate + y-squash about the chart centre, plus per-elevation lift). Tweens
@@ -821,6 +896,8 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
821
896
  private seatBaseColor;
822
897
  /** Apply fill/stroke/opacity for a seat's current status + selection. */
823
898
  private paintSeat;
899
+ /** True when a seat sits in a section/zone currently marked `closed`. */
900
+ private seatInClosedSection;
824
901
  /**
825
902
  * Colorblind-safe mode: swap category hues for the Okabe-Ito palette and
826
903
  * render booked seats hollow. Off restores the exact default rendering.
@@ -832,11 +909,53 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
832
909
  * clears. Unlike the buyer's applyHidden, the sections stay rendered.
833
910
  */
834
911
  setDimmedSections(ids: string[] | null): void;
912
+ /**
913
+ * Phase 2 event-level section states: mark these section/zone ids `closed` —
914
+ * flat grey block, seats greyed + not pickable, but the section stays rendered
915
+ * (unlike the buyer's applyHidden which strips it). `null`/empty clears.
916
+ */
917
+ setClosedSections(ids: string[] | null): void;
918
+ /**
919
+ * AXS section-focus: dim + desaturate every other section, draw a calm backdrop
920
+ * panel behind this section's seats, and glide the camera in to frame it (the
921
+ * seat-pick gate below only lets buyers pick once seats are ≥ LABEL_SCALE big).
922
+ */
923
+ focusSection(id: string): void;
924
+ /** Clear an AXS section focus — restore full-bowl brightness + drop the backdrop. */
925
+ clearSectionFocus(): void;
926
+ /** The currently AXS-focused section id, or null. */
927
+ getFocusedSection(): string | null;
928
+ /** Draw (or replace) the light backdrop panel behind the focused section. */
929
+ private drawFocusBackdrop;
930
+ /** Repaint every seat + section block to reflect closed/focus state, then redraw. */
931
+ private repaintSectionsAndSeats;
932
+ /** The world-space rectangle currently visible in the viewport (minimap F3). */
933
+ getVisibleWorldRect(): {
934
+ x: number;
935
+ y: number;
936
+ width: number;
937
+ height: number;
938
+ };
939
+ /** Axis-aligned world bounds of all seats + section outlines (minimap F3 frame). */
940
+ getWorldBounds(): {
941
+ x: number;
942
+ y: number;
943
+ width: number;
944
+ height: number;
945
+ };
835
946
  /** Legend hover: highlight one category (dim the rest), or null to clear. */
836
947
  setCategoryHighlight(key: string | null): void;
837
948
  private renderBackground;
838
949
  /** Organizer floor-plan photo, dimmed, at the very bottom of the bg layer. */
839
950
  private renderBackgroundImage;
951
+ /**
952
+ * A decor graphic (rink / court / stage art). The KImage node is added to the
953
+ * bgLayer synchronously so it keeps its z-slot beneath the sections drawn right
954
+ * after; the bitmap is decoded async and pasted in on load. A single node = a
955
+ * single drawImage per frame, and it rides the same layer cache — effectively
956
+ * zero per-frame cost. Never listens, so it can't intercept a seat click.
957
+ */
958
+ private renderDecorImage;
840
959
  private renderTable;
841
960
  private renderText;
842
961
  private renderShape;
@@ -854,6 +973,14 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
854
973
  private renderSection;
855
974
  /** Recompute a section's availability-tinted fill + "N LEFT" (cheap; on status change). */
856
975
  private refreshSectionFill;
976
+ /** True when a section/zone is currently in the `closed` event-state. */
977
+ private isSectionClosed;
978
+ /**
979
+ * The block-fill colour for a section: flat desaturated grey when `closed`,
980
+ * else the availability-darkened category mix; then desaturated toward neutral
981
+ * when another section holds focus (AXS dim treatment).
982
+ */
983
+ private sectionBlockFill;
857
984
  /**
858
985
  * Zone rung: one giant screen-constant label per zone (+ optional "FROM $n"),
859
986
  * shown at the farthest zoom in place of per-section detail. Skipped entirely
@@ -870,6 +997,15 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
870
997
  * Section/zone labels are scale-compensated to hold a roughly constant screen size.
871
998
  */
872
999
  private applySectionLod;
1000
+ /**
1001
+ * Greedy label de-collision for the zone/section rungs (same approach as the
1002
+ * designer's cullRowLabels): price/"N LEFT" sublabels are lowest priority and
1003
+ * drop first; name labels keep top-to-bottom, left-to-right; anything whose
1004
+ * on-screen box (+4px gap) overlaps an already-kept box hides. Recomputed on
1005
+ * every LOD pass so hidden labels reappear as zoom spreads them apart.
1006
+ * Culling multiplies the opacity applySectionLod just assigned (never raises).
1007
+ */
1008
+ private decollideRungLabels;
873
1009
  /** Set a centred label's world fontSize (for a target screen px) and re-anchor it. */
874
1010
  private sizeLabel;
875
1011
  /**
@@ -1056,6 +1192,7 @@ interface PickerTransport {
1056
1192
  objects(key: string): Promise<{
1057
1193
  seats: Record<string, string>;
1058
1194
  hidden?: string[];
1195
+ closed?: string[];
1059
1196
  }>;
1060
1197
  hold(key: string, selections: HoldSelectionRequest[], ttlMs?: number, replaceHoldId?: string): Promise<HoldResponse>;
1061
1198
  bestAvailable(key: string, qty: number, categoryKey?: string): Promise<BestAvailableResponse>;
@@ -1127,6 +1264,9 @@ declare class PickerController {
1127
1264
  private _doc;
1128
1265
  /** Section/zone ids hidden from buyers this event (3.3) — seats vanish, not grey. */
1129
1266
  private hidden;
1267
+ /** Section/zone ids in the `closed` event-state (Phase 2) — seats stay, greyed
1268
+ * + not pickable. Kept separate from `hidden` (which strips them). */
1269
+ private closedSections;
1130
1270
  /** label ⇄ id maps — backend speaks labels, the engine speaks ids. */
1131
1271
  private labelToId;
1132
1272
  private labelToSeat;
@@ -1149,6 +1289,11 @@ declare class PickerController {
1149
1289
  private visibleDoc;
1150
1290
  /** Adopt a new hidden set; rebuild the visible chart only if it differs. */
1151
1291
  private syncHidden;
1292
+ /** Adopt a new closed-section set; restyle (grey + non-pickable) if it differs.
1293
+ * Cheap restyle — no chart rebuild — so mid-sale open/close repaints live. */
1294
+ private syncClosed;
1295
+ /** Whether a section is currently in the `closed` state (card must not open). */
1296
+ isSectionClosed(id: string): boolean;
1152
1297
  currentHold(): HoldInfo | null;
1153
1298
  getRenderer(): ISeatmapRenderer | null;
1154
1299
  seatByLabel(label: string): ExpandedSeat | undefined;
@@ -1189,6 +1334,8 @@ declare class PickerController {
1189
1334
  * onStatusChange — this is what a price panel's "N left" counters read.
1190
1335
  */
1191
1336
  categoryAvailability(): Record<string, number>;
1337
+ /** Seat ids belonging to a currently-closed section (excluded from counts). */
1338
+ private closedMemberIds;
1192
1339
  getGAAreas(): {
1193
1340
  id: string;
1194
1341
  label: string;
@@ -1257,11 +1404,31 @@ declare class PickerController {
1257
1404
  getRung(): LodRung;
1258
1405
  /** Jump to a rung; ZONES clears any focused summary (back to overview). */
1259
1406
  setRung(rung: LodRung): void;
1407
+ /** Price-band filter (F4): dim free seats whose category is outside `keys`
1408
+ * (null clears). The widget resolves which categories fall in the band. */
1409
+ setCategoryFilter(keys: string[] | null): void;
1410
+ /** World-space rect currently visible + full chart bounds (F3 minimap frame). */
1411
+ getViewport(): {
1412
+ visible: {
1413
+ x: number;
1414
+ y: number;
1415
+ width: number;
1416
+ height: number;
1417
+ };
1418
+ bounds: {
1419
+ x: number;
1420
+ y: number;
1421
+ width: number;
1422
+ height: number;
1423
+ };
1424
+ } | null;
1260
1425
  /** Glide in on a section and surface its summary (same path as a section tap). */
1261
1426
  focusSection(id: string): void;
1262
- /** Zoom back out to the whole chart and clear the section-summary card. */
1427
+ /** Zoom back out to the whole chart and clear the section-summary card + focus. */
1263
1428
  overview(): void;
1264
- /** Glide the camera into a tapped section and emit its computed summary. */
1429
+ /** Glide the camera into a tapped section and emit its computed summary. Uses
1430
+ * the AXS focus treatment (dim + backdrop) when the engine supports it; a
1431
+ * closed section is framed but never opens a buyer card. */
1265
1432
  private handleSectionTap;
1266
1433
  /**
1267
1434
  * Build a section summary from the renderer's spatial membership: section +
@@ -1402,4 +1569,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
1402
1569
  /** Bare symbol for input adornments ("€", "$", "₹"). */
1403
1570
  declare function currencySymbol(currency?: string): string;
1404
1571
 
1405
- export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
1572
+ export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type DecorImageObject, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
package/dist/index.d.ts CHANGED
@@ -267,7 +267,32 @@ interface TextObject {
267
267
  rotation: number;
268
268
  color?: string;
269
269
  }
270
- type ChartObject = RowObject | GAAreaObject | ShapeObject | TableObject | BoothObject | TextObject | SectionObject;
270
+ /**
271
+ * A raster/vector decor graphic drawn IN the chart, beneath the seats and
272
+ * sections (ice rink, basketball court, stage art, pitch markings). Purely
273
+ * visual venue context — never bookable, never hit-tested, so it never steals a
274
+ * seat click. `href` is a self-contained data URL (image or SVG) produced by the
275
+ * same client-side downscale used for row photos, so it travels with the doc and
276
+ * caches as a single bitmap blit (zero per-frame cost). Placed by top-left
277
+ * (x,y) + size, rotated about its centre — the same handles a shape rect uses.
278
+ */
279
+ interface DecorImageObject {
280
+ type: 'decorImage';
281
+ id: string;
282
+ /** Image or SVG data URL. */
283
+ href: string;
284
+ x: number;
285
+ y: number;
286
+ width: number;
287
+ height: number;
288
+ /** Degrees clockwise about the image centre (default 0). */
289
+ rotation?: number;
290
+ /** 0–1 (default 1). Multiplied by any chart-theme dimming at render time. */
291
+ opacity?: number;
292
+ /** Optional caption for the designer inspector / accessibility (not drawn). */
293
+ label?: string;
294
+ }
295
+ type ChartObject = RowObject | GAAreaObject | ShapeObject | TableObject | BoothObject | TextObject | SectionObject | DecorImageObject;
271
296
  /**
272
297
  * One floor / level of a multi-floor venue (Batch 5). Each floor owns its own
273
298
  * geometry, stage focal point, and trace image; categories/zones/tiers stay
@@ -423,8 +448,41 @@ interface ISeatmapRenderer {
423
448
  setAccessibilityFilter(types: AccessibilityType[] | null): void;
424
449
  /** Legend hover-highlight: dim free seats of other categories (null clears). */
425
450
  setCategoryHighlight?(key: string | null): void;
451
+ /** Price-band filter (F4): dim free seats whose category is NOT in `keys`
452
+ * (null clears). The widget resolves which categories fall in the band. */
453
+ setCategoryFilter?(keys: string[] | null): void;
426
454
  /** Dim the seats of these section/zone ids (organizer manager: held-back inventory). */
427
455
  setDimmedSections?(ids: string[] | null): void;
456
+ /**
457
+ * Phase 2 event-level section states: mark these section/zone ids `closed` —
458
+ * flat grey block, seats greyed + not pickable, section stays rendered.
459
+ * `null`/empty clears. (Distinct from the buyer's applyHidden seat-strip.)
460
+ */
461
+ setClosedSections?(ids: string[] | null): void;
462
+ /**
463
+ * AXS section-focus: dim + desaturate every other section, draw a calm backdrop
464
+ * behind this section, and glide the camera to frame it. Seat-picking is gated
465
+ * until seats are large enough on screen (≥ LABEL_SCALE). Slice 5 / Phase 2 §4.
466
+ */
467
+ focusSection?(id: string): void;
468
+ /** Clear an AXS section focus (restore full-bowl brightness + drop backdrop). */
469
+ clearSectionFocus?(): void;
470
+ /** The currently AXS-focused section id, or null. */
471
+ getFocusedSection?(): string | null;
472
+ /** World-space rect currently visible in the viewport (minimap viewport frame). */
473
+ getVisibleWorldRect?(): {
474
+ x: number;
475
+ y: number;
476
+ width: number;
477
+ height: number;
478
+ };
479
+ /** Axis-aligned world bounds of all seats + section outlines (minimap frame). */
480
+ getWorldBounds?(): {
481
+ x: number;
482
+ y: number;
483
+ width: number;
484
+ height: number;
485
+ };
428
486
  /**
429
487
  * Colorblind-safe mode: category hues switch to an Okabe-Ito palette and
430
488
  * booked seats render hollow (a non-color cue), so seat state never relies
@@ -579,11 +637,13 @@ declare const UNGROUPED_ID = "__ungrouped__";
579
637
  * 'hidden' — manual: hidden until the organizer reveals it (3.3).
580
638
  * 'timed' — hidden until `revealAt` (epoch ms), then auto-reveals.
581
639
  * 'threshold' — auto-reveals once the on-sale inventory is `thresholdPct`% sold.
640
+ * 'closed' — visible to buyers but not purchasable (rendered flat grey);
641
+ * unlike 'hidden', the seats stay on the map, just off sale.
582
642
  * `labels` are the seat labels the id governs, so a threshold's denominator can
583
643
  * exclude still-hidden seats.
584
644
  */
585
645
  interface AvailabilityRule {
586
- mode: 'hidden' | 'timed' | 'threshold';
646
+ mode: 'hidden' | 'timed' | 'threshold' | 'closed';
587
647
  revealAt?: number;
588
648
  thresholdPct?: number;
589
649
  labels?: string[];
@@ -678,6 +738,8 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
678
738
  private accessFilter;
679
739
  /** Category highlight (legend hover): dims free seats NOT of this category. */
680
740
  private categoryHighlight;
741
+ /** Price-band filter (F4): dim free seats whose category is NOT in this set. */
742
+ private categoryFilter;
681
743
  private sections;
682
744
  private zones;
683
745
  private seatSection;
@@ -686,6 +748,13 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
686
748
  private currency;
687
749
  /** Section/zone ids to render dimmed (organizer manager: held-back inventory). */
688
750
  private dimmedSections;
751
+ /** Phase 2: section/zone ids in the event-level `closed` state — flat grey
752
+ * block, seats greyed + not pickable, but the section stays rendered. */
753
+ private closedSections;
754
+ /** AXS section-focus: the currently-focused section id (others dim), or null. */
755
+ private focusedSectionId;
756
+ /** Light backdrop panel drawn behind the focused section (removed on clear). */
757
+ private focusBackdrop;
689
758
  /** Object id → floor id (multi-floor only) — resolves a deck tap in the 3D stack. */
690
759
  private objectFloor;
691
760
  /** Zone id → colour (drives extruded side faces in iso view). */
@@ -769,6 +838,12 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
769
838
  setAccessibleFilter(on: boolean): void;
770
839
  setAccessibilityFilter(types: AccessibilityType[] | null): void;
771
840
  private sameAccessFilter;
841
+ /**
842
+ * Price-band filter (F4): dim free, unselected seats whose category key is NOT
843
+ * in `keys`. `null` clears the filter (all categories fully visible). The
844
+ * widget resolves which categories fall inside the buyer's chosen band.
845
+ */
846
+ setCategoryFilter(keys: string[] | null): void;
772
847
  /**
773
848
  * Switch the projection between flat top-down and the isometric "3D" view
774
849
  * (rotate + y-squash about the chart centre, plus per-elevation lift). Tweens
@@ -821,6 +896,8 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
821
896
  private seatBaseColor;
822
897
  /** Apply fill/stroke/opacity for a seat's current status + selection. */
823
898
  private paintSeat;
899
+ /** True when a seat sits in a section/zone currently marked `closed`. */
900
+ private seatInClosedSection;
824
901
  /**
825
902
  * Colorblind-safe mode: swap category hues for the Okabe-Ito palette and
826
903
  * render booked seats hollow. Off restores the exact default rendering.
@@ -832,11 +909,53 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
832
909
  * clears. Unlike the buyer's applyHidden, the sections stay rendered.
833
910
  */
834
911
  setDimmedSections(ids: string[] | null): void;
912
+ /**
913
+ * Phase 2 event-level section states: mark these section/zone ids `closed` —
914
+ * flat grey block, seats greyed + not pickable, but the section stays rendered
915
+ * (unlike the buyer's applyHidden which strips it). `null`/empty clears.
916
+ */
917
+ setClosedSections(ids: string[] | null): void;
918
+ /**
919
+ * AXS section-focus: dim + desaturate every other section, draw a calm backdrop
920
+ * panel behind this section's seats, and glide the camera in to frame it (the
921
+ * seat-pick gate below only lets buyers pick once seats are ≥ LABEL_SCALE big).
922
+ */
923
+ focusSection(id: string): void;
924
+ /** Clear an AXS section focus — restore full-bowl brightness + drop the backdrop. */
925
+ clearSectionFocus(): void;
926
+ /** The currently AXS-focused section id, or null. */
927
+ getFocusedSection(): string | null;
928
+ /** Draw (or replace) the light backdrop panel behind the focused section. */
929
+ private drawFocusBackdrop;
930
+ /** Repaint every seat + section block to reflect closed/focus state, then redraw. */
931
+ private repaintSectionsAndSeats;
932
+ /** The world-space rectangle currently visible in the viewport (minimap F3). */
933
+ getVisibleWorldRect(): {
934
+ x: number;
935
+ y: number;
936
+ width: number;
937
+ height: number;
938
+ };
939
+ /** Axis-aligned world bounds of all seats + section outlines (minimap F3 frame). */
940
+ getWorldBounds(): {
941
+ x: number;
942
+ y: number;
943
+ width: number;
944
+ height: number;
945
+ };
835
946
  /** Legend hover: highlight one category (dim the rest), or null to clear. */
836
947
  setCategoryHighlight(key: string | null): void;
837
948
  private renderBackground;
838
949
  /** Organizer floor-plan photo, dimmed, at the very bottom of the bg layer. */
839
950
  private renderBackgroundImage;
951
+ /**
952
+ * A decor graphic (rink / court / stage art). The KImage node is added to the
953
+ * bgLayer synchronously so it keeps its z-slot beneath the sections drawn right
954
+ * after; the bitmap is decoded async and pasted in on load. A single node = a
955
+ * single drawImage per frame, and it rides the same layer cache — effectively
956
+ * zero per-frame cost. Never listens, so it can't intercept a seat click.
957
+ */
958
+ private renderDecorImage;
840
959
  private renderTable;
841
960
  private renderText;
842
961
  private renderShape;
@@ -854,6 +973,14 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
854
973
  private renderSection;
855
974
  /** Recompute a section's availability-tinted fill + "N LEFT" (cheap; on status change). */
856
975
  private refreshSectionFill;
976
+ /** True when a section/zone is currently in the `closed` event-state. */
977
+ private isSectionClosed;
978
+ /**
979
+ * The block-fill colour for a section: flat desaturated grey when `closed`,
980
+ * else the availability-darkened category mix; then desaturated toward neutral
981
+ * when another section holds focus (AXS dim treatment).
982
+ */
983
+ private sectionBlockFill;
857
984
  /**
858
985
  * Zone rung: one giant screen-constant label per zone (+ optional "FROM $n"),
859
986
  * shown at the farthest zoom in place of per-section detail. Skipped entirely
@@ -870,6 +997,15 @@ declare class SeatmapRenderer implements ISeatmapRenderer {
870
997
  * Section/zone labels are scale-compensated to hold a roughly constant screen size.
871
998
  */
872
999
  private applySectionLod;
1000
+ /**
1001
+ * Greedy label de-collision for the zone/section rungs (same approach as the
1002
+ * designer's cullRowLabels): price/"N LEFT" sublabels are lowest priority and
1003
+ * drop first; name labels keep top-to-bottom, left-to-right; anything whose
1004
+ * on-screen box (+4px gap) overlaps an already-kept box hides. Recomputed on
1005
+ * every LOD pass so hidden labels reappear as zoom spreads them apart.
1006
+ * Culling multiplies the opacity applySectionLod just assigned (never raises).
1007
+ */
1008
+ private decollideRungLabels;
873
1009
  /** Set a centred label's world fontSize (for a target screen px) and re-anchor it. */
874
1010
  private sizeLabel;
875
1011
  /**
@@ -1056,6 +1192,7 @@ interface PickerTransport {
1056
1192
  objects(key: string): Promise<{
1057
1193
  seats: Record<string, string>;
1058
1194
  hidden?: string[];
1195
+ closed?: string[];
1059
1196
  }>;
1060
1197
  hold(key: string, selections: HoldSelectionRequest[], ttlMs?: number, replaceHoldId?: string): Promise<HoldResponse>;
1061
1198
  bestAvailable(key: string, qty: number, categoryKey?: string): Promise<BestAvailableResponse>;
@@ -1127,6 +1264,9 @@ declare class PickerController {
1127
1264
  private _doc;
1128
1265
  /** Section/zone ids hidden from buyers this event (3.3) — seats vanish, not grey. */
1129
1266
  private hidden;
1267
+ /** Section/zone ids in the `closed` event-state (Phase 2) — seats stay, greyed
1268
+ * + not pickable. Kept separate from `hidden` (which strips them). */
1269
+ private closedSections;
1130
1270
  /** label ⇄ id maps — backend speaks labels, the engine speaks ids. */
1131
1271
  private labelToId;
1132
1272
  private labelToSeat;
@@ -1149,6 +1289,11 @@ declare class PickerController {
1149
1289
  private visibleDoc;
1150
1290
  /** Adopt a new hidden set; rebuild the visible chart only if it differs. */
1151
1291
  private syncHidden;
1292
+ /** Adopt a new closed-section set; restyle (grey + non-pickable) if it differs.
1293
+ * Cheap restyle — no chart rebuild — so mid-sale open/close repaints live. */
1294
+ private syncClosed;
1295
+ /** Whether a section is currently in the `closed` state (card must not open). */
1296
+ isSectionClosed(id: string): boolean;
1152
1297
  currentHold(): HoldInfo | null;
1153
1298
  getRenderer(): ISeatmapRenderer | null;
1154
1299
  seatByLabel(label: string): ExpandedSeat | undefined;
@@ -1189,6 +1334,8 @@ declare class PickerController {
1189
1334
  * onStatusChange — this is what a price panel's "N left" counters read.
1190
1335
  */
1191
1336
  categoryAvailability(): Record<string, number>;
1337
+ /** Seat ids belonging to a currently-closed section (excluded from counts). */
1338
+ private closedMemberIds;
1192
1339
  getGAAreas(): {
1193
1340
  id: string;
1194
1341
  label: string;
@@ -1257,11 +1404,31 @@ declare class PickerController {
1257
1404
  getRung(): LodRung;
1258
1405
  /** Jump to a rung; ZONES clears any focused summary (back to overview). */
1259
1406
  setRung(rung: LodRung): void;
1407
+ /** Price-band filter (F4): dim free seats whose category is outside `keys`
1408
+ * (null clears). The widget resolves which categories fall in the band. */
1409
+ setCategoryFilter(keys: string[] | null): void;
1410
+ /** World-space rect currently visible + full chart bounds (F3 minimap frame). */
1411
+ getViewport(): {
1412
+ visible: {
1413
+ x: number;
1414
+ y: number;
1415
+ width: number;
1416
+ height: number;
1417
+ };
1418
+ bounds: {
1419
+ x: number;
1420
+ y: number;
1421
+ width: number;
1422
+ height: number;
1423
+ };
1424
+ } | null;
1260
1425
  /** Glide in on a section and surface its summary (same path as a section tap). */
1261
1426
  focusSection(id: string): void;
1262
- /** Zoom back out to the whole chart and clear the section-summary card. */
1427
+ /** Zoom back out to the whole chart and clear the section-summary card + focus. */
1263
1428
  overview(): void;
1264
- /** Glide the camera into a tapped section and emit its computed summary. */
1429
+ /** Glide the camera into a tapped section and emit its computed summary. Uses
1430
+ * the AXS focus treatment (dim + backdrop) when the engine supports it; a
1431
+ * closed section is framed but never opens a buyer card. */
1265
1432
  private handleSectionTap;
1266
1433
  /**
1267
1434
  * Build a section summary from the renderer's spatial membership: section +
@@ -1402,4 +1569,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
1402
1569
  /** Bare symbol for input adornments ("€", "$", "₹"). */
1403
1570
  declare function currencySymbol(currency?: string): string;
1404
1571
 
1405
- export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
1572
+ export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type DecorImageObject, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };