bsmnt 0.3.0 → 0.3.2

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.
Files changed (80) hide show
  1. package/dist/helpers/create/setup-sanity.d.ts.map +1 -1
  2. package/dist/helpers/create/setup-sanity.js +19 -1
  3. package/dist/helpers/create/setup-sanity.js.map +1 -1
  4. package/dist/helpers/integrate/sanity/config.d.ts.map +1 -1
  5. package/dist/helpers/integrate/sanity/config.js +11 -2
  6. package/dist/helpers/integrate/sanity/config.js.map +1 -1
  7. package/index.js +2 -2
  8. package/package.json +1 -1
  9. package/src/templates/next-default/.vscode/settings.json +1 -1
  10. package/src/templates/next-default/README.md +6 -7
  11. package/src/templates/next-default/app/layout.tsx +17 -4
  12. package/src/templates/next-default/biome.json +1 -1
  13. package/src/templates/next-default/css.d.ts +1 -0
  14. package/src/templates/next-default/lib/README.md +4 -8
  15. package/src/templates/next-default/lib/hooks/use-media.ts +3 -1
  16. package/src/templates/next-default/lib/styles/global.css +182 -0
  17. package/src/templates/next-default/lib/utils/json-ld.tsx +13 -18
  18. package/src/templates/next-default/lib/utils/portable-text-to-markdown.ts +83 -0
  19. package/src/templates/next-default/package.json +3 -3
  20. package/src/templates/next-experiments/.vscode/settings.json +1 -1
  21. package/src/templates/next-experiments/README.md +6 -7
  22. package/src/templates/next-experiments/app/layout.tsx +17 -4
  23. package/src/templates/next-experiments/biome.json +1 -1
  24. package/src/templates/next-experiments/css.d.ts +1 -0
  25. package/src/templates/next-experiments/lib/README.md +4 -8
  26. package/src/templates/next-experiments/lib/hooks/use-media.ts +3 -1
  27. package/src/templates/next-experiments/lib/styles/global.css +182 -0
  28. package/src/templates/next-experiments/lib/utils/json-ld.tsx +13 -18
  29. package/src/templates/next-experiments/lib/utils/portable-text-to-markdown.ts +83 -0
  30. package/src/templates/next-experiments/package.json +3 -3
  31. package/src/templates/next-webgl/.vscode/settings.json +1 -1
  32. package/src/templates/next-webgl/README.md +6 -7
  33. package/src/templates/next-webgl/app/layout.tsx +17 -4
  34. package/src/templates/next-webgl/biome.json +1 -1
  35. package/src/templates/next-webgl/css.d.ts +1 -0
  36. package/src/templates/next-webgl/lib/README.md +4 -8
  37. package/src/templates/next-webgl/lib/hooks/use-media.ts +3 -1
  38. package/src/templates/next-webgl/lib/styles/global.css +182 -0
  39. package/src/templates/next-webgl/lib/utils/json-ld.tsx +13 -18
  40. package/src/templates/next-webgl/lib/utils/portable-text-to-markdown.ts +83 -0
  41. package/src/templates/next-webgl/package.json +3 -3
  42. package/src/templates/next-default/lib/scripts/dev.ts +0 -32
  43. package/src/templates/next-default/lib/styles/README.md +0 -13
  44. package/src/templates/next-default/lib/styles/fonts.ts +0 -20
  45. package/src/templates/next-default/lib/styles/index.css +0 -3
  46. package/src/templates/next-default/lib/styles/tokens.css +0 -179
  47. package/src/templates/next-default/lib/utils/README.md +0 -40
  48. package/src/templates/next-default/lib/utils/easings.ts +0 -240
  49. package/src/templates/next-default/lib/utils/fetch.ts +0 -84
  50. package/src/templates/next-default/lib/utils/global-css.d.ts +0 -1
  51. package/src/templates/next-default/lib/utils/math.ts +0 -236
  52. package/src/templates/next-default/lib/utils/strings.ts +0 -246
  53. package/src/templates/next-default/lib/utils/types.d.ts +0 -15
  54. package/src/templates/next-default/lib/utils/viewport.ts +0 -199
  55. package/src/templates/next-experiments/lib/scripts/dev.ts +0 -32
  56. package/src/templates/next-experiments/lib/styles/README.md +0 -13
  57. package/src/templates/next-experiments/lib/styles/fonts.ts +0 -20
  58. package/src/templates/next-experiments/lib/styles/index.css +0 -3
  59. package/src/templates/next-experiments/lib/styles/tokens.css +0 -179
  60. package/src/templates/next-experiments/lib/utils/README.md +0 -40
  61. package/src/templates/next-experiments/lib/utils/easings.ts +0 -240
  62. package/src/templates/next-experiments/lib/utils/fetch.ts +0 -84
  63. package/src/templates/next-experiments/lib/utils/global-css.d.ts +0 -1
  64. package/src/templates/next-experiments/lib/utils/math.ts +0 -236
  65. package/src/templates/next-experiments/lib/utils/strings.ts +0 -246
  66. package/src/templates/next-experiments/lib/utils/types.d.ts +0 -15
  67. package/src/templates/next-experiments/lib/utils/viewport.ts +0 -199
  68. package/src/templates/next-webgl/lib/scripts/dev.ts +0 -32
  69. package/src/templates/next-webgl/lib/styles/README.md +0 -13
  70. package/src/templates/next-webgl/lib/styles/fonts.ts +0 -20
  71. package/src/templates/next-webgl/lib/styles/index.css +0 -3
  72. package/src/templates/next-webgl/lib/styles/tokens.css +0 -179
  73. package/src/templates/next-webgl/lib/utils/README.md +0 -40
  74. package/src/templates/next-webgl/lib/utils/easings.ts +0 -240
  75. package/src/templates/next-webgl/lib/utils/fetch.ts +0 -84
  76. package/src/templates/next-webgl/lib/utils/global-css.d.ts +0 -1
  77. package/src/templates/next-webgl/lib/utils/math.ts +0 -236
  78. package/src/templates/next-webgl/lib/utils/strings.ts +0 -246
  79. package/src/templates/next-webgl/lib/utils/types.d.ts +0 -15
  80. package/src/templates/next-webgl/lib/utils/viewport.ts +0 -199
