@wix/himalaya-cli 0.1064.0 → 0.1066.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.
Files changed (48) hide show
  1. package/dist/cli.mjs +175 -45
  2. package/dist/preview-assets.generated.bin +0 -0
  3. package/guides/wix-site-to-himi-app.md +2 -2
  4. package/package.json +2 -2
  5. package/templates/beauty-salon/dev/index.ts +1 -5
  6. package/templates/beauty-salon/tier5-src/_shared/himi-layouts.ts +8 -6
  7. package/templates/beauty-salon/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  8. package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +5 -5
  9. package/templates/branded-lite/dev/index.ts +2 -6
  10. package/templates/branded-lite/tier5-src/_shared/himi-layouts.ts +8 -6
  11. package/templates/branded-lite/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  12. package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +5 -5
  13. package/templates/community-club/dev/index.ts +1 -5
  14. package/templates/community-club/tier5-src/_shared/himi-layouts.ts +8 -6
  15. package/templates/community-club/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  16. package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +5 -5
  17. package/templates/events-meetups/dev/index.ts +1 -5
  18. package/templates/events-meetups/tier5-src/_shared/himi-layouts.ts +8 -6
  19. package/templates/events-meetups/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  20. package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +5 -5
  21. package/templates/gym-fitness/dev/index.ts +1 -5
  22. package/templates/gym-fitness/tier5-src/_shared/himi-layouts.ts +8 -6
  23. package/templates/gym-fitness/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  24. package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +5 -5
  25. package/templates/nonprofit-cause/dev/index.ts +1 -5
  26. package/templates/nonprofit-cause/tier5-src/_shared/himi-layouts.ts +8 -6
  27. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  28. package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +5 -5
  29. package/templates/podcast-creator/dev/index.ts +1 -5
  30. package/templates/podcast-creator/tier5-src/_shared/himi-layouts.ts +8 -6
  31. package/templates/podcast-creator/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  32. package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +5 -5
  33. package/templates/portfolio-creative/dev/index.ts +1 -5
  34. package/templates/portfolio-creative/tier5-src/_shared/himi-layouts.ts +8 -6
  35. package/templates/portfolio-creative/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  36. package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +5 -5
  37. package/templates/restaurant/dev/index.ts +1 -5
  38. package/templates/restaurant/tier5-src/_shared/himi-layouts.ts +8 -6
  39. package/templates/restaurant/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  40. package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +5 -5
  41. package/templates/retail-store/dev/index.ts +2 -6
  42. package/templates/retail-store/tier5-src/_shared/himi-layouts.ts +8 -6
  43. package/templates/retail-store/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  44. package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +5 -5
  45. package/templates/yoga-studio/dev/index.ts +1 -5
  46. package/templates/yoga-studio/tier5-src/_shared/himi-layouts.ts +8 -6
  47. package/templates/yoga-studio/tier5-src/himi-branded-lite-appearance/index.ts +13 -18
  48. package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +5 -5
