@seatlayer/js 0.49.0 → 0.50.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.cjs +222 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +222 -53
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2756,7 +2756,12 @@ var CSS2 = (
|
|
|
2756
2756
|
never inherits (or fights) the host page's own timing. Values mirror
|
|
2757
2757
|
docs/motion-system-2026-08-01.md \xA72. */
|
|
2758
2758
|
--slm-mo-instant:80ms;--slm-mo-quick:140ms;--slm-mo-base:200ms;--slm-mo-slow:320ms;
|
|
2759
|
-
--slm-mo-out:cubic-bezier(0.2,0.8,0.2,1);--slm-mo-exit:cubic-bezier(0.4,0,1,1)
|
|
2759
|
+
--slm-mo-out:cubic-bezier(0.2,0.8,0.2,1);--slm-mo-exit:cubic-bezier(0.4,0,1,1);
|
|
2760
|
+
/* Semantic palette tokens, defined here (not resolveTokens) because they are
|
|
2761
|
+
the WIDGET's meanings, not an org's brand: premium gold, environment
|
|
2762
|
+
warning, danger, success. Hosts can still override them with CSS. */
|
|
2763
|
+
--sl-premium:#e8c15a;--sl-premium-deep:#c9a24b;--sl-premium-ink:#1c1608;
|
|
2764
|
+
--sl-warn:#d8a425;--sl-danger:#e5484d;--sl-success:#22a06b}
|
|
2760
2765
|
.sl-picker *{box-sizing:border-box;margin:0;padding:0}
|
|
2761
2766
|
.sl-picker button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
|
|
2762
2767
|
|
|
@@ -2782,21 +2787,41 @@ var CSS2 = (
|
|
|
2782
2787
|
.sl-close.on{display:inline-flex}
|
|
2783
2788
|
.sl-close svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round}
|
|
2784
2789
|
|
|
2785
|
-
/* A page or popup may already own the event heading
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
.
|
|
2789
|
-
|
|
2790
|
-
.
|
|
2791
|
-
.
|
|
2792
|
-
.sl-picker[data-event-details-hidden="true"] .sl-
|
|
2793
|
-
.sl-picker[data-event-details-hidden="true"] .sl-
|
|
2790
|
+
/* A page or popup may already own the event heading \u2014 but "already" is true at
|
|
2791
|
+
load and false thirty seconds later: the buyer scrolls, the sheet opens over
|
|
2792
|
+
the map, fullscreen removes the page, and two-tab comparison shopping is
|
|
2793
|
+
normal ticket behaviour. So identity DEMOTES instead of disappearing: one
|
|
2794
|
+
compact line (thumb + name) that answers "which event is this money for"
|
|
2795
|
+
without competing with the host's own heading. The hold clock keeps a
|
|
2796
|
+
labelled row around it instead of floating in a dark corner. */
|
|
2797
|
+
.sl-picker[data-event-details-hidden="true"] .sl-head{padding-block:7px}
|
|
2798
|
+
.sl-picker[data-event-details-hidden="true"] .sl-logo{width:22px;height:22px;border-radius:6px;font-size:11px}
|
|
2799
|
+
.sl-picker[data-event-details-hidden="true"] .sl-head-name{font-size:12.5px}
|
|
2800
|
+
.sl-picker[data-event-details-hidden="true"] .sl-head-meta{display:none}
|
|
2794
2801
|
|
|
2795
2802
|
/* body */
|
|
2796
2803
|
.sl-body{display:flex;flex:1;min-height:0}
|
|
2797
2804
|
.sl-map{position:relative;flex:1;min-width:0}
|
|
2798
2805
|
.sl-map-host{position:absolute;inset:0}
|
|
2799
2806
|
.sl-side{width:300px;flex:none;border-left:1px solid var(--sl-line);display:flex;flex-direction:column;min-height:0;overflow:hidden}
|
|
2807
|
+
/* Wide-layout panel collapse: THE CHART IS THE PRODUCT, and a fixed 300px
|
|
2808
|
+
panel holding an empty cart is the map's room spent on nothing. The panel
|
|
2809
|
+
slides to zero (children keep their laid-out width so text doesn't rewrap
|
|
2810
|
+
mid-slide); the "Tickets" pill in the top-right region brings it back, and
|
|
2811
|
+
the first seat landing in the cart reopens it automatically \u2014 a collapsed
|
|
2812
|
+
panel must never hide a checkout. */
|
|
2813
|
+
.sl-picker[data-layout="wide"] .sl-side{transition:width var(--slm-mo-slow) var(--slm-mo-out)}
|
|
2814
|
+
.sl-picker[data-layout="wide"][data-side-collapsed="true"] .sl-side{width:0;min-width:0;border-left-width:0}
|
|
2815
|
+
/* min-width:0 above is load-bearing: the panel is a flex item, and its
|
|
2816
|
+
automatic minimum size (from these 300px-wide children) would otherwise
|
|
2817
|
+
clamp the explicit width:0 straight back to 300 \u2014 verified in-browser. */
|
|
2818
|
+
.sl-picker[data-layout="wide"][data-side-collapsed="true"] .sl-side>*{min-width:300px}
|
|
2819
|
+
.sl-side-toggle{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;padding:0 12px;
|
|
2820
|
+
border-radius:999px;font-size:11px;font-weight:800;letter-spacing:.02em;white-space:nowrap;
|
|
2821
|
+
background:var(--sl-surface);border:1px solid var(--sl-line);color:var(--sl-text);transition:border-color .15s}
|
|
2822
|
+
.sl-side-toggle:hover{border-color:var(--sl-muted)}
|
|
2823
|
+
.sl-side-toggle svg{width:13px;height:13px;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
2824
|
+
.sl-picker[data-layout="narrow"] .sl-side-toggle{display:none}
|
|
2800
2825
|
|
|
2801
2826
|
/* narrow (container < 640px): map-first \u2014 the map claims ~80-85% of the
|
|
2802
2827
|
container and the side panel becomes a PEEKING bottom sheet (AXS/Ticketmaster
|
|
@@ -2879,6 +2904,15 @@ var CSS2 = (
|
|
|
2879
2904
|
the buyer explicitly opens the ticket panel. */
|
|
2880
2905
|
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-filtersec.has{display:block!important}
|
|
2881
2906
|
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-filters.has{display:flex!important}
|
|
2907
|
+
/* The price list is the mobile buyer's ONLY legend \u2014 colour \u2192 ticket type \u2192
|
|
2908
|
+
price \u2192 how many are left. Hiding it in the peek state is right (map-first);
|
|
2909
|
+
never restoring it forced phone buyers to tap dots to learn prices. The OPEN
|
|
2910
|
+
sheet brings it back, exactly like the filters row above. The tray hint comes
|
|
2911
|
+
back with it: the first-time buyer on a phone needs the instruction more than
|
|
2912
|
+
the desktop buyer, not less. */
|
|
2913
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-prices-sec{display:flex!important}
|
|
2914
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-prices{display:flex!important}
|
|
2915
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-tray-hint{display:block!important}
|
|
2882
2916
|
.sl-cbbtn{width:32px;height:32px;border-radius:999px;background:var(--sl-surface);border:1px solid var(--sl-line);
|
|
2883
2917
|
color:var(--sl-text);display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
2884
2918
|
.sl-cbbtn:hover{border-color:var(--sl-muted)}
|
|
@@ -2888,13 +2922,13 @@ var CSS2 = (
|
|
|
2888
2922
|
.sl-offer{display:none;margin:12px 14px 2px;padding:12px;border:1px solid color-mix(in srgb,var(--sl-accent) 34%,var(--sl-line));
|
|
2889
2923
|
border-radius:12px;background:color-mix(in srgb,var(--sl-accent) 8%,var(--sl-surface));color:var(--sl-text)}
|
|
2890
2924
|
.sl-offer.has{display:block}.sl-offer-main{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
|
|
2891
|
-
.sl-offer-copy{min-width:0}.sl-offer-kicker{display:block;font-size:
|
|
2925
|
+
.sl-offer-copy{min-width:0}.sl-offer-kicker{display:block;font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--sl-accent)}
|
|
2892
2926
|
.sl-offer-name{display:block;margin-top:2px;font-size:13px;font-weight:800;line-height:1.3}.sl-offer-line{display:block;margin-top:3px;font-size:11px;line-height:1.35;color:var(--sl-muted)}
|
|
2893
2927
|
.sl-offer-info{position:relative;flex:none}.sl-offer-info>summary{list-style:none;width:25px;height:25px;border:1px solid var(--sl-line);border-radius:999px;
|
|
2894
2928
|
display:grid;place-items:center;cursor:pointer;font-size:12px;font-weight:850;color:var(--sl-text);background:var(--sl-surface)}
|
|
2895
2929
|
.sl-offer-info>summary::-webkit-details-marker{display:none}.sl-offer-info[open]>summary{border-color:var(--sl-accent);color:var(--sl-accent)}
|
|
2896
2930
|
.sl-offer-detail{margin-top:10px;padding-top:9px;border-top:1px solid var(--sl-line);font-size:10.5px;line-height:1.45;color:var(--sl-muted)}
|
|
2897
|
-
.sl-sec{padding:14px 14px 4px;font-size:
|
|
2931
|
+
.sl-sec{padding:14px 14px 4px;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--sl-muted);font-weight:700}
|
|
2898
2932
|
.sl-prices-sec{display:flex;align-items:center;justify-content:space-between;gap:10px;padding-top:13px}
|
|
2899
2933
|
.sl-price-select{min-height:32px;max-width:130px;padding:5px 28px 5px 9px;border:1px solid var(--sl-line);border-radius:9px;
|
|
2900
2934
|
background:var(--sl-surface);color:var(--sl-text);font:inherit;font-size:11px;font-weight:750;letter-spacing:0;text-transform:none}
|
|
@@ -2904,7 +2938,7 @@ var CSS2 = (
|
|
|
2904
2938
|
padding:0 6px;margin:0 -6px;border-radius:8px;cursor:pointer;transition:background .15s}
|
|
2905
2939
|
.sl-price-row:hover,.sl-price-row:focus-visible{background:color-mix(in srgb,var(--sl-line) 40%,transparent)}
|
|
2906
2940
|
.sl-price-row.sl-active{background:color-mix(in srgb,var(--sl-accent) 9%,transparent)}
|
|
2907
|
-
.sl-price-was{margin-left:auto;color:var(--sl-muted);font-size:10px;text-decoration:line-through}.sl-price-offer{display:block;color:var(--sl-accent);font-size:
|
|
2941
|
+
.sl-price-was{margin-left:auto;color:var(--sl-muted);font-size:10px;text-decoration:line-through}.sl-price-offer{display:block;color:var(--sl-accent);font-size:10px;font-weight:750}
|
|
2908
2942
|
.sl-price-row.sl-active .sl-price-label{color:var(--sl-accent)}
|
|
2909
2943
|
.sl-dot{width:9px;height:9px;border-radius:50%;flex:none}
|
|
2910
2944
|
.sl-price-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}
|
|
@@ -2947,7 +2981,7 @@ var CSS2 = (
|
|
|
2947
2981
|
.sl-chip-id .fld{min-width:0}
|
|
2948
2982
|
.sl-chip-id .fld.sec{flex:1}
|
|
2949
2983
|
.sl-chip-id .fld.mid{flex:none;text-align:center}
|
|
2950
|
-
.sl-chip-eb{display:block;font-size:
|
|
2984
|
+
.sl-chip-eb{display:block;font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--sl-muted);margin-bottom:1px}
|
|
2951
2985
|
.sl-chip-id .val{display:block;font-weight:600;font-size:13px;line-height:1.25;white-space:nowrap}
|
|
2952
2986
|
.sl-chip-id .fld.sec .val{overflow:hidden;text-overflow:ellipsis}
|
|
2953
2987
|
.sl-chip-sub{display:flex;align-items:center;gap:6px;min-width:0}
|
|
@@ -2957,7 +2991,7 @@ var CSS2 = (
|
|
|
2957
2991
|
.sl-chip .rm,.sl-chip .view{flex:1;min-height:26px;border-radius:0;display:flex;align-items:center;justify-content:center;
|
|
2958
2992
|
color:var(--sl-muted);transition:color .15s,background .15s}
|
|
2959
2993
|
.sl-chip .view{border-top:1px solid var(--sl-line)}
|
|
2960
|
-
.sl-chip .rm:hover,.sl-chip .rm:focus-visible{color
|
|
2994
|
+
.sl-chip .rm:hover,.sl-chip .rm:focus-visible{color:var(--sl-danger);background:color-mix(in srgb,var(--sl-danger) 9%,transparent)}
|
|
2961
2995
|
.sl-chip .view:hover,.sl-chip .view:focus-visible{color:var(--sl-text);background:color-mix(in srgb,var(--sl-accent) 10%,transparent)}
|
|
2962
2996
|
.sl-chip .rm svg{width:11px;height:11px;stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round}
|
|
2963
2997
|
.sl-chip .view svg{width:13px;height:13px;stroke:currentColor;stroke-width:1.8;fill:none}
|
|
@@ -2967,7 +3001,7 @@ var CSS2 = (
|
|
|
2967
3001
|
.sl-live{display:none;align-items:center;gap:7px;margin:10px 14px 0;padding:7px 9px;flex:none;
|
|
2968
3002
|
border:1px solid var(--sl-line);border-radius:8px;background:color-mix(in srgb,var(--sl-accent) 4%,var(--sl-surface));
|
|
2969
3003
|
font-size:11px;color:var(--sl-muted)}
|
|
2970
|
-
.sl-live .dot{width:6px;height:6px;border-radius:999px;background
|
|
3004
|
+
.sl-live .dot{width:6px;height:6px;border-radius:999px;background:var(--sl-success);box-shadow:0 0 6px color-mix(in srgb,var(--sl-success) 75%,transparent);flex:none}
|
|
2971
3005
|
.sl-live span:last-child{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
2972
3006
|
.sl-live.on{display:flex;animation:slNoticeIn .38s cubic-bezier(.2,.8,.2,1) both}
|
|
2973
3007
|
|
|
@@ -3037,17 +3071,17 @@ var CSS2 = (
|
|
|
3037
3071
|
.sl-picker[data-layout="narrow"] .sl-anchor[data-region="top-left"]{max-width:30%}
|
|
3038
3072
|
.sl-picker[data-layout="narrow"] .sl-anchor[data-region="top-center"]{max-width:44%}
|
|
3039
3073
|
|
|
3040
|
-
/* TEST MODE is environment context, not an action. A
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3074
|
+
/* TEST MODE is environment context, not an action. A small squared chip that
|
|
3075
|
+
flows FIRST in the top-left anchor region: the old rotated corner ribbon sat
|
|
3076
|
+
at a negative offset and was clipped by the widget root's rounded
|
|
3077
|
+
overflow:hidden (its ends cut mid-word), and its accent fill made an
|
|
3078
|
+
environment flag wear the same gold as "buy". Amber warning tone, dashed
|
|
3079
|
+
border \u2014 reads as a tag, never as a control; the a11y chips wrap beside it
|
|
3080
|
+
in the same region, so no displacement hack is needed. */
|
|
3081
|
+
.sl-testbadge{display:inline-flex;align-items:center;padding:5px 10px;border-radius:7px;pointer-events:none;
|
|
3082
|
+
font-size:10px;font-weight:850;letter-spacing:.13em;line-height:1.2;text-transform:uppercase;white-space:nowrap;
|
|
3083
|
+
color:var(--sl-warn);background:color-mix(in srgb,var(--sl-warn) 13%,var(--sl-surface));
|
|
3084
|
+
border:1px dashed color-mix(in srgb,var(--sl-warn) 55%,transparent)}
|
|
3051
3085
|
|
|
3052
3086
|
/* zoom column (flows within the bottom-right region) */
|
|
3053
3087
|
.sl-zoom{display:flex;flex-direction:column;gap:6px}
|
|
@@ -3057,6 +3091,18 @@ var CSS2 = (
|
|
|
3057
3091
|
color:var(--sl-text);font-size:17px;font-weight:700;display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
3058
3092
|
.sl-zoom button:hover{border-color:var(--sl-muted)}
|
|
3059
3093
|
.sl-zoom svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3094
|
+
/* Full-screen promotion on phones: the capability existed (native + iOS overlay
|
|
3095
|
+
+ framed-host paths) but hid as the 4th unlabelled glyph in a corner stack.
|
|
3096
|
+
On narrow layouts dockLayoutChrome moves the SAME button into the top-right
|
|
3097
|
+
region beside Map|3D and this class dresses it as a labelled pill \u2014 the one
|
|
3098
|
+
accelerator with the highest payoff on a small screen gets words. */
|
|
3099
|
+
.sl-zfs-lbl{display:none}
|
|
3100
|
+
.sl-fs-pill.sl-fs-pill{display:inline-flex;align-items:center;justify-content:center;width:auto;min-height:40px;height:auto;
|
|
3101
|
+
padding:0 13px;gap:6px;border-radius:999px;font-size:11px;font-weight:800;
|
|
3102
|
+
background:var(--sl-surface);border:1px solid var(--sl-line);color:var(--sl-text);transition:border-color .15s}
|
|
3103
|
+
.sl-fs-pill.sl-fs-pill:hover{border-color:var(--sl-muted)}
|
|
3104
|
+
.sl-fs-pill svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3105
|
+
.sl-fs-pill .sl-zfs-lbl{display:inline;letter-spacing:.02em;white-space:nowrap}
|
|
3060
3106
|
|
|
3061
3107
|
/* toast + boot states (toast flows in the bottom-center region) */
|
|
3062
3108
|
.sl-toast{transform:translateY(6px) scale(.98);max-width:100%;
|
|
@@ -3067,9 +3113,9 @@ var CSS2 = (
|
|
|
3067
3113
|
.sl-toast.has-action{pointer-events:auto;display:flex;align-items:center;gap:12px;padding-right:8px}
|
|
3068
3114
|
.sl-toast-action{min-height:30px;padding:5px 10px;border-radius:999px;background:var(--sl-accent);color:var(--sl-accent-ink);
|
|
3069
3115
|
font:inherit;font-weight:800}
|
|
3070
|
-
.sl-toast[data-tone="error"]{border-color
|
|
3116
|
+
.sl-toast[data-tone="error"]{border-color:var(--sl-danger)}
|
|
3071
3117
|
.sl-toast[data-tone="warning"]{border-color:var(--sl-accent)}
|
|
3072
|
-
.sl-toast[data-tone="success"]{border-color
|
|
3118
|
+
.sl-toast[data-tone="success"]{border-color:var(--sl-success)}
|
|
3073
3119
|
.sl-toast.on[data-tone="error"]{animation:slToastNudge .32s ease-out}
|
|
3074
3120
|
.sl-boot{position:absolute;inset:0;z-index:6;display:flex;flex-direction:column;align-items:center;justify-content:center;
|
|
3075
3121
|
gap:10px;background:var(--sl-bg);font-size:13px;font-weight:600;color:var(--sl-muted)}
|
|
@@ -3165,7 +3211,7 @@ var CSS2 = (
|
|
|
3165
3211
|
.sl-confirm-field{min-width:0;padding:12px 11px 10px;border-right:1px solid var(--sl-line)}
|
|
3166
3212
|
.sl-confirm-field:last-child{border-right:0;text-align:center}
|
|
3167
3213
|
.sl-confirm-field:nth-child(2){text-align:center}
|
|
3168
|
-
.sl-confirm-key{display:block;font-size:
|
|
3214
|
+
.sl-confirm-key{display:block;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--sl-muted);font-weight:800}
|
|
3169
3215
|
.sl-confirm-value{display:block;margin-top:4px;color:var(--sl-text);font-size:17px;line-height:1.1;font-weight:850;
|
|
3170
3216
|
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
3171
3217
|
/* Long venue section names must read in full: smaller type + up to two lines
|
|
@@ -3230,7 +3276,7 @@ var CSS2 = (
|
|
|
3230
3276
|
.sl-tip-field{min-width:0;padding:6px 9px;border-right:1px solid var(--sl-line)}
|
|
3231
3277
|
.sl-tip-field:last-child{border-right:0;text-align:center}
|
|
3232
3278
|
.sl-tip-grid:not(.one) .sl-tip-field:nth-child(2){text-align:center}
|
|
3233
|
-
.sl-tip-key{display:block;font-size:
|
|
3279
|
+
.sl-tip-key{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--sl-muted);font-weight:800}
|
|
3234
3280
|
.sl-tip-val{display:block;margin-top:2px;color:var(--sl-text);font-size:13px;line-height:1.1;font-weight:750;
|
|
3235
3281
|
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
3236
3282
|
.sl-tip-cat{display:flex;align-items:center;gap:7px;padding:6px 10px;font-size:11px;
|
|
@@ -3238,7 +3284,7 @@ var CSS2 = (
|
|
|
3238
3284
|
.sl-tip-dot{width:8px;height:8px;border-radius:50%;flex:none}
|
|
3239
3285
|
.sl-tip-name{color:var(--sl-muted);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
3240
3286
|
.sl-tip-amt{margin-left:auto;font-weight:800;color:var(--sl-text);font-variant-numeric:tabular-nums;font-size:12px}
|
|
3241
|
-
.sl-tip-status{padding:5px 10px 7px;font-size:
|
|
3287
|
+
.sl-tip-status{padding:5px 10px 7px;font-size:10px;letter-spacing:.09em;text-transform:uppercase;font-weight:700;color:var(--sl-muted)}
|
|
3242
3288
|
|
|
3243
3289
|
/* Best available is a first-class shortcut, not an anonymous utility row. */
|
|
3244
3290
|
.sl-ba{position:relative;flex:none;overflow:hidden;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:7px;
|
|
@@ -3254,12 +3300,12 @@ var CSS2 = (
|
|
|
3254
3300
|
the confirm popover; deliberately distinct from the accent-toned qty/go. */
|
|
3255
3301
|
.sl-ba-premium{position:relative;z-index:1;grid-column:1/-1;justify-self:start;display:inline-flex;align-items:center;gap:6px;
|
|
3256
3302
|
padding:6px 12px;border-radius:999px;font-size:11px;font-weight:800;letter-spacing:.02em;cursor:pointer;
|
|
3257
|
-
color
|
|
3258
|
-
border:1px solid color-mix(in srgb
|
|
3259
|
-
.sl-ba-premium .star{font-size:12px;line-height:1;color
|
|
3303
|
+
color:var(--sl-premium-deep);background:color-mix(in srgb,var(--sl-premium) 10%,var(--sl-surface));
|
|
3304
|
+
border:1px solid color-mix(in srgb,var(--sl-premium) 34%,var(--sl-line));transition:filter .15s,background .15s,color .15s}
|
|
3305
|
+
.sl-ba-premium .star{font-size:12px;line-height:1;color:var(--sl-premium)}
|
|
3260
3306
|
.sl-ba-premium:hover{filter:brightness(1.05)}
|
|
3261
|
-
.sl-ba-premium.on{color
|
|
3262
|
-
box-shadow:0 6px 16px color-mix(in srgb
|
|
3307
|
+
.sl-ba-premium.on{color:var(--sl-premium-ink);background:linear-gradient(135deg,#f0cf6b,#e0b23f);border-color:transparent;
|
|
3308
|
+
box-shadow:0 6px 16px color-mix(in srgb,var(--sl-premium) 26%,transparent)}
|
|
3263
3309
|
.sl-ba-premium.on .star{color:#5a4410}
|
|
3264
3310
|
.sl-ba select{background:var(--sl-surface);color:var(--sl-text);border:1px solid var(--sl-line);border-radius:8px;
|
|
3265
3311
|
font:inherit;font-size:11px;padding:7px 8px;min-width:0;width:100%;max-width:none}
|
|
@@ -3271,7 +3317,15 @@ var CSS2 = (
|
|
|
3271
3317
|
color:var(--sl-accent-ink);font-weight:800;font-size:12px;transition:filter .15s,opacity .15s;display:flex;align-items:center;justify-content:center;gap:6px;
|
|
3272
3318
|
box-shadow:0 8px 18px color-mix(in srgb,var(--sl-accent) 18%,transparent)}
|
|
3273
3319
|
.sl-picker .sl-ba-go:hover{filter:brightness(1.06)}
|
|
3274
|
-
|
|
3320
|
+
/* ONE disabled language, shared with the checkout CTA: surface + muted ink +
|
|
3321
|
+
not-allowed. A gold button at 62% still reads as gold, and cursor:wait means
|
|
3322
|
+
"working" \u2014 that pairing made a dead control look live. The wait cursor is
|
|
3323
|
+
reserved for the genuinely in-flight search, which keeps its accent fill
|
|
3324
|
+
via .sl-busy. */
|
|
3325
|
+
.sl-picker .sl-ba-go:disabled{background:var(--sl-surface);color:var(--sl-muted);cursor:not-allowed;
|
|
3326
|
+
filter:none;box-shadow:none}
|
|
3327
|
+
.sl-picker .sl-ba-go.sl-busy:disabled{background:var(--sl-accent);color:var(--sl-accent-ink);opacity:.85;cursor:wait;
|
|
3328
|
+
box-shadow:0 8px 18px color-mix(in srgb,var(--sl-accent) 18%,transparent)}
|
|
3275
3329
|
.sl-ba-replace{grid-column:1/-1;padding:3px 0 1px}
|
|
3276
3330
|
.sl-ba-replace b{display:block;font-size:12.5px}
|
|
3277
3331
|
.sl-ba-replace span{display:block;margin-top:3px;color:var(--sl-muted);font-size:10.5px;line-height:1.35}
|
|
@@ -3288,6 +3342,35 @@ var CSS2 = (
|
|
|
3288
3342
|
.sl-picker[data-layout="narrow"] .sl-ba-qty button{width:30px;height:30px}
|
|
3289
3343
|
.sl-picker[data-layout="narrow"] .sl-ba-go{min-height:40px}
|
|
3290
3344
|
|
|
3345
|
+
/* Sales-closed is a designed state, not a set of disables: one statement in
|
|
3346
|
+
the tray where the buying flow was, carrying the event's own date so the
|
|
3347
|
+
buyer knows which night the verdict belongs to. Neutral like the header
|
|
3348
|
+
pill \u2014 "unavailable" never wears the accent. */
|
|
3349
|
+
.sl-closed-note{flex:none;display:flex;flex-direction:column;gap:4px;padding:13px;border-radius:13px;
|
|
3350
|
+
border:1px solid var(--sl-line);background:color-mix(in srgb,var(--sl-text) 5%,var(--sl-surface))}
|
|
3351
|
+
.sl-closed-note b{font-size:13px;font-weight:850}
|
|
3352
|
+
.sl-closed-note span{font-size:11.5px;line-height:1.45;color:var(--sl-muted)}
|
|
3353
|
+
.sl-closed-note .when{display:block;margin-top:2px;font-size:11.5px;font-weight:700;color:var(--sl-text)}
|
|
3354
|
+
|
|
3355
|
+
/* 44px HIT FLOOR ON TOUCH. Visual sizes stay exactly as designed \u2014 the target
|
|
3356
|
+
grows through an invisible centred pseudo-element, the same grow-the-target-
|
|
3357
|
+
not-the-ink pattern the hosted event page documents for its footer links.
|
|
3358
|
+
Applied only to controls with clearance around them; tightly stacked pairs
|
|
3359
|
+
(the cart chip's remove/view rail) instead get real height on narrow. */
|
|
3360
|
+
@media (pointer:coarse){
|
|
3361
|
+
.sl-zoom button,.sl-cbbtn,.sl-close,.sl-ga-qty button,.sl-ba-qty button,.sl-price-more,
|
|
3362
|
+
.sl-hold-change,.sl-seccard-x,.sl-fs-pill,.sl-side-toggle{position:relative}
|
|
3363
|
+
.sl-zoom button::after,.sl-cbbtn::after,.sl-close::after,.sl-ga-qty button::after,.sl-ba-qty button::after,
|
|
3364
|
+
.sl-price-more::after,.sl-hold-change::after,.sl-seccard-x::after,.sl-fs-pill::after,.sl-side-toggle::after{
|
|
3365
|
+
content:'';position:absolute;top:50%;left:50%;width:max(100%,44px);height:max(100%,44px);
|
|
3366
|
+
transform:translate(-50%,-50%)}
|
|
3367
|
+
/* The chip rail stacks remove over view in ~53px \u2014 pseudo-targets would
|
|
3368
|
+
overlap and make a destructive tap ambiguous. Give the pair real height. */
|
|
3369
|
+
.sl-picker[data-layout="narrow"] .sl-chip{min-height:64px}
|
|
3370
|
+
.sl-picker[data-layout="narrow"] .sl-chip .rm,
|
|
3371
|
+
.sl-picker[data-layout="narrow"] .sl-chip .view{min-height:32px}
|
|
3372
|
+
}
|
|
3373
|
+
|
|
3291
3374
|
/* screen-reader live region */
|
|
3292
3375
|
.sl-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
3293
3376
|
|
|
@@ -3657,8 +3740,12 @@ var CSS2 = (
|
|
|
3657
3740
|
.sl-picker[data-layout="narrow"] .sl-minimap{display:none}
|
|
3658
3741
|
|
|
3659
3742
|
/* F4 legend reflection: rows + counts for out-of-band categories read muted */
|
|
3660
|
-
|
|
3661
|
-
|
|
3743
|
+
/* Out-of-band rows are exactly the rows a buyer reads while deciding whether
|
|
3744
|
+
to widen a filter: whole-row opacity .4 took the label to ~2:1. Dim the
|
|
3745
|
+
SWATCH and soften the numerals; the words stay legible muted ink. */
|
|
3746
|
+
.sl-price-row.sl-dim .sl-dot{opacity:.35}
|
|
3747
|
+
.sl-price-row.sl-dim .sl-price-label,.sl-price-row.sl-dim .sl-price-left,.sl-price-row.sl-dim .sl-price-amt{color:var(--sl-muted)}
|
|
3748
|
+
.sl-seccard-mix-item.sl-dim{opacity:.55}
|
|
3662
3749
|
|
|
3663
3750
|
/* Buyer-journey motion: every animation explains a state transition (selected,
|
|
3664
3751
|
held, checkout handoff, conflict or booked). No decorative infinite motion
|
|
@@ -3784,6 +3871,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
3784
3871
|
// state
|
|
3785
3872
|
this.currency = "USD";
|
|
3786
3873
|
this.eventTimezone = null;
|
|
3874
|
+
/** The event's formatted date-time (event-zone), reused by the closed-state note. */
|
|
3875
|
+
this.eventWhenText = null;
|
|
3787
3876
|
this.offerAvailability = null;
|
|
3788
3877
|
this.hold = null;
|
|
3789
3878
|
/** Latest server expiry for the open hold (moves on extend). */
|
|
@@ -3890,6 +3979,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
3890
3979
|
this.fsEscHandler = null;
|
|
3891
3980
|
/** Host-level event chrome owns the duplicate identity outside full screen. */
|
|
3892
3981
|
this.eventDetailsHidden = false;
|
|
3982
|
+
/** Wide-layout ticket panel collapsed (map owns the full width). */
|
|
3983
|
+
this.sideCollapsed = false;
|
|
3984
|
+
this.sideToggleEl = null;
|
|
3893
3985
|
/** True once we've asked the host page to pin us fullscreen (framed, no native). */
|
|
3894
3986
|
this.framedFs = false;
|
|
3895
3987
|
/** Last height (px) posted to a host frame; dedupes redundant reports. */
|
|
@@ -4199,9 +4291,10 @@ var SeatPicker = class _SeatPicker {
|
|
|
4199
4291
|
const active = !!document.fullscreenElement || this.fsFallback || this.framedFs;
|
|
4200
4292
|
const hideEventDetails = this.eventDetailsHidden && !active;
|
|
4201
4293
|
this.root?.setAttribute("data-event-details-hidden", String(hideEventDetails));
|
|
4202
|
-
this.els.logo?.toggleAttribute("hidden", hideEventDetails);
|
|
4203
|
-
this.els.headInfo?.toggleAttribute("hidden", hideEventDetails);
|
|
4204
4294
|
this.els.zfs?.setAttribute("aria-pressed", String(active));
|
|
4295
|
+
this.els.zfs?.setAttribute("title", active ? "Exit full screen" : "Full screen");
|
|
4296
|
+
const zfsLabel = this.els.zfs?.querySelector(".sl-zfs-lbl");
|
|
4297
|
+
if (zfsLabel) zfsLabel.textContent = active ? "Exit full screen" : "Full screen";
|
|
4205
4298
|
this.view3dEl?.querySelector(".sl-view3d-fs")?.setAttribute("aria-pressed", String(active));
|
|
4206
4299
|
}
|
|
4207
4300
|
/**
|
|
@@ -4434,13 +4527,14 @@ var SeatPicker = class _SeatPicker {
|
|
|
4434
4527
|
<div class="sl-map">
|
|
4435
4528
|
<div class="sl-map-host" data-ref="map"></div>
|
|
4436
4529
|
<div class="sl-zoom" data-ref="zoom">
|
|
4437
|
-
<button type="button" aria-label="Zoom in" data-ref="zin">+</button>
|
|
4438
|
-
<button type="button" aria-label="Zoom out" data-ref="zout">\u2212</button>
|
|
4439
|
-
<button type="button" aria-label="Fit to screen" data-ref="zfit">
|
|
4530
|
+
<button type="button" aria-label="Zoom in" title="Zoom in" data-ref="zin">+</button>
|
|
4531
|
+
<button type="button" aria-label="Zoom out" title="Zoom out" data-ref="zout">\u2212</button>
|
|
4532
|
+
<button type="button" aria-label="Fit to screen" title="Fit to screen" data-ref="zfit">
|
|
4440
4533
|
<svg viewBox="0 0 24 24"><path d="M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>
|
|
4441
4534
|
</button>
|
|
4442
|
-
<button type="button" aria-label="Full screen" aria-pressed="false" data-ref="zfs">
|
|
4535
|
+
<button type="button" aria-label="Full screen" title="Full screen" aria-pressed="false" data-ref="zfs">
|
|
4443
4536
|
<svg viewBox="0 0 24 24"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg>
|
|
4537
|
+
<span class="sl-zfs-lbl" aria-hidden="true">Full screen</span>
|
|
4444
4538
|
</button>
|
|
4445
4539
|
</div>
|
|
4446
4540
|
<div class="sl-boot" data-ref="boot"><span class="sl-boot-spin"></span>Loading seat map\u2026</div>
|
|
@@ -4604,17 +4698,18 @@ var SeatPicker = class _SeatPicker {
|
|
|
4604
4698
|
badge.className = "sl-testbadge";
|
|
4605
4699
|
badge.textContent = (0, import_core2.t)("picker.testMode");
|
|
4606
4700
|
badge.setAttribute("aria-label", (0, import_core2.t)("picker.testMode"));
|
|
4607
|
-
this.
|
|
4701
|
+
this.regions["top-left"].appendChild(badge);
|
|
4608
4702
|
}
|
|
4609
4703
|
const chartTheme = this.controller.doc?.theme;
|
|
4610
4704
|
Object.entries(resolveTokens(chartTheme, this.opts.theme)).forEach(([k, v]) => root.style.setProperty(k, v));
|
|
4611
4705
|
this.currency = info.currency ?? this.opts.currency ?? "USD";
|
|
4612
4706
|
this.eventTimezone = info.timezone ?? null;
|
|
4613
|
-
const logoUrl = this.opts.theme?.logoUrl ?? chartTheme?.logoUrl;
|
|
4707
|
+
const logoUrl = this.opts.theme?.logoUrl ?? chartTheme?.logoUrl ?? info.posterUrl ?? null;
|
|
4614
4708
|
if (logoUrl) this.els.logo.innerHTML = `<img src="${logoUrl}" alt="">`;
|
|
4615
4709
|
else this.els.logo.textContent = (this.opts.theme?.brandName ?? chartTheme?.brandName ?? info.eventName ?? "?").slice(0, 1).toUpperCase();
|
|
4616
4710
|
this.els.name.textContent = info.eventName ?? "";
|
|
4617
4711
|
const when = info.startsAt ? formatWhen(info.startsAt, info.timezone ?? null, this.opts.locale) : "";
|
|
4712
|
+
this.eventWhenText = when || null;
|
|
4618
4713
|
this.els.meta.textContent = [info.venue, when].filter(Boolean).join(" \xB7 ");
|
|
4619
4714
|
this.buildBadge(chartTheme);
|
|
4620
4715
|
const present = /* @__PURE__ */ new Set();
|
|
@@ -4705,6 +4800,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
4705
4800
|
this.buildExtendPrompt();
|
|
4706
4801
|
this.buildBookedOverlay();
|
|
4707
4802
|
this.buildSoldoutOverlay();
|
|
4803
|
+
this.buildPanelToggle();
|
|
4804
|
+
if (this.opts.panelCollapsed) this.setPanelCollapsed(true);
|
|
4708
4805
|
this.dockLayoutChrome();
|
|
4709
4806
|
await this.restoreRememberedHold();
|
|
4710
4807
|
if (this.destroyed) return this;
|
|
@@ -4751,8 +4848,63 @@ var SeatPicker = class _SeatPicker {
|
|
|
4751
4848
|
* re-render the section card in the form the layout wants (docked card/pill
|
|
4752
4849
|
* on wide, sheet strip on narrow). Runs on every layout flip + once post-render.
|
|
4753
4850
|
*/
|
|
4851
|
+
/**
|
|
4852
|
+
* The wide-layout panel toggle: a labelled pill in the top-right region
|
|
4853
|
+
* beside Map|3D. Collapsing gives the map the panel's 300px; the pill's own
|
|
4854
|
+
* label is the way back ("Tickets"), and syncTray reopens the panel when the
|
|
4855
|
+
* first seat lands so the checkout can never be hidden behind a collapse.
|
|
4856
|
+
*/
|
|
4857
|
+
buildPanelToggle() {
|
|
4858
|
+
if (!this.regions["top-right"]) return;
|
|
4859
|
+
const btn = document.createElement("button");
|
|
4860
|
+
btn.type = "button";
|
|
4861
|
+
btn.className = "sl-side-toggle";
|
|
4862
|
+
btn.addEventListener("click", () => this.setPanelCollapsed(!this.sideCollapsed));
|
|
4863
|
+
this.sideToggleEl = btn;
|
|
4864
|
+
this.regions["top-right"].appendChild(btn);
|
|
4865
|
+
this.syncPanelToggle();
|
|
4866
|
+
}
|
|
4867
|
+
syncPanelToggle() {
|
|
4868
|
+
const btn = this.sideToggleEl;
|
|
4869
|
+
if (!btn) return;
|
|
4870
|
+
const collapsed = this.sideCollapsed;
|
|
4871
|
+
btn.setAttribute("aria-expanded", String(!collapsed));
|
|
4872
|
+
btn.setAttribute("aria-label", collapsed ? "Show the ticket panel" : "Hide the ticket panel");
|
|
4873
|
+
btn.innerHTML = collapsed ? '<svg viewBox="0 0 24 24"><path d="M15 6l-6 6 6 6"/></svg><span>Tickets</span>' : '<svg viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg><span>Hide panel</span>';
|
|
4874
|
+
}
|
|
4875
|
+
/**
|
|
4876
|
+
* Collapse or reopen the wide-layout ticket panel in place (host-drivable —
|
|
4877
|
+
* a map-first embed can mount collapsed via `panelCollapsed` and reopen on
|
|
4878
|
+
* its own cue). Inert while collapsed so a keyboard buyer cannot tab into a
|
|
4879
|
+
* zero-width panel; narrow layouts ignore the state entirely (the sheet is
|
|
4880
|
+
* already the collapse) but keep it for the next flip back to wide.
|
|
4881
|
+
*/
|
|
4882
|
+
setPanelCollapsed(collapsed) {
|
|
4883
|
+
if (this.destroyed) return;
|
|
4884
|
+
this.sideCollapsed = collapsed;
|
|
4885
|
+
this.applyPanelCollapsed();
|
|
4886
|
+
this.scheduleMotion(() => this.controller.zoomToFit(), 340);
|
|
4887
|
+
}
|
|
4888
|
+
/** Idempotent DOM apply, also run on every layout flip (inert must lift on narrow). */
|
|
4889
|
+
applyPanelCollapsed() {
|
|
4890
|
+
const wide = this.root?.dataset.layout !== "narrow";
|
|
4891
|
+
this.root?.setAttribute("data-side-collapsed", String(this.sideCollapsed));
|
|
4892
|
+
this.els.side?.toggleAttribute("inert", this.sideCollapsed && wide);
|
|
4893
|
+
this.syncPanelToggle();
|
|
4894
|
+
}
|
|
4754
4895
|
dockLayoutChrome() {
|
|
4755
4896
|
const narrow = this.root?.dataset.layout === "narrow";
|
|
4897
|
+
this.applyPanelCollapsed();
|
|
4898
|
+
const zfs = this.els.zfs;
|
|
4899
|
+
if (zfs) {
|
|
4900
|
+
if (narrow && this.regions["top-right"]) {
|
|
4901
|
+
zfs.classList.add("sl-fs-pill");
|
|
4902
|
+
this.regions["top-right"].appendChild(zfs);
|
|
4903
|
+
} else if (!narrow && this.els.zoom && zfs.parentElement !== this.els.zoom) {
|
|
4904
|
+
zfs.classList.remove("sl-fs-pill");
|
|
4905
|
+
this.els.zoom.appendChild(zfs);
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4756
4908
|
const filters = this.els.filters;
|
|
4757
4909
|
if (filters) {
|
|
4758
4910
|
if (this.cbEl) this.els.zoom?.appendChild(this.cbEl);
|
|
@@ -4855,6 +5007,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
4855
5007
|
text.textContent = this.tf("picker.salesClosedPill", "Sales are closed");
|
|
4856
5008
|
}
|
|
4857
5009
|
this.root?.setAttribute("data-sales-closed", String(this.salesClosed));
|
|
5010
|
+
if (this.salesClosed && this.srEl) {
|
|
5011
|
+
this.srEl.textContent = this.tf("picker.salesClosedToast", "Sales are closed for this event.");
|
|
5012
|
+
}
|
|
4858
5013
|
this.syncCta();
|
|
4859
5014
|
this.syncTray();
|
|
4860
5015
|
}
|
|
@@ -5700,6 +5855,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5700
5855
|
this.confirmEl = null;
|
|
5701
5856
|
this.confirmSeat = seat;
|
|
5702
5857
|
this.root?.setAttribute("data-confirming", "true");
|
|
5858
|
+
this.els.side?.toggleAttribute("inert", true);
|
|
5859
|
+
Object.values(this.regions).forEach((region) => region.toggleAttribute("inert", true));
|
|
5703
5860
|
this.controller.setSelectionFocus(seat.id);
|
|
5704
5861
|
if (previousId && previousId !== seat.id) this.controller.deselect([previousId]);
|
|
5705
5862
|
if (this.tipEl) this.tipEl.style.display = "none";
|
|
@@ -5721,7 +5878,6 @@ var SeatPicker = class _SeatPicker {
|
|
|
5721
5878
|
const el2 = document.createElement("div");
|
|
5722
5879
|
el2.className = "sl-confirm";
|
|
5723
5880
|
el2.setAttribute("role", "dialog");
|
|
5724
|
-
el2.setAttribute("aria-modal", "true");
|
|
5725
5881
|
el2.setAttribute("aria-label", `Confirm seat ${seat.label}`);
|
|
5726
5882
|
el2.style.setProperty("--sl-cat", cat?.color ?? "#6e7bff");
|
|
5727
5883
|
el2.innerHTML = `<div class="sl-confirm-grid">` + identityFields + `</div><div class="sl-confirm-cat"><span class="sl-dot" style="background:${cat?.color ?? "#6e7bff"}"></span><span class="sl-confirm-cat-name">${safe(details?.categoryLabel ?? cat?.label ?? seat.categoryKey)}</span>` + (price != null ? `<span class="sl-confirm-price">${this.money(price)}</span>` : "") + `</div><div class="sl-confirm-body">` + this.wheelchairConfirmHtml(details?.wheelchairSpaceType) + this.commercialConfirmHtml(seat.commercial) + (this.seatViewEnabled() && this.buyerView !== "venue3d" ? this.confirmThumbHtml(seat) : "") + (this.buyerView === "venue3d" ? `${this.seatConfidenceConfirmHtml(seat, `${details?.displayLabel ?? seat.displayLabel ?? seat.label} \xB7 ${price == null ? this.tf("picker.priceNotSupplied", "Price not supplied") : this.money(price)}`)}<div class="sl-confirm-inspect-row">${this.view3dCompareConfirmHtml(seat)}${this.see3dConfirmHtml()}</div>` : this.see3dConfirmHtml()) + `<div class="sl-confirm-row"><button type="button" class="sl-confirm-cancel">Cancel</button><button type="button" class="sl-confirm-add"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5l4 4L19 7"/></svg>Select</button></div></div>`;
|
|
@@ -5776,6 +5932,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5776
5932
|
this.confirmEl = null;
|
|
5777
5933
|
this.confirmSeat = null;
|
|
5778
5934
|
this.root?.removeAttribute("data-confirming");
|
|
5935
|
+
Object.values(this.regions).forEach((region) => region.toggleAttribute("inert", false));
|
|
5936
|
+
this.applyPanelCollapsed();
|
|
5779
5937
|
this.controller.setSelectionFocus(null);
|
|
5780
5938
|
}
|
|
5781
5939
|
commitConfirm() {
|
|
@@ -6214,19 +6372,24 @@ var SeatPicker = class _SeatPicker {
|
|
|
6214
6372
|
const heldItems = this.hold?.items ?? [];
|
|
6215
6373
|
const parts = [];
|
|
6216
6374
|
const nextTrayKeys = /* @__PURE__ */ new Set();
|
|
6217
|
-
if (
|
|
6375
|
+
if (this.salesClosed && !seats.length && !heldItems.length) {
|
|
6376
|
+
const closedWhen = this.eventWhenText ? `<span class="when">${String(this.eventWhenText).replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c])}</span>` : "";
|
|
6377
|
+
parts.push(
|
|
6378
|
+
`<div class="sl-closed-note" role="status"><b>${this.tf("picker.salesClosedPill", "Sales are closed")}</b><span>${this.tf("picker.salesClosedCopy", "Ticket sales for this event have ended.")}${closedWhen}</span></div>`
|
|
6379
|
+
);
|
|
6380
|
+
} else if (!seats.length && !heldItems.length && !gaAreas.length) {
|
|
6218
6381
|
parts.push(`<div class="sl-tray-hint">Tap a seat on the map, or let us pick the best available for you.</div>`);
|
|
6219
6382
|
} else if (!seats.length && !heldItems.length) {
|
|
6220
6383
|
parts.push(`<div class="sl-tray-hint">Tap a seat on the map \u2014 or grab standing tickets below.</div>`);
|
|
6221
6384
|
}
|
|
6222
6385
|
const noPicks = !seats.length && !heldItems.length && !this.pendingGACount();
|
|
6223
|
-
if (!this.hold && (noPicks || this.bestAvailableBusy || this.bestAvailableConfirm)) {
|
|
6386
|
+
if (!this.salesClosed && !this.hold && (noPicks || this.bestAvailableBusy || this.bestAvailableConfirm)) {
|
|
6224
6387
|
const cats = this.controller.doc?.categories ?? [];
|
|
6225
6388
|
const zones = this.controller.getBestAvailableZones();
|
|
6226
6389
|
if (this.baZone && !zones.some((zone) => zone.id === this.baZone)) this.baZone = "";
|
|
6227
6390
|
parts.push(this.bestAvailableConfirm ? `<div class="sl-ba" role="alert"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>Replace your current choices?</div><div class="sl-ba-replace"><b>We\u2019ll find ${this.baQty} seats together.</b><span>Your manually selected tickets will be removed only after a new group is secured.</span></div><div class="sl-ba-actions"><button type="button" data-ba-cancel>Keep mine</button><button type="button" class="replace" data-ba-replace>Find new seats</button></div></div>` : `<div class="sl-ba"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>Find the best seats together</div><div class="sl-ba-copy"><span class="wide">We\u2019ll choose the closest available group for you.</span><span class="narrow">Closest available group, chosen instantly.</span></div>` + // Premium quick-pick — present only when the chart actually has premium
|
|
6228
6391
|
// seats (same present-only philosophy as the a11y filter chips).
|
|
6229
|
-
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="Preferred ticket type" data-ba-cat><option value="">Any ticket type</option>` + cats.map((c) => `<option value="${c.key}"${this.baCat === c.key ? " selected" : ""}>${c.label}</option>`).join("") + `</select>` : `<span aria-hidden="true"></span>`) + (zones.length ? `<select aria-label="Preferred venue zone" data-ba-zone><option value="">Any venue zone</option>` + zones.map((zone) => `<option value="${escapeOption(zone.id)}"${this.baZone === zone.id ? " selected" : ""}>${escapeOption(zone.label)}</option>`).join("") + `</select>` : "") + `<div class="sl-ba-qty"><button type="button" data-ba="-1" aria-label="Fewer seats">\u2212</button><span>${this.baQty}</span><button type="button" data-ba="1" aria-label="More seats">+</button></div><button type="button" class="sl-ba-go"${this.bestAvailableBusy ? " disabled" : ""}>` + (this.bestAvailableBusy ? `<span class="sl-ba-spin" aria-hidden="true"></span>Finding the best seats\u2026` : `Find ${this.baQty} best ${this.baQty === 1 ? "seat" : "seats"}`) + `</button></div>`);
|
|
6392
|
+
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="Preferred ticket type" data-ba-cat><option value="">Any ticket type</option>` + cats.map((c) => `<option value="${c.key}"${this.baCat === c.key ? " selected" : ""}>${c.label}</option>`).join("") + `</select>` : `<span aria-hidden="true"></span>`) + (zones.length ? `<select aria-label="Preferred venue zone" data-ba-zone><option value="">Any venue zone</option>` + zones.map((zone) => `<option value="${escapeOption(zone.id)}"${this.baZone === zone.id ? " selected" : ""}>${escapeOption(zone.label)}</option>`).join("") + `</select>` : "") + `<div class="sl-ba-qty"><button type="button" data-ba="-1" aria-label="Fewer seats">\u2212</button><span>${this.baQty}</span><button type="button" data-ba="1" aria-label="More seats">+</button></div><button type="button" class="sl-ba-go${this.bestAvailableBusy ? " sl-busy" : ""}"${this.bestAvailableBusy ? " disabled" : ""}>` + (this.bestAvailableBusy ? `<span class="sl-ba-spin" aria-hidden="true"></span>Finding the best seats\u2026` : `Find ${this.baQty} best ${this.baQty === 1 ? "seat" : "seats"}`) + `</button></div>`);
|
|
6230
6393
|
}
|
|
6231
6394
|
const idGrid = (seatId, label, objectType, quantity = 1, objectId, identity) => {
|
|
6232
6395
|
const esc = (value) => String(value ?? "\u2014").replace(/[&<>"]/g, (char) => ({
|
|
@@ -6436,11 +6599,16 @@ var SeatPicker = class _SeatPicker {
|
|
|
6436
6599
|
}
|
|
6437
6600
|
if (count !== previousCount) this.animateOnce(this.els.count, "sl-value-pop", 380);
|
|
6438
6601
|
if (total !== previousTotal) this.animateOnce(this.els.total, "sl-value-pop", 380);
|
|
6439
|
-
if (previousCount === 0 && count > 0)
|
|
6602
|
+
if (previousCount === 0 && count > 0) {
|
|
6603
|
+
this.animateOnce(this.els.cta, "sl-ready", 520);
|
|
6604
|
+
if (this.sideCollapsed && this.root?.dataset.layout !== "narrow") this.setPanelCollapsed(false);
|
|
6605
|
+
}
|
|
6440
6606
|
if (this.els.peek) {
|
|
6441
6607
|
if (count) {
|
|
6442
6608
|
const holding = !!this.hold && !pendingCount;
|
|
6443
6609
|
this.els.peek.innerHTML = `<span>${count} ${count === 1 ? "ticket" : "tickets"} \xB7 ${this.money(total)}</span><button type="button" class="go sl-sheet-go" data-act="${holding ? "checkout" : "open"}">${this.hold ? pendingCount ? "Secure more" : "Continue" : "Review"}</button>`;
|
|
6610
|
+
} else if (this.salesClosed) {
|
|
6611
|
+
this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
|
|
6444
6612
|
} else {
|
|
6445
6613
|
const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
|
|
6446
6614
|
this.els.peek.innerHTML = (prices.length ? `<span>From ${this.money(Math.min(...prices))}</span>` : "<span>Pick your seats</span>") + `<button type="button" class="go sl-sheet-go" data-act="open">\u2726 Best seats</button>`;
|
|
@@ -7896,6 +8064,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7896
8064
|
const button = this.els.tray?.querySelector(".sl-ba-go");
|
|
7897
8065
|
if (button) {
|
|
7898
8066
|
button.disabled = true;
|
|
8067
|
+
button.classList.add("sl-busy");
|
|
7899
8068
|
button.innerHTML = '<span class="sl-ba-spin" aria-hidden="true"></span>Finding\u2026';
|
|
7900
8069
|
}
|
|
7901
8070
|
try {
|