@@ -1,3 +1,185 @@
1
+ @import "tailwindcss/utilities.css";
2
+
3
+ @custom-media --hover (hover: hover);
4
+ @custom-media --reduced-motion (prefers-reduced-motion: reduce);
5
+ @custom-media --mobile-only (width < 768px);
6
+ @custom-media --tablet (width >= 768px);
7
+ @custom-media --tablet-lg (width >= 1024px);
8
+ @custom-media --desktop (width >= 1440px);
9
+ @custom-media --desktop-large (width >= 1920px);
10
+
11
+ :root {
12
+ --device-width: 640;
13
+ --device-height: 650;
14
+ --columns: 4;
15
+ --gap: 16px;
16
+ --safe: 16px;
17
+ --header-height: 58px;
18
+ --layout-width: calc(100vw - (2 * var(--safe)));
19
+ --column-width: calc(
20
+ (var(--layout-width) - (var(--columns) - 1) * var(--gap)) / var(--columns)
21
+ );
22
+ --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);
23
+ --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
24
+ --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);
25
+ --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
26
+ --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
27
+ --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);
28
+ --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
29
+ --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
30
+ --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
31
+ --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
32
+ --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
33
+ --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);
34
+ --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);
35
+ --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
36
+ --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
37
+ --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
38
+ --ease-in-out-expo: cubic-bezier(1, 0, 0, 1);
39
+ --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
40
+ --ease-gleasing: cubic-bezier(0.4, 0, 0, 1);
41
+ --color-black: #000000;
42
+ --color-white: #ffffff;
43
+ --color-orange: #ff4d00;
44
+ --color-blue: #487cff;
45
+ --color-green: #00ff9b;
46
+ --color-violet: #f101a5;
47
+ --color-pink: #ff73a6;
48
+ --color-gray: #666666;
49
+
50
+ @variant desktop {
51
+ --device-width: 1440;
52
+ --device-height: 816;
53
+ --columns: 12;
54
+ --header-height: 98px;
55
+ }
56
+ }
57
+
58
+ @theme {
59
+ --breakpoint-*: initial;
60
+ --breakpoint-desktop-large: 1920px;
61
+ --breakpoint-desktop: 1440px;
62
+ --breakpoint-tablet-lg: 1024px;
63
+ --breakpoint-tablet: 768px;
64
+ --breakpoint-mobile: 640px;
65
+
66
+ --color-*: initial;
67
+ --color-primary: #ffffff;
68
+ --color-secondary: #000000;
69
+ --color-contrast: #ff4d00;
70
+ --color-black: #000000;
71
+ --color-white: #ffffff;
72
+ --color-orange: #ff4d00;
73
+ --color-blue: #487cff;
74
+ --color-green: #00ff9b;
75
+ --color-violet: #f101a5;
76
+ --color-pink: #ff73a6;
77
+ --color-gray: #666666;
78
+ --color-gray-50: #f5f5f5;
79
+ --color-gray-100: #e0e0e0;
80
+ --color-gray-200: #c2c2c2;
81
+ --color-gray-300: #a3a3a3;
82
+ --color-gray-400: #858585;
83
+ --color-gray-500: #666666;
84
+ --color-gray-600: #4d4d4d;
85
+ --color-gray-700: #333333;
86
+ --color-gray-800: #1a1a1a;
87
+
88
+ --spacing: 0.25rem;
89
+ --spacing-0: 0;
90
+ --spacing-safe: var(--safe);
91
+ --spacing-gap: var(--gap);
92
+ --spacing-header-height: var(--header-height);
93
+
94
+ --font-*: initial;
95
+ --font-mono: var(--geist-mono);
96
+
97
+ --ease-*: initial;
98
+ --ease-in-quad: var(--ease-in-quad);
99
+ --ease-in-cubic: var(--ease-in-cubic);
100
+ --ease-in-quart: var(--ease-in-quart);
101
+ --ease-in-quint: var(--ease-in-quint);
102
+ --ease-in-expo: var(--ease-in-expo);
103
+ --ease-in-circ: var(--ease-in-circ);
104
+ --ease-out-quad: var(--ease-out-quad);
105
+ --ease-out-cubic: var(--ease-out-cubic);
106
+ --ease-out-quart: var(--ease-out-quart);
107
+ --ease-out-quint: var(--ease-out-quint);
108
+ --ease-out-expo: var(--ease-out-expo);
109
+ --ease-out-circ: var(--ease-out-circ);
110
+ --ease-in-out-quad: var(--ease-in-out-quad);
111
+ --ease-in-out-cubic: var(--ease-in-out-cubic);
112
+ --ease-in-out-quart: var(--ease-in-out-quart);
113
+ --ease-in-out-quint: var(--ease-in-out-quint);
114
+ --ease-in-out-expo: var(--ease-in-out-expo);
115
+ --ease-in-out-circ: var(--ease-in-out-circ);
116
+ --ease-gleasing: var(--ease-gleasing);
117
+ }
118
+
119
+ [data-theme="light"] {
120
+ --color-primary: #ffffff;
121
+ --color-secondary: #000000;
122
+ --color-contrast: #ff4d00;
123
+ }
124
+
125
+ [data-theme="dark"] {
126
+ --color-primary: #000000;
127
+ --color-secondary: #ffffff;
128
+ --color-contrast: #ff4d00;
129
+ }
130
+
131
+ @utility test-mono {
132
+ font-family: var(--geist-mono);
133
+ font-size: 20px;
134
+ font-style: normal;
135
+ font-weight: 400;
136
+ letter-spacing: 0;
137
+ line-height: 90%;
138
+
139
+ @variant desktop {
140
+ font-size: 24px;
141
+ }
142
+ }
143
+
144
+ @utility desktop-only {
145
+ @media (--mobile-only) {
146
+ display: none !important;
147
+ }
148
+ }
149
+
150
+ @utility mobile-only {
151
+ @media (--tablet) {
152
+ display: none !important;
153
+ }
154
+ }
155
+
156
+ @utility b-grid {
157
+ column-gap: var(--gap);
158
+ display: grid;
159
+ grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
160
+ }
161
+
162
+ @utility b-layout-block {
163
+ margin-inline: auto;
164
+ width: calc(100% - 2 * var(--safe));
165
+ }
166
+
167
+ @utility b-layout-block-inner {
168
+ padding-inline: var(--safe);
169
+ width: 100%;
170
+ }
171
+
172
+ @utility b-layout-grid {
173
+ @apply b-layout-block b-grid;
174
+ }
175
+
176
+ @utility b-layout-grid-inner {
177
+ @apply b-layout-block-inner b-grid;
178
+ }
179
+
180
+ @custom-variant light (&:where([data-theme="light"], [data-theme="light"] *));
181
+ @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
182
+
1
183
  /***
2
184
  The new CSS reset - version 1.11.3 (last updated 25.08.2024)
3
185
  GitHub page: https://github.com/elad2412/the-new-css-reset
@@ -1,13 +1,8 @@
1
- import type {
2
- Article,
3
- BreadcrumbList,
4
- Organization,
5
- SearchAction,
6
- Thing,
7
- WebPage,
8
- WebSite,
9
- WithContext,
10
- } from "schema-dts";
1
+ type JsonLdValue = {
2
+ "@context": "https://schema.org";
3
+ "@type": string;
4
+ [key: string]: unknown;
5
+ };
11
6
 
12
7
  const APP_BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
13
8
 
@@ -25,10 +20,10 @@ function resolveUrl(value?: string) {
25
20
 
26
21
  /* -------------------------------- Component ------------------------------- */
