@dmitriikapustin/ui 0.2.6 → 0.2.8

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/README.md CHANGED
@@ -10,14 +10,23 @@ npm install @dmitriikapustin/ui
10
10
 
11
11
  ## Usage
12
12
 
13
+ **Step 1.** Import design tokens stylesheet **once** in your app's root layout (e.g. `app/layout.tsx` for Next.js, or `main.tsx` for Vite):
14
+
13
15
  ```tsx
14
- import { Button, Input, Badge } from '@dmitriikapustin/ui';
15
16
  import '@dmitriikapustin/ui/styles.css';
17
+ ```
18
+
19
+ This registers all CSS custom properties (`--bg`, `--fg`, `--brand-primary`, `--radius-lg`, etc.) on `:root`. Components reference these tokens — without this import, components render without colors / typography / spacing.
20
+
21
+ **Step 2.** Use components anywhere:
22
+
23
+ ```tsx
24
+ import { Button, Input, Badge } from '@dmitriikapustin/ui';
16
25
 
17
26
  export function App() {
18
27
  return (
19
28
  <div>
20
- <Button variant="primary">Get Started</Button>
29
+ <Button variant="primary" size="hero">Get Started</Button>
21
30
  <Input label="Email" placeholder="you@example.com" />
22
31
  <Badge color="success">Active</Badge>
23
32
  </div>
@@ -41,10 +50,10 @@ Dark mode activates via `[data-theme="dark"]` on `<html>`.
41
50
  Button, Input, Badge, Tag, Toggle, Avatar, Spinner, Divider, MenuItem, IconButton, Logo, StatBadge, Textarea, Select, Checkbox, Radio, Link, Tooltip, Skeleton, Icons
42
51
 
43
52
  ### Molecules
44
- Card, FormField, SearchBar, Stat, Alert, Tabs, ChatInput, ChatMessage, TopPromo, ProfileNav, IconWithText, StampCard, PasswordInput, Breadcrumbs, Toast, Pagination, CodeInput, Modal, DropdownMenu
53
+ Card, IconBadge, Gallery, FormField, SearchBar, Stat, Alert, Tabs, ChatInput, ChatMessage, TopPromo, ProfileNav, IconWithText, StampCard, PasswordInput, Breadcrumbs, Toast, Pagination, CodeInput, Modal, DropdownMenu
45
54
 
46
55
  ### Organisms
47
- Header, Footer, PricingCard, TestimonialCard, FeatureGrid, Sidebar, AppCard, AppTopLine, EmptyState, HeroSection, LogoCloud, StatsBar, CTASection, BentoGrid, FAQSection, ComparisonTable, PromoBento, PromoShowcase, PromoSplit, PromoTrustGrid, PromoDevicesCTA, PromoTestimonials, PromoHero, PromoPricing, PromoActionCards
56
+ Header, Footer, PricingCard, TestimonialCard, FeatureGrid, Sidebar, AppCard, AppTopLine, EmptyState, HeroSection, LogoCloud, StatsBar, CTASection, BentoGrid, FAQSection, ComparisonTable, PromoBento, PromoShowcase, PromoSplit, PromoTrustGrid, PromoDevicesCTA, PromoTestimonials, PromoHero, PromoHeroForm, PromoPricing, PromoActionCards
48
57
 
49
58
  ### Templates
50
59
  ArticleHero, ArticleBody, ArticleHeading, ArticleFigure, ArticleTable, ArticleList, ArticleNote, ArticleChatBlock, ArticleLinkButton, ArticleFooter, ArticleLayout, LandingLayout, ArticleLineChart, ArticleBarChart, ArticleScatterChart
package/dist/index.cjs CHANGED
@@ -915,40 +915,61 @@ function IconButton(_a) {
915
915
  }
916
916
 
917
917
  // css-inject-scss:/Users/dimakozh/Desktop/projects/kapustin.cc/packages/ui/src/atoms/Logo.module.scss
918
- __styleInject(`.Logo-module_short {
919
- width: 19px;
920
- height: 20px;
921
- }
922
-
923
- .Logo-module_full {
924
- height: 20px;
925
- width: 130px;
926
- }
927
-
928
- .Logo-module_third {
929
- display: flex;
918
+ __styleInject(`.Logo-module_root {
919
+ display: inline-flex;
930
920
  align-items: center;
931
921
  gap: 0.375rem;
932
922
  }
933
923
 
934
- .Logo-module_thirdText {
935
- font-size: 13px;
936
- font-weight: 500;
924
+ .Logo-module_image {
925
+ display: block;
926
+ }
927
+
928
+ .Logo-module_text {
929
+ font-size: 16px;
930
+ font-weight: 600;
937
931
  color: var(--fg);
938
932
  letter-spacing: -0.25px;
933
+ line-height: 1;
934
+ }
935
+
936
+ .Logo-module_accent {
937
+ color: var(--brand-primary);
939
938
  }`);
940
- var __default11 = { "short": "Logo-module_short", "full": "Logo-module_full", "third": "Logo-module_third", "thirdText": "Logo-module_thirdText" };
941
- function Logo({ version = "short", className = "" }) {
942
- if (version === "short") {
943
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${__default11.short}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { className: "logo-img", src: "/assets/logos/logo-short.svg", alt: "aiacade.me", width: 19, height: 20 }) });
944
- }
945
- if (version === "third") {
946
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${__default11.third}${className ? ` ${className}` : ""}`, children: [
947
- /* @__PURE__ */ jsxRuntime.jsx("img", { className: "logo-img", src: "/assets/logos/logo-icon.svg", alt: "", width: 20, height: 20 }),
948
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default11.thirdText, children: "aiacade.me" })
949
- ] });
939
+ var __default11 = { "root": "Logo-module_root", "image": "Logo-module_image", "text": "Logo-module_text", "accent": "Logo-module_accent" };
940
+ function Logo({
941
+ children,
942
+ src,
943
+ alt = "",
944
+ width,
945
+ height,
946
+ text,
947
+ accent,
948
+ className = ""
949
+ }) {
950
+ const rootClass = `${__default11.root}${className ? ` ${className}` : ""}`;
951
+ if (children) {
952
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: rootClass, children });
953
+ }
954
+ if (src) {
955
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: rootClass, children: /* @__PURE__ */ jsxRuntime.jsx("img", { className: __default11.image, src, alt, width, height }) });
956
+ }
957
+ if (text) {
958
+ const accentText = accent != null ? accent : text.charAt(0);
959
+ const idx = accent ? text.indexOf(accent) : 0;
960
+ if (idx >= 0 && accentText) {
961
+ const before = text.slice(0, idx);
962
+ const middle = text.slice(idx, idx + accentText.length);
963
+ const after = text.slice(idx + accentText.length);
964
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: rootClass, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: __default11.text, children: [
965
+ before,
966
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default11.accent, children: middle }),
967
+ after
968
+ ] }) });
969
+ }
970
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: rootClass, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default11.text, children: text }) });
950
971
  }
951
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${__default11.full}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { className: "logo-img", src: "/assets/logos/logo-full.svg", alt: "aiacade.me", width: 130, height: 20 }) });
972
+ return null;
952
973
  }
953
974
 
954
975
  // css-inject-scss:/Users/dimakozh/Desktop/projects/kapustin.cc/packages/ui/src/atoms/StatBadge.module.scss
@@ -3540,16 +3561,13 @@ __styleInject(`.Header-module_root {
3540
3561
  padding-top: 1rem;
3541
3562
  border-top: 1px solid var(--border-color);
3542
3563
  }`);
3543
- var __default42 = { "root": "Header-module_root", "container": "Header-module_container", "bar": "Header-module_bar", "leftGroup": "Header-module_leftGroup", "logoFallback": "Header-module_logoFallback", "logoBrand": "Header-module_logoBrand", "desktopNav": "Header-module_desktopNav", "navLink": "Header-module_navLink", "desktopActions": "Header-module_desktopActions", "mobileToggle": "Header-module_mobileToggle", "mobileMenu": "Header-module_mobileMenu", "mobileNav": "Header-module_mobileNav", "mobileActions": "Header-module_mobileActions" };
3544
- function Header({ logo, navItems = [], className = "" }) {
3564
+ var __default42 = { "root": "Header-module_root", "container": "Header-module_container", "bar": "Header-module_bar", "leftGroup": "Header-module_leftGroup", "desktopNav": "Header-module_desktopNav", "navLink": "Header-module_navLink", "desktopActions": "Header-module_desktopActions", "mobileToggle": "Header-module_mobileToggle", "mobileMenu": "Header-module_mobileMenu", "mobileNav": "Header-module_mobileNav", "mobileActions": "Header-module_mobileActions" };
3565
+ function Header({ logo, navItems = [], actions, className = "" }) {
3545
3566
  const [mobileOpen, setMobileOpen] = react.useState(false);
3546
3567
  return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: `${__default42.root}${className ? ` ${className}` : ""}`, children: [
3547
3568
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default42.container, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default42.bar, children: [
3548
3569
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default42.leftGroup, children: [
3549
- logo || /* @__PURE__ */ jsxRuntime.jsxs("span", { className: __default42.logoFallback, children: [
3550
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default42.logoBrand, children: "K" }),
3551
- "apustin"
3552
- ] }),
3570
+ logo,
3553
3571
  /* @__PURE__ */ jsxRuntime.jsx("nav", { className: __default42.desktopNav, children: navItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
3554
3572
  "a",
3555
3573
  {
@@ -3560,10 +3578,7 @@ function Header({ logo, navItems = [], className = "" }) {
3560
3578
  item.label
3561
3579
  )) })
3562
3580
  ] }),
3563
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default42.desktopActions, children: [
3564
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "md", children: "Sign in" }),
3565
- /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "md", children: "Get started" })
3566
- ] }),
3581
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default42.desktopActions, children: actions }),
3567
3582
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default42.mobileToggle, children: /* @__PURE__ */ jsxRuntime.jsx(
3568
3583
  IconButton,
3569
3584
  {
@@ -3584,10 +3599,7 @@ function Header({ logo, navItems = [], className = "" }) {
3584
3599
  },
3585
3600
  item.label
3586
3601
  )) }),
3587
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default42.mobileActions, children: [
3588
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "md", children: "Sign in" }),
3589
- /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "md", children: "Get started" })
3590
- ] })
3602
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default42.mobileActions, children: actions })
3591
3603
  ] })
3592
3604
  ] });
3593
3605
  }
@@ -3706,72 +3718,34 @@ __styleInject(`.Footer-module_root {
3706
3718
  .Footer-module_socialLink:hover {
3707
3719
  color: var(--fg);
3708
3720
  }`);
3709
- var __default43 = { "root": "Footer-module_root", "container": "Footer-module_container", "grid": "Footer-module_grid", "brand": "Footer-module_brand", "brandAccent": "Footer-module_brandAccent", "tagline": "Footer-module_tagline", "columnTitle": "Footer-module_columnTitle", "linkList": "Footer-module_linkList", "link": "Footer-module_link", "bottom": "Footer-module_bottom", "copyright": "Footer-module_copyright", "socials": "Footer-module_socials", "socialLink": "Footer-module_socialLink" };
3710
- var defaultColumns = [
3711
- {
3712
- title: "Product",
3713
- links: [
3714
- { label: "Components", href: "#" },
3715
- { label: "Templates", href: "#" },
3716
- { label: "Pricing", href: "#" },
3717
- { label: "Changelog", href: "#" }
3718
- ]
3719
- },
3720
- {
3721
- title: "Resources",
3722
- links: [
3723
- { label: "Documentation", href: "#" },
3724
- { label: "Guides", href: "#" },
3725
- { label: "API Reference", href: "#" },
3726
- { label: "Blog", href: "#" }
3727
- ]
3728
- },
3729
- {
3730
- title: "Company",
3731
- links: [
3732
- { label: "About", href: "#" },
3733
- { label: "Careers", href: "#" },
3734
- { label: "Contact", href: "#" },
3735
- { label: "Legal", href: "#" }
3736
- ]
3737
- }
3738
- ];
3739
- function Footer({ columns = defaultColumns, className = "" }) {
3721
+ var __default43 = { "root": "Footer-module_root", "container": "Footer-module_container", "grid": "Footer-module_grid", "columnTitle": "Footer-module_columnTitle", "linkList": "Footer-module_linkList", "link": "Footer-module_link", "bottom": "Footer-module_bottom", "copyright": "Footer-module_copyright", "socials": "Footer-module_socials", "socialLink": "Footer-module_socialLink" };
3722
+ function Footer({
3723
+ brand,
3724
+ columns,
3725
+ socials,
3726
+ copyright,
3727
+ className = ""
3728
+ }) {
3729
+ const hasGrid = !!brand || columns && columns.length > 0;
3730
+ const hasBottom = !!copyright || socials && socials.length > 0;
3740
3731
  return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: `${__default43.root}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default43.container, children: [
3741
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default43.grid, children: [
3742
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3743
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: __default43.brand, children: [
3744
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default43.brandAccent, children: "K" }),
3745
- "apustin"
3746
- ] }),
3747
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: __default43.tagline, children: "A modern design system for building beautiful interfaces." })
3748
- ] }),
3749
- columns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3732
+ hasGrid && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default43.grid, children: [
3733
+ brand && /* @__PURE__ */ jsxRuntime.jsx("div", { children: brand }),
3734
+ columns == null ? void 0 : columns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3750
3735
  /* @__PURE__ */ jsxRuntime.jsx("h4", { className: __default43.columnTitle, children: col.title }),
3751
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: __default43.linkList, children: col.links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
3752
- "a",
3753
- {
3754
- href: link.href,
3755
- className: __default43.link,
3756
- children: link.label
3757
- }
3758
- ) }, link.label)) })
3736
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: __default43.linkList, children: col.links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: link.href, className: __default43.link, children: link.label }) }, link.label)) })
3759
3737
  ] }, col.title))
