@vectoriox/iox-ui 5.77.0 → 5.78.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.
@@ -414,6 +414,568 @@ const SPEC_SITE_ARCHETYPES = {
414
414
  }
415
415
  };
416
416
  const SPEC_SITE_PATTERNS = {
417
+ "hero.scene-depth": {
418
+ "family": "hero",
419
+ "scene": true,
420
+ "label": "Hero — a picture that opens as you scroll",
421
+ "intent": "One strong picture of the work that opens and settles while the page holds still — a first screen that moves, for a studio with a picture worth it.",
422
+ "node": {
423
+ "t": "Section",
424
+ "es": "section",
425
+ "scheme": "inverse",
426
+ "role": "scene",
427
+ "lay": {
428
+ "position": "relative",
429
+ "display": "block",
430
+ "width": "100%",
431
+ "height": "300vh",
432
+ "padding": "0px"
433
+ },
434
+ "c": [
435
+ {
436
+ "t": "Container",
437
+ "role": "scene.stage",
438
+ "lay": {
439
+ "position": "sticky",
440
+ "top": "0px",
441
+ "display": "block",
442
+ "width": "100%",
443
+ "height": "100svh",
444
+ "overflow": "hidden",
445
+ "padding": "0px"
446
+ },
447
+ "c": [
448
+ {
449
+ "t": "Image",
450
+ "es": "media",
451
+ "ph": "image",
452
+ "lay": {
453
+ "position": "absolute",
454
+ "top": "0px",
455
+ "left": "0px",
456
+ "width": "100%",
457
+ "height": "100%",
458
+ "aspectRatio": "auto",
459
+ "borderRadius": "0px",
460
+ "objectFit": "cover"
461
+ },
462
+ "tracks": [
463
+ {
464
+ "prop": "scale",
465
+ "keys": [
466
+ [
467
+ 0,
468
+ 1.3
469
+ ],
470
+ [
471
+ 1,
472
+ 1
473
+ ]
474
+ ]
475
+ },
476
+ {
477
+ "prop": "clip",
478
+ "from": "bottom",
479
+ "keys": [
480
+ [
481
+ 0,
482
+ 38
483
+ ],
484
+ [
485
+ 0.42,
486
+ 100
487
+ ]
488
+ ]
489
+ }
490
+ ]
491
+ },
492
+ {
493
+ "t": "Container",
494
+ "es": "media-scrim",
495
+ "lay": {
496
+ "display": "flex",
497
+ "flexDirection": "column",
498
+ "gap": "14px",
499
+ "position": "absolute",
500
+ "left": "0px",
501
+ "bottom": "0px",
502
+ "width": "100%",
503
+ "padding": "48px 32px 56px 32px"
504
+ },
505
+ "c": [
506
+ {
507
+ "t": "Heading",
508
+ "es": "display",
509
+ "level": "h1",
510
+ "slot": "headline",
511
+ "max": 56,
512
+ "fromBusiness": "name",
513
+ "tracks": [
514
+ {
515
+ "prop": "y",
516
+ "keys": [
517
+ [
518
+ 0,
519
+ 0
520
+ ],
521
+ [
522
+ 1,
523
+ -6
524
+ ]
525
+ ]
526
+ }
527
+ ]
528
+ },
529
+ {
530
+ "t": "Text",
531
+ "es": "lead",
532
+ "slot": "lead",
533
+ "max": 180,
534
+ "fromBusiness": "tagline",
535
+ "ph": "copy",
536
+ "tracks": [
537
+ {
538
+ "prop": "opacity",
539
+ "keys": [
540
+ [
541
+ 0.45,
542
+ 0
543
+ ],
544
+ [
545
+ 0.6,
546
+ 1
547
+ ]
548
+ ]
549
+ }
550
+ ]
551
+ },
552
+ {
553
+ "t": "ButtonBlock",
554
+ "es": "button-primary",
555
+ "href": "/contact",
556
+ "slot": "cta",
557
+ "max": 24,
558
+ "text": "Get in touch",
559
+ "tracks": [
560
+ {
561
+ "prop": "opacity",
562
+ "keys": [
563
+ [
564
+ 0.5,
565
+ 0
566
+ ],
567
+ [
568
+ 0.65,
569
+ 1
570
+ ]
571
+ ]
572
+ }
573
+ ]
574
+ }
575
+ ]
576
+ }
577
+ ]
578
+ }
579
+ ]
580
+ }
581
+ },
582
+ "story.scene-chapters": {
583
+ "family": "story",
584
+ "scene": true,
585
+ "label": "Story — three chapters on one held stage",
586
+ "intent": "How you work in three short chapters that take turns over one picture while the page holds still — a process worth slowing down for.",
587
+ "node": {
588
+ "t": "Section",
589
+ "es": "section",
590
+ "scheme": "inverse",
591
+ "role": "scene",
592
+ "lay": {
593
+ "position": "relative",
594
+ "display": "block",
595
+ "width": "100%",
596
+ "height": "400vh",
597
+ "padding": "0px"
598
+ },
599
+ "c": [
600
+ {
601
+ "t": "Container",
602
+ "role": "scene.stage",
603
+ "lay": {
604
+ "position": "sticky",
605
+ "top": "0px",
606
+ "display": "block",
607
+ "width": "100%",
608
+ "height": "100svh",
609
+ "overflow": "hidden",
610
+ "padding": "0px"
611
+ },
612
+ "c": [
613
+ {
614
+ "t": "Image",
615
+ "es": "media",
616
+ "ph": "image",
617
+ "lay": {
618
+ "position": "absolute",
619
+ "top": "0px",
620
+ "left": "0px",
621
+ "width": "100%",
622
+ "height": "100%",
623
+ "aspectRatio": "auto",
624
+ "borderRadius": "0px",
625
+ "objectFit": "cover"
626
+ },
627
+ "tracks": [
628
+ {
629
+ "prop": "scale",
630
+ "keys": [
631
+ [
632
+ 0,
633
+ 1.12
634
+ ],
635
+ [
636
+ 1,
637
+ 1
638
+ ]
639
+ ]
640
+ }
641
+ ]
642
+ },
643
+ {
644
+ "t": "Container",
645
+ "es": "media-scrim",
646
+ "lay": {
647
+ "position": "absolute",
648
+ "left": "0px",
649
+ "bottom": "0px",
650
+ "width": "100%",
651
+ "height": "62%",
652
+ "padding": "0px"
653
+ },
654
+ "c": [
655
+ {
656
+ "t": "Container",
657
+ "es": "box",
658
+ "lay": {
659
+ "display": "flex",
660
+ "flexDirection": "column",
661
+ "gap": "12px",
662
+ "position": "absolute",
663
+ "left": "32px",
664
+ "right": "32px",
665
+ "bottom": "56px",
666
+ "maxWidth": "640px"
667
+ },
668
+ "tracks": [
669
+ {
670
+ "prop": "opacity",
671
+ "keys": [
672
+ [
673
+ 0,
674
+ 1
675
+ ],
676
+ [
677
+ 0.26,
678
+ 1
679
+ ],
680
+ [
681
+ 0.33,
682
+ 0
683
+ ]
684
+ ]
685
+ },
686
+ {
687
+ "prop": "y",
688
+ "keys": [
689
+ [
690
+ 0.26,
691
+ 0
692
+ ],
693
+ [
694
+ 0.33,
695
+ -6
696
+ ]
697
+ ]
698
+ }
699
+ ],
700
+ "c": [
701
+ {
702
+ "t": "Text",
703
+ "es": "eyebrow",
704
+ "slot": "eyebrow",
705
+ "max": 32,
706
+ "ph": "copy",
707
+ "text": "How we work"
708
+ },
709
+ {
710
+ "t": "Heading",
711
+ "es": "h2",
712
+ "level": "h2",
713
+ "slot": "title",
714
+ "max": 52,
715
+ "ph": "copy",
716
+ "text": "It starts with a conversation"
717
+ },
718
+ {
719
+ "t": "Text",
720
+ "es": "lead",
721
+ "slot": "text",
722
+ "max": 180,
723
+ "ph": "copy",
724
+ "text": "What the first step is, in a sentence or two."
725
+ }
726
+ ]
727
+ },
728
+ {
729
+ "t": "Container",
730
+ "es": "box",
731
+ "lay": {
732
+ "display": "flex",
733
+ "flexDirection": "column",
734
+ "gap": "12px",
735
+ "position": "absolute",
736
+ "left": "32px",
737
+ "right": "32px",
738
+ "bottom": "56px",
739
+ "maxWidth": "640px"
740
+ },
741
+ "tracks": [
742
+ {
743
+ "prop": "opacity",
744
+ "keys": [
745
+ [
746
+ 0.33,
747
+ 0
748
+ ],
749
+ [
750
+ 0.4,
751
+ 1
752
+ ],
753
+ [
754
+ 0.6,
755
+ 1
756
+ ],
757
+ [
758
+ 0.67,
759
+ 0
760
+ ]
761
+ ]
762
+ },
763
+ {
764
+ "prop": "y",
765
+ "keys": [
766
+ [
767
+ 0.33,
768
+ 6
769
+ ],
770
+ [
771
+ 0.4,
772
+ 0
773
+ ],
774
+ [
775
+ 0.6,
776
+ 0
777
+ ],
778
+ [
779
+ 0.67,
780
+ -6
781
+ ]
782
+ ]
783
+ }
784
+ ],
785
+ "c": [
786
+ {
787
+ "t": "Heading",
788
+ "es": "h2",
789
+ "level": "h2",
790
+ "slot": "title2",
791
+ "max": 52,
792
+ "ph": "copy",
793
+ "text": "Then we make it"
794
+ },
795
+ {
796
+ "t": "Text",
797
+ "es": "lead",
798
+ "slot": "text2",
799
+ "max": 180,
800
+ "ph": "copy",
801
+ "text": "What the middle of the work is, in a sentence or two."
802
+ }
803
+ ]
804
+ },
805
+ {
806
+ "t": "Container",
807
+ "es": "box",
808
+ "lay": {
809
+ "display": "flex",
810
+ "flexDirection": "column",
811
+ "gap": "12px",
812
+ "position": "absolute",
813
+ "left": "32px",
814
+ "right": "32px",
815
+ "bottom": "56px",
816
+ "maxWidth": "640px"
817
+ },
818
+ "tracks": [
819
+ {
820
+ "prop": "opacity",
821
+ "keys": [
822
+ [
823
+ 0.67,
824
+ 0
825
+ ],
826
+ [
827
+ 0.74,
828
+ 1
829
+ ],
830
+ [
831
+ 1,
832
+ 1
833
+ ]
834
+ ]
835
+ },
836
+ {
837
+ "prop": "y",
838
+ "keys": [
839
+ [
840
+ 0.67,
841
+ 6
842
+ ],
843
+ [
844
+ 0.74,
845
+ 0
846
+ ]
847
+ ]
848
+ }
849
+ ],
850
+ "c": [
851
+ {
852
+ "t": "Heading",
853
+ "es": "h2",
854
+ "level": "h2",
855
+ "slot": "title3",
856
+ "max": 52,
857
+ "ph": "copy",
858
+ "text": "And it is yours"
859
+ },
860
+ {
861
+ "t": "Text",
862
+ "es": "lead",
863
+ "slot": "text3",
864
+ "max": 180,
865
+ "ph": "copy",
866
+ "text": "What the client leaves with, in a sentence or two."
867
+ }
868
+ ]
869
+ }
870
+ ]
871
+ }
872
+ ]
873
+ }
874
+ ]
875
+ }
876
+ },
877
+ "proof.scene-words": {
878
+ "family": "proof",
879
+ "scene": true,
880
+ "label": "A testimonial that lights word by word",
881
+ "intent": "One client's words, lit one word at a time while the page holds still — only once the studio has a real quote worth slowing down for.",
882
+ "node": {
883
+ "t": "Section",
884
+ "es": "section",
885
+ "role": "scene",
886
+ "lay": {
887
+ "position": "relative",
888
+ "display": "block",
889
+ "width": "100%",
890
+ "height": "250vh",
891
+ "padding": "0px"
892
+ },
893
+ "c": [
894
+ {
895
+ "t": "Container",
896
+ "role": "scene.stage",
897
+ "lay": {
898
+ "position": "sticky",
899
+ "top": "0px",
900
+ "display": "flex",
901
+ "width": "100%",
902
+ "height": "100svh",
903
+ "overflow": "hidden",
904
+ "padding": "32px 32px 32px 32px",
905
+ "alignItems": "center",
906
+ "justifyContent": "center"
907
+ },
908
+ "c": [
909
+ {
910
+ "t": "Container",
911
+ "es": "box",
912
+ "lay": {
913
+ "display": "flex",
914
+ "flexDirection": "column",
915
+ "gap": "20px",
916
+ "maxWidth": "900px",
917
+ "width": "100%",
918
+ "margin": "0px auto 0px auto"
919
+ },
920
+ "c": [
921
+ {
922
+ "t": "Text",
923
+ "es": "eyebrow",
924
+ "slot": "eyebrow",
925
+ "max": 32,
926
+ "ph": "copy",
927
+ "text": "What clients say"
928
+ },
929
+ {
930
+ "t": "Heading",
931
+ "es": "h2",
932
+ "level": "h2",
933
+ "ph": "copy",
934
+ "text": "A sentence a client actually said, in their own words.",
935
+ "tracks": [
936
+ {
937
+ "prop": "words",
938
+ "keys": [
939
+ [
940
+ 0.08,
941
+ 0
942
+ ],
943
+ [
944
+ 0.7,
945
+ 100
946
+ ]
947
+ ]
948
+ }
949
+ ]
950
+ },
951
+ {
952
+ "t": "Text",
953
+ "es": "small",
954
+ "ph": "copy",
955
+ "text": "[Client name] · [Project, city]",
956
+ "tracks": [
957
+ {
958
+ "prop": "opacity",
959
+ "keys": [
960
+ [
961
+ 0.7,
962
+ 0
963
+ ],
964
+ [
965
+ 0.82,
966
+ 1
967
+ ]
968
+ ]
969
+ }
970
+ ]
971
+ }
972
+ ]
973
+ }
974
+ ]
975
+ }
976
+ ]
977
+ }
978
+ },
417
979
  "nav.inline-cta": {
418
980
  "family": "nav",
419
981
  "label": "Navigation bar",
@@ -4919,6 +5481,11 @@ const SPEC_SITE_LIBRARY = [
4919
5481
  "family": "hero",
4920
5482
  "composed": true
4921
5483
  },
5484
+ {
5485
+ "id": "hero.scene-depth",
5486
+ "family": "hero",
5487
+ "composed": true
5488
+ },
4922
5489
  {
4923
5490
  "id": "proof.logo-strip",
4924
5491
  "family": "proof",
@@ -4939,6 +5506,11 @@ const SPEC_SITE_LIBRARY = [
4939
5506
  "family": "proof",
4940
5507
  "composed": true
4941
5508
  },
5509
+ {
5510
+ "id": "proof.scene-words",
5511
+ "family": "proof",
5512
+ "composed": true
5513
+ },
4942
5514
  {
4943
5515
  "id": "feature.triad",
4944
5516
  "family": "feature",
@@ -4994,6 +5566,11 @@ const SPEC_SITE_LIBRARY = [
4994
5566
  "family": "story",
4995
5567
  "composed": true
4996
5568
  },
5569
+ {
5570
+ "id": "story.scene-chapters",
5571
+ "family": "story",
5572
+ "composed": true
5573
+ },
4997
5574
  {
4998
5575
  "id": "cta.banner",
4999
5576
  "family": "cta",
@@ -10514,11 +11091,19 @@ function patternLinkSlots(pattern) {
10514
11091
  function patternHasForm(pattern) {
10515
11092
  return patternNodes(pattern).some(n => !!n.preset);
10516
11093
  }
10517
- /** The library's 31 sections (contract `site.library`), each with whether it is composed. */
11094
+ /** SC6: the level a Scene needs — the site's How animated, never a section's own `enter` (a Scene takes no entrance). */
11095
+ const SCENE_LEVEL = 'expressive';
11096
+ /** SC6: Scenes on the home page and at most this many other pages, one per page (`validateSitePlan`). */
11097
+ const SCENE_OTHER_PAGES = 1;
11098
+ /** The library's sections (contract `site.library`), each with whether it is composed. */
10518
11099
  const SITE_LIBRARY = SPEC_SITE_LIBRARY;
10519
- /** The composed library as the model reads it — every pattern, its budgets under `density` (M1-3's manifest). */
10520
- function patternManifest(density) {
10521
- return Object.entries(SITE_PATTERNS).map(([id, p]) => ({
11100
+ /**
11101
+ * The composed library as the model reads it — every pattern, its budgets under `density` (M1-3's manifest). Given the
11102
+ * site's How animated (SC6), the Scenes are listed only at `SCENE_LEVEL`, marked `scene`; without it, all of them.
11103
+ */
11104
+ function patternManifest(density, options = {}) {
11105
+ const scenes = !('animate' in options) || options.animate === SCENE_LEVEL;
11106
+ return Object.entries(SITE_PATTERNS).filter(([, p]) => scenes || !p.scene).map(([id, p]) => ({
10522
11107
  id, family: p.family, label: p.label, intent: p.intent, ...(p.global ? { global: p.global } : {}),
10523
11108
  slots: Object.fromEntries(Object.keys(patternSlotBudgets(p)).map(slot => [slot, slotBudget(p, slot, density)])),
10524
11109
  links: patternLinkSlots(p),
@@ -10526,6 +11111,7 @@ function patternManifest(density) {
10526
11111
  roles: [...new Set(patternRoleNeeds(p).map(r => `${r.scope}.@${r.role}${r.optional ? OPTIONAL_MARK$2 : ''}`))],
10527
11112
  optionalParts: patternOptionalParts(p),
10528
11113
  form: patternHasForm(p),
11114
+ ...(p.scene ? { scene: true } : {}),
10529
11115
  }));
10530
11116
  }
10531
11117
  /** The bind scopes a pattern reads (`route`, `next`, …) — what its page must provide. */
@@ -10866,6 +11452,9 @@ var SitePlanIssueCode;
10866
11452
  SitePlanIssueCode["UnknownNeed"] = "unknown-need";
10867
11453
  /** A page key that is a global slot's name (`header`, `footer`): its sections' ids would be the global's. */
10868
11454
  SitePlanIssueCode["ReservedPageKey"] = "reserved-page-key";
11455
+ /** SC6: a Scene below How animated Expressive, a second Scene on a page, or Scenes on more than the home page and
11456
+ * one other — the pages answer by choosing another pattern. */
11457
+ SitePlanIssueCode["SceneBudget"] = "scene-budget";
10869
11458
  })(SitePlanIssueCode || (SitePlanIssueCode = {}));
10870
11459
  class SitePlanError extends Error {
10871
11460
  constructor(issues) {
@@ -11322,6 +11911,29 @@ function validatePages(c, list, types, sources, density) {
11322
11911
  if (homes.length !== 1)
11323
11912
  c.add(SitePlanIssueCode.Home, 'pages', `exactly one page is the home page (found ${homes.length})`);
11324
11913
  }
11914
+ /** SC6 (premium-sites plan, APPROVED 2026-11-05): who may hold the page — Scenes only at Expressive, one per page, on the
11915
+ * home page and at most one other. A Scene past that is an issue at its pattern, so the pages choose another. */
11916
+ function validateScenes(c, pages, animate) {
11917
+ let otherPages = 0;
11918
+ pages.forEach((raw, i) => {
11919
+ if (!isPlainObject(raw) || !Array.isArray(raw['sections']))
11920
+ return;
11921
+ let onPage = 0;
11922
+ const counted = raw['isHome'] === true;
11923
+ raw['sections'].forEach((s, j) => {
11924
+ const pattern = isPlainObject(s) && typeof s['pattern'] === 'string' ? patternById(s['pattern']) : null;
11925
+ if (!pattern?.scene)
11926
+ return;
11927
+ const at = `pages[${i}].sections[${j}].pattern`;
11928
+ if (animate !== SCENE_LEVEL)
11929
+ return c.add(SitePlanIssueCode.SceneBudget, at, `"${s['pattern']}" holds the page as it scrolls — only on a site whose How animated is Expressive (this one is ${animate ?? 'unset'})`);
11930
+ if (++onPage > 1)
11931
+ return c.add(SitePlanIssueCode.SceneBudget, at, 'one Scene per page — choose a section that does not hold the page');
11932
+ if (!counted && onPage === 1 && ++otherPages > SCENE_OTHER_PAGES)
11933
+ c.add(SitePlanIssueCode.SceneBudget, at, `Scenes on the home page and at most ${SCENE_OTHER_PAGES} other page — choose a section that does not hold the page`);
11934
+ });
11935
+ });
11936
+ }
11325
11937
  function validatePageSeo(c, seo, path) {
11326
11938
  if (seo === undefined)
11327
11939
  return;
@@ -11374,6 +11986,7 @@ function validateSitePlan(plan) {
11374
11986
  const design = isPlainObject(plan['design']) ? plan['design'] : {};
11375
11987
  validatePages(c, c.array(plan, 'pages', ''), types, sources, typeof design['density'] === 'string' ? design['density'] : null);
11376
11988
  validateGlobals(c, plan['globals']);
11989
+ validateScenes(c, c.array(plan, 'pages', ''), typeof design['animate'] === 'string' ? design['animate'] : null);
11377
11990
  return { valid: c.issues.length === 0, issues: c.issues };
11378
11991
  }
11379
11992
  /** Throw a `SitePlanError` carrying every issue unless the plan is valid. */
@@ -12509,6 +13122,10 @@ function composeNode(given, id, repeater, ctx) {
12509
13122
  const node = create(id, type, props, pn.es ?? null);
12510
13123
  if (pn.role)
12511
13124
  node.role = pn.role;
13125
+ if (pn.tracks?.length)
13126
+ node.sceneTracks = pn.tracks.map(cloneTrack);
13127
+ if (pn.phoneTracks?.length)
13128
+ node.scenePhoneTracks = pn.phoneTracks.map(cloneTrack);
12512
13129
  markEntrance(pn, id, repeater, ctx);
12513
13130
  // Words.
12514
13131
  if (words.placeholder) {
@@ -12962,6 +13579,13 @@ function wireOpeners(root, openers) {
12962
13579
  };
12963
13580
  visit(root);
12964
13581
  }
13582
+ /** How a composed section moves in (M1-6b): the look's How animated (or the section's own) on the page's direction. */
13583
+ /** SC6: a track's own copy, so a composed page never shares an array with the contract. */
13584
+ const cloneTrack = (track) => ({
13585
+ prop: track.prop,
13586
+ keys: track.keys.map(([at, value]) => [at, value]),
13587
+ ...(track.from ? { from: track.from } : {}),
13588
+ });
12965
13589
  function composePattern(pattern, id, ctx, motion = null) {
12966
13590
  if (pattern.node.each)
12967
13591
  throw new ComposeError(`${id}: a pattern's root cannot be stamped per page`);
@@ -12971,7 +13595,8 @@ function composePattern(pattern, id, ctx, motion = null) {
12971
13595
  throw new ComposeError(`${id}: a pattern's root cannot be optional or a link`);
12972
13596
  wireOpeners(node, own.openers ?? []);
12973
13597
  wireShownWhen(node, own.shownWhen ?? []);
12974
- if (motion && !pattern.global)
13598
+ // A Scene moves by the scroll alone: the look's entrances would fade its pinned stage in on arrival (SC6).
13599
+ if (motion && !pattern.global && !pattern.scene)
12975
13600
  stampEntrances(node, pattern.family, own.entrances ?? [], motion);
12976
13601
  node.label = pattern.label;
12977
13602
  return node;
@@ -13308,7 +13933,7 @@ function showcasePages() {
13308
13933
  const byFamily = new Map();
13309
13934
  const onItemPage = [];
13310
13935
  for (const [id, p] of Object.entries(SITE_PATTERNS)) {
13311
- if (p.global)
13936
+ if (p.global || p.scene)
13312
13937
  continue;
13313
13938
  if (readsRouteItem(id)) {
13314
13939
  onItemPage.push(id);
@@ -13333,22 +13958,32 @@ function showcaseGlobals() {
13333
13958
  const of = (position) => Object.entries(SITE_PATTERNS).filter(([, p]) => p.global === position).map(([id]) => id);
13334
13959
  return { headers: of(PatternGlobalPosition.Before), footers: of(PatternGlobalPosition.After) };
13335
13960
  }
13336
- /** The showcase as Site Plans — as many as it takes for every header and every footer to be composed once. */
13961
+ /** SC6: the Scene patterns — each shown alone on the home page of its own plan, as a site may hold one (validateScenes). */
13962
+ function showcaseScenes() {
13963
+ return Object.entries(SITE_PATTERNS).filter(([, p]) => p.scene && !p.global).map(([id]) => id);
13964
+ }
13965
+ /**
13966
+ * The showcase as Site Plans — as many as it takes for every header and every footer to be composed once, then one per
13967
+ * Scene pattern (SC6): its home page holds that Scene and nothing else, at How animated Expressive, the only level a
13968
+ * Scene is composed at.
13969
+ */
13337
13970
  function showcasePlans(input) {
13338
13971
  const { headers, footers } = showcaseGlobals();
13339
13972
  const count = Math.max(headers.length, footers.length, 1);
13340
13973
  const pages = showcasePages();
13341
- return Array.from({ length: count }, (_, i) => ({
13974
+ const plan = (i, planPages, design) => ({
13342
13975
  version: SITE_PLAN_VERSION,
13343
13976
  source: { kind: SitePlanSourceKind.Template, templateId: 'showcase', templateVersion: 1 },
13344
13977
  business: JSON.parse(JSON.stringify(input.business)),
13345
13978
  ...(input.locale ? { locale: input.locale } : {}),
13346
- design: JSON.parse(JSON.stringify(input.design)),
13979
+ design: JSON.parse(JSON.stringify(design)),
13347
13980
  contentTypes: JSON.parse(JSON.stringify(STUDIO_TEMPLATE.contentTypes)),
13348
13981
  dataSources: JSON.parse(JSON.stringify(STUDIO_TEMPLATE.dataSources)),
13349
- pages: JSON.parse(JSON.stringify(pages)),
13982
+ pages: JSON.parse(JSON.stringify(planPages)),
13350
13983
  globals: { [GlobalSlot.Header]: headers[i % headers.length], [GlobalSlot.Footer]: footers[i % footers.length] },
13351
- }));
13984
+ });
13985
+ const scenes = showcaseScenes().map((id, i) => plan(i, [{ key: 'home', name: 'Home', route: '/', isHome: true, inNav: false, sections: [sectionFor(id)] }], { ...input.design, animate: SCENE_LEVEL }));
13986
+ return [...Array.from({ length: count }, (_, i) => plan(i, pages, input.design)), ...scenes];
13352
13987
  }
13353
13988
 
13354
13989
  /**
@@ -15880,5 +16515,5 @@ function addStockCredits(footer, credits) {
15880
16515
  * Generated bundle index. Do not edit.
15881
16516
  */
15882
16517
 
15883
- export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_PART_TOKENS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiFeature, AiGenerationStage, AiKeyMode, AiLimit, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CONTENT_ROLE_MEANINGS, CREDITS_PER_USD, CardBindTarget, CheckSeverity, ComposeError, ComposeIssueCode, ContentFieldControl, ContentFieldType, ContentRole, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, DEFAULT_SITE_LOCALE, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, EntranceSide, FACT_KEYS, FIELD_TYPE_OF_CONTROL, FINAL_GENERATION_STAGES, FINDING_SEVERITY, GRAMMAR_TOO_LARGE_MESSAGE, GlobalSlot, HEBREW_PREFIXES, JSON_SCHEMA_BANNED_KEYWORDS, JsonSchemaShapeError, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PAGE_ARCHETYPES, PLAN_EDITS_ANSWER_SHAPES, PLAN_EDITS_PART_SCHEMA_NAMES, PLAN_EDIT_OP_PART, PLAN_EDIT_SHAPE, PLAN_EDIT_WIRE_KEYS, PLAN_PARTS, PLAN_PART_KEYS, PLAN_WIRE_DERIVED, PLAN_WIRE_PART_SCHEMA_NAMES, PLAN_WIRE_SHAPE, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PageDataKind, PathIssueCollector, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanChangeAction, PlanChangeKind, PlanDataSourceMode, PlanDataSourceType, PlanEditIssueCode, PlanEditOp, PlanEditsOutcome, PlanPart, PlanWireEntry, PlanWireShapeError, PlanWordIssueCode, PreflightRefusalCode, PublishRefusalCode, REQUIRED_CONTENT_ROLES, RelativeOp, SAMPLE_IMAGE_REF, SITE_CHECKS, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_LIBRARY, SITE_LOCALES, SITE_NEED_IDS, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_ARCHETYPES, SPEC_SITE_COPY_LENGTHS, SPEC_SITE_DENSITY_COPY, SPEC_SITE_FACTS, SPEC_SITE_LIBRARY, SPEC_SITE_LOCALES, SPEC_SITE_NEED_IDS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_REQUIRED_ROLES, SPEC_SITE_ROLES, SPEC_SITE_TEMPLATES, STOCK_FAMILIES, STOCK_FAMILY_INTENTS, STOCK_INTENT_ORDER, STOCK_INTENT_SUBJECTS, STOCK_ITEM_ASPECT, STOCK_MIN_KEPT, STOCK_PROVIDER_TERMS, STOCK_SUBJECT_WORDS, STRICT_SCHEMA_BUDGET, STRICT_SCHEMA_LIMITS, STUDIO_TEMPLATE, SiteBuildKind, SiteBuildStatus, SiteCheckId, SiteFindingCode, SiteLocale, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, StepState, StockIntent, StockOrientation, StockProviderId, StockReviewFlag, StockReviewVerdict, StockSlotKind, StockSubject, addBarItem, addStockCredits, aiStepParts, applyOwnPhotoGalleries, applyPlanEdits, applyStockItemPhotos, applyStockPhotos, archetypeIssues, aspectRatioOf, assertStyleSlots, assertValidSitePlan, auditSite, barIconForRoute, blocksPublish, buildKeys, buildStepFacts, builtHomePageId, composeNavHeader, composeSection, composeSite, contentTypePreviewFields, contentTypeToWire, copyLengthOf, costUsd, createSerializedNode, creditsOfUsd, dataSourceToWire, derivedDataSources, describePlanData, describeShapeKey, entranceAction, entranceInteraction, estimateStepCredits, expandPlanWire, expandWireContentType, expandWireDataSource, expandWireEdit, expandWireField, expandWirePage, expandWireSection, failedBuildStep, fieldToWire, findNavRoot, isActiveBuild, isNonEmptyString, isPlainObject, isRtlLocale, jsonAnyOf, jsonBoolean, jsonClosedObject, jsonInteger, jsonListOf, jsonOneOf, jsonSchemaKeywords, jsonSchemaObjects, jsonShapedObject, jsonText, modelCanDo, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, orientationOfRatio, pageToWire, parsePatternPath, parseSampleImageRef, pathAt, patternById, patternHasForm, patternLinkSlots, patternListGap, patternManifest, patternNeedsBinding, patternNodes, patternOptionalParts, patternRoleNeeds, patternScopes, patternSlotBudgets, patternSlots, patternTakesBinding, phoneMenuPages, planEditOps, planEditToWire, planEditWireGaps, planEditWireKeys, planEditWireOps, planEditWireShape, planEditsFromWire, planEditsJsonSchema, planEditsToWire, planEntrances, planFromTemplate, planNavShape, planOwnPhotos, planPartOfPath, planPartToWire, planStockPhotos, planToWire, planWireGaps, planWirePartJsonSchema, planWirePartShape, planWordIssues, publishRefusal, publishVerdict, recipeListBinds, releasedLayoutDefaults, removeBarItem, requiredAcknowledgements, requiredShapeKeys, roleField, routeMatches, routeParams, sampleImageRef, scoreStockPhoto, sectionEntrances, sectionPatternIds, sectionToWire, setStyleProps, shapeKeys, showcaseGlobals, showcasePages, showcasePlans, siteNavPages, slotBudget, stockCopyKey, stockCreditLine, stockCreditLines, stockCreditNode, stockCreditNodeId, stockFits, stockGroupOf, stockItemSlots, stockKept, stockPhotoRatio, stockPhotoSubject, stockPhotoUsable, stockPhotoWords, stockSlots, stockWord, stockWords, strictSchemaComplexity, strictSchemaRefusal, typicalStepTokens, validatePlanEdits, validateSitePlan, walkSerialized, wireContentTypeJsonSchema, wireDataSourceJsonSchema, wireFieldJsonSchema, wirePageJsonSchema, wireSectionJsonSchema, withDerivedSources, wordPattern, writtenTexts };
16518
+ export { ACTIVE_BUILD_STATUSES, AI_REFUSAL_NEXT, AI_REFUSAL_STATUS, AI_STEPS, AI_STEP_LABELS, AI_STEP_NEEDS, AI_STEP_PART_TOKENS, AI_STEP_TYPICAL_TOKENS, AiCallStatus, AiCapability, AiFeature, AiGenerationStage, AiKeyMode, AiLimit, AiNextKind, AiProviderId, AiRefusalCode, AiStep, BAR_ITEMS_MAX, BAR_ITEMS_MIN, BASELINE_ROLES, BUILD_STEPS, BaselineRole, BindScope, BuildNoticeCode, BuildStep, CONTENT_ROLE_MEANINGS, CREDITS_PER_USD, CardBindTarget, CheckSeverity, ComposeError, ComposeIssueCode, ContentFieldControl, ContentFieldType, ContentRole, ContentTypeAction, CreatedKind, DANGLING_LINK_CODES, DEFAULT_PHONE_MENU_BREAKPOINT, DEFAULT_SITE_LOCALE, ENTRANCE_EASING, ENTRANCE_ORIGIN_LOOK, ENTRANCE_TRIGGER, EntrancePart, EntranceSide, FACT_KEYS, FIELD_TYPE_OF_CONTROL, FINAL_GENERATION_STAGES, FINDING_SEVERITY, GRAMMAR_TOO_LARGE_MESSAGE, GlobalSlot, HEBREW_PREFIXES, JSON_SCHEMA_BANNED_KEYWORDS, JsonSchemaShapeError, KeptReason, NAV_PART_LABELS, NAV_SHAPE_COPY, NEUTRAL_STYLE_PROPS, NODE_BASELINES, NO_TOKENS, NavPagesSource, NavRole, NavShape, NavShapeError, PAGE_ARCHETYPES, PLAN_EDITS_ANSWER_SHAPES, PLAN_EDITS_PART_SCHEMA_NAMES, PLAN_EDIT_OP_PART, PLAN_EDIT_SHAPE, PLAN_EDIT_WIRE_KEYS, PLAN_PARTS, PLAN_PART_KEYS, PLAN_WIRE_DERIVED, PLAN_WIRE_PART_SCHEMA_NAMES, PLAN_WIRE_SHAPE, PRICING_PATTERN, PUBLISH_BLOCKING_PLACEHOLDERS, PageDataKind, PathIssueCollector, PatternDirective, PatternGlobalPosition, PatternOpens, PatternPlaceholder, PatternRecipe, PhoneMenuBreakpoint, PlaceholderKind, PlanChangeAction, PlanChangeKind, PlanDataSourceMode, PlanDataSourceType, PlanEditIssueCode, PlanEditOp, PlanEditsOutcome, PlanPart, PlanWireEntry, PlanWireShapeError, PlanWordIssueCode, PreflightRefusalCode, PublishRefusalCode, REQUIRED_CONTENT_ROLES, RelativeOp, SAMPLE_IMAGE_REF, SCENE_LEVEL, SCENE_OTHER_PAGES, SITE_CHECKS, SITE_FACT_LABELS, SITE_HEADER_PATTERN, SITE_LIBRARY, SITE_LOCALES, SITE_NEED_IDS, SITE_PATTERNS, SITE_PLAN_VERSION, SITE_TEMPLATES, SPEC_SITE_ARCHETYPES, SPEC_SITE_COPY_LENGTHS, SPEC_SITE_DENSITY_COPY, SPEC_SITE_FACTS, SPEC_SITE_LIBRARY, SPEC_SITE_LOCALES, SPEC_SITE_NEED_IDS, SPEC_SITE_PATTERNS, SPEC_SITE_PLAN_SHAPE, SPEC_SITE_REQUIRED_ROLES, SPEC_SITE_ROLES, SPEC_SITE_TEMPLATES, STOCK_FAMILIES, STOCK_FAMILY_INTENTS, STOCK_INTENT_ORDER, STOCK_INTENT_SUBJECTS, STOCK_ITEM_ASPECT, STOCK_MIN_KEPT, STOCK_PROVIDER_TERMS, STOCK_SUBJECT_WORDS, STRICT_SCHEMA_BUDGET, STRICT_SCHEMA_LIMITS, STUDIO_TEMPLATE, SiteBuildKind, SiteBuildStatus, SiteCheckId, SiteFindingCode, SiteLocale, SitePlanError, SitePlanIssueCode, SitePlanSourceKind, SiteTemplateError, SiteTemplateId, StepState, StockIntent, StockOrientation, StockProviderId, StockReviewFlag, StockReviewVerdict, StockSlotKind, StockSubject, addBarItem, addStockCredits, aiStepParts, applyOwnPhotoGalleries, applyPlanEdits, applyStockItemPhotos, applyStockPhotos, archetypeIssues, aspectRatioOf, assertStyleSlots, assertValidSitePlan, auditSite, barIconForRoute, blocksPublish, buildKeys, buildStepFacts, builtHomePageId, composeNavHeader, composeSection, composeSite, contentTypePreviewFields, contentTypeToWire, copyLengthOf, costUsd, createSerializedNode, creditsOfUsd, dataSourceToWire, derivedDataSources, describePlanData, describeShapeKey, entranceAction, entranceInteraction, estimateStepCredits, expandPlanWire, expandWireContentType, expandWireDataSource, expandWireEdit, expandWireField, expandWirePage, expandWireSection, failedBuildStep, fieldToWire, findNavRoot, isActiveBuild, isNonEmptyString, isPlainObject, isRtlLocale, jsonAnyOf, jsonBoolean, jsonClosedObject, jsonInteger, jsonListOf, jsonOneOf, jsonSchemaKeywords, jsonSchemaObjects, jsonShapedObject, jsonText, modelCanDo, moveBarItem, navPages, navShapeBreakpoint, navShapeOf, nextSourceOf, nodeBindPaths, orientationOfRatio, pageToWire, parsePatternPath, parseSampleImageRef, pathAt, patternById, patternHasForm, patternLinkSlots, patternListGap, patternManifest, patternNeedsBinding, patternNodes, patternOptionalParts, patternRoleNeeds, patternScopes, patternSlotBudgets, patternSlots, patternTakesBinding, phoneMenuPages, planEditOps, planEditToWire, planEditWireGaps, planEditWireKeys, planEditWireOps, planEditWireShape, planEditsFromWire, planEditsJsonSchema, planEditsToWire, planEntrances, planFromTemplate, planNavShape, planOwnPhotos, planPartOfPath, planPartToWire, planStockPhotos, planToWire, planWireGaps, planWirePartJsonSchema, planWirePartShape, planWordIssues, publishRefusal, publishVerdict, recipeListBinds, releasedLayoutDefaults, removeBarItem, requiredAcknowledgements, requiredShapeKeys, roleField, routeMatches, routeParams, sampleImageRef, scoreStockPhoto, sectionEntrances, sectionPatternIds, sectionToWire, setStyleProps, shapeKeys, showcaseGlobals, showcasePages, showcasePlans, showcaseScenes, siteNavPages, slotBudget, stockCopyKey, stockCreditLine, stockCreditLines, stockCreditNode, stockCreditNodeId, stockFits, stockGroupOf, stockItemSlots, stockKept, stockPhotoRatio, stockPhotoSubject, stockPhotoUsable, stockPhotoWords, stockSlots, stockWord, stockWords, strictSchemaComplexity, strictSchemaRefusal, typicalStepTokens, validatePlanEdits, validateSitePlan, walkSerialized, wireContentTypeJsonSchema, wireDataSourceJsonSchema, wireFieldJsonSchema, wirePageJsonSchema, wireSectionJsonSchema, withDerivedSources, wordPattern, writtenTexts };
15884
16519
  //# sourceMappingURL=vectoriox-iox-ui-generation-core.mjs.map