27
22
 
28
- export function JsonLd<T extends Thing>({
23
+ export function JsonLd<T extends JsonLdValue>({
29
24
  data,
30
25
  }: {
31
- data: WithContext<T>;
26
+ data: T;
32
27
  }) {
33
28
  return (
34
29
  <script
@@ -52,7 +47,7 @@ interface WebSiteJsonLdOptions {
52
47
 
53
48
  export function generateWebSiteJsonLd(
54
49
  options: WebSiteJsonLdOptions
55
- ): WithContext<WebSite> {
50
+ ): JsonLdValue {
56
51
  const { name, url, description, searchUrl } = options;
57
52
  const resolvedUrl = resolveUrl(url);
58
53
  const resolvedSearchUrl = resolveUrl(searchUrl);
@@ -68,7 +63,7 @@ export function generateWebSiteJsonLd(
68
63
  "@type": "SearchAction",
69
64
  target: resolvedSearchUrl,
70
65
  "query-input": "required name=search_term_string",
71
- } as SearchAction & { "query-input": string },
66
+ },
72
67
  }),
73
68
  };
74
69
  }
@@ -83,7 +78,7 @@ interface OrganizationJsonLdOptions {
83
78
 
84
79
  export function generateOrganizationJsonLd(
85
80
  options: OrganizationJsonLdOptions
86
- ): WithContext<Organization> {
81
+ ): JsonLdValue {
87
82
  const { name, url, logo, description, sameAs } = options;
88
83
  const resolvedUrl = resolveUrl(url);
89
84
  const resolvedLogo = resolveUrl(logo);
@@ -110,7 +105,7 @@ interface WebPageJsonLdOptions {
110
105
 
111
106
  export function generateWebPageJsonLd(
112
107
  options: WebPageJsonLdOptions
113
- ): WithContext<WebPage> {
108
+ ): JsonLdValue {
114
109
  const { title, url, description, image, datePublished, dateModified } =
115
110
  options;
116
111
  const resolvedUrl = resolveUrl(url);
@@ -141,7 +136,7 @@ interface ArticleJsonLdOptions {
141
136
 
142
137
  export function generateArticleJsonLd(
143
138
  options: ArticleJsonLdOptions
144
- ): WithContext<Article> {
139
+ ): JsonLdValue {
145
140
  const {
146
141
  title,
147
142
  url,
@@ -181,7 +176,7 @@ interface BreadcrumbItem {
181
176
 
182
177
  export function generateBreadcrumbJsonLd(
183
178
  items: BreadcrumbItem[]
184
- ): WithContext<BreadcrumbList> {
179
+ ): JsonLdValue {
185
180
  return {
186
181
  "@context": "https://schema.org",
187
182
  "@type": "BreadcrumbList",
@@ -0,0 +1,83 @@
1
+ export interface PortableTextMarkDefinition {
2
+ _key?: string;
3
+ _type?: string;
4
+ href?: string;
5
+ }
6
+
7
+ export interface PortableTextSpan {
8
+ _type?: string;
9
+ text?: string;
10
+ marks?: string[];
11
+ }
12
+
13
+ export interface PortableTextBlock {
14
+ _type?: string;
15
+ style?: string;
16
+ listItem?: "bullet" | "number";
17
+ level?: number;
18
+ children?: PortableTextSpan[];
19
+ markDefs?: PortableTextMarkDefinition[];
20
+ }
21
+
22
+ const headingStyles: Record<string, string> = {
23
+ h1: "#",
24
+ h2: "##",
25
+ h3: "###",
26
+ h4: "####",
27
+ h5: "#####",
28
+ h6: "######",
29
+ }
30
+
31
+ function applyMarks(
32
+ text: string,
33
+ marks: string[] | undefined,
34
+ markDefs: PortableTextMarkDefinition[]
35
+ ) {
36
+ return (marks ?? []).reduce((result, mark) => {
37
+ if (mark === "strong") return `**${result}**`
38
+ if (mark === "em") return `*${result}*`
39
+ if (mark === "code") return `\`${result}\``
40
+
41
+ const link = markDefs.find((definition) => definition._key === mark)
42
+ if (link?._type === "link" && link.href) {
43
+ return `[${result}](${link.href})`
44
+ }
45
+
46
+ return result
47
+ }, text)
48
+ }
49
+
50
+ function serializeBlock(block: PortableTextBlock) {
51
+ const text = (block.children ?? [])
52
+ .map((child) =>
53
+ applyMarks(child.text ?? "", child.marks, block.markDefs ?? [])
54
+ )
55
+ .join("")
56
+ .trim()
57
+
58
+ if (!text) return ""
59
+
60
+ if (block.listItem) {
61
+ const level = Math.max((block.level ?? 1) - 1, 0)
62
+ const indent = " ".repeat(level)
63
+ const marker = block.listItem === "number" ? "1." : "-"
64
+ return `${indent}${marker} ${text}`
65
+ }
66
+
67
+ if (block.style === "blockquote") {
68
+ return `> ${text}`
69
+ }
70
+
71
+ const headingPrefix = headingStyles[block.style ?? ""]
72
+ if (headingPrefix) {
73
+ return `${headingPrefix} ${text}`
74
+ }
75
+
76
+ return text
77
+ }
78
+
79
+ export function portableTextToMarkdown(
80
+ value: PortableTextBlock[] | null | undefined
81
+ ) {
82
+ return (value ?? []).map(serializeBlock).filter(Boolean).join("\n\n")
83
+ }
@@ -8,9 +8,9 @@
8
8
  "analyze": "cross-env ANALYZE=true bun run build",
9
9
  "analyze:experimental": "next experimental-analyze",
10
10
  "build": "next build",
11
- "dev": "bun ./lib/scripts/dev.ts",
12
- "dev:https": "bun ./lib/scripts/dev.ts --https",
13
- "dev:inspect": "bun ./lib/scripts/dev.ts --inspect",
11
+ "dev": "next dev",
12
+ "dev:https": "next dev --experimental-https",
13
+ "dev:inspect": "next dev --inspect",
14
14
  "format": "biome format --write .",
15
15
  "lighthouse": "bunx @unlighthouse/cli --site http://localhost:3000",
16
16
  "lint": "biome lint --max-diagnostics=200",
@@ -1,32 +0,0 @@
1
- /**
2
- * Cross-platform Next.js dev launcher.
3
- */
4
-
5
- import { bunExecutable, colorEnv } from "./utils"
6
-
7
- const isHttps = process.argv.includes("--https")
8
- const isInspect = process.argv.includes("--inspect")
9
-
10
- // Build next dev command args
11
- const nextDevArgs = [bunExecutable, "next", "dev"]
12
- if (isHttps) nextDevArgs.push("--experimental-https")
13
- if (isInspect) nextDevArgs.push("--inspect")
14
-
15
- const devEnv = colorEnv()
16
-
17
- const nextDevProcess = Bun.spawn(nextDevArgs, {
18
- stdout: "inherit",
19
- stderr: "inherit",
20
- env: devEnv,
21
- })
22
-
23
- const cleanup = () => {
24
- nextDevProcess.kill()
25
- process.exit(0)
26
- }
27
-
28
- process.on("SIGINT", cleanup)
29
- process.on("SIGTERM", cleanup)
30
-
31
- await nextDevProcess.exited
32
- cleanup()
@@ -1,13 +0,0 @@
1
- # Styles
2
-
3
- Minimal Tailwind setup for the starter.
4
-
5
- ## Files
6
-
7
- | File | Purpose |
8
- |------|---------|
9
- | `index.css` | Single stylesheet entrypoint imported by `app/layout.tsx` |
10
- | `tokens.css` | Theme variables, breakpoints, and custom Tailwind utilities |
11
- | `global.css` | Reset and global app styles |
12
- | `fonts.ts` | Font variable setup |
13
- | `cn.ts` | Tailwind class merging helper |
@@ -1,20 +0,0 @@
1
- import { Geist_Mono } from "next/font/google";
2
-
3
- const mono = Geist_Mono({
4
- subsets: ["latin"],
5
- display: "swap",
6
- variable: "--geist-mono",
7
- fallback: [
8
- "ui-monospace",
9
- "SFMono-Regular",
10
- "Consolas",
11
- "Liberation Mono",
12
- "Menlo",
13
- "monospace",
14
- ],
15
- });
16
-
17
- const fonts = [mono];
18
- const fontsVariable = fonts.map((font) => font.variable).join(" ");
19
-
20
- export { fontsVariable };
@@ -1,3 +0,0 @@
1
- @import "tailwindcss/utilities.css";
2
- @import "./tokens.css";
3
- @import "./global.css";
@@ -1,179 +0,0 @@
1
- @custom-media --hover (hover: hover);
2
- @custom-media --reduced-motion (prefers-reduced-motion: reduce);
3
- @custom-media --mobile-only (width < 768px);
4
- @custom-media --tablet (width >= 768px);
5
- @custom-media --tablet-lg (width >= 1024px);
6
- @custom-media --desktop (width >= 1440px);
7
- @custom-media --desktop-large (width >= 1920px);
8
-
9
- :root {
10
- --device-width: 640;
11
- --device-height: 650;
12
- --columns: 4;
13
- --gap: 16px;
14
- --safe: 16px;
15
- --header-height: 58px;
16
- --layout-width: calc(100vw - (2 * var(--safe)));
17
- --column-width: calc(
18
- (var(--layout-width) - (var(--columns) - 1) * var(--gap)) / var(--columns)
19
- );
20
- --ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);
21
- --ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
22
- --ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);
23
- --ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
24
- --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
25
- --ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);
26
- --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
27
- --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
28
- --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
29
- --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
30
- --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
31
- --ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);
32
- --ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);
33
- --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
34
- --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
35
- --ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
36
- --ease-in-out-expo: cubic-bezier(1, 0, 0, 1);
37
- --ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
38
- --ease-gleasing: cubic-bezier(0.4, 0, 0, 1);
39
- --color-black: #000000;
40
- --color-white: #ffffff;
41
- --color-orange: #ff4d00;
42
- --color-blue: #487cff;
43
- --color-green: #00ff9b;
44
- --color-violet: #f101a5;
45
- --color-pink: #ff73a6;
46
- --color-gray: #666666;
47
-
48
- @variant desktop {
49
- --device-width: 1440;
50
- --device-height: 816;
51
- --columns: 12;
52
- --header-height: 98px;
53
- }
54
- }
55
-
56
- @theme {
57
- --breakpoint-*: initial;
58
- --breakpoint-desktop-large: 1920px;
59
- --breakpoint-desktop: 1440px;
60
- --breakpoint-tablet-lg: 1024px;
61
- --breakpoint-tablet: 768px;
62
- --breakpoint-mobile: 640px;
63
-
64
- --color-*: initial;
65
- --color-primary: #ffffff;
66
- --color-secondary: #000000;
67
- --color-contrast: #ff4d00;
68
- --color-black: #000000;
69
- --color-white: #ffffff;
70
- --color-orange: #ff4d00;
71
- --color-blue: #487cff;
72
- --color-green: #00ff9b;
73
- --color-violet: #f101a5;
74
- --color-pink: #ff73a6;
75
- --color-gray: #666666;
76
- --color-gray-50: #f5f5f5;
77
- --color-gray-100: #e0e0e0;
78
- --color-gray-200: #c2c2c2;
79
- --color-gray-300: #a3a3a3;
80
- --color-gray-400: #858585;
81
- --color-gray-500: #666666;
82
- --color-gray-600: #4d4d4d;
83
- --color-gray-700: #333333;
84
- --color-gray-800: #1a1a1a;
85
-
86
- --spacing: 0.25rem;
87
- --spacing-0: 0;
88
- --spacing-safe: var(--safe);
89
- --spacing-gap: var(--gap);
90
- --spacing-header-height: var(--header-height);
91
-
92
- --font-*: initial;
93
- --font-mono: var(--geist-mono);
94
-
95
- --ease-*: initial;
96
- --ease-in-quad: var(--ease-in-quad);
97
- --ease-in-cubic: var(--ease-in-cubic);
98
- --ease-in-quart: var(--ease-in-quart);
99
- --ease-in-quint: var(--ease-in-quint);
100
- --ease-in-expo: var(--ease-in-expo);
101
- --ease-in-circ: var(--ease-in-circ);
102
- --ease-out-quad: var(--ease-out-quad);
103
- --ease-out-cubic: var(--ease-out-cubic);
104
- --ease-out-quart: var(--ease-out-quart);
105
- --ease-out-quint: var(--ease-out-quint);
106
- --ease-out-expo: var(--ease-out-expo);
107
- --ease-out-circ: var(--ease-out-circ);
108
- --ease-in-out-quad: var(--ease-in-out-quad);
109
- --ease-in-out-cubic: var(--ease-in-out-cubic);
110
- --ease-in-out-quart: var(--ease-in-out-quart);
111
- --ease-in-out-quint: var(--ease-in-out-quint);
112
- --ease-in-out-expo: var(--ease-in-out-expo);
113
- --ease-in-out-circ: var(--ease-in-out-circ);
114
- --ease-gleasing: var(--ease-gleasing);
115
- }
116
-
117
- [data-theme="light"] {
118
- --color-primary: #ffffff;
119
- --color-secondary: #000000;
120
- --color-contrast: #ff4d00;
121
- }
122
-
123
- [data-theme="dark"] {
124
- --color-primary: #000000;
125
- --color-secondary: #ffffff;
126
- --color-contrast: #ff4d00;
127
- }
128
-
129
- @utility test-mono {
130
- font-family: var(--geist-mono);
131
- font-size: 20px;
132
- font-style: normal;
133
- font-weight: 400;
134
- letter-spacing: 0;
135
- line-height: 90%;
136
-
137
- @variant desktop {
138
- font-size: 24px;
139
- }
140
- }
141
-
142
- @utility desktop-only {
143
- @media (--mobile-only) {
144
- display: none !important;
145
- }
146
- }
147
-
148
- @utility mobile-only {
149
- @media (--tablet) {
150
- display: none !important;
151
- }
152
- }
153
-
154
- @utility b-grid {
155
- column-gap: var(--gap);
156
- display: grid;
157
- grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
158
- }
159
-
160
- @utility b-layout-block {
161
- margin-inline: auto;
162
- width: calc(100% - 2 * var(--safe));
163
- }
164
-
165
- @utility b-layout-block-inner {
166
- padding-inline: var(--safe);
167
- width: 100%;
168
- }
169
-
170
- @utility b-layout-grid {
171
- @apply b-layout-block b-grid;
172
- }
173
-
174
- @utility b-layout-grid-inner {
175
- @apply b-layout-block-inner b-grid;
176
- }
177
-
178
- @custom-variant light (&:where([data-theme="light"], [data-theme="light"] *));
179
- @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
@@ -1,40 +0,0 @@
1
- # Utils
2
-
3
- Pure utility functions organized by concern.
4
-
5
- Use explicit imports for clarity and better tree-shaking:
6
-
7
- ```tsx
8
- import { clamp, lerp, mapRange } from '@/utils/math'
9
- import { slugify } from '@/utils/strings'
10
- import { generatePageMetadata } from '@/utils/metadata'
11
- import { tovw, torem, toem } from '@/utils/viewport'
12
- ```
13
-
14
- ## Modules
15
-
16
- | Module | Functions |
17
- |--------|-----------|
18
- | `math` | `clamp`, `lerp`, `mapRange`, `modulo`, `normalize`, `distance` |
19
- | `easings` | All easing functions (`easeOutCubic`, etc.) |
20
- | `viewport` | `tovw`, `torem`, `toem` |
21
- | `strings` | `slugify`, `mergeRefs`, `capitalizeFirstLetter` |
22
- | `metadata` | `generatePageMetadata` |
23
-
24
- ## Common Patterns
25
-
26
- ```tsx
27
- // Math
28
- clamp(0, value, 100)
29
- lerp(0, 100, 0.5) // → 50
30
- mapRange(0, 1000, scrollY, 0, 1)
31
-
32
- // Viewport units
33
- tovw(100, 50, 'desktop') // → "max(50px, 6.94vw)"
34
- tovw(16, undefined, 'mobile') // → "4.27vw"
35
- torem(24) // → "1.5rem"
36
- toem(16, 14) // → "1.14em"
37
-
38
- // SEO
39
- export const metadata = generatePageMetadata({ title: 'About' })
40
- ```