@vectoriox/iox-ui 5.76.1 → 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.
- package/design-core/index.d.ts +34 -4
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +34 -4
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +647 -12
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs +38 -3
- package/fesm2022/vectoriox-iox-ui-harness-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-media-core.mjs +11 -11
- package/fesm2022/vectoriox-iox-ui-media-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-scene-core.mjs +29 -1
- package/fesm2022/vectoriox-iox-ui-scene-core.mjs.map +1 -1
- package/generation-core/index.d.ts +411 -7
- package/harness-core/index.d.ts +37 -2
- package/media-core/index.d.ts +7 -5
- package/package.json +1 -1
- package/scene-core/index.d.ts +19 -2
- package/src/design-core/flavor-spec.generated.ts +34 -4
- package/src/generation-core/compose-site.ts +12 -2
- package/src/generation-core/patterns.ts +37 -4
- package/src/generation-core/serialized-node.ts +3 -0
- package/src/generation-core/showcase.ts +18 -7
- package/src/generation-core/site-spec.generated.ts +577 -0
- package/src/generation-core/validate-site-plan.ts +24 -2
- package/src/harness-core/business-types.ts +3 -0
- package/src/harness-core/harness-spec.generated.ts +32 -2
- package/src/harness-core/motion.ts +8 -1
- package/src/media-core/frames.ts +10 -11
- package/src/scene-core/scene-edit.ts +35 -0
|
@@ -417,6 +417,568 @@ export const SPEC_SITE_ARCHETYPES = {
|
|
|
417
417
|
} as const;
|
|
418
418
|
|
|
419
419
|
export const SPEC_SITE_PATTERNS = {
|
|
420
|
+
"hero.scene-depth": {
|
|
421
|
+
"family": "hero",
|
|
422
|
+
"scene": true,
|
|
423
|
+
"label": "Hero — a picture that opens as you scroll",
|
|
424
|
+
"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.",
|
|
425
|
+
"node": {
|
|
426
|
+
"t": "Section",
|
|
427
|
+
"es": "section",
|
|
428
|
+
"scheme": "inverse",
|
|
429
|
+
"role": "scene",
|
|
430
|
+
"lay": {
|
|
431
|
+
"position": "relative",
|
|
432
|
+
"display": "block",
|
|
433
|
+
"width": "100%",
|
|
434
|
+
"height": "300vh",
|
|
435
|
+
"padding": "0px"
|
|
436
|
+
},
|
|
437
|
+
"c": [
|
|
438
|
+
{
|
|
439
|
+
"t": "Container",
|
|
440
|
+
"role": "scene.stage",
|
|
441
|
+
"lay": {
|
|
442
|
+
"position": "sticky",
|
|
443
|
+
"top": "0px",
|
|
444
|
+
"display": "block",
|
|
445
|
+
"width": "100%",
|
|
446
|
+
"height": "100svh",
|
|
447
|
+
"overflow": "hidden",
|
|
448
|
+
"padding": "0px"
|
|
449
|
+
},
|
|
450
|
+
"c": [
|
|
451
|
+
{
|
|
452
|
+
"t": "Image",
|
|
453
|
+
"es": "media",
|
|
454
|
+
"ph": "image",
|
|
455
|
+
"lay": {
|
|
456
|
+
"position": "absolute",
|
|
457
|
+
"top": "0px",
|
|
458
|
+
"left": "0px",
|
|
459
|
+
"width": "100%",
|
|
460
|
+
"height": "100%",
|
|
461
|
+
"aspectRatio": "auto",
|
|
462
|
+
"borderRadius": "0px",
|
|
463
|
+
"objectFit": "cover"
|
|
464
|
+
},
|
|
465
|
+
"tracks": [
|
|
466
|
+
{
|
|
467
|
+
"prop": "scale",
|
|
468
|
+
"keys": [
|
|
469
|
+
[
|
|
470
|
+
0,
|
|
471
|
+
1.3
|
|
472
|
+
],
|
|
473
|
+
[
|
|
474
|
+
1,
|
|
475
|
+
1
|
|
476
|
+
]
|
|
477
|
+
]
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
"prop": "clip",
|
|
481
|
+
"from": "bottom",
|
|
482
|
+
"keys": [
|
|
483
|
+
[
|
|
484
|
+
0,
|
|
485
|
+
38
|
|
486
|
+
],
|
|
487
|
+
[
|
|
488
|
+
0.42,
|
|
489
|
+
100
|
|
490
|
+
]
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"t": "Container",
|
|
497
|
+
"es": "media-scrim",
|
|
498
|
+
"lay": {
|
|
499
|
+
"display": "flex",
|
|
500
|
+
"flexDirection": "column",
|
|
501
|
+
"gap": "14px",
|
|
502
|
+
"position": "absolute",
|
|
503
|
+
"left": "0px",
|
|
504
|
+
"bottom": "0px",
|
|
505
|
+
"width": "100%",
|
|
506
|
+
"padding": "48px 32px 56px 32px"
|
|
507
|
+
},
|
|
508
|
+
"c": [
|
|
509
|
+
{
|
|
510
|
+
"t": "Heading",
|
|
511
|
+
"es": "display",
|
|
512
|
+
"level": "h1",
|
|
513
|
+
"slot": "headline",
|
|
514
|
+
"max": 56,
|
|
515
|
+
"fromBusiness": "name",
|
|
516
|
+
"tracks": [
|
|
517
|
+
{
|
|
518
|
+
"prop": "y",
|
|
519
|
+
"keys": [
|
|
520
|
+
[
|
|
521
|
+
0,
|
|
522
|
+
0
|
|
523
|
+
],
|
|
524
|
+
[
|
|
525
|
+
1,
|
|
526
|
+
-6
|
|
527
|
+
]
|
|
528
|
+
]
|
|
529
|
+
}
|
|
530
|
+
]
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
"t": "Text",
|
|
534
|
+
"es": "lead",
|
|
535
|
+
"slot": "lead",
|
|
536
|
+
"max": 180,
|
|
537
|
+
"fromBusiness": "tagline",
|
|
538
|
+
"ph": "copy",
|
|
539
|
+
"tracks": [
|
|
540
|
+
{
|
|
541
|
+
"prop": "opacity",
|
|
542
|
+
"keys": [
|
|
543
|
+
[
|
|
544
|
+
0.45,
|
|
545
|
+
0
|
|
546
|
+
],
|
|
547
|
+
[
|
|
548
|
+
0.6,
|
|
549
|
+
1
|
|
550
|
+
]
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"t": "ButtonBlock",
|
|
557
|
+
"es": "button-primary",
|
|
558
|
+
"href": "/contact",
|
|
559
|
+
"slot": "cta",
|
|
560
|
+
"max": 24,
|
|
561
|
+
"text": "Get in touch",
|
|
562
|
+
"tracks": [
|
|
563
|
+
{
|
|
564
|
+
"prop": "opacity",
|
|
565
|
+
"keys": [
|
|
566
|
+
[
|
|
567
|
+
0.5,
|
|
568
|
+
0
|
|
569
|
+
],
|
|
570
|
+
[
|
|
571
|
+
0.65,
|
|
572
|
+
1
|
|
573
|
+
]
|
|
574
|
+
]
|
|
575
|
+
}
|
|
576
|
+
]
|
|
577
|
+
}
|
|
578
|
+
]
|
|
579
|
+
}
|
|
580
|
+
]
|
|
581
|
+
}
|
|
582
|
+
]
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
"story.scene-chapters": {
|
|
586
|
+
"family": "story",
|
|
587
|
+
"scene": true,
|
|
588
|
+
"label": "Story — three chapters on one held stage",
|
|
589
|
+
"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.",
|
|
590
|
+
"node": {
|
|
591
|
+
"t": "Section",
|
|
592
|
+
"es": "section",
|
|
593
|
+
"scheme": "inverse",
|
|
594
|
+
"role": "scene",
|
|
595
|
+
"lay": {
|
|
596
|
+
"position": "relative",
|
|
597
|
+
"display": "block",
|
|
598
|
+
"width": "100%",
|
|
599
|
+
"height": "400vh",
|
|
600
|
+
"padding": "0px"
|
|
601
|
+
},
|
|
602
|
+
"c": [
|
|
603
|
+
{
|
|
604
|
+
"t": "Container",
|
|
605
|
+
"role": "scene.stage",
|
|
606
|
+
"lay": {
|
|
607
|
+
"position": "sticky",
|
|
608
|
+
"top": "0px",
|
|
609
|
+
"display": "block",
|
|
610
|
+
"width": "100%",
|
|
611
|
+
"height": "100svh",
|
|
612
|
+
"overflow": "hidden",
|
|
613
|
+
"padding": "0px"
|
|
614
|
+
},
|
|
615
|
+
"c": [
|
|
616
|
+
{
|
|
617
|
+
"t": "Image",
|
|
618
|
+
"es": "media",
|
|
619
|
+
"ph": "image",
|
|
620
|
+
"lay": {
|
|
621
|
+
"position": "absolute",
|
|
622
|
+
"top": "0px",
|
|
623
|
+
"left": "0px",
|
|
624
|
+
"width": "100%",
|
|
625
|
+
"height": "100%",
|
|
626
|
+
"aspectRatio": "auto",
|
|
627
|
+
"borderRadius": "0px",
|
|
628
|
+
"objectFit": "cover"
|
|
629
|
+
},
|
|
630
|
+
"tracks": [
|
|
631
|
+
{
|
|
632
|
+
"prop": "scale",
|
|
633
|
+
"keys": [
|
|
634
|
+
[
|
|
635
|
+
0,
|
|
636
|
+
1.12
|
|
637
|
+
],
|
|
638
|
+
[
|
|
639
|
+
1,
|
|
640
|
+
1
|
|
641
|
+
]
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
]
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"t": "Container",
|
|
648
|
+
"es": "media-scrim",
|
|
649
|
+
"lay": {
|
|
650
|
+
"position": "absolute",
|
|
651
|
+
"left": "0px",
|
|
652
|
+
"bottom": "0px",
|
|
653
|
+
"width": "100%",
|
|
654
|
+
"height": "62%",
|
|
655
|
+
"padding": "0px"
|
|
656
|
+
},
|
|
657
|
+
"c": [
|
|
658
|
+
{
|
|
659
|
+
"t": "Container",
|
|
660
|
+
"es": "box",
|
|
661
|
+
"lay": {
|
|
662
|
+
"display": "flex",
|
|
663
|
+
"flexDirection": "column",
|
|
664
|
+
"gap": "12px",
|
|
665
|
+
"position": "absolute",
|
|
666
|
+
"left": "32px",
|
|
667
|
+
"right": "32px",
|
|
668
|
+
"bottom": "56px",
|
|
669
|
+
"maxWidth": "640px"
|
|
670
|
+
},
|
|
671
|
+
"tracks": [
|
|
672
|
+
{
|
|
673
|
+
"prop": "opacity",
|
|
674
|
+
"keys": [
|
|
675
|
+
[
|
|
676
|
+
0,
|
|
677
|
+
1
|
|
678
|
+
],
|
|
679
|
+
[
|
|
680
|
+
0.26,
|
|
681
|
+
1
|
|
682
|
+
],
|
|
683
|
+
[
|
|
684
|
+
0.33,
|
|
685
|
+
0
|
|
686
|
+
]
|
|
687
|
+
]
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"prop": "y",
|
|
691
|
+
"keys": [
|
|
692
|
+
[
|
|
693
|
+
0.26,
|
|
694
|
+
0
|
|
695
|
+
],
|
|
696
|
+
[
|
|
697
|
+
0.33,
|
|
698
|
+
-6
|
|
699
|
+
]
|
|
700
|
+
]
|
|
701
|
+
}
|
|
702
|
+
],
|
|
703
|
+
"c": [
|
|
704
|
+
{
|
|
705
|
+
"t": "Text",
|
|
706
|
+
"es": "eyebrow",
|
|
707
|
+
"slot": "eyebrow",
|
|
708
|
+
"max": 32,
|
|
709
|
+
"ph": "copy",
|
|
710
|
+
"text": "How we work"
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"t": "Heading",
|
|
714
|
+
"es": "h2",
|
|
715
|
+
"level": "h2",
|
|
716
|
+
"slot": "title",
|
|
717
|
+
"max": 52,
|
|
718
|
+
"ph": "copy",
|
|
719
|
+
"text": "It starts with a conversation"
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"t": "Text",
|
|
723
|
+
"es": "lead",
|
|
724
|
+
"slot": "text",
|
|
725
|
+
"max": 180,
|
|
726
|
+
"ph": "copy",
|
|
727
|
+
"text": "What the first step is, in a sentence or two."
|
|
728
|
+
}
|
|
729
|
+
]
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
"t": "Container",
|
|
733
|
+
"es": "box",
|
|
734
|
+
"lay": {
|
|
735
|
+
"display": "flex",
|
|
736
|
+
"flexDirection": "column",
|
|
737
|
+
"gap": "12px",
|
|
738
|
+
"position": "absolute",
|
|
739
|
+
"left": "32px",
|
|
740
|
+
"right": "32px",
|
|
741
|
+
"bottom": "56px",
|
|
742
|
+
"maxWidth": "640px"
|
|
743
|
+
},
|
|
744
|
+
"tracks": [
|
|
745
|
+
{
|
|
746
|
+
"prop": "opacity",
|
|
747
|
+
"keys": [
|
|
748
|
+
[
|
|
749
|
+
0.33,
|
|
750
|
+
0
|
|
751
|
+
],
|
|
752
|
+
[
|
|
753
|
+
0.4,
|
|
754
|
+
1
|
|
755
|
+
],
|
|
756
|
+
[
|
|
757
|
+
0.6,
|
|
758
|
+
1
|
|
759
|
+
],
|
|
760
|
+
[
|
|
761
|
+
0.67,
|
|
762
|
+
0
|
|
763
|
+
]
|
|
764
|
+
]
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"prop": "y",
|
|
768
|
+
"keys": [
|
|
769
|
+
[
|
|
770
|
+
0.33,
|
|
771
|
+
6
|
|
772
|
+
],
|
|
773
|
+
[
|
|
774
|
+
0.4,
|
|
775
|
+
0
|
|
776
|
+
],
|
|
777
|
+
[
|
|
778
|
+
0.6,
|
|
779
|
+
0
|
|
780
|
+
],
|
|
781
|
+
[
|
|
782
|
+
0.67,
|
|
783
|
+
-6
|
|
784
|
+
]
|
|
785
|
+
]
|
|
786
|
+
}
|
|
787
|
+
],
|
|
788
|
+
"c": [
|
|
789
|
+
{
|
|
790
|
+
"t": "Heading",
|
|
791
|
+
"es": "h2",
|
|
792
|
+
"level": "h2",
|
|
793
|
+
"slot": "title2",
|
|
794
|
+
"max": 52,
|
|
795
|
+
"ph": "copy",
|
|
796
|
+
"text": "Then we make it"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"t": "Text",
|
|
800
|
+
"es": "lead",
|
|
801
|
+
"slot": "text2",
|
|
802
|
+
"max": 180,
|
|
803
|
+
"ph": "copy",
|
|
804
|
+
"text": "What the middle of the work is, in a sentence or two."
|
|
805
|
+
}
|
|
806
|
+
]
|
|
807
|
+
},
|
|
808
|
+
{
|
|
809
|
+
"t": "Container",
|
|
810
|
+
"es": "box",
|
|
811
|
+
"lay": {
|
|
812
|
+
"display": "flex",
|
|
813
|
+
"flexDirection": "column",
|
|
814
|
+
"gap": "12px",
|
|
815
|
+
"position": "absolute",
|
|
816
|
+
"left": "32px",
|
|
817
|
+
"right": "32px",
|
|
818
|
+
"bottom": "56px",
|
|
819
|
+
"maxWidth": "640px"
|
|
820
|
+
},
|
|
821
|
+
"tracks": [
|
|
822
|
+
{
|
|
823
|
+
"prop": "opacity",
|
|
824
|
+
"keys": [
|
|
825
|
+
[
|
|
826
|
+
0.67,
|
|
827
|
+
0
|
|
828
|
+
],
|
|
829
|
+
[
|
|
830
|
+
0.74,
|
|
831
|
+
1
|
|
832
|
+
],
|
|
833
|
+
[
|
|
834
|
+
1,
|
|
835
|
+
1
|
|
836
|
+
]
|
|
837
|
+
]
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
"prop": "y",
|
|
841
|
+
"keys": [
|
|
842
|
+
[
|
|
843
|
+
0.67,
|
|
844
|
+
6
|
|
845
|
+
],
|
|
846
|
+
[
|
|
847
|
+
0.74,
|
|
848
|
+
0
|
|
849
|
+
]
|
|
850
|
+
]
|
|
851
|
+
}
|
|
852
|
+
],
|
|
853
|
+
"c": [
|
|
854
|
+
{
|
|
855
|
+
"t": "Heading",
|
|
856
|
+
"es": "h2",
|
|
857
|
+
"level": "h2",
|
|
858
|
+
"slot": "title3",
|
|
859
|
+
"max": 52,
|
|
860
|
+
"ph": "copy",
|
|
861
|
+
"text": "And it is yours"
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
"t": "Text",
|
|
865
|
+
"es": "lead",
|
|
866
|
+
"slot": "text3",
|
|
867
|
+
"max": 180,
|
|
868
|
+
"ph": "copy",
|
|
869
|
+
"text": "What the client leaves with, in a sentence or two."
|
|
870
|
+
}
|
|
871
|
+
]
|
|
872
|
+
}
|
|
873
|
+
]
|
|
874
|
+
}
|
|
875
|
+
]
|
|
876
|
+
}
|
|
877
|
+
]
|
|
878
|
+
}
|
|
879
|
+
},
|
|
880
|
+
"proof.scene-words": {
|
|
881
|
+
"family": "proof",
|
|
882
|
+
"scene": true,
|
|
883
|
+
"label": "A testimonial that lights word by word",
|
|
884
|
+
"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.",
|
|
885
|
+
"node": {
|
|
886
|
+
"t": "Section",
|
|
887
|
+
"es": "section",
|
|
888
|
+
"role": "scene",
|
|
889
|
+
"lay": {
|
|
890
|
+
"position": "relative",
|
|
891
|
+
"display": "block",
|
|
892
|
+
"width": "100%",
|
|
893
|
+
"height": "250vh",
|
|
894
|
+
"padding": "0px"
|
|
895
|
+
},
|
|
896
|
+
"c": [
|
|
897
|
+
{
|
|
898
|
+
"t": "Container",
|
|
899
|
+
"role": "scene.stage",
|
|
900
|
+
"lay": {
|
|
901
|
+
"position": "sticky",
|
|
902
|
+
"top": "0px",
|
|
903
|
+
"display": "flex",
|
|
904
|
+
"width": "100%",
|
|
905
|
+
"height": "100svh",
|
|
906
|
+
"overflow": "hidden",
|
|
907
|
+
"padding": "32px 32px 32px 32px",
|
|
908
|
+
"alignItems": "center",
|
|
909
|
+
"justifyContent": "center"
|
|
910
|
+
},
|
|
911
|
+
"c": [
|
|
912
|
+
{
|
|
913
|
+
"t": "Container",
|
|
914
|
+
"es": "box",
|
|
915
|
+
"lay": {
|
|
916
|
+
"display": "flex",
|
|
917
|
+
"flexDirection": "column",
|
|
918
|
+
"gap": "20px",
|
|
919
|
+
"maxWidth": "900px",
|
|
920
|
+
"width": "100%",
|
|
921
|
+
"margin": "0px auto 0px auto"
|
|
922
|
+
},
|
|
923
|
+
"c": [
|
|
924
|
+
{
|
|
925
|
+
"t": "Text",
|
|
926
|
+
"es": "eyebrow",
|
|
927
|
+
"slot": "eyebrow",
|
|
928
|
+
"max": 32,
|
|
929
|
+
"ph": "copy",
|
|
930
|
+
"text": "What clients say"
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
"t": "Heading",
|
|
934
|
+
"es": "h2",
|
|
935
|
+
"level": "h2",
|
|
936
|
+
"ph": "copy",
|
|
937
|
+
"text": "A sentence a client actually said, in their own words.",
|
|
938
|
+
"tracks": [
|
|
939
|
+
{
|
|
940
|
+
"prop": "words",
|
|
941
|
+
"keys": [
|
|
942
|
+
[
|
|
943
|
+
0.08,
|
|
944
|
+
0
|
|
945
|
+
],
|
|
946
|
+
[
|
|
947
|
+
0.7,
|
|
948
|
+
100
|
|
949
|
+
]
|
|
950
|
+
]
|
|
951
|
+
}
|
|
952
|
+
]
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
"t": "Text",
|
|
956
|
+
"es": "small",
|
|
957
|
+
"ph": "copy",
|
|
958
|
+
"text": "[Client name] · [Project, city]",
|
|
959
|
+
"tracks": [
|
|
960
|
+
{
|
|
961
|
+
"prop": "opacity",
|
|
962
|
+
"keys": [
|
|
963
|
+
[
|
|
964
|
+
0.7,
|
|
965
|
+
0
|
|
966
|
+
],
|
|
967
|
+
[
|
|
968
|
+
0.82,
|
|
969
|
+
1
|
|
970
|
+
]
|
|
971
|
+
]
|
|
972
|
+
}
|
|
973
|
+
]
|
|
974
|
+
}
|
|
975
|
+
]
|
|
976
|
+
}
|
|
977
|
+
]
|
|
978
|
+
}
|
|
979
|
+
]
|
|
980
|
+
}
|
|
981
|
+
},
|
|
420
982
|
"nav.inline-cta": {
|
|
421
983
|
"family": "nav",
|
|
422
984
|
"label": "Navigation bar",
|
|
@@ -4924,6 +5486,11 @@ export const SPEC_SITE_LIBRARY = [
|
|
|
4924
5486
|
"family": "hero",
|
|
4925
5487
|
"composed": true
|
|
4926
5488
|
},
|
|
5489
|
+
{
|
|
5490
|
+
"id": "hero.scene-depth",
|
|
5491
|
+
"family": "hero",
|
|
5492
|
+
"composed": true
|
|
5493
|
+
},
|
|
4927
5494
|
{
|
|
4928
5495
|
"id": "proof.logo-strip",
|
|
4929
5496
|
"family": "proof",
|
|
@@ -4944,6 +5511,11 @@ export const SPEC_SITE_LIBRARY = [
|
|
|
4944
5511
|
"family": "proof",
|
|
4945
5512
|
"composed": true
|
|
4946
5513
|
},
|
|
5514
|
+
{
|
|
5515
|
+
"id": "proof.scene-words",
|
|
5516
|
+
"family": "proof",
|
|
5517
|
+
"composed": true
|
|
5518
|
+
},
|
|
4947
5519
|
{
|
|
4948
5520
|
"id": "feature.triad",
|
|
4949
5521
|
"family": "feature",
|
|
@@ -4999,6 +5571,11 @@ export const SPEC_SITE_LIBRARY = [
|
|
|
4999
5571
|
"family": "story",
|
|
5000
5572
|
"composed": true
|
|
5001
5573
|
},
|
|
5574
|
+
{
|
|
5575
|
+
"id": "story.scene-chapters",
|
|
5576
|
+
"family": "story",
|
|
5577
|
+
"composed": true
|
|
5578
|
+
},
|
|
5002
5579
|
{
|
|
5003
5580
|
"id": "cta.banner",
|
|
5004
5581
|
"family": "cta",
|
|
@@ -4,8 +4,7 @@ import { SEO_DESCRIPTION_MAX, SEO_TITLE_MAX } from '@vectoriox/iox-ui/seo-core';
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
BindScope, patternById, patternHasForm, patternLinkSlots, patternNeedsBinding, patternOptionalParts, patternRoleNeeds, patternTakesBinding, patternScopes,
|
|
7
|
-
patternSlots, PatternGlobalPosition, slotBudget,
|
|
8
|
-
} from './patterns';
|
|
7
|
+
patternSlots, PatternGlobalPosition, slotBudget, SCENE_LEVEL, SCENE_OTHER_PAGES } from './patterns';
|
|
9
8
|
import { ContentFieldControl, FIELD_TYPE_OF_CONTROL,
|
|
10
9
|
FACT_KEYS, GlobalSlot, PAGE_ARCHETYPES, SITE_NEED_IDS, PlanDataSourceMode, PlanDataSourceType, RelativeOp, REQUIRED_CONTENT_ROLES, SitePlan, SitePlanSourceKind,
|
|
11
10
|
SITE_LOCALES, SITE_PLAN_VERSION,
|
|
@@ -70,6 +69,9 @@ export enum SitePlanIssueCode {
|
|
|
70
69
|
UnknownNeed = 'unknown-need',
|
|
71
70
|
/** A page key that is a global slot's name (`header`, `footer`): its sections' ids would be the global's. */
|
|
72
71
|
ReservedPageKey = 'reserved-page-key',
|
|
72
|
+
/** SC6: a Scene below How animated Expressive, a second Scene on a page, or Scenes on more than the home page and
|
|
73
|
+
* one other — the pages answer by choosing another pattern. */
|
|
74
|
+
SceneBudget = 'scene-budget',
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export type SitePlanIssue = PathIssue<SitePlanIssueCode>;
|
|
@@ -455,6 +457,25 @@ function validatePages(c: Collector, list: unknown[], types: Map<string, Content
|
|
|
455
457
|
}
|
|
456
458
|
|
|
457
459
|
|
|
460
|
+
/** SC6 (premium-sites plan, APPROVED 2026-11-05): who may hold the page — Scenes only at Expressive, one per page, on the
|
|
461
|
+
* home page and at most one other. A Scene past that is an issue at its pattern, so the pages choose another. */
|
|
462
|
+
function validateScenes(c: Collector, pages: unknown[], animate: string | null): void {
|
|
463
|
+
let otherPages = 0;
|
|
464
|
+
pages.forEach((raw, i) => {
|
|
465
|
+
if (!isObject(raw) || !Array.isArray(raw['sections'])) return;
|
|
466
|
+
let onPage = 0;
|
|
467
|
+
const counted = raw['isHome'] === true;
|
|
468
|
+
raw['sections'].forEach((s, j) => {
|
|
469
|
+
const pattern = isObject(s) && typeof s['pattern'] === 'string' ? patternById(s['pattern']) : null;
|
|
470
|
+
if (!pattern?.scene) return;
|
|
471
|
+
const at = `pages[${i}].sections[${j}].pattern`;
|
|
472
|
+
if (animate !== SCENE_LEVEL) 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'})`);
|
|
473
|
+
if (++onPage > 1) return c.add(SitePlanIssueCode.SceneBudget, at, 'one Scene per page — choose a section that does not hold the page');
|
|
474
|
+
if (!counted && onPage === 1 && ++otherPages > SCENE_OTHER_PAGES) 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`);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
458
479
|
function validatePageSeo(c: Collector, seo: unknown, path: string): void {
|
|
459
480
|
if (seo === undefined) return;
|
|
460
481
|
if (!isObject(seo)) return c.add(SitePlanIssueCode.Shape, path, 'must be an object');
|
|
@@ -501,6 +522,7 @@ export function validateSitePlan(plan: unknown): SitePlanValidation {
|
|
|
501
522
|
const design = isObject(plan['design']) ? plan['design'] : {};
|
|
502
523
|
validatePages(c, c.array(plan, 'pages', ''), types, sources, typeof design['density'] === 'string' ? design['density'] : null);
|
|
503
524
|
validateGlobals(c, plan['globals']);
|
|
525
|
+
validateScenes(c, c.array(plan, 'pages', ''), typeof design['animate'] === 'string' ? design['animate'] : null);
|
|
504
526
|
return { valid: c.issues.length === 0, issues: c.issues };
|
|
505
527
|
}
|
|
506
528
|
|
|
@@ -111,6 +111,9 @@ export interface BusinessType {
|
|
|
111
111
|
readonly motion: MotionId;
|
|
112
112
|
/** How its site usually scrolls, how animated it is and what plays between pages (rev 3.1). */
|
|
113
113
|
readonly moves: Readonly<DesignMotion>;
|
|
114
|
+
/** SC6: the most How animated a GENERATED site of this type may start at (`motionFor`). A Scene needs Expressive,
|
|
115
|
+
* so a type capped below it never gets one. Binds generated output only — the owner may choose any level. */
|
|
116
|
+
readonly ceiling: DesignMotion['animate'];
|
|
114
117
|
readonly imagery: string;
|
|
115
118
|
readonly pages: ReadonlyArray<string>;
|
|
116
119
|
/** The needs its page set implies, in page order (derived from `pages` at contract build). */
|