kedhar-ui 0.2.0 → 0.3.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.
@@ -44,6 +44,7 @@
44
44
  --ks-leading-tight: 1.25;
45
45
  --ks-leading-normal: 1.5;
46
46
  --ks-leading-relaxed: 1.625;
47
+ --ks-leading-body: 1.7;
47
48
 
48
49
  --ks-weight-normal: 400;
49
50
  --ks-weight-medium: 500;
@@ -110,7 +111,7 @@ body {
110
111
  padding: 0;
111
112
  font-family: var(--ks-font-sans);
112
113
  font-size: var(--ks-text-base);
113
- line-height: var(--ks-leading-normal);
114
+ line-height: var(--ks-leading-body);
114
115
  color: var(--ks-color-text);
115
116
  background-color: var(--ks-color-bg);
116
117
  -webkit-font-smoothing: antialiased;
@@ -131,6 +132,20 @@ a:hover {
131
132
  color: var(--ks-color-primary-hover);
132
133
  }
133
134
 
135
+ /* Underline animation for inline links */
136
+ .ks-link-underline {
137
+ background-image: linear-gradient(var(--ks-color-primary), var(--ks-color-primary));
138
+ background-size: 0% 2px;
139
+ background-repeat: no-repeat;
140
+ background-position: left bottom;
141
+ transition: background-size var(--ks-duration-normal) var(--ks-ease-out);
142
+ padding-bottom: 2px;
143
+ }
144
+
145
+ .ks-link-underline:hover {
146
+ background-size: 100% 2px;
147
+ }
148
+
134
149
  /* ─── Images ───────────────────────────────────────────────── */
135
150
  img {
136
151
  max-width: 100%;
@@ -381,6 +396,7 @@ pre {
381
396
  border: 1px solid var(--ks-color-border);
382
397
  border-radius: var(--ks-radius-lg);
383
398
  padding: var(--ks-space-6);
399
+ box-shadow: var(--ks-shadow-sm);
384
400
  transition:
385
401
  box-shadow var(--ks-duration-normal) var(--ks-ease-out),
386
402
  border-color var(--ks-duration-normal) var(--ks-ease-out),
@@ -389,8 +405,8 @@ pre {
389
405
 
390
406
  .ks-card-hover:hover {
391
407
  border-color: var(--ks-color-primary-alpha);
392
- box-shadow: var(--ks-shadow-md);
393
- transform: translateY(-2px);
408
+ box-shadow: var(--ks-shadow-lg);
409
+ transform: translateY(-3px);
394
410
  }
395
411
 
396
412
 
@@ -733,3 +749,201 @@ pre {
733
749
  white-space: nowrap;
734
750
  border: 0;
735
751
  }
752
+
753
+
754
+ /* ══════════════════════════════════════════════════════════════
755
+ 11. Reveal Animations
756
+ ══════════════════════════════════════════════════════════════
757
+ Scroll-triggered reveal via IntersectionObserver + .visible class.
758
+ ══════════════════════════════════════════════════════════════ */
759
+ .ks-reveal {
760
+ opacity: 0;
761
+ transform: translateY(24px);
762
+ transition:
763
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
764
+ transform var(--ks-duration-slow) var(--ks-ease-out);
765
+ }
766
+
767
+ .ks-reveal-up {
768
+ opacity: 0;
769
+ transform: translateY(40px);
770
+ transition:
771
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
772
+ transform var(--ks-duration-slow) var(--ks-ease-out);
773
+ }
774
+
775
+ .ks-reveal.visible,
776
+ .ks-reveal-up.visible {
777
+ opacity: 1;
778
+ transform: translateY(0);
779
+ }
780
+
781
+ /* Stagger children */
782
+ .ks-stagger > * {
783
+ opacity: 0;
784
+ transform: translateY(20px);
785
+ transition:
786
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
787
+ transform var(--ks-duration-slow) var(--ks-ease-out);
788
+ }
789
+
790
+ .ks-stagger.visible > *:nth-child(1) { transition-delay: 0ms; }
791
+ .ks-stagger.visible > *:nth-child(2) { transition-delay: 80ms; }
792
+ .ks-stagger.visible > *:nth-child(3) { transition-delay: 160ms; }
793
+ .ks-stagger.visible > *:nth-child(4) { transition-delay: 240ms; }
794
+ .ks-stagger.visible > *:nth-child(5) { transition-delay: 320ms; }
795
+ .ks-stagger.visible > *:nth-child(6) { transition-delay: 400ms; }
796
+ .ks-stagger.visible > *:nth-child(7) { transition-delay: 480ms; }
797
+ .ks-stagger.visible > *:nth-child(8) { transition-delay: 560ms; }
798
+ .ks-stagger.visible > *:nth-child(9) { transition-delay: 640ms; }
799
+ .ks-stagger.visible > *:nth-child(10) { transition-delay: 720ms; }
800
+
801
+ .ks-stagger.visible > * {
802
+ opacity: 1;
803
+ transform: translateY(0);
804
+ }
805
+
806
+
807
+ /* ══════════════════════════════════════════════════════════════
808
+ 12. Hero Section
809
+ ══════════════════════════════════════════════════════════════ */
810
+ .ks-hero {
811
+ min-height: 70vh;
812
+ display: flex;
813
+ align-items: center;
814
+ justify-content: center;
815
+ text-align: center;
816
+ padding: var(--ks-space-16) var(--ks-space-4);
817
+ position: relative;
818
+ overflow: hidden;
819
+ }
820
+
821
+ .ks-hero-gradient {
822
+ position: absolute;
823
+ inset: 0;
824
+ pointer-events: none;
825
+ z-index: 0;
826
+ }
827
+
828
+ .ks-hero-gradient::before {
829
+ content: '';
830
+ position: absolute;
831
+ top: -50%;
832
+ left: -50%;
833
+ width: 200%;
834
+ height: 200%;
835
+ background: radial-gradient(ellipse at 30% 50%, var(--ks-color-primary-alpha) 0%, transparent 60%),
836
+ radial-gradient(ellipse at 70% 50%, var(--ks-color-primary-light) 0%, transparent 50%);
837
+ opacity: 0.6;
838
+ }
839
+
840
+ .dark .ks-hero-gradient::before {
841
+ opacity: 0.3;
842
+ }
843
+
844
+ .ks-hero-content {
845
+ position: relative;
846
+ z-index: 1;
847
+ max-width: 720px;
848
+ }
849
+
850
+ .ks-hero-badge {
851
+ display: inline-flex;
852
+ align-items: center;
853
+ gap: var(--ks-space-1);
854
+ padding: var(--ks-space-1) var(--ks-space-3);
855
+ border-radius: var(--ks-radius-full);
856
+ font-size: var(--ks-text-sm);
857
+ font-weight: var(--ks-weight-medium);
858
+ color: var(--ks-color-primary);
859
+ background: var(--ks-color-primary-alpha);
860
+ margin-bottom: var(--ks-space-4);
861
+ }
862
+
863
+ .ks-hero h1 {
864
+ font-size: clamp(2rem, 5vw, 3.5rem);
865
+ font-weight: var(--ks-weight-bold);
866
+ letter-spacing: -0.03em;
867
+ line-height: 1.1;
868
+ color: var(--ks-color-text);
869
+ margin: 0 0 var(--ks-space-4);
870
+ }
871
+
872
+ .ks-hero p {
873
+ font-size: clamp(1rem, 2vw, 1.2rem);
874
+ color: var(--ks-color-text-muted);
875
+ line-height: var(--ks-leading-relaxed);
876
+ max-width: 560px;
877
+ margin: 0 auto var(--ks-space-8);
878
+ }
879
+
880
+ .ks-hero-actions {
881
+ display: flex;
882
+ gap: var(--ks-space-3);
883
+ justify-content: center;
884
+ flex-wrap: wrap;
885
+ }
886
+
887
+
888
+ /* ══════════════════════════════════════════════════════════════
889
+ 13. Section Header
890
+ ══════════════════════════════════════════════════════════════ */
891
+ .ks-section-header {
892
+ text-align: center;
893
+ margin-bottom: var(--ks-space-10);
894
+ }
895
+
896
+ .ks-section-header h2 {
897
+ font-size: var(--ks-text-3xl);
898
+ font-weight: var(--ks-weight-bold);
899
+ color: var(--ks-color-text);
900
+ letter-spacing: -0.02em;
901
+ margin: 0 0 var(--ks-space-2);
902
+ }
903
+
904
+ @media (min-width: 640px) {
905
+ .ks-section-header h2 {
906
+ font-size: var(--ks-text-4xl);
907
+ }
908
+ }
909
+
910
+ .ks-section-header p {
911
+ color: var(--ks-color-text-muted);
912
+ max-width: 480px;
913
+ margin: 0 auto;
914
+ }
915
+
916
+ .ks-section-divider {
917
+ width: 48px;
918
+ height: 3px;
919
+ border-radius: var(--ks-radius-full);
920
+ background: var(--ks-color-primary);
921
+ margin: var(--ks-space-3) auto 0;
922
+ }
923
+
924
+
925
+ /* ══════════════════════════════════════════════════════════════
926
+ 14. Button Active State
927
+ ══════════════════════════════════════════════════════════════ */
928
+ .ks-btn:active {
929
+ transform: scale(0.97);
930
+ }
931
+
932
+
933
+ /* ══════════════════════════════════════════════════════════════
934
+ 15. Nav Link Active Indicator
935
+ ══════════════════════════════════════════════════════════════ */
936
+ .ks-nav-links a.active,
937
+ .ks-nav-links a[aria-current="page"] {
938
+ color: var(--ks-color-text);
939
+ }
940
+
941
+ .ks-nav-links a.active::after,
942
+ .ks-nav-links a[aria-current="page"]::after {
943
+ content: '';
944
+ display: block;
945
+ height: 2px;
946
+ border-radius: var(--ks-radius-full);
947
+ background: var(--ks-color-primary);
948
+ margin-top: 2px;
949
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kedhar-ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Shared design system for Kedhar's projects — CSS tokens, components, and themes.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -9,11 +9,18 @@
9
9
  * <p>Content here...</p>
10
10
  * </Card>
11
11
  *
12
+ * <!-- As a link -->
13
+ * <Card hover ripple tag="a" href="/projects/my-project/">
14
+ * ...
15
+ * </Card>
16
+ *
12
17
  * Props:
13
18
  * hover — Enable lift-on-hover effect (default: false)
14
19
  * ripple — Enable CSS ripple effect (default: false)
15
- * tag — HTML tag to use (default: 'div', can be 'article', 'section', 'a')
20
+ * tag — HTML tag to use (default: 'div', can be 'div', 'article', 'section', 'a')
16
21
  * class — Additional CSS classes
22
+ *
23
+ * All other attributes (href, target, rel, etc.) are forwarded to the root element.
17
24
  */
18
25
 
19
26
  export interface Props {
@@ -23,9 +30,18 @@ export interface Props {
23
30
  class?: string;
24
31
  }
25
32
 
26
- const { hover = false, ripple = false, tag: Tag = 'div' } = Astro.props;
33
+ const {
34
+ hover = false,
35
+ ripple = false,
36
+ tag: Tag = 'div',
37
+ class: className,
38
+ ...rest
39
+ } = Astro.props;
27
40
  ---
28
41
 
29
- <Tag class:list={['ks-card', { 'ks-card-hover': hover, 'ks-ripple': ripple }, Astro.props.class]}>
42
+ <Tag
43
+ class:list={['ks-card', { 'ks-card-hover': hover, 'ks-ripple': ripple }, className]}
44
+ {...rest}
45
+ >
30
46
  <slot />
31
47
  </Tag>
@@ -22,7 +22,7 @@ body {
22
22
  padding: 0;
23
23
  font-family: var(--ks-font-sans);
24
24
  font-size: var(--ks-text-base);
25
- line-height: var(--ks-leading-normal);
25
+ line-height: var(--ks-leading-body);
26
26
  color: var(--ks-color-text);
27
27
  background-color: var(--ks-color-bg);
28
28
  -webkit-font-smoothing: antialiased;
@@ -43,6 +43,20 @@ a:hover {
43
43
  color: var(--ks-color-primary-hover);
44
44
  }
45
45
 
46
+ /* Underline animation for inline links */
47
+ .ks-link-underline {
48
+ background-image: linear-gradient(var(--ks-color-primary), var(--ks-color-primary));
49
+ background-size: 0% 2px;
50
+ background-repeat: no-repeat;
51
+ background-position: left bottom;
52
+ transition: background-size var(--ks-duration-normal) var(--ks-ease-out);
53
+ padding-bottom: 2px;
54
+ }
55
+
56
+ .ks-link-underline:hover {
57
+ background-size: 100% 2px;
58
+ }
59
+
46
60
  /* ─── Images ───────────────────────────────────────────────── */
47
61
  img {
48
62
  max-width: 100%;
@@ -215,6 +215,7 @@
215
215
  border: 1px solid var(--ks-color-border);
216
216
  border-radius: var(--ks-radius-lg);
217
217
  padding: var(--ks-space-6);
218
+ box-shadow: var(--ks-shadow-sm);
218
219
  transition:
219
220
  box-shadow var(--ks-duration-normal) var(--ks-ease-out),
220
221
  border-color var(--ks-duration-normal) var(--ks-ease-out),
@@ -223,8 +224,8 @@
223
224
 
224
225
  .ks-card-hover:hover {
225
226
  border-color: var(--ks-color-primary-alpha);
226
- box-shadow: var(--ks-shadow-md);
227
- transform: translateY(-2px);
227
+ box-shadow: var(--ks-shadow-lg);
228
+ transform: translateY(-3px);
228
229
  }
229
230
 
230
231
 
@@ -567,3 +568,201 @@
567
568
  white-space: nowrap;
568
569
  border: 0;
569
570
  }
571
+
572
+
573
+ /* ══════════════════════════════════════════════════════════════
574
+ 11. Reveal Animations
575
+ ══════════════════════════════════════════════════════════════
576
+ Scroll-triggered reveal via IntersectionObserver + .visible class.
577
+ ══════════════════════════════════════════════════════════════ */
578
+ .ks-reveal {
579
+ opacity: 0;
580
+ transform: translateY(24px);
581
+ transition:
582
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
583
+ transform var(--ks-duration-slow) var(--ks-ease-out);
584
+ }
585
+
586
+ .ks-reveal-up {
587
+ opacity: 0;
588
+ transform: translateY(40px);
589
+ transition:
590
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
591
+ transform var(--ks-duration-slow) var(--ks-ease-out);
592
+ }
593
+
594
+ .ks-reveal.visible,
595
+ .ks-reveal-up.visible {
596
+ opacity: 1;
597
+ transform: translateY(0);
598
+ }
599
+
600
+ /* Stagger children */
601
+ .ks-stagger > * {
602
+ opacity: 0;
603
+ transform: translateY(20px);
604
+ transition:
605
+ opacity var(--ks-duration-slow) var(--ks-ease-out),
606
+ transform var(--ks-duration-slow) var(--ks-ease-out);
607
+ }
608
+
609
+ .ks-stagger.visible > *:nth-child(1) { transition-delay: 0ms; }
610
+ .ks-stagger.visible > *:nth-child(2) { transition-delay: 80ms; }
611
+ .ks-stagger.visible > *:nth-child(3) { transition-delay: 160ms; }
612
+ .ks-stagger.visible > *:nth-child(4) { transition-delay: 240ms; }
613
+ .ks-stagger.visible > *:nth-child(5) { transition-delay: 320ms; }
614
+ .ks-stagger.visible > *:nth-child(6) { transition-delay: 400ms; }
615
+ .ks-stagger.visible > *:nth-child(7) { transition-delay: 480ms; }
616
+ .ks-stagger.visible > *:nth-child(8) { transition-delay: 560ms; }
617
+ .ks-stagger.visible > *:nth-child(9) { transition-delay: 640ms; }
618
+ .ks-stagger.visible > *:nth-child(10) { transition-delay: 720ms; }
619
+
620
+ .ks-stagger.visible > * {
621
+ opacity: 1;
622
+ transform: translateY(0);
623
+ }
624
+
625
+
626
+ /* ══════════════════════════════════════════════════════════════
627
+ 12. Hero Section
628
+ ══════════════════════════════════════════════════════════════ */
629
+ .ks-hero {
630
+ min-height: 70vh;
631
+ display: flex;
632
+ align-items: center;
633
+ justify-content: center;
634
+ text-align: center;
635
+ padding: var(--ks-space-16) var(--ks-space-4);
636
+ position: relative;
637
+ overflow: hidden;
638
+ }
639
+
640
+ .ks-hero-gradient {
641
+ position: absolute;
642
+ inset: 0;
643
+ pointer-events: none;
644
+ z-index: 0;
645
+ }
646
+
647
+ .ks-hero-gradient::before {
648
+ content: '';
649
+ position: absolute;
650
+ top: -50%;
651
+ left: -50%;
652
+ width: 200%;
653
+ height: 200%;
654
+ background: radial-gradient(ellipse at 30% 50%, var(--ks-color-primary-alpha) 0%, transparent 60%),
655
+ radial-gradient(ellipse at 70% 50%, var(--ks-color-primary-light) 0%, transparent 50%);
656
+ opacity: 0.6;
657
+ }
658
+
659
+ .dark .ks-hero-gradient::before {
660
+ opacity: 0.3;
661
+ }
662
+
663
+ .ks-hero-content {
664
+ position: relative;
665
+ z-index: 1;
666
+ max-width: 720px;
667
+ }
668
+
669
+ .ks-hero-badge {
670
+ display: inline-flex;
671
+ align-items: center;
672
+ gap: var(--ks-space-1);
673
+ padding: var(--ks-space-1) var(--ks-space-3);
674
+ border-radius: var(--ks-radius-full);
675
+ font-size: var(--ks-text-sm);
676
+ font-weight: var(--ks-weight-medium);
677
+ color: var(--ks-color-primary);
678
+ background: var(--ks-color-primary-alpha);
679
+ margin-bottom: var(--ks-space-4);
680
+ }
681
+
682
+ .ks-hero h1 {
683
+ font-size: clamp(2rem, 5vw, 3.5rem);
684
+ font-weight: var(--ks-weight-bold);
685
+ letter-spacing: -0.03em;
686
+ line-height: 1.1;
687
+ color: var(--ks-color-text);
688
+ margin: 0 0 var(--ks-space-4);
689
+ }
690
+
691
+ .ks-hero p {
692
+ font-size: clamp(1rem, 2vw, 1.2rem);
693
+ color: var(--ks-color-text-muted);
694
+ line-height: var(--ks-leading-relaxed);
695
+ max-width: 560px;
696
+ margin: 0 auto var(--ks-space-8);
697
+ }
698
+
699
+ .ks-hero-actions {
700
+ display: flex;
701
+ gap: var(--ks-space-3);
702
+ justify-content: center;
703
+ flex-wrap: wrap;
704
+ }
705
+
706
+
707
+ /* ══════════════════════════════════════════════════════════════
708
+ 13. Section Header
709
+ ══════════════════════════════════════════════════════════════ */
710
+ .ks-section-header {
711
+ text-align: center;
712
+ margin-bottom: var(--ks-space-10);
713
+ }
714
+
715
+ .ks-section-header h2 {
716
+ font-size: var(--ks-text-3xl);
717
+ font-weight: var(--ks-weight-bold);
718
+ color: var(--ks-color-text);
719
+ letter-spacing: -0.02em;
720
+ margin: 0 0 var(--ks-space-2);
721
+ }
722
+
723
+ @media (min-width: 640px) {
724
+ .ks-section-header h2 {
725
+ font-size: var(--ks-text-4xl);
726
+ }
727
+ }
728
+
729
+ .ks-section-header p {
730
+ color: var(--ks-color-text-muted);
731
+ max-width: 480px;
732
+ margin: 0 auto;
733
+ }
734
+
735
+ .ks-section-divider {
736
+ width: 48px;
737
+ height: 3px;
738
+ border-radius: var(--ks-radius-full);
739
+ background: var(--ks-color-primary);
740
+ margin: var(--ks-space-3) auto 0;
741
+ }
742
+
743
+
744
+ /* ══════════════════════════════════════════════════════════════
745
+ 14. Button Active State
746
+ ══════════════════════════════════════════════════════════════ */
747
+ .ks-btn:active {
748
+ transform: scale(0.97);
749
+ }
750
+
751
+
752
+ /* ══════════════════════════════════════════════════════════════
753
+ 15. Nav Link Active Indicator
754
+ ══════════════════════════════════════════════════════════════ */
755
+ .ks-nav-links a.active,
756
+ .ks-nav-links a[aria-current="page"] {
757
+ color: var(--ks-color-text);
758
+ }
759
+
760
+ .ks-nav-links a.active::after,
761
+ .ks-nav-links a[aria-current="page"]::after {
762
+ content: '';
763
+ display: block;
764
+ height: 2px;
765
+ border-radius: var(--ks-radius-full);
766
+ background: var(--ks-color-primary);
767
+ margin-top: 2px;
768
+ }
@@ -42,6 +42,7 @@
42
42
  --ks-leading-tight: 1.25;
43
43
  --ks-leading-normal: 1.5;
44
44
  --ks-leading-relaxed: 1.625;
45
+ --ks-leading-body: 1.7;
45
46
 
46
47
  --ks-weight-normal: 400;
47
48
  --ks-weight-medium: 500;