3760
3738
  ] }),
3761
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default43.bottom, children: [
3762
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: __default43.copyright, children: [
3763
- "\xA9 ",
3764
- (/* @__PURE__ */ new Date()).getFullYear(),
3765
- " Kapustin Team. All rights reserved."
3766
- ] }),
3767
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default43.socials, children: ["Twitter", "GitHub", "Discord"].map((social) => /* @__PURE__ */ jsxRuntime.jsx(
3739
+ hasBottom && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: __default43.bottom, children: [
3740
+ copyright && /* @__PURE__ */ jsxRuntime.jsx("p", { className: __default43.copyright, children: copyright }),
3741
+ socials && socials.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: __default43.socials, children: socials.map((social) => /* @__PURE__ */ jsxRuntime.jsx(
3768
3742
  "a",
3769
3743
  {
3770
- href: "#",
3744
+ href: social.href,
3771
3745
  className: __default43.socialLink,
3772
- children: social
3746
+ children: social.label
3773
3747
  },
3774
- social
3748
+ social.label
3775
3749
  )) })
3776
3750
  ] })
3777
3751
  ] }) });
@@ -3865,6 +3839,7 @@ function PricingCard({
3865
3839
  features,
3866
3840
  highlighted = false,
3867
3841
  badge,
3842
+ cta,
3868
3843
  className = ""
3869
3844
  }) {
3870
3845
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3885,7 +3860,15 @@ function PricingCard({
3885
3860
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: __default44.featureIcon, children: /* @__PURE__ */ jsxRuntime.jsx(IconlyCheck, { size: 16 }) }),
3886
3861
  feature
3887
3862
  ] }, i)) }),
3888
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: highlighted ? "primary" : "outline", className: __default44.cta, children: "Get started" })
3863
+ cta && /* @__PURE__ */ jsxRuntime.jsx(
3864
+ Button,
3865
+ {
3866
+ variant: highlighted ? "primary" : "outline",
3867
+ className: __default44.cta,
3868
+ onClick: cta.onClick,
3869
+ children: cta.label
3870
+ }
3871
+ )
3889
3872
  ]
3890
3873
  }
3891
3874
  );
package/dist/index.css ADDED
@@ -0,0 +1,161 @@
1
+ /* css-inject-plain:/Users/dimakozh/Desktop/projects/kapustin.cc/packages/ui/src/styles.css */
2
+ :root {
3
+ --neutral-50: #fafafa;
4
+ --neutral-100: #f7f7f7;
5
+ --neutral-200: #f3f3f3;
6
+ --neutral-300: #e0e0e0;
7
+ --neutral-400: #babbbd;
8
+ --neutral-500: #737373;
9
+ --neutral-600: #4c4c4c;
10
+ --neutral-700: #404040;
11
+ --neutral-800: #262626;
12
+ --neutral-900: #18181b;
13
+ --neutral-950: #0a0a0a;
14
+ --brand-primary: #18181b;
15
+ --brand-primary-light: #4c4c4c;
16
+ --brand-primary-dark: #0a0a0a;
17
+ --brand-secondary: #f3f3f3;
18
+ --brand-secondary-light: #f7f7f7;
19
+ --brand-secondary-dark: #e0e0e0;
20
+ --brand-accent: #18181b;
21
+ --brand-accent-light: #4c4c4c;
22
+ --brand-accent-dark: #0a0a0a;
23
+ --color-accent: #02ad41;
24
+ --color-accent-light: #34c759;
25
+ --color-accent-dark: #029236;
26
+ --color-success: #22c55e;
27
+ --color-success-light: #86efac;
28
+ --color-success-dark: #16a34a;
29
+ --color-warning: #f59e0b;
30
+ --color-warning-light: #fcd34d;
31
+ --color-warning-dark: #d97706;
32
+ --color-error: #ef4444;
33
+ --color-error-light: #fca5a5;
34
+ --color-error-dark: #dc2626;
35
+ --color-info: #3b82f6;
36
+ --color-info-light: #93c5fd;
37
+ --color-info-dark: #2563eb;
38
+ --bg: #ffffff;
39
+ --bg-secondary: #f7f7f7;
40
+ --bg-tertiary: #f3f3f3;
41
+ --fg: #18181b;
42
+ --fg-secondary: #4c4c4c;
43
+ --fg-muted: #babbbd;
44
+ --border-color: #e0e0e0;
45
+ --border-color-strong: #babbbd;
46
+ --font-sans:
47
+ var(--font-onest),
48
+ system-ui,
49
+ -apple-system,
50
+ sans-serif;
51
+ --font-mono:
52
+ "Geist Mono",
53
+ "SF Mono",
54
+ "Fira Code",
55
+ monospace;
56
+ --text-xs: 0.75rem;
57
+ --text-sm: 0.875rem;
58
+ --text-base: 1rem;
59
+ --text-lg: 1.125rem;
60
+ --text-xl: 1.25rem;
61
+ --text-2xl: 1.5rem;
62
+ --text-3xl: 1.875rem;
63
+ --text-4xl: 2.25rem;
64
+ --text-5xl: 3rem;
65
+ --text-6xl: 3.75rem;
66
+ --space-1: 0.25rem;
67
+ --space-2: 0.5rem;
68
+ --space-3: 0.75rem;
69
+ --space-4: 1rem;
70
+ --space-5: 1.25rem;
71
+ --space-6: 1.5rem;
72
+ --space-8: 2rem;
73
+ --space-10: 2.5rem;
74
+ --space-12: 3rem;
75
+ --space-16: 4rem;
76
+ --space-20: 5rem;
77
+ --space-24: 6rem;
78
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
79
+ --shadow-sm: 0 7px 7px 0 rgb(0 0 0 / 0.07);
80
+ --shadow-md: 0 7px 13px 0 rgb(0 0 0 / 0.05);
81
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
82
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
83
+ --radius-sm: 0.25rem;
84
+ --radius-md: 0.5rem;
85
+ --radius-lg: 1rem;
86
+ --radius-xl: 1rem;
87
+ --radius-2xl: 1rem;
88
+ --radius-full: 9999px;
89
+ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
90
+ --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
91
+ --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
92
+ --button-primary-border-gradient:
93
+ linear-gradient(
94
+ 275.38deg,
95
+ rgba(255, 255, 255, 0.07) 1.53%,
96
+ rgba(255, 255, 255, 0.028) 94.58%);
97
+ }
98
+ [data-theme=dark] {
99
+ --bg: #09090b;
100
+ --bg-secondary: #18181b;
101
+ --bg-tertiary: #27272a;
102
+ --fg: #fafafa;
103
+ --fg-secondary: #a1a1aa;
104
+ --fg-muted: #71717a;
105
+ --border-color: #27272a;
106
+ --border-color-strong: #3f3f46;
107
+ --brand-primary: #818cf8;
108
+ --brand-primary-light: #a5b4fc;
109
+ --brand-primary-dark: #6366f1;
110
+ --brand-secondary: #f472b6;
111
+ --brand-secondary-light: #f9a8d4;
112
+ --brand-secondary-dark: #ec4899;
113
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.3);
114
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
115
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
116
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4);
117
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4);
118
+ --button-primary-border-gradient:
119
+ linear-gradient(
120
+ 275.38deg,
121
+ rgba(255, 255, 255, 0.04) 1.53%,
122
+ rgba(255, 255, 255, 0.02) 94.58%);
123
+ }
124
+ [data-theme=dark] .logo-img {
125
+ filter: invert(1);
126
+ }
127
+ :root,
128
+ :host {
129
+ --font-sans: var(--font-sans);
130
+ --font-mono: var(--font-mono);
131
+ }
132
+ * {
133
+ border-color: var(--border-color);
134
+ }
135
+ body {
136
+ background: var(--bg);
137
+ color: var(--fg);
138
+ font-family: var(--font-sans);
139
+ line-height: 1.6;
140
+ -webkit-font-smoothing: antialiased;
141
+ -moz-osx-font-smoothing: grayscale;
142
+ }
143
+ ::selection {
144
+ background: var(--brand-primary);
145
+ color: white;
146
+ }
147
+ ::-webkit-scrollbar {
148
+ width: 8px;
149
+ height: 8px;
150
+ }
151
+ ::-webkit-scrollbar-track {
152
+ background: var(--bg-secondary);
153
+ }
154
+ ::-webkit-scrollbar-thumb {
155
+ background: var(--fg-muted);
156
+ border-radius: var(--radius-full);
157
+ }
158
+ ::-webkit-scrollbar-thumb:hover {
159
+ background: var(--fg-secondary);
160
+ }
161
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
package/dist/index.d.cts CHANGED
@@ -89,12 +89,24 @@ interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
89
89
  }
90
90
  declare function IconButton({ icon, variant, className, disabled, ...props }: IconButtonProps): react_jsx_runtime.JSX.Element;
91
91
 
92
- type LogoVersion = 'short' | 'full' | 'third';
93
92
  interface LogoProps {
94
- version?: LogoVersion;
93
+ /** Полный override через произвольный JSX. Имеет приоритет над text/src. */
94
+ children?: ReactNode;
95
+ /** URL картинки-логотипа. */
96
+ src?: string;
97
+ /** alt для картинки. */
98
+ alt?: string;
99
+ /** Ширина картинки. */
100
+ width?: number;
101
+ /** Высота картинки. */
102
+ height?: number;
103
+ /** Текстовый brand-name. */
104
+ text?: string;
105
+ /** Подстрока внутри text, выделяемая accent-цветом (первое вхождение). По умолчанию — первая буква text. */
106
+ accent?: string;
95
107
  className?: string;
96
108
  }
97
- declare function Logo({ version, className }: LogoProps): react_jsx_runtime.JSX.Element;
109
+ declare function Logo({ children, src, alt, width, height, text, accent, className, }: LogoProps): react_jsx_runtime.JSX.Element | null;
98
110
 
99
111
  interface StatBadgeProps {
100
112
  value: string;
@@ -440,11 +452,13 @@ interface NavItem {
440
452
  href: string;
441
453
  }
442
454
  interface HeaderProps {
443
- logo?: React.ReactNode;
455
+ logo?: ReactNode;
444
456
  navItems?: NavItem[];
457
+ /** Кнопки/контент справа (CTA). Если undefined — блок не рендерится. */
458
+ actions?: ReactNode;
445
459
  className?: string;
446
460
  }
447
- declare function Header({ logo, navItems, className }: HeaderProps): react_jsx_runtime.JSX.Element;
461
+ declare function Header({ logo, navItems, actions, className }: HeaderProps): react_jsx_runtime.JSX.Element;
448
462
 
449
463
  interface FooterColumn {
450
464
  title: string;
@@ -453,11 +467,22 @@ interface FooterColumn {
453
467
  href: string;
454
468
  }[];
455
469
  }
470
+ interface FooterSocial {
471
+ label: string;
472
+ href: string;
473
+ }
456
474
  interface FooterProps {
475
+ /** Brand-cell слева в grid. Если undefined — ячейка не рендерится. */
476
+ brand?: ReactNode;
477
+ /** Колонки навигации. */
457
478
  columns?: FooterColumn[];
479
+ /** Соц-ссылки в нижнем баре. Если undefined / [] — не рендерится. */
480
+ socials?: FooterSocial[];
481
+ /** Copyright-строка. Если undefined / null — не рендерится. */
482
+ copyright?: string | null;
458
483
  className?: string;
459
484
  }
460
- declare function Footer({ columns, className }: FooterProps): react_jsx_runtime.JSX.Element;
485
+ declare function Footer({ brand, columns, socials, copyright, className, }: FooterProps): react_jsx_runtime.JSX.Element;
461
486
 
462
487
  interface PricingCardProps {
463
488
  plan: string;
@@ -467,9 +492,15 @@ interface PricingCardProps {
467
492
  features: string[];
468
493
  highlighted?: boolean;
469
494
  badge?: string;
495
+ /** CTA-кнопка. Если undefined — кнопка не рендерится. */
496
+ cta?: {
497
+ label: string;
498
+ href?: string;
499
+ onClick?: () => void;
500
+ };
470
501
  className?: string;
471
502
  }
472
- declare function PricingCard({ plan, price, period, description, features, highlighted, badge, className, }: PricingCardProps): react_jsx_runtime.JSX.Element;
503
+ declare function PricingCard({ plan, price, period, description, features, highlighted, badge, cta, className, }: PricingCardProps): react_jsx_runtime.JSX.Element;
473
504
 
474
505
  interface TestimonialCardProps {
475
506
  quote: string;
package/dist/index.d.ts CHANGED
@@ -89,12 +89,24 @@ interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
89
89
  }
90
90
  declare function IconButton({ icon, variant, className, disabled, ...props }: IconButtonProps): react_jsx_runtime.JSX.Element;
91
91
 
92
- type LogoVersion = 'short' | 'full' | 'third';
93
92
  interface LogoProps {
94
- version?: LogoVersion;
93
+ /** Полный override через произвольный JSX. Имеет приоритет над text/src. */
94
+ children?: ReactNode;
95
+ /** URL картинки-логотипа. */
96
+ src?: string;
97
+ /** alt для картинки. */
98
+ alt?: string;
99
+ /** Ширина картинки. */
100
+ width?: number;
101
+ /** Высота картинки. */
102
+ height?: number;
103
+ /** Текстовый brand-name. */
104
+ text?: string;
105
+ /** Подстрока внутри text, выделяемая accent-цветом (первое вхождение). По умолчанию — первая буква text. */
106
+ accent?: string;
95
107
  className?: string;
96
108
  }
97
- declare function Logo({ version, className }: LogoProps): react_jsx_runtime.JSX.Element;
109
+ declare function Logo({ children, src, alt, width, height, text, accent, className, }: LogoProps): react_jsx_runtime.JSX.Element | null;
98
110
 
99
111
  interface StatBadgeProps {
100
112
  value: string;
@@ -440,11 +452,13 @@ interface NavItem {
440
452
  href: string;
441
453
  }
442
454
  interface HeaderProps {
443
- logo?: React.ReactNode;
455
+ logo?: ReactNode;
444
456
  navItems?: NavItem[];
457
+ /** Кнопки/контент справа (CTA). Если undefined — блок не рендерится. */
458
+ actions?: ReactNode;
445
459
  className?: string;
446
460
  }
447
- declare function Header({ logo, navItems, className }: HeaderProps): react_jsx_runtime.JSX.Element;
461
+ declare function Header({ logo, navItems, actions, className }: HeaderProps): react_jsx_runtime.JSX.Element;
448
462
 
449
463
  interface FooterColumn {
450
464
  title: string;
@@ -453,11 +467,22 @@ interface FooterColumn {
453
467
  href: string;
454
468
  }[];
455
469
  }
470
+ interface FooterSocial {
471
+ label: string;
472
+ href: string;
473
+ }
456
474
  interface FooterProps {
475
+ /** Brand-cell слева в grid. Если undefined — ячейка не рендерится. */
476
+ brand?: ReactNode;
477
+ /** Колонки навигации. */
457
478
  columns?: FooterColumn[];
479
+ /** Соц-ссылки в нижнем баре. Если undefined / [] — не рендерится. */
480
+ socials?: FooterSocial[];
481
+ /** Copyright-строка. Если undefined / null — не рендерится. */
482
+ copyright?: string | null;
458
483
  className?: string;
459
484
  }
460
- declare function Footer({ columns, className }: FooterProps): react_jsx_runtime.JSX.Element;
485
+ declare function Footer({ brand, columns, socials, copyright, className, }: FooterProps): react_jsx_runtime.JSX.Element;
461
486
 
462
487
  interface PricingCardProps {
463
488
  plan: string;
@@ -467,9 +492,15 @@ interface PricingCardProps {
467
492
  features: string[];
468
493
  highlighted?: boolean;
469
494
  badge?: string;
495
+ /** CTA-кнопка. Если undefined — кнопка не рендерится. */
496
+ cta?: {
497
+ label: string;
498
+ href?: string;
499
+ onClick?: () => void;
500
+ };
470
501
  className?: string;
471
502
  }
472
- declare function PricingCard({ plan, price, period, description, features, highlighted, badge, className, }: PricingCardProps): react_jsx_runtime.JSX.Element;
503
+ declare function PricingCard({ plan, price, period, description, features, highlighted, badge, cta, className, }: PricingCardProps): react_jsx_runtime.JSX.Element;
473
504
 
474
505
  interface TestimonialCardProps {
475
506
  quote: string;
package/dist/index.js CHANGED
@@ -909,40 +909,61 @@ function IconButton(_a) {
909
909
  }
910
910
 
911
911
  // css-inject-scss:/Users/dimakozh/Desktop/projects/kapustin.cc/packages/ui/src/atoms/Logo.module.scss
912
- __styleInject(`.Logo-module_short {
913
- width: 19px;
914
- height: 20px;
915
- }
916
-
917
- .Logo-module_full {
918
- height: 20px;
919
- width: 130px;
920
- }
921
-
922
- .Logo-module_third {
923
- display: flex;
912
+ __styleInject(`.Logo-module_root {
913
+ display: inline-flex;
924
914
  align-items: center;
925
915
  gap: 0.375rem;
926
916
  }
927
917
 
928
- .Logo-module_thirdText {
929
- font-size: 13px;
930
- font-weight: 500;
918
+ .Logo-module_image {
919
+ display: block;
920
+ }
921
+
922
+ .Logo-module_text {
923
+ font-size: 16px;
924
+ font-weight: 600;
931
925
  color: var(--fg);
932
926
  letter-spacing: -0.25px;
927
+ line-height: 1;
928
+ }
929
+
930
+ .Logo-module_accent {
931
+ color: var(--brand-primary);
933
932
  }`);
934
- var __default11 = { "short": "Logo-module_short", "full": "Logo-module_full", "third": "Logo-module_third", "thirdText": "Logo-module_thirdText" };
935
- function Logo({ version = "short", className = "" }) {
936
- if (version === "short") {
937
- return /* @__PURE__ */ jsx("div", { className: `${__default11.short}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsx("img", { className: "logo-img", src: "/assets/logos/logo-short.svg", alt: "aiacade.me", width: 19, height: 20 }) });
938
- }
939
- if (version === "third") {
940
- return /* @__PURE__ */ jsxs("div", { className: `${__default11.third}${className ? ` ${className}` : ""}`, children: [
941
- /* @__PURE__ */ jsx("img", { className: "logo-img", src: "/assets/logos/logo-icon.svg", alt: "", width: 20, height: 20 }),
942
- /* @__PURE__ */ jsx("span", { className: __default11.thirdText, children: "aiacade.me" })
943
- ] });
933
+ var __default11 = { "root": "Logo-module_root", "image": "Logo-module_image", "text": "Logo-module_text", "accent": "Logo-module_accent" };
934
+ function Logo({
935
+ children,
936
+ src,
937
+ alt = "",
938
+ width,
939
+ height,
940
+ text,
941
+ accent,
942
+ className = ""
943
+ }) {
944
+ const rootClass = `${__default11.root}${className ? ` ${className}` : ""}`;
945
+ if (children) {
946
+ return /* @__PURE__ */ jsx("span", { className: rootClass, children });
947
+ }
948
+ if (src) {
949
+ return /* @__PURE__ */ jsx("span", { className: rootClass, children: /* @__PURE__ */ jsx("img", { className: __default11.image, src, alt, width, height }) });
950
+ }
951
+ if (text) {
952
+ const accentText = accent != null ? accent : text.charAt(0);
953
+ const idx = accent ? text.indexOf(accent) : 0;
954
+ if (idx >= 0 && accentText) {
955
+ const before = text.slice(0, idx);
956
+ const middle = text.slice(idx, idx + accentText.length);
957
+ const after = text.slice(idx + accentText.length);
958
+ return /* @__PURE__ */ jsx("span", { className: rootClass, children: /* @__PURE__ */ jsxs("span", { className: __default11.text, children: [
959
+ before,
960
+ /* @__PURE__ */ jsx("span", { className: __default11.accent, children: middle }),
961
+ after
962
+ ] }) });
963
+ }
964
+ return /* @__PURE__ */ jsx("span", { className: rootClass, children: /* @__PURE__ */ jsx("span", { className: __default11.text, children: text }) });
944
965
  }
945
- return /* @__PURE__ */ jsx("div", { className: `${__default11.full}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsx("img", { className: "logo-img", src: "/assets/logos/logo-full.svg", alt: "aiacade.me", width: 130, height: 20 }) });
966
+ return null;
946
967
  }
947
968
 
948
969
  // css-inject-scss:/Users/dimakozh/Desktop/projects/kapustin.cc/packages/ui/src/atoms/StatBadge.module.scss
@@ -3534,16 +3555,13 @@ __styleInject(`.Header-module_root {
3534
3555
  padding-top: 1rem;
3535
3556
  border-top: 1px solid var(--border-color);
3536
3557
  }`);
3537
- var __default42 = { "root": "Header-module_root", "container": "Header-module_container", "bar": "Header-module_bar", "leftGroup": "Header-module_leftGroup", "logoFallback": "Header-module_logoFallback", "logoBrand": "Header-module_logoBrand", "desktopNav": "Header-module_desktopNav", "navLink": "Header-module_navLink", "desktopActions": "Header-module_desktopActions", "mobileToggle": "Header-module_mobileToggle", "mobileMenu": "Header-module_mobileMenu", "mobileNav": "Header-module_mobileNav", "mobileActions": "Header-module_mobileActions" };
3538
- function Header({ logo, navItems = [], className = "" }) {
3558
+ var __default42 = { "root": "Header-module_root", "container": "Header-module_container", "bar": "Header-module_bar", "leftGroup": "Header-module_leftGroup", "desktopNav": "Header-module_desktopNav", "navLink": "Header-module_navLink", "desktopActions": "Header-module_desktopActions", "mobileToggle": "Header-module_mobileToggle", "mobileMenu": "Header-module_mobileMenu", "mobileNav": "Header-module_mobileNav", "mobileActions": "Header-module_mobileActions" };
3559
+ function Header({ logo, navItems = [], actions, className = "" }) {
3539
3560
  const [mobileOpen, setMobileOpen] = useState(false);
3540
3561
  return /* @__PURE__ */ jsxs("header", { className: `${__default42.root}${className ? ` ${className}` : ""}`, children: [
3541
3562
  /* @__PURE__ */ jsx("div", { className: __default42.container, children: /* @__PURE__ */ jsxs("div", { className: __default42.bar, children: [
3542
3563
  /* @__PURE__ */ jsxs("div", { className: __default42.leftGroup, children: [
3543
- logo || /* @__PURE__ */ jsxs("span", { className: __default42.logoFallback, children: [
3544
- /* @__PURE__ */ jsx("span", { className: __default42.logoBrand, children: "K" }),
3545
- "apustin"
3546
- ] }),
3564
+ logo,
3547
3565
  /* @__PURE__ */ jsx("nav", { className: __default42.desktopNav, children: navItems.map((item) => /* @__PURE__ */ jsx(
3548
3566
  "a",
3549
3567
  {
@@ -3554,10 +3572,7 @@ function Header({ logo, navItems = [], className = "" }) {
3554
3572
  item.label
3555
3573
  )) })
3556
3574
  ] }),
3557
- /* @__PURE__ */ jsxs("div", { className: __default42.desktopActions, children: [
3558
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "md", children: "Sign in" }),
3559
- /* @__PURE__ */ jsx(Button, { size: "md", children: "Get started" })
3560
- ] }),
3575
+ actions && /* @__PURE__ */ jsx("div", { className: __default42.desktopActions, children: actions }),
3561
3576
  /* @__PURE__ */ jsx("div", { className: __default42.mobileToggle, children: /* @__PURE__ */ jsx(
3562
3577
  IconButton,
3563
3578
  {
@@ -3578,10 +3593,7 @@ function Header({ logo, navItems = [], className = "" }) {
3578
3593
  },
3579
3594
  item.label
3580
3595
  )) }),
3581
- /* @__PURE__ */ jsxs("div", { className: __default42.mobileActions, children: [
3582
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "md", children: "Sign in" }),
3583
- /* @__PURE__ */ jsx(Button, { size: "md", children: "Get started" })
3584
- ] })
3596
+ actions && /* @__PURE__ */ jsx("div", { className: __default42.mobileActions, children: actions })
3585
3597
  ] })
3586
3598
  ] });
3587
3599
  }
@@ -3700,72 +3712,34 @@ __styleInject(`.Footer-module_root {
3700
3712
  .Footer-module_socialLink:hover {
3701
3713
  color: var(--fg);
3702
3714
  }`);
3703
- var __default43 = { "root": "Footer-module_root", "container": "Footer-module_container", "grid": "Footer-module_grid", "brand": "Footer-module_brand", "brandAccent": "Footer-module_brandAccent", "tagline": "Footer-module_tagline", "columnTitle": "Footer-module_columnTitle", "linkList": "Footer-module_linkList", "link": "Footer-module_link", "bottom": "Footer-module_bottom", "copyright": "Footer-module_copyright", "socials": "Footer-module_socials", "socialLink": "Footer-module_socialLink" };
3704
- var defaultColumns = [
3705
- {
3706
- title: "Product",
3707
- links: [
3708
- { label: "Components", href: "#" },
3709
- { label: "Templates", href: "#" },
3710
- { label: "Pricing", href: "#" },
3711
- { label: "Changelog", href: "#" }
3712
- ]
3713
- },
3714
- {
3715
- title: "Resources",
3716
- links: [
3717
- { label: "Documentation", href: "#" },
3718
- { label: "Guides", href: "#" },
3719
- { label: "API Reference", href: "#" },
3720
- { label: "Blog", href: "#" }
3721
- ]
3722
- },
3723
- {
3724
- title: "Company",
3725
- links: [
3726
- { label: "About", href: "#" },
3727
- { label: "Careers", href: "#" },
3728
- { label: "Contact", href: "#" },
3729
- { label: "Legal", href: "#" }
3730
- ]
3731
- }
3732
- ];
3733
- function Footer({ columns = defaultColumns, className = "" }) {
3715
+ var __default43 = { "root": "Footer-module_root", "container": "Footer-module_container", "grid": "Footer-module_grid", "columnTitle": "Footer-module_columnTitle", "linkList": "Footer-module_linkList", "link": "Footer-module_link", "bottom": "Footer-module_bottom", "copyright": "Footer-module_copyright", "socials": "Footer-module_socials", "socialLink": "Footer-module_socialLink" };
3716
+ function Footer({
3717
+ brand,
3718
+ columns,
3719
+ socials,
3720
+ copyright,
3721
+ className = ""
3722
+ }) {
3723
+ const hasGrid = !!brand || columns && columns.length > 0;
3724
+ const hasBottom = !!copyright || socials && socials.length > 0;
3734
3725
  return /* @__PURE__ */ jsx("footer", { className: `${__default43.root}${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsxs("div", { className: __default43.container, children: [
3735
- /* @__PURE__ */ jsxs("div", { className: __default43.grid, children: [
3736
- /* @__PURE__ */ jsxs("div", { children: [
3737
- /* @__PURE__ */ jsxs("span", { className: __default43.brand, children: [
3738
- /* @__PURE__ */ jsx("span", { className: __default43.brandAccent, children: "K" }),
3739
- "apustin"
3740
- ] }),
3741
- /* @__PURE__ */ jsx("p", { className: __default43.tagline, children: "A modern design system for building beautiful interfaces." })
3742
- ] }),
3743
- columns.map((col) => /* @__PURE__ */ jsxs("div", { children: [
3726
+ hasGrid && /* @__PURE__ */ jsxs("div", { className: __default43.grid, children: [
3727
+ brand && /* @__PURE__ */ jsx("div", { children: brand }),
3728
+ columns == null ? void 0 : columns.map((col) => /* @__PURE__ */ jsxs("div", { children: [
3744
3729
  /* @__PURE__ */ jsx("h4", { className: __default43.columnTitle, children: col.title }),
3745
- /* @__PURE__ */ jsx("ul", { className: __default43.linkList, children: col.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
3746
- "a",
3747
- {
3748
- href: link.href,
3749
- className: __default43.link,
3750
- children: link.label
3751
- }
3752
- ) }, link.label)) })
3730
+ /* @__PURE__ */ jsx("ul", { className: __default43.linkList, children: col.links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: __default43.link, children: link.label }) }, link.label)) })
3753
3731
  ] }, col.title))
3754
3732
  ] }),
3755
- /* @__PURE__ */ jsxs("div", { className: __default43.bottom, children: [
3756
- /* @__PURE__ */ jsxs("p", { className: __default43.copyright, children: [
3757
- "\xA9 ",
3758
- (/* @__PURE__ */ new Date()).getFullYear(),
3759
- " Kapustin Team. All rights reserved."
3760
- ] }),
3761
- /* @__PURE__ */ jsx("div", { className: __default43.socials, children: ["Twitter", "GitHub", "Discord"].map((social) => /* @__PURE__ */ jsx(
3733
+ hasBottom && /* @__PURE__ */ jsxs("div", { className: __default43.bottom, children: [
3734
+ copyright && /* @__PURE__ */ jsx("p", { className: __default43.copyright, children: copyright }),
3735
+ socials && socials.length > 0 && /* @__PURE__ */ jsx("div", { className: __default43.socials, children: socials.map((social) => /* @__PURE__ */ jsx(
3762
3736
  "a",
3763
3737
  {
3764
- href: "#",
3738
+ href: social.href,
3765
3739
  className: __default43.socialLink,
3766
- children: social
3740
+ children: social.label
3767
3741
  },
3768
- social
3742
+ social.label
3769
3743
  )) })
3770
3744
  ] })
3771
3745
  ] }) });
@@ -3859,6 +3833,7 @@ function PricingCard({
3859
3833
  features,
3860
3834
  highlighted = false,
3861
3835
  badge,
3836
+ cta,
3862
3837
  className = ""
3863
3838
  }) {
3864
3839
  return /* @__PURE__ */ jsxs(
@@ -3879,7 +3854,15 @@ function PricingCard({
3879
3854
  /* @__PURE__ */ jsx("span", { className: __default44.featureIcon, children: /* @__PURE__ */ jsx(IconlyCheck, { size: 16 }) }),
3880
3855
  feature
3881
3856
  ] }, i)) }),
3882
- /* @__PURE__ */ jsx(Button, { variant: highlighted ? "primary" : "outline", className: __default44.cta, children: "Get started" })
3857
+ cta && /* @__PURE__ */ jsx(
3858
+ Button,
3859
+ {
3860
+ variant: highlighted ? "primary" : "outline",
3861
+ className: __default44.cta,
3862
+ onClick: cta.onClick,
3863
+ children: cta.label
3864
+ }
3865
+ )
3883
3866
  ]
3884
3867
  }
3885
3868
  );
@@ -0,0 +1,180 @@
1
+ /* ─── Design Tokens ─── */
2
+ :root {
3
+ /* Neutral Palette */
4
+ --neutral-50: #fafafa;
5
+ --neutral-100: #f7f7f7;
6
+ --neutral-200: #f3f3f3;
7
+ --neutral-300: #e0e0e0;
8
+ --neutral-400: #babbbd;
9
+ --neutral-500: #737373;
10
+ --neutral-600: #4c4c4c;
11
+ --neutral-700: #404040;
12
+ --neutral-800: #262626;
13
+ --neutral-900: #18181b;
14
+ --neutral-950: #0a0a0a;
15
+
16
+ /* Brand Colors */
17
+ --brand-primary: #18181b;
18
+ --brand-primary-light: #4c4c4c;
19
+ --brand-primary-dark: #0a0a0a;
20
+ --brand-secondary: #f3f3f3;
21
+ --brand-secondary-light: #f7f7f7;
22
+ --brand-secondary-dark: #e0e0e0;
23
+ --brand-accent: #18181b;
24
+ --brand-accent-light: #4c4c4c;
25
+ --brand-accent-dark: #0a0a0a;
26
+
27
+ /* Accent */
28
+ --color-accent: #02ad41;
29
+ --color-accent-light: #34c759;
30
+ --color-accent-dark: #029236;
31
+
32
+ /* Semantic Colors */
33
+ --color-success: #22c55e;
34
+ --color-success-light: #86efac;
35
+ --color-success-dark: #16a34a;
36
+ --color-warning: #f59e0b;
37
+ --color-warning-light: #fcd34d;
38
+ --color-warning-dark: #d97706;
39
+ --color-error: #ef4444;
40
+ --color-error-light: #fca5a5;
41
+ --color-error-dark: #dc2626;
42
+ --color-info: #3b82f6;
43
+ --color-info-light: #93c5fd;
44
+ --color-info-dark: #2563eb;
45
+
46
+ /* Surfaces */
47
+ --bg: #ffffff;
48
+ --bg-secondary: #f7f7f7;
49
+ --bg-tertiary: #f3f3f3;
50
+ --fg: #18181b;
51
+ --fg-secondary: #4c4c4c;
52
+ --fg-muted: #babbbd;
53
+ --border-color: #e0e0e0;
54
+ --border-color-strong: #babbbd;
55
+
56
+ /* Typography */
57
+ --font-sans: var(--font-onest), system-ui, -apple-system, sans-serif;
58
+ --font-mono: 'Geist Mono', 'SF Mono', 'Fira Code', monospace;
59
+ --text-xs: 0.75rem;
60
+ --text-sm: 0.875rem;
61
+ --text-base: 1rem;
62
+ --text-lg: 1.125rem;
63
+ --text-xl: 1.25rem;
64
+ --text-2xl: 1.5rem;
65
+ --text-3xl: 1.875rem;
66
+ --text-4xl: 2.25rem;
67
+ --text-5xl: 3rem;
68
+ --text-6xl: 3.75rem;
69
+
70
+ /* Spacing */
71
+ --space-1: 0.25rem;
72
+ --space-2: 0.5rem;
73
+ --space-3: 0.75rem;
74
+ --space-4: 1rem;
75
+ --space-5: 1.25rem;
76
+ --space-6: 1.5rem;
77
+ --space-8: 2rem;
78
+ --space-10: 2.5rem;
79
+ --space-12: 3rem;
80
+ --space-16: 4rem;
81
+ --space-20: 5rem;
82
+ --space-24: 6rem;
83
+
84
+ /* Shadows */
85
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
86
+ --shadow-sm: 0 7px 7px 0 rgb(0 0 0 / 0.07);
87
+ --shadow-md: 0 7px 13px 0 rgb(0 0 0 / 0.05);
88
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
89
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
90
+
91
+ /* Border Radius */
92
+ --radius-sm: 0.25rem;
93
+ --radius-md: 0.5rem;
94
+ --radius-lg: 1rem;
95
+ --radius-xl: 1rem;
96
+ --radius-2xl: 1rem;
97
+ --radius-full: 9999px;
98
+
99
+ /* Transitions */
100
+ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
101
+ --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
102
+ --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
103
+
104
+ /* Component-specific tokens */
105
+ --button-primary-border-gradient: linear-gradient(275.38deg, rgba(255, 255, 255, 0.07) 1.53%, rgba(255, 255, 255, 0.028) 94.58%);
106
+ }
107
+
108
+ /* Dark Mode */
109
+ [data-theme="dark"] {
110
+ --bg: #09090b;
111
+ --bg-secondary: #18181b;
112
+ --bg-tertiary: #27272a;
113
+ --fg: #fafafa;
114
+ --fg-secondary: #a1a1aa;
115
+ --fg-muted: #71717a;
116
+ --border-color: #27272a;
117
+ --border-color-strong: #3f3f46;
118
+
119
+ --brand-primary: #818cf8;
120
+ --brand-primary-light: #a5b4fc;
121
+ --brand-primary-dark: #6366f1;
122
+ --brand-secondary: #f472b6;
123
+ --brand-secondary-light: #f9a8d4;
124
+ --brand-secondary-dark: #ec4899;
125
+
126
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.3);
127
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
128
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
129
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4);
130
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.4), 0 8px 10px -6px rgb(0 0 0 / 0.4);
131
+
132
+ --button-primary-border-gradient: linear-gradient(275.38deg, rgba(255, 255, 255, 0.04) 1.53%, rgba(255, 255, 255, 0.02) 94.58%);
133
+ }
134
+
135
+ /* Logo dark-mode: invert dark SVG fills to light when loaded via <img> */
136
+ [data-theme="dark"] .logo-img {
137
+ filter: invert(1);
138
+ }
139
+
140
+ @theme inline {
141
+ --color-background: var(--bg);
142
+ --color-foreground: var(--fg);
143
+ --font-sans: var(--font-sans);
144
+ --font-mono: var(--font-mono);
145
+ }
146
+
147
+ /* ─── Base Styles ─── */
148
+ * {
149
+ border-color: var(--border-color);
150
+ }
151
+
152
+ body {
153
+ background: var(--bg);
154
+ color: var(--fg);
155
+ font-family: var(--font-sans);
156
+ line-height: 1.6;
157
+ -webkit-font-smoothing: antialiased;
158
+ -moz-osx-font-smoothing: grayscale;
159
+ }
160
+
161
+ ::selection {
162
+ background: var(--brand-primary);
163
+ color: white;
164
+ }
165
+
166
+ /* Scrollbar */
167
+ ::-webkit-scrollbar {
168
+ width: 8px;
169
+ height: 8px;
170
+ }
171
+ ::-webkit-scrollbar-track {
172
+ background: var(--bg-secondary);
173
+ }
174
+ ::-webkit-scrollbar-thumb {
175
+ background: var(--fg-muted);
176
+ border-radius: var(--radius-full);
177
+ }
178
+ ::-webkit-scrollbar-thumb:hover {
179
+ background: var(--fg-secondary);
180
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmitriikapustin/ui",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "Universal UI/UX Kit — React 19 component library with Atomic Design, CSS custom properties, and SCSS modules",
5
5
  "author": "Kapustin Team",
6
6
  "license": "MIT",
@@ -18,7 +18,8 @@
18
18
  "types": "./dist/index.d.cts",
19
19
  "default": "./dist/index.cjs"
20
20
  }
21
- }
21
+ },
22
+ "./styles.css": "./dist/styles.css"
22
23
  },
23
24
  "files": [
24
25
  "dist",
@@ -26,7 +27,7 @@
26
27
  ],
27
28
  "sideEffects": true,
28
29
  "scripts": {
29
- "build": "tsup && rm -f dist/index.css",
30
+ "build": "tsup && cp src/styles.css dist/styles.css",
30
31
  "dev": "tsup --watch",
31
32
  "typecheck": "tsc --noEmit",
32
33
  "clean": "rm -rf dist"