package/dist/cli.mjs CHANGED
@@ -764,6 +764,36 @@ var init_file_store = __esm({
764
764
  else ledger.push(entry);
765
765
  writeFileSync2(this.ledgerPath(app), JSON.stringify(ledger, null, 2));
766
766
  }
767
+ // ---- RFC 0061 §3.1 owner-follow `wip` pointer ----
768
+ // Inside the app directory, so `remove` and `reset` take it with the app. `clearWipIf` is a CAS
769
+ // for the way this backend is deployed — ONE writer process (serve-control; serve only reads):
770
+ // the read, compare and delete below are synchronous with no await between them, so no other
771
+ // request in that process can land in the middle. It is not a cross-process lock.
772
+ wipPath(app) {
773
+ return join2(this.appDir(app), "_wip.json");
774
+ }
775
+ readWipSync(app) {
776
+ const b = this.read(app, "_wip.json");
777
+ if (!b) return null;
778
+ try {
779
+ const wip = JSON.parse(b.toString("utf8"));
780
+ return wip && typeof wip.releaseId === "string" ? wip : null;
781
+ } catch {
782
+ return null;
783
+ }
784
+ }
785
+ async putWip(app, wip) {
786
+ mkdirSync2(this.appDir(app), { recursive: true });
787
+ writeFileSync2(this.wipPath(app), JSON.stringify(wip, null, 2));
788
+ }
789
+ async getWip(app) {
790
+ return this.readWipSync(app);
791
+ }
792
+ async clearWipIf(app, releaseId) {
793
+ if (this.readWipSync(app)?.releaseId !== releaseId) return false;
794
+ rmSync(this.wipPath(app), { force: true });
795
+ return true;
796
+ }
767
797
  bundleUrl(_app, sha2565) {
768
798
  return `/v1/bundles/${sha2565}.bundle.js`;
769
799
  }
@@ -12416,6 +12446,7 @@ function resolveIdiom(tokens, ctx = {}) {
12416
12446
  var IDIOM_CONTEXTS, UNSAFE_KEYS;
12417
12447
  var init_idiom = __esm({
12418
12448
  "../../core/ts/src/idiom.ts"() {
12449
+ "use strict";
12419
12450
  IDIOM_CONTEXTS = {
12420
12451
  ios: { native: ["ios"] },
12421
12452
  android: { native: ["material"] },
@@ -22843,6 +22874,7 @@ function shouldRevealError(args) {
22843
22874
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
22844
22875
  var init_validation = __esm({
22845
22876
  "../../core/ts/src/validation.ts"() {
22877
+ "use strict";
22846
22878
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
22847
22879
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
22848
22880
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -26443,6 +26475,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
26443
26475
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
26444
26476
  var init_worker_subtree = __esm({
26445
26477
  "../../core/ts/src/worker-subtree.ts"() {
26478
+ "use strict";
26446
26479
  init_worker_subtree_safe_types_generated();
26447
26480
  WORKER_SUBTREE_CEILINGS = Object.freeze({
26448
26481
  maxEncodedBytes: 65536,
@@ -27186,6 +27219,49 @@ function sourceFragment(src) {
27186
27219
  return "";
27187
27220
  }
27188
27221
  }
27222
+ function cloneWithKids(el, props, kids2) {
27223
+ if (kids2 === el.props.children) return React5.cloneElement(el, props);
27224
+ return React5.cloneElement(el, props, ...Array.isArray(kids2) ? kids2 : [kids2]);
27225
+ }
27226
+ function editA11yParts(node, edit) {
27227
+ if (Array.isArray(node)) {
27228
+ let changed = false;
27229
+ const out = node.map((child) => {
27230
+ const next = editA11yParts(child, edit);
27231
+ if (next !== child) changed = true;
27232
+ return next;
27233
+ });
27234
+ return changed ? out : node;
27235
+ }
27236
+ if (!React5.isValidElement(node) || typeof node.type !== "string") return node;
27237
+ const own3 = node.props;
27238
+ if (own3["data-component-id"] != null) return node;
27239
+ const part = own3[A11Y_PART];
27240
+ const kids2 = own3.children;
27241
+ const nextKids = kids2 == null ? kids2 : editA11yParts(kids2, edit);
27242
+ if (typeof part !== "string" && nextKids === kids2) return node;
27243
+ return cloneWithKids(node, typeof part === "string" ? { ...edit(part, own3), [A11Y_PART]: void 0 } : {}, nextKids);
27244
+ }
27245
+ function a11yPartEdit(routed, authoredName, onNode) {
27246
+ return (part, own3) => {
27247
+ if (part === "derived-name") return authoredName ? {} : { "aria-hidden": "true" };
27248
+ if (part !== "node") return {};
27249
+ onNode();
27250
+ const patch = { ...routed };
27251
+ if (typeof routed["aria-describedby"] === "string" && typeof own3["aria-describedby"] === "string") {
27252
+ patch["aria-describedby"] = `${own3["aria-describedby"]} ${routed["aria-describedby"]}`;
27253
+ }
27254
+ if ("role" in routed && routed.role !== own3.role) {
27255
+ if (!(typeof routed.role === "string" && RANGE_ROLES.has(routed.role))) {
27256
+ patch["aria-valuenow"] = void 0;
27257
+ patch["aria-valuemin"] = void 0;
27258
+ patch["aria-valuemax"] = void 0;
27259
+ }
27260
+ if (routed.role !== "heading" && routed["aria-level"] == null) patch["aria-level"] = void 0;
27261
+ }
27262
+ return patch;
27263
+ };
27264
+ }
27189
27265
  function isNativeInteractiveElement(el) {
27190
27266
  const props = el.props;
27191
27267
  return typeof el.type === "string" && (["button", "input", "select", "textarea"].includes(el.type) || el.type === "a" && typeof props.href === "string");
@@ -27227,9 +27303,19 @@ function withExtras(name, render) {
27227
27303
  const inferredDecorative = el.props[INFERRED_DECORATIVE] === true;
27228
27304
  const selfRenderedLeaf = el.props[SELF_RENDERED_LEAF] === true;
27229
27305
  const roleWhenNamed = el.props[ROLE_WHEN_NAMED];
27306
+ const hasA11yParts = el.props[A11Y_PART] === "root";
27230
27307
  if (!Object.keys(pass).length) {
27231
- if (inferredDecorative || selfRenderedLeaf || roleWhenNamed != null) {
27232
- return React5.cloneElement(el, { [INFERRED_DECORATIVE]: void 0, [SELF_RENDERED_LEAF]: void 0, [ROLE_WHEN_NAMED]: void 0, [PENDING_RANGE]: void 0, ...additive ? { style: additive } : {} });
27308
+ if (inferredDecorative || selfRenderedLeaf || roleWhenNamed != null || hasA11yParts) {
27309
+ const kids2 = el.props.children;
27310
+ return cloneWithKids(el, {
27311
+ [INFERRED_DECORATIVE]: void 0,
27312
+ [SELF_RENDERED_LEAF]: void 0,
27313
+ [ROLE_WHEN_NAMED]: void 0,
27314
+ [PENDING_RANGE]: void 0,
27315
+ [A11Y_PART]: void 0,
27316
+ ...additive ? { style: additive } : {}
27317
+ }, hasA11yParts ? editA11yParts(kids2, a11yPartEdit({}, false, () => {
27318
+ })) : kids2);
27233
27319
  }
27234
27320
  return additive ? React5.cloneElement(el, { style: additive }) : /* @__PURE__ */ jsx6(Fragment3, { children: el });
27235
27321
  }
@@ -27300,6 +27386,21 @@ function withExtras(name, render) {
27300
27386
  pass.onClick(e);
27301
27387
  };
27302
27388
  }
27389
+ if (hasA11yParts) {
27390
+ next[A11Y_PART] = void 0;
27391
+ const routed = {};
27392
+ const rootIsControl = (typeof pass.onClick === "function" || typeof pass.onDoubleClick === "function") && !ownsInteractiveSemantics;
27393
+ if (!rootIsControl) {
27394
+ for (const k of NODE_A11Y_ATTRS) if (next[k] !== void 0) routed[k] = next[k];
27395
+ if (pass[AUTHORED_ROLE] === true || pass["aria-level"] != null) routed.role = next.role;
27396
+ }
27397
+ let nodeFound = false;
27398
+ const kids2 = editA11yParts(prev.children, a11yPartEdit(routed, pass["aria-label"] != null, () => {
27399
+ nodeFound = true;
27400
+ }));
27401
+ if (nodeFound) for (const k of Object.keys(routed)) delete next[k];
27402
+ return cloneWithKids(el, next, kids2);
27403
+ }
27303
27404
  return React5.cloneElement(el, next);
27304
27405
  };
27305
27406
  Wrapped.displayName = name;
@@ -27814,15 +27915,16 @@ function ariaModal(modal, dflt) {
27814
27915
  const on3 = modal === true || modal === false ? modal : dflt;
27815
27916
  return on3 ? "true" : void 0;
27816
27917
  }
27918
+ function a11yModifierString(v, ctx) {
27919
+ if (v == null) return void 0;
27920
+ const r = resolveScalarStatic(v, ctx);
27921
+ const s = r == null ? "" : String(r).trim();
27922
+ return s === "" ? void 0 : s;
27923
+ }
27817
27924
  function applyA11ySemantics(node, ctx, extra) {
27818
27925
  const m = node?.modifiers;
27819
27926
  if (!m) return void 0;
27820
- const str7 = (v) => {
27821
- if (v == null) return void 0;
27822
- const r = resolveScalarStatic(v, ctx);
27823
- const s = r == null ? "" : String(r).trim();
27824
- return s === "" ? void 0 : s;
27825
- };
27927
+ const str7 = (v) => a11yModifierString(v, ctx);
27826
27928
  if ((m.accessibilityHidden ?? m.accessibility_hidden) === true) {
27827
27929
  extra["aria-hidden"] = "true";
27828
27930
  extra.inert = "";
@@ -28415,9 +28517,13 @@ function renderInner(node, ctx) {
28415
28517
  case "Badge": {
28416
28518
  const _bt = boundTokenName(props.tokenPath, props.token, ctx);
28417
28519
  const c = _bt ? C(_bt, "#116DFF") : sevColor(ctx, props.style ?? "info");
28520
+ const m = modifiers;
28521
+ const authoredRole = a11yModifierString(m?.accessibilityRole ?? m?.accessibility_role, ctx);
28522
+ const headingLevel = m?.headingLevel ?? m?.heading_level;
28523
+ const roleDeclared = typeof authoredRole === "string" && (authoredRole === "decorative" || Object.prototype.hasOwnProperty.call(ARIA_ROLE, authoredRole)) || typeof headingLevel === "number" && headingLevel >= 1 && headingLevel <= 6;
28418
28524
  const liveCount = typeof props.text === "string" && /^\$(?:service|flag)\b/.test(props.text);
28419
- const badgeLabel = modifiers?.accessibilityLabel;
28420
- const badgeRole = liveCount ? "status" : typeof badgeLabel === "string" && badgeLabel.trim() !== "" ? "img" : void 0;
28525
+ const badgeLabel = m?.accessibilityLabel ?? m?.accessibility_label;
28526
+ const badgeRole = roleDeclared ? void 0 : liveCount ? "status" : typeof badgeLabel === "string" && badgeLabel.trim() !== "" ? "img" : void 0;
28421
28527
  return /* @__PURE__ */ jsx6("span", { role: badgeRole, style: { display: "inline-flex", alignItems: "center", padding: "3px 9px", borderRadius: 999, fontSize: 12, fontWeight: 700, fontFamily: bodyFont(ctx), background: `color-mix(in srgb, ${c} 16%, ${C("surfacePrimary", "#fff")})`, color: c, ...wrap }, children: ctx.empty ? "" : txt(props.text, ctx) || "Badge" });
28422
28528
  }
28423
28529
  case "Tag": {
@@ -28762,7 +28868,7 @@ function renderInner(node, ctx) {
28762
28868
  }
28763
28869
  }
28764
28870
  }
28765
- var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, SYNTHETIC_TABINDEX, INFERRED_DECORATIVE, SELF_RENDERED_LEAF, ROLE_WHEN_NAMED, AUTHORED_ROLE, PENDING_RANGE, RANGE_ROLES, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, ANIMATION_LEAF, LottieNode, RiveNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, NATIVELY_TABBABLE, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, initialFocusScheduled, initialFocusSeen, PRESENTED_SCOPE, presentedOpeners, presentedObserver, A11yHintDescription, WebRenderer;
28871
+ var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, SYNTHETIC_TABINDEX, INFERRED_DECORATIVE, SELF_RENDERED_LEAF, ROLE_WHEN_NAMED, AUTHORED_ROLE, PENDING_RANGE, RANGE_ROLES, A11Y_PART, NODE_A11Y_ATTRS, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, ANIMATION_LEAF, LottieNode, RiveNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, NATIVELY_TABBABLE, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, initialFocusScheduled, initialFocusSeen, PRESENTED_SCOPE, presentedOpeners, presentedObserver, A11yHintDescription, WebRenderer;
28766
28872
  var init_renderNode = __esm({
28767
28873
  "../../core/web-renderer/src/renderNode.tsx"() {
28768
28874
  "use strict";
@@ -30280,13 +30386,20 @@ var init_renderNode = __esm({
30280
30386
  if (!onChange || !ctx.onAction) return;
30281
30387
  ctx.onAction({ ...onChange, params: { ...onChange.params ?? {}, value: next }, args: { ...onChange.args ?? {}, value: next } });
30282
30388
  };
30283
- const bump = (delta) => {
30284
- const next = Math.min(max, Math.max(min, value + delta));
30389
+ const commit = (target) => {
30390
+ const next = Math.min(max, Math.max(min, target));
30285
30391
  if (next === value) return;
30286
30392
  setValue(next);
30287
30393
  setBagValue(encodeStepperFieldValue(next, { min, max }));
30288
30394
  dispatch(next);
30289
30395
  };
30396
+ const bump = (delta) => commit(value + delta);
30397
+ const onValueKeyDown = (e) => {
30398
+ const target = e.key === "ArrowUp" ? value + step : e.key === "ArrowDown" ? value - step : e.key === "Home" && typeof props.min === "number" ? min : e.key === "End" && typeof props.max === "number" ? max : void 0;
30399
+ if (target === void 0) return;
30400
+ e.preventDefault();
30401
+ commit(target);
30402
+ };
30290
30403
  const box = { display: "inline-flex", alignItems: "center", gap: 12, background: C("surfaceTertiary", "#eee"), borderRadius: ctx.radius("md", 8), padding: "4px 6px", width: "fit-content", ...wrap };
30291
30404
  const disabled = (at) => at === "min" ? value <= min : value >= max;
30292
30405
  const btn = (at) => ({
@@ -30303,25 +30416,31 @@ var init_renderNode = __esm({
30303
30416
  opacity: disabled(at) ? 0.4 : 1,
30304
30417
  userSelect: "none"
30305
30418
  });
30306
- const named = { [ROLE_WHEN_NAMED]: "group" };
30419
+ const valueA11y = {
30420
+ [A11Y_PART]: "node",
30421
+ role: "spinbutton",
30422
+ "aria-valuemin": typeof props.min === "number" ? min : void 0,
30423
+ "aria-valuemax": typeof props.max === "number" ? max : void 0
30424
+ };
30425
+ const root = { [A11Y_PART]: "root" };
30307
30426
  if (ctx.empty) {
30308
- return /* @__PURE__ */ jsxs3("div", { ...named, style: box, children: [
30427
+ return /* @__PURE__ */ jsxs3("div", { ...root, style: box, children: [
30309
30428
  /* @__PURE__ */ jsx6("span", { style: btn("min"), children: "\u2212" }),
30310
- /* @__PURE__ */ jsx6("b", { style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111") }, children: "\u2014" }),
30429
+ /* @__PURE__ */ jsx6("b", { ...valueA11y, style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111") }, children: "\u2014" }),
30311
30430
  /* @__PURE__ */ jsx6("span", { style: btn("max"), children: "+" })
30312
30431
  ] });
30313
30432
  }
30314
30433
  if (!ctx.onAction) {
30315
- return /* @__PURE__ */ jsxs3("div", { ...named, style: box, children: [
30434
+ return /* @__PURE__ */ jsxs3("div", { ...root, style: box, children: [
30316
30435
  /* @__PURE__ */ jsx6("span", { style: btn("min"), children: "\u2212" }),
30317
- /* @__PURE__ */ jsx6("b", { style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111") }, children: value }),
30436
+ /* @__PURE__ */ jsx6("b", { ...valueA11y, "aria-valuenow": value, "aria-readonly": "true", style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111") }, children: value }),
30318
30437
  /* @__PURE__ */ jsx6("span", { style: btn("max"), children: "+" })
30319
30438
  ] });
30320
30439
  }
30321
- return /* @__PURE__ */ jsxs3("div", { ...named, style: box, children: [
30322
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Decrease", disabled: disabled("min"), onClick: () => bump(-step), style: { ...btn("min"), font: "inherit" }, children: "\u2212" }),
30323
- /* @__PURE__ */ jsx6("b", { style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111"), fontVariantNumeric: "tabular-nums" }, children: value }),
30324
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Increase", disabled: disabled("max"), onClick: () => bump(step), style: { ...btn("max"), font: "inherit" }, children: "+" })
30440
+ return /* @__PURE__ */ jsxs3("div", { ...root, style: box, children: [
30441
+ /* @__PURE__ */ jsx6("button", { type: "button", tabIndex: -1, "aria-label": "Decrease", disabled: disabled("min"), onClick: () => bump(-step), style: { ...btn("min"), font: "inherit" }, children: "\u2212" }),
30442
+ /* @__PURE__ */ jsx6("b", { ...valueA11y, "aria-valuenow": value, tabIndex: 0, onKeyDown: onValueKeyDown, style: { fontSize: 16, minWidth: 24, textAlign: "center", color: C("textPrimary", "#111"), fontVariantNumeric: "tabular-nums" }, children: value }),
30443
+ /* @__PURE__ */ jsx6("button", { type: "button", tabIndex: -1, "aria-label": "Increase", disabled: disabled("max"), onClick: () => bump(step), style: { ...btn("max"), font: "inherit" }, children: "+" })
30325
30444
  ] });
30326
30445
  });
30327
30446
  SYNTHETIC_TAP_ROLE = "data-hm-synthetic-role";
@@ -30332,6 +30451,8 @@ var init_renderNode = __esm({
30332
30451
  AUTHORED_ROLE = "data-hm-authored-role";
30333
30452
  PENDING_RANGE = "data-hm-pending-range";
30334
30453
  RANGE_ROLES = /* @__PURE__ */ new Set(["progressbar", "slider", "scrollbar", "spinbutton", "meter"]);
30454
+ A11Y_PART = "data-hm-a11y-part";
30455
+ NODE_A11Y_ATTRS = ["aria-label", "aria-valuetext", "aria-level", "aria-describedby", "aria-disabled", "aria-selected"];
30335
30456
  INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
30336
30457
  "button",
30337
30458
  "checkbox",
@@ -30914,19 +31035,21 @@ var init_renderNode = __esm({
30914
31035
  const count2 = shown2.length + overflow;
30915
31036
  const countText = count2 > 0 ? `${count2} ${count2 === 1 ? "person" : "people"}` : "";
30916
31037
  const groupName = [caption, countText].filter(Boolean).join(", ");
30917
- return /* @__PURE__ */ jsxs3("div", { role: "group", "aria-label": groupName || void 0, "data-a11y-value": countText || void 0, ...{ [SELF_RENDERED_LEAF]: true }, style: { width: "100%", ...wrap }, children: [
30918
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex" }, children: [
31038
+ return /* @__PURE__ */ jsxs3("div", { role: "group", "aria-label": groupName || void 0, "data-a11y-value": countText || void 0, ...{ [SELF_RENDERED_LEAF]: true, [A11Y_PART]: "root" }, style: { width: "100%", ...wrap }, children: [
31039
+ /* @__PURE__ */ jsxs3("div", { role: "list", style: { display: "flex" }, children: [
30919
31040
  shown2.map((a, i) => {
30920
31041
  const ring = props.ringGradient ? ctx.gradient(props.ringGradient) : void 0;
30921
31042
  const wrapStyle = ring ? { marginLeft: i === 0 ? 0 : -(size - shift), background: ring, padding: 2.5, borderRadius: "50%" } : { marginLeft: i === 0 ? 0 : -(size - shift), border: `2px solid ${C("surfacePrimary", "#fff")}`, borderRadius: "50%" };
30922
- return /* @__PURE__ */ jsx6("div", { style: wrapStyle, children: avatarCircle(asText2(a.initials) || "?", size, C, true, bodyFont(ctx)) }, i);
31043
+ const who = asText2(a.initials).trim();
31044
+ const circle = avatarCircle(who || "?", size, C, true, bodyFont(ctx));
31045
+ return who ? /* @__PURE__ */ jsx6("div", { role: "listitem", style: wrapStyle, children: React5.cloneElement(circle, { role: "img", "aria-label": who }) }, i) : /* @__PURE__ */ jsx6("div", { "aria-hidden": "true", style: wrapStyle, children: circle }, i);
30923
31046
  }),
30924
- overflow > 0 && /* @__PURE__ */ jsxs3("div", { style: { marginLeft: -(size - shift), width: size, height: size, borderRadius: "50%", border: `2px solid ${C("surfacePrimary", "#fff")}`, background: C("surfaceTertiary", "#e6e6e6"), color: C("textPrimary", "#111"), display: "grid", placeItems: "center", fontSize: size * 0.32, fontWeight: 700, fontFamily: bodyFont(ctx) }, children: [
31047
+ overflow > 0 && /* @__PURE__ */ jsx6("div", { role: "listitem", style: { marginLeft: -(size - shift), width: size, height: size, borderRadius: "50%", border: `2px solid ${C("surfacePrimary", "#fff")}`, background: C("surfaceTertiary", "#e6e6e6"), color: C("textPrimary", "#111"), display: "grid", placeItems: "center", fontSize: size * 0.32, fontWeight: 700, fontFamily: bodyFont(ctx) }, children: /* @__PURE__ */ jsxs3("span", { role: "img", "aria-label": `${overflow} more`, children: [
30925
31048
  "+",
30926
31049
  overflow
30927
- ] })
31050
+ ] }) })
30928
31051
  ] }),
30929
- props.caption && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, color: C("textSecondary", "#888"), marginTop: 8 }, children: txt(props.caption, ctx) })
31052
+ props.caption && /* @__PURE__ */ jsx6("div", { ...{ [A11Y_PART]: "derived-name" }, style: { fontSize: 13, color: C("textSecondary", "#888"), marginTop: 8 }, children: txt(props.caption, ctx) })
30930
31053
  ] });
30931
31054
  });
30932
31055
  CHART_STROKE_CYCLE = ["solid", "dashed", "dotted"];
@@ -31739,11 +31862,11 @@ var init_renderNode = __esm({
31739
31862
  const boundImageUrl = useResolvedScalar(props.imageUrl != null && isBinding(props.imageUrl) ? props.imageUrl : void 0, ctx);
31740
31863
  const rawImageUrl = props.imageUrl != null && isBinding(props.imageUrl) ? boundImageUrl : props.imageUrl;
31741
31864
  const imageUrl = typeof rawImageUrl === "string" && rawImageUrl !== "" ? resolveAssetUrl(rawImageUrl, ctx.assetBaseUrl) : void 0;
31742
- return /* @__PURE__ */ jsxs3("div", { style: { width: "100%", ...wrap }, children: [
31865
+ return /* @__PURE__ */ jsxs3("div", { ...{ [A11Y_PART]: "root" }, style: { width: "100%", ...wrap }, children: [
31743
31866
  /* @__PURE__ */ jsxs3("div", { style: { position: "relative", height: Math.min(props.expandedHeight ?? 120, 160), borderRadius: ctx.radius("md", 10), overflow: "hidden", background: imageUrl ? void 0 : `linear-gradient(135deg, ${C("accentPrimary", "#116DFF")}, ${C("accentSecondary", "#0E5FE3")})` }, children: [
31744
31867
  imageUrl && /* @__PURE__ */ jsx6("img", { src: imageUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "cover" } }),
31745
31868
  /* @__PURE__ */ jsxs3("div", { style: { position: "absolute", left: 14, bottom: 12, color: "#fff", textShadow: "0 1px 4px rgba(0,0,0,.5)" }, children: [
31746
- /* @__PURE__ */ jsx6("div", { role: "heading", "aria-level": 2, style: { fontFamily: ctx.font("title1").family || ctx.idiom && ctx.idiom !== "base" ? fontStack(ctx.font("title1").family, ctx.idiom) : '"Wix Madefor Display", system-ui', fontWeight: 700, fontSize: 20 }, children: txt(props.title, ctx) }),
31869
+ /* @__PURE__ */ jsx6("div", { ...{ [A11Y_PART]: "node" }, role: "heading", "aria-level": 2, style: { fontFamily: ctx.font("title1").family || ctx.idiom && ctx.idiom !== "base" ? fontStack(ctx.font("title1").family, ctx.idiom) : '"Wix Madefor Display", system-ui', fontWeight: 700, fontSize: 20 }, children: txt(props.title, ctx) }),
31747
31870
  props.subtitle && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, opacity: 0.9 }, children: txt(props.subtitle, ctx) })
31748
31871
  ] })
31749
31872
  ] }),
@@ -38067,6 +38190,12 @@ var init_src6 = __esm({
38067
38190
  }
38068
38191
  });
38069
38192
 
38193
+ // ../../core/serve-storage/src/wip-pointer.ts
38194
+ var init_wip_pointer = __esm({
38195
+ "../../core/serve-storage/src/wip-pointer.ts"() {
38196
+ }
38197
+ });
38198
+
38070
38199
  // ../../core/serve-storage/src/release-patch.ts
38071
38200
  import { createHash as createHash17 } from "node:crypto";
38072
38201
  function sha256hex(b) {
@@ -38102,6 +38231,7 @@ function releaseContentId(m) {
38102
38231
  var init_release_patch = __esm({
38103
38232
  "../../core/serve-storage/src/release-patch.ts"() {
38104
38233
  init_widget_identity();
38234
+ init_wip_pointer();
38105
38235
  }
38106
38236
  });
38107
38237
 
@@ -52940,21 +53070,21 @@ var init_preview_assets_generated = __esm({
52940
53070
  "../../packages/serve/src/preview-assets.generated.ts"() {
52941
53071
  init_preview_assets_format();
52942
53072
  PREVIEW_ASSET_MANIFEST = [
52943
- { key: "assets/index-BU6QijMM.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1060352, sha256: "f608f6d0e14dafe6c495e5df15d09d7512e0a8d87732feea4f4e8e36de7917e4" },
52944
- { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1060360, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
52945
- { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1064970, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
52946
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1553554, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
52947
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1644478, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
52948
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1735462, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
52949
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1826442, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
52950
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1917314, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
52951
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2008294, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
52952
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2116930, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
52953
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2226014, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
52954
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2335062, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
52955
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2442762, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
52956
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 2530870, length: 4947, sha256: "c760d7592d0a40904bb13edaec8e8991f79fc2eb732c5dfee54fea36e6dceecb" },
52957
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2535817, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
53073
+ { key: "assets/index-RMW-OZ7N.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1062852, sha256: "5ceea282c8f188d80853097ec1e56e9f363fcd19e5b7d0882134f326db513d89" },
53074
+ { key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1062860, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
53075
+ { key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1067470, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
53076
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1556054, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
53077
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1646978, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
53078
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1737962, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
53079
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1828942, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
53080
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1919814, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
53081
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2010794, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
53082
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2119430, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
53083
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2228514, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
53084
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2337562, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
53085
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2445262, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
53086
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 2533370, length: 4947, sha256: "f7717e4d819fee4e0719a369ca061f514e02ff24f7f0dacaa6469a4a2fca8dcf" },
53087
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2538317, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
52958
53088
  ];
52959
53089
  }
52960
53090
  });
Binary file
@@ -178,8 +178,8 @@ book says which happened on the `cms collections:` line (`(skipped: no owner tok
178
178
  The `clientId`-is-the-binding rule above is about the **app's** runtime site binding, not this.
179
179
 
180
180
  `--apply` writes `provisioning.json` + token **values**, and patches the branded-lite
181
- home in `dev/index.ts`: its `onAppear` params (`ownerDefaultLayout`, `brandAccent`,
182
- `verticals`) and, when the analysis recognized any vertical, the Explore grid, the home
181
+ home in `dev/index.ts`: its `onAppear` params (`ownerDefaultLayout`, `verticals`, and
182
+ `brandAccent` in apps scaffolded before the home's brand colour followed the tokens) and, when the analysis recognized any vertical, the Explore grid, the home
183
183
  modules and — on a site without `store` — the Shop calls to action, naming what it
184
184
  removed in its notes (`himi docs wix-business-context`). It does **not** rewrite
185
185
  `config.ts` tabBar — you still set 2–4 Hebrew/RTL tabs to the site's jobs. If home still
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1064.0",
3
+ "version": "0.1066.0",
4
4
  "type": "module",
5
5
  "description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
6
6
  "keywords": [
@@ -65,5 +65,5 @@
65
65
  "artifactId": "himalaya-cli"
66
66
  }
67
67
  },
68
- "falconPackageHash": "4d146293883eafab0850062d46a7da667bdbb7ab5849fe455b318cca"
68
+ "falconPackageHash": "20e0465f099842099a9eb46bc0b20993df3071ca402d303dc0e7d66d"
69
69
  }
@@ -2335,7 +2335,6 @@ const SCREENS = runtimeSetting({
2335
2335
  "verticals": "[\"store\",\"bookings\",\"plans\",\"blog\"]",
2336
2336
  "homeModules": "[{\"id\":\"member_progress\",\"label\":\"This week's schedule\",\"dataSource\":\"member.bookings.schedule\",\"emptyWhen\":[\"hideMemberProgress\"]},{\"id\":\"up_next\",\"label\":\"Up next\",\"dataSource\":\"member.bookings\",\"emptyWhen\":[\"hideNextBooking\",\"hidePersonalError\"]},{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"Discover 1\",\"dataSource\":\"salonLuxe.section0\",\"emptyWhen\":[\"hideHeroImage\"]},{\"id\":\"section_1\",\"label\":\"__HIMI_APP_NAME__\",\"dataSource\":\"salonLuxe.section1\"}]",
2337
2337
  "ownerDefaultLayout": "salonLuxe",
2338
- "brandAccent": "#A65E58",
2339
2338
  "copy": "{\"home.bookVisitCta\":\"Book a visit\",\"home.featuredTitle\":\"Salon picks\",\"home.stylistsCaption\":\"Meet your stylists\",\"home.treatmentsSubtitle\":\"Book your favorite in a couple of taps.\",\"home.treatmentsTitle\":\"Signature treatments\"}"
2340
2339
  }
2341
2340
  }
@@ -4953,10 +4952,7 @@ const SCREENS = runtimeSetting({
4953
4952
  "bottom": 28
4954
4953
  },
4955
4954
  "onAppear": {
4956
- "actionId": "tier5.himiBrandedAppearance.sync",
4957
- "params": {
4958
- "brandAccent": "#A65E58"
4959
- }
4955
+ "actionId": "tier5.himiBrandedAppearance.sync"
4960
4956
  }
4961
4957
  }
4962
4958
  },
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
134
134
  return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
135
135
  }
136
136
 
137
- /** Resolve an accent id to a concrete hex, falling back to the app's brand color
138
- * for `brand` or any unknown value — so `backgroundColorPath` always binds to a
139
- * valid color. */
140
- export function accentColor(id: string, brandFallback: string): string {
141
- if (isAccentId(id) && ACCENT_META[id].hex) return ACCENT_META[id].hex;
142
- return brandFallback;
137
+ /** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
138
+ * "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
139
+ * own `accentPrimary` token on every renderer, and that token IS the brand — after a
140
+ * `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
141
+ * into the descriptor instead (the old `brandAccent` param) went stale on the second path:
142
+ * the Home pill kept the template's blue after a rebrand. */
143
+ export function accentColor(id: string): string {
144
+ return isAccentId(id) ? ACCENT_META[id].hex : "";
143
145
  }
144
146
 
145
147
  /** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.
@@ -19,11 +19,10 @@ import {
19
19
  interface State {
20
20
  /** The pending accent id (persisted on Apply, re-read by the home worker). */
21
21
  pendingAccent: string;
22
- /** The app's brand color (from the onAppear param) — the "brand" accent swatch
23
- * and the accent fallback resolve to it. */
24
- brandAccent: string;
25
- // Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but
26
- // NOT per-row `$item.` fields, so each static swatch binds its own flat field.
22
+ // Per-accent swatch colors. backgroundColorPath resolves `$service:` paths but NOT
23
+ // per-row `$item.` fields, so each static swatch binds its own flat field.
24
+ // `accentHex_brand` is "" on purpose: the swatch keeps its own accentPrimary token,
25
+ // which is the brand (see accentColor in _shared/himi-layouts.ts).
27
26
  accentHex_brand: string;
28
27
  accentHex_amber: string;
29
28
  accentHex_terracotta: string;
@@ -54,7 +53,7 @@ function paramValue(arg: unknown, key: string): string {
54
53
  return typeof result === "string" ? result : "";
55
54
  }
56
55
 
57
- function build(pendingAccent: string, brandAccent: string): State {
56
+ function build(pendingAccent: string): State {
58
57
  const flags: Record<string, boolean> = {};
59
58
  for (const id of ACCENT_IDS) {
60
59
  flags[`selected_${id}`] = id === pendingAccent;
@@ -63,8 +62,7 @@ function build(pendingAccent: string, brandAccent: string): State {
63
62
  return {
64
63
  ...flags,
65
64
  pendingAccent,
66
- brandAccent,
67
- accentHex_brand: brandAccent || ACCENT_META.amber.hex,
65
+ accentHex_brand: "",
68
66
  accentHex_amber: ACCENT_META.amber.hex,
69
67
  accentHex_terracotta: ACCENT_META.terracotta.hex,
70
68
  accentHex_sage: ACCENT_META.sage.hex,
@@ -84,24 +82,21 @@ const svc = defineService<State, {
84
82
  apply: (state: State) => State;
85
83
  reset: (state: State) => State;
86
84
  }>("himiBrandedAppearance", {
87
- state: build(initialAccent(), ""),
85
+ state: build(initialAccent()),
88
86
  actions: {
89
- // onAppear: re-read the persisted accent + the app's brand color so the swatches
90
- // reflect reality (the brand swatch tints to the app's own color).
91
- sync: (state, arg) => {
92
- const brandAccent = paramValue(arg, "brandAccent") || state.brandAccent;
93
- return build(initialAccent(), brandAccent);
94
- },
87
+ // onAppear: re-read the persisted accent so the swatches reflect reality. An older
88
+ // descriptor may still pass a `brandAccent`; it is not used (the Brand swatch is the token).
89
+ sync: () => build(initialAccent()),
95
90
  // Tapping an accent swatch marks it pending (persisted on Apply).
96
91
  selectAccent: (state, arg) => {
97
92
  const id = paramValue(arg, "id");
98
93
  if (!isAccentId(id)) return state;
99
- return build(id, state.brandAccent);
94
+ return build(id);
100
95
  },
101
96
  // Apply: persist the accent; the home worker re-reads it on launch.
102
97
  apply: (state) => {
103
98
  try { storage()?.setItem(ACCENT_KEY, state.pendingAccent); } catch { /* best-effort */ }
104
- return build(state.pendingAccent, state.brandAccent);
99
+ return build(state.pendingAccent);
105
100
  },
106
101
  // Reset: clear the override, reverting to the brand accent.
107
102
  reset: (state) => {
@@ -110,7 +105,7 @@ const svc = defineService<State, {
110
105
  if (store?.removeItem) store.removeItem(ACCENT_KEY);
111
106
  else store?.setItem(ACCENT_KEY, "");
112
107
  } catch { /* best-effort */ }
113
- return build(DEFAULT_ACCENT, state.brandAccent);
108
+ return build(DEFAULT_ACCENT);
114
109
  },
115
110
  },
116
111
  });
@@ -338,11 +338,11 @@ function storedLayout(): string | null {
338
338
  function storedAccent(): string {
339
339
  try { return storage()?.getItem(ACCENT_KEY) ?? ""; } catch { return ""; }
340
340
  }
341
- // user accent (storage) → brand color (onAppear param) fallback. Always a valid
342
- // hex so backgroundColorPath binds cleanly; "" brand param at first paint just
343
- // falls the surface back to its accentPrimary token.
344
- function resolveAccent(arg: unknown): string {
345
- return resolveAccentColor(storedAccent(), paramValue(arg, "brandAccent"));
341
+ // The member's chosen accent (storage), else "" — the surface keeps its accentPrimary token,
342
+ // which is the brand. An older descriptor's `brandAccent` param is ignored: it was a copy of
343
+ // the brand that a hand edit of tokens.json left behind.
344
+ function resolveAccent(_arg?: unknown): string {
345
+ return resolveAccentColor(storedAccent());
346
346
  }
347
347
 
348
348
  // onAppear param reader (the himi-branded-lite-cms pattern): the descriptor
@@ -2923,8 +2923,7 @@ const SCREENS = runtimeSetting({
2923
2923
  "params": {
2924
2924
  "verticals": "[\"store\",\"bookings\",\"restaurants\",\"programs\",\"plans\",\"feed\",\"members\",\"forum\",\"coupons\",\"notifications\",\"loyalty\",\"reviews\",\"portfolio\",\"reservations\",\"invoices\",\"badges\",\"notifsettings\",\"events\",\"blog\",\"groups\",\"cms\",\"donations\",\"giftCards\",\"videos\",\"podcasts\",\"forms\",\"galleries\",\"inbox\",\"faq\"]",
2925
2925
  "homeModules": "[{\"id\":\"member_progress\",\"label\":\"This week's schedule\",\"dataSource\":\"member.bookings.schedule\",\"emptyWhen\":[\"hideMemberProgress\"]},{\"id\":\"up_next\",\"label\":\"Up next\",\"dataSource\":\"member.bookings\",\"emptyWhen\":[\"hideNextBooking\",\"hidePersonalError\"]},{\"id\":\"saved\",\"label\":\"Saved on this device\",\"dataSource\":\"device.saved_items\",\"emptyWhen\":[\"noSavedContent\"]},{\"id\":\"section_0\",\"label\":\"Discover 1\",\"dataSource\":\"classic.section0\",\"emptyWhen\":[\"hideFeaturedSkeleton\"]},{\"id\":\"section_1\",\"label\":\"Featured products\",\"dataSource\":\"classic.section1\"}]",
2926
- "ownerDefaultLayout": "",
2927
- "brandAccent": "#0A66C2"
2926
+ "ownerDefaultLayout": ""
2928
2927
  }
2929
2928
  }
2930
2929
  }
@@ -5981,10 +5980,7 @@ const SCREENS = runtimeSetting({
5981
5980
  "bottom": 28
5982
5981
  },
5983
5982
  "onAppear": {
5984
- "actionId": "tier5.himiBrandedAppearance.sync",
5985
- "params": {
5986
- "brandAccent": "#0A66C2"
5987
- }
5983
+ "actionId": "tier5.himiBrandedAppearance.sync"
5988
5984
  }
5989
5985
  }
5990
5986
  },
@@ -134,12 +134,14 @@ export function isAccentId(x: unknown): x is AccentId {
134
134
  return typeof x === "string" && (ACCENT_IDS as readonly string[]).includes(x);
135
135
  }
136
136
 
137
- /** Resolve an accent id to a concrete hex, falling back to the app's brand color
138
- * for `brand` or any unknown value — so `backgroundColorPath` always binds to a
139
- * valid color. */
140
- export function accentColor(id: string, brandFallback: string): string {
141
- if (isAccentId(id) && ACCENT_META[id].hex) return ACCENT_META[id].hex;
142
- return brandFallback;
137
+ /** Resolve an accent id to its curated hex, or "" for `brand` and any unknown value.
138
+ * "" is deliberate: a bound `backgroundColorPath` that resolves empty keeps the surface's
139
+ * own `accentPrimary` token on every renderer, and that token IS the brand — after a
140
+ * `site analyze --apply` and after a hand edit of tokens.json alike. A brand colour copied
141
+ * into the descriptor instead (the old `brandAccent` param) went stale on the second path:
142
+ * the Home pill kept the template's blue after a rebrand. */
143
+ export function accentColor(id: string): string {
144
+ return isAccentId(id) ? ACCENT_META[id].hex : "";
143
145
  }
144
146
 
145
147
  /** Content-derived default: booking intent > deep catalog > editorial (blog-forward) > balanced.