@circadian/sol 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { l as lerpHex, n as useSolarTheme, r as SKINS, t as SolarThemeProvider } from "./solar-theme-provider-BWHxbh0l.js";
2
- import { useEffect, useLayoutEffect, useMemo, useState } from "react";
3
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { l as lerpColor, n as useSolarTheme, r as SKINS, t as SolarThemeProvider, u as lerpHex } from "./solar-theme-provider-CSustvmw.js";
2
+ import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
4
 
5
5
  //#region src/widgets/solar-widget.shell.tsx
6
6
  const PALETTES = SKINS.foundry.widgetPalettes;
@@ -320,5 +320,1037 @@ function CompactWidget({ design: designOverride, overridePhase, time, location =
320
320
  }
321
321
 
322
322
  //#endregion
323
- export { CompactWidget, SolarThemeProvider, SolarWidget, useSolarTheme };
323
+ //#region src/shared/shader-motion-profiles.tsx
324
+ const UNIVERSAL_PHASE_MOTION = {
325
+ midnight: {
326
+ distortion: .2,
327
+ swirl: .04,
328
+ speed: .1,
329
+ grainOverlay: .18
330
+ },
331
+ night: {
332
+ distortion: .28,
333
+ swirl: .06,
334
+ speed: .15,
335
+ grainOverlay: .15
336
+ },
337
+ dawn: {
338
+ distortion: .52,
339
+ swirl: .14,
340
+ speed: .26,
341
+ grainOverlay: .1
342
+ },
343
+ sunrise: {
344
+ distortion: .68,
345
+ swirl: .22,
346
+ speed: .38,
347
+ grainOverlay: .07
348
+ },
349
+ morning: {
350
+ distortion: .54,
351
+ swirl: .13,
352
+ speed: .5,
353
+ grainOverlay: .05
354
+ },
355
+ "solar-noon": {
356
+ distortion: .36,
357
+ swirl: .07,
358
+ speed: .64,
359
+ grainOverlay: .04
360
+ },
361
+ afternoon: {
362
+ distortion: .44,
363
+ swirl: .1,
364
+ speed: .5,
365
+ grainOverlay: .05
366
+ },
367
+ sunset: {
368
+ distortion: .72,
369
+ swirl: .3,
370
+ speed: .34,
371
+ grainOverlay: .08
372
+ },
373
+ dusk: {
374
+ distortion: .44,
375
+ swirl: .18,
376
+ speed: .2,
377
+ grainOverlay: .14
378
+ }
379
+ };
380
+ const VOID_MOTION = {
381
+ midnight: {
382
+ distortion: .08,
383
+ swirl: .01,
384
+ speed: .04,
385
+ grainOverlay: .28
386
+ },
387
+ night: {
388
+ distortion: .1,
389
+ swirl: .02,
390
+ speed: .05,
391
+ grainOverlay: .22
392
+ },
393
+ dawn: {
394
+ distortion: .14,
395
+ swirl: .03,
396
+ speed: .07,
397
+ grainOverlay: .16
398
+ },
399
+ sunrise: {
400
+ distortion: .16,
401
+ swirl: .04,
402
+ speed: .09,
403
+ grainOverlay: .12
404
+ },
405
+ morning: {
406
+ distortion: .14,
407
+ swirl: .03,
408
+ speed: .1,
409
+ grainOverlay: .1
410
+ },
411
+ "solar-noon": {
412
+ distortion: .1,
413
+ swirl: .02,
414
+ speed: .12,
415
+ grainOverlay: .08
416
+ },
417
+ afternoon: {
418
+ distortion: .12,
419
+ swirl: .03,
420
+ speed: .1,
421
+ grainOverlay: .1
422
+ },
423
+ sunset: {
424
+ distortion: .18,
425
+ swirl: .05,
426
+ speed: .08,
427
+ grainOverlay: .14
428
+ },
429
+ dusk: {
430
+ distortion: .12,
431
+ swirl: .03,
432
+ speed: .06,
433
+ grainOverlay: .2
434
+ }
435
+ };
436
+ const PARCHMENT_MOTION = {
437
+ midnight: {
438
+ distortion: 0,
439
+ swirl: 0,
440
+ speed: 0,
441
+ grainOverlay: .06
442
+ },
443
+ night: {
444
+ distortion: 0,
445
+ swirl: 0,
446
+ speed: 0,
447
+ grainOverlay: .05
448
+ },
449
+ dawn: {
450
+ distortion: 0,
451
+ swirl: 0,
452
+ speed: 0,
453
+ grainOverlay: .04
454
+ },
455
+ sunrise: {
456
+ distortion: 0,
457
+ swirl: 0,
458
+ speed: 0,
459
+ grainOverlay: .03
460
+ },
461
+ morning: {
462
+ distortion: 0,
463
+ swirl: 0,
464
+ speed: 0,
465
+ grainOverlay: .02
466
+ },
467
+ "solar-noon": {
468
+ distortion: 0,
469
+ swirl: 0,
470
+ speed: 0,
471
+ grainOverlay: .02
472
+ },
473
+ afternoon: {
474
+ distortion: 0,
475
+ swirl: 0,
476
+ speed: 0,
477
+ grainOverlay: .02
478
+ },
479
+ sunset: {
480
+ distortion: 0,
481
+ swirl: 0,
482
+ speed: 0,
483
+ grainOverlay: .03
484
+ },
485
+ dusk: {
486
+ distortion: 0,
487
+ swirl: 0,
488
+ speed: 0,
489
+ grainOverlay: .05
490
+ }
491
+ };
492
+ const SIGNAL_MOTION = {
493
+ midnight: {
494
+ distortion: .06,
495
+ swirl: 0,
496
+ speed: .06,
497
+ grainOverlay: .32
498
+ },
499
+ night: {
500
+ distortion: .06,
501
+ swirl: 0,
502
+ speed: .06,
503
+ grainOverlay: .3
504
+ },
505
+ dawn: {
506
+ distortion: .08,
507
+ swirl: .01,
508
+ speed: .08,
509
+ grainOverlay: .26
510
+ },
511
+ sunrise: {
512
+ distortion: .08,
513
+ swirl: .01,
514
+ speed: .08,
515
+ grainOverlay: .24
516
+ },
517
+ morning: {
518
+ distortion: .1,
519
+ swirl: .01,
520
+ speed: .1,
521
+ grainOverlay: .22
522
+ },
523
+ "solar-noon": {
524
+ distortion: .1,
525
+ swirl: .01,
526
+ speed: .1,
527
+ grainOverlay: .2
528
+ },
529
+ afternoon: {
530
+ distortion: .1,
531
+ swirl: .01,
532
+ speed: .1,
533
+ grainOverlay: .22
534
+ },
535
+ sunset: {
536
+ distortion: .08,
537
+ swirl: .01,
538
+ speed: .08,
539
+ grainOverlay: .26
540
+ },
541
+ dusk: {
542
+ distortion: .06,
543
+ swirl: 0,
544
+ speed: .06,
545
+ grainOverlay: .3
546
+ }
547
+ };
548
+ const MERIDIAN_MOTION = {
549
+ midnight: {
550
+ distortion: .12,
551
+ swirl: .02,
552
+ speed: .08,
553
+ grainOverlay: .08
554
+ },
555
+ night: {
556
+ distortion: .14,
557
+ swirl: .03,
558
+ speed: .1,
559
+ grainOverlay: .07
560
+ },
561
+ dawn: {
562
+ distortion: .24,
563
+ swirl: .06,
564
+ speed: .14,
565
+ grainOverlay: .05
566
+ },
567
+ sunrise: {
568
+ distortion: .3,
569
+ swirl: .09,
570
+ speed: .2,
571
+ grainOverlay: .04
572
+ },
573
+ morning: {
574
+ distortion: .26,
575
+ swirl: .06,
576
+ speed: .26,
577
+ grainOverlay: .03
578
+ },
579
+ "solar-noon": {
580
+ distortion: .18,
581
+ swirl: .04,
582
+ speed: .32,
583
+ grainOverlay: .02
584
+ },
585
+ afternoon: {
586
+ distortion: .22,
587
+ swirl: .05,
588
+ speed: .26,
589
+ grainOverlay: .03
590
+ },
591
+ sunset: {
592
+ distortion: .32,
593
+ swirl: .12,
594
+ speed: .18,
595
+ grainOverlay: .04
596
+ },
597
+ dusk: {
598
+ distortion: .22,
599
+ swirl: .08,
600
+ speed: .12,
601
+ grainOverlay: .06
602
+ }
603
+ };
604
+ const SUNDIAL_MOTION = {
605
+ midnight: {
606
+ distortion: .18,
607
+ swirl: .03,
608
+ speed: .07,
609
+ grainOverlay: .2
610
+ },
611
+ night: {
612
+ distortion: .2,
613
+ swirl: .04,
614
+ speed: .08,
615
+ grainOverlay: .18
616
+ },
617
+ dawn: {
618
+ distortion: .28,
619
+ swirl: .07,
620
+ speed: .14,
621
+ grainOverlay: .12
622
+ },
623
+ sunrise: {
624
+ distortion: .34,
625
+ swirl: .1,
626
+ speed: .18,
627
+ grainOverlay: .09
628
+ },
629
+ morning: {
630
+ distortion: .28,
631
+ swirl: .06,
632
+ speed: .22,
633
+ grainOverlay: .08
634
+ },
635
+ "solar-noon": {
636
+ distortion: .2,
637
+ swirl: .04,
638
+ speed: .28,
639
+ grainOverlay: .06
640
+ },
641
+ afternoon: {
642
+ distortion: .24,
643
+ swirl: .05,
644
+ speed: .22,
645
+ grainOverlay: .07
646
+ },
647
+ sunset: {
648
+ distortion: .36,
649
+ swirl: .14,
650
+ speed: .16,
651
+ grainOverlay: .1
652
+ },
653
+ dusk: {
654
+ distortion: .24,
655
+ swirl: .08,
656
+ speed: .1,
657
+ grainOverlay: .14
658
+ }
659
+ };
660
+ const PAPER_MOTION = {
661
+ midnight: {
662
+ distortion: .22,
663
+ swirl: .04,
664
+ speed: .1,
665
+ grainOverlay: .22
666
+ },
667
+ night: {
668
+ distortion: .26,
669
+ swirl: .06,
670
+ speed: .14,
671
+ grainOverlay: .18
672
+ },
673
+ dawn: {
674
+ distortion: .38,
675
+ swirl: .1,
676
+ speed: .22,
677
+ grainOverlay: .12
678
+ },
679
+ sunrise: {
680
+ distortion: .46,
681
+ swirl: .14,
682
+ speed: .3,
683
+ grainOverlay: .09
684
+ },
685
+ morning: {
686
+ distortion: .38,
687
+ swirl: .09,
688
+ speed: .38,
689
+ grainOverlay: .07
690
+ },
691
+ "solar-noon": {
692
+ distortion: .28,
693
+ swirl: .05,
694
+ speed: .46,
695
+ grainOverlay: .05
696
+ },
697
+ afternoon: {
698
+ distortion: .34,
699
+ swirl: .07,
700
+ speed: .38,
701
+ grainOverlay: .06
702
+ },
703
+ sunset: {
704
+ distortion: .5,
705
+ swirl: .2,
706
+ speed: .26,
707
+ grainOverlay: .1
708
+ },
709
+ dusk: {
710
+ distortion: .34,
711
+ swirl: .12,
712
+ speed: .16,
713
+ grainOverlay: .14
714
+ }
715
+ };
716
+ const FOUNDRY_MOTION = {
717
+ midnight: {
718
+ distortion: .22,
719
+ swirl: .04,
720
+ speed: .1,
721
+ grainOverlay: .16
722
+ },
723
+ night: {
724
+ distortion: .3,
725
+ swirl: .07,
726
+ speed: .16,
727
+ grainOverlay: .13
728
+ },
729
+ dawn: {
730
+ distortion: .55,
731
+ swirl: .16,
732
+ speed: .28,
733
+ grainOverlay: .09
734
+ },
735
+ sunrise: {
736
+ distortion: .7,
737
+ swirl: .26,
738
+ speed: .4,
739
+ grainOverlay: .06
740
+ },
741
+ morning: {
742
+ distortion: .56,
743
+ swirl: .15,
744
+ speed: .52,
745
+ grainOverlay: .04
746
+ },
747
+ "solar-noon": {
748
+ distortion: .38,
749
+ swirl: .08,
750
+ speed: .66,
751
+ grainOverlay: .03
752
+ },
753
+ afternoon: {
754
+ distortion: .46,
755
+ swirl: .12,
756
+ speed: .52,
757
+ grainOverlay: .04
758
+ },
759
+ sunset: {
760
+ distortion: .74,
761
+ swirl: .34,
762
+ speed: .36,
763
+ grainOverlay: .07
764
+ },
765
+ dusk: {
766
+ distortion: .46,
767
+ swirl: .2,
768
+ speed: .22,
769
+ grainOverlay: .12
770
+ }
771
+ };
772
+ const MINERAL_MOTION = {
773
+ midnight: {
774
+ distortion: .14,
775
+ swirl: .1,
776
+ speed: .12,
777
+ grainOverlay: .06
778
+ },
779
+ night: {
780
+ distortion: .16,
781
+ swirl: .12,
782
+ speed: .14,
783
+ grainOverlay: .05
784
+ },
785
+ dawn: {
786
+ distortion: .22,
787
+ swirl: .18,
788
+ speed: .22,
789
+ grainOverlay: .04
790
+ },
791
+ sunrise: {
792
+ distortion: .28,
793
+ swirl: .24,
794
+ speed: .32,
795
+ grainOverlay: .03
796
+ },
797
+ morning: {
798
+ distortion: .22,
799
+ swirl: .18,
800
+ speed: .4,
801
+ grainOverlay: .02
802
+ },
803
+ "solar-noon": {
804
+ distortion: .16,
805
+ swirl: .14,
806
+ speed: .5,
807
+ grainOverlay: .02
808
+ },
809
+ afternoon: {
810
+ distortion: .2,
811
+ swirl: .16,
812
+ speed: .4,
813
+ grainOverlay: .02
814
+ },
815
+ sunset: {
816
+ distortion: .3,
817
+ swirl: .28,
818
+ speed: .28,
819
+ grainOverlay: .03
820
+ },
821
+ dusk: {
822
+ distortion: .2,
823
+ swirl: .2,
824
+ speed: .18,
825
+ grainOverlay: .04
826
+ }
827
+ };
828
+ const TIDE_MOTION = {
829
+ midnight: {
830
+ distortion: .5,
831
+ swirl: .08,
832
+ speed: .18,
833
+ grainOverlay: .03
834
+ },
835
+ night: {
836
+ distortion: .54,
837
+ swirl: .1,
838
+ speed: .22,
839
+ grainOverlay: .03
840
+ },
841
+ dawn: {
842
+ distortion: .64,
843
+ swirl: .16,
844
+ speed: .34,
845
+ grainOverlay: .02
846
+ },
847
+ sunrise: {
848
+ distortion: .72,
849
+ swirl: .2,
850
+ speed: .44,
851
+ grainOverlay: .02
852
+ },
853
+ morning: {
854
+ distortion: .68,
855
+ swirl: .16,
856
+ speed: .54,
857
+ grainOverlay: .01
858
+ },
859
+ "solar-noon": {
860
+ distortion: .6,
861
+ swirl: .12,
862
+ speed: .62,
863
+ grainOverlay: .01
864
+ },
865
+ afternoon: {
866
+ distortion: .64,
867
+ swirl: .14,
868
+ speed: .54,
869
+ grainOverlay: .01
870
+ },
871
+ sunset: {
872
+ distortion: .74,
873
+ swirl: .24,
874
+ speed: .4,
875
+ grainOverlay: .02
876
+ },
877
+ dusk: {
878
+ distortion: .6,
879
+ swirl: .18,
880
+ speed: .28,
881
+ grainOverlay: .03
882
+ }
883
+ };
884
+ const AURORA_MOTION = {
885
+ midnight: {
886
+ distortion: .8,
887
+ swirl: .44,
888
+ speed: .7,
889
+ grainOverlay: .02
890
+ },
891
+ night: {
892
+ distortion: .86,
893
+ swirl: .5,
894
+ speed: .8,
895
+ grainOverlay: .02
896
+ },
897
+ dawn: {
898
+ distortion: .62,
899
+ swirl: .32,
900
+ speed: .52,
901
+ grainOverlay: .03
902
+ },
903
+ sunrise: {
904
+ distortion: .38,
905
+ swirl: .16,
906
+ speed: .3,
907
+ grainOverlay: .04
908
+ },
909
+ morning: {
910
+ distortion: .18,
911
+ swirl: .05,
912
+ speed: .18,
913
+ grainOverlay: .04
914
+ },
915
+ "solar-noon": {
916
+ distortion: .14,
917
+ swirl: .03,
918
+ speed: .14,
919
+ grainOverlay: .03
920
+ },
921
+ afternoon: {
922
+ distortion: .18,
923
+ swirl: .05,
924
+ speed: .18,
925
+ grainOverlay: .04
926
+ },
927
+ sunset: {
928
+ distortion: .46,
929
+ swirl: .24,
930
+ speed: .42,
931
+ grainOverlay: .03
932
+ },
933
+ dusk: {
934
+ distortion: .68,
935
+ swirl: .38,
936
+ speed: .6,
937
+ grainOverlay: .02
938
+ }
939
+ };
940
+ const SKIN_MOTION_PROFILES = {
941
+ void: VOID_MOTION,
942
+ parchment: PARCHMENT_MOTION,
943
+ signal: SIGNAL_MOTION,
944
+ meridian: MERIDIAN_MOTION,
945
+ sundial: SUNDIAL_MOTION,
946
+ paper: PAPER_MOTION,
947
+ foundry: FOUNDRY_MOTION,
948
+ mineral: MINERAL_MOTION,
949
+ tide: TIDE_MOTION,
950
+ aurora: AURORA_MOTION
951
+ };
952
+
953
+ //#endregion
954
+ //#region src/shared/solar-shader-bg.tsx
955
+ const ShaderVariantCtx = createContext("showcase");
956
+ function useShaderVariant() {
957
+ return useContext(ShaderVariantCtx);
958
+ }
959
+ const DASHBOARD_MOTION_SCALE = {
960
+ speed: .45,
961
+ distortion: .5,
962
+ swirl: .4,
963
+ grainOverlay: 1.3
964
+ };
965
+ const DASHBOARD_OPACITY_SCALE = .65;
966
+ function applyDashboardMotion(m) {
967
+ return {
968
+ speed: m.speed * DASHBOARD_MOTION_SCALE.speed,
969
+ distortion: m.distortion * DASHBOARD_MOTION_SCALE.distortion,
970
+ swirl: m.swirl * DASHBOARD_MOTION_SCALE.swirl,
971
+ grainOverlay: Math.min(1, m.grainOverlay * DASHBOARD_MOTION_SCALE.grainOverlay)
972
+ };
973
+ }
974
+ const EDITORIAL_MOTION_SCALE = {
975
+ speed: .3,
976
+ distortion: .35,
977
+ swirl: .25,
978
+ grainOverlay: 1.4
979
+ };
980
+ const EDITORIAL_OPACITY_SCALE = .35;
981
+ function applyEditorialMotion(m) {
982
+ return {
983
+ speed: m.speed * EDITORIAL_MOTION_SCALE.speed,
984
+ distortion: m.distortion * EDITORIAL_MOTION_SCALE.distortion,
985
+ swirl: m.swirl * EDITORIAL_MOTION_SCALE.swirl,
986
+ grainOverlay: Math.min(1, m.grainOverlay * EDITORIAL_MOTION_SCALE.grainOverlay)
987
+ };
988
+ }
989
+ function mixToward(hex, target, mix) {
990
+ return lerpColor(hex, target, mix);
991
+ }
992
+ function applyEditorialPalette(p) {
993
+ const darkBase = "#08080c";
994
+ const darkVignette = "#030306";
995
+ return {
996
+ ...p,
997
+ colors: p.colors.map((c) => mixToward(c, darkBase, .92)),
998
+ colorBack: mixToward(p.colorBack, darkBase, .95),
999
+ vignette: mixToward(p.vignette, darkVignette, .9),
1000
+ cssFallback: `linear-gradient(135deg, ${darkBase} 0%, #0c0c14 100%)`
1001
+ };
1002
+ }
1003
+ function lerpNum(a, b, t) {
1004
+ return a + (b - a) * t;
1005
+ }
1006
+ function lerpMotion(a, b, t) {
1007
+ return {
1008
+ distortion: lerpNum(a.distortion, b.distortion, t),
1009
+ swirl: lerpNum(a.swirl, b.swirl, t),
1010
+ speed: lerpNum(a.speed, b.speed, t),
1011
+ grainOverlay: lerpNum(a.grainOverlay, b.grainOverlay, t)
1012
+ };
1013
+ }
1014
+ function lerpPalette(a, b, t) {
1015
+ return {
1016
+ colors: a.colors.map((ca, i) => lerpColor(ca, b.colors[i] ?? ca, t)),
1017
+ colorBack: lerpColor(a.colorBack, b.colorBack, t),
1018
+ opacity: lerpNum(a.opacity, b.opacity, t),
1019
+ vignette: lerpColor(a.vignette, b.vignette, t),
1020
+ cssFallback: a.cssFallback,
1021
+ image: a.image
1022
+ };
1023
+ }
1024
+ function resolveMotionProfile(skin) {
1025
+ if (skin.shaderMotion) return skin.shaderMotion;
1026
+ return SKIN_MOTION_PROFILES[skin.id] ?? UNIVERSAL_PHASE_MOTION;
1027
+ }
1028
+ function resolveImage(skin, palette) {
1029
+ return palette.image ?? skin.defaultImage;
1030
+ }
1031
+ function computeConfig(skin, blend) {
1032
+ const motionProfile = resolveMotionProfile(skin);
1033
+ const { phase, nextPhase, t } = blend;
1034
+ return {
1035
+ palette: lerpPalette(skin.shaderPalettes[phase], skin.shaderPalettes[nextPhase], t),
1036
+ motion: lerpMotion(motionProfile[phase], motionProfile[nextPhase], t)
1037
+ };
1038
+ }
1039
+ function hexToRgb(hex) {
1040
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1041
+ return result ? [
1042
+ Number.parseInt(result[1], 16) / 255,
1043
+ Number.parseInt(result[2], 16) / 255,
1044
+ Number.parseInt(result[3], 16) / 255
1045
+ ] : [
1046
+ 0,
1047
+ 0,
1048
+ 0
1049
+ ];
1050
+ }
1051
+ const VS_SOURCE = `#version 300 es
1052
+ in vec2 a_position;
1053
+ void main() {
1054
+ gl_Position = vec4(a_position, 0.0, 1.0);
1055
+ }
1056
+ `;
1057
+ const FS_SOURCE = `#version 300 es
1058
+ precision highp float;
1059
+
1060
+ uniform vec2 r; // resolution
1061
+ uniform float t; // time
1062
+ uniform vec3 u_bg; // background color (colorBack)
1063
+ uniform vec3 u_c0; // palette color 0
1064
+ uniform vec3 u_c1; // palette color 1
1065
+ uniform vec3 u_c2; // palette color 2
1066
+ uniform vec3 u_c3; // palette color 3
1067
+ uniform float u_intensity;
1068
+ uniform float u_spread;
1069
+ uniform float u_pulseRate;
1070
+ uniform float u_speed;
1071
+ uniform float u_grain;
1072
+
1073
+ out vec4 o;
1074
+
1075
+ // Hash for grain
1076
+ float hash(vec2 p) {
1077
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
1078
+ }
1079
+
1080
+ void main() {
1081
+ vec4 FC = gl_FragCoord;
1082
+ vec2 p = (FC.xy * 2. - r) / r.y;
1083
+
1084
+ // Average all 4 palette colors
1085
+ vec3 avgColor = (u_c0 + u_c1 + u_c2 + u_c3) * 0.25;
1086
+
1087
+ // Normalize to a fixed luminance so the flare shape is identical
1088
+ // across all skins regardless of how bright/dark the palette is.
1089
+ // Dark palettes (Void midnight ≈ 0.01) and bright palettes
1090
+ // (Paper morning ≈ 0.95) both produce the same-sized sun.
1091
+ float lum = dot(avgColor, vec3(0.299, 0.587, 0.114));
1092
+ vec3 flareColor = lum > 0.001
1093
+ ? avgColor * (0.30 / lum) // rescale to target luminance 0.30
1094
+ : vec3(0.30); // neutral grey fallback
1095
+
1096
+ // Solar flare radiance — matches the reference SolarFlare shader.
1097
+ // length(p) creates a circular distance field from center.
1098
+ // The exp(mod(dot(...))) creates alive, pulsing texture inside the sun.
1099
+ float l = u_intensity - length(p);
1100
+
1101
+ o = tanh(
1102
+ vec4(flareColor, 0.0)
1103
+ / max(l, -l * u_spread)
1104
+ / exp(
1105
+ mod(dot(FC, sin(FC.yxyx)) + t * u_speed, 2.0)
1106
+ + sin(t * u_speed + sin(t * u_speed / u_pulseRate + p.y))
1107
+ )
1108
+ );
1109
+
1110
+ // Film grain
1111
+ float grain = (hash(FC.xy + fract(t)) - 0.5) * u_grain;
1112
+
1113
+ // Composite: background + flare glow + grain
1114
+ o = vec4(u_bg + o.rgb + grain, 1.0);
1115
+ }
1116
+ `;
1117
+ function SolarFlareCanvas({ backgroundColor, colors, speed, intensity, spread, pulseRate, grain }) {
1118
+ const canvasRef = useRef(null);
1119
+ const animationRef = useRef(null);
1120
+ const configRef = useRef({
1121
+ backgroundColor,
1122
+ colors,
1123
+ speed,
1124
+ intensity,
1125
+ spread,
1126
+ pulseRate,
1127
+ grain
1128
+ });
1129
+ useEffect(() => {
1130
+ configRef.current = {
1131
+ backgroundColor,
1132
+ colors,
1133
+ speed,
1134
+ intensity,
1135
+ spread,
1136
+ pulseRate,
1137
+ grain
1138
+ };
1139
+ }, [
1140
+ backgroundColor,
1141
+ colors,
1142
+ speed,
1143
+ intensity,
1144
+ spread,
1145
+ pulseRate,
1146
+ grain
1147
+ ]);
1148
+ useLayoutEffect(() => {
1149
+ const canvas = canvasRef.current;
1150
+ if (!canvas) return;
1151
+ const gl = canvas.getContext("webgl2");
1152
+ if (!gl) return;
1153
+ const createShader = (type, source) => {
1154
+ const shader = gl.createShader(type);
1155
+ if (!shader) return null;
1156
+ gl.shaderSource(shader, source);
1157
+ gl.compileShader(shader);
1158
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
1159
+ gl.deleteShader(shader);
1160
+ return null;
1161
+ }
1162
+ return shader;
1163
+ };
1164
+ const vs = createShader(gl.VERTEX_SHADER, VS_SOURCE);
1165
+ const fs = createShader(gl.FRAGMENT_SHADER, FS_SOURCE);
1166
+ if (!vs || !fs) return;
1167
+ const program = gl.createProgram();
1168
+ if (!program) return;
1169
+ gl.attachShader(program, vs);
1170
+ gl.attachShader(program, fs);
1171
+ gl.linkProgram(program);
1172
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return;
1173
+ const positionBuffer = gl.createBuffer();
1174
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
1175
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1176
+ -1,
1177
+ -1,
1178
+ 1,
1179
+ -1,
1180
+ -1,
1181
+ 1,
1182
+ -1,
1183
+ 1,
1184
+ 1,
1185
+ -1,
1186
+ 1,
1187
+ 1
1188
+ ]), gl.STATIC_DRAW);
1189
+ const posLoc = gl.getAttribLocation(program, "a_position");
1190
+ gl.enableVertexAttribArray(posLoc);
1191
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
1192
+ const loc = {
1193
+ r: gl.getUniformLocation(program, "r"),
1194
+ t: gl.getUniformLocation(program, "t"),
1195
+ bg: gl.getUniformLocation(program, "u_bg"),
1196
+ c0: gl.getUniformLocation(program, "u_c0"),
1197
+ c1: gl.getUniformLocation(program, "u_c1"),
1198
+ c2: gl.getUniformLocation(program, "u_c2"),
1199
+ c3: gl.getUniformLocation(program, "u_c3"),
1200
+ intensity: gl.getUniformLocation(program, "u_intensity"),
1201
+ spread: gl.getUniformLocation(program, "u_spread"),
1202
+ pulseRate: gl.getUniformLocation(program, "u_pulseRate"),
1203
+ speed: gl.getUniformLocation(program, "u_speed"),
1204
+ grain: gl.getUniformLocation(program, "u_grain")
1205
+ };
1206
+ const resizeCanvas = () => {
1207
+ const dpr = window.devicePixelRatio || 1;
1208
+ canvas.width = Math.round(canvas.offsetWidth * dpr);
1209
+ canvas.height = Math.round(canvas.offsetHeight * dpr);
1210
+ gl.viewport(0, 0, canvas.width, canvas.height);
1211
+ };
1212
+ window.addEventListener("resize", resizeCanvas);
1213
+ resizeCanvas();
1214
+ const startTime = performance.now();
1215
+ const render = () => {
1216
+ const cfg = configRef.current;
1217
+ gl.useProgram(program);
1218
+ gl.uniform2f(loc.r, canvas.width, canvas.height);
1219
+ gl.uniform1f(loc.t, (performance.now() - startTime) / 1e3);
1220
+ const bg = hexToRgb(cfg.backgroundColor);
1221
+ gl.uniform3f(loc.bg, bg[0], bg[1], bg[2]);
1222
+ const c0 = hexToRgb(cfg.colors[0]);
1223
+ const c1 = hexToRgb(cfg.colors[1]);
1224
+ const c2 = hexToRgb(cfg.colors[2]);
1225
+ const c3 = hexToRgb(cfg.colors[3]);
1226
+ gl.uniform3f(loc.c0, c0[0], c0[1], c0[2]);
1227
+ gl.uniform3f(loc.c1, c1[0], c1[1], c1[2]);
1228
+ gl.uniform3f(loc.c2, c2[0], c2[1], c2[2]);
1229
+ gl.uniform3f(loc.c3, c3[0], c3[1], c3[2]);
1230
+ gl.uniform1f(loc.intensity, cfg.intensity);
1231
+ gl.uniform1f(loc.spread, cfg.spread);
1232
+ gl.uniform1f(loc.pulseRate, cfg.pulseRate);
1233
+ gl.uniform1f(loc.speed, cfg.speed);
1234
+ gl.uniform1f(loc.grain, cfg.grain);
1235
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
1236
+ animationRef.current = requestAnimationFrame(render);
1237
+ };
1238
+ render();
1239
+ return () => {
1240
+ window.removeEventListener("resize", resizeCanvas);
1241
+ if (animationRef.current) cancelAnimationFrame(animationRef.current);
1242
+ gl.deleteProgram(program);
1243
+ gl.deleteShader(vs);
1244
+ gl.deleteShader(fs);
1245
+ gl.deleteBuffer(positionBuffer);
1246
+ };
1247
+ }, []);
1248
+ return /* @__PURE__ */ jsx("canvas", {
1249
+ ref: canvasRef,
1250
+ style: {
1251
+ position: "absolute",
1252
+ top: 0,
1253
+ left: 0,
1254
+ width: "100%",
1255
+ height: "100%"
1256
+ }
1257
+ });
1258
+ }
1259
+ let _hasHydrated = false;
1260
+ function SolarShaderBg({ skinOverride, blendOverride, opacityOverride, variant: variantProp, className, style } = {}) {
1261
+ const { activeSkin, blend: contextBlend } = useSolarTheme();
1262
+ const contextVariant = useShaderVariant();
1263
+ const skin = skinOverride ?? activeSkin;
1264
+ const blend = blendOverride ?? contextBlend;
1265
+ const variant = variantProp ?? contextVariant;
1266
+ const { palette, motion: rawMotion } = useMemo(() => computeConfig(skin, blend), [
1267
+ blend.phase,
1268
+ blend.nextPhase,
1269
+ blend.t,
1270
+ skin
1271
+ ]);
1272
+ const variantPalette = variant === "editorial" ? applyEditorialPalette(palette) : palette;
1273
+ const shaderMotion = variant === "dashboard" ? applyDashboardMotion(rawMotion) : variant === "editorial" ? applyEditorialMotion(rawMotion) : rawMotion;
1274
+ const resolvedOpacity = opacityOverride ?? (variant === "dashboard" ? variantPalette.opacity * DASHBOARD_OPACITY_SCALE : variant === "editorial" ? variantPalette.opacity * EDITORIAL_OPACITY_SCALE : variantPalette.opacity);
1275
+ const imageConfig = resolveImage(skin, variantPalette);
1276
+ const [mounted, setMounted] = useState(_hasHydrated);
1277
+ useLayoutEffect(() => {
1278
+ _hasHydrated = true;
1279
+ setMounted(true);
1280
+ }, []);
1281
+ useEffect(() => {
1282
+ document.documentElement.style.setProperty("--solar-shader-bg", variantPalette.colorBack);
1283
+ return () => {
1284
+ document.documentElement.style.removeProperty("--solar-shader-bg");
1285
+ };
1286
+ }, [variantPalette.colorBack]);
1287
+ const flareSpeed = .6 + shaderMotion.speed * .8;
1288
+ const flareIntensity = 3.5 + shaderMotion.distortion * .5;
1289
+ const flareSpread = 8 + shaderMotion.swirl * 8;
1290
+ const flarePulseRate = .4 + (1 - shaderMotion.swirl) * .5;
1291
+ const flareGrain = shaderMotion.grainOverlay * .12;
1292
+ return /* @__PURE__ */ jsx("div", {
1293
+ className,
1294
+ suppressHydrationWarning: true,
1295
+ style: {
1296
+ position: "absolute",
1297
+ inset: 0,
1298
+ overflow: "hidden",
1299
+ background: variantPalette.cssFallback || variantPalette.colorBack,
1300
+ ...style
1301
+ },
1302
+ children: mounted && /* @__PURE__ */ jsxs(Fragment$1, { children: [
1303
+ /* @__PURE__ */ jsx("div", {
1304
+ className: "absolute inset-0",
1305
+ style: { opacity: resolvedOpacity },
1306
+ children: /* @__PURE__ */ jsx(SolarFlareCanvas, {
1307
+ backgroundColor: variantPalette.colorBack,
1308
+ colors: variantPalette.colors,
1309
+ speed: flareSpeed,
1310
+ intensity: flareIntensity,
1311
+ spread: flareSpread,
1312
+ pulseRate: flarePulseRate,
1313
+ grain: flareGrain
1314
+ })
1315
+ }),
1316
+ imageConfig && /* @__PURE__ */ jsx("div", {
1317
+ className: "absolute inset-0",
1318
+ "aria-hidden": true,
1319
+ style: {
1320
+ opacity: imageConfig.opacity ?? .18,
1321
+ pointerEvents: "none",
1322
+ background: "var(--solar-accent)",
1323
+ WebkitMaskImage: `url(${imageConfig.src})`,
1324
+ maskImage: `url(${imageConfig.src})`,
1325
+ WebkitMaskSize: "cover",
1326
+ maskSize: "cover",
1327
+ WebkitMaskPosition: imageConfig.objectPosition ?? "center center",
1328
+ maskPosition: imageConfig.objectPosition ?? "center center",
1329
+ WebkitMaskRepeat: "no-repeat",
1330
+ maskRepeat: "no-repeat"
1331
+ }
1332
+ }),
1333
+ /* @__PURE__ */ jsx("div", {
1334
+ className: "absolute inset-0",
1335
+ "aria-hidden": true,
1336
+ style: {
1337
+ pointerEvents: "none",
1338
+ background: `radial-gradient(ellipse 85% 70% at 50% 50%, transparent 0%, ${variantPalette.vignette} 100%)`
1339
+ }
1340
+ })
1341
+ ] })
1342
+ });
1343
+ }
1344
+ function SolarShaderBgFull(props = {}) {
1345
+ return /* @__PURE__ */ jsx(SolarShaderBg, {
1346
+ ...props,
1347
+ style: {
1348
+ zIndex: 0,
1349
+ ...props.style
1350
+ }
1351
+ });
1352
+ }
1353
+
1354
+ //#endregion
1355
+ export { CompactWidget, SolarShaderBg, SolarShaderBgFull, SolarThemeProvider, SolarWidget, useSolarTheme };
324
1356
  //# sourceMappingURL=index